Source/WebCore/ChangeLog

 12011-11-10 Nikolas Zimmermann <nzimmermann@rim.com>
 2
 3 Move unit resolving for all resources to rendering/
 4 https://bugs.webkit.org/show_bug.cgi?id=72011
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Remove maskBoundingBox()/filterBoundingBox(), to avoid doing length resolution in svg/.
 9 RenderSVGResource* now uses SVGLengthContext::resolveRectangle, to do this while laying out.
 10
 11 Move linear gradient start/end point, radial gradient focal/center point, radius calculations into
 12 their RenderSVGResource classes, cleanup code a bit.
 13
 14 Convert filters to use SVGLengthContext. Fix DRT dumps for filters, while I'm at it, to give
 15 meaningful values, when objectBoundingBox is used as primitive units, when applying to <text>/<tspan>s.
 16
 17 Several tests results need rebaselines on all platforms.
 18
 19 * platform/graphics/filters/Filter.h:
 20 * rendering/svg/RenderSVGInlineText.h:
 21 (WebCore::RenderSVGInlineText::objectBoundingBox):
 22 * rendering/svg/RenderSVGResourceFilter.cpp:
 23 (WebCore::RenderSVGResourceFilter::buildPrimitives):
 24 (WebCore::RenderSVGResourceFilter::applyResource):
 25 (WebCore::RenderSVGResourceFilter::resourceBoundingBox):
 26 * rendering/svg/RenderSVGResourceFilter.h:
 27 * rendering/svg/RenderSVGResourceFilterPrimitive.cpp:
 28 (WebCore::RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion):
 29 * rendering/svg/RenderSVGResourceGradient.cpp:
 30 (WebCore::RenderSVGResourceGradient::applyResource):
 31 * rendering/svg/RenderSVGResourceGradient.h:
 32 * rendering/svg/RenderSVGResourceLinearGradient.cpp:
 33 (WebCore::RenderSVGResourceLinearGradient::startPoint):
 34 (WebCore::RenderSVGResourceLinearGradient::endPoint):
 35 (WebCore::RenderSVGResourceLinearGradient::buildGradient):
 36 * rendering/svg/RenderSVGResourceLinearGradient.h:
 37 * rendering/svg/RenderSVGResourceMasker.cpp:
 38 (WebCore::RenderSVGResourceMasker::resourceBoundingBox):
 39 * rendering/svg/RenderSVGResourceRadialGradient.cpp:
 40 (WebCore::RenderSVGResourceRadialGradient::centerPoint):
 41 (WebCore::RenderSVGResourceRadialGradient::focalPoint):
 42 (WebCore::RenderSVGResourceRadialGradient::radius):
 43 (WebCore::RenderSVGResourceRadialGradient::adjustFocalPointIfNeeded):
 44 (WebCore::RenderSVGResourceRadialGradient::buildGradient):
 45 * rendering/svg/RenderSVGResourceRadialGradient.h:
 46 * rendering/svg/SVGRenderTreeAsText.cpp:
 47 (WebCore::writeSVGResourceContainer):
 48 * svg/SVGFilterElement.cpp:
 49 * svg/SVGFilterElement.h:
 50 * svg/SVGFilterPrimitiveStandardAttributes.cpp:
 51 (WebCore::SVGFilterPrimitiveStandardAttributes::setStandardAttributes):
 52 * svg/SVGFilterPrimitiveStandardAttributes.h:
 53 * svg/SVGLinearGradientElement.cpp:
 54 * svg/SVGLinearGradientElement.h:
 55 * svg/SVGMaskElement.cpp:
 56 * svg/SVGMaskElement.h:
 57 * svg/SVGRadialGradientElement.cpp:
 58 * svg/SVGRadialGradientElement.h:
 59 * svg/graphics/filters/SVGFilter.h:
 60 (WebCore::SVGFilter::filterRegionInUserSpace):
 61
1622011-11-10 Pavel Feldman <pfeldman@google.com>
263
364 Web Inspector: do not highlight files larger than 10KLOC.
99847

Source/WebCore/platform/graphics/filters/Filter.h

2424#include "FloatRect.h"
2525#include "FloatSize.h"
2626#include "ImageBuffer.h"
27 
28 #include <wtf/PassRefPtr.h>
2927#include <wtf/RefCounted.h>
30 #include <wtf/RefPtr.h>
31 #include <wtf/text/StringHash.h>
3228
3329namespace WebCore {
3430
35  class FilterEffect;
 31class FilterEffect;
3632
37  class Filter : public RefCounted<Filter> {
38  public:
39  virtual ~Filter() { }
40 
41  void setSourceImage(PassOwnPtr<ImageBuffer> sourceImage) { m_sourceImage = sourceImage; }
42  ImageBuffer* sourceImage() { return m_sourceImage.get(); }
43 
44  FloatSize filterResolution() const { return m_filterResolution; }
45  void setFilterResolution(const FloatSize& filterResolution) { m_filterResolution = filterResolution; }
46 
47  virtual float applyHorizontalScale(float value) const { return value * m_filterResolution.width(); }
48  virtual float applyVerticalScale(float value) const { return value * m_filterResolution.height(); }
49 
50  virtual FloatRect sourceImageRect() const = 0;
51  virtual FloatRect filterRegion() const = 0;
52 
53  virtual FloatPoint mapAbsolutePointToLocalPoint(const FloatPoint&) const { return FloatPoint(); }
54 
55  virtual FloatRect filterRegionInUserSpace() const { return FloatRect(); }
56 
57  virtual bool effectBoundingBoxMode() const = 0;
58 
59  private:
60  OwnPtr<ImageBuffer> m_sourceImage;
61  FloatSize m_filterResolution;
62  };
 33class Filter : public RefCounted<Filter> {
 34public:
 35 virtual ~Filter() { }
 36
 37 void setSourceImage(PassOwnPtr<ImageBuffer> sourceImage) { m_sourceImage = sourceImage; }
 38 ImageBuffer* sourceImage() { return m_sourceImage.get(); }
 39
 40 FloatSize filterResolution() const { return m_filterResolution; }
 41 void setFilterResolution(const FloatSize& filterResolution) { m_filterResolution = filterResolution; }
 42
 43 virtual float applyHorizontalScale(float value) const { return value * m_filterResolution.width(); }
 44 virtual float applyVerticalScale(float value) const { return value * m_filterResolution.height(); }
 45
 46 virtual FloatRect sourceImageRect() const = 0;
 47 virtual FloatRect filterRegion() const = 0;
 48
 49 virtual FloatPoint mapAbsolutePointToLocalPoint(const FloatPoint&) const { return FloatPoint(); }
 50
 51private:
 52 OwnPtr<ImageBuffer> m_sourceImage;
 53 FloatSize m_filterResolution;
 54};
6355
6456} // namespace WebCore
6557
99838

