diff options
author | Steve Block <steveblock@google.com> | 2010-02-02 14:57:50 +0000 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-02-04 15:06:55 +0000 |
commit | d0825bca7fe65beaee391d30da42e937db621564 (patch) | |
tree | 7461c49eb5844ffd1f35d1ba2c8b7584c1620823 /WebCore/svg/graphics | |
parent | 3db770bd97c5a59b6c7574ca80a39e5a51c1defd (diff) | |
download | external_webkit-d0825bca7fe65beaee391d30da42e937db621564.zip external_webkit-d0825bca7fe65beaee391d30da42e937db621564.tar.gz external_webkit-d0825bca7fe65beaee391d30da42e937db621564.tar.bz2 |
Merge webkit.org at r54127 : Initial merge by git
Change-Id: Ib661abb595522f50ea406f72d3a0ce17f7193c82
Diffstat (limited to 'WebCore/svg/graphics')
24 files changed, 221 insertions, 264 deletions
diff --git a/WebCore/svg/graphics/SVGImage.cpp b/WebCore/svg/graphics/SVGImage.cpp index 5f050a4..348df4f 100644 --- a/WebCore/svg/graphics/SVGImage.cpp +++ b/WebCore/svg/graphics/SVGImage.cpp @@ -30,6 +30,7 @@ #include "CachedPage.h" #include "DocumentLoader.h" +#include "FileChooser.h" #include "FloatRect.h" #include "Frame.h" #include "FrameLoader.h" @@ -54,7 +55,7 @@ namespace WebCore { -class SVGImageChromeClient : public EmptyChromeClient { +class SVGImageChromeClient : public EmptyChromeClient, public Noncopyable { public: SVGImageChromeClient(SVGImage* image) : m_image(image) @@ -192,7 +193,7 @@ void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const Fl if (view->needsLayout()) view->layout(); - view->paint(context, enclosingIntRect(srcRect)); + view->paint(context, IntRect(0, 0, view->width(), view->height())); if (compositeOp != CompositeSourceOver) context->endTransparencyLayer(); @@ -267,6 +268,11 @@ bool SVGImage::dataChanged(bool allDataReceived) return m_page; } +String SVGImage::filenameExtension() const +{ + return "svg"; +} + } #endif // ENABLE(SVG) diff --git a/WebCore/svg/graphics/SVGImage.h b/WebCore/svg/graphics/SVGImage.h index 10f39ba..a0414fe 100644 --- a/WebCore/svg/graphics/SVGImage.h +++ b/WebCore/svg/graphics/SVGImage.h @@ -47,6 +47,8 @@ namespace WebCore { private: virtual ~SVGImage(); + virtual String filenameExtension() const; + virtual void setContainerSize(const IntSize&); virtual bool usesContainerSize() const; virtual bool hasRelativeWidth() const; diff --git a/WebCore/svg/graphics/SVGPaintServer.cpp b/WebCore/svg/graphics/SVGPaintServer.cpp index 6b81f72..9d84b0e 100644 --- a/WebCore/svg/graphics/SVGPaintServer.cpp +++ b/WebCore/svg/graphics/SVGPaintServer.cpp @@ -57,9 +57,9 @@ TextStream& operator<<(TextStream& ts, const SVGPaintServer& paintServer) return paintServer.externalRepresentation(ts); } -SVGPaintServer* getPaintServerById(Document* document, const AtomicString& id) +SVGPaintServer* getPaintServerById(Document* document, const AtomicString& id, const RenderObject* object) { - SVGResource* resource = getResourceById(document, id); + SVGResource* resource = getResourceById(document, id, object); if (resource && resource->isPaintServer()) return static_cast<SVGPaintServer*>(resource); @@ -85,7 +85,7 @@ SVGPaintServer* SVGPaintServer::fillPaintServer(const RenderStyle* style, const if (paintType == SVGPaint::SVG_PAINTTYPE_URI || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR) { AtomicString id(SVGURIReference::getTarget(fill->uri())); - fillPaintServer = getPaintServerById(item->document(), id); + fillPaintServer = getPaintServerById(item->document(), id, item); SVGElement* svgElement = static_cast<SVGElement*>(item->node()); ASSERT(svgElement && svgElement->document() && svgElement->isStyled()); @@ -126,7 +126,7 @@ SVGPaintServer* SVGPaintServer::strokePaintServer(const RenderStyle* style, cons if (paintType == SVGPaint::SVG_PAINTTYPE_URI || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR) { AtomicString id(SVGURIReference::getTarget(stroke->uri())); - strokePaintServer = getPaintServerById(item->document(), id); + strokePaintServer = getPaintServerById(item->document(), id, item); SVGElement* svgElement = static_cast<SVGElement*>(item->node()); ASSERT(svgElement && svgElement->document() && svgElement->isStyled()); diff --git a/WebCore/svg/graphics/SVGPaintServer.h b/WebCore/svg/graphics/SVGPaintServer.h index 244243c..6e8997c 100644 --- a/WebCore/svg/graphics/SVGPaintServer.h +++ b/WebCore/svg/graphics/SVGPaintServer.h @@ -29,6 +29,7 @@ #if ENABLE(SVG) #include "DashArray.h" +#include "RenderObject.h" #include "SVGResource.h" #if PLATFORM(CG) @@ -82,7 +83,7 @@ namespace WebCore { TextStream& operator<<(TextStream&, const SVGPaintServer&); - SVGPaintServer* getPaintServerById(Document*, const AtomicString&); + SVGPaintServer* getPaintServerById(Document*, const AtomicString&, const RenderObject*); void applyStrokeStyleToContext(GraphicsContext*, RenderStyle*, const RenderObject*); DashArray dashArrayFromRenderingStyle(const RenderStyle* style, RenderStyle* rootStyle); diff --git a/WebCore/svg/graphics/SVGPaintServerGradient.cpp b/WebCore/svg/graphics/SVGPaintServerGradient.cpp index 74e3c22..6c58a82 100644 --- a/WebCore/svg/graphics/SVGPaintServerGradient.cpp +++ b/WebCore/svg/graphics/SVGPaintServerGradient.cpp @@ -193,7 +193,7 @@ bool SVGPaintServerGradient::setup(GraphicsContext*& context, const RenderObject bool isFilled = (type & ApplyToFillTargetType) && style->hasFill(); bool isStroked = (type & ApplyToStrokeTargetType) && style->hasStroke(); - ASSERT(isFilled && !isStroked || !isFilled && isStroked); + ASSERT((isFilled && !isStroked) || (!isFilled && isStroked)); context->save(); diff --git a/WebCore/svg/graphics/SVGPaintServerPattern.cpp b/WebCore/svg/graphics/SVGPaintServerPattern.cpp index 289c40c..28706ba 100644 --- a/WebCore/svg/graphics/SVGPaintServerPattern.cpp +++ b/WebCore/svg/graphics/SVGPaintServerPattern.cpp @@ -103,7 +103,7 @@ bool SVGPaintServerPattern::setup(GraphicsContext*& context, const RenderObject* bool isFilled = (type & ApplyToFillTargetType) && style->hasFill(); bool isStroked = (type & ApplyToStrokeTargetType) && style->hasStroke(); - ASSERT(isFilled && !isStroked || !isFilled && isStroked); + ASSERT((isFilled && !isStroked) || (!isFilled && isStroked)); m_ownerElement->buildPattern(targetRect); if (!tile()) diff --git a/WebCore/svg/graphics/SVGResource.cpp b/WebCore/svg/graphics/SVGResource.cpp index 514b70d..a071996 100644 --- a/WebCore/svg/graphics/SVGResource.cpp +++ b/WebCore/svg/graphics/SVGResource.cpp @@ -31,61 +31,30 @@ #include "RenderPath.h" #include "SVGElement.h" #include "SVGStyledElement.h" +#include <wtf/HashSet.h> #include <wtf/StdLibExtras.h> namespace WebCore { -SVGResource::SVGResource() +typedef HashSet<SVGResource*> ResourceSet; + +static ResourceSet& resourceSet() { + DEFINE_STATIC_LOCAL(ResourceSet, set, ()); + return set; } -struct ResourceSet : Noncopyable { - ResourceSet() - { - for (int i = 0; i < _ResourceTypeCount; i++) - resources[i] = 0; - } - SVGResource* resources[_ResourceTypeCount]; -}; - -typedef HashMap<SVGStyledElement*, ResourceSet*> ResourceClientMap; - -static ResourceClientMap& clientMap() +SVGResource::SVGResource() { - DEFINE_STATIC_LOCAL(ResourceClientMap, map, ()); - return map; + ASSERT(!resourceSet().contains(this)); + resourceSet().add(this); } + SVGResource::~SVGResource() { - int type = -1; - HashSet<SVGStyledElement*>::iterator itr = m_clients.begin(); - - for (; type < 0 && itr != m_clients.end(); ++itr) { - ResourceSet* target = clientMap().get(*itr); - if (!target) - continue; - - for (int i = 0; i < _ResourceTypeCount; i++) { - if (target->resources[i] != this) - continue; - type = i; - target->resources[i] = 0; - break; - } - } - - if (type < 0) - return; - - for (; itr != m_clients.end(); ++itr) { - ResourceSet* target = clientMap().get(*itr); - if (!target) - continue; - - if (target->resources[type] == this) - target->resources[type] = 0; - } + ASSERT(resourceSet().contains(this)); + resourceSet().remove(this); } void SVGResource::invalidate() @@ -120,20 +89,15 @@ void SVGResource::invalidateClients(HashSet<SVGStyledElement*> clients) void SVGResource::removeClient(SVGStyledElement* item) { - ResourceClientMap::iterator resourcePtr = clientMap().find(item); - if (resourcePtr == clientMap().end()) - return; - - ResourceSet* set = resourcePtr->second; - ASSERT(set); - - clientMap().remove(resourcePtr); - - for (int i = 0; i < _ResourceTypeCount; i++) - if (set->resources[i]) - set->resources[i]->m_clients.remove(item); - - delete set; + ResourceSet::iterator it = resourceSet().begin(); + ResourceSet::iterator end = resourceSet().end(); + + for (; it != end; ++it) { + SVGResource* resource = *it; + if (!resource->m_clients.contains(item)) + continue; + resource->m_clients.remove(item); + } } void SVGResource::addClient(SVGStyledElement* item) @@ -142,17 +106,6 @@ void SVGResource::addClient(SVGStyledElement* item) return; m_clients.add(item); - - ResourceSet* target = clientMap().get(item); - if (!target) - target = new ResourceSet; - - SVGResourceType type = resourceType(); - if (SVGResource* oldResource = target->resources[type]) - oldResource->m_clients.remove(item); - - target->resources[type] = this; - clientMap().set(item, target); } TextStream& SVGResource::externalRepresentation(TextStream& ts) const @@ -160,7 +113,7 @@ TextStream& SVGResource::externalRepresentation(TextStream& ts) const return ts; } -SVGResource* getResourceById(Document* document, const AtomicString& id) +SVGResource* getResourceById(Document* document, const AtomicString& id, const RenderObject* object) { if (id.isEmpty()) return 0; @@ -171,7 +124,7 @@ SVGResource* getResourceById(Document* document, const AtomicString& id) svgElement = static_cast<SVGElement*>(element); if (svgElement && svgElement->isStyled()) - return static_cast<SVGStyledElement*>(svgElement)->canvasResource(); + return static_cast<SVGStyledElement*>(svgElement)->canvasResource(object); return 0; } diff --git a/WebCore/svg/graphics/SVGResource.h b/WebCore/svg/graphics/SVGResource.h index 7ee98f6..8f303b5 100644 --- a/WebCore/svg/graphics/SVGResource.h +++ b/WebCore/svg/graphics/SVGResource.h @@ -28,6 +28,7 @@ #if ENABLE(SVG) #include "PlatformString.h" +#include "RenderObject.h" #include "StringHash.h" #include <wtf/HashMap.h> @@ -91,7 +92,7 @@ namespace WebCore { HashSet<SVGStyledElement*> m_clients; }; - SVGResource* getResourceById(Document*, const AtomicString&); + SVGResource* getResourceById(Document*, const AtomicString&, const RenderObject*); TextStream& operator<<(TextStream&, const SVGResource&); diff --git a/WebCore/svg/graphics/SVGResourceClipper.cpp b/WebCore/svg/graphics/SVGResourceClipper.cpp index 5998afb..c0fccaf 100644 --- a/WebCore/svg/graphics/SVGResourceClipper.cpp +++ b/WebCore/svg/graphics/SVGResourceClipper.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> + * (C) 2009 Dirk Schulze <krit@webkit.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -28,9 +29,9 @@ #if ENABLE(SVG) #include "SVGResourceClipper.h" -#include "TransformationMatrix.h" #include "GraphicsContext.h" #include "SVGRenderTreeAsText.h" +#include "TransformationMatrix.h" #if PLATFORM(CG) #include <ApplicationServices/ApplicationServices.h> @@ -50,6 +51,36 @@ SVGResourceClipper::~SVGResourceClipper() void SVGResourceClipper::resetClipData() { m_clipData.clear(); + m_clipperBoundingBox = FloatRect(); +} + +void SVGResourceClipper::invalidate() +{ + SVGResource::invalidate(); + resetClipData(); +} + +FloatRect SVGResourceClipper::clipperBoundingBox(const FloatRect& objectBoundingBox) +{ + // FIXME: We need a different calculation for other clip content than paths. + if (!m_clipperBoundingBox.isEmpty()) + return m_clipperBoundingBox; + + if (m_clipData.clipData().isEmpty()) + return FloatRect(); + + for (unsigned x = 0; x < m_clipData.clipData().size(); x++) { + ClipData clipData = m_clipData.clipData()[x]; + + FloatRect clipPathRect = clipData.path.boundingRect(); + if (clipData.bboxUnits) { + clipPathRect.scale(objectBoundingBox.width(), objectBoundingBox.height()); + clipPathRect.move(objectBoundingBox.x(), objectBoundingBox.y()); + } + m_clipperBoundingBox.unite(clipPathRect); + } + + return m_clipperBoundingBox; } void SVGResourceClipper::applyClip(GraphicsContext* context, const FloatRect& boundingBox) const @@ -125,9 +156,9 @@ TextStream& operator<<(TextStream& ts, const ClipData& d) return ts; } -SVGResourceClipper* getClipperById(Document* document, const AtomicString& id) +SVGResourceClipper* getClipperById(Document* document, const AtomicString& id, const RenderObject* object) { - SVGResource* resource = getResourceById(document, id); + SVGResource* resource = getResourceById(document, id, object); if (resource && resource->isClipper()) return static_cast<SVGResourceClipper*>(resource); diff --git a/WebCore/svg/graphics/SVGResourceClipper.h b/WebCore/svg/graphics/SVGResourceClipper.h index 98c295f..df5562d 100644 --- a/WebCore/svg/graphics/SVGResourceClipper.h +++ b/WebCore/svg/graphics/SVGResourceClipper.h @@ -27,9 +27,10 @@ #define SVGResourceClipper_h #if ENABLE(SVG) - -#include "SVGResource.h" +#include "FloatRect.h" #include "Path.h" +#include "RenderObject.h" +#include "SVGResource.h" namespace WebCore { @@ -65,7 +66,9 @@ namespace WebCore { public: static PassRefPtr<SVGResourceClipper> create() { return adoptRef(new SVGResourceClipper); } virtual ~SVGResourceClipper(); - + + virtual void invalidate(); + void resetClipData(); void addClipData(const Path&, WindRule, bool bboxUnits); @@ -76,15 +79,17 @@ namespace WebCore { // To be implemented by the specific rendering devices void applyClip(GraphicsContext*, const FloatRect& boundingBox) const; + FloatRect clipperBoundingBox(const FloatRect& oob); private: SVGResourceClipper(); ClipDataList m_clipData; + FloatRect m_clipperBoundingBox; }; TextStream& operator<<(TextStream&, WindRule); TextStream& operator<<(TextStream&, const ClipData&); - SVGResourceClipper* getClipperById(Document*, const AtomicString&); + SVGResourceClipper* getClipperById(Document*, const AtomicString&, const RenderObject*); } // namespace WebCore diff --git a/WebCore/svg/graphics/SVGResourceFilter.cpp b/WebCore/svg/graphics/SVGResourceFilter.cpp index fcf0e40..72ae203 100644 --- a/WebCore/svg/graphics/SVGResourceFilter.cpp +++ b/WebCore/svg/graphics/SVGResourceFilter.cpp @@ -32,6 +32,7 @@ #include "SVGFilter.h" #include "SVGFilterBuilder.h" #include "SVGFilterElement.h" +#include "SVGRenderSupport.h" #include "SVGRenderTreeAsText.h" #include "SVGFilterPrimitiveStandardAttributes.h" @@ -52,17 +53,21 @@ SVGResourceFilter::SVGResourceFilter(const SVGFilterElement* ownerElement) , m_savedContext(0) , m_sourceGraphicBuffer(0) { - m_filterBuilder.set(new SVGFilterBuilder()); + m_filterBuilder.set(new SVGFilterBuilder()); } SVGResourceFilter::~SVGResourceFilter() { } -static inline bool shouldProcessFilter(SVGResourceFilter* filter) +FloatRect SVGResourceFilter::filterBoundingBox(const FloatRect& obb) const { - return (!filter->scaleX() || !filter->scaleY() || !filter->filterBoundingBox().width() - || !filter->filterBoundingBox().height()); + return m_ownerElement->filterBoundingBox(obb); +} + +static inline bool shouldProcessFilter(SVGResourceFilter* filter, const FloatRect& filterRect) +{ + return (!filter->scaleX() || !filter->scaleY() || !filterRect.width() || !filterRect.height()); } void SVGResourceFilter::addFilterEffect(SVGFilterPrimitiveStandardAttributes* effectAttributes, PassRefPtr<FilterEffect> effect) @@ -86,16 +91,21 @@ bool SVGResourceFilter::fitsInMaximumImageSize(const FloatSize& size) return matchesFilterSize; } -void SVGResourceFilter::prepareFilter(GraphicsContext*& context, const RenderObject* object) +bool SVGResourceFilter::prepareFilter(GraphicsContext*& context, const RenderObject* object) { - FloatRect targetRect = object->objectBoundingBox(); - m_ownerElement->buildFilter(targetRect); + m_ownerElement->buildFilter(object->objectBoundingBox()); + const SVGRenderBase* renderer = object->toSVGRenderBase(); + if (!renderer) + return false; - if (shouldProcessFilter(this)) - return; + FloatRect paintRect = renderer->strokeBoundingBox(); + paintRect.unite(renderer->markerBoundingBox()); + + if (shouldProcessFilter(this, m_filterBBox)) + return false; // clip sourceImage to filterRegion - FloatRect clippedSourceRect = targetRect; + FloatRect clippedSourceRect = paintRect; clippedSourceRect.intersect(m_filterBBox); // scale filter size to filterRes @@ -110,7 +120,7 @@ void SVGResourceFilter::prepareFilter(GraphicsContext*& context, const RenderObj fitsInMaximumImageSize(tempSourceRect.size()); // prepare Filters - m_filter = SVGFilter::create(targetRect, m_filterBBox, m_effectBBoxMode); + m_filter = SVGFilter::create(paintRect, m_filterBBox, m_effectBBoxMode); m_filter->setFilterResolution(FloatSize(m_scaleX, m_scaleY)); FilterEffect* lastEffect = m_filterBuilder->lastEffect(); @@ -122,7 +132,8 @@ void SVGResourceFilter::prepareFilter(GraphicsContext*& context, const RenderObj m_filter->setFilterResolution(FloatSize(m_scaleX, m_scaleY)); lastEffect->calculateEffectRect(m_filter.get()); } - } + } else + return false; clippedSourceRect.scale(m_scaleX, m_scaleY); @@ -132,23 +143,21 @@ void SVGResourceFilter::prepareFilter(GraphicsContext*& context, const RenderObj OwnPtr<ImageBuffer> sourceGraphic(ImageBuffer::create(bufferRect.size(), LinearRGB)); if (!sourceGraphic.get()) - return; + return false; GraphicsContext* sourceGraphicContext = sourceGraphic->context(); + sourceGraphicContext->translate(-clippedSourceRect.x(), -clippedSourceRect.y()); sourceGraphicContext->scale(FloatSize(m_scaleX, m_scaleY)); - sourceGraphicContext->translate(-targetRect.x(), -targetRect.y()); - sourceGraphicContext->clearRect(FloatRect(FloatPoint(), targetRect.size())); + sourceGraphicContext->clearRect(FloatRect(FloatPoint(), paintRect.size())); m_sourceGraphicBuffer.set(sourceGraphic.release()); m_savedContext = context; context = sourceGraphicContext; + return true; } void SVGResourceFilter::applyFilter(GraphicsContext*& context, const RenderObject* object) { - if (shouldProcessFilter(this)) - return; - if (!m_savedContext) return; @@ -204,9 +213,9 @@ TextStream& SVGResourceFilter::externalRepresentation(TextStream& ts) const return ts; } -SVGResourceFilter* getFilterById(Document* document, const AtomicString& id) +SVGResourceFilter* getFilterById(Document* document, const AtomicString& id, const RenderObject* object) { - SVGResource* resource = getResourceById(document, id); + SVGResource* resource = getResourceById(document, id, object); if (resource && resource->isFilter()) return static_cast<SVGResourceFilter*>(resource); diff --git a/WebCore/svg/graphics/SVGResourceFilter.h b/WebCore/svg/graphics/SVGResourceFilter.h index ffd926d..ee8627c 100644 --- a/WebCore/svg/graphics/SVGResourceFilter.h +++ b/WebCore/svg/graphics/SVGResourceFilter.h @@ -68,10 +68,10 @@ public: float scaleX() const { return m_scaleX; } float scaleY() const { return m_scaleY; } - FloatRect filterBoundingBox() { return m_filterBBox; } + FloatRect filterBoundingBox(const FloatRect& obb) const; void setFilterBoundingBox(const FloatRect& rect) { m_filterBBox = rect; } - void prepareFilter(GraphicsContext*&, const RenderObject*); + bool prepareFilter(GraphicsContext*&, const RenderObject*); void applyFilter(GraphicsContext*&, const RenderObject*); bool fitsInMaximumImageSize(const FloatSize&); @@ -103,7 +103,7 @@ private: RefPtr<Filter> m_filter; }; -SVGResourceFilter* getFilterById(Document*, const AtomicString&); +SVGResourceFilter* getFilterById(Document*, const AtomicString&, const RenderObject*); } // namespace WebCore diff --git a/WebCore/svg/graphics/SVGResourceMarker.cpp b/WebCore/svg/graphics/SVGResourceMarker.cpp index 112e4d6..955c048 100644 --- a/WebCore/svg/graphics/SVGResourceMarker.cpp +++ b/WebCore/svg/graphics/SVGResourceMarker.cpp @@ -38,10 +38,8 @@ namespace WebCore { SVGResourceMarker::SVGResourceMarker() : SVGResource() - , m_refX(0.0) - , m_refY(0.0) , m_angle(-1) // just like using setAutoAngle() - , m_marker(0) + , m_renderer(0) , m_useStrokeWidth(true) { } @@ -50,20 +48,20 @@ SVGResourceMarker::~SVGResourceMarker() { } -void SVGResourceMarker::setMarker(RenderSVGViewportContainer* marker) +TransformationMatrix SVGResourceMarker::markerTransformation(const FloatPoint& origin, float angle, float strokeWidth) const { - m_marker = marker; -} + ASSERT(m_renderer); -void SVGResourceMarker::setRef(double refX, double refY) -{ - m_refX = refX; - m_refY = refY; + TransformationMatrix transform; + transform.translate(origin.x(), origin.y()); + transform.rotate(m_angle == -1 ? angle : m_angle); + transform = m_renderer->markerContentTransformation(transform, m_referencePoint, m_useStrokeWidth ? strokeWidth : -1); + return transform; } -void SVGResourceMarker::draw(GraphicsContext* context, const FloatRect& rect, double x, double y, double strokeWidth, double angle) +void SVGResourceMarker::draw(RenderObject::PaintInfo& paintInfo, const TransformationMatrix& transform) { - if (!m_marker) + if (!m_renderer) return; DEFINE_STATIC_LOCAL(HashSet<SVGResourceMarker*>, currentlyDrawingMarkers, ()); @@ -73,45 +71,18 @@ void SVGResourceMarker::draw(GraphicsContext* context, const FloatRect& rect, do return; currentlyDrawingMarkers.add(this); - - TransformationMatrix transform; - transform.translate(x, y); - transform.rotate(m_angle > -1 ? m_angle : angle); - - // refX and refY are given in coordinates relative to the viewport established by the marker, yet they affect - // the translation performed on the viewport itself. - TransformationMatrix viewportTransform; - if (m_useStrokeWidth) - viewportTransform.scaleNonUniform(strokeWidth, strokeWidth); - viewportTransform *= m_marker->viewportTransform(); - double refX, refY; - viewportTransform.map(m_refX, m_refY, refX, refY); - transform.translate(-refX, -refY); - - if (m_useStrokeWidth) - transform.scaleNonUniform(strokeWidth, strokeWidth); - - // FIXME: PaintInfo should be passed into this method instead of being created here - // FIXME: bounding box fractions are lost - RenderObject::PaintInfo info(context, enclosingIntRect(rect), PaintPhaseForeground, 0, 0, 0); - - context->save(); - context->concatCTM(transform); - m_marker->setDrawsContents(true); - m_marker->paint(info, 0, 0); - m_marker->setDrawsContents(false); - context->restore(); - - m_cachedBounds = transform.mapRect(m_marker->absoluteClippedOverflowRect()); + ASSERT(!m_renderer->drawsContents()); + RenderObject::PaintInfo info(paintInfo); + info.context->save(); + applyTransformToPaintInfo(info, transform); + m_renderer->setDrawsContents(true); + m_renderer->paint(info, 0, 0); + m_renderer->setDrawsContents(false); + info.context->restore(); currentlyDrawingMarkers.remove(this); } -FloatRect SVGResourceMarker::cachedBounds() const -{ - return m_cachedBounds; -} - TextStream& SVGResourceMarker::externalRepresentation(TextStream& ts) const { ts << "[type=MARKER]" @@ -122,13 +93,13 @@ TextStream& SVGResourceMarker::externalRepresentation(TextStream& ts) const else ts << angle() << "]"; - ts << " [ref x=" << refX() << " y=" << refY() << "]"; + ts << " [ref x=" << m_referencePoint.x() << " y=" << m_referencePoint.y() << "]"; return ts; } -SVGResourceMarker* getMarkerById(Document* document, const AtomicString& id) +SVGResourceMarker* getMarkerById(Document* document, const AtomicString& id, const RenderObject* object) { - SVGResource* resource = getResourceById(document, id); + SVGResource* resource = getResourceById(document, id, object); if (resource && resource->isMarker()) return static_cast<SVGResourceMarker*>(resource); diff --git a/WebCore/svg/graphics/SVGResourceMarker.h b/WebCore/svg/graphics/SVGResourceMarker.h index bb4039c..5c98d2f 100644 --- a/WebCore/svg/graphics/SVGResourceMarker.h +++ b/WebCore/svg/graphics/SVGResourceMarker.h @@ -27,25 +27,26 @@ #define SVGResourceMarker_h #if ENABLE(SVG) - +#include "FloatPoint.h" #include "FloatRect.h" +#include "RenderObject.h" #include "SVGResource.h" namespace WebCore { - class GraphicsContext; class RenderSVGViewportContainer; + class TransformationMatrix; class SVGResourceMarker : public SVGResource { public: static PassRefPtr<SVGResourceMarker> create() { return adoptRef(new SVGResourceMarker); } virtual ~SVGResourceMarker(); - void setMarker(RenderSVGViewportContainer*); + RenderSVGViewportContainer* renderer() const { return m_renderer; } + void setRenderer(RenderSVGViewportContainer* marker) { m_renderer = marker; } - void setRef(double refX, double refY); - double refX() const { return m_refX; } - double refY() const { return m_refY; } + void setReferencePoint(const FloatPoint& point) { m_referencePoint = point; } + FloatPoint referencePoint() const { return m_referencePoint; } void setAngle(float angle) { m_angle = angle; } void setAutoAngle() { m_angle = -1; } @@ -54,22 +55,22 @@ namespace WebCore { void setUseStrokeWidth(bool useStrokeWidth = true) { m_useStrokeWidth = useStrokeWidth; } bool useStrokeWidth() const { return m_useStrokeWidth; } - FloatRect cachedBounds() const; - void draw(GraphicsContext*, const FloatRect&, double x, double y, double strokeWidth = 1, double angle = 0); - + TransformationMatrix markerTransformation(const FloatPoint& origin, float angle, float strokeWidth) const; + void draw(RenderObject::PaintInfo&, const TransformationMatrix&); + virtual SVGResourceType resourceType() const { return MarkerResourceType; } virtual TextStream& externalRepresentation(TextStream&) const; private: SVGResourceMarker(); - double m_refX, m_refY; - FloatRect m_cachedBounds; + + FloatPoint m_referencePoint; float m_angle; - RenderSVGViewportContainer* m_marker; + RenderSVGViewportContainer* m_renderer; bool m_useStrokeWidth; }; - SVGResourceMarker* getMarkerById(Document*, const AtomicString&); + SVGResourceMarker* getMarkerById(Document*, const AtomicString&, const RenderObject*); } // namespace WebCore diff --git a/WebCore/svg/graphics/SVGResourceMasker.cpp b/WebCore/svg/graphics/SVGResourceMasker.cpp index 97467c1..18bc71a 100644 --- a/WebCore/svg/graphics/SVGResourceMasker.cpp +++ b/WebCore/svg/graphics/SVGResourceMasker.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> + * 2009 Dirk Schulze <krit@webkit.org> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,13 +34,12 @@ #include "ImageBuffer.h" #include "ImageData.h" #include "GraphicsContext.h" +#include "RenderObject.h" #include "SVGMaskElement.h" #include "SVGRenderSupport.h" #include "SVGRenderStyle.h" #include "TextStream.h" -#include <wtf/ByteArray.h> - using namespace std; namespace WebCore { @@ -47,6 +47,7 @@ namespace WebCore { SVGResourceMasker::SVGResourceMasker(const SVGMaskElement* ownerElement) : SVGResource() , m_ownerElement(ownerElement) + , m_emptyMask(false) { } @@ -58,44 +59,24 @@ void SVGResourceMasker::invalidate() { SVGResource::invalidate(); m_mask.clear(); + m_emptyMask = false; } -void SVGResourceMasker::applyMask(GraphicsContext* context, const FloatRect& boundingBox) +FloatRect SVGResourceMasker::maskerBoundingBox(const FloatRect& objectBoundingBox) const { - if (!m_mask) - m_mask = m_ownerElement->drawMaskerContent(boundingBox, m_maskRect); - - if (!m_mask) - return; - - IntSize imageSize(m_mask->size()); - IntRect intImageRect(0, 0, imageSize.width(), imageSize.height()); - - // Create new ImageBuffer to apply luminance - OwnPtr<ImageBuffer> luminancedImage = ImageBuffer::create(imageSize); - if (!luminancedImage) - return; - - PassRefPtr<CanvasPixelArray> srcPixelArray(m_mask->getUnmultipliedImageData(intImageRect)->data()); - PassRefPtr<ImageData> destImageData(luminancedImage->getUnmultipliedImageData(intImageRect)); - - for (unsigned pixelOffset = 0; pixelOffset < srcPixelArray->length(); pixelOffset++) { - unsigned pixelByteOffset = pixelOffset * 4; - - unsigned char r = 0, g = 0, b = 0, a = 0; - srcPixelArray->get(pixelByteOffset, r); - srcPixelArray->get(pixelByteOffset + 1, g); - srcPixelArray->get(pixelByteOffset + 2, b); - srcPixelArray->get(pixelByteOffset + 3, a); - - double luma = (r * 0.2125 + g * 0.7154 + b * 0.0721) * ((double)a / 255.0); + return m_ownerElement->maskBoundingBox(objectBoundingBox); +} - destImageData->data()->set(pixelByteOffset + 3, luma); - } +bool SVGResourceMasker::applyMask(GraphicsContext* context, const RenderObject* object) +{ + if (!m_mask && !m_emptyMask) + m_mask = m_ownerElement->drawMaskerContent(object, m_maskRect, m_emptyMask); - luminancedImage->putUnmultipliedImageData(destImageData.get(), intImageRect, IntPoint(0, 0)); + if (!m_mask) + return false; - context->clipToImageBuffer(m_maskRect, luminancedImage.get()); + context->clipToImageBuffer(m_maskRect, m_mask.get()); + return true; } TextStream& SVGResourceMasker::externalRepresentation(TextStream& ts) const @@ -104,9 +85,9 @@ TextStream& SVGResourceMasker::externalRepresentation(TextStream& ts) const return ts; } -SVGResourceMasker* getMaskerById(Document* document, const AtomicString& id) +SVGResourceMasker* getMaskerById(Document* document, const AtomicString& id, const RenderObject* object) { - SVGResource* resource = getResourceById(document, id); + SVGResource* resource = getResourceById(document, id, object); if (resource && resource->isMasker()) return static_cast<SVGResourceMasker*>(resource); diff --git a/WebCore/svg/graphics/SVGResourceMasker.h b/WebCore/svg/graphics/SVGResourceMasker.h index f945f56..27364c2 100644 --- a/WebCore/svg/graphics/SVGResourceMasker.h +++ b/WebCore/svg/graphics/SVGResourceMasker.h @@ -29,6 +29,8 @@ #if ENABLE(SVG) #include "GraphicsContext.h" +#include "RenderObject.h" +#include "SVGMaskElement.h" #include "SVGResource.h" #include <memory> @@ -52,8 +54,8 @@ namespace WebCore { virtual SVGResourceType resourceType() const { return MaskerResourceType; } virtual TextStream& externalRepresentation(TextStream&) const; - // To be implemented by the specific rendering devices - void applyMask(GraphicsContext*, const FloatRect& boundingBox); + FloatRect maskerBoundingBox(const FloatRect&) const; + bool applyMask(GraphicsContext*, const RenderObject*); private: SVGResourceMasker(const SVGMaskElement*); @@ -62,9 +64,10 @@ namespace WebCore { OwnPtr<ImageBuffer> m_mask; FloatRect m_maskRect; + bool m_emptyMask; }; - SVGResourceMasker* getMaskerById(Document*, const AtomicString&); + SVGResourceMasker* getMaskerById(Document*, const AtomicString&, const RenderObject* object); } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFEImage.cpp b/WebCore/svg/graphics/filters/SVGFEImage.cpp index e82328a..331de4f 100644 --- a/WebCore/svg/graphics/filters/SVGFEImage.cpp +++ b/WebCore/svg/graphics/filters/SVGFEImage.cpp @@ -2,6 +2,7 @@ Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005 Rob Buis <buis@kde.org> 2005 Eric Seidel <eric@webkit.org> + 2010 Dirk Schulze <krit@webkit.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -23,50 +24,42 @@ #if ENABLE(SVG) && ENABLE(FILTERS) #include "SVGFEImage.h" -#include "SVGRenderTreeAsText.h" + #include "Filter.h" +#include "GraphicsContext.h" +#include "SVGPreserveAspectRatio.h" +#include "SVGRenderTreeAsText.h" +#include "TransformationMatrix.h" namespace WebCore { -FEImage::FEImage(CachedImage* cachedImage) +FEImage::FEImage(RefPtr<Image> image, SVGPreserveAspectRatio preserveAspectRatio) : FilterEffect() - , m_cachedImage(cachedImage) + , m_image(image) + , m_preserveAspectRatio(preserveAspectRatio) { - m_cachedImage->addClient(this); } -PassRefPtr<FEImage> FEImage::create(CachedImage* cachedImage) +PassRefPtr<FEImage> FEImage::create(RefPtr<Image> image, SVGPreserveAspectRatio preserveAspectRatio) { - return adoptRef(new FEImage(cachedImage)); + return adoptRef(new FEImage(image, preserveAspectRatio)); } -FEImage::~FEImage() -{ - if (m_cachedImage) - m_cachedImage->removeClient(this); -} - -CachedImage* FEImage::cachedImage() const +void FEImage::apply(Filter*) { - return m_cachedImage.get(); -} + if (!m_image.get()) + return; -void FEImage::setCachedImage(CachedImage* image) -{ - if (m_cachedImage == image) + GraphicsContext* filterContext = getEffectContext(); + if (!filterContext) return; - - if (m_cachedImage) - m_cachedImage->removeClient(this); - m_cachedImage = image; + FloatRect srcRect(FloatPoint(), m_image->size()); + FloatRect destRect(FloatPoint(), subRegion().size()); - if (m_cachedImage) - m_cachedImage->addClient(this); -} + m_preserveAspectRatio.transformRect(destRect, srcRect); -void FEImage::apply(Filter*) -{ + filterContext->drawImage(m_image.get(), DeviceColorSpace, destRect, srcRect); } void FEImage::dump() diff --git a/WebCore/svg/graphics/filters/SVGFEImage.h b/WebCore/svg/graphics/filters/SVGFEImage.h index f29d266..0883aad 100644 --- a/WebCore/svg/graphics/filters/SVGFEImage.h +++ b/WebCore/svg/graphics/filters/SVGFEImage.h @@ -2,6 +2,7 @@ Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005 Rob Buis <buis@kde.org> 2005 Eric Seidel <eric@webkit.org> + 2010 Dirk Schulze <krit@webkit.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -23,33 +24,26 @@ #define SVGFEImage_h #if ENABLE(SVG) && ENABLE(FILTERS) -#include "CachedImage.h" -#include "CachedResourceClient.h" -#include "CachedResourceHandle.h" +#include "Image.h" #include "FilterEffect.h" #include "Filter.h" +#include "SVGPreserveAspectRatio.h" namespace WebCore { - class FEImage : public FilterEffect - , public CachedResourceClient { + class FEImage : public FilterEffect { public: - static PassRefPtr<FEImage> create(CachedImage*); - virtual ~FEImage(); - - // FIXME: We need to support <svg> (RenderObject*) as well as image data. - - CachedImage* cachedImage() const; - void setCachedImage(CachedImage*); + static PassRefPtr<FEImage> create(RefPtr<Image>, SVGPreserveAspectRatio); void apply(Filter*); void dump(); TextStream& externalRepresentation(TextStream& ts) const; private: - FEImage(CachedImage*); + FEImage(RefPtr<Image>, SVGPreserveAspectRatio); - CachedResourceHandle<CachedImage> m_cachedImage; + RefPtr<Image> m_image; + SVGPreserveAspectRatio m_preserveAspectRatio; }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFEMerge.cpp b/WebCore/svg/graphics/filters/SVGFEMerge.cpp index 3f9ad38..6ea0fb9 100644 --- a/WebCore/svg/graphics/filters/SVGFEMerge.cpp +++ b/WebCore/svg/graphics/filters/SVGFEMerge.cpp @@ -30,23 +30,23 @@ namespace WebCore { -FEMerge::FEMerge(const Vector<FilterEffect*>& mergeInputs) +FEMerge::FEMerge(const Vector<RefPtr<FilterEffect> >& mergeInputs) : FilterEffect() , m_mergeInputs(mergeInputs) { } -PassRefPtr<FEMerge> FEMerge::create(const Vector<FilterEffect*>& mergeInputs) +PassRefPtr<FEMerge> FEMerge::create(const Vector<RefPtr<FilterEffect> >& mergeInputs) { return adoptRef(new FEMerge(mergeInputs)); } -const Vector<FilterEffect*>& FEMerge::mergeInputs() const +const Vector<RefPtr<FilterEffect> >& FEMerge::mergeInputs() const { return m_mergeInputs; } -void FEMerge::setMergeInputs(const Vector<FilterEffect*>& mergeInputs) +void FEMerge::setMergeInputs(const Vector<RefPtr<FilterEffect> >& mergeInputs) { m_mergeInputs = mergeInputs; } diff --git a/WebCore/svg/graphics/filters/SVGFEMerge.h b/WebCore/svg/graphics/filters/SVGFEMerge.h index 02fbfac..7653be3 100644 --- a/WebCore/svg/graphics/filters/SVGFEMerge.h +++ b/WebCore/svg/graphics/filters/SVGFEMerge.h @@ -31,10 +31,10 @@ namespace WebCore { class FEMerge : public FilterEffect { public: - static PassRefPtr<FEMerge> create(const Vector<FilterEffect*>&); + static PassRefPtr<FEMerge> create(const Vector<RefPtr<FilterEffect> >&); - const Vector<FilterEffect*>& mergeInputs() const; - void setMergeInputs(const Vector<FilterEffect*>& mergeInputs); + const Vector<RefPtr<FilterEffect> >& mergeInputs() const; + void setMergeInputs(const Vector<RefPtr<FilterEffect> >& mergeInputs); virtual FloatRect uniteChildEffectSubregions(Filter*); void apply(Filter*); @@ -42,9 +42,9 @@ namespace WebCore { TextStream& externalRepresentation(TextStream& ts) const; private: - FEMerge(const Vector<FilterEffect*>&); + FEMerge(const Vector<RefPtr<FilterEffect> >&); - Vector<FilterEffect*> m_mergeInputs; + Vector<RefPtr<FilterEffect> > m_mergeInputs; }; } // namespace WebCore diff --git a/WebCore/svg/graphics/filters/SVGFEMorphology.cpp b/WebCore/svg/graphics/filters/SVGFEMorphology.cpp index 20d109a..987350d 100644 --- a/WebCore/svg/graphics/filters/SVGFEMorphology.cpp +++ b/WebCore/svg/graphics/filters/SVGFEMorphology.cpp @@ -90,6 +90,8 @@ void FEMorphology::apply(Filter* filter) if (!getEffectContext()) return; + setIsAlphaImage(m_in->isAlphaImage()); + if (!m_radiusX || !m_radiusY) return; diff --git a/WebCore/svg/graphics/filters/SVGFEOffset.cpp b/WebCore/svg/graphics/filters/SVGFEOffset.cpp index 9fd50ed..0066c3e 100644 --- a/WebCore/svg/graphics/filters/SVGFEOffset.cpp +++ b/WebCore/svg/graphics/filters/SVGFEOffset.cpp @@ -74,6 +74,8 @@ void FEOffset::apply(Filter* filter) if (!filterContext) return; + setIsAlphaImage(m_in->isAlphaImage()); + FloatRect sourceImageRect = filter->sourceImageRect(); sourceImageRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); diff --git a/WebCore/svg/graphics/filters/SVGFETile.cpp b/WebCore/svg/graphics/filters/SVGFETile.cpp index e97f68f..42da34d 100644 --- a/WebCore/svg/graphics/filters/SVGFETile.cpp +++ b/WebCore/svg/graphics/filters/SVGFETile.cpp @@ -58,6 +58,8 @@ void FETile::apply(Filter* filter) if (!filterContext) return; + setIsAlphaImage(m_in->isAlphaImage()); + IntRect tileRect = enclosingIntRect(m_in->scaledSubRegion()); // Source input needs more attention. It has the size of the filterRegion but gives the diff --git a/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp b/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp index 67668d6..fc6924a 100644 --- a/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp +++ b/WebCore/svg/graphics/filters/SVGFilterBuilder.cpp @@ -42,14 +42,14 @@ SVGFilterBuilder::SVGFilterBuilder() void SVGFilterBuilder::add(const AtomicString& id, RefPtr<FilterEffect> effect) { if (id.isEmpty()) { - m_lastEffect = effect.get(); + m_lastEffect = effect; return; } if (m_builtinEffects.contains(id)) return; - m_lastEffect = effect.get(); + m_lastEffect = effect; m_namedEffects.set(id, m_lastEffect); } |