| Differences between
and this patch
- WebCore/ChangeLog +133 lines
Lines 1-3 WebCore/ChangeLog_sec1
1
2010-10-05  Dirk Schulze  <krit@webkit.org>
2
3
        Reviewed by NOBODY (OOPS!).
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
1
2010-10-05  Kimmo Kinnunen  <kimmo.t.kinnunen@nokia.com>
134
2010-10-05  Kimmo Kinnunen  <kimmo.t.kinnunen@nokia.com>
2
135
3
        Reviewed by Kenneth Rohde Christiansen.
136
        Reviewed by Kenneth Rohde Christiansen.
- WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp -2 / +2 lines
Lines 944-955 PlatformRefPtr<cairo_surface_t> Graphics WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp_sec1
944
    RefPtr<Filter> filter = ImageBufferFilter::create();
944
    RefPtr<Filter> filter = ImageBufferFilter::create();
945
    filter->setSourceImage(buffer);
945
    filter->setSourceImage(buffer);
946
    RefPtr<FilterEffect> source = SourceGraphic::create();
946
    RefPtr<FilterEffect> source = SourceGraphic::create();
947
    source->setRepaintRectInLocalCoordinates(FloatRect(FloatPoint(), shadowRect.size()));
947
    source->setAbsolutePaintRect(IntRect(IntPoint(), roundedIntSize(shadowRect.size())));
948
    source->setIsAlphaImage(true);
948
    source->setIsAlphaImage(true);
949
    RefPtr<FilterEffect> blur = FEGaussianBlur::create(stdDeviation, stdDeviation);
949
    RefPtr<FilterEffect> blur = FEGaussianBlur::create(stdDeviation, stdDeviation);
950
    FilterEffectVector& inputEffects = blur->inputEffects();
950
    FilterEffectVector& inputEffects = blur->inputEffects();
951
    inputEffects.append(source.get());
951
    inputEffects.append(source.get());
952
    blur->setRepaintRectInLocalCoordinates(FloatRect(FloatPoint(), shadowRect.size()));
952
    blur->setAbsolutePaintRect(IntRect(IntPoint(), roundedIntSize(shadowRect.size())));
953
    blur->apply(filter.get());
953
    blur->apply(filter.get());
954
    return blur->resultImage()->m_data.m_surface;
954
    return blur->resultImage()->m_data.m_surface;
955
#endif
955
#endif
- WebCore/platform/graphics/filters/FEBlend.cpp -3 / +3 lines
Lines 98-110 void FEBlend::apply(Filter* filter) WebCore/platform/graphics/filters/FEBlend.cpp_sec1
98
    if (m_mode == FEBLEND_MODE_UNKNOWN)
98
    if (m_mode == FEBLEND_MODE_UNKNOWN)
99
        return;
99
        return;
100
100
101
    if (!effectContext())
101
    if (!effectContext(filter))
102
        return;
102
        return;
103
103
104
    IntRect effectADrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
104
    IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
105
    RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data());
105
    RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data());
106
106
107
    IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->repaintRectInLocalCoordinates());
107
    IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect());
108
    RefPtr<CanvasPixelArray> srcPixelArrayB(in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)->data());
108
    RefPtr<CanvasPixelArray> srcPixelArrayB(in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)->data());
109
109
110
    IntRect imageRect(IntPoint(), resultImage()->size());
110
    IntRect imageRect(IntPoint(), resultImage()->size());
- WebCore/platform/graphics/filters/FEColorMatrix.cpp -2 / +2 lines
Lines 160-170 void FEColorMatrix::apply(Filter* filter WebCore/platform/graphics/filters/FEColorMatrix.cpp_sec1
160
    if (!in->resultImage())
160
    if (!in->resultImage())
161
        return;
161
        return;
162
162
163
    GraphicsContext* filterContext = effectContext();
163
    GraphicsContext* filterContext = effectContext(filter);
164
    if (!filterContext)
164
    if (!filterContext)
165
        return;
165
        return;
166
166
167
    filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()));
167
    filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect()));
168
168
169
    IntRect imageRect(IntPoint(), resultImage()->size());
169
    IntRect imageRect(IntPoint(), resultImage()->size());
170
    PassRefPtr<ImageData> imageData(resultImage()->getUnmultipliedImageData(imageRect));
170
    PassRefPtr<ImageData> imageData(resultImage()->getUnmultipliedImageData(imageRect));
- WebCore/platform/graphics/filters/FEComponentTransfer.cpp -2 / +2 lines
Lines 154-160 void FEComponentTransfer::apply(Filter* WebCore/platform/graphics/filters/FEComponentTransfer.cpp_sec1
154
    if (!in->resultImage())
154
    if (!in->resultImage())
155
        return;
155
        return;
156
156
157
    if (!effectContext())
157
    if (!effectContext(filter))
158
        return;
158
        return;
159
159
160
    unsigned char rValues[256], gValues[256], bValues[256], aValues[256];
160
    unsigned char rValues[256], gValues[256], bValues[256], aValues[256];
Lines 167-173 void FEComponentTransfer::apply(Filter* WebCore/platform/graphics/filters/FEComponentTransfer.cpp_sec2
167
    for (unsigned channel = 0; channel < 4; channel++)
167
    for (unsigned channel = 0; channel < 4; channel++)
168
        (*callEffect[transferFunction[channel].type])(tables[channel], transferFunction[channel]);
168
        (*callEffect[transferFunction[channel].type])(tables[channel], transferFunction[channel]);
169
169
170
    IntRect drawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
170
    IntRect drawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
171
    RefPtr<ImageData> imageData(in->resultImage()->getUnmultipliedImageData(drawingRect));
171
    RefPtr<ImageData> imageData(in->resultImage()->getUnmultipliedImageData(drawingRect));
172
    CanvasPixelArray* srcPixelArray(imageData->data());
172
    CanvasPixelArray* srcPixelArray(imageData->data());
173
173
- WebCore/platform/graphics/filters/FEComposite.cpp -13 / +34 lines
Lines 112-117 inline void arithmetic(const RefPtr<Canv WebCore/platform/graphics/filters/FEComposite.cpp_sec1
112
        }
112
        }
113
    }
113
    }
114
}
114
}
115
    
116
void FEComposite::determineAbsolutePaintRect(Filter* filter)
117
{
118
    switch (m_type) {
119
    case FECOMPOSITE_OPERATOR_IN:
120
    case FECOMPOSITE_OPERATOR_ATOP:
121
        // For In and Atop the first effect just influences the result of
122
        // the second effect. So just use the absolute paint rect of the second effect here.
123
        setAbsolutePaintRect(inputEffect(1)->absolutePaintRect());
124
        return;
125
    case FECOMPOSITE_OPERATOR_ARITHMETIC:
126
        // Arithmetic may influnce the comple filter primitive region. So we can't
127
        // optimize the paint region here.
128
        setAbsolutePaintRect(maxEffectRect());
129
        return;
130
    default:
131
        // Take the union of both input effects.
132
        FilterEffect::determineAbsolutePaintRect(filter);
133
        return;
134
    }
135
}
115
136
116
void FEComposite::apply(Filter* filter)
137
void FEComposite::apply(Filter* filter)
117
{
138
{
Lines 122-160 void FEComposite::apply(Filter* filter) WebCore/platform/graphics/filters/FEComposite.cpp_sec2
122
    if (!in->resultImage() || !in2->resultImage())
143
    if (!in->resultImage() || !in2->resultImage())
123
        return;
144
        return;
124
145
125
    GraphicsContext* filterContext = effectContext();
146
    GraphicsContext* filterContext = effectContext(filter);
126
    if (!filterContext)
147
    if (!filterContext)
127
        return;
148
        return;
128
149
129
    FloatRect srcRect = FloatRect(0, 0, -1, -1);
150
    FloatRect srcRect = FloatRect(0, 0, -1, -1);
130
    switch (m_type) {
151
    switch (m_type) {
131
    case FECOMPOSITE_OPERATOR_OVER:
152
    case FECOMPOSITE_OPERATOR_OVER:
132
        filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates()));
153
        filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->absolutePaintRect()));
133
        filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()));
154
        filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect()));
134
        break;
155
        break;
135
    case FECOMPOSITE_OPERATOR_IN:
156
    case FECOMPOSITE_OPERATOR_IN:
136
        filterContext->save();
157
        filterContext->save();
137
        filterContext->clipToImageBuffer(in2->resultImage(), drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates()));
158
        filterContext->clipToImageBuffer(in2->resultImage(), drawingRegionOfInputImage(in2->absolutePaintRect()));
138
        filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()));
159
        filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect()));
139
        filterContext->restore();
160
        filterContext->restore();
140
        break;
161
        break;
141
    case FECOMPOSITE_OPERATOR_OUT:
162
    case FECOMPOSITE_OPERATOR_OUT:
142
        filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()));
163
        filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect()));
143
        filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates()), srcRect, CompositeDestinationOut);
164
        filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->absolutePaintRect()), srcRect, CompositeDestinationOut);
144
        break;
165
        break;
145
    case FECOMPOSITE_OPERATOR_ATOP:
166
    case FECOMPOSITE_OPERATOR_ATOP:
146
        filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates()));
167
        filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->absolutePaintRect()));
147
        filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()), srcRect, CompositeSourceAtop);
168
        filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect()), srcRect, CompositeSourceAtop);
148
        break;
169
        break;
149
    case FECOMPOSITE_OPERATOR_XOR:
170
    case FECOMPOSITE_OPERATOR_XOR:
150
        filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->repaintRectInLocalCoordinates()));
171
        filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->absolutePaintRect()));
151
        filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()), srcRect, CompositeXOR);
172
        filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect()), srcRect, CompositeXOR);
152
        break;
173
        break;
153
    case FECOMPOSITE_OPERATOR_ARITHMETIC: {
174
    case FECOMPOSITE_OPERATOR_ARITHMETIC: {
154
        IntRect effectADrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
175
        IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
155
        RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data());
176
        RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data());
156
177
157
        IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->repaintRectInLocalCoordinates());
178
        IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect());
158
        RefPtr<ImageData> imageData(in2->resultImage()->getPremultipliedImageData(effectBDrawingRect));
