Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
SVG: applyResource() should take a RenderElement&.
<https://webkit.org/b/123286>

This function is always called with an object, and that object
is guaranteed to never be a text renderer.

Reviewed by Antti Koivisto.

Canonical link: https://commits.webkit.org/141430@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@158004 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Andreas Kling committed Oct 25, 2013
1 parent 0e89e21 commit 1726966
Show file tree
Hide file tree
Showing 20 changed files with 73 additions and 71 deletions.
10 changes: 10 additions & 0 deletions Source/WebCore/ChangeLog
@@ -1,3 +1,13 @@
2013-10-24 Andreas Kling <akling@apple.com>

SVG: applyResource() should take a RenderElement&.
<https://webkit.org/b/123286>

This function is always called with an object, and that object
is guaranteed to never be a text renderer.

Reviewed by Antti Koivisto.

2013-10-25 Andreas Kling <akling@apple.com>

RenderElement::styleWillChange() should pass newStyle as reference.
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/rendering/RenderLayer.cpp
Expand Up @@ -3730,7 +3730,7 @@ bool RenderLayer::setupClipPath(GraphicsContext* context, const LayerPaintingInf

// FIXME: This should use a safer cast such as toRenderSVGResourceContainer().
// FIXME: Should this do a context->save() and return true so we restore the context?
static_cast<RenderSVGResourceClipper*>(element->renderer())->applyClippingToContext(&renderer(), rootRelativeBounds, paintingInfo.paintDirtyRect, context);
static_cast<RenderSVGResourceClipper*>(element->renderer())->applyClippingToContext(renderer(), rootRelativeBounds, paintingInfo.paintDirtyRect, context);
}
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/rendering/svg/RenderSVGResource.h
Expand Up @@ -62,7 +62,7 @@ class RenderSVGResource {
virtual void removeAllClientsFromCache(bool markForInvalidation = true) = 0;
virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true) = 0;

virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode) = 0;
virtual bool applyResource(RenderElement&, RenderStyle*, GraphicsContext*&, unsigned short resourceMode) = 0;
virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short, const Path*, const RenderSVGShape*) { }
virtual FloatRect resourceBoundingBox(const RenderObject&) = 0;

Expand Down
17 changes: 8 additions & 9 deletions Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp
Expand Up @@ -79,13 +79,12 @@ void RenderSVGResourceClipper::removeClientFromCache(RenderObject* client, bool
markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidation : ParentOnlyInvalidation);
}

bool RenderSVGResourceClipper::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
bool RenderSVGResourceClipper::applyResource(RenderElement& renderer, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
{
ASSERT(object);
ASSERT(context);
ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode);

return applyClippingToContext(object, object->objectBoundingBox(), object->repaintRectInLocalCoordinates(), context);
return applyClippingToContext(renderer, renderer.objectBoundingBox(), renderer.repaintRectInLocalCoordinates(), context);
}

bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext* context, const AffineTransform& animatedLocalTransform, const FloatRect& objectBoundingBox)
Expand Down Expand Up @@ -143,24 +142,24 @@ bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext* context, const
return true;
}

