Changeset 69181 in webkit


Ignore:
Timestamp:
Oct 6, 2010 2:45:18 AM (14 years ago)
Author:
krit@webkit.org
Message:

2010-10-06 Dirk Schulze <krit@webkit.org>

Reviewed by Nikolas Zimmermann.

SVGs with filters look grainy when scaled
https://bugs.webkit.org/show_bug.cgi?id=5526

SVG filter effects need smarter size calculation
https://bugs.webkit.org/show_bug.cgi?id=31370

SVG elements use Filters before own transformations
https://bugs.webkit.org/show_bug.cgi?id=32486

Calculate all filter results in device space instead of the filtered objects user space. This change is similar to
the patches for SVG Pattern and SVG Masker before. It avoids pixelation and guarantees smooth filter results for
every scale level and is independent of any transformation to the target element or any ancester of the target.
The second part of this patch reduces the size of every effect to the smallest affected region instead of the complete
filter primitive subregion (http://www.w3.org/TR/SVG/filters.html#FilterPrimitiveSubRegion). We just use the subregion
as clipping region, like mentioned in the SVG specification, to make the affected region even smaller now.

This is a huge speed up. The ECMA cloud (http://ejohn.org/files/ecma-cloud.svg) is more than 100 times faster on Gtk and
renders in less than a second.
Some examples on svg-wow.org can be viewed the first time now, since the subregions were much bigger than the affected
region.
There's still more potential to speed up filters, by further reducing the ImageBuffer sizes.
Renamed repaintRectInLocalCoordinates to absolutePaintRect, since all coordinates are in device space instead of the
user space now.
The absolute paint rect is calculated by determineAbsolutePaintRect() and gets called by FilterEffect::effectContext() on
applying the effect.
Partly rewrote filter resolution (http://www.w3.org/TR/SVG/filters.html#FilterElementFilterResAttribute) to work with the
new concept. This also corrects the old behavior to match the SVG specification.

Tests: svg/filters/filterRes1.svg

svg/filters/filterRes2.svg
svg/filters/filterRes3.svg

  • platform/graphics/cairo/GraphicsContextCairo.cpp: Call setAbsolutePaintRect instead of setRepaintRectInLocalCoordinates. (WebCore::GraphicsContext::createShadowMask):
  • platform/graphics/filters/FEBlend.cpp: Renamed repaintRectInLocalCoordinates to absolutePaintRect. (WebCore::FEBlend::apply):
  • platform/graphics/filters/FEColorMatrix.cpp: Ditto. (WebCore::FEColorMatrix::apply):
  • platform/graphics/filters/FEComponentTransfer.cpp: Ditto. (WebCore::FEComponentTransfer::apply):
  • platform/graphics/filters/FEComposite.cpp: Ditto. (WebCore::FEComposite::determineAbsolutePaintRect): (WebCore::FEComposite::apply):
  • platform/graphics/filters/FEComposite.h:
  • platform/graphics/filters/FEConvolveMatrix.cpp: Ditto. (WebCore::FEConvolveMatrix::apply):
  • platform/graphics/filters/FEConvolveMatrix.h: (WebCore::FEConvolveMatrix::determineAbsolutePaintRect):
  • platform/graphics/filters/FEDisplacementMap.cpp: Ditto. (WebCore::FEDisplacementMap::apply):
  • platform/graphics/filters/FEDisplacementMap.h: (WebCore::FEDisplacementMap::determineAbsolutePaintRect):
  • platform/graphics/filters/FEFlood.cpp: Ditto. (WebCore::FEFlood::apply):
  • platform/graphics/filters/FEFlood.h: (WebCore::FEFlood::determineAbsolutePaintRect):
  • platform/graphics/filters/FEGaussianBlur.cpp: Ditto. (WebCore::calculateKernelSize): (WebCore::FEGaussianBlur::determineAbsolutePaintRect): (WebCore::FEGaussianBlur::apply):
  • platform/graphics/filters/FEGaussianBlur.h:
  • platform/graphics/filters/FELighting.cpp: Ditto. (WebCore::FELighting::apply):
  • platform/graphics/filters/FEMerge.cpp: Ditto. (WebCore::FEMerge::apply):
  • platform/graphics/filters/FEMorphology.cpp: Ditto. (WebCore::FEMorphology::determineAbsolutePaintRect): (WebCore::FEMorphology::apply):
  • platform/graphics/filters/FEMorphology.h:
  • platform/graphics/filters/FEOffset.cpp: Ditto. (WebCore::FEOffset::determineAbsolutePaintRect): (WebCore::FEOffset::apply):
  • platform/graphics/filters/FEOffset.h:
  • platform/graphics/filters/FETile.cpp: Ditto. (WebCore::FETile::determineFilterPrimitiveSubregion): (WebCore::FETile::apply):
  • platform/graphics/filters/FETile.h: (WebCore::FETile::determineAbsolutePaintRect):
  • platform/graphics/filters/FETurbulence.cpp: Ditto. (WebCore::FETurbulence::apply):
  • platform/graphics/filters/FETurbulence.h: (WebCore::FETurbulence::determineAbsolutePaintRect):
  • platform/graphics/filters/Filter.h: (WebCore::Filter::applyHorizontalScale): Map horizontal effect values to absolute coordinates. (WebCore::Filter::applyVerticalScale): Map vertical effect values to absolute coordinates. (WebCore::Filter::mapAbsolutePointToLocalPoint): (WebCore::Filter::filterRegionInUserSpace):
  • platform/graphics/filters/FilterEffect.cpp: Ditto. (WebCore::FilterEffect::determineFilterPrimitiveSubregion): (WebCore::FilterEffect::determineAbsolutePaintRect): (WebCore::FilterEffect::requestedRegionOfInputImageData): (WebCore::FilterEffect::drawingRegionOfInputImage): (WebCore::FilterEffect::effectContext):
  • platform/graphics/filters/FilterEffect.h: (WebCore::FilterEffect::absolutePaintRect): (WebCore::FilterEffect::setAbsolutePaintRect): (WebCore::FilterEffect::maxEffectRect): The subregion in absolute coordinates for SVG. (WebCore::FilterEffect::setMaxEffectRect):
  • platform/graphics/filters/SourceAlpha.cpp: Ditto. (WebCore::SourceAlpha::determineAbsolutePaintRect): (WebCore::SourceAlpha::apply):
  • platform/graphics/filters/SourceAlpha.h:
  • platform/graphics/filters/SourceGraphic.cpp: Ditto. (WebCore::SourceGraphic::determineAbsolutePaintRect): (WebCore::SourceGraphic::apply):
  • platform/graphics/filters/SourceGraphic.h:
  • rendering/RenderSVGResourceFilter.cpp: (WebCore::RenderSVGResourceFilter::applyResource): (WebCore::RenderSVGResourceFilter::postApplyResource):
  • rendering/RenderSVGResourceFilter.h: (WebCore::FilterData::FilterData):
  • svg/graphics/filters/SVGFEImage.cpp: Ditto. (WebCore::FEImage::apply):
  • svg/graphics/filters/SVGFEImage.h: (WebCore::FEImage::determineAbsolutePaintRect):
  • svg/graphics/filters/SVGFilter.cpp: (WebCore::SVGFilter::SVGFilter): (WebCore::SVGFilter::determineFilterPrimitiveSubregion): (WebCore::SVGFilter::applyHorizontalScale): (WebCore::SVGFilter::applyVerticalScale): (WebCore::SVGFilter::create):
  • svg/graphics/filters/SVGFilter.h: (WebCore::SVGFilter::effectBoundingBoxMode): (WebCore::SVGFilter::filterRegionInUserSpace): (WebCore::SVGFilter::filterRegion): (WebCore::SVGFilter::mapAbsolutePointToLocalPoint): Map absolute point to local point in userspace. (WebCore::SVGFilter::sourceImageRect): (WebCore::SVGFilter::maxImageSize):

2010-10-06 Dirk Schulze <krit@webkit.org>

Reviewed by Nikolas Zimmermann.

SVGs with filters look grainy when scaled
https://bugs.webkit.org/show_bug.cgi?id=5526

Added three new tests for SVGs filterRes.
Shadow tests for SVG Filter needed an update. Current tests didn't respect
primitiveUnits "objectBoundingBox" for stdDeviation on feGaussianBlur correctly.

  • platform/mac/svg/filters/filterRes1-expected.checksum: Added.
  • platform/mac/svg/filters/filterRes1-expected.png: Added.
  • platform/mac/svg/filters/filterRes1-expected.txt: Added.
  • platform/mac/svg/filters/filterRes2-expected.checksum: Added.
  • platform/mac/svg/filters/filterRes2-expected.png: Added.
  • platform/mac/svg/filters/filterRes2-expected.txt: Added.
  • platform/mac/svg/filters/filterRes3-expected.checksum: Added.
  • platform/mac/svg/filters/filterRes3-expected.png: Added.
  • platform/mac/svg/filters/filterRes3-expected.txt: Added.
  • platform/mac/svg/filters/shadow-on-filter-expected.txt:
  • platform/mac/svg/filters/shadow-on-rect-with-filter-expected.txt:
  • svg/filters/filterRes1.svg: Added.
  • svg/filters/filterRes2.svg: Added.
  • svg/filters/filterRes3.svg: Added.
  • svg/filters/shadow-on-filter.svg:
  • svg/filters/shadow-on-rect-with-filter.svg:
Location:
trunk
Files:
12 added
44 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r69179 r69181  
     12010-10-06  Dirk Schulze  <krit@webkit.org>
     2
     3        Reviewed by Nikolas Zimmermann.
     4
     5        SVGs with filters look grainy when scaled
     6        https://bugs.webkit.org/show_bug.cgi?id=5526
     7
     8        Added three new tests for SVGs filterRes.
     9        Shadow tests for SVG Filter needed an update. Current tests didn't respect
     10        primitiveUnits "objectBoundingBox" for stdDeviation on feGaussianBlur correctly.
     11
     12        * platform/mac/svg/filters/filterRes1-expected.checksum: Added.
     13        * platform/mac/svg/filters/filterRes1-expected.png: Added.
     14        * platform/mac/svg/filters/filterRes1-expected.txt: Added.
     15        * platform/mac/svg/filters/filterRes2-expected.checksum: Added.
     16        * platform/mac/svg/filters/filterRes2-expected.png: Added.
     17        * platform/mac/svg/filters/filterRes2-expected.txt: Added.
     18        * platform/mac/svg/filters/filterRes3-expected.checksum: Added.
     19        * platform/mac/svg/filters/filterRes3-expected.png: Added.
     20        * platform/mac/svg/filters/filterRes3-expected.txt: Added.
     21        * platform/mac/svg/filters/shadow-on-filter-expected.txt:
     22        * platform/mac/svg/filters/shadow-on-rect-with-filter-expected.txt:
     23        * svg/filters/filterRes1.svg: Added.
     24        * svg/filters/filterRes2.svg: Added.
     25        * svg/filters/filterRes3.svg: Added.
     26        * svg/filters/shadow-on-filter.svg:
     27        * svg/filters/shadow-on-rect-with-filter.svg:
     28
    1292010-10-06  Kent Tamura  <tkent@chromium.org>
    230
  • trunk/LayoutTests/platform/mac/svg/filters/shadow-on-filter-expected.txt

    r62922 r69181  
    55    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
    66      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=objectBoundingBox]
    7         [feGaussianBlur stdDeviation="4.00, 4.00"]
     7        [feGaussianBlur stdDeviation="0.01, 0.01"]
    88          [feComposite operation="OVER"]
    99            [feFlood flood-color="#FF0000" flood-opacity="1.00"]
  • trunk/LayoutTests/platform/mac/svg/filters/shadow-on-rect-with-filter-expected.txt

    r62922 r69181  
    55    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
    66      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=objectBoundingBox]
    7         [feGaussianBlur stdDeviation="4.00, 4.00"]
     7        [feGaussianBlur stdDeviation="0.01, 0.01"]
    88          [feComposite operation="OVER"]
    99            [feFlood flood-color="#FF0000" flood-opacity="1.00"]
  • trunk/LayoutTests/svg/filters/shadow-on-filter.svg

    r53157 r69181  
    55<feFlood x="-20%" y="-20%" width="50%" height="50%" flood-color="green" result="flood2"/>
    66<feComposite in="flood1" in2="flood2" width="120%" height="120%" result="comp1" style="-webkit-svg-shadow:4px -1px 3px green;"/>
    7 <feGaussianBlur stdDeviation="4 4" style="-webkit-svg-shadow: 6px 4px 8px yellow;"/>
     7<feGaussianBlur stdDeviation="0.0133" style="-webkit-svg-shadow: 6px 4px 8px yellow;"/>
    88</filter>
    99</defs>
  • trunk/LayoutTests/svg/filters/shadow-on-rect-with-filter.svg

    r53157 r69181  
    55<feFlood x="-20%" y="-20%" width="50%" height="50%" flood-color="green" result="flood2"/>
    66<feComposite in="flood1" in2="flood2" width="120%" height="120%" result="comp1" />
    7 <feGaussianBlur stdDeviation="4 4" />
     7<feGaussianBlur stdDeviation="0.0133" />
    88</filter>
    99</defs>
  • trunk/WebCore/ChangeLog

    r69180 r69181  
     12010-10-06  Dirk Schulze  <krit@webkit.org>
     2
     3        Reviewed by Nikolas Zimmermann.
     4
     5        SVGs with filters look grainy when scaled
     6        https://bugs.webkit.org/show_bug.cgi?id=5526
     7
     8        SVG filter effects need smarter size calculation
     9        https://bugs.webkit.org/show_bug.cgi?id=31370
     10
     11        SVG elements use Filters before own transformations
     12        https://bugs.webkit.org/show_bug.cgi?id=32486
     13
     14        Calculate all filter results in device space instead of the filtered objects user space. This change is similar to
     15        the patches for SVG Pattern and SVG Masker before. It avoids pixelation and guarantees smooth filter results for
     16        every scale level and is independent of any transformation to the target element or any ancester of the target.
     17        The second part of this patch reduces the size of every effect to the smallest affected region instead of the complete
     18        filter primitive subregion (http://www.w3.org/TR/SVG/filters.html#FilterPrimitiveSubRegion). We just use the subregion
     19        as clipping region, like mentioned in the SVG specification, to make the affected region even smaller now.
     20
     21        This is a huge speed up. The ECMA cloud (http://ejohn.org/files/ecma-cloud.svg) is more than 100 times faster on Gtk and
     22        renders in less than a second.
     23        Some examples on svg-wow.org can be viewed the first time now, since the subregions were much bigger than the affected
     24        region.
     25        There's still more potential to speed up filters, by further reducing the ImageBuffer sizes.
     26        Renamed repaintRectInLocalCoordinates to absolutePaintRect, since all coordinates are in device space instead of the
     27        user space now.
     28        The absolute paint rect is calculated by determineAbsolutePaintRect() and gets called by FilterEffect::effectContext() on
     29        applying the effect.
     30        Partly rewrote filter resolution (http://www.w3.org/TR/SVG/filters.html#FilterElementFilterResAttribute) to work with the
     31        new concept. This also corrects the old behavior to match the SVG specification.
     32
     33        Tests: svg/filters/filterRes1.svg
     34               svg/filters/filterRes2.svg
     35               svg/filters/filterRes3.svg
     36
     37        * platform/graphics/cairo/GraphicsContextCairo.cpp: Call setAbsolutePaintRect instead of setRepaintRectInLocalCoordinates.
     38        (WebCore::GraphicsContext::createShadowMask):
     39        * platform/graphics/filters/FEBlend.cpp: Renamed repaintRectInLocalCoordinates to absolutePaintRect.
     40        (WebCore::FEBlend::apply):
     41        * platform/graphics/filters/FEColorMatrix.cpp: Ditto.
     42        (WebCore::FEColorMatrix::apply):
     43        * platform/graphics/filters/FEComponentTransfer.cpp: Ditto.
     44        (WebCore::FEComponentTransfer::apply):
     45        * platform/graphics/filters/FEComposite.cpp: Ditto.
     46        (WebCore::FEComposite::determineAbsolutePaintRect):
     47        (WebCore::FEComposite::apply):
     48        * platform/graphics/filters/FEComposite.h:
     49        * platform/graphics/filters/FEConvolveMatrix.cpp: Ditto.
     50        (WebCore::FEConvolveMatrix::apply):
     51        * platform/graphics/filters/FEConvolveMatrix.h:
     52        (WebCore::FEConvolveMatrix::determineAbsolutePaintRect):
     53        * platform/graphics/filters/FEDisplacementMap.cpp: Ditto.
     54        (WebCore::FEDisplacementMap::apply):
     55        * platform/graphics/filters/FEDisplacementMap.h:
     56        (WebCore::FEDisplacementMap::determineAbsolutePaintRect):
     57        * platform/graphics/filters/FEFlood.cpp: Ditto.
     58        (WebCore::FEFlood::apply):
     59        * platform/graphics/filters/FEFlood.h:
     60        (WebCore::FEFlood::determineAbsolutePaintRect):
     61        * platform/graphics/filters/FEGaussianBlur.cpp: Ditto.
     62        (WebCore::calculateKernelSize):
     63        (WebCore::FEGaussianBlur::determineAbsolutePaintRect):
     64        (WebCore::FEGaussianBlur::apply):
     65        * platform/graphics/filters/FEGaussianBlur.h:
     66        * platform/graphics/filters/FELighting.cpp: Ditto.
     67        (WebCore::FELighting::apply):
     68        * platform/graphics/filters/FEMerge.cpp: Ditto.
     69        (WebCore::FEMerge::apply):
     70        * platform/graphics/filters/FEMorphology.cpp: Ditto.
     71        (WebCore::FEMorphology::determineAbsolutePaintRect):
     72        (WebCore::FEMorphology::apply):
     73        * platform/graphics/filters/FEMorphology.h:
     74        * platform/graphics/filters/FEOffset.cpp: Ditto.
     75        (WebCore::FEOffset::determineAbsolutePaintRect):
     76        (WebCore::FEOffset::apply):
     77        * platform/graphics/filters/FEOffset.h:
     78        * platform/graphics/filters/FETile.cpp: Ditto.
     79        (WebCore::FETile::determineFilterPrimitiveSubregion):
     80        (WebCore::FETile::apply):
     81        * platform/graphics/filters/FETile.h:
     82        (WebCore::FETile::determineAbsolutePaintRect):
     83        * platform/graphics/filters/FETurbulence.cpp: Ditto.
     84        (WebCore::FETurbulence::apply):
     85        * platform/graphics/filters/FETurbulence.h:
     86        (WebCore::FETurbulence::determineAbsolutePaintRect):
     87        * platform/graphics/filters/Filter.h:
     88        (WebCore::Filter::applyHorizontalScale): Map horizontal effect values to absolute coordinates.
     89        (WebCore::Filter::applyVerticalScale): Map vertical effect values to absolute coordinates.
     90        (WebCore::Filter::mapAbsolutePointToLocalPoint):
     91        (WebCore::Filter::filterRegionInUserSpace):
     92        * platform/graphics/filters/FilterEffect.cpp: Ditto.
     93        (WebCore::FilterEffect::determineFilterPrimitiveSubregion):
     94        (WebCore::FilterEffect::determineAbsolutePaintRect):
     95        (WebCore::FilterEffect::requestedRegionOfInputImageData):
     96        (WebCore::FilterEffect::drawingRegionOfInputImage):
     97        (WebCore::FilterEffect::effectContext):
     98        * platform/graphics/filters/FilterEffect.h:
     99        (WebCore::FilterEffect::absolutePaintRect):
     100        (WebCore::FilterEffect::setAbsolutePaintRect):
     101        (WebCore::FilterEffect::maxEffectRect): The subregion in absolute coordinates for SVG.
     102        (WebCore::FilterEffect::setMaxEffectRect):
     103        * platform/graphics/filters/SourceAlpha.cpp: Ditto.
     104        (WebCore::SourceAlpha::determineAbsolutePaintRect):
     105        (WebCore::SourceAlpha::apply):
     106        * platform/graphics/filters/SourceAlpha.h:
     107        * platform/graphics/filters/SourceGraphic.cpp: Ditto.
     108        (WebCore::SourceGraphic::determineAbsolutePaintRect):
     109        (WebCore::SourceGraphic::apply):
     110        * platform/graphics/filters/SourceGraphic.h:
     111        * rendering/RenderSVGResourceFilter.cpp:
     112        (WebCore::RenderSVGResourceFilter::applyResource):
     113        (WebCore::RenderSVGResourceFilter::postApplyResource):
     114        * rendering/RenderSVGResourceFilter.h:
     115        (WebCore::FilterData::FilterData):
     116        * svg/graphics/filters/SVGFEImage.cpp: Ditto.
     117        (WebCore::FEImage::apply):
     118        * svg/graphics/filters/SVGFEImage.h:
     119        (WebCore::FEImage::determineAbsolutePaintRect):
     120        * svg/graphics/filters/SVGFilter.cpp:
     121        (WebCore::SVGFilter::SVGFilter):
     122        (WebCore::SVGFilter::determineFilterPrimitiveSubregion):
     123        (WebCore::SVGFilter::applyHorizontalScale):
     124        (WebCore::SVGFilter::applyVerticalScale):
     125        (WebCore::SVGFilter::create):
     126        * svg/graphics/filters/SVGFilter.h:
     127        (WebCore::SVGFilter::effectBoundingBoxMode):
     128        (WebCore::SVGFilter::filterRegionInUserSpace):
     129        (WebCore::SVGFilter::filterRegion):
     130        (WebCore::SVGFilter::mapAbsolutePointToLocalPoint): Map absolute point to local point in userspace.
     131        (WebCore::SVGFilter::sourceImageRect):
     132        (WebCore::SVGFilter::maxImageSize):
     133
    11342010-10-06  Pavel Podivilov  <podivilov@chromium.org>
    2135
  • trunk/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp

    r69015 r69181  
    945945    filter->setSourceImage(buffer);
    946946    RefPtr<FilterEffect> source = SourceGraphic::create();
    947     source->setRepaintRectInLocalCoordinates(FloatRect(FloatPoint(), shadowRect.size()));
     947    source->setAbsolutePaintRect(IntRect(IntPoint(), roundedIntSize(shadowRect.size())));
    948948    source->setIsAlphaImage(true);
    949949    RefPtr<FilterEffect> blur = FEGaussianBlur::create(stdDeviation, stdDeviation);
    950950    FilterEffectVector& inputEffects = blur->inputEffects();
    951951    inputEffects.append(source.get());
    952     blur->setRepaintRectInLocalCoordinates(FloatRect(FloatPoint(), shadowRect.size()));
     952    blur->setAbsolutePaintRect(IntRect(IntPoint(), roundedIntSize(shadowRect.size())));
    953953    blur->apply(filter.get());
    954954    return blur->resultImage()->m_data.m_surface;
  • trunk/WebCore/platform/graphics/filters/FEBlend.cpp

    r67929 r69181  
    9999        return;
    100100
    101     if (!effectContext())
     101    if (!effectContext(filter))
    102102        return;
    103103
    104     IntRect effectADrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
     104    IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    105105    RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data());
    106106
    107     IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->repaintRectInLocalCoordinates());
     107    IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect());
    108108    RefPtr<CanvasPixelArray> srcPixelArrayB(in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)->data());
    109109
  • trunk/WebCore/platform/graphics/filters/FEColorMatrix.cpp

    r67929 r69181  
    161161        return;
    162162
    163     GraphicsContext* filterContext = effectContext();
     163    GraphicsContext* filterContext = effectContext(filter);
    164164    if (!filterContext)
    165165        return;
    166166
    167     filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()));
     167    filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect()));
    168168
    169169    IntRect imageRect(IntPoint(), resultImage()->size());
  • trunk/WebCore/platform/graphics/filters/FEComponentTransfer.cpp

    r67929 r69181  
    155155        return;
    156156
    157     if (!effectContext())
     157    if (!effectContext(filter))
    158158        return;
    159159
     
    168168        (*callEffect[transferFunction[channel].type])(tables[channel], transferFunction[channel]);
    169169
    170     IntRect drawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
     170    IntRect drawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    171171    RefPtr<ImageData> imageData(in->resultImage()->getUnmultipliedImageData(drawingRect));
    172172    CanvasPixelArray* srcPixelArray(imageData->data());
  • trunk/WebCore/platform/graphics/filters/FEComposite.cpp

    r67929 r69181  
    44 * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
    55 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
     6 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
    67 *
    78 * This library is free software; you can redistribute it and/or
     
    113114    }
    114115}
     116   
     117void FEComposite::determineAbsolutePaintRect(Filter* filter)
     118{
     119    switch (m_type) {
     120    case FECOMPOSITE_OPERATOR_IN:
     121    case FECOMPOSITE_OPERATOR_ATOP:
     122        // For In and Atop the first effect just influences the result of
     123        // the second effect. So just use the absolute paint rect of the second effect here.
     124        setAbsolutePaintRect(inputEffect(1)->absolutePaintRect());
     125        return;
     126    case FECOMPOSITE_OPERATOR_ARITHMETIC:
     127        // Arithmetic may influnce the compele filter primitive region. So we can't
     128        // optimize the paint region here.
     129        setAbsolutePaintRect(maxEffectRect());
     130        return;
     131    default:
     132        // Take the union of both input effects.
     133        FilterEffect::determineAbsolutePaintRect(filter);
     134        return;
     135    }
     136}
    115137
    116138void FEComposite::apply(Filter* filter)
     
    123145        return;
    124146
    125     GraphicsContext* filterContext = effectContext();
     147    GraphicsContext* filterContext = effectContext(filter);
    126148    if (!filterContext)
    127149        return;
     
    130152    switch (m_type) {
    131153    case FECOMPOSITE_OPERATOR_OVER:
    132         filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates()));
    133         filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()));
     154        filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->absolutePaintRect()));
     155        filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect()));
    134156        break;
    135157    case FECOMPOSITE_OPERATOR_IN:
    136158        filterContext->save();
    137         filterContext->clipToImageBuffer(in2->resultImage(), drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates()));
    138         filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()));
     159        filterContext->clipToImageBuffer(in2->resultImage(), drawingRegionOfInputImage(in2->absolutePaintRect()));
     160        filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect()));
    139161        filterContext->restore();
    140162        break;
    141163    case FECOMPOSITE_OPERATOR_OUT:
    142         filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()));
    143         filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates()), srcRect, CompositeDestinationOut);
     164        filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect()));
     165        filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->absolutePaintRect()), srcRect, CompositeDestinationOut);
    144166        break;
    145167    case FECOMPOSITE_OPERATOR_ATOP:
    146         filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates()));
    147         filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()), srcRect, CompositeSourceAtop);
     168        filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->absolutePaintRect()));
     169        filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect()), srcRect, CompositeSourceAtop);
    148170        break;
    149171    case FECOMPOSITE_OPERATOR_XOR:
    150         filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates()));
    151         filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()), srcRect, CompositeXOR);
     172        filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->absolutePaintRect()));
     173        filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect()), srcRect, CompositeXOR);
    152174        break;
    153175    case FECOMPOSITE_OPERATOR_ARITHMETIC: {
    154         IntRect effectADrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
     176        IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    155177        RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data());
    156178
    157         IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->repaintRectInLocalCoordinates());
     179        IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect());
    158180        RefPtr<ImageData> imageData(in2->resultImage()->getPremultipliedImageData(effectBDrawingRect));
    159181        CanvasPixelArray* srcPixelArrayB(imageData->data());
  • trunk/WebCore/platform/graphics/filters/FEComposite.h

    r67929 r69181  
    6262    virtual void apply(Filter*);
    6363    virtual void dump();
     64   
     65    virtual void determineAbsolutePaintRect(Filter*);
    6466
    6567    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
  • trunk/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp

    r68022 r69181  
    378378        return;
    379379
    380     if (!effectContext())
     380    if (!effectContext(filter))
    381381        return;
    382382
    383383    IntRect imageRect(IntPoint(), resultImage()->size());
    384     IntRect effectDrawingRect = requestedRegionOfInputImageData(in->filterPrimitiveSubregion());
     384    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    385385
    386386    RefPtr<CanvasPixelArray> srcPixelArray;
  • trunk/WebCore/platform/graphics/filters/FEConvolveMatrix.h

    r68022 r69181  
    7676    virtual void dump();
    7777
     78    virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); }
     79
    7880    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
    7981
  • trunk/WebCore/platform/graphics/filters/FEDisplacementMap.cpp

    r68022 r69181  
    44 * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
    55 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
     6 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
    67 *
    78 * This library is free software; you can redistribute it and/or
     
    8990        return;
    9091
    91     if (!effectContext())
     92    if (!effectContext(filter))
    9293        return;
    9394
    94     IntRect effectADrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
     95    IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    9596    RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data());
    9697
    97     IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->repaintRectInLocalCoordinates());
     98    IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect());
    9899    RefPtr<CanvasPixelArray> srcPixelArrayB(in2->resultImage()->getUnmultipliedImageData(effectBDrawingRect)->data());
    99100
     
    103104    ASSERT(srcPixelArrayA->length() == srcPixelArrayB->length());
    104105
    105     float scaleX = m_scale / 255.f * filter->filterResolution().width();
    106     float scaleY = m_scale / 255.f * filter->filterResolution().height();
    107     float scaleAdjustmentX = (0.5f - 0.5f * m_scale) * filter->filterResolution().width();
    108     float scaleAdjustmentY = (0.5f - 0.5f * m_scale) * filter->filterResolution().height();
     106    float scaleX = filter->applyHorizontalScale(m_scale / 255);
     107    float scaleY = filter->applyVerticalScale(m_scale / 255);
     108    float scaleAdjustmentX = filter->applyHorizontalScale(0.5f - 0.5f * m_scale);
     109    float scaleAdjustmentY = filter->applyVerticalScale(0.5f - 0.5f * m_scale);
    109110    int stride = imageRect.width() * 4;
    110111    for (int y = 0; y < imageRect.height(); ++y) {
  • trunk/WebCore/platform/graphics/filters/FEDisplacementMap.h

    r68022 r69181  
    5454    virtual void dump();
    5555
     56    virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); }
     57
    5658    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
    5759
  • trunk/WebCore/platform/graphics/filters/FEFlood.cpp

    r68022 r69181  
    6363}
    6464
    65 void FEFlood::apply(Filter*)
     65void FEFlood::apply(Filter* filter)
    6666{
    67     GraphicsContext* filterContext = effectContext();
     67    GraphicsContext* filterContext = effectContext(filter);
    6868    if (!filterContext)
    6969        return;
    7070
    7171    Color color = colorWithOverrideAlpha(floodColor().rgb(), floodOpacity());
    72     filterContext->fillRect(FloatRect(FloatPoint(), repaintRectInLocalCoordinates().size()), color, DeviceColorSpace);
     72    filterContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), color, DeviceColorSpace);
    7373}
    7474
  • trunk/WebCore/platform/graphics/filters/FEFlood.h

    r68022 r69181  
    4343    virtual void dump();
    4444
     45    virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); }
     46
    4547    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
    4648
  • trunk/WebCore/platform/graphics/filters/FEGaussianBlur.cpp

    r67929 r69181  
    55 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
    66 * Copyright (C) 2010 Igalia, S.L.
     7 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
    78 *
    89 * This library is free software; you can redistribute it and/or
     
    3536using std::max;
    3637
    37 static const float gGaussianKernelFactor = (3 * sqrtf(2 * piFloat) / 4.f);
     38static const float gGaussianKernelFactor = 3 / 4.f * sqrtf(2 * piFloat);
     39static const unsigned gMaxKernelSize = 1000;
    3840
    3941namespace WebCore {
     
    126128}
    127129
     130inline void calculateKernelSize(Filter* filter, unsigned& kernelSizeX, unsigned& kernelSizeY, float stdX, float stdY)
     131{
     132    stdX = filter->applyHorizontalScale(stdX);
     133    stdY = filter->applyVerticalScale(stdY);
     134   
     135    kernelSizeX = 0;
     136    if (stdX)
     137        kernelSizeX = max<unsigned>(2, static_cast<unsigned>(floorf(stdX * gGaussianKernelFactor + 0.5f)));
     138    kernelSizeY = 0;
     139    if (stdY)
     140        kernelSizeY = max<unsigned>(2, static_cast<unsigned>(floorf(stdY * gGaussianKernelFactor + 0.5f)));
     141   
     142    // Limit the kernel size to 1000. A bigger radius won't make a big difference for the result image but
     143    // inflates the absolute paint rect to much. This is compatible with Firefox' behavior.
     144    if (kernelSizeX > gMaxKernelSize)
     145        kernelSizeX = gMaxKernelSize;
     146    if (kernelSizeY > gMaxKernelSize)
     147        kernelSizeY = gMaxKernelSize;
     148}
     149
     150void FEGaussianBlur::determineAbsolutePaintRect(Filter* filter)
     151{
     152    FloatRect absolutePaintRect = inputEffect(0)->absolutePaintRect();
     153    absolutePaintRect.intersect(maxEffectRect());
     154
     155    unsigned kernelSizeX = 0;
     156    unsigned kernelSizeY = 0;
     157    calculateKernelSize(filter, kernelSizeX, kernelSizeY, m_stdX, m_stdY);
     158
     159    // We take the half kernel size and multiply it with three, because we run box blur three times.
     160    absolutePaintRect.inflateX(3 * kernelSizeX * 0.5f);
     161    absolutePaintRect.inflateY(3 * kernelSizeY * 0.5f);
     162    setAbsolutePaintRect(enclosingIntRect(absolutePaintRect));
     163}
     164
    128165void FEGaussianBlur::apply(Filter* filter)
    129166{
     
    133170        return;
    134171
    135     if (!effectContext())
     172    if (!effectContext(filter))
    136173        return;
    137174
    138175    setIsAlphaImage(in->isAlphaImage());
    139176
    140     IntRect effectDrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
     177    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    141178    RefPtr<ImageData> srcImageData(in->resultImage()->getPremultipliedImageData(effectDrawingRect));
    142179    IntRect imageRect(IntPoint(), resultImage()->size());
     
    148185
    149186    unsigned kernelSizeX = 0;
    150     if (m_stdX)
    151         kernelSizeX = max(2U, static_cast<unsigned>(floor(m_stdX * filter->filterResolution().width() * gGaussianKernelFactor + 0.5f)));
    152 
    153187    unsigned kernelSizeY = 0;
    154     if (m_stdY)
    155         kernelSizeY = max(2U, static_cast<unsigned>(floor(m_stdY * filter->filterResolution().height() * gGaussianKernelFactor + 0.5f)));
     188    calculateKernelSize(filter, kernelSizeX, kernelSizeY, m_stdX, m_stdY);
    156189
    157190    CanvasPixelArray* srcPixelArray(srcImageData->data());
  • trunk/WebCore/platform/graphics/filters/FEGaussianBlur.h

    r67929 r69181  
    4343    virtual void apply(Filter*);
    4444    virtual void dump();
     45   
     46    virtual void determineAbsolutePaintRect(Filter*);
    4547
    4648    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
  • trunk/WebCore/platform/graphics/filters/FELighting.cpp

    r68022 r69181  
    248248        return;
    249249
    250     if (!effectContext())
     250    if (!effectContext(filter))
    251251        return;
    252252
    253253    setIsAlphaImage(false);
    254254
    255     IntRect effectDrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
     255    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    256256    RefPtr<ImageData> srcImageData(in->resultImage()->getUnmultipliedImageData(effectDrawingRect));
    257257    CanvasPixelArray* srcPixelArray(srcImageData->data());
     
    262262    // Anyway, feConvolveMatrix should also use the implementation
    263263
    264     if (drawLighting(srcPixelArray, effectDrawingRect.width(), effectDrawingRect.height()))
    265         resultImage()->putUnmultipliedImageData(srcImageData.get(), IntRect(IntPoint(), resultImage()->size()), IntPoint());
     264    IntSize absolutePaintSize = absolutePaintRect().size();
     265    if (drawLighting(srcPixelArray, absolutePaintSize.width(), absolutePaintSize.height()))
     266        resultImage()->putUnmultipliedImageData(srcImageData.get(), IntRect(IntPoint(), absolutePaintSize), IntPoint());
    266267}
    267268
  • trunk/WebCore/platform/graphics/filters/FELighting.h

    r68022 r69181  
    4444public:
    4545    virtual void apply(Filter*);
     46
     47    virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); }
    4648
    4749protected:
  • trunk/WebCore/platform/graphics/filters/FEMerge.cpp

    r68022 r69181  
    5151    }
    5252
    53     GraphicsContext* filterContext = effectContext();
     53    GraphicsContext* filterContext = effectContext(filter);
    5454    if (!filterContext)
    5555        return;
     
    5757    for (unsigned i = 0; i < size; ++i) {
    5858        FilterEffect* in = inputEffect(i);
    59         filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()));
     59        filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect()));
    6060    }
    6161}
  • trunk/WebCore/platform/graphics/filters/FEMorphology.cpp

    r68022 r69181  
    44 * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
    55 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
     6 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
    67 *
    78 * This library is free software; you can redistribute it and/or
     
    7576}
    7677
     78void FEMorphology::determineAbsolutePaintRect(Filter* filter)
     79{
     80    FloatRect paintRect = inputEffect(0)->absolutePaintRect();
     81    paintRect.inflateX(filter->applyHorizontalScale(m_radiusX));
     82    paintRect.inflateY(filter->applyVerticalScale(m_radiusY));
     83    setAbsolutePaintRect(enclosingIntRect(paintRect));
     84}
     85
    7786void FEMorphology::setRadiusY(float radiusY)
    7887{
     
    8796        return;
    8897
    89     if (!effectContext())
     98    if (!effectContext(filter))
    9099        return;
    91100
    92101    setIsAlphaImage(in->isAlphaImage());
    93 
    94     int radiusX = static_cast<int>(m_radiusX * filter->filterResolution().width());
    95     int radiusY = static_cast<int>(m_radiusY * filter->filterResolution().height());
    96     if (radiusX <= 0 || radiusY <= 0)
     102    if (m_radiusX <= 0 || m_radiusY <= 0)
    97103        return;
    98104
     105    int radiusX = static_cast<int>(floorf(filter->applyHorizontalScale(m_radiusX)));
     106    int radiusY = static_cast<int>(floorf(filter->applyVerticalScale(m_radiusY)));
     107
    99108    IntRect imageRect(IntPoint(), resultImage()->size());
    100     IntRect effectDrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
     109    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
    101110    RefPtr<CanvasPixelArray> srcPixelArray(in->resultImage()->getPremultipliedImageData(effectDrawingRect)->data());
    102111    RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());
  • trunk/WebCore/platform/graphics/filters/FEMorphology.h

    r68022 r69181  
    5050    virtual void dump();
    5151
     52    virtual void determineAbsolutePaintRect(Filter*);
     53
    5254    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
    5355
  • trunk/WebCore/platform/graphics/filters/FEOffset.cpp

    r68022 r69181  
    44 * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
    55 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
     6 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
    67 *
    78 * This library is free software; you can redistribute it and/or
     
    6364}
    6465
     66void FEOffset::determineAbsolutePaintRect(Filter* filter)
     67{
     68    FloatRect paintRect = inputEffect(0)->absolutePaintRect();
     69    paintRect.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy));
     70    paintRect.intersect(maxEffectRect());
     71    setAbsolutePaintRect(enclosingIntRect(paintRect));
     72}
     73
    6574void FEOffset::apply(Filter* filter)
    6675{
     
    7079        return;
    7180
    72     GraphicsContext* filterContext = effectContext();
     81    GraphicsContext* filterContext = effectContext(filter);
    7382    if (!filterContext)
    7483        return;
     
    7685    setIsAlphaImage(in->isAlphaImage());
    7786
    78     FloatRect sourceImageRect = filter->sourceImageRect();
    79     sourceImageRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
    80 
    81     if (filter->effectBoundingBoxMode()) {
    82         m_dx *= sourceImageRect.width();
    83         m_dy *= sourceImageRect.height();
    84     }
    85     m_dx *= filter->filterResolution().width();
    86     m_dy *= filter->filterResolution().height();
    87 
    88     FloatRect dstRect = FloatRect(m_dx + in->repaintRectInLocalCoordinates().x() - repaintRectInLocalCoordinates().x(),
    89                                   m_dy + in->repaintRectInLocalCoordinates().y() - repaintRectInLocalCoordinates().y(),
    90                                   in->repaintRectInLocalCoordinates().width(),
    91                                   in->repaintRectInLocalCoordinates().height());
    92 
    93     filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, dstRect);
     87    FloatRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect());
     88    drawingRegion.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy));
     89    filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegion);
    9490}
    9591
  • trunk/WebCore/platform/graphics/filters/FEOffset.h

    r68022 r69181  
    4141    virtual void apply(Filter*);
    4242    virtual void dump();
     43   
     44    virtual void determineAbsolutePaintRect(Filter*);
    4345
    4446    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
  • trunk/WebCore/platform/graphics/filters/FETile.cpp

    r68022 r69181  
    2828#include "GraphicsContext.h"
    2929#include "Pattern.h"
     30#include "SVGImageBufferTools.h"
    3031
    3132namespace WebCore {
     
    4546    inputEffect(0)->determineFilterPrimitiveSubregion(filter);
    4647
    47     filter->determineFilterPrimitiveSubregion(this, filter->filterRegion());
     48    filter->determineFilterPrimitiveSubregion(this, filter->filterRegionInUserSpace());
    4849    return filterPrimitiveSubregion();
    4950}
     
    5657        return;
    5758
    58     GraphicsContext* filterContext = effectContext();
     59    GraphicsContext* filterContext = effectContext(filter);
    5960    if (!filterContext)
    6061        return;
     
    6263    setIsAlphaImage(in->isAlphaImage());
    6364
    64     IntRect tileRect = enclosingIntRect(in->repaintRectInLocalCoordinates());
    65 
    6665    // Source input needs more attention. It has the size of the filterRegion but gives the
    6766    // size of the cutted sourceImage back. This is part of the specification and optimization.
     67    FloatRect tileRect = in->maxEffectRect();
     68    FloatPoint inMaxEffectLocation = tileRect.location();
     69    FloatPoint maxEffectLocation = maxEffectRect().location();
    6870    if (in->isSourceInput()) {
    69         FloatRect filterRegion = filter->filterRegion();
    70         filterRegion.scale(filter->filterResolution().width(), filter->filterResolution().height());
    71         tileRect = enclosingIntRect(filterRegion);
     71        tileRect = filter->filterRegion();
     72        tileRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
    7273    }
    7374
    74     OwnPtr<ImageBuffer> tileImage = ImageBuffer::create(tileRect.size());
     75    OwnPtr<ImageBuffer> tileImage;
     76    if (!SVGImageBufferTools::createImageBuffer(tileRect, tileRect, tileImage, DeviceRGB))
     77        return;
     78
    7579    GraphicsContext* tileImageContext = tileImage->context();
    76     tileImageContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, IntPoint());
     80    tileImageContext->translate(-inMaxEffectLocation.x(), -inMaxEffectLocation.y());
     81    tileImageContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, in->absolutePaintRect().location());
     82
    7783    RefPtr<Pattern> pattern = Pattern::create(tileImage->copyImage(), true, true);
    7884
    79     AffineTransform matrix;
    80     matrix.translate(in->repaintRectInLocalCoordinates().x() - repaintRectInLocalCoordinates().x(),
    81                      in->repaintRectInLocalCoordinates().y() - repaintRectInLocalCoordinates().y());
    82     pattern.get()->setPatternSpaceTransform(matrix);
    83 
     85    AffineTransform patternTransform;
     86    patternTransform.translate(inMaxEffectLocation.x() - maxEffectLocation.x(), inMaxEffectLocation.y() - maxEffectLocation.y());
     87    pattern->setPatternSpaceTransform(patternTransform);
    8488    filterContext->setFillPattern(pattern);
    85     filterContext->fillRect(FloatRect(FloatPoint(), repaintRectInLocalCoordinates().size()));
     89    filterContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()));
    8690}
    8791
  • trunk/WebCore/platform/graphics/filters/FETile.h

    r68022 r69181  
    3636    virtual void dump();
    3737
     38    virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); }
     39
    3840    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
    3941
  • trunk/WebCore/platform/graphics/filters/FETurbulence.cpp

    r68022 r69181  
    322322void FETurbulence::apply(Filter* filter)
    323323{
    324     if (!effectContext())
     324    if (!effectContext(filter))
    325325        return;
    326326
     
    330330
    331331    RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());
    332     PaintingData paintingData(m_seed, imageRect.size());
     332    PaintingData paintingData(m_seed, roundedIntSize(filterPrimitiveSubregion().size()));
    333333    initPaint(paintingData);
    334334
    335     FloatRect filterRegion = filter->filterRegion();
     335    FloatRect filterRegion = absolutePaintRect();
    336336    FloatPoint point;
    337337    point.setY(filterRegion.y());
     
    343343            point.setX(point.x() + 1);
    344344            for (paintingData.channel = 0; paintingData.channel < 4; ++paintingData.channel, ++indexOfPixelChannel)
    345                 imageData->data()->set(indexOfPixelChannel, calculateTurbulenceValueForPoint(paintingData, point));
     345                imageData->data()->set(indexOfPixelChannel, calculateTurbulenceValueForPoint(paintingData, filter->mapAbsolutePointToLocalPoint(point)));
    346346        }
    347347    }
  • trunk/WebCore/platform/graphics/filters/FETurbulence.h

    r68022 r69181  
    6161    virtual void apply(Filter*);
    6262    virtual void dump();
     63   
     64    virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); }
    6365
    6466    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
  • trunk/WebCore/platform/graphics/filters/Filter.h

    r67929 r69181  
    4545        void setFilterResolution(const FloatSize& filterResolution) { m_filterResolution = filterResolution; }
    4646
     47        virtual float applyHorizontalScale(float value) const { return value * m_filterResolution.width(); }
     48        virtual float applyVerticalScale(float value) const { return value * m_filterResolution.height(); }
     49       
    4750        virtual FloatRect sourceImageRect() const = 0;
    4851        virtual FloatRect filterRegion() const = 0;
     52       
     53        virtual FloatPoint mapAbsolutePointToLocalPoint(const FloatPoint&) const { return FloatPoint(); }
    4954
    5055        // SVG specific
    5156        virtual void determineFilterPrimitiveSubregion(FilterEffect*, const FloatRect&) { }
     57       
     58        virtual FloatRect filterRegionInUserSpace() const { return FloatRect(); }
    5259
    5360        virtual FloatSize maxImageSize() const = 0;
  • trunk/WebCore/platform/graphics/filters/FilterEffect.cpp

    r67929 r69181  
    4747    // FETurbulence, FEImage and FEFlood don't have input effects, take the filter region as unite rect.
    4848    if (!size)
    49         uniteRect = filter->filterRegion();
     49        uniteRect = filter->filterRegionInUserSpace();
    5050    else {
    5151        for (unsigned i = 0; i < size; ++i)
     
    5757}
    5858
    59 IntRect FilterEffect::requestedRegionOfInputImageData(const FloatRect& effectRect) const
     59void FilterEffect::determineAbsolutePaintRect(Filter*)
     60{
     61    m_absolutePaintRect = IntRect();
     62    unsigned size = m_inputEffects.size();
     63    for (unsigned i = 0; i < size; ++i)
     64        m_absolutePaintRect.unite(m_inputEffects.at(i)->absolutePaintRect());
     65   
     66    // SVG specification wants us to clip to primitive subregion.
     67    m_absolutePaintRect.intersect(m_maxEffectRect);
     68}
     69
     70IntRect FilterEffect::requestedRegionOfInputImageData(const IntRect& effectRect) const
    6071{
    6172    ASSERT(m_effectBuffer);
    62     FloatPoint location = m_repaintRectInLocalCoordinates.location();
     73    IntPoint location = m_absolutePaintRect.location();
    6374    location.move(-effectRect.x(), -effectRect.y());
    64     return IntRect(roundedIntPoint(location), m_effectBuffer->size());
     75    return IntRect(location, m_effectBuffer->size());
    6576}
    6677
    67 FloatRect FilterEffect::drawingRegionOfInputImage(const FloatRect& srcRect) const
     78IntRect FilterEffect::drawingRegionOfInputImage(const IntRect& srcRect) const
    6879{
    69     return FloatRect(FloatPoint(srcRect.x() - m_repaintRectInLocalCoordinates.x(),
    70                                 srcRect.y() - m_repaintRectInLocalCoordinates.y()), srcRect.size());
     80    return IntRect(IntPoint(srcRect.x() - m_absolutePaintRect.x(),
     81                            srcRect.y() - m_absolutePaintRect.y()), srcRect.size());
    7182}
    7283
     
    7788}
    7889
    79 GraphicsContext* FilterEffect::effectContext()
     90GraphicsContext* FilterEffect::effectContext(Filter* filter)
    8091{
    81     IntRect bufferRect = enclosingIntRect(m_repaintRectInLocalCoordinates);
    82     m_effectBuffer = ImageBuffer::create(bufferRect.size(), LinearRGB);
     92    determineAbsolutePaintRect(filter);
     93    if (m_absolutePaintRect.isEmpty())
     94        return 0;
     95    m_effectBuffer = ImageBuffer::create(m_absolutePaintRect.size(), LinearRGB);
    8396    if (!m_effectBuffer)
    8497        return 0;
  • trunk/WebCore/platform/graphics/filters/FilterEffect.h

    r67929 r69181  
    5050    // Creates the ImageBuffer for the current filter primitive result in the size of the
    5151    // repaintRect. Gives back the GraphicsContext of the own ImageBuffer.
    52     GraphicsContext* effectContext();
     52    GraphicsContext* effectContext(Filter*);
    5353
    5454    FilterEffectVector& inputEffects() { return m_inputEffects; }
     
    5656    unsigned numberOfEffectInputs() const { return m_inputEffects.size(); }
    5757
    58     FloatRect drawingRegionOfInputImage(const FloatRect&) const;
    59     IntRect requestedRegionOfInputImageData(const FloatRect&) const;
     58    IntRect drawingRegionOfInputImage(const IntRect&) const;
     59    IntRect requestedRegionOfInputImageData(const IntRect&) const;
    6060
    6161    // Solid black image with different alpha values.
     
    6363    void setIsAlphaImage(bool alphaImage) { m_alphaImage = alphaImage; }
    6464
    65     FloatRect repaintRectInLocalCoordinates() const { return m_repaintRectInLocalCoordinates; }
    66     void setRepaintRectInLocalCoordinates(const FloatRect& repaintRectInLocalCoordinates) { m_repaintRectInLocalCoordinates = repaintRectInLocalCoordinates; }
     65    IntRect absolutePaintRect() const { return m_absolutePaintRect; }
     66    void setAbsolutePaintRect(const IntRect& absolutePaintRect) { m_absolutePaintRect = absolutePaintRect; }
     67   
     68    IntRect maxEffectRect() const { return m_maxEffectRect; }
     69    void setMaxEffectRect(const IntRect& maxEffectRect) { m_maxEffectRect = maxEffectRect; }
    6770
    6871    virtual void apply(Filter*) = 0;
    6972    virtual void dump() = 0;
    7073
     74    virtual void determineAbsolutePaintRect(Filter*);
     75   
    7176    virtual bool isSourceInput() const { return false; }
    7277
     
    8893    void setHasHeight(bool value) { m_hasHeight = value; }
    8994
    90     // FIXME: Pseudo primitives like SourceGraphic and SourceAlpha as well as FETile still need special handling.
     95    // FIXME: FETile still needs special handling.
    9196    virtual FloatRect determineFilterPrimitiveSubregion(Filter*);
    9297
     
    106111    bool m_alphaImage;
    107112
    108     // FIXME: Should be the paint region of the filter primitive, instead of the scaled subregion on use of filterRes.
    109     FloatRect m_repaintRectInLocalCoordinates;
     113    IntRect m_absolutePaintRect;
     114   
     115    // The maximum size of a filter primitive. In SVG this is the primitive subregion in absolute coordinate space.
     116    // The absolute paint rect should never be bigger than m_maxEffectRect.
     117    IntRect m_maxEffectRect;
    110118
    111119private:
  • trunk/WebCore/platform/graphics/filters/SourceAlpha.cpp

    r67929 r69181  
    4343}
    4444
    45 FloatRect SourceAlpha::determineFilterPrimitiveSubregion(Filter* filter)
     45void SourceAlpha::determineAbsolutePaintRect(Filter* filter)
    4646{
    47     FloatRect clippedSourceRect = filter->sourceImageRect();
    48     if (filter->sourceImageRect().x() < filter->filterRegion().x())
    49         clippedSourceRect.setX(filter->filterRegion().x());
    50     if (filter->sourceImageRect().y() < filter->filterRegion().y())
    51         clippedSourceRect.setY(filter->filterRegion().y());
    52     setFilterPrimitiveSubregion(clippedSourceRect);
    53     clippedSourceRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
    54     setRepaintRectInLocalCoordinates(clippedSourceRect);
    55     return filter->filterRegion();
     47    FloatRect paintRect = filter->sourceImageRect();
     48    paintRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
     49    setAbsolutePaintRect(enclosingIntRect(paintRect));
    5650}
    5751
    5852void SourceAlpha::apply(Filter* filter)
    5953{
    60     GraphicsContext* filterContext = effectContext();
    61     if (!filterContext)
     54    GraphicsContext* filterContext = effectContext(filter);
     55    if (!filterContext || !filter->sourceImage())
    6256        return;
    6357
    6458    setIsAlphaImage(true);
    6559
    66     FloatRect imageRect(FloatPoint(), filter->sourceImage()->size());
     60    FloatRect imageRect(FloatPoint(), absolutePaintRect().size());
    6761    filterContext->save();
    6862    filterContext->clipToImageBuffer(filter->sourceImage(), imageRect);
  • trunk/WebCore/platform/graphics/filters/SourceAlpha.h

    r67929 r69181  
    3535    static const AtomicString& effectName();
    3636
    37     virtual FloatRect determineFilterPrimitiveSubregion(Filter*);
    38 
    3937    virtual void apply(Filter*);
    4038    virtual void dump();
     39
     40    virtual void determineAbsolutePaintRect(Filter*);
    4141
    4242    virtual bool isSourceInput() const { return true; }
  • trunk/WebCore/platform/graphics/filters/SourceGraphic.cpp

    r67929 r69181  
    4242}
    4343
    44 FloatRect SourceGraphic::determineFilterPrimitiveSubregion(Filter* filter)
     44void SourceGraphic::determineAbsolutePaintRect(Filter* filter)
    4545{
    46     FloatRect clippedSourceRect = filter->sourceImageRect();
    47     if (filter->sourceImageRect().x() < filter->filterRegion().x())
    48         clippedSourceRect.setX(filter->filterRegion().x());
    49     if (filter->sourceImageRect().y() < filter->filterRegion().y())
    50         clippedSourceRect.setY(filter->filterRegion().y());
    51     setFilterPrimitiveSubregion(clippedSourceRect);
    52     clippedSourceRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
    53     setRepaintRectInLocalCoordinates(clippedSourceRect);
    54     return filter->filterRegion();
     46    FloatRect paintRect = filter->sourceImageRect();
     47    paintRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
     48    setAbsolutePaintRect(enclosingIntRect(paintRect));
    5549}
    5650
    5751void SourceGraphic::apply(Filter* filter)
    5852{
    59     GraphicsContext* filterContext = effectContext();
    60     if (!filterContext)
     53    GraphicsContext* filterContext = effectContext(filter);
     54    if (!filterContext || !filter->sourceImage())
    6155        return;
    6256
  • trunk/WebCore/platform/graphics/filters/SourceGraphic.h

    r67929 r69181  
    3636    static const AtomicString& effectName();
    3737
    38     virtual FloatRect determineFilterPrimitiveSubregion(Filter*);
    39 
    4038    virtual void apply(Filter*);
    4139    virtual void dump();
     40
     41    virtual void determineAbsolutePaintRect(Filter*);
    4242
    4343    virtual bool isSourceInput() const { return true; }
  • trunk/WebCore/rendering/RenderSVGResourceFilter.cpp

    r68385 r69181  
    4040#include "SVGFilterElement.h"
    4141#include "SVGFilterPrimitiveStandardAttributes.h"
     42#include "SVGImageBufferTools.h"
    4243#include "SVGStyledElement.h"
    4344#include "SVGUnitTypes.h"
     
    151152
    152153    OwnPtr<FilterData> filterData(new FilterData);
     154    FloatRect targetBoundingBox = object->objectBoundingBox();
     155
     156    SVGFilterElement* filterElement = static_cast<SVGFilterElement*>(node());
     157    filterData->boundaries = filterElement->filterBoundingBox(targetBoundingBox);
     158    if (filterData->boundaries.isEmpty())
     159        return false;
     160
     161    // Determine absolute transformation matrix for filter.
     162    AffineTransform absoluteTransform;
     163    SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransform);
     164    if (!absoluteTransform.isInvertible())
     165        return false;
     166
     167    // Eliminate shear of the absolute transformation matrix, to be able to produce unsheared tile images for feTile.
     168    filterData->shearFreeAbsoluteTransform = AffineTransform(absoluteTransform.xScale(), 0, 0, absoluteTransform.yScale(), absoluteTransform.e(), absoluteTransform.f());
     169
     170    // Determine absolute boundaries of the filter and the drawing region.
     171    FloatRect absoluteFilterBoundaries = filterData->shearFreeAbsoluteTransform.mapRect(filterData->boundaries);
     172    FloatRect drawingRegion = object->strokeBoundingBox();
     173    drawingRegion.intersect(filterData->boundaries);
     174    FloatRect absoluteDrawingRegion = filterData->shearFreeAbsoluteTransform.mapRect(drawingRegion);
     175
     176    // Create the SVGFilter object.
     177    bool primitiveBoundingBoxMode = filterElement->primitiveUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
     178    filterData->filter = SVGFilter::create(filterData->shearFreeAbsoluteTransform, absoluteDrawingRegion, targetBoundingBox, filterData->boundaries, primitiveBoundingBoxMode);
     179
     180    // Create all relevant filter primitives.
    153181    filterData->builder = buildPrimitives();
    154182    if (!filterData->builder)
    155183        return false;
    156184
    157     FloatRect paintRect = object->strokeBoundingBox();
    158 
    159185    // Calculate the scale factor for the use of filterRes.
    160186    // Also see http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion
    161     SVGFilterElement* filterElement = static_cast<SVGFilterElement*>(node());
    162     filterData->boundaries = filterElement->filterBoundingBox(object->objectBoundingBox());
    163     if (filterData->boundaries.isEmpty())
    164         return false;
    165 
    166     FloatSize scale(1.0f, 1.0f);
     187    FloatSize scale(1, 1);
    167188    if (filterElement->hasAttribute(SVGNames::filterResAttr)) {
    168         scale.setWidth(filterElement->filterResX() / filterData->boundaries.width());
    169         scale.setHeight(filterElement->filterResY() / filterData->boundaries.height());
     189        scale.setWidth(filterElement->filterResX() / absoluteFilterBoundaries.width());
     190        scale.setHeight(filterElement->filterResY() / absoluteFilterBoundaries.height());
    170191    }
    171192
     
    173194        return false;
    174195
    175     // clip sourceImage to filterRegion
    176     FloatRect clippedSourceRect = paintRect;
    177     clippedSourceRect.intersect(filterData->boundaries);
    178 
    179     // scale filter size to filterRes
    180     FloatRect tempSourceRect = clippedSourceRect;
    181 
    182     // scale to big sourceImage size to kMaxFilterSize
     196    // Determine scale factor for filter. The size of intermediate ImageBuffers shouldn't be bigger than kMaxFilterSize.
     197    FloatRect tempSourceRect = absoluteDrawingRegion;
    183198    tempSourceRect.scale(scale.width(), scale.height());
    184199    fitsInMaximumImageSize(tempSourceRect.size(), scale);
    185200
    186     // prepare Filters
    187     bool primitiveBoundingBoxMode = filterElement->primitiveUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
    188     filterData->filter = SVGFilter::create(paintRect, filterData->boundaries, primitiveBoundingBoxMode);
     201    // Set the scale level in SVGFilter.
    189202    filterData->filter->setFilterResolution(scale);
    190203
     
    192205    if (!lastEffect)
    193206        return false;
    194    
     207
     208    // Determine the filter primitive subregions of every effect.
    195209    lastEffect->determineFilterPrimitiveSubregion(filterData->filter.get());
    196     // At least one FilterEffect has a too big image size,
    197     // recalculate the effect sizes with new scale factors.
    198210    if (!fitsInMaximumImageSize(filterData->filter->maxImageSize(), scale)) {
     211        // At least one FilterEffect has a too big image size,
     212        // recalculate the effect sizes with new scale factor.
    199213        filterData->filter->setFilterResolution(scale);
    200214        lastEffect->determineFilterPrimitiveSubregion(filterData->filter.get());
    201215    }
    202216
    203     clippedSourceRect.scale(scale.width(), scale.height());
    204 
    205     // Draw the content of the current element and it's childs to a imageBuffer to get the SourceGraphic.
    206     // The size of the SourceGraphic is clipped to the size of the filterRegion.
    207     IntRect bufferRect = enclosingIntRect(clippedSourceRect);
    208     OwnPtr<ImageBuffer> sourceGraphic(ImageBuffer::create(bufferRect.size(), LinearRGB));
     217    // If the drawingRegion is empty, we have something like <g filter=".."/>.
     218    // Even if the target objectBoundingBox() is empty, we still have to draw the last effect result image in postApplyResource.
     219    if (drawingRegion.isEmpty()) {
     220        ASSERT(!m_filter.contains(object));
     221        filterData->savedContext = context;
     222        m_filter.set(object, filterData.leakPtr());
     223        return false;
     224    }
     225
     226    absoluteDrawingRegion.scale(scale.width(), scale.height());
     227
     228    OwnPtr<ImageBuffer> sourceGraphic;
     229    if (!SVGImageBufferTools::createImageBuffer(absoluteDrawingRegion, absoluteDrawingRegion, sourceGraphic, LinearRGB))
     230        return false;
    209231   
    210     if (!sourceGraphic.get())
    211         return false;
    212 
    213232    GraphicsContext* sourceGraphicContext = sourceGraphic->context();
    214     sourceGraphicContext->translate(-clippedSourceRect.x(), -clippedSourceRect.y());
    215     sourceGraphicContext->scale(scale);
    216     sourceGraphicContext->clearRect(FloatRect(FloatPoint(), paintRect.size()));
     233    ASSERT(sourceGraphicContext);
     234 
     235    sourceGraphicContext->translate(-absoluteDrawingRegion.x(), -absoluteDrawingRegion.y());
     236    if (scale.width() != 1 || scale.height() != 1)
     237        sourceGraphicContext->scale(scale);
     238
     239    sourceGraphicContext->concatCTM(filterData->shearFreeAbsoluteTransform);
     240    sourceGraphicContext->clearRect(FloatRect(FloatPoint(), absoluteDrawingRegion.size()));
    217241    filterData->sourceGraphicBuffer = sourceGraphic.release();
    218242    filterData->savedContext = context;
     
    271295
    272296        ImageBuffer* resultImage = lastEffect->resultImage();
    273         if (resultImage)
    274             context->drawImageBuffer(resultImage, object->style()->colorSpace(), lastEffect->filterPrimitiveSubregion());
    275     }
    276 
     297        if (resultImage) {
     298            context->concatCTM(filterData->shearFreeAbsoluteTransform.inverse());
     299
     300            context->scale(FloatSize(1 / filterData->filter->filterResolution().width(), 1 / filterData->filter->filterResolution().height()));
     301            context->clip(lastEffect->maxEffectRect());
     302            context->drawImageBuffer(resultImage, object->style()->colorSpace(), lastEffect->absolutePaintRect());
     303            context->scale(filterData->filter->filterResolution());
     304
     305            context->concatCTM(filterData->shearFreeAbsoluteTransform);
     306        }
     307    }
    277308    filterData->sourceGraphicBuffer.clear();
    278309}
  • trunk/WebCore/rendering/RenderSVGResourceFilter.h

    r65310 r69181  
    4343struct FilterData {
    4444    FilterData()
    45         : builded(false)
     45        : savedContext(0)
     46        , builded(false)
    4647    {
    4748    }
     
    5152    OwnPtr<ImageBuffer> sourceGraphicBuffer;
    5253    GraphicsContext* savedContext;
     54    AffineTransform shearFreeAbsoluteTransform;
    5355    FloatRect boundaries;
    5456    FloatSize scale;
  • trunk/WebCore/svg/graphics/filters/SVGFEImage.cpp

    r67929 r69181  
    4545}
    4646
    47 void FEImage::apply(Filter*)
     47void FEImage::apply(Filter* filter)
    4848{
    4949    if (!m_image.get())
    5050        return;
    5151
    52     GraphicsContext* filterContext = effectContext();
     52    GraphicsContext* filterContext = effectContext(filter);
    5353    if (!filterContext)
    5454        return;
    5555
    5656    FloatRect srcRect(FloatPoint(), m_image->size());
    57     FloatRect destRect(FloatPoint(), filterPrimitiveSubregion().size());
     57    FloatRect destRect(FloatPoint(), absolutePaintRect().size());
    5858
    5959    m_preserveAspectRatio.transformRect(destRect, srcRect);
  • trunk/WebCore/svg/graphics/filters/SVGFEImage.h

    r67929 r69181  
    3737    virtual void dump();
    3838
     39    virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); }
     40
    3941    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
    4042   
  • trunk/WebCore/svg/graphics/filters/SVGFilter.cpp

    r67847 r69181  
    11/*
    22 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
     3 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
    34 *
    45 * This library is free software; you can redistribute it and/or
     
    2526namespace WebCore {
    2627
    27 SVGFilter::SVGFilter(const FloatRect& targetBoundingBox, const FloatRect& filterRect, bool effectBBoxMode)
     28SVGFilter::SVGFilter(const AffineTransform& absoluteTransform, const FloatRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode)
    2829    : Filter()
     30    , m_absoluteTransform(absoluteTransform)
     31    , m_absoluteSourceDrawingRegion(absoluteSourceDrawingRegion)
    2932    , m_targetBoundingBox(targetBoundingBox)
    30     , m_filterRect(filterRect)
     33    , m_filterRegion(filterRegion)
    3134    , m_effectBBoxMode(effectBBoxMode)
    3235{
     36    m_absoluteFilterRegion = absoluteTransform.mapRect(filterRegion);
    3337}
    3438
     
    6771
    6872    // clip every filter effect to the filter region
    69     newSubRegion.intersect(m_filterRect);
     73    newSubRegion.intersect(m_filterRegion);
    7074
    7175    effect->setFilterPrimitiveSubregion(newSubRegion);
    72    
    7376    // TODO: Everything above should be moved to a first phase of layout in RenderSVGResourceFilterPrimitive.
    7477    // The scaling of the subregion to the repaint rect should be merged with a more intelligent repaint logic
    7578    // and moved to the second phase of layout in RenderSVGResourceFilterPrimitive.
    7679    // See bug https://bugs.webkit.org/show_bug.cgi?id=45614.
     80    newSubRegion = m_absoluteTransform.mapRect(newSubRegion);
    7781    newSubRegion.scale(filterResolution().width(), filterResolution().height());
    78     effect->setRepaintRectInLocalCoordinates(newSubRegion);
    79     m_maxImageSize = m_maxImageSize.expandedTo(newSubRegion.size());
     82    effect->setMaxEffectRect(enclosingIntRect(newSubRegion));
     83    if (!effect->isSourceInput())
     84        m_maxImageSize = m_maxImageSize.expandedTo(newSubRegion.size());
    8085}
    8186
    82 PassRefPtr<SVGFilter> SVGFilter::create(const FloatRect& targetBoundingBox, const FloatRect& filterRect, bool effectBBoxMode)
     87float SVGFilter::applyHorizontalScale(float value) const
    8388{
    84     return adoptRef(new SVGFilter(targetBoundingBox, filterRect, effectBBoxMode));
     89    if (m_effectBBoxMode)
     90        value *= m_targetBoundingBox.width();
     91    return Filter::applyHorizontalScale(value) * m_absoluteFilterRegion.width() / m_filterRegion.width();
     92}
     93
     94float SVGFilter::applyVerticalScale(float value) const
     95{
     96    if (m_effectBBoxMode)
     97        value *= m_targetBoundingBox.height();
     98    return Filter::applyVerticalScale(value) * m_absoluteFilterRegion.height() / m_filterRegion.height();
     99}
     100
     101PassRefPtr<SVGFilter> SVGFilter::create(const AffineTransform& absoluteTransform, const FloatRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode)
     102{
     103    return adoptRef(new SVGFilter(absoluteTransform, absoluteSourceDrawingRegion, targetBoundingBox, filterRegion, effectBBoxMode));
    85104}
    86105
  • trunk/WebCore/svg/graphics/filters/SVGFilter.h

    r67847 r69181  
    2222
    2323#if ENABLE(SVG) && ENABLE(FILTERS)
     24#include "AffineTransform.h"
    2425#include "Filter.h"
    2526#include "FilterEffect.h"
     
    3334namespace WebCore {
    3435
    35     class SVGFilter : public Filter {
    36     public:
    37         static PassRefPtr<SVGFilter> create(const FloatRect&, const FloatRect&, bool);
     36class SVGFilter : public Filter {
     37public:
     38    static PassRefPtr<SVGFilter> create(const AffineTransform&, const FloatRect&, const FloatRect&, const FloatRect&, bool);
    3839
    39         virtual bool effectBoundingBoxMode() const { return m_effectBBoxMode; }
     40    virtual bool effectBoundingBoxMode() const { return m_effectBBoxMode; }
    4041
    41         virtual FloatRect filterRegion() const { return m_filterRect; }
    42        
    43         virtual FloatRect sourceImageRect() const { return m_targetBoundingBox; }
     42    virtual FloatRect filterRegionInUserSpace() const { return m_filterRegion; }
     43    virtual FloatRect filterRegion() const { return m_absoluteFilterRegion; }
    4444
    45         virtual FloatSize maxImageSize() const { return m_maxImageSize; }
    46         virtual void determineFilterPrimitiveSubregion(FilterEffect*, const FloatRect&);
     45    virtual FloatPoint mapAbsolutePointToLocalPoint(const FloatPoint& point) const { return m_absoluteTransform.inverse().mapPoint(point); }
    4746
    48     private:
    49         SVGFilter(const FloatRect& targetBoundingBox, const FloatRect& filterRect, bool effectBBoxMode);
     47    virtual float applyHorizontalScale(float value) const;
     48    virtual float applyVerticalScale(float value) const;
    5049
    51         FloatSize m_maxImageSize;
    52         FloatRect m_targetBoundingBox;
    53         FloatRect m_filterRect;
    54         bool m_effectBBoxMode;
    55     };
     50    virtual FloatRect sourceImageRect() const { return m_absoluteSourceDrawingRegion; }
     51   
     52    virtual FloatSize maxImageSize() const { return m_maxImageSize; }
     53    virtual void determineFilterPrimitiveSubregion(FilterEffect*, const FloatRect&);
     54
     55private:
     56    SVGFilter(const AffineTransform& absoluteTransform, const FloatRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode);
     57
     58    AffineTransform m_absoluteTransform;
     59    FloatRect m_absoluteSourceDrawingRegion;
     60    FloatRect m_targetBoundingBox;
     61    FloatRect m_absoluteFilterRegion;
     62    FloatRect m_filterRegion;
     63    bool m_effectBBoxMode;
     64    FloatSize m_maxImageSize;
     65};
    5666
    5767} // namespace WebCore
Note: See TracChangeset for help on using the changeset viewer.