Source/WebCore/rendering/svg/RenderSVGInlineText.h

@@private:
5353 virtual void setStyle(PassRefPtr<RenderStyle>);
5454 virtual void styleDidChange(StyleDifference, const RenderStyle*);
5555
56  // FIXME: We need objectBoundingBox for DRT results and filters at the moment.
57  // This should be fixed to give back the objectBoundingBox of the text root.
58  virtual FloatRect objectBoundingBox() const { return FloatRect(); }
 56 virtual FloatRect objectBoundingBox() const { return linesBoundingBox(); }
5957
6058 virtual bool requiresLayer() const { return false; }
6159 virtual bool isSVGInlineText() const { return true; }
99838

Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp

@@void RenderSVGResourceFilter::removeClie
9393 markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidation : ParentOnlyInvalidation);
9494}
9595
96 PassRefPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(Filter* filter)
 96PassRefPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(SVGFilter* filter)
9797{
9898 SVGFilterElement* filterElement = static_cast<SVGFilterElement*>(node());
99  bool primitiveBoundingBoxMode = filterElement->primitiveUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
 99 FloatRect targetBoundingBox = filter->targetBoundingBox();
100100
101101 // Add effects to the builder
102102 RefPtr<SVGFilterBuilder> builder = SVGFilterBuilder::create(filter);

@@PassRefPtr<SVGFilterBuilder> RenderSVGRe
115115 return 0;
116116 }
117117 builder->appendEffectToEffectReferences(effect, effectElement->renderer());
118  effectElement->setStandardAttributes(primitiveBoundingBoxMode, effect.get());
 118 effectElement->setStandardAttributes(effect.get());
 119 effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(effectElement, filterElement->primitiveUnits(), targetBoundingBox));
119120 builder->add(effectElement->result(), effect);
120121 }
121122 return builder.release();

@@bool RenderSVGResourceFilter::applyResou
160161 FloatRect targetBoundingBox = object->objectBoundingBox();
161162
162163 SVGFilterElement* filterElement = static_cast<SVGFilterElement*>(node());
163  filterData->boundaries = filterElement->filterBoundingBox(targetBoundingBox);
 164 filterData->boundaries = SVGLengthContext::resolveRectangle<SVGFilterElement>(filterElement, filterElement->filterUnits(), targetBoundingBox);
164165 if (filterData->boundaries.isEmpty())
165166 return false;
166167

@@bool RenderSVGResourceFilter::applyResou
184185 filterData->filter = SVGFilter::create(filterData->shearFreeAbsoluteTransform, absoluteDrawingRegion, targetBoundingBox, filterData->boundaries, primitiveBoundingBoxMode);
185186
186187 // Create all relevant filter primitives.
187  filterData->builder = buildPrimitives(filterData->filter.get());
 188 filterData->builder = buildPrimitives(static_cast<SVGFilter*>(filterData->filter.get()));
188189 if (!filterData->builder)
189190 return false;
190191

@@void RenderSVGResourceFilter::postApplyR
330331FloatRect RenderSVGResourceFilter::resourceBoundingBox(RenderObject* object)
331332{
332333 if (SVGFilterElement* element = static_cast<SVGFilterElement*>(node()))
333  return element->filterBoundingBox(object->objectBoundingBox());
 334 return SVGLengthContext::resolveRectangle<SVGFilterElement>(element, element->filterUnits(), object->objectBoundingBox());
334335
335336 return FloatRect();
336337}
99838

Source/WebCore/rendering/svg/RenderSVGResourceFilter.h

@@public:
7676
7777 virtual FloatRect resourceBoundingBox(RenderObject*);
7878
79  PassRefPtr<SVGFilterBuilder> buildPrimitives(Filter*);
 79 PassRefPtr<SVGFilterBuilder> buildPrimitives(SVGFilter*);
8080
8181 SVGUnitTypes::SVGUnitType filterUnits() const { return static_cast<SVGFilterElement*>(node())->filterUnits(); }
8282 SVGUnitTypes::SVGUnitType primitiveUnits() const { return static_cast<SVGFilterElement*>(node())->primitiveUnits(); }
99838

Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp

@@void RenderSVGResourceFilterPrimitive::s
6565FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(FilterEffect* effect)
6666{
6767 FloatRect uniteRect;
68  FloatRect subregionBoundingBox = effect->effectBoundaries();
69  FloatRect subregion = subregionBoundingBox;
 68 FloatRect subregion = effect->effectBoundaries();
7069 SVGFilter* filter = static_cast<SVGFilter*>(effect->filter());
7170 ASSERT(filter);
7271

@@FloatRect RenderSVGResourceFilterPrimiti
8281 uniteRect = filter->filterRegionInUserSpace();
8382 }
8483
85  if (filter->effectBoundingBoxMode()) {
86  subregion = uniteRect;
87  // Avoid the calling of a virtual method several times.
88  FloatRect targetBoundingBox = filter->targetBoundingBox();
89 
90  if (effect->hasX())
91  subregion.setX(targetBoundingBox.x() + subregionBoundingBox.x() * targetBoundingBox.width());
92 
93  if (effect->hasY())
94  subregion.setY(targetBoundingBox.y() + subregionBoundingBox.y() * targetBoundingBox.height());
95 
96  if (effect->hasWidth())
97  subregion.setWidth(subregionBoundingBox.width() * targetBoundingBox.width());
98 
99  if (effect->hasHeight())
100  subregion.setHeight(subregionBoundingBox.height() * targetBoundingBox.height());
101  } else {
102  if (!effect->hasX())
103  subregion.setX(uniteRect.x());
104 
105  if (!effect->hasY())
106  subregion.setY(uniteRect.y());
107 
108  if (!effect->hasWidth())
109  subregion.setWidth(uniteRect.width());
110 
111  if (!effect->hasHeight())
112  subregion.setHeight(uniteRect.height());
113  }
114 
 84 if (!effect->hasX())
 85 subregion.setX(uniteRect.x());
 86 if (!effect->hasY())
 87 subregion.setY(uniteRect.y());
 88 if (!effect->hasWidth())
 89 subregion.setWidth(uniteRect.width());
 90 if (!effect->hasHeight())
 91 subregion.setHeight(uniteRect.height());
