Refactor RenderMathMLMenclose.
authorfred.wang@free.fr <fred.wang@free.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 25 Apr 2016 09:46:31 +0000 (09:46 +0000)
committerfred.wang@free.fr <fred.wang@free.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 25 Apr 2016 09:46:31 +0000 (09:46 +0000)
https://bugs.webkit.org/show_bug.cgi?id=155019

Patch by Frederic Wang <fwang@igalia.com> on 2016-04-25
Reviewed by Sergio Villar Senin.

Source/WebCore:

Tests: mathml/presentation/menclose-notation-equivalence.html
       mathml/presentation/menclose-notation-values.html

We rewrite RenderMathMLMenclose so that layout functions correctly override the
behavior of RenderMathMLRow. We try and rely on the draft  of the MathML in HTML5
implementation note, to make easier to get consistency with other rendering engines
in the future. All notations are now drawn with GraphicContext functions instead of
mixing them with CSS style. To save memory space, the list of known notations are
now saved on a short integer using bit masks instead of a vector of string names.
Finally, we remove support for the radical notation so that we no longer need to
create an anonymous RenderMathMLRoot.

* mathml/MathMLMencloseElement.cpp: Remove code for some special notations and just
reimplement parsing of the notation attribute.
(WebCore::MathMLMencloseElement::MathMLMencloseElement): By default, the notation is longdiv.
(WebCore::MathMLMencloseElement::parseAttribute): By default, the list of notation is empty.
If there is no notation attribute, the default value longdiv is used.
Otherwise, we parse the notation attribute and add each notation, using some equivalences
for box, actuarial and madruwb.
(WebCore::MathMLMencloseElement::isPresentationAttribute): Deleted. No need to define
specific style for some notation.
(WebCore::MathMLMencloseElement::finishParsingChildren): Deleted. No need to add an
anonymous square root.
(WebCore::MathMLMencloseElement::collectStyleForPresentationAttribute): Deleted. No need to
define specific style for some notation.
(WebCore::MathMLMencloseElement::longDivLeftPadding): Deleted. RenderMathMLMenclose uses an
arbitrary size instead of measure a glyph.
* mathml/MathMLMencloseElement.h: Define simple bit mask for each notation, add a short
integer to store the list of notations together with helper functions. Remove old code.
* rendering/mathml/RenderMathMLMenclose.cpp: Rewrite RenderMathMLMenclose so that layout
functions correctly override the behavior of RenderMathMLRow.
(WebCore::RenderMathMLMenclose::RenderMathMLMenclose): Init m_ascent to 0.
(WebCore::RenderMathMLMenclose::ruleThickness): For now, we use the fallback value used by
for other bars. We may refine that in the future.
(WebCore::RenderMathMLMenclose::getSpaceAroundContent): Helper function to retrieve the
space to add around the content, depending on the notations specified. Note that for
notation circle, this spacing depends on the content size.
(WebCore::RenderMathMLMenclose::computePreferredLogicalWidths): Reimplement this function.
This is just adding left/right spacing around the content.
(WebCore::RenderMathMLMenclose::layoutBlock): Reimplement this function. We do the normal
RenderMathMLRow layout, adjust spacing and child position and
calculate m_ascent and m_contentRect.
(WebCore::RenderMathMLMenclose::firstLineBaseline): Implement this function.
We just return m_ascent.
(WebCore::drawLine): Helper function to draw a line using strokePath.
(WebCore::RenderMathMLMenclose::paint): We reimplement this function to draw
all notations using GraphicContext.
(WebCore::RenderMathMLMenclose::addChild): Deleted. No need to manage anonymous renderers.
(WebCore::RenderMathMLMenclose::updateLogicalHeight): Deleted. Height is now calculated
in layoutBlock.
(WebCore::RenderMathMLMenclose::checkNotationalValuesValidity): Deleted.
* rendering/mathml/RenderMathMLMenclose.h: Update member definitions.
* rendering/mathml/RenderMathMLRoot.cpp: We no longer need anonymous roots.
(WebCore::RenderMathMLRoot::RenderMathMLRoot): Deleted.
* rendering/mathml/RenderMathMLRoot.h: We no longer need anonymous roots.
* rendering/mathml/RenderMathMLRow.cpp: Allow to get the exact metrics of the chid row,
for use in RenderMathMLRoot.
(WebCore::RenderMathMLRow::computeLineVerticalStretch): rename parameters.
(WebCore::RenderMathMLRow::layoutRowItems): Set parameters to the final ascent, descent and
logical width of the chid row. Set the temporary logical width for RenderMathMenclose before
laying the children out.
(WebCore::RenderMathMLRow::layoutBlock): Rename parameters ; add a dummy logicalWidth
parameter.
* rendering/mathml/RenderMathMLRow.h: Make some functions accessible or overridable by
RenderMathMLRoot. Make layoutRowItems return the final ascent, descent and logical width
after the chid row is laid out.
* rendering/mathml/RenderMathMLSquareRoot.cpp: We no longer need anonymous roots.
(WebCore::RenderMathMLSquareRoot::RenderMathMLSquareRoot): Deleted.
(WebCore::RenderMathMLSquareRoot::createAnonymousWithParentRenderer): Deleted.
* rendering/mathml/RenderMathMLSquareRoot.h: We no longer need anonymous roots.

LayoutTests:

* mathml/presentation/menclose-notation-attribute-set1.html: Removed.
This is replaced with menclose-notation-values.
* mathml/presentation/menclose-notation-attribute-set1-expected.txt: Removed.
This is replaced with menclose-notation-values.
* mathml/presentation/menclose-notation-attribute-set2-expected-mismatch.html: Removed.
This is replaced with menclose-notation-values.
* mathml/presentation/menclose-notation-attribute-set2.html: Removed.
This is replaced with menclose-notation-values.
* mathml/presentation/menclose-notation-values.html: Added.
This test verifies the rendering of various menclose notations.
* mathml/presentation/menclose-notation-equivalence.html: Added.
This test verifies some equivalence for the notation attribute value.
* mathml/presentation/menclose-notation-equivalence-expected.html: Added.
* mathml/presentation/menclose-notation-radical.html: Update the test now that support for
the radical notation is removed.
* mathml/presentation/menclose-notation-radical-expected.html: ditto.
* platform/gtk/mathml/presentation/menclose-notation-default-longdiv-expected.png: Update
reference due to small changes in longdiv implementation.
* platform/gtk/mathml/presentation/menclose-notation-default-longdiv-expected.txt: ditto.
* platform/mac/mathml/presentation/menclose-notation-default-longdiv-expected.png: ditto.
* platform/mac/mathml/presentation/menclose-notation-default-longdiv-expected.txt: ditto.
* platform/ios-simulator/mathml/presentation/menclose-notation-default-longdiv-expected.txt: ditto
* platform/gtk/mathml/presentation/menclose-notation-values-expected.png: Added.
* platform/gtk/mathml/presentation/menclose-notation-values-expected.txt: Added.
* platform/mac/mathml/presentation/menclose-notation-values-expected.png: Added.
* platform/mac/mathml/presentation/menclose-notation-values-expected.txt: Added.
* platform/ios-simulator/mathml/presentation/menclose-notation-values-expected.txt: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@199980 268f45cc-cd09-0410-ab3c-d52691b4dbfc

31 files changed:
LayoutTests/ChangeLog
LayoutTests/mathml/presentation/menclose-notation-attribute-set1-expected.txt [deleted file]
LayoutTests/mathml/presentation/menclose-notation-attribute-set1.html [deleted file]
LayoutTests/mathml/presentation/menclose-notation-attribute-set2-expected-mismatch.html [deleted file]
LayoutTests/mathml/presentation/menclose-notation-attribute-set2.html [deleted file]
LayoutTests/mathml/presentation/menclose-notation-equivalence-expected.html [new file with mode: 0644]
LayoutTests/mathml/presentation/menclose-notation-equivalence.html [new file with mode: 0644]
LayoutTests/mathml/presentation/menclose-notation-radical-expected.html
LayoutTests/mathml/presentation/menclose-notation-radical.html
LayoutTests/mathml/presentation/menclose-notation-values.html [new file with mode: 0644]
LayoutTests/platform/gtk/mathml/presentation/menclose-notation-default-longdiv-expected.png
LayoutTests/platform/gtk/mathml/presentation/menclose-notation-default-longdiv-expected.txt
LayoutTests/platform/gtk/mathml/presentation/menclose-notation-values-expected.png [new file with mode: 0644]
LayoutTests/platform/gtk/mathml/presentation/menclose-notation-values-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-simulator/mathml/presentation/menclose-notation-default-longdiv-expected.txt
LayoutTests/platform/ios-simulator/mathml/presentation/menclose-notation-values-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/mathml/presentation/menclose-notation-default-longdiv-expected.png
LayoutTests/platform/mac/mathml/presentation/menclose-notation-default-longdiv-expected.txt
LayoutTests/platform/mac/mathml/presentation/menclose-notation-values-expected.png [new file with mode: 0755]
LayoutTests/platform/mac/mathml/presentation/menclose-notation-values-expected.txt [new file with mode: 0755]
Source/WebCore/ChangeLog
Source/WebCore/mathml/MathMLMencloseElement.cpp
Source/WebCore/mathml/MathMLMencloseElement.h
Source/WebCore/rendering/mathml/RenderMathMLMenclose.cpp
Source/WebCore/rendering/mathml/RenderMathMLMenclose.h
Source/WebCore/rendering/mathml/RenderMathMLRoot.cpp
Source/WebCore/rendering/mathml/RenderMathMLRoot.h
Source/WebCore/rendering/mathml/RenderMathMLRow.cpp
Source/WebCore/rendering/mathml/RenderMathMLRow.h
Source/WebCore/rendering/mathml/RenderMathMLSquareRoot.cpp
Source/WebCore/rendering/mathml/RenderMathMLSquareRoot.h

index 5f7fc17..a96da72 100644 (file)
@@ -1,3 +1,38 @@
+2016-04-25  Frederic Wang  <fwang@igalia.com>
+
+        Refactor RenderMathMLMenclose.
+        https://bugs.webkit.org/show_bug.cgi?id=155019
+
+        Reviewed by Sergio Villar Senin.
+
+        * mathml/presentation/menclose-notation-attribute-set1.html: Removed.
+        This is replaced with menclose-notation-values.
+        * mathml/presentation/menclose-notation-attribute-set1-expected.txt: Removed.
+        This is replaced with menclose-notation-values.
+        * mathml/presentation/menclose-notation-attribute-set2-expected-mismatch.html: Removed.
+        This is replaced with menclose-notation-values.
+        * mathml/presentation/menclose-notation-attribute-set2.html: Removed.
+        This is replaced with menclose-notation-values.
+        * mathml/presentation/menclose-notation-values.html: Added.
+        This test verifies the rendering of various menclose notations.
+        * mathml/presentation/menclose-notation-equivalence.html: Added.
+        This test verifies some equivalence for the notation attribute value.
+        * mathml/presentation/menclose-notation-equivalence-expected.html: Added.
+        * mathml/presentation/menclose-notation-radical.html: Update the test now that support for
+        the radical notation is removed.
+        * mathml/presentation/menclose-notation-radical-expected.html: ditto.
+        * platform/gtk/mathml/presentation/menclose-notation-default-longdiv-expected.png: Update
+        reference due to small changes in longdiv implementation.
+        * platform/gtk/mathml/presentation/menclose-notation-default-longdiv-expected.txt: ditto.
+        * platform/mac/mathml/presentation/menclose-notation-default-longdiv-expected.png: ditto.
+        * platform/mac/mathml/presentation/menclose-notation-default-longdiv-expected.txt: ditto.
+        * platform/ios-simulator/mathml/presentation/menclose-notation-default-longdiv-expected.txt: ditto
+        * platform/gtk/mathml/presentation/menclose-notation-values-expected.png: Added.
+        * platform/gtk/mathml/presentation/menclose-notation-values-expected.txt: Added.
+        * platform/mac/mathml/presentation/menclose-notation-values-expected.png: Added.
+        * platform/mac/mathml/presentation/menclose-notation-values-expected.txt: Added.
+        * platform/ios-simulator/mathml/presentation/menclose-notation-values-expected.txt: Added.
+
 2016-04-24  Gyuyoung Kim  <gyuyoung.kim@webkit.org>
 
         [EFL] Some media tests have been failed after bumping gstreamer ver.
