[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.15.1-1414-gc69ee75

agl at chromium.org agl at chromium.org
Thu Oct 29 20:42:08 UTC 2009


The following commit has been merged in the webkit-1.1 branch:
commit 87f57b2e6ea442e6d8e3d0a6a4be0f0bfd7b7f59
Author: agl at chromium.org <agl at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Oct 8 22:31:11 2009 +0000

    2009-10-08  Adam Langley  <agl at google.com>
    
            Reviewed by Eric Seidel.
    
            Currently, Skia clip paths are 1-bit. This patch makes our path
            clipping anti-aliased for non-canvas drawing.
    
            http://code.google.com/p/chromium/issues/detail?id=5927
            https://bugs.webkit.org/show_bug.cgi?id=28820
            http://www.imperialviolet.org/2009/09/02/anti-aliased-clipping.html
    
            Already covered by layout tests. New baselines will be needed in the
            Chromium tree.
    
            * html/canvas/CanvasRenderingContext2D.cpp:
            (WebCore::CanvasRenderingContext2D::clip):
            * platform/graphics/GraphicsContext.h:
            * platform/graphics/cairo/GraphicsContextCairo.cpp:
            (WebCore::GraphicsContext::canvasClip):
            * platform/graphics/cg/GraphicsContextCG.cpp:
            (WebCore::GraphicsContext::canvasClip):
            * platform/graphics/haiku/GraphicsContextHaiku.cpp:
            (WebCore::GraphicsContext::canvasClip):
            * platform/graphics/qt/GraphicsContextQt.cpp:
            (WebCore::GraphicsContext::canvasClip):
            * platform/graphics/skia/GraphicsContextSkia.cpp:
            (WebCore::GraphicsContext::addInnerRoundedRectClip):
            (WebCore::GraphicsContext::clip):
            (WebCore::GraphicsContext::canvasClip):
            (WebCore::GraphicsContext::clipPath):
            * platform/graphics/skia/PlatformContextSkia.cpp:
            (PlatformContextSkia::clipPathAntiAliased):
            (PlatformContextSkia::restore):
            (PlatformContextSkia::applyAntiAliasedClipPaths):
            * platform/graphics/skia/PlatformContextSkia.h:
            * platform/graphics/win/GraphicsContextWin.cpp:
            (WebCore::GraphicsContext::canvasClip):
            * platform/graphics/wince/GraphicsContextWince.cpp:
            (WebCore::GraphicsContext::canvasClip):
            * platform/graphics/wx/GraphicsContextWx.cpp:
            (WebCore::GraphicsContext::canvasClip):
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@49329 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index d26cf88..711a1c1 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,45 @@
+2009-10-08  Adam Langley  <agl at google.com>
+
+        Reviewed by Eric Seidel.
+
+        Currently, Skia clip paths are 1-bit. This patch makes our path
+        clipping anti-aliased for non-canvas drawing.
+
+        http://code.google.com/p/chromium/issues/detail?id=5927
+        https://bugs.webkit.org/show_bug.cgi?id=28820
+        http://www.imperialviolet.org/2009/09/02/anti-aliased-clipping.html
+
+        Already covered by layout tests. New baselines will be needed in the
+        Chromium tree.
+
+        * html/canvas/CanvasRenderingContext2D.cpp:
+        (WebCore::CanvasRenderingContext2D::clip):
+        * platform/graphics/GraphicsContext.h:
+        * platform/graphics/cairo/GraphicsContextCairo.cpp:
+        (WebCore::GraphicsContext::canvasClip):
+        * platform/graphics/cg/GraphicsContextCG.cpp:
+        (WebCore::GraphicsContext::canvasClip):
+        * platform/graphics/haiku/GraphicsContextHaiku.cpp:
+        (WebCore::GraphicsContext::canvasClip):
+        * platform/graphics/qt/GraphicsContextQt.cpp:
+        (WebCore::GraphicsContext::canvasClip):
+        * platform/graphics/skia/GraphicsContextSkia.cpp:
+        (WebCore::GraphicsContext::addInnerRoundedRectClip):
+        (WebCore::GraphicsContext::clip):
+        (WebCore::GraphicsContext::canvasClip):
+        (WebCore::GraphicsContext::clipPath):
+        * platform/graphics/skia/PlatformContextSkia.cpp:
+        (PlatformContextSkia::clipPathAntiAliased):
+        (PlatformContextSkia::restore):
+        (PlatformContextSkia::applyAntiAliasedClipPaths):
+        * platform/graphics/skia/PlatformContextSkia.h:
+        * platform/graphics/win/GraphicsContextWin.cpp:
+        (WebCore::GraphicsContext::canvasClip):
+        * platform/graphics/wince/GraphicsContextWince.cpp:
+        (WebCore::GraphicsContext::canvasClip):
+        * platform/graphics/wx/GraphicsContextWx.cpp:
+        (WebCore::GraphicsContext::canvasClip):
+
 2009-10-08  Brian Weinstein  <bweinstein at apple.com>
 
         Reviewed by Timothy Hatcher.
diff --git a/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index ed462fc..5e25b93 100644
--- a/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -687,7 +687,7 @@ void CanvasRenderingContext2D::clip()
         return;
     if (!state().m_invertibleCTM)
         return;
-    c->clip(m_path);
+    c->canvasClip(m_path);
 #if ENABLE(DASHBOARD_SUPPORT)
     clearPathForDashboardBackwardCompatibilityMode();
 #endif
diff --git a/WebCore/platform/graphics/GraphicsContext.h b/WebCore/platform/graphics/GraphicsContext.h
index e0d9294..c6bb20c 100644
--- a/WebCore/platform/graphics/GraphicsContext.h
+++ b/WebCore/platform/graphics/GraphicsContext.h
@@ -297,6 +297,11 @@ namespace WebCore {
         void addPath(const Path&);
 
         void clip(const Path&);
+
+        // This clip function is used only by <canvas> code. It allows
+        // implementations to handle clipping on the canvas differently since
+        // the disipline is different.
+        void canvasClip(const Path&);
         void clipOut(const Path&);
 
         void scale(const FloatSize&);
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index de8afb3..8741c5e 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -931,6 +931,11 @@ void GraphicsContext::clip(const Path& path)
     m_data->clip(path);
 }
 
+void GraphicsContext::canvasClip(const Path& path)
+{
+    clip(path);
+}
+
 void GraphicsContext::clipOut(const Path& path)
 {
     if (paintingDisabled())
diff --git a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
index 1b843e4..1350bd3 100644
--- a/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
+++ b/WebCore/platform/graphics/cg/GraphicsContextCG.cpp
@@ -849,6 +849,11 @@ void GraphicsContext::clip(const Path& path)
     m_data->clip(path);
 }
 
+void GraphicsContext::canvasClip(const Path& path)
+{
+    clip(path);
+}
+
 void GraphicsContext::clipOut(const Path& path)
 {
     if (paintingDisabled())
diff --git a/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp
index d785ef4..c23b8a9 100644
--- a/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp
+++ b/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp
@@ -369,6 +369,11 @@ void GraphicsContext::clip(const Path& path)
     m_data->m_view->ConstrainClippingRegion(path.platformPath());
 }
 
+void GraphicsContext::canvasClip(const Path& path)
+{
+    clip(path);
+}
+
 void GraphicsContext::clipOut(const Path& path)
 {
     if (paintingDisabled())
diff --git a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
index fa7b070..57a481a 100644
--- a/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContextQt.cpp
@@ -1053,6 +1053,11 @@ void GraphicsContext::clip(const Path& path)
     m_data->p()->setClipPath(*path.platformPath(), Qt::IntersectClip);
 }
 
+void GraphicsContext::canvasClip(const Path& path)
+{
+    clip(path);
+}
+
 void GraphicsContext::clipOut(const Path& path)
 {
     if (paintingDisabled())
diff --git a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
index c9f1349..889c41b 100644
--- a/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp
@@ -296,7 +296,7 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness
         r.inset(SkIntToScalar(thickness), SkIntToScalar(thickness));
         path.addOval(r, SkPath::kCCW_Direction);
     }
-    platformContext()->canvas()->clipPath(path);
+    platformContext()->clipPathAntiAliased(path);
 }
 
 void GraphicsContext::addPath(const Path& path)
