Changeset 64318 in webkit


Ignore:
Timestamp:
Jul 29, 2010 4:17:46 PM (14 years ago)
Author:
Martin Robinson
Message:

2010-07-29 Martin Robinson <mrobinson@igalia.com>

Reviewed by Dirk Schulze.

[Cairo] Bring behavior of paths on the Cairo GraphicsContext into line with the CoreGraphics port
https://bugs.webkit.org/show_bug.cgi?id=41732

Do not apply paths added to the Cairo GraphicsContext, until they are used.
This prevents drawing routines such as fillRect from interacting with any
path which callers are constructing on the GraphicsContext.

This behavior is necessary to close bug https://bugs.webkit.org/show_bug.cgi?id=41308
so tests for that issue will test this fix.

  • platform/graphics/cairo/GraphicsContextCairo.cpp: (WebCore::appendPathToCairoContext): Added. A helper method which adds a path to a native Cairo context. (WebCore::setPathOnCairoContext): Added. Like appendPathToCairoContext, but clears the existing path first. (WebCore::appendWebCorePathToCairoContext): Added. Like appendPathToCairoContext, but operates on a WebCore path. (WebCore::GraphicsContext::drawEllipse): Only clear the Cairo path if cairo_stroke was not called, because cairo_stroke implicitly clears the path. (WebCore::GraphicsContext::drawConvexPolygon): Ditto. (WebCore::GraphicsContext::fillPath): Copy the path from m_pendingPath to the context and clear m_pendingPath, instead of relying on the pre-existing context path. (WebCore::GraphicsContext::strokePath): Ditto. (WebCore::GraphicsContext::drawPath): Ditto. (WebCore::GraphicsContext::drawFocusRing): Use the new appendWebCorePathToCairoContext helper instead of addPath (which will blow away any path callers are building). (WebCore::GraphicsContext::addInnerRoundedRectClip): Use the new appendWebCorePathToCairoContext helper instead of addPath (which will blow away any path callers are building). (WebCore::GraphicsContext::beginPath): Clear out m_pendingPath here instead of the main native context. (WebCore::GraphicsContext::addPath): Add the path to m_pendingPath instead of the main native context. Also ensure that the transformation matrix of the m_pendingPath is equal to that of the main cairo context. (WebCore::GraphicsContext::clipOut): Use the appendWebCorePathToCairoContext helper here. (WebCore::GraphicsContext::fillRoundedRect): Ditto and remove an unnecessary beginPath call.
  • platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h: Add a new m_pendingPath member.
