diff options
Diffstat (limited to 'WebCore/svg/graphics/SVGPaintServerGradient.cpp')
-rw-r--r-- | WebCore/svg/graphics/SVGPaintServerGradient.cpp | 71 |
1 files changed, 31 insertions, 40 deletions
diff --git a/WebCore/svg/graphics/SVGPaintServerGradient.cpp b/WebCore/svg/graphics/SVGPaintServerGradient.cpp index b06eca1..eb0d80b 100644 --- a/WebCore/svg/graphics/SVGPaintServerGradient.cpp +++ b/WebCore/svg/graphics/SVGPaintServerGradient.cpp @@ -40,11 +40,6 @@ #include "SVGRenderSupport.h" #include "SVGRenderTreeAsText.h" -#if PLATFORM(CG) -#include <wtf/MathExtras.h> -#include <wtf/RetainPtr.h> -#endif - using namespace std; namespace WebCore { @@ -76,10 +71,8 @@ static TextStream& operator<<(TextStream& ts, const Vector<SVGGradientStop>& l) } SVGPaintServerGradient::SVGPaintServerGradient(const SVGGradientElement* owner) - : m_spreadMethod(SpreadMethodPad) - , m_boundingBoxMode(true) + : m_boundingBoxMode(true) , m_ownerElement(owner) - #if PLATFORM(CG) , m_savedContext(0) , m_imageBuffer(0) @@ -102,16 +95,6 @@ void SVGPaintServerGradient::setGradient(PassRefPtr<Gradient> gradient) m_gradient = gradient; } -GradientSpreadMethod SVGPaintServerGradient::spreadMethod() const -{ - return m_spreadMethod; -} - -void SVGPaintServerGradient::setGradientSpreadMethod(const GradientSpreadMethod& method) -{ - m_spreadMethod = method; -} - bool SVGPaintServerGradient::boundingBoxMode() const { return m_boundingBoxMode; @@ -133,8 +116,6 @@ void SVGPaintServerGradient::setGradientTransform(const TransformationMatrix& tr } #if PLATFORM(CG) -// Helper function for text painting in CG -// This Cg specific code should move to GraphicsContext and Font* in a next step. static inline const RenderObject* findTextRootObject(const RenderObject* start) { while (start && !start->isSVGText()) @@ -174,7 +155,7 @@ static inline bool createMaskAndSwapContextForTextGradient( return true; } -static inline void clipToTextMask(GraphicsContext* context, +static inline TransformationMatrix clipToTextMask(GraphicsContext* context, OwnPtr<ImageBuffer>& imageBuffer, const RenderObject* object, const SVGPaintServerGradient* gradientServer) { @@ -193,11 +174,13 @@ static inline void clipToTextMask(GraphicsContext* context, context->clipToImageBuffer(textBoundary, imageBuffer.get()); context->concatCTM(transform); + TransformationMatrix matrix; if (gradientServer->boundingBoxMode()) { - context->translate(maskBBox.x(), maskBBox.y()); - context->scale(FloatSize(maskBBox.width(), maskBBox.height())); + matrix.translate(maskBBox.x(), maskBBox.y()); + matrix.scaleNonUniform(maskBBox.width(), maskBBox.height()); } - context->concatCTM(gradientServer->gradientTransform()); + matrix.multiply(gradientServer->gradientTransform()); + return matrix; } #endif @@ -234,25 +217,29 @@ bool SVGPaintServerGradient::setup(GraphicsContext*& context, const RenderObject applyStrokeStyleToContext(context, object->style(), object); } + TransformationMatrix matrix; + // CG platforms will handle the gradient space transform for text in + // teardown, so we don't apply it here. For non-CG platforms, we + // want the text bounding box applied to the gradient space transform now, + // so the gradient shader can use it. +#if PLATFORM(CG) if (boundingBoxMode() && !isPaintingText) { +#else + if (boundingBoxMode()) { +#endif FloatRect bbox = object->relativeBBox(false); - // Don't use gradientes for 1d objects like horizontal/vertical + // Don't use gradients for 1d objects like horizontal/vertical // lines or rectangles without width or height. if (bbox.width() == 0 || bbox.height() == 0) { Color color(0, 0, 0); context->setStrokeColor(color); return true; } - context->translate(bbox.x(), bbox.y()); - context->scale(FloatSize(bbox.width(), bbox.height())); - - // With scaling the context, the strokeThickness is scaled too. We have to - // undo this. - float strokeThickness = std::max((context->strokeThickness() / ((bbox.width() + bbox.height()) / 2) - 0.001f), 0.f); - context->setStrokeThickness(strokeThickness); + matrix.translate(bbox.x(), bbox.y()); + matrix.scaleNonUniform(bbox.width(), bbox.height()); } - context->concatCTM(gradientTransform()); - context->setSpreadMethod(spreadMethod()); + matrix.multiply(gradientTransform()); + m_gradient->setGradientSpaceTransform(matrix); return true; } @@ -262,15 +249,19 @@ void SVGPaintServerGradient::teardown(GraphicsContext*& context, const RenderObj #if PLATFORM(CG) // renderPath() is not used when painting text, so we paint the gradient during teardown() if (isPaintingText && m_savedContext) { + // Restore on-screen drawing context context = m_savedContext; m_savedContext = 0; - clipToTextMask(context, m_imageBuffer, object, this); + TransformationMatrix matrix = clipToTextMask(context, m_imageBuffer, object, this); + m_gradient->setGradientSpaceTransform(matrix); + context->setFillGradient(m_gradient); + + FloatRect maskBBox = const_cast<RenderObject*>(findTextRootObject(object))->relativeBBox(false); + + context->fillRect(maskBBox); - // finally fill the text clip with the shading - CGContextDrawShading(context->platformContext(), m_gradient->platformGradient()); - m_imageBuffer.clear(); // we're done with our text mask buffer } #endif @@ -284,8 +275,8 @@ TextStream& SVGPaintServerGradient::externalRepresentation(TextStream& ts) const // abstract, don't stream type ts << "[stops=" << gradientStops() << "]"; - if (spreadMethod() != SpreadMethodPad) - ts << "[method=" << spreadMethod() << "]"; + if (m_gradient->spreadMethod() != SpreadMethodPad) + ts << "[method=" << m_gradient->spreadMethod() << "]"; if (!boundingBoxMode()) ts << " [bounding box mode=" << boundingBoxMode() << "]"; if (!gradientTransform().isIdentity()) |