[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:45:31 UTC 2009
The following commit has been merged in the webkit-1.1 branch:
commit bf28f7035f5bb85392bc6891160001e68fa16a0f
Author: agl at chromium.org <agl at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Thu Oct 15 18:16:38 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.
(Reland. First landed in r49329, reverted in r49330 due to Windows
build break)
* 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@49641 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index b68a770..3c30504 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,48 @@
+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.
+
+ (Reland. First landed in r49329, reverted in r49330 due to Windows
+ build break)
+
+ * 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-15 Eric Carlson <eric.carlson at apple.com>
Reviewed by Simon Fraser.
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/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