179
        RefPtr<ImageData> imageData(in2->resultImage()->getPremultipliedImageData(effectBDrawingRect));
159
        CanvasPixelArray* srcPixelArrayB(imageData->data());
180
        CanvasPixelArray* srcPixelArrayB(imageData->data());
160
181
- WebCore/platform/graphics/filters/FEComposite.h +2 lines
Lines 61-66 public: WebCore/platform/graphics/filters/FEComposite.h_sec1
61
61
62
    virtual void apply(Filter*);
62
    virtual void apply(Filter*);
63
    virtual void dump();
63
    virtual void dump();
64
    
65
    virtual void determineAbsolutePaintRect(Filter*);
64
66
65
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
67
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
66
68
- WebCore/platform/graphics/filters/FEConvolveMatrix.cpp -2 / +2 lines
Lines 377-387 void FEConvolveMatrix::apply(Filter* fil WebCore/platform/graphics/filters/FEConvolveMatrix.cpp_sec1
377
    if (!in->resultImage())
377
    if (!in->resultImage())
378
        return;
378
        return;
379
379
380
    if (!effectContext())
380
    if (!effectContext(filter))
381
        return;
381
        return;
382
382
383
    IntRect imageRect(IntPoint(), resultImage()->size());
383
    IntRect imageRect(IntPoint(), resultImage()->size());
384
    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->filterPrimitiveSubregion());
384
    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
385
385
386
    RefPtr<CanvasPixelArray> srcPixelArray;
386
    RefPtr<CanvasPixelArray> srcPixelArray;
387
    if (m_preserveAlpha)
387
    if (m_preserveAlpha)
- WebCore/platform/graphics/filters/FEConvolveMatrix.h +2 lines
Lines 75-80 public: WebCore/platform/graphics/filters/FEConvolveMatrix.h_sec1
75
    virtual void apply(Filter*);
75
    virtual void apply(Filter*);
76
    virtual void dump();
76
    virtual void dump();
77
77
78
    virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); }
79
78
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
80
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
79
81
80
private:
82
private:
- WebCore/platform/graphics/filters/FEDisplacementMap.cpp -7 / +7 lines
Lines 88-100 void FEDisplacementMap::apply(Filter* fi WebCore/platform/graphics/filters/FEDisplacementMap.cpp_sec1
88
    if (m_xChannelSelector == CHANNEL_UNKNOWN || m_yChannelSelector == CHANNEL_UNKNOWN)
88
    if (m_xChannelSelector == CHANNEL_UNKNOWN || m_yChannelSelector == CHANNEL_UNKNOWN)
89
        return;
89
        return;
90
90
91
    if (!effectContext())
91
    if (!effectContext(filter))
92
        return;
92
        return;
93
93
94
    IntRect effectADrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
94
    IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
95
    RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data());
95
    RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data());
96
96
97
    IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->repaintRectInLocalCoordinates());
97
    IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect());
98
    RefPtr<CanvasPixelArray> srcPixelArrayB(in2->resultImage()->getUnmultipliedImageData(effectBDrawingRect)->data());
98
    RefPtr<CanvasPixelArray> srcPixelArrayB(in2->resultImage()->getUnmultipliedImageData(effectBDrawingRect)->data());
99
99
100
    IntRect imageRect(IntPoint(), resultImage()->size());
100
    IntRect imageRect(IntPoint(), resultImage()->size());
Lines 102-111 void FEDisplacementMap::apply(Filter* fi WebCore/platform/graphics/filters/FEDisplacementMap.cpp_sec2
102
102
103
    ASSERT(srcPixelArrayA->length() == srcPixelArrayB->length());
103
    ASSERT(srcPixelArrayA->length() == srcPixelArrayB->length());
104
104
105
    float scaleX = m_scale / 255.f * filter->filterResolution().width();
105
    float scaleX = filter->applyHorizontalScale(m_scale / 255);
106
    float scaleY = m_scale / 255.f * filter->filterResolution().height();
106
    float scaleY = filter->applyVerticalScale(m_scale / 255);
107
    float scaleAdjustmentX = (0.5f - 0.5f * m_scale) * filter->filterResolution().width();
107
    float scaleAdjustmentX = filter->applyHorizontalScale(0.5f - 0.5f * m_scale);
108
    float scaleAdjustmentY = (0.5f - 0.5f * m_scale) * filter->filterResolution().height();
108
    float scaleAdjustmentY = filter->applyVerticalScale(0.5f - 0.5f * m_scale);
109
    int stride = imageRect.width() * 4;
109
    int stride = imageRect.width() * 4;
110
    for (int y = 0; y < imageRect.height(); ++y) {
110
    for (int y = 0; y < imageRect.height(); ++y) {
111
        int line = y * stride;
111
        int line = y * stride;
- WebCore/platform/graphics/filters/FEDisplacementMap.h +2 lines
Lines 53-58 public: WebCore/platform/graphics/filters/FEDisplacementMap.h_sec1
53
    virtual void apply(Filter*);
53
    virtual void apply(Filter*);
54
    virtual void dump();
54
    virtual void dump();
55
55
56
    virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); }
57
56
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
58
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
57
59
58
private:
60
private:
- WebCore/platform/graphics/filters/FEFlood.cpp -3 / +3 lines
Lines 62-75 void FEFlood::setFloodOpacity(float floo WebCore/platform/graphics/filters/FEFlood.cpp_sec1
62
    m_floodOpacity = floodOpacity;
62
    m_floodOpacity = floodOpacity;
63
}
63
}
64
64
65
void FEFlood::apply(Filter*)
65
void FEFlood::apply(Filter* filter)
66
{
66
{
67
    GraphicsContext* filterContext = effectContext();
67
    GraphicsContext* filterContext = effectContext(filter);
68
    if (!filterContext)
68
    if (!filterContext)
69
        return;
69
        return;
70
70
71
    Color color = colorWithOverrideAlpha(floodColor().rgb(), floodOpacity());
71
    Color color = colorWithOverrideAlpha(floodColor().rgb(), floodOpacity());
72
    filterContext->fillRect(FloatRect(FloatPoint(), repaintRectInLocalCoordinates().size()), color, DeviceColorSpace);
72
    filterContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()), color, DeviceColorSpace);
73
}
73
}
74
74
75
void FEFlood::dump()
75
void FEFlood::dump()
- WebCore/platform/graphics/filters/FEFlood.h +2 lines
Lines 42-47 public: WebCore/platform/graphics/filters/FEFlood.h_sec1
42
    virtual void apply(Filter*);
42
    virtual void apply(Filter*);
43
    virtual void dump();
43
    virtual void dump();
44
44
45
    virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); }
46
45
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
47
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
46
48
47
private:
49
private:
- WebCore/platform/graphics/filters/FEGaussianBlur.cpp -7 / +38 lines
Lines 125-130 void FEGaussianBlur::kernelPosition(int WebCore/platform/graphics/filters/FEGaussianBlur.cpp_sec1
125
    }
125
    }
126
}
126
}
127
127
128
inline void calculateKernelSize(unsigned& kernelSizeX, unsigned& kernelSizeY, float stdX, float stdY, Filter* filter)
129
{
130
    stdX = filter->applyHorizontalScale(stdX);
131
    stdY = filter->applyVerticalScale(stdY);
132
    
133
    kernelSizeX = 0;
134
    if (stdX)
135
        kernelSizeX = max<unsigned>(2, static_cast<unsigned>(floorf(stdX * gGaussianKernelFactor + 0.5f)));
136
    kernelSizeY = 0;
137
    if (stdY)
138
        kernelSizeY = max<unsigned>(2, static_cast<unsigned>(floorf(stdY * gGaussianKernelFactor + 0.5f)));
139
    
140
    // Limit the kernel size to 1000. A bigger radius won't make a big difference for the result image but
141
    // inflates the absolute paint rect to much.
142
    if (kernelSizeX > 1000)
143
        kernelSizeX = 1000;
144
    if (kernelSizeY > 1000)
145
        kernelSizeY = 1000;
146
}
147
148
void FEGaussianBlur::determineAbsolutePaintRect(Filter* filter)
149
{
150
    IntRect absolutePaintRect = inputEffect(0)->absolutePaintRect();
151
    absolutePaintRect.intersect(maxEffectRect());
152
153
    unsigned kernelSizeX = 0;
154
    unsigned kernelSizeY = 0;
155
    calculateKernelSize(kernelSizeX, kernelSizeY, m_stdX, m_stdY, filter);
156
157
    // We take the half kernel size and multiply it with three, because we run box blur three times.
158
    absolutePaintRect.inflateX(3 * (kernelSizeX * 0.5f));
159
    absolutePaintRect.inflateY(3 * (kernelSizeY * 0.5f));
160
    setAbsolutePaintRect(absolutePaintRect);
161
}
162
128
void FEGaussianBlur::apply(Filter* filter)
163
void FEGaussianBlur::apply(Filter* filter)
129
{
164
{
130
    FilterEffect* in = inputEffect(0);
165
    FilterEffect* in = inputEffect(0);
Lines 132-143 void FEGaussianBlur::apply(Filter* filte WebCore/platform/graphics/filters/FEGaussianBlur.cpp_sec2
132
    if (!in->resultImage())
167
    if (!in->resultImage())
133
        return;
168
        return;
134
169
135
    if (!effectContext())
170
    if (!effectContext(filter))
136
        return;
171
        return;
137
172
138
    setIsAlphaImage(in->isAlphaImage());
173
    setIsAlphaImage(in->isAlphaImage());
139
174
140
    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
175
    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
141
    RefPtr<ImageData> srcImageData(in->resultImage()->getPremultipliedImageData(effectDrawingRect));
176
    RefPtr<ImageData> srcImageData(in->resultImage()->getPremultipliedImageData(effectDrawingRect));
142
    IntRect imageRect(IntPoint(), resultImage()->size());
177
    IntRect imageRect(IntPoint(), resultImage()->size());
143
178
Lines 147-158 void FEGaussianBlur::apply(Filter* filte WebCore/platform/graphics/filters/FEGaussianBlur.cpp_sec3
147
    }
182
    }
148
183
149
    unsigned kernelSizeX = 0;
184
    unsigned kernelSizeX = 0;
150
    if (m_stdX)
151
        kernelSizeX = max(2U, static_cast<unsigned>(floor(m_stdX * filter->filterResolution().width() * gGaussianKernelFactor + 0.5f)));
152
153
    unsigned kernelSizeY = 0;
185
    unsigned kernelSizeY = 0;
154
    if (m_stdY)
186
    calculateKernelSize(kernelSizeX, kernelSizeY, m_stdX, m_stdY, filter);
155
        kernelSizeY = max(2U, static_cast<unsigned>(floor(m_stdY * filter->filterResolution().height() * gGaussianKernelFactor + 0.5f)));
156
187
157
    CanvasPixelArray* srcPixelArray(srcImageData->data());
188
    CanvasPixelArray* srcPixelArray(srcImageData->data());
158
    RefPtr<ImageData> tmpImageData = ImageData::create(imageRect.width(), imageRect.height());
189
    RefPtr<ImageData> tmpImageData = ImageData::create(imageRect.width(), imageRect.height());
- WebCore/platform/graphics/filters/FEGaussianBlur.h +2 lines
Lines 42-47 public: WebCore/platform/graphics/filters/FEGaussianBlur.h_sec1
42
42
43
    virtual void apply(Filter*);
43
    virtual void apply(Filter*);
44
    virtual void dump();
44
    virtual void dump();
45
    
46
    virtual void determineAbsolutePaintRect(Filter*);
45
47
46
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
48
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
47
49
- WebCore/platform/graphics/filters/FELighting.cpp -2 / +2 lines
Lines 247-258 void FELighting::apply(Filter* filter) WebCore/platform/graphics/filters/FELighting.cpp_sec1
247
    if (!in->resultImage())
247
    if (!in->resultImage())
248
        return;
248
        return;
249
249
250
    if (!effectContext())
250
    if (!effectContext(filter))
251
        return;
251
        return;
252
252
253
    setIsAlphaImage(false);
253
    setIsAlphaImage(false);
254
254
255
    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
255
    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
256
    RefPtr<ImageData> srcImageData(in->resultImage()->getUnmultipliedImageData(effectDrawingRect));
256
    RefPtr<ImageData> srcImageData(in->resultImage()->getUnmultipliedImageData(effectDrawingRect));
257
    CanvasPixelArray* srcPixelArray(srcImageData->data());
257
    CanvasPixelArray* srcPixelArray(srcImageData->data());
258
258
- WebCore/platform/graphics/filters/FEMerge.cpp -2 / +2 lines
Lines 50-62 void FEMerge::apply(Filter* filter) WebCore/platform/graphics/filters/FEMerge.cpp_sec1
50
            return;
50
            return;
51
    }
51
    }
