Title: [152140] trunk
Revision
152140
Author
commit-qu...@webkit.org
Date
2013-06-27 17:14:57 -0700 (Thu, 27 Jun 2013)

Log Message

Implement parsing of MathML lengths.
https://bugs.webkit.org/show_bug.cgi?id=118053

Patch by Frédéric Wang <fred.w...@free.fr> on 2013-06-27
Reviewed by Chris Fleizach.

Source/WebCore:

A parsing function for MathML lengths, similar to Gecko's one, is
implemented. It is currently only used to parse mfrac@linethickness but
will be convenient to parse other MathML attributes in the future.

Tests: mathml/presentation/mfrac-linethickness1.html
       mathml/presentation/mfrac-linethickness2.html
       mathml/presentation/mfrac-linethickness3.html

* rendering/mathml/RenderMathMLBlock.cpp: add parsing functions
(WebCore::parseMathMLLength): parsing MathML Length (number unit)
(WebCore::parseNamedSpace): parsing MathML namedspaces
* rendering/mathml/RenderMathMLBlock.h: declare parsing functions
* rendering/mathml/RenderMathMLFraction.cpp: use the parsing function for linethickness
(WebCore::RenderMathMLFraction::updateFromElement):

LayoutTests:

Add some reftests for mfrac@linethickness. Better tests for the parsing
of MathML lengths will be provided when mspace is implemented
(bug 115610)

* mathml/presentation/mfrac-linethickness1-expected-mismatch.html: Added.
* mathml/presentation/mfrac-linethickness1.html: Added.
* mathml/presentation/mfrac-linethickness2-expected.html: Added.
* mathml/presentation/mfrac-linethickness2.html: Added.
* mathml/presentation/mfrac-linethickness3-expected-mismatch.html: Added.
* mathml/presentation/mfrac-linethickness3.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (152139 => 152140)


--- trunk/LayoutTests/ChangeLog	2013-06-28 00:02:12 UTC (rev 152139)
+++ trunk/LayoutTests/ChangeLog	2013-06-28 00:14:57 UTC (rev 152140)
@@ -1,3 +1,21 @@
+2013-06-27  Frédéric Wang  <fred.w...@free.fr>
+
+        Implement parsing of MathML lengths.
+        https://bugs.webkit.org/show_bug.cgi?id=118053
+
+        Reviewed by Chris Fleizach.
+
+        Add some reftests for mfrac@linethickness. Better tests for the parsing
+        of MathML lengths will be provided when mspace is implemented
+        (bug 115610)
+
+        * mathml/presentation/mfrac-linethickness1-expected-mismatch.html: Added.
+        * mathml/presentation/mfrac-linethickness1.html: Added.
+        * mathml/presentation/mfrac-linethickness2-expected.html: Added.
+        * mathml/presentation/mfrac-linethickness2.html: Added.
+        * mathml/presentation/mfrac-linethickness3-expected-mismatch.html: Added.
+        * mathml/presentation/mfrac-linethickness3.html: Added.
+
 2013-06-27  Jessie Berlin  <jber...@apple.com>
 
         [Mac WK2] compositing/repaint/positioned-movement.html flaky, missing repaint

Added: trunk/LayoutTests/mathml/presentation/mfrac-linethickness1-expected-mismatch.html (0 => 152140)


--- trunk/LayoutTests/mathml/presentation/mfrac-linethickness1-expected-mismatch.html	                        (rev 0)
+++ trunk/LayoutTests/mathml/presentation/mfrac-linethickness1-expected-mismatch.html	2013-06-28 00:14:57 UTC (rev 152140)
@@ -0,0 +1,11 @@
+<!doctype html>
+<html>
+  <head>
+    <title>mfrac linethickness</title>
+  </head>
+  <body>
+
+  <div style="position: absolute; top: 0; left: 0; width: 500px; height: 150px; background: blue;"></div>
+
+  </body>
+</html>

Added: trunk/LayoutTests/mathml/presentation/mfrac-linethickness1.html (0 => 152140)


--- trunk/LayoutTests/mathml/presentation/mfrac-linethickness1.html	                        (rev 0)
+++ trunk/LayoutTests/mathml/presentation/mfrac-linethickness1.html	2013-06-28 00:14:57 UTC (rev 152140)
@@ -0,0 +1,21 @@
+<!doctype html>
+<html>
+  <head>
+    <title>mfrac linethickness</title>
+  </head>
+  <body>
+
+  <!-- This mfrac should be tall enough, or it will be hidden by the blue rectangle -->
+  <div style="position: absolute; top: 0; left: 0;">
+    <math>
+      <mfrac linethickness="200px">
+        <mi>x</mi>
+        <mi>y</mi>
+      </mfrac>
+    </math>
+  </div>
+
+  <div style="position: absolute; top: 0; left: 0; width: 500px; height: 150px; background: blue;"></div>
+
+  </body>
+</html>

