Skip to content

Commit

Permalink
Update multi-column implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
sammycage committed Nov 24, 2024
1 parent c6158ff commit ada9ab9
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 43 deletions.
67 changes: 39 additions & 28 deletions source/layout/blockbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,8 @@ BlockFlowBox::~BlockFlowBox() = default;

bool BlockFlowBox::avoidsFloats() const
{
return isInline() || isFloating() || isPositioned() || isOverflowHidden() || isRootBox() || isFlexItem();
return isInline() || isFloating() || isPositioned() || isOverflowHidden()
|| hasColumnFlowBox() || hasColumnSpanBox() || isRootBox() || isFlexItem();
}

void BlockFlowBox::addChild(Box* newChild)
Expand Down Expand Up @@ -1349,6 +1350,35 @@ void BlockFlowBox::clearFloats(Clear clear)
}
}

void BlockFlowBox::determineHorizontalPosition(BoxFrame* child) const
{
if(style()->isLeftToRightDirection()) {
auto offsetX = borderLeft() + paddingLeft() + child->marginLeft();
if(containsFloats() && child->avoidsFloats()) {
auto startOffset = startOffsetForLine(child->y(), false);
if(child->style()->marginLeft().isAuto())
offsetX = std::max(offsetX, startOffset + child->marginLeft());
else if(startOffset > borderAndPaddingLeft()) {
offsetX = std::max(offsetX, startOffset);
}
}

child->setX(offsetX);
} else {
auto offsetX = borderRight() + paddingRight() + child->marginRight();
if(containsFloats() && child->avoidsFloats()) {
auto startOffset = startOffsetForLine(child->y(), false);
if(child->style()->marginRight().isAuto())
offsetX = std::max(offsetX, startOffset + child->marginRight());
else if(startOffset > borderAndPaddingRight()) {
offsetX = std::max(offsetX, startOffset);
}
}

child->setX(width() - offsetX - child->width());
}
}

void BlockFlowBox::layoutBlockChild(BoxFrame* child, MarginInfo& marginInfo)
{
auto posTop = m_maxPositiveMarginTop;
Expand Down Expand Up @@ -1385,32 +1415,7 @@ void BlockFlowBox::layoutBlockChild(BoxFrame* child, MarginInfo& marginInfo)
marginInfo.setAtTopOfBlock(false);
}

if(style()->isLeftToRightDirection()) {
auto offsetX = borderLeft() + paddingLeft() + child->marginLeft();
if(containsFloats() && child->avoidsFloats()) {
auto startOffset = startOffsetForLine(child->y(), false);
if(child->style()->marginLeft().isAuto())
offsetX = std::max(offsetX, startOffset + child->marginLeft());
else if(startOffset > borderAndPaddingLeft()) {
offsetX = std::max(offsetX, startOffset);
}
}

child->setX(offsetX);
} else {
auto offsetX = borderRight() + paddingRight() + child->marginRight();
if(containsFloats() && child->avoidsFloats()) {
auto startOffset = startOffsetForLine(child->y(), false);
if(child->style()->marginRight().isAuto())
offsetX = std::max(offsetX, startOffset + child->marginRight());
else if(startOffset > borderAndPaddingRight()) {
offsetX = std::max(offsetX, startOffset);
}
}

child->setX(width() - offsetX - child->width());
}

determineHorizontalPosition(child);
if(child->isMultiColumnSpanBox()) {
auto spanner = to<MultiColumnSpanBox>(child);
spanner->box()->setX(child->x());
Expand All @@ -1436,10 +1441,15 @@ void BlockFlowBox::layoutBlockChildren()
} else if(child->isFloating()) {
insertFloatingBox(child);
adjustFloatingBox(marginInfo);
} else if(child->isColumnSpanAll()) {
} else if(child->hasColumnSpanBox()) {
setHeight(height() + marginInfo.margin());
child->columnSpanBox()->columnFlowBox()->skipColumnSpanBox(child, height());
marginInfo.clearMargin();
} else if(child->isMultiColumnFlowBox()) {
assert(child == m_columnFlowBox);
child->setY(top);
child->layout();
determineHorizontalPosition(child);
} else {
layoutBlockChild(child, marginInfo);
}
Expand Down Expand Up @@ -1489,6 +1499,7 @@ void BlockFlowBox::build()
appendChild(columnFlowBox);
columnFlowBox->setChildrenInline(isChildrenInline());
setChildrenInline(false);
setHasColumnFlowBox(true);
m_columnFlowBox = columnFlowBox;
}