52
52
53
    GraphicsContext* filterContext = effectContext();
53
    GraphicsContext* filterContext = effectContext(filter);
54
    if (!filterContext)
54
    if (!filterContext)
55
        return;
55
        return;
56
56
57
    for (unsigned i = 0; i < size; ++i) {
57
    for (unsigned i = 0; i < size; ++i) {
58
        FilterEffect* in = inputEffect(i);
58
        FilterEffect* in = inputEffect(i);
59
        filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->repaintRectInLocalCoordinates()));
59
        filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect()));
60
    }
60
    }
61
}
61
}
62
62
- WebCore/platform/graphics/filters/FEMorphology.cpp -6 / +14 lines
Lines 74-79 float FEMorphology::radiusY() const WebCore/platform/graphics/filters/FEMorphology.cpp_sec1
74
    return m_radiusY;
74
    return m_radiusY;
75
}
75
}
76
76
77
void FEMorphology::determineAbsolutePaintRect(Filter* filter)
78
{
79
    IntRect paintRect = inputEffect(0)->absolutePaintRect();
80
    paintRect.inflateX(floorf(filter->applyHorizontalScale(m_radiusX)));
81
    paintRect.inflateY(floorf(filter->applyVerticalScale(m_radiusY)));
82
    setAbsolutePaintRect(paintRect);
83
}
84
77
void FEMorphology::setRadiusY(float radiusY)
85
void FEMorphology::setRadiusY(float radiusY)
78
{
86
{
79
    m_radiusY = radiusY;
87
    m_radiusY = radiusY;
Lines 86-103 void FEMorphology::apply(Filter* filter) WebCore/platform/graphics/filters/FEMorphology.cpp_sec2
86
    if (!in->resultImage())
94
    if (!in->resultImage())
87
        return;
95
        return;
88
96
89
    if (!effectContext())
97
    if (!effectContext(filter))
90
        return;
98
        return;
91
99
92
    setIsAlphaImage(in->isAlphaImage());
100
    setIsAlphaImage(in->isAlphaImage());
93
101
    if (m_radiusX <= 0 || m_radiusY <= 0)
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)
97
        return;
102
        return;
98
103
104
    int radiusX = floorf(filter->applyHorizontalScale(m_radiusX));
105
    int radiusY = floorf(filter->applyVerticalScale(m_radiusY));
106
99
    IntRect imageRect(IntPoint(), resultImage()->size());
107
    IntRect imageRect(IntPoint(), resultImage()->size());
100
    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->repaintRectInLocalCoordinates());
108
    IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect());
101
    RefPtr<CanvasPixelArray> srcPixelArray(in->resultImage()->getPremultipliedImageData(effectDrawingRect)->data());
109
    RefPtr<CanvasPixelArray> srcPixelArray(in->resultImage()->getPremultipliedImageData(effectDrawingRect)->data());
102
    RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());
110
    RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());
103
111
- WebCore/platform/graphics/filters/FEMorphology.h +2 lines
Lines 49-54 public: WebCore/platform/graphics/filters/FEMorphology.h_sec1
49
    virtual void apply(Filter*);
49
    virtual void apply(Filter*);
50
    virtual void dump();
50
    virtual void dump();
51
51
52
    virtual void determineAbsolutePaintRect(Filter*);
53
52
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
54
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
53
55
54
private:
56
private:
- WebCore/platform/graphics/filters/FEOffset.cpp -17 / +12 lines
Lines 62-67 void FEOffset::setDy(float dy) WebCore/platform/graphics/filters/FEOffset.cpp_sec1
62
    m_dy = dy;
62
    m_dy = dy;
63
}
63
}
64
64
65
void FEOffset::determineAbsolutePaintRect(Filter* filter)
66
{
67
    FloatRect paintRect = inputEffect(0)->absolutePaintRect();
68
    paintRect.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy));
69
    paintRect.intersect(maxEffectRect());
70
    setAbsolutePaintRect(enclosingIntRect(paintRect));
71
}
72
65
void FEOffset::apply(Filter* filter)
73
void FEOffset::apply(Filter* filter)
66
{
74
{
67
    FilterEffect* in = inputEffect(0);
75
    FilterEffect* in = inputEffect(0);
Lines 69-96 void FEOffset::apply(Filter* filter) WebCore/platform/graphics/filters/FEOffset.cpp_sec2
69
    if (!in->resultImage())
77
    if (!in->resultImage())
70
        return;
78
        return;
71
79
72
    GraphicsContext* filterContext = effectContext();
80
    GraphicsContext* filterContext = effectContext(filter);
73
    if (!filterContext)
81
    if (!filterContext)
74
        return;
82
        return;
75
83
76
    setIsAlphaImage(in->isAlphaImage());
84
    setIsAlphaImage(in->isAlphaImage());
77
85
78
    FloatRect sourceImageRect = filter->sourceImageRect();
86
    FloatRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect());
79
    sourceImageRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
87
    drawingRegion.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy));
80
88
    filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegion);
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);
94
}
89
}
95
90
96
void FEOffset::dump()
91
void FEOffset::dump()
- WebCore/platform/graphics/filters/FEOffset.h +2 lines
Lines 40-45 public: WebCore/platform/graphics/filters/FEOffset.h_sec1
40
40
41
    virtual void apply(Filter*);
41
    virtual void apply(Filter*);
42
    virtual void dump();
42
    virtual void dump();
43
    
44
    virtual void determineAbsolutePaintRect(Filter*);
43
45
44
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
46
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
45
47
- WebCore/platform/graphics/filters/FETile.cpp -15 / +17 lines
Lines 27-32 WebCore/platform/graphics/filters/FETile.cpp_sec1
27
#include "Filter.h"
27
#include "Filter.h"
28
#include "GraphicsContext.h"
28
#include "GraphicsContext.h"
29
#include "Pattern.h"
29
#include "Pattern.h"
30
#include "SVGImageBufferTools.h"
30
31
31
namespace WebCore {
32
namespace WebCore {
32
33
Lines 44-50 FloatRect FETile::determineFilterPrimiti WebCore/platform/graphics/filters/FETile.cpp_sec2
44
{
45
{
45
    inputEffect(0)->determineFilterPrimitiveSubregion(filter);
46
    inputEffect(0)->determineFilterPrimitiveSubregion(filter);
46
47
47
    filter->determineFilterPrimitiveSubregion(this, filter->filterRegion());
48
    filter->determineFilterPrimitiveSubregion(this, filter->filterRegionInUserSpace());
48
    return filterPrimitiveSubregion();
49
    return filterPrimitiveSubregion();
49
}
50
}
50
51
Lines 55-88 void FETile::apply(Filter* filter) WebCore/platform/graphics/filters/FETile.cpp_sec3
55
    if (!in->resultImage())
56
    if (!in->resultImage())
56
        return;
57
        return;
57
58
58
    GraphicsContext* filterContext = effectContext();
59
    GraphicsContext* filterContext = effectContext(filter);
59
    if (!filterContext)
60
    if (!filterContext)
60
        return;
61
        return;
61
62
62
    setIsAlphaImage(in->isAlphaImage());
63
    setIsAlphaImage(in->isAlphaImage());
63
64
64
    IntRect tileRect = enclosingIntRect(in->repaintRectInLocalCoordinates());
65
66
    // Source input needs more attention. It has the size of the filterRegion but gives the
65
    // Source input needs more attention. It has the size of the filterRegion but gives the
67
    // size of the cutted sourceImage back. This is part of the specification and optimization.
66
    // size of the cutted sourceImage back. This is part of the specification and optimization.
67
    FloatRect tileRect = in->maxEffectRect();
68
    if (in->isSourceInput()) {
68
    if (in->isSourceInput()) {
69
        FloatRect filterRegion = filter->filterRegion();
69
        tileRect = filter->filterRegion();
70
        filterRegion.scale(filter->filterResolution().width(), filter->filterResolution().height());
70
        tileRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
71
        tileRect = enclosingIntRect(filterRegion);
72
    }
71
    }
73
72
74
    OwnPtr<ImageBuffer> tileImage = ImageBuffer::create(tileRect.size());
73
    OwnPtr<ImageBuffer> tileImage;
74
    if (!SVGImageBufferTools::createImageBuffer(tileRect, tileRect, tileImage, DeviceRGB))
75
        return;
76
75
    GraphicsContext* tileImageContext = tileImage->context();
77
    GraphicsContext* tileImageContext = tileImage->context();
76
    tileImageContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, IntPoint());
78
    tileImageContext->translate(-in->maxEffectRect().x(), -in->maxEffectRect().y());
77
    RefPtr<Pattern> pattern = Pattern::create(tileImage->copyImage(), true, true);
79
    tileImageContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, in->absolutePaintRect().location());