Added: trunk/LayoutTests/mathml/presentation/mfrac-linethickness2-expected.html (0 => 152140)


--- trunk/LayoutTests/mathml/presentation/mfrac-linethickness2-expected.html	                        (rev 0)
+++ trunk/LayoutTests/mathml/presentation/mfrac-linethickness2-expected.html	2013-06-28 00:14:57 UTC (rev 152140)
@@ -0,0 +1,30 @@
+<!doctype html>
+<html>
+  <head>
+    <title>mfrac linethickness</title>
+  </head>
+  <body>
+
+  <math>
+    <mfrac>
+      <mi>x</mi>
+      <mi>y</mi>
+    </mfrac>
+  </math>
+
+  <math>
+    <mfrac linethickness="5">
+      <mi>x</mi>
+      <mi>y</mi>
+    </mfrac>
+  </math>
+
+  <math>
+    <mfrac linethickness="0.388888889em">
+      <mi>x</mi>
+      <mi>y</mi>
+    </mfrac>
+  </math>
+
+  </body>
+</html>

Added: trunk/LayoutTests/mathml/presentation/mfrac-linethickness2.html (0 => 152140)


--- trunk/LayoutTests/mathml/presentation/mfrac-linethickness2.html	                        (rev 0)
+++ trunk/LayoutTests/mathml/presentation/mfrac-linethickness2.html	2013-06-28 00:14:57 UTC (rev 152140)
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+  <head>
+    <title>mfrac linethickness</title>
+  </head>
+  <body>
+
+  <!-- The linethickness should be ignored -->
+  <math>
+    <mfrac linethickness="-1.23em">
+      <mi>x</mi>
+      <mi>y</mi>
+    </mfrac>
+  </math>
+
+  <!-- The linethickness should be 5 times the default value -->
+  <math>
+    <mfrac linethickness="500%">
+      <mi>x</mi>
+      <mi>y</mi>
+    </mfrac>
+  </math>
+
+  <!-- The linethickness should be ~7/18em -->
+  <math>
+    <mfrac linethickness="veryverythickmathspace">
+      <mi>x</mi>
+      <mi>y</mi>
+    </mfrac>
+  </math>
+
+  </body>
+</html>

Added: trunk/LayoutTests/mathml/presentation/mfrac-linethickness3-expected-mismatch.html (0 => 152140)


--- trunk/LayoutTests/mathml/presentation/mfrac-linethickness3-expected-mismatch.html	                        (rev 0)
+++ trunk/LayoutTests/mathml/presentation/mfrac-linethickness3-expected-mismatch.html	2013-06-28 00:14:57 UTC (rev 152140)
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+  <head>
+    <title>mfrac linethickness</title>
+  </head>
+  <body>
+
+  <math>
+    <mfrac>
+      <mi>x</mi>
+      <mi>y</mi>
+    </mfrac>
+  </math>
+
+  </body>
+</html>

Added: trunk/LayoutTests/mathml/presentation/mfrac-linethickness3.html (0 => 152140)


--- trunk/LayoutTests/mathml/presentation/mfrac-linethickness3.html	                        (rev 0)
+++ trunk/LayoutTests/mathml/presentation/mfrac-linethickness3.html	2013-06-28 00:14:57 UTC (rev 152140)
@@ -0,0 +1,17 @@
+<!doctype html>
+<html>
+  <head>
+    <title>mfrac linethickness</title>
+  </head>
+  <body>
+
+  <!-- The fraction bar should not be visible -->
+  <math>
+    <mfrac linethickness="0">
+      <mi>x</mi>
+      <mi>y</mi>
+    </mfrac>
+  </math>
+
+  </body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (152139 => 152140)


