Changeset 51310 in webkit
- Timestamp:
- Nov 23, 2009 8:15:24 AM (14 years ago)
- Location:
- trunk/WebCore
- Files:
-
- 28 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/WebCore/ChangeLog
r51306 r51310 1 2009-11-23 Dirk Schulze <krit@webkit.org> 2 3 Reviewed by Nikolas Zimmermann. 4 5 This is the implementation of the filterRes attribute. It 6 helps the SVG developer to set the quality of a filter by 7 giving the width or height of filter. 8 This patch also sets the filter resolution to lower values 9 if a intermediate ImageBuffer size is bigger than the given 10 maximal size. 11 The maximal size is set to 5000x5000 by default. This is a 12 subjectiv decission. Everthing greater than this values gets 13 sensible slower. Values of 10000x10000 crashed on WebKitGtk. 14 For mobil devices a maximum size of 100x100 or 200x200 seems 15 to be reasonable. 16 The important fact on filter resolution is, that the output 17 size is still the size given by the <filter> element. 18 19 Tests: svg/filters/big-sized-filter-2.svg 20 svg/filters/big-sized-filter.svg 21 svg/filters/filterRes.svg 22 23 * platform/graphics/FloatRect.cpp: 24 (WebCore::FloatRect::scale): Add the abbility to scale a rect by x and y. 25 * platform/graphics/FloatRect.h: 26 (WebCore::FloatRect::scale): Add the abbility to scale a rect by x and y. 27 * platform/graphics/cairo/GraphicsContextCairo.cpp: 28 (WebCore::GraphicsContext::createPlatformShadow): Use scaledSubRegion for 29 calculation. 30 * platform/graphics/filters/FEBlend.cpp: 31 (WebCore::FEBlend::apply): Use scaledSubRegion for effect intern calculations. 32 * platform/graphics/filters/FEColorMatrix.cpp: 33 (WebCore::FEColorMatrix::apply): Use scaledSubRegion for effect intern calculations. 34 * platform/graphics/filters/FEComponentTransfer.cpp: 35 (WebCore::FEComponentTransfer::apply): Use scaledSubRegion for effect intern 36 calculations. 37 * platform/graphics/filters/FEComposite.cpp: 38 (WebCore::FEComposite::apply): Use scaledSubRegion for effect intern calculations. 39 * platform/graphics/filters/FEGaussianBlur.cpp: 40 (WebCore::FEGaussianBlur::apply): Use scaledSubRegion for effect intern calculations. 41 * platform/graphics/filters/Filter.h: Add the abbility to change the quality 42 of a filter output. 43 (WebCore::Filter::filterResolution): 44 (WebCore::Filter::setFilterResolution): 45 (WebCore::Filter::calculateEffectSubRegion): Calculates the correct subRegion 46 as well as the scaledSubRegion. It also searches for the biggest effect size. 47 We have to change the filter resolution, if one intermediate ImageBuffer size 48 doesn't fit in the maximal image size. 49 * platform/graphics/filters/FilterEffect.cpp: 50 (WebCore::FilterEffect::calculateDrawingIntRect): Use scaledSubRegion to get 51 the right part of a previous effect result. 52 (WebCore::FilterEffect::calculateDrawingRect): Use scaledSubRegion to get 53 the right part of a previous effect result. 54 (WebCore::FilterEffect::getEffectContext): Use scaledSubRegion to create 55 a new intermediate ImageBuffer for the result of the current effect. 56 * platform/graphics/filters/FilterEffect.h: 57 (WebCore::FilterEffect::scaledSubRegion): The scaled subRegion of a the 58 filter effect. 59 (WebCore::FilterEffect::setScaledSubRegion): 60 (WebCore::FilterEffect::effectBoundaries): The original values of the 61 EffectElement for a second subRegion calculation. 62 (WebCore::FilterEffect::setEffectBoundaries): 63 * platform/graphics/filters/ImageBufferFilter.cpp: 64 (WebCore::ImageBufferFilter::ImageBufferFilter): Set the scale factor to one. 65 * platform/graphics/filters/ImageBufferFilter.h: 66 (WebCore::ImageBufferFilter::maxImageSize): 67 (WebCore::ImageBufferFilter::calculateEffectSubRegion): 68 * platform/graphics/filters/SourceAlpha.cpp: 69 (WebCore::SourceAlpha::calculateEffectRect): Use scaledSubRegion for effect 70 intern calculations. 71 * platform/graphics/filters/SourceGraphic.cpp: 72 (WebCore::SourceGraphic::calculateEffectRect): Use scaledSubRegion for effect 73 intern calculations. 74 * svg/SVGFilterElement.cpp: 75 (WebCore::SVGFilterElement::parseMappedAttribute): Parse filterRes attribute. 76 (WebCore::SVGFilterElement::buildFilter): Give SVGResourceFilter the current 77 filterResolution. 78 * svg/SVGFilterPrimitiveStandardAttributes.cpp: 79 (WebCore::SVGFilterPrimitiveStandardAttributes::setStandardAttributes): Save 80 values to effectBoundaries of the filter effect 81 * svg/graphics/SVGResourceFilter.cpp: 82 (WebCore::SVGResourceFilter::SVGResourceFilter): 83 (WebCore::shouldProcessFilter): Return signal if a neccessary value is zero. 84 (WebCore::SVGResourceFilter::fitsInMaximumImageSize): Checks if the given size 85 fits into the maximal image size, modifys scale factors if not and return a 86 bool: fits. 87 (WebCore::SVGResourceFilter::prepareFilter): Scale the SourceImage to 88 filterResolution (given by FilterElement or calculated on to big image sizes). 89 Set the scale level to SVGFilter. 90 (WebCore::SVGResourceFilter::applyFilter): Don't apply filters if shouldProcessFilter 91 is wrong. 92 * svg/graphics/SVGResourceFilter.h: 93 (WebCore::SVGResourceFilter::setFilterResolution): FilterResolution of FilterElement. 94 (WebCore::SVGResourceFilter::setHasFilterResolution): Does FilterElement provides 95 a FilterResolution? 96 (WebCore::SVGResourceFilter::scaleX): Current scale factor for horizontal. 97 (WebCore::SVGResourceFilter::scaleY): Current scale factor for vertical. 98 * svg/graphics/filters/SVGFEDisplacementMap.cpp: 99 (WebCore::FEDisplacementMap::apply): Use scaledSubRegion for effect intern calculations. 100 Kernel values are scaled to current filter resolution too. 101 * svg/graphics/filters/SVGFEFlood.cpp: 102 (WebCore::FEFlood::apply): Use scaledSubRegion for effect intern calculations. 103 * svg/graphics/filters/SVGFEMerge.cpp: 104 (WebCore::FEMerge::apply): Use scaledSubRegion for effect intern calculations. 105 Kernel values are scaled to current filter resolution too. 106 * svg/graphics/filters/SVGFEMorphology.cpp: 107 (WebCore::FEMorphology::apply): Use scaledSubRegion for effect intern calculations. 108 Kernel values are scaled to current filter resolution too. 109 * svg/graphics/filters/SVGFEOffset.cpp: 110 (WebCore::FEOffset::apply): Use scaledSubRegion for effect intern calculations. 111 * svg/graphics/filters/SVGFETile.cpp: 112 (WebCore::FETile::apply): Use scaledSubRegion for effect intern calculations. 113 * svg/graphics/filters/SVGFilter.cpp: 114 (WebCore::SVGFilter::calculateEffectSubRegion): Calculate subRegion for LayoutTests, 115 scaledSubRegion according to the current filterResolution and get the maximal image size. 116 * svg/graphics/filters/SVGFilter.h: 117 (WebCore::SVGFilter::effectBoundingBoxMode): Original values of the FilterElement. 118 (WebCore::SVGFilter::filterRegion): Use virtual for clarification. 119 (WebCore::SVGFilter::sourceImageRect): Use virtual for clarification. 120 (WebCore::SVGFilter::maxImageSize): Get the maximal image size. 121 1 122 2009-11-23 Simon Hausmann <simon.hausmann@nokia.com> 2 123 -
trunk/WebCore/platform/graphics/FloatRect.cpp
r39538 r51310 103 103 } 104 104 105 void FloatRect::scale(float s )105 void FloatRect::scale(float sx, float sy) 106 106 { 107 m_location.setX(x() * s );108 m_location.setY(y() * s );109 m_size.setWidth(width() * s );110 m_size.setHeight(height() * s );107 m_location.setX(x() * sx); 108 m_location.setY(y() * sy); 109 m_size.setWidth(width() * sx); 110 m_size.setHeight(height() * sy); 111 111 } 112 112 -
trunk/WebCore/platform/graphics/FloatRect.h
r48469 r51310 121 121 } 122 122 void inflate(float d) { inflateX(d); inflateY(d); } 123 void scale(float s); 123 void scale(float s) { scale(s, s); } 124 void scale(float sx, float sy); 124 125 125 126 #if PLATFORM(CG) -
trunk/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
r51161 r51310 861 861 filter->setSourceImage(buffer.release()); 862 862 RefPtr<FilterEffect> source = SourceGraphic::create(); 863 source->setS ubRegion(FloatRect(FloatPoint(), shadowRect.size()));863 source->setScaledSubRegion(FloatRect(FloatPoint(), shadowRect.size())); 864 864 source->setIsAlphaImage(true); 865 865 RefPtr<FilterEffect> blur = FEGaussianBlur::create(source.get(), kernelSize, kernelSize); 866 blur->setS ubRegion(FloatRect(FloatPoint(), shadowRect.size()));866 blur->setScaledSubRegion(FloatRect(FloatPoint(), shadowRect.size())); 867 867 blur->apply(filter.get()); 868 868 -
trunk/WebCore/platform/graphics/filters/FEBlend.cpp
r47456 r51310 112 112 return; 113 113 114 IntRect effectADrawingRect = calculateDrawingIntRect(m_in->s ubRegion());114 IntRect effectADrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion()); 115 115 RefPtr<CanvasPixelArray> srcPixelArrayA(m_in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data()); 116 116 117 IntRect effectBDrawingRect = calculateDrawingIntRect(m_in2->s ubRegion());117 IntRect effectBDrawingRect = calculateDrawingIntRect(m_in2->scaledSubRegion()); 118 118 RefPtr<CanvasPixelArray> srcPixelArrayB(m_in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)->data()); 119 119 -
trunk/WebCore/platform/graphics/filters/FEColorMatrix.cpp
r51240 r51310 165 165 return; 166 166 167 filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->s ubRegion()));167 filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); 168 168 169 169 IntRect imageRect(IntPoint(), resultImage()->size()); -
trunk/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
r50016 r51310 166 166 (*callEffect[transferFunction[channel].type])(tables[channel], transferFunction[channel]); 167 167 168 IntRect drawingRect = calculateDrawingIntRect(m_in->s ubRegion());168 IntRect drawingRect = calculateDrawingIntRect(m_in->scaledSubRegion()); 169 169 RefPtr<ImageData> imageData(m_in->resultImage()->getUnmultipliedImageData(drawingRect)); 170 170 CanvasPixelArray* srcPixelArray(imageData->data()); -
trunk/WebCore/platform/graphics/filters/FEComposite.cpp
r51240 r51310 134 134 switch (m_type) { 135 135 case FECOMPOSITE_OPERATOR_OVER: 136 filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->s ubRegion()));137 filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->s ubRegion()));136 filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion())); 137 filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); 138 138 break; 139 139 case FECOMPOSITE_OPERATOR_IN: 140 140 filterContext->save(); 141 filterContext->clipToImageBuffer(calculateDrawingRect(m_in2->s ubRegion()), m_in2->resultImage());142 filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->s ubRegion()));141 filterContext->clipToImageBuffer(calculateDrawingRect(m_in2->scaledSubRegion()), m_in2->resultImage()); 142 filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); 143 143 filterContext->restore(); 144 144 break; 145 145 case FECOMPOSITE_OPERATOR_OUT: 146 filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->s ubRegion()));147 filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->s ubRegion()), srcRect, CompositeDestinationOut);146 filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion())); 147 filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion()), srcRect, CompositeDestinationOut); 148 148 break; 149 149 case FECOMPOSITE_OPERATOR_ATOP: 150 filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->s ubRegion()));151 filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->s ubRegion()), srcRect, CompositeSourceAtop);150 filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion())); 151 filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()), srcRect, CompositeSourceAtop); 152 152 break; 153 153 case FECOMPOSITE_OPERATOR_XOR: 154 filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->s ubRegion()));155 filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->s ubRegion()), srcRect, CompositeXOR);154 filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion())); 155 filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()), srcRect, CompositeXOR); 156 156 break; 157 157 case FECOMPOSITE_OPERATOR_ARITHMETIC: { 158 IntRect effectADrawingRect = calculateDrawingIntRect(m_in->s ubRegion());158 IntRect effectADrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion()); 159 159 RefPtr<CanvasPixelArray> srcPixelArrayA(m_in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data()); 160 160 161 IntRect effectBDrawingRect = calculateDrawingIntRect(m_in2->s ubRegion());161 IntRect effectBDrawingRect = calculateDrawingIntRect(m_in2->scaledSubRegion()); 162 162 RefPtr<ImageData> imageData(m_in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)); 163 163 CanvasPixelArray* srcPixelArrayB(imageData->data()); -
trunk/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
r50118 r51310 32 32 #include <math.h> 33 33 #include <wtf/MathExtras.h> 34 35 using std::max; 34 36 35 37 namespace WebCore { … … 112 114 return; 113 115 114 unsigned sdx = static_cast<unsigned>(floor(m_x * 3 * sqrt(2 * piDouble) / 4.f + 0.5f)); 115 unsigned sdy = static_cast<unsigned>(floor(m_y * 3 * sqrt(2 * piDouble) / 4.f + 0.5f)); 116 unsigned sdx = static_cast<unsigned>(floor(m_x * filter->filterResolution().width() * 3 * sqrt(2 * piDouble) / 4.f + 0.5f)); 117 unsigned sdy = static_cast<unsigned>(floor(m_y * filter->filterResolution().height() * 3 * sqrt(2 * piDouble) / 4.f + 0.5f)); 118 sdx = max(sdx, static_cast<unsigned>(1)); 119 sdy = max(sdy, static_cast<unsigned>(1)); 116 120 117 IntRect effectDrawingRect = calculateDrawingIntRect(m_in->s ubRegion());121 IntRect effectDrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion()); 118 122 RefPtr<ImageData> srcImageData(m_in->resultImage()->getPremultipliedImageData(effectDrawingRect)); 119 123 CanvasPixelArray* srcPixelArray(srcImageData->data()); -
trunk/WebCore/platform/graphics/filters/Filter.h
r50920 r51310 23 23 #if ENABLE(FILTERS) 24 24 #include "FloatRect.h" 25 #include "FloatSize.h" 25 26 #include "ImageBuffer.h" 26 27 #include "StringHash.h" … … 41 42 ImageBuffer* sourceImage() { return m_sourceImage.get(); } 42 43 44 FloatSize filterResolution() const { return m_filterResolution; } 45 void setFilterResolution(const FloatSize& filterResolution) { m_filterResolution = filterResolution; } 46 43 47 virtual FloatRect sourceImageRect() const = 0; 44 48 virtual FloatRect filterRegion() const = 0; 45 49 46 50 // SVG specific 47 virtual void calculateEffectSubRegion(FilterEffect*) const = 0; 51 virtual void calculateEffectSubRegion(FilterEffect*) { } 52 53 virtual FloatSize maxImageSize() const = 0; 48 54 virtual bool effectBoundingBoxMode() const = 0; 49 55 50 56 private: 51 57 OwnPtr<ImageBuffer> m_sourceImage; 58 FloatSize m_filterResolution; 52 59 }; 53 60 -
trunk/WebCore/platform/graphics/filters/FilterEffect.cpp
r49582 r51310 59 59 IntRect FilterEffect::calculateDrawingIntRect(const FloatRect& effectRect) 60 60 { 61 IntPoint location = roundedIntPoint(FloatPoint(s ubRegion().x() - effectRect.x(),62 s ubRegion().y() - effectRect.y()));61 IntPoint location = roundedIntPoint(FloatPoint(scaledSubRegion().x() - effectRect.x(), 62 scaledSubRegion().y() - effectRect.y())); 63 63 return IntRect(location, resultImage()->size()); 64 64 } … … 66 66 FloatRect FilterEffect::calculateDrawingRect(const FloatRect& srcRect) 67 67 { 68 FloatPoint startPoint = FloatPoint(srcRect.x() - s ubRegion().x(), srcRect.y() - subRegion().y());68 FloatPoint startPoint = FloatPoint(srcRect.x() - scaledSubRegion().x(), srcRect.y() - scaledSubRegion().y()); 69 69 FloatRect drawingRect = FloatRect(startPoint, srcRect.size()); 70 70 return drawingRect; … … 73 73 GraphicsContext* FilterEffect::getEffectContext() 74 74 { 75 IntRect bufferRect = enclosingIntRect(s ubRegion());75 IntRect bufferRect = enclosingIntRect(scaledSubRegion()); 76 76 m_effectBuffer = ImageBuffer::create(bufferRect.size(), LinearRGB); 77 77 return m_effectBuffer->context(); -
trunk/WebCore/platform/graphics/filters/FilterEffect.h
r49582 r51310 44 44 FloatRect subRegion() const { return m_subRegion; } 45 45 void setSubRegion(const FloatRect& subRegion) { m_subRegion = subRegion; } 46 47 FloatRect scaledSubRegion() const { return m_scaledSubRegion; } 48 void setScaledSubRegion(const FloatRect& scaledSubRegion) { m_scaledSubRegion = scaledSubRegion; } 49 50 FloatRect effectBoundaries() const { return m_effectBoundaries; } 51 void setEffectBoundaries(const FloatRect& effectBoundaries) { m_effectBoundaries = effectBoundaries; } 46 52 47 53 bool hasX() { return m_hasX; } … … 97 103 bool m_alphaImage; 98 104 105 FloatRect m_effectBoundaries; 99 106 FloatRect m_subRegion; 107 FloatRect m_scaledSubRegion; 100 108 FloatRect m_unionOfChildEffectSubregions; 101 109 -
trunk/WebCore/platform/graphics/filters/ImageBufferFilter.cpp
r50920 r51310 24 24 #include "ImageBufferFilter.h" 25 25 26 #include "FloatSize.h" 27 26 28 namespace WebCore { 27 29 … … 29 31 : Filter() 30 32 { 33 setFilterResolution(FloatSize(1.f, 1.f)); 31 34 } 32 35 -
trunk/WebCore/platform/graphics/filters/ImageBufferFilter.h
r50920 r51310 26 26 #include "FilterEffect.h" 27 27 #include "FloatRect.h" 28 #include "FloatSize.h" 28 29 29 30 #include <wtf/PassRefPtr.h> … … 42 43 // SVG specific 43 44 virtual bool effectBoundingBoxMode() const { return false; } 44 virtual void calculateEffectSubRegion(FilterEffect*) const { } 45 46 virtual FloatSize maxImageSize() const { return FloatSize(); } 47 virtual void calculateEffectSubRegion(FilterEffect*) { } 45 48 46 49 private: -
trunk/WebCore/platform/graphics/filters/SourceAlpha.cpp
r50864 r51310 51 51 clippedSourceRect.setY(filter->filterRegion().y()); 52 52 setSubRegion(clippedSourceRect); 53 clippedSourceRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); 54 setScaledSubRegion(clippedSourceRect); 53 55 return filter->filterRegion(); 54 56 } -
trunk/WebCore/platform/graphics/filters/SourceGraphic.cpp
r51240 r51310 50 50 clippedSourceRect.setY(filter->filterRegion().y()); 51 51 setSubRegion(clippedSourceRect); 52 clippedSourceRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); 53 setScaledSubRegion(clippedSourceRect); 52 54 return filter->filterRegion(); 53 55 } -
trunk/WebCore/svg/SVGFilterElement.cpp
r50583 r51310 27 27 28 28 #include "Attr.h" 29 #include " SVGFilterBuilder.h"29 #include "FloatSize.h" 30 30 #include "MappedAttribute.h" 31 31 #include "PlatformString.h" 32 #include "SVGFilterBuilder.h" 32 33 #include "SVGFilterPrimitiveStandardAttributes.h" 33 34 #include "SVGLength.h" 34 35 #include "SVGNames.h" 36 #include "SVGParserUtilities.h" 35 37 #include "SVGResourceFilter.h" 36 38 #include "SVGUnitTypes.h" … … 90 92 else if (attr->name() == SVGNames::heightAttr) 91 93 setHeightBaseValue(SVGLength(LengthModeHeight, value)); 92 else { 94 else if (attr->name() == SVGNames::filterResAttr) { 95 float x, y; 96 if (parseNumberOptionalNumber(value, x, y)) { 97 setFilterResXBaseValue(x); 98 setFilterResYBaseValue(y); 99 } 100 } else { 93 101 if (SVGURIReference::parseMappedAttribute(attr)) 94 102 return; … … 131 139 m_filter->setFilterBoundingBoxMode(filterBBoxMode); 132 140 141 if (hasAttribute(SVGNames::filterResAttr)) { 142 m_filter->setHasFilterResolution(true); 143 m_filter->setFilterResolution(FloatSize(filterResX(), filterResY())); 144 } 145 133 146 // Add effects to the filter 134 147 m_filter->builder()->clearEffects(); -
trunk/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp
r49582 r51310 98 98 height().value(this)); 99 99 100 filterEffect->set SubRegion(effectBBox);100 filterEffect->setEffectBoundaries(effectBBox); 101 101 } 102 102 -
trunk/WebCore/svg/graphics/SVGResourceFilter.cpp
r51240 r51310 36 36 #include "SVGFilterPrimitiveStandardAttributes.h" 37 37 38 static const float kMaxFilterSize = 5000.0f; 39 40 using std::min; 41 38 42 namespace WebCore { 39 43 … … 43 47 , m_filterBBoxMode(false) 44 48 , m_effectBBoxMode(false) 49 , m_filterRes(false) 50 , m_scaleX(1.f) 51 , m_scaleY(1.f) 45 52 , m_savedContext(0) 46 53 , m_sourceGraphicBuffer(0) … … 53 60 } 54 61 62 static inline bool shouldProcessFilter(SVGResourceFilter* filter) 63 { 64 return (!filter->scaleX() || !filter->scaleY() || !filter->filterBoundingBox().width() 65 || !filter->filterBoundingBox().height()); 66 } 67 55 68 void SVGResourceFilter::addFilterEffect(SVGFilterPrimitiveStandardAttributes* effectAttributes, PassRefPtr<FilterEffect> effect) 56 69 { … … 59 72 } 60 73 74 bool SVGResourceFilter::fitsInMaximumImageSize(const FloatSize& size) 75 { 76 bool matchesFilterSize = true; 77 if (size.width() > kMaxFilterSize) { 78 m_scaleX *= kMaxFilterSize / size.width(); 79 matchesFilterSize = false; 80 } 81 if (size.height() > kMaxFilterSize) { 82 m_scaleY *= kMaxFilterSize / size.height(); 83 matchesFilterSize = false; 84 } 85 86 return matchesFilterSize; 87 } 88 61 89 void SVGResourceFilter::prepareFilter(GraphicsContext*& context, const RenderObject* object) 62 90 { 63 91 FloatRect targetRect = object->objectBoundingBox(); 64 92 m_ownerElement->buildFilter(targetRect); 93 94 if (shouldProcessFilter(this)) 95 return; 65 96 66 97 // clip sourceImage to filterRegion … … 68 99 clippedSourceRect.intersect(m_filterBBox); 69 100 101 // scale filter size to filterRes 102 FloatRect tempSourceRect = clippedSourceRect; 103 if (m_filterRes) { 104 m_scaleX = m_filterResSize.width() / m_filterBBox.width(); 105 m_scaleY = m_filterResSize.height() / m_filterBBox.height(); 106 } 107 108 // scale to big sourceImage size to kMaxFilterSize 109 tempSourceRect.scale(m_scaleX, m_scaleY); 110 fitsInMaximumImageSize(tempSourceRect.size()); 111 70 112 // prepare Filters 71 113 m_filter = SVGFilter::create(targetRect, m_filterBBox, m_effectBBoxMode); 114 m_filter->setFilterResolution(FloatSize(m_scaleX, m_scaleY)); 72 115 73 116 FilterEffect* lastEffect = m_filterBuilder->lastEffect(); 74 if (lastEffect) 117 if (lastEffect) { 75 118 lastEffect->calculateEffectRect(m_filter.get()); 119 // at least one FilterEffect has a too big image size, 120 // recalculate the effect sizes with new scale factors 121 if (!fitsInMaximumImageSize(m_filter->maxImageSize())) { 122 m_filter->setFilterResolution(FloatSize(m_scaleX, m_scaleY)); 123 lastEffect->calculateEffectRect(m_filter.get()); 124 } 125 } 126 127 clippedSourceRect.scale(m_scaleX, m_scaleY); 76 128 77 129 // Draw the content of the current element and it's childs to a imageBuffer to get the SourceGraphic. … … 84 136 85 137 GraphicsContext* sourceGraphicContext = sourceGraphic->context(); 138 sourceGraphicContext->scale(FloatSize(m_scaleX, m_scaleY)); 86 139 sourceGraphicContext->translate(-targetRect.x(), -targetRect.y()); 87 140 sourceGraphicContext->clearRect(FloatRect(FloatPoint(), targetRect.size())); … … 94 147 void SVGResourceFilter::applyFilter(GraphicsContext*& context, const RenderObject* object) 95 148 { 149 if (shouldProcessFilter(this)) 150 return; 151 96 152 if (!m_savedContext) 97 153 return; -
trunk/WebCore/svg/graphics/SVGResourceFilter.h
r49582 r51310 54 54 virtual SVGResourceType resourceType() const { return FilterResourceType; } 55 55 56 void setFilterResolution(const FloatSize& filterResSize) { m_filterResSize = filterResSize; } 57 void setHasFilterResolution(bool filterRes) { m_filterRes = filterRes; } 58 56 59 bool filterBoundingBoxMode() const { return m_filterBBoxMode; } 57 60 void setFilterBoundingBoxMode(bool bboxMode) { m_filterBBoxMode = bboxMode; } … … 63 66 void setFilterRect(const FloatRect& rect) { m_filterRect = rect; } 64 67 68 float scaleX() const { return m_scaleX; } 69 float scaleY() const { return m_scaleY; } 70 65 71 FloatRect filterBoundingBox() { return m_filterBBox; } 66 72 void setFilterBoundingBox(const FloatRect& rect) { m_filterBBox = rect; } … … 68 74 void prepareFilter(GraphicsContext*&, const RenderObject*); 69 75 void applyFilter(GraphicsContext*&, const RenderObject*); 76 77 bool fitsInMaximumImageSize(const FloatSize&); 70 78 71 79 void addFilterEffect(SVGFilterPrimitiveStandardAttributes*, PassRefPtr<FilterEffect>); … … 82 90 bool m_filterBBoxMode : 1; 83 91 bool m_effectBBoxMode : 1; 92 bool m_filterRes : 1; 93 float m_scaleX; 94 float m_scaleY; 84 95 85 96 FloatRect m_filterRect; 86 97 FloatRect m_filterBBox; 98 FloatSize m_filterResSize; 87 99 88 100 OwnPtr<SVGFilterBuilder> m_filterBuilder; -
trunk/WebCore/svg/graphics/filters/SVGFEDisplacementMap.cpp
r50718 r51310 94 94 return; 95 95 96 IntRect effectADrawingRect = calculateDrawingIntRect(m_in->s ubRegion());96 IntRect effectADrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion()); 97 97 RefPtr<CanvasPixelArray> srcPixelArrayA(m_in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data()); 98 98 99 IntRect effectBDrawingRect = calculateDrawingIntRect(m_in2->s ubRegion());99 IntRect effectBDrawingRect = calculateDrawingIntRect(m_in2->scaledSubRegion()); 100 100 RefPtr<CanvasPixelArray> srcPixelArrayB(m_in2->resultImage()->getUnmultipliedImageData(effectBDrawingRect)->data()); 101 101 … … 105 105 ASSERT(srcPixelArrayA->length() == srcPixelArrayB->length()); 106 106 107 float scale = m_scale / 255.f; 108 float scaleAdjustment = 0.5f - 0.5f * m_scale; 107 float scaleX = m_scale / 255.f * filter->filterResolution().width(); 108 float scaleY = m_scale / 255.f * filter->filterResolution().height(); 109 float scaleAdjustmentX = (0.5f - 0.5f * m_scale) * filter->filterResolution().width(); 110 float scaleAdjustmentY = (0.5f - 0.5f * m_scale) * filter->filterResolution().height(); 109 111 int stride = imageRect.width() * 4; 110 112 for (int y = 0; y < imageRect.height(); ++y) { … … 112 114 for (int x = 0; x < imageRect.width(); ++x) { 113 115 int dstIndex = line + x * 4; 114 int srcX = x + static_cast<int>(scale * srcPixelArrayB->get(dstIndex + m_xChannelSelector - 1) + scaleAdjustment);115 int srcY = y + static_cast<int>(scale * srcPixelArrayB->get(dstIndex + m_yChannelSelector - 1) + scaleAdjustment);116 int srcX = x + static_cast<int>(scaleX * srcPixelArrayB->get(dstIndex + m_xChannelSelector - 1) + scaleAdjustmentX); 117 int srcY = y + static_cast<int>(scaleY * srcPixelArrayB->get(dstIndex + m_yChannelSelector - 1) + scaleAdjustmentY); 116 118 for (unsigned channel = 0; channel < 4; ++channel) { 117 119 if (srcX < 0 || srcX >= imageRect.width() || srcY < 0 || srcY >= imageRect.height()) -
trunk/WebCore/svg/graphics/filters/SVGFEFlood.cpp
r50864 r51310 71 71 72 72 Color color = colorWithOverrideAlpha(floodColor().rgb(), floodOpacity()); 73 filterContext->fillRect(FloatRect(FloatPoint(), s ubRegion().size()), color, DeviceColorSpace);73 filterContext->fillRect(FloatRect(FloatPoint(), scaledSubRegion().size()), color, DeviceColorSpace); 74 74 } 75 75 -
trunk/WebCore/svg/graphics/filters/SVGFEMerge.cpp
r51240 r51310 79 79 80 80 for (unsigned i = 0; i < m_mergeInputs.size(); i++) { 81 FloatRect destRect = calculateDrawingRect(m_mergeInputs[i]->s ubRegion());81 FloatRect destRect = calculateDrawingRect(m_mergeInputs[i]->scaledSubRegion()); 82 82 filterContext->drawImage(m_mergeInputs[i]->resultImage()->image(), DeviceColorSpace, destRect); 83 83 } -
trunk/WebCore/svg/graphics/filters/SVGFEMorphology.cpp
r50604 r51310 95 95 96 96 IntRect imageRect(IntPoint(), resultImage()->size()); 97 IntRect effectDrawingRect = calculateDrawingIntRect(m_in->s ubRegion());97 IntRect effectDrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion()); 98 98 RefPtr<CanvasPixelArray> srcPixelArray(m_in->resultImage()->getPremultipliedImageData(effectDrawingRect)->data()); 99 99 RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height()); 100 100 101 int radiusX = static_cast<int>(m_radiusX );102 int radiusY = static_cast<int>(m_radiusY );101 int radiusX = static_cast<int>(m_radiusX * filter->filterResolution().width()); 102 int radiusY = static_cast<int>(m_radiusY * filter->filterResolution().height()); 103 103 int effectWidth = effectDrawingRect.width() * 4; 104 104 -
trunk/WebCore/svg/graphics/filters/SVGFEOffset.cpp
r51240 r51310 75 75 return; 76 76 77 FloatRect sourceImageRect = filter->sourceImageRect(); 78 sourceImageRect.scale(filter->filterResolution().width(), filter->filterResolution().height()); 79 77 80 if (filter->effectBoundingBoxMode()) { 78 setDx(dx() * filter->sourceImageRect().width());79 setDy(dy() * filter->sourceImageRect().height());81 m_dx *= sourceImageRect.width(); 82 m_dy *= sourceImageRect.height(); 80 83 } 84 m_dx *= filter->filterResolution().width(); 85 m_dy *= filter->filterResolution().height(); 81 86 82 FloatRect dstRect = FloatRect( dx() + m_in->subRegion().x() - subRegion().x(),83 dy() + m_in->subRegion().y() - subRegion().y(),84 m_in->s ubRegion().width(),85 m_in->s ubRegion().height());87 FloatRect dstRect = FloatRect(m_dx + m_in->scaledSubRegion().x() - scaledSubRegion().x(), 88 m_dy + m_in->scaledSubRegion().y() - scaledSubRegion().y(), 89 m_in->scaledSubRegion().width(), 90 m_in->scaledSubRegion().height()); 86 91 87 92 filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, dstRect); -
trunk/WebCore/svg/graphics/filters/SVGFETile.cpp
r51240 r51310 59 59 return; 60 60 61 IntRect tileRect = enclosingIntRect(m_in->s ubRegion());61 IntRect tileRect = enclosingIntRect(m_in->scaledSubRegion()); 62 62 63 63 // Source input needs more attention. It has the size of the filterRegion but gives the 64 64 // size of the cutted sourceImage back. This is part of the specification and optimization. 65 if (m_in->isSourceInput()) 66 tileRect = enclosingIntRect(filter->filterRegion()); 65 if (m_in->isSourceInput()) { 66 FloatRect filterRegion = filter->filterRegion(); 67 filterRegion.scale(filter->filterResolution().width(), filter->filterResolution().height()); 68 tileRect = enclosingIntRect(filterRegion); 69 } 67 70 68 71 OwnPtr<ImageBuffer> tileImage = ImageBuffer::create(tileRect.size()); … … 72 75 73 76 TransformationMatrix matrix; 74 matrix.translate(m_in->s ubRegion().x() - subRegion().x(), m_in->subRegion().y() - subRegion().y());77 matrix.translate(m_in->scaledSubRegion().x() - scaledSubRegion().x(), m_in->scaledSubRegion().y() - scaledSubRegion().y()); 75 78 pattern.get()->setPatternSpaceTransform(matrix); 76 79 77 80 filterContext->setFillPattern(pattern); 78 filterContext->fillRect(FloatRect(FloatPoint(), s ubRegion().size()));81 filterContext->fillRect(FloatRect(FloatPoint(), scaledSubRegion().size())); 79 82 } 80 83 -
trunk/WebCore/svg/graphics/filters/SVGFilter.cpp
r50920 r51310 33 33 } 34 34 35 void SVGFilter::calculateEffectSubRegion(FilterEffect* effect) const35 void SVGFilter::calculateEffectSubRegion(FilterEffect* effect) 36 36 { 37 FloatRect subRegionBBox = effect-> subRegion();37 FloatRect subRegionBBox = effect->effectBoundaries(); 38 38 FloatRect useBBox = effect->unionOfChildEffectSubregions(); 39 39 FloatRect newSubRegion = subRegionBBox; … … 71 71 72 72 effect->setSubRegion(newSubRegion); 73 newSubRegion.scale(filterResolution().width(), filterResolution().height()); 74 effect->setScaledSubRegion(newSubRegion); 75 m_maxImageSize = m_maxImageSize.expandedTo(newSubRegion.size()); 73 76 } 74 77 -
trunk/WebCore/svg/graphics/filters/SVGFilter.h
r50920 r51310 25 25 #include "FilterEffect.h" 26 26 #include "FloatRect.h" 27 #include "FloatSize.h" 27 28 28 29 #include <wtf/PassRefPtr.h> … … 36 37 static PassRefPtr<SVGFilter> create(const FloatRect&, const FloatRect&, bool); 37 38 38 bool effectBoundingBoxMode() const { return m_effectBBoxMode; }39 virtual bool effectBoundingBoxMode() const { return m_effectBBoxMode; } 39 40 40 FloatRect filterRegion() const { return m_filterRect; } 41 FloatRect sourceImageRect() const { return m_itemBox; } 42 void calculateEffectSubRegion(FilterEffect*) const; 41 virtual FloatRect filterRegion() const { return m_filterRect; } 42 virtual FloatRect sourceImageRect() const { return m_itemBox; } 43 44 virtual FloatSize maxImageSize() const { return m_maxImageSize; } 45 virtual void calculateEffectSubRegion(FilterEffect*); 43 46 44 47 private: 45 48 SVGFilter(const FloatRect& itemBox, const FloatRect& filterRect, bool effectBBoxMode); 46 49 50 FloatSize m_maxImageSize; 47 51 FloatRect m_itemBox; 48 52 FloatRect m_filterRect;
Note: See TracChangeset
for help on using the changeset viewer.