78
80
79
    AffineTransform matrix;
81
    RefPtr<Pattern> pattern = Pattern::create(tileImage->copyImage(), true, true);
80
    matrix.translate(in->repaintRectInLocalCoordinates().x() - repaintRectInLocalCoordinates().x(),
81
                     in->repaintRectInLocalCoordinates().y() - repaintRectInLocalCoordinates().y());
82
    pattern.get()->setPatternSpaceTransform(matrix);
83
82
83
    AffineTransform patternTransform;
84
    patternTransform.translate(in->maxEffectRect().x() - maxEffectRect().x(), in->maxEffectRect().y() - maxEffectRect().y());
85
    pattern->setPatternSpaceTransform(patternTransform);
84
    filterContext->setFillPattern(pattern);
86
    filterContext->setFillPattern(pattern);
85
    filterContext->fillRect(FloatRect(FloatPoint(), repaintRectInLocalCoordinates().size()));
87
    filterContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size()));
86
}
88
}
87
89
88
void FETile::dump()
90
void FETile::dump()
- WebCore/platform/graphics/filters/FETile.h +2 lines
Lines 35-40 public: WebCore/platform/graphics/filters/FETile.h_sec1
35
    virtual void apply(Filter*);
35
    virtual void apply(Filter*);
36
    virtual void dump();
36
    virtual void dump();
37
37
38
    virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); }
39
38
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
40
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
39
41
40
    virtual FloatRect determineFilterPrimitiveSubregion(Filter*);
42
    virtual FloatRect determineFilterPrimitiveSubregion(Filter*);
- WebCore/platform/graphics/filters/FETurbulence.cpp -4 / +4 lines
Lines 321-327 unsigned char FETurbulence::calculateTur WebCore/platform/graphics/filters/FETurbulence.cpp_sec1
321
321
322
void FETurbulence::apply(Filter* filter)
322
void FETurbulence::apply(Filter* filter)
323
{
323
{
324
    if (!effectContext())
324
    if (!effectContext(filter))
325
        return;
325
        return;
326
326
327
    IntRect imageRect(IntPoint(), resultImage()->size());
327
    IntRect imageRect(IntPoint(), resultImage()->size());
Lines 329-338 void FETurbulence::apply(Filter* filter) WebCore/platform/graphics/filters/FETurbulence.cpp_sec2
329
        return;
329
        return;
330
330
331
    RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());
331
    RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());
332
    PaintingData paintingData(m_seed, imageRect.size());
332
    PaintingData paintingData(m_seed, roundedIntSize(filterPrimitiveSubregion().size()));
333
    initPaint(paintingData);
333
    initPaint(paintingData);
334
334
335
    FloatRect filterRegion = filter->filterRegion();
335
    FloatRect filterRegion = absolutePaintRect();
336
    FloatPoint point;
336
    FloatPoint point;
337
    point.setY(filterRegion.y());
337
    point.setY(filterRegion.y());
338
    int indexOfPixelChannel = 0;
338
    int indexOfPixelChannel = 0;
Lines 342-348 void FETurbulence::apply(Filter* filter) WebCore/platform/graphics/filters/FETurbulence.cpp_sec3
342
        for (int x = 0; x < imageRect.width(); ++x) {
342
        for (int x = 0; x < imageRect.width(); ++x) {
343
            point.setX(point.x() + 1);
343
            point.setX(point.x() + 1);
344
            for (paintingData.channel = 0; paintingData.channel < 4; ++paintingData.channel, ++indexOfPixelChannel)
344
            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)));
346
        }
346
        }
347
    }
347
    }
348
    resultImage()->putUnmultipliedImageData(imageData.get(), imageRect, IntPoint());
348
    resultImage()->putUnmultipliedImageData(imageData.get(), imageRect, IntPoint());
- WebCore/platform/graphics/filters/FETurbulence.h +2 lines
Lines 60-65 public: WebCore/platform/graphics/filters/FETurbulence.h_sec1
60
60
61
    virtual void apply(Filter*);
61
    virtual void apply(Filter*);
62
    virtual void dump();
62
    virtual void dump();
63
    
64
    virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); }
