Reviewed by Oliver & Rob.
authoroliver <oliver@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Oct 2007 13:37:01 +0000 (13:37 +0000)
committeroliver <oliver@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Oct 2007 13:37:01 +0000 (13:37 +0000)
Fixes: http://bugs.webkit.org/show_bug.cgi?id=12501 (SVG Text fails to respect opacity, fill-opacity and stroke-opacity)
Fixes: http://bugs.webkit.org/show_bug.cgi?id=14045 (Incorrect support for opacity, fill-opacity and stroke-opacity)

Based on an older patch from Rob, this fixes SVG text opacity as well as group opacity for solid fills & gradients.
The pattern changes are still missing a testcase (need to wait for Antoine Quint for that).

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@26437 268f45cc-cd09-0410-ab3c-d52691b4dbfc

33 files changed:
LayoutTests/ChangeLog
LayoutTests/svg/batik/text/textAnchor-expected.checksum
LayoutTests/svg/batik/text/textAnchor-expected.png
LayoutTests/svg/batik/text/textFeatures-expected.checksum
LayoutTests/svg/batik/text/textFeatures-expected.png
LayoutTests/svg/batik/text/textFeatures.svg
LayoutTests/svg/custom/focus-ring-expected.checksum
LayoutTests/svg/custom/focus-ring-expected.png
LayoutTests/svg/custom/group-opacity-expected.checksum [new file with mode: 0644]
LayoutTests/svg/custom/group-opacity-expected.png [new file with mode: 0644]
LayoutTests/svg/custom/group-opacity-expected.txt [new file with mode: 0644]
LayoutTests/svg/custom/group-opacity.svg [new file with mode: 0644]
LayoutTests/svg/custom/resources/groupOpacityReference1.png [new file with mode: 0644]
LayoutTests/svg/custom/resources/groupOpacityReference2.png [new file with mode: 0644]
LayoutTests/svg/custom/resources/groupOpacityReference3.png [new file with mode: 0644]
LayoutTests/svg/custom/resources/groupOpacityReference4.png [new file with mode: 0644]
LayoutTests/svg/text/text-text-08-b-expected.checksum
LayoutTests/svg/text/text-text-08-b-expected.png
LayoutTests/svg/text/text-text-08-b-expected.txt
WebCore/ChangeLog
WebCore/platform/graphics/svg/SVGResourceFilter.h
WebCore/platform/graphics/svg/cg/SVGPaintServerGradientCg.cpp
WebCore/platform/graphics/svg/cg/SVGPaintServerPatternCg.cpp
WebCore/platform/graphics/svg/cg/SVGPaintServerSolidCg.cpp
WebCore/platform/graphics/svg/cg/SVGResourceFilterCg.mm
WebCore/rendering/RenderPath.cpp
WebCore/rendering/RenderSVGContainer.cpp
WebCore/rendering/RenderSVGImage.cpp
WebCore/rendering/RenderSVGRoot.cpp
WebCore/rendering/RenderSVGText.cpp
WebCore/rendering/SVGRenderSupport.cpp
WebCore/rendering/SVGRenderSupport.h
WebCore/rendering/SVGRootInlineBox.cpp

index 2a0e9d1..0667011 100644 (file)
@@ -1,3 +1,49 @@
+2007-08-10  Nikolas Zimmermann  <zimmermann@kde.org>
+
+        Reviewed by Oliver & Rob.
+
+        Fix test results after the SVG text & group opacity fixes.
+
+        * svg/W3C-SVG-1.1/filters-blend-01-b-expected.checksum:
+        * svg/W3C-SVG-1.1/filters-blend-01-b-expected.png:
+        * svg/W3C-SVG-1.1/text-text-08-b-expected.checksum:
+        * svg/W3C-SVG-1.1/text-text-08-b-expected.png:
+        * svg/W3C-SVG-1.1/text-text-08-b-expected.txt:
+        * svg/batik/text/textAnchor-expected.checksum:
+        * svg/batik/text/textAnchor-expected.png:
+        * svg/batik/text/textFeatures-expected.checksum:
+        * svg/batik/text/textFeatures-expected.png:
+        * svg/custom/group-opacity-expected.checksum: Added.
+        * svg/custom/group-opacity-expected.png: Added.
+        * svg/custom/group-opacity-expected.txt: Added.
+        * svg/custom/group-opacity.svg: Added.
+        * svg/custom/js-update-bounce-expected.checksum:
+        * svg/custom/js-update-bounce-expected.png:
+        * svg/custom/resources/groupOpacityReference1.png: Added.
+        * svg/custom/resources/groupOpacityReference2.png: Added.
+        * svg/custom/resources/groupOpacityReference3.png: Added.
+        * svg/custom/resources/groupOpacityReference4.png: Added.
+        * svg/custom/text-image-opacity-expected.checksum:
+        * svg/custom/text-image-opacity-expected.png:
+        * svg/custom/use-instanceRoot-modifications-expected.checksum:
+        * svg/custom/use-instanceRoot-modifications-expected.png:
+        * svg/custom/use-modify-container-in-target-expected.checksum:
+        * svg/custom/use-modify-container-in-target-expected.png:
+        * svg/custom/use-modify-target-container-expected.checksum:
+        * svg/custom/use-modify-target-container-expected.png:
+        * svg/custom/use-on-g-containing-use-expected.checksum:
+        * svg/custom/use-on-g-containing-use-expected.png:
+        * svg/custom/use-on-g-expected.checksum:
+        * svg/custom/use-on-g-expected.png:
+        * svg/custom/use-on-use-expected.checksum:
+        * svg/custom/use-on-use-expected.png:
+        * svg/custom/use-transform-expected.checksum:
+        * svg/custom/use-transform-expected.png:
+        * svg/hixie/text/003-expected.txt:
+        * svg/text/text-text-08-b-expected.checksum:
+        * svg/text/text-text-08-b-expected.png:
+        * svg/text/text-text-08-b-expected.txt:
+
 2007-08-08  Rob Buis  <buis@kde.org>
 
         Reviewed by Nikolas.