11592 effect->setFilterPrimitiveSubregion(subregion);
11693
11794 FloatRect absoluteSubregion = filter->mapLocalRectToAbsoluteRect(subregion);
99838

Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp

@@bool RenderSVGResourceGradient::applyRes
175175
176176 // Create gradient object
177177 if (!gradientData->gradient) {
178  buildGradient(gradientData, gradientElement);
 178 buildGradient(gradientData);
179179
180180 // CG platforms will handle the gradient space transform for text after applying the
181181 // resource, so don't apply it here. For non-CG platforms, we want the text bounding
99838

Source/WebCore/rendering/svg/RenderSVGResourceGradient.h

@@protected:
5959 virtual SVGUnitTypes::SVGUnitType gradientUnits() const = 0;
6060 virtual void calculateGradientTransform(AffineTransform&) = 0;
6161 virtual bool collectGradientAttributes(SVGGradientElement*) = 0;
62  virtual void buildGradient(GradientData*, SVGGradientElement*) const = 0;
 62 virtual void buildGradient(GradientData*) const = 0;
6363
6464 GradientSpreadMethod platformSpreadMethodFromSVGType(SVGSpreadMethodType) const;
6565
99838

Source/WebCore/rendering/svg/RenderSVGResourceLinearGradient.cpp

@@bool RenderSVGResourceLinearGradient::co
4545 return static_cast<SVGLinearGradientElement*>(gradientElement)->collectGradientAttributes(m_attributes);
4646}
4747
48 void RenderSVGResourceLinearGradient::buildGradient(GradientData* gradientData, SVGGradientElement* gradientElement) const
 48FloatPoint RenderSVGResourceLinearGradient::startPoint(const LinearGradientAttributes& attributes) const
4949{
50  SVGLinearGradientElement* linearGradientElement = static_cast<SVGLinearGradientElement*>(gradientElement);
 50 return SVGLengthContext::resolvePoint(static_cast<const SVGElement*>(node()), attributes.gradientUnits(), attributes.x1(), attributes.y1());
 51}
5152
52  // Determine gradient start/end points
53  FloatPoint startPoint;
54  FloatPoint endPoint;
55  linearGradientElement->calculateStartEndPoints(m_attributes, startPoint, endPoint);
 53FloatPoint RenderSVGResourceLinearGradient::endPoint(const LinearGradientAttributes& attributes) const
 54{
 55 return SVGLengthContext::resolvePoint(static_cast<const SVGElement*>(node()), attributes.gradientUnits(), attributes.x2(), attributes.y2());
 56}
5657
57  gradientData->gradient = Gradient::create(startPoint, endPoint);
 58void RenderSVGResourceLinearGradient::buildGradient(GradientData* gradientData) const
 59{
 60 gradientData->gradient = Gradient::create(startPoint(m_attributes), endPoint(m_attributes));
5861 gradientData->gradient->setSpreadMethod(platformSpreadMethodFromSVGType(m_attributes.spreadMethod()));
59 
60  // Add stops
6162 addStops(gradientData, m_attributes.stops());
6263}
6364
99838

Source/WebCore/rendering/svg/RenderSVGResourceLinearGradient.h

@@public:
4242 virtual SVGUnitTypes::SVGUnitType gradientUnits() const { return m_attributes.gradientUnits(); }
4343 virtual void calculateGradientTransform(AffineTransform& transform) { transform = m_attributes.gradientTransform(); }
4444 virtual bool collectGradientAttributes(SVGGradientElement*);
45  virtual void buildGradient(GradientData*, SVGGradientElement*) const;
 45 virtual void buildGradient(GradientData*) const;
 46
 47 FloatPoint startPoint(const LinearGradientAttributes&) const;
 48 FloatPoint endPoint(const LinearGradientAttributes&) const;
4649
4750private:
4851 LinearGradientAttributes m_attributes;
99838

Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp

@@FloatRect RenderSVGResourceMasker::resou
187187 ASSERT(maskElement);
188188
189189 FloatRect objectBoundingBox = object->objectBoundingBox();
190  FloatRect maskBoundaries = maskElement->maskBoundingBox(objectBoundingBox);
 190 FloatRect maskBoundaries = SVGLengthContext::resolveRectangle<SVGMaskElement>(maskElement, maskElement->maskUnits(), objectBoundingBox);
191191
192192 // Resource was not layouted yet. Give back clipping rect of the mask.
193193 if (selfNeedsLayout())
99838

Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.cpp

@@bool RenderSVGResourceRadialGradient::co
4545 return static_cast<SVGRadialGradientElement*>(gradientElement)->collectGradientAttributes(m_attributes);
4646}
4747
48 void RenderSVGResourceRadialGradient::buildGradient(GradientData* gradientData, SVGGradientElement* gradientElement) const
 48FloatPoint RenderSVGResourceRadialGradient::centerPoint(const RadialGradientAttributes& attributes) const
4949{
50  SVGRadialGradientElement* radialGradientElement = static_cast<SVGRadialGradientElement*>(gradientElement);
 50 return SVGLengthContext::resolvePoint(static_cast<const SVGElement*>(node()), attributes.gradientUnits(), attributes.cx(), attributes.cy());
 51}
 52
 53FloatPoint RenderSVGResourceRadialGradient::focalPoint(const RadialGradientAttributes& attributes) const
 54{
 55 return SVGLengthContext::resolvePoint(static_cast<const SVGElement*>(node()), attributes.gradientUnits(), attributes.fx(), attributes.fy());
 56}
