static void writeStyle(TextStream& ts, const RenderObject& object)
{
    const RenderStyle* style = object.style();
    const SVGRenderStyle* svgStyle = style->svgStyle();

    if (!object.localTransform().isIdentity())
        writeNameValuePair(ts, "transform", object.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);
        ASSERT(shape.node());
        ASSERT(shape.node()->isSVGElement());

        Color fallbackColor;
        if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(const_cast<RenderSVGShape*>(&shape), shape.style(), fallbackColor)) {
            TextStreamSeparator s(" ");
            ts << " [stroke={" << s;
            writeSVGPaintingResource(ts, strokePaintingResource);

            SVGLengthContext lengthContext(toSVGElement(shape.node()));
            double dashOffset = svgStyle->strokeDashOffset().value(lengthContext);
            double strokeWidth = svgStyle->strokeWidth().value(lengthContext);
            const Vector<SVGLength>& 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));

            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, "dash offset", dashOffset, 0.0);
            if (!dashArray.isEmpty())
                writeNameValuePair(ts, "dash array", dashArray);

            ts << "}]";
        }

        if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(const_cast<RenderSVGShape*>(&shape), shape.style(), fallbackColor)) {
            TextStreamSeparator s(" ");
            ts << " [fill={" << s;
            writeSVGPaintingResource(ts, fillPaintingResource);

            writeIfNotDefault(ts, "opacity", svgStyle->fillOpacity(), 1.0f);
            writeIfNotDefault(ts, "fill rule", svgStyle->fillRule(), RULE_NONZERO);
            ts << "}]";
        }
        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());
}
static void writeStyle(TextStream& ts, const RenderObject& object)
{
    const RenderStyle* style = object.style();
    const SVGRenderStyle* svgStyle = style->svgStyle();

    if (!object.localTransform().isIdentity())
        writeNameValuePair(ts, "transform", object.localTransform());
    writeIfNotDefault(ts, "image rendering", svgStyle->imageRendering(), SVGRenderStyle::initialImageRendering());
    writeIfNotDefault(ts, "opacity", style->opacity(), RenderStyle::initialOpacity());
    if (object.isRenderPath()) {
        const RenderPath& path = static_cast<const RenderPath&>(object);
        SVGPaintServer* strokePaintServer = SVGPaintServer::strokePaintServer(style, &path);
        if (strokePaintServer) {
            TextStreamSeparator s(" ");
            ts << " [stroke={";
            if (strokePaintServer)
                ts << s << *strokePaintServer;

            double dashOffset = SVGRenderStyle::cssPrimitiveToLength(&path, svgStyle->strokeDashOffset(), 0.0f);
            const DashArray& dashArray = dashArrayFromRenderingStyle(style, object.document()->documentElement()->renderStyle());
            double strokeWidth = SVGRenderStyle::cssPrimitiveToLength(&path, svgStyle->strokeWidth(), 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, "dash offset", dashOffset, 0.0);
            if (!dashArray.isEmpty())
                writeNameValuePair(ts, "dash array", dashArray);

            ts << "}]";
        }
        SVGPaintServer* fillPaintServer = SVGPaintServer::fillPaintServer(style, &path);
        if (fillPaintServer) {
            TextStreamSeparator s(" ");
            ts << " [fill={";
            if (fillPaintServer)
                ts << s << *fillPaintServer;

            writeIfNotDefault(ts, "opacity", svgStyle->fillOpacity(), 1.0f);
            writeIfNotDefault(ts, "fill rule", svgStyle->fillRule(), RULE_NONZERO);
            ts << "}]";
        }
    }

    if (!svgStyle->clipPath().isEmpty())
        writeNameAndQuotedValue(ts, "clip path", svgStyle->clipPath());
    writeIfNotEmpty(ts, "start marker", svgStyle->startMarker());
    writeIfNotEmpty(ts, "middle marker", svgStyle->midMarker());
    writeIfNotEmpty(ts, "end marker", svgStyle->endMarker());
    writeIfNotEmpty(ts, "filter", svgStyle->filter());
}
static void writeStyle(TextStream& ts, const LayoutObject& object)
{
    const ComputedStyle& style = object.styleRef();
    const SVGComputedStyle& svgStyle = style.svgStyle();

    if (!object.localTransform().isIdentity())
        writeNameValuePair(ts, "transform", object.localTransform());
    writeIfNotDefault(ts, "image rendering", style.imageRendering(), ComputedStyle::initialImageRendering());
    writeIfNotDefault(ts, "opacity", style.opacity(), ComputedStyle::initialOpacity());
    if (object.isSVGShape()) {
        const LayoutSVGShape& shape = static_cast<const LayoutSVGShape&>(object);
        ASSERT(shape.element());

        SVGPaintDescription strokePaintDescription = LayoutSVGResourcePaintServer::requestPaintDescription(shape, shape.styleRef(), ApplyToStrokeMode);
        if (strokePaintDescription.isValid) {
            TextStreamSeparator s(" ");
            ts << " [stroke={" << s;
            writeSVGPaintingResource(ts, strokePaintDescription);

            SVGLengthContext lengthContext(shape.element());
            double dashOffset = lengthContext.valueForLength(svgStyle.strokeDashOffset(), style);
            double strokeWidth = lengthContext.valueForLength(svgStyle.strokeWidth());
            DashArray dashArray = SVGLayoutSupport::resolveSVGDashArray(*svgStyle.strokeDashArray(), style, 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, "dash offset", dashOffset, 0.0);
            if (!dashArray.isEmpty())
                writeNameValuePair(ts, "dash array", dashArray);

            ts << "}]";
        }

        SVGPaintDescription fillPaintDescription = LayoutSVGResourcePaintServer::requestPaintDescription(shape, shape.styleRef(), ApplyToFillMode);
        if (fillPaintDescription.isValid) {
            TextStreamSeparator s(" ");
            ts << " [fill={" << s;
            writeSVGPaintingResource(ts, fillPaintDescription);

            writeIfNotDefault(ts, "opacity", svgStyle.fillOpacity(), 1.0f);
            writeIfNotDefault(ts, "fill rule", svgStyle.fillRule(), RULE_NONZERO);
            ts << "}]";
        }
        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());
}
static inline void writeCommonGradientProperties(TextStream& ts, GradientSpreadMethod spreadMethod, const AffineTransform& gradientTransform, bool boundingBoxMode)
{
    writeNameValuePair(ts, "gradientUnits", boundingBoxModeString(boundingBoxMode));

    if (spreadMethod != SpreadMethodPad)
        ts << " [spreadMethod=" << spreadMethod << "]";

    if (!gradientTransform.isIdentity())
        ts << " [gradientTransform=" << gradientTransform << "]";
}
static inline void writeCommonGradientProperties(TextStream& ts, SVGSpreadMethodType spreadMethod, const AffineTransform& gradientTransform, SVGUnitTypes::SVGUnitType gradientUnits)
{
    writeNameValuePair(ts, "gradientUnits", gradientUnits);

    if (spreadMethod != SVGSpreadMethodPad)
        ts << " [spreadMethod=" << spreadMethod << "]";

    if (!gradientTransform.isIdentity())
        ts << " [gradientTransform=" << gradientTransform << "]";
}
static void writeRenderSVGTextBox(TextStream& ts, const RenderBlock& text)
{
    SVGRootInlineBox* box = static_cast<SVGRootInlineBox*>(text.firstRootBox());

    if (!box)
        return;

    Vector<SVGTextChunk>& chunks = const_cast<Vector<SVGTextChunk>& >(box->svgTextChunks());
    ts << " at (" << text.x() << "," << text.y() << ") size " << box->width() << "x" << box->height() << " contains " << chunks.size() << " chunk(s)";

    if (text.parent() && (text.parent()->style()->color() != text.style()->color()))
        writeNameValuePair(ts, "color", text.style()->color().name());
}
示例#7
0
static void writeRenderSVGTextBox(TextStream& ts, const RenderBlock& text)
{
    SVGRootInlineBox* box = static_cast<SVGRootInlineBox*>(text.firstRootBox());
    if (!box)
        return;

    ts << " at (" << text.x() << "," << text.y() << ") size " << box->logicalWidth() << "x" << box->logicalHeight();
    
    // 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 << " contains 1 chunk(s)";

    if (text.parent() && (text.parent()->style()->visitedDependentColor(CSSPropertyColor) != text.style()->visitedDependentColor(CSSPropertyColor)))
        writeNameValuePair(ts, "color", text.style()->visitedDependentColor(CSSPropertyColor).name());
}
static void writeRenderSVGTextBox(TextStream& ts, const RenderSVGText& text)
{
    SVGRootInlineBox* box = toSVGRootInlineBox(text.firstRootBox());
    if (!box)
        return;

    ts << " " << enclosingIntRect(FloatRect(text.location(), FloatSize(box->logicalWidth(), box->logicalHeight())));

    // 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 << " contains 1 chunk(s)";

    if (text.parent() && (text.parent()->style()->visitedDependentColor(CSSPropertyColor) != text.style()->visitedDependentColor(CSSPropertyColor)))
        writeNameValuePair(ts, "color", text.resolveColor(CSSPropertyColor).nameForRenderTreeAsText());
}
void writeSVGResource(TextStream& ts, const RenderObject& object, int indent)
{
    writeStandardPrefix(ts, object, indent);

    Element* element = static_cast<Element*>(object.node());
    const AtomicString& id = element->getIDAttribute();
    writeNameAndQuotedValue(ts, "id", id);    

    RenderSVGResource* resource = const_cast<RenderObject&>(object).toRenderSVGResource();
    if (resource->resourceType() == MaskerResourceType) {
        RenderSVGResourceMasker* masker = static_cast<RenderSVGResourceMasker*>(resource);
        ASSERT(masker);
        writeNameValuePair(ts, "maskUnits", masker->maskUnits());
        writeNameValuePair(ts, "maskContentUnits", masker->maskContentUnits());
    } else if (resource->resourceType() == ClipperResourceType) {
        RenderSVGResourceClipper* clipper = static_cast<RenderSVGResourceClipper*>(resource);
        ASSERT(clipper);
        writeNameValuePair(ts, "clipPathUnits", clipper->clipPathUnits());
    }

    // FIXME: Handle other RenderSVGResource* classes here, after converting them from SVGResource*.
    ts << "\n";
    writeChildren(ts, object, indent);
}
示例#10
0
static void writeRenderSVGTextBox(TextStream& ts, const RenderBlock& text)
{
    SVGRootInlineBox* box = static_cast<SVGRootInlineBox*>(text.firstRootBox());
    if (!box)
        return;

    // FIXME: For now use an int for logicalWidth, although this makes it harder
    // to detect any changes caused by the conversion to floating point. :(
    int logicalWidth = ceilf(box->x() + box->logicalWidth()) - box->x();
    ts << " at (" << text.x() << "," << text.y() << ") size " << logicalWidth << "x" << box->logicalHeight();
    
    // 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 << " contains 1 chunk(s)";

    if (text.parent() && (text.parent()->style()->visitedDependentColor(CSSPropertyColor) != text.style()->visitedDependentColor(CSSPropertyColor)))
        writeNameValuePair(ts, "color", text.style()->visitedDependentColor(CSSPropertyColor).nameForRenderTreeAsText());
}
void writeSVGResourceContainer(TextStream& ts, const RenderObject& object, int indent)
{
    writeStandardPrefix(ts, object, indent);

    Element* element = toElement(object.node());
    const AtomicString& id = element->getIdAttribute();
    writeNameAndQuotedValue(ts, "id", id);

    RenderSVGResourceContainer* resource = const_cast<RenderObject&>(object).toRenderSVGResourceContainer();
    ASSERT(resource);

    if (resource->resourceType() == MaskerResourceType) {
        RenderSVGResourceMasker* masker = toRenderSVGResourceMasker(resource);
        writeNameValuePair(ts, "maskUnits", masker->maskUnits());
        writeNameValuePair(ts, "maskContentUnits", masker->maskContentUnits());
        ts << "\n";
    } else if (resource->resourceType() == FilterResourceType) {
        RenderSVGResourceFilter* filter = toRenderSVGResourceFilter(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 (RefPtr<SVGFilterBuilder> builder = filter->buildPrimitives(dummyFilter.get())) {
            if (FilterEffect* lastEffect = builder->lastEffect())
                lastEffect->externalRepresentation(ts, indent + 1);
        }
    } else if (resource->resourceType() == ClipperResourceType) {
        writeNameValuePair(ts, "clipPathUnits", toRenderSVGResourceClipper(resource)->clipPathUnits());
        ts << "\n";
    } else if (resource->resourceType() == MarkerResourceType) {
        RenderSVGResourceMarker* marker = toRenderSVGResourceMarker(resource);
        writeNameValuePair(ts, "markerUnits", marker->markerUnits());
        ts << " [ref at " << marker->referencePoint() << "]";
        ts << " [angle=";
        if (marker->angle() == -1)
            ts << "auto" << "]\n";
        else
            ts << marker->angle() << "]\n";
    } else if (resource->resourceType() == PatternResourceType) {
        RenderSVGResourcePattern* pattern = static_cast<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;
        toSVGPatternElement(pattern->element())->collectPatternAttributes(attributes);

        writeNameValuePair(ts, "patternUnits", attributes.patternUnits());
        writeNameValuePair(ts, "patternContentUnits", attributes.patternContentUnits());

        AffineTransform transform = attributes.patternTransform();
        if (!transform.isIdentity())
            ts << " [patternTransform=" << transform << "]";
        ts << "\n";
    } else if (resource->resourceType() == LinearGradientResourceType) {
        RenderSVGResourceLinearGradient* gradient = static_cast<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;
        toSVGLinearGradientElement(gradient->element())->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 = toRenderSVGResourceRadialGradient(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;
        toSVGRadialGradientElement(gradient->element())->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);

        ts << " [center=" << centerPoint << "] [focal=" << focalPoint << "] [radius=" << radius << "] [focalRadius=" << focalRadius << "]\n";
    } else
        ts << "\n";
    writeChildren(ts, object, indent);
}
示例#12
0
static TextStream& operator<<(TextStream& ts, const RenderSVGPath& path)
{
    writePositionAndStyle(ts, path);

    ASSERT(path.node()->isSVGElement());
    SVGElement* svgElement = static_cast<SVGElement*>(path.node());

    if (svgElement->hasTagName(SVGNames::rectTag)) {
        SVGRectElement* element = static_cast<SVGRectElement*>(svgElement);
        writeNameValuePair(ts, "x", element->x().value(element));
        writeNameValuePair(ts, "y", element->y().value(element));
        writeNameValuePair(ts, "width", element->width().value(element));
        writeNameValuePair(ts, "height", element->height().value(element));
    } else if (svgElement->hasTagName(SVGNames::lineTag)) {
        SVGLineElement* element = static_cast<SVGLineElement*>(svgElement);
        writeNameValuePair(ts, "x1", element->x1().value(element));
        writeNameValuePair(ts, "y1", element->y1().value(element));
        writeNameValuePair(ts, "x2", element->x2().value(element));
        writeNameValuePair(ts, "y2", element->y2().value(element));
    } else if (svgElement->hasTagName(SVGNames::ellipseTag)) {
        SVGEllipseElement* element = static_cast<SVGEllipseElement*>(svgElement);
        writeNameValuePair(ts, "cx", element->cx().value(element));
        writeNameValuePair(ts, "cy", element->cy().value(element));
        writeNameValuePair(ts, "rx", element->rx().value(element));
        writeNameValuePair(ts, "ry", element->ry().value(element));
    } else if (svgElement->hasTagName(SVGNames::circleTag)) {
        SVGCircleElement* element = static_cast<SVGCircleElement*>(svgElement);
        writeNameValuePair(ts, "cx", element->cx().value(element));
        writeNameValuePair(ts, "cy", element->cy().value(element));
        writeNameValuePair(ts, "r", element->r().value(element));
    } else if (svgElement->hasTagName(SVGNames::polygonTag) || svgElement->hasTagName(SVGNames::polylineTag)) {
        SVGPolyElement* element = static_cast<SVGPolyElement*>(svgElement);
        writeNameAndQuotedValue(ts, "points", element->pointList().valueAsString());
    } else if (svgElement->hasTagName(SVGNames::pathTag)) {
        SVGPathElement* element = static_cast<SVGPathElement*>(svgElement);
        String pathString;
        // FIXME: We should switch to UnalteredParsing here - this will affect the path dumping output of dozens of tests.
        SVGPathParserFactory::self()->buildStringFromByteStream(element->pathByteStream(), pathString, NormalizedParsing);
        writeNameAndQuotedValue(ts, "data", pathString);
    } else
        ASSERT_NOT_REACHED();
    return ts;
}
static TextStream& operator<<(TextStream& ts, const RenderSVGShape& shape)
{
    writePositionAndStyle(ts, shape);

    SVGElement* svgElement = shape.element();
    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)) {
        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);
        writeNameAndQuotedValue(ts, "data", pathString);
    } else
        ASSERT_NOT_REACHED();
    return ts;
}
static void writeIfNotDefault(TextStream& ts, const char* name, ValueType value, ValueType defaultValue)
{
    if (value != defaultValue)
        writeNameValuePair(ts, name, value);
}
static void writeIfNotEmpty(TextStream& ts, const char* name, const String& value)
{
    if (!value.isEmpty())
        writeNameValuePair(ts, name, value);
}
static TextStream& operator<<(TextStream& ts, const LayoutSVGShape& shape)
{
    writePositionAndStyle(ts, shape);

    SVGElement* svgElement = shape.element();
    ASSERT(svgElement);
    SVGLengthContext lengthContext(svgElement);

    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);
        writeNameAndQuotedValue(ts, "data", pathString);
    } else {
        ASSERT_NOT_REACHED();
    }
    return ts;
}
示例#17
0
static TextStream& operator<<(TextStream& ts, const RenderSVGShape& shape)
{
    writePositionAndStyle(ts, shape);

    SVGGraphicsElement& svgElement = shape.graphicsElement();
    SVGLengthContext lengthContext(&svgElement);

    if (isSVGRectElement(svgElement)) {
        const SVGRectElement& element = toSVGRectElement(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);
        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);
        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);
        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);
        writeNameAndQuotedValue(ts, "points", element.pointList().valueAsString());
    } else if (isSVGPathElement(svgElement)) {
        const SVGPathElement& element = toSVGPathElement(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);
        writeNameAndQuotedValue(ts, "data", pathString);
    } else
        ASSERT_NOT_REACHED();
    return ts;
}
void writeSVGResourceContainer(TextStream& ts, const RenderObject& object, int indent)
{
    writeStandardPrefix(ts, object, indent);

    Element* element = static_cast<Element*>(object.node());
    const AtomicString& id = 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());
        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());
        ts << "\n";
        if (RefPtr<SVGFilterBuilder> builder = filter->buildPrimitives()) {
            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());
        ts << "\n";
    } else if (resource->resourceType() == MarkerResourceType) {
        RenderSVGResourceMarker* marker = static_cast<RenderSVGResourceMarker*>(resource);
        writeNameValuePair(ts, "markerUnits", marker->markerUnits());
        ts << " [ref at " << marker->referencePoint() << "]";
        ts << " [angle=";
        if (marker->angle() == -1)
            ts << "auto" << "]\n";
        else
            ts << marker->angle() << "]\n";
    } else if (resource->resourceType() == PatternResourceType) {
        RenderSVGResourcePattern* pattern = static_cast<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 = static_cast<SVGPatternElement*>(pattern->node())->collectPatternProperties();
        writeNameValuePair(ts, "patternUnits", boundingBoxModeString(attributes.boundingBoxMode()));
        writeNameValuePair(ts, "patternContentUnits", boundingBoxModeString(attributes.boundingBoxModeContent()));

        AffineTransform transform = attributes.patternTransform();
        if (!transform.isIdentity())
            ts << " [patternTransform=" << transform << "]";
        ts << "\n";
    } else if (resource->resourceType() == LinearGradientResourceType) {
        RenderSVGResourceLinearGradient* gradient = static_cast<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()
        SVGLinearGradientElement* linearGradientElement = static_cast<SVGLinearGradientElement*>(gradient->node());

        LinearGradientAttributes attributes = linearGradientElement->collectGradientProperties();
        writeCommonGradientProperties(ts, attributes.spreadMethod(), attributes.gradientTransform(), attributes.boundingBoxMode());

        FloatPoint startPoint;
        FloatPoint endPoint;
        linearGradientElement->calculateStartEndPoints(attributes, startPoint, endPoint);

        ts << " [start=" << startPoint << "] [end=" << endPoint << "]\n";
    }  else if (resource->resourceType() == RadialGradientResourceType) {
        RenderSVGResourceRadialGradient* gradient = static_cast<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()
        SVGRadialGradientElement* radialGradientElement = static_cast<SVGRadialGradientElement*>(gradient->node());

        RadialGradientAttributes attributes = radialGradientElement->collectGradientProperties();
        writeCommonGradientProperties(ts, attributes.spreadMethod(), attributes.gradientTransform(), attributes.boundingBoxMode());

        FloatPoint focalPoint;
        FloatPoint centerPoint;
        float radius;
        radialGradientElement->calculateFocalCenterPointsAndRadius(attributes, focalPoint, centerPoint, radius);

        ts << " [center=" << centerPoint << "] [focal=" << focalPoint << "] [radius=" << radius << "]\n";
    } else
        ts << "\n";
    writeChildren(ts, object, indent);
}