Changeset 65880 in webkit
- Timestamp:
- Aug 24, 2010 2:25:11 AM (14 years ago)
- Location:
- trunk
- Files:
-
- 36 added
- 30 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r65879 r65880 1 2010-08-24 Nikolas Zimmermann <nzimmermann@rim.com> 2 3 Reviewed by Dirk Schulze. 4 5 clip-path does not work inside mask element 6 https://bugs.webkit.org/show_bug.cgi?id=41428 7 8 Update results of all tests containing <mask> / <pattern> and/or gradient on text (using CG). 9 The ImageBuffer content is now scaled to account for rounding differences, when zooming. 10 11 * platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.checksum: 12 * platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.png: 13 * platform/mac/svg/W3C-SVG-1.1/pservers-grad-08-b-expected.checksum: 14 * platform/mac/svg/W3C-SVG-1.1/pservers-grad-08-b-expected.png: 15 * platform/mac/svg/clip-path/clip-in-mask-expected.checksum: Added. 16 * platform/mac/svg/clip-path/clip-in-mask-expected.png: Added. 17 * platform/mac/svg/clip-path/clip-in-mask-expected.txt: Added. 18 * platform/mac/svg/clip-path/clip-in-mask-objectBoundingBox-expected.checksum: Added. 19 * platform/mac/svg/clip-path/clip-in-mask-objectBoundingBox-expected.png: Added. 20 * platform/mac/svg/clip-path/clip-in-mask-objectBoundingBox-expected.txt: Added. 21 * platform/mac/svg/clip-path/clip-in-mask-userSpaceOnUse-expected.checksum: Added. 22 * platform/mac/svg/clip-path/clip-in-mask-userSpaceOnUse-expected.png: Added. 23 * platform/mac/svg/clip-path/clip-in-mask-userSpaceOnUse-expected.txt: Added. 24 * platform/mac/svg/clip-path/deep-nested-clip-in-mask-different-unitTypes-expected.checksum: Added. 25 * platform/mac/svg/clip-path/deep-nested-clip-in-mask-different-unitTypes-expected.png: Added. 26 * platform/mac/svg/clip-path/deep-nested-clip-in-mask-different-unitTypes-expected.txt: Added. 27 * platform/mac/svg/clip-path/deep-nested-clip-in-mask-expected.checksum: Added. 28 * platform/mac/svg/clip-path/deep-nested-clip-in-mask-expected.png: Added. 29 * platform/mac/svg/clip-path/deep-nested-clip-in-mask-expected.txt: Added. 30 * platform/mac/svg/clip-path/nested-clip-in-mask-image-based-clipping-expected.checksum: Added. 31 * platform/mac/svg/clip-path/nested-clip-in-mask-image-based-clipping-expected.png: Added. 32 * platform/mac/svg/clip-path/nested-clip-in-mask-image-based-clipping-expected.txt: Added. 33 * platform/mac/svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping-expected.checksum: Added. 34 * platform/mac/svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping-expected.png: Added. 35 * platform/mac/svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping-expected.txt: Added. 36 * platform/mac/svg/clip-path/nested-clip-in-mask-path-based-clipping-expected.checksum: Added. 37 * platform/mac/svg/clip-path/nested-clip-in-mask-path-based-clipping-expected.png: Added. 38 * platform/mac/svg/clip-path/nested-clip-in-mask-path-based-clipping-expected.txt: Added. 39 * platform/mac/svg/custom/absolute-sized-content-with-resources-expected.checksum: 40 * platform/mac/svg/custom/absolute-sized-content-with-resources-expected.png: 41 * platform/mac/svg/custom/grayscale-gradient-mask-expected.checksum: 42 * platform/mac/svg/custom/grayscale-gradient-mask-expected.png: 43 * platform/mac/svg/custom/js-late-gradient-and-object-creation-expected.checksum: 44 * platform/mac/svg/custom/js-late-gradient-and-object-creation-expected.png: 45 * platform/mac/svg/custom/text-rotated-gradient-expected.checksum: 46 * platform/mac/svg/custom/text-rotated-gradient-expected.png: 47 * platform/mac/svg/text/selection-background-color-expected.checksum: 48 * platform/mac/svg/text/selection-background-color-expected.png: 49 * platform/mac/svg/transforms/text-with-mask-with-svg-transform-expected.checksum: 50 * platform/mac/svg/transforms/text-with-mask-with-svg-transform-expected.png: 51 * platform/mac/svg/zoom/page/zoom-mask-with-percentages-expected.checksum: 52 * platform/mac/svg/zoom/page/zoom-mask-with-percentages-expected.png: 53 * svg/clip-path/clip-in-mask-objectBoundingBox.svg: Added. 54 * svg/clip-path/clip-in-mask-userSpaceOnUse.svg: Added. 55 * svg/clip-path/clip-in-mask.svg: Added. 56 * svg/clip-path/deep-nested-clip-in-mask-different-unitTypes.svg: Added. 57 * svg/clip-path/deep-nested-clip-in-mask.svg: Added. 58 * svg/clip-path/nested-clip-in-mask-image-based-clipping.svg: Added. 59 * svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping.svg: Added. 60 * svg/clip-path/nested-clip-in-mask-path-based-clipping.svg: Added. 61 1 62 2010-08-24 Andrei Popescu <andreip@dhcp-172-16-14-12.lon.corp.google.com> 2 63 -
trunk/LayoutTests/platform/mac/svg/W3C-SVG-1.1/masking-intro-01-f-expected.checksum
r65229 r65880 1 62a68fa8de7ea652f54ced5930397a1e 1 c9143af98632ecc250a30eb1902e35dc -
trunk/LayoutTests/platform/mac/svg/W3C-SVG-1.1/pservers-grad-08-b-expected.checksum
r65665 r65880 1 effebeceed60e2edcd5795281c16f129 1 b4d10b39924990573785324a4e3813da -
trunk/LayoutTests/platform/mac/svg/custom/absolute-sized-content-with-resources-expected.checksum
r65665 r65880 1 f482ede9c5fc18f3f09a70545af6ba67 1 70e709058a071d7207192c403ee1deb2 -
trunk/LayoutTests/platform/mac/svg/custom/grayscale-gradient-mask-expected.checksum
r65665 r65880 1 c9fa987aacc7c5064491999daceb0d4f 1 791d8651a70b39d17fac23e5ccafca53 -
trunk/LayoutTests/platform/mac/svg/custom/js-late-gradient-and-object-creation-expected.checksum
r65665 r65880 1 79c35c1f034795088b8a008729997baa 1 3cdac160082fd7d24f5e65d83ddf7958 -
trunk/LayoutTests/platform/mac/svg/custom/text-rotated-gradient-expected.checksum
r65665 r65880 1 7c0fe736cb4ed2a2a51eb2458251e610 1 ce7c2f3d28648885b0045fc74eaaf8f4 -
trunk/LayoutTests/platform/mac/svg/text/selection-background-color-expected.checksum
r65665 r65880 1 1ad4cec1470600775011aa727d7a5c94 1 3165f6d9b00829dfa0119222f11e2585 -
trunk/LayoutTests/platform/mac/svg/transforms/text-with-mask-with-svg-transform-expected.checksum
r65665 r65880 1 ab99a5d800d7ea930b1151158e14be69 1 34ebee33d4d97a2e82a75241afcfe9eb -
trunk/LayoutTests/platform/mac/svg/zoom/page/zoom-mask-with-percentages-expected.checksum
r65665 r65880 1 28befae5e6709c12c60fd2e448dff271 1 c9f4cbaab8844bc7b6bf998831f89a3e -
trunk/WebCore/ChangeLog
r65879 r65880 1 2010-08-24 Nikolas Zimmermann <nzimmermann@rim.com> 2 3 Reviewed by Dirk Schulze 4 5 clip-path does not work inside mask element 6 https://bugs.webkit.org/show_bug.cgi?id=41428 7 8 Add new tests covering nesting of clippers and maskers, with different unitTypes for the content coordinate system. 9 Scale all ImageBuffer content to take into account that ImageBuffers use integer based sizes, where the content 10 is floating-point sized. This compensates rounded errors, when scaling the document. 11 12 Tests: svg/clip-path/clip-in-mask-objectBoundingBox.svg 13 svg/clip-path/clip-in-mask-userSpaceOnUse.svg 14 svg/clip-path/clip-in-mask.svg 15 svg/clip-path/deep-nested-clip-in-mask-different-unitTypes.svg 16 svg/clip-path/deep-nested-clip-in-mask-panning.svg 17 svg/clip-path/deep-nested-clip-in-mask.svg 18 svg/clip-path/nested-clip-in-mask-image-based-clipping.svg 19 svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping.svg 20 svg/clip-path/nested-clip-in-mask-path-based-clipping.svg 21 22 * rendering/RenderSVGResourceClipper.cpp: 23 (WebCore::RenderSVGResourceClipper::applyResource): Return the value of applyClippingToContext, instead of always true. 24 (WebCore::RenderSVGResourceClipper::applyClippingToContext): Moved some code from createClipData, to avoid having to pass 5 arguments to createClipData. 25 (WebCore::RenderSVGResourceClipper::drawContentIntoMaskImage): Renamed from createClipData. 26 * rendering/RenderSVGResourceClipper.h: 27 * rendering/RenderSVGResourceGradient.cpp: 28 (WebCore::createMaskAndSwapContextForTextGradient): Pass absoluteTargetRect to createImageBuffer. 29 (WebCore::clipToTextMask): Ditto. 30 * rendering/RenderSVGResourceMasker.cpp: 31 (WebCore::RenderSVGResourceMasker::applyResource): Ditto. 32 (WebCore::RenderSVGResourceMasker::drawContentIntoMaskImage): Pass content transformation to renderSubtreeToImageBuffer, to support nesting objectBoundingBox resources. 33 * rendering/RenderSVGResourcePattern.cpp: 34 (WebCore::RenderSVGResourcePattern::applyResource): Adapt to calculateTransformationToOutermostSVGCoordinateSystem changes. AffineTransform is now passed as reference. 35 (WebCore::RenderSVGResourcePattern::createTileImage): ImageBuffer content scaling is now handled by createImageBuffer. 36 * rendering/SVGImageBufferTools.cpp: 37 (WebCore::SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem): Renamed. Don't return an AffineTransform copy, but instead pass it as reference. 38 (WebCore::SVGImageBufferTools::createImageBuffer): Always scale the ImageBuffer content, to compensate rounding effects (code was only present in patterns so far). 39 Now also needs the 'absoluteTargetRect' parameter, not only 'clampedAbsoluteTargetRect'. 40 (WebCore::SVGImageBufferTools::renderSubtreeToImageBuffer): Moved from SVGRenderSupport. 41 (WebCore::SVGImageBufferTools::clipToImageBuffer): Pass ImageBuffer as OwnPtr reference, to allow to clear it under certain circumstances (see comment). 42 (WebCore::SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer): Remove AffineTransform parameter, absoluteTargetRect is calculated before passing into this function. 43 * rendering/SVGImageBufferTools.h: 44 * rendering/SVGRenderSupport.cpp: 45 (WebCore::SVGRenderSupport::prepareToRenderSVGContent): Important change, respect the RenderSVGResourceClipper::applyResource() return value! 46 * rendering/SVGRenderSupport.h: 47 * svg/SVGFEImageElement.cpp: 48 (WebCore::SVGFEImageElement::build): renderSubtreeToImage now lives in SVGImageBufferTools, adapt code. 49 1 50 2010-08-24 Andrei Popescu <andreip@dhcp-172-16-14-12.lon.corp.google.com> 2 51 -
trunk/WebCore/rendering/RenderSVGResourceClipper.cpp
r65729 r65880 102 102 #endif 103 103 104 applyClippingToContext(object, object->objectBoundingBox(), object->repaintRectInLocalCoordinates(), context); 105 return true; 104 return applyClippingToContext(object, object->objectBoundingBox(), object->repaintRectInLocalCoordinates(), context); 106 105 } 107 106 … … 173 172 } 174 173 175 AffineTransform absoluteTransform = SVGImageBufferTools::transformationToOutermostSVGCoordinateSystem(object); 176 FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(object, absoluteTransform, repaintRect); 177 178 if (shouldCreateClipData) 179 createClipData(clipperData, objectBoundingBox, repaintRect, clampedAbsoluteTargetRect, absoluteTransform); 174 AffineTransform absoluteTransform; 175 SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransform); 176 177 FloatRect absoluteTargetRect = absoluteTransform.mapRect(repaintRect); 178 FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(object, absoluteTargetRect); 179 180 if (shouldCreateClipData && !clampedAbsoluteTargetRect.isEmpty()) { 181 if (!SVGImageBufferTools::createImageBuffer(absoluteTargetRect, clampedAbsoluteTargetRect, clipperData->clipMaskImage, DeviceRGB)) 182 return false; 183 184 GraphicsContext* maskContext = clipperData->clipMaskImage->context(); 185 ASSERT(maskContext); 186 187 // The save/restore pair is needed for clipToImageBuffer - it doesn't work without it on non-Cg platforms. 188 maskContext->save(); 189 maskContext->translate(-clampedAbsoluteTargetRect.x(), -clampedAbsoluteTargetRect.y()); 190 maskContext->concatCTM(absoluteTransform); 191 192 // clipPath can also be clipped by another clipPath. 193 if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this)) { 194 if (RenderSVGResourceClipper* clipper = resources->clipper()) { 195 if (!clipper->applyClippingToContext(this, objectBoundingBox, repaintRect, maskContext)) { 196 maskContext->restore(); 197 return false; 198 } 199 } 200 } 201 202 drawContentIntoMaskImage(clipperData, objectBoundingBox); 203 maskContext->restore(); 204 } 180 205 181 206 if (!clipperData->clipMaskImage) 182 207 return false; 183 208 184 SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, clampedAbsoluteTargetRect, clipperData->clipMaskImage .get());209 SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, clampedAbsoluteTargetRect, clipperData->clipMaskImage); 185 210 return true; 186 211 } 187 212 188 bool RenderSVGResourceClipper::createClipData(ClipperData* clipperData, 189 const FloatRect& objectBoundingBox, 190 const FloatRect& repaintRect, 191 const FloatRect& clampedAbsoluteTargetRect, 192 const AffineTransform& absoluteTransform) 193 { 194 if (!SVGImageBufferTools::createImageBuffer(clampedAbsoluteTargetRect, clipperData->clipMaskImage, DeviceRGB)) 195 return false; 213 bool RenderSVGResourceClipper::drawContentIntoMaskImage(ClipperData* clipperData, const FloatRect& objectBoundingBox) 214 { 215 ASSERT(clipperData); 216 ASSERT(clipperData->clipMaskImage); 196 217 197 218 GraphicsContext* maskContext = clipperData->clipMaskImage->context(); 198 219 ASSERT(maskContext); 199 220 200 maskContext->save(); 201 maskContext->translate(-clampedAbsoluteTargetRect.x(), -clampedAbsoluteTargetRect.y()); 202 maskContext->concatCTM(absoluteTransform); 203 204 // clipPath can also be clipped by another clipPath. 205 if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this)) { 206 if (RenderSVGResourceClipper* clipper = resources->clipper()) { 207 if (!clipper->applyClippingToContext(this, objectBoundingBox, repaintRect, maskContext)) { 208 maskContext->restore(); 209 return false; 210 } 211 } 212 } 213 221 AffineTransform maskContentTransformation; 214 222 SVGClipPathElement* clipPath = static_cast<SVGClipPathElement*>(node()); 215 223 if (clipPath->clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { 216 maskContext->translate(objectBoundingBox.x(), objectBoundingBox.y()); 217 maskContext->scale(objectBoundingBox.size()); 224 maskContentTransformation.translate(objectBoundingBox.x(), objectBoundingBox.y()); 225 maskContentTransformation.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height()); 226 maskContext->concatCTM(maskContentTransformation); 218 227 } 219 228 … … 263 272 264 273 // In the case of a <use> element, we obtained its renderere above, to retrieve its clipRule. 265 // We h sve to pass the <use> renderer itself to renderSubtreeToImage() to apply it's x/y/transform/etc. values when rendering.274 // We have to pass the <use> renderer itself to renderSubtreeToImageBuffer() to apply it's x/y/transform/etc. values when rendering. 266 275 // So if isUseElement is true, refetch the childNode->renderer(), as renderer got overriden above. 267 SVG RenderSupport::renderSubtreeToImage(clipperData->clipMaskImage.get(), isUseElement ? childNode->renderer() : renderer);276 SVGImageBufferTools::renderSubtreeToImageBuffer(clipperData->clipMaskImage.get(), isUseElement ? childNode->renderer() : renderer, maskContentTransformation); 268 277 269 278 renderer->setStyle(oldRenderStyle.release()); 270 279 m_invalidationBlocked = false; 271 280 } 272 273 maskContext->restore();274 281 275 282 return true; -
trunk/WebCore/rendering/RenderSVGResourceClipper.h
r65729 r65880 66 66 bool applyClippingToContext(RenderObject*, const FloatRect&, const FloatRect&, GraphicsContext*); 67 67 bool pathOnlyClipping(GraphicsContext*, const FloatRect&); 68 bool createClipData(ClipperData*, const FloatRect& objectBoundingBox, const FloatRect& repaintRect, const FloatRect& clampedAbsoluteTargetRect, const AffineTransform& absoluteTransform); 69 68 bool drawContentIntoMaskImage(ClipperData*, const FloatRect& objectBoundingBox); 70 69 void calculateClipContentRepaintRect(); 71 70 -
trunk/WebCore/rendering/RenderSVGResourceGradient.cpp
r65665 r65880 81 81 ASSERT(textRootBlock); 82 82 83 AffineTransform absoluteTransform(SVGImageBufferTools::transformationToOutermostSVGCoordinateSystem(textRootBlock)); 84 FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(textRootBlock, absoluteTransform, textRootBlock->repaintRectInLocalCoordinates()); 83 AffineTransform absoluteTransform; 84 SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(textRootBlock, absoluteTransform); 85 86 FloatRect absoluteTargetRect = absoluteTransform.mapRect(textRootBlock->repaintRectInLocalCoordinates()); 87 FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(textRootBlock, absoluteTargetRect); 85 88 if (clampedAbsoluteTargetRect.isEmpty()) 86 89 return false; 87 90 88 91 OwnPtr<ImageBuffer> maskImage; 89 if (!SVGImageBufferTools::createImageBuffer( clampedAbsoluteTargetRect, maskImage, DeviceRGB))92 if (!SVGImageBufferTools::createImageBuffer(absoluteTargetRect, clampedAbsoluteTargetRect, maskImage, DeviceRGB)) 90 93 return false; 91 94 … … 114 117 targetRect = textRootBlock->repaintRectInLocalCoordinates(); 115 118 116 AffineTransform absoluteTransform(SVGImageBufferTools::transformationToOutermostSVGCoordinateSystem(textRootBlock)); 117 FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(textRootBlock, absoluteTransform, targetRect); 118 119 SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, clampedAbsoluteTargetRect, imageBuffer.get()); 119 AffineTransform absoluteTransform; 120 SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(textRootBlock, absoluteTransform); 121 122 FloatRect absoluteTargetRect = absoluteTransform.mapRect(targetRect); 123 FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(textRootBlock, absoluteTargetRect); 124 125 SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, clampedAbsoluteTargetRect, imageBuffer); 120 126 121 127 AffineTransform matrix; -
trunk/WebCore/rendering/RenderSVGResourceMasker.cpp
r65665 r65880 97 97 MaskerData* maskerData = m_masker.get(object); 98 98 99 AffineTransform absoluteTransform(SVGImageBufferTools::transformationToOutermostSVGCoordinateSystem(object)); 100 FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(object, absoluteTransform, object->repaintRectInLocalCoordinates()); 99 AffineTransform absoluteTransform; 100 SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransform); 101 102 FloatRect absoluteTargetRect = absoluteTransform.mapRect(object->repaintRectInLocalCoordinates()); 103 FloatRect clampedAbsoluteTargetRect = SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(object, absoluteTargetRect); 101 104 102 105 if (!maskerData->maskImage && !clampedAbsoluteTargetRect.isEmpty()) { … … 105 108 return false; 106 109 107 if (!SVGImageBufferTools::createImageBuffer( clampedAbsoluteTargetRect, maskerData->maskImage, LinearRGB))110 if (!SVGImageBufferTools::createImageBuffer(absoluteTargetRect, clampedAbsoluteTargetRect, maskerData->maskImage, LinearRGB)) 108 111 return false; 109 112 … … 111 114 ASSERT(maskImageContext); 112 115 116 // The save/restore pair is needed for clipToImageBuffer - it doesn't work without it on non-Cg platforms. 117 maskImageContext->save(); 113 118 maskImageContext->translate(-clampedAbsoluteTargetRect.x(), -clampedAbsoluteTargetRect.y()); 114 119 maskImageContext->concatCTM(absoluteTransform); … … 120 125 return false; 121 126 122 SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, clampedAbsoluteTargetRect, maskerData->maskImage .get());127 SVGImageBufferTools::clipToImageBuffer(context, absoluteTransform, clampedAbsoluteTargetRect, maskerData->maskImage); 123 128 return true; 124 129 } … … 126 131 void RenderSVGResourceMasker::drawContentIntoMaskImage(MaskerData* maskerData, const SVGMaskElement* maskElement, RenderObject* object) 127 132 { 133 GraphicsContext* maskImageContext = maskerData->maskImage->context(); 134 ASSERT(maskImageContext); 135 128 136 // Eventually adjust the mask image context according to the target objectBoundingBox. 137 AffineTransform maskContentTransformation; 129 138 if (maskElement->maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { 130 GraphicsContext* maskImageContext = maskerData->maskImage->context();131 ASSERT(maskImageContext);132 133 139 FloatRect objectBoundingBox = object->objectBoundingBox(); 134 maskImageContext->translate(objectBoundingBox.x(), objectBoundingBox.y()); 135 maskImageContext->scale(FloatSize(objectBoundingBox.width(), objectBoundingBox.height())); 140 maskContentTransformation.translate(objectBoundingBox.x(), objectBoundingBox.y()); 141 maskContentTransformation.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height()); 142 maskImageContext->concatCTM(maskContentTransformation); 136 143 } 137 144 … … 144 151 if (!style || style->display() == NONE || style->visibility() != VISIBLE) 145 152 continue; 146 SVGRenderSupport::renderSubtreeToImage(maskerData->maskImage.get(), renderer); 147 } 153 SVGImageBufferTools::renderSubtreeToImageBuffer(maskerData->maskImage.get(), renderer, maskContentTransformation); 154 } 155 156 maskImageContext->restore(); 148 157 149 158 #if !PLATFORM(CG) -
trunk/WebCore/rendering/RenderSVGResourcePattern.cpp
r65665 r65880 102 102 AffineTransform tileImageTransform = buildTileImageTransform(object, attributes, patternElement, tileBoundaries); 103 103 104 AffineTransform absoluteTransform(SVGImageBufferTools::transformationToOutermostSVGCoordinateSystem(object)); 104 AffineTransform absoluteTransform; 105 SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransform); 106 105 107 FloatRect absoluteTileBoundaries = absoluteTransform.mapRect(tileBoundaries); 106 108 … … 245 247 OwnPtr<ImageBuffer> tileImage; 246 248 247 if (!SVGImageBufferTools::createImageBuffer( clampedAbsoluteTileBoundaries, tileImage, DeviceRGB))249 if (!SVGImageBufferTools::createImageBuffer(absoluteTileBoundaries, clampedAbsoluteTileBoundaries, tileImage, DeviceRGB)) 248 250 return PassOwnPtr<ImageBuffer>(); 249 251 250 252 GraphicsContext* tileImageContext = tileImage->context(); 251 253 ASSERT(tileImageContext); 252 253 // Compensate rounding effects, as the absolute target rect is using floating-point numbers and the image buffer size is integer.254 IntSize unclampedImageSize(SVGImageBufferTools::roundedImageBufferSize(absoluteTileBoundaries.size()));255 tileImageContext->scale(FloatSize(unclampedImageSize.width() / absoluteTileBoundaries.width(),256 unclampedImageSize.height() / absoluteTileBoundaries.height()));257 254 258 255 // The image buffer represents the final rendered size, so the content has to be scaled (to avoid pixelation). … … 263 260 if (!tileImageTransform.isIdentity()) 264 261 tileImageContext->concatCTM(tileImageTransform); 262 263 AffineTransform contentTransformation; 265 264 266 265 // Draw the content into the ImageBuffer. … … 268 267 if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !node->renderer()) 269 268 continue; 270 SVG RenderSupport::renderSubtreeToImage(tileImage.get(), node->renderer());269 SVGImageBufferTools::renderSubtreeToImageBuffer(tileImage.get(), node->renderer(), contentTransformation); 271 270 } 272 271 -
trunk/WebCore/rendering/SVGImageBufferTools.cpp
r65665 r65880 26 26 #include "GraphicsContext.h" 27 27 #include "RenderObject.h" 28 #include "RenderSVGContainer.h" 28 29 #include "RenderSVGRoot.h" 29 30 30 31 namespace WebCore { 31 32 32 AffineTransform SVGImageBufferTools::transformationToOutermostSVGCoordinateSystem(const RenderObject* renderer)33 static AffineTransform& currentContentTransformation() 33 34 { 34 ASSERT(renderer); 35 DEFINE_STATIC_LOCAL(AffineTransform, s_currentContentTransformation, ()); 36 return s_currentContentTransformation; 37 } 35 38 39 void SVGImageBufferTools::calculateTransformationToOutermostSVGCoordinateSystem(const RenderObject* renderer, AffineTransform& absoluteTransform) 40 { 36 41 const RenderObject* current = renderer; 37 42 ASSERT(current); 38 43 39 AffineTransform ctm;44 absoluteTransform = currentContentTransformation(); 40 45 while (current) { 41 ctm.multiply(current->localToParentTransform());46 absoluteTransform.multiply(current->localToParentTransform()); 42 47 if (current->isSVGRoot()) 43 48 break; 44 45 49 current = current->parent(); 46 50 } 47 48 return ctm;49 51 } 50 52 51 bool SVGImageBufferTools::createImageBuffer(const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>& imageBuffer, ImageColorSpace colorSpace)53 bool SVGImageBufferTools::createImageBuffer(const FloatRect& absoluteTargetRect, const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>& imageBuffer, ImageColorSpace colorSpace) 52 54 { 53 55 IntSize imageSize(roundedImageBufferSize(clampedAbsoluteTargetRect.size())); 56 IntSize unclampedImageSize(SVGImageBufferTools::roundedImageBufferSize(absoluteTargetRect.size())); 54 57 55 58 // Don't create empty ImageBuffers. … … 61 64 return false; 62 65 66 GraphicsContext* imageContext = image->context(); 67 ASSERT(imageContext); 68 69 // Compensate rounding effects, as the absolute target rect is using floating-point numbers and the image buffer size is integer. 70 imageContext->scale(FloatSize(unclampedImageSize.width() / absoluteTargetRect.width(), unclampedImageSize.height() / absoluteTargetRect.height())); 71 63 72 imageBuffer = image.release(); 64 73 return true; 65 74 } 66 75 67 void SVGImageBufferTools::clipToImageBuffer(GraphicsContext* context, const AffineTransform& absoluteTransform, const FloatRect& clampedAbsoluteTargetRect, ImageBuffer* imageBuffer) 76 void SVGImageBufferTools::renderSubtreeToImageBuffer(ImageBuffer* image, RenderObject* item, const AffineTransform& subtreeContentTransformation) 77 { 78 ASSERT(item); 79 ASSERT(image); 80 ASSERT(image->context()); 81 82 PaintInfo info(image->context(), PaintInfo::infiniteRect(), PaintPhaseForeground, 0, 0, 0); 83 84 // FIXME: isSVGContainer returns true for RenderSVGViewportContainer, so if this is ever 85 // called with one of those, we will read from the wrong offset in an object due to a bad cast. 86 RenderSVGContainer* svgContainer = 0; 87 if (item && item->isSVGContainer()) 88 svgContainer = toRenderSVGContainer(item); 89 90 bool drawsContents = svgContainer ? svgContainer->drawsContents() : false; 91 if (svgContainer && !drawsContents) 92 svgContainer->setDrawsContents(true); 93 94 AffineTransform& contentTransformation = currentContentTransformation(); 95 AffineTransform savedContentTransformation = contentTransformation; 96 contentTransformation.multiply(subtreeContentTransformation); 97 98 item->layoutIfNeeded(); 99 item->paint(info, 0, 0); 100 101 contentTransformation = savedContentTransformation; 102 103 if (svgContainer && !drawsContents) 104 svgContainer->setDrawsContents(false); 105 } 106 107 void SVGImageBufferTools::clipToImageBuffer(GraphicsContext* context, const AffineTransform& absoluteTransform, const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>& imageBuffer) 68 108 { 69 109 ASSERT(context); 70 110 ASSERT(imageBuffer); 71 111 72 // The mask image has been created in the device coordinate space, as the image should not be scaled.73 // So the actual masking process has to be done in the device coordinate space as well.112 // The mask image has been created in the absolute coordinate space, as the image should not be scaled. 113 // So the actual masking process has to be done in the absolute coordinate space as well. 74 114 context->concatCTM(absoluteTransform.inverse()); 75 context->clipToImageBuffer(imageBuffer , clampedAbsoluteTargetRect);115 context->clipToImageBuffer(imageBuffer.get(), clampedAbsoluteTargetRect); 76 116 context->concatCTM(absoluteTransform); 117 118 // When nesting resources, with objectBoundingBox as content unit types, there's no use in caching the 119 // resulting image buffer as the parent resource already caches the result. 120 if (!currentContentTransformation().isIdentity()) 121 imageBuffer.clear(); 77 122 } 78 123 … … 82 127 } 83 128 84 FloatRect SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(const RenderObject* renderer, const AffineTransform& absoluteTransform, const FloatRect& targetRect)129 FloatRect SVGImageBufferTools::clampedAbsoluteTargetRectForRenderer(const RenderObject* renderer, const FloatRect& absoluteTargetRect) 85 130 { 86 131 ASSERT(renderer); 87 132 88 133 const RenderSVGRoot* svgRoot = SVGRenderSupport::findTreeRootObject(renderer); 89 FloatRect clampedAbsoluteTargetRect = absoluteT ransform.mapRect(targetRect);134 FloatRect clampedAbsoluteTargetRect = absoluteTargetRect; 90 135 clampedAbsoluteTargetRect.intersect(svgRoot->contentBoxRect()); 91 136 return clampedAbsoluteTargetRect; -
trunk/WebCore/rendering/SVGImageBufferTools.h
r65665 r65880 35 35 class SVGImageBufferTools : public Noncopyable { 36 36 public: 37 static bool createImageBuffer(const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>&, ImageColorSpace); 38 static void clipToImageBuffer(GraphicsContext*, const AffineTransform& absoluteTransform, const FloatRect& clampedAbsoluteTargetRect, ImageBuffer*); 37 static bool createImageBuffer(const FloatRect& absoluteTargetRect, const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>&, ImageColorSpace); 38 static void renderSubtreeToImageBuffer(ImageBuffer*, RenderObject*, const AffineTransform&); 39 static void clipToImageBuffer(GraphicsContext*, const AffineTransform& absoluteTransform, const FloatRect& clampedAbsoluteTargetRect, OwnPtr<ImageBuffer>&); 39 40 40 static AffineTransform transformationToOutermostSVGCoordinateSystem(const RenderObject*);41 static FloatRect clampedAbsoluteTargetRectForRenderer(const RenderObject*, const AffineTransform& absouteTransform, const FloatRect& targetRect);41 static void calculateTransformationToOutermostSVGCoordinateSystem(const RenderObject*, AffineTransform& absoluteTransform); 42 static FloatRect clampedAbsoluteTargetRectForRenderer(const RenderObject*, const FloatRect& absoluteTargetRect); 42 43 static IntSize roundedImageBufferSize(const FloatSize&); 43 44 -
trunk/WebCore/rendering/SVGRenderSupport.cpp
r65665 r65880 34 34 #include "RenderLayer.h" 35 35 #include "RenderPath.h" 36 #include "RenderSVGContainer.h"37 36 #include "RenderSVGResource.h" 38 37 #include "RenderSVGResourceClipper.h" … … 117 116 } 118 117 119 if (RenderSVGResourceClipper* clipper = resources->clipper()) 120 clipper->applyResource(object, style, paintInfo.context, ApplyToDefaultMode); 118 if (RenderSVGResourceClipper* clipper = resources->clipper()) { 119 if (!clipper->applyResource(object, style, paintInfo.context, ApplyToDefaultMode)) 120 return false; 121 } 121 122 122 123 #if ENABLE(FILTERS) … … 162 163 if (svgStyle->shadow()) 163 164 paintInfo.context->endTransparencyLayer(); 164 }165 166 void SVGRenderSupport::renderSubtreeToImage(ImageBuffer* image, RenderObject* item)167 {168 ASSERT(item);169 ASSERT(image);170 ASSERT(image->context());171 172 PaintInfo info(image->context(), PaintInfo::infiniteRect(), PaintPhaseForeground, 0, 0, 0);173 174 // FIXME: isSVGContainer returns true for RenderSVGViewportContainer, so if this is ever175 // called with one of those, we will read from the wrong offset in an object due to a bad cast.176 RenderSVGContainer* svgContainer = 0;177 if (item && item->isSVGContainer())178 svgContainer = toRenderSVGContainer(item);179 180 bool drawsContents = svgContainer ? svgContainer->drawsContents() : false;181 if (svgContainer && !drawsContents)182 svgContainer->setDrawsContents(true);183 184 item->layoutIfNeeded();185 item->paint(info, 0, 0);186 187 if (svgContainer && !drawsContents)188 svgContainer->setDrawsContents(false);189 165 } 190 166 -
trunk/WebCore/rendering/SVGRenderSupport.h
r65665 r65880 74 74 static void mapLocalToContainer(const RenderObject*, RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&); 75 75 76 // This offers a way to render parts of a WebKit rendering tree into a ImageBuffer.77 static void renderSubtreeToImage(ImageBuffer*, RenderObject*);78 79 76 // Shared between SVG renderers and resources. 80 77 static void applyStrokeStyleToContext(GraphicsContext*, const RenderStyle*, const RenderObject*); -
trunk/WebCore/svg/SVGFEImageElement.cpp
r65449 r65880 31 31 #include "RenderObject.h" 32 32 #include "RenderSVGResource.h" 33 #include "SVGImageBufferTools.h" 33 34 #include "SVGLength.h" 34 35 #include "SVGNames.h" 35 36 #include "SVGPreserveAspectRatio.h" 36 #include "SVGRenderSupport.h"37 37 38 38 namespace WebCore { … … 135 135 m_targetImage = ImageBuffer::create(targetRect.size(), LinearRGB); 136 136 137 SVGRenderSupport::renderSubtreeToImage(m_targetImage.get(), renderer); 137 AffineTransform contentTransformation; 138 SVGImageBufferTools::renderSubtreeToImageBuffer(m_targetImage.get(), renderer, contentTransformation); 138 139 } 139 140
Note: See TracChangeset
for help on using the changeset viewer.