|
Lines 61-89
std::optional<int> RenderMathMLRow::firstLineBaseline() const
a/Source/WebCore/rendering/mathml/RenderMathMLRow.cpp_sec1
|
| 61 |
return std::optional<int>(static_cast<int>(lroundf(ascentForChild(*baselineChild) + baselineChild->logicalTop()))); |
61 |
return std::optional<int>(static_cast<int>(lroundf(ascentForChild(*baselineChild) + baselineChild->logicalTop()))); |
| 62 |
} |
62 |
} |
| 63 |
|
63 |
|
| 64 |
void RenderMathMLRow::computeLineVerticalStretch(LayoutUnit& ascent, LayoutUnit& descent) |
64 |
static RenderMathMLOperator* toVerticalStretchyOperator(RenderBox* box) |
| 65 |
{ |
65 |
{ |
|
|
66 |
if (is<RenderMathMLBlock>(box)) { |
| 67 |
auto* renderOperator = downcast<RenderMathMLBlock>(*box).unembellishedOperator(); |
| 68 |
if (renderOperator && renderOperator->isStretchy() && renderOperator->isVertical()) |
| 69 |
return renderOperator; |
| 70 |
} |
| 71 |
return nullptr; |
| 72 |
} |
| 73 |
|
| 74 |
void RenderMathMLRow::stretchVerticalOperatorsAndLayoutChildren() |
| 75 |
{ |
| 76 |
// First calculate stretch ascent and descent. |
| 77 |
LayoutUnit stretchAscent, stretchDescent; |
| 66 |
for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) { |
78 |
for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) { |
| 67 |
if (is<RenderMathMLBlock>(child)) { |
79 |
if (child->isOutOfFlowPositioned()) { |
| 68 |
auto* renderOperator = downcast<RenderMathMLBlock>(child)->unembellishedOperator(); |
80 |
child->containingBlock()->insertPositionedObject(*child); |
| 69 |
if (renderOperator && renderOperator->isStretchy()) |
81 |
continue; |
| 70 |
continue; |
|
|
| 71 |
} |
82 |
} |
| 72 |
|
83 |
if (toVerticalStretchyOperator(child)) |
|
|
84 |
continue; |
| 73 |
child->layoutIfNeeded(); |
85 |
child->layoutIfNeeded(); |
|
|
86 |
LayoutUnit childAscent = ascentForChild(*child); |
| 87 |
LayoutUnit childDescent = child->logicalHeight() - childAscent; |
| 88 |
stretchAscent = std::max(stretchAscent, childAscent); |
| 89 |
stretchDescent = std::max(stretchDescent, childDescent); |
| 90 |
} |
| 91 |
if (stretchAscent + stretchDescent <= 0) { |
| 92 |
// We ensure a minimal stretch size. |
| 93 |
stretchAscent = style().computedFontPixelSize(); |
| 94 |
stretchDescent = 0; |
| 95 |
} |
| 74 |
|
96 |
|
| 75 |
LayoutUnit childHeightAboveBaseline = ascentForChild(*child); |
97 |
// Next, we stretch the vertical operators. |
| 76 |
LayoutUnit childDepthBelowBaseline = child->logicalHeight() - childHeightAboveBaseline; |
98 |
for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) { |
| 77 |
|
99 |
if (child->isOutOfFlowPositioned()) |
| 78 |
ascent = std::max(ascent, childHeightAboveBaseline); |
100 |
continue; |
| 79 |
descent = std::max(descent, childDepthBelowBaseline); |
101 |
if (auto renderOperator = toVerticalStretchyOperator(child)) { |
|
|
102 |
renderOperator->stretchTo(stretchAscent, stretchDescent); |
| 103 |
renderOperator->layoutIfNeeded(); |
| 104 |
} |
| 80 |
} |
105 |
} |
|
|
106 |
} |
| 107 |
|
| 108 |
void RenderMathMLRow::getContentBoundingBox(LayoutUnit& width, LayoutUnit& ascent, LayoutUnit& descent) const |
| 109 |
{ |
| 110 |
ascent = 0; |
| 111 |
descent = 0; |
| 112 |
width = borderAndPaddingStart(); |
| 113 |
for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) { |
| 114 |
if (child->isOutOfFlowPositioned()) |
| 115 |
continue; |
| 81 |
|
116 |
|
| 82 |
// We ensure a minimal stretch size. |
117 |
width += child->marginStart() + child->logicalWidth() + child->marginEnd(); |
| 83 |
if (ascent + descent <= 0) { |
118 |
LayoutUnit childAscent = ascentForChild(*child); |
| 84 |
ascent = style().computedFontPixelSize(); |
119 |
LayoutUnit childDescent = child->logicalHeight() - childAscent; |
| 85 |
descent = 0; |
120 |
ascent = std::max(ascent, childAscent + child->marginTop()); |
|
|
121 |
descent = std::max(descent, childDescent + child->marginBottom()); |
| 86 |
} |
122 |
} |
|
|
123 |
width += borderEnd() + paddingEnd(); |
| 87 |
} |
124 |
} |
| 88 |
|
125 |
|
| 89 |
void RenderMathMLRow::computePreferredLogicalWidths() |
126 |
void RenderMathMLRow::computePreferredLogicalWidths() |
|
Lines 93-171
void RenderMathMLRow::computePreferredLogicalWidths()
a/Source/WebCore/rendering/mathml/RenderMathMLRow.cpp_sec2
|
| 93 |
m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = 0; |
130 |
m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = 0; |
| 94 |
|
131 |
|
| 95 |
LayoutUnit preferredWidth = 0; |
132 |
LayoutUnit preferredWidth = 0; |
| 96 |
for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) |
133 |
for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) { |
|
|
134 |
if (child->isOutOfFlowPositioned()) |
| 135 |
continue; |
| 97 |
preferredWidth += child->maxPreferredLogicalWidth() + child->marginLogicalWidth(); |
136 |
preferredWidth += child->maxPreferredLogicalWidth() + child->marginLogicalWidth(); |
|
|
137 |
} |
| 98 |
|
138 |
|
| 99 |
m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = preferredWidth + borderAndPaddingLogicalWidth(); |
139 |
m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = preferredWidth + borderAndPaddingLogicalWidth(); |
| 100 |
|
140 |
|
| 101 |
setPreferredLogicalWidthsDirty(false); |
141 |
setPreferredLogicalWidthsDirty(false); |
| 102 |
} |
142 |
} |
| 103 |
|
143 |
|
| 104 |
void RenderMathMLRow::layoutRowItems(LayoutUnit& ascent, LayoutUnit& descent) |
144 |
void RenderMathMLRow::layoutRowItems(LayoutUnit width, LayoutUnit ascent) |
| 105 |
{ |
145 |
{ |
| 106 |
// We first stretch the vertical operators. |
|
|
| 107 |
// For inline formulas, we can then calculate the logical width. |
| 108 |
LayoutUnit width = borderAndPaddingStart(); |
| 109 |
for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) { |
| 110 |
if (child->isOutOfFlowPositioned()) |
| 111 |
continue; |
| 112 |
|
| 113 |
if (is<RenderMathMLBlock>(child)) { |
| 114 |
auto renderOperator = downcast<RenderMathMLBlock>(child)->unembellishedOperator(); |
| 115 |
if (renderOperator && renderOperator->isStretchy() && renderOperator->isVertical()) |
| 116 |
renderOperator->stretchTo(ascent, descent); |
| 117 |
} |
| 118 |
|
| 119 |
child->layoutIfNeeded(); |
| 120 |
|
| 121 |
width += child->marginStart() + child->logicalWidth() + child->marginEnd(); |
| 122 |
} |
| 123 |
|
| 124 |
width += borderEnd() + paddingEnd(); |
| 125 |
if ((!isRenderMathMLMath() || style().display() == INLINE)) |
| 126 |
setLogicalWidth(width); |
| 127 |
|
| 128 |
LayoutUnit verticalOffset = borderTop() + paddingTop(); |
| 129 |
LayoutUnit maxAscent = 0, maxDescent = 0; // Used baseline alignment. |
| 130 |
LayoutUnit horizontalOffset = borderAndPaddingStart(); |
146 |
LayoutUnit horizontalOffset = borderAndPaddingStart(); |
| 131 |
bool shouldFlipHorizontal = !style().isLeftToRightDirection(); |
|
|
| 132 |
for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) { |
147 |
for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) { |
| 133 |
if (child->isOutOfFlowPositioned()) { |
148 |
if (child->isOutOfFlowPositioned()) |
| 134 |
child->containingBlock()->insertPositionedObject(*child); |
|
|
| 135 |
continue; |
149 |
continue; |
| 136 |
} |
|
|
| 137 |
LayoutUnit childHorizontalExtent = child->logicalWidth(); |
| 138 |
LayoutUnit ascent = ascentForChild(*child); |
| 139 |
LayoutUnit descent = child->verticalMarginExtent() + child->logicalHeight() - ascent; |
| 140 |
maxAscent = std::max(maxAscent, ascent); |
| 141 |
maxDescent = std::max(maxDescent, descent); |
| 142 |
LayoutUnit childVerticalMarginBoxExtent = maxAscent + maxDescent; |
| 143 |
|
| 144 |
horizontalOffset += child->marginStart(); |
150 |
horizontalOffset += child->marginStart(); |
| 145 |
|
151 |
LayoutUnit childAscent = ascentForChild(*child); |
| 146 |
setLogicalHeight(std::max(logicalHeight(), verticalOffset + borderBottom() + paddingBottom() + childVerticalMarginBoxExtent + horizontalScrollbarHeight())); |
152 |
LayoutUnit childVerticalOffset = borderTop() + paddingTop() + child->marginTop() + ascent - childAscent; |
| 147 |
|
153 |
LayoutUnit childWidth = child->logicalWidth(); |
| 148 |
LayoutPoint childLocation(shouldFlipHorizontal ? logicalWidth() - horizontalOffset - childHorizontalExtent : horizontalOffset, verticalOffset + child->marginTop()); |
154 |
LayoutUnit childHorizontalOffset = style().isLeftToRightDirection() ? horizontalOffset : width - horizontalOffset - childWidth; |
| 149 |
child->setLocation(childLocation); |
155 |
child->setLocation(LayoutPoint(childHorizontalOffset, childVerticalOffset)); |
| 150 |
|
156 |
horizontalOffset += childWidth + child->marginEnd(); |
| 151 |
horizontalOffset += childHorizontalExtent + child->marginEnd(); |
|
|
| 152 |
} |
157 |
} |
| 153 |
|
|
|
| 154 |
LayoutUnit centerBlockOffset = 0; |
| 155 |
if (style().display() == BLOCK) |
| 156 |
centerBlockOffset = std::max<LayoutUnit>(0, (logicalWidth() - (horizontalOffset + borderEnd() + paddingEnd())) / 2); |
| 157 |
|
| 158 |
if (shouldFlipHorizontal && centerBlockOffset > 0) |
| 159 |
centerBlockOffset = -centerBlockOffset; |
| 160 |
|
| 161 |
for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) { |
| 162 |
LayoutUnit ascent = ascentForChild(*child); |
| 163 |
LayoutUnit startOffset = maxAscent - ascent; |
| 164 |
child->setLocation(child->location() + LayoutPoint(centerBlockOffset, startOffset)); |
| 165 |
} |
| 166 |
|
| 167 |
ascent = maxAscent; |
| 168 |
descent = maxDescent; |
| 169 |
} |
158 |
} |
| 170 |
|
159 |
|
| 171 |
void RenderMathMLRow::layoutBlock(bool relayoutChildren, LayoutUnit) |
160 |
void RenderMathMLRow::layoutBlock(bool relayoutChildren, LayoutUnit) |
|
Lines 175-190
void RenderMathMLRow::layoutBlock(bool relayoutChildren, LayoutUnit)
a/Source/WebCore/rendering/mathml/RenderMathMLRow.cpp_sec3
|
| 175 |
if (!relayoutChildren && simplifiedLayout()) |
164 |
if (!relayoutChildren && simplifiedLayout()) |
| 176 |
return; |
165 |
return; |
| 177 |
|
166 |
|
| 178 |
LayoutUnit ascent = 0; |
|
|
| 179 |
LayoutUnit descent = 0; |
| 180 |
computeLineVerticalStretch(ascent, descent); |
| 181 |
|
| 182 |
recomputeLogicalWidth(); |
167 |
recomputeLogicalWidth(); |
| 183 |
|
168 |
|
| 184 |
setLogicalHeight(borderAndPaddingLogicalHeight() + scrollbarLogicalHeight()); |
169 |
setLogicalHeight(borderAndPaddingLogicalHeight() + scrollbarLogicalHeight()); |
| 185 |
|
170 |
|
| 186 |
layoutRowItems(ascent, descent); |
171 |
LayoutUnit width, ascent, descent; |
|
|
172 |
stretchVerticalOperatorsAndLayoutChildren(); |
| 173 |
getContentBoundingBox(width, ascent, descent); |
| 174 |
|
| 175 |
if (isRenderMathMLMath() && style().display() == BLOCK) { |
| 176 |
// Display formulas must be centered horizontally. |
| 177 |
layoutRowItems(logicalWidth(), ascent); |
| 178 |
LayoutUnit centerBlockOffset = std::max<LayoutUnit>(0, logicalWidth() - width) / 2; |
| 179 |
if (!style().isLeftToRightDirection()) |
| 180 |
centerBlockOffset = -centerBlockOffset; |
| 181 |
for (auto* child = firstChildBox(); child; child = child->nextSiblingBox()) { |
| 182 |
if (!child->isOutOfFlowPositioned()) |
| 183 |
child->setLocation(child->location() + LayoutPoint(centerBlockOffset, 0)); |
| 184 |
} |
| 185 |
} else { |
| 186 |
layoutRowItems(width, ascent); |
| 187 |
setLogicalWidth(width); |
| 188 |
} |
| 187 |
|
189 |
|
|
|
190 |
setLogicalHeight(borderTop() + paddingTop() + ascent + descent + borderBottom() + paddingBottom() + horizontalScrollbarHeight()); |
| 188 |
updateLogicalHeight(); |
191 |
updateLogicalHeight(); |
| 189 |
|
192 |
|
| 190 |
layoutPositionedObjects(relayoutChildren); |
193 |
layoutPositionedObjects(relayoutChildren); |