5157
 58float RenderSVGResourceRadialGradient::radius(const RadialGradientAttributes& attributes) const
 59{
 60 return SVGLengthContext::resolveLength(static_cast<const SVGElement*>(node()), attributes.gradientUnits(), attributes.r());
 61}
 62
 63void RenderSVGResourceRadialGradient::adjustFocalPointIfNeeded(float radius, const FloatPoint& centerPoint, FloatPoint& focalPoint) const
 64{
 65 // Eventually adjust focal points, as described below
 66 float deltaX = focalPoint.x() - centerPoint.x();
 67 float deltaY = focalPoint.y() - centerPoint.y();
 68 float radiusMax = 0.99f * radius;
 69
 70 // Spec: If (fx, fy) lies outside the circle defined by (cx, cy) and r, set
 71 // (fx, fy) to the point of intersection of the line through (fx, fy) and the circle.
 72 // We scale the radius by 0.99 to match the behavior of FireFox.
 73 if (sqrt(deltaX * deltaX + deltaY * deltaY) <= radiusMax)
 74 return;
 75
 76 float angle = atan2f(deltaY, deltaX);
 77 deltaX = cosf(angle) * radiusMax;
 78 deltaY = sinf(angle) * radiusMax;
 79 focalPoint = FloatPoint(deltaX + centerPoint.x(), deltaY + centerPoint.y());
 80}
 81
 82void RenderSVGResourceRadialGradient::buildGradient(GradientData* gradientData) const
 83{
5284 // Determine gradient focal/center points and radius
53  FloatPoint focalPoint;
54  FloatPoint centerPoint;
55  float radius;
56  radialGradientElement->calculateFocalCenterPointsAndRadius(m_attributes, focalPoint, centerPoint, radius);
 85 float radius = this->radius(m_attributes);
 86 FloatPoint centerPoint = this->centerPoint(m_attributes);
 87 FloatPoint focalPoint = this->focalPoint(m_attributes);
 88 adjustFocalPointIfNeeded(radius, centerPoint, focalPoint);
5789
5890 gradientData->gradient = Gradient::create(focalPoint,
5991 0, // SVG does not support a "focus radius"

@@void RenderSVGResourceRadialGradient::bu
6294
6395 gradientData->gradient->setSpreadMethod(platformSpreadMethodFromSVGType(m_attributes.spreadMethod()));
6496
65  // Add stops
6697 addStops(gradientData, m_attributes.stops());
6798}
6899
99838

Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.h

@@public:
4242 virtual SVGUnitTypes::SVGUnitType gradientUnits() const { return m_attributes.gradientUnits(); }
4343 virtual void calculateGradientTransform(AffineTransform& transform) { transform = m_attributes.gradientTransform(); }
4444 virtual bool collectGradientAttributes(SVGGradientElement*);
45  virtual void buildGradient(GradientData*, SVGGradientElement*) const;
 45 virtual void buildGradient(GradientData*) const;
 46
 47 FloatPoint centerPoint(const RadialGradientAttributes&) const;
 48 FloatPoint focalPoint(const RadialGradientAttributes&) const;
 49 float radius(const RadialGradientAttributes&) const;
 50 void adjustFocalPointIfNeeded(float radius, const FloatPoint& centerPoint, FloatPoint&) const;
4651
4752private:
4853 RadialGradientAttributes m_attributes;
99838

Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp

@@void writeSVGResourceContainer(TextStrea
575575 linearGradientElement->collectGradientAttributes(attributes);
576576 writeCommonGradientProperties(ts, attributes.spreadMethod(), attributes.gradientTransform(), attributes.gradientUnits());
577577
578  FloatPoint startPoint;
579  FloatPoint endPoint;
580  linearGradientElement->calculateStartEndPoints(attributes, startPoint, endPoint);
581 
582  ts << " [start=" << startPoint << "] [end=" << endPoint << "]\n";
 578 ts << " [start=" << gradient->startPoint(attributes) << "] [end=" << gradient->endPoint(attributes) << "]\n";
583579 } else if (resource->resourceType() == RadialGradientResourceType) {
584580 RenderSVGResourceRadialGradient* gradient = static_cast<RenderSVGResourceRadialGradient*>(resource);
585581

@@void writeSVGResourceContainer(TextStrea
591587 radialGradientElement->collectGradientAttributes(attributes);
592588 writeCommonGradientProperties(ts, attributes.spreadMethod(), attributes.gradientTransform(), attributes.gradientUnits());
593589
594  FloatPoint focalPoint;
595  FloatPoint centerPoint;
596  float radius;
597  radialGradientElement->calculateFocalCenterPointsAndRadius(attributes, focalPoint, centerPoint, radius);
 590 FloatPoint focalPoint = gradient->focalPoint(attributes);
 591 FloatPoint centerPoint = gradient->centerPoint(attributes);
 592 float radius = gradient->radius(attributes);
 593 gradient->adjustFocalPointIfNeeded(radius, centerPoint, focalPoint);;
598594
599595 ts << " [center=" << centerPoint << "] [focal=" << focalPoint << "] [radius=" << radius << "]\n";
600596 } else
99838

Source/WebCore/svg/SVGFilterElement.cpp

@@void SVGFilterElement::childrenChanged(b
188188 object->setNeedsLayout(true);
189189}
190190
191 FloatRect SVGFilterElement::filterBoundingBox(const FloatRect& objectBoundingBox) const
192 {
193  // FIXME: A follow-up patch will make filters use SVGLengthContext::resolveRectangle.
194  FloatRect filterBBox;
195  if (filterUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
196  filterBBox = FloatRect(x().valueAsPercentage() * objectBoundingBox.width() + objectBoundingBox.x(),
197  y().valueAsPercentage() * objectBoundingBox.height() + objectBoundingBox.y(),
198  width().valueAsPercentage() * objectBoundingBox.width(),
199  height().valueAsPercentage() * objectBoundingBox.height());
200  else
201  filterBBox = FloatRect(x().value(this),
202  y().value(this),
203  width().value(this),
204  height().value(this));
205 
206  return filterBBox;
207 }
208 
209191RenderObject* SVGFilterElement::createRenderer(RenderArena* arena, RenderStyle*)
210192{
211193 return new (arena) RenderSVGResourceFilter(this);
99838

Source/WebCore/svg/SVGFilterElement.h

@@public:
4444 static PassRefPtr<SVGFilterElement> create(const QualifiedName&, Document*);
4545
4646 void setFilterRes(unsigned long filterResX, unsigned long filterResY);
47  FloatRect filterBoundingBox(const FloatRect&) const;
4847
4948private:
5049 SVGFilterElement(const QualifiedName&, Document*);
99838

Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp

@@void SVGFilterPrimitiveStandardAttribute
126126 invalidate();
127127}
128128
129 void SVGFilterPrimitiveStandardAttributes::setStandardAttributes(bool primitiveBoundingBoxMode, FilterEffect* filterEffect) const
 129void SVGFilterPrimitiveStandardAttributes::setStandardAttributes(FilterEffect* filterEffect) const
130130{
131131 ASSERT(filterEffect);
132132 if (!filterEffect)
133133 return;
134134
135  if (this->hasAttribute(SVGNames::xAttr))
 135 if (hasAttribute(SVGNames::xAttr))
136136 filterEffect->setHasX(true);
137  if (this->hasAttribute(SVGNames::yAttr))
 137 if (hasAttribute(SVGNames::yAttr))
138138 filterEffect->setHasY(true);
139  if (this->hasAttribute(SVGNames::widthAttr))
 139 if (hasAttribute(SVGNames::widthAttr))
140140 filterEffect->setHasWidth(true);
141  if (this->hasAttribute(SVGNames::heightAttr))
 141 if (hasAttribute(SVGNames::heightAttr))
142142 filterEffect->setHasHeight(true);
143 
144  FloatRect effectBBox;
145  if (primitiveBoundingBoxMode)
146  effectBBox = FloatRect(x().valueAsPercentage(),
147  y().valueAsPercentage(),
148  width().valueAsPercentage(),
149  height().valueAsPercentage());
150  else
151  effectBBox = FloatRect(x().value(this),
152  y().value(this),
153  width().value(this),
154  height().value(this));
155 
156  filterEffect->setEffectBoundaries(effectBBox);
157143}
158144
159145RenderObject* SVGFilterPrimitiveStandardAttributes::createRenderer(RenderArena* arena, RenderStyle*)
99838

Source/WebCore/svg/SVGFilterPrimitiveStandardAttributes.h

@@class SVGFilterBuilder;
3939
4040class SVGFilterPrimitiveStandardAttributes : public SVGStyledElement {
4141public:
42  void setStandardAttributes(bool, FilterEffect*) const;
 42 void setStandardAttributes(FilterEffect*) const;
4343
4444 virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter* filter) = 0;
4545 // Returns true, if the new value is different from the old one.
99838

Source/WebCore/svg/SVGLinearGradientElement.cpp

@@bool SVGLinearGradientElement::collectGr
189189 return true;
190190}
191191
192 void SVGLinearGradientElement::calculateStartEndPoints(const LinearGradientAttributes& attributes, FloatPoint& startPoint, FloatPoint& endPoint)
193 {
194  startPoint = SVGLengthContext::resolvePoint(this, attributes.gradientUnits(), attributes.x1(), attributes.y1());
195  endPoint = SVGLengthContext::resolvePoint(this, attributes.gradientUnits(), attributes.x2(), attributes.y2());
196 }
197 
198192bool SVGLinearGradientElement::selfHasRelativeLengths() const
199193{
200194 return x1().isRelative()
99838

Source/WebCore/svg/SVGLinearGradientElement.h

@@public:
3434 static PassRefPtr<SVGLinearGradientElement> create(const QualifiedName&, Document*);
3535
3636 bool collectGradientAttributes(LinearGradientAttributes&);
37  void calculateStartEndPoints(const LinearGradientAttributes&, FloatPoint& startPoint, FloatPoint& endPoint);
3837
3938private:
4039 SVGLinearGradientElement(const QualifiedName&, Document*);
99838

Source/WebCore/svg/SVGMaskElement.cpp

@@void SVGMaskElement::childrenChanged(boo
157157 object->setNeedsLayout(true);
158158}
159159
160 FloatRect SVGMaskElement::maskBoundingBox(const FloatRect& objectBoundingBox) const
161 {
162  return SVGLengthContext::resolveRectangle<SVGMaskElement>(this, maskUnits(), objectBoundingBox);
163 }
164 
165160RenderObject* SVGMaskElement::createRenderer(RenderArena* arena, RenderStyle*)
166161{
167162 return new (arena) RenderSVGResourceMasker(this);
99838

Source/WebCore/svg/SVGMaskElement.h

@@class SVGMaskElement : public SVGStyledL
3939public:
4040 static PassRefPtr<SVGMaskElement> create(const QualifiedName&, Document*);
4141
42  FloatRect maskBoundingBox(const FloatRect&) const;
43 
4442private:
4543 SVGMaskElement(const QualifiedName&, Document*);
4644
99838

Source/WebCore/svg/SVGRadialGradientElement.cpp

@@bool SVGRadialGradientElement::collectGr
205205 return true;
206206}
207207
208 void SVGRadialGradientElement::calculateFocalCenterPointsAndRadius(const RadialGradientAttributes& attributes, FloatPoint& focalPoint, FloatPoint& centerPoint, float& radius)
209 {
210  // Determine gradient focal/center points and radius
211  focalPoint = SVGLengthContext::resolvePoint(this, attributes.gradientUnits(), attributes.fx(), attributes.fy());
212  centerPoint = SVGLengthContext::resolvePoint(this, attributes.gradientUnits(), attributes.cx(), attributes.cy());
213  radius = SVGLengthContext::resolveLength(this, attributes.gradientUnits(), attributes.r());
214 
215  // Eventually adjust focal points, as described below
216  float deltaX = focalPoint.x() - centerPoint.x();
217  float deltaY = focalPoint.y() - centerPoint.y();
218  float radiusMax = 0.99f * radius;
219 
220  // Spec: If (fx, fy) lies outside the circle defined by (cx, cy) and r, set
221  // (fx, fy) to the point of intersection of the line through (fx, fy) and the circle.
222  // We scale the radius by 0.99 to match the behavior of FireFox.
223  if (sqrt(deltaX * deltaX + deltaY * deltaY) > radiusMax) {
224  float angle = atan2f(deltaY, deltaX);
225 
226  deltaX = cosf(angle) * radiusMax;
227  deltaY = sinf(angle) * radiusMax;
228  focalPoint = FloatPoint(deltaX + centerPoint.x(), deltaY + centerPoint.y());
229  }
230 }
231 
232208bool SVGRadialGradientElement::selfHasRelativeLengths() const
233209{
234210 return cx().isRelative()
99838

Source/WebCore/svg/SVGRadialGradientElement.h

@@public:
3434 static PassRefPtr<SVGRadialGradientElement> create(const QualifiedName&, Document*);
3535
3636 bool collectGradientAttributes(RadialGradientAttributes&);
37  void calculateFocalCenterPointsAndRadius(const RadialGradientAttributes&, FloatPoint& focalPoint, FloatPoint& centerPoint, float& radius);
3837
3938private:
4039 SVGRadialGradientElement(const QualifiedName&, Document*);
99838

Source/WebCore/svg/graphics/filters/SVGFilter.h

@@class SVGFilter : public Filter {
3737public:
3838 static PassRefPtr<SVGFilter> create(const AffineTransform&, const FloatRect&, const FloatRect&, const FloatRect&, bool);
3939
40  virtual bool effectBoundingBoxMode() const { return m_effectBBoxMode; }
41 
42  virtual FloatRect filterRegionInUserSpace() const { return m_filterRegion; }
 40 FloatRect filterRegionInUserSpace() const { return m_filterRegion; }
4341 virtual FloatRect filterRegion() const { return m_absoluteFilterRegion; }
4442
4543 virtual FloatPoint mapAbsolutePointToLocalPoint(const FloatPoint& point) const { return m_absoluteTransform.inverse().mapPoint(point); }
99838

LayoutTests/ChangeLog

 12011-11-10 Nikolas Zimmermann <nzimmermann@rim.com>
 2
 3 Move unit resolving for all resources to rendering/
 4 https://bugs.webkit.org/show_bug.cgi?id=72011
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Update expected results for some filters tests, now that their bounding box is correctly dumped.
 9
 10 * platform/mac/svg/batik/text/textEffect-expected.txt:
 11 * platform/mac/svg/batik/text/textEffect3-expected.txt:
 12 * platform/mac/svg/custom/text-filter-expected.txt:
 13 * platform/mac/svg/filters/feColorMatrix-values-expected.txt:
 14 * platform/mac/svg/filters/feMerge-wrong-input-expected.txt:
 15 * platform/mac/svg/filters/filter-on-filter-for-text-expected.txt:
 16 * platform/mac/svg/filters/filter-on-tspan-expected.txt:
 17
1182011-11-10 Csaba Osztrogonác <ossy@webkit.org>
219
320 [Qt] Unreviewed trivial fix after r99721.
99847

LayoutTests/platform/mac/svg/batik/text/textEffect3-expected.txt

@@layer at (0,0) size 450x500
8484 RenderSVGText {text} at (54,292) size 146x80 contains 1 chunk(s)
8585 [filter="dropShadow"] RenderSVGResourceFilter {filter} at (39.40,284) size 175.20x96
8686 RenderSVGInlineText {#text} at (0,20) size 36x60
87  [filter="dropShadow"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 87 [filter="dropShadow"] RenderSVGResourceFilter {filter} at (50.40,306) size 43.20x72
8888 chunk 1 (middle anchor) text run 1 at (54.50,360.00) startOffset 0 endOffset 1 width 35.00: "B"
8989 RenderSVGTSpan {tspan} at (0,0) size 19x31
9090 RenderSVGInlineText {#text} at (35,23) size 19x31
9191 chunk 1 (middle anchor) text run 1 at (89.50,340.00) startOffset 0 endOffset 1 width 18.00: "A"
9292 RenderSVGInlineText {#text} at (53,0) size 33x60
93  [filter="dropShadow"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 93 [filter="dropShadow"] RenderSVGResourceFilter {filter} at (103.70,286) size 39.60x72
9494 chunk 1 (middle anchor) text run 1 at (107.50,340.00) startOffset 0 endOffset 1 width 32.00: "T"
9595 RenderSVGTSpan {tspan} at (0,0) size 12x46
9696 RenderSVGInlineText {#text} at (85,11) size 12x46

@@layer at (0,0) size 450x500
9999 RenderSVGInlineText {#text} at (92,2) size 54x69
100100 chunk 1 (middle anchor) text run 1 at (150.50,340.00) startOffset 0 endOffset 1 width 35.00: "K"
101101 RenderSVGInlineText {#text} at (0,0) size 0x0
102  [filter="dropShadow"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 102 [filter="dropShadow"] RenderSVGResourceFilter {filter} at (-45,-50) size 540x600
103103 RenderSVGText {text} at (263,292) size 148x80 contains 1 chunk(s)
104104 [filter="dropShadow"] RenderSVGResourceFilter {filter} at (248.20,284) size 177.60x96
105105 RenderSVGInlineText {#text} at (0,20) size 37x60
106  [filter="dropShadow"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 106 [filter="dropShadow"] RenderSVGResourceFilter {filter} at (259.30,306) size 44.40x72
107107 chunk 1 (middle anchor) text run 1 at (263.90,360.00) startOffset 0 endOffset 1 width 35.35: "B"
108108 RenderSVGTSpan {tspan} at (0,0) size 19x31
109109 RenderSVGInlineText {#text} at (36,23) size 19x31
110110 chunk 1 (middle anchor) text run 1 at (299.25,340.00) startOffset 0 endOffset 1 width 18.01: "A"
111111 RenderSVGInlineText {#text} at (54,0) size 33x60
112  [filter="dropShadow"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 112 [filter="dropShadow"] RenderSVGResourceFilter {filter} at (313.70,286) size 39.60x72
113113 chunk 1 (middle anchor) text run 1 at (317.26,340.00) startOffset 0 endOffset 1 width 32.37: "T"
114114 RenderSVGTSpan {tspan} at (0,0) size 12x46
115115 RenderSVGInlineText {#text} at (86,11) size 12x46

@@layer at (0,0) size 450x500
118118 RenderSVGInlineText {#text} at (93,2) size 55x69
119119 chunk 1 (middle anchor) text run 1 at (360.75,340.00) startOffset 0 endOffset 1 width 35.35: "K"
120120 RenderSVGInlineText {#text} at (0,0) size 0x0
121  [filter="dropShadow"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 121 [filter="dropShadow"] RenderSVGResourceFilter {filter} at (-45,-50) size 540x600
122122 RenderSVGText {text} at (87,389) size 66x14 contains 1 chunk(s)
123123 RenderSVGInlineText {#text} at (0,0) size 66x14
124124 chunk 1 (middle anchor) text run 1 at (87.50,400.00) startOffset 0 endOffset 13 width 65.00: "(System font)"
99838

LayoutTests/platform/mac/svg/batik/text/textEffect-expected.txt

@@layer at (0,0) size 450x500
3636 RenderSVGText {text} at (44,312) size 152x60 contains 1 chunk(s)
3737 [filter="dropShadow"] RenderSVGResourceFilter {filter} at (28.80,306) size 182.40x72
3838 RenderSVGInlineText {#text} at (0,0) size 152x60
39  [filter="dropShadow"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 39 [filter="dropShadow"] RenderSVGResourceFilter {filter} at (28.80,306) size 182.40x72
4040 chunk 1 (middle anchor) text run 1 at (44.00,360.00) startOffset 0 endOffset 5 width 152.00: "BATIK"
4141 RenderSVGText {text} at (253,312) size 154x60 contains 1 chunk(s)
4242 [filter="dropShadow"] RenderSVGResourceFilter {filter} at (237.60,306) size 184.80x72
4343 RenderSVGInlineText {#text} at (0,0) size 154x60
44  [filter="dropShadow"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 44 [filter="dropShadow"] RenderSVGResourceFilter {filter} at (237.60,306) size 184.80x72
4545 chunk 1 (middle anchor) text run 1 at (253.42,360.00) startOffset 0 endOffset 5 width 153.15: "BATIK"
4646 RenderSVGText {text} at (87,389) size 66x14 contains 1 chunk(s)
4747 RenderSVGInlineText {#text} at (0,0) size 66x14
99838

LayoutTests/platform/mac/svg/custom/text-filter-expected.txt

@@layer at (0,0) size 800x600
99 RenderSVGText {text} at (4,10) size 567x64 contains 1 chunk(s)
1010 [filter="myfilter"] RenderSVGResourceFilter {filter} at (-52.70,3.60) size 680.40x76.80
1111 RenderSVGInlineText {#text} at (0,0) size 567x64
12  [filter="myfilter"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 12 [filter="myfilter"] RenderSVGResourceFilter {filter} at (-52.70,3.60) size 680.40x76.80
1313 chunk 1 text run 1 at (4.00,60.00) startOffset 0 endOffset 26 width 567.00: "This text should be blury."
99838

LayoutTests/platform/mac/svg/filters/feColorMatrix-values-expected.txt

@@layer at (0,0) size 800x600
6363 RenderSVGText {text} at (210,18) size 139x28 contains 1 chunk(s)
6464 [filter="matbad"] RenderSVGResourceFilter {filter} at (196.10,15.20) size 166.80x33.60
6565 RenderSVGInlineText {#text} at (0,0) size 139x28
66  [filter="matbad"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 66 [filter="matbad"] RenderSVGResourceFilter {filter} at (196.10,15.20) size 166.80x33.60
6767 chunk 1 text run 1 at (210.00,40.00) startOffset 0 endOffset 14 width 139.00: "Invalid matrix"
6868 RenderSVGText {text} at (210,48) size 156x28 contains 1 chunk(s)
6969 [filter="matbad"] RenderSVGResourceFilter {filter} at (194.40,45.20) size 187.20x33.60
7070 RenderSVGInlineText {#text} at (0,0) size 156x28
71  [filter="matbad"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 71 [filter="matbad"] RenderSVGResourceFilter {filter} at (194.40,45.20) size 187.20x33.60
7272 chunk 1 text run 1 at (210.00,70.00) startOffset 0 endOffset 17 width 156.00: "values attribute."
7373 RenderSVGPath {rect} at (182,92) size 236x116 [fill={[type=SOLID] [color=#FF0000]}] [x=202.00] [y=102.00] [width=196.00] [height=96.00]
7474 [filter="huebad"] RenderSVGResourceFilter {filter} at (182.40,92.40) size 235.20x115.20
7575 RenderSVGText {text} at (210,118) size 151x28 contains 1 chunk(s)
7676 [filter="huebad"] RenderSVGResourceFilter {filter} at (194.90,115.20) size 181.20x33.60
7777 RenderSVGInlineText {#text} at (0,0) size 151x28
78  [filter="huebad"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 78 [filter="huebad"] RenderSVGResourceFilter {filter} at (194.90,115.20) size 181.20x33.60
7979 chunk 1 text run 1 at (210.00,140.00) startOffset 0 endOffset 16 width 151.00: "Invalid saturate"
8080 RenderSVGText {text} at (210,148) size 156x28 contains 1 chunk(s)
8181 [filter="huebad"] RenderSVGResourceFilter {filter} at (194.40,145.20) size 187.20x33.60
8282 RenderSVGInlineText {#text} at (0,0) size 156x28
83  [filter="huebad"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 83 [filter="huebad"] RenderSVGResourceFilter {filter} at (194.40,145.20) size 187.20x33.60
8484 chunk 1 text run 1 at (210.00,170.00) startOffset 0 endOffset 17 width 156.00: "values attribute."
8585 RenderSVGPath {rect} at (182,192) size 236x116 [fill={[type=SOLID] [color=#FF0000]}] [x=202.00] [y=202.00] [width=196.00] [height=96.00]
8686 [filter="satbad"] RenderSVGResourceFilter {filter} at (182.40,192.40) size 235.20x115.20
8787 RenderSVGText {text} at (210,218) size 174x28 contains 1 chunk(s)
8888 [filter="satbad"] RenderSVGResourceFilter {filter} at (192.60,215.20) size 208.80x33.60
8989 RenderSVGInlineText {#text} at (0,0) size 174x28
90  [filter="satbad"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 90 [filter="satbad"] RenderSVGResourceFilter {filter} at (192.60,215.20) size 208.80x33.60
9191 chunk 1 text run 1 at (210.00,240.00) startOffset 0 endOffset 17 width 174.00: "Invalid hueRotate"
9292 RenderSVGText {text} at (210,248) size 156x28 contains 1 chunk(s)
9393 [filter="satbad"] RenderSVGResourceFilter {filter} at (194.40,245.20) size 187.20x33.60
9494 RenderSVGInlineText {#text} at (0,0) size 156x28
95  [filter="satbad"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 95 [filter="satbad"] RenderSVGResourceFilter {filter} at (194.40,245.20) size 187.20x33.60
9696 chunk 1 text run 1 at (210.00,270.00) startOffset 0 endOffset 17 width 156.00: "values attribute."
9797 RenderSVGPath {rect} at (182,292) size 236x116 [fill={[type=SOLID] [color=#FF0000]}] [x=202.00] [y=302.00] [width=196.00] [height=96.00]
9898 [filter="satrange"] RenderSVGResourceFilter {filter} at (182.40,292.40) size 235.20x115.20
9999 RenderSVGText {text} at (210,318) size 133x28 contains 1 chunk(s)
100100 [filter="satrange"] RenderSVGResourceFilter {filter} at (196.70,315.20) size 159.60x33.60
101101 RenderSVGInlineText {#text} at (0,0) size 133x28
102  [filter="satrange"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 102 [filter="satrange"] RenderSVGResourceFilter {filter} at (196.70,315.20) size 159.60x33.60
103103 chunk 1 text run 1 at (210.00,340.00) startOffset 0 endOffset 13 width 133.00: "Saturate must"
104104 RenderSVGText {text} at (210,348) size 152x28 contains 1 chunk(s)
105105 [filter="satrange"] RenderSVGResourceFilter {filter} at (194.80,345.20) size 182.40x33.60
106106 RenderSVGInlineText {#text} at (0,0) size 152x28
107  [filter="satrange"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 107 [filter="satrange"] RenderSVGResourceFilter {filter} at (194.80,345.20) size 182.40x33.60
108108 chunk 1 text run 1 at (210.00,370.00) startOffset 0 endOffset 15 width 152.00: "have one value."
99838

LayoutTests/platform/mac/svg/filters/feMerge-wrong-input-expected.txt

11layer at (0,0) size 800x600
22 RenderView at (0,0) size 800x600
33layer at (0,0) size 800x600
4  RenderSVGRoot {svg} at (0,0) size 100x100
 4 RenderSVGRoot {svg} at (0,0) size 800x600
55 RenderSVGHiddenContainer {defs} at (0,0) size 0x0
66 RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=objectBoundingBox]
7  RenderSVGContainer {g} at (0,0) size 0x0
8  [filter="filter"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 7 RenderSVGContainer {g} at (0,0) size 800x600
 8 [filter="filter"] RenderSVGResourceFilter {filter} at (-80,-60) size 960x720
99 RenderSVGPath {rect} at (0,0) size 100x100 [fill={[type=SOLID] [color=#008000]}] [x=0.00] [y=0.00] [width=100.00] [height=100.00]
99838

LayoutTests/platform/mac/svg/filters/filter-on-filter-for-text-expected.txt

@@layer at (0,0) size 800x600
99 RenderSVGText {text} at (30,12) size 206x23 contains 1 chunk(s)
1010 [filter="filter"] RenderSVGResourceFilter {filter} at (9.40,9.70) size 247.20x27.60
1111 RenderSVGInlineText {#text} at (0,0) size 135x23
12  [filter="filter"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 12 [filter="filter"] RenderSVGResourceFilter {filter} at (16.50,9.70) size 162x27.60
1313 chunk 1 text run 1 at (30.00,30.00) startOffset 0 endOffset 19 width 135.00: "This is for filter "
1414 RenderSVGTSpan {tspan} at (0,0) size 66x23
1515 RenderSVGInlineText {#text} at (135,0) size 66x23
16  [filter="filter"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 16 [filter="filter"] RenderSVGResourceFilter {filter} at (158.40,9.70) size 79.20x27.60
1717 chunk 1 text run 1 at (165.00,30.00) startOffset 0 endOffset 9 width 66.00: "on filter"
1818 RenderSVGInlineText {#text} at (201,0) size 5x23
19  [filter="filter"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 19 [filter="filter"] RenderSVGResourceFilter {filter} at (230.50,9.70) size 6x27.60
2020 chunk 1 text run 1 at (231.00,30.00) startOffset 0 endOffset 1 width 5.00: "."
99838

LayoutTests/platform/mac/svg/filters/filter-on-tspan-expected.txt

@@layer at (0,0) size 800x600
1010 chunk 1 text run 1 at (100.00,100.00) startOffset 0 endOffset 12 width 68.00: "Die ist ein "
1111 RenderSVGTSpan {tspan} at (0,0) size 27x18
1212 RenderSVGInlineText {#text} at (68,0) size 27x18
13  [filter="filter"] RenderSVGResourceFilter {filter} at (0,0) size 0x0
 13 [filter="filter"] RenderSVGResourceFilter {filter} at (165.30,84.20) size 32.40x21.60
1414 chunk 1 text run 1 at (168.00,100.00) startOffset 0 endOffset 4 width 27.00: "Test"
1515 RenderSVGInlineText {#text} at (95,0) size 4x18
1616 chunk 1 text run 1 at (195.00,100.00) startOffset 0 endOffset 1 width 4.00: "."
99838