Expand Down
2 changes: 2 additions & 0 deletions source/layout/blockbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ class BlockFlowBox : public BlockBox {
float getClearDelta(BoxFrame* child, float y) const;
void clearFloats(Clear clear);

void determineHorizontalPosition(BoxFrame* child) const;

void layoutBlockChild(BoxFrame* child, MarginInfo& marginInfo);
void layoutBlockChildren();

Expand Down
6 changes: 3 additions & 3 deletions source/layout/box.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ BlockFlowBox* Box::createAnonymousBlock(const BoxStyle* parentStyle)

BlockBox* Box::containingBlock() const
{
if(isColumnSpanAll())
if(hasColumnSpanBox())
return containingColumn()->containingBlock();
auto parent = parentBox();
if(position() == Position::Static || position() == Position::Relative || isTextBox()) {
Expand Down Expand Up @@ -221,7 +221,7 @@ BlockBox* Box::containingBlock() const

BoxModel* Box::containingBox() const
{
if(isColumnSpanAll())
if(hasColumnSpanBox())
return containingColumn()->containingBox();
auto parent = parentBox();
if(!isTextBox()) {
Expand All @@ -245,7 +245,7 @@ BoxModel* Box::containingBox() const

MultiColumnFlowBox* Box::containingColumn() const
{
assert(isInsideColumn());
assert(isInsideColumnFlow());
auto parent = parentBox();
while(parent) {
if(parent->isMultiColumnFlowBox())
Expand Down
15 changes: 9 additions & 6 deletions source/layout/box.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,9 @@ class Box : public HeapMember {
bool isFloatingOrPositioned() const { return m_floating || m_positioned; }
bool isReplaced() const { return m_replaced; }
bool isOverflowHidden() const { return m_overflowHidden; }
bool isColumnSpanAll() const { return m_isColumnSpanAll; }
bool isInsideColumn() const { return m_isInsideColumn; }
bool isInsideColumnFlow() const { return m_isInsideColumnFlow; }
bool hasColumnFlowBox() const { return m_hasColumnFlowBox; }
bool hasColumnSpanBox() const { return m_hasColumnSpanBox; }
bool hasTransform() const { return m_hasTransform; }
bool hasLayer() const { return m_hasLayer; }

Expand All @@ -158,8 +159,9 @@ class Box : public HeapMember {
void setPositioned(bool value) { m_positioned = value; }
void setReplaced(bool value) { m_replaced = value; }
void setOverflowHidden(bool value) { m_overflowHidden = value; }
void setIsColumnSpanAll(bool value) { m_isColumnSpanAll = value; }
void setIsInsideColumn(bool value) { m_isInsideColumn = value; }
void setIsInsideColumnFlow(bool value) { m_isInsideColumnFlow = value; }
void setHasColumnFlowBox(bool value) { m_hasColumnFlowBox = value; }
void setHasColumnSpanBox(bool value) { m_hasColumnSpanBox = value; }
void setHasTransform(bool value) { m_hasTransform = value; }
void setHasLayer(bool value) { m_hasLayer = value; }

Expand Down Expand Up @@ -195,8 +197,9 @@ class Box : public HeapMember {
bool m_positioned : 1 {false};
bool m_replaced : 1 {false};
bool m_overflowHidden : 1 {false};
bool m_isColumnSpanAll : 1 {false};
bool m_isInsideColumn : 1 {false};
bool m_isInsideColumnFlow : 1 {false};
bool m_hasColumnFlowBox : 1 {false};
bool m_hasColumnSpanBox : 1 {false};
bool m_hasTransform : 1 {false};
bool m_hasLayer : 1 {false};
};
Expand Down
10 changes: 4 additions & 6 deletions source/layout/multicolumnbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ void MultiColumnRowBox::distributeImplicitBreaks()
MultiColumnSpanBox* MultiColumnSpanBox::create(BoxFrame* box, const BoxStyle* parentStyle)
{
auto newStyle = BoxStyle::create(*parentStyle, Display::Block);
auto newSpanner = new (newStyle->heap()) MultiColumnSpanBox(box,newStyle);
auto newSpanner = new (newStyle->heap()) MultiColumnSpanBox(box, newStyle);
newSpanner->setAnonymous(true);
return newSpanner;
}
Expand Down Expand Up @@ -300,7 +300,7 @@ void MultiColumnFlowBox::updateMinimumColumnHeight(float offset, float minHeight
void MultiColumnFlowBox::skipColumnSpanBox(BoxFrame* box, float offset)
{
auto columnSpanBox = box->columnSpanBox();
assert(columnSpanBox && box->isColumnSpanAll());
assert(columnSpanBox && box->hasColumnSpanBox());
auto prevColumnBox = columnSpanBox->prevMultiColumnBox();
if(prevColumnBox && prevColumnBox->isMultiColumnRowBox()) {
auto columnRow = to<MultiColumnRowBox>(prevColumnBox);
Expand All @@ -319,8 +319,6 @@ void MultiColumnFlowBox::skipColumnSpanBox(BoxFrame* box, float offset)

MultiColumnRowBox* MultiColumnFlowBox::columnRowAtOffset(float offset) const
{
if(m_currentRow == nullptr)
return firstRow();
auto row = m_currentRow;
while(row->rowTop() > offset) {
auto prevRow = row->prevRow();
Expand Down Expand Up @@ -397,12 +395,12 @@ void MultiColumnFlowBox::build()
const MultiColumnSpanBox* currentColumnSpanner = nullptr;
auto child = firstChild();
while(child) {
child->setIsInsideColumn(true);
child->setIsInsideColumnFlow(true);
if(auto box = to<BoxFrame>(child); isValidColumnSpanBox(box)) {
auto newSpanner = MultiColumnSpanBox::create(box, style());
parentBox()->addChild(newSpanner);
box->setIsColumnSpanAll(true);
box->setColumnSpanBox(newSpanner);
box->setHasColumnSpanBox(true);
currentColumnSpanner = newSpanner;
} else if(!child->isFloatingOrPositioned()) {
if(m_lastRow == nullptr || currentColumnSpanner) {
Expand Down

0 comments on commit ada9ab9

Please sign in to comment.