diff --git a/LayoutTests/mathml/presentation/menclose-notation-attribute-set1-expected.txt b/LayoutTests/mathml/presentation/menclose-notation-attribute-set1-expected.txt
deleted file mode 100644 (file)
index cbc12ea..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-Tests that left, right, top, bottom, box, roundedbox, madruwb, actuarial attribute value is applied for menclose
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS window.getComputedStyle(document.getElementById('mathmenclose1'),null).getPropertyValue('border-left-style') is "solid"
-PASS window.getComputedStyle(document.getElementById('mathmenclose1'),null).getPropertyValue('border-left-width') is "1px"
-PASS window.getComputedStyle(document.getElementById('mathmenclose1'),null).getPropertyValue('border-right-style') is "none"
-PASS window.getComputedStyle(document.getElementById('mathmenclose1'),null).getPropertyValue('border-right-width') is "0px"
-PASS window.getComputedStyle(document.getElementById('mathmenclose2'),null).getPropertyValue('border-right-style') is "solid"
-PASS window.getComputedStyle(document.getElementById('mathmenclose2'),null).getPropertyValue('border-right-width') is "1px"
-PASS window.getComputedStyle(document.getElementById('mathmenclose2'),null).getPropertyValue('border-left-style') is "none"
-PASS window.getComputedStyle(document.getElementById('mathmenclose2'),null).getPropertyValue('border-left-width') is "0px"
-PASS window.getComputedStyle(document.getElementById('mathmenclose3'),null).getPropertyValue('border-top-style') is "solid"
-PASS window.getComputedStyle(document.getElementById('mathmenclose3'),null).getPropertyValue('border-top-width') is "1px"
-PASS window.getComputedStyle(document.getElementById('mathmenclose3'),null).getPropertyValue('border-bottom-style') is "none"
-PASS window.getComputedStyle(document.getElementById('mathmenclose3'),null).getPropertyValue('border-bottom-width') is "0px"
-PASS window.getComputedStyle(document.getElementById('mathmenclose4'),null).getPropertyValue('border-bottom-style') is "solid"
-PASS window.getComputedStyle(document.getElementById('mathmenclose4'),null).getPropertyValue('border-bottom-width') is "1px"
-PASS window.getComputedStyle(document.getElementById('mathmenclose4'),null).getPropertyValue('border-top-style') is "none"
-PASS window.getComputedStyle(document.getElementById('mathmenclose4'),null).getPropertyValue('border-top-width') is "0px"
-PASS window.getComputedStyle(document.getElementById('mathmenclose5'),null).getPropertyValue('border') is "1px solid rgb(0, 0, 0)"
-PASS window.getComputedStyle(document.getElementById('mathmenclose6'),null).getPropertyValue('border') is "1px solid rgb(0, 0, 0)"
-PASS window.getComputedStyle(document.getElementById('mathmenclose6'),null).getPropertyValue('border-radius') is "5px"
-PASS window.getComputedStyle(document.getElementById('mathmenclose7'),null).getPropertyValue('border-right-style') is "solid"
-PASS window.getComputedStyle(document.getElementById('mathmenclose7'),null).getPropertyValue('border-right-width') is "1px"
-PASS window.getComputedStyle(document.getElementById('mathmenclose7'),null).getPropertyValue('border-bottom-style') is "solid"
-PASS window.getComputedStyle(document.getElementById('mathmenclose7'),null).getPropertyValue('border-bottom-width') is "1px"
-PASS window.getComputedStyle(document.getElementById('mathmenclose7'),null).getPropertyValue('border-top-style') is "none"
-PASS window.getComputedStyle(document.getElementById('mathmenclose7'),null).getPropertyValue('border-top-width') is "0px"
-PASS window.getComputedStyle(document.getElementById('mathmenclose8'),null).getPropertyValue('border-right-style') is "solid"
-PASS window.getComputedStyle(document.getElementById('mathmenclose8'),null).getPropertyValue('border-right-width') is "1px"
-PASS window.getComputedStyle(document.getElementById('mathmenclose8'),null).getPropertyValue('border-top-style') is "solid"
-PASS window.getComputedStyle(document.getElementById('mathmenclose8'),null).getPropertyValue('border-top-width') is "1px"
-PASS window.getComputedStyle(document.getElementById('mathmenclose8'),null).getPropertyValue('border-bottom-style') is "none"
-PASS window.getComputedStyle(document.getElementById('mathmenclose8'),null).getPropertyValue('border-bottom-width') is "0px"
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
-
-
-
-
-
-
-
diff --git a/LayoutTests/mathml/presentation/menclose-notation-attribute-set1.html b/LayoutTests/mathml/presentation/menclose-notation-attribute-set1.html
deleted file mode 100644 (file)
index bf834a9..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <script src="../../resources/js-test-pre.js"></script>
-        <script>
-            function runTest() {
-                description('Tests that left, right, top, bottom, box, roundedbox, madruwb, actuarial attribute value is applied for menclose');
-
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose1'),null).getPropertyValue('border-left-style')","solid");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose1'),null).getPropertyValue('border-left-width')","1px");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose1'),null).getPropertyValue('border-right-style')","none");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose1'),null).getPropertyValue('border-right-width')","0px");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose2'),null).getPropertyValue('border-right-style')","solid");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose2'),null).getPropertyValue('border-right-width')","1px");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose2'),null).getPropertyValue('border-left-style')","none");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose2'),null).getPropertyValue('border-left-width')","0px");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose3'),null).getPropertyValue('border-top-style')","solid");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose3'),null).getPropertyValue('border-top-width')","1px");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose3'),null).getPropertyValue('border-bottom-style')","none");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose3'),null).getPropertyValue('border-bottom-width')","0px");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose4'),null).getPropertyValue('border-bottom-style')","solid");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose4'),null).getPropertyValue('border-bottom-width')","1px");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose4'),null).getPropertyValue('border-top-style')","none");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose4'),null).getPropertyValue('border-top-width')","0px");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose5'),null).getPropertyValue('border')","1px solid rgb(0, 0, 0)");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose6'),null).getPropertyValue('border')","1px solid rgb(0, 0, 0)");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose6'),null).getPropertyValue('border-radius')","5px");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose7'),null).getPropertyValue('border-right-style')","solid");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose7'),null).getPropertyValue('border-right-width')","1px");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose7'),null).getPropertyValue('border-bottom-style')","solid");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose7'),null).getPropertyValue('border-bottom-width')","1px");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose7'),null).getPropertyValue('border-top-style')","none");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose7'),null).getPropertyValue('border-top-width')","0px");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose8'),null).getPropertyValue('border-right-style')","solid");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose8'),null).getPropertyValue('border-right-width')","1px");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose8'),null).getPropertyValue('border-top-style')","solid");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose8'),null).getPropertyValue('border-top-width')","1px");
-                               shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose8'),null).getPropertyValue('border-bottom-style')","none");
-                shouldBeEqualToString("window.getComputedStyle(document.getElementById('mathmenclose8'),null).getPropertyValue('border-bottom-width')","0px");              
-                isSuccessfullyParsed();                                
-            }
-        </script>
-    </head>
-    <body onload="runTest()">
-        <p>
-            <math>
-                <menclose notation="left" id="mathmenclose1"><mspace width="100px" height="50px" mathbackground="red"/></menclose>
-            </math>
-        </p>
-        <p>
-            <math>
-                <menclose notation="right" id="mathmenclose2"><mspace width="100px" height="50px" mathbackground="red"/></menclose>
-            </math>
-        </p>
-        <p>
-            <math>
-                <menclose notation="top" id="mathmenclose3"><mspace width="100px" height="50px" mathbackground="red"/></menclose>
-            </math>
-        </p>
-        <p>
-            <math>
-                <menclose notation="bottom" id="mathmenclose4"><mspace width="100px" height="50px" mathbackground="red"/></menclose>
-            </math>
-        </p>
-        <p>
-            <math>
-                <menclose notation="box" id="mathmenclose5"><mspace width="100px" height="50px" mathbackground="red"/></menclose>
-            </math>
-        </p>
-        <p>
-            <math>
-                <menclose notation="roundedbox" id="mathmenclose6"><mspace width="100px" height="50px" mathbackground="red"/></menclose>
-            </math>
-        </p>
-        <p>
-            <math>
-                <menclose notation="madruwb" id="mathmenclose7"><mspace width="100px" height="50px" mathbackground="red"/></menclose>
-            </math>
-        </p>
-        <p>
-            <math>
-                <menclose notation="actuarial" id="mathmenclose8"><mspace width="100px" height="50px" mathbackground="red"/></menclose>
-            </math>
-        </p>
-    </body>
-</html>
\ No newline at end of file
diff --git a/LayoutTests/mathml/presentation/menclose-notation-attribute-set2-expected-mismatch.html b/LayoutTests/mathml/presentation/menclose-notation-attribute-set2-expected-mismatch.html
deleted file mode 100644 (file)
index e17a6b3..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <body>
-        <p>
-            <math>
-                <mrow><mspace width="100px" height="50px" mathbackground="red"/></mrow>
-            </math>
-        <p>        
-    </body>
-</html>
\ No newline at end of file
diff --git a/LayoutTests/mathml/presentation/menclose-notation-attribute-set2.html b/LayoutTests/mathml/presentation/menclose-notation-attribute-set2.html
deleted file mode 100644 (file)
index 82257d2..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <title>menclose notation downdiagonalstrike test</title>
-    </head>
-    <body>
-        <p>
-            <math>
-                <menclose notation="downdiagonalstrike"><mspace width="100px" height="50px" mathbackground="red"/></menclose>
-            </math>
-        </p>           
-    </body>
-</html>
\ No newline at end of file
diff --git a/LayoutTests/mathml/presentation/menclose-notation-equivalence-expected.html b/LayoutTests/mathml/presentation/menclose-notation-equivalence-expected.html
new file mode 100644 (file)
index 0000000..601948b
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>menclose equivalence of notation values</title>
+  </head>
+  <body>
+    <!-- Order does not matter -->
+    <math><mrow><menclose notation="horizontalstrike circle top "><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+
+    <!-- Duplicate does not matter -->
+    <math><mrow><menclose notation="top longdiv circle actuarial left"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+
+    <!-- Invalid values are ignored -->
+    <math><mrow><menclose notation="circle box"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+
+    <!-- box is like left right top bottom -->
+    <math><mrow><menclose notation="left right top bottom"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+
+    <!-- actuarial is like right top -->
+    <math><mrow><menclose notation="right top"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+
+    <!-- madruwb is like right bottom -->
+    <math><mrow><menclose notation="right bottom"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+
+    <!-- menclose notations are independent of overall directionality -->
+    <math><mrow><menclose notation="left updiagonalstrike"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+
+  </body>
+</html>
diff --git a/LayoutTests/mathml/presentation/menclose-notation-equivalence.html b/LayoutTests/mathml/presentation/menclose-notation-equivalence.html
new file mode 100644 (file)
index 0000000..dca8ab9
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>menclose equivalence of notation values</title>
+  </head>
+  <body>
+    <!-- Order does not matter -->
+    <math><mrow><menclose notation="top circle horizontalstrike"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+
+    <!-- Duplicate does not matter -->
+    <math><mrow><menclose notation="top longdiv circle actuarial top circle left longdiv circle top left"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+
+    <!-- Invalid values are ignored -->
+    <math><mrow><menclose notation="circle triangle box"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+
+    <!-- box is like left right top bottom -->
+    <math><mrow><menclose notation="box"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+
+    <!-- actuarial is like right top -->
+    <math><mrow><menclose notation="actuarial"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+
+    <!-- madruwb is like right bottom -->
+    <math><mrow><menclose notation="madruwb"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+
+    <!-- menclose notations are independent of overall directionality -->
+    <math dir="rtl"><mrow><menclose notation="left updiagonalstrike"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+
+  </body>
+</html>
index 19c2cca..edb7f54 100644 (file)
@@ -5,7 +5,7 @@
     </head>
     <body>
         <p>
