[SVG2] support paint-order presentation attribute
https://bugs.webkit.org/show_bug.cgi?id=129373

Reviewed by Dean Jackson.

Source/WebCore:

Add support for the paint-order property from SVG2. The presentation
attribute/CSS property allows to paint fill, stroke and markers in any order
the author desires.

Firefox supports this but behind a runtime flag. It is just activated in
nightly builds by default.

Chromium supports it behind a runtime flag as well but is going to ship it
pretty soon.

Tests: svg/paint-order/paint-order-fill-expected.svg
       svg/paint-order/paint-order-fill-markers-expected.svg
       svg/paint-order/paint-order-fill-markers.svg
       svg/paint-order/paint-order-fill.svg
       svg/paint-order/paint-order-markers-expected.svg
       svg/paint-order/paint-order-markers-stroke-expected.svg
       svg/paint-order/paint-order-markers-stroke.svg
       svg/paint-order/paint-order-markers.svg
       svg/paint-order/paint-order-normal-expected.svg
       svg/paint-order/paint-order-normal.svg
       svg/paint-order/paint-order-stroke-expected.svg
       svg/paint-order/paint-order-stroke-marker-expected.svg
       svg/paint-order/paint-order-stroke-marker.svg
       svg/paint-order/paint-order-stroke.svg
       svg/paint-order/paint-order-text-markers-expected.svg
       svg/paint-order/paint-order-text-markers.svg
       svg/paint-order/paint-order-text-normal-expected.svg
       svg/paint-order/paint-order-text-normal.svg
       svg/paint-order/paint-order-text-stroke-expected.svg
       svg/paint-order/paint-order-text-stroke.svg
       svg/paint-order/paint-order-text-tspan-001-expected.svg
       svg/paint-order/paint-order-text-tspan-001.svg
       svg/paint-order/paint-order-text-tspan-002-expected.svg
       svg/paint-order/paint-order-text-tspan-002.svg
       svg/paint-order/parsing-paint-order.html

* css/CSSComputedStyleDeclaration.cpp: Computed style for paint-order.
(WebCore::ComputedStyleExtractor::propertyValue):
* css/CSSParser.h:
* css/CSSPropertyNames.in:
* css/CSSValueKeywords.in:
* css/SVGCSSComputedStyleDeclaration.cpp:
(WebCore::paintOrder):
(WebCore::ComputedStyleExtractor::svgPropertyValue):
* css/SVGCSSParser.cpp: Parse paint-order. Take care of serialization
    at this point already to get element style correct.
(WebCore::CSSParser::parseSVGValue):
(WebCore::CSSParser::parsePaintOrder):
* css/SVGCSSStyleSelector.cpp:
(WebCore::StyleResolver::applySVGProperty):
* rendering/style/SVGRenderStyle.cpp:
(WebCore::SVGRenderStyle::paintTypesForPaintOrder):
(WebCore::SVGRenderStyle::diff): Repaint on change.
* rendering/style/SVGRenderStyle.h:
(WebCore::SVGRenderStyle::initialPaintOrder):
(WebCore::SVGRenderStyle::setPaintOrder):
(WebCore::SVGRenderStyle::paintOrder):
(WebCore::SVGRenderStyle::InheritedFlags::operator==):
(WebCore::SVGRenderStyle::setBitDefaults):
* rendering/style/SVGRenderStyleDefs.h:
* rendering/svg/RenderSVGShape.cpp: Change order of painting based on paint-order.
(WebCore::RenderSVGShape::strokeShape):
(WebCore::RenderSVGShape::fillStrokeMarkers):
(WebCore::RenderSVGShape::paint):
(WebCore::RenderSVGShape::addFocusRingRects):
* rendering/svg/RenderSVGShape.h:
* rendering/svg/SVGInlineTextBox.cpp:
(WebCore::SVGInlineTextBox::paint): Ditto.
* svg/SVGElement.cpp: Make property a presentation attribute.
(WebCore::populateAttributeNameToCSSPropertyIDMap):
(WebCore::populateAttributeNameToAnimatedPropertyTypeMap):
* svg/svgattrs.in: Add paint-order attribute.

LayoutTests:

Test parsing and bahvior of the paint-order property.