@@ -356,6 +356,18 @@ void GraphicsContext::clip(const Path& path)
     if (!isPathSkiaSafe(getCTM(), p))
         return;
 
+    platformContext()->clipPathAntiAliased(p);
+}
+
+void GraphicsContext::canvasClip(const Path& path)
+{
+    if (paintingDisabled())
+        return;
+
+    const SkPath& p = *path.platformPath();
+    if (!isPathSkiaSafe(getCTM(), p))
+        return;
+
     platformContext()->canvas()->clipPath(p);
 }
 
@@ -407,7 +419,7 @@ void GraphicsContext::clipPath(WindRule clipRule)
         return;
 
     path.setFillType(clipRule == RULE_EVENODD ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType);
-    platformContext()->canvas()->clipPath(path);
+    platformContext()->clipPathAntiAliased(path);
 }
 
 void GraphicsContext::clipToImageBuffer(const FloatRect& rect,
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
index 1fb62fc..8cb53a0 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
@@ -45,6 +45,7 @@
 #include "SkDashPathEffect.h"
 
 #include <wtf/MathExtras.h>
+#include <wtf/Vector.h>
 
 namespace WebCore 
 {
@@ -95,6 +96,10 @@ struct PlatformContextSkia::State {
     WebCore::FloatRect m_clip;
 #endif
 
+    // This is a list of clipping paths which are currently active, in the
+    // order in which they were pushed.
+    WTF::Vector<SkPath> m_antiAliasClipPaths;
+
 private:
     // Not supported.
     void operator=(const State&);
@@ -249,6 +254,21 @@ void PlatformContextSkia::beginLayerClippedToImage(const WebCore::FloatRect& rec
 }
 #endif
 
+void PlatformContextSkia::clipPathAntiAliased(const SkPath& clipPath)
+{
+    // If we are currently tracking any anti-alias clip paths, then we already
+    // have a layer in place and don't need to add another.
+    bool haveLayerOutstanding = m_state->m_antiAliasClipPaths.size();
+
+    // See comments in applyAntiAliasedClipPaths about how this works.
+    m_state->m_antiAliasClipPaths.append(clipPath);
+
+    if (!haveLayerOutstanding) {
+        SkRect bounds = clipPath.getBounds();
+        canvas()->saveLayerAlpha(&bounds, 255, static_cast<SkCanvas::SaveFlags>(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag | SkCanvas::kClipToLayer_SaveFlag));
+    }
+}
+
 void PlatformContextSkia::restore()
 {
 #if defined(__linux__) || PLATFORM(WIN_OS)
@@ -258,6 +278,9 @@ void PlatformContextSkia::restore()
     }
 #endif
 
+    if (!m_state->m_antiAliasClipPaths.isEmpty())
+        applyAntiAliasedClipPaths(m_state->m_antiAliasClipPaths);
+
     m_stateStack.removeLast();
     m_state = &m_stateStack.last();
 
@@ -549,3 +572,40 @@ void PlatformContextSkia::applyClipFromImage(const WebCore::FloatRect& rect, con
     m_canvas->drawBitmap(imageBuffer, SkFloatToScalar(rect.x()), SkFloatToScalar(rect.y()), &paint);
 }
 #endif
+
+void PlatformContextSkia::applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths)
+{
+    // Anti-aliased clipping:
+    //
+    // Skia's clipping is 1-bit only. Consider what would happen if it were 8-bit:
+    // We have a square canvas, filled with white and we declare a circular
+    // clipping path. Then we fill twice with a black rectangle. The fractional
+    // pixels would first get the correct color (white * alpha + black * (1 -
+    // alpha)), but the second fill would apply the alpha to the already
+    // modified color and the result would be too dark.
+    //
+    // This, anti-aliased clipping needs to be performed after the drawing has
+    // been done. In order to do this, we create a new layer of the canvas in
+    // clipPathAntiAliased and store the clipping path. All drawing is done to
+    // the layer's bitmap while it's in effect. When WebKit calls restore() to
+    // undo the clipping, this function is called.
+    //
+    // Here, we walk the list of clipping paths backwards and, for each, we
+    // clear outside of the clipping path. We only need a single extra layer
+    // for any number of clipping paths.
+    //
+    // When we call restore on the SkCanvas, the layer's bitmap is composed
+    // into the layer below and we end up with correct, anti-aliased clipping.
+
+    SkPaint paint;
+    paint.setXfermodeMode(SkXfermode::kClear_Mode);
+    paint.setAntiAlias(true);
+    paint.setStyle(SkPaint::kFill_Style);
+
+    for (size_t i = paths.size() - 1; i < paths.size(); --i) {
+        paths[i].setFillType(SkPath::kInverseWinding_FillType);
+        m_canvas->drawPath(paths[i], paint);
+    }
+
+    m_canvas->restore();
+}
diff --git a/WebCore/platform/graphics/skia/PlatformContextSkia.h b/WebCore/platform/graphics/skia/PlatformContextSkia.h
index 0c87fc2..53590bf 100644
--- a/WebCore/platform/graphics/skia/PlatformContextSkia.h
+++ b/WebCore/platform/graphics/skia/PlatformContextSkia.h
@@ -92,6 +92,7 @@ public:
     void beginLayerClippedToImage(const WebCore::FloatRect&,
                                   const WebCore::ImageBuffer*);
 #endif
+    void clipPathAntiAliased(const SkPath&);
 
     // Sets up the common flags on a paint for antialiasing, effects, etc.
     // This is implicitly called by setupPaintFill and setupPaintStroke, but
@@ -172,6 +173,7 @@ private:
     // m_canvas that are also in imageBuffer.
     void applyClipFromImage(const WebCore::FloatRect&, const SkBitmap&);
 #endif
+    void applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths);
 
     // Defines drawing style.
     struct State;
diff --git a/WebCore/platform/graphics/win/GraphicsContextWin.cpp b/WebCore/platform/graphics/win/GraphicsContextWin.cpp
index 54b0cb2..7bcfbc1 100644
--- a/WebCore/platform/graphics/win/GraphicsContextWin.cpp
+++ b/WebCore/platform/graphics/win/GraphicsContextWin.cpp
@@ -163,6 +163,11 @@ void GraphicsContextPlatformPrivate::clip(const Path&)
     notImplemented();
 }
 