63
65
64
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
66
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
65
67
- WebCore/platform/graphics/filters/Filter.h +7 lines
Lines 44-54 namespace WebCore { WebCore/platform/graphics/filters/Filter.h_sec1
44
        FloatSize filterResolution() const { return m_filterResolution; }
44
        FloatSize filterResolution() const { return m_filterResolution; }
45
        void setFilterResolution(const FloatSize& filterResolution) { m_filterResolution = filterResolution; }
45
        void setFilterResolution(const FloatSize& filterResolution) { m_filterResolution = filterResolution; }
46
46
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
        
47
        virtual FloatRect sourceImageRect() const = 0;
50
        virtual FloatRect sourceImageRect() const = 0;
48
        virtual FloatRect filterRegion() const = 0;
51
        virtual FloatRect filterRegion() const = 0;
52
        
53
        virtual FloatPoint mapAbsolutePointToLocalPoint(const FloatPoint&) const { return FloatPoint(); }
49
54
50
        // SVG specific
55
        // SVG specific
51
        virtual void determineFilterPrimitiveSubregion(FilterEffect*, const FloatRect&) { }
56
        virtual void determineFilterPrimitiveSubregion(FilterEffect*, const FloatRect&) { }
57
        
58
        virtual FloatRect filterRegionInUserSpace() const { return FloatRect(); }
52
59
53
        virtual FloatSize maxImageSize() const = 0;
60
        virtual FloatSize maxImageSize() const = 0;
54
        virtual bool effectBoundingBoxMode() const = 0;
61
        virtual bool effectBoundingBoxMode() const = 0;
- WebCore/platform/graphics/filters/FilterEffect.cpp -10 / +23 lines
Lines 46-52 FloatRect FilterEffect::determineFilterP WebCore/platform/graphics/filters/FilterEffect.cpp_sec1
46
46
47
    // FETurbulence, FEImage and FEFlood don't have input effects, take the filter region as unite rect.
47
    // FETurbulence, FEImage and FEFlood don't have input effects, take the filter region as unite rect.
48
    if (!size)
48
    if (!size)
49
        uniteRect = filter->filterRegion();
49
        uniteRect = filter->filterRegionInUserSpace();
50
    else {
50
    else {
51
        for (unsigned i = 0; i < size; ++i)
51
        for (unsigned i = 0; i < size; ++i)
52
            uniteRect.unite(m_inputEffects.at(i)->determineFilterPrimitiveSubregion(filter));
52
            uniteRect.unite(m_inputEffects.at(i)->determineFilterPrimitiveSubregion(filter));
Lines 56-73 FloatRect FilterEffect::determineFilterP WebCore/platform/graphics/filters/FilterEffect.cpp_sec2
56
    return m_filterPrimitiveSubregion;
56
    return m_filterPrimitiveSubregion;
57
}
57
}
58
58
59
IntRect FilterEffect::requestedRegionOfInputImageData(const FloatRect& effectRect) const
59
void 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
70
IntRect FilterEffect::requestedRegionOfInputImageData(const IntRect& effectRect) const
60
{
71
{
61
    ASSERT(m_effectBuffer);
72
    ASSERT(m_effectBuffer);
62
    FloatPoint location = m_repaintRectInLocalCoordinates.location();
73
    IntPoint location = m_absolutePaintRect.location();
63
    location.move(-effectRect.x(), -effectRect.y());
74
    location.move(-effectRect.x(), -effectRect.y());
64
    return IntRect(roundedIntPoint(location), m_effectBuffer->size());
75
    return IntRect(location, m_effectBuffer->size());
65
}
76
}
66
77
67
FloatRect FilterEffect::drawingRegionOfInputImage(const FloatRect& srcRect) const
78
IntRect FilterEffect::drawingRegionOfInputImage(const IntRect& srcRect) const
68
{
79
{
69
    return FloatRect(FloatPoint(srcRect.x() - m_repaintRectInLocalCoordinates.x(),
80
    return IntRect(IntPoint(srcRect.x() - m_absolutePaintRect.x(),
70
                                srcRect.y() - m_repaintRectInLocalCoordinates.y()), srcRect.size());
81
                            srcRect.y() - m_absolutePaintRect.y()), srcRect.size());
71
}
82
}
72
83
73
FilterEffect* FilterEffect::inputEffect(unsigned number) const
84
FilterEffect* FilterEffect::inputEffect(unsigned number) const
Lines 76-85 FilterEffect* FilterEffect::inputEffect( WebCore/platform/graphics/filters/FilterEffect.cpp_sec3
76
    return m_inputEffects.at(number).get();
87
    return m_inputEffects.at(number).get();
77
}
88
}
78
89
79
GraphicsContext* FilterEffect::effectContext()
90
GraphicsContext* FilterEffect::effectContext(Filter* filter)
80
{
91
{
81
    IntRect bufferRect = enclosingIntRect(m_repaintRectInLocalCoordinates);
92
    determineAbsolutePaintRect(filter);
82
    m_effectBuffer = ImageBuffer::create(bufferRect.size(), LinearRGB);
93
    if (m_absolutePaintRect.isEmpty())
94
        return 0;
95
    m_effectBuffer = ImageBuffer::create(m_absolutePaintRect.size(), LinearRGB);
83
    if (!m_effectBuffer)
96
    if (!m_effectBuffer)
84
        return 0;
97
        return 0;
85
    return m_effectBuffer->context();
98
    return m_effectBuffer->context();
- WebCore/platform/graphics/filters/FilterEffect.h -8 / +16 lines
Lines 49-73 public: WebCore/platform/graphics/filters/FilterEffect.h_sec1
49
49
50
    // Creates the ImageBuffer for the current filter primitive result in the size of the
50
    // Creates the ImageBuffer for the current filter primitive result in the size of the
51
    // repaintRect. Gives back the GraphicsContext of the own ImageBuffer.
51
    // repaintRect. Gives back the GraphicsContext of the own ImageBuffer.
52
    GraphicsContext* effectContext();
52
    GraphicsContext* effectContext(Filter*);
53
53
54
    FilterEffectVector& inputEffects() { return m_inputEffects; }
54
    FilterEffectVector& inputEffects() { return m_inputEffects; }
55
    FilterEffect* inputEffect(unsigned) const;
55
    FilterEffect* inputEffect(unsigned) const;
56
    unsigned numberOfEffectInputs() const { return m_inputEffects.size(); }
56
    unsigned numberOfEffectInputs() const { return m_inputEffects.size(); }
57
57
58
    FloatRect drawingRegionOfInputImage(const FloatRect&) const;
58
    IntRect drawingRegionOfInputImage(const IntRect&) const;
59
    IntRect requestedRegionOfInputImageData(const FloatRect&) const;
59
    IntRect requestedRegionOfInputImageData(const IntRect&) const;
60
60
61
    // Solid black image with different alpha values.
61
    // Solid black image with different alpha values.
62
    bool isAlphaImage() const { return m_alphaImage; }
62
    bool isAlphaImage() const { return m_alphaImage; }
63
    void setIsAlphaImage(bool alphaImage) { m_alphaImage = alphaImage; }
63
    void setIsAlphaImage(bool alphaImage) { m_alphaImage = alphaImage; }
64
64
65
    FloatRect repaintRectInLocalCoordinates() const { return m_repaintRectInLocalCoordinates; }
65
    IntRect absolutePaintRect() const { return m_absolutePaintRect; }
66
    void setRepaintRectInLocalCoordinates(const FloatRect& repaintRectInLocalCoordinates) { m_repaintRectInLocalCoordinates = repaintRectInLocalCoordinates; }
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; } 
67
70
68
    virtual void apply(Filter*) = 0;
71
    virtual void apply(Filter*) = 0;
69
    virtual void dump() = 0;
72
    virtual void dump() = 0;
70
73
74
    virtual void determineAbsolutePaintRect(Filter*);
75
    
71
    virtual bool isSourceInput() const { return false; }
76
    virtual bool isSourceInput() const { return false; }
72
77
73
    virtual TextStream& externalRepresentation(TextStream&, int indention = 0) const;
78
    virtual TextStream& externalRepresentation(TextStream&, int indention = 0) const;
Lines 87-93 public: WebCore/platform/graphics/filters/FilterEffect.h_sec2
87
    bool hasHeight() const { return m_hasHeight; }
92
    bool hasHeight() const { return m_hasHeight; }
88
    void setHasHeight(bool value) { m_hasHeight = value; }
93
    void setHasHeight(bool value) { m_hasHeight = value; }
89
94
90
    // FIXME: Pseudo primitives like SourceGraphic and SourceAlpha as well as FETile still need special handling.
95
    // FIXME: FETile still needs special handling.
91
    virtual FloatRect determineFilterPrimitiveSubregion(Filter*);
96
    virtual FloatRect determineFilterPrimitiveSubregion(Filter*);
92
97
93
    FloatRect filterPrimitiveSubregion() const { return m_filterPrimitiveSubregion; }
98
    FloatRect filterPrimitiveSubregion() const { return m_filterPrimitiveSubregion; }
Lines 105-112 private: WebCore/platform/graphics/filters/FilterEffect.h_sec3
105
110
106
    bool m_alphaImage;
111
    bool m_alphaImage;
107
112
108
    // FIXME: Should be the paint region of the filter primitive, instead of the scaled subregion on use of filterRes.
113
    IntRect m_absolutePaintRect;
109
    FloatRect m_repaintRectInLocalCoordinates;
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;
110
118
111
private:
119
private:
112
    // The following member variables are SVG specific and will move to RenderSVGResourceFilterPrimitive.
120
    // The following member variables are SVG specific and will move to RenderSVGResourceFilterPrimitive.
- WebCore/platform/graphics/filters/SourceAlpha.cpp -9 / +3 lines
Lines 42-63 const AtomicString& SourceAlpha::effectN WebCore/platform/graphics/filters/SourceAlpha.cpp_sec1
42
    return s_effectName;
42
    return s_effectName;
43
}
43
}
44
44
45
FloatRect SourceAlpha::determineFilterPrimitiveSubregion(Filter* filter)
45
void SourceAlpha::determineAbsolutePaintRect(Filter* filter)
46
{
46
{
47
    FloatRect clippedSourceRect = filter->sourceImageRect();
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());
48
    clippedSourceRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
54
    setRepaintRectInLocalCoordinates(clippedSourceRect);
49
    setAbsolutePaintRect(enclosingIntRect(clippedSourceRect));
55
    return filter->filterRegion();
56
}
50
}
57
51
58
void SourceAlpha::apply(Filter* filter)
52
void SourceAlpha::apply(Filter* filter)
59
{
53
{
60
    GraphicsContext* filterContext = effectContext();
54
    GraphicsContext* filterContext = effectContext(filter);
61
    if (!filterContext)
55
    if (!filterContext)
62
        return;
56
        return;
63
57
- WebCore/platform/graphics/filters/SourceAlpha.h -2 / +2 lines
Lines 34-44 public: WebCore/platform/graphics/filters/SourceAlpha.h_sec1
34
34
35
    static const AtomicString& effectName();
35
    static const AtomicString& effectName();
36
36
37
    virtual FloatRect determineFilterPrimitiveSubregion(Filter*);
38
39
    virtual void apply(Filter*);
37
    virtual void apply(Filter*);
40
    virtual void dump();
38
    virtual void dump();
41
39
40
    virtual void determineAbsolutePaintRect(Filter*);
41
42
    virtual bool isSourceInput() const { return true; }
42
    virtual bool isSourceInput() const { return true; }
43
43
44
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
44
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
- WebCore/platform/graphics/filters/SourceGraphic.cpp -9 / +3 lines
Lines 41-62 const AtomicString& SourceGraphic::effec WebCore/platform/graphics/filters/SourceGraphic.cpp_sec1
41
    return s_effectName;
41
    return s_effectName;
42
}
42
}
43
43
44
FloatRect SourceGraphic::determineFilterPrimitiveSubregion(Filter* filter)
44
void SourceGraphic::determineAbsolutePaintRect(Filter* filter)
45
{
45
{
46
    FloatRect clippedSourceRect = filter->sourceImageRect();
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());
47
    clippedSourceRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
53
    setRepaintRectInLocalCoordinates(clippedSourceRect);
48
    setAbsolutePaintRect(enclosingIntRect(clippedSourceRect));
54
    return filter->filterRegion();
55
}
49
}
56
50
57
void SourceGraphic::apply(Filter* filter)
51
void SourceGraphic::apply(Filter* filter)
58
{
52
{
59
    GraphicsContext* filterContext = effectContext();
53
    GraphicsContext* filterContext = effectContext(filter);
60
    if (!filterContext)
54
    if (!filterContext)
61
        return;
55
        return;
62
56
- WebCore/platform/graphics/filters/SourceGraphic.h -2 / +2 lines
Lines 35-45 public: WebCore/platform/graphics/filters/SourceGraphic.h_sec1
35
35
36
    static const AtomicString& effectName();
36
    static const AtomicString& effectName();
37
37
38
    virtual FloatRect determineFilterPrimitiveSubregion(Filter*);
39
40
    virtual void apply(Filter*);
38
    virtual void apply(Filter*);
41
    virtual void dump();
39
    virtual void dump();
42
40
41
    virtual void determineAbsolutePaintRect(Filter*);
42
43
    virtual bool isSourceInput() const { return true; }
43
    virtual bool isSourceInput() const { return true; }
44
44
45
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
45
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
- WebCore/rendering/RenderSVGResourceFilter.cpp -38 / +69 lines
Lines 39-44 WebCore/rendering/RenderSVGResourceFilter.cpp_sec1
39
#include "SVGFilter.h"
39
#include "SVGFilter.h"
40
#include "SVGFilterElement.h"
40
#include "SVGFilterElement.h"
41
#include "SVGFilterPrimitiveStandardAttributes.h"
41
#include "SVGFilterPrimitiveStandardAttributes.h"
42
#include "SVGImageBufferTools.h"
42
#include "SVGStyledElement.h"
43
#include "SVGStyledElement.h"
43
#include "SVGUnitTypes.h"
44
#include "SVGUnitTypes.h"
44
#include <wtf/Vector.h>
45
#include <wtf/Vector.h>
Lines 150-219 bool RenderSVGResourceFilter::applyResou WebCore/rendering/RenderSVGResourceFilter.cpp_sec2
150
    }
151
    }
151
152
152
    OwnPtr<FilterData> filterData(new FilterData);
153
    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 increase the quality of results in 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.
153
    filterData->builder = buildPrimitives();
181
    filterData->builder = buildPrimitives();
154
    if (!filterData->builder)
182
    if (!filterData->builder)
155
        return false;
183
        return false;
156
184
157
    FloatRect paintRect = object->strokeBoundingBox();
158
159
    // Calculate the scale factor for the use of filterRes.
185
    // Calculate the scale factor for the use of filterRes.
160
    // Also see http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion
186
    // Also see http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion
161
    SVGFilterElement* filterElement = static_cast<SVGFilterElement*>(node());
187
    FloatSize scale(1, 1);
162
    filterData->boundaries = filterElement->filterBoundingBox(object->objectBoundingBox());
163
    if (filterData->boundaries.isEmpty())
164
        return false;
165
166
    FloatSize scale(1.0f, 1.0f);
