Changeset 205441 in webkit
- Timestamp:
- Sep 5, 2016 2:19:48 AM (8 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r205430 r205441 1 2016-09-05 Frederic Wang <fwang@igalia.com> 2 3 More refactoring of RenderMathMLScripts 4 https://bugs.webkit.org/show_bug.cgi?id=161371 5 6 Reviewed by Darin Adler. 7 8 This is a follow-up of bug 161084. The function getScriptMetricsAndLayoutIfNeeded was quite 9 complicated and it was not obvious that we have to call it twice with the same reference 10 to a struture holding vertical metrics. We extract the part retrieving layout parameters 11 into verticalParameters and move its layoutIfNeeded calls into layoutBlock. Then it can 12 be reduced to a simple function that retrieve the vertical metrics in one call. 13 We also improve getBaseAndScripts to make clear that it is performing validation. It returns 14 a ReferenceChildren structure encapsulating pointers to important children so that we no 15 longer pass these pointers as function parameters. We continue to need them to browse the 16 list of prescripts & postscripts but we refactor a bit the loop to avoid explicit mention 17 of RenderBox*. 18 19 No new tests, already covered by existing tests. 20 21 * rendering/mathml/RenderMathMLScripts.cpp: 22 (WebCore::RenderMathMLScripts::validateAndGetReferenceChildren): We now store the pointers to 23 the base, firstPostScript and firstPreScript children in the ReferenceChildren structure. We 24 also add a pointer to the prescriptDelimiter for convenience. 25 (WebCore::RenderMathMLScripts::italicCorrection): Use the ReferenceChildren structure so that 26 we are sure the base has been validated before calling this function. 27 (WebCore::RenderMathMLScripts::computePreferredLogicalWidths): Retrieve the reference 28 children with validateAndGetReferenceChildren instead of calling getBaseAndScripts and use 29 ReferenceChildren to handle these children and to call italicCorrection. The loops for 30 SubSup, UnderOver, Multiscripts are also rewritten a bit to avoid declaring a null RenderBox* 31 outside of them and hence allow to use auto. 32 (WebCore::RenderMathMLScripts::verticalParameters): This part to extract the layout 33 parameters is extracted from getScriptMetricsAndLayoutIfNeeded. The parameters are returned 34 as a VerticalParameters struct. 35 (WebCore::RenderMathMLScripts::verticalMetrics): This is the remaining part of 36 getScriptMetricsAndLayoutIfNeeded It used to call layoutIfNeeded on children and to 37 calculate maximum vertical metrics. For Multiscripts it was called twice: We did a first 38 call to handle the prescripts and then pass the result again in the second call to handle 39 the postscripts. We modify a bit the loop so that all the scripts are handled in one call and 40 hence we can directly return a VerticalMetrics. Again, the reference children are now handled 41 using the ReferenceChildren structure passed as a parameter. 42 (WebCore::RenderMathMLScripts::layoutBlock): We retrieve the reference children with 43 validateAndGetReferenceChildren instead of calling getBaseAndScripts and use 44 ReferenceChildren to handle these children and to call italicCorrection. We layout all the 45 children if needed in one loop at the beginning instead of doing that when their vertical 46 metrics are needed. We can now also retrieve vertical metrics with a single call. 47 (WebCore::RenderMathMLScripts::getBaseAndScripts): Renamed validateAndGetReferenceChildren. 48 (WebCore::RenderMathMLScripts::getScriptMetricsAndLayoutIfNeeded): Deleted. Split into 49 verticalParameters and verticalMetrics. 50 * rendering/mathml/RenderMathMLScripts.h: New structure to handle the pointers to reference 51 children. Update the signature of getBaseAndScripts to use this struture and give a clearer 52 name. Update the signature of italicCorrection to use this structure too. Add a new structure 53 VerticalParameters and declare the helper function to retrieve them. Rename ScriptMetrics 54 to VerticalMetrics and update the signature of the function needed to retrieve it. 55 1 56 2016-09-05 Zan Dobersek <zdobersek@igalia.com> 2 57 -
trunk/Source/WebCore/rendering/mathml/RenderMathMLScripts.cpp
r205105 r205441 77 77 } 78 78 79 bool RenderMathMLScripts::getBaseAndScripts(RenderBox*& base, RenderBox*& firstPostScript, RenderBox*& firstPreScript)79 Optional<RenderMathMLScripts::ReferenceChildren> RenderMathMLScripts::validateAndGetReferenceChildren() 80 80 { 81 81 // All scripted elements must have at least one child. 82 82 // The first child is the base. 83 base = firstChildBox(); 84 firstPostScript = nullptr; 85 firstPreScript = nullptr; 83 auto base = firstChildBox(); 86 84 if (!base) 87 return false; 85 return Nullopt; 86 87 ReferenceChildren reference; 88 reference.base = base; 89 reference.firstPostScript = nullptr; 90 reference.firstPreScript = nullptr; 91 reference.prescriptDelimiter = nullptr; 88 92 89 93 switch (m_scriptType) { … … 91 95 case Super: 92 96 case Under: 93 case Over: 97 case Over: { 94 98 // These elements must have exactly two children. 95 99 // The second child is a postscript and there are no prescripts. … … 98 102 // <munder> base underscript </munder> 99 103 // <mover> base overscript </mover> 100 firstPostScript = base->nextSiblingBox(); 101 return firstPostScript && !isPrescriptDelimiter(*firstPostScript) && !firstPostScript->nextSiblingBox(); 104 auto script = base->nextSiblingBox(); 105 if (!script || isPrescriptDelimiter(*script) || script->nextSiblingBox()) 106 return Nullopt; 107 reference.firstPostScript = script; 108 return reference; 109 } 102 110 case SubSup: 103 111 case UnderOver: { … … 106 114 // <msubsup> base subscript superscript </msubsup> 107 115 // <munderover> base subscript superscript </munderover> 108 firstPostScript = base->nextSiblingBox(); 109 if (!firstPostScript || isPrescriptDelimiter(*firstPostScript)) 110 return false; 111 auto superScript = firstPostScript->nextSiblingBox(); 112 return superScript && !isPrescriptDelimiter(*superScript) && !superScript->nextSiblingBox(); 116 auto subScript = base->nextSiblingBox(); 117 if (!subScript || isPrescriptDelimiter(*subScript)) 118 return Nullopt; 119 auto superScript = subScript->nextSiblingBox(); 120 if (!superScript || isPrescriptDelimiter(*superScript) || superScript->nextSiblingBox()) 121 return Nullopt; 122 reference.firstPostScript = subScript; 123 return reference; 113 124 } 114 125 case Multiscripts: { … … 125 136 // We set the first postscript, unless (subscript superscript)* is empty. 126 137 if (base->nextSiblingBox() && !isPrescriptDelimiter(*base->nextSiblingBox())) 127 firstPostScript = base->nextSiblingBox();138 reference.firstPostScript = base->nextSiblingBox(); 128 139 129 140 // We browse the children in order to … … 137 148 if (isPrescriptDelimiter(*script)) { 138 149 // This is a <mprescripts/>. Let's check 2a) and 2c). 139 if (!numberOfScriptIsEven || firstPreScript) 140 return false; 141 firstPreScript = script->nextSiblingBox(); // We do 1). 150 if (!numberOfScriptIsEven || reference.firstPreScript) 151 return Nullopt; 152 reference.firstPreScript = script->nextSiblingBox(); // We do 1). 153 reference.prescriptDelimiter = script; 142 154 continue; 143 155 } 144 156 numberOfScriptIsEven = !numberOfScriptIsEven; 145 157 } 146 return numberOfScriptIsEven ; // We verify 2b).158 return numberOfScriptIsEven ? Optional<ReferenceChildren>(reference) : Nullopt; // We verify 2b). 147 159 } 148 160 } 149 161 150 162 ASSERT_NOT_REACHED(); 151 return false;163 return Nullopt; 152 164 } 153 165 … … 160 172 } 161 173 162 LayoutUnit RenderMathMLScripts::italicCorrection( RenderBox* base)163 { 164 if (is<RenderMathMLBlock>(* base)) {165 if (auto* renderOperator = downcast<RenderMathMLBlock>(* base).unembellishedOperator())174 LayoutUnit RenderMathMLScripts::italicCorrection(const ReferenceChildren& reference) 175 { 176 if (is<RenderMathMLBlock>(*reference.base)) { 177 if (auto* renderOperator = downcast<RenderMathMLBlock>(*reference.base).unembellishedOperator()) 166 178 return renderOperator->italicCorrection(); 167 179 } … … 174 186 m_maxPreferredLogicalWidth = 0; 175 187 176 RenderBox* base; 177 RenderBox* firstPostScript; 178 RenderBox* firstPreScript; 179 if (!getBaseAndScripts(base, firstPostScript, firstPreScript)) 188 auto possibleReference = validateAndGetReferenceChildren(); 189 if (!possibleReference) 180 190 return; 181 182 LayoutUnit baseItalicCorrection = std::min(base->maxPreferredLogicalWidth(), italicCorrection(base)); 191 auto& reference = possibleReference.value(); 192 193 LayoutUnit baseItalicCorrection = std::min(reference.base->maxPreferredLogicalWidth(), italicCorrection(reference)); 183 194 LayoutUnit space = spaceAfterScript(); 184 195 … … 186 197 case Sub: 187 198 case Under: 188 m_maxPreferredLogicalWidth += base->maxPreferredLogicalWidth();189 m_maxPreferredLogicalWidth += std::max(LayoutUnit(0), firstPostScript->maxPreferredLogicalWidth() - baseItalicCorrection + space);199 m_maxPreferredLogicalWidth += reference.base->maxPreferredLogicalWidth(); 200 m_maxPreferredLogicalWidth += std::max(LayoutUnit(0), reference.firstPostScript->maxPreferredLogicalWidth() - baseItalicCorrection + space); 190 201 break; 191 202 case Super: 192 203 case Over: 193 m_maxPreferredLogicalWidth += base->maxPreferredLogicalWidth();194 m_maxPreferredLogicalWidth += std::max(LayoutUnit(0), firstPostScript->maxPreferredLogicalWidth() + space);204 m_maxPreferredLogicalWidth += reference.base->maxPreferredLogicalWidth(); 205 m_maxPreferredLogicalWidth += std::max(LayoutUnit(0), reference.firstPostScript->maxPreferredLogicalWidth() + space); 195 206 break; 196 207 case SubSup: 197 208 case UnderOver: 198 209 case Multiscripts: { 199 RenderBox* supScript;200 for (auto* subScript = firstPreScript; subScript; subScript = supScript->nextSiblingBox()) {201 supScript = subScript->nextSiblingBox();210 auto subScript = reference.firstPreScript; 211 while (subScript) { 212 auto supScript = subScript->nextSiblingBox(); 202 213 ASSERT(supScript); 203 214 LayoutUnit subSupPairWidth = std::max(subScript->maxPreferredLogicalWidth(), supScript->maxPreferredLogicalWidth()); 204 215 m_maxPreferredLogicalWidth += subSupPairWidth + space; 205 } 206 m_maxPreferredLogicalWidth += base->maxPreferredLogicalWidth(); 207 for (auto* subScript = firstPostScript; subScript && !isPrescriptDelimiter(*subScript); subScript = supScript->nextSiblingBox()) { 208 supScript = subScript->nextSiblingBox(); 216 subScript = supScript->nextSiblingBox(); 217 } 218 m_maxPreferredLogicalWidth += reference.base->maxPreferredLogicalWidth(); 219 subScript = reference.firstPostScript; 220 while (subScript && subScript != reference.prescriptDelimiter) { 221 auto supScript = subScript->nextSiblingBox(); 209 222 ASSERT(supScript); 210 223 LayoutUnit subSupPairWidth = std::max(std::max(LayoutUnit(0), subScript->maxPreferredLogicalWidth() - baseItalicCorrection), supScript->maxPreferredLogicalWidth()); 211 224 m_maxPreferredLogicalWidth += subSupPairWidth + space; 225 subScript = supScript->nextSiblingBox(); 212 226 } 213 227 } … … 217 231 } 218 232 219 void RenderMathMLScripts::getScriptMetricsAndLayoutIfNeeded(RenderBox* base, RenderBox* script, ScriptMetrics& metrics) 220 { 221 LayoutUnit baseAscent = ascentForChild(*base); 222 LayoutUnit baseDescent = base->logicalHeight() - baseAscent; 223 LayoutUnit subscriptShiftDown; 224 LayoutUnit superscriptShiftUp; 225 LayoutUnit subscriptBaselineDropMin; 226 LayoutUnit superScriptBaselineDropMax; 227 LayoutUnit subSuperscriptGapMin; 228 LayoutUnit superscriptBottomMin; 229 LayoutUnit subscriptTopMax; 230 LayoutUnit superscriptBottomMaxWithSubscript; 231 233 auto RenderMathMLScripts::verticalParameters() const -> VerticalParameters 234 { 235 VerticalParameters parameters; 232 236 const auto& primaryFont = style().fontCascade().primaryFont(); 233 237 if (auto* mathData = primaryFont.mathData()) { 234 subscriptShiftDown = mathData->getMathConstant(primaryFont, OpenTypeMathData::SubscriptShiftDown);235 superscriptShiftUp = mathData->getMathConstant(primaryFont, OpenTypeMathData::SuperscriptShiftUp);236 subscriptBaselineDropMin = mathData->getMathConstant(primaryFont, OpenTypeMathData::SubscriptBaselineDropMin);237 superScriptBaselineDropMax = mathData->getMathConstant(primaryFont, OpenTypeMathData::SuperscriptBaselineDropMax);238 subSuperscriptGapMin = mathData->getMathConstant(primaryFont, OpenTypeMathData::SubSuperscriptGapMin);239 superscriptBottomMin = mathData->getMathConstant(primaryFont, OpenTypeMathData::SuperscriptBottomMin);240 subscriptTopMax = mathData->getMathConstant(primaryFont, OpenTypeMathData::SubscriptTopMax);241 superscriptBottomMaxWithSubscript = mathData->getMathConstant(primaryFont, OpenTypeMathData::SuperscriptBottomMaxWithSubscript);238 parameters.subscriptShiftDown = mathData->getMathConstant(primaryFont, OpenTypeMathData::SubscriptShiftDown); 239 parameters.superscriptShiftUp = mathData->getMathConstant(primaryFont, OpenTypeMathData::SuperscriptShiftUp); 240 parameters.subscriptBaselineDropMin = mathData->getMathConstant(primaryFont, OpenTypeMathData::SubscriptBaselineDropMin); 241 parameters.superScriptBaselineDropMax = mathData->getMathConstant(primaryFont, OpenTypeMathData::SuperscriptBaselineDropMax); 242 parameters.subSuperscriptGapMin = mathData->getMathConstant(primaryFont, OpenTypeMathData::SubSuperscriptGapMin); 243 parameters.superscriptBottomMin = mathData->getMathConstant(primaryFont, OpenTypeMathData::SuperscriptBottomMin); 244 parameters.subscriptTopMax = mathData->getMathConstant(primaryFont, OpenTypeMathData::SubscriptTopMax); 245 parameters.superscriptBottomMaxWithSubscript = mathData->getMathConstant(primaryFont, OpenTypeMathData::SuperscriptBottomMaxWithSubscript); 242 246 } else { 243 247 // Default heuristic values when you do not have a font. 244 subscriptShiftDown = style().fontMetrics().xHeight() / 3; 245 superscriptShiftUp = style().fontMetrics().xHeight(); 246 subscriptBaselineDropMin = style().fontMetrics().xHeight() / 2; 247 superScriptBaselineDropMax = style().fontMetrics().xHeight() / 2; 248 subSuperscriptGapMin = style().fontCascade().size() / 5; 249 superscriptBottomMin = style().fontMetrics().xHeight() / 4; 250 subscriptTopMax = 4 * style().fontMetrics().xHeight() / 5; 251 superscriptBottomMaxWithSubscript = 4 * style().fontMetrics().xHeight() / 5; 252 } 253 248 parameters.subscriptShiftDown = style().fontMetrics().xHeight() / 3; 249 parameters.superscriptShiftUp = style().fontMetrics().xHeight(); 250 parameters.subscriptBaselineDropMin = style().fontMetrics().xHeight() / 2; 251 parameters.superScriptBaselineDropMax = style().fontMetrics().xHeight() / 2; 252 parameters.subSuperscriptGapMin = style().fontCascade().size() / 5; 253 parameters.superscriptBottomMin = style().fontMetrics().xHeight() / 4; 254 parameters.subscriptTopMax = 4 * style().fontMetrics().xHeight() / 5; 255 parameters.superscriptBottomMaxWithSubscript = 4 * style().fontMetrics().xHeight() / 5; 256 } 257 return parameters; 258 } 259 260 RenderMathMLScripts::VerticalMetrics RenderMathMLScripts::verticalMetrics(const ReferenceChildren& reference) 261 { 262 VerticalParameters parameters = verticalParameters(); 263 VerticalMetrics metrics = { 0, 0, 0, 0 }; 264 265 LayoutUnit baseAscent = ascentForChild(*reference.base); 266 LayoutUnit baseDescent = reference.base->logicalHeight() - baseAscent; 254 267 if (m_scriptType == Sub || m_scriptType == SubSup || m_scriptType == Multiscripts || m_scriptType == Under || m_scriptType == UnderOver) { 255 metrics.subShift = std::max( subscriptShiftDown, baseDescent +subscriptBaselineDropMin);268 metrics.subShift = std::max(parameters.subscriptShiftDown, baseDescent + parameters.subscriptBaselineDropMin); 256 269 if (!isRenderMathMLUnderOver()) { 257 270 // It is not clear how to interpret the default shift and it is not available yet anyway. … … 262 275 } 263 276 if (m_scriptType == Super || m_scriptType == SubSup || m_scriptType == Multiscripts || m_scriptType == Over || m_scriptType == UnderOver) { 264 metrics.supShift = std::max( superscriptShiftUp, baseAscent -superScriptBaselineDropMax);277 metrics.supShift = std::max(parameters.superscriptShiftUp, baseAscent - parameters.superScriptBaselineDropMax); 265 278 if (!isRenderMathMLUnderOver()) { 266 279 // It is not clear how to interpret the default shift and it is not available yet anyway. … … 274 287 case Sub: 275 288 case Under: { 276 script->layoutIfNeeded(); 277 LayoutUnit subAscent = ascentForChild(*script); 278 LayoutUnit subDescent = script->logicalHeight() - subAscent; 289 LayoutUnit subAscent = ascentForChild(*reference.firstPostScript); 290 LayoutUnit subDescent = reference.firstPostScript->logicalHeight() - subAscent; 279 291 metrics.descent = subDescent; 280 metrics.subShift = std::max(metrics.subShift, subAscent - subscriptTopMax);292 metrics.subShift = std::max(metrics.subShift, subAscent - parameters.subscriptTopMax); 281 293 } 282 294 break; 283 295 case Super: 284 296 case Over: { 285 script->layoutIfNeeded(); 286 LayoutUnit supAscent = ascentForChild(*script); 287 LayoutUnit supDescent = script->logicalHeight() - supAscent; 297 LayoutUnit supAscent = ascentForChild(*reference.firstPostScript); 298 LayoutUnit supDescent = reference.firstPostScript->logicalHeight() - supAscent; 288 299 metrics.ascent = supAscent; 289 metrics.supShift = std::max(metrics.supShift, superscriptBottomMin + supDescent);300 metrics.supShift = std::max(metrics.supShift, parameters.superscriptBottomMin + supDescent); 290 301 } 291 302 break; … … 293 304 case UnderOver: 294 305 case Multiscripts: { 295 RenderBox* supScript; 296 for (auto* subScript = script; subScript && !isPrescriptDelimiter(*subScript); subScript = supScript->nextSiblingBox()) { 297 supScript = subScript->nextSiblingBox(); 298 ASSERT(supScript); 299 subScript->layoutIfNeeded(); 300 supScript->layoutIfNeeded(); 306 // FIXME: We should move the code updating VerticalMetrics for each sub/sup pair in a helper 307 // function. That way, SubSup/UnderOver can just make one call and the loop for Multiscripts 308 // can be rewritten in a more readable. 309 auto subScript = reference.firstPostScript ? reference.firstPostScript : reference.firstPreScript; 310 while (subScript) { 311 auto supScript = subScript->nextSiblingBox(); 312 ASSERT(supScript); 301 313 LayoutUnit subAscent = ascentForChild(*subScript); 302 314 LayoutUnit subDescent = subScript->logicalHeight() - subAscent; … … 305 317 metrics.ascent = std::max(metrics.ascent, supAscent); 306 318 metrics.descent = std::max(metrics.descent, subDescent); 307 LayoutUnit subScriptShift = std::max( subscriptShiftDown, baseDescent +subscriptBaselineDropMin);308 subScriptShift = std::max(subScriptShift, subAscent - subscriptTopMax);309 LayoutUnit supScriptShift = std::max( superscriptShiftUp, baseAscent -superScriptBaselineDropMax);310 supScriptShift = std::max(supScriptShift, superscriptBottomMin + supDescent);319 LayoutUnit subScriptShift = std::max(parameters.subscriptShiftDown, baseDescent + parameters.subscriptBaselineDropMin); 320 subScriptShift = std::max(subScriptShift, subAscent - parameters.subscriptTopMax); 321 LayoutUnit supScriptShift = std::max(parameters.superscriptShiftUp, baseAscent - parameters.superScriptBaselineDropMax); 322 supScriptShift = std::max(supScriptShift, parameters.superscriptBottomMin + supDescent); 311 323 312 324 LayoutUnit subSuperscriptGap = (subScriptShift - subAscent) + (supScriptShift - supDescent); 313 if (subSuperscriptGap < subSuperscriptGapMin) {325 if (subSuperscriptGap < parameters.subSuperscriptGapMin) { 314 326 // First, we try and push the superscript up. 315 LayoutUnit delta = superscriptBottomMaxWithSubscript - (supScriptShift - supDescent);327 LayoutUnit delta = parameters.superscriptBottomMaxWithSubscript - (supScriptShift - supDescent); 316 328 if (delta > 0) { 317 delta = std::min(delta, subSuperscriptGapMin - subSuperscriptGap);329 delta = std::min(delta, parameters.subSuperscriptGapMin - subSuperscriptGap); 318 330 supScriptShift += delta; 319 331 subSuperscriptGap += delta; 320 332 } 321 333 // If that is not enough, we push the subscript down. 322 if (subSuperscriptGap < subSuperscriptGapMin)323 subScriptShift += subSuperscriptGapMin - subSuperscriptGap;334 if (subSuperscriptGap < parameters.subSuperscriptGapMin) 335 subScriptShift += parameters.subSuperscriptGapMin - subSuperscriptGap; 324 336 } 325 337 326 338 metrics.subShift = std::max(metrics.subShift, subScriptShift); 327 339 metrics.supShift = std::max(metrics.supShift, supScriptShift); 328 } 329 } 330 } 340 341 subScript = supScript->nextSiblingBox(); 342 if (subScript == reference.prescriptDelimiter) 343 subScript = reference.firstPreScript; 344 } 345 } 346 } 347 348 return metrics; 331 349 } 332 350 … … 338 356 return; 339 357 340 RenderBox* base; 341 RenderBox* firstPostScript; 342 RenderBox* firstPreScript; 343 if (!getBaseAndScripts(base, firstPostScript, firstPreScript)) { 358 auto possibleReference = validateAndGetReferenceChildren(); 359 if (!possibleReference) { 344 360 setLogicalWidth(0); 345 361 setLogicalHeight(0); … … 347 363 return; 348 364 } 365 auto& reference = possibleReference.value(); 366 349 367 recomputeLogicalWidth(); 350 base->layoutIfNeeded(); 368 for (auto child = firstChildBox(); child; child = child->nextSiblingBox()) 369 child->layoutIfNeeded(); 351 370 352 371 LayoutUnit space = spaceAfterScript(); 353 372 354 373 // We determine the minimal shift/size of each script and take the maximum of the values. 355 ScriptMetrics metrics; 356 metrics.subShift = 0; 357 metrics.supShift = 0; 358 metrics.descent = 0; 359 metrics.ascent = 0; 360 if (m_scriptType == Multiscripts) 361 getScriptMetricsAndLayoutIfNeeded(base, firstPreScript, metrics); 362 getScriptMetricsAndLayoutIfNeeded(base, firstPostScript, metrics); 363 364 LayoutUnit baseAscent = ascentForChild(*base); 365 LayoutUnit baseDescent = base->logicalHeight() - baseAscent; 366 LayoutUnit baseItalicCorrection = std::min(base->logicalWidth(), italicCorrection(base)); 374 VerticalMetrics metrics = verticalMetrics(reference); 375 376 LayoutUnit baseAscent = ascentForChild(*reference.base); 377 LayoutUnit baseDescent = reference.base->logicalHeight() - baseAscent; 378 LayoutUnit baseItalicCorrection = std::min(reference.base->logicalWidth(), italicCorrection(reference)); 367 379 LayoutUnit horizontalOffset = 0; 368 380 … … 374 386 case Sub: 375 387 case Under: { 376 setLogicalWidth( base->logicalWidth() + std::max(LayoutUnit(0),firstPostScript->logicalWidth() - baseItalicCorrection + space));377 LayoutPoint baseLocation(mirrorIfNeeded(horizontalOffset, * base), ascent - baseAscent);378 base->setLocation(baseLocation);379 horizontalOffset += base->logicalWidth();380 LayoutUnit scriptAscent = ascentForChild(* firstPostScript);381 LayoutPoint scriptLocation(mirrorIfNeeded(horizontalOffset - baseItalicCorrection, * firstPostScript), ascent + metrics.subShift - scriptAscent);382 firstPostScript->setLocation(scriptLocation);388 setLogicalWidth(reference.base->logicalWidth() + std::max(LayoutUnit(0), reference.firstPostScript->logicalWidth() - baseItalicCorrection + space)); 389 LayoutPoint baseLocation(mirrorIfNeeded(horizontalOffset, *reference.base), ascent - baseAscent); 390 reference.base->setLocation(baseLocation); 391 horizontalOffset += reference.base->logicalWidth(); 392 LayoutUnit scriptAscent = ascentForChild(*reference.firstPostScript); 393 LayoutPoint scriptLocation(mirrorIfNeeded(horizontalOffset - baseItalicCorrection, *reference.firstPostScript), ascent + metrics.subShift - scriptAscent); 394 reference.firstPostScript->setLocation(scriptLocation); 383 395 } 384 396 break; 385 397 case Super: 386 398 case Over: { 387 setLogicalWidth( base->logicalWidth() + std::max(LayoutUnit(0),firstPostScript->logicalWidth() + space));388 LayoutPoint baseLocation(mirrorIfNeeded(horizontalOffset, * base), ascent - baseAscent);389 base->setLocation(baseLocation);390 horizontalOffset += base->logicalWidth();391 LayoutUnit scriptAscent = ascentForChild(* firstPostScript);392 LayoutPoint scriptLocation(mirrorIfNeeded(horizontalOffset, * firstPostScript), ascent - metrics.supShift - scriptAscent);393 firstPostScript->setLocation(scriptLocation);399 setLogicalWidth(reference.base->logicalWidth() + std::max(LayoutUnit(0), reference.firstPostScript->logicalWidth() + space)); 400 LayoutPoint baseLocation(mirrorIfNeeded(horizontalOffset, *reference.base), ascent - baseAscent); 401 reference.base->setLocation(baseLocation); 402 horizontalOffset += reference.base->logicalWidth(); 403 LayoutUnit scriptAscent = ascentForChild(*reference.firstPostScript); 404 LayoutPoint scriptLocation(mirrorIfNeeded(horizontalOffset, *reference.firstPostScript), ascent - metrics.supShift - scriptAscent); 405 reference.firstPostScript->setLocation(scriptLocation); 394 406 } 395 407 break; … … 397 409 case UnderOver: 398 410 case Multiscripts: { 399 RenderBox* supScript;400 401 411 // Calculate the logical width. 402 412 LayoutUnit logicalWidth = 0; 403 for (auto* subScript = firstPreScript; subScript; subScript = supScript->nextSiblingBox()) { 404 supScript = subScript->nextSiblingBox(); 413 auto subScript = reference.firstPreScript; 414 while (subScript) { 415 auto supScript = subScript->nextSiblingBox(); 405 416 ASSERT(supScript); 406 417 LayoutUnit subSupPairWidth = std::max(subScript->logicalWidth(), supScript->logicalWidth()); 407 418 logicalWidth += subSupPairWidth + space; 408 } 409 logicalWidth += base->logicalWidth(); 410 for (auto* subScript = firstPostScript; subScript && !isPrescriptDelimiter(*subScript); subScript = supScript->nextSiblingBox()) { 411 supScript = subScript->nextSiblingBox(); 419 subScript = supScript->nextSiblingBox(); 420 } 421 logicalWidth += reference.base->logicalWidth(); 422 subScript = reference.firstPostScript; 423 while (subScript && subScript != reference.prescriptDelimiter) { 424 auto supScript = subScript->nextSiblingBox(); 412 425 ASSERT(supScript); 413 426 LayoutUnit subSupPairWidth = std::max(std::max(LayoutUnit(0), subScript->logicalWidth() - baseItalicCorrection), supScript->logicalWidth()); 414 427 logicalWidth += subSupPairWidth + space; 428 subScript = supScript->nextSiblingBox(); 415 429 } 416 430 setLogicalWidth(logicalWidth); 417 431 418 for (auto* subScript = firstPreScript; subScript; subScript = supScript->nextSiblingBox()) { 419 supScript = subScript->nextSiblingBox(); 432 subScript = reference.firstPreScript; 433 while (subScript) { 434 auto supScript = subScript->nextSiblingBox(); 420 435 ASSERT(supScript); 421 436 LayoutUnit subSupPairWidth = std::max(subScript->logicalWidth(), supScript->logicalWidth()); … … 427 442 LayoutPoint supScriptLocation(mirrorIfNeeded(horizontalOffset - supScript->logicalWidth(), *supScript), ascent - metrics.supShift - supAscent); 428 443 supScript->setLocation(supScriptLocation); 429 } 430 LayoutPoint baseLocation(mirrorIfNeeded(horizontalOffset, *base), ascent - baseAscent); 431 base->setLocation(baseLocation); 432 horizontalOffset += base->logicalWidth(); 433 for (auto* subScript = firstPostScript; subScript && !isPrescriptDelimiter(*subScript); subScript = supScript->nextSiblingBox()) { 434 supScript = subScript->nextSiblingBox(); 444 subScript = supScript->nextSiblingBox(); 445 } 446 LayoutPoint baseLocation(mirrorIfNeeded(horizontalOffset, *reference.base), ascent - baseAscent); 447 reference.base->setLocation(baseLocation); 448 horizontalOffset += reference.base->logicalWidth(); 449 subScript = reference.firstPostScript; 450 while (subScript && subScript != reference.prescriptDelimiter) { 451 auto supScript = subScript->nextSiblingBox(); 435 452 ASSERT(supScript); 436 453 LayoutUnit subAscent = ascentForChild(*subScript); … … 443 460 LayoutUnit subSupPairWidth = std::max(subScript->logicalWidth(), supScript->logicalWidth()); 444 461 horizontalOffset += subSupPairWidth + space; 462 subScript = supScript->nextSiblingBox(); 445 463 } 446 464 } -
trunk/Source/WebCore/rendering/mathml/RenderMathMLScripts.h
r205105 r205441 54 54 MathMLScriptsElement& element() const; 55 55 Optional<int> firstLineBaseline() const final; 56 bool getBaseAndScripts(RenderBox*& base, RenderBox*& firstPostScript, RenderBox*& firstPreScript); 56 struct ReferenceChildren { 57 RenderBox* base; 58 RenderBox* prescriptDelimiter; 59 RenderBox* firstPostScript; 60 RenderBox* firstPreScript; 61 }; 62 Optional<ReferenceChildren> validateAndGetReferenceChildren(); 57 63 LayoutUnit spaceAfterScript(); 58 LayoutUnit italicCorrection(RenderBox* base); 59 struct ScriptMetrics { 64 LayoutUnit italicCorrection(const ReferenceChildren&); 65 struct VerticalParameters { 66 LayoutUnit subscriptShiftDown; 67 LayoutUnit superscriptShiftUp; 68 LayoutUnit subscriptBaselineDropMin; 69 LayoutUnit superScriptBaselineDropMax; 70 LayoutUnit subSuperscriptGapMin; 71 LayoutUnit superscriptBottomMin; 72 LayoutUnit subscriptTopMax; 73 LayoutUnit superscriptBottomMaxWithSubscript; 74 }; 75 VerticalParameters verticalParameters() const; 76 struct VerticalMetrics { 60 77 LayoutUnit subShift; 61 78 LayoutUnit supShift; … … 63 80 LayoutUnit descent; 64 81 }; 65 void getScriptMetricsAndLayoutIfNeeded(RenderBox* base, RenderBox* script, ScriptMetrics&);82 VerticalMetrics verticalMetrics(const ReferenceChildren&); 66 83 }; 67 84
Note: See TracChangeset
for help on using the changeset viewer.