--- trunk/Source/WebCore/ChangeLog	2013-06-28 00:02:12 UTC (rev 152139)
+++ trunk/Source/WebCore/ChangeLog	2013-06-28 00:14:57 UTC (rev 152140)
@@ -1,3 +1,25 @@
+2013-06-27  Frédéric Wang  <fred.w...@free.fr>
+
+        Implement parsing of MathML lengths.
+        https://bugs.webkit.org/show_bug.cgi?id=118053
+
+        Reviewed by Chris Fleizach.
+
+        A parsing function for MathML lengths, similar to Gecko's one, is
+        implemented. It is currently only used to parse mfrac@linethickness but
+        will be convenient to parse other MathML attributes in the future.
+
+        Tests: mathml/presentation/mfrac-linethickness1.html
+               mathml/presentation/mfrac-linethickness2.html
+               mathml/presentation/mfrac-linethickness3.html
+
+        * rendering/mathml/RenderMathMLBlock.cpp: add parsing functions
+        (WebCore::parseMathMLLength): parsing MathML Length (number unit)
+        (WebCore::parseNamedSpace): parsing MathML namedspaces
+        * rendering/mathml/RenderMathMLBlock.h: declare parsing functions
+        * rendering/mathml/RenderMathMLFraction.cpp: use the parsing function for linethickness
+        (WebCore::RenderMathMLFraction::updateFromElement):
+
 2013-06-27  Anders Carlsson  <ander...@apple.com>
 
         Remove call to deprecatedCharactersWithNullTermination() in WebGL code

Modified: trunk/Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp (152139 => 152140)


--- trunk/Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp	2013-06-28 00:02:12 UTC (rev 152139)
+++ trunk/Source/WebCore/rendering/mathml/RenderMathMLBlock.cpp	2013-06-28 00:14:57 UTC (rev 152140)
@@ -33,6 +33,7 @@
 #include "GraphicsContext.h"
 #include "MathMLNames.h"
 #include "RenderView.h"
+#include <wtf/text/StringBuilder.h>
 
 #if ENABLE(DEBUG_MATH_LAYOUT)
 #include "PaintInfo.h"
@@ -187,6 +188,179 @@
 }
 #endif // ENABLE(DEBUG_MATH_LAYOUT)
 