167
    if (filterElement->hasAttribute(SVGNames::filterResAttr)) {
188
    if (filterElement->hasAttribute(SVGNames::filterResAttr)) {
168
        scale.setWidth(filterElement->filterResX() / filterData->boundaries.width());
189
        scale.setWidth(filterElement->filterResX() / absoluteFilterBoundaries.width());
169
        scale.setHeight(filterElement->filterResY() / filterData->boundaries.height());
190
        scale.setHeight(filterElement->filterResY() / absoluteFilterBoundaries.height());
170
    }
191
    }
171
192
172
    if (scale.isEmpty())
193
    if (scale.isEmpty())
173
        return false;
194
        return false;
174
195
175
    // clip sourceImage to filterRegion
196
    // Determine scale factor for filter. The size of intermediate ImageBuffers shouldn't be bigger than kMaxFilterSize.
176
    FloatRect clippedSourceRect = paintRect;
197
    FloatRect tempSourceRect = absoluteDrawingRegion;
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
183
    tempSourceRect.scale(scale.width(), scale.height());
198
    tempSourceRect.scale(scale.width(), scale.height());
184
    fitsInMaximumImageSize(tempSourceRect.size(), scale);
199
    fitsInMaximumImageSize(tempSourceRect.size(), scale);
185
200
186
    // prepare Filters
201
    // Set the scale level in SVGFilter.
187
    bool primitiveBoundingBoxMode = filterElement->primitiveUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
188
    filterData->filter = SVGFilter::create(paintRect, filterData->boundaries, primitiveBoundingBoxMode);
189
    filterData->filter->setFilterResolution(scale);
202
    filterData->filter->setFilterResolution(scale);
190
203
191
    FilterEffect* lastEffect = filterData->builder->lastEffect();
204
    FilterEffect* lastEffect = filterData->builder->lastEffect();
192
    if (!lastEffect)
205
    if (!lastEffect)
193
        return false;
206
        return false;
194
    
207
208
    // Determine the filter primitive subregions of every effect.
195
    lastEffect->determineFilterPrimitiveSubregion(filterData->filter.get());
209
    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.
198
    if (!fitsInMaximumImageSize(filterData->filter->maxImageSize(), scale)) {
210
    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.
199
        filterData->filter->setFilterResolution(scale);
213
        filterData->filter->setFilterResolution(scale);
200
        lastEffect->determineFilterPrimitiveSubregion(filterData->filter.get());
214
        lastEffect->determineFilterPrimitiveSubregion(filterData->filter.get());
201
    }
215
    }
202
216
203
    clippedSourceRect.scale(scale.width(), scale.height());
217
    // If the drawingRegion is empty, we have something like <g filter=".."/>.
204
218
    // Even if the target objectBoundingBox() is empty, we still have to draw something.
205
    // Draw the content of the current element and it's childs to a imageBuffer to get the SourceGraphic.
219
    if (drawingRegion.isEmpty()) {
206
    // The size of the SourceGraphic is clipped to the size of the filterRegion.
220
        ASSERT(!m_filter.contains(object));
207
    IntRect bufferRect = enclosingIntRect(clippedSourceRect);
221
        filterData->savedContext = context;
208
    OwnPtr<ImageBuffer> sourceGraphic(ImageBuffer::create(bufferRect.size(), LinearRGB));
222
        m_filter.set(object, filterData.leakPtr());
209
    
210
    if (!sourceGraphic.get())
211
        return false;
223
        return false;
224
    }
212
225
226
    absoluteDrawingRegion.scale(scale.width(), scale.height());
227
228
    OwnPtr<ImageBuffer> sourceGraphic;
229
    if (!SVGImageBufferTools::createImageBuffer(absoluteDrawingRegion, absoluteDrawingRegion, sourceGraphic, LinearRGB))
230
        return false;
231
    
213
    GraphicsContext* sourceGraphicContext = sourceGraphic->context();
232
    GraphicsContext* sourceGraphicContext = sourceGraphic->context();
214
    sourceGraphicContext->translate(-clippedSourceRect.x(), -clippedSourceRect.y());
233
    ASSERT(sourceGraphicContext);
215
    sourceGraphicContext->scale(scale);
234
  
216
    sourceGraphicContext->clearRect(FloatRect(FloatPoint(), paintRect.size()));
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()));
217
    filterData->sourceGraphicBuffer = sourceGraphic.release();
241
    filterData->sourceGraphicBuffer = sourceGraphic.release();
218
    filterData->savedContext = context;
242
    filterData->savedContext = context;
219
243
Lines 270-279 void RenderSVGResourceFilter::postApplyR WebCore/rendering/RenderSVGResourceFilter.cpp_sec3
270
        }
294
        }
271
295
272
        ImageBuffer* resultImage = lastEffect->resultImage();
296
        ImageBuffer* resultImage = lastEffect->resultImage();
273
        if (resultImage)
297
        if (resultImage) {
274
            context->drawImageBuffer(resultImage, object->style()->colorSpace(), lastEffect->filterPrimitiveSubregion());
298
            context->concatCTM(filterData->shearFreeAbsoluteTransform.inverse());
275
    }
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());
276
304
305
            context->concatCTM(filterData->shearFreeAbsoluteTransform);
306
        }
307
    }
277
    filterData->sourceGraphicBuffer.clear();
308
    filterData->sourceGraphicBuffer.clear();
