Changeset 169305 in webkit
- Timestamp:
- May 23, 2014 9:56:50 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 30 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r169298 r169305 1 2014-05-24 Frédéric Wang <fred.wang@free.fr> 2 3 Use size variants and glyph assembly from the MATH data. 4 https://bugs.webkit.org/show_bug.cgi?id=130322 5 6 Reviewed by Chris Fleizach. 7 8 This adds some pixel tests for large operators and vertical stretchy operators. 9 10 * mathml/opentype/LICENSE-LatinModern.txt: Added. 11 * mathml/opentype/large-operators-LatinModern.html: Added. 12 * mathml/opentype/latinmodern-math.woff: Added. 13 * mathml/opentype/opentype-stretchy.html: Added. 14 * mathml/opentype/stretchy.woff: Added. 15 * mathml/opentype/vertical-LatinModern.html: Added. 16 * platform/efl/mathml/opentype/large-operators-LatinModern-expected.png: Added. 17 * platform/efl/mathml/opentype/large-operators-LatinModern-expected.txt: Added. 18 * platform/efl/mathml/opentype/opentype-stretchy-expected.png: Added. 19 * platform/efl/mathml/opentype/opentype-stretchy-expected.txt: Added. 20 * platform/efl/mathml/opentype/vertical-LatinModern-expected.png: Added. 21 * platform/efl/mathml/opentype/vertical-LatinModern-expected.txt: Added. 22 * platform/gtk/mathml/opentype/large-operators-LatinModern-expected.png: Added. 23 * platform/gtk/mathml/opentype/large-operators-LatinModern-expected.txt: Added. 24 * platform/gtk/mathml/opentype/opentype-stretchy-expected.png: Added. 25 * platform/gtk/mathml/opentype/opentype-stretchy-expected.txt: Added. 26 * platform/gtk/mathml/opentype/vertical-LatinModern-expected.png: Added. 27 * platform/gtk/mathml/opentype/vertical-LatinModern-expected.txt: Added. 28 * platform/gtk/mathml/presentation/mo-stretch-expected.png: update reference due to change in mathml.css 29 * platform/gtk/mathml/presentation/mo-stretch-expected.txt: ditto 30 * platform/mac/mathml/opentype/large-operators-LatinModern-expected.txt: Added. 31 * platform/mac/mathml/opentype/opentype-stretchy-expected.txt: Added. 32 * platform/mac/mathml/opentype/vertical-LatinModern-expected.txt: Added. 33 * platform/mac-wk2/mathml/opentype/large-operators-LatinModern-expected.txt: Added. 34 * platform/mac-wk2/mathml/opentype/opentype-stretchy-expected.txt: Added. 35 * platform/mac-wk2/mathml/opentype/vertical-LatinModern-expected.txt: Added. 36 * platform/win/TestExpectations: Mark the OpenType MATH tests as failing 37 1 38 2014-05-23 Yusuke Suzuki <utatane.tea@gmail.com> 2 39 -
trunk/LayoutTests/platform/gtk/mathml/presentation/mo-stretch-expected.txt
r168677 r169305 1 1 layer at (0,0) size 800x600 2 2 RenderView at (0,0) size 800x600 3 layer at (0,0) size 800x2 564 RenderBlock {HTML} at (0,0) size 800x2 565 RenderBody {BODY} at (8,8) size 784x24 06 RenderMathMLMath {math} at (0,0) size 126x2 0[padding: 0 1 0 1]7 RenderMathMLRow {mrow} at (1,0) size 124x2 08 RenderMathMLOperator {mo} at (0, 3) size 7x143 layer at (0,0) size 800x260 4 RenderBlock {HTML} at (0,0) size 800x260 5 RenderBody {BODY} at (8,8) size 784x244 6 RenderMathMLMath {math} at (0,0) size 126x24 [padding: 0 1 0 1] 7 RenderMathMLRow {mrow} at (1,0) size 124x24 8 RenderMathMLOperator {mo} at (0,5) size 7x14 9 9 RenderMathMLBlock (anonymous, flex) at (0,0) size 7x14 10 10 RenderBlock (anonymous) at (0,0) size 5x14 11 11 RenderText at (0,-6) size 5x25 12 12 text run at (0,-6) width 5: "(" 13 RenderMathMLOperator {mo} at (7, 3) size 7x1413 RenderMathMLOperator {mo} at (7,5) size 7x14 14 14 RenderMathMLBlock (anonymous, flex) at (0,0) size 7x14 15 15 RenderBlock (anonymous) at (0,0) size 5x14 16 16 RenderText at (0,-6) size 5x25 17 17 text run at (0,-6) width 5: ")" 18 RenderMathMLOperator {mo} at (14, 3) size 10x1418 RenderMathMLOperator {mo} at (14,5) size 10x14 19 19 RenderMathMLBlock (anonymous, flex) at (0,0) size 10x14 20 20 RenderBlock (anonymous) at (0,0) size 8x14 21 21 RenderText at (0,-6) size 8x25 22 22 text run at (0,-6) width 8: "{" 23 RenderMathMLOperator {mo} at (24, 3) size 10x1423 RenderMathMLOperator {mo} at (24,5) size 10x14 24 24 RenderMathMLBlock (anonymous, flex) at (0,0) size 10x14 25 25 RenderBlock (anonymous) at (0,0) size 8x14 26 26 RenderText at (0,-6) size 8x25 27 27 text run at (0,-6) width 8: "}" 28 RenderMathMLOperator {mo} at (34, 3) size 7x1428 RenderMathMLOperator {mo} at (34,5) size 7x14 29 29 RenderMathMLBlock (anonymous, flex) at (0,0) size 7x14 30 30 RenderBlock (anonymous) at (0,0) size 5x14 31 31 RenderText at (0,-6) size 5x25 32 32 text run at (0,-6) width 5: "[" 33 RenderMathMLOperator {mo} at (41, 3) size 7x1433 RenderMathMLOperator {mo} at (41,5) size 7x14 34 34 RenderMathMLBlock (anonymous, flex) at (0,0) size 7x14 35 35 RenderBlock (anonymous) at (0,0) size 5x14 36 36 RenderText at (0,-6) size 5x25 37 37 text run at (0,-6) width 5: "]" 38 RenderMathMLOperator {mo} at (48, 2) size 8x1638 RenderMathMLOperator {mo} at (48,4) size 8x16 39 39 RenderMathMLBlock (anonymous, flex) at (0,0) size 8x16 40 40 RenderBlock (anonymous) at (0,0) size 8x16 41 41 RenderText at (0,-5) size 8x25 42 42 text run at (0,-5) width 8: "\x{2308}" 43 RenderMathMLOperator {mo} at (56, 2) size 8x1643 RenderMathMLOperator {mo} at (56,4) size 8x16 44 44 RenderMathMLBlock (anonymous, flex) at (0,0) size 8x16 45 45 RenderBlock (anonymous) at (0,0) size 8x16 46 46 RenderText at (0,-5) size 8x25 47 47 text run at (0,-5) width 8: "\x{2309}" 48 RenderMathMLOperator {mo} at (64, 2) size 8x1648 RenderMathMLOperator {mo} at (64,4) size 8x16 49 49 RenderMathMLBlock (anonymous, flex) at (0,0) size 8x16 50 50 RenderBlock (anonymous) at (0,0) size 8x16 51 51 RenderText at (0,-5) size 8x25 52 52 text run at (0,-5) width 8: "\x{230A}" 53 RenderMathMLOperator {mo} at (72, 2) size 8x1653 RenderMathMLOperator {mo} at (72,4) size 8x16 54 54 RenderMathMLBlock (anonymous, flex) at (0,0) size 8x16 55 55 RenderBlock (anonymous) at (0,0) size 8x16 56 56 RenderText at (0,-5) size 8x25 57 57 text run at (0,-5) width 8: "\x{230B}" 58 RenderMathMLOperator {mo} at (80, 0) size 12x2058 RenderMathMLOperator {mo} at (80,2) size 12x20 59 59 RenderMathMLBlock (anonymous, flex) at (0,0) size 11x20 60 60 RenderBlock (anonymous) at (0,0) size 7x20 61 61 RenderText at (0,-3) size 7x25 62 62 text run at (0,-3) width 7: "\x{222B}" 63 RenderMathMLOperator {mo} at (91, 3) size 8x1263 RenderMathMLOperator {mo} at (91,0) size 8x24 64 64 RenderMathMLBlock (anonymous, flex) at (1,0) size 4x12 65 65 RenderBlock (anonymous) at (0,0) size 3x12 66 66 RenderText at (0,-6) size 3x25 67 67 text run at (0,-6) width 3: "|" 68 RenderMathMLOperator {mo} at (98, 2) size 9x1668 RenderMathMLOperator {mo} at (98,4) size 9x16 69 69 RenderMathMLBlock (anonymous, flex) at (0,0) size 8x16 70 70 RenderBlock (anonymous) at (0,0) size 8x16 71 71 RenderText at (0,-5) size 8x25 72 72 text run at (0,-5) width 8: "\x{2016}" 73 RenderMathMLOperator {mo} at (106, 2) size 18x1673 RenderMathMLOperator {mo} at (106,4) size 18x16 74 74 RenderMathMLBlock (anonymous, flex) at (4,0) size 9x16 75 75 RenderBlock (anonymous) at (0,0) size 8x16 76 76 RenderText at (0,-5) size 8x25 77 77 text run at (0,-5) width 8: "\x{2225}" 78 RenderText {#text} at (125, 0) size 5x1779 text run at (125, 0) width 5: " "78 RenderText {#text} at (125,2) size 5x17 79 text run at (125,2) width 5: " " 80 80 RenderBR {BR} at (0,0) size 0x0 81 RenderMathMLMath {math} at (0,2 0) size 126x142 [padding: 0 1 0 1]81 RenderMathMLMath {math} at (0,24) size 126x142 [padding: 0 1 0 1] 82 82 RenderMathMLRow {mrow} at (1,0) size 124x142 83 83 RenderMathMLOperator {mo} at (0,0) size 7x142 -
trunk/LayoutTests/platform/win/TestExpectations
r168426 r169305 2745 2745 fast/canvas/canvas-path-addPath.html [ Crash ] 2746 2746 2747 # Missing references on Windows 2748 webkit.org/b/130322 mathml/opentype/large-operators-LatinModern.html [ Failure ] 2749 webkit.org/b/130322 mathml/opentype/opentype-stretchy.html [ Failure ] 2750 webkit.org/b/130322 mathml/opentype/vertical-LatinModern.html [ Failure ] -
trunk/Source/WebCore/ChangeLog
r169299 r169305 1 2014-05-24 Frédéric Wang <fred.wang@free.fr> 2 3 Use size variants and glyph assembly from the MATH data. 4 https://bugs.webkit.org/show_bug.cgi?id=130322 5 6 Reviewed by Chris Fleizach. 7 8 This patch modifies the RenderMathMLOperator code to use the MATH table 9 when one is provided in the current font on the <math> tag. More 10 precisely, the MathVariants table is used to draw a size variant or 11 a glyph assembly. The displaystyle attribute is not supported yet, so 12 for now large operators are always assumed to be in display style. The 13 MATH support does not work well with all platforms+fonts, so at the 14 moment the default font-family on the <math> is not changed. 15 16 Tests: mathml/opentype/large-operators-LatinModern.html 17 mathml/opentype/opentype-stretchy.html 18 mathml/opentype/vertical-LatinModern.html 19 20 * css/mathml.css: We only specify the default font-family on the math root, so that people can easily style the mathematics. 21 For now, old fonts without the MATH table are still used as the default. 22 (math): 23 (math, mfenced > *): Deleted. 24 (mo, mfenced): Deleted. 25 * platform/graphics/SimpleFontData.cpp: don't return the math data if the font is loading. 26 (WebCore::SimpleFontData::mathData): 27 * platform/graphics/opentype/OpenTypeMathData.cpp: update #ifdef so that disabling ENABLE_OPENTYPE_MATH won't lead to errors with unused parameters. 28 (WebCore::OpenTypeMathData::OpenTypeMathData): 29 (WebCore::OpenTypeMathData::getMathConstant): 30 (WebCore::OpenTypeMathData::getItalicCorrection): 31 (WebCore::OpenTypeMathData::getMathVariants): 32 * rendering/mathml/RenderMathMLOperator.cpp: 33 (WebCore::RenderMathMLOperator::boundsForGlyph): 34 (WebCore::RenderMathMLOperator::heightForGlyph): 35 (WebCore::RenderMathMLOperator::advanceForGlyph): 36 (WebCore::RenderMathMLOperator::computePreferredLogicalWidths): We handle preferred width of size variants. 37 (WebCore::RenderMathMLOperator::shouldAllowStretching): This function now only returns whether the operator will stretch and no longer has side effect. 38 (WebCore::RenderMathMLOperator::getGlyphAssemblyFallBack): We add a function to convert from the MathVariant table data to the format supported by RenderMathMLOperator. 39 (WebCore::RenderMathMLOperator::getDisplayStyleLargeOperator): We add a function to get the glyph that will be used for large operators in display style. 40 (WebCore::RenderMathMLOperator::findStretchyData): We make this function handle size variants. 41 (WebCore::RenderMathMLOperator::updateStyle): We handle size variants. 42 (WebCore::RenderMathMLOperator::paint): We handle size variants. 43 * rendering/mathml/RenderMathMLOperator.h: 44 1 45 2014-05-23 Tim Horton <timothy_horton@apple.com> 2 46 -
trunk/Source/WebCore/css/mathml.css
r165461 r169305 11 11 12 12 /* Keep font-family and other defaults here consistent with http://mxr.mozilla.org/mozilla-central/source/layout/mathml/mathml.css and feedback from www-math. */ 13 math , mfenced > *{13 math { 14 14 #if defined(WTF_PLATFORM_IOS) && WTF_PLATFORM_IOS 15 15 /* We explicitly include the font Symbol as it's the iOS equivalent of font STIXGeneral. */ 16 16 font-family: STIXGeneral, Symbol, "Times New Roman", sans-serif; 17 17 #else 18 font-family: MathJax_Main, STIXGeneral, "DejaVu Serif", Cambria, "Cambria Math", Times, serif; 19 #endif 20 } 21 mo, mfenced { 22 #if defined(WTF_PLATFORM_IOS) && WTF_PLATFORM_IOS 23 /* We explicitly include the font Symbol as it's the iOS equivalent of font STIXGeneral. */ 24 font-family: STIXGeneral, Symbol, "Times New Roman", sans-serif; 25 #else 26 font-family: MathJax_Main, STIXGeneral, STIXSizeOneSym, "DejaVu Sans", "DejaVu Serif", Cambria, "Cambria Math", 27 "Lucida Sans Unicode", "Arial Unicode MS", "Lucida Grande", OpenSymbol, "Standard Symbols L", sans-serif; 18 font-family: MathJax_Main, STIXGeneral, STIXSizeOneSym, "DejaVu Sans", "DejaVu Serif", Cambria, "Cambria Math", "Lucida Sans Unicode", "Arial Unicode MS", "Lucida Grande", OpenSymbol, "Standard Symbols L", Times, serif; 28 19 #endif 29 20 } -
trunk/Source/WebCore/platform/graphics/SimpleFontData.cpp
r166633 r169305 262 262 const OpenTypeMathData* SimpleFontData::mathData() const 263 263 { 264 if (m_isLoading) 265 return nullptr; 264 266 if (!m_mathData) { 265 267 m_mathData = OpenTypeMathData::create(m_platformData); -
trunk/Source/WebCore/platform/graphics/opentype/OpenTypeMathData.cpp
r166640 r169305 230 230 #endif // ENABLE(OPENTYPE_MATH) 231 231 232 #if ENABLE(OPENTYPE_MATH) 232 233 OpenTypeMathData::OpenTypeMathData(const FontPlatformData& fontData) 233 234 { 234 #if ENABLE(OPENTYPE_MATH)235 235 m_mathBuffer = fontData.openTypeTable(OpenType::MATHTag); 236 236 const OpenType::MATHTable* math = OpenType::validateTable<OpenType::MATHTable>(m_mathBuffer); … … 250 250 m_mathBuffer = nullptr; 251 251 #else 252 OpenTypeMathData::OpenTypeMathData(const FontPlatformData&) 253 { 252 254 m_mathBuffer = nullptr; 253 255 #endif 254 256 } 255 257 258 #if ENABLE(OPENTYPE_MATH) 256 259 float OpenTypeMathData::getMathConstant(const SimpleFontData* font, MathConstant constant) const 257 260 { 258 #if ENABLE(OPENTYPE_MATH)259 261 int32_t value = 0; 260 262 … … 278 280 return value * font->sizePerUnit(); 279 281 #else 282 float OpenTypeMathData::getMathConstant(const SimpleFontData*, MathConstant) const 283 { 280 284 ASSERT_NOT_REACHED(); 281 285 return 0; … … 283 287 } 284 288 289 #if ENABLE(OPENTYPE_MATH) 285 290 float OpenTypeMathData::getItalicCorrection(const SimpleFontData* font, Glyph glyph) const 286 291 { 287 #if ENABLE(OPENTYPE_MATH)288 292 const OpenType::MATHTable* math = OpenType::validateTable<OpenType::MATHTable>(m_mathBuffer); 289 293 ASSERT(math); … … 298 302 return mathItalicsCorrectionInfo->getItalicCorrection(*m_mathBuffer, glyph) * font->sizePerUnit(); 299 303 #else 304 float OpenTypeMathData::getItalicCorrection(const SimpleFontData*, Glyph) const 305 { 300 306 ASSERT_NOT_REACHED(); 301 307 return 0; … … 303 309 } 304 310 311 #if ENABLE(OPENTYPE_MATH) 305 312 void OpenTypeMathData::getMathVariants(Glyph glyph, bool isVertical, Vector<Glyph>& sizeVariants, Vector<AssemblyPart>& assemblyParts) const 306 313 { 307 314 sizeVariants.clear(); 308 315 assemblyParts.clear(); 309 #if ENABLE(OPENTYPE_MATH)310 316 const OpenType::MATHTable* math = OpenType::validateTable<OpenType::MATHTable>(m_mathBuffer); 311 317 ASSERT(math); … … 320 326 mathGlyphConstruction->getAssemblyParts(*m_mathBuffer, assemblyParts); 321 327 #else 328 void OpenTypeMathData::getMathVariants(Glyph, bool, Vector<Glyph>&, Vector<AssemblyPart>&) const 329 { 322 330 ASSERT_NOT_REACHED(); 323 331 #endif -
trunk/Source/WebCore/rendering/mathml/RenderMathMLOperator.cpp
r166170 r169305 26 26 */ 27 27 28 #define _USE_MATH_DEFINES 1 28 29 #include "config.h" 29 30 … … 1283 1284 } 1284 1285 1285 FloatRect RenderMathMLOperator::boundsForGlyph(const GlyphData& data) 1286 FloatRect RenderMathMLOperator::boundsForGlyph(const GlyphData& data) const 1286 1287 { 1287 1288 return data.fontData->boundsForGlyph(data.glyph); 1288 1289 } 1289 1290 1290 float RenderMathMLOperator::heightForGlyph(const GlyphData& data) 1291 float RenderMathMLOperator::heightForGlyph(const GlyphData& data) const 1291 1292 { 1292 1293 return boundsForGlyph(data).height(); 1293 1294 } 1294 1295 1295 float RenderMathMLOperator::advanceForGlyph(const GlyphData& data) 1296 float RenderMathMLOperator::advanceForGlyph(const GlyphData& data) const 1296 1297 { 1297 1298 return data.fontData->widthForGlyph(data.glyph); … … 1303 1304 1304 1305 SetOperatorProperties(); 1305 UChar stretchedCharacter; 1306 bool allowStretching = shouldAllowStretching(stretchedCharacter); 1307 if (!allowStretching) { 1306 if (!shouldAllowStretching()) { 1308 1307 RenderMathMLToken::computePreferredLogicalWidths(); 1309 1308 if (isInvisibleOperator()) { … … 1318 1317 } 1319 1318 1320 GlyphData data = style().font().glyphDataForCharacter( stretchedCharacter, false);1319 GlyphData data = style().font().glyphDataForCharacter(m_operator, false); 1321 1320 float maximumGlyphWidth = advanceForGlyph(data); 1322 findStretchyData(stretchedCharacter, &maximumGlyphWidth); 1321 if (isLargeOperatorInDisplayStyle()) { 1322 // 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/). 1323 StretchyData largeOperator = getDisplayStyleLargeOperator(m_operator); 1324 if (largeOperator.mode() == DrawSizeVariant) 1325 maximumGlyphWidth = boundsForGlyph(largeOperator.variant()).width(); 1326 } else { 1327 // 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). 1328 findStretchyData(m_operator, &maximumGlyphWidth); 1329 } 1323 1330 m_maxPreferredLogicalWidth = m_minPreferredLogicalWidth = m_leadingSpace + maximumGlyphWidth + m_trailingSpace; 1324 1331 } … … 1372 1379 } 1373 1380 1374 bool RenderMathMLOperator::shouldAllowStretching(UChar& stretchedCharacter) 1375 { 1376 if (!hasOperatorFlag(MathMLOperatorDictionary::Stretchy)) 1377 return false; 1378 1379 stretchedCharacter = m_operator; 1380 return stretchedCharacter; 1381 } 1382 1383 // FIXME: We should also look at alternate characters defined in the OpenType MATH table (http://wkbug/122297). 1384 RenderMathMLOperator::StretchyData RenderMathMLOperator::findStretchyData(UChar character, float* maximumGlyphWidth) 1385 { 1386 // FIXME: This function should first try size variants. 1387 StretchyData data; 1388 1389 const StretchyCharacter* stretchyCharacter = 0; 1390 const int maxIndex = WTF_ARRAY_LENGTH(stretchyCharacters); 1391 for (int index = 0; index < maxIndex; ++index) { 1392 if (stretchyCharacters[index].character == character) { 1393 stretchyCharacter = &stretchyCharacters[index]; 1394 break; 1381 bool RenderMathMLOperator::shouldAllowStretching() const 1382 { 1383 return m_operator && (hasOperatorFlag(MathMLOperatorDictionary::Stretchy) || isLargeOperatorInDisplayStyle()); 1384 } 1385 1386 bool RenderMathMLOperator::getGlyphAssemblyFallBack(Vector<OpenTypeMathData::AssemblyPart> assemblyParts, StretchyData& stretchyData) const 1387 { 1388 GlyphData top; 1389 GlyphData extension; 1390 GlyphData bottom; 1391 GlyphData middle; 1392 1393 // 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. 1394 // FIXME: RenderMathMLOperator should support the most general format (https://bugs.webkit.org/show_bug.cgi?id=130327). 1395 // We use the approach of the copyComponents function in github.com/mathjax/MathJax-dev/blob/master/fonts/OpenTypeMath/fontUtil.py 1396 1397 // We count the number of non extender pieces. 1398 int nonExtenderCount = 0; 1399 for (auto& part : assemblyParts) { 1400 if (!part.isExtender) 1401 nonExtenderCount++; 1402 } 1403 if (nonExtenderCount > 3) 1404 return false; // This is not supported: there are too many pieces. 1405 1406 // We now browse the list of pieces. 1407 // 1 = look for a left/bottom glyph 1408 // 2 = look for an extender between left/bottom and mid 1409 // 4 = look for a middle glyph 1410 // 5 = look for an extender between middle and right/top 1411 // 5 = look for a right/top glyph 1412 // 6 = no more piece expected 1413 unsigned state = 1; 1414 1415 extension.glyph = 0; 1416 middle.glyph = 0; 1417 for (auto& part : assemblyParts) { 1418 if ((state == 2 || state == 3) && nonExtenderCount < 3) { 1419 // We do not try to find a middle glyph. 1420 state += 2; 1421 } 1422 if (part.isExtender) { 1423 if (!extension.glyph) 1424 extension.glyph = part.glyph; 1425 else if (extension.glyph != part.glyph) 1426 return false; // This is not supported: the assembly has different extenders. 1427 1428 if (state == 1) { 1429 // We ignore left/bottom piece and multiple successive extenders. 1430 state = 2; 1431 } else if (state == 3) { 1432 // We ignore middle piece and multiple successive extenders. 1433 state = 4; 1434 } else if (state >= 5) 1435 return false; // This is not supported: we got an unexpected extender. 1436 continue; 1437 } 1438 1439 if (state == 1) { 1440 // We copy the left/bottom part. 1441 bottom.glyph = part.glyph; 1442 state = 2; 1443 continue; 1444 } 1445 1446 if (state == 2 || state == 3) { 1447 // We copy the middle part. 1448 middle.glyph = part.glyph; 1449 state = 4; 1450 continue; 1451 } 1452 1453 if (state == 4 || state == 5) { 1454 // We copy the right/top part. 1455 top.glyph = part.glyph; 1456 state = 6; 1395 1457 } 1396 1458 } 1397 1459 1398 // If we didn't find a stretchy character set for this character, we don't know how to stretch it. 1399 if (!stretchyCharacter) 1460 if (!extension.glyph) 1461 return false; // This is not supported: we always assume that we have an extension glyph. 1462 1463 // If we don't have top/bottom glyphs, we use the extension glyph. 1464 if (!top.glyph) 1465 top.glyph = extension.glyph; 1466 if (!bottom.glyph) 1467 bottom.glyph = extension.glyph; 1468 1469 top.fontData = style().font().primaryFont(); 1470 extension.fontData = top.fontData; 1471 bottom.fontData = top.fontData; 1472 if (middle.glyph) 1473 middle.fontData = top.fontData; 1474 1475 stretchyData.setGlyphAssemblyMode(top, extension, bottom, middle); 1476 1477 return true; 1478 } 1479 1480 RenderMathMLOperator::StretchyData RenderMathMLOperator::getDisplayStyleLargeOperator(UChar character) const 1481 { 1482 StretchyData data; 1483 1484 ASSERT(isLargeOperatorInDisplayStyle()); 1485 1486 const auto& primaryFontData = style().font().primaryFont(); 1487 GlyphData baseGlyph = style().font().glyphDataForCharacter(character, false); 1488 if (!primaryFontData || !primaryFontData->mathData() || baseGlyph.fontData != primaryFontData) 1400 1489 return data; 1401 1490 1402 // We convert the list of Unicode characters into a list of glyph data. 1403 GlyphData top = style().font().glyphDataForCharacter(stretchyCharacter->topChar, false); 1404 GlyphData extension = style().font().glyphDataForCharacter(stretchyCharacter->extensionChar, false); 1405 GlyphData bottom = style().font().glyphDataForCharacter(stretchyCharacter->bottomChar, false); 1406 GlyphData middle; 1407 if (stretchyCharacter->middleChar) 1408 middle = style().font().glyphDataForCharacter(stretchyCharacter->middleChar, false); 1491 Vector<Glyph> sizeVariants; 1492 Vector<OpenTypeMathData::AssemblyPart> assemblyParts; 1493 1494 // 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. 1495 float displayOperatorMinHeight = std::max(baseGlyph.fontData->boundsForGlyph(baseGlyph.glyph).height() * float(M_SQRT2), primaryFontData->mathData()->getMathConstant(primaryFontData, OpenTypeMathData::DisplayOperatorMinHeight)); 1496 1497 primaryFontData->mathData()->getMathVariants(baseGlyph.glyph, true, sizeVariants, assemblyParts); 1498 1499 // We choose the first size variant that is larger than the expected displayOperatorMinHeight and otherwise fallback to the largest variant. 1500 for (auto& variant : sizeVariants) { 1501 GlyphData sizeVariant; 1502 sizeVariant.glyph = variant; 1503 sizeVariant.fontData = primaryFontData; 1504 data.setSizeVariantMode(sizeVariant); 1505 if (boundsForGlyph(sizeVariant).height() >= displayOperatorMinHeight) 1506 return data; 1507 } 1508 return data; 1509 } 1510 1511 RenderMathMLOperator::StretchyData RenderMathMLOperator::findStretchyData(UChar character, float* maximumGlyphWidth) 1512 { 1513 StretchyData data; 1514 StretchyData assemblyData; 1515 1516 const auto& primaryFontData = style().font().primaryFont(); 1517 GlyphData baseGlyph = style().font().glyphDataForCharacter(character, false); 1518 1519 if (primaryFontData && primaryFontData->mathData() && baseGlyph.fontData == primaryFontData) { 1520 Vector<Glyph> sizeVariants; 1521 Vector<OpenTypeMathData::AssemblyPart> assemblyParts; 1522 primaryFontData->mathData()->getMathVariants(baseGlyph.glyph, true, sizeVariants, assemblyParts); 1523 // We verify the size variants. 1524 for (auto& variant : sizeVariants) { 1525 GlyphData sizeVariant; 1526 sizeVariant.glyph = variant; 1527 sizeVariant.fontData = primaryFontData; 1528 if (maximumGlyphWidth) 1529 *maximumGlyphWidth = std::max(*maximumGlyphWidth, advanceForGlyph(sizeVariant)); 1530 else { 1531 data.setSizeVariantMode(sizeVariant); 1532 if (heightForGlyph(sizeVariant) >= stretchSize()) 1533 return data; 1534 } 1535 } 1536 1537 // We verify if there is a construction. 1538 if (!getGlyphAssemblyFallBack(assemblyParts, assemblyData)) 1539 return data; 1540 } else { 1541 // If the font does not have a MATH table, we fallback to the Unicode-only constructions. 1542 const StretchyCharacter* stretchyCharacter = nullptr; 1543 const unsigned maxIndex = WTF_ARRAY_LENGTH(stretchyCharacters); 1544 for (unsigned index = 0; index < maxIndex; ++index) { 1545 if (stretchyCharacters[index].character == character) { 1546 stretchyCharacter = &stretchyCharacters[index]; 1547 break; 1548 } 1549 } 1550 1551 // If we didn't find a stretchy character set for this character, we don't know how to stretch it. 1552 if (!stretchyCharacter) 1553 return data; 1554 1555 // We convert the list of Unicode characters into a list of glyph data. 1556 GlyphData top = style().font().glyphDataForCharacter(stretchyCharacter->topChar, false); 1557 GlyphData extension = style().font().glyphDataForCharacter(stretchyCharacter->extensionChar, false); 1558 GlyphData bottom = style().font().glyphDataForCharacter(stretchyCharacter->bottomChar, false); 1559 GlyphData middle; 1560 if (stretchyCharacter->middleChar) 1561 middle = style().font().glyphDataForCharacter(stretchyCharacter->middleChar, false); 1562 assemblyData.setGlyphAssemblyMode(top, extension, bottom, middle); 1563 } 1564 1565 ASSERT(assemblyData.mode() == DrawGlyphAssembly); 1409 1566 1410 1567 // If we are measuring the maximum width, verify each component. 1411 1568 if (maximumGlyphWidth) { 1412 *maximumGlyphWidth = std::max(*maximumGlyphWidth, advanceForGlyph( top));1413 *maximumGlyphWidth = std::max(*maximumGlyphWidth, advanceForGlyph( extension));1414 if ( middle.glyph)1415 *maximumGlyphWidth = std::max(*maximumGlyphWidth, advanceForGlyph( middle));1416 *maximumGlyphWidth = std::max(*maximumGlyphWidth, advanceForGlyph( bottom));1417 return data;1569 *maximumGlyphWidth = std::max(*maximumGlyphWidth, advanceForGlyph(assemblyData.top())); 1570 *maximumGlyphWidth = std::max(*maximumGlyphWidth, advanceForGlyph(assemblyData.extension())); 1571 if (assemblyData.middle().glyph) 1572 *maximumGlyphWidth = std::max(*maximumGlyphWidth, advanceForGlyph(assemblyData.middle())); 1573 *maximumGlyphWidth = std::max(*maximumGlyphWidth, advanceForGlyph(assemblyData.bottom())); 1574 return assemblyData; 1418 1575 } 1419 1576 1420 float height = heightForGlyph(top) + heightForGlyph(bottom); 1421 if (middle.glyph) 1422 height += heightForGlyph(middle); 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()); 1423 1581 if (height > stretchSize()) 1424 1582 return data; 1425 1583 1426 data.setGlyphAssemblyMode(top, extension, bottom, middle); 1427 return data; 1584 return assemblyData; 1428 1585 } 1429 1586 1430 1587 void RenderMathMLOperator::updateStyle() 1431 1588 { 1589 FontCachePurgePreventer fontCachePurgePreventer; 1590 1432 1591 ASSERT(firstChild()); 1433 1592 if (!firstChild()) 1434 1593 return; 1435 1594 1436 UChar stretchedCharacter;1437 bool allowStretching = shouldAllowStretching(stretchedCharacter);1438 1439 float stretchedCharacterHeight = style().fontMetrics().floatHeight();1440 1595 m_stretchyData.setNormalMode(); 1441 1442 // Sometimes we cannot stretch an operator properly, so in that case, we should just use the original size.1443 if (allowStretching && stretchSize() > stretchedCharacterHeight)1444 m_stretchyData = findStretchyData(stretchedCharacter, nullptr);1445 1446 1596 // We add spacing around the operator. 1447 1597 // FIXME: The spacing should be added to the whole embellished operator (https://bugs.webkit.org/show_bug.cgi?id=124831). … … 1453 1603 wrapper->setStyle(std::move(newStyle)); 1454 1604 wrapper->setNeedsLayoutAndPrefWidthsRecalc(); 1605 1606 if (!shouldAllowStretching()) 1607 return; 1608 1609 if (isLargeOperatorInDisplayStyle()) 1610 m_stretchyData = getDisplayStyleLargeOperator(m_operator); 1611 else { 1612 // We do not stretch if the base glyph is large enough. 1613 GlyphData baseGlyph = style().font().glyphDataForCharacter(m_operator, false); 1614 float baseHeight = heightForGlyph(baseGlyph); 1615 if (stretchSize() <= baseHeight) 1616 return; 1617 m_stretchyData = findStretchyData(m_operator, nullptr); 1618 } 1619 1620 if (m_stretchyData.mode() == DrawSizeVariant) { 1621 // We resize the operator to match the one of the size variant. 1622 if (isLargeOperatorInDisplayStyle()) { 1623 // The stretch size is actually not involved in the selection of the size variant in getDisplayStyleLargeOperator. 1624 // We simply use the height and depth of the selected size variant glyph. 1625 FloatRect glyphBounds = boundsForGlyph(m_stretchyData.variant()); 1626 m_stretchHeightAboveBaseline = -glyphBounds.y(); 1627 m_stretchDepthBelowBaseline = glyphBounds.maxY(); 1628 } else { 1629 // We rescale the height and depth proportionately. 1630 float variantSize = heightForGlyph(m_stretchyData.variant()); 1631 float size = stretchSize(); 1632 float aspect = size > 0 ? variantSize / size : 1.0; 1633 m_stretchHeightAboveBaseline *= aspect; 1634 m_stretchDepthBelowBaseline *= aspect; 1635 } 1636 } 1455 1637 } 1456 1638 … … 1558 1740 info.context->setFillColor(style().visitedDependentColor(CSSPropertyColor), style().colorSpace()); 1559 1741 1742 if (m_stretchyData.mode() == DrawSizeVariant) { 1743 ASSERT(m_stretchyData.variant().glyph); 1744 GlyphBuffer buffer; 1745 buffer.add(m_stretchyData.variant().glyph, m_stretchyData.variant().fontData, advanceForGlyph(m_stretchyData.variant())); 1746 LayoutPoint operatorTopLeft = ceiledIntPoint(paintOffset + location()); 1747 FloatRect glyphBounds = boundsForGlyph(m_stretchyData.variant()); 1748 LayoutPoint operatorOrigin(operatorTopLeft.x(), operatorTopLeft.y() - glyphBounds.y()); 1749 info.context->drawGlyphs(style().font(), *m_stretchyData.variant().fontData, buffer, 0, 1, operatorOrigin); 1750 return; 1751 } 1752 1560 1753 ASSERT(m_stretchyData.mode() == DrawGlyphAssembly); 1561 1754 ASSERT(m_stretchyData.top().glyph); -
trunk/Source/WebCore/rendering/mathml/RenderMathMLOperator.h
r165608 r169305 31 31 #include "GlyphPage.h" 32 32 #include "MathMLElement.h" 33 #include "OpenTypeMathData.h" 33 34 #include "RenderMathMLToken.h" 35 #include "SimpleFontData.h" 34 36 35 37 namespace WebCore { … … 41 43 Accent = 0x1, // FIXME: This must be used to implement accentunder/accent on munderover (https://bugs.webkit.org/show_bug.cgi?id=124826). 42 44 Fence = 0x2, // This has no visual effect but allows to expose semantic information via the accessibility tree. 43 LargeOp = 0x4, // FIXME: This must be used to implement displaystyle (https://bugs.webkit.org/show_bug.cgi?id=118737)45 LargeOp = 0x4, 44 46 MovableLimits = 0x8, // FIXME: This must be used to implement displaystyle (https://bugs.webkit.org/show_bug.cgi?id=118737). 45 47 Separator = 0x10, // This has no visual effect but allows to expose semantic information via the accessibility tree. … … 66 68 67 69 bool hasOperatorFlag(MathMLOperatorDictionary::Flag flag) const { return m_operatorFlags & flag; } 70 // FIXME: The displaystyle property is not implemented (https://bugs.webkit.org/show_bug.cgi?id=118737). 71 bool isLargeOperatorInDisplayStyle() const { return !hasOperatorFlag(MathMLOperatorDictionary::Stretchy) && hasOperatorFlag(MathMLOperatorDictionary::LargeOp); } 68 72 69 73 void updateStyle() override final; … … 90 94 void updateFromElement() override; 91 95 92 bool shouldAllowStretching( UChar& characterForStretching);96 bool shouldAllowStretching() const; 93 97 94 FloatRect boundsForGlyph(const GlyphData&) ;95 float heightForGlyph(const GlyphData&) ;96 float advanceForGlyph(const GlyphData&) ;98 FloatRect boundsForGlyph(const GlyphData&) const; 99 float heightForGlyph(const GlyphData&) const; 100 float advanceForGlyph(const GlyphData&) const; 97 101 98 // FIXME: DrawSizeVariant is not implemented yet.99 102 enum DrawMode { 100 103 DrawNormal, DrawSizeVariant, DrawGlyphAssembly … … 147 150 GlyphData m_data[4]; 148 151 }; 152 bool getGlyphAssemblyFallBack(Vector<OpenTypeMathData::AssemblyPart>, StretchyData&) const; 153 StretchyData getDisplayStyleLargeOperator(UChar) const; 149 154 StretchyData findStretchyData(UChar, float* maximumGlyphWidth); 150 155
Note: See TracChangeset
for help on using the changeset viewer.