Changeset 65229 in webkit


Ignore:
Timestamp:
Aug 12, 2010 3:11:08 AM (14 years ago)
Author:
Nikolas Zimmermann
Message:

2010-08-12 Nikolas Zimmermann <nzimmermann@rim.com>

Reviewed by Dirk Schulze.

SVG masking performance very slow
https://bugs.webkit.org/show_bug.cgi?id=43622

Create ImageBuffers only as large as the final rendered size on screen. Only gradient on text on CG handled this correctly so far.
Refactored the code into a new SVGImageBufferTools class, and use the code from RenderSVGResourceMasker -> makes the IE9 demo SVG dice usable.
Clippers, Patterns and Filters remain to be converted.

Test: svg/zoom/page/zoom-mask-with-percentages.svg

  • Android.mk: Add SVGImageBufferTools.* to build.
  • CMakeLists.txt: Ditto.
  • GNUmakefile.am: Ditto.
  • WebCore.gypi: Ditto.
  • WebCore.pro: Ditto.
  • WebCore.xcodeproj/project.pbxproj: Ditto.
  • rendering/RenderSVGAllInOne.cpp: Ditto.
  • rendering/RenderSVGResourceGradient.cpp: Refactored CG gradient specific "create image buffer in absolute coordinates" code into SVGImageBufferTools class. (WebCore::createMaskAndSwapContextForTextGradient): (WebCore::clipToTextMask): (WebCore::RenderSVGResourceGradient::applyResource):
  • rendering/RenderSVGResourceMasker.cpp: Use new SVGImageBufferTools class, to avoid pixelation when zooming and to create image buffers as big as the final rendered size on screen, not more. (WebCore::RenderSVGResourceMasker::invalidateClients): (WebCore::RenderSVGResourceMasker::applyResource): (WebCore::RenderSVGResourceMasker::drawContentIntoMaskImage): (WebCore::RenderSVGResourceMasker::calculateMaskContentRepaintRect): (WebCore::RenderSVGResourceMasker::resourceBoundingBox):
  • rendering/RenderSVGResourceMasker.h:
  • rendering/SVGImageBufferTools.cpp: Added. (WebCore::SVGImageBufferTools::absoluteTransformFromContext): (WebCore::SVGImageBufferTools::createImageBuffer): (WebCore::SVGImageBufferTools::clipToImageBuffer):
  • rendering/SVGImageBufferTools.h: Added. (WebCore::SVGImageBufferTools::SVGImageBufferTools): (WebCore::SVGImageBufferTools::~SVGImageBufferTools):

2010-08-12 Nikolas Zimmermann <nzimmermann@rim.com>

Reviewed by Dirk Schulze.

SVG masking performance very slow
https://bugs.webkit.org/show_bug.cgi?id=43622

Update mask results, now that mask image buffers are as big as the finaled rendered size on screen.
Add new test covering zooming into masks, to show that it doesn't pixelate anymore.

  • platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.checksum:
  • platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png:
  • platform/mac/svg/batik/masking/maskRegions-expected.checksum:
  • platform/mac/svg/batik/masking/maskRegions-expected.png:
  • platform/mac/svg/custom/grayscale-gradient-mask-expected.checksum:
  • platform/mac/svg/custom/grayscale-gradient-mask-expected.png:
  • platform/mac/svg/zoom/page/zoom-mask-with-percentages-expected.checksum: Added.
  • platform/mac/svg/zoom/page/zoom-mask-with-percentages-expected.png: Added.
  • platform/mac/svg/zoom/page/zoom-mask-with-percentages-expected.txt: Added.
  • svg/zoom/page/zoom-mask-with-percentages.svg: Added.
Location:
trunk
Files:
7 added
18 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r65226 r65229  
     12010-08-12  Nikolas Zimmermann  <nzimmermann@rim.com>
     2
     3        Reviewed by Dirk Schulze.
     4
     5        SVG masking performance very slow
     6        https://bugs.webkit.org/show_bug.cgi?id=43622
     7
     8        Update mask results, now that mask image buffers are as big as the finaled rendered size on screen.
     9        Add new test covering zooming into masks, to show that it doesn't pixelate anymore.
     10
     11        * platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.checksum:
     12        * platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png:
     13        * platform/mac/svg/batik/masking/maskRegions-expected.checksum:
     14        * platform/mac/svg/batik/masking/maskRegions-expected.png:
     15        * platform/mac/svg/custom/grayscale-gradient-mask-expected.checksum:
     16        * platform/mac/svg/custom/grayscale-gradient-mask-expected.png:
     17        * platform/mac/svg/zoom/page/zoom-mask-with-percentages-expected.checksum: Added.
     18        * platform/mac/svg/zoom/page/zoom-mask-with-percentages-expected.png: Added.
     19        * platform/mac/svg/zoom/page/zoom-mask-with-percentages-expected.txt: Added.
     20        * svg/zoom/page/zoom-mask-with-percentages.svg: Added.
     21
    1222010-07-14  Marcus Bulach  <bulach@chromium.org>
    223
  • trunk/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.checksum

    r57511 r65229  
    1 12ac53d50854581aa61d0a7b692d688e
     162a68fa8de7ea652f54ced5930397a1e
  • trunk/LayoutTests/platform/mac/svg/batik/masking/maskRegions-expected.checksum

    r52449 r65229  
    1 367e3619b5c94ebd2bc6d7a884c5fde1
     1c8563205e30594d271e4f9ca61aa1817
  • trunk/LayoutTests/platform/mac/svg/custom/grayscale-gradient-mask-expected.checksum

    r53197 r65229  
    1 86c9087a83ecdd5b74c9a4a877f643db
     163c76778f56ccf67c8ad2e82f15dc4e4
  • trunk/WebCore/Android.mk

    r65228 r65229  
    691691        rendering/SVGCharacterData.cpp \
    692692        rendering/SVGCharacterLayoutInfo.cpp \
     693        rendering/SVGImageBufferTools.cpp \
    693694        rendering/SVGInlineFlowBox.cpp \
    694695        rendering/SVGInlineTextBox.cpp \
  • trunk/WebCore/CMakeLists.txt

    r65228 r65229  
    15831583        rendering/SVGCharacterData.cpp
    15841584        rendering/SVGCharacterLayoutInfo.cpp
     1585        rendering/SVGImageBufferTools.cpp
    15851586        rendering/SVGInlineFlowBox.cpp
    15861587        rendering/SVGInlineTextBox.cpp
  • trunk/WebCore/ChangeLog

    r65228 r65229  
     12010-08-12  Nikolas Zimmermann  <nzimmermann@rim.com>
     2
     3        Reviewed by Dirk Schulze.
     4
     5        SVG masking performance very slow
     6        https://bugs.webkit.org/show_bug.cgi?id=43622
     7
     8        Create ImageBuffers only as large as the final rendered size on screen. Only gradient on text on CG handled this correctly so far.
     9        Refactored the code into a new SVGImageBufferTools class, and use the code from RenderSVGResourceMasker -> makes the IE9 demo SVG dice usable.
     10        Clippers, Patterns and Filters remain to be converted.
     11
     12        Test: svg/zoom/page/zoom-mask-with-percentages.svg
     13
     14        * Android.mk: Add SVGImageBufferTools.* to build.
     15        * CMakeLists.txt: Ditto.
     16        * GNUmakefile.am: Ditto.
     17        * WebCore.gypi: Ditto.
     18        * WebCore.pro: Ditto.
     19        * WebCore.xcodeproj/project.pbxproj: Ditto.
     20        * rendering/RenderSVGAllInOne.cpp: Ditto.
     21        * rendering/RenderSVGResourceGradient.cpp: Refactored CG gradient specific "create image buffer in absolute coordinates" code into SVGImageBufferTools class.
     22        (WebCore::createMaskAndSwapContextForTextGradient):
     23        (WebCore::clipToTextMask):
     24        (WebCore::RenderSVGResourceGradient::applyResource):
     25        * rendering/RenderSVGResourceMasker.cpp: Use new SVGImageBufferTools class, to avoid pixelation when zooming and to create image buffers as big as the final rendered size on screen, not more.
     26        (WebCore::RenderSVGResourceMasker::invalidateClients):
     27        (WebCore::RenderSVGResourceMasker::applyResource):
     28        (WebCore::RenderSVGResourceMasker::drawContentIntoMaskImage):
     29        (WebCore::RenderSVGResourceMasker::calculateMaskContentRepaintRect):
     30        (WebCore::RenderSVGResourceMasker::resourceBoundingBox):
     31        * rendering/RenderSVGResourceMasker.h:
     32        * rendering/SVGImageBufferTools.cpp: Added.
     33        (WebCore::SVGImageBufferTools::absoluteTransformFromContext):
     34        (WebCore::SVGImageBufferTools::createImageBuffer):
     35        (WebCore::SVGImageBufferTools::clipToImageBuffer):
     36        * rendering/SVGImageBufferTools.h: Added.
     37        (WebCore::SVGImageBufferTools::SVGImageBufferTools):
     38        (WebCore::SVGImageBufferTools::~SVGImageBufferTools):
     39
    1402010-08-10  Jeremy Orlow  <jorlow@chromium.org>
    241
  • trunk/WebCore/GNUmakefile.am

    r65228 r65229  
    38733873        WebCore/rendering/SVGInlineFlowBox.cpp \
    38743874        WebCore/rendering/SVGInlineFlowBox.h \
     3875        WebCore/rendering/SVGImageBufferTools.cpp \
     3876        WebCore/rendering/SVGImageBufferTools.h \
    38753877        WebCore/rendering/SVGInlineTextBox.cpp \
    38763878        WebCore/rendering/SVGInlineTextBox.h \
  • trunk/WebCore/WebCore.gypi

    r65228 r65229  
    34473447            'rendering/SVGInlineFlowBox.cpp',
    34483448            'rendering/SVGInlineFlowBox.h',
     3449            'rendering/SVGImageBufferTools.cpp',
     3450            'rendering/SVGImageBufferTools.h',
    34493451            'rendering/SVGInlineTextBox.cpp',
    34503452            'rendering/SVGInlineTextBox.h',
  • trunk/WebCore/WebCore.pro

    r65228 r65229  
    19191919    rendering/SVGCharacterData.h \
    19201920    rendering/SVGCharacterLayoutInfo.h \
     1921    rendering/SVGImageBufferTools.h \
    19211922    rendering/SVGInlineFlowBox.h \
    19221923    rendering/SVGInlineTextBox.h \
     
    29722973        rendering/SVGCharacterData.cpp \
    29732974        rendering/SVGCharacterLayoutInfo.cpp \
     2975        rendering/SVGImageBufferTools.cpp \
    29742976        rendering/SVGInlineFlowBox.cpp \
    29752977        rendering/SVGInlineTextBox.cpp \
  • trunk/WebCore/WebCore.xcodeproj/project.pbxproj

    r65228 r65229  
    180180                08C34AFD1179C072002D7456 /* RenderSVGResourceRadialGradient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08C34AFB1179C072002D7456 /* RenderSVGResourceRadialGradient.cpp */; };
    181181                08C34AFE1179C072002D7456 /* RenderSVGResourceRadialGradient.h in Headers */ = {isa = PBXBuildFile; fileRef = 08C34AFC1179C072002D7456 /* RenderSVGResourceRadialGradient.h */; };
     182                08C46B691212F15E0011AF40 /* SVGImageBufferTools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08C46B671212F15D0011AF40 /* SVGImageBufferTools.cpp */; };
     183                08C46B6A1212F15E0011AF40 /* SVGImageBufferTools.h in Headers */ = {isa = PBXBuildFile; fileRef = 08C46B681212F15D0011AF40 /* SVGImageBufferTools.h */; };
    182184                08C4C5180EF19A4000E4840F /* WMLImageElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 08C4C5140EF19A4000E4840F /* WMLImageElement.cpp */; };
    183185                08C4C5190EF19A4000E4840F /* WMLImageElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 08C4C5150EF19A4000E4840F /* WMLImageElement.h */; };
     
    58875889                08C34AFB1179C072002D7456 /* RenderSVGResourceRadialGradient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGResourceRadialGradient.cpp; sourceTree = "<group>"; };
    58885890                08C34AFC1179C072002D7456 /* RenderSVGResourceRadialGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGResourceRadialGradient.h; sourceTree = "<group>"; };
     5891                08C46B671212F15D0011AF40 /* SVGImageBufferTools.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SVGImageBufferTools.cpp; sourceTree = "<group>"; };
     5892                08C46B681212F15D0011AF40 /* SVGImageBufferTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGImageBufferTools.h; sourceTree = "<group>"; };
    58895893                08C4C5140EF19A4000E4840F /* WMLImageElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WMLImageElement.cpp; sourceTree = "<group>"; };
    58905894                08C4C5150EF19A4000E4840F /* WMLImageElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WMLImageElement.h; sourceTree = "<group>"; };
     
    1709117095                                B2B33A5D0B887CEF00C15984 /* SVGCharacterLayoutInfo.cpp */,
    1709217096                                B2B33A5E0B887CEF00C15984 /* SVGCharacterLayoutInfo.h */,
     17097                                08C46B671212F15D0011AF40 /* SVGImageBufferTools.cpp */,
     17098                                08C46B681212F15D0011AF40 /* SVGImageBufferTools.h */,
    1709317099                                853CA9E20AEEC608002372DC /* SVGInlineFlowBox.cpp */,
    1709417100                                853CA9E30AEEC608002372DC /* SVGInlineFlowBox.h */,
     
    2014220148                                97DD4D870FDF4D6E00ECF9A4 /* XSSAuditor.h in Headers */,
    2014320149                                CE172E011136E8CE0062A533 /* ZoomMode.h in Headers */,
     20150                                08C46B6A1212F15E0011AF40 /* SVGImageBufferTools.h in Headers */,
    2014420151                                7AB0B1C11211A62200A76940 /* InspectorStorageAgent.h in Headers */,
    2014520152                                2EED575312109ED0007656BB /* BlobRegistryImpl.h in Headers */,
     
    2256922576                                E1BE512D0CF6C512002EA959 /* XSLTUnicodeSort.cpp in Sources */,
    2257022577                                97DD4D860FDF4D6E00ECF9A4 /* XSSAuditor.cpp in Sources */,
     22578                                08C46B691212F15E0011AF40 /* SVGImageBufferTools.cpp in Sources */,
    2257122579                                7AB0B1C01211A62200A76940 /* InspectorStorageAgent.cpp in Sources */,
    2257222580                                2EED575212109ED0007656BB /* BlobRegistryImpl.cpp in Sources */,
  • trunk/WebCore/rendering/RenderSVGAllInOne.cpp

    r64196 r65229  
    5454#include "SVGCharacterData.cpp"
    5555#include "SVGCharacterLayoutInfo.cpp"
     56#include "SVGImageBufferTools.cpp"
    5657#include "SVGInlineFlowBox.cpp"
    5758#include "SVGInlineTextBox.cpp"
  • trunk/WebCore/rendering/RenderSVGResourceGradient.cpp

    r64275 r65229  
    2929#include "GradientAttributes.h"
    3030#include "GraphicsContext.h"
     31#include "SVGImageBufferTools.h"
    3132#include "SVGRenderSupport.h"
    3233#include <wtf/UnusedParam.h>
     
    7374
    7475#if PLATFORM(CG)
    75 static inline AffineTransform absoluteTransformFromContext(GraphicsContext* context)
    76 {
    77     // Extract current transformation matrix used in the original context. Note that this coordinate
    78     // system is flipped compared to SVGs internal coordinate system, done in WebKit level. Fix
    79     // this transformation by flipping the y component.
    80     return context->getCTM() * AffineTransform().flipY();
    81 }
    82 
    8376static inline bool createMaskAndSwapContextForTextGradient(GraphicsContext*& context,
    8477                                                           GraphicsContext*& savedContext,
     
    8780{
    8881    const RenderObject* textRootBlock = SVGRenderSupport::findTextRootObject(object);
    89 
    90     AffineTransform transform(absoluteTransformFromContext(context));
    91     FloatRect maskAbsoluteBoundingBox = transform.mapRect(textRootBlock->repaintRectInLocalCoordinates());
    92 
    93     IntRect maskImageRect = enclosingIntRect(maskAbsoluteBoundingBox);
    94     if (maskImageRect.isEmpty())
     82    ASSERT(textRootBlock);
     83
     84    AffineTransform absoluteTransform(SVGImageBufferTools::absoluteTransformFromContext(context));
     85    FloatRect absoluteTargetRect = absoluteTransform.mapRect(textRootBlock->repaintRectInLocalCoordinates());
     86
     87    OwnPtr<ImageBuffer> maskImage;
     88    if (!SVGImageBufferTools::createImageBuffer(context, absoluteTransform, absoluteTargetRect, maskImage, DeviceRGB))
    9589        return false;
    9690
    97     // Allocate an image buffer as big as the absolute unclipped size of the object
    98     OwnPtr<ImageBuffer> maskImage = ImageBuffer::create(maskImageRect.size());
    99     if (!maskImage)
    100         return false;
    101 
    102     GraphicsContext* maskImageContext = maskImage->context();
    103 
    104     // Transform the mask image coordinate system to absolute screen coordinates
    105     maskImageContext->translate(-maskAbsoluteBoundingBox.x(), -maskAbsoluteBoundingBox.y());
    106     maskImageContext->concatCTM(transform);
    107 
     91    ASSERT(maskImage);
     92    savedContext = context;
     93    context = maskImage->context();
    10894    imageBuffer = maskImage.release();
    109     savedContext = context;
    110     context = maskImageContext;
    111 
    11295    return true;
    11396}
     
    11598static inline AffineTransform clipToTextMask(GraphicsContext* context,
    11699                                             OwnPtr<ImageBuffer>& imageBuffer,
     100                                             FloatRect& repaintRect,
    117101                                             const RenderObject* object,
    118102                                             GradientData* gradientData)
    119103{
    120104    const RenderObject* textRootBlock = SVGRenderSupport::findTextRootObject(object);
    121 
    122     // The mask image has been created in the device coordinate space, as the image should not be scaled.
    123     // So the actual masking process has to be done in the device coordinate space as well.
    124     AffineTransform transform(absoluteTransformFromContext(context));
    125     context->concatCTM(transform.inverse());
    126     context->clipToImageBuffer(transform.mapRect(textRootBlock->repaintRectInLocalCoordinates()), imageBuffer.get());
    127     context->concatCTM(transform);
     105    ASSERT(textRootBlock);
     106
     107    repaintRect = textRootBlock->repaintRectInLocalCoordinates();
     108
     109    AffineTransform absoluteTransform(SVGImageBufferTools::absoluteTransformFromContext(context));
     110    FloatRect absoluteTargetRect = absoluteTransform.mapRect(repaintRect);
     111
     112    SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, absoluteTargetRect, imageBuffer.get());
    128113
    129114    AffineTransform matrix;
     
    233218            m_savedContext = 0;
    234219
    235             gradientData->gradient->setGradientSpaceTransform(clipToTextMask(context, m_imageBuffer, object, gradientData));
     220            FloatRect repaintRect;
     221            gradientData->gradient->setGradientSpaceTransform(clipToTextMask(context, m_imageBuffer, repaintRect, object, gradientData));
    236222            context->setFillGradient(gradientData->gradient);
    237223
    238             const RenderObject* textRootBlock = SVGRenderSupport::findTextRootObject(object);
    239             context->fillRect(textRootBlock->repaintRectInLocalCoordinates());
    240 
     224            context->fillRect(repaintRect);
    241225            m_imageBuffer.clear();
    242226        }
  • trunk/WebCore/rendering/RenderSVGResourceMasker.cpp

    r64275 r65229  
    3636#include "RenderSVGResource.h"
    3737#include "SVGElement.h"
     38#include "SVGImageBufferTools.h"
    3839#include "SVGMaskElement.h"
    3940#include "SVGStyledElement.h"
     
    6263void RenderSVGResourceMasker::invalidateClients()
    6364{
    64     m_maskBoundaries = FloatRect();
     65    m_maskContentBoundaries = FloatRect();
    6566    if (!m_masker.isEmpty()) {
    6667        deleteAllValues(m_masker);
     
    9697
    9798    MaskerData* maskerData = m_masker.get(object);
    98     if (!maskerData->maskImage && !maskerData->emptyMask) {
     99
     100    AffineTransform absoluteTransform(SVGImageBufferTools::absoluteTransformFromContext(context));
     101    FloatRect maskRect = absoluteTransform.mapRect(object->repaintRectInLocalCoordinates());
     102
     103    if (!maskerData->maskImage && !maskRect.isEmpty()) {
    99104        SVGMaskElement* maskElement = static_cast<SVGMaskElement*>(node());
    100105        if (!maskElement)
    101106            return false;
    102         createMaskImage(maskerData, maskElement, object);
     107
     108        if (!SVGImageBufferTools::createImageBuffer(context, absoluteTransform, maskRect, maskerData->maskImage, LinearRGB))
     109            return false;
     110
     111        ASSERT(maskerData->maskImage);
     112        drawContentIntoMaskImage(maskRect, maskerData, maskElement, object);
    103113    }
    104114
     
    106116        return false;
    107117
    108     context->clipToImageBuffer(maskerData->maskRect, maskerData->maskImage.get());
     118    SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, maskRect, maskerData->maskImage.get());
    109119    return true;
    110120}
    111121
    112 void RenderSVGResourceMasker::createMaskImage(MaskerData* maskerData, const SVGMaskElement* maskElement, RenderObject* object)
    113 {
    114     FloatRect objectBoundingBox = object->objectBoundingBox();
    115 
    116     // Mask rect clipped with clippingBoundingBox and filterBoundingBox as long as they are present.
    117     maskerData->maskRect = object->repaintRectInLocalCoordinates();
    118     if (maskerData->maskRect.isEmpty()) {
    119         maskerData->emptyMask = true;
    120         return;
    121     }
    122    
    123     if (m_maskBoundaries.isEmpty())
    124         calculateMaskContentRepaintRect();
    125 
    126     FloatRect repaintRect = m_maskBoundaries;
    127     AffineTransform contextTransform;
    128     // We need to scale repaintRect for objectBoundingBox to get the drawing area.
     122void RenderSVGResourceMasker::drawContentIntoMaskImage(const FloatRect& maskRect, MaskerData* maskerData, const SVGMaskElement* maskElement, RenderObject* object)
     123{
     124    IntRect maskImageRect = enclosingIntRect(maskRect);
     125    maskImageRect.setLocation(IntPoint());
     126
     127    // Eventually adjust the mask image context according to the target objectBoundingBox.
    129128    if (maskElement->maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
     129        GraphicsContext* maskImageContext = maskerData->maskImage->context();
     130        ASSERT(maskImageContext);
     131
     132        FloatRect objectBoundingBox = object->objectBoundingBox();
     133        AffineTransform contextTransform;
     134        contextTransform.translate(objectBoundingBox.x(), objectBoundingBox.y());
    130135        contextTransform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
    131         FloatPoint contextAdjustment = repaintRect.location();
    132         repaintRect = contextTransform.mapRect(repaintRect);
    133         repaintRect.move(objectBoundingBox.x(), objectBoundingBox.y());
    134         contextTransform.translate(-contextAdjustment.x(), -contextAdjustment.y());
    135     }
    136     repaintRect.intersect(maskerData->maskRect);
    137     maskerData->maskRect = repaintRect;
    138     IntRect maskImageRect = enclosingIntRect(maskerData->maskRect);
    139 
    140     maskImageRect.setLocation(IntPoint());
    141 
    142     // Don't create ImageBuffers with image size of 0
    143     if (maskImageRect.isEmpty()) {
    144         maskerData->emptyMask = true;
    145         return;
    146     }
    147 
    148     // FIXME: This changes color space to linearRGB, the default color space
    149     // for masking operations in SVG. We need a switch for the other color-space
    150     // attribute values sRGB, inherit and auto.
    151     maskerData->maskImage = ImageBuffer::create(maskImageRect.size(), LinearRGB);
    152     if (!maskerData->maskImage)
    153         return;
    154 
    155     GraphicsContext* maskImageContext = maskerData->maskImage->context();
    156     ASSERT(maskImageContext);
    157 
    158     maskImageContext->save();
    159 
    160     if (maskElement->maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)
    161         maskImageContext->translate(-maskerData->maskRect.x(), -maskerData->maskRect.y());
    162     maskImageContext->concatCTM(contextTransform);
    163 
    164     // draw the content into the ImageBuffer
     136        maskImageContext->concatCTM(contextTransform);
     137    }
     138
     139    // Draw the content into the ImageBuffer.
    165140    for (Node* node = maskElement->firstChild(); node; node = node->nextSibling()) {
    166141        RenderObject* renderer = node->renderer();
     
    173148    }
    174149
    175     maskImageContext->restore();
    176 
    177150#if !PLATFORM(CG)
    178151    maskerData->maskImage->transformColorSpace(DeviceRGB, LinearRGB);
     
    207180        if (!style || style->display() == NONE || style->visibility() != VISIBLE)
    208181             continue;
    209         m_maskBoundaries.unite(renderer->localToParentTransform().mapRect(renderer->repaintRectInLocalCoordinates()));
     182        m_maskContentBoundaries.unite(renderer->localToParentTransform().mapRect(renderer->repaintRectInLocalCoordinates()));
    210183    }
    211184}
     
    213186FloatRect RenderSVGResourceMasker::resourceBoundingBox(RenderObject* object)
    214187{
    215     // Resource was not layouted yet. Give back clipping rect of the mask.
    216188    SVGMaskElement* maskElement = static_cast<SVGMaskElement*>(node());
     189    ASSERT(maskElement);
     190
    217191    FloatRect objectBoundingBox = object->objectBoundingBox();
    218192    FloatRect maskBoundaries = maskElement->maskBoundingBox(objectBoundingBox);
     193
     194    // Resource was not layouted yet. Give back clipping rect of the mask.
    219195    if (selfNeedsLayout())
    220196        return maskBoundaries;
    221197
    222     if (m_maskBoundaries.isEmpty())
     198    if (m_maskContentBoundaries.isEmpty())
    223199        calculateMaskContentRepaintRect();
    224200
    225     if (!maskElement)
    226         return FloatRect();
    227 
    228     FloatRect maskRect = m_maskBoundaries;
     201    FloatRect maskRect = m_maskContentBoundaries;
    229202    if (maskElement->maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
    230203        AffineTransform transform;
    231204        transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
    232205        transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
    233         maskRect =  transform.mapRect(maskRect);
     206        maskRect = transform.mapRect(maskRect);
    234207    }
    235208
  • trunk/WebCore/rendering/RenderSVGResourceMasker.h

    r64275 r65229  
    3737
    3838struct MaskerData {
    39     MaskerData()
    40         : emptyMask(false)
    41     {
    42     }
    43 
    4439    OwnPtr<ImageBuffer> maskImage;
    45     FloatRect maskRect;
    46     bool emptyMask;
    4740};
    4841
     
    6760
    6861private:
    69     void createMaskImage(MaskerData*, const SVGMaskElement*, RenderObject*);
     62    void drawContentIntoMaskImage(const FloatRect& maskRect, MaskerData*, const SVGMaskElement*, RenderObject*);
    7063    void calculateMaskContentRepaintRect();
    7164
    72     FloatRect m_maskBoundaries;
     65    FloatRect m_maskContentBoundaries;
    7366    HashMap<RenderObject*, MaskerData*> m_masker;
    7467};
Note: See TracChangeset for help on using the changeset viewer.