Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / rendering / svg / SVGRenderTreeAsText.cpp
index 4f59f08..0966adf 100644 (file)
@@ -30,7 +30,6 @@
 
 #include "core/rendering/svg/SVGRenderTreeAsText.h"
 
-#include "SVGNames.h"
 #include "core/rendering/InlineTextBox.h"
 #include "core/rendering/RenderTreeAsText.h"
 #include "core/rendering/svg/RenderSVGGradientStop.h"
 #include "core/svg/SVGRadialGradientElement.h"
 #include "core/svg/SVGRectElement.h"
 #include "core/svg/SVGStopElement.h"
+#include "platform/graphics/DashArray.h"
 #include "platform/graphics/GraphicsTypes.h"
 
 #include <math.h>
 #include <memory>
 
-namespace WebCore {
+namespace blink {
 
 /** class + iomanip to help streaming list separators, i.e. ", " in string "a, b, c, d"
  * Can be used in cases where you don't know which item in the list is the first
@@ -154,15 +154,35 @@ static TextStream& operator<<(TextStream& ts, const WindRule rule)
     return ts;
 }
 
+namespace {
+
+template<typename Enum>
+String SVGEnumerationToString(Enum value)
+{
+    const SVGEnumerationStringEntries& entries = getStaticStringEntries<Enum>();
+
+    SVGEnumerationStringEntries::const_iterator it = entries.begin();
+    SVGEnumerationStringEntries::const_iterator itEnd = entries.end();
+    for (; it != itEnd; ++it) {
+        if (value == it->first)
+            return it->second;
+    }
+
+    ASSERT_NOT_REACHED();
+    return String();
+}
+
+}
+
 static TextStream& operator<<(TextStream& ts, const SVGUnitTypes::SVGUnitType& unitType)
 {
-    ts << SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::toString(unitType);
+    ts << SVGEnumerationToString<SVGUnitTypes::SVGUnitType>(unitType);
     return ts;
 }
 
 static TextStream& operator<<(TextStream& ts, const SVGMarkerUnitsType& markerUnit)
 {
-    ts << SVGPropertyTraits<SVGMarkerUnitsType>::toString(markerUnit);
+    ts << SVGEnumerationToString<SVGMarkerUnitsType>(markerUnit);
     return ts;
 }
 
@@ -221,7 +241,7 @@ static TextStream& operator<<(TextStream& ts, LineJoin style)
 
 static TextStream& operator<<(TextStream& ts, const SVGSpreadMethodType& type)
 {
-    ts << SVGPropertyTraits<SVGSpreadMethodType>::toString(type).upper();
+    ts << SVGEnumerationToString<SVGSpreadMethodType>(type).upper();
     return ts;
 }
 
@@ -250,7 +270,7 @@ static void writeSVGPaintingResource(TextStream& ts, RenderSVGResource* resource
 static void writeStyle(TextStream& ts, const RenderObject& object)
 {
     const RenderStyle* style = object.style();
-    const SVGRenderStyle* svgStyle = style->svgStyle();
+    const SVGRenderStyle& svgStyle = style->svgStyle();
 
     if (!object.localTransform().isIdentity())
         writeNameValuePair(ts, "transform", object.localTransform());
@@ -260,27 +280,28 @@ static void writeStyle(TextStream& ts, const RenderObject& object)
         const RenderSVGShape& shape = static_cast<const RenderSVGShape&>(object);
         ASSERT(shape.element());
 
-        Color fallbackColor;
-        if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(const_cast<RenderSVGShape*>(&shape), shape.style(), fallbackColor)) {
+        bool hasFallback;
+        if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(const_cast<RenderSVGShape*>(&shape), shape.style(), hasFallback)) {
             TextStreamSeparator s(" ");
             ts << " [stroke={" << s;
             writeSVGPaintingResource(ts, strokePaintingResource);
 
             SVGLengthContext lengthContext(shape.element());
-            double dashOffset = svgStyle->strokeDashOffset().value(lengthContext);
-            double strokeWidth = svgStyle->strokeWidth().value(lengthContext);
-            const Vector<SVGLength>& dashes = svgStyle->strokeDashArray();
+            double dashOffset = svgStyle.strokeDashOffset()->value(lengthContext);
+            double strokeWidth = svgStyle.strokeWidth()->value(lengthContext);
+            RefPtr<SVGLengthList> dashes = svgStyle.strokeDashArray();
 
             DashArray dashArray;
-            const Vector<SVGLength>::const_iterator end = dashes.end();
-            for (Vector<SVGLength>::const_iterator it = dashes.begin(); it != end; ++it)
-                dashArray.append((*it).value(lengthContext));
+            SVGLengthList::ConstIterator it = dashes->begin();
+            SVGLengthList::ConstIterator itEnd = dashes->end();
+            for (; it != itEnd; ++it)
+                dashArray.append(it->value(lengthContext));
 
-            writeIfNotDefault(ts, "opacity", svgStyle->strokeOpacity(), 1.0f);
+            writeIfNotDefault(ts, "opacity", svgStyle.strokeOpacity(), 1.0f);
             writeIfNotDefault(ts, "stroke width", strokeWidth, 1.0);
-            writeIfNotDefault(ts, "miter limit", svgStyle->strokeMiterLimit(), 4.0f);
-            writeIfNotDefault(ts, "line cap", svgStyle->capStyle(), ButtCap);
-            writeIfNotDefault(ts, "line join", svgStyle->joinStyle(), MiterJoin);
+            writeIfNotDefault(ts, "miter limit", svgStyle.strokeMiterLimit(), 4.0f);
+            writeIfNotDefault(ts, "line cap", svgStyle.capStyle(), ButtCap);
+            writeIfNotDefault(ts, "line join", svgStyle.joinStyle(), MiterJoin);
             writeIfNotDefault(ts, "dash offset", dashOffset, 0.0);
             if (!dashArray.isEmpty())
                 writeNameValuePair(ts, "dash array", dashArray);
@@ -288,21 +309,21 @@ static void writeStyle(TextStream& ts, const RenderObject& object)
             ts << "}]";
         }
 
-        if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(const_cast<RenderSVGShape*>(&shape), shape.style(), fallbackColor)) {
+        if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(const_cast<RenderSVGShape*>(&shape), shape.style(), hasFallback)) {
             TextStreamSeparator s(" ");
             ts << " [fill={" << s;
             writeSVGPaintingResource(ts, fillPaintingResource);
 
-            writeIfNotDefault(ts, "opacity", svgStyle->fillOpacity(), 1.0f);
-            writeIfNotDefault(ts, "fill rule", svgStyle->fillRule(), RULE_NONZERO);
+            writeIfNotDefault(ts, "opacity", svgStyle.fillOpacity(), 1.0f);
+            writeIfNotDefault(ts, "fill rule", svgStyle.fillRule(), RULE_NONZERO);
             ts << "}]";
         }
-        writeIfNotDefault(ts, "clip rule", svgStyle->clipRule(), RULE_NONZERO);
+        writeIfNotDefault(ts, "clip rule", svgStyle.clipRule(), RULE_NONZERO);
     }
 
-    writeIfNotEmpty(ts, "start marker", svgStyle->markerStartResource());
-    writeIfNotEmpty(ts, "middle marker", svgStyle->markerMidResource());
-    writeIfNotEmpty(ts, "end marker", svgStyle->markerEndResource());
+    writeIfNotEmpty(ts, "start marker", svgStyle.markerStartResource());
+    writeIfNotEmpty(ts, "middle marker", svgStyle.markerMidResource());
+    writeIfNotEmpty(ts, "end marker", svgStyle.markerEndResource());
 }
 
 static TextStream& writePositionAndStyle(TextStream& ts, const RenderObject& object)
@@ -317,37 +338,38 @@ static TextStream& operator<<(TextStream& ts, const RenderSVGShape& shape)
     writePositionAndStyle(ts, shape);
 
     SVGElement* svgElement = shape.element();
+    ASSERT(svgElement);
     SVGLengthContext lengthContext(svgElement);
 
-    if (svgElement->hasTagName(SVGNames::rectTag)) {
-        SVGRectElement* element = toSVGRectElement(svgElement);
-        writeNameValuePair(ts, "x", element->xCurrentValue().value(lengthContext));
-        writeNameValuePair(ts, "y", element->yCurrentValue().value(lengthContext));
-        writeNameValuePair(ts, "width", element->widthCurrentValue().value(lengthContext));
-        writeNameValuePair(ts, "height", element->heightCurrentValue().value(lengthContext));
-    } else if (svgElement->hasTagName(SVGNames::lineTag)) {
-        SVGLineElement* element = toSVGLineElement(svgElement);
-        writeNameValuePair(ts, "x1", element->x1CurrentValue().value(lengthContext));
-        writeNameValuePair(ts, "y1", element->y1CurrentValue().value(lengthContext));
-        writeNameValuePair(ts, "x2", element->x2CurrentValue().value(lengthContext));
-        writeNameValuePair(ts, "y2", element->y2CurrentValue().value(lengthContext));
-    } else if (svgElement->hasTagName(SVGNames::ellipseTag)) {
-        SVGEllipseElement* element = toSVGEllipseElement(svgElement);
-        writeNameValuePair(ts, "cx", element->cxCurrentValue().value(lengthContext));
-        writeNameValuePair(ts, "cy", element->cyCurrentValue().value(lengthContext));
-        writeNameValuePair(ts, "rx", element->rxCurrentValue().value(lengthContext));
-        writeNameValuePair(ts, "ry", element->ryCurrentValue().value(lengthContext));
-    } else if (svgElement->hasTagName(SVGNames::circleTag)) {
-        SVGCircleElement* element = toSVGCircleElement(svgElement);
-        writeNameValuePair(ts, "cx", element->cxCurrentValue().value(lengthContext));
-        writeNameValuePair(ts, "cy", element->cyCurrentValue().value(lengthContext));
-        writeNameValuePair(ts, "r", element->rCurrentValue().value(lengthContext));
-    } else if (svgElement->hasTagName(SVGNames::polygonTag) || svgElement->hasTagName(SVGNames::polylineTag)) {
-        writeNameAndQuotedValue(ts, "points", toSVGPolyElement(svgElement)->pointList().valueAsString());
-    } else if (svgElement->hasTagName(SVGNames::pathTag)) {
+    if (isSVGRectElement(*svgElement)) {
+        SVGRectElement& element = toSVGRectElement(*svgElement);
+        writeNameValuePair(ts, "x", element.x()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "y", element.y()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "width", element.width()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "height", element.height()->currentValue()->value(lengthContext));
+    } else if (isSVGLineElement(*svgElement)) {
+        SVGLineElement& element = toSVGLineElement(*svgElement);
+        writeNameValuePair(ts, "x1", element.x1()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "y1", element.y1()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "x2", element.x2()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "y2", element.y2()->currentValue()->value(lengthContext));
+    } else if (isSVGEllipseElement(*svgElement)) {
+        SVGEllipseElement& element = toSVGEllipseElement(*svgElement);
+        writeNameValuePair(ts, "cx", element.cx()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "cy", element.cy()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "rx", element.rx()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "ry", element.ry()->currentValue()->value(lengthContext));
+    } else if (isSVGCircleElement(*svgElement)) {
+        SVGCircleElement& element = toSVGCircleElement(*svgElement);
+        writeNameValuePair(ts, "cx", element.cx()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "cy", element.cy()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "r", element.r()->currentValue()->value(lengthContext));
+    } else if (isSVGPolyElement(*svgElement)) {
+        writeNameAndQuotedValue(ts, "points", toSVGPolyElement(*svgElement).points()->currentValue()->valueAsString());
+    } else if (isSVGPathElement(*svgElement)) {
         String pathString;
         // FIXME: We should switch to UnalteredParsing here - this will affect the path dumping output of dozens of tests.
-        buildStringFromByteStream(toSVGPathElement(svgElement)->pathByteStream(), pathString, NormalizedParsing);
+        buildStringFromByteStream(toSVGPathElement(*svgElement).pathByteStream(), pathString, NormalizedParsing);
         writeNameAndQuotedValue(ts, "data", pathString);
     } else
         ASSERT_NOT_REACHED();
@@ -380,11 +402,10 @@ static inline void writeSVGInlineTextBox(TextStream& ts, SVGInlineTextBox* textB
     if (fragments.isEmpty())
         return;
 
-    RenderSVGInlineText* textRenderer = toRenderSVGInlineText(textBox->textRenderer());
-    ASSERT(textRenderer);
+    RenderSVGInlineText& textRenderer = toRenderSVGInlineText(textBox->renderer());
 
-    const SVGRenderStyle* svgStyle = textRenderer->style()->svgStyle();
-    String text = textBox->textRenderer()->text();
+    const SVGRenderStyle& svgStyle = textRenderer.style()->svgStyle();
+    String text = textBox->renderer().text();
 
     unsigned fragmentsSize = fragments.size();
     for (unsigned i = 0; i < fragmentsSize; ++i) {
@@ -396,8 +417,8 @@ static inline void writeSVGInlineTextBox(TextStream& ts, SVGInlineTextBox* textB
 
         // FIXME: Remove this hack, once the new text layout engine is completly landed. We want to preserve the old layout test results for now.
         ts << "chunk 1 ";
-        ETextAnchor anchor = svgStyle->textAnchor();
-        bool isVerticalText = svgStyle->isVerticalWritingMode();
+        ETextAnchor anchor = svgStyle.textAnchor();
+        bool isVerticalText = svgStyle.isVerticalWritingMode();
         if (anchor == TA_MIDDLE) {
             ts << "(middle anchor";
             if (isVerticalText)
@@ -452,7 +473,7 @@ static void writeStandardPrefix(TextStream& ts, const RenderObject& object, int
 
 static void writeChildren(TextStream& ts, const RenderObject& object, int indent)
 {
-    for (RenderObject* child = object.firstChild(); child; child = child->nextSibling())
+    for (RenderObject* child = object.slowFirstChild(); child; child = child->nextSibling())
         write(ts, *child, indent + 1);
 }
 
@@ -490,7 +511,8 @@ void writeSVGResourceContainer(TextStream& ts, const RenderObject& object, int i
         ts << "\n";
         // Creating a placeholder filter which is passed to the builder.
         FloatRect dummyRect;
-        RefPtr<SVGFilter> dummyFilter = SVGFilter::create(AffineTransform(), dummyRect, dummyRect, dummyRect, true);
+        IntRect dummyIntRect;
+        RefPtr<SVGFilter> dummyFilter = SVGFilter::create(AffineTransform(), dummyIntRect, dummyRect, dummyRect, true);
         if (RefPtr<SVGFilterBuilder> builder = filter->buildPrimitives(dummyFilter.get())) {
             if (FilterEffect* lastEffect = builder->lastEffect())
                 lastEffect->externalRepresentation(ts, indent + 1);
@@ -614,42 +636,42 @@ void writeSVGGradientStop(TextStream& ts, const RenderSVGGradientStop& stop, int
     if (!style)
         return;
 
-    ts << " [offset=" << stopElement->offsetCurrentValue() << "] [color=" << stopElement->stopColorIncludingOpacity() << "]\n";
+    ts << " [offset=" << stopElement->offset()->currentValue()->value() << "] [color=" << stopElement->stopColorIncludingOpacity() << "]\n";
 }
 
 void writeResources(TextStream& ts, const RenderObject& object, int indent)
 {
     const RenderStyle* style = object.style();
-    const SVGRenderStyle* svgStyle = style->svgStyle();
+    const SVGRenderStyle& svgStyle = style->svgStyle();
 
     // FIXME: We want to use SVGResourcesCache to determine which resources are present, instead of quering the resource <-> id cache.
     // For now leave the DRT output as is, but later on we should change this so cycles are properly ignored in the DRT output.
     RenderObject& renderer = const_cast<RenderObject&>(object);
-    if (!svgStyle->maskerResource().isEmpty()) {
-        if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object.document(), svgStyle->maskerResource())) {
+    if (!svgStyle.maskerResource().isEmpty()) {
+        if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object.document(), svgStyle.maskerResource())) {
             writeIndent(ts, indent);
             ts << " ";
-            writeNameAndQuotedValue(ts, "masker", svgStyle->maskerResource());
+            writeNameAndQuotedValue(ts, "masker", svgStyle.maskerResource());
             ts << " ";
             writeStandardPrefix(ts, *masker, 0);
             ts << " " << masker->resourceBoundingBox(&renderer) << "\n";
         }
     }
-    if (!svgStyle->clipperResource().isEmpty()) {
-        if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(object.document(), svgStyle->clipperResource())) {
+    if (!svgStyle.clipperResource().isEmpty()) {
+        if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(object.document(), svgStyle.clipperResource())) {
             writeIndent(ts, indent);
             ts << " ";
-            writeNameAndQuotedValue(ts, "clipPath", svgStyle->clipperResource());
+            writeNameAndQuotedValue(ts, "clipPath", svgStyle.clipperResource());
             ts << " ";
             writeStandardPrefix(ts, *clipper, 0);
             ts << " " << clipper->resourceBoundingBox(&renderer) << "\n";
         }
     }
-    if (!svgStyle->filterResource().isEmpty()) {
-        if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(object.document(), svgStyle->filterResource())) {
+    if (!svgStyle.filterResource().isEmpty()) {
+        if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(object.document(), svgStyle.filterResource())) {
             writeIndent(ts, indent);
             ts << " ";
-            writeNameAndQuotedValue(ts, "filter", svgStyle->filterResource());
+            writeNameAndQuotedValue(ts, "filter", svgStyle.filterResource());
             ts << " ";
             writeStandardPrefix(ts, *filter, 0);
             ts << " " << filter->resourceBoundingBox(&renderer) << "\n";
@@ -657,4 +679,4 @@ void writeResources(TextStream& ts, const RenderObject& object, int indent)
     }
 }
 
-} // namespace WebCore
+} // namespace blink