+void GraphicsContext::canvasClip(const Path& path)
+{
+    clip(path);
+}
+
 void GraphicsContextPlatformPrivate::scale(const FloatSize& size)
 {
     if (!m_hdc)
diff --git a/WebCore/platform/graphics/wince/GraphicsContextWince.cpp b/WebCore/platform/graphics/wince/GraphicsContextWince.cpp
index c114c0e..f308840 100644
--- a/WebCore/platform/graphics/wince/GraphicsContextWince.cpp
+++ b/WebCore/platform/graphics/wince/GraphicsContextWince.cpp
@@ -1219,6 +1219,11 @@ void GraphicsContext::clip(const Path& path)
     notImplemented();
 }
 
+void GraphicsContext::canvasClip(const Path& path)
+{
+    clip(path);
+}
+
 void GraphicsContext::clipOut(const Path&)
 {
     notImplemented();
diff --git a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
index 686fb07..39f14f4 100644
--- a/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
+++ b/WebCore/platform/graphics/wx/GraphicsContextWx.cpp
@@ -344,6 +344,11 @@ void GraphicsContext::clip(const Path&)
     notImplemented();
 }
 
+void GraphicsContext::canvasClip(const Path& path)
+{
+    clip(path);
+}
+
 void GraphicsContext::clipToImageBuffer(const FloatRect&, const ImageBuffer*)
 {
     notImplemented();

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list