index 660cdac..7ab0c63 100644 (file)
@@ -1 +1 @@
-29972ef68534a9eb7d763868059a70dd
\ No newline at end of file
+72d2d37f4008484873b54600fe501793
\ No newline at end of file
index 90a64b1..6db0e33 100644 (file)
Binary files a/LayoutTests/svg/batik/text/textAnchor-expected.png and b/LayoutTests/svg/batik/text/textAnchor-expected.png differ
index 7c9bc59..ee2472a 100644 (file)
@@ -1 +1 @@
-9254b86390a67f60c297854bc98581f2
\ No newline at end of file
+ba9c8bd4269637a70bcedb31ee753545
\ No newline at end of file
index 9da7a7d..b78d750 100644 (file)
Binary files a/LayoutTests/svg/batik/text/textFeatures-expected.png and b/LayoutTests/svg/batik/text/textFeatures-expected.png differ
index d87348a..cfceb65 100755 (executable)
     <!-- Test content                                                  -->
     <!-- ============================================================= -->
 
-<!-- CRASHES WEBKIT
     <defs>
         <filter id="blur"  filterUnits="userSpaceOnUse" x="0" y="-80" width="200" height="100" filterRes="200">
             <feGaussianBlur stdDeviation="2 2" x="0" y="-80" width="200" height="100"/> 
         </filter>
     </defs>
--->
+
     <g id="testContent">
         <text class="title" x="50%" y="10%" font-size="15" text-anchor="middle" >
             Text Element Features</text>