-            <math><mrow><msqrt><mspace width="100px" height="50px" mathbackground="red"/></msqrt></mrow></math>
+            <math><mrow><mrow><mspace width="100px" height="50px" mathbackground="red"/></mrow></mrow></math>
         </p>
     </body>
-</html>
\ No newline at end of file
+</html>
index 2b00a09..cceaf3d 100644 (file)
@@ -4,8 +4,9 @@
         <title>menclose notation radical test</title>
     </head>
     <body>
+        <!-- We removed support for the radical notation, so this menclose element should render the same as an mrow element. -->
         <p>
             <math><mrow><menclose notation="radical"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
         </p>
     </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/LayoutTests/mathml/presentation/menclose-notation-values.html b/LayoutTests/mathml/presentation/menclose-notation-values.html
new file mode 100644 (file)
index 0000000..acfbdfa
--- /dev/null
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>menclose notations</title>
+    </head>
+    <body>
+      <!-- Test each individual notation -->
+      <math><mrow><menclose notation="longdiv"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+      <math><mrow><menclose notation="actuarial"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+      <math><mrow><menclose notation="box"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+      <math><mrow><menclose notation="roundedbox"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+      <math><mrow><menclose notation="circle"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+      <math><mrow><menclose notation="left"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+      <math><mrow><menclose notation="right"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+      <math><mrow><menclose notation="top"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+      <math><mrow><menclose notation="bottom"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+      <math><mrow><menclose notation="updiagonalstrike"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+      <math><mrow><menclose notation="downdiagonalstrike"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+      <math><mrow><menclose notation="verticalstrike"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+      <math><mrow><menclose notation="horizontalstrike"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+      <math><mrow><menclose notation="madruwb"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+
+      <!-- Test combinations of several notations -->
+      <math><mrow><menclose notation="longdiv circle updiagonalstrike"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+      <math><mrow><menclose notation="roundedbox updiagonalstrike horizontalstrike"><mspace width="100px" height="50px" mathbackground="red"/></menclose></mrow></math>
+    </body>
+</html>
index 8d3aaf8..0009243 100644 (file)
Binary files a/LayoutTests/platform/gtk/mathml/presentation/menclose-notation-default-longdiv-expected.png and b/LayoutTests/platform/gtk/mathml/presentation/menclose-notation-default-longdiv-expected.png differ
index f1bedbd..3d0126a 100644 (file)
@@ -1,11 +1,11 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
-layer at (0,0) size 800x91
-  RenderBlock {HTML} at (0,0) size 800x91
-    RenderBody {BODY} at (8,16) size 784x59
-      RenderBlock {P} at (0,0) size 784x59
-        RenderMathMLMath {math} at (0,0) size 102x56 [padding: 0 1 0 1]
-          RenderMathMLRow {mrow} at (1,0) size 100x56
-            RenderMathMLMenclose {menclose} at (0,0) size 100x56 [padding: 6 0 0 6]
-              RenderMathMLSpace {mspace} at (6,6) size 100x50 [bgcolor=#FF0000]
+layer at (0,0) size 800x89
+  RenderBlock {HTML} at (0,0) size 800x89
+    RenderBody {BODY} at (8,16) size 784x57
+      RenderBlock {P} at (0,0) size 784x57
+        RenderMathMLMath {math} at (0,0) size 114x58 [padding: 0 1 0 1]
+          RenderMathMLRow {mrow} at (1,0) size 112x58
+            RenderMathMLMenclose {menclose} at (0,0) size 112x58
+              RenderMathMLSpace {mspace} at (7,3) size 101x51 [bgcolor=#FF0000]
         RenderText {#text} at (0,0) size 0x0
diff --git a/LayoutTests/platform/gtk/mathml/presentation/menclose-notation-values-expected.png b/LayoutTests/platform/gtk/mathml/presentation/menclose-notation-values-expected.png
new file mode 100644 (file)
index 0000000..b55d6aa
Binary files /dev/null and b/LayoutTests/platform/gtk/mathml/presentation/menclose-notation-values-expected.png differ
diff --git a/LayoutTests/platform/gtk/mathml/presentation/menclose-notation-values-expected.txt b/LayoutTests/platform/gtk/mathml/presentation/menclose-notation-values-expected.txt
new file mode 100644 (file)
index 0000000..559a17f
--- /dev/null
@@ -0,0 +1,99 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x219
+  RenderBlock {HTML} at (0,0) size 800x219
+    RenderBody {BODY} at (8,8) size 784x203
+      RenderMathMLMath {math} at (0,8) size 114x58 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 112x58
+          RenderMathMLMenclose {menclose} at (0,0) size 112x58
+            RenderMathMLSpace {mspace} at (7,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (113,48) size 5x17
+        text run at (113,48) width 5: " "
+      RenderMathMLMath {math} at (117,8) size 110x58 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 108x58
+          RenderMathMLMenclose {menclose} at (0,0) size 108x58
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (226,48) size 5x17
+        text run at (226,48) width 5: " "
+      RenderMathMLMath {math} at (230,8) size 111x58 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 108x58
+          RenderMathMLMenclose {menclose} at (0,0) size 108x58
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (340,48) size 5x17
+        text run at (340,48) width 5: " "
+      RenderMathMLMath {math} at (344,8) size 111x58 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 108x58
+          RenderMathMLMenclose {menclose} at (0,0) size 108x58
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (454,48) size 5x17
+        text run at (454,48) width 5: " "
+      RenderMathMLMath {math} at (458,0) size 147x74 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 144x74
+          RenderMathMLMenclose {menclose} at (0,0) size 144x74
+            RenderMathMLSpace {mspace} at (21,11) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (604,48) size 5x17
+        text run at (604,48) width 5: " "
+      RenderMathMLMath {math} at (608,9) size 107x57 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 104x57
+          RenderMathMLMenclose {menclose} at (0,0) size 104x57
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (0,0) size 0x0
+      RenderMathMLMath {math} at (0,74) size 106x57 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 104x57
+          RenderMathMLMenclose {menclose} at (0,0) size 104x57
+            RenderMathMLSpace {mspace} at (0,3) size 100x51 [bgcolor=#FF0000]
+      RenderText {#text} at (105,113) size 5x17
+        text run at (105,113) width 5: " "
+      RenderMathMLMath {math} at (109,73) size 110x54 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 107x54
+          RenderMathMLMenclose {menclose} at (0,0) size 107x54
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (218,113) size 5x17
+        text run at (218,113) width 5: " "
+      RenderMathMLMath {math} at (222,77) size 109x54 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 107x54
+          RenderMathMLMenclose {menclose} at (0,0) size 107x54
+            RenderMathMLSpace {mspace} at (3,0) size 101x50 [bgcolor=#FF0000]
+      RenderText {#text} at (330,113) size 5x17
+        text run at (330,113) width 5: " "
+      RenderMathMLMath {math} at (334,77) size 104x51 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 101x51
+          RenderMathMLMenclose {menclose} at (0,0) size 101x51
+            RenderMathMLSpace {mspace} at (0,0) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (437,113) size 5x17
+        text run at (437,113) width 5: " "
+      RenderMathMLMath {math} at (441,77) size 104x51 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 101x51
+          RenderMathMLMenclose {menclose} at (0,0) size 101x51
+            RenderMathMLSpace {mspace} at (0,0) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (544,113) size 5x17
+        text run at (544,113) width 5: " "
+      RenderMathMLMath {math} at (548,77) size 103x50 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 100x50
+          RenderMathMLMenclose {menclose} at (0,0) size 100x50
+            RenderMathMLSpace {mspace} at (0,0) size 100x50 [bgcolor=#FF0000]
+      RenderText {#text} at (650,113) size 5x17
+        text run at (650,113) width 5: " "
+      RenderMathMLMath {math} at (654,77) size 103x50 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 100x50
+          RenderMathMLMenclose {menclose} at (0,0) size 100x50
+            RenderMathMLSpace {mspace} at (0,0) size 100x50 [bgcolor=#FF0000]
+      RenderText {#text} at (0,0) size 0x0
+      RenderMathMLMath {math} at (0,139) size 110x58 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 108x58
+          RenderMathMLMenclose {menclose} at (0,0) size 108x58
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (109,178) size 5x17
+        text run at (109,178) width 5: " "
+      RenderText {#text} at (0,0) size 0x0
+      RenderMathMLMath {math} at (113,130) size 146x74 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 144x74
+          RenderMathMLMenclose {menclose} at (0,0) size 144x74
+            RenderMathMLSpace {mspace} at (21,11) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (258,178) size 5x17
+        text run at (258,178) width 5: " "
+      RenderMathMLMath {math} at (262,138) size 111x58 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 108x58
+          RenderMathMLMenclose {menclose} at (0,0) size 108x58
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (0,0) size 0x0
index b9f2679..3591f02 100644 (file)
@@ -1,11 +1,11 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
-layer at (0,0) size 800x93
-  RenderBlock {HTML} at (0,0) size 800x93
-    RenderBody {BODY} at (8,16) size 784x61
-      RenderBlock {P} at (0,0) size 784x61
-        RenderMathMLMath {math} at (0,0) size 102x56 [padding: 0 1 0 1]
-          RenderMathMLRow {mrow} at (1,0) size 100x56
-            RenderMathMLMenclose {menclose} at (0,0) size 100x56 [padding: 6 0 0 5]
-              RenderMathMLSpace {mspace} at (5,6) size 100x50 [bgcolor=#FF0000]
+layer at (0,0) size 800x91
+  RenderBlock {HTML} at (0,0) size 800x91
+    RenderBody {BODY} at (8,16) size 784x59
+      RenderBlock {P} at (0,0) size 784x59
+        RenderMathMLMath {math} at (0,0) size 114x58 [padding: 0 1 0 1]
+          RenderMathMLRow {mrow} at (1,0) size 112x58
+            RenderMathMLMenclose {menclose} at (0,0) size 112x58
+              RenderMathMLSpace {mspace} at (7,3) size 101x51 [bgcolor=#FF0000]
         RenderText {#text} at (0,0) size 0x0
diff --git a/LayoutTests/platform/ios-simulator/mathml/presentation/menclose-notation-values-expected.txt b/LayoutTests/platform/ios-simulator/mathml/presentation/menclose-notation-values-expected.txt
new file mode 100644 (file)
index 0000000..76afe60
--- /dev/null
@@ -0,0 +1,99 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x221
+  RenderBlock {HTML} at (0,0) size 800x221
+    RenderBody {BODY} at (8,8) size 784x205
+      RenderMathMLMath {math} at (0,8) size 114x58 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 112x58
+          RenderMathMLMenclose {menclose} at (0,0) size 112x58
+            RenderMathMLSpace {mspace} at (7,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (113,47) size 5x19
+        text run at (113,47) width 5: " "
+      RenderMathMLMath {math} at (117,8) size 110x58 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 108x58
+          RenderMathMLMenclose {menclose} at (0,0) size 108x58
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (226,47) size 5x19
+        text run at (226,47) width 5: " "
+      RenderMathMLMath {math} at (230,8) size 111x58 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 108x58
+          RenderMathMLMenclose {menclose} at (0,0) size 108x58
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (340,47) size 5x19
+        text run at (340,47) width 5: " "
+      RenderMathMLMath {math} at (344,8) size 111x58 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 108x58
+          RenderMathMLMenclose {menclose} at (0,0) size 108x58
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (454,47) size 5x19
+        text run at (454,47) width 5: " "
+      RenderMathMLMath {math} at (458,0) size 147x74 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 144x74
+          RenderMathMLMenclose {menclose} at (0,0) size 144x74
+            RenderMathMLSpace {mspace} at (21,11) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (604,47) size 5x19
+        text run at (604,47) width 5: " "
+      RenderMathMLMath {math} at (608,9) size 107x57 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 104x57
+          RenderMathMLMenclose {menclose} at (0,0) size 104x57
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (0,0) size 0x0
+      RenderMathMLMath {math} at (0,74) size 106x57 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 104x57
+          RenderMathMLMenclose {menclose} at (0,0) size 104x57
+            RenderMathMLSpace {mspace} at (0,3) size 100x51 [bgcolor=#FF0000]
+      RenderText {#text} at (105,112) size 5x19
+        text run at (105,112) width 5: " "
+      RenderMathMLMath {math} at (109,73) size 110x54 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 107x54
+          RenderMathMLMenclose {menclose} at (0,0) size 107x54
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (218,112) size 5x19
+        text run at (218,112) width 5: " "
+      RenderMathMLMath {math} at (222,77) size 109x54 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 107x54
+          RenderMathMLMenclose {menclose} at (0,0) size 107x54
+            RenderMathMLSpace {mspace} at (3,0) size 101x50 [bgcolor=#FF0000]
+      RenderText {#text} at (330,112) size 5x19
+        text run at (330,112) width 5: " "
+      RenderMathMLMath {math} at (334,77) size 104x51 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 101x51
+          RenderMathMLMenclose {menclose} at (0,0) size 101x51
+            RenderMathMLSpace {mspace} at (0,0) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (437,112) size 5x19
+        text run at (437,112) width 5: " "
+      RenderMathMLMath {math} at (441,77) size 104x51 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 101x51
+          RenderMathMLMenclose {menclose} at (0,0) size 101x51
+            RenderMathMLSpace {mspace} at (0,0) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (544,112) size 5x19
+        text run at (544,112) width 5: " "
+      RenderMathMLMath {math} at (548,77) size 103x50 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 100x50
+          RenderMathMLMenclose {menclose} at (0,0) size 100x50
+            RenderMathMLSpace {mspace} at (0,0) size 100x50 [bgcolor=#FF0000]
+      RenderText {#text} at (650,112) size 5x19
+        text run at (650,112) width 5: " "
+      RenderMathMLMath {math} at (654,77) size 103x50 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 100x50
+          RenderMathMLMenclose {menclose} at (0,0) size 100x50
+            RenderMathMLSpace {mspace} at (0,0) size 100x50 [bgcolor=#FF0000]
+      RenderText {#text} at (0,0) size 0x0
+      RenderMathMLMath {math} at (0,141) size 110x58 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 108x58
+          RenderMathMLMenclose {menclose} at (0,0) size 108x58
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (109,179) size 5x19
+        text run at (109,179) width 5: " "
+      RenderText {#text} at (0,0) size 0x0
+      RenderMathMLMath {math} at (113,132) size 146x74 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 144x74
+          RenderMathMLMenclose {menclose} at (0,0) size 144x74
+            RenderMathMLSpace {mspace} at (21,11) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (258,179) size 5x19
+        text run at (258,179) width 5: " "
+      RenderMathMLMath {math} at (262,140) size 111x58 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 108x58
+          RenderMathMLMenclose {menclose} at (0,0) size 108x58
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (0,0) size 0x0
index c2b9fd0..24aa4a1 100644 (file)
Binary files a/LayoutTests/platform/mac/mathml/presentation/menclose-notation-default-longdiv-expected.png and b/LayoutTests/platform/mac/mathml/presentation/menclose-notation-default-longdiv-expected.png differ
index 0fdfc4b..f05e30f 100644 (file)
@@ -1,11 +1,11 @@
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
-layer at (0,0) size 800x92
-  RenderBlock {HTML} at (0,0) size 800x92
-    RenderBody {BODY} at (8,16) size 784x60
-      RenderBlock {P} at (0,0) size 784x60
-        RenderMathMLMath {math} at (0,0) size 102x56 [padding: 0 1 0 1]
-          RenderMathMLRow {mrow} at (1,0) size 100x56
-            RenderMathMLMenclose {menclose} at (0,0) size 100x56 [padding: 6 0 0 5]
-              RenderMathMLSpace {mspace} at (5,6) size 100x50 [bgcolor=#FF0000]
+layer at (0,0) size 800x90
+  RenderBlock {HTML} at (0,0) size 800x90
+    RenderBody {BODY} at (8,16) size 784x58
+      RenderBlock {P} at (0,0) size 784x58
+        RenderMathMLMath {math} at (0,0) size 114x58 [padding: 0 1 0 1]
+          RenderMathMLRow {mrow} at (1,0) size 112x58
+            RenderMathMLMenclose {menclose} at (0,0) size 112x58
+              RenderMathMLSpace {mspace} at (7,3) size 101x51 [bgcolor=#FF0000]
         RenderText {#text} at (0,0) size 0x0
diff --git a/LayoutTests/platform/mac/mathml/presentation/menclose-notation-values-expected.png b/LayoutTests/platform/mac/mathml/presentation/menclose-notation-values-expected.png
new file mode 100755 (executable)
index 0000000..e63bf93
Binary files /dev/null and b/LayoutTests/platform/mac/mathml/presentation/menclose-notation-values-expected.png differ
diff --git a/LayoutTests/platform/mac/mathml/presentation/menclose-notation-values-expected.txt b/LayoutTests/platform/mac/mathml/presentation/menclose-notation-values-expected.txt
new file mode 100755 (executable)
index 0000000..5f044b2
--- /dev/null
@@ -0,0 +1,99 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x220
+  RenderBlock {HTML} at (0,0) size 800x220
+    RenderBody {BODY} at (8,8) size 784x204
+      RenderMathMLMath {math} at (0,8) size 114x58 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 112x58
+          RenderMathMLMenclose {menclose} at (0,0) size 112x58
+            RenderMathMLSpace {mspace} at (7,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (113,48) size 5x18
+        text run at (113,48) width 5: " "
+      RenderMathMLMath {math} at (117,8) size 110x58 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 108x58
+          RenderMathMLMenclose {menclose} at (0,0) size 108x58
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (226,48) size 5x18
+        text run at (226,48) width 5: " "
+      RenderMathMLMath {math} at (230,8) size 111x58 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 108x58
+          RenderMathMLMenclose {menclose} at (0,0) size 108x58
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (340,48) size 5x18
+        text run at (340,48) width 5: " "
+      RenderMathMLMath {math} at (344,8) size 111x58 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 108x58
+          RenderMathMLMenclose {menclose} at (0,0) size 108x58
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (454,48) size 5x18
+        text run at (454,48) width 5: " "
+      RenderMathMLMath {math} at (458,0) size 147x74 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 144x74
+          RenderMathMLMenclose {menclose} at (0,0) size 144x74
+            RenderMathMLSpace {mspace} at (21,11) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (604,48) size 5x18
+        text run at (604,48) width 5: " "
+      RenderMathMLMath {math} at (608,9) size 107x57 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 104x57
+          RenderMathMLMenclose {menclose} at (0,0) size 104x57
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (0,0) size 0x0
+      RenderMathMLMath {math} at (0,74) size 106x57 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 104x57
+          RenderMathMLMenclose {menclose} at (0,0) size 104x57
+            RenderMathMLSpace {mspace} at (0,3) size 100x51 [bgcolor=#FF0000]
+      RenderText {#text} at (105,113) size 5x18
+        text run at (105,113) width 5: " "
+      RenderMathMLMath {math} at (109,73) size 110x54 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 107x54
+          RenderMathMLMenclose {menclose} at (0,0) size 107x54
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (218,113) size 5x18
+        text run at (218,113) width 5: " "
+      RenderMathMLMath {math} at (222,77) size 109x54 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 107x54
+          RenderMathMLMenclose {menclose} at (0,0) size 107x54
+            RenderMathMLSpace {mspace} at (3,0) size 101x50 [bgcolor=#FF0000]
+      RenderText {#text} at (330,113) size 5x18
+        text run at (330,113) width 5: " "
+      RenderMathMLMath {math} at (334,77) size 104x51 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 101x51
+          RenderMathMLMenclose {menclose} at (0,0) size 101x51
+            RenderMathMLSpace {mspace} at (0,0) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (437,113) size 5x18
+        text run at (437,113) width 5: " "
+      RenderMathMLMath {math} at (441,77) size 104x51 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 101x51
+          RenderMathMLMenclose {menclose} at (0,0) size 101x51
+            RenderMathMLSpace {mspace} at (0,0) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (544,113) size 5x18
+        text run at (544,113) width 5: " "
+      RenderMathMLMath {math} at (548,77) size 103x50 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 100x50
+          RenderMathMLMenclose {menclose} at (0,0) size 100x50
+            RenderMathMLSpace {mspace} at (0,0) size 100x50 [bgcolor=#FF0000]
+      RenderText {#text} at (650,113) size 5x18
+        text run at (650,113) width 5: " "
+      RenderMathMLMath {math} at (654,77) size 103x50 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 100x50
+          RenderMathMLMenclose {menclose} at (0,0) size 100x50
+            RenderMathMLSpace {mspace} at (0,0) size 100x50 [bgcolor=#FF0000]
+      RenderText {#text} at (0,0) size 0x0
+      RenderMathMLMath {math} at (0,140) size 110x58 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 108x58
+          RenderMathMLMenclose {menclose} at (0,0) size 108x58
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (109,179) size 5x18
+        text run at (109,179) width 5: " "
+      RenderText {#text} at (0,0) size 0x0
+      RenderMathMLMath {math} at (113,131) size 146x74 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 144x74
+          RenderMathMLMenclose {menclose} at (0,0) size 144x74
+            RenderMathMLSpace {mspace} at (21,11) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (258,179) size 5x18
+        text run at (258,179) width 5: " "
+      RenderMathMLMath {math} at (262,139) size 111x58 [padding: 0 1 0 1]
+        RenderMathMLRow {mrow} at (1,0) size 108x58
+          RenderMathMLMenclose {menclose} at (0,0) size 108x58
+            RenderMathMLSpace {mspace} at (3,3) size 101x51 [bgcolor=#FF0000]
+      RenderText {#text} at (0,0) size 0x0
index 24d77cf..e087137 100644 (file)
@@ -1,5 +1,83 @@
 2016-04-25  Frederic Wang  <fwang@igalia.com>
 
+        Refactor RenderMathMLMenclose.
+        https://bugs.webkit.org/show_bug.cgi?id=155019
+
+        Reviewed by Sergio Villar Senin.
+
+        Tests: mathml/presentation/menclose-notation-equivalence.html
+               mathml/presentation/menclose-notation-values.html
+
+        We rewrite RenderMathMLMenclose so that layout functions correctly override the
+        behavior of RenderMathMLRow. We try and rely on the draft  of the MathML in HTML5
+        implementation note, to make easier to get consistency with other rendering engines
+        in the future. All notations are now drawn with GraphicContext functions instead of
+        mixing them with CSS style. To save memory space, the list of known notations are
+        now saved on a short integer using bit masks instead of a vector of string names.
+        Finally, we remove support for the radical notation so that we no longer need to
+        create an anonymous RenderMathMLRoot.
+
+        * mathml/MathMLMencloseElement.cpp: Remove code for some special notations and just
+        reimplement parsing of the notation attribute.
+        (WebCore::MathMLMencloseElement::MathMLMencloseElement): By default, the notation is longdiv.
+        (WebCore::MathMLMencloseElement::parseAttribute): By default, the list of notation is empty.
+        If there is no notation attribute, the default value longdiv is used.
+        Otherwise, we parse the notation attribute and add each notation, using some equivalences
+        for box, actuarial and madruwb.
+        (WebCore::MathMLMencloseElement::isPresentationAttribute): Deleted. No need to define
+        specific style for some notation.
+        (WebCore::MathMLMencloseElement::finishParsingChildren): Deleted. No need to add an
+        anonymous square root.
+        (WebCore::MathMLMencloseElement::collectStyleForPresentationAttribute): Deleted. No need to
+        define specific style for some notation.
+        (WebCore::MathMLMencloseElement::longDivLeftPadding): Deleted. RenderMathMLMenclose uses an
+        arbitrary size instead of measure a glyph.
+        * mathml/MathMLMencloseElement.h: Define simple bit mask for each notation, add a short
+        integer to store the list of notations together with helper functions. Remove old code.
+        * rendering/mathml/RenderMathMLMenclose.cpp: Rewrite RenderMathMLMenclose so that layout
+        functions correctly override the behavior of RenderMathMLRow.
+        (WebCore::RenderMathMLMenclose::RenderMathMLMenclose): Init m_ascent to 0.
+        (WebCore::RenderMathMLMenclose::ruleThickness): For now, we use the fallback value used by
+        for other bars. We may refine that in the future.
+        (WebCore::RenderMathMLMenclose::getSpaceAroundContent): Helper function to retrieve the
+        space to add around the content, depending on the notations specified. Note that for
+        notation circle, this spacing depends on the content size.
+        (WebCore::RenderMathMLMenclose::computePreferredLogicalWidths): Reimplement this function.
+        This is just adding left/right spacing around the content.
+        (WebCore::RenderMathMLMenclose::layoutBlock): Reimplement this function. We do the normal
+        RenderMathMLRow layout, adjust spacing and child position and
+        calculate m_ascent and m_contentRect.
+        (WebCore::RenderMathMLMenclose::firstLineBaseline): Implement this function.
+        We just return m_ascent.
+        (WebCore::drawLine): Helper function to draw a line using strokePath.
+        (WebCore::RenderMathMLMenclose::paint): We reimplement this function to draw
+        all notations using GraphicContext.
+        (WebCore::RenderMathMLMenclose::addChild): Deleted. No need to manage anonymous renderers.
+        (WebCore::RenderMathMLMenclose::updateLogicalHeight): Deleted. Height is now calculated
+        in layoutBlock.
+        (WebCore::RenderMathMLMenclose::checkNotationalValuesValidity): Deleted.
+        * rendering/mathml/RenderMathMLMenclose.h: Update member definitions.
+        * rendering/mathml/RenderMathMLRoot.cpp: We no longer need anonymous roots.
+        (WebCore::RenderMathMLRoot::RenderMathMLRoot): Deleted.
+        * rendering/mathml/RenderMathMLRoot.h: We no longer need anonymous roots.
+        * rendering/mathml/RenderMathMLRow.cpp: Allow to get the exact metrics of the chid row,
+        for use in RenderMathMLRoot.
+        (WebCore::RenderMathMLRow::computeLineVerticalStretch): rename parameters.
+        (WebCore::RenderMathMLRow::layoutRowItems): Set parameters to the final ascent, descent and
+        logical width of the chid row. Set the temporary logical width for RenderMathMenclose before
+        laying the children out.
+        (WebCore::RenderMathMLRow::layoutBlock): Rename parameters ; add a dummy logicalWidth
+        parameter.
+        * rendering/mathml/RenderMathMLRow.h: Make some functions accessible or overridable by
+        RenderMathMLRoot. Make layoutRowItems return the final ascent, descent and logical width
+        after the chid row is laid out.
+        * rendering/mathml/RenderMathMLSquareRoot.cpp: We no longer need anonymous roots.
+        (WebCore::RenderMathMLSquareRoot::RenderMathMLSquareRoot): Deleted.
+        (WebCore::RenderMathMLSquareRoot::createAnonymousWithParentRenderer): Deleted.
+        * rendering/mathml/RenderMathMLSquareRoot.h: We no longer need anonymous roots.
+
+2016-04-25  Frederic Wang  <fwang@igalia.com>
+
         Minor refactoring in RenderMathMLOperator
         https://bugs.webkit.org/show_bug.cgi?id=156906
 
index 5f1583a..0fb8e4c 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2014 Gurpreet Kaur (k.gurpreet@samsung.com). All rights reserved.
+ * Copyright (C) 2016 Igalia S.L.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "MathMLMencloseElement.h"
 
 #include "MathMLNames.h"
-#include "RenderElement.h"
 #include "RenderMathMLMenclose.h"
-#include "RenderObject.h"
-#include "TextRun.h"
-#include <wtf/Ref.h>
-#include <wtf/text/StringBuilder.h>
-
 
 namespace WebCore {
 
 MathMLMencloseElement::MathMLMencloseElement(const QualifiedName& tagName, Document& document)
     : MathMLInlineContainerElement(tagName, document)
-    , m_isRadicalValue(false)
 {
+    // By default we draw a longdiv.
+    clearNotations();
+    addNotation(LongDiv);
 }
 
 Ref<MathMLMencloseElement> MathMLMencloseElement::create(const QualifiedName& tagName, Document& document)
@@ -55,89 +52,60 @@ RenderPtr<RenderElement> MathMLMencloseElement::createElementRenderer(std::uniqu
     return createRenderer<RenderMathMLMenclose>(*this, WTFMove(style));
 }
 
-bool MathMLMencloseElement::isPresentationAttribute(const QualifiedName& name) const
-{
-    if (name == MathMLNames::notationAttr)
-        return true;
-    return MathMLElement::isPresentationAttribute(name);
-}
-
-void MathMLMencloseElement::finishParsingChildren()
+void MathMLMencloseElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
 {
-    MathMLInlineContainerElement::finishParsingChildren();
-    // When notation value is a radical and menclose does not have any child 
-    // then we add anonymous squareroot child to menclose so that square root
-    // symbol can be rendered.
-    if (m_isRadicalValue && !firstElementChild())
-        renderer()->addChild(nullptr, nullptr);
-}
-
-void MathMLMencloseElement::collectStyleForPresentationAttribute(const QualifiedName& name, const AtomicString& value, MutableStyleProperties& style)
-{
-    String val = value;
-    if (val.isEmpty())
-        return;
     if (name == MathMLNames::notationAttr) {
-        val.split(' ', m_notationValues);
-        size_t notationValueSize = m_notationValues.size();
-        for (size_t i = 0; i < notationValueSize; i++) {
-            if (m_notationValues[i] == "top" || m_notationValues[i] == "longdiv") {
-                if (m_notationValues[i] == "longdiv")
-                    addPropertyToPresentationAttributeStyle(style, CSSPropertyPaddingLeft, longDivLeftPadding());
-                addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderTopStyle, "solid");
-                addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderTopWidth, "thin");
-                addPropertyToPresentationAttributeStyle(style, CSSPropertyPaddingTop, ".3ex");
-            } else if (m_notationValues[i] == "bottom") {
-                addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderBottomStyle, "solid");
-                addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderBottomWidth, "thin");
-                addPropertyToPresentationAttributeStyle(style, CSSPropertyPaddingBottom, ".3ex");
-            } else if (m_notationValues[i] == "left") {
-                addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderLeftStyle, "solid");
-                addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderLeftWidth, "thin");
-                addPropertyToPresentationAttributeStyle(style, CSSPropertyPaddingLeft, ".3ex");
-            } else if (m_notationValues[i] == "right") {
-                addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderRightStyle, "solid");
-                addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderRightWidth, "thin");
-                addPropertyToPresentationAttributeStyle(style, CSSPropertyPaddingRight, ".3ex");
-            } else if (m_notationValues[i] == "box" || m_notationValues[i] == "roundedbox") {
-                addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderStyle, "solid");
-                addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderWidth, "thin");
-                addPropertyToPresentationAttributeStyle(style, CSSPropertyPadding, ".3ex");
-                if (m_notationValues[i] == "roundedbox")
-                    addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderRadius, ASCIILiteral("5px"));
-            } else if (m_notationValues[i] == "actuarial" || m_notationValues[i] == "madruwb") {
-                addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderRightStyle, "solid");
-                addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderRightWidth, "thin");
-                addPropertyToPresentationAttributeStyle(style, CSSPropertyPaddingRight, ".3ex");
-                if (m_notationValues[i] == "actuarial") {
-                    addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderTopStyle, "solid");
-                    addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderTopWidth, "thin");
-                    addPropertyToPresentationAttributeStyle(style, CSSPropertyPaddingTop, ".3ex");
-                } else if (m_notationValues[i] == "madruwb") {
-                    addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderBottomStyle, "solid");
-                    addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderBottomWidth, "thin");
-                    addPropertyToPresentationAttributeStyle(style, CSSPropertyPaddingBottom, ".3ex");
-                }
-            } else if (m_notationValues[i] == "radical")
-                m_isRadicalValue = true;
+        clearNotations();
+        if (!hasAttribute(name)) {
+            addNotation(LongDiv); // default value is longdiv
+            return;
         }
-    } else
-        MathMLInlineContainerElement::collectStyleForPresentationAttribute(name, value, style);
-}
-
-
-String MathMLMencloseElement::longDivLeftPadding() const
-{
-    StringBuilder padding;
-    String closingBrace(")", String::ConstructFromLiteral);
-    TextRun run(closingBrace);
-    Node* node = parentNode();
-    if (node && node->renderer()) {
-        const FontCascade& font = node->renderer()->style().fontCascade();
-        padding.appendNumber(font.width(run));
-        padding.appendLiteral("px");
+        Vector<String> notationsList;
+        String(value).split(' ', notationsList);
+        for (auto& notation : notationsList) {
+            if (notation == "longdiv") {
+                addNotation(LongDiv);
+            } else if (notation == "roundedbox") {
+                addNotation(RoundedBox);
+            } else if (notation == "circle") {
+                addNotation(Circle);
+            } else if (notation == "left") {
+                addNotation(Left);
+            } else if (notation == "right") {
+                addNotation(Right);
+            } else if (notation == "top") {
+                addNotation(Top);
+            } else if (notation == "bottom") {
+                addNotation(Bottom);
+            } else if (notation == "updiagonalstrike") {
+                addNotation(UpDiagonalStrike);
+            } else if (notation == "downdiagonalstrike") {
+                addNotation(DownDiagonalStrike);
+            } else if (notation == "verticalstrike") {
+                addNotation(VerticalStrike);
+            } else if (notation == "horizontalstrike") {
+                addNotation(HorizontalStrike);
+            } else if (notation == "updiagonalarrow") {
+                addNotation(UpDiagonalArrow);
+            } else if (notation == "phasorangle") {
+                addNotation(PhasorAngle);
+            } else if (notation == "box") {
+                addNotation(Left);
+                addNotation(Right);
+                addNotation(Top);
+                addNotation(Bottom);
+            } else if (notation == "actuarial") {
+                addNotation(Right);
+                addNotation(Top);
+            } else if (notation == "madruwb") {
+                addNotation(Right);
+                addNotation(Bottom);
+            }
+        }
+        return;
     }
-    return padding.toString();
+
+    MathMLInlineContainerElement::parseAttribute(name, value);
 }
 
 }
index 2045f46..321e0cf 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2014 Gurpreet Kaur (k.gurpreet@samsung.com). All rights reserved.
+ * Copyright (C) 2016 Igalia S.L.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -27,6 +28,7 @@
 #define MathMLMencloseElement_h
 
 #if ENABLE(MATHML)
+#include "Element.h"
 #include "MathMLInlineContainerElement.h"
 
 namespace WebCore {
@@ -34,20 +36,32 @@ namespace WebCore {
 class MathMLMencloseElement final: public MathMLInlineContainerElement {
 public:
     static Ref<MathMLMencloseElement> create(const QualifiedName& tagName, Document&);
-    const Vector<String>& notationValues() const { return m_notationValues; }
-    bool isRadical() const { return m_isRadicalValue; }
-    String longDivLeftPadding() const;
-    bool isDefaultLongDiv() const { return !hasAttribute(MathMLNames::notationAttr); }
+    void parseAttribute(const QualifiedName&, const AtomicString&) final;
+
+    enum MencloseNotationFlag {
+        LongDiv = 1 << 1,
+        RoundedBox = 1 << 2,
+        Circle = 1 << 3,
+        Left = 1 << 4,
+        Right = 1 << 5,
+        Top = 1 << 6,
+        Bottom = 1 << 7,
+        UpDiagonalStrike = 1 << 8,
+        DownDiagonalStrike = 1 << 9,
+        VerticalStrike = 1 << 10,
+        HorizontalStrike = 1 << 11,
+        UpDiagonalArrow = 1 << 12, // FIXME: updiagonalarrow is not implemented. See http://wkb.ug/127466
+        PhasorAngle = 1 << 13 // FIXME: phasorangle is not implemented. See http://wkb.ug/127466
+        // We do not implement the Radical notation. Authors should instead use the <msqrt> element.
+    };
+    bool hasNotation(MencloseNotationFlag notationFlag) const { return m_notationFlags & notationFlag; }
 
 private:
     MathMLMencloseElement(const QualifiedName&, Document&);
-    RenderPtr<RenderElement> createElementRenderer(std::unique_ptr<RenderStyle>, const RenderTreePosition&) override;
-    bool isPresentationAttribute(const QualifiedName&) const override;
-    void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStyleProperties&) override;
-    void finishParsingChildren() override;
-
-    Vector<String> m_notationValues;
-    bool m_isRadicalValue;
+    RenderPtr<RenderElement> createElementRenderer(std::unique_ptr<RenderStyle>, const RenderTreePosition&) final;
+    void clearNotations() { m_notationFlags = 0; }
+    void addNotation(MencloseNotationFlag notationFlag) { m_notationFlags |= notationFlag; }
+    unsigned short m_notationFlags;
 };
 
 }
index c3dd467..b9044a2 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2014 Gurpreet Kaur (k.gurpreet@samsung.com). All rights reserved.
+ * Copyright (C) 2016 Igalia S.L.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "RenderMathMLMenclose.h"
 
 #include "GraphicsContext.h"
-#include "MathMLMencloseElement.h"
+#include "MathMLNames.h"
 #include "PaintInfo.h"
-#include "RenderMathMLSquareRoot.h"
 #include <wtf/MathExtras.h>
 
 namespace WebCore {
 
 using namespace MathMLNames;
 
+// The MathML in HTML5 implementation note suggests drawing the left part of longdiv with a parenthesis.
+// For now, we use a Bezier curve and this somewhat arbitrary value.
+const unsigned short longDivLeftSpace = 10;
+
 RenderMathMLMenclose::RenderMathMLMenclose(Element& element, std::unique_ptr<RenderStyle> style)
     : RenderMathMLRow(element, WTFMove(style))
+    , m_ascent(0)
+{
+}
+
+// This arbitrary thickness value is used for the parameter \xi_8 from the MathML in HTML5 implementation note.
+// For now, we take:
+// - OverbarVerticalGap = UnderbarVerticalGap = 3\xi_8
+// - OverbarRuleThickness = UnderbarRuleThickness = \xi_8
+// - OverbarExtraAscender = UnderbarExtraAscender = \xi_8
+// FIXME: OverBar and UnderBar parameters should be read from the MATH tables.
+// See https://bugs.webkit.org/show_bug.cgi?id=122297
+LayoutUnit RenderMathMLMenclose::ruleThickness() const
 {
+    return 0.05f * style().fontCascade().size();
 }
 
-void RenderMathMLMenclose::addChild(RenderObject* newChild, RenderObject* beforeChild)
+void RenderMathMLMenclose::getSpaceAroundContent(LayoutUnit contentWidth, LayoutUnit contentHeight, LayoutUnit& leftSpace, LayoutUnit& rightSpace, LayoutUnit& topSpace, LayoutUnit& bottomSpace) const
 {
-    MathMLMencloseElement* menclose = downcast<MathMLMencloseElement>(element());
-    // Allow an anonymous RenderMathMLSquareRoot to handle drawing the radical
-    // notation, rather than duplicating the code needed to paint a root.
-    if (!firstChild() && menclose->isRadical())        
-        RenderMathMLBlock::addChild(RenderMathMLSquareRoot::createAnonymousWithParentRenderer(*this).leakPtr());
-    
-    if (newChild) {
-        if (firstChild() && menclose->isRadical())
-            downcast<RenderElement>(*firstChild()).addChild(newChild, beforeChild && beforeChild->parent() == firstChild() ? beforeChild : nullptr);
-        else
-            RenderMathMLBlock::addChild(newChild, beforeChild);
+    leftSpace = rightSpace = topSpace = bottomSpace = 0;
+
+    LayoutUnit thickness = ruleThickness();
+
+    // In the MathML in HTML5 implementation note, the "left" notation is described as follows:
+    // - left side is 3\xi_8 padding + \xi_8 border + \xi_8 margin = 5\xi_8
+    // - top space is Overbar Vertical Gap + Overbar Rule Thickness = 3\xi_8 + \xi_8 = 4\xi_8
+    // - bottom space is Underbar Vertical Gap + Underbar Rule Thickness = 3\xi_8 + \xi_8 = 4\xi_8
+    // The "right" notation is symmetric.
+    if (hasNotation(MathMLMencloseElement::Left))
+        leftSpace = std::max(leftSpace, 5 * thickness);
+    if (hasNotation(MathMLMencloseElement::Right))
+        rightSpace = std::max(rightSpace, 5 * thickness);
+    if (hasNotation(MathMLMencloseElement::Left) || hasNotation(MathMLMencloseElement::Right)) {
+        LayoutUnit extraSpace = 4 * thickness;
+        topSpace = std::max(topSpace, extraSpace);
+        bottomSpace = std::max(bottomSpace, extraSpace);
+    }
+
+    // In the MathML in HTML5 implementation note, the "top" notation is described as follows:
+    // - left and right space are 4\xi_8
+    // - top side is Vertical Gap + Rule Thickness + Extra Ascender = 3\xi_8 + \xi_8 + \xi_8 = 5\xi_8
+    // The "bottom" notation is symmetric.
+    if (hasNotation(MathMLMencloseElement::Top))
+        topSpace = std::max(topSpace, 5 * thickness);
+    if (hasNotation(MathMLMencloseElement::Bottom))
+        bottomSpace = std::max(bottomSpace, 5 * thickness);
+    if (hasNotation(MathMLMencloseElement::Top) || hasNotation(MathMLMencloseElement::Bottom)) {
+        LayoutUnit extraSpace = 4 * thickness;
+        leftSpace = std::max(leftSpace, extraSpace);
+        rightSpace = std::max(rightSpace, extraSpace);
+    }
+
+    // For longdiv, we use our own rules for now:
+    // - top space is like "top" notation
+    // - bottom space is like "bottom" notation
+    // - right space is like "right" notation
+    // - left space is longDivLeftSpace * \xi_8
+    if (hasNotation(MathMLMencloseElement::LongDiv)) {
+        topSpace = std::max(topSpace, 5 * thickness);
+        bottomSpace = std::max(bottomSpace, 5 * thickness);
+        leftSpace = std::max(leftSpace, longDivLeftSpace * thickness);
+        rightSpace = std::max(rightSpace, 4 * thickness);
+    }
+
+    // In the MathML in HTML5 implementation note, the "rounded" notation is described as follows:
+    // - top/bottom/left/right side have 3\xi_8 padding + \xi_8 border + \xi_8 margin = 5\xi_8
+    if (hasNotation(MathMLMencloseElement::RoundedBox)) {
+        LayoutUnit extraSpace = 5 * thickness;
+        leftSpace = std::max(leftSpace, extraSpace);
+        rightSpace = std::max(rightSpace, extraSpace);
+        topSpace = std::max(topSpace, extraSpace);
+        bottomSpace = std::max(bottomSpace, extraSpace);
+    }
+
+    // In the MathML in HTML5 implementation note, the "rounded" notation is described as follows:
+    // - top/bottom/left/right spaces are \xi_8/2
+    if (hasNotation(MathMLMencloseElement::UpDiagonalStrike) || hasNotation(MathMLMencloseElement::DownDiagonalStrike)) {
+        LayoutUnit extraSpace = thickness / 2;
+        leftSpace = std::max(leftSpace, extraSpace);
+        rightSpace = std::max(rightSpace, extraSpace);
+        topSpace = std::max(topSpace, extraSpace);
+        bottomSpace = std::max(bottomSpace, extraSpace);
     }
+
+    // In the MathML in HTML5 implementation note, the "circle" notation is described as follows:
+    // - We draw the ellipse of axes the axes of symmetry of this ink box
+    // - The radii of the ellipse are \sqrt{2}contentWidth/2 and \sqrt{2}contentHeight/2
+    // - The thickness of the ellipse is \xi_8
+    // - We add extra margin of \xi_8
+    // Then for example the top space is \sqrt{2}contentHeight/2 - contentHeight/2 + \xi_8/2 + \xi_8.
+    if (hasNotation(MathMLMencloseElement::Circle)) {
+        LayoutUnit extraSpace = (contentWidth * (sqrtOfTwoFloat - 1) + 3 * thickness) / 2;
+        leftSpace = std::max(leftSpace, extraSpace);
+        rightSpace = std::max(rightSpace, extraSpace);
+        extraSpace = (contentHeight * (sqrtOfTwoFloat - 1) + 3 * thickness) / 2;
+        topSpace = std::max(topSpace, extraSpace);
+        bottomSpace = std::max(bottomSpace, extraSpace);
+    }
+
+    // In the MathML in HTML5 implementation note, the "vertical" and "horizontal" notations do not add space around the content.
 }
 
 void RenderMathMLMenclose::computePreferredLogicalWidths()
 {
     ASSERT(preferredLogicalWidthsDirty());
 
-    RenderMathMLBlock::computePreferredLogicalWidths();
-    const int paddingTop = 6;
-
-    MathMLMencloseElement* menclose = downcast<MathMLMencloseElement>(element());
-    const Vector<String>& notationValues = menclose->notationValues();
-    size_t notationalValueSize = notationValues.size();
-    for (size_t i = 0; i < notationalValueSize; i++) {
-        if (notationValues[i] == "circle") {
-            m_minPreferredLogicalWidth = minPreferredLogicalWidth() * sqrtOfTwoFloat;
-            m_maxPreferredLogicalWidth = maxPreferredLogicalWidth() * sqrtOfTwoFloat;
-        }
-    }
+    RenderMathMLRow::computePreferredLogicalWidths();
+
+    LayoutUnit preferredWidth = m_maxPreferredLogicalWidth;
+    LayoutUnit leftSpace, rightSpace, dummy;
+    getSpaceAroundContent(preferredWidth, 0, leftSpace, rightSpace, dummy, dummy);
+    m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = leftSpace + preferredWidth + rightSpace;
 
-    if (menclose->isDefaultLongDiv()) {
-        style().setPaddingTop(Length(paddingTop, Fixed));
-        style().setPaddingLeft(Length(menclose->longDivLeftPadding().toInt(), Fixed));
-    }
     setPreferredLogicalWidthsDirty(false);
 }
 
-void RenderMathMLMenclose::updateLogicalHeight()
+void RenderMathMLMenclose::layoutBlock(bool relayoutChildren, LayoutUnit)
+{
+    ASSERT(needsLayout());
+
+    if (!relayoutChildren && simplifiedLayout())
+        return;
+
+    LayoutUnit contentAscent = 0;
+    LayoutUnit contentDescent = 0;
+    RenderMathMLRow::computeLineVerticalStretch(contentAscent, contentDescent);
+    RenderMathMLRow::layoutRowItems(contentAscent, contentDescent);
+    LayoutUnit contentWidth = logicalWidth();
+
+    LayoutUnit leftSpace, rightSpace, topSpace, bottomSpace;
+    getSpaceAroundContent(contentWidth, contentAscent + contentDescent, leftSpace, rightSpace, topSpace, bottomSpace);
+    setLogicalWidth(leftSpace + contentWidth + rightSpace);
+    m_ascent = topSpace + contentAscent;
+    LayoutUnit descent = contentDescent + bottomSpace;
+    LayoutPoint contentLocation(leftSpace, m_ascent - contentAscent);
+    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox())
+        child->setLocation(child->location() + contentLocation);
+
+    setLogicalHeight(m_ascent + descent);
+
+    m_contentRect = LayoutRect(leftSpace, topSpace, contentWidth, contentAscent + contentDescent);
+
+    clearNeedsLayout();
+}
+
+Optional<int> RenderMathMLMenclose::firstLineBaseline() const
 {
-    MathMLMencloseElement* menclose = downcast<MathMLMencloseElement>(element());
-    const Vector<String>& notationValues = menclose->notationValues();
-    size_t notationalValueSize = notationValues.size();
-    for (size_t i = 0; i < notationalValueSize; i++)
-        if (notationValues[i] == "circle")
-            setLogicalHeight(logicalHeight() * sqrtOfTwoFloat);
+    return Optional<int>(static_cast<int>(lroundf(m_ascent)));
+}
+
+// GraphicsContext::drawLine does not seem appropriate to draw menclose lines.
+// To avoid unexpected behaviors and inconsistency with other notations, we just use strokePath.
+static void drawLine(PaintInfo& info, const LayoutUnit& xStart, const LayoutUnit& yStart, const LayoutUnit& xEnd, const LayoutUnit& yEnd)
+{
+    Path line;
+    line.moveTo(LayoutPoint(xStart, yStart));
+    line.addLineTo(LayoutPoint(xEnd, yEnd));
+    info.context().strokePath(line);
 }
 
 void RenderMathMLMenclose::paint(PaintInfo& info, const LayoutPoint& paintOffset)
 {
-    RenderMathMLBlock::paint(info, paintOffset);
+    RenderMathMLRow::paint(info, paintOffset);
 
     if (info.context().paintingDisabled() || info.phase != PaintPhaseForeground || style().visibility() != VISIBLE)
         return;
-    
-    MathMLMencloseElement* menclose = downcast<MathMLMencloseElement>(element());
-    const Vector<String>& notationValues = menclose->notationValues();
-    size_t notationalValueSize = notationValues.size();
-    bool isDefaultLongDiv = menclose->isDefaultLongDiv();
-    if ((notationalValueSize && checkNotationalValuesValidity(notationValues)) || isDefaultLongDiv) {
-        IntRect rect = absoluteBoundingBoxRect();
-        int left = rect.x();
-        int top = rect.y();
-        int boxWidth = rect.width();
-        int boxHeight = rect.height();
-        int halfboxWidth = rect.width() / 2;
-        int halfboxHeight = rect.height() / 2;
-
-        GraphicsContextStateSaver stateSaver(info.context());
-        info.context().setStrokeThickness(1);
-        info.context().setStrokeStyle(SolidStroke);
-        info.context().setStrokeColor(style().visitedDependentColor(CSSPropertyColor));
-        // TODO add support for notation value updiagonalarrow https://bugs.webkit.org/show_bug.cgi?id=127466
-        for (size_t i = 0; i < notationalValueSize; i++) {
-            if (notationValues[i] == "updiagonalstrike")
-                info.context().drawLine(IntPoint(left, top + boxHeight), IntPoint(left + boxWidth, top));
-            else if (notationValues[i] == "downdiagonalstrike")
-                info.context().drawLine(IntPoint(left, top), IntPoint(left + boxWidth, top + boxHeight));
-            else if (notationValues[i] == "verticalstrike")
-                info.context().drawLine(IntPoint(left + halfboxWidth, top), IntPoint(left + halfboxWidth, top + boxHeight));
-            else if (notationValues[i] == "horizontalstrike")
-                info.context().drawLine(IntPoint(left, top + halfboxHeight), IntPoint(left + boxWidth, top + halfboxHeight));
-            else if (notationValues[i] == "circle") {
-                info.context().setFillColor(Color::transparent);
-                info.context().drawEllipse(rect);
-            } else if (notationValues[i] == "longdiv")
-                isDefaultLongDiv = true;
-        }
-        if (isDefaultLongDiv) {
-            Path root;
-            int midxPoint = 0;
-            root.moveTo(FloatPoint(left, top));
-            int childLeft = firstChild() ? firstChild()->absoluteBoundingBoxRect().x() : 0;
-            if (childLeft)
-                midxPoint= childLeft - left;
-            else
-                midxPoint = style().paddingLeft().value();
-            root.addBezierCurveTo(FloatPoint(left, top), FloatPoint(left + midxPoint, top + halfboxHeight), FloatPoint(left, top + boxHeight));
-            info.context().strokePath(root);
-            if (isDefaultLongDiv)
-                info.context().drawLine(IntPoint(left, top), IntPoint(left + boxWidth + midxPoint, top));
-        }
+
+    LayoutUnit thickness = ruleThickness();
+    GraphicsContextStateSaver stateSaver(info.context());
+
+    info.context().setStrokeThickness(thickness);
+    info.context().setStrokeStyle(SolidStroke);
+    info.context().setStrokeColor(style().visitedDependentColor(CSSPropertyColor));
+    info.context().setFillColor(Color::transparent);
+    info.applyTransform(AffineTransform().translate(paintOffset + location()));
+
+    // In the MathML in HTML5 implementation note, the "left" notation is described as follows:
+    // - center of the left vertical bar is at 3\xi_8 padding + \xi_8 border/2 = 7\xi_8/2
+    // - top space is Overbar Vertical Gap + Overbar Rule Thickness = 3\xi_8 + \xi_8 = 4\xi_8
+    // - bottom space is Underbar Vertical Gap + Underbar Rule Thickness = 3\xi_8 + \xi_8 = 4\xi_8
+    if (hasNotation(MathMLMencloseElement::Left)) {
+        LayoutUnit x = m_contentRect.x() - 7 * thickness / 2;
+        LayoutUnit yStart = m_contentRect.y() - 4 * thickness;
+        LayoutUnit yEnd = m_contentRect.maxY() + 4 * thickness;
+        drawLine(info, x, yStart, x, yEnd);
     }
-}
 
-bool RenderMathMLMenclose::checkNotationalValuesValidity(const Vector<String>& attr) const
-{
-    size_t attrSize = attr.size();
-    for (size_t i = 0; i < attrSize; i++) {
-        if (attr[i] == "updiagonalstrike" || attr[i] == "downdiagonalstrike" || attr[i] == "horizontalstrike" || attr[i] == "verticalstrike"
-            || attr[i] == "circle" || attr[i] == "longdiv")
-            return true;
+    // In the MathML in HTML5 implementation note, the "right" notation is described as follows:
+    // - center of the right vertical bar is at 3\xi_8 padding + \xi_8 border/2 = 7\xi_8/2
+    // - top space is Overbar Vertical Gap + Overbar Rule Thickness = 3\xi_8 + \xi_8 = 4\xi_8
+    // - bottom space is Underbar Vertical Gap + Underbar Rule Thickness = 3\xi_8 + \xi_8 = 4\xi_8
+    if (hasNotation(MathMLMencloseElement::Right)) {
+        LayoutUnit x = m_contentRect.maxX() + 7 * thickness / 2;
+        LayoutUnit yStart = m_contentRect.y() - 4 * thickness;
+        LayoutUnit yEnd = m_contentRect.maxY() + 4 * thickness;
+        drawLine(info, x, yStart, x, yEnd);
+    }
+
+    // In the MathML in HTML5 implementation note, the "vertical" notation is horizontally centered.
+    if (hasNotation(MathMLMencloseElement::VerticalStrike)) {
+        LayoutUnit x = m_contentRect.x() + (m_contentRect.width() - thickness) / 2;
+        LayoutUnit yStart = m_contentRect.y();
+        LayoutUnit yEnd = m_contentRect.maxY();
+        drawLine(info, x, yStart, x, yEnd);
+    }
+
+    // In the MathML in HTML5 implementation note, the "top" notation is described as follows:
+    // - middle of the top horizontal bar is at Vertical Gap + Rule Thickness / 2 = 7\xi_8/2
+    // - left and right spaces have size 4\xi_8
+    if (hasNotation(MathMLMencloseElement::Top)) {
+        LayoutUnit y = m_contentRect.y() - 7 * thickness / 2;
+        LayoutUnit xStart = m_contentRect.x() - 4 * thickness;
+        LayoutUnit xEnd = m_contentRect.maxX() + 4 * thickness;
+        drawLine(info, xStart, y, xEnd, y);
+    }
+
+    // In the MathML in HTML5 implementation note, the "bottom" notation is described as follows:
+    // - middle of the bottom horizontal bar is at Vertical Gap + Rule Thickness / 2 = 7\xi_8/2
+    // - left and right spaces have size 4\xi_8
+    if (hasNotation(MathMLMencloseElement::Bottom)) {
+        LayoutUnit y = m_contentRect.maxY() + 7 * thickness / 2;
+        LayoutUnit xStart = m_contentRect.x() - 4 * thickness;
+        LayoutUnit xEnd = m_contentRect.maxX() + 4 * thickness;
+        drawLine(info, xStart, y, xEnd, y);
+    }
+
+    // In the MathML in HTML5 implementation note, the "vertical" notation is vertically centered.
+    if (hasNotation(MathMLMencloseElement::HorizontalStrike)) {
+        LayoutUnit y = m_contentRect.y() + (m_contentRect.height() - thickness) / 2;
+        LayoutUnit xStart = m_contentRect.x();
+        LayoutUnit xEnd = m_contentRect.maxX();
+        drawLine(info, xStart, y, xEnd, y);
+    }
+
+    // In the MathML in HTML5 implementation note, the "updiagonalstrike" goes from the bottom left corner
+    // to the top right corner.
+    if (hasNotation(MathMLMencloseElement::UpDiagonalStrike))
+        drawLine(info, m_contentRect.x(), m_contentRect.maxY(), m_contentRect.maxX(), m_contentRect.y());
+
+    // In the MathML in HTML5 implementation note, the "downdiagonalstrike" goes from the top left corner
+    // to the bottom right corner.
+    if (hasNotation(MathMLMencloseElement::DownDiagonalStrike))
+        drawLine(info, m_contentRect.x(), m_contentRect.y(), m_contentRect.maxX(), m_contentRect.maxY());
+
+    // In the MathML in HTML5 implementation note, the "roundedbox" has radii size 3\xi_8 and is obtained
+    // by inflating the content box by 3\xi_8 + \xi_8/2 = 7\xi_8/2
+    if (hasNotation(MathMLMencloseElement::RoundedBox)) {
+        LayoutSize radiiSize(3 * thickness, 3 * thickness);
+        RoundedRect::Radii radii(radiiSize, radiiSize, radiiSize, radiiSize);
+        RoundedRect roundedRect(m_contentRect, radii);
+        roundedRect.inflate(7 * thickness / 2);
+        Path path;
+        path.addRoundedRect(roundedRect);
+        info.context().strokePath(path);
+    }
+
+    // For longdiv, we use our own rules for now:
+    // - top space is like "top" notation
+    // - bottom space is like "bottom" notation
+    // - right space is like "right" notation
+    // - left space is longDivLeftSpace * \xi_8
+    // - We subtract half of the thickness from these spaces to obtain "top", "bottom", "left"
+    //   and "right" coordinates.
+    // - The top bar is drawn from "right" to "left" and positioned at vertical offset "top".
+    // - The left part is draw as a quadratic Bezier curve with end points going from "top" to
+    //   "bottom" and positioned at horizontal offset "left".
+    // - In order to force the curvature of the left part, we use a middle point that is vertically
+    //   centered and shifted towards the right by longDivLeftSpace * \xi_8
+    if (hasNotation(MathMLMencloseElement::LongDiv)) {
+        LayoutUnit top = m_contentRect.y() - 7 * thickness / 2;
+        LayoutUnit bottom = m_contentRect.maxY() + 7 * thickness / 2;
+        LayoutUnit left = m_contentRect.x() - longDivLeftSpace * thickness + thickness / 2;
+        LayoutUnit right = m_contentRect.maxX() + 4 * thickness;
+        LayoutUnit midX = left + longDivLeftSpace * thickness;
+        LayoutUnit midY = (top + bottom) / 2;
+        Path path;
+        path.moveTo(LayoutPoint(right, top));
+        path.addLineTo(LayoutPoint(left, top));
+        path.addQuadCurveTo(LayoutPoint(midX, midY), FloatPoint(left, bottom));
+        info.context().strokePath(path);
+    }
+
+    // In the MathML in HTML5 implementation note, the "circle" notation is described as follows:
+    // - The center and axes are the same as the content bounding box.
+    // - The width of the bounding box is \xi_8/2 + contentWidth * \sqrt{2} + \xi_8/2
+    // - The height is \xi_8/2 + contentHeight * \sqrt{2} + \xi_8/2
+    if (hasNotation(MathMLMencloseElement::Circle)) {
+        LayoutRect ellipseRect;
+        ellipseRect.setWidth(m_contentRect.width() * sqrtOfTwoFloat + thickness);
+        ellipseRect.setHeight(m_contentRect.height() * sqrtOfTwoFloat + thickness);
+        ellipseRect.setX(m_contentRect.x() - (ellipseRect.width() - m_contentRect.width()) / 2);
+        ellipseRect.setY(m_contentRect.y() - (ellipseRect.height() - m_contentRect.height()) / 2);
+        Path path;
+        path.addEllipse(ellipseRect);
+        info.context().strokePath(path);
     }
-    return false;
 }
 
 }
index 2794a70..fbf8710 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2014 Gurpreet Kaur (k.gurpreet@samsung.com). All rights reserved.
+ * Copyright (C) 2016 Igalia S.L.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -27,6 +28,7 @@
 #define RenderMathMLMenclose_h
 
 #if ENABLE(MATHML)
+#include "MathMLMencloseElement.h"
 #include "RenderMathMLRow.h"
 
 namespace WebCore {
@@ -36,13 +38,19 @@ public:
     RenderMathMLMenclose(Element&, std::unique_ptr<RenderStyle>);
 
 private:
-    bool isRenderMathMLMenclose() const final { return true; }
     const char* renderName() const final { return "RenderMathMLMenclose"; }
-    void paint(PaintInfo&, const LayoutPoint&) final;
-    void updateLogicalHeight() override;
-    void addChild(RenderObject* newChild, RenderObject* beforeChild = nullptr) override;
     void computePreferredLogicalWidths() final;
-    bool checkNotationalValuesValidity(const Vector<String>&) const;
+    void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) final;
+    Optional<int> firstLineBaseline() const final;
+    void paint(PaintInfo&, const LayoutPoint&) final;
+
+    LayoutUnit ruleThickness() const;
+    bool hasNotation(MathMLMencloseElement::MencloseNotationFlag notationFlag) const { return downcast<MathMLMencloseElement>(element())->hasNotation(notationFlag); }
+
+    void getSpaceAroundContent(LayoutUnit contentWidth, LayoutUnit contentHeight, LayoutUnit& leftSpace, LayoutUnit& rightSpace, LayoutUnit& topSpace, LayoutUnit& bottomSpace) const;
+
+    LayoutUnit m_ascent;
+    LayoutRect m_contentRect;
 };
     
 }
index 86f6358..0176515 100644 (file)
@@ -60,11 +60,6 @@ RenderMathMLRoot::RenderMathMLRoot(Element& element, std::unique_ptr<RenderStyle
 {
 }
 
-RenderMathMLRoot::RenderMathMLRoot(Document& document, std::unique_ptr<RenderStyle> style)
-    : RenderMathMLBlock(document, WTFMove(style))
-{
-}
-
 RenderMathMLRootWrapper* RenderMathMLRoot::baseWrapper() const
 {
     ASSERT(!isEmpty());
index 2d5b12f..dc94048 100644 (file)
@@ -43,7 +43,6 @@ friend class RenderMathMLRootWrapper;
 
 public:
     RenderMathMLRoot(Element&, std::unique_ptr<RenderStyle>);
-    RenderMathMLRoot(Document&, std::unique_ptr<RenderStyle>);
 
     void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) override;
     void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
index 177163e..a75628a 100644 (file)
@@ -70,7 +70,7 @@ Optional<int> RenderMathMLRow::firstLineBaseline() const
     return Optional<int>(static_cast<int>(lroundf(ascentForChild(*baselineChild) + baselineChild->logicalTop())));
 }
 
-void RenderMathMLRow::computeLineVerticalStretch(int& stretchHeightAboveBaseline, int& stretchDepthBelowBaseline)
+void RenderMathMLRow::computeLineVerticalStretch(LayoutUnit& ascent, LayoutUnit& descent)
 {
     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
         if (is<RenderMathMLBlock>(child)) {
@@ -84,14 +84,14 @@ void RenderMathMLRow::computeLineVerticalStretch(int& stretchHeightAboveBaseline
         LayoutUnit childHeightAboveBaseline = ascentForChild(*child);
         LayoutUnit childDepthBelowBaseline = child->logicalHeight() - childHeightAboveBaseline;
 
-        stretchHeightAboveBaseline = std::max<LayoutUnit>(stretchHeightAboveBaseline, childHeightAboveBaseline);
-        stretchDepthBelowBaseline = std::max<LayoutUnit>(stretchDepthBelowBaseline, childDepthBelowBaseline);
+        ascent = std::max<LayoutUnit>(ascent, childHeightAboveBaseline);
+        descent = std::max<LayoutUnit>(descent, childDepthBelowBaseline);
     }
 
     // We ensure a minimal stretch size.
-    if (stretchHeightAboveBaseline + stretchDepthBelowBaseline <= 0) {
-        stretchHeightAboveBaseline = style().fontSize();
-        stretchDepthBelowBaseline = 0;
+    if (ascent + descent <= 0) {
+        ascent = style().fontSize();
+        descent = 0;
     }
 }
 
@@ -110,7 +110,7 @@ void RenderMathMLRow::computePreferredLogicalWidths()
     setPreferredLogicalWidthsDirty(false);
 }
 
-void RenderMathMLRow::layoutRowItems(int stretchHeightAboveBaseline, int stretchDepthBelowBaseline)
+void RenderMathMLRow::layoutRowItems(LayoutUnit& ascent, LayoutUnit& descent)
 {
     // We first stretch the vertical operators.
     // For inline formulas, we can then calculate the logical width.
@@ -122,7 +122,7 @@ void RenderMathMLRow::layoutRowItems(int stretchHeightAboveBaseline, int stretch
         if (is<RenderMathMLBlock>(child)) {
             auto renderOperator = downcast<RenderMathMLBlock>(child)->unembellishedOperator();
             if (renderOperator && renderOperator->hasOperatorFlag(MathMLOperatorDictionary::Stretchy) && renderOperator->isVertical())
-                renderOperator->stretchTo(stretchHeightAboveBaseline, stretchDepthBelowBaseline);
+                renderOperator->stretchTo(ascent, descent);
         }
 
         child->layoutIfNeeded();
@@ -131,9 +131,9 @@ void RenderMathMLRow::layoutRowItems(int stretchHeightAboveBaseline, int stretch
     }
 
     width += borderEnd() + paddingEnd();
-    // FIXME: RenderMathMLRoot and RenderMathMLEnclose classes should also recalculate the exact logical width instead of using the preferred width.
-    // See https://bugs.webkit.org/show_bug.cgi?id=130326
-    if ((!isRenderMathMLMath() || style().display() == INLINE) && !isRenderMathMLRoot() && !isRenderMathMLMenclose())
+    // FIXME: RenderMathMLRoot classes should also recalculate the exact logical width instead of using the preferred width.
+    // See http://webkit.org/b/153987
+    if ((!isRenderMathMLMath() || style().display() == INLINE) && !isRenderMathMLRoot())
         setLogicalWidth(width);
 
     LayoutUnit verticalOffset = borderTop() + paddingTop();
@@ -175,6 +175,9 @@ void RenderMathMLRow::layoutRowItems(int stretchHeightAboveBaseline, int stretch
         LayoutUnit startOffset = maxAscent - ascent;
         child->setLocation(child->location() + LayoutPoint(centerBlockOffset, startOffset));
     }
+
+    ascent = maxAscent;
+    descent = maxDescent;
 }
 
 void RenderMathMLRow::layoutBlock(bool relayoutChildren, LayoutUnit)
@@ -184,15 +187,15 @@ void RenderMathMLRow::layoutBlock(bool relayoutChildren, LayoutUnit)
     if (!relayoutChildren && simplifiedLayout())
         return;
 
-    int stretchHeightAboveBaseline = 0;
-    int stretchDepthBelowBaseline = 0;
-    computeLineVerticalStretch(stretchHeightAboveBaseline, stretchDepthBelowBaseline);
+    LayoutUnit ascent = 0;
+    LayoutUnit descent = 0;
+    computeLineVerticalStretch(ascent, descent);
 
     recomputeLogicalWidth();
 
     setLogicalHeight(borderAndPaddingLogicalHeight() + scrollbarLogicalHeight());
 
-    layoutRowItems(stretchHeightAboveBaseline, stretchDepthBelowBaseline);
+    layoutRowItems(ascent, descent);
 
     updateLogicalHeight();
 
index 8b6742f..e241b96 100644 (file)
@@ -42,17 +42,18 @@ public:
 
     void updateOperatorProperties();
 
-    void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) final;
-    void paintChildren(PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect) final;
-    Optional<int> firstLineBaseline() const final;
+    void layoutBlock(bool relayoutChildren, LayoutUnit pageLogicalHeight = 0) override;
+    void paintChildren(PaintInfo& forSelf, const LayoutPoint&, PaintInfo& forChild, bool usePrintRect) override;
+    Optional<int> firstLineBaseline() const override;
+
+protected:
+    void layoutRowItems(LayoutUnit& ascent, LayoutUnit& descent);
+    void computeLineVerticalStretch(LayoutUnit& ascent, LayoutUnit& descent);
+    void computePreferredLogicalWidths() override;
 
 private:
     bool isRenderMathMLRow() const final { return true; }
     const char* renderName() const override { return isAnonymous() ? "RenderMathMLRow (anonymous)" : "RenderMathMLRow"; }
-
-    void layoutRowItems(int stretchHeightAboveBaseline, int stretchDepthBelowBaseline);
-    void computeLineVerticalStretch(int& stretchHeightAboveBaseline, int& stretchDepthBelowBaseline);
-    void computePreferredLogicalWidths() override;
 };
 
 } // namespace WebCore
index 13fd979..85567f5 100644 (file)
@@ -39,17 +39,5 @@ RenderMathMLSquareRoot::RenderMathMLSquareRoot(Element& element, std::unique_ptr
 {
 }
 
-RenderMathMLSquareRoot::RenderMathMLSquareRoot(Document& document, std::unique_ptr<RenderStyle> style)
-    : RenderMathMLRoot(document, WTFMove(style))
-{
-}
-
-RenderPtr<RenderMathMLSquareRoot> RenderMathMLSquareRoot::createAnonymousWithParentRenderer(RenderMathMLMenclose& parent)
-{
-    RenderPtr<RenderMathMLSquareRoot> squareRoot = createRenderer<RenderMathMLSquareRoot>(parent.document(), RenderStyle::createAnonymousStyleWithDisplay(&parent.style(), FLEX));
-    squareRoot->initializeStyle();
-    return squareRoot;
-}
-
 }
 #endif // ENABLE(MATHML)
index 96cb922..1359cc7 100644 (file)
@@ -39,7 +39,6 @@ class RenderMathMLMenclose;
 class RenderMathMLSquareRoot final : public RenderMathMLRoot {
 public:
     RenderMathMLSquareRoot(Element&, std::unique_ptr<RenderStyle>);
-    RenderMathMLSquareRoot(Document&, std::unique_ptr<RenderStyle>);
     static RenderPtr<RenderMathMLSquareRoot> createAnonymousWithParentRenderer(RenderMathMLMenclose&);
     
 private: