Changeset 65880 in webkit


Ignore:
Timestamp:
Aug 24, 2010 2:25:11 AM (14 years ago)
Author:
Nikolas Zimmermann
Message:

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

Reviewed by Dirk Schulze

clip-path does not work inside mask element
https://bugs.webkit.org/show_bug.cgi?id=41428

Add new tests covering nesting of clippers and maskers, with different unitTypes for the content coordinate system.
Scale all ImageBuffer content to take into account that ImageBuffers use integer based sizes, where the content
is floating-point sized. This compensates rounded errors, when scaling the document.

Tests: svg/clip-path/clip-in-mask-objectBoundingBox.svg

svg/clip-path/clip-in-mask-userSpaceOnUse.svg
svg/clip-path/clip-in-mask.svg
svg/clip-path/deep-nested-clip-in-mask-different-unitTypes.svg
svg/clip-path/deep-nested-clip-in-mask-panning.svg
svg/clip-path/deep-nested-clip-in-mask.svg
svg/clip-path/nested-clip-in-mask-image-based-clipping.svg
svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping.svg
svg/clip-path/nested-clip-in-mask-path-based-clipping.svg

  • rendering/RenderSVGResourceClipper.cpp: (WebCore::RenderSVGResourceClipper::applyResource): Return the value of applyClippingToContext, instead of always true. (WebCore::RenderSVGResourceClipper::applyClippingToContext): Moved some code from createClipData, to avoid having to pass 5 arguments to createClipData. (WebCore::RenderSVGResourceClipper::drawContentIntoMaskImage): Renamed from createClipData.
  • rendering/RenderSVGResourceClipper.h:
  • rendering/RenderSVGResourceGradient.cpp: (WebCore::createMaskAndSwapContextForTextGradient): Pass absoluteTargetRect to createImageBuffer. (WebCore::clipToTextMask): Ditto.
  • rendering/RenderSVGResourceMasker.cpp: (WebCore::RenderSVGResourceMasker::applyResource): Ditto. (WebCore::RenderSVGResourceMasker::drawContentIntoMaskImage): Pass content transformation to renderSubtreeToImageBuffer, to support nesting objectBoundingBox resources.
  • rendering/RenderSVGResourcePattern.cpp: (WebCore::RenderSVGResourcePattern::applyResource): Adapt to calculateTransformationToOutermostSVGCoordinateSystem changes. AffineTransform is now passed as reference. (WebCore::RenderSVGResourcePattern::createTileImage): ImageBuffer content scaling is now handled by createImageBuffer.
  • rendering/SVGImageBufferTools.cpp: (WebCore::SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem): Renamed. Don't return an AffineTransform copy, but instead pass it as reference. (WebCore::SVGImageBufferTools::createImageBuffer): Always scale the ImageBuffer content, to compensate rounding effects (code was only present in patterns so far).

Now also needs the 'absoluteTargetRect' parameter, not only 'clampedAbsoluteTargetRect'.

(WebCore::SVGImageBufferTools::renderSubtreeToImageBuffer): Moved from SVGRenderSupport.
(WebCore::SVGImageBufferTools::clipToImageBuffer): Pass ImageBuffer as OwnPtr reference, to allow to clear it under certain circumstances (see comment).
(WebCore::SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer): Remove AffineTransform parameter, absoluteTargetRect is calculated before passing into this function.

  • rendering/SVGImageBufferTools.h:
  • rendering/SVGRenderSupport.cpp: (WebCore::SVGRenderSupport::prepareToRenderSVGContent): Important change, respect the RenderSVGResourceClipper::applyResource() return value!
  • rendering/SVGRenderSupport.h:
  • svg/SVGFEImageElement.cpp: (WebCore::SVGFEImageElement::build): renderSubtreeToImage now lives in SVGImageBufferTools, adapt code.

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

Reviewed by Dirk Schulze.

clip-path does not work inside mask element
https://bugs.webkit.org/show_bug.cgi?id=41428

Update results of all tests containing <mask> / <pattern> and/or gradient on text (using CG).
The ImageBuffer content is now scaled to account for rounding differences, when zooming.

  • 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/W3C-SVG-1.1/pservers-grad-08-b-expected.checksum:
  • platform/mac/svg/W3C-SVG-1.1/pservers-grad-08-b-expected.png:
  • platform/mac/svg/clip-path/clip-in-mask-expected.checksum: Added.
  • platform/mac/svg/clip-path/clip-in-mask-expected.png: Added.
  • platform/mac/svg/clip-path/clip-in-mask-expected.txt: Added.
  • platform/mac/svg/clip-path/clip-in-mask-objectBoundingBox-expected.checksum: Added.
  • platform/mac/svg/clip-path/clip-in-mask-objectBoundingBox-expected.png: Added.
  • platform/mac/svg/clip-path/clip-in-mask-objectBoundingBox-expected.txt: Added.
  • platform/mac/svg/clip-path/clip-in-mask-userSpaceOnUse-expected.checksum: Added.
  • platform/mac/svg/clip-path/clip-in-mask-userSpaceOnUse-expected.png: Added.
  • platform/mac/svg/clip-path/clip-in-mask-userSpaceOnUse-expected.txt: Added.
  • platform/mac/svg/clip-path/deep-nested-clip-in-mask-different-unitTypes-expected.checksum: Added.
  • platform/mac/svg/clip-path/deep-nested-clip-in-mask-different-unitTypes-expected.png: Added.
  • platform/mac/svg/clip-path/deep-nested-clip-in-mask-different-unitTypes-expected.txt: Added.
  • platform/mac/svg/clip-path/deep-nested-clip-in-mask-expected.checksum: Added.
  • platform/mac/svg/clip-path/deep-nested-clip-in-mask-expected.png: Added.
  • platform/mac/svg/clip-path/deep-nested-clip-in-mask-expected.txt: Added.
  • platform/mac/svg/clip-path/nested-clip-in-mask-image-based-clipping-expected.checksum: Added.
  • platform/mac/svg/clip-path/nested-clip-in-mask-image-based-clipping-expected.png: Added.
  • platform/mac/svg/clip-path/nested-clip-in-mask-image-based-clipping-expected.txt: Added.
  • platform/mac/svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping-expected.checksum: Added.
  • platform/mac/svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping-expected.png: Added.
  • platform/mac/svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping-expected.txt: Added.
  • platform/mac/svg/clip-path/nested-clip-in-mask-path-based-clipping-expected.checksum: Added.
  • platform/mac/svg/clip-path/nested-clip-in-mask-path-based-clipping-expected.png: Added.
  • platform/mac/svg/clip-path/nested-clip-in-mask-path-based-clipping-expected.txt: Added.
  • platform/mac/svg/custom/absolute-sized-content-with-resources-expected.checksum:
  • platform/mac/svg/custom/absolute-sized-content-with-resources-expected.png:
  • platform/mac/svg/custom/grayscale-gradient-mask-expected.checksum:
  • platform/mac/svg/custom/grayscale-gradient-mask-expected.png:
  • platform/mac/svg/custom/js-late-gradient-and-object-creation-expected.checksum:
  • platform/mac/svg/custom/js-late-gradient-and-object-creation-expected.png:
  • platform/mac/svg/custom/text-rotated-gradient-expected.checksum:
  • platform/mac/svg/custom/text-rotated-gradient-expected.png:
  • platform/mac/svg/text/selection-background-color-expected.checksum:
  • platform/mac/svg/text/selection-background-color-expected.png:
  • platform/mac/svg/transforms/text-with-mask-with-svg-transform-expected.checksum:
  • platform/mac/svg/transforms/text-with-mask-with-svg-transform-expected.png:
  • platform/mac/svg/zoom/page/zoom-mask-with-percentages-expected.checksum:
  • platform/mac/svg/zoom/page/zoom-mask-with-percentages-expected.png:
  • svg/clip-path/clip-in-mask-objectBoundingBox.svg: Added.
  • svg/clip-path/clip-in-mask-userSpaceOnUse.svg: Added.
  • svg/clip-path/clip-in-mask.svg: Added.
  • svg/clip-path/deep-nested-clip-in-mask-different-unitTypes.svg: Added.
  • svg/clip-path/deep-nested-clip-in-mask.svg: Added.
  • svg/clip-path/nested-clip-in-mask-image-based-clipping.svg: Added.
  • svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping.svg: Added.
  • svg/clip-path/nested-clip-in-mask-path-based-clipping.svg: Added.
Location:
trunk
Files:
36 added
30 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r65879 r65880  
     12010-08-24  Nikolas Zimmermann  <nzimmermann@rim.com>
     2
     3        Reviewed by Dirk Schulze.
     4
     5        clip-path does not work inside mask element
     6        https://bugs.webkit.org/show_bug.cgi?id=41428
     7
     8        Update results of all tests containing <mask> / <pattern> and/or gradient on text (using CG).
     9        The ImageBuffer content is now scaled to account for rounding differences, when zooming.
     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/W3C-SVG-1.1/pservers-grad-08-b-expected.checksum:
     14        * platform/mac/svg/W3C-SVG-1.1/pservers-grad-08-b-expected.png:
     15        * platform/mac/svg/clip-path/clip-in-mask-expected.checksum: Added.
     16        * platform/mac/svg/clip-path/clip-in-mask-expected.png: Added.
     17        * platform/mac/svg/clip-path/clip-in-mask-expected.txt: Added.
     18        * platform/mac/svg/clip-path/clip-in-mask-objectBoundingBox-expected.checksum: Added.
     19        * platform/mac/svg/clip-path/clip-in-mask-objectBoundingBox-expected.png: Added.
     20        * platform/mac/svg/clip-path/clip-in-mask-objectBoundingBox-expected.txt: Added.
     21        * platform/mac/svg/clip-path/clip-in-mask-userSpaceOnUse-expected.checksum: Added.
     22        * platform/mac/svg/clip-path/clip-in-mask-userSpaceOnUse-expected.png: Added.
     23        * platform/mac/svg/clip-path/clip-in-mask-userSpaceOnUse-expected.txt: Added.
     24        * platform/mac/svg/clip-path/deep-nested-clip-in-mask-different-unitTypes-expected.checksum: Added.
     25        * platform/mac/svg/clip-path/deep-nested-clip-in-mask-different-unitTypes-expected.png: Added.
     26        * platform/mac/svg/clip-path/deep-nested-clip-in-mask-different-unitTypes-expected.txt: Added.
     27        * platform/mac/svg/clip-path/deep-nested-clip-in-mask-expected.checksum: Added.
     28        * platform/mac/svg/clip-path/deep-nested-clip-in-mask-expected.png: Added.
     29        * platform/mac/svg/clip-path/deep-nested-clip-in-mask-expected.txt: Added.
     30        * platform/mac/svg/clip-path/nested-clip-in-mask-image-based-clipping-expected.checksum: Added.
     31        * platform/mac/svg/clip-path/nested-clip-in-mask-image-based-clipping-expected.png: Added.
     32        * platform/mac/svg/clip-path/nested-clip-in-mask-image-based-clipping-expected.txt: Added.
     33        * platform/mac/svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping-expected.checksum: Added.
     34        * platform/mac/svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping-expected.png: Added.
     35        * platform/mac/svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping-expected.txt: Added.
     36        * platform/mac/svg/clip-path/nested-clip-in-mask-path-based-clipping-expected.checksum: Added.
     37        * platform/mac/svg/clip-path/nested-clip-in-mask-path-based-clipping-expected.png: Added.
     38        * platform/mac/svg/clip-path/nested-clip-in-mask-path-based-clipping-expected.txt: Added.
     39        * platform/mac/svg/custom/absolute-sized-content-with-resources-expected.checksum:
     40        * platform/mac/svg/custom/absolute-sized-content-with-resources-expected.png:
     41        * platform/mac/svg/custom/grayscale-gradient-mask-expected.checksum:
     42        * platform/mac/svg/custom/grayscale-gradient-mask-expected.png:
     43        * platform/mac/svg/custom/js-late-gradient-and-object-creation-expected.checksum:
     44        * platform/mac/svg/custom/js-late-gradient-and-object-creation-expected.png:
     45        * platform/mac/svg/custom/text-rotated-gradient-expected.checksum:
     46        * platform/mac/svg/custom/text-rotated-gradient-expected.png:
     47        * platform/mac/svg/text/selection-background-color-expected.checksum:
     48        * platform/mac/svg/text/selection-background-color-expected.png:
     49        * platform/mac/svg/transforms/text-with-mask-with-svg-transform-expected.checksum:
     50        * platform/mac/svg/transforms/text-with-mask-with-svg-transform-expected.png:
     51        * platform/mac/svg/zoom/page/zoom-mask-with-percentages-expected.checksum:
     52        * platform/mac/svg/zoom/page/zoom-mask-with-percentages-expected.png:
     53        * svg/clip-path/clip-in-mask-objectBoundingBox.svg: Added.
     54        * svg/clip-path/clip-in-mask-userSpaceOnUse.svg: Added.
     55        * svg/clip-path/clip-in-mask.svg: Added.
     56        * svg/clip-path/deep-nested-clip-in-mask-different-unitTypes.svg: Added.
     57        * svg/clip-path/deep-nested-clip-in-mask.svg: Added.
     58        * svg/clip-path/nested-clip-in-mask-image-based-clipping.svg: Added.
     59        * svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping.svg: Added.
     60        * svg/clip-path/nested-clip-in-mask-path-based-clipping.svg: Added.
     61
    1622010-08-24  Andrei Popescu  <andreip@dhcp-172-16-14-12.lon.corp.google.com>
    263
  • trunk/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.checksum

    r65229 r65880  
    1 62a68fa8de7ea652f54ced5930397a1e
     1c9143af98632ecc250a30eb1902e35dc
  • trunk/LayoutTests/platform/mac/svg/W3C-SVG-1.1/pservers-grad-08-b-expected.checksum

    r65665 r65880  
    1 effebeceed60e2edcd5795281c16f129
     1b4d10b39924990573785324a4e3813da
  • trunk/LayoutTests/platform/mac/svg/custom/absolute-sized-content-with-resources-expected.checksum

    r65665 r65880  
    1 f482ede9c5fc18f3f09a70545af6ba67
     170e709058a071d7207192c403ee1deb2
  • trunk/LayoutTests/platform/mac/svg/custom/grayscale-gradient-mask-expected.checksum

    r65665 r65880  
    1 c9fa987aacc7c5064491999daceb0d4f
     1791d8651a70b39d17fac23e5ccafca53
  • trunk/LayoutTests/platform/mac/svg/custom/js-late-gradient-and-object-creation-expected.checksum

    r65665 r65880  
    1 79c35c1f034795088b8a008729997baa
     13cdac160082fd7d24f5e65d83ddf7958
  • trunk/LayoutTests/platform/mac/svg/custom/text-rotated-gradient-expected.checksum

    r65665 r65880  
    1 7c0fe736cb4ed2a2a51eb2458251e610
     1ce7c2f3d28648885b0045fc74eaaf8f4
  • trunk/LayoutTests/platform/mac/svg/text/selection-background-color-expected.checksum

    r65665 r65880  
    1 1ad4cec1470600775011aa727d7a5c94
     13165f6d9b00829dfa0119222f11e2585
  • trunk/LayoutTests/platform/mac/svg/transforms/text-with-mask-with-svg-transform-expected.checksum

    r65665 r65880  
    1 ab99a5d800d7ea930b1151158e14be69
     134ebee33d4d97a2e82a75241afcfe9eb
  • trunk/LayoutTests/platform/mac/svg/zoom/page/zoom-mask-with-percentages-expected.checksum

    r65665 r65880  
    1 28befae5e6709c12c60fd2e448dff271
     1c9f4cbaab8844bc7b6bf998831f89a3e
  • trunk/WebCore/ChangeLog

    r65879 r65880  
     12010-08-24  Nikolas Zimmermann  <nzimmermann@rim.com>
     2
     3        Reviewed by Dirk Schulze
     4
     5        clip-path does not work inside mask element
     6        https://bugs.webkit.org/show_bug.cgi?id=41428
     7
     8        Add new tests covering nesting of clippers and maskers, with different unitTypes for the content coordinate system.
     9        Scale all ImageBuffer content to take into account that ImageBuffers use integer based sizes, where the content
     10        is floating-point sized. This compensates rounded errors, when scaling the document.
     11
     12        Tests: svg/clip-path/clip-in-mask-objectBoundingBox.svg
     13               svg/clip-path/clip-in-mask-userSpaceOnUse.svg
     14               svg/clip-path/clip-in-mask.svg
     15               svg/clip-path/deep-nested-clip-in-mask-different-unitTypes.svg
     16               svg/clip-path/deep-nested-clip-in-mask-panning.svg
     17               svg/clip-path/deep-nested-clip-in-mask.svg
     18               svg/clip-path/nested-clip-in-mask-image-based-clipping.svg
     19               svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping.svg
     20               svg/clip-path/nested-clip-in-mask-path-based-clipping.svg
     21
     22        * rendering/RenderSVGResourceClipper.cpp:
     23        (WebCore::RenderSVGResourceClipper::applyResource): Return the value of applyClippingToContext, instead of always true.
     24        (WebCore::RenderSVGResourceClipper::applyClippingToContext): Moved some code from createClipData, to avoid having to pass 5 arguments to createClipData.
     25        (WebCore::RenderSVGResourceClipper::drawContentIntoMaskImage): Renamed from createClipData.
     26        * rendering/RenderSVGResourceClipper.h:
     27        * rendering/RenderSVGResourceGradient.cpp:
     28        (WebCore::createMaskAndSwapContextForTextGradient): Pass absoluteTargetRect to createImageBuffer.
     29        (WebCore::clipToTextMask): Ditto.
     30        * rendering/RenderSVGResourceMasker.cpp:
     31        (WebCore::RenderSVGResourceMasker::applyResource): Ditto.
     32        (WebCore::RenderSVGResourceMasker::drawContentIntoMaskImage): Pass content transformation to renderSubtreeToImageBuffer, to support nesting objectBoundingBox resources.
     33        * rendering/RenderSVGResourcePattern.cpp:
     34        (WebCore::RenderSVGResourcePattern::applyResource): Adapt to calculateTransformationToOutermostSVGCoordinateSystem changes. AffineTransform is now passed as reference.
     35        (WebCore::RenderSVGResourcePattern::createTileImage): ImageBuffer content scaling is now handled by createImageBuffer.
     36        * rendering/SVGImageBufferTools.cpp:
     37        (WebCore::SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem): Renamed. Don't return an AffineTransform copy, but instead pass it as reference.
     38        (WebCore::SVGImageBufferTools::createImageBuffer): Always scale the ImageBuffer content, to compensate rounding effects (code was only present in patterns so far).
     39                                                           Now also needs the 'absoluteTargetRect' parameter, not only 'clampedAbsoluteTargetRect'.
     40        (WebCore::SVGImageBufferTools::renderSubtreeToImageBuffer): Moved from SVGRenderSupport.
     41        (WebCore::SVGImageBufferTools::clipToImageBuffer): Pass ImageBuffer as OwnPtr reference, to allow to clear it under certain circumstances (see comment).
     42        (WebCore::SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer): Remove AffineTransform parameter, absoluteTargetRect is calculated before passing into this function.
     43        * rendering/SVGImageBufferTools.h:
     44        * rendering/SVGRenderSupport.cpp:
     45        (WebCore::SVGRenderSupport::prepareToRenderSVGContent): Important change, respect the RenderSVGResourceClipper::applyResource() return value!
     46        * rendering/SVGRenderSupport.h:
     47        * svg/SVGFEImageElement.cpp:
     48        (WebCore::SVGFEImageElement::build): renderSubtreeToImage now lives in SVGImageBufferTools, adapt code.
     49
    1502010-08-24  Andrei Popescu  <andreip@dhcp-172-16-14-12.lon.corp.google.com>
    251
  • trunk/WebCore/rendering/RenderSVGResourceClipper.cpp

    r65729 r65880  
    102102#endif
    103103
    104     applyClippingToContext(object, object->objectBoundingBox(), object->repaintRectInLocalCoordinates(), context);
    105     return true;
     104    return applyClippingToContext(object, object->objectBoundingBox(), object->repaintRectInLocalCoordinates(), context);
    106105}
    107106
     
    173172    }
    174173
    175     AffineTransform absoluteTransform = SVGImageBufferTools::transformationToOutermostSVGCoordinateSystem(object);
    176     FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(object, absoluteTransform, repaintRect);
    177 
    178     if (shouldCreateClipData)
    179         createClipData(clipperData, objectBoundingBox, repaintRect, clampedAbsoluteTargetRect, absoluteTransform);
     174    AffineTransform absoluteTransform;
     175    SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransform);
     176
     177    FloatRect absoluteTargetRect = absoluteTransform.mapRect(repaintRect);
     178    FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(object, absoluteTargetRect);
     179
     180    if (shouldCreateClipData && !clampedAbsoluteTargetRect.isEmpty()) {
     181        if (!SVGImageBufferTools::createImageBuffer(absoluteTargetRect, clampedAbsoluteTargetRect, clipperData->clipMaskImage, DeviceRGB))
     182            return false;
     183
     184        GraphicsContext* maskContext = clipperData->clipMaskImage->context();
     185        ASSERT(maskContext);
     186
     187        // The save/restore pair is needed for clipToImageBuffer - it doesn't work without it on non-Cg platforms.
     188        maskContext->save();
     189        maskContext->translate(-clampedAbsoluteTargetRect.x(), -clampedAbsoluteTargetRect.y());
     190        maskContext->concatCTM(absoluteTransform);
     191
     192        // clipPath can also be clipped by another clipPath.
     193        if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this)) {
     194            if (RenderSVGResourceClipper* clipper = resources->clipper()) {
     195                if (!clipper->applyClippingToContext(this, objectBoundingBox, repaintRect, maskContext)) {
     196                    maskContext->restore();
     197                    return false;
     198                }
     199            }
     200        }
     201
     202        drawContentIntoMaskImage(clipperData, objectBoundingBox);
     203        maskContext->restore();
     204    }
    180205
    181206    if (!clipperData->clipMaskImage)
    182207        return false;
    183208
    184     SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, clampedAbsoluteTargetRect, clipperData->clipMaskImage.get());
     209    SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, clampedAbsoluteTargetRect, clipperData->clipMaskImage);
    185210    return true;
    186211}
    187212
    188 bool RenderSVGResourceClipper::createClipData(ClipperData* clipperData,
    189                                               const FloatRect& objectBoundingBox,
    190                                               const FloatRect& repaintRect,
    191                                               const FloatRect& clampedAbsoluteTargetRect,
    192                                               const AffineTransform& absoluteTransform)
    193 {
    194     if (!SVGImageBufferTools::createImageBuffer(clampedAbsoluteTargetRect, clipperData->clipMaskImage, DeviceRGB))
    195         return false;
     213bool RenderSVGResourceClipper::drawContentIntoMaskImage(ClipperData* clipperData, const FloatRect& objectBoundingBox)
     214{
     215    ASSERT(clipperData);
     216    ASSERT(clipperData->clipMaskImage);
    196217
    197218    GraphicsContext* maskContext = clipperData->clipMaskImage->context();
    198219    ASSERT(maskContext);
    199220
    200     maskContext->save();
    201     maskContext->translate(-clampedAbsoluteTargetRect.x(), -clampedAbsoluteTargetRect.y());
    202     maskContext->concatCTM(absoluteTransform);
    203 
    204     // clipPath can also be clipped by another clipPath.
    205     if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this)) {
    206         if (RenderSVGResourceClipper* clipper = resources->clipper()) {
    207             if (!clipper->applyClippingToContext(this, objectBoundingBox, repaintRect, maskContext)) {
    208                 maskContext->restore();
    209                 return false;
    210             }
    211         }
    212     }
    213 
     221    AffineTransform maskContentTransformation;
    214222    SVGClipPathElement* clipPath = static_cast<SVGClipPathElement*>(node());
    215223    if (clipPath->clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
    216         maskContext->translate(objectBoundingBox.x(), objectBoundingBox.y());
    217         maskContext->scale(objectBoundingBox.size());
     224        maskContentTransformation.translate(objectBoundingBox.x(), objectBoundingBox.y());
     225        maskContentTransformation.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
     226        maskContext->concatCTM(maskContentTransformation);
    218227    }
    219228
     
    263272
    264273        // In the case of a <use> element, we obtained its renderere above, to retrieve its clipRule.
    265         // We hsve to pass the <use> renderer itself to renderSubtreeToImage() to apply it's x/y/transform/etc. values when rendering.
     274        // We have to pass the <use> renderer itself to renderSubtreeToImageBuffer() to apply it's x/y/transform/etc. values when rendering.
    266275        // So if isUseElement is true, refetch the childNode->renderer(), as renderer got overriden above.
    267         SVGRenderSupport::renderSubtreeToImage(clipperData->clipMaskImage.get(), isUseElement ? childNode->renderer() : renderer);
     276        SVGImageBufferTools::renderSubtreeToImageBuffer(clipperData->clipMaskImage.get(), isUseElement ? childNode->renderer() : renderer, maskContentTransformation);
    268277
    269278        renderer->setStyle(oldRenderStyle.release());
    270279        m_invalidationBlocked = false;
    271280    }
    272 
    273     maskContext->restore();
    274281
    275282    return true;
  • trunk/WebCore/rendering/RenderSVGResourceClipper.h

    r65729 r65880  
    6666    bool applyClippingToContext(RenderObject*, const FloatRect&, const FloatRect&, GraphicsContext*);
    6767    bool pathOnlyClipping(GraphicsContext*, const FloatRect&);
    68     bool createClipData(ClipperData*, const FloatRect& objectBoundingBox, const FloatRect& repaintRect, const FloatRect& clampedAbsoluteTargetRect, const AffineTransform& absoluteTransform);
    69 
     68    bool drawContentIntoMaskImage(ClipperData*, const FloatRect& objectBoundingBox);
    7069    void calculateClipContentRepaintRect();
    7170
  • trunk/WebCore/rendering/RenderSVGResourceGradient.cpp

    r65665 r65880  
    8181    ASSERT(textRootBlock);
    8282
    83     AffineTransform absoluteTransform(SVGImageBufferTools::transformationToOutermostSVGCoordinateSystem(textRootBlock));
    84     FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(textRootBlock, absoluteTransform, textRootBlock->repaintRectInLocalCoordinates());
     83    AffineTransform absoluteTransform;
     84    SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(textRootBlock, absoluteTransform);
     85
     86    FloatRect absoluteTargetRect = absoluteTransform.mapRect(textRootBlock->repaintRectInLocalCoordinates());
     87    FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(textRootBlock, absoluteTargetRect);
    8588    if (clampedAbsoluteTargetRect.isEmpty())
    8689        return false;
    8790
    8891    OwnPtr<ImageBuffer> maskImage;
    89     if (!SVGImageBufferTools::createImageBuffer(clampedAbsoluteTargetRect, maskImage, DeviceRGB))
     92    if (!SVGImageBufferTools::createImageBuffer(absoluteTargetRect, clampedAbsoluteTargetRect, maskImage, DeviceRGB))
    9093        return false;
    9194
     
    114117    targetRect = textRootBlock->repaintRectInLocalCoordinates();
    115118
    116     AffineTransform absoluteTransform(SVGImageBufferTools::transformationToOutermostSVGCoordinateSystem(textRootBlock));
    117     FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(textRootBlock, absoluteTransform, targetRect);
    118 
    119     SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, clampedAbsoluteTargetRect, imageBuffer.get());
     119    AffineTransform absoluteTransform;
     120    SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(textRootBlock, absoluteTransform);
     121
     122    FloatRect absoluteTargetRect = absoluteTransform.mapRect(targetRect);
     123    FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(textRootBlock, absoluteTargetRect);
     124
     125    SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, clampedAbsoluteTargetRect, imageBuffer);
    120126
    121127    AffineTransform matrix;
  • trunk/WebCore/rendering/RenderSVGResourceMasker.cpp

    r65665 r65880  
    9797    MaskerData* maskerData = m_masker.get(object);
    9898
    99     AffineTransform absoluteTransform(SVGImageBufferTools::transformationToOutermostSVGCoordinateSystem(object));
    100     FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(object, absoluteTransform, object->repaintRectInLocalCoordinates());
     99    AffineTransform absoluteTransform;
     100    SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransform);
     101
     102    FloatRect absoluteTargetRect = absoluteTransform.mapRect(object->repaintRectInLocalCoordinates());
     103    FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(object, absoluteTargetRect);
    101104
    102105    if (!maskerData->maskImage && !clampedAbsoluteTargetRect.isEmpty()) {
     
    105108            return false;
    106109
    107         if (!SVGImageBufferTools::createImageBuffer(clampedAbsoluteTargetRect, maskerData->maskImage, LinearRGB))
     110        if (!SVGImageBufferTools::createImageBuffer(absoluteTargetRect, clampedAbsoluteTargetRect, maskerData->maskImage, LinearRGB))
    108111            return false;
    109112
     
    111114        ASSERT(maskImageContext);
    112115
     116        // The save/restore pair is needed for clipToImageBuffer - it doesn't work without it on non-Cg platforms.
     117        maskImageContext->save();
    113118        maskImageContext->translate(-clampedAbsoluteTargetRect.x(), -clampedAbsoluteTargetRect.y());
    114119        maskImageContext->concatCTM(absoluteTransform);
     
    120125        return false;
    121126
    122     SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, clampedAbsoluteTargetRect, maskerData->maskImage.get());
     127    SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, clampedAbsoluteTargetRect, maskerData->maskImage);
    123128    return true;
    124129}
     
    126131void RenderSVGResourceMasker::drawContentIntoMaskImage(MaskerData* maskerData, const SVGMaskElement* maskElement, RenderObject* object)
    127132{
     133    GraphicsContext* maskImageContext = maskerData->maskImage->context();
     134    ASSERT(maskImageContext);
     135
    128136    // Eventually adjust the mask image context according to the target objectBoundingBox.
     137    AffineTransform maskContentTransformation;
    129138    if (maskElement->maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
    130         GraphicsContext* maskImageContext = maskerData->maskImage->context();
    131         ASSERT(maskImageContext);
    132 
    133139        FloatRect objectBoundingBox = object->objectBoundingBox();
    134         maskImageContext->translate(objectBoundingBox.x(), objectBoundingBox.y());
    135         maskImageContext->scale(FloatSize(objectBoundingBox.width(), objectBoundingBox.height()));
     140        maskContentTransformation.translate(objectBoundingBox.x(), objectBoundingBox.y());
     141        maskContentTransformation.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
     142        maskImageContext->concatCTM(maskContentTransformation);
    136143    }
    137144
     
    144151        if (!style || style->display() == NONE || style->visibility() != VISIBLE)
    145152            continue;
    146         SVGRenderSupport::renderSubtreeToImage(maskerData->maskImage.get(), renderer);
    147     }
     153        SVGImageBufferTools::renderSubtreeToImageBuffer(maskerData->maskImage.get(), renderer, maskContentTransformation);
     154    }
     155
     156    maskImageContext->restore();
    148157
    149158#if !PLATFORM(CG)
  • trunk/WebCore/rendering/RenderSVGResourcePattern.cpp

    r65665 r65880  
    102102        AffineTransform tileImageTransform = buildTileImageTransform(object, attributes, patternElement, tileBoundaries);
    103103
    104         AffineTransform absoluteTransform(SVGImageBufferTools::transformationToOutermostSVGCoordinateSystem(object));
     104        AffineTransform absoluteTransform;
     105        SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransform);
     106
    105107        FloatRect absoluteTileBoundaries = absoluteTransform.mapRect(tileBoundaries);
    106108
     
    245247    OwnPtr<ImageBuffer> tileImage;
    246248
    247     if (!SVGImageBufferTools::createImageBuffer(clampedAbsoluteTileBoundaries, tileImage, DeviceRGB))
     249    if (!SVGImageBufferTools::createImageBuffer(absoluteTileBoundaries, clampedAbsoluteTileBoundaries, tileImage, DeviceRGB))
    248250        return PassOwnPtr<ImageBuffer>();
    249251
    250252    GraphicsContext* tileImageContext = tileImage->context();
    251253    ASSERT(tileImageContext);
    252 
    253     // Compensate rounding effects, as the absolute target rect is using floating-point numbers and the image buffer size is integer.
    254     IntSize unclampedImageSize(SVGImageBufferTools::roundedImageBufferSize(absoluteTileBoundaries.size()));
    255     tileImageContext->scale(FloatSize(unclampedImageSize.width() / absoluteTileBoundaries.width(),
    256                                       unclampedImageSize.height() / absoluteTileBoundaries.height()));
    257254
    258255    // The image buffer represents the final rendered size, so the content has to be scaled (to avoid pixelation).
     
    263260    if (!tileImageTransform.isIdentity())
    264261        tileImageContext->concatCTM(tileImageTransform);
     262
     263    AffineTransform contentTransformation;
    265264
    266265    // Draw the content into the ImageBuffer.
     
    268267        if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !node->renderer())
    269268            continue;
    270         SVGRenderSupport::renderSubtreeToImage(tileImage.get(), node->renderer());
     269        SVGImageBufferTools::renderSubtreeToImageBuffer(tileImage.get(), node->renderer(), contentTransformation);
    271270    }
    272271
  • trunk/WebCore/rendering/SVGImageBufferTools.cpp

    r65665 r65880  
    2626#include "GraphicsContext.h"
    2727#include "RenderObject.h"
     28#include "RenderSVGContainer.h"
    2829#include "RenderSVGRoot.h"
    2930
    3031namespace WebCore {
    3132
    32 AffineTransform SVGImageBufferTools::transformationToOutermostSVGCoordinateSystem(const RenderObject* renderer)
     33static AffineTransform& currentContentTransformation()
    3334{
    34     ASSERT(renderer);
     35    DEFINE_STATIC_LOCAL(AffineTransform, s_currentContentTransformation, ());
     36    return s_currentContentTransformation;
     37}
    3538
     39void SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(const RenderObject* renderer, AffineTransform& absoluteTransform)
     40{
    3641    const RenderObject* current = renderer;
    3742    ASSERT(current);
    3843
    39     AffineTransform ctm;
     44    absoluteTransform = currentContentTransformation();
    4045    while (current) {
    41         ctm.multiply(current->localToParentTransform());
     46        absoluteTransform.multiply(current->localToParentTransform());
    4247        if (current->isSVGRoot())
    4348            break;
    44 
    4549        current = current->parent();
    4650    }
    47 
    48     return ctm;
    4951}
    5052
    51 bool SVGImageBufferTools::createImageBuffer(const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>& imageBuffer, ImageColorSpace colorSpace)
     53bool SVGImageBufferTools::createImageBuffer(const FloatRect& absoluteTargetRect, const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>& imageBuffer, ImageColorSpace colorSpace)
    5254{
    5355    IntSize imageSize(roundedImageBufferSize(clampedAbsoluteTargetRect.size()));
     56    IntSize unclampedImageSize(SVGImageBufferTools::roundedImageBufferSize(absoluteTargetRect.size()));
    5457
    5558    // Don't create empty ImageBuffers.
     
    6164        return false;
    6265
     66    GraphicsContext* imageContext = image->context();
     67    ASSERT(imageContext);
     68
     69    // Compensate rounding effects, as the absolute target rect is using floating-point numbers and the image buffer size is integer.
     70    imageContext->scale(FloatSize(unclampedImageSize.width() / absoluteTargetRect.width(), unclampedImageSize.height() / absoluteTargetRect.height()));
     71
    6372    imageBuffer = image.release();
    6473    return true;
    6574}
    6675
    67 void SVGImageBufferTools::clipToImageBuffer(GraphicsContext* context, const AffineTransform& absoluteTransform, const FloatRect& clampedAbsoluteTargetRect, ImageBuffer* imageBuffer)
     76void SVGImageBufferTools::renderSubtreeToImageBuffer(ImageBuffer* image, RenderObject* item, const AffineTransform& subtreeContentTransformation)
     77{
     78    ASSERT(item);
     79    ASSERT(image);
     80    ASSERT(image->context());
     81
     82    PaintInfo info(image->context(), PaintInfo::infiniteRect(), PaintPhaseForeground, 0, 0, 0);
     83
     84    // FIXME: isSVGContainer returns true for RenderSVGViewportContainer, so if this is ever
     85    // called with one of those, we will read from the wrong offset in an object due to a bad cast.
     86    RenderSVGContainer* svgContainer = 0;
     87    if (item && item->isSVGContainer())
     88        svgContainer = toRenderSVGContainer(item);
     89
     90    bool drawsContents = svgContainer ? svgContainer->drawsContents() : false;
     91    if (svgContainer && !drawsContents)
     92        svgContainer->setDrawsContents(true);
     93
     94    AffineTransform& contentTransformation = currentContentTransformation();
     95    AffineTransform savedContentTransformation = contentTransformation;
     96    contentTransformation.multiply(subtreeContentTransformation);
     97
     98    item->layoutIfNeeded();
     99    item->paint(info, 0, 0);
     100
     101    contentTransformation = savedContentTransformation;
     102
     103    if (svgContainer && !drawsContents)
     104        svgContainer->setDrawsContents(false);
     105}
     106
     107void SVGImageBufferTools::clipToImageBuffer(GraphicsContext* context, const AffineTransform& absoluteTransform, const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>& imageBuffer)
    68108{
    69109    ASSERT(context);
    70110    ASSERT(imageBuffer);
    71111
    72     // The mask image has been created in the device coordinate space, as the image should not be scaled.
    73     // So the actual masking process has to be done in the device coordinate space as well.
     112    // The mask image has been created in the absolute coordinate space, as the image should not be scaled.
     113    // So the actual masking process has to be done in the absolute coordinate space as well.
    74114    context->concatCTM(absoluteTransform.inverse());
    75     context->clipToImageBuffer(imageBuffer, clampedAbsoluteTargetRect);
     115    context->clipToImageBuffer(imageBuffer.get(), clampedAbsoluteTargetRect);
    76116    context->concatCTM(absoluteTransform);
     117
     118    // When nesting resources, with objectBoundingBox as content unit types, there's no use in caching the
     119    // resulting image buffer as the parent resource already caches the result.
     120    if (!currentContentTransformation().isIdentity())
     121        imageBuffer.clear();
    77122}
    78123
     
    82127}
    83128
    84 FloatRect SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(const RenderObject* renderer, const AffineTransform& absoluteTransform, const FloatRect& targetRect)
     129FloatRect SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(const RenderObject* renderer, const FloatRect& absoluteTargetRect)
    85130{
    86131    ASSERT(renderer);
    87132
    88133    const RenderSVGRoot* svgRoot = SVGRenderSupport::findTreeRootObject(renderer);
    89     FloatRect clampedAbsoluteTargetRect = absoluteTransform.mapRect(targetRect);
     134    FloatRect clampedAbsoluteTargetRect = absoluteTargetRect;
    90135    clampedAbsoluteTargetRect.intersect(svgRoot->contentBoxRect());
    91136    return clampedAbsoluteTargetRect;
  • trunk/WebCore/rendering/SVGImageBufferTools.h

    r65665 r65880  
    3535class SVGImageBufferTools : public Noncopyable {
    3636public:
    37     static bool createImageBuffer(const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>&, ImageColorSpace);
    38     static void clipToImageBuffer(GraphicsContext*, const AffineTransform& absoluteTransform, const FloatRect& clampedAbsoluteTargetRect, ImageBuffer*);
     37    static bool createImageBuffer(const FloatRect& absoluteTargetRect, const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>&, ImageColorSpace);
     38    static void renderSubtreeToImageBuffer(ImageBuffer*, RenderObject*, const AffineTransform&);
     39    static void clipToImageBuffer(GraphicsContext*, const AffineTransform& absoluteTransform, const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>&);
    3940
    40     static AffineTransform transformationToOutermostSVGCoordinateSystem(const RenderObject*);
    41     static FloatRect clampedAbsoluteTargetRectForRenderer(const RenderObject*, const AffineTransform& absouteTransform, const FloatRect& targetRect);
     41    static void calculateTransformationToOutermostSVGCoordinateSystem(const RenderObject*, AffineTransform& absoluteTransform);
     42    static FloatRect clampedAbsoluteTargetRectForRenderer(const RenderObject*, const FloatRect& absoluteTargetRect);
    4243    static IntSize roundedImageBufferSize(const FloatSize&);
    4344
  • trunk/WebCore/rendering/SVGRenderSupport.cpp

    r65665 r65880  
    3434#include "RenderLayer.h"
    3535#include "RenderPath.h"
    36 #include "RenderSVGContainer.h"
    3736#include "RenderSVGResource.h"
    3837#include "RenderSVGResourceClipper.h"
     
    117116    }
    118117
    119     if (RenderSVGResourceClipper* clipper = resources->clipper())
    120         clipper->applyResource(object, style, paintInfo.context, ApplyToDefaultMode);
     118    if (RenderSVGResourceClipper* clipper = resources->clipper()) {
     119        if (!clipper->applyResource(object, style, paintInfo.context, ApplyToDefaultMode))
     120            return false;
     121    }
    121122
    122123#if ENABLE(FILTERS)
     
    162163    if (svgStyle->shadow())
    163164        paintInfo.context->endTransparencyLayer();
    164 }
    165 
    166 void SVGRenderSupport::renderSubtreeToImage(ImageBuffer* image, RenderObject* item)
    167 {
    168     ASSERT(item);
    169     ASSERT(image);
    170     ASSERT(image->context());
    171 
    172     PaintInfo info(image->context(), PaintInfo::infiniteRect(), PaintPhaseForeground, 0, 0, 0);
    173 
    174     // FIXME: isSVGContainer returns true for RenderSVGViewportContainer, so if this is ever
    175     // called with one of those, we will read from the wrong offset in an object due to a bad cast.
    176     RenderSVGContainer* svgContainer = 0;
    177     if (item && item->isSVGContainer())
    178         svgContainer = toRenderSVGContainer(item);
    179 
    180     bool drawsContents = svgContainer ? svgContainer->drawsContents() : false;
    181     if (svgContainer && !drawsContents)
    182         svgContainer->setDrawsContents(true);
    183 
    184     item->layoutIfNeeded();
    185     item->paint(info, 0, 0);
    186 
    187     if (svgContainer && !drawsContents)
    188         svgContainer->setDrawsContents(false);
    189165}
    190166
  • trunk/WebCore/rendering/SVGRenderSupport.h

    r65665 r65880  
    7474    static void mapLocalToContainer(const RenderObject*, RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&);
    7575
    76     // This offers a way to render parts of a WebKit rendering tree into a ImageBuffer.
    77     static void renderSubtreeToImage(ImageBuffer*, RenderObject*);
    78 
    7976    // Shared between SVG renderers and resources.
    8077    static void applyStrokeStyleToContext(GraphicsContext*, const RenderStyle*, const RenderObject*);
  • trunk/WebCore/svg/SVGFEImageElement.cpp

    r65449 r65880  
    3131#include "RenderObject.h"
    3232#include "RenderSVGResource.h"
     33#include "SVGImageBufferTools.h"
    3334#include "SVGLength.h"
    3435#include "SVGNames.h"
    3536#include "SVGPreserveAspectRatio.h"
    36 #include "SVGRenderSupport.h"
    3737
    3838namespace WebCore {
     
    135135        m_targetImage = ImageBuffer::create(targetRect.size(), LinearRGB);
    136136
    137         SVGRenderSupport::renderSubtreeToImage(m_targetImage.get(), renderer);
     137        AffineTransform contentTransformation;
     138        SVGImageBufferTools::renderSubtreeToImageBuffer(m_targetImage.get(), renderer, contentTransformation);
    138139    }
    139140
Note: See TracChangeset for help on using the changeset viewer.