Changeset 201854 in webkit
- Timestamp:
- Jun 8, 2016, 11:17:40 PM (10 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 added
- 5 edited
-
CMakeLists.txt (modified) (1 diff)
-
ChangeLog (modified) (1 diff)
-
WebCore.xcodeproj/project.pbxproj (modified) (5 diffs)
-
rendering/mathml/MathOperator.cpp (added)
-
rendering/mathml/MathOperator.h (added)
-
rendering/mathml/RenderMathMLOperator.cpp (modified) (12 diffs)
-
rendering/mathml/RenderMathMLOperator.h (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/CMakeLists.txt
r201810 r201854 2518 2518 2519 2519 rendering/mathml/MathMLOperatorDictionary.cpp 2520 rendering/mathml/MathOperator.cpp 2520 2521 rendering/mathml/RenderMathMLBlock.cpp 2521 2522 rendering/mathml/RenderMathMLFenced.cpp -
trunk/Source/WebCore/ChangeLog
r201852 r201854 1 2016-06-08 Frederic Wang <fwang@igalia.com> 2 3 Move selection and drawing of stretchy operators into a separate MathOperator class 4 https://bugs.webkit.org/show_bug.cgi?id=156921 5 6 Reviewed by Martin Robinson. 7 8 No new tests, behavior is not changed. 9 10 * CMakeLists.txt: Add the MathOperator files. 11 * WebCore.xcodeproj/project.pbxproj: Ditto. 12 * rendering/mathml/MathOperator.cpp: Added. 13 (WebCore::boundsForGlyph): Moved from RenderMathMLOperator. 14 (WebCore::heightForGlyph): Moved from RenderMathMLOperator. 15 (WebCore::advanceWidthForGlyph): Moved from RenderMathMLOperator. 16 (WebCore::MathOperator::MathOperator): 17 (WebCore::MathOperator::setOperator): 18 (WebCore::MathOperator::getBaseGlyph): Moved from RenderMathMLOperator. 19 (WebCore::MathOperator::setSizeVariant): Moved from RenderMathMLOperator. 20 (WebCore::MathOperator::setGlyphAssembly): Moved from RenderMathMLOperator. 21 (WebCore::MathOperator::calculateDisplayStyleLargeOperator): Moved from RenderMathMLOperator with additional style parameter. 22 (WebCore::MathOperator::calculateGlyphAssemblyFallBack): Ditto. 23 (WebCore::MathOperator::calculateStretchyData): Ditto. 24 (WebCore::MathOperator::paintGlyph): Ditto. 25 (WebCore::MathOperator::fillWithVerticalExtensionGlyph): Ditto. 26 (WebCore::MathOperator::fillWithHorizontalExtensionGlyph): Ditto. 27 (WebCore::MathOperator::paintVerticalGlyphAssembly): Ditto. 28 (WebCore::MathOperator::paintHorizontalGlyphAssembly): Ditto. 29 * rendering/mathml/MathOperator.h: Added. 30 (WebCore::MathOperator::italicCorrection): 31 (WebCore::MathOperator::isStretched): 32 (WebCore::MathOperator::unstretch): 33 (WebCore::MathOperator::GlyphAssemblyData::GlyphAssemblyData): Moved from RenderMathMLOperator. 34 (WebCore::MathOperator::stretchSize): 35 * rendering/mathml/RenderMathMLOperator.cpp: 36 (WebCore::RenderMathMLOperator::computePreferredLogicalWidths): Updated to use MathOperator members. 37 For now we call setOperator to transmit information to m_mathOperator. 38 (WebCore::RenderMathMLOperator::updateStyle): Updated to use MathOperator members. 39 For now we set some m_mathOperator members to transmit it some information. 40 (WebCore::RenderMathMLOperator::firstLineBaseline): Updated to use MathOperator members. 41 (WebCore::RenderMathMLOperator::computeLogicalHeight): Ditto. 42 (WebCore::RenderMathMLOperator::paint): Ditto. 43 For now we set some m_mathOperator members to transmit it some information. 44 (WebCore::RenderMathMLOperator::paintChildren): Updated to use MathOperator members. 45 (WebCore::RenderMathMLOperator::trailingSpaceError): Ditto. 46 (WebCore::RenderMathMLOperator::getBaseGlyph): Deleted. 47 (WebCore::RenderMathMLOperator::setSizeVariant): Deleted. 48 (WebCore::RenderMathMLOperator::setGlyphAssembly): Deleted. 49 (WebCore::RenderMathMLOperator::calculateGlyphAssemblyFallBack): Deleted. 50 (WebCore::RenderMathMLOperator::calculateDisplayStyleLargeOperator): Deleted. 51 (WebCore::RenderMathMLOperator::calculateStretchyData): Deleted. 52 (WebCore::RenderMathMLOperator::paintGlyph): Deleted. 53 (WebCore::RenderMathMLOperator::fillWithVerticalExtensionGlyph): Deleted. 54 (WebCore::RenderMathMLOperator::fillWithHorizontalExtensionGlyph): Deleted. 55 (WebCore::RenderMathMLOperator::paintVerticalGlyphAssembly): Deleted. 56 (WebCore::RenderMathMLOperator::paintHorizontalGlyphAssembly): Deleted. 57 * rendering/mathml/RenderMathMLOperator.h: 58 (WebCore::RenderMathMLOperator::italicCorrection): Updated to use MathOperator members. 59 (WebCore::RenderMathMLOperator::GlyphAssemblyData::GlyphAssemblyData): Deleted. 60 1 61 2016-06-08 Chris Dumez <cdumez@apple.com> 2 62 -
trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj
r201831 r201854 1671 1671 439046E912DA25E800AF80A2 /* RenderMathMLUnderOver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 439046D512DA25E800AF80A2 /* RenderMathMLUnderOver.cpp */; }; 1672 1672 439046EA12DA25E800AF80A2 /* RenderMathMLUnderOver.h in Headers */ = {isa = PBXBuildFile; fileRef = 439046D612DA25E800AF80A2 /* RenderMathMLUnderOver.h */; }; 1673 439046E912DA25E812AF80AC /* MathOperator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 439046D512DA25E812AF80AC /* MathOperator.cpp */; }; 1674 439046EA12DA25E812AF80AC /* MathOperator.h in Headers */ = {isa = PBXBuildFile; fileRef = 439046D612DA25E812AF80AC /* MathOperator.h */; }; 1673 1675 439046EB12DA25E800AF80A9 /* RenderMathMLToken.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 439046D712DA25E800AF80A9 /* RenderMathMLToken.cpp */; }; 1674 1676 439046EC12DA25E800AF80A9 /* RenderMathMLToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 439046D812DA25E800AF80A9 /* RenderMathMLToken.h */; }; … … 9234 9236 439046D512DA25E800AF80A2 /* RenderMathMLUnderOver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderMathMLUnderOver.cpp; sourceTree = "<group>"; }; 9235 9237 439046D612DA25E800AF80A2 /* RenderMathMLUnderOver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderMathMLUnderOver.h; sourceTree = "<group>"; }; 9238 439046D512DA25E812AF80AC /* MathOperator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathOperator.cpp; sourceTree = "<group>"; }; 9239 439046D612DA25E812AF80AC /* MathOperator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MathOperator.h; sourceTree = "<group>"; }; 9236 9240 439046D712DA25E800AF80A9 /* RenderMathMLToken.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderMathMLToken.cpp; sourceTree = "<group>"; }; 9237 9241 439046D812DA25E800AF80A9 /* RenderMathMLToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderMathMLToken.h; sourceTree = "<group>"; }; … … 16984 16988 439046D512DA25E800AF80A2 /* RenderMathMLUnderOver.cpp */, 16985 16989 439046D612DA25E800AF80A2 /* RenderMathMLUnderOver.h */, 16990 439046D512DA25E812AF80AC /* MathOperator.cpp */, 16991 439046D612DA25E812AF80AC /* MathOperator.h */, 16986 16992 ); 16987 16993 path = mathml; … … 27702 27708 439046EC12DA25E800AF80A9 /* RenderMathMLToken.h in Headers */, 27703 27709 439046EA12DA25E800AF80A2 /* RenderMathMLUnderOver.h in Headers */, 27710 439046EA12DA25E812AF80AC /* MathOperator.h in Headers */, 27704 27711 E4C279590CF9741900E97B98 /* RenderMedia.h in Headers */, 27705 27712 DEBCCDD216646E8200A452E1 /* RenderMediaControlElements.h in Headers */, … … 31382 31389 439046EB12DA25E800AF80A9 /* RenderMathMLToken.cpp in Sources */, 31383 31390 439046E912DA25E800AF80A2 /* RenderMathMLUnderOver.cpp in Sources */, 31391 439046E912DA25E812AF80AC /* MathOperator.cpp in Sources */, 31384 31392 E4C279580CF9741900E97B98 /* RenderMedia.cpp in Sources */, 31385 31393 DE49B309165F2FE10010338D /* RenderMediaControlElements.cpp in Sources */, -
trunk/Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp
r200569 r201854 46 46 using namespace MathMLNames; 47 47 48 // FIXME: The OpenType MATH table contains information that should override this table (http://wkbug/122297).49 struct StretchyCharacter {50 UChar character;51 UChar topChar;52 UChar extensionChar;53 UChar bottomChar;54 UChar middleChar;55 };56 // The first leftRightPairsCount pairs correspond to left/right fences that can easily be mirrored in RTL.57 static const short leftRightPairsCount = 5;58 static const StretchyCharacter stretchyCharacters[14] = {59 { 0x28 , 0x239b, 0x239c, 0x239d, 0x0 }, // left parenthesis60 { 0x29 , 0x239e, 0x239f, 0x23a0, 0x0 }, // right parenthesis61 { 0x5b , 0x23a1, 0x23a2, 0x23a3, 0x0 }, // left square bracket62 { 0x5d , 0x23a4, 0x23a5, 0x23a6, 0x0 }, // right square bracket63 { 0x7b , 0x23a7, 0x23aa, 0x23a9, 0x23a8 }, // left curly bracket64 { 0x7d , 0x23ab, 0x23aa, 0x23ad, 0x23ac }, // right curly bracket65 { 0x2308, 0x23a1, 0x23a2, 0x23a2, 0x0 }, // left ceiling66 { 0x2309, 0x23a4, 0x23a5, 0x23a5, 0x0 }, // right ceiling67 { 0x230a, 0x23a2, 0x23a2, 0x23a3, 0x0 }, // left floor68 { 0x230b, 0x23a5, 0x23a5, 0x23a6, 0x0 }, // right floor69 { 0x7c , 0x7c, 0x7c, 0x7c, 0x0 }, // vertical bar70 { 0x2016, 0x2016, 0x2016, 0x2016, 0x0 }, // double vertical line71 { 0x2225, 0x2225, 0x2225, 0x2225, 0x0 }, // parallel to72 { 0x222b, 0x2320, 0x23ae, 0x2321, 0x0 } // integral sign73 };74 75 48 RenderMathMLOperator::RenderMathMLOperator(MathMLElement& element, RenderStyle&& style) 76 49 : RenderMathMLToken(element, WTFMove(style)) … … 295 268 } 296 269 270 m_mathOperator.setOperator(m_textContent, m_isVertical); 297 271 GlyphData baseGlyph; 298 float maximumGlyphWidth = getBaseGlyph(style(), baseGlyph) ? advanceWidthForGlyph(baseGlyph) : 0;272 float maximumGlyphWidth = m_mathOperator.getBaseGlyph(style(), baseGlyph) ? advanceWidthForGlyph(baseGlyph) : 0; 299 273 if (!m_isVertical) { 300 274 if (maximumGlyphWidth < stretchSize()) … … 306 280 if (isLargeOperatorInDisplayStyle()) { 307 281 // Large operators in STIX Word have incorrect advance width, causing misplacement of superscript, so we use the glyph bound instead (http://sourceforge.net/p/stixfonts/tracking/49/). 308 calculateDisplayStyleLargeOperator();309 if (m_ stretchType ==StretchType::SizeVariant)310 maximumGlyphWidth = boundsForGlyph(m_ variant).width();282 m_mathOperator.calculateDisplayStyleLargeOperator(style()); 283 if (m_mathOperator.m_stretchType == MathOperator::StretchType::SizeVariant) 284 maximumGlyphWidth = boundsForGlyph(m_mathOperator.m_variant).width(); 311 285 } else { 312 286 // FIXME: some glyphs (e.g. the one for "FRACTION SLASH" in the STIX Math font or large operators) have a width that depends on the height, resulting in large gaps (https://bugs.webkit.org/show_bug.cgi?id=130326). 313 calculateStretchyData(&maximumGlyphWidth);287 m_mathOperator.calculateStretchyData(style(), &maximumGlyphWidth); 314 288 } 315 289 m_maxPreferredLogicalWidth = m_minPreferredLogicalWidth = m_leadingSpace + maximumGlyphWidth + m_trailingSpace; … … 375 349 } 376 350 377 bool RenderMathMLOperator::getBaseGlyph(const RenderStyle& style, GlyphData& baseGlyph) const378 {379 baseGlyph = style.fontCascade().glyphDataForCharacter(m_textContent, !style.isLeftToRightDirection());380 return baseGlyph.isValid() && baseGlyph.font == &style.fontCascade().primaryFont();381 }382 383 void RenderMathMLOperator::setSizeVariant(const GlyphData& sizeVariant)384 {385 ASSERT(sizeVariant.isValid() && sizeVariant.font->mathData());386 m_stretchType = StretchType::SizeVariant;387 m_variant = sizeVariant;388 }389 390 void RenderMathMLOperator::setGlyphAssembly(const GlyphAssemblyData& assemblyData)391 {392 m_stretchType = StretchType::GlyphAssembly;393 m_assembly = assemblyData;394 }395 396 bool RenderMathMLOperator::calculateGlyphAssemblyFallBack(const Vector<OpenTypeMathData::AssemblyPart>& assemblyParts, GlyphAssemblyData& assemblyData) const397 {398 // The structure of the Open Type Math table is a bit more general than the one currently used by the RenderMathMLOperator code, so we try to fallback in a reasonable way.399 // FIXME: RenderMathMLOperator should support the most general format (https://bugs.webkit.org/show_bug.cgi?id=130327).400 // We use the approach of the copyComponents function in github.com/mathjax/MathJax-dev/blob/master/fonts/OpenTypeMath/fontUtil.py401 402 // We count the number of non extender pieces.403 int nonExtenderCount = 0;404 for (auto& part : assemblyParts) {405 if (!part.isExtender)406 nonExtenderCount++;407 }408 if (nonExtenderCount > 3)409 return false; // This is not supported: there are too many pieces.410 411 // We now browse the list of pieces from left to right for horizontal operators and from bottom to top for vertical operators.412 enum PartType {413 Start,414 ExtenderBetweenStartAndMiddle,415 Middle,416 ExtenderBetweenMiddleAndEnd,417 End,418 None419 };420 PartType expectedPartType = Start;421 assemblyData.extension.glyph = 0;422 assemblyData.middle.glyph = 0;423 for (auto& part : assemblyParts) {424 if (nonExtenderCount < 3) {425 // If we only have at most two non-extenders then we skip the middle glyph.426 if (expectedPartType == ExtenderBetweenStartAndMiddle)427 expectedPartType = ExtenderBetweenMiddleAndEnd;428 else if (expectedPartType == Middle)429 expectedPartType = End;430 }431 if (part.isExtender) {432 if (!assemblyData.extension.glyph)433 assemblyData.extension.glyph = part.glyph; // We copy the extender part.434 else if (assemblyData.extension.glyph != part.glyph)435 return false; // This is not supported: the assembly has different extenders.436 437 switch (expectedPartType) {438 case Start:439 // We ignore the left/bottom part.440 expectedPartType = ExtenderBetweenStartAndMiddle;441 continue;442 case Middle:443 // We ignore the middle part.444 expectedPartType = ExtenderBetweenMiddleAndEnd;445 continue;446 case End:447 case None:448 // This is not supported: we got an unexpected extender.449 return false;450 case ExtenderBetweenStartAndMiddle:451 case ExtenderBetweenMiddleAndEnd:452 // We ignore multiple consecutive extenders.453 continue;454 }455 }456 457 switch (expectedPartType) {458 case Start:459 // We copy the left/bottom part.460 assemblyData.bottomOrLeft.glyph = part.glyph;461 expectedPartType = ExtenderBetweenStartAndMiddle;462 continue;463 case ExtenderBetweenStartAndMiddle:464 case Middle:465 // We copy the middle part.466 assemblyData.middle.glyph = part.glyph;467 expectedPartType = ExtenderBetweenMiddleAndEnd;468 continue;469 case ExtenderBetweenMiddleAndEnd:470 case End:471 // We copy the right/top part.472 assemblyData.topOrRight.glyph = part.glyph;473 expectedPartType = None;474 continue;475 case None:476 // This is not supported: we got an unexpected non-extender part.477 return false;478 }479 }480 481 if (!assemblyData.extension.glyph)482 return false; // This is not supported: we always assume that we have an extension glyph.483 484 // If we don't have top/right or left/bottom glyphs, we use the extension glyph.485 if (!assemblyData.topOrRight.glyph)486 assemblyData.topOrRight.glyph = assemblyData.extension.glyph;487 if (!assemblyData.bottomOrLeft.glyph)488 assemblyData.bottomOrLeft.glyph = assemblyData.extension.glyph;489 490 assemblyData.topOrRight.font = &style().fontCascade().primaryFont();491 assemblyData.extension.font = assemblyData.topOrRight.font;492 assemblyData.bottomOrLeft.font = assemblyData.topOrRight.font;493 assemblyData.middle.font = assemblyData.middle.glyph ? assemblyData.topOrRight.font : nullptr;494 495 return true;496 }497 498 void RenderMathMLOperator::calculateDisplayStyleLargeOperator()499 {500 ASSERT(m_isVertical && isLargeOperatorInDisplayStyle());501 502 GlyphData baseGlyph;503 if (!getBaseGlyph(style(), baseGlyph) || !baseGlyph.font->mathData())504 return;505 506 Vector<Glyph> sizeVariants;507 Vector<OpenTypeMathData::AssemblyPart> assemblyParts;508 509 // The value of displayOperatorMinHeight is sometimes too small, so we ensure that it is at least \sqrt{2} times the size of the base glyph.510 float displayOperatorMinHeight = std::max(baseGlyph.font->boundsForGlyph(baseGlyph.glyph).height() * sqrtOfTwoFloat, baseGlyph.font->mathData()->getMathConstant(*baseGlyph.font, OpenTypeMathData::DisplayOperatorMinHeight));511 512 baseGlyph.font->mathData()->getMathVariants(baseGlyph.glyph, true, sizeVariants, assemblyParts);513 514 // We choose the first size variant that is larger than the expected displayOperatorMinHeight and otherwise fallback to the largest variant.515 for (auto& sizeVariant : sizeVariants) {516 GlyphData glyphData(sizeVariant, baseGlyph.font);517 setSizeVariant(glyphData);518 m_italicCorrection = glyphData.font->mathData()->getItalicCorrection(*glyphData.font, glyphData.glyph);519 if (heightForGlyph(glyphData) >= displayOperatorMinHeight)520 break;521 }522 }523 524 void RenderMathMLOperator::calculateStretchyData(float* maximumGlyphWidth, LayoutUnit targetSize)525 {526 ASSERT(!maximumGlyphWidth || m_isVertical);527 528 GlyphData baseGlyph;529 if (!getBaseGlyph(style(), baseGlyph))530 return;531 532 if (!maximumGlyphWidth) {533 // We do not stretch if the base glyph is large enough.534 float baseSize = m_isVertical ? heightForGlyph(baseGlyph) : advanceWidthForGlyph(baseGlyph);535 if (targetSize <= baseSize)536 return;537 }538 539 GlyphAssemblyData assemblyData;540 if (baseGlyph.font->mathData()) {541 Vector<Glyph> sizeVariants;542 Vector<OpenTypeMathData::AssemblyPart> assemblyParts;543 baseGlyph.font->mathData()->getMathVariants(baseGlyph.glyph, m_isVertical, sizeVariants, assemblyParts);544 // We verify the size variants.545 for (auto& sizeVariant : sizeVariants) {546 GlyphData glyphData(sizeVariant, baseGlyph.font);547 if (maximumGlyphWidth)548 *maximumGlyphWidth = std::max(*maximumGlyphWidth, advanceWidthForGlyph(glyphData));549 else {550 setSizeVariant(glyphData);551 float size = m_isVertical ? heightForGlyph(glyphData) : advanceWidthForGlyph(glyphData);552 if (size >= targetSize)553 return;554 }555 }556 557 // We verify if there is a construction.558 if (!calculateGlyphAssemblyFallBack(assemblyParts, assemblyData))559 return;560 } else {561 if (!m_isVertical)562 return;563 564 // If the font does not have a MATH table, we fallback to the Unicode-only constructions.565 const StretchyCharacter* stretchyCharacter = nullptr;566 const unsigned maxIndex = WTF_ARRAY_LENGTH(stretchyCharacters);567 for (unsigned index = 0; index < maxIndex; ++index) {568 if (stretchyCharacters[index].character == m_textContent) {569 stretchyCharacter = &stretchyCharacters[index];570 if (!style().isLeftToRightDirection() && index < leftRightPairsCount * 2) {571 // If we are in right-to-left direction we select the mirrored form by adding -1 or +1 according to the parity of index.572 index += index % 2 ? -1 : 1;573 }574 break;575 }576 }577 578 // If we didn't find a stretchy character set for this character, we don't know how to stretch it.579 if (!stretchyCharacter)580 return;581 582 // We convert the list of Unicode characters into a list of glyph data.583 assemblyData.topOrRight = style().fontCascade().glyphDataForCharacter(stretchyCharacter->topChar, false);584 assemblyData.extension = style().fontCascade().glyphDataForCharacter(stretchyCharacter->extensionChar, false);585 assemblyData.bottomOrLeft = style().fontCascade().glyphDataForCharacter(stretchyCharacter->bottomChar, false);586 assemblyData.middle = stretchyCharacter->middleChar ? style().fontCascade().glyphDataForCharacter(stretchyCharacter->middleChar, false) : GlyphData();587 }588 589 // If we are measuring the maximum width, verify each component.590 if (maximumGlyphWidth) {591 *maximumGlyphWidth = std::max(*maximumGlyphWidth, advanceWidthForGlyph(assemblyData.topOrRight));592 *maximumGlyphWidth = std::max(*maximumGlyphWidth, advanceWidthForGlyph(assemblyData.extension));593 *maximumGlyphWidth = std::max(*maximumGlyphWidth, advanceWidthForGlyph(assemblyData.middle));594 *maximumGlyphWidth = std::max(*maximumGlyphWidth, advanceWidthForGlyph(assemblyData.bottomOrLeft));595 return;596 }597 598 // We ensure that the size is large enough to avoid glyph overlaps.599 float minSize = m_isVertical ?600 heightForGlyph(assemblyData.topOrRight) + heightForGlyph(assemblyData.middle) + heightForGlyph(assemblyData.bottomOrLeft)601 : advanceWidthForGlyph(assemblyData.bottomOrLeft) + advanceWidthForGlyph(assemblyData.middle) + advanceWidthForGlyph(assemblyData.topOrRight);602 if (minSize > targetSize)603 return;604 605 setGlyphAssembly(assemblyData);606 }607 608 351 void RenderMathMLOperator::updateStyle() 609 352 { … … 612 355 return; 613 356 614 m_ stretchType = StretchType::Unstretched;615 m_ italicCorrection = 0;357 m_mathOperator.unstretch(); 358 m_mathOperator.m_italicCorrection = 0; 616 359 // We add spacing around the operator. 617 360 // FIXME: The spacing should be added to the whole embellished operator (https://bugs.webkit.org/show_bug.cgi?id=124831). … … 627 370 return; 628 371 372 m_mathOperator.setOperator(m_textContent, m_isVertical); 629 373 if (m_isVertical && isLargeOperatorInDisplayStyle()) 630 calculateDisplayStyleLargeOperator();374 m_mathOperator.calculateDisplayStyleLargeOperator(style()); 631 375 else { 632 calculateStretchyData(nullptr, stretchSize());633 if ( m_stretchType == StretchType::Unstretched)376 m_mathOperator.calculateStretchyData(style(), nullptr, stretchSize()); 377 if (!m_mathOperator.isStretched()) 634 378 return; 635 379 } 636 380 637 if (m_isVertical && m_ stretchType ==StretchType::SizeVariant) {381 if (m_isVertical && m_mathOperator.m_stretchType == MathOperator::StretchType::SizeVariant) { 638 382 // We resize the operator to match the one of the size variant. 639 383 if (isLargeOperatorInDisplayStyle()) { 640 384 // The stretch size is actually not involved in the selection of the size variant in findDisplayStyleLargeOperator. 641 385 // We simply use the height and depth of the selected size variant glyph. 642 FloatRect glyphBounds = boundsForGlyph(m_ variant);386 FloatRect glyphBounds = boundsForGlyph(m_mathOperator.m_variant); 643 387 m_stretchHeightAboveBaseline = -glyphBounds.y(); 644 388 m_stretchDepthBelowBaseline = glyphBounds.maxY(); 645 389 } else { 646 390 // We rescale the height and depth proportionately. 647 float variantSize = heightForGlyph(m_ variant);391 float variantSize = heightForGlyph(m_mathOperator.m_variant); 648 392 float size = stretchSize(); 649 393 float aspect = size > 0 ? variantSize / size : 1.0; … … 654 398 655 399 if (!m_isVertical) { 656 if (m_ stretchType ==StretchType::SizeVariant) {657 FloatRect glyphBounds = boundsForGlyph(m_ variant);400 if (m_mathOperator.m_stretchType == MathOperator::StretchType::SizeVariant) { 401 FloatRect glyphBounds = boundsForGlyph(m_mathOperator.m_variant); 658 402 m_stretchHeightAboveBaseline = -glyphBounds.y(); 659 403 m_stretchDepthBelowBaseline = glyphBounds.maxY(); 660 m_stretchWidth = advanceWidthForGlyph(m_ variant);661 } else if (m_ stretchType ==StretchType::GlyphAssembly) {404 m_stretchWidth = advanceWidthForGlyph(m_mathOperator.m_variant); 405 } else if (m_mathOperator.m_stretchType == MathOperator::StretchType::GlyphAssembly) { 662 406 FloatRect glyphBounds; 663 407 m_stretchHeightAboveBaseline = 0; 664 408 m_stretchDepthBelowBaseline = 0; 665 409 666 glyphBounds = boundsForGlyph(m_ assembly.bottomOrLeft);410 glyphBounds = boundsForGlyph(m_mathOperator.m_assembly.bottomOrLeft); 667 411 m_stretchHeightAboveBaseline = std::max<LayoutUnit>(m_stretchHeightAboveBaseline, -glyphBounds.y()); 668 412 m_stretchDepthBelowBaseline = std::max<LayoutUnit>(m_stretchDepthBelowBaseline, glyphBounds.maxY()); 669 413 670 glyphBounds = boundsForGlyph(m_ assembly.topOrRight);414 glyphBounds = boundsForGlyph(m_mathOperator.m_assembly.topOrRight); 671 415 m_stretchHeightAboveBaseline = std::max<LayoutUnit>(m_stretchHeightAboveBaseline, -glyphBounds.y()); 672 416 m_stretchDepthBelowBaseline = std::max<LayoutUnit>(m_stretchDepthBelowBaseline, glyphBounds.maxY()); 673 417 674 glyphBounds = boundsForGlyph(m_ assembly.extension);418 glyphBounds = boundsForGlyph(m_mathOperator.m_assembly.extension); 675 419 m_stretchHeightAboveBaseline = std::max<LayoutUnit>(m_stretchHeightAboveBaseline, -glyphBounds.y()); 676 420 m_stretchDepthBelowBaseline = std::max<LayoutUnit>(m_stretchDepthBelowBaseline, glyphBounds.maxY()); 677 421 678 if (m_ assembly.middle.isValid()) {679 glyphBounds = boundsForGlyph(m_ assembly.middle);422 if (m_mathOperator.m_assembly.middle.isValid()) { 423 glyphBounds = boundsForGlyph(m_mathOperator.m_assembly.middle); 680 424 m_stretchHeightAboveBaseline = std::max<LayoutUnit>(m_stretchHeightAboveBaseline, -glyphBounds.y()); 681 425 m_stretchDepthBelowBaseline = std::max<LayoutUnit>(m_stretchDepthBelowBaseline, glyphBounds.maxY()); … … 687 431 Optional<int> RenderMathMLOperator::firstLineBaseline() const 688 432 { 689 if (m_ stretchType != StretchType::Unstretched)433 if (m_mathOperator.isStretched()) 690 434 return Optional<int>(m_stretchHeightAboveBaseline); 691 435 return RenderMathMLToken::firstLineBaseline(); … … 694 438 void RenderMathMLOperator::computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues& computedValues) const 695 439 { 696 if (m_ stretchType != StretchType::Unstretched)440 if (m_mathOperator.isStretched()) 697 441 logicalHeight = m_stretchHeightAboveBaseline + m_stretchDepthBelowBaseline; 698 442 RenderBox::computeLogicalHeight(logicalHeight, logicalTop, computedValues); 699 443 } 700 444 701 LayoutRect RenderMathMLOperator::paintGlyph(PaintInfo& info, const GlyphData& data, const LayoutPoint& origin, GlyphPaintTrimming trim)702 {703 FloatRect glyphBounds = boundsForGlyph(data);704 705 LayoutRect glyphPaintRect(origin, LayoutSize(glyphBounds.x() + glyphBounds.width(), glyphBounds.height()));706 glyphPaintRect.setY(origin.y() + glyphBounds.y());707 708 // In order to have glyphs fit snugly with one another we snap the connecting edges to pixel boundaries709 // and trim off one pixel. The pixel trim is to account for fonts that have edge pixels that have less710 // than full coverage. These edge pixels can introduce small seams between connected glyphs.711 FloatRect clipBounds = info.rect;712 switch (trim) {713 case TrimTop:714 glyphPaintRect.shiftYEdgeTo(glyphPaintRect.y().ceil() + 1);715 clipBounds.shiftYEdgeTo(glyphPaintRect.y());716 break;717 case TrimBottom:718 glyphPaintRect.shiftMaxYEdgeTo(glyphPaintRect.maxY().floor() - 1);719 clipBounds.shiftMaxYEdgeTo(glyphPaintRect.maxY());720 break;721 case TrimTopAndBottom:722 glyphPaintRect.shiftYEdgeTo(glyphPaintRect.y().ceil() + 1);723 glyphPaintRect.shiftMaxYEdgeTo(glyphPaintRect.maxY().floor() - 1);724 clipBounds.shiftYEdgeTo(glyphPaintRect.y());725 clipBounds.shiftMaxYEdgeTo(glyphPaintRect.maxY());726 break;727 case TrimLeft:728 glyphPaintRect.shiftXEdgeTo(glyphPaintRect.x().ceil() + 1);729 clipBounds.shiftXEdgeTo(glyphPaintRect.x());730 break;731 case TrimRight:732 glyphPaintRect.shiftMaxXEdgeTo(glyphPaintRect.maxX().floor() - 1);733 clipBounds.shiftMaxXEdgeTo(glyphPaintRect.maxX());734 break;735 case TrimLeftAndRight:736 glyphPaintRect.shiftXEdgeTo(glyphPaintRect.x().ceil() + 1);737 glyphPaintRect.shiftMaxXEdgeTo(glyphPaintRect.maxX().floor() - 1);738 clipBounds.shiftXEdgeTo(glyphPaintRect.x());739 clipBounds.shiftMaxXEdgeTo(glyphPaintRect.maxX());740 }741 742 // Clipping the enclosing IntRect avoids any potential issues at joined edges.743 GraphicsContextStateSaver stateSaver(info.context());744 info.context().clip(clipBounds);745 746 GlyphBuffer buffer;747 buffer.add(data.glyph, data.font, advanceWidthForGlyph(data));748 info.context().drawGlyphs(style().fontCascade(), *data.font, buffer, 0, 1, origin);749 750 return glyphPaintRect;751 }752 753 void RenderMathMLOperator::fillWithVerticalExtensionGlyph(PaintInfo& info, const LayoutPoint& from, const LayoutPoint& to)754 {755 ASSERT(m_isVertical);756 ASSERT(m_stretchType == StretchType::GlyphAssembly);757 ASSERT(m_assembly.extension.isValid());758 ASSERT(from.y() <= to.y());759 760 // If there is no space for the extension glyph, we don't need to do anything.761 if (from.y() == to.y())762 return;763 764 GraphicsContextStateSaver stateSaver(info.context());765 766 FloatRect glyphBounds = boundsForGlyph(m_assembly.extension);767 768 // Clipping the extender region here allows us to draw the bottom extender glyph into the769 // regions of the bottom glyph without worrying about overdraw (hairy pixels) and simplifies later clipping.770 LayoutRect clipBounds = info.rect;771 clipBounds.shiftYEdgeTo(from.y());772 clipBounds.shiftMaxYEdgeTo(to.y());773 info.context().clip(clipBounds);774 775 // Trimming may remove up to two pixels from the top of the extender glyph, so we move it up by two pixels.776 float offsetToGlyphTop = glyphBounds.y() + 2;777 LayoutPoint glyphOrigin = LayoutPoint(from.x(), from.y() - offsetToGlyphTop);778 FloatRect lastPaintedGlyphRect(from, FloatSize());779 780 while (lastPaintedGlyphRect.maxY() < to.y()) {781 lastPaintedGlyphRect = paintGlyph(info, m_assembly.extension, glyphOrigin, TrimTopAndBottom);782 glyphOrigin.setY(glyphOrigin.y() + lastPaintedGlyphRect.height());783 784 // There's a chance that if the font size is small enough the glue glyph has been reduced to an empty rectangle785 // with trimming. In that case we just draw nothing.786 if (lastPaintedGlyphRect.isEmpty())787 break;788 }789 }790 791 void RenderMathMLOperator::fillWithHorizontalExtensionGlyph(PaintInfo& info, const LayoutPoint& from, const LayoutPoint& to)792 {793 ASSERT(!m_isVertical);794 ASSERT(m_stretchType == StretchType::GlyphAssembly);795 ASSERT(m_assembly.extension.isValid());796 ASSERT(from.x() <= to.x());797 798 // If there is no space for the extension glyph, we don't need to do anything.799 if (from.x() == to.x())800 return;801 802 GraphicsContextStateSaver stateSaver(info.context());803 804 // Clipping the extender region here allows us to draw the bottom extender glyph into the805 // regions of the bottom glyph without worrying about overdraw (hairy pixels) and simplifies later clipping.806 LayoutRect clipBounds = info.rect;807 clipBounds.shiftXEdgeTo(from.x());808 clipBounds.shiftMaxXEdgeTo(to.x());809 info.context().clip(clipBounds);810 811 // Trimming may remove up to two pixels from the left of the extender glyph, so we move it left by two pixels.812 float offsetToGlyphLeft = -2;813 LayoutPoint glyphOrigin = LayoutPoint(from.x() + offsetToGlyphLeft, std::min(from.y(), to.y()) + m_stretchHeightAboveBaseline);814 FloatRect lastPaintedGlyphRect(from, FloatSize());815 816 while (lastPaintedGlyphRect.maxX() < to.x()) {817 lastPaintedGlyphRect = paintGlyph(info, m_assembly.extension, glyphOrigin, TrimLeftAndRight);818 glyphOrigin.setX(glyphOrigin.x() + lastPaintedGlyphRect.width());819 820 // There's a chance that if the font size is small enough the glue glyph has been reduced to an empty rectangle821 // with trimming. In that case we just draw nothing.822 if (lastPaintedGlyphRect.isEmpty())823 break;824 }825 }826 827 445 void RenderMathMLOperator::paint(PaintInfo& info, const LayoutPoint& paintOffset) 828 446 { 829 447 RenderMathMLToken::paint(info, paintOffset); 830 448 831 if (info.context().paintingDisabled() || info.phase != PaintPhaseForeground || style().visibility() != VISIBLE || m_stretchType == StretchType::Unstretched)449 if (info.context().paintingDisabled() || info.phase != PaintPhaseForeground || style().visibility() != VISIBLE || !m_mathOperator.isStretched()) 832 450 return; 833 451 … … 835 453 info.context().setFillColor(style().visitedDependentColor(CSSPropertyColor)); 836 454 837 if (m_ stretchType ==StretchType::SizeVariant) {838 ASSERT(m_ variant.isValid());455 if (m_mathOperator.m_stretchType == MathOperator::StretchType::SizeVariant) { 456 ASSERT(m_mathOperator.m_variant.isValid()); 839 457 GlyphBuffer buffer; 840 buffer.add(m_ variant.glyph, m_variant.font, advanceWidthForGlyph(m_variant));458 buffer.add(m_mathOperator.m_variant.glyph, m_mathOperator.m_variant.font, advanceWidthForGlyph(m_mathOperator.m_variant)); 841 459 LayoutPoint operatorTopLeft = ceiledIntPoint(paintOffset + location()); 842 FloatRect glyphBounds = boundsForGlyph(m_ variant);460 FloatRect glyphBounds = boundsForGlyph(m_mathOperator.m_variant); 843 461 LayoutPoint operatorOrigin(operatorTopLeft.x(), operatorTopLeft.y() - glyphBounds.y()); 844 info.context().drawGlyphs(style().fontCascade(), *m_variant.font, buffer, 0, 1, operatorOrigin); 845 return; 846 } 847 848 if (m_isVertical) 849 paintVerticalGlyphAssembly(info, paintOffset); 850 else 851 paintHorizontalGlyphAssembly(info, paintOffset); 852 } 853 854 void RenderMathMLOperator::paintVerticalGlyphAssembly(PaintInfo& info, const LayoutPoint& paintOffset) 855 { 856 ASSERT(m_isVertical); 857 ASSERT(m_stretchType == StretchType::GlyphAssembly); 858 ASSERT(m_assembly.topOrRight.isValid()); 859 ASSERT(m_assembly.bottomOrLeft.isValid()); 860 861 // We are positioning the glyphs so that the edge of the tight glyph bounds line up exactly with the edges of our paint box. 462 info.context().drawGlyphs(style().fontCascade(), *m_mathOperator.m_variant.font, buffer, 0, 1, operatorOrigin); 463 return; 464 } 465 466 m_mathOperator.m_ascent = m_stretchHeightAboveBaseline; 467 m_mathOperator.m_descent = m_stretchDepthBelowBaseline; 468 m_mathOperator.m_width = logicalWidth(); 862 469 LayoutPoint operatorTopLeft = paintOffset + location(); 863 470 operatorTopLeft.move(style().isLeftToRightDirection() ? m_leadingSpace : m_trailingSpace, 0); 864 operatorTopLeft = ceiledIntPoint(operatorTopLeft); 865 FloatRect topGlyphBounds = boundsForGlyph(m_assembly.topOrRight); 866 LayoutPoint topGlyphOrigin(operatorTopLeft.x(), operatorTopLeft.y() - topGlyphBounds.y()); 867 LayoutRect topGlyphPaintRect = paintGlyph(info, m_assembly.topOrRight, topGlyphOrigin, TrimBottom); 868 869 FloatRect bottomGlyphBounds = boundsForGlyph(m_assembly.bottomOrLeft); 870 LayoutPoint bottomGlyphOrigin(operatorTopLeft.x(), operatorTopLeft.y() + offsetHeight() - (bottomGlyphBounds.height() + bottomGlyphBounds.y())); 871 LayoutRect bottomGlyphPaintRect = paintGlyph(info, m_assembly.bottomOrLeft, bottomGlyphOrigin, TrimTop); 872 873 if (m_assembly.middle.isValid()) { 874 // Center the glyph origin between the start and end glyph paint extents. Then shift it half the paint height toward the bottom glyph. 875 FloatRect middleGlyphBounds = boundsForGlyph(m_assembly.middle); 876 LayoutPoint middleGlyphOrigin(operatorTopLeft.x(), topGlyphOrigin.y()); 877 middleGlyphOrigin.moveBy(LayoutPoint(0, (bottomGlyphPaintRect.y() - topGlyphPaintRect.maxY()) / 2.0)); 878 middleGlyphOrigin.moveBy(LayoutPoint(0, middleGlyphBounds.height() / 2.0)); 879 880 LayoutRect middleGlyphPaintRect = paintGlyph(info, m_assembly.middle, middleGlyphOrigin, TrimTopAndBottom); 881 fillWithVerticalExtensionGlyph(info, topGlyphPaintRect.minXMaxYCorner(), middleGlyphPaintRect.minXMinYCorner()); 882 fillWithVerticalExtensionGlyph(info, middleGlyphPaintRect.minXMaxYCorner(), bottomGlyphPaintRect.minXMinYCorner()); 883 } else 884 fillWithVerticalExtensionGlyph(info, topGlyphPaintRect.minXMaxYCorner(), bottomGlyphPaintRect.minXMinYCorner()); 885 } 886 887 void RenderMathMLOperator::paintHorizontalGlyphAssembly(PaintInfo& info, const LayoutPoint& paintOffset) 888 { 889 ASSERT(!m_isVertical); 890 ASSERT(m_stretchType == StretchType::GlyphAssembly); 891 ASSERT(m_assembly.bottomOrLeft.isValid()); 892 ASSERT(m_assembly.topOrRight.isValid()); 893 894 // We are positioning the glyphs so that the edge of the tight glyph bounds line up exactly with the edges of our paint box. 895 LayoutPoint operatorTopLeft = paintOffset + location(); 896 operatorTopLeft.move(m_leadingSpace, 0); 897 operatorTopLeft = ceiledIntPoint(operatorTopLeft); 898 LayoutPoint leftGlyphOrigin(operatorTopLeft.x(), operatorTopLeft.y() + m_stretchHeightAboveBaseline); 899 LayoutRect leftGlyphPaintRect = paintGlyph(info, m_assembly.bottomOrLeft, leftGlyphOrigin, TrimRight); 900 901 FloatRect rightGlyphBounds = boundsForGlyph(m_assembly.topOrRight); 902 LayoutPoint rightGlyphOrigin(operatorTopLeft.x() + offsetWidth() - rightGlyphBounds.width(), operatorTopLeft.y() + m_stretchHeightAboveBaseline); 903 LayoutRect rightGlyphPaintRect = paintGlyph(info, m_assembly.topOrRight, rightGlyphOrigin, TrimLeft); 904 905 if (m_assembly.middle.isValid()) { 906 // Center the glyph origin between the start and end glyph paint extents. 907 LayoutPoint middleGlyphOrigin(operatorTopLeft.x(), leftGlyphOrigin.y()); 908 middleGlyphOrigin.moveBy(LayoutPoint((rightGlyphPaintRect.x() - leftGlyphPaintRect.maxX()) / 2.0, 0)); 909 LayoutRect middleGlyphPaintRect = paintGlyph(info, m_assembly.middle, middleGlyphOrigin, TrimLeftAndRight); 910 fillWithHorizontalExtensionGlyph(info, leftGlyphPaintRect.maxXMinYCorner(), middleGlyphPaintRect.minXMinYCorner()); 911 fillWithHorizontalExtensionGlyph(info, middleGlyphPaintRect.maxXMinYCorner(), rightGlyphPaintRect.minXMinYCorner()); 912 } else 913 fillWithHorizontalExtensionGlyph(info, leftGlyphPaintRect.maxXMinYCorner(), rightGlyphPaintRect.minXMinYCorner()); 471 if (m_isVertical) 472 m_mathOperator.paintVerticalGlyphAssembly(style(), info, operatorTopLeft); 473 else 474 m_mathOperator.paintHorizontalGlyphAssembly(style(), info, operatorTopLeft); 914 475 } 915 476 … … 917 478 { 918 479 // We skip painting for invisible operators too to avoid some "missing character" glyph to appear if appropriate math fonts are not available. 919 if (m_ stretchType != StretchType::Unstretched|| isInvisibleOperator())480 if (m_mathOperator.isStretched() || isInvisibleOperator()) 920 481 return; 921 482 RenderMathMLToken::paintChildren(paintInfo, paintOffset, paintInfoForChild, usePrintRect); … … 932 493 LayoutUnit width = logicalWidth(); 933 494 934 if ( m_stretchType == StretchType::Unstretched) {495 if (!m_mathOperator.isStretched()) { 935 496 GlyphData data = style().fontCascade().glyphDataForCharacter(textContent(), !style().isLeftToRightDirection()); 936 497 return width - advanceWidthForGlyph(data); 937 498 } 938 499 939 if (m_ stretchType ==StretchType::SizeVariant)940 return width - advanceWidthForGlyph(m_ variant);941 942 float assemblyWidth = advanceWidthForGlyph(m_ assembly.topOrRight);943 assemblyWidth = std::max(assemblyWidth, advanceWidthForGlyph(m_ assembly.bottomOrLeft));944 assemblyWidth = std::max(assemblyWidth, advanceWidthForGlyph(m_ assembly.extension));945 if (m_ assembly.middle.isValid())946 assemblyWidth = std::max(assemblyWidth, advanceWidthForGlyph(m_ assembly.middle));500 if (m_mathOperator.m_stretchType == MathOperator::StretchType::SizeVariant) 501 return width - advanceWidthForGlyph(m_mathOperator.m_variant); 502 503 float assemblyWidth = advanceWidthForGlyph(m_mathOperator.m_assembly.topOrRight); 504 assemblyWidth = std::max(assemblyWidth, advanceWidthForGlyph(m_mathOperator.m_assembly.bottomOrLeft)); 505 assemblyWidth = std::max(assemblyWidth, advanceWidthForGlyph(m_mathOperator.m_assembly.extension)); 506 if (m_mathOperator.m_assembly.middle.isValid()) 507 assemblyWidth = std::max(assemblyWidth, advanceWidthForGlyph(m_mathOperator.m_assembly.middle)); 947 508 return width - assemblyWidth; 948 509 } -
trunk/Source/WebCore/rendering/mathml/RenderMathMLOperator.h
r200569 r201854 33 33 #include "MathMLElement.h" 34 34 #include "MathMLOperatorDictionary.h" 35 #include "MathOperator.h" 35 36 #include "OpenTypeMathData.h" 36 37 #include "RenderMathMLToken.h" … … 52 53 bool isLargeOperatorInDisplayStyle() const { return !hasOperatorFlag(MathMLOperatorDictionary::Stretchy) && hasOperatorFlag(MathMLOperatorDictionary::LargeOp); } 53 54 bool isVertical() const { return m_isVertical; } 54 LayoutUnit italicCorrection() const { return m_ italicCorrection; }55 LayoutUnit italicCorrection() const { return m_mathOperator.italicCorrection(); } 55 56 56 57 void styleDidChange(StyleDifference, const RenderStyle* oldStyle) final; … … 74 75 75 76 private: 76 struct GlyphAssemblyData {77 GlyphData topOrRight;78 GlyphData extension;79 GlyphData bottomOrLeft;80 GlyphData middle;81 };82 enum class StretchType { Unstretched, SizeVariant, GlyphAssembly };83 StretchType m_stretchType;84 union {85 GlyphData m_variant;86 GlyphAssemblyData m_assembly;87 };88 LayoutUnit m_italicCorrection;89 90 77 const char* renderName() const override { return isAnonymous() ? "RenderMathMLOperator (anonymous)" : "RenderMathMLOperator"; } 91 78 void paintChildren(PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect) final; … … 101 88 bool shouldAllowStretching() const; 102 89 103 bool getBaseGlyph(const RenderStyle&, GlyphData&) const;104 void setSizeVariant(const GlyphData&);105 void setGlyphAssembly(const GlyphAssemblyData&);106 bool calculateGlyphAssemblyFallBack(const Vector<OpenTypeMathData::AssemblyPart>&, GlyphAssemblyData&) const;107 void calculateDisplayStyleLargeOperator();108 void calculateStretchyData(float* maximumGlyphWidth, LayoutUnit targetSize = 0);109 110 enum GlyphPaintTrimming {111 TrimTop,112 TrimBottom,113 TrimTopAndBottom,114 TrimLeft,115 TrimRight,116 TrimLeftAndRight117 };118 119 LayoutRect paintGlyph(PaintInfo&, const GlyphData&, const LayoutPoint& origin, GlyphPaintTrimming);120 void fillWithVerticalExtensionGlyph(PaintInfo&, const LayoutPoint& from, const LayoutPoint& to);121 void fillWithHorizontalExtensionGlyph(PaintInfo&, const LayoutPoint& from, const LayoutPoint& to);122 void paintVerticalGlyphAssembly(PaintInfo&, const LayoutPoint&);123 void paintHorizontalGlyphAssembly(PaintInfo&, const LayoutPoint&);124 90 void setOperatorFlagFromAttribute(MathMLOperatorDictionary::Flag, const QualifiedName&); 125 91 void setOperatorFlagFromAttributeValue(MathMLOperatorDictionary::Flag, const AtomicString& attributeValue); … … 138 104 LayoutUnit m_minSize; 139 105 LayoutUnit m_maxSize; 106 MathOperator m_mathOperator; 140 107 }; 141 108
Note:
See TracChangeset
for help on using the changeset viewer.