278
}
309
}
279
310
- WebCore/rendering/RenderSVGResourceFilter.h -1 / +3 lines
Lines 42-48 namespace WebCore { WebCore/rendering/RenderSVGResourceFilter.h_sec1
42
42
43
struct FilterData {
43
struct FilterData {
44
    FilterData()
44
    FilterData()
45
        : builded(false)
45
        : savedContext(0)
46
        , builded(false)
46
    {
47
    {
47
    }
48
    }
48
49
Lines 50-55 struct FilterData { WebCore/rendering/RenderSVGResourceFilter.h_sec2
50
    RefPtr<SVGFilterBuilder> builder;
51
    RefPtr<SVGFilterBuilder> builder;
51
    OwnPtr<ImageBuffer> sourceGraphicBuffer;
52
    OwnPtr<ImageBuffer> sourceGraphicBuffer;
52
    GraphicsContext* savedContext;
53
    GraphicsContext* savedContext;
54
    AffineTransform shearFreeAbsoluteTransform;
53
    FloatRect boundaries;
55
    FloatRect boundaries;
54
    FloatSize scale;
56
    FloatSize scale;
55
    bool builded;
57
    bool builded;
- WebCore/svg/graphics/filters/SVGFEImage.cpp -3 / +3 lines
Lines 44-60 PassRefPtr<FEImage> FEImage::create(RefP WebCore/svg/graphics/filters/SVGFEImage.cpp_sec1
44
    return adoptRef(new FEImage(image, preserveAspectRatio));
44
    return adoptRef(new FEImage(image, preserveAspectRatio));
45
}
45
}
46
46
47
void FEImage::apply(Filter*)
47
void FEImage::apply(Filter* filter)
48
{
48
{
49
    if (!m_image.get())
49
    if (!m_image.get())
50
        return;
50
        return;
51
51
52
    GraphicsContext* filterContext = effectContext();
52
    GraphicsContext* filterContext = effectContext(filter);
53
    if (!filterContext)
53
    if (!filterContext)
54
        return;
54
        return;
55
55
56
    FloatRect srcRect(FloatPoint(), m_image->size());
56
    FloatRect srcRect(FloatPoint(), m_image->size());
57
    FloatRect destRect(FloatPoint(), filterPrimitiveSubregion().size());
57
    FloatRect destRect(FloatPoint(), absolutePaintRect().size());
58
58
59
    m_preserveAspectRatio.transformRect(destRect, srcRect);
59
    m_preserveAspectRatio.transformRect(destRect, srcRect);
60
60
- WebCore/svg/graphics/filters/SVGFEImage.h +2 lines
Lines 36-41 public: WebCore/svg/graphics/filters/SVGFEImage.h_sec1
36
    virtual void apply(Filter*);
36
    virtual void apply(Filter*);
37
    virtual void dump();
37
    virtual void dump();
38
38
39
    virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); }
40
39
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
41
    virtual TextStream& externalRepresentation(TextStream&, int indention) const;
40
    
42
    
41
private:
43
private:
- WebCore/svg/graphics/filters/SVGFilter.cpp -8 / +26 lines
Lines 24-35 WebCore/svg/graphics/filters/SVGFilter.cpp_sec1
24
24
25
namespace WebCore {
25
namespace WebCore {
26
26
27
SVGFilter::SVGFilter(const FloatRect& targetBoundingBox, const FloatRect& filterRect, bool effectBBoxMode)
27
SVGFilter::SVGFilter(const AffineTransform& absoluteTransform, const FloatRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode)
28
    : Filter()
28
    : Filter()
29
    , m_absoluteTransform(absoluteTransform)
30
    , m_absoluteSourceDrawingRegion(absoluteSourceDrawingRegion)
29
    , m_targetBoundingBox(targetBoundingBox)
31
    , m_targetBoundingBox(targetBoundingBox)
30
    , m_filterRect(filterRect)
32
    , m_filterRegion(filterRegion)
31
    , m_effectBBoxMode(effectBBoxMode)
33
    , m_effectBBoxMode(effectBBoxMode)
32
{
34
{
35
    m_absoluteFilterRegion = absoluteTransform.mapRect(filterRegion);
33
}
36
}
34
37
35
void SVGFilter::determineFilterPrimitiveSubregion(FilterEffect* effect, const FloatRect& unionOfPreviousPrimitiveSubregions)
38
void SVGFilter::determineFilterPrimitiveSubregion(FilterEffect* effect, const FloatRect& unionOfPreviousPrimitiveSubregions)
Lines 66-87 void SVGFilter::determineFilterPrimitive WebCore/svg/graphics/filters/SVGFilter.cpp_sec2
66
    }
69
    }
67
70
68
    // clip every filter effect to the filter region
71
    // clip every filter effect to the filter region
69
    newSubRegion.intersect(m_filterRect);
72
    newSubRegion.intersect(m_filterRegion);
70
73
71
    effect->setFilterPrimitiveSubregion(newSubRegion);
74
    effect->setFilterPrimitiveSubregion(newSubRegion);
72
    
73
    // TODO: Everything above should be moved to a first phase of layout in RenderSVGResourceFilterPrimitive.
75
    // TODO: Everything above should be moved to a first phase of layout in RenderSVGResourceFilterPrimitive.
74
    // The scaling of the subregion to the repaint rect should be merged with a more intelligent repaint logic
76
    // The scaling of the subregion to the repaint rect should be merged with a more intelligent repaint logic
75
    // and moved to the second phase of layout in RenderSVGResourceFilterPrimitive.
77
    // and moved to the second phase of layout in RenderSVGResourceFilterPrimitive.
76
    // See bug https://bugs.webkit.org/show_bug.cgi?id=45614.
78
    // See bug https://bugs.webkit.org/show_bug.cgi?id=45614.
79
    newSubRegion = m_absoluteTransform.mapRect(newSubRegion);
77
    newSubRegion.scale(filterResolution().width(), filterResolution().height());
80
    newSubRegion.scale(filterResolution().width(), filterResolution().height());
78
    effect->setRepaintRectInLocalCoordinates(newSubRegion);
81
    effect->setMaxEffectRect(enclosingIntRect(newSubRegion));
79
    m_maxImageSize = m_maxImageSize.expandedTo(newSubRegion.size()); 
82
    if (!effect->isSourceInput())
83
        m_maxImageSize = m_maxImageSize.expandedTo(newSubRegion.size()); 
80
}
84
}
81
85
82
PassRefPtr<SVGFilter> SVGFilter::create(const FloatRect& targetBoundingBox, const FloatRect& filterRect, bool effectBBoxMode)
86
float SVGFilter::applyHorizontalScale(float value) const
83
{
87
{
84
    return adoptRef(new SVGFilter(targetBoundingBox, filterRect, effectBBoxMode));
88
    if (m_effectBBoxMode)
89
        value *= m_targetBoundingBox.width();
90
    return Filter::applyHorizontalScale(value) * m_absoluteFilterRegion.width() / m_filterRegion.width();
91
}
92
93
float SVGFilter::applyVerticalScale(float value) const
94
{
95
    if (m_effectBBoxMode)
96
        value *= m_targetBoundingBox.height();
97
    return Filter::applyVerticalScale(value) * m_absoluteFilterRegion.height() / m_filterRegion.height();
98
}
99
100
PassRefPtr<SVGFilter> SVGFilter::create(const AffineTransform& absoluteTransform, const FloatRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode)
101
{
102
    return adoptRef(new SVGFilter(absoluteTransform, absoluteSourceDrawingRegion, targetBoundingBox, filterRegion, effectBBoxMode));
85
}
103
}
86
104
87
} // namespace WebCore
105
} // namespace WebCore
- WebCore/svg/graphics/filters/SVGFilter.h -21 / +31 lines
Lines 21-26 WebCore/svg/graphics/filters/SVGFilter.h_sec1
21
#define SVGFilter_h
21
#define SVGFilter_h
22
22
23
#if ENABLE(SVG) && ENABLE(FILTERS)
23
#if ENABLE(SVG) && ENABLE(FILTERS)
24
#include "AffineTransform.h"
24
#include "Filter.h"
25
#include "Filter.h"
25
#include "FilterEffect.h"
26
#include "FilterEffect.h"
26
#include "FloatRect.h"
27
#include "FloatRect.h"
Lines 32-58 WebCore/svg/graphics/filters/SVGFilter.h_sec2
32
33
33
namespace WebCore {
34
namespace WebCore {
34
35
35
    class SVGFilter : public Filter {
36
class SVGFilter : public Filter {
36
    public:
37
public:
37
        static PassRefPtr<SVGFilter> create(const FloatRect&, const FloatRect&, bool);
38
    static PassRefPtr<SVGFilter> create(const AffineTransform&, const FloatRect&, const FloatRect&, const FloatRect&, bool);
38
39
39
        virtual bool effectBoundingBoxMode() const { return m_effectBBoxMode; }
40
    virtual bool effectBoundingBoxMode() const { return m_effectBBoxMode; }
40
41
41
        virtual FloatRect filterRegion() const { return m_filterRect; }
42
    virtual FloatRect filterRegionInUserSpace() const { return m_filterRegion; }
42
        
43
    virtual FloatRect filterRegion() const { return m_absoluteFilterRegion; }
43
        virtual FloatRect sourceImageRect() const { return m_targetBoundingBox; }
44
44
45
    virtual FloatPoint mapAbsolutePointToLocalPoint(const FloatPoint& point) const { return m_absoluteTransform.inverse().mapPoint(point); }
45
        virtual FloatSize maxImageSize() const { return m_maxImageSize; }
46
46
        virtual void determineFilterPrimitiveSubregion(FilterEffect*, const FloatRect&);
47
    virtual float applyHorizontalScale(float value) const;
47
48
    virtual float applyVerticalScale(float value) const;
48
    private:
49
49
        SVGFilter(const FloatRect& targetBoundingBox, const FloatRect& filterRect, bool effectBBoxMode);
50
    virtual FloatRect sourceImageRect() const { return m_absoluteSourceDrawingRegion; }
50
51
    
51
        FloatSize m_maxImageSize;
52
    virtual FloatSize maxImageSize() const { return m_maxImageSize; }
52
        FloatRect m_targetBoundingBox;
53
    virtual void determineFilterPrimitiveSubregion(FilterEffect*, const FloatRect&);
53
        FloatRect m_filterRect;
54
54
        bool m_effectBBoxMode;
55
private:
55
    };
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
};
56
66
57
} // namespace WebCore
67
} // namespace WebCore
58
68
- LayoutTests/ChangeLog +29 lines
Lines 1-3 LayoutTests/ChangeLog_sec1
1
2010-10-05  Dirk Schulze  <krit@webkit.org>
2
3
        Reviewed by NOBODY (OOPS!).
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 feGaussianBlu correctly.
11
        
12
13
        * platform/mac/svg/filters/filterRes1-expected.checksum: Added.
14
        * platform/mac/svg/filters/filterRes1-expected.png: Added.
15
        * platform/mac/svg/filters/filterRes1-expected.txt: Added.
16
        * platform/mac/svg/filters/filterRes2-expected.checksum: Added.
17
        * platform/mac/svg/filters/filterRes2-expected.png: Added.
18
        * platform/mac/svg/filters/filterRes2-expected.txt: Added.
19
        * platform/mac/svg/filters/filterRes3-expected.checksum: Added.
20
        * platform/mac/svg/filters/filterRes3-expected.png: Added.
21
        * platform/mac/svg/filters/filterRes3-expected.txt: Added.
22
        * platform/mac/svg/filters/shadow-on-filter-expected.txt:
23
        * platform/mac/svg/filters/shadow-on-rect-with-filter-expected.txt:
24
        * svg/filters/filterRes1.svg: Added.
25
        * svg/filters/filterRes2.svg: Added.
26
        * svg/filters/filterRes3.svg: Added.
27
        * svg/filters/shadow-on-filter.svg:
28
        * svg/filters/shadow-on-rect-with-filter.svg:
29
1
2010-10-05  Robert Hogan  <robert@webkit.org>
30
2010-10-05  Robert Hogan  <robert@webkit.org>
2
31
3
        Reviewed by Andreas Kling.
32
        Reviewed by Andreas Kling.
- LayoutTests/platform/mac/svg/filters/filterRes1-expected.checksum +1 lines
Line 0 LayoutTests/platform/mac/svg/filters/filterRes1-expected.checksum_sec1
1
516097e4549a4f7197ca0fa54100a0ee
- LayoutTests/platform/mac/svg/filters/filterRes1-expected.txt +17 lines
Line 0 LayoutTests/platform/mac/svg/filters/filterRes1-expected.txt_sec1
1
layer at (0,0) size 800x600
2
  RenderView at (0,0) size 800x600
3
layer at (0,0) size 800x600
4
  RenderSVGRoot {svg} at (10,10) size 400x120
5
    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