Location:
trunk/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r64315 r64318  
     12010-07-29  Martin Robinson  <mrobinson@igalia.com>
     2
     3        Reviewed by Dirk Schulze.
     4
     5        [Cairo] Bring behavior of paths on the Cairo GraphicsContext into line with the CoreGraphics port
     6        https://bugs.webkit.org/show_bug.cgi?id=41732
     7
     8        Do not apply paths added to the Cairo GraphicsContext, until they are used.
     9        This prevents drawing routines such as fillRect from interacting with any
     10        path which callers are constructing on the GraphicsContext.
     11
     12         This behavior is necessary to close bug https://bugs.webkit.org/show_bug.cgi?id=41308
     13         so tests for that issue will test this fix.
     14
     15        * platform/graphics/cairo/GraphicsContextCairo.cpp:
     16        (WebCore::appendPathToCairoContext): Added. A helper method which adds a path
     17        to a native Cairo context.
     18        (WebCore::setPathOnCairoContext): Added. Like appendPathToCairoContext, but clears the
     19        existing path first.
     20        (WebCore::appendWebCorePathToCairoContext): Added. Like appendPathToCairoContext, but
     21        operates on a WebCore path.
     22        (WebCore::GraphicsContext::drawEllipse): Only clear the Cairo path if cairo_stroke
     23        was not called, because cairo_stroke implicitly clears the path.
     24        (WebCore::GraphicsContext::drawConvexPolygon): Ditto.
     25        (WebCore::GraphicsContext::fillPath): Copy the path from m_pendingPath to the context
     26        and clear m_pendingPath, instead of relying on the pre-existing context path.
     27        (WebCore::GraphicsContext::strokePath): Ditto.
     28        (WebCore::GraphicsContext::drawPath): Ditto.
     29        (WebCore::GraphicsContext::drawFocusRing): Use the new appendWebCorePathToCairoContext helper instead
     30        of addPath (which will blow away any path callers are building).
     31        (WebCore::GraphicsContext::addInnerRoundedRectClip): Use the new appendWebCorePathToCairoContext helper instead
     32        of addPath (which will blow away any path callers are building).
     33        (WebCore::GraphicsContext::beginPath): Clear out m_pendingPath here instead of the main native context.
     34        (WebCore::GraphicsContext::addPath): Add the path to m_pendingPath instead of the main native context.
     35        Also ensure that the transformation matrix of the m_pendingPath is equal to that of the main
     36        cairo context.
     37        (WebCore::GraphicsContext::clipOut): Use the appendWebCorePathToCairoContext helper here.
     38        (WebCore::GraphicsContext::fillRoundedRect): Ditto and remove an unnecessary beginPath call.
     39        * platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h: Add a new m_pendingPath member.
     40
    1412010-07-29  Martin Robinson  <mrobinson@igalia.com>
    242
  • trunk/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp

    r64315 r64318  
    55 * Copyright (C) 2008 Nuanti Ltd.
    66 * Copyright (C) 2009 Brent Fulgham <bfulgham@webkit.org>
     7 * Copyright (C) 2010 Igalia S.L.
    78 *
    89 * Redistribution and use in source and binary forms, with or without
     
    144145}
    145146
     147static void appendPathToCairoContext(cairo_t* to, cairo_t* from)
     148{
     149    cairo_path_t* cairoPath = cairo_copy_path(from);
     150    cairo_append_path(to, cairoPath);
     151    cairo_path_destroy(cairoPath);
     152}
     153
     154// We apply the pending path built via addPath to the Cairo context
     155// lazily. This prevents interaction between the path and other routines
     156// such as fillRect.
     157static void setPathOnCairoContext(cairo_t* to, cairo_t* from)
     158{
     159    cairo_new_path(to);
     160    appendPathToCairoContext(to, from);
     161}
     162
     163static void appendWebCorePathToCairoContext(cairo_t* context, const Path& path)
     164{
     165    appendPathToCairoContext(context, path.platformPath()->m_cr);
     166}
     167
    146168void GraphicsContext::calculateShadowBufferDimensions(IntSize& shadowBufferSize, FloatRect& shadowRect, float& kernelSize, const FloatRect& sourceRect, const FloatSize& shadowSize, float shadowBlur)
    147169{
     
    381403        cairo_set_line_width(cr, strokeThickness());
    382404        cairo_stroke(cr);
    383     }
    384 
    385     cairo_new_path(cr);
     405    } else
     406        cairo_new_path(cr);
    386407}
    387408
     
    499520        cairo_set_line_width(cr, strokeThickness());
    500521        cairo_stroke(cr);
    501     }
    502 
    503     cairo_new_path(cr);
     522    } else
     523        cairo_new_path(cr);
     524
    504525    cairo_restore(cr);
    505526}
     
    523544    cairo_t* cr = m_data->cr;
    524545
     546    setPathOnCairoContext(cr, m_data->m_pendingPath.m_cr);
     547
    525548    cairo_set_fill_rule(cr, fillRule() == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING);
    526549    drawPathShadow(this, m_common, true, false);
     
    536559
    537560    cairo_t* cr = m_data->cr;
     561
     562    setPathOnCairoContext(cr, m_data->m_pendingPath.m_cr);
     563
    538564    drawPathShadow(this, m_common, false, true);
    539565
     
    549575
    550576    cairo_t* cr = m_data->cr;
     577
     578    setPathOnCairoContext(cr, m_data->m_pendingPath.m_cr);
    551579
    552580    cairo_set_fill_rule(cr, fillRule() == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING);
     
    674702    int radius = (width - 1) / 2;
    675703    for (unsigned i = 0; i < rectCount; i++)
    676         addPath(Path::createRoundedRectangle(rects[i], FloatSize(radius, radius)));
     704        appendWebCorePathToCairoContext(cr, Path::createRoundedRectangle(rects[i], FloatSize(radius, radius)));
    677705
    678706    // Force the alpha to 50%.  This matches what the Mac does with outline rings.
     
    841869        return;
    842870
     871    cairo_t* cr = m_data->cr;
    843872    clip(rect);
    844873
     
    850879    r.inflate(-thickness);
    851880    p.addEllipse(r);
    852     addPath(p);
    853 
    854     cairo_t* cr = m_data->cr;
     881    appendWebCorePathToCairoContext(cr, p);
     882
    855883    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
    856884    cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
     
    10801108        return;
    10811109
    1082     cairo_t* cr = m_data->cr;
    1083     cairo_new_path(cr);
     1110    cairo_new_path(m_data->m_pendingPath.m_cr);
    10841111}
    10851112
     
    10891116        return;
    10901117
    1091     cairo_t* cr = m_data->cr;
    1092     cairo_path_t* p = cairo_copy_path(path.platformPath()->m_cr);
    1093     cairo_append_path(cr, p);
    1094     cairo_path_destroy(p);
     1118    cairo_matrix_t currentMatrix;
     1119    cairo_get_matrix(m_data->cr, &currentMatrix);
     1120    cairo_set_matrix(m_data->m_pendingPath.m_cr, &currentMatrix);
     1121    appendWebCorePathToCairoContext(m_data->m_pendingPath.m_cr, path);
    10951122}
    10961123
     
    11251152    cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
    11261153    cairo_rectangle(cr, x1, y1, x2 - x1, y2 - y1);
    1127     addPath(path);
     1154    appendWebCorePathToCairoContext(cr, path);
    11281155
    11291156    cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
     
    11841211    cairo_t* cr = m_data->cr;
    11851212    cairo_save(cr);
    1186     beginPath();
    1187     addPath(Path::createRoundedRectangle(r, topLeft, topRight, bottomLeft, bottomRight));
     1213    appendWebCorePathToCairoContext(cr, Path::createRoundedRectangle(r, topLeft, topRight, bottomLeft, bottomRight));
    11881214    setColor(cr, color);
    11891215    drawPathShadow(this, m_common, true, false);
  • trunk/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h

    r54137 r64318  
    9696    cairo_t* cr;
    9797    Vector<float> layers;
     98    CairoPath m_pendingPath;
    9899
    99100#if PLATFORM(GTK)
Note: See TracChangeset for help on using the changeset viewer.