bool RenderSVGResourceClipper::applyClippingToContext(RenderObject* object, const FloatRect& objectBoundingBox,
bool RenderSVGResourceClipper::applyClippingToContext(RenderElement& renderer, const FloatRect& objectBoundingBox,
const FloatRect& repaintRect, GraphicsContext* context)
{
bool missingClipperData = !m_clipper.contains(object);
bool missingClipperData = !m_clipper.contains(&renderer);
if (missingClipperData)
m_clipper.set(object, std::make_unique<ClipperData>());
m_clipper.set(&renderer, std::make_unique<ClipperData>());

bool shouldCreateClipData = false;
AffineTransform animatedLocalTransform = clipPathElement().animatedLocalTransform();
ClipperData* clipperData = m_clipper.get(object);
ClipperData* clipperData = m_clipper.get(&renderer);
if (!clipperData->clipMaskImage) {
if (pathOnlyClipping(context, animatedLocalTransform, objectBoundingBox))
return true;
shouldCreateClipData = true;
}

AffineTransform absoluteTransform;
SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(object, absoluteTransform);
SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(&renderer, absoluteTransform);

if (shouldCreateClipData && !repaintRect.isEmpty()) {
if (!SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, clipperData->clipMaskImage, ColorSpaceDeviceRGB, Unaccelerated))
Expand All @@ -178,7 +177,7 @@ bool RenderSVGResourceClipper::applyClippingToContext(RenderObject* object, cons
if (resources && (clipper = resources->clipper())) {
GraphicsContextStateSaver stateSaver(*maskContext);

if (!clipper->applyClippingToContext(this, objectBoundingBox, repaintRect, maskContext))
if (!clipper->applyClippingToContext(*this, objectBoundingBox, repaintRect, maskContext))
return false;

succeeded = drawContentIntoMaskImage(clipperData, objectBoundingBox);
Expand Down
4 changes: 2 additions & 2 deletions Source/WebCore/rendering/svg/RenderSVGResourceClipper.h
Expand Up @@ -51,11 +51,11 @@ class RenderSVGResourceClipper FINAL : public RenderSVGResourceContainer {
virtual void removeAllClientsFromCache(bool markForInvalidation = true);
virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);

virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
virtual bool applyResource(RenderElement&, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
// clipPath can be clipped too, but don't have a boundingBox or repaintRect. So we can't call
// applyResource directly and use the rects from the object, since they are empty for RenderSVGResources
// FIXME: We made applyClippingToContext public because we cannot call applyResource on HTML elements (it asserts on RenderObject::objectBoundingBox)
bool applyClippingToContext(RenderObject*, const FloatRect&, const FloatRect&, GraphicsContext*);
bool applyClippingToContext(RenderElement&, const FloatRect&, const FloatRect&, GraphicsContext*);
virtual FloatRect resourceBoundingBox(const RenderObject&) OVERRIDE;

virtual RenderSVGResourceType resourceType() const { return ClipperResourceType; }
Expand Down
27 changes: 13 additions & 14 deletions Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
Expand Up @@ -126,29 +126,28 @@ bool RenderSVGResourceFilter::fitsInMaximumImageSize(const FloatSize& size, Floa
return matchesFilterSize;
}

bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
bool RenderSVGResourceFilter::applyResource(RenderElement& renderer, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
{
ASSERT(object);
ASSERT(context);
ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode);

if (m_filter.contains(object)) {
FilterData* filterData = m_filter.get(object);
if (m_filter.contains(&renderer)) {
FilterData* filterData = m_filter.get(&renderer);
if (filterData->state == FilterData::PaintingSource || filterData->state == FilterData::Applying)
filterData->state = FilterData::CycleDetected;
return false; // Already built, or we're in a cycle, or we're marked for removal. Regardless, just do nothing more now.
}

auto filterData = std::make_unique<FilterData>();
FloatRect targetBoundingBox = object->objectBoundingBox();
FloatRect targetBoundingBox = renderer.objectBoundingBox();

filterData->boundaries = SVGLengthContext::resolveRectangle<SVGFilterElement>(&filterElement(), filterElement().filterUnits(), targetBoundingBox);
if (filterData->boundaries.isEmpty())
return false;

// Determine absolute transformation matrix for filter.
AffineTransform absoluteTransform;
SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(object, absoluteTransform);
SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(&renderer, absoluteTransform);
if (!absoluteTransform.isInvertible())
return false;

Expand All @@ -157,7 +156,7 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,

// Determine absolute boundaries of the filter and the drawing region.
FloatRect absoluteFilterBoundaries = filterData->shearFreeAbsoluteTransform.mapRect(filterData->boundaries);
filterData->drawingRegion = object->strokeBoundingBox();
filterData->drawingRegion = renderer.strokeBoundingBox();
filterData->drawingRegion.intersect(filterData->boundaries);
FloatRect absoluteDrawingRegion = filterData->shearFreeAbsoluteTransform.mapRect(filterData->drawingRegion);

Expand Down Expand Up @@ -205,9 +204,9 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
// If the drawingRegion is empty, we have something like <g filter=".."/>.
// Even if the target objectBoundingBox() is empty, we still have to draw the last effect result image in postApplyResource.
if (filterData->drawingRegion.isEmpty()) {
ASSERT(!m_filter.contains(object));
ASSERT(!m_filter.contains(&renderer));
filterData->savedContext = context;
m_filter.set(object, std::move(filterData));
m_filter.set(&renderer, std::move(filterData));
return false;
}

Expand All @@ -217,11 +216,11 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
effectiveTransform.multiply(filterData->shearFreeAbsoluteTransform);

OwnPtr<ImageBuffer> sourceGraphic;
RenderingMode renderingMode = object->frame().settings().acceleratedFiltersEnabled() ? Accelerated : Unaccelerated;
RenderingMode renderingMode = renderer.frame().settings().acceleratedFiltersEnabled() ? Accelerated : Unaccelerated;
if (!SVGRenderingContext::createImageBuffer(filterData->drawingRegion, effectiveTransform, sourceGraphic, ColorSpaceLinearRGB, renderingMode)) {
ASSERT(!m_filter.contains(object));
ASSERT(!m_filter.contains(&renderer));
filterData->savedContext = context;
m_filter.set(object, std::move(filterData));
m_filter.set(&renderer, std::move(filterData));
return false;
}

Expand All @@ -236,8 +235,8 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,

context = sourceGraphicContext;

ASSERT(!m_filter.contains(object));
m_filter.set(object, std::move(filterData));
ASSERT(!m_filter.contains(&renderer));
m_filter.set(&renderer, std::move(filterData));

return true;
}
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/rendering/svg/RenderSVGResourceFilter.h
Expand Up @@ -74,7 +74,7 @@ class RenderSVGResourceFilter FINAL : public RenderSVGResourceContainer {
virtual void removeAllClientsFromCache(bool markForInvalidation = true);
virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);

virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
virtual bool applyResource(RenderElement&, RenderStyle*, GraphicsContext*&, unsigned short resourceMode) OVERRIDE;
virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*, const RenderSVGShape*);

virtual FloatRect resourceBoundingBox(const RenderObject&) OVERRIDE;
Expand Down
15 changes: 7 additions & 8 deletions Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp
Expand Up @@ -110,9 +110,8 @@ static inline AffineTransform clipToTextMask(GraphicsContext* context,
}
#endif

bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle* style, GraphicsContext*& context, unsigned short resourceMode)
bool RenderSVGResourceGradient::applyResource(RenderElement& renderer, RenderStyle* style, GraphicsContext*& context, unsigned short resourceMode)
{
ASSERT(object);
ASSERT(style);
ASSERT(context);
ASSERT(resourceMode != ApplyToDefaultMode);
Expand All @@ -131,11 +130,11 @@ bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle*

// Spec: When the geometry of the applicable element has no width or height and objectBoundingBox is specified,
// then the given effect (e.g. a gradient or a filter) will be ignored.
FloatRect objectBoundingBox = object->objectBoundingBox();
FloatRect objectBoundingBox = renderer.objectBoundingBox();
if (gradientUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX && objectBoundingBox.isEmpty())
return false;

OwnPtr<GradientData>& gradientData = m_gradientMap.add(object, nullptr).iterator->value;
OwnPtr<GradientData>& gradientData = m_gradientMap.add(&renderer, nullptr).iterator->value;
if (!gradientData)
gradientData = adoptPtr(new GradientData);

Expand Down Expand Up @@ -165,7 +164,7 @@ bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle*
// Depending on font scaling factor, we may need to rescale the gradient here since
// text painting removes the scale factor from the context.
AffineTransform additionalTextTransform;
if (shouldTransformOnTextPainting(object, additionalTextTransform))
if (shouldTransformOnTextPainting(&renderer, additionalTextTransform))
gradientData->userspaceTransform *= additionalTextTransform;
}
gradientData->gradient->setGradientSpaceTransform(gradientData->userspaceTransform);
Expand All @@ -179,7 +178,7 @@ bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle*

if (isPaintingText) {
#if USE(CG)
if (!createMaskAndSwapContextForTextGradient(context, m_savedContext, m_imageBuffer, object)) {
if (!createMaskAndSwapContextForTextGradient(context, m_savedContext, m_imageBuffer, &renderer)) {
context->restore();
return false;
}
Expand All @@ -197,10 +196,10 @@ bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle*
context->setFillRule(svgStyle->fillRule());
} else if (resourceMode & ApplyToStrokeMode) {
if (svgStyle->vectorEffect() == VE_NON_SCALING_STROKE)
gradientData->gradient->setGradientSpaceTransform(transformOnNonScalingStroke(object, gradientData->userspaceTransform));
gradientData->gradient->setGradientSpaceTransform(transformOnNonScalingStroke(&renderer, gradientData->userspaceTransform));
context->setAlpha(svgStyle->strokeOpacity());
context->setStrokeGradient(gradientData->gradient);
SVGRenderSupport::applyStrokeStyleToContext(context, style, object);
SVGRenderSupport::applyStrokeStyleToContext(context, style, &renderer);
}

return true;
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/rendering/svg/RenderSVGResourceGradient.h
Expand Up @@ -50,7 +50,7 @@ class RenderSVGResourceGradient : public RenderSVGResourceContainer {
virtual void removeAllClientsFromCache(bool markForInvalidation = true) OVERRIDE FINAL;
virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true) OVERRIDE FINAL;

virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode) OVERRIDE FINAL;
virtual bool applyResource(RenderElement&, RenderStyle*, GraphicsContext*&, unsigned short resourceMode) OVERRIDE FINAL;
virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short resourceMode, const Path*, const RenderSVGShape*) OVERRIDE FINAL;
virtual FloatRect resourceBoundingBox(const RenderObject&) OVERRIDE FINAL { return FloatRect(); }

Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/rendering/svg/RenderSVGResourceMarker.h
Expand Up @@ -55,7 +55,7 @@ class RenderSVGResourceMarker FINAL : public RenderSVGResourceContainer {
virtual const AffineTransform& localToParentTransform() const;
AffineTransform markerTransformation(const FloatPoint& origin, float angle, float strokeWidth) const;

virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short) { return false; }
virtual bool applyResource(RenderElement&, RenderStyle*, GraphicsContext*&, unsigned short) OVERRIDE { return false; }
virtual FloatRect resourceBoundingBox(const RenderObject&) OVERRIDE { return FloatRect(); }

FloatPoint referencePoint() const;
Expand Down
15 changes: 7 additions & 8 deletions Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp
Expand Up @@ -67,22 +67,21 @@ void RenderSVGResourceMasker::removeClientFromCache(RenderObject* client, bool m
markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidation : ParentOnlyInvalidation);
}

bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
bool RenderSVGResourceMasker::applyResource(RenderElement& renderer, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
{
ASSERT(object);
ASSERT(context);
ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode);

bool missingMaskerData = !m_masker.contains(object);
bool missingMaskerData = !m_masker.contains(&renderer);
if (missingMaskerData)
m_masker.set(object, std::make_unique<MaskerData>());
m_masker.set(&renderer, std::make_unique<MaskerData>());

MaskerData* maskerData = m_masker.get(object);
MaskerData* maskerData = m_masker.get(&renderer);

AffineTransform absoluteTransform;
SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(object, absoluteTransform);
SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(&renderer, absoluteTransform);

FloatRect repaintRect = object->repaintRectInLocalCoordinates();
FloatRect repaintRect = renderer.repaintRectInLocalCoordinates();

if (!maskerData->maskImage && !repaintRect.isEmpty()) {
ASSERT(style());
Expand All @@ -92,7 +91,7 @@ bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*,
if (!SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, maskerData->maskImage, colorSpace, Unaccelerated))
return false;

if (!drawContentIntoMaskImage(maskerData, colorSpace, object)) {
if (!drawContentIntoMaskImage(maskerData, colorSpace, &renderer)) {
maskerData->maskImage.clear();
}
}
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/rendering/svg/RenderSVGResourceMasker.h
Expand Up @@ -47,7 +47,7 @@ class RenderSVGResourceMasker FINAL : public RenderSVGResourceContainer {

virtual void removeAllClientsFromCache(bool markForInvalidation = true);
virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
virtual bool applyResource(RenderObject*, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
virtual bool applyResource(RenderElement&, RenderStyle*, GraphicsContext*&, unsigned short resourceMode);
virtual FloatRect resourceBoundingBox(const RenderObject&) OVERRIDE;

SVGUnitTypes::SVGUnitType maskUnits() const { return maskElement().maskUnits(); }
Expand Down

0 comments on commit 1726966

Please sign in to comment.