Changeset 69181 in webkit
- Timestamp:
- Oct 6, 2010 2:45:18 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 12 added
- 44 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r69179 r69181 1 2010-10-06 Dirk Schulze <krit@webkit.org> 2 3 Reviewed by Nikolas Zimmermann. 4 5 SVGs with filters look grainy when scaled 6 https://bugs.webkit.org/show_bug.cgi?id=5526 7 8 Added three new tests for SVGs filterRes. 9 Shadow tests for SVG Filter needed an update. Current tests didn't respect 10 primitiveUnits "objectBoundingBox" for stdDeviation on feGaussianBlur correctly. 11 12 * platform/mac/svg/filters/filterRes1-expected.checksum: Added. 13 * platform/mac/svg/filters/filterRes1-expected.png: Added. 14 * platform/mac/svg/filters/filterRes1-expected.txt: Added. 15 * platform/mac/svg/filters/filterRes2-expected.checksum: Added. 16 * platform/mac/svg/filters/filterRes2-expected.png: Added. 17 * platform/mac/svg/filters/filterRes2-expected.txt: Added. 18 * platform/mac/svg/filters/filterRes3-expected.checksum: Added. 19 * platform/mac/svg/filters/filterRes3-expected.png: Added. 20 * platform/mac/svg/filters/filterRes3-expected.txt: Added. 21 * platform/mac/svg/filters/shadow-on-filter-expected.txt: 22 * platform/mac/svg/filters/shadow-on-rect-with-filter-expected.txt: 23 * svg/filters/filterRes1.svg: Added. 24 * svg/filters/filterRes2.svg: Added. 25 * svg/filters/filterRes3.svg: Added. 26 * svg/filters/shadow-on-filter.svg: 27 * svg/filters/shadow-on-rect-with-filter.svg: 28 1 29 2010-10-06 Kent Tamura <tkent@chromium.org> 2 30 -
trunk/LayoutTests/platform/mac/svg/filters/shadow-on-filter-expected.txt
r62922 r69181 5 5 RenderSVGHiddenContainer {defs} at (0,0) size 0x0 6 6 RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=objectBoundingBox] 7 [feGaussianBlur stdDeviation=" 4.00, 4.00"]7 [feGaussianBlur stdDeviation="0.01, 0.01"] 8 8 [feComposite operation="OVER"] 9 9 [feFlood flood-color="#FF0000" flood-opacity="1.00"] -
trunk/LayoutTests/platform/mac/svg/filters/shadow-on-rect-with-filter-expected.txt
r62922 r69181 5 5 RenderSVGHiddenContainer {defs} at (0,0) size 0x0 6 6 RenderSVGResourceFilter {filter} [id="filter"] [filterUnits=objectBoundingBox] [primitiveUnits=objectBoundingBox] 7 [feGaussianBlur stdDeviation=" 4.00, 4.00"]7 [feGaussianBlur stdDeviation="0.01, 0.01"] 8 8 [feComposite operation="OVER"] 9 9 [feFlood flood-color="#FF0000" flood-opacity="1.00"] -
trunk/LayoutTests/svg/filters/shadow-on-filter.svg
r53157 r69181 5 5 <feFlood x="-20%" y="-20%" width="50%" height="50%" flood-color="green" result="flood2"/> 6 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 8 </filter> 9 9 </defs> -
trunk/LayoutTests/svg/filters/shadow-on-rect-with-filter.svg
r53157 r69181 5 5 <feFlood x="-20%" y="-20%" width="50%" height="50%" flood-color="green" result="flood2"/> 6 6 <feComposite in="flood1" in2="flood2" width="120%" height="120%" result="comp1" /> 7 <feGaussianBlur stdDeviation=" 4 4" />7 <feGaussianBlur stdDeviation="0.0133" /> 8 8 </filter> 9 9 </defs> -
trunk/WebCore/ChangeLog
r69180 r69181 1 2010-10-06 Dirk Schulze <krit@webkit.org> 2 3 Reviewed by Nikolas Zimmermann. 4 5 SVGs with filters look grainy when scaled 6 https://bugs.webkit.org/show_bug.cgi?id=5526 7 8 SVG filter effects need smarter size calculation 9 https://bugs.webkit.org/show_bug.cgi?id=31370 10 11 SVG elements use Filters before own transformations 12 https://bugs.webkit.org/show_bug.cgi?id=32486 13 14 Calculate all filter results in device space instead of the filtered objects user space. This change is similar to 15 the patches for SVG Pattern and SVG Masker before. It avoids pixelation and guarantees smooth filter results for 16 every scale level and is independent of any transformation to the target element or any ancester of the target. 17 The second part of this patch reduces the size of every effect to the smallest affected region instead of the complete 18 filter primitive subregion (http://www.w3.org/TR/SVG/filters.html#FilterPrimitiveSubRegion). We just use the subregion 19 as clipping region, like mentioned in the SVG specification, to make the affected region even smaller now. 20 21 This is a huge speed up. The ECMA cloud (http://ejohn.org/files/ecma-cloud.svg) is more than 100 times faster on Gtk and 22 renders in less than a second. 23 Some examples on svg-wow.org can be viewed the first time now, since the subregions were much bigger than the affected 24 region. 25 There's still more potential to speed up filters, by further reducing the ImageBuffer sizes. 26 Renamed repaintRectInLocalCoordinates to absolutePaintRect, since all coordinates are in device space instead of the 27 user space now. 28 The absolute paint rect is calculated by determineAbsolutePaintRect() and gets called by FilterEffect::effectContext() on 29 applying the effect. 30 Partly rewrote filter resolution (http://www.w3.org/TR/SVG/filters.html#FilterElementFilterResAttribute) to work with the 31 new concept. This also corrects the old behavior to match the SVG specification. 32 33 Tests: svg/filters/filterRes1.svg 34 svg/filters/filterRes2.svg 35 svg/filters/filterRes3.svg 36 37 * platform/graphics/cairo/GraphicsContextCairo.cpp: Call setAbsolutePaintRect instead of setRepaintRectInLocalCoordinates. 38 (WebCore::GraphicsContext::createShadowMask): 39 * platform/graphics/filters/FEBlend.cpp: Renamed repaintRectInLocalCoordinates to absolutePaintRect. 40 (WebCore::FEBlend::apply): 41 * platform/graphics/filters/FEColorMatrix.cpp: Ditto. 42 (WebCore::FEColorMatrix::apply): 43 * platform/graphics/filters/FEComponentTransfer.cpp: Ditto. 44 (WebCore::FEComponentTransfer::apply): 45 * platform/graphics/filters/FEComposite.cpp: Ditto. 46 (WebCore::FEComposite::determineAbsolutePaintRect): 47 (WebCore::FEComposite::apply): 48 * platform/graphics/filters/FEComposite.h: 49 * platform/graphics/filters/FEConvolveMatrix.cpp: Ditto. 50 (WebCore::FEConvolveMatrix::apply): 51 * platform/graphics/filters/FEConvolveMatrix.h: 52 (WebCore::FEConvolveMatrix::determineAbsolutePaintRect): 53 * platform/graphics/filters/FEDisplacementMap.cpp: Ditto. 54 (WebCore::FEDisplacementMap::apply): 55 * platform/graphics/filters/FEDisplacementMap.h: 56 (WebCore::FEDisplacementMap::determineAbsolutePaintRect): 57 * platform/graphics/filters/FEFlood.cpp: Ditto. 58 (WebCore::FEFlood::apply): 59 * platform/graphics/filters/FEFlood.h: 60 (WebCore::FEFlood::determineAbsolutePaintRect): 61 * platform/graphics/filters/FEGaussianBlur.cpp: Ditto. 62 (WebCore::calculateKernelSize): 63 (WebCore::FEGaussianBlur::determineAbsolutePaintRect): 64 (WebCore::FEGaussianBlur::apply): 65 * platform/graphics/filters/FEGaussianBlur.h: 66 * platform/graphics/filters/FELighting.cpp: Ditto. 67 (WebCore::FELighting::apply): 68 * platform/graphics/filters/FEMerge.cpp: Ditto. 69 (WebCore::FEMerge::apply): 70 * platform/graphics/filters/FEMorphology.cpp: Ditto. 71 (WebCore::FEMorphology::determineAbsolutePaintRect): 72 (WebCore::FEMorphology::apply): 73 * platform/graphics/filters/FEMorphology.h: 74 * platform/graphics/filters/FEOffset.cpp: Ditto. 75 (WebCore::FEOffset::determineAbsolutePaintRect): 76 (WebCore::FEOffset::apply): 77 * platform/graphics/filters/FEOffset.h: 78 * platform/graphics/filters/FETile.cpp: Ditto. 79 (WebCore::FETile::determineFilterPrimitiveSubregion): 80 (WebCore::FETile::apply): 81 * platform/graphics/filters/FETile.h: 82 (WebCore::FETile::determineAbsolutePaintRect): 83 * platform/graphics/filters/FETurbulence.cpp: Ditto. 84 (WebCore::FETurbulence::apply): 85 * platform/graphics/filters/FETurbulence.h: 86 (WebCore::FETurbulence::determineAbsolutePaintRect): 87 * platform/graphics/filters/Filter.h: 88 (WebCore::Filter::applyHorizontalScale): Map horizontal effect values to absolute coordinates. 89 (WebCore::Filter::applyVerticalScale): Map vertical effect values to absolute coordinates. 90 (WebCore::Filter::mapAbsolutePointToLocalPoint): 91 (WebCore::Filter::filterRegionInUserSpace): 92 * platform/graphics/filters/FilterEffect.cpp: Ditto. 93 (WebCore::FilterEffect::determineFilterPrimitiveSubregion): 94 (WebCore::FilterEffect::determineAbsolutePaintRect): 95 (WebCore::FilterEffect::requestedRegionOfInputImageData): 96 (WebCore::FilterEffect::drawingRegionOfInputImage): 97 (WebCore::FilterEffect::effectContext): 98 * platform/graphics/filters/FilterEffect.h: 99 (WebCore::FilterEffect::absolutePaintRect): 100 (WebCore::FilterEffect::setAbsolutePaintRect): 101 (WebCore::FilterEffect::maxEffectRect): The subregion in absolute coordinates for SVG. 102 (WebCore::FilterEffect::setMaxEffectRect): 103 * platform/graphics/filters/SourceAlpha.cpp: Ditto. 104 (WebCore::SourceAlpha::determineAbsolutePaintRect): 105 (WebCore::SourceAlpha::apply): 106 * platform/graphics/filters/SourceAlpha.h: 107 * platform/graphics/filters/SourceGraphic.cpp: Ditto. 108 (WebCore::SourceGraphic::determineAbsolutePaintRect): 109 (WebCore::SourceGraphic::apply): 110 * platform/graphics/filters/SourceGraphic.h: 111 * rendering/RenderSVGResourceFilter.cpp: 112 (WebCore::RenderSVGResourceFilter::applyResource): 113 (WebCore::RenderSVGResourceFilter::postApplyResource): 114 * rendering/RenderSVGResourceFilter.h: 115 (WebCore::FilterData::FilterData): 116 * svg/graphics/filters/SVGFEImage.cpp: Ditto. 117 (WebCore::FEImage::apply): 118 * svg/graphics/filters/SVGFEImage.h: 119 (WebCore::FEImage::determineAbsolutePaintRect): 120 * svg/graphics/filters/SVGFilter.cpp: 121 (WebCore::SVGFilter::SVGFilter): 122 (WebCore::SVGFilter::determineFilterPrimitiveSubregion): 123 (WebCore::SVGFilter::applyHorizontalScale): 124 (WebCore::SVGFilter::applyVerticalScale): 125 (WebCore::SVGFilter::create): 126 * svg/graphics/filters/SVGFilter.h: 127 (WebCore::SVGFilter::effectBoundingBoxMode): 128 (WebCore::SVGFilter::filterRegionInUserSpace): 129 (WebCore::SVGFilter::filterRegion): 130 (WebCore::SVGFilter::mapAbsolutePointToLocalPoint): Map absolute point to local point in userspace. 131 (WebCore::SVGFilter::sourceImageRect): 132 (WebCore::SVGFilter::maxImageSize): 133 1 134 2010-10-06 Pavel Podivilov <podivilov@chromium.org> 2 135 -
trunk/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
r69015 r69181 945 945 filter->setSourceImage(buffer); 946 946 RefPtr<FilterEffect> source = SourceGraphic::create(); 947 source->set RepaintRectInLocalCoordinates(FloatRect(FloatPoint(), shadowRect.size()));947 source->setAbsolutePaintRect(IntRect(IntPoint(), roundedIntSize(shadowRect.size()))); 948 948 source->setIsAlphaImage(true); 949 949 RefPtr<FilterEffect> blur = FEGaussianBlur::create(stdDeviation, stdDeviation); 950 950 FilterEffectVector& inputEffects = blur->inputEffects(); 951 951 inputEffects.append(source.get()); 952 blur->set RepaintRectInLocalCoordinates(FloatRect(FloatPoint(), shadowRect.size()));952 blur->setAbsolutePaintRect(IntRect(IntPoint(), roundedIntSize(shadowRect.size()))); 953 953 blur->apply(filter.get()); 954 954 return blur->resultImage()->m_data.m_surface; -
trunk/WebCore/platform/graphics/filters/FEBlend.cpp
r67929 r69181 99 99 return; 100 100 101 if (!effectContext( ))101 if (!effectContext(filter)) 102 102 return; 103 103 104 IntRect effectADrawingRect = requestedRegionOfInputImageData(in-> repaintRectInLocalCoordinates());104 IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); 105 105 RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data()); 106 106 107 IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2-> repaintRectInLocalCoordinates());107 IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect()); 108 108 RefPtr<CanvasPixelArray> srcPixelArrayB(in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)->data()); 109 109 -
trunk/WebCore/platform/graphics/filters/FEColorMatrix.cpp
r67929 r69181 161 161 return; 162 162 163 GraphicsContext* filterContext = effectContext( );163 GraphicsContext* filterContext = effectContext(filter); 164 164 if (!filterContext) 165 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 169 IntRect imageRect(IntPoint(), resultImage()->size()); -
trunk/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
r67929 r69181 155 155 return; 156 156 157 if (!effectContext( ))157 if (!effectContext(filter)) 158 158 return; 159 159 … … 168 168 (*callEffect[transferFunction[channel].type])(tables[channel], transferFunction[channel]); 169 169 170 IntRect drawingRect = requestedRegionOfInputImageData(in-> repaintRectInLocalCoordinates());170 IntRect drawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); 171 171 RefPtr<ImageData> imageData(in->resultImage()->getUnmultipliedImageData(drawingRect)); 172 172 CanvasPixelArray* srcPixelArray(imageData->data()); -
trunk/WebCore/platform/graphics/filters/FEComposite.cpp
r67929 r69181 4 4 * Copyright (C) 2005 Eric Seidel <eric@webkit.org> 5 5 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 6 7 * 7 8 * This library is free software; you can redistribute it and/or … … 113 114 } 114 115 } 116 117 void FEComposite::determineAbsolutePaintRect(Filter* filter) 118 { 119 switch (m_type) { 120 case FECOMPOSITE_OPERATOR_IN: 121 case FECOMPOSITE_OPERATOR_ATOP: 122 // For In and Atop the first effect just influences the result of 123 // the second effect. So just use the absolute paint rect of the second effect here. 124 setAbsolutePaintRect(inputEffect(1)->absolutePaintRect()); 125 return; 126 case FECOMPOSITE_OPERATOR_ARITHMETIC: 127 // Arithmetic may influnce the compele filter primitive region. So we can't 128 // optimize the paint region here. 129 setAbsolutePaintRect(maxEffectRect()); 130 return; 131 default: 132 // Take the union of both input effects. 133 FilterEffect::determineAbsolutePaintRect(filter); 134 return; 135 } 136 } 115 137 116 138 void FEComposite::apply(Filter* filter) … … 123 145 return; 124 146 125 GraphicsContext* filterContext = effectContext( );147 GraphicsContext* filterContext = effectContext(filter); 126 148 if (!filterContext) 127 149 return; … … 130 152 switch (m_type) { 131 153 case FECOMPOSITE_OPERATOR_OVER: 132 filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2-> repaintRectInLocalCoordinates()));133 filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in-> repaintRectInLocalCoordinates()));154 filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->absolutePaintRect())); 155 filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect())); 134 156 break; 135 157 case FECOMPOSITE_OPERATOR_IN: 136 158 filterContext->save(); 137 filterContext->clipToImageBuffer(in2->resultImage(), drawingRegionOfInputImage(in2-> repaintRectInLocalCoordinates()));138 filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in-> repaintRectInLocalCoordinates()));159 filterContext->clipToImageBuffer(in2->resultImage(), drawingRegionOfInputImage(in2->absolutePaintRect())); 160 filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect())); 139 161 filterContext->restore(); 140 162 break; 141 163 case FECOMPOSITE_OPERATOR_OUT: 142 filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in-> repaintRectInLocalCoordinates()));143 filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2-> repaintRectInLocalCoordinates()), srcRect, CompositeDestinationOut);164 filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect())); 165 filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->absolutePaintRect()), srcRect, CompositeDestinationOut); 144 166 break; 145 167 case FECOMPOSITE_OPERATOR_ATOP: 146 filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2-> repaintRectInLocalCoordinates()));147 filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in-> repaintRectInLocalCoordinates()), srcRect, CompositeSourceAtop);168 filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->absolutePaintRect())); 169 filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect()), srcRect, CompositeSourceAtop); 148 170 break; 149 171 case FECOMPOSITE_OPERATOR_XOR: 150 filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2-> repaintRectInLocalCoordinates()));151 filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in-> repaintRectInLocalCoordinates()), srcRect, CompositeXOR);172 filterContext->drawImageBuffer(in2->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in2->absolutePaintRect())); 173 filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegionOfInputImage(in->absolutePaintRect()), srcRect, CompositeXOR); 152 174 break; 153 175 case FECOMPOSITE_OPERATOR_ARITHMETIC: { 154 IntRect effectADrawingRect = requestedRegionOfInputImageData(in-> repaintRectInLocalCoordinates());176 IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); 155 177 RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data()); 156 178 157 IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2-> repaintRectInLocalCoordinates());179 IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect()); 158 180 RefPtr<ImageData> imageData(in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)); 159 181 CanvasPixelArray* srcPixelArrayB(imageData->data()); -
trunk/WebCore/platform/graphics/filters/FEComposite.h
r67929 r69181 62 62 virtual void apply(Filter*); 63 63 virtual void dump(); 64 65 virtual void determineAbsolutePaintRect(Filter*); 64 66 65 67 virtual TextStream& externalRepresentation(TextStream&, int indention) const; -
trunk/WebCore/platform/graphics/filters/FEConvolveMatrix.cpp
r68022 r69181 378 378 return; 379 379 380 if (!effectContext( ))380 if (!effectContext(filter)) 381 381 return; 382 382 383 383 IntRect imageRect(IntPoint(), resultImage()->size()); 384 IntRect effectDrawingRect = requestedRegionOfInputImageData(in-> filterPrimitiveSubregion());384 IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); 385 385 386 386 RefPtr<CanvasPixelArray> srcPixelArray; -
trunk/WebCore/platform/graphics/filters/FEConvolveMatrix.h
r68022 r69181 76 76 virtual void dump(); 77 77 78 virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); } 79 78 80 virtual TextStream& externalRepresentation(TextStream&, int indention) const; 79 81 -
trunk/WebCore/platform/graphics/filters/FEDisplacementMap.cpp
r68022 r69181 4 4 * Copyright (C) 2005 Eric Seidel <eric@webkit.org> 5 5 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 6 7 * 7 8 * This library is free software; you can redistribute it and/or … … 89 90 return; 90 91 91 if (!effectContext( ))92 if (!effectContext(filter)) 92 93 return; 93 94 94 IntRect effectADrawingRect = requestedRegionOfInputImageData(in-> repaintRectInLocalCoordinates());95 IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); 95 96 RefPtr<CanvasPixelArray> srcPixelArrayA(in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data()); 96 97 97 IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2-> repaintRectInLocalCoordinates());98 IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect()); 98 99 RefPtr<CanvasPixelArray> srcPixelArrayB(in2->resultImage()->getUnmultipliedImageData(effectBDrawingRect)->data()); 99 100 … … 103 104 ASSERT(srcPixelArrayA->length() == srcPixelArrayB->length()); 104 105 105 float scaleX = m_scale / 255.f * filter->filterResolution().width();106 float scaleY = m_scale / 255.f * filter->filterResolution().height();107 float scaleAdjustmentX = (0.5f - 0.5f * m_scale) * filter->filterResolution().width();108 float scaleAdjustmentY = (0.5f - 0.5f * m_scale) * filter->filterResolution().height();106 float scaleX = filter->applyHorizontalScale(m_scale / 255); 107 float scaleY = filter->applyVerticalScale(m_scale / 255); 108 float scaleAdjustmentX = filter->applyHorizontalScale(0.5f - 0.5f * m_scale); 109 float scaleAdjustmentY = filter->applyVerticalScale(0.5f - 0.5f * m_scale); 109 110 int stride = imageRect.width() * 4; 110 111 for (int y = 0; y < imageRect.height(); ++y) { -
trunk/WebCore/platform/graphics/filters/FEDisplacementMap.h
r68022 r69181 54 54 virtual void dump(); 55 55 56 virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); } 57 56 58 virtual TextStream& externalRepresentation(TextStream&, int indention) const; 57 59 -
trunk/WebCore/platform/graphics/filters/FEFlood.cpp
r68022 r69181 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 68 if (!filterContext) 69 69 return; 70 70 71 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 -
trunk/WebCore/platform/graphics/filters/FEFlood.h
r68022 r69181 43 43 virtual void dump(); 44 44 45 virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); } 46 45 47 virtual TextStream& externalRepresentation(TextStream&, int indention) const; 46 48 -
trunk/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
r67929 r69181 5 5 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> 6 6 * Copyright (C) 2010 Igalia, S.L. 7 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 7 8 * 8 9 * This library is free software; you can redistribute it and/or … … 35 36 using std::max; 36 37 37 static const float gGaussianKernelFactor = (3 * sqrtf(2 * piFloat) / 4.f); 38 static const float gGaussianKernelFactor = 3 / 4.f * sqrtf(2 * piFloat); 39 static const unsigned gMaxKernelSize = 1000; 38 40 39 41 namespace WebCore { … … 126 128 } 127 129 130 inline void calculateKernelSize(Filter* filter, unsigned& kernelSizeX, unsigned& kernelSizeY, float stdX, float stdY) 131 { 132 stdX = filter->applyHorizontalScale(stdX); 133 stdY = filter->applyVerticalScale(stdY); 134 135 kernelSizeX = 0; 136 if (stdX) 137 kernelSizeX = max<unsigned>(2, static_cast<unsigned>(floorf(stdX * gGaussianKernelFactor + 0.5f))); 138 kernelSizeY = 0; 139 if (stdY) 140 kernelSizeY = max<unsigned>(2, static_cast<unsigned>(floorf(stdY * gGaussianKernelFactor + 0.5f))); 141 142 // Limit the kernel size to 1000. A bigger radius won't make a big difference for the result image but 143 // inflates the absolute paint rect to much. This is compatible with Firefox' behavior. 144 if (kernelSizeX > gMaxKernelSize) 145 kernelSizeX = gMaxKernelSize; 146 if (kernelSizeY > gMaxKernelSize) 147 kernelSizeY = gMaxKernelSize; 148 } 149 150 void FEGaussianBlur::determineAbsolutePaintRect(Filter* filter) 151 { 152 FloatRect absolutePaintRect = inputEffect(0)->absolutePaintRect(); 153 absolutePaintRect.intersect(maxEffectRect()); 154 155 unsigned kernelSizeX = 0; 156 unsigned kernelSizeY = 0; 157 calculateKernelSize(filter, kernelSizeX, kernelSizeY, m_stdX, m_stdY); 158 159 // We take the half kernel size and multiply it with three, because we run box blur three times. 160 absolutePaintRect.inflateX(3 * kernelSizeX * 0.5f); 161 absolutePaintRect.inflateY(3 * kernelSizeY * 0.5f); 162 setAbsolutePaintRect(enclosingIntRect(absolutePaintRect)); 163 } 164 128 165 void FEGaussianBlur::apply(Filter* filter) 129 166 { … … 133 170 return; 134 171 135 if (!effectContext( ))172 if (!effectContext(filter)) 136 173 return; 137 174 138 175 setIsAlphaImage(in->isAlphaImage()); 139 176 140 IntRect effectDrawingRect = requestedRegionOfInputImageData(in-> repaintRectInLocalCoordinates());177 IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); 141 178 RefPtr<ImageData> srcImageData(in->resultImage()->getPremultipliedImageData(effectDrawingRect)); 142 179 IntRect imageRect(IntPoint(), resultImage()->size()); … … 148 185 149 186 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 187 unsigned kernelSizeY = 0; 154 if (m_stdY) 155 kernelSizeY = max(2U, static_cast<unsigned>(floor(m_stdY * filter->filterResolution().height() * gGaussianKernelFactor + 0.5f))); 188 calculateKernelSize(filter, kernelSizeX, kernelSizeY, m_stdX, m_stdY); 156 189 157 190 CanvasPixelArray* srcPixelArray(srcImageData->data()); -
trunk/WebCore/platform/graphics/filters/FEGaussianBlur.h
r67929 r69181 43 43 virtual void apply(Filter*); 44 44 virtual void dump(); 45 46 virtual void determineAbsolutePaintRect(Filter*); 45 47 46 48 virtual TextStream& externalRepresentation(TextStream&, int indention) const; -
trunk/WebCore/platform/graphics/filters/FELighting.cpp
r68022 r69181 248 248 return; 249 249 250 if (!effectContext( ))250 if (!effectContext(filter)) 251 251 return; 252 252 253 253 setIsAlphaImage(false); 254 254 255 IntRect effectDrawingRect = requestedRegionOfInputImageData(in-> repaintRectInLocalCoordinates());255 IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); 256 256 RefPtr<ImageData> srcImageData(in->resultImage()->getUnmultipliedImageData(effectDrawingRect)); 257 257 CanvasPixelArray* srcPixelArray(srcImageData->data()); … … 262 262 // Anyway, feConvolveMatrix should also use the implementation 263 263 264 if (drawLighting(srcPixelArray, effectDrawingRect.width(), effectDrawingRect.height())) 265 resultImage()->putUnmultipliedImageData(srcImageData.get(), IntRect(IntPoint(), resultImage()->size()), IntPoint()); 264 IntSize absolutePaintSize = absolutePaintRect().size(); 265 if (drawLighting(srcPixelArray, absolutePaintSize.width(), absolutePaintSize.height())) 266 resultImage()->putUnmultipliedImageData(srcImageData.get(), IntRect(IntPoint(), absolutePaintSize), IntPoint()); 266 267 } 267 268 -
trunk/WebCore/platform/graphics/filters/FELighting.h
r68022 r69181 44 44 public: 45 45 virtual void apply(Filter*); 46 47 virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); } 46 48 47 49 protected: -
trunk/WebCore/platform/graphics/filters/FEMerge.cpp
r68022 r69181 51 51 } 52 52 53 GraphicsContext* filterContext = effectContext( );53 GraphicsContext* filterContext = effectContext(filter); 54 54 if (!filterContext) 55 55 return; … … 57 57 for (unsigned i = 0; i < size; ++i) { 58 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 } -
trunk/WebCore/platform/graphics/filters/FEMorphology.cpp
r68022 r69181 4 4 * Copyright (C) 2005 Eric Seidel <eric@webkit.org> 5 5 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 6 7 * 7 8 * This library is free software; you can redistribute it and/or … … 75 76 } 76 77 78 void FEMorphology::determineAbsolutePaintRect(Filter* filter) 79 { 80 FloatRect paintRect = inputEffect(0)->absolutePaintRect(); 81 paintRect.inflateX(filter->applyHorizontalScale(m_radiusX)); 82 paintRect.inflateY(filter->applyVerticalScale(m_radiusY)); 83 setAbsolutePaintRect(enclosingIntRect(paintRect)); 84 } 85 77 86 void FEMorphology::setRadiusY(float radiusY) 78 87 { … … 87 96 return; 88 97 89 if (!effectContext( ))98 if (!effectContext(filter)) 90 99 return; 91 100 92 101 setIsAlphaImage(in->isAlphaImage()); 93 94 int radiusX = static_cast<int>(m_radiusX * filter->filterResolution().width()); 95 int radiusY = static_cast<int>(m_radiusY * filter->filterResolution().height()); 96 if (radiusX <= 0 || radiusY <= 0) 102 if (m_radiusX <= 0 || m_radiusY <= 0) 97 103 return; 98 104 105 int radiusX = static_cast<int>(floorf(filter->applyHorizontalScale(m_radiusX))); 106 int radiusY = static_cast<int>(floorf(filter->applyVerticalScale(m_radiusY))); 107 99 108 IntRect imageRect(IntPoint(), resultImage()->size()); 100 IntRect effectDrawingRect = requestedRegionOfInputImageData(in-> repaintRectInLocalCoordinates());109 IntRect effectDrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); 101 110 RefPtr<CanvasPixelArray> srcPixelArray(in->resultImage()->getPremultipliedImageData(effectDrawingRect)->data()); 102 111 RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height()); -
trunk/WebCore/platform/graphics/filters/FEMorphology.h
r68022 r69181 50 50 virtual void dump(); 51 51 52 virtual void determineAbsolutePaintRect(Filter*); 53 52 54 virtual TextStream& externalRepresentation(TextStream&, int indention) const; 53 55 -
trunk/WebCore/platform/graphics/filters/FEOffset.cpp
r68022 r69181 4 4 * Copyright (C) 2005 Eric Seidel <eric@webkit.org> 5 5 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> 6 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 6 7 * 7 8 * This library is free software; you can redistribute it and/or … … 63 64 } 64 65 66 void FEOffset::determineAbsolutePaintRect(Filter* filter) 67 { 68 FloatRect paintRect = inputEffect(0)->absolutePaintRect(); 69 paintRect.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy)); 70 paintRect.intersect(maxEffectRect()); 71 setAbsolutePaintRect(enclosingIntRect(paintRect)); 72 } 73 65 74 void FEOffset::apply(Filter* filter) 66 75 { … … 70 79 return; 71 80 72 GraphicsContext* filterContext = effectContext( );81 GraphicsContext* filterContext = effectContext(filter); 73 82 if (!filterContext) 74 83 return; … … 76 85 setIsAlphaImage(in->isAlphaImage()); 77 86 78 FloatRect sourceImageRect = filter->sourceImageRect(); 79 sourceImageRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); 80 81 if (filter->effectBoundingBoxMode()) { 82 m_dx *= sourceImageRect.width(); 83 m_dy *= sourceImageRect.height(); 84 } 85 m_dx *= filter->filterResolution().width(); 86 m_dy *= filter->filterResolution().height(); 87 88 FloatRect dstRect = FloatRect(m_dx + in->repaintRectInLocalCoordinates().x() - repaintRectInLocalCoordinates().x(), 89 m_dy + in->repaintRectInLocalCoordinates().y() - repaintRectInLocalCoordinates().y(), 90 in->repaintRectInLocalCoordinates().width(), 91 in->repaintRectInLocalCoordinates().height()); 92 93 filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, dstRect); 87 FloatRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect()); 88 drawingRegion.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy)); 89 filterContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, drawingRegion); 94 90 } 95 91 -
trunk/WebCore/platform/graphics/filters/FEOffset.h
r68022 r69181 41 41 virtual void apply(Filter*); 42 42 virtual void dump(); 43 44 virtual void determineAbsolutePaintRect(Filter*); 43 45 44 46 virtual TextStream& externalRepresentation(TextStream&, int indention) const; -
trunk/WebCore/platform/graphics/filters/FETile.cpp
r68022 r69181 28 28 #include "GraphicsContext.h" 29 29 #include "Pattern.h" 30 #include "SVGImageBufferTools.h" 30 31 31 32 namespace WebCore { … … 45 46 inputEffect(0)->determineFilterPrimitiveSubregion(filter); 46 47 47 filter->determineFilterPrimitiveSubregion(this, filter->filterRegion ());48 filter->determineFilterPrimitiveSubregion(this, filter->filterRegionInUserSpace()); 48 49 return filterPrimitiveSubregion(); 49 50 } … … 56 57 return; 57 58 58 GraphicsContext* filterContext = effectContext( );59 GraphicsContext* filterContext = effectContext(filter); 59 60 if (!filterContext) 60 61 return; … … 62 63 setIsAlphaImage(in->isAlphaImage()); 63 64 64 IntRect tileRect = enclosingIntRect(in->repaintRectInLocalCoordinates());65 66 65 // Source input needs more attention. It has the size of the filterRegion but gives the 67 66 // size of the cutted sourceImage back. This is part of the specification and optimization. 67 FloatRect tileRect = in->maxEffectRect(); 68 FloatPoint inMaxEffectLocation = tileRect.location(); 69 FloatPoint maxEffectLocation = maxEffectRect().location(); 68 70 if (in->isSourceInput()) { 69 FloatRect filterRegion = filter->filterRegion(); 70 filterRegion.scale(filter->filterResolution().width(), filter->filterResolution().height()); 71 tileRect = enclosingIntRect(filterRegion); 71 tileRect = filter->filterRegion(); 72 tileRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); 72 73 } 73 74 74 OwnPtr<ImageBuffer> tileImage = ImageBuffer::create(tileRect.size()); 75 OwnPtr<ImageBuffer> tileImage; 76 if (!SVGImageBufferTools::createImageBuffer(tileRect, tileRect, tileImage, DeviceRGB)) 77 return; 78 75 79 GraphicsContext* tileImageContext = tileImage->context(); 76 tileImageContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, IntPoint()); 80 tileImageContext->translate(-inMaxEffectLocation.x(), -inMaxEffectLocation.y()); 81 tileImageContext->drawImageBuffer(in->resultImage(), DeviceColorSpace, in->absolutePaintRect().location()); 82 77 83 RefPtr<Pattern> pattern = Pattern::create(tileImage->copyImage(), true, true); 78 84 79 AffineTransform matrix; 80 matrix.translate(in->repaintRectInLocalCoordinates().x() - repaintRectInLocalCoordinates().x(), 81 in->repaintRectInLocalCoordinates().y() - repaintRectInLocalCoordinates().y()); 82 pattern.get()->setPatternSpaceTransform(matrix); 83 85 AffineTransform patternTransform; 86 patternTransform.translate(inMaxEffectLocation.x() - maxEffectLocation.x(), inMaxEffectLocation.y() - maxEffectLocation.y()); 87 pattern->setPatternSpaceTransform(patternTransform); 84 88 filterContext->setFillPattern(pattern); 85 filterContext->fillRect(FloatRect(FloatPoint(), repaintRectInLocalCoordinates().size()));89 filterContext->fillRect(FloatRect(FloatPoint(), absolutePaintRect().size())); 86 90 } 87 91 -
trunk/WebCore/platform/graphics/filters/FETile.h
r68022 r69181 36 36 virtual void dump(); 37 37 38 virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); } 39 38 40 virtual TextStream& externalRepresentation(TextStream&, int indention) const; 39 41 -
trunk/WebCore/platform/graphics/filters/FETurbulence.cpp
r68022 r69181 322 322 void FETurbulence::apply(Filter* filter) 323 323 { 324 if (!effectContext( ))324 if (!effectContext(filter)) 325 325 return; 326 326 … … 330 330 331 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 333 initPaint(paintingData); 334 334 335 FloatRect filterRegion = filter->filterRegion();335 FloatRect filterRegion = absolutePaintRect(); 336 336 FloatPoint point; 337 337 point.setY(filterRegion.y()); … … 343 343 point.setX(point.x() + 1); 344 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 } -
trunk/WebCore/platform/graphics/filters/FETurbulence.h
r68022 r69181 61 61 virtual void apply(Filter*); 62 62 virtual void dump(); 63 64 virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); } 63 65 64 66 virtual TextStream& externalRepresentation(TextStream&, int indention) const; -
trunk/WebCore/platform/graphics/filters/Filter.h
r67929 r69181 45 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 50 virtual FloatRect sourceImageRect() const = 0; 48 51 virtual FloatRect filterRegion() const = 0; 52 53 virtual FloatPoint mapAbsolutePointToLocalPoint(const FloatPoint&) const { return FloatPoint(); } 49 54 50 55 // SVG specific 51 56 virtual void determineFilterPrimitiveSubregion(FilterEffect*, const FloatRect&) { } 57 58 virtual FloatRect filterRegionInUserSpace() const { return FloatRect(); } 52 59 53 60 virtual FloatSize maxImageSize() const = 0; -
trunk/WebCore/platform/graphics/filters/FilterEffect.cpp
r67929 r69181 47 47 // FETurbulence, FEImage and FEFlood don't have input effects, take the filter region as unite rect. 48 48 if (!size) 49 uniteRect = filter->filterRegion ();49 uniteRect = filter->filterRegionInUserSpace(); 50 50 else { 51 51 for (unsigned i = 0; i < size; ++i) … … 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 72 ASSERT(m_effectBuffer); 62 FloatPoint location = m_repaintRectInLocalCoordinates.location();73 IntPoint location = m_absolutePaintRect.location(); 63 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) const78 IntRect FilterEffect::drawingRegionOfInputImage(const IntRect& srcRect) const 68 79 { 69 return FloatRect(FloatPoint(srcRect.x() - m_repaintRectInLocalCoordinates.x(),70 srcRect.y() - m_repaintRectInLocalCoordinates.y()), srcRect.size());80 return IntRect(IntPoint(srcRect.x() - m_absolutePaintRect.x(), 81 srcRect.y() - m_absolutePaintRect.y()), srcRect.size()); 71 82 } 72 83 … … 77 88 } 78 89 79 GraphicsContext* FilterEffect::effectContext( )90 GraphicsContext* FilterEffect::effectContext(Filter* filter) 80 91 { 81 IntRect bufferRect = enclosingIntRect(m_repaintRectInLocalCoordinates); 82 m_effectBuffer = ImageBuffer::create(bufferRect.size(), LinearRGB); 92 determineAbsolutePaintRect(filter); 93 if (m_absolutePaintRect.isEmpty()) 94 return 0; 95 m_effectBuffer = ImageBuffer::create(m_absolutePaintRect.size(), LinearRGB); 83 96 if (!m_effectBuffer) 84 97 return 0; -
trunk/WebCore/platform/graphics/filters/FilterEffect.h
r67929 r69181 50 50 // Creates the ImageBuffer for the current filter primitive result in the size of the 51 51 // repaintRect. Gives back the GraphicsContext of the own ImageBuffer. 52 GraphicsContext* effectContext( );52 GraphicsContext* effectContext(Filter*); 53 53 54 54 FilterEffectVector& inputEffects() { return m_inputEffects; } … … 56 56 unsigned numberOfEffectInputs() const { return m_inputEffects.size(); } 57 57 58 FloatRect drawingRegionOfInputImage(const FloatRect&) const;59 IntRect requestedRegionOfInputImageData(const FloatRect&) const;58 IntRect drawingRegionOfInputImage(const IntRect&) const; 59 IntRect requestedRegionOfInputImageData(const IntRect&) const; 60 60 61 61 // Solid black image with different alpha values. … … 63 63 void setIsAlphaImage(bool alphaImage) { m_alphaImage = alphaImage; } 64 64 65 FloatRect repaintRectInLocalCoordinates() const { return m_repaintRectInLocalCoordinates; } 66 void setRepaintRectInLocalCoordinates(const FloatRect& repaintRectInLocalCoordinates) { m_repaintRectInLocalCoordinates = repaintRectInLocalCoordinates; } 65 IntRect absolutePaintRect() const { return m_absolutePaintRect; } 66 void setAbsolutePaintRect(const IntRect& absolutePaintRect) { m_absolutePaintRect = absolutePaintRect; } 67 68 IntRect maxEffectRect() const { return m_maxEffectRect; } 69 void setMaxEffectRect(const IntRect& maxEffectRect) { m_maxEffectRect = maxEffectRect; } 67 70 68 71 virtual void apply(Filter*) = 0; 69 72 virtual void dump() = 0; 70 73 74 virtual void determineAbsolutePaintRect(Filter*); 75 71 76 virtual bool isSourceInput() const { return false; } 72 77 … … 88 93 void setHasHeight(bool value) { m_hasHeight = value; } 89 94 90 // FIXME: Pseudo primitives like SourceGraphic and SourceAlpha as well as FETile still needspecial handling.95 // FIXME: FETile still needs special handling. 91 96 virtual FloatRect determineFilterPrimitiveSubregion(Filter*); 92 97 … … 106 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. 109 FloatRect m_repaintRectInLocalCoordinates; 113 IntRect m_absolutePaintRect; 114 115 // The maximum size of a filter primitive. In SVG this is the primitive subregion in absolute coordinate space. 116 // The absolute paint rect should never be bigger than m_maxEffectRect. 117 IntRect m_maxEffectRect; 110 118 111 119 private: -
trunk/WebCore/platform/graphics/filters/SourceAlpha.cpp
r67929 r69181 43 43 } 44 44 45 FloatRect SourceAlpha::determineFilterPrimitiveSubregion(Filter* filter)45 void SourceAlpha::determineAbsolutePaintRect(Filter* filter) 46 46 { 47 FloatRect clippedSourceRect = filter->sourceImageRect(); 48 if (filter->sourceImageRect().x() < filter->filterRegion().x()) 49 clippedSourceRect.setX(filter->filterRegion().x()); 50 if (filter->sourceImageRect().y() < filter->filterRegion().y()) 51 clippedSourceRect.setY(filter->filterRegion().y()); 52 setFilterPrimitiveSubregion(clippedSourceRect); 53 clippedSourceRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); 54 setRepaintRectInLocalCoordinates(clippedSourceRect); 55 return filter->filterRegion(); 47 FloatRect paintRect = filter->sourceImageRect(); 48 paintRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); 49 setAbsolutePaintRect(enclosingIntRect(paintRect)); 56 50 } 57 51 58 52 void SourceAlpha::apply(Filter* filter) 59 53 { 60 GraphicsContext* filterContext = effectContext( );61 if (!filterContext )54 GraphicsContext* filterContext = effectContext(filter); 55 if (!filterContext || !filter->sourceImage()) 62 56 return; 63 57 64 58 setIsAlphaImage(true); 65 59 66 FloatRect imageRect(FloatPoint(), filter->sourceImage()->size());60 FloatRect imageRect(FloatPoint(), absolutePaintRect().size()); 67 61 filterContext->save(); 68 62 filterContext->clipToImageBuffer(filter->sourceImage(), imageRect); -
trunk/WebCore/platform/graphics/filters/SourceAlpha.h
r67929 r69181 35 35 static const AtomicString& effectName(); 36 36 37 virtual FloatRect determineFilterPrimitiveSubregion(Filter*);38 39 37 virtual void apply(Filter*); 40 38 virtual void dump(); 39 40 virtual void determineAbsolutePaintRect(Filter*); 41 41 42 42 virtual bool isSourceInput() const { return true; } -
trunk/WebCore/platform/graphics/filters/SourceGraphic.cpp
r67929 r69181 42 42 } 43 43 44 FloatRect SourceGraphic::determineFilterPrimitiveSubregion(Filter* filter)44 void SourceGraphic::determineAbsolutePaintRect(Filter* filter) 45 45 { 46 FloatRect clippedSourceRect = filter->sourceImageRect(); 47 if (filter->sourceImageRect().x() < filter->filterRegion().x()) 48 clippedSourceRect.setX(filter->filterRegion().x()); 49 if (filter->sourceImageRect().y() < filter->filterRegion().y()) 50 clippedSourceRect.setY(filter->filterRegion().y()); 51 setFilterPrimitiveSubregion(clippedSourceRect); 52 clippedSourceRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); 53 setRepaintRectInLocalCoordinates(clippedSourceRect); 54 return filter->filterRegion(); 46 FloatRect paintRect = filter->sourceImageRect(); 47 paintRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); 48 setAbsolutePaintRect(enclosingIntRect(paintRect)); 55 49 } 56 50 57 51 void SourceGraphic::apply(Filter* filter) 58 52 { 59 GraphicsContext* filterContext = effectContext( );60 if (!filterContext )53 GraphicsContext* filterContext = effectContext(filter); 54 if (!filterContext || !filter->sourceImage()) 61 55 return; 62 56 -
trunk/WebCore/platform/graphics/filters/SourceGraphic.h
r67929 r69181 36 36 static const AtomicString& effectName(); 37 37 38 virtual FloatRect determineFilterPrimitiveSubregion(Filter*);39 40 38 virtual void apply(Filter*); 41 39 virtual void dump(); 40 41 virtual void determineAbsolutePaintRect(Filter*); 42 42 43 43 virtual bool isSourceInput() const { return true; } -
trunk/WebCore/rendering/RenderSVGResourceFilter.cpp
r68385 r69181 40 40 #include "SVGFilterElement.h" 41 41 #include "SVGFilterPrimitiveStandardAttributes.h" 42 #include "SVGImageBufferTools.h" 42 43 #include "SVGStyledElement.h" 43 44 #include "SVGUnitTypes.h" … … 151 152 152 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 be able to produce unsheared tile images for feTile. 168 filterData->shearFreeAbsoluteTransform = AffineTransform(absoluteTransform.xScale(), 0, 0, absoluteTransform.yScale(), absoluteTransform.e(), absoluteTransform.f()); 169 170 // Determine absolute boundaries of the filter and the drawing region. 171 FloatRect absoluteFilterBoundaries = filterData->shearFreeAbsoluteTransform.mapRect(filterData->boundaries); 172 FloatRect drawingRegion = object->strokeBoundingBox(); 173 drawingRegion.intersect(filterData->boundaries); 174 FloatRect absoluteDrawingRegion = filterData->shearFreeAbsoluteTransform.mapRect(drawingRegion); 175 176 // Create the SVGFilter object. 177 bool primitiveBoundingBoxMode = filterElement->primitiveUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; 178 filterData->filter = SVGFilter::create(filterData->shearFreeAbsoluteTransform, absoluteDrawingRegion, targetBoundingBox, filterData->boundaries, primitiveBoundingBoxMode); 179 180 // Create all relevant filter primitives. 153 181 filterData->builder = buildPrimitives(); 154 182 if (!filterData->builder) 155 183 return false; 156 184 157 FloatRect paintRect = object->strokeBoundingBox();158 159 185 // Calculate the scale factor for the use of filterRes. 160 186 // Also see http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion 161 SVGFilterElement* filterElement = static_cast<SVGFilterElement*>(node()); 162 filterData->boundaries = filterElement->filterBoundingBox(object->objectBoundingBox()); 163 if (filterData->boundaries.isEmpty()) 164 return false; 165 166 FloatSize scale(1.0f, 1.0f); 187 FloatSize scale(1, 1); 167 188 if (filterElement->hasAttribute(SVGNames::filterResAttr)) { 168 scale.setWidth(filterElement->filterResX() / filterData->boundaries.width());169 scale.setHeight(filterElement->filterResY() / filterData->boundaries.height());189 scale.setWidth(filterElement->filterResX() / absoluteFilterBoundaries.width()); 190 scale.setHeight(filterElement->filterResY() / absoluteFilterBoundaries.height()); 170 191 } 171 192 … … 173 194 return false; 174 195 175 // clip sourceImage to filterRegion 176 FloatRect clippedSourceRect = paintRect; 177 clippedSourceRect.intersect(filterData->boundaries); 178 179 // scale filter size to filterRes 180 FloatRect tempSourceRect = clippedSourceRect; 181 182 // scale to big sourceImage size to kMaxFilterSize 196 // Determine scale factor for filter. The size of intermediate ImageBuffers shouldn't be bigger than kMaxFilterSize. 197 FloatRect tempSourceRect = absoluteDrawingRegion; 183 198 tempSourceRect.scale(scale.width(), scale.height()); 184 199 fitsInMaximumImageSize(tempSourceRect.size(), scale); 185 200 186 // prepare Filters 187 bool primitiveBoundingBoxMode = filterElement->primitiveUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; 188 filterData->filter = SVGFilter::create(paintRect, filterData->boundaries, primitiveBoundingBoxMode); 201 // Set the scale level in SVGFilter. 189 202 filterData->filter->setFilterResolution(scale); 190 203 … … 192 205 if (!lastEffect) 193 206 return false; 194 207 208 // Determine the filter primitive subregions of every effect. 195 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 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 213 filterData->filter->setFilterResolution(scale); 200 214 lastEffect->determineFilterPrimitiveSubregion(filterData->filter.get()); 201 215 } 202 216 203 clippedSourceRect.scale(scale.width(), scale.height()); 204 205 // Draw the content of the current element and it's childs to a imageBuffer to get the SourceGraphic. 206 // The size of the SourceGraphic is clipped to the size of the filterRegion. 207 IntRect bufferRect = enclosingIntRect(clippedSourceRect); 208 OwnPtr<ImageBuffer> sourceGraphic(ImageBuffer::create(bufferRect.size(), LinearRGB)); 217 // If the drawingRegion is empty, we have something like <g filter=".."/>. 218 // Even if the target objectBoundingBox() is empty, we still have to draw the last effect result image in postApplyResource. 219 if (drawingRegion.isEmpty()) { 220 ASSERT(!m_filter.contains(object)); 221 filterData->savedContext = context; 222 m_filter.set(object, filterData.leakPtr()); 223 return false; 224 } 225 226 absoluteDrawingRegion.scale(scale.width(), scale.height()); 227 228 OwnPtr<ImageBuffer> sourceGraphic; 229 if (!SVGImageBufferTools::createImageBuffer(absoluteDrawingRegion, absoluteDrawingRegion, sourceGraphic, LinearRGB)) 230 return false; 209 231 210 if (!sourceGraphic.get())211 return false;212 213 232 GraphicsContext* sourceGraphicContext = sourceGraphic->context(); 214 sourceGraphicContext->translate(-clippedSourceRect.x(), -clippedSourceRect.y()); 215 sourceGraphicContext->scale(scale); 216 sourceGraphicContext->clearRect(FloatRect(FloatPoint(), paintRect.size())); 233 ASSERT(sourceGraphicContext); 234 235 sourceGraphicContext->translate(-absoluteDrawingRegion.x(), -absoluteDrawingRegion.y()); 236 if (scale.width() != 1 || scale.height() != 1) 237 sourceGraphicContext->scale(scale); 238 239 sourceGraphicContext->concatCTM(filterData->shearFreeAbsoluteTransform); 240 sourceGraphicContext->clearRect(FloatRect(FloatPoint(), absoluteDrawingRegion.size())); 217 241 filterData->sourceGraphicBuffer = sourceGraphic.release(); 218 242 filterData->savedContext = context; … … 271 295 272 296 ImageBuffer* resultImage = lastEffect->resultImage(); 273 if (resultImage) 274 context->drawImageBuffer(resultImage, object->style()->colorSpace(), lastEffect->filterPrimitiveSubregion()); 275 } 276 297 if (resultImage) { 298 context->concatCTM(filterData->shearFreeAbsoluteTransform.inverse()); 299 300 context->scale(FloatSize(1 / filterData->filter->filterResolution().width(), 1 / filterData->filter->filterResolution().height())); 301 context->clip(lastEffect->maxEffectRect()); 302 context->drawImageBuffer(resultImage, object->style()->colorSpace(), lastEffect->absolutePaintRect()); 303 context->scale(filterData->filter->filterResolution()); 304 305 context->concatCTM(filterData->shearFreeAbsoluteTransform); 306 } 307 } 277 308 filterData->sourceGraphicBuffer.clear(); 278 309 } -
trunk/WebCore/rendering/RenderSVGResourceFilter.h
r65310 r69181 43 43 struct FilterData { 44 44 FilterData() 45 : builded(false) 45 : savedContext(0) 46 , builded(false) 46 47 { 47 48 } … … 51 52 OwnPtr<ImageBuffer> sourceGraphicBuffer; 52 53 GraphicsContext* savedContext; 54 AffineTransform shearFreeAbsoluteTransform; 53 55 FloatRect boundaries; 54 56 FloatSize scale; -
trunk/WebCore/svg/graphics/filters/SVGFEImage.cpp
r67929 r69181 45 45 } 46 46 47 void FEImage::apply(Filter* )47 void FEImage::apply(Filter* filter) 48 48 { 49 49 if (!m_image.get()) 50 50 return; 51 51 52 GraphicsContext* filterContext = effectContext( );52 GraphicsContext* filterContext = effectContext(filter); 53 53 if (!filterContext) 54 54 return; 55 55 56 56 FloatRect srcRect(FloatPoint(), m_image->size()); 57 FloatRect destRect(FloatPoint(), filterPrimitiveSubregion().size());57 FloatRect destRect(FloatPoint(), absolutePaintRect().size()); 58 58 59 59 m_preserveAspectRatio.transformRect(destRect, srcRect); -
trunk/WebCore/svg/graphics/filters/SVGFEImage.h
r67929 r69181 37 37 virtual void dump(); 38 38 39 virtual void determineAbsolutePaintRect(Filter*) { setAbsolutePaintRect(maxEffectRect()); } 40 39 41 virtual TextStream& externalRepresentation(TextStream&, int indention) const; 40 42 -
trunk/WebCore/svg/graphics/filters/SVGFilter.cpp
r67847 r69181 1 1 /* 2 2 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> 3 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 3 4 * 4 5 * This library is free software; you can redistribute it and/or … … 25 26 namespace WebCore { 26 27 27 SVGFilter::SVGFilter(const FloatRect& targetBoundingBox, const FloatRect& filterRect, bool effectBBoxMode)28 SVGFilter::SVGFilter(const AffineTransform& absoluteTransform, const FloatRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode) 28 29 : Filter() 30 , m_absoluteTransform(absoluteTransform) 31 , m_absoluteSourceDrawingRegion(absoluteSourceDrawingRegion) 29 32 , m_targetBoundingBox(targetBoundingBox) 30 , m_filterRe ct(filterRect)33 , m_filterRegion(filterRegion) 31 34 , m_effectBBoxMode(effectBBoxMode) 32 35 { 36 m_absoluteFilterRegion = absoluteTransform.mapRect(filterRegion); 33 37 } 34 38 … … 67 71 68 72 // clip every filter effect to the filter region 69 newSubRegion.intersect(m_filterRe ct);73 newSubRegion.intersect(m_filterRegion); 70 74 71 75 effect->setFilterPrimitiveSubregion(newSubRegion); 72 73 76 // TODO: Everything above should be moved to a first phase of layout in RenderSVGResourceFilterPrimitive. 74 77 // The scaling of the subregion to the repaint rect should be merged with a more intelligent repaint logic 75 78 // and moved to the second phase of layout in RenderSVGResourceFilterPrimitive. 76 79 // See bug https://bugs.webkit.org/show_bug.cgi?id=45614. 80 newSubRegion = m_absoluteTransform.mapRect(newSubRegion); 77 81 newSubRegion.scale(filterResolution().width(), filterResolution().height()); 78 effect->setRepaintRectInLocalCoordinates(newSubRegion); 79 m_maxImageSize = m_maxImageSize.expandedTo(newSubRegion.size()); 82 effect->setMaxEffectRect(enclosingIntRect(newSubRegion)); 83 if (!effect->isSourceInput()) 84 m_maxImageSize = m_maxImageSize.expandedTo(newSubRegion.size()); 80 85 } 81 86 82 PassRefPtr<SVGFilter> SVGFilter::create(const FloatRect& targetBoundingBox, const FloatRect& filterRect, bool effectBBoxMode) 87 float SVGFilter::applyHorizontalScale(float value) const 83 88 { 84 return adoptRef(new SVGFilter(targetBoundingBox, filterRect, effectBBoxMode)); 89 if (m_effectBBoxMode) 90 value *= m_targetBoundingBox.width(); 91 return Filter::applyHorizontalScale(value) * m_absoluteFilterRegion.width() / m_filterRegion.width(); 92 } 93 94 float SVGFilter::applyVerticalScale(float value) const 95 { 96 if (m_effectBBoxMode) 97 value *= m_targetBoundingBox.height(); 98 return Filter::applyVerticalScale(value) * m_absoluteFilterRegion.height() / m_filterRegion.height(); 99 } 100 101 PassRefPtr<SVGFilter> SVGFilter::create(const AffineTransform& absoluteTransform, const FloatRect& absoluteSourceDrawingRegion, const FloatRect& targetBoundingBox, const FloatRect& filterRegion, bool effectBBoxMode) 102 { 103 return adoptRef(new SVGFilter(absoluteTransform, absoluteSourceDrawingRegion, targetBoundingBox, filterRegion, effectBBoxMode)); 85 104 } 86 105 -
trunk/WebCore/svg/graphics/filters/SVGFilter.h
r67847 r69181 22 22 23 23 #if ENABLE(SVG) && ENABLE(FILTERS) 24 #include "AffineTransform.h" 24 25 #include "Filter.h" 25 26 #include "FilterEffect.h" … … 33 34 namespace WebCore { 34 35 35 36 37 static PassRefPtr<SVGFilter> create(const FloatRect&, const FloatRect&, bool);36 class SVGFilter : public Filter { 37 public: 38 static PassRefPtr<SVGFilter> create(const AffineTransform&, const FloatRect&, const FloatRect&, const FloatRect&, bool); 38 39 39 40 virtual bool effectBoundingBoxMode() const { return m_effectBBoxMode; } 40 41 41 virtual FloatRect filterRegion() const { return m_filterRect; } 42 43 virtual FloatRect sourceImageRect() const { return m_targetBoundingBox; } 42 virtual FloatRect filterRegionInUserSpace() const { return m_filterRegion; } 43 virtual FloatRect filterRegion() const { return m_absoluteFilterRegion; } 44 44 45 virtual FloatSize maxImageSize() const { return m_maxImageSize; } 46 virtual void determineFilterPrimitiveSubregion(FilterEffect*, const FloatRect&); 45 virtual FloatPoint mapAbsolutePointToLocalPoint(const FloatPoint& point) const { return m_absoluteTransform.inverse().mapPoint(point); } 47 46 48 private:49 SVGFilter(const FloatRect& targetBoundingBox, const FloatRect& filterRect, bool effectBBoxMode);47 virtual float applyHorizontalScale(float value) const; 48 virtual float applyVerticalScale(float value) const; 50 49 51 FloatSize m_maxImageSize; 52 FloatRect m_targetBoundingBox; 53 FloatRect m_filterRect; 54 bool m_effectBBoxMode; 55 }; 50 virtual FloatRect sourceImageRect() const { return m_absoluteSourceDrawingRegion; } 51 52 virtual FloatSize maxImageSize() const { return m_maxImageSize; } 53 virtual void determineFilterPrimitiveSubregion(FilterEffect*, const FloatRect&); 54 55 private: 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 67 } // namespace WebCore
Note: See TracChangeset
for help on using the changeset viewer.