index 6a6a098..c6cb931 100644 (file)
@@ -1 +1 @@
-24a23b13cc8aa1019263c4e170e73cae
\ No newline at end of file
+5c09e4e41ef5f3e69444e9bc3ddf93d1
\ No newline at end of file
index fee2374..1f67b2f 100644 (file)
Binary files a/LayoutTests/svg/custom/focus-ring-expected.png and b/LayoutTests/svg/custom/focus-ring-expected.png differ
diff --git a/LayoutTests/svg/custom/group-opacity-expected.checksum b/LayoutTests/svg/custom/group-opacity-expected.checksum
new file mode 100644 (file)
index 0000000..6a2a758
--- /dev/null
@@ -0,0 +1 @@
+1c99315ef4dd35ac45abbecf8e7c80e9
\ No newline at end of file
diff --git a/LayoutTests/svg/custom/group-opacity-expected.png b/LayoutTests/svg/custom/group-opacity-expected.png
new file mode 100644 (file)
index 0000000..8cbfa3f
Binary files /dev/null and b/LayoutTests/svg/custom/group-opacity-expected.png differ
diff --git a/LayoutTests/svg/custom/group-opacity-expected.txt b/LayoutTests/svg/custom/group-opacity-expected.txt
new file mode 100644 (file)
index 0000000..3152412
--- /dev/null
@@ -0,0 +1,26 @@
+KRenderingPaintServer {id="gradient_fill" [type=LINEAR-GRADIENT] [stops=[(0.00,#FF0000), (1.00,#008000)]] [start=(0,0)] [end=(1,0)]}
+KRenderingPaintServer {id="stroke_fill" [type=LINEAR-GRADIENT] [stops=[(0.00,#0000FF), (1.00,#FFFF00)]] [start=(0,0)] [end=(1,0)]}
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderSVGRoot {svg} at (5,5) size 570x225
+    RenderSVGHiddenContainer {defs} at (0,0) size 0x0
+      RenderSVGHiddenContainer {linearGradient} at (0,0) size 0x0
+        RenderSVGGradientStop {stop} at (0,0) size 0x0
+        RenderSVGGradientStop {stop} at (0,0) size 0x0
+      RenderSVGHiddenContainer {linearGradient} at (0,0) size 0x0
+        RenderSVGGradientStop {stop} at (0,0) size 0x0
+        RenderSVGGradientStop {stop} at (0,0) size 0x0
+    RenderSVGContainer {g} at (5,5) size 570x110 [transform={m=((1.00,0.00)(0.00,1.00)) t=(10.00,10.00)}]
+      RenderPath {rect} at (5,5) size 110x110 [stroke={[type=SOLID] [color=#008000] [opacity=0.50] [stroke width=10.00]}] [fill={[type=SOLID] [color=#FF0000] [opacity=0.50]}] [data="M0.00,0.00L100.00,0.00L100.00,100.00L0.00,100.00"]
+      RenderSVGContainer {g} at (120,5) size 110x110 [opacity=0.50]
+        RenderPath {rect} at (120,5) size 110x110 [stroke={[type=SOLID] [color=#008000] [stroke width=10.00]}] [fill={[type=SOLID] [color=#FF0000]}] [data="M115.00,0.00L215.00,0.00L215.00,100.00L115.00,100.00"]
+      RenderPath {rect} at (235,5) size 110x110 [opacity=0.50] [stroke={[type=SOLID] [color=#008000] [stroke width=10.00]}] [fill={[type=SOLID] [color=#FF0000]}] [data="M230.00,0.00L330.00,0.00L330.00,100.00L230.00,100.00"]
+      RenderPath {rect} at (350,5) size 110x110 [stroke={[type=LINEAR-GRADIENT] [stops=[(0.00,#0000FF), (1.00,#FFFF00)]] [start=(0,0)] [end=(1,0)] [opacity=0.50] [stroke width=10.00]}] [fill={[type=LINEAR-GRADIENT] [stops=[(0.00,#FF0000), (1.00,#008000)]] [start=(0,0)] [end=(1,0)] [opacity=0.50]}] [data="M345.00,0.00L445.00,0.00L445.00,100.00L345.00,100.00"]
+      RenderPath {rect} at (465,5) size 110x110 [opacity=0.50] [stroke={[type=LINEAR-GRADIENT] [stops=[(0.00,#0000FF), (1.00,#FFFF00)]] [start=(0,0)] [end=(1,0)] [stroke width=10.00]}] [fill={[type=LINEAR-GRADIENT] [stops=[(0.00,#FF0000), (1.00,#008000)]] [start=(0,0)] [end=(1,0)]}] [data="M460.00,0.00L560.00,0.00L560.00,100.00L460.00,100.00"]
+    RenderSVGContainer {g} at (5,120) size 570x110 [transform={m=((1.00,0.00)(0.00,1.00)) t=(5.00,120.00)}]
+      RenderImage {image} at (0,0) size 110x110
+      RenderImage {image} at (0,0) size 110x110
+      RenderImage {image} at (0,0) size 110x110
+      RenderImage {image} at (0,0) size 110x110
+      RenderImage {image} at (0,0) size 110x110
diff --git a/LayoutTests/svg/custom/group-opacity.svg b/LayoutTests/svg/custom/group-opacity.svg
new file mode 100644 (file)
index 0000000..7cf4ee1
--- /dev/null
@@ -0,0 +1,62 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+
+  <title>
+    Fills, strokes and opacity
+  </title>
+
+  <defs>
+    <linearGradient id="gradient_fill">
+      <stop offset="0" stop-color="red" />
+      <stop offset="1" stop-color="green" />
+    </linearGradient>
+    <linearGradient id="stroke_fill">
+      <stop offset="0" stop-color="blue" />
+      <stop offset="1" stop-color="yellow" />
+    </linearGradient>
+  </defs>
+
+  <g transform="translate(10,10)">
+    <rect width="100" height="100"
+          fill="red" stroke="green" stroke-width="10"
+          fill-opacity="0.5" stroke-opacity="0.5" />
+
+    <g opacity="0.5">
+      <rect x="115" width="100" height="100"
+            fill="red" stroke="green" stroke-width="10" />
+    </g>
+
+    <!--
+      was wrong in WebKit, should render as preceding example
+      as "opacity" is not equivalent to "stroke-opacity"
+      and "fill-opacity" combined
+    -->
+    <rect x="230" width="100" height="100"
+          fill="red" stroke="green" stroke-width="10"
+          opacity="0.5" />
+
+    <!--
+      was wrong in WebKit, "fill-opacity" and "stroke-opacity"
+      are not taken into account for gradient fills and strokes
+     -->
+    <rect x="345" width="100" height="100"
+          fill="url(#gradient_fill)" stroke="url(#stroke_fill)" stroke-width="10"
+          fill-opacity="0.5" stroke-opacity="0.5" />
+
+    <!--
+      was wrong in WebKit, same bug as rect #2
+     -->
+    <rect x="460" width="100" height="100"
+          fill="url(#gradient_fill)" stroke="url(#stroke_fill)" stroke-width="10"
+          opacity="0.5" />
+  </g>
+
+  <!-- reference images -->
+  <g transform="translate(5,120)">
+    <image xlink:href="resources/groupOpacityReference1.png" width="110" height="110" />
+    <image x="115" xlink:href="resources/groupOpacityReference2.png" width="110" height="110" />
+    <image x="230" xlink:href="resources/groupOpacityReference2.png" width="110" height="110" />
+    <image x="345" xlink:href="resources/groupOpacityReference3.png" width="110" height="110" />
+    <image x="460" xlink:href="resources/groupOpacityReference4.png" width="110" height="110" />
+  </g>
+
+</svg>
diff --git a/LayoutTests/svg/custom/resources/groupOpacityReference1.png b/LayoutTests/svg/custom/resources/groupOpacityReference1.png
new file mode 100644 (file)
index 0000000..50e7ff9
Binary files /dev/null and b/LayoutTests/svg/custom/resources/groupOpacityReference1.png differ
diff --git a/LayoutTests/svg/custom/resources/groupOpacityReference2.png b/LayoutTests/svg/custom/resources/groupOpacityReference2.png
new file mode 100644 (file)
index 0000000..f5f2a07
Binary files /dev/null and b/LayoutTests/svg/custom/resources/groupOpacityReference2.png differ
diff --git a/LayoutTests/svg/custom/resources/groupOpacityReference3.png b/LayoutTests/svg/custom/resources/groupOpacityReference3.png
new file mode 100644 (file)
index 0000000..a419f4e
Binary files /dev/null and b/LayoutTests/svg/custom/resources/groupOpacityReference3.png differ
diff --git a/LayoutTests/svg/custom/resources/groupOpacityReference4.png b/LayoutTests/svg/custom/resources/groupOpacityReference4.png
new file mode 100644 (file)
index 0000000..fa623b7
Binary files /dev/null and b/LayoutTests/svg/custom/resources/groupOpacityReference4.png differ
index 0a0f1f5..ead83c2 100644 (file)
@@ -1 +1 @@
-4eb6dcfe4ea554d8d768d14b14e141c3
\ No newline at end of file
+1cfd29410fed3ae4d50390b23ebc93b7
\ No newline at end of file
index 3b75a44..c9ccdfe 100644 (file)
Binary files a/LayoutTests/svg/text/text-text-08-b-expected.png and b/LayoutTests/svg/text/text-text-08-b-expected.png differ
index 397f500..0aee329 100644 (file)
@@ -9,7 +9,7 @@ layer at (0,0) size 800x600
       RenderSVGText {text} at (19,120) size 345x77 contains 1 chunk(s) [color=#FF0000]
         RenderSVGInlineText {#text} at (0,-64) size 345x77
           chunk 1 text run 1 at (19.00,120.00) startOffset 0 endOffset 12 width 345.00: "Fill opacity"
-      RenderSVGText {text} at (19,180) size 465x77 contains 1 chunk(s) [color=#FF0000]
+      RenderSVGText {text} at (19,180) size 465x77 contains 1 chunk(s) [color=#FF00007F]
         RenderSVGInlineText {#text} at (0,-64) size 465x77
           chunk 1 text run 1 at (19.00,180.00) startOffset 0 endOffset 14 width 465.00: "Stroke opacity"
       RenderSVGText {text} at (19,240) size 242x77 contains 1 chunk(s) [color=#FF0000]
index f534415..e3eff1d 100644 (file)
@@ -1,3 +1,46 @@
+2007-08-10  Nikolas Zimmermann  <zimmermann@kde.org>
+
+        Reviewed by Oliver & Rob.
+
+        Fixes: http://bugs.webkit.org/show_bug.cgi?id=12501 (SVG Text fails to respect opacity, fill-opacity and stroke-opacity)
+        Fixes: http://bugs.webkit.org/show_bug.cgi?id=14045 (Incorrect support for opacity, fill-opacity and stroke-opacity)
+
+        Based on an older patch from Rob, this fixes SVG text opacity as well as group opacity for solid fills & gradients.
+        The pattern changes are still missing a testcase (need to wait for Antoine Quint for that).
+
+        * platform/graphics/svg/SVGResourceFilter.h:
+        * platform/graphics/svg/cg/SVGPaintServerGradientCg.cpp:
+        (WebCore::SVGPaintServerGradient::setup):
+        * platform/graphics/svg/cg/SVGPaintServerPatternCg.cpp:
+        (WebCore::SVGPaintServerPattern::setup):
+        * platform/graphics/svg/cg/SVGPaintServerSolidCg.cpp:
+        (WebCore::colorFromFloatComponents):
+        (WebCore::SVGPaintServerSolid::setup):
+        * platform/graphics/svg/cg/SVGResourceFilterCg.mm:
+        (WebCore::SVGResourceFilter::SVGResourceFilter):
+        (WebCore::SVGResourceFilter::prepareFilter):
+        (WebCore::SVGResourceFilter::applyFilter):
+        * rendering/RenderPath.cpp:
+        (WebCore::RenderPath::paint):
+        * rendering/RenderSVGContainer.cpp:
+        (WebCore::RenderSVGContainer::paint):
+        (WebCore::RenderSVGContainer::absoluteClippedOverflowRect):
+        * rendering/RenderSVGImage.cpp:
+        (WebCore::RenderSVGImage::paint):
+        (WebCore::RenderSVGImage::absoluteClippedOverflowRect):
+        * rendering/RenderSVGRoot.cpp:
+        (WebCore::RenderSVGRoot::paint):
+        * rendering/RenderSVGText.cpp:
+        (WebCore::RenderSVGText::absoluteClippedOverflowRect):
+        * rendering/SVGRenderSupport.cpp:
+        (WebCore::prepareToRenderSVGContent):
+        (WebCore::finishRenderSVGContent):
+        * rendering/SVGRenderSupport.h:
+        * rendering/SVGRootInlineBox.cpp:
+        (WebCore::prepareTextRendering):
+        (WebCore::SVGRootInlineBox::paint):
+        (WebCore::SVGRootInlineBox::paintChildInlineFlowBox):
+
 2007-08-08  Rob Buis  <buis@kde.org>
 
         Reviewed by Nikolas.
index bf7a70b..29eb1f5 100644 (file)
@@ -97,7 +97,6 @@ private:
 
     CIContext* m_filterCIContext;
     CGLayerRef m_filterCGLayer;
-    GraphicsContext* m_savedContext;
     NSMutableDictionary* m_imagesByName;
 #endif
 
index e7eb61c..bd21410 100644 (file)
@@ -260,9 +260,9 @@ bool SVGPaintServerGradient::setup(GraphicsContext*& context, const RenderObject
     ASSERT(contextRef);
 
     context->save();
-    CGContextSetAlpha(contextRef, style->opacity());
 
     if ((type & ApplyToFillTargetType) && style->svgStyle()->hasFill()) {
+        CGContextSetAlpha(contextRef, style->svgStyle()->fillOpacity());
         context->save();      
 
         if (isPaintingText)
@@ -270,6 +270,7 @@ bool SVGPaintServerGradient::setup(GraphicsContext*& context, const RenderObject
     }
 
     if ((type & ApplyToStrokeTargetType) && style->svgStyle()->hasStroke()) {
+        CGContextSetAlpha(contextRef, style->svgStyle()->strokeOpacity());
         context->save();
         applyStrokeStyleToContext(contextRef, style, object);
 
index b64f1a4..edecf07 100644 (file)
@@ -58,11 +58,10 @@ bool SVGPaintServerPattern::setup(GraphicsContext*& context, const RenderObject*
         return false;
 
     CGSize cellSize = CGSize(tile()->size());
-    CGFloat alpha = 1; // canvasStyle->opacity(); //which?
 
     context->save();
 
-    // Repesct local pattern transformations
+    // Respect local pattern transformation
     CGContextConcatCTM(contextRef, patternTransform());
 
     // Pattern space seems to start in the lower-left, so we flip the Y here. 
@@ -70,7 +69,7 @@ bool SVGPaintServerPattern::setup(GraphicsContext*& context, const RenderObject*
     CGContextSetPatternPhase(contextRef, phase);
 
     RenderStyle* style = object->style();
-    CGContextSetAlpha(contextRef, style->opacity()); // or do I set the alpha above?
+    CGContextSetAlpha(contextRef, style->opacity());
 
     ASSERT(!m_pattern);
     CGPatternCallbacks callbacks = {0, patternCallback, NULL};
@@ -87,6 +86,7 @@ bool SVGPaintServerPattern::setup(GraphicsContext*& context, const RenderObject*
         m_patternSpace = CGColorSpaceCreatePattern(0);
 
     if ((type & ApplyToFillTargetType) && style->svgStyle()->hasFill()) {
+        CGFloat alpha = style->svgStyle()->fillOpacity();
         CGContextSetFillColorSpace(contextRef, m_patternSpace);
         CGContextSetFillPattern(contextRef, m_pattern, &alpha);
  
@@ -95,6 +95,7 @@ bool SVGPaintServerPattern::setup(GraphicsContext*& context, const RenderObject*
     }
 
     if ((type & ApplyToStrokeTargetType) && style->svgStyle()->hasStroke()) {
+        CGFloat alpha = style->svgStyle()->strokeOpacity();
         CGContextSetStrokeColorSpace(contextRef, m_patternSpace);
         CGContextSetStrokePattern(contextRef, m_pattern, &alpha);
         applyStrokeStyleToContext(contextRef, style, object);
index 3011f2a..5c21874 100644 (file)
 
 namespace WebCore {
 
+static inline Color colorFromFloatComponents(CGFloat* colorComponents)
+{
+    return Color(float(colorComponents[0]) * 255.0f,
+                 float(colorComponents[1]) * 255.0f,
+                 float(colorComponents[2]) * 255.0f,
+                 float(colorComponents[3]) * 255.0f);
+}
+
 bool SVGPaintServerSolid::setup(GraphicsContext*& context, const RenderObject* object, SVGPaintTargetType type, bool isPaintingText) const
 {
     CGContextRef contextRef = context->platformContext();
     RenderStyle* style = object->style();
 
-    CGContextSetAlpha(contextRef, style->opacity());
-
     static CGColorSpaceRef deviceRGBColorSpace = CGColorSpaceCreateDeviceRGB(); // This should be shared from GraphicsContext, or some other central location
 
     if ((type & ApplyToFillTargetType) && style->svgStyle()->hasFill()) {
@@ -47,7 +53,7 @@ bool SVGPaintServerSolid::setup(GraphicsContext*& context, const RenderObject* o
         CGContextSetFillColorSpace(contextRef, deviceRGBColorSpace);
         CGContextSetFillColor(contextRef, colorComponents);
         if (isPaintingText) {
-            const_cast<RenderObject*>(object)->style()->setColor(color());
+            const_cast<RenderObject*>(object)->style()->setColor(colorFromFloatComponents(colorComponents));
             context->setTextDrawingMode(cTextFill);
         }
     }
@@ -61,7 +67,7 @@ bool SVGPaintServerSolid::setup(GraphicsContext*& context, const RenderObject* o
         CGContextSetStrokeColor(contextRef, colorComponents);
         applyStrokeStyleToContext(contextRef, style, object);
         if (isPaintingText) {
-            const_cast<RenderObject*>(object)->style()->setColor(color());
+            const_cast<RenderObject*>(object)->style()->setColor(colorFromFloatComponents(colorComponents));
             context->setTextDrawingMode(cTextStroke);
         }
     }
index 3043e93..a01cd62 100644 (file)
@@ -54,7 +54,6 @@ static const char* const SVGPreviousFilterOutputName = "__previousOutput__";
 SVGResourceFilter::SVGResourceFilter()
     : m_filterCIContext(0)
     , m_filterCGLayer(0)
-    , m_savedContext(0)
 {
     m_imagesByName = HardRetainWithNSRelease([[NSMutableDictionary alloc] init]);
 }
@@ -114,11 +113,11 @@ void SVGResourceFilter::prepareFilter(GraphicsContext*& context, const FloatRect
     [filterContextPool drain];
 
     m_filterCGLayer = [m_filterCIContext createCGLayerWithSize:CGRect(bbox).size info:NULL];
-    m_savedContext = context;
 
     context = new GraphicsContext(CGLayerGetContext(m_filterCGLayer));
     context->save();
-    context->concatCTM(AffineTransform().translate(-1.0f * bbox.x(), -1.0f * bbox.y()));
+
+    context->translate(-bbox.x(), -bbox.y());
 }
 
 void SVGResourceFilter::applyFilter(GraphicsContext*& context, const FloatRect& bbox)
@@ -133,11 +132,11 @@ void SVGResourceFilter::applyFilter(GraphicsContext*& context, const FloatRect&
         CIImage* outputImage = [[filterStack lastObject] valueForKey:@"outputImage"];
         if (outputImage) {
             CGRect filterRect = CGRect(filterBBoxForItemBBox(bbox));
-            CGRect translated = filterRect;
-            CGPoint bboxOrigin = CGRect(bbox).origin;
-            CGRect sourceRect = CGRectIntersection(translated,[outputImage extent]);
+            CGRect sourceRect = CGRectIntersection(filterRect, [outputImage extent]);
 
+            CGPoint bboxOrigin = CGRect(bbox).origin;
             CGPoint destOrigin = sourceRect.origin;
+
             destOrigin.x += bboxOrigin.x;
             destOrigin.y += bboxOrigin.y;
 
@@ -152,8 +151,7 @@ void SVGResourceFilter::applyFilter(GraphicsContext*& context, const FloatRect&
     m_filterCIContext = 0;
 
     delete context;
-    context = m_savedContext;
-    m_savedContext = 0;
+    context = 0;
 }
 
 NSArray* SVGResourceFilter::getCIFilterStack(CIImage* inputImage)
index cb35447..d0b0212 100644 (file)
@@ -199,26 +199,21 @@ void RenderPath::paint(PaintInfo& paintInfo, int, int)
     paintInfo.context->save();
     paintInfo.context->concatCTM(localTransform());
 
-#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
     SVGResourceFilter* filter = 0;
-#else
-    void* filter = 0;
-#endif
+
     FloatRect boundingBox = relativeBBox(true);
     if (paintInfo.phase == PaintPhaseForeground) {
+        PaintInfo savedInfo(paintInfo);
+
         prepareToRenderSVGContent(this, paintInfo, boundingBox, filter);
-        
         fillAndStrokePath(m_path, paintInfo.context, style(), this);
 
         if (static_cast<SVGStyledElement*>(element())->supportsMarkers())
             m_markerBounds = drawMarkersIfNeeded(paintInfo.context, paintInfo.rect, m_path);
 
-#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
-        if (filter)
-            filter->applyFilter(paintInfo.context, boundingBox);
-#endif
+        finishRenderSVGContent(this, paintInfo, boundingBox, filter, savedInfo.context);
     }
-    
+
     if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth())
         paintOutline(paintInfo.context, boundingBox.x(), boundingBox.y(), boundingBox.width(), boundingBox.height(), style());
 
index a7258b9..0b586fe 100644 (file)
@@ -33,9 +33,7 @@
 #include "SVGLength.h"
 #include "SVGMarkerElement.h"
 #include "SVGRenderSupport.h"
-#include "SVGResourceClipper.h"
 #include "SVGResourceFilter.h"
-#include "SVGResourceMasker.h"
 #include "SVGSVGElement.h"
 #include "SVGStyledElement.h"
 #include "SVGURIReference.h"
@@ -340,21 +338,13 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, int parentX, int parentY)
     paintInfo.context->save();
     applyContentTransforms(paintInfo);
 
-#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
     SVGResourceFilter* filter = 0;
-#else
-    void* filter = 0;
-#endif
+
+    PaintInfo savedInfo(paintInfo);
+
     FloatRect boundingBox = relativeBBox(true);
-    float opacity = style()->opacity();
-    if (paintInfo.phase == PaintPhaseForeground) {
-        prepareToRenderSVGContent(this, paintInfo, boundingBox, filter);
-        
-        if (opacity < 1.0f) {
-            paintInfo.context->clip(enclosingIntRect(boundingBox));
-            paintInfo.context->beginTransparencyLayer(opacity);
-        }
-    }
+    if (paintInfo.phase == PaintPhaseForeground)
+        prepareToRenderSVGContent(this, paintInfo, boundingBox, filter); 
 
     paintInfo.context->concatCTM(viewportTransform());
 
@@ -364,15 +354,8 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, int parentX, int parentY)
     for (RenderObject* child = firstChild(); child; child = child->nextSibling())
         child->paint(childInfo, 0, 0);
 
-    if (paintInfo.phase == PaintPhaseForeground) {
-#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
-        if (filter)
-            filter->applyFilter(paintInfo.context, boundingBox);
-#endif
-
-        if (opacity < 1.0f)
-            paintInfo.context->endTransparencyLayer();
-    }
+    if (paintInfo.phase == PaintPhaseForeground)
+        finishRenderSVGContent(this, paintInfo, boundingBox, filter, savedInfo.context);
 
     paintInfo.context->restore();
     
@@ -429,7 +412,7 @@ AffineTransform RenderSVGContainer::viewportTransform() const
 
 IntRect RenderSVGContainer::absoluteClippedOverflowRect()
 {
-    IntRect repaintRect;
+    FloatRect repaintRect;
 
     for (RenderObject* current = firstChild(); current != 0; current = current->nextSibling())
         repaintRect.unite(current->absoluteClippedOverflowRect());
@@ -438,10 +421,13 @@ IntRect RenderSVGContainer::absoluteClippedOverflowRect()
     // Filters can expand the bounding box
     SVGResourceFilter* filter = getFilterById(document(), SVGURIReference::getTarget(style()->svgStyle()->filter()));
     if (filter)
-        repaintRect.unite(enclosingIntRect(filter->filterBBoxForItemBBox(repaintRect)));
+        repaintRect.unite(filter->filterBBoxForItemBBox(repaintRect));
 #endif
 
-    return repaintRect;
+    if (!repaintRect.isEmpty())
+        repaintRect.inflate(1); // inflate 1 pixel for antialiasing
+
+    return enclosingIntRect(repaintRect);
 }
 
 void RenderSVGContainer::addFocusRingRects(GraphicsContext* graphicsContext, int tx, int ty)
index c324771..77a9b82 100644 (file)
@@ -134,24 +134,13 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, int, int)
     paintInfo.context->concatCTM(localTransform());
 
     if (paintInfo.phase == PaintPhaseForeground) {
-#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
         SVGResourceFilter* filter = 0;
-#else
-        void* filter = 0;
-#endif
+
         AffineTransform imageCtm(translationForAttributes());
+        PaintInfo savedInfo(paintInfo);
 
         FloatRect boundingBox = FloatRect(imageCtm.e(), imageCtm.f(), m_imageWidth, m_imageHeight);
         prepareToRenderSVGContent(this, paintInfo, boundingBox, filter);
-        float opacity = style()->opacity();
-        if (opacity < 1.0f) {
-            paintInfo.context->clip(enclosingIntRect(boundingBox));
-            paintInfo.context->beginTransparencyLayer(opacity);
-        }
-
-        PaintInfo pi(paintInfo);
-        pi.rect = absoluteTransform().inverse().mapRect(pi.rect);
 
         SVGImageElement* imageElt = static_cast<SVGImageElement*>(node());
 
@@ -164,13 +153,7 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, int, int)
         paintInfo.context->concatCTM(imageCtm);
         paintInfo.context->drawImage(image(), destRect, srcRect);
 
-#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
-        if (filter)
-            filter->applyFilter(paintInfo.context, boundingBox);
-#endif
-
-        if (opacity < 1.0f)
-            paintInfo.context->endTransparencyLayer();
+        finishRenderSVGContent(this, paintInfo, boundingBox, filter, savedInfo.context);
     }
     
     if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth())
@@ -225,8 +208,7 @@ void RenderSVGImage::imageChanged(CachedImage* image)
 
 IntRect RenderSVGImage::absoluteClippedOverflowRect()
 {
-    FloatRect repaintRect = relativeBBox(true);
-    repaintRect = absoluteTransform().mapRect(repaintRect);
+    FloatRect repaintRect = absoluteTransform().mapRect(relativeBBox(true));
 
 #if ENABLE(SVG_EXPERIMENTAL_FEATURES)
     // Filters can expand the bounding box
index 17af674..0307fc8 100644 (file)
@@ -170,35 +170,17 @@ void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY)
  
     applyContentTransforms(childPaintInfo, parentX, parentY);
 
-#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
     SVGResourceFilter* filter = 0;
-#else
-    void* filter = 0;
-#endif
-    FloatRect boundingBox = relativeBBox(true);
-    float opacity = style()->opacity();
-    if (childPaintInfo.phase == PaintPhaseForeground) {
-        prepareToRenderSVGContent(this, childPaintInfo, boundingBox, filter);
-        
-        if (opacity < 1.0f) {
-            childPaintInfo.context->clip(enclosingIntRect(boundingBox));
-            childPaintInfo.context->beginTransparencyLayer(opacity);
-        }
-    }
 
-    paintInfo.context->concatCTM(svg->viewBoxToViewTransform(width(), height()));
+    FloatRect boundingBox = relativeBBox(true);
+    if (childPaintInfo.phase == PaintPhaseForeground)
+        prepareToRenderSVGContent(this, childPaintInfo, boundingBox, filter);        
 
+    childPaintInfo.context->concatCTM(svg->viewBoxToViewTransform(width(), height()));
     RenderContainer::paint(childPaintInfo, 0, 0);
 
-    if (childPaintInfo.phase == PaintPhaseForeground) {
-#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
-        if (filter)
-            filter->applyFilter(childPaintInfo.context, boundingBox);
-#endif
-
-        if (opacity < 1.0f)
-            childPaintInfo.context->endTransparencyLayer();
-    }
+    if (childPaintInfo.phase == PaintPhaseForeground)
+        finishRenderSVGContent(this, childPaintInfo, boundingBox, filter, paintInfo.context);
 
     childPaintInfo.context->restore();
     
index af27342..53206b6 100644 (file)
 #include "RenderSVGRoot.h"
 #include "SVGLength.h"
 #include "SVGLengthList.h"
+#include "SVGURIReference.h"
+#include "SVGResourceFilter.h"
 #include "SVGRootInlineBox.h"
 #include "SVGTextElement.h"
+
 #include <wtf/OwnPtr.h>
 
 namespace WebCore {
@@ -47,7 +50,19 @@ RenderSVGText::RenderSVGText(SVGTextElement* node)
 
 IntRect RenderSVGText::absoluteClippedOverflowRect()
 {
-    return enclosingIntRect(absoluteTransform().mapRect(relativeBBox(true)));
+    FloatRect repaintRect = absoluteTransform().mapRect(relativeBBox(true));
+
+#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
+    // Filters can expand the bounding box
+    SVGResourceFilter* filter = getFilterById(document(), SVGURIReference::getTarget(style()->svgStyle()->filter()));
+    if (filter)
+        repaintRect.unite(filter->filterBBoxForItemBBox(repaintRect));
+#endif
+
+    if (!repaintRect.isEmpty())
+        repaintRect.inflate(1); // inflate 1 pixel for antialiasing
+
+    return enclosingIntRect(repaintRect);
 }
 
 bool RenderSVGText::requiresLayer()
index fa2797a..740029d 100644 (file)
@@ -26,6 +26,8 @@
 
 #if ENABLE(SVG)
 
+#include "SVGRenderSupport.h"
+
 #include "AffineTransform.h"
 #include "RenderObject.h"
 #include "SVGResourceClipper.h"
 
 namespace WebCore {
 
-#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
 void prepareToRenderSVGContent(RenderObject* object, RenderObject::PaintInfo& paintInfo, const FloatRect& boundingBox, SVGResourceFilter*& filter)
-#else
-void prepareToRenderSVGContent(RenderObject* object, RenderObject::PaintInfo& paintInfo, const FloatRect& boundingBox, void*)
-#endif
 {    
     SVGElement* svgElement = static_cast<SVGElement*>(object->element());
     ASSERT(svgElement && svgElement->document() && svgElement->isStyled());
+    ASSERT(object);
     
     SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(svgElement);
-    const SVGRenderStyle* svgStyle = object->style()->svgStyle();
-    
+    const RenderStyle* style = object->style();
+    ASSERT(style);
+
+    const SVGRenderStyle* svgStyle = style->svgStyle();
+    ASSERT(svgStyle);
+
+    // Setup transparency layers before setting up filters!
+    float opacity = style->opacity();    
+    if (opacity < 1.0f) {
+        paintInfo.context->clip(enclosingIntRect(boundingBox));
+        paintInfo.context->beginTransparencyLayer(opacity);
+    }
+
 #if ENABLE(SVG_EXPERIMENTAL_FEATURES)
     AtomicString filterId(SVGURIReference::getTarget(svgStyle->filter()));
 #endif
+
     AtomicString clipperId(SVGURIReference::getTarget(svgStyle->clipPath()));
     AtomicString maskerId(SVGURIReference::getTarget(svgStyle->maskElement()));
-    
+
     Document* document = object->document();
 #if ENABLE(SVG_EXPERIMENTAL_FEATURES)
     filter = getFilterById(document, filterId);
 #endif
+
     SVGResourceClipper* clipper = getClipperById(document, clipperId);
     SVGResourceMasker* masker = getMaskerById(document, maskerId);
-    
+
 #if ENABLE(SVG_EXPERIMENTAL_FEATURES)
     if (filter)
         filter->prepareFilter(paintInfo.context, boundingBox);
     else if (!filterId.isEmpty())
         svgElement->document()->accessSVGExtensions()->addPendingResource(filterId, styledElement);
 #endif
-    
+
     if (clipper) {
         clipper->addClient(styledElement);
         clipper->applyClip(paintInfo.context, boundingBox);
@@ -81,6 +93,25 @@ void prepareToRenderSVGContent(RenderObject* object, RenderObject::PaintInfo& pa
         svgElement->document()->accessSVGExtensions()->addPendingResource(maskerId, styledElement);
 }
 
+void finishRenderSVGContent(RenderObject* object, RenderObject::PaintInfo& paintInfo, const FloatRect& boundingBox, SVGResourceFilter*& filter, GraphicsContext* savedContext)
+{
+    ASSERT(object);
+
+    const RenderStyle* style = object->style();
+    ASSERT(style);
+
+#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
+    if (filter) {
+        filter->applyFilter(paintInfo.context, boundingBox);
+        paintInfo.context = savedContext;
+    }
+#endif
+
+    float opacity = style->opacity();    
+    if (opacity < 1.0f)
+        paintInfo.context->endTransparencyLayer();
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(SVG)
index 7a7641f..283a5a9 100644 (file)
 
 namespace WebCore {
 
-#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
 class SVGResourceFilter;
-void prepareToRenderSVGContent(RenderObject*, RenderObject::PaintInfo& paintInfo, const FloatRect& boundingBox, SVGResourceFilter*&);
-#else
-void prepareToRenderSVGContent(RenderObject*, RenderObject::PaintInfo& paintInfo, const FloatRect& boundingBox, void*);
-#endif
+void prepareToRenderSVGContent(RenderObject*, RenderObject::PaintInfo&, const FloatRect& boundingBox, SVGResourceFilter*&);
+void finishRenderSVGContent(RenderObject*, RenderObject::PaintInfo&, const FloatRect& boundingBox, SVGResourceFilter*&, GraphicsContext* savedContext);
 
 }
 
index c40634d..9c77ca6 100644 (file)
 
 namespace WebCore {
 
-#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
 static void prepareTextRendering(RenderObject::PaintInfo& paintInfo, int tx, int ty, InlineFlowBox* flowBox, FloatRect& boundingBox, SVGResourceFilter*& filter)
-#else
-static void prepareTextRendering(RenderObject::PaintInfo& paintInfo, int tx, int ty, InlineFlowBox* flowBox, FloatRect& boundingBox, void* filter)
-#endif
 {
     ASSERT(paintInfo.phase == PaintPhaseForeground);
+    ASSERT(flowBox);
+
     RenderObject* object = flowBox->object();
+    ASSERT(object);
 
     paintInfo.context->save();
     paintInfo.context->concatCTM(object->localTransform());
 
     boundingBox = FloatRect(tx + flowBox->xPos(), ty + flowBox->yPos(), flowBox->width(), flowBox->height());
-
     prepareToRenderSVGContent(object, paintInfo, boundingBox, filter);
 }
 
@@ -134,22 +132,12 @@ void SVGRootInlineBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
         return;
 
     FloatRect boundingBox;
-
-#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
     SVGResourceFilter* filter = 0;
-#else
-    void* filter = 0;
-#endif
+
+    RenderObject::PaintInfo savedInfo(paintInfo);
     prepareTextRendering(paintInfo, tx, ty, this, boundingBox, filter);
 
     RenderObject::PaintInfo pi(paintInfo);
-
-    float opacity = object()->style()->opacity();
-    if (opacity < 1.0f) {
-        paintInfo.context->clip(enclosingIntRect(boundingBox));
-        paintInfo.context->beginTransparencyLayer(opacity);
-    }
-
     SVGPaintServer* fillPaintServer = SVGPaintServer::fillPaintServer(object()->style(), object());
     if (fillPaintServer) {
         if (fillPaintServer->setup(pi.context, object(), ApplyToFillTargetType, true)) {
@@ -172,14 +160,7 @@ void SVGRootInlineBox::paint(RenderObject::PaintInfo& paintInfo, int tx, int ty)
         }
     }
 
-#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
-    if (filter)
-        filter->applyFilter(paintInfo.context, boundingBox);
-#endif
-
-    if (opacity < 1.0f)
-        paintInfo.context->endTransparencyLayer();
-
+    finishRenderSVGContent(object(), paintInfo, boundingBox, filter, savedInfo.context);
     paintInfo.context->restore();
 }
 
@@ -1021,58 +1002,42 @@ void SVGRootInlineBox::paintChildInlineTextBox(RenderObject::PaintInfo& paintInf
 void SVGRootInlineBox::paintChildInlineFlowBox(RenderObject::PaintInfo& paintInfo, int tx, int ty, InlineFlowBox* flowBox, Vector<SVGChar>::iterator& it)
 {
     FloatRect boundingBox;
-    
-#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
     SVGResourceFilter* filter = 0;
-#else
-    void* filter = 0;
-#endif
+
+    RenderObject::PaintInfo savedInfo(paintInfo);
     prepareTextRendering(paintInfo, tx, ty, flowBox, boundingBox, filter);
-    
+
     RenderObject* object = flowBox->object();
     RenderObject::PaintInfo pi(paintInfo);
-    
+
     if (!flowBox->isRootInlineBox())
         pi.rect = (object->localTransform()).inverse().mapRect(pi.rect);
-    
-    float opacity = object->style()->opacity();
-    if (opacity < 1.0f) {
-        paintInfo.context->clip(enclosingIntRect(boundingBox));
-        paintInfo.context->beginTransparencyLayer(opacity);
-    }
-    
+
     bool painted = false;
     Vector<SVGChar>::iterator savedIt = it;
-    
+
     SVGPaintServer* fillPaintServer = SVGPaintServer::fillPaintServer(object->style(), object);
     if (fillPaintServer) {
         if (fillPaintServer->setup(pi.context, object, ApplyToFillTargetType, true)) {
             painted = true;
-            
+
             paintInlineBoxes(pi, tx, ty, flowBox, it);
             fillPaintServer->teardown(pi.context, object, ApplyToFillTargetType, true);
         }
     }
-    
+
     SVGPaintServer* strokePaintServer = SVGPaintServer::strokePaintServer(object->style(), object);
     if (strokePaintServer) {
         if (strokePaintServer->setup(pi.context, object, ApplyToStrokeTargetType, true)) {
             if (painted)
                 it = savedIt;
-            
+
             paintInlineBoxes(pi, tx, ty, flowBox, it);
             strokePaintServer->teardown(pi.context, object, ApplyToStrokeTargetType, true);
         }
     }
-    
-#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
-    if (filter)
-        filter->applyFilter(paintInfo.context, boundingBox);
-#endif
-    
-    if (opacity < 1.0f)
-        paintInfo.context->endTransparencyLayer();
-    
+
+    finishRenderSVGContent(object, paintInfo, boundingBox, filter, savedInfo.context);
     paintInfo.context->restore();
 }