6
      RenderSVGResourceFilter {filter} [id="f1"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
7
        [feFlood flood-color="#008000" flood-opacity="1.00"]
8
      RenderSVGResourceFilter {filter} [id="f2"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
9
        [feFlood flood-color="#008000" flood-opacity="1.00"]
10
      RenderSVGResourceFilter {filter} [id="f3"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
11
        [feFlood flood-color="#008000" flood-opacity="1.00"]
12
    RenderPath {rect} at (10,10) size 120x120 [fill={[type=SOLID] [color=#000000]}] [data="M20.00,20.00 L120.00,20.00 L120.00,120.00 L20.00,120.00 Z"]
13
      [filter="f1"] RenderSVGResourceFilter {filter} at (10,10) size 120x120
14
    RenderPath {rect} at (150,10) size 120x120 [fill={[type=SOLID] [color=#000000]}] [data="M160.00,20.00 L260.00,20.00 L260.00,120.00 L160.00,120.00 Z"]
15
      [filter="f2"] RenderSVGResourceFilter {filter} at (150,10) size 120x120
16
    RenderPath {rect} at (290,10) size 120x120 [fill={[type=SOLID] [color=#000000]}] [data="M300.00,20.00 L400.00,20.00 L400.00,120.00 L300.00,120.00 Z"]
17
      [filter="f3"] RenderSVGResourceFilter {filter} at (290,10) size 120x120
- LayoutTests/platform/mac/svg/filters/filterRes2-expected.checksum +1 lines
Line 0 LayoutTests/platform/mac/svg/filters/filterRes2-expected.checksum_sec1
1
65bfcfc9dd4b5c7da633e3bb46c116f8
- LayoutTests/platform/mac/svg/filters/filterRes2-expected.txt +20 lines
Line 0 LayoutTests/platform/mac/svg/filters/filterRes2-expected.txt_sec1
1
layer at (0,0) size 800x600
2
  RenderView at (0,0) size 800x600
3
layer at (0,0) size 800x600
4
  RenderSVGRoot {svg} at (10,10) size 400x120
5
    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
6
      RenderSVGResourceFilter {filter} [id="f1"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
7
        [feOffset dx="0.00" dy="0.00"]
8
          [SourceGraphic]
9
      RenderSVGResourceFilter {filter} [id="f2"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
10
        [feOffset dx="0.00" dy="0.00"]
11
          [SourceGraphic]
12
      RenderSVGResourceFilter {filter} [id="f3"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
13
        [feOffset dx="0.00" dy="0.00"]
14
          [SourceGraphic]
15
    RenderPath {rect} at (10,10) size 120x120 [fill={[type=SOLID] [color=#008000]}] [data="M20.00,20.00 L120.00,20.00 L120.00,120.00 L20.00,120.00 Z"]
16
      [filter="f1"] RenderSVGResourceFilter {filter} at (10,10) size 120x120
17
    RenderPath {rect} at (150,10) size 120x120 [fill={[type=SOLID] [color=#008000]}] [data="M160.00,20.00 L260.00,20.00 L260.00,120.00 L160.00,120.00 Z"]
18
      [filter="f2"] RenderSVGResourceFilter {filter} at (150,10) size 120x120
19
    RenderPath {rect} at (290,10) size 120x120 [fill={[type=SOLID] [color=#008000]}] [data="M300.00,20.00 L400.00,20.00 L400.00,120.00 L300.00,120.00 Z"]
20
      [filter="f3"] RenderSVGResourceFilter {filter} at (290,10) size 120x120
- LayoutTests/platform/mac/svg/filters/filterRes3-expected.checksum +1 lines
Line 0 LayoutTests/platform/mac/svg/filters/filterRes3-expected.checksum_sec1
1
516097e4549a4f7197ca0fa54100a0ee
- LayoutTests/platform/mac/svg/filters/filterRes3-expected.txt +17 lines
Line 0 LayoutTests/platform/mac/svg/filters/filterRes3-expected.txt_sec1
1
layer at (0,0) size 800x600
2
  RenderView at (0,0) size 800x600
3
layer at (0,0) size 800x600
4
  RenderSVGRoot {svg} at (10,10) size 400x120
5
    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
6
      RenderSVGResourceFilter {filter} [id="f1"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
7
        [feFlood flood-color="#008000" flood-opacity="1.00"]
8
      RenderSVGResourceFilter {filter} [id="f2"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
9
        [feFlood flood-color="#008000" flood-opacity="1.00"]
10
      RenderSVGResourceFilter {filter} [id="f3"] [filterUnits=objectBoundingBox] [primitiveUnits=userSpaceOnUse]
11
        [feFlood flood-color="#008000" flood-opacity="1.00"]
12
    RenderPath {rect} at (10,10) size 120x120 [fill={[type=SOLID] [color=#000000]}] [data="M20.00,20.00 L120.00,20.00 L120.00,120.00 L20.00,120.00 Z"]
13
      [filter="f1"] RenderSVGResourceFilter {filter} at (10,10) size 120x120
14
    RenderPath {rect} at (150,10) size 120x120 [fill={[type=SOLID] [color=#000000]}] [data="M160.00,20.00 L260.00,20.00 L260.00,120.00 L160.00,120.00 Z"]
15
      [filter="f2"] RenderSVGResourceFilter {filter} at (150,10) size 120x120
16
    RenderPath {rect} at (290,10) size 120x120 [fill={[type=SOLID] [color=#000000]}] [data="M300.00,20.00 L400.00,20.00 L400.00,120.00 L300.00,120.00 Z"]
17
      [filter="f3"] RenderSVGResourceFilter {filter} at (290,10) size 120x120
- LayoutTests/platform/mac/svg/filters/shadow-on-filter-expected.txt -1 / +1 lines
Lines 4-10 layer at (0,0) size 800x600 LayoutTests/platform/mac/svg/filters/shadow-on-filter-expected.txt_sec1
4
  RenderSVGRoot {svg} at (50,50) size 480x480
4
  RenderSVGRoot {svg} at (50,50) size 480x480
5
    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
5
    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
6
      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=objectBoundingBox]
6
      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=objectBoundingBox]
7
        [feGaussianBlur stdDeviation="4.00, 4.00"]
7
        [feGaussianBlur stdDeviation="0.01, 0.01"]
8
          [feComposite operation="OVER"]
8
          [feComposite operation="OVER"]
9
            [feFlood flood-color="#FF0000" flood-opacity="1.00"]
9
            [feFlood flood-color="#FF0000" flood-opacity="1.00"]
10
            [feFlood flood-color="#008000" flood-opacity="1.00"]
10
            [feFlood flood-color="#008000" flood-opacity="1.00"]
- LayoutTests/platform/mac/svg/filters/shadow-on-rect-with-filter-expected.txt -1 / +1 lines
Lines 4-10 layer at (0,0) size 800x600 LayoutTests/platform/mac/svg/filters/shadow-on-rect-with-filter-expected.txt_sec1
4
  RenderSVGRoot {svg} at (37,37) size 493x493
4
  RenderSVGRoot {svg} at (37,37) size 493x493
5
    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
5
    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
6
      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=objectBoundingBox]
6
      RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=objectBoundingBox]
7
        [feGaussianBlur stdDeviation="4.00, 4.00"]
7
        [feGaussianBlur stdDeviation="0.01, 0.01"]
8
          [feComposite operation="OVER"]
8
          [feComposite operation="OVER"]
9
            [feFlood flood-color="#FF0000" flood-opacity="1.00"]
9
            [feFlood flood-color="#FF0000" flood-opacity="1.00"]
10
            [feFlood flood-color="#008000" flood-opacity="1.00"]
10
            [feFlood flood-color="#008000" flood-opacity="1.00"]
- LayoutTests/svg/filters/filterRes1.svg +17 lines
Line 0 LayoutTests/svg/filters/filterRes1.svg_sec1
1
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
2
<defs>
3
<filter id="f1" filterRes="60">
4
    <feFlood flood-color="green"/>
5
</filter>
6
<filter id="f2" filterRes="120">
7
    <feFlood flood-color="green"/>
8
</filter>
9
<filter id="f3">
10
    <feFlood flood-color="green"/>
11
</filter>
12
</defs>
13
<rect x="20" y="20" width="100" height="100" filter="url(#f1)"/>
14
<rect x="160" y="20" width="100" height="100" filter="url(#f2)"/>
15
<rect x="300" y="20" width="100" height="100" filter="url(#f3)"/>
16
</svg>
17
- LayoutTests/svg/filters/filterRes2.svg +17 lines
Line 0 LayoutTests/svg/filters/filterRes2.svg_sec1
1
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
2
<defs>
3
<filter id="f1" filterRes="60">
4
    <feOffset/>
5
</filter>
6
<filter id="f2" filterRes="120">
7
    <feOffset/>
8
</filter>
9
<filter id="f3">
10
    <feOffset/>
11
</filter>
12
</defs>
13
<rect x="20" y="20" width="100" height="100" fill="green" filter="url(#f1)"/>
14
<rect x="160" y="20" width="100" height="100" fill="green" filter="url(#f2)"/>
15
<rect x="300" y="20" width="100" height="100" fill="green" filter="url(#f3)"/>
16
</svg>
17
- LayoutTests/svg/filters/filterRes3.svg +20 lines
Line 0 LayoutTests/svg/filters/filterRes3.svg_sec1
1
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
2
<defs>
3
<filter id="f1" filterRes="60">
4
    <feFlood flood-color="green"/>
5
    <feOfffset/>
6
</filter>
7
<filter id="f2" filterRes="120">
8
    <feFlood flood-color="green"/>
9
    <feOfffset/>
10
</filter>
11
<filter id="f3">
12
    <feFlood flood-color="green"/>
13
    <feOfffset/>
14
</filter>
15
</defs>
16
<rect x="20" y="20" width="100" height="100" filter="url(#f1)"/>
17
<rect x="160" y="20" width="100" height="100" filter="url(#f2)"/>
18
<rect x="300" y="20" width="100" height="100" filter="url(#f3)"/>
19
</svg>
20
- LayoutTests/svg/filters/shadow-on-filter.svg -1 / +1 lines
Lines 4-10 LayoutTests/svg/filters/shadow-on-filter.svg_sec1
4
<feFlood x="-40%" y="-40%" width="50%" height="50%" flood-color="red" style="-webkit-svg-shadow:-4px -4px 0px blue;" result="flood1"/>
4
<feFlood x="-40%" y="-40%" width="50%" height="50%" flood-color="red" style="-webkit-svg-shadow:-4px -4px 0px blue;" result="flood1"/>
5
<feFlood x="-20%" y="-20%" width="50%" height="50%" flood-color="green" result="flood2"/>
5
<feFlood x="-20%" y="-20%" width="50%" height="50%" flood-color="green" result="flood2"/>
6
<feComposite in="flood1" in2="flood2" width="120%" height="120%" result="comp1" style="-webkit-svg-shadow:4px -1px 3px green;"/>
6
<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;"/>
8
</filter>
8
</filter>
9
</defs>
9
</defs>
10
<rect x="200" y="200" width="300" height="300" fill="green" style="filter:url(#filter);"/>
10
<rect x="200" y="200" width="300" height="300" fill="green" style="filter:url(#filter);"/>
- LayoutTests/svg/filters/shadow-on-rect-with-filter.svg -1 / +1 lines
Lines 4-10 LayoutTests/svg/filters/shadow-on-rect-with-filter.svg_sec1
4
<feFlood x="-40%" y="-40%" width="50%" height="50%" flood-color="red" result="flood1"/>
4
<feFlood x="-40%" y="-40%" width="50%" height="50%" flood-color="red" result="flood1"/>
5
<feFlood x="-20%" y="-20%" width="50%" height="50%" flood-color="green" result="flood2"/>
5
<feFlood x="-20%" y="-20%" width="50%" height="50%" flood-color="green" result="flood2"/>
6
<feComposite in="flood1" in2="flood2" width="120%" height="120%" result="comp1" />
6
<feComposite in="flood1" in2="flood2" width="120%" height="120%" result="comp1" />
7
<feGaussianBlur stdDeviation="4 4" />
7
<feGaussianBlur stdDeviation="0.0133" />
8
</filter>
8
</filter>
9
</defs>
9
</defs>
10
<rect x="200" y="200" width="300" height="300" fill="green" style="filter:url(#filter);-webkit-svg-shadow:-10px -10px 3px orange;"/>
10
<rect x="200" y="200" width="300" height="300" fill="green" style="filter:url(#filter);-webkit-svg-shadow:-10px -10px 3px orange;"/>

Return to Bug 31370