diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp')
-rw-r--r-- | Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp | 361 |
1 files changed, 141 insertions, 220 deletions
diff --git a/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp b/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp index aa6040968..8823bc668 100644 --- a/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp +++ b/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp @@ -13,10 +13,10 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR @@ -27,14 +27,12 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGRenderTreeAsText.h" #include "GraphicsTypes.h" -#include "HTMLNames.h" #include "NodeRenderStyle.h" #include "RenderImage.h" +#include "RenderIterator.h" #include "RenderSVGGradientStop.h" #include "RenderSVGImage.h" #include "RenderSVGPath.h" @@ -48,15 +46,12 @@ #include "RenderSVGResourceSolidColor.h" #include "RenderSVGRoot.h" #include "RenderSVGText.h" -#include "RenderTreeAsText.h" #include "SVGCircleElement.h" #include "SVGEllipseElement.h" #include "SVGInlineTextBox.h" #include "SVGLineElement.h" -#include "SVGNames.h" #include "SVGPathElement.h" #include "SVGPathUtilities.h" -#include "SVGPointList.h" #include "SVGPolyElement.h" #include "SVGRectElement.h" #include "SVGRootInlineBox.h" @@ -119,45 +114,6 @@ static void writeIfNotDefault(TextStream& ts, const char* name, ValueType value, writeNameValuePair(ts, name, value); } -TextStream& operator<<(TextStream& ts, const FloatRect& r) -{ - ts << "at (" << TextStream::FormatNumberRespectingIntegers(r.x()); - ts << "," << TextStream::FormatNumberRespectingIntegers(r.y()); - ts << ") size " << TextStream::FormatNumberRespectingIntegers(r.width()); - ts << "x" << TextStream::FormatNumberRespectingIntegers(r.height()); - return ts; -} - -TextStream& operator<<(TextStream& ts, const AffineTransform& transform) -{ - if (transform.isIdentity()) - ts << "identity"; - else - ts << "{m=((" - << transform.a() << "," << transform.b() - << ")(" - << transform.c() << "," << transform.d() - << ")) t=(" - << transform.e() << "," << transform.f() - << ")}"; - - return ts; -} - -static TextStream& operator<<(TextStream& ts, const WindRule rule) -{ - switch (rule) { - case RULE_NONZERO: - ts << "NON-ZERO"; - break; - case RULE_EVENODD: - ts << "EVEN-ODD"; - break; - } - - return ts; -} - static TextStream& operator<<(TextStream& ts, const SVGUnitTypes::SVGUnitType& unitType) { ts << SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::toString(unitType); @@ -170,11 +126,6 @@ static TextStream& operator<<(TextStream& ts, const SVGMarkerUnitsType& markerUn return ts; } -TextStream& operator<<(TextStream& ts, const Color& c) -{ - return ts << c.nameForRenderTreeAsText(); -} - // FIXME: Maybe this should be in KCanvasRenderingStyle.cpp static TextStream& operator<<(TextStream& ts, const DashArray& a) { @@ -189,43 +140,9 @@ static TextStream& operator<<(TextStream& ts, const DashArray& a) return ts; } -// FIXME: Maybe this should be in GraphicsTypes.cpp -static TextStream& operator<<(TextStream& ts, LineCap style) -{ - switch (style) { - case ButtCap: - ts << "BUTT"; - break; - case RoundCap: - ts << "ROUND"; - break; - case SquareCap: - ts << "SQUARE"; - break; - } - return ts; -} - -// FIXME: Maybe this should be in GraphicsTypes.cpp -static TextStream& operator<<(TextStream& ts, LineJoin style) -{ - switch (style) { - case MiterJoin: - ts << "MITER"; - break; - case RoundJoin: - ts << "ROUND"; - break; - case BevelJoin: - ts << "BEVEL"; - break; - } - return ts; -} - static TextStream& operator<<(TextStream& ts, const SVGSpreadMethodType& type) { - ts << SVGPropertyTraits<SVGSpreadMethodType>::toString(type).upper(); + ts << SVGPropertyTraits<SVGSpreadMethodType>::toString(type).convertToASCIIUppercase(); return ts; } @@ -250,17 +167,17 @@ static void writeSVGPaintingResource(TextStream& ts, RenderSVGResource* resource ts << " [id=\"" << element.getIdAttribute() << "\"]"; } -static void writeStyle(TextStream& ts, const RenderObject& object) +static void writeStyle(TextStream& ts, const RenderElement& renderer) { - const RenderStyle& style = object.style(); + const RenderStyle& style = renderer.style(); const SVGRenderStyle& svgStyle = style.svgStyle(); - if (!object.localTransform().isIdentity()) - writeNameValuePair(ts, "transform", object.localTransform()); + if (!renderer.localTransform().isIdentity()) + writeNameValuePair(ts, "transform", renderer.localTransform()); writeIfNotDefault(ts, "image rendering", style.imageRendering(), RenderStyle::initialImageRendering()); writeIfNotDefault(ts, "opacity", style.opacity(), RenderStyle::initialOpacity()); - if (object.isSVGShape()) { - const RenderSVGShape& shape = static_cast<const RenderSVGShape&>(object); + if (is<RenderSVGShape>(renderer)) { + const auto& shape = downcast<RenderSVGShape>(renderer); Color fallbackColor; if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(const_cast<RenderSVGShape&>(shape), shape.style(), fallbackColor)) { @@ -269,20 +186,19 @@ static void writeStyle(TextStream& ts, const RenderObject& object) writeSVGPaintingResource(ts, strokePaintingResource); SVGLengthContext lengthContext(&shape.graphicsElement()); - double dashOffset = svgStyle.strokeDashOffset().value(lengthContext); - double strokeWidth = svgStyle.strokeWidth().value(lengthContext); - const Vector<SVGLength>& dashes = svgStyle.strokeDashArray(); + double dashOffset = lengthContext.valueForLength(svgStyle.strokeDashOffset()); + double strokeWidth = lengthContext.valueForLength(style.strokeWidth()); + const auto& 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)); + for (auto& length : dashes) + dashArray.append(length.value(lengthContext)); 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, "line cap", style.capStyle(), ButtCap); + writeIfNotDefault(ts, "line join", style.joinStyle(), MiterJoin); writeIfNotDefault(ts, "dash offset", dashOffset, 0.0); if (!dashArray.isEmpty()) writeNameValuePair(ts, "dash array", dashArray); @@ -307,10 +223,20 @@ static void writeStyle(TextStream& ts, const RenderObject& object) writeIfNotEmpty(ts, "end marker", svgStyle.markerEndResource()); } -static TextStream& writePositionAndStyle(TextStream& ts, const RenderObject& object) +static TextStream& writePositionAndStyle(TextStream& ts, const RenderElement& renderer, RenderAsTextBehavior behavior = RenderAsTextBehaviorNormal) { - ts << " " << enclosingIntRect(const_cast<RenderObject&>(object).absoluteClippedOverflowRect()); - writeStyle(ts, object); + if (behavior & RenderAsTextShowSVGGeometry) { + if (is<RenderBox>(renderer)) { + LayoutRect r = downcast<RenderBox>(renderer).frameRect(); + ts << " " << enclosingIntRect(r); + } + + ts << " clipped"; + } + + ts << " " << enclosingIntRect(renderer.absoluteClippedOverflowRect()); + + writeStyle(ts, renderer); return ts; } @@ -321,34 +247,34 @@ static TextStream& operator<<(TextStream& ts, const RenderSVGShape& shape) SVGGraphicsElement& svgElement = shape.graphicsElement(); SVGLengthContext lengthContext(&svgElement); - if (isSVGRectElement(svgElement)) { - const SVGRectElement& element = toSVGRectElement(svgElement); + if (is<SVGRectElement>(svgElement)) { + const SVGRectElement& element = downcast<SVGRectElement>(svgElement); writeNameValuePair(ts, "x", element.x().value(lengthContext)); writeNameValuePair(ts, "y", element.y().value(lengthContext)); writeNameValuePair(ts, "width", element.width().value(lengthContext)); writeNameValuePair(ts, "height", element.height().value(lengthContext)); - } else if (isSVGLineElement(svgElement)) { - const SVGLineElement& element = toSVGLineElement(svgElement); + } else if (is<SVGLineElement>(svgElement)) { + const SVGLineElement& element = downcast<SVGLineElement>(svgElement); writeNameValuePair(ts, "x1", element.x1().value(lengthContext)); writeNameValuePair(ts, "y1", element.y1().value(lengthContext)); writeNameValuePair(ts, "x2", element.x2().value(lengthContext)); writeNameValuePair(ts, "y2", element.y2().value(lengthContext)); - } else if (isSVGEllipseElement(svgElement)) { - const SVGEllipseElement& element = toSVGEllipseElement(svgElement); + } else if (is<SVGEllipseElement>(svgElement)) { + const SVGEllipseElement& element = downcast<SVGEllipseElement>(svgElement); writeNameValuePair(ts, "cx", element.cx().value(lengthContext)); writeNameValuePair(ts, "cy", element.cy().value(lengthContext)); writeNameValuePair(ts, "rx", element.rx().value(lengthContext)); writeNameValuePair(ts, "ry", element.ry().value(lengthContext)); - } else if (isSVGCircleElement(svgElement)) { - const SVGCircleElement& element = toSVGCircleElement(svgElement); + } else if (is<SVGCircleElement>(svgElement)) { + const SVGCircleElement& element = downcast<SVGCircleElement>(svgElement); writeNameValuePair(ts, "cx", element.cx().value(lengthContext)); writeNameValuePair(ts, "cy", element.cy().value(lengthContext)); writeNameValuePair(ts, "r", element.r().value(lengthContext)); - } else if (svgElement.hasTagName(SVGNames::polygonTag) || svgElement.hasTagName(SVGNames::polylineTag)) { - const SVGPolyElement& element = toSVGPolyElement(svgElement); + } else if (is<SVGPolyElement>(svgElement)) { + const SVGPolyElement& element = downcast<SVGPolyElement>(svgElement); writeNameAndQuotedValue(ts, "points", element.pointList().valueAsString()); - } else if (isSVGPathElement(svgElement)) { - const SVGPathElement& element = toSVGPathElement(svgElement); + } else if (is<SVGPathElement>(svgElement)) { + const SVGPathElement& element = downcast<SVGPathElement>(svgElement); String pathString; // FIXME: We should switch to UnalteredParsing here - this will affect the path dumping output of dozens of tests. buildStringFromByteStream(element.pathByteStream(), pathString, NormalizedParsing); @@ -358,14 +284,9 @@ static TextStream& operator<<(TextStream& ts, const RenderSVGShape& shape) return ts; } -static TextStream& operator<<(TextStream& ts, const RenderSVGRoot& root) -{ - return writePositionAndStyle(ts, root); -} - static void writeRenderSVGTextBox(TextStream& ts, const RenderSVGText& text) { - SVGRootInlineBox* box = toSVGRootInlineBox(text.firstRootBox()); + auto* box = downcast<SVGRootInlineBox>(text.firstRootBox()); if (!box) return; @@ -398,7 +319,7 @@ 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(); + bool isVerticalText = textBox->renderer().style().isVerticalWritingMode(); if (anchor == TA_MIDDLE) { ts << "(middle anchor"; if (isVerticalText) @@ -435,26 +356,31 @@ static inline void writeSVGInlineTextBox(TextStream& ts, SVGInlineTextBox* textB static inline void writeSVGInlineTextBoxes(TextStream& ts, const RenderText& text, int indent) { for (InlineTextBox* box = text.firstTextBox(); box; box = box->nextTextBox()) { - if (!box->isSVGInlineTextBox()) + if (!is<SVGInlineTextBox>(*box)) continue; - writeSVGInlineTextBox(ts, toSVGInlineTextBox(box), indent); + writeSVGInlineTextBox(ts, downcast<SVGInlineTextBox>(box), indent); } } -static void writeStandardPrefix(TextStream& ts, const RenderObject& object, int indent) +static void writeStandardPrefix(TextStream& ts, const RenderObject& object, int indent, RenderAsTextBehavior behavior) { writeIndent(ts, indent); ts << object.renderName(); + if (behavior & RenderAsTextShowAddresses) + ts << " " << static_cast<const void*>(&object); + if (object.node()) ts << " {" << object.node()->nodeName() << "}"; + + writeDebugInfo(ts, object, behavior); } -static void writeChildren(TextStream& ts, const RenderObject& object, int indent) +static void writeChildren(TextStream& ts, const RenderElement& parent, int indent, RenderAsTextBehavior behavior) { - for (RenderObject* child = object.firstChildSlow(); child; child = child->nextSibling()) - write(ts, *child, indent + 1); + for (const auto& child : childrenOfType<RenderObject>(parent)) + write(ts, child, indent + 1, behavior); } static inline void writeCommonGradientProperties(TextStream& ts, SVGSpreadMethodType spreadMethod, const AffineTransform& gradientTransform, SVGUnitTypes::SVGUnitType gradientUnits) @@ -468,56 +394,50 @@ static inline void writeCommonGradientProperties(TextStream& ts, SVGSpreadMethod ts << " [gradientTransform=" << gradientTransform << "]"; } -void writeSVGResourceContainer(TextStream& ts, const RenderObject& object, int indent) +void writeSVGResourceContainer(TextStream& ts, const RenderSVGResourceContainer& resource, int indent, RenderAsTextBehavior behavior) { - writeStandardPrefix(ts, object, indent); + writeStandardPrefix(ts, resource, indent, behavior); - Element* element = toElement(object.node()); - const AtomicString& id = element->getIdAttribute(); + const AtomicString& id = resource.element().getIdAttribute(); writeNameAndQuotedValue(ts, "id", id); - RenderSVGResourceContainer* resource = const_cast<RenderObject&>(object).toRenderSVGResourceContainer(); - ASSERT(resource); - - if (resource->resourceType() == MaskerResourceType) { - RenderSVGResourceMasker* masker = static_cast<RenderSVGResourceMasker*>(resource); - writeNameValuePair(ts, "maskUnits", masker->maskUnits()); - writeNameValuePair(ts, "maskContentUnits", masker->maskContentUnits()); + if (resource.resourceType() == MaskerResourceType) { + const auto& masker = static_cast<const RenderSVGResourceMasker&>(resource); + writeNameValuePair(ts, "maskUnits", masker.maskUnits()); + writeNameValuePair(ts, "maskContentUnits", masker.maskContentUnits()); ts << "\n"; -#if ENABLE(FILTERS) - } else if (resource->resourceType() == FilterResourceType) { - RenderSVGResourceFilter* filter = static_cast<RenderSVGResourceFilter*>(resource); - writeNameValuePair(ts, "filterUnits", filter->filterUnits()); - writeNameValuePair(ts, "primitiveUnits", filter->primitiveUnits()); + } else if (resource.resourceType() == FilterResourceType) { + const auto& filter = static_cast<const RenderSVGResourceFilter&>(resource); + writeNameValuePair(ts, "filterUnits", filter.filterUnits()); + writeNameValuePair(ts, "primitiveUnits", filter.primitiveUnits()); ts << "\n"; // Creating a placeholder filter which is passed to the builder. FloatRect dummyRect; RefPtr<SVGFilter> dummyFilter = SVGFilter::create(AffineTransform(), dummyRect, dummyRect, dummyRect, true); - if (auto builder = filter->buildPrimitives(dummyFilter.get())) { + if (auto builder = filter.buildPrimitives(*dummyFilter)) { if (FilterEffect* lastEffect = builder->lastEffect()) lastEffect->externalRepresentation(ts, indent + 1); } -#endif - } else if (resource->resourceType() == ClipperResourceType) { - RenderSVGResourceClipper* clipper = static_cast<RenderSVGResourceClipper*>(resource); - writeNameValuePair(ts, "clipPathUnits", clipper->clipPathUnits()); + } else if (resource.resourceType() == ClipperResourceType) { + const auto& clipper = static_cast<const RenderSVGResourceClipper&>(resource); + writeNameValuePair(ts, "clipPathUnits", clipper.clipPathUnits()); ts << "\n"; - } else if (resource->resourceType() == MarkerResourceType) { - RenderSVGResourceMarker* marker = static_cast<RenderSVGResourceMarker*>(resource); - writeNameValuePair(ts, "markerUnits", marker->markerUnits()); - ts << " [ref at " << marker->referencePoint() << "]"; + } else if (resource.resourceType() == MarkerResourceType) { + const auto& marker = static_cast<const RenderSVGResourceMarker&>(resource); + writeNameValuePair(ts, "markerUnits", marker.markerUnits()); + ts << " [ref at " << marker.referencePoint() << "]"; ts << " [angle="; - if (marker->angle() == -1) + if (marker.angle() == -1) ts << "auto" << "]\n"; else - ts << marker->angle() << "]\n"; - } else if (resource->resourceType() == PatternResourceType) { - RenderSVGResourcePattern* pattern = static_cast<RenderSVGResourcePattern*>(resource); + ts << marker.angle() << "]\n"; + } else if (resource.resourceType() == PatternResourceType) { + const auto& pattern = static_cast<const RenderSVGResourcePattern&>(resource); // Dump final results that are used for rendering. No use in asking SVGPatternElement for its patternUnits(), as it may // link to other patterns using xlink:href, we need to build the full inheritance chain, aka. collectPatternProperties() PatternAttributes attributes; - pattern->patternElement().collectPatternAttributes(attributes); + pattern.collectPatternAttributes(attributes); writeNameValuePair(ts, "patternUnits", attributes.patternUnits()); writeNameValuePair(ts, "patternContentUnits", attributes.patternContentUnits()); @@ -526,139 +446,140 @@ void writeSVGResourceContainer(TextStream& ts, const RenderObject& object, int i if (!transform.isIdentity()) ts << " [patternTransform=" << transform << "]"; ts << "\n"; - } else if (resource->resourceType() == LinearGradientResourceType) { - RenderSVGResourceLinearGradient* gradient = static_cast<RenderSVGResourceLinearGradient*>(resource); + } else if (resource.resourceType() == LinearGradientResourceType) { + const auto& gradient = static_cast<const RenderSVGResourceLinearGradient&>(resource); // Dump final results that are used for rendering. No use in asking SVGGradientElement for its gradientUnits(), as it may // link to other gradients using xlink:href, we need to build the full inheritance chain, aka. collectGradientProperties() LinearGradientAttributes attributes; - gradient->linearGradientElement().collectGradientAttributes(attributes); + gradient.linearGradientElement().collectGradientAttributes(attributes); writeCommonGradientProperties(ts, attributes.spreadMethod(), attributes.gradientTransform(), attributes.gradientUnits()); - ts << " [start=" << gradient->startPoint(attributes) << "] [end=" << gradient->endPoint(attributes) << "]\n"; - } else if (resource->resourceType() == RadialGradientResourceType) { - RenderSVGResourceRadialGradient* gradient = static_cast<RenderSVGResourceRadialGradient*>(resource); + ts << " [start=" << gradient.startPoint(attributes) << "] [end=" << gradient.endPoint(attributes) << "]\n"; + } else if (resource.resourceType() == RadialGradientResourceType) { + const auto& gradient = static_cast<const RenderSVGResourceRadialGradient&>(resource); // Dump final results that are used for rendering. No use in asking SVGGradientElement for its gradientUnits(), as it may // link to other gradients using xlink:href, we need to build the full inheritance chain, aka. collectGradientProperties() RadialGradientAttributes attributes; - gradient->radialGradientElement().collectGradientAttributes(attributes); + gradient.radialGradientElement().collectGradientAttributes(attributes); writeCommonGradientProperties(ts, attributes.spreadMethod(), attributes.gradientTransform(), attributes.gradientUnits()); - FloatPoint focalPoint = gradient->focalPoint(attributes); - FloatPoint centerPoint = gradient->centerPoint(attributes); - float radius = gradient->radius(attributes); - float focalRadius = gradient->focalRadius(attributes); + FloatPoint focalPoint = gradient.focalPoint(attributes); + FloatPoint centerPoint = gradient.centerPoint(attributes); + float radius = gradient.radius(attributes); + float focalRadius = gradient.focalRadius(attributes); ts << " [center=" << centerPoint << "] [focal=" << focalPoint << "] [radius=" << radius << "] [focalRadius=" << focalRadius << "]\n"; } else ts << "\n"; - writeChildren(ts, object, indent); + writeChildren(ts, resource, indent, behavior); } -void writeSVGContainer(TextStream& ts, const RenderObject& container, int indent) +void writeSVGContainer(TextStream& ts, const RenderSVGContainer& container, int indent, RenderAsTextBehavior behavior) { // Currently RenderSVGResourceFilterPrimitive has no meaningful output. if (container.isSVGResourceFilterPrimitive()) return; - writeStandardPrefix(ts, container, indent); - writePositionAndStyle(ts, container); + writeStandardPrefix(ts, container, indent, behavior); + writePositionAndStyle(ts, container, behavior); ts << "\n"; - writeResources(ts, container, indent); - writeChildren(ts, container, indent); + writeResources(ts, container, indent, behavior); + writeChildren(ts, container, indent, behavior); } -void write(TextStream& ts, const RenderSVGRoot& root, int indent) +void write(TextStream& ts, const RenderSVGRoot& root, int indent, RenderAsTextBehavior behavior) { - writeStandardPrefix(ts, root, indent); - ts << root << "\n"; - writeChildren(ts, root, indent); + writeStandardPrefix(ts, root, indent, behavior); + writePositionAndStyle(ts, root, behavior); + ts << "\n"; + writeChildren(ts, root, indent, behavior); } -void writeSVGText(TextStream& ts, const RenderSVGText& text, int indent) +void writeSVGText(TextStream& ts, const RenderSVGText& text, int indent, RenderAsTextBehavior behavior) { - writeStandardPrefix(ts, text, indent); + writeStandardPrefix(ts, text, indent, behavior); writeRenderSVGTextBox(ts, text); ts << "\n"; - writeResources(ts, text, indent); - writeChildren(ts, text, indent); + writeResources(ts, text, indent, behavior); + writeChildren(ts, text, indent, behavior); } -void writeSVGInlineText(TextStream& ts, const RenderSVGInlineText& text, int indent) +void writeSVGInlineText(TextStream& ts, const RenderSVGInlineText& text, int indent, RenderAsTextBehavior behavior) { - writeStandardPrefix(ts, text, indent); - ts << " " << enclosingIntRect(FloatRect(text.firstRunOrigin(), text.floatLinesBoundingBox().size())) << "\n"; - writeResources(ts, text, indent); + writeStandardPrefix(ts, text, indent, behavior); + ts << " " << enclosingIntRect(FloatRect(text.firstRunLocation(), text.floatLinesBoundingBox().size())) << "\n"; + writeResources(ts, text, indent, behavior); writeSVGInlineTextBoxes(ts, text, indent); } -void writeSVGImage(TextStream& ts, const RenderSVGImage& image, int indent) +void writeSVGImage(TextStream& ts, const RenderSVGImage& image, int indent, RenderAsTextBehavior behavior) { - writeStandardPrefix(ts, image, indent); - writePositionAndStyle(ts, image); + writeStandardPrefix(ts, image, indent, behavior); + writePositionAndStyle(ts, image, behavior); ts << "\n"; - writeResources(ts, image, indent); + writeResources(ts, image, indent, behavior); } -void write(TextStream& ts, const RenderSVGShape& shape, int indent) +void write(TextStream& ts, const RenderSVGShape& shape, int indent, RenderAsTextBehavior behavior) { - writeStandardPrefix(ts, shape, indent); + writeStandardPrefix(ts, shape, indent, behavior); ts << shape << "\n"; - writeResources(ts, shape, indent); + writeResources(ts, shape, indent, behavior); } -void writeSVGGradientStop(TextStream& ts, const RenderSVGGradientStop& stop, int indent) +void writeSVGGradientStop(TextStream& ts, const RenderSVGGradientStop& stop, int indent, RenderAsTextBehavior behavior) { - writeStandardPrefix(ts, stop, indent); + writeStandardPrefix(ts, stop, indent, behavior); - SVGStopElement* stopElement = toSVGStopElement(toSVGElement(stop.element())); - ASSERT(stopElement); - - ts << " [offset=" << stopElement->offset() << "] [color=" << stopElement->stopColorIncludingOpacity() << "]\n"; + ts << " [offset=" << stop.element().offset() << "] [color=" << stop.element().stopColorIncludingOpacity() << "]\n"; } -void writeResources(TextStream& ts, const RenderObject& object, int indent) +void writeResources(TextStream& ts, const RenderObject& renderer, int indent, RenderAsTextBehavior behavior) { - const RenderStyle& style = object.style(); + const RenderStyle& style = renderer.style(); 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 (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(renderer.document(), svgStyle.maskerResource())) { writeIndent(ts, indent); ts << " "; writeNameAndQuotedValue(ts, "masker", svgStyle.maskerResource()); ts << " "; - writeStandardPrefix(ts, *masker, 0); + writeStandardPrefix(ts, *masker, 0, behavior); ts << " " << masker->resourceBoundingBox(renderer) << "\n"; } } if (!svgStyle.clipperResource().isEmpty()) { - if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(object.document(), svgStyle.clipperResource())) { + if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(renderer.document(), svgStyle.clipperResource())) { writeIndent(ts, indent); ts << " "; writeNameAndQuotedValue(ts, "clipPath", svgStyle.clipperResource()); ts << " "; - writeStandardPrefix(ts, *clipper, 0); + writeStandardPrefix(ts, *clipper, 0, behavior); ts << " " << clipper->resourceBoundingBox(renderer) << "\n"; } } -#if ENABLE(FILTERS) - if (!svgStyle.filterResource().isEmpty()) { - if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(object.document(), svgStyle.filterResource())) { - writeIndent(ts, indent); - ts << " "; - writeNameAndQuotedValue(ts, "filter", svgStyle.filterResource()); - ts << " "; - writeStandardPrefix(ts, *filter, 0); - ts << " " << filter->resourceBoundingBox(renderer) << "\n"; + if (style.hasFilter()) { + const FilterOperations& filterOperations = style.filter(); + if (filterOperations.size() == 1) { + const FilterOperation& filterOperation = *filterOperations.at(0); + if (filterOperation.type() == FilterOperation::REFERENCE) { + const auto& referenceFilterOperation = downcast<ReferenceFilterOperation>(filterOperation); + AtomicString id = SVGURIReference::fragmentIdentifierFromIRIString(referenceFilterOperation.url(), renderer.document()); + if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(renderer.document(), id)) { + writeIndent(ts, indent); + ts << " "; + writeNameAndQuotedValue(ts, "filter", id); + ts << " "; + writeStandardPrefix(ts, *filter, 0, behavior); + ts << " " << filter->resourceBoundingBox(renderer) << "\n"; + } + } } } -#endif } } // namespace WebCore - -#endif // ENABLE(SVG) |