+//
+// The MathML specification says:
+// (http://www.w3.org/TR/MathML/chapter2.html#fund.units)
+//
+// "Most presentation elements have attributes that accept values representing
+// lengths to be used for size, spacing or similar properties. The syntax of a
+// length is specified as
+//
+// number | number unit | namedspace
+//
+// There should be no space between the number and the unit of a length."
+// 
+// "A trailing '%' represents a percent of the default value. The default
+// value, or how it is obtained, is listed in the table of attributes for each
+// element. [...] A number without a unit is intepreted as a multiple of the
+// default value."
+//
+// "The possible units in MathML are:
+//  
+// Unit Description
+// em   an em (font-relative unit traditionally used for horizontal lengths)
+// ex   an ex (font-relative unit traditionally used for vertical lengths)
+// px   pixels, or size of a pixel in the current display
+// in   inches (1 inch = 2.54 centimeters)
+// cm   centimeters
+// mm   millimeters
+// pt   points (1 point = 1/72 inch)
+// pc   picas (1 pica = 12 points)
+// %    percentage of default value"
+//
+// The numbers are defined that way:
+// - unsigned-number: "a string of decimal digits with up to one decimal point
+//   (U+002E), representing a non-negative terminating decimal number (a type of
+//   rational number)"
+// - number: "an optional prefix of '-' (U+002D), followed by an unsigned
+//   number, representing a terminating decimal number (a type of rational
+//   number)"
+//
+bool parseMathMLLength(const String& string, float& lengthValue, const RenderStyle* style, bool allowNegative)
+{
+    String s = string.simplifyWhiteSpace();
+
+    int stringLength = s.length();
+    if (!stringLength)
+        return false;
+
+    if (parseMathMLNamedSpace(s, lengthValue, style, allowNegative))
+        return true;
+
+    StringBuilder number;
+    String unit;
+
+    // This verifies whether the negative sign is there.
+    int i = 0;
+    UChar c = s[0];
+    if (c == '-') {
+        number.append(c);
+        i++;
+    }
+
+    // This gathers up characters that make up the number.
+    bool gotDot = false;
+    for ( ; i < stringLength; i++) {
+        c = s[i];
+        // The string is invalid if it contains two dots.
+        if (gotDot && c == '.')
+            return false;
+        if (c == '.')
+            gotDot = true;
+        else if (!isASCIIDigit(c)) {
+            unit = s.substring(i, stringLength - i);
+            // Some authors leave blanks before the unit, but that shouldn't
+            // be allowed, so don't simplifyWhitespace on 'unit'.
+            break;
+        }
+        number.append(c);
+    }
+
+    // Convert number to floating point
+    bool ok;
+    float floatValue = number.toString().toFloat(&ok);
+    if (!ok)
+        return false;
+    if (floatValue < 0 && !allowNegative)
+        return false;
+
+    if (unit.isEmpty()) {
+        // no explicit unit, this is a number that will act as a multiplier
+        lengthValue *= floatValue;
+        return true;
+    }
+    if (unit == "%") {
+        lengthValue *= floatValue / 100;
+        return true;
+    }
+    if (unit == "em") {
+        lengthValue = floatValue * style->font().size();
+        return true;
+    }
+    if (unit == "ex") {
+        lengthValue = floatValue * style->fontMetrics().xHeight();
+        return true;
+    }
+    if (unit == "px") {
+        lengthValue = floatValue;
+        return true;
+    }
+    if (unit == "pt") {
+        lengthValue = 4 / 3 * floatValue;
+        return true;
+    }
+    if (unit == "pc") {
+        lengthValue = (4 / 3 * floatValue) * 12;
+        return true;
+    }
+    if (unit == "in") {
+        lengthValue = 96 * floatValue;
+        return true;
+    }
+    if (unit == "cm") {
+        lengthValue = 96 * floatValue / 2.54;
+        return true;
+    }
+    if (unit == "mm") {
+        lengthValue = (96 * floatValue / 2.54) / 10;
+        return true;
+    }
+
+    // unexpected unit
+    return false;
+}
+
+bool parseMathMLNamedSpace(const String& string, float& lengthValue, const RenderStyle* style, bool allowNegative)
+{
+    float length = 0;
+    // See if it is one of the namedspaces (ranging -7/18em, -6/18, ... 7/18em)
+    if (string == "veryverythinmathspace")
+        length = 1;
+    else if (string == "verythinmathspace")
+        length = 2;
+    else if (string == "thinmathspace")
+        length = 3;
+    else if (string == "mediummathspace")
+        length = 4;
+    else if (string == "thickmathspace")
+        length = 5;
+    else if (string == "verythickmathspace")
+        length = 6;
+    else if (string == "veryverythickmathspace")
+        length = 7;
+    else if (allowNegative) {
+        if (string == "negativeveryverythinmathspace")
+            length = -1;
+        else if (string == "negativeverythinmathspace")
+            length = -2;
+        else if (string == "negativethinmathspace")
+            length = -3;
+        else if (string == "negativemediummathspace")
+            length = -4;
+        else if (string == "negativethickmathspace")
+            length = -5;
+        else if (string == "negativeverythickmathspace")
+            length = -6;
+        else if (string == "negativeveryverythickmathspace")
+            length = -7;        
+    }
+    if (length) {
+        lengthValue = length * style->font().size() / 18;
+        return true;
+    }
+    return false;
+}
+
 int RenderMathMLTable::firstLineBoxBaseline() const
 {
     // In legal MathML, we'll have a MathML parent. That RenderFlexibleBox parent will use our firstLineBoxBaseline() for baseline alignment, per

Modified: trunk/Source/WebCore/rendering/mathml/RenderMathMLBlock.h (152139 => 152140)


--- trunk/Source/WebCore/rendering/mathml/RenderMathMLBlock.h	2013-06-28 00:02:12 UTC (rev 152139)
+++ trunk/Source/WebCore/rendering/mathml/RenderMathMLBlock.h	2013-06-28 00:14:57 UTC (rev 152140)
@@ -127,6 +127,9 @@
     virtual const char* renderName() const OVERRIDE { return "RenderMathMLTable"; }
 };
 
+// Parsing functions for MathML Length values
+bool parseMathMLLength(const String&, float&, const RenderStyle*, bool allowNegative = true);
+bool parseMathMLNamedSpace(const String&, float&, const RenderStyle*, bool allowNegative = true);
 }
 
 #endif // ENABLE(MATHML)

Modified: trunk/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp (152139 => 152140)


--- trunk/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp	2013-06-28 00:02:12 UTC (rev 152139)
+++ trunk/Source/WebCore/rendering/mathml/RenderMathMLFraction.cpp	2013-06-28 00:14:57 UTC (rev 152140)
@@ -78,12 +78,11 @@
         m_lineThickness = gLineMedium;
     else if (equalIgnoringCase(thickness, "thick"))
         m_lineThickness = gLineThick;
-    else {
-        bool converted = false;
-        int thicknessIntValue = thickness.toIntStrict(&converted);
-        if (converted)
-            m_lineThickness = thicknessIntValue;
-    }
+    else
+        // This function parses the thickness attribute using gLineMedium as
+        // the default value. If the parsing fails, m_lineThickness will not be
+        // modified i.e. the default value will be used.
+        parseMathMLLength(thickness, m_lineThickness, style(), false);
 
     // Update the style for the padding of the denominator for the line thickness
     lastChild()->style()->setPaddingTop(Length(static_cast<int>(m_lineThickness), Fixed));
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to