* svg/paint-order/paint-order-fill-expected.svg: Added.
* svg/paint-order/paint-order-fill-markers-expected.svg: Added.
* svg/paint-order/paint-order-fill-markers.svg: Added.
* svg/paint-order/paint-order-fill.svg: Added.
* svg/paint-order/paint-order-markers-expected.svg: Added.
* svg/paint-order/paint-order-markers-stroke-expected.svg: Added.
* svg/paint-order/paint-order-markers-stroke.svg: Added.
* svg/paint-order/paint-order-markers.svg: Added.
* svg/paint-order/paint-order-normal-expected.svg: Added.
* svg/paint-order/paint-order-normal.svg: Added.
* svg/paint-order/paint-order-stroke-expected.svg: Added.
* svg/paint-order/paint-order-stroke-marker-expected.svg: Added.
* svg/paint-order/paint-order-stroke-marker.svg: Added.
* svg/paint-order/paint-order-stroke.svg: Added.
* svg/paint-order/paint-order-text-markers-expected.svg: Added.
* svg/paint-order/paint-order-text-markers.svg: Added.
* svg/paint-order/paint-order-text-normal-expected.svg: Added.
* svg/paint-order/paint-order-text-normal.svg: Added.
* svg/paint-order/paint-order-text-stroke-expected.svg: Added.
* svg/paint-order/paint-order-text-stroke.svg: Added.
* svg/paint-order/paint-order-text-tspan-001-expected.svg: Added.
* svg/paint-order/paint-order-text-tspan-001.svg: Added.
* svg/paint-order/paint-order-text-tspan-002-expected.svg: Added.
* svg/paint-order/paint-order-text-tspan-002.svg: Added.
* svg/paint-order/parsing-paint-order-expected.txt: Added.
* svg/paint-order/parsing-paint-order.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@165595 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/svg/paint-order/parsing-paint-order.html b/LayoutTests/svg/paint-order/parsing-paint-order.html
new file mode 100644
index 0000000..a357864
--- /dev/null
+++ b/LayoutTests/svg/paint-order/parsing-paint-order.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<html>
+<style>
+* { font-size: 16px; }
+div { font-size: 8px; }
+</style>
+<body>
+<script src="../../resources/js-test-pre.js"></script>
+<script>
+description('Test parsing, element style and computed style for paint-order property.');
+
+function computedStyle(property, value) {
+    var div = document.createElement("div");
+    document.body.appendChild(div);
+    div.style.setProperty(property, value);
+    var computedValue = getComputedStyle(div).getPropertyValue(property);
+    document.body.removeChild(div);
+    return computedValue;
+}
+
+function innerStyle(property, value) {
+    var div = document.createElement("div");
+    div.style.setProperty(property, value);
+    return div.style.getPropertyValue(property);
+}
+
+function testComputed(property, value, expected) {
+    shouldBeEqualToString('computedStyle("' + property + '", "' + value + '")', expected);
+}
+
+function testInner(property, value, expected) {
+    if (expected === null)
+        shouldBeNull('innerStyle("' + property + '", "' + value + '")');
+    else
+        shouldBeEqualToString('innerStyle("' + property + '", "' + value + '")', expected);
+}
+
+function negativeTest(property, value) {
+    testInner(property, value, null);
+    testComputed(property, value, 'normal');
+}
+
+// Test element style.
+testInner("paint-order", "normal", "normal");
+testInner("paint-order", "fill", "fill");
+testInner("paint-order", "stroke", "stroke");
+testInner("paint-order", "markers", "markers");
+testInner("paint-order", "fill stroke", "fill");
+testInner("paint-order", "fill stroke markers", "fill");
+testInner("paint-order", "fill markers", "fill markers");
+testInner("paint-order", "fill markers stroke", "fill markers");
+testInner("paint-order", "stroke fill", "stroke");
+testInner("paint-order", "stroke fill markers", "stroke");
+testInner("paint-order", "stroke markers", "stroke markers");
+testInner("paint-order", "stroke markers fill", "stroke markers");
+testInner("paint-order", "stroke fill", "stroke");
+testInner("paint-order", "stroke fill markers", "stroke");
+testInner("paint-order", "stroke markers", "stroke markers");
+testInner("paint-order", "stroke markers fill", "stroke markers");
+
+// Test computed style.
+testComputed("paint-order", "normal", "normal");
+testComputed("paint-order", "fill", "fill");
+testComputed("paint-order", "stroke", "stroke");
+testComputed("paint-order", "markers", "markers");
+testComputed("paint-order", "fill stroke", "fill");
+testComputed("paint-order", "fill stroke markers", "fill");
+testComputed("paint-order", "fill markers", "fill markers");
+testComputed("paint-order", "fill markers stroke", "fill markers");
+testComputed("paint-order", "stroke fill", "stroke");
+testComputed("paint-order", "stroke fill markers", "stroke");
+testComputed("paint-order", "stroke markers", "stroke markers");
+testComputed("paint-order", "stroke markers fill", "stroke markers");
+testComputed("paint-order", "stroke fill", "stroke");
+testComputed("paint-order", "stroke fill markers", "stroke");
+testComputed("paint-order", "stroke markers", "stroke markers");
+testComputed("paint-order", "stroke markers fill", "stroke markers");
+
+// Negative tests.
+negativeTest("paint-order", "normal fill");
+negativeTest("paint-order", "normal stroke");
+negativeTest("paint-order", "normal markers");
+negativeTest("paint-order", "fill fill");
+negativeTest("paint-order", "stroke stroke");
+negativeTest("paint-order", "markers markers");
+negativeTest("paint-order", "markers fill markers");
+negativeTest("paint-order", "markers stroke markers");
+
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>