Changeset 169607 in webkit
- Timestamp:
- Jun 4, 2014 11:35:04 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 9 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r169606 r169607 1 2014-06-05 Frédéric Wang <fred.wang@free.fr> 2 3 MathML operators not stretched horizontally 4 https://bugs.webkit.org/show_bug.cgi?id=72828 5 6 Reviewed by Chris Fleizach. 7 8 Add some tests to verify horizontal stretching with the MATH data. 9 10 * mathml/opentype/horizontal-LatinModern-munderover.html: Added. 11 * mathml/opentype/horizontal-LatinModern.html: Added. 12 * mathml/opentype/opentype-stretchy-horizontal.html: Added. 13 * platform/efl/TestExpectations: mark tests as failing. 14 * platform/gtk/mathml/opentype/horizontal-LatinModern-expected.png: Added. 15 * platform/gtk/mathml/opentype/horizontal-LatinModern-expected.txt: Added. 16 * platform/gtk/mathml/opentype/horizontal-LatinModern-munderover-expected.png: Added. 17 * platform/gtk/mathml/opentype/horizontal-LatinModern-munderover-expected.txt: Added. 18 * platform/gtk/mathml/opentype/opentype-stretchy-horizontal-expected.png: Added. 19 * platform/gtk/mathml/opentype/opentype-stretchy-horizontal-expected.txt: Added. 20 * platform/mac/TestExpectations: mark tests as failing. 21 * platform/win/TestExpectations: ditto. 22 1 23 2014-06-04 Bem Jones-Bey <bjonesbe@adobe.com> 2 24 -
trunk/LayoutTests/platform/efl/TestExpectations
r169526 r169607 1627 1627 1628 1628 webkit.org/b/133308 fast/selectors/hover-quirks.html [ Failure ] 1629 1630 # Missing or bad references 1631 webkit.org/b/130322 mathml/opentype/large-operators-LatinModern.html [ Failure ] 1632 webkit.org/b/130322 mathml/opentype/opentype-stretchy.html [ Failure ] 1633 webkit.org/b/130322 mathml/opentype/vertical-LatinModern.html [ Failure ] 1634 webkit.org/b/72828 mathml/opentype/horizontal-LatinModern.html [ Failure ] 1635 webkit.org/b/72828 mathml/opentype/opentype-stretchy-horizontal.html [ Failure ] 1636 webkit.org/b/72828 mathml/opentype/horizontal-LatinModern-munderover.html [ Failure ] -
trunk/LayoutTests/platform/mac/TestExpectations
r169515 r169607 1326 1326 webkit.org/b/130322 [ MountainLion Mavericks ] mathml/opentype/opentype-stretchy.html [ Failure ] 1327 1327 webkit.org/b/130322 [ MountainLion Mavericks ] mathml/opentype/vertical-LatinModern.html [ Failure ] 1328 webkit.org/b/72828 mathml/opentype/horizontal-LatinModern.html [ Failure ] 1329 webkit.org/b/72828 mathml/opentype/opentype-stretchy-horizontal.html [ Failure ] 1330 webkit.org/b/72828 mathml/opentype/horizontal-LatinModern-munderover.html [ Failure ] 1328 1331 1329 1332 # WebKitDataCue is supported, not DataCue -
trunk/LayoutTests/platform/win/TestExpectations
r169334 r169607 2747 2747 webkit.org/b/130322 mathml/opentype/opentype-stretchy.html [ Failure ] 2748 2748 webkit.org/b/130322 mathml/opentype/vertical-LatinModern.html [ Failure ] 2749 webkit.org/b/72828 mathml/opentype/horizontal-LatinModern.html [ Failure ] 2750 webkit.org/b/72828 mathml/opentype/opentype-stretchy-horizontal.html [ Failure ] 2751 webkit.org/b/72828 mathml/opentype/horizontal-LatinModern-munderover.html [ Failure ] -
trunk/Source/WebCore/ChangeLog
r169606 r169607 1 2014-06-05 Frédéric Wang <fred.wang@free.fr> 2 3 MathML operators not stretched horizontally 4 https://bugs.webkit.org/show_bug.cgi?id=72828 5 6 Reviewed by Chris Fleizach. 7 8 This patch adds basic horizontal stretching rules for operators inside 9 an <munder>, <mover> or <munderover> elements. The stretchy operators 10 in such an element stretch to cover the size of the non-stretchy 11 operators. This only works when fonts that have an OpenType MATH table 12 are used. 13 14 Tests: mathml/opentype/horizontal-LatinModern.html 15 mathml/opentype/opentype-stretchy-horizontal.html 16 mathml/opentype/horizontal-LatinModern-munderover.html 17 18 * rendering/mathml/RenderMathMLOperator.cpp: 19 (WebCore::MathMLOperatorDictionary::ExtractKeyHorizontal): We add an ordered list of operators that have horizontal stretch direction. 20 (WebCore::RenderMathMLOperator::RenderMathMLOperator): init m_Vertical 21 (WebCore::RenderMathMLOperator::SetOperatorProperties): set m_Vertical by checking whether the operator is in the horizontalOperators list. 22 (WebCore::RenderMathMLOperator::stretchTo): We do not stretch vertically 23 if the operator has horizontal direction. 24 We also add a new version stretchTo(LayoutUnit width) for horizontal stretching only. 25 (WebCore::RenderMathMLOperator::computePreferredLogicalWidths): Handle horizontal stretching: the maximumGlyphWidth is the maximum of 26 the base size or of the stretch size. 27 (WebCore::RenderMathMLOperator::getDisplayStyleLargeOperator): Add an ASSERT to ensure that this function is only called for vertical stretching. 28 (WebCore::RenderMathMLOperator::findStretchyData): Add an ASSERT to ensure that this function is not called to get the maximum width of a horizontal stretchy operator. 29 We take into account m_isVertical when calling getMathVariants or computing sizes. 30 There is not any Unicode-only construction for horizontal stretching, so a MATH table is required for horizontal stretching. 31 (WebCore::RenderMathMLOperator::updateStyle): Ignore some code paths specific to vertical stretching and take into account the m_Vertical parameters. 32 For horizontal stretching, the m_stretch*Baseline parameters are now updated to match the metrics of the size variant or of the maximum of the parts in the glyph assembly. 33 (WebCore::RenderMathMLOperator::computeLogicalHeight): logicalHeight is now explicitely the sum of m_stretchHeightAboveBaseline and m_stretchDepthBelowBaseline, since it can be different from the stretchSize() in horizontal stretching. 34 (WebCore::RenderMathMLOperator::paintGlyph): handle trimming for horizontal stretching. 35 (WebCore::RenderMathMLOperator::fillWithVerticalExtensionGlyph): rename the function and ensure it is only call for m_isVertical. 36 (WebCore::RenderMathMLOperator::fillWithHorizontalExtensionGlyph): same as fillWithVerticalExtensionGlyph, but for horizontal stretching. 37 (WebCore::RenderMathMLOperator::paint): For glyph assembly, choose between paintVerticalGlyphAssembly or paintHorizontalGlyphAssembly. 38 (WebCore::RenderMathMLOperator::paintVerticalGlyphAssembly): rename the function and ensure it is only call for m_isVertical. 39 (WebCore::RenderMathMLOperator::paintHorizontalGlyphAssembly): same as paintVerticalGlyphAssembly but for horizontal stretching. 40 * rendering/mathml/RenderMathMLOperator.h: we add a m_isVertical member to indicate the stretch direction and a m_stretchWidth to indicate the width of the stretchy character. 41 We define the horizontal counterparts of fillWith*ExtensionGlyph, paint*GlyphAssembly, GlyphPaintTrimming StretchyData. 42 Finally stretchSize() takes into account the stretch direction. 43 * rendering/mathml/RenderMathMLUnderOver.cpp: We override the layout() function to stretch munderover children horizontally. 44 (WebCore::RenderMathMLUnderOver::layout): 45 * rendering/mathml/RenderMathMLUnderOver.h: we declare layout(). 46 1 47 2014-06-04 Bem Jones-Bey <bjonesbe@adobe.com> 2 48 -
trunk/Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp
r169305 r169607 1126 1126 }; 1127 1127 1128 // A list of operators that stretch in the horizontal direction. This has been generated from Mozilla's MathML operator dictionary. 1129 inline UChar ExtractKeyHorizontal(const UChar* entry) { return *entry; } 1130 static const UChar horizontalOperators[] = { 1131 0x003D, 0x005E, 0x005F, 0x007E, 0x00AF, 0x02C6, 0x02C7, 0x02C9, 0x02CD, 0x02DC, 0x02F7, 0x0302, 0x0332, 0x203E, 0x20D0, 0x20D1, 0x20D6, 0x20D7, 0x20E1, 0x2190, 0x2192, 0x2194, 0x2198, 0x2199, 0x219C, 0x219D, 0x219E, 0x21A0, 0x21A2, 0x21A3, 0x21A4, 0x21A6, 0x21A9, 0x21AA, 0x21AB, 0x21AC, 0x21AD, 0x21B4, 0x21B9, 0x21BC, 0x21BD, 0x21C0, 0x21C1, 0x21C4, 0x21C6, 0x21C7, 0x21C9, 0x21CB, 0x21CC, 0x21D0, 0x21D2, 0x21D4, 0x21DA, 0x21DB, 0x21DC, 0x21DD, 0x21E0, 0x21E2, 0x21E4, 0x21E5, 0x21E6, 0x21E8, 0x21F0, 0x21F6, 0x21FD, 0x21FE, 0x21FF, 0x23B4, 0x23B5, 0x23DC, 0x23DD, 0x23DE, 0x23DF, 0x23E0, 0x23E1, 0x2500, 0x27F5, 0x27F6, 0x27F7, 0x27F8, 0x27F9, 0x27FA, 0x27FB, 0x27FC, 0x27FD, 0x27FE, 0x27FF, 0x290C, 0x290D, 0x290E, 0x290F, 0x2910, 0x294E, 0x2950, 0x2952, 0x2953, 0x2956, 0x2957, 0x295A, 0x295B, 0x295E, 0x295F, 0x2B45, 0x2B46, 0xFE35, 0xFE36, 0xFE37, 0xFE38 1132 }; 1133 1128 1134 } 1129 1135 … … 1133 1139 , m_stretchDepthBelowBaseline(0) 1134 1140 , m_operator(0) 1141 , m_isVertical(true) 1135 1142 { 1136 1143 updateTokenContent(); … … 1142 1149 , m_stretchDepthBelowBaseline(0) 1143 1150 , m_operator(0) 1151 , m_isVertical(true) 1144 1152 , m_operatorForm(form) 1145 1153 , m_operatorFlags(flag) … … 1174 1182 void RenderMathMLOperator::SetOperatorProperties() 1175 1183 { 1184 // We determine the stretch direction (default is vertical). 1185 m_isVertical = !(tryBinarySearch<const UChar, UChar>(MathMLOperatorDictionary::horizontalOperators, WTF_ARRAY_LENGTH(MathMLOperatorDictionary::horizontalOperators), m_operator, MathMLOperatorDictionary::ExtractKeyHorizontal)); 1186 1176 1187 // We determine the form of the operator. 1177 1188 bool explicitForm = true; … … 1254 1265 void RenderMathMLOperator::stretchTo(LayoutUnit heightAboveBaseline, LayoutUnit depthBelowBaseline) 1255 1266 { 1256 if ( heightAboveBaseline == m_stretchHeightAboveBaseline && depthBelowBaseline == m_stretchDepthBelowBaseline)1267 if (!m_isVertical || (heightAboveBaseline == m_stretchHeightAboveBaseline && depthBelowBaseline == m_stretchDepthBelowBaseline)) 1257 1268 return; 1258 1269 … … 1281 1292 m_stretchHeightAboveBaseline *= aspect; 1282 1293 m_stretchDepthBelowBaseline *= aspect; 1294 updateStyle(); 1295 } 1296 1297 void RenderMathMLOperator::stretchTo(LayoutUnit width) 1298 { 1299 if (m_isVertical || m_stretchWidth == width) 1300 return; 1301 1302 m_stretchWidth = width; 1303 1304 SetOperatorProperties(); 1305 1283 1306 updateStyle(); 1284 1307 } … … 1319 1342 GlyphData data = style().font().glyphDataForCharacter(m_operator, false); 1320 1343 float maximumGlyphWidth = advanceForGlyph(data); 1344 if (!m_isVertical) { 1345 if (maximumGlyphWidth < stretchSize()) 1346 maximumGlyphWidth = stretchSize(); 1347 m_maxPreferredLogicalWidth = m_leadingSpace + maximumGlyphWidth + m_trailingSpace; 1348 m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth; 1349 return; 1350 } 1321 1351 if (isLargeOperatorInDisplayStyle()) { 1322 1352 // 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/). … … 1482 1512 StretchyData data; 1483 1513 1484 ASSERT( isLargeOperatorInDisplayStyle());1514 ASSERT(m_isVertical && isLargeOperatorInDisplayStyle()); 1485 1515 1486 1516 const auto& primaryFontData = style().font().primaryFont(); … … 1511 1541 RenderMathMLOperator::StretchyData RenderMathMLOperator::findStretchyData(UChar character, float* maximumGlyphWidth) 1512 1542 { 1543 ASSERT(!maximumGlyphWidth || m_isVertical); 1544 1513 1545 StretchyData data; 1514 1546 StretchyData assemblyData; … … 1520 1552 Vector<Glyph> sizeVariants; 1521 1553 Vector<OpenTypeMathData::AssemblyPart> assemblyParts; 1522 primaryFontData->mathData()->getMathVariants(baseGlyph.glyph, true, sizeVariants, assemblyParts);1554 primaryFontData->mathData()->getMathVariants(baseGlyph.glyph, m_isVertical, sizeVariants, assemblyParts); 1523 1555 // We verify the size variants. 1524 1556 for (auto& variant : sizeVariants) { … … 1530 1562 else { 1531 1563 data.setSizeVariantMode(sizeVariant); 1532 if (heightForGlyph(sizeVariant) >= stretchSize()) 1564 float size = m_isVertical ? heightForGlyph(sizeVariant) : advanceForGlyph(sizeVariant); 1565 if (size >= stretchSize()) 1533 1566 return data; 1534 1567 } … … 1539 1572 return data; 1540 1573 } else { 1574 if (!m_isVertical) 1575 return data; 1576 1541 1577 // If the font does not have a MATH table, we fallback to the Unicode-only constructions. 1542 1578 const StretchyCharacter* stretchyCharacter = nullptr; … … 1575 1611 } 1576 1612 1577 // We ensure that the stretch height is large enough to avoid glyph overlaps. 1578 float height = heightForGlyph(assemblyData.top()) + heightForGlyph(assemblyData.bottom()); 1579 if (assemblyData.middle().glyph) 1580 height += heightForGlyph(assemblyData.middle()); 1581 if (height > stretchSize()) 1613 // We ensure that the size is large enough to avoid glyph overlaps. 1614 float size; 1615 if (m_isVertical) { 1616 size = heightForGlyph(assemblyData.top()) + heightForGlyph(assemblyData.bottom()); 1617 if (assemblyData.middle().glyph) 1618 size += heightForGlyph(assemblyData.middle()); 1619 } else { 1620 size = advanceForGlyph(assemblyData.left()) + advanceForGlyph(assemblyData.right()); 1621 if (assemblyData.middle().glyph) 1622 size += advanceForGlyph(assemblyData.middle()); 1623 } 1624 if (size > stretchSize()) 1582 1625 return data; 1583 1626 … … 1607 1650 return; 1608 1651 1609 if ( isLargeOperatorInDisplayStyle())1652 if (m_isVertical && isLargeOperatorInDisplayStyle()) 1610 1653 m_stretchyData = getDisplayStyleLargeOperator(m_operator); 1611 1654 else { 1612 1655 // We do not stretch if the base glyph is large enough. 1613 1656 GlyphData baseGlyph = style().font().glyphDataForCharacter(m_operator, false); 1614 float base Height = heightForGlyph(baseGlyph);1615 if (stretchSize() <= base Height)1657 float baseSize = m_isVertical ? heightForGlyph(baseGlyph) : advanceForGlyph(baseGlyph); 1658 if (stretchSize() <= baseSize) 1616 1659 return; 1617 1660 m_stretchyData = findStretchyData(m_operator, nullptr); 1618 1661 } 1619 1662 1620 if (m_ stretchyData.mode() == DrawSizeVariant) {1663 if (m_isVertical && m_stretchyData.mode() == DrawSizeVariant) { 1621 1664 // We resize the operator to match the one of the size variant. 1622 1665 if (isLargeOperatorInDisplayStyle()) { … … 1635 1678 } 1636 1679 } 1680 1681 if (!m_isVertical) { 1682 if (m_stretchyData.mode() == DrawSizeVariant) { 1683 FloatRect glyphBounds = boundsForGlyph(m_stretchyData.variant()); 1684 m_stretchHeightAboveBaseline = -glyphBounds.y(); 1685 m_stretchDepthBelowBaseline = glyphBounds.maxY(); 1686 m_stretchWidth = advanceForGlyph(m_stretchyData.variant()); 1687 } else if (m_stretchyData.mode() == DrawGlyphAssembly) { 1688 FloatRect glyphBounds; 1689 m_stretchHeightAboveBaseline = 0; 1690 m_stretchDepthBelowBaseline = 0; 1691 1692 glyphBounds = boundsForGlyph(m_stretchyData.left()); 1693 m_stretchHeightAboveBaseline = std::max<LayoutUnit>(m_stretchHeightAboveBaseline, -glyphBounds.y()); 1694 m_stretchDepthBelowBaseline = std::max<LayoutUnit>(m_stretchDepthBelowBaseline, glyphBounds.maxY()); 1695 1696 glyphBounds = boundsForGlyph(m_stretchyData.right()); 1697 m_stretchHeightAboveBaseline = std::max<LayoutUnit>(m_stretchHeightAboveBaseline, -glyphBounds.y()); 1698 m_stretchDepthBelowBaseline = std::max<LayoutUnit>(m_stretchDepthBelowBaseline, glyphBounds.maxY()); 1699 1700 glyphBounds = boundsForGlyph(m_stretchyData.extension()); 1701 m_stretchHeightAboveBaseline = std::max<LayoutUnit>(m_stretchHeightAboveBaseline, -glyphBounds.y()); 1702 m_stretchDepthBelowBaseline = std::max<LayoutUnit>(m_stretchDepthBelowBaseline, glyphBounds.maxY()); 1703 1704 if (m_stretchyData.middle().glyph) { 1705 glyphBounds = boundsForGlyph(m_stretchyData.middle()); 1706 m_stretchHeightAboveBaseline = std::max<LayoutUnit>(m_stretchHeightAboveBaseline, -glyphBounds.y()); 1707 m_stretchDepthBelowBaseline = std::max<LayoutUnit>(m_stretchDepthBelowBaseline, glyphBounds.maxY()); 1708 } 1709 } 1710 } 1637 1711 } 1638 1712 … … 1647 1721 { 1648 1722 if (m_stretchyData.mode() != DrawNormal) 1649 logicalHeight = stretchSize();1723 logicalHeight = m_stretchHeightAboveBaseline + m_stretchDepthBelowBaseline; 1650 1724 RenderBox::computeLogicalHeight(logicalHeight, logicalTop, computedValues); 1651 1725 } … … 1671 1745 clipBounds.shiftMaxYEdgeTo(glyphPaintRect.maxY()); 1672 1746 break; 1673 case TrimTopAndBottom: 1747 case TrimTopAndBottom: { 1674 1748 LayoutUnit temp = glyphPaintRect.y() + 1; 1675 1749 glyphPaintRect.shiftYEdgeTo(temp.ceil()); … … 1677 1751 clipBounds.shiftYEdgeTo(glyphPaintRect.y()); 1678 1752 clipBounds.shiftMaxYEdgeTo(glyphPaintRect.maxY()); 1753 } 1679 1754 break; 1755 case TrimLeft: 1756 glyphPaintRect.shiftXEdgeTo(glyphPaintRect.x().ceil() + 1); 1757 clipBounds.shiftXEdgeTo(glyphPaintRect.x()); 1758 break; 1759 case TrimRight: 1760 glyphPaintRect.shiftMaxXEdgeTo(glyphPaintRect.maxX().floor() - 1); 1761 clipBounds.shiftMaxXEdgeTo(glyphPaintRect.maxX()); 1762 break; 1763 case TrimLeftAndRight: { 1764 LayoutUnit temp = glyphPaintRect.x() + 1; 1765 glyphPaintRect.shiftXEdgeTo(temp.ceil()); 1766 glyphPaintRect.shiftMaxXEdgeTo(glyphPaintRect.maxX().floor() - 1); 1767 clipBounds.shiftXEdgeTo(glyphPaintRect.x()); 1768 clipBounds.shiftMaxXEdgeTo(glyphPaintRect.maxX()); 1769 } 1680 1770 } 1681 1771 … … 1691 1781 } 1692 1782 1693 void RenderMathMLOperator::fillWithExtensionGlyph(PaintInfo& info, const LayoutPoint& from, const LayoutPoint& to) 1694 { 1783 void RenderMathMLOperator::fillWithVerticalExtensionGlyph(PaintInfo& info, const LayoutPoint& from, const LayoutPoint& to) 1784 { 1785 ASSERT(m_isVertical); 1695 1786 ASSERT(m_stretchyData.mode() == DrawGlyphAssembly); 1696 1787 ASSERT(m_stretchyData.extension().glyph); … … 1720 1811 lastPaintedGlyphRect = paintGlyph(info, m_stretchyData.extension(), glyphOrigin, TrimTopAndBottom); 1721 1812 glyphOrigin.setY(glyphOrigin.y() + lastPaintedGlyphRect.height()); 1813 1814 // There's a chance that if the font size is small enough the glue glyph has been reduced to an empty rectangle 1815 // with trimming. In that case we just draw nothing. 1816 if (lastPaintedGlyphRect.isEmpty()) 1817 break; 1818 } 1819 } 1820 1821 void RenderMathMLOperator::fillWithHorizontalExtensionGlyph(PaintInfo& info, const LayoutPoint& from, const LayoutPoint& to) 1822 { 1823 ASSERT(!m_isVertical); 1824 ASSERT(m_stretchyData.mode() == DrawGlyphAssembly); 1825 ASSERT(m_stretchyData.extension().glyph); 1826 ASSERT(from.x() <= to.x()); 1827 1828 // If there is no space for the extension glyph, we don't need to do anything. 1829 if (from.x() == to.x()) 1830 return; 1831 1832 GraphicsContextStateSaver stateSaver(*info.context); 1833 1834 // Clipping the extender region here allows us to draw the bottom extender glyph into the 1835 // regions of the bottom glyph without worrying about overdraw (hairy pixels) and simplifies later clipping. 1836 LayoutRect clipBounds = info.rect; 1837 clipBounds.shiftXEdgeTo(from.x()); 1838 clipBounds.shiftMaxXEdgeTo(to.x()); 1839 info.context->clip(clipBounds); 1840 1841 // Trimming may remove up to two pixels from the left of the extender glyph, so we move it left by two pixels. 1842 float offsetToGlyphLeft = -2; 1843 LayoutPoint glyphOrigin = LayoutPoint(from.x() + offsetToGlyphLeft, std::min(from.y(), to.y()) + m_stretchHeightAboveBaseline); 1844 FloatRect lastPaintedGlyphRect(from, FloatSize()); 1845 1846 while (lastPaintedGlyphRect.maxX() < to.x()) { 1847 lastPaintedGlyphRect = paintGlyph(info, m_stretchyData.extension(), glyphOrigin, TrimLeftAndRight); 1848 glyphOrigin.setX(glyphOrigin.x() + lastPaintedGlyphRect.width()); 1722 1849 1723 1850 // There's a chance that if the font size is small enough the glue glyph has been reduced to an empty rectangle … … 1751 1878 } 1752 1879 1880 if (m_isVertical) 1881 paintVerticalGlyphAssembly(info, paintOffset); 1882 else 1883 paintHorizontalGlyphAssembly(info, paintOffset); 1884 } 1885 1886 void RenderMathMLOperator::paintVerticalGlyphAssembly(PaintInfo& info, const LayoutPoint& paintOffset) 1887 { 1888 ASSERT(m_isVertical); 1753 1889 ASSERT(m_stretchyData.mode() == DrawGlyphAssembly); 1754 1890 ASSERT(m_stretchyData.top().glyph); … … 1775 1911 1776 1912 LayoutRect middleGlyphPaintRect = paintGlyph(info, m_stretchyData.middle(), middleGlyphOrigin, TrimTopAndBottom); 1777 fillWith ExtensionGlyph(info, topGlyphPaintRect.minXMaxYCorner(), middleGlyphPaintRect.minXMinYCorner());1778 fillWith ExtensionGlyph(info, middleGlyphPaintRect.minXMaxYCorner(), bottomGlyphPaintRect.minXMinYCorner());1913 fillWithVerticalExtensionGlyph(info, topGlyphPaintRect.minXMaxYCorner(), middleGlyphPaintRect.minXMinYCorner()); 1914 fillWithVerticalExtensionGlyph(info, middleGlyphPaintRect.minXMaxYCorner(), bottomGlyphPaintRect.minXMinYCorner()); 1779 1915 } else 1780 fillWithExtensionGlyph(info, topGlyphPaintRect.minXMaxYCorner(), bottomGlyphPaintRect.minXMinYCorner()); 1916 fillWithVerticalExtensionGlyph(info, topGlyphPaintRect.minXMaxYCorner(), bottomGlyphPaintRect.minXMinYCorner()); 1917 } 1918 1919 void RenderMathMLOperator::paintHorizontalGlyphAssembly(PaintInfo& info, const LayoutPoint& paintOffset) 1920 { 1921 ASSERT(!m_isVertical); 1922 ASSERT(m_stretchyData.mode() == DrawGlyphAssembly); 1923 ASSERT(m_stretchyData.left().glyph); 1924 ASSERT(m_stretchyData.right().glyph); 1925 1926 // We are positioning the glyphs so that the edge of the tight glyph bounds line up exactly with the edges of our paint box. 1927 LayoutPoint operatorTopLeft = paintOffset + location(); 1928 operatorTopLeft.move(m_leadingSpace, 0); 1929 operatorTopLeft = ceiledIntPoint(operatorTopLeft); 1930 LayoutPoint leftGlyphOrigin(operatorTopLeft.x(), operatorTopLeft.y() + m_stretchHeightAboveBaseline); 1931 LayoutRect leftGlyphPaintRect = paintGlyph(info, m_stretchyData.left(), leftGlyphOrigin, TrimRight); 1932 1933 FloatRect rightGlyphBounds = boundsForGlyph(m_stretchyData.right()); 1934 LayoutPoint rightGlyphOrigin(operatorTopLeft.x() + offsetWidth() - rightGlyphBounds.width(), operatorTopLeft.y() + m_stretchHeightAboveBaseline); 1935 LayoutRect rightGlyphPaintRect = paintGlyph(info, m_stretchyData.right(), rightGlyphOrigin, TrimLeft); 1936 1937 if (m_stretchyData.middle().glyph) { 1938 // Center the glyph origin between the start and end glyph paint extents. 1939 LayoutPoint middleGlyphOrigin(operatorTopLeft.x(), leftGlyphOrigin.y()); 1940 middleGlyphOrigin.moveBy(LayoutPoint((rightGlyphPaintRect.x() - leftGlyphPaintRect.maxX()) / 2.0, 0)); 1941 LayoutRect middleGlyphPaintRect = paintGlyph(info, m_stretchyData.middle(), middleGlyphOrigin, TrimLeftAndRight); 1942 fillWithHorizontalExtensionGlyph(info, leftGlyphPaintRect.maxXMinYCorner(), middleGlyphPaintRect.minXMinYCorner()); 1943 fillWithHorizontalExtensionGlyph(info, middleGlyphPaintRect.maxXMinYCorner(), rightGlyphPaintRect.minXMinYCorner()); 1944 } else 1945 fillWithHorizontalExtensionGlyph(info, leftGlyphPaintRect.maxXMinYCorner(), rightGlyphPaintRect.minXMinYCorner()); 1781 1946 } 1782 1947 -
trunk/Source/WebCore/rendering/mathml/RenderMathMLOperator.h
r169305 r169607 65 65 66 66 void stretchTo(LayoutUnit heightAboveBaseline, LayoutUnit depthBelowBaseline); 67 LayoutUnit stretchSize() const { return m_stretchHeightAboveBaseline + m_stretchDepthBelowBaseline; } 67 void stretchTo(LayoutUnit width); 68 LayoutUnit stretchSize() const { return m_isVertical ? m_stretchHeightAboveBaseline + m_stretchDepthBelowBaseline : m_stretchWidth; } 68 69 69 70 bool hasOperatorFlag(MathMLOperatorDictionary::Flag flag) const { return m_operatorFlags & flag; } … … 111 112 GlyphData bottom() const { return m_data[2]; } 112 113 GlyphData middle() const { return m_data[3]; } 114 GlyphData left() const { return m_data[2]; } 115 GlyphData right() const { return m_data[0]; } 113 116 114 117 void setNormalMode() … … 158 161 TrimBottom, 159 162 TrimTopAndBottom, 163 TrimLeft, 164 TrimRight, 165 TrimLeftAndRight 160 166 }; 161 167 162 168 LayoutRect paintGlyph(PaintInfo&, const GlyphData&, const LayoutPoint& origin, GlyphPaintTrimming); 163 void fillWithExtensionGlyph(PaintInfo&, const LayoutPoint& from, const LayoutPoint& to); 169 void fillWithVerticalExtensionGlyph(PaintInfo&, const LayoutPoint& from, const LayoutPoint& to); 170 void fillWithHorizontalExtensionGlyph(PaintInfo&, const LayoutPoint& from, const LayoutPoint& to); 171 void paintVerticalGlyphAssembly(PaintInfo&, const LayoutPoint&); 172 void paintHorizontalGlyphAssembly(PaintInfo&, const LayoutPoint&); 164 173 165 174 LayoutUnit m_stretchHeightAboveBaseline; 166 175 LayoutUnit m_stretchDepthBelowBaseline; 176 LayoutUnit m_stretchWidth; 167 177 168 178 UChar m_operator; 179 bool m_isVertical; 169 180 StretchyData m_stretchyData; 170 181 MathMLOperatorDictionary::Form m_operatorForm; -
trunk/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.cpp
r165699 r169607 31 31 32 32 #include "MathMLElement.h" 33 #include "MathMLNames.h" 34 #include "RenderIterator.h" 35 #include "RenderMathMLOperator.h" 33 36 34 37 namespace WebCore { … … 69 72 } 70 73 74 void RenderMathMLUnderOver::layout() 75 { 76 LayoutUnit stretchWidth = 0; 77 for (RenderObject* child = firstChild(); child; child = child->nextSibling()) { 78 if (child->needsLayout()) 79 toRenderElement(child)->layout(); 80 // Skipping the embellished op does not work for nested structures like 81 // <munder><mover><mo>_</mo>...</mover> <mo>_</mo></munder>. 82 if (child->isBox()) 83 stretchWidth = std::max<LayoutUnit>(stretchWidth, toRenderBox(child)->logicalWidth()); 84 } 85 86 // Set the sizes of (possibly embellished) stretchy operator children. 87 for (auto& child : childrenOfType<RenderMathMLBlock>(*this)) { 88 if (auto renderOperator = child.unembellishedOperator()) 89 renderOperator->stretchTo(stretchWidth); 90 } 91 92 RenderMathMLBlock::layout(); 93 } 94 71 95 } 72 96 -
trunk/Source/WebCore/rendering/mathml/RenderMathMLUnderOver.h
r162139 r169607 41 41 virtual int firstLineBaseline() const override; 42 42 43 protected: 44 virtual void layout(); 45 43 46 private: 44 47 virtual bool isRenderMathMLUnderOver() const override { return true; }
Note: See TracChangeset
for help on using the changeset viewer.