Changeset 49641 in webkit


Ignore:
Timestamp:
Oct 15, 2009 11:16:38 AM (15 years ago)
Author:
agl@chromium.org
Message:

2009-10-08 Adam Langley <agl@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):
Location:
trunk/WebCore
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r49636 r49641  
     12009-10-08  Adam Langley  <agl@google.com>
     2
     3        Reviewed by Eric Seidel.
     4
     5        Currently, Skia clip paths are 1-bit. This patch makes our path
     6        clipping anti-aliased for non-canvas drawing.
     7
     8        http://code.google.com/p/chromium/issues/detail?id=5927
     9        https://bugs.webkit.org/show_bug.cgi?id=28820
     10        http://www.imperialviolet.org/2009/09/02/anti-aliased-clipping.html
     11
     12        Already covered by layout tests. New baselines will be needed in the
     13        Chromium tree.
     14
     15        (Reland. First landed in r49329, reverted in r49330 due to Windows
     16        build break)
     17
     18        * html/canvas/CanvasRenderingContext2D.cpp:
     19        (WebCore::CanvasRenderingContext2D::clip):
     20        * platform/graphics/GraphicsContext.h:
     21        * platform/graphics/cairo/GraphicsContextCairo.cpp:
     22        (WebCore::GraphicsContext::canvasClip):
     23        * platform/graphics/cg/GraphicsContextCG.cpp:
     24        (WebCore::GraphicsContext::canvasClip):
     25        * platform/graphics/haiku/GraphicsContextHaiku.cpp:
     26        (WebCore::GraphicsContext::canvasClip):
     27        * platform/graphics/qt/GraphicsContextQt.cpp:
     28        (WebCore::GraphicsContext::canvasClip):
     29        * platform/graphics/skia/GraphicsContextSkia.cpp:
     30        (WebCore::GraphicsContext::addInnerRoundedRectClip):
     31        (WebCore::GraphicsContext::clip):
     32        (WebCore::GraphicsContext::canvasClip):
     33        (WebCore::GraphicsContext::clipPath):
     34        * platform/graphics/skia/PlatformContextSkia.cpp:
     35        (PlatformContextSkia::clipPathAntiAliased):
     36        (PlatformContextSkia::restore):
     37        (PlatformContextSkia::applyAntiAliasedClipPaths):
     38        * platform/graphics/skia/PlatformContextSkia.h:
     39        * platform/graphics/win/GraphicsContextWin.cpp:
     40        (WebCore::GraphicsContext::canvasClip):
     41        * platform/graphics/wince/GraphicsContextWince.cpp:
     42        (WebCore::GraphicsContext::canvasClip):
     43        * platform/graphics/wx/GraphicsContextWx.cpp:
     44        (WebCore::GraphicsContext::canvasClip):
     45
    1462009-10-15  Eric Carlson  <eric.carlson@apple.com>
    247
  • trunk/WebCore/html/canvas/CanvasRenderingContext2D.cpp

    r49330 r49641  
    688688    if (!state().m_invertibleCTM)
    689689        return;
    690     c->clip(m_path);
     690    c->canvasClip(m_path);
    691691#if ENABLE(DASHBOARD_SUPPORT)
    692692    clearPathForDashboardBackwardCompatibilityMode();
  • trunk/WebCore/platform/graphics/GraphicsContext.h

    r49330 r49641  
    298298
    299299        void clip(const Path&);
     300
     301        // This clip function is used only by <canvas> code. It allows
     302        // implementations to handle clipping on the canvas differently since
     303        // the disipline is different.
     304        void canvasClip(const Path&);
    300305        void clipOut(const Path&);
    301306
  • trunk/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp

    r49330 r49641  
    932932}
    933933
     934void GraphicsContext::canvasClip(const Path& path)
     935{
     936    clip(path);
     937}
     938
    934939void GraphicsContext::clipOut(const Path& path)
    935940{
  • trunk/WebCore/platform/graphics/cg/GraphicsContextCG.cpp

    r49330 r49641  
    850850}
    851851
     852void GraphicsContext::canvasClip(const Path& path)
     853{
     854    clip(path);
     855}
     856
    852857void GraphicsContext::clipOut(const Path& path)
    853858{
  • trunk/WebCore/platform/graphics/haiku/GraphicsContextHaiku.cpp

    r49330 r49641  
    370370}
    371371
     372void GraphicsContext::canvasClip(const Path& path)
     373{
     374    clip(path);
     375}
     376
    372377void GraphicsContext::clipOut(const Path& path)
    373378{
  • trunk/WebCore/platform/graphics/qt/GraphicsContextQt.cpp

    r49330 r49641  
    10541054}
    10551055
     1056void GraphicsContext::canvasClip(const Path& path)
     1057{
     1058    clip(path);
     1059}
     1060
    10561061void GraphicsContext::clipOut(const Path& path)
    10571062{
  • trunk/WebCore/platform/graphics/skia/GraphicsContextSkia.cpp

    r49330 r49641  
    297297        path.addOval(r, SkPath::kCCW_Direction);
    298298    }
    299     platformContext()->canvas()->clipPath(path);
     299    platformContext()->clipPathAntiAliased(path);
    300300}
    301301
     
    357357        return;
    358358
     359    platformContext()->clipPathAntiAliased(p);
     360}
     361
     362void GraphicsContext::canvasClip(const Path& path)
     363{
     364    if (paintingDisabled())
     365        return;
     366
     367    const SkPath& p = *path.platformPath();
     368    if (!isPathSkiaSafe(getCTM(), p))
     369        return;
     370
    359371    platformContext()->canvas()->clipPath(p);
    360372}
     
    408420
    409421    path.setFillType(clipRule == RULE_EVENODD ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType);
    410     platformContext()->canvas()->clipPath(path);
     422    platformContext()->clipPathAntiAliased(path);
    411423}
    412424
  • trunk/WebCore/platform/graphics/skia/PlatformContextSkia.cpp

    r49330 r49641  
    4646
    4747#include <wtf/MathExtras.h>
     48#include <wtf/Vector.h>
    4849
    4950namespace WebCore
     
    9596    WebCore::FloatRect m_clip;
    9697#endif
     98
     99    // This is a list of clipping paths which are currently active, in the
     100    // order in which they were pushed.
     101    WTF::Vector<SkPath> m_antiAliasClipPaths;
    97102
    98103private:
     
    250255#endif
    251256
     257void PlatformContextSkia::clipPathAntiAliased(const SkPath& clipPath)
     258{
     259    // If we are currently tracking any anti-alias clip paths, then we already
     260    // have a layer in place and don't need to add another.
     261    bool haveLayerOutstanding = m_state->m_antiAliasClipPaths.size();
     262
     263    // See comments in applyAntiAliasedClipPaths about how this works.
     264    m_state->m_antiAliasClipPaths.append(clipPath);
     265
     266    if (!haveLayerOutstanding) {
     267        SkRect bounds = clipPath.getBounds();
     268        canvas()->saveLayerAlpha(&bounds, 255, static_cast<SkCanvas::SaveFlags>(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag | SkCanvas::kClipToLayer_SaveFlag));
     269    }
     270}
     271
    252272void PlatformContextSkia::restore()
    253273{
     
    258278    }
    259279#endif
     280
     281    if (!m_state->m_antiAliasClipPaths.isEmpty())
     282        applyAntiAliasedClipPaths(m_state->m_antiAliasClipPaths);
    260283
    261284    m_stateStack.removeLast();
     
    550573}
    551574#endif
     575
     576void PlatformContextSkia::applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths)
     577{
     578    // Anti-aliased clipping:
     579    //
     580    // Skia's clipping is 1-bit only. Consider what would happen if it were 8-bit:
     581    // We have a square canvas, filled with white and we declare a circular
     582    // clipping path. Then we fill twice with a black rectangle. The fractional
     583    // pixels would first get the correct color (white * alpha + black * (1 -
     584    // alpha)), but the second fill would apply the alpha to the already
     585    // modified color and the result would be too dark.
     586    //
     587    // This, anti-aliased clipping needs to be performed after the drawing has
     588    // been done. In order to do this, we create a new layer of the canvas in
     589    // clipPathAntiAliased and store the clipping path. All drawing is done to
     590    // the layer's bitmap while it's in effect. When WebKit calls restore() to
     591    // undo the clipping, this function is called.
     592    //
     593    // Here, we walk the list of clipping paths backwards and, for each, we
     594    // clear outside of the clipping path. We only need a single extra layer
     595    // for any number of clipping paths.
     596    //
     597    // When we call restore on the SkCanvas, the layer's bitmap is composed
     598    // into the layer below and we end up with correct, anti-aliased clipping.
     599
     600    SkPaint paint;
     601    paint.setXfermodeMode(SkXfermode::kClear_Mode);
     602    paint.setAntiAlias(true);
     603    paint.setStyle(SkPaint::kFill_Style);
     604
     605    for (size_t i = paths.size() - 1; i < paths.size(); --i) {
     606        paths[i].setFillType(SkPath::kInverseWinding_FillType);
     607        m_canvas->drawPath(paths[i], paint);
     608    }
     609
     610    m_canvas->restore();
     611}
  • trunk/WebCore/platform/graphics/skia/PlatformContextSkia.h

    r49330 r49641  
    9393                                  const WebCore::ImageBuffer*);
    9494#endif
     95    void clipPathAntiAliased(const SkPath&);
    9596
    9697    // Sets up the common flags on a paint for antialiasing, effects, etc.
     
    173174    void applyClipFromImage(const WebCore::FloatRect&, const SkBitmap&);
    174175#endif
     176    void applyAntiAliasedClipPaths(WTF::Vector<SkPath>& paths);
    175177
    176178    // Defines drawing style.
  • trunk/WebCore/platform/graphics/wince/GraphicsContextWince.cpp

    r49330 r49641  
    12181218{
    12191219    notImplemented();
     1220}
     1221
     1222void GraphicsContext::canvasClip(const Path& path)
     1223{
     1224    clip(path);
    12201225}
    12211226
  • trunk/WebCore/platform/graphics/wx/GraphicsContextWx.cpp

    r49330 r49641  
    345345}
    346346
     347void GraphicsContext::canvasClip(const Path& path)
     348{
     349    clip(path);
     350}
     351
    347352void GraphicsContext::clipToImageBuffer(const FloatRect&, const ImageBuffer*)
    348353{
Note: See TracChangeset for help on using the changeset viewer.