2011-03-30 Martin Robinson <mrobinson@igalia.com>
authormrobinson@webkit.org <mrobinson@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 30 Mar 2011 20:56:40 +0000 (20:56 +0000)
committermrobinson@webkit.org <mrobinson@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 30 Mar 2011 20:56:40 +0000 (20:56 +0000)
        Reviewed by Dirk Schulze.

        [Cairo] Better separate the concerns of GraphicsContextCairo
        https://bugs.webkit.org/show_bug.cgi?id=55150

        Add a PlatformContextCairo which right now stores the cairo_t* for a
        GraphicsContextCairo. Later patches will move logic for tracking ContextShadow
        and image masking layers into this PlatformContextCairo class.

        No new tests. This patch is only a code cleanup.

        * GNUmakefile.am:
        * platform/graphics/GraphicsContext.h: The platform context is no longer a
        cairo_t, but our new class the PlatformContextCairo.
        * platform/graphics/cairo/ContextShadowCairo.cpp: Updated to reflect new class.j
        * platform/graphics/cairo/FontCairo.cpp: Ditto.
        * platform/graphics/cairo/GradientCairo.cpp: Ditto.
        * platform/graphics/cairo/GraphicsContextCairo.cpp: Mostly mechanical
        changes which now reference platformContext()->cr() to get the cairo_t.
        * platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h: Now hold the
        PlatformContextCairo instead of the cairo_t.
        * platform/graphics/cairo/ImageBufferCairo.cpp: Update to reflect new class.
        * platform/graphics/cairo/ImageCairo.cpp: Ditto.
        * platform/graphics/cairo/PathCairo.cpp: Ditto.
        * platform/graphics/cairo/PlatformContextCairo.cpp: Added.
        * platform/graphics/cairo/PlatformContextCairo.h: Added.
        * platform/graphics/gtk/FontGtk.cpp: Update to reflect new class.
        * platform/graphics/gtk/IconGtk.cpp: Ditto.
        * platform/graphics/win/GraphicsContextCairoWin.cpp: Now fill out
        m_data with a private section containing the platform context instead of
        just a cairo_t.
        * platform/gtk/RenderThemeGtk.cpp: Update to reflect new class.
        * platform/gtk/WidgetRenderingContext.cpp: Ditto.
        (WebCore::WidgetRenderingContext::~WidgetRenderingContext): Ditto.
        * plugins/gtk/PluginViewGtk.cpp: Ditto.
2011-03-30  Martin Robinson  <mrobinson@igalia.com>

        Reviewed by Dirk Schulze.

        [Cairo] Better separate the concerns of GraphicsContextCairo
        https://bugs.webkit.org/show_bug.cgi?id=55150

        Add a PlatformContextCairo which right now stores the cairo_t* for a
        GraphicsContextCairo. Later patches will move logic for tracking ContextShadow
        and image masking layers into this PlatformContextCairo class.

        * webkit/webkitwebframe.cpp:
        (draw_page_callback):
        * webkit/webkitwebview.cpp:
        (webkit_web_view_expose_event):
        (webkit_web_view_draw):
2011-03-30  Martin Robinson  <mrobinson@igalia.com>

        Reviewed by Dirk Schulze.

        [Cairo] Better separate the concerns of GraphicsContextCairo
        https://bugs.webkit.org/show_bug.cgi?id=55150

        * WebFrame.cpp:
        (hdcFromContext): Modify this method to take PlatformContextCairo
        instead of a cairo_t.
        (WebFrame::spoolPage): Update to reflect new platform context.
        (WebFrame::spoolPages): Ditto.
        * WebFrame.h: Ditto.

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

26 files changed:
Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.am
Source/WebCore/platform/graphics/GraphicsContext.h
Source/WebCore/platform/graphics/cairo/ContextShadowCairo.cpp
Source/WebCore/platform/graphics/cairo/FontCairo.cpp
Source/WebCore/platform/graphics/cairo/GradientCairo.cpp
Source/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
Source/WebCore/platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h
Source/WebCore/platform/graphics/cairo/ImageBufferCairo.cpp
Source/WebCore/platform/graphics/cairo/ImageBufferData.h
Source/WebCore/platform/graphics/cairo/ImageCairo.cpp
Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp [new file with mode: 0644]
Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h [new file with mode: 0644]
Source/WebCore/platform/graphics/gtk/FontGtk.cpp
Source/WebCore/platform/graphics/gtk/IconGtk.cpp
Source/WebCore/platform/graphics/win/GraphicsContextCairoWin.cpp
Source/WebCore/platform/gtk/RenderThemeGtk.cpp
Source/WebCore/platform/gtk/WidgetRenderingContext.cpp
Source/WebCore/plugins/gtk/PluginViewGtk.cpp
Source/WebCore/plugins/win/PluginViewWin.cpp
Source/WebKit/gtk/ChangeLog
Source/WebKit/gtk/webkit/webkitwebframe.cpp
Source/WebKit/gtk/webkit/webkitwebview.cpp
Source/WebKit/win/ChangeLog
Source/WebKit/win/WebFrame.cpp
Source/WebKit/win/WebFrame.h

index 753ce4f..ec7e6de 100644 (file)
@@ -1,3 +1,41 @@
+2011-03-30  Martin Robinson  <mrobinson@igalia.com>
+
+        Reviewed by Dirk Schulze.
+
+        [Cairo] Better separate the concerns of GraphicsContextCairo
+        https://bugs.webkit.org/show_bug.cgi?id=55150
+
+        Add a PlatformContextCairo which right now stores the cairo_t* for a
+        GraphicsContextCairo. Later patches will move logic for tracking ContextShadow
+        and image masking layers into this PlatformContextCairo class.
+
+        No new tests. This patch is only a code cleanup.
+
+        * GNUmakefile.am:
+        * platform/graphics/GraphicsContext.h: The platform context is no longer a
+        cairo_t, but our new class the PlatformContextCairo.
+        * platform/graphics/cairo/ContextShadowCairo.cpp: Updated to reflect new class.j
+        * platform/graphics/cairo/FontCairo.cpp: Ditto.
+        * platform/graphics/cairo/GradientCairo.cpp: Ditto.
+        * platform/graphics/cairo/GraphicsContextCairo.cpp: Mostly mechanical
+        changes which now reference platformContext()->cr() to get the cairo_t.
+        * platform/graphics/cairo/GraphicsContextPlatformPrivateCairo.h: Now hold the
+        PlatformContextCairo instead of the cairo_t.
+        * platform/graphics/cairo/ImageBufferCairo.cpp: Update to reflect new class.
+        * platform/graphics/cairo/ImageCairo.cpp: Ditto.
+        * platform/graphics/cairo/PathCairo.cpp: Ditto.
+        * platform/graphics/cairo/PlatformContextCairo.cpp: Added.
+        * platform/graphics/cairo/PlatformContextCairo.h: Added.
+        * platform/graphics/gtk/FontGtk.cpp: Update to reflect new class.
+        * platform/graphics/gtk/IconGtk.cpp: Ditto.
+        * platform/graphics/win/GraphicsContextCairoWin.cpp: Now fill out
+        m_data with a private section containing the platform context instead of
+        just a cairo_t.
+        * platform/gtk/RenderThemeGtk.cpp: Update to reflect new class.
+        * platform/gtk/WidgetRenderingContext.cpp: Ditto.
+        (WebCore::WidgetRenderingContext::~WidgetRenderingContext): Ditto.
+        * plugins/gtk/PluginViewGtk.cpp: Ditto.
+
 2011-03-30  Patrick Gansterer  <paroga@webkit.org>
 
         Unreviewed WinCE build fix for r82465.
index 41e69ee..eedbc9a 100644 (file)
@@ -3760,6 +3760,8 @@ webcoregtk_sources += \
        Source/WebCore/platform/graphics/cairo/OwnPtrCairo.h \
        Source/WebCore/platform/graphics/cairo/PathCairo.cpp \
        Source/WebCore/platform/graphics/cairo/PatternCairo.cpp \
+       Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp \
+       Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h \
        Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp \
        Source/WebCore/platform/graphics/cairo/RefPtrCairo.h \
        Source/WebCore/platform/graphics/cairo/TransformationMatrixCairo.cpp \
index c86c952..13b0e39 100644 (file)
@@ -42,8 +42,9 @@ typedef struct CGContext PlatformGraphicsContext;
 #elif PLATFORM(CAIRO)
 namespace WebCore {
 class ContextShadow;
+class PlatformContextCairo;
 }
-typedef struct _cairo PlatformGraphicsContext;
+typedef WebCore::PlatformContextCairo PlatformGraphicsContext;
 #elif PLATFORM(OPENVG)
 namespace WebCore {
 class SurfaceOpenVG;
@@ -490,6 +491,7 @@ namespace WebCore {
 #endif
 
 #if PLATFORM(CAIRO)
+        GraphicsContext(cairo_t*);
         void pushImageMask(cairo_surface_t*, const FloatRect&);
 #endif
 
index b0588d6..0f90ce4 100644 (file)
@@ -34,6 +34,7 @@
 #include "GraphicsContext.h"
 #include "OwnPtrCairo.h"
 #include "Path.h"
+#include "PlatformContextCairo.h"
 #include "Timer.h"
 #include <cairo.h>
 
@@ -88,7 +89,7 @@ PlatformContext ContextShadow::beginShadowLayer(GraphicsContext* context, const
     adjustBlurDistance(context);
 
     double x1, x2, y1, y2;
-    cairo_clip_extents(context->platformContext(), &x1, &y1, &x2, &y2);
+    cairo_clip_extents(context->platformContext()->cr(), &x1, &y1, &x2, &y2);
     IntRect layerRect = calculateLayerBoundingRect(context, layerArea, IntRect(x1, y1, x2 - x1, y2 - y1));
 
     // Don't paint if we are totally outside the clip region.
@@ -120,7 +121,7 @@ void ContextShadow::endShadowLayer(GraphicsContext* context)
         cairo_surface_mark_dirty(m_layerImage);
     }
 
-    cairo_t* cr = context->platformContext();
+    cairo_t* cr = context->platformContext()->cr();
     cairo_save(cr);
     setSourceRGBAFromColor(cr, m_color);
     cairo_mask_surface(cr, m_layerImage, m_layerOrigin.x(), m_layerOrigin.y());
@@ -198,7 +199,7 @@ void ContextShadow::drawRectShadow(GraphicsContext* context, const IntRect& rect
     int internalShadowHeight = radiusTwice + max(topLeftRadius.height(), topRightRadius.height()) +
         max(bottomLeftRadius.height(), bottomRightRadius.height());
 
-    cairo_t* cr = context->platformContext();
+    cairo_t* cr = context->platformContext()->cr();
 
     // drawShadowedRect still does not work with rotations.
     // https://bugs.webkit.org/show_bug.cgi?id=45042
index 2d79499..58a7fd2 100644 (file)
@@ -36,6 +36,7 @@
 #include "GlyphBuffer.h"
 #include "Gradient.h"
 #include "GraphicsContext.h"
+#include "PlatformContextCairo.h"
 #include "ImageBuffer.h"
 #include "Pattern.h"
 #include "SimpleFontData.h"
@@ -64,7 +65,7 @@ static void drawGlyphsToContext(cairo_t* context, const SimpleFontData* font, Gl
     }
 }
 
-static void drawGlyphsShadow(GraphicsContext* graphicsContext, cairo_t* context, const FloatPoint& point, const SimpleFontData* font, GlyphBufferGlyph* glyphs, int numGlyphs)
+static void drawGlyphsShadow(GraphicsContext* graphicsContext, const FloatPoint& point, const SimpleFontData* font, GlyphBufferGlyph* glyphs, int numGlyphs)
 {
     ContextShadow* shadow = graphicsContext->contextShadow();
     ASSERT(shadow);
@@ -74,6 +75,7 @@ static void drawGlyphsShadow(GraphicsContext* graphicsContext, cairo_t* context,
 
     if (!shadow->mustUseContextShadow(graphicsContext)) {
         // Optimize non-blurry shadows, by just drawing text without the ContextShadow.
+        cairo_t* context = graphicsContext->platformContext()->cr();
         cairo_save(context);
         cairo_translate(context, shadow->m_offset.width(), shadow->m_offset.height());
         setSourceRGBAFromColor(context, shadow->m_color);
@@ -106,9 +108,10 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
         offset += glyphBuffer.advanceAt(from + i);
     }
 
-    cairo_t* cr = context->platformContext();
-    drawGlyphsShadow(context, cr, point, font, glyphs, numGlyphs);
+    PlatformContextCairo* platformContext = context->platformContext();
+    drawGlyphsShadow(context, point, font, glyphs, numGlyphs);
 
+    cairo_t* cr = platformContext->cr();
     cairo_save(cr);
     prepareContextForGlyphDrawing(cr, font, point);
     if (context->textDrawingMode() & TextModeFill) {
index 4e6ed07..225046a 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "CSSParser.h"
 #include "GraphicsContext.h"
+#include "PlatformContextCairo.h"
 #include <cairo.h>
 
 namespace WebCore {
@@ -87,7 +88,7 @@ void Gradient::setPlatformGradientSpaceTransform(const AffineTransform& gradient
 
 void Gradient::fill(GraphicsContext* context, const FloatRect& rect)
 {
-    cairo_t* cr = context->platformContext();
+    cairo_t* cr = context->platformContext()->cr();
 
     context->save();
     cairo_set_source(cr, platformGradient());
index e69a7a5..0fc94df 100644 (file)
@@ -47,6 +47,7 @@
 #include "NotImplemented.h"
 #include "Path.h"
 #include "Pattern.h"
+#include "PlatformContextCairo.h"
 #include "RefPtrCairo.h"
 #include "SimpleFontData.h"
 #include <cairo.h>
@@ -148,7 +149,7 @@ static inline void drawPathShadow(GraphicsContext* context, PathDrawingStyle dra
         return;
 
     // Calculate the extents of the rendered solid paths.
-    cairo_t* cairoContext = context->platformContext();
+    cairo_t* cairoContext = context->platformContext()->cr();
     OwnPtr<cairo_path_t> path(cairo_copy_path(cairoContext));
 
     FloatRect solidFigureExtents;
@@ -199,12 +200,18 @@ static void strokeCurrentCairoPath(GraphicsContext* context,  cairo_t* cairoCont
     cairo_new_path(cairoContext);
 }
 
-void GraphicsContext::platformInit(PlatformGraphicsContext* cr)
+GraphicsContext::GraphicsContext(cairo_t* cr)
 {
-    m_data = new GraphicsContextPlatformPrivate;
-    m_data->cr = cairo_reference(cr);
-    m_data->syncContext(cr);
-    setPaintingDisabled(!cr);
+    m_data = new GraphicsContextPlatformPrivate(new PlatformContextCairo(cr));
+}
+
+void GraphicsContext::platformInit(PlatformContextCairo* platformContext)
+{
+    m_data = new GraphicsContextPlatformPrivate(platformContext);
+    if (platformContext)
+        m_data->syncContext(platformContext->cr());
+    else
+        setPaintingDisabled(true);
 }
 
 void GraphicsContext::platformDestroy()
@@ -214,20 +221,20 @@ void GraphicsContext::platformDestroy()
 
 AffineTransform GraphicsContext::getCTM() const
 {
-    cairo_t* cr = platformContext();
+    cairo_t* cr = platformContext()->cr();
     cairo_matrix_t m;
     cairo_get_matrix(cr, &m);
     return AffineTransform(m.xx, m.yx, m.xy, m.yy, m.x0, m.y0);
 }
 
-cairo_t* GraphicsContext::platformContext() const
+PlatformContextCairo* GraphicsContext::platformContext() const
 {
-    return m_data->cr;
+    return m_data->platformContext;
 }
 
 void GraphicsContext::savePlatformState()
 {
-    cairo_save(m_data->cr);
+    cairo_save(platformContext()->cr());
     m_data->save();
     m_data->shadowStack.append(m_data->shadow);
     m_data->maskImageStack.append(ImageMaskInformation());
@@ -235,7 +242,8 @@ void GraphicsContext::savePlatformState()
 
 void GraphicsContext::restorePlatformState()
 {
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
+
     const ImageMaskInformation& maskInformation = m_data->maskImageStack.last();
     if (maskInformation.isValid()) {
         const FloatRect& maskRect = maskInformation.maskRect();
@@ -251,7 +259,7 @@ void GraphicsContext::restorePlatformState()
         m_data->shadowStack.removeLast();
     }
 
-    cairo_restore(m_data->cr);
+    cairo_restore(cr);
     m_data->restore();
 }
 
@@ -261,7 +269,7 @@ void GraphicsContext::drawRect(const IntRect& rect)
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     cairo_save(cr);
 
     if (fillColor().alpha())
@@ -289,7 +297,7 @@ void GraphicsContext::drawLine(const IntPoint& point1, const IntPoint& point2)
     if (style == NoStroke)
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     cairo_save(cr);
 
     float width = strokeThickness();
@@ -376,7 +384,7 @@ void GraphicsContext::drawEllipse(const IntRect& rect)
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     cairo_save(cr);
     float yRadius = .5 * rect.height();
     float xRadius = .5 * rect.width();
@@ -415,7 +423,7 @@ void GraphicsContext::strokeArc(const IntRect& rect, int startAngle, int angleSp
     float fa = startAngle;
     float falen =  fa + angleSpan;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     cairo_save(cr);
 
     if (w != h)
@@ -492,7 +500,7 @@ void GraphicsContext::drawConvexPolygon(size_t npoints, const FloatPoint* points
     if (npoints <= 1)
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
 
     cairo_save(cr);
     cairo_set_antialias(cr, shouldAntialias ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);
@@ -522,7 +530,7 @@ void GraphicsContext::clipConvexPolygon(size_t numPoints, const FloatPoint* poin
     if (numPoints <= 1)
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
 
     cairo_new_path(cr);
     cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
@@ -542,7 +550,7 @@ void GraphicsContext::fillPath(const Path& path)
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     setPathOnCairoContext(cr, path.platformPath()->context());
     fillCurrentCairoPath(this, cr);
 }
@@ -552,7 +560,7 @@ void GraphicsContext::strokePath(const Path& path)
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     setPathOnCairoContext(cr, path.platformPath()->context());
     strokeCurrentCairoPath(this, cr);
 }
@@ -562,7 +570,7 @@ void GraphicsContext::fillRect(const FloatRect& rect)
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     cairo_save(cr);
     cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
     fillCurrentCairoPath(this, cr);
@@ -578,7 +586,7 @@ void GraphicsContext::fillRect(const FloatRect& rect, const Color& color, ColorS
         m_data->shadow.drawRectShadow(this, enclosingIntRect(rect));
 
     if (color.alpha())
-        fillRectSourceOver(m_data->cr, rect, color);
+        fillRectSourceOver(platformContext()->cr(), rect, color);
 }
 
 void GraphicsContext::clip(const FloatRect& rect)
@@ -586,7 +594,7 @@ void GraphicsContext::clip(const FloatRect& rect)
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
     cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
     cairo_set_fill_rule(cr, CAIRO_FILL_RULE_WINDING);
@@ -600,7 +608,7 @@ void GraphicsContext::clipPath(const Path& path, WindRule clipRule)
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     setPathOnCairoContext(cr, path.platformPath()->context());
     cairo_set_fill_rule(cr, clipRule == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING);
     cairo_clip(cr);
@@ -638,7 +646,7 @@ void GraphicsContext::drawFocusRing(const Path& path, int width, int /* offset *
     adjustFocusRingColor(ringColor);
     adjustFocusRingLineWidth(width);
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     cairo_save(cr);
     appendWebCorePathToCairoContext(cr, path);
     setSourceRGBAFromColor(cr, ringColor);
@@ -655,7 +663,7 @@ void GraphicsContext::drawFocusRing(const Vector<IntRect>& rects, int width, int
 
     unsigned rectCount = rects.size();
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     cairo_save(cr);
     cairo_push_group(cr);
     cairo_new_path(cr);
@@ -732,7 +740,7 @@ void GraphicsContext::drawLineForTextChecking(const FloatPoint& origin, float wi
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     cairo_save(cr);
 
     switch (style) {
@@ -762,7 +770,7 @@ FloatRect GraphicsContext::roundToDevicePixels(const FloatRect& frect)
     FloatRect result;
     double x = frect.x();
     double y = frect.y();
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     cairo_user_to_device(cr, &x, &y);
     x = round(x);
     y = round(y);
@@ -799,7 +807,7 @@ void GraphicsContext::translate(float x, float y)
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     cairo_translate(cr, x, y);
     m_data->translate(x, y);
 }
@@ -821,7 +829,7 @@ void GraphicsContext::setPlatformStrokeThickness(float strokeThickness)
     if (paintingDisabled())
         return;
 
-    cairo_set_line_width(m_data->cr, strokeThickness);
+    cairo_set_line_width(platformContext()->cr(), strokeThickness);
 }
 
 void GraphicsContext::setPlatformStrokeStyle(StrokeStyle strokeStyle)
@@ -835,16 +843,16 @@ void GraphicsContext::setPlatformStrokeStyle(StrokeStyle strokeStyle)
     switch (strokeStyle) {
     case NoStroke:
         // FIXME: is it the right way to emulate NoStroke?
-        cairo_set_line_width(m_data->cr, 0);
+        cairo_set_line_width(platformContext()->cr(), 0);
         break;
     case SolidStroke:
-        cairo_set_dash(m_data->cr, 0, 0, 0);
+        cairo_set_dash(platformContext()->cr(), 0, 0, 0);
         break;
     case DottedStroke:
-        cairo_set_dash(m_data->cr, dotPattern, 2, 0);
+        cairo_set_dash(platformContext()->cr(), dotPattern, 2, 0);
         break;
     case DashedStroke:
-        cairo_set_dash(m_data->cr, dashPattern, 2, 0);
+        cairo_set_dash(platformContext()->cr(), dashPattern, 2, 0);
         break;
     }
 }
@@ -859,7 +867,7 @@ void GraphicsContext::concatCTM(const AffineTransform& transform)
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     const cairo_matrix_t matrix = cairo_matrix_t(transform);
     cairo_transform(cr, &matrix);
     m_data->concatCTM(transform);
@@ -870,7 +878,7 @@ void GraphicsContext::setCTM(const AffineTransform& transform)
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     const cairo_matrix_t matrix = cairo_matrix_t(transform);
     cairo_set_matrix(cr, &matrix);
     m_data->setCTM(transform);
@@ -881,7 +889,7 @@ void GraphicsContext::addInnerRoundedRectClip(const IntRect& rect, int thickness
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     clip(rect);
 
     Path p;
@@ -928,7 +936,7 @@ void GraphicsContext::beginTransparencyLayer(float opacity)
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     cairo_push_group(cr);
     m_data->layers.append(opacity);
     m_data->beginTransparencyLayer();
@@ -939,7 +947,7 @@ void GraphicsContext::endTransparencyLayer()
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
 
     cairo_pop_group_to_source(cr);
     cairo_paint_with_alpha(cr, m_data->layers.last());
@@ -952,7 +960,7 @@ void GraphicsContext::clearRect(const FloatRect& rect)
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
 
     cairo_save(cr);
     cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
@@ -966,7 +974,7 @@ void GraphicsContext::strokeRect(const FloatRect& rect, float width)
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     cairo_save(cr);
     cairo_rectangle(cr, rect.x(), rect.y(), rect.width(), rect.height());
     cairo_set_line_width(cr, width);
@@ -991,12 +999,12 @@ void GraphicsContext::setLineCap(LineCap lineCap)
         cairoCap = CAIRO_LINE_CAP_SQUARE;
         break;
     }
-    cairo_set_line_cap(m_data->cr, cairoCap);
+    cairo_set_line_cap(platformContext()->cr(), cairoCap);
 }
 
 void GraphicsContext::setLineDash(const DashArray& dashes, float dashOffset)
 {
-    cairo_set_dash(m_data->cr, dashes.data(), dashes.size(), dashOffset);
+    cairo_set_dash(platformContext()->cr(), dashes.data(), dashes.size(), dashOffset);
 }
 
 void GraphicsContext::setLineJoin(LineJoin lineJoin)
@@ -1016,7 +1024,7 @@ void GraphicsContext::setLineJoin(LineJoin lineJoin)
         cairoJoin = CAIRO_LINE_JOIN_BEVEL;
         break;
     }
-    cairo_set_line_join(m_data->cr, cairoJoin);
+    cairo_set_line_join(platformContext()->cr(), cairoJoin);
 }
 
 void GraphicsContext::setMiterLimit(float miter)
@@ -1024,7 +1032,7 @@ void GraphicsContext::setMiterLimit(float miter)
     if (paintingDisabled())
         return;
 
-    cairo_set_miter_limit(m_data->cr, miter);
+    cairo_set_miter_limit(platformContext()->cr(), miter);
 }
 
 void GraphicsContext::setAlpha(float alpha)
@@ -1042,7 +1050,7 @@ void GraphicsContext::setPlatformCompositeOperation(CompositeOperator op)
     if (paintingDisabled())
         return;
 
-    cairo_set_operator(m_data->cr, toCairoOperator(op));
+    cairo_set_operator(platformContext()->cr(), toCairoOperator(op));
 }
 
 void GraphicsContext::clip(const Path& path)
@@ -1050,7 +1058,7 @@ void GraphicsContext::clip(const Path& path)
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     OwnPtr<cairo_path_t> p(cairo_copy_path(path.platformPath()->context()));
     cairo_append_path(cr, p.get());
     cairo_fill_rule_t savedFillRule = cairo_get_fill_rule(cr);
@@ -1070,7 +1078,7 @@ void GraphicsContext::clipOut(const Path& path)
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     double x1, y1, x2, y2;
     cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
     cairo_rectangle(cr, x1, y1, x2 - x1, y2 - y1);
@@ -1087,7 +1095,7 @@ void GraphicsContext::rotate(float radians)
     if (paintingDisabled())
         return;
 
-    cairo_rotate(m_data->cr, radians);
+    cairo_rotate(platformContext()->cr(), radians);
     m_data->rotate(radians);
 }
 
@@ -1096,7 +1104,7 @@ void GraphicsContext::scale(const FloatSize& size)
     if (paintingDisabled())
         return;
 
-    cairo_scale(m_data->cr, size.width(), size.height());
+    cairo_scale(platformContext()->cr(), size.width(), size.height());
     m_data->scale(size);
 }
 
@@ -1105,7 +1113,7 @@ void GraphicsContext::clipOut(const IntRect& r)
     if (paintingDisabled())
         return;
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     double x1, y1, x2, y2;
     cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
     cairo_rectangle(cr, x1, y1, x2 - x1, y2 - y1);
@@ -1132,7 +1140,7 @@ void GraphicsContext::fillRoundedRect(const IntRect& r, const IntSize& topLeft,
     if (hasShadow())
         m_data->shadow.drawRectShadow(this, r, topLeft, topRight, bottomLeft, bottomRight);
 
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     cairo_save(cr);
     Path path;
     path.addRoundedRect(r, topLeft, topRight, bottomLeft, bottomRight);
@@ -1170,7 +1178,7 @@ void GraphicsContext::setPlatformShouldAntialias(bool enable)
     // When true, use the default Cairo backend antialias mode (usually this
     // enables standard 'grayscale' antialiasing); false to explicitly disable
     // antialiasing. This is the same strategy as used in drawConvexPolygon().
-    cairo_set_antialias(m_data->cr, enable ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);
+    cairo_set_antialias(platformContext()->cr(), enable ? CAIRO_ANTIALIAS_DEFAULT : CAIRO_ANTIALIAS_NONE);
 }
 
 void GraphicsContext::setImageInterpolationQuality(InterpolationQuality)
@@ -1196,7 +1204,7 @@ void GraphicsContext::pushImageMask(cairo_surface_t* surface, const FloatRect& r
     // We want to allow the clipped elements to composite with the surface as it
     // is now, but they are isolated in another group. To make this work, we're
     // going to blit the current surface contents onto the new group once we push it.
-    cairo_t* cr = m_data->cr;
+    cairo_t* cr = platformContext()->cr();
     cairo_surface_t* currentTarget = cairo_get_target(cr);
     cairo_surface_flush(currentTarget);
 
index 924f69a..2bc290b 100644 (file)
@@ -31,6 +31,7 @@
 #include "GraphicsContext.h"
 
 #include "ContextShadow.h"
+#include "PlatformContextCairo.h"
 #include "RefPtrCairo.h"
 #include <cairo.h>
 #include <math.h>
@@ -67,8 +68,8 @@ private:
 
 class GraphicsContextPlatformPrivate {
 public:
-    GraphicsContextPlatformPrivate()
-        : cr(0)
+    GraphicsContextPlatformPrivate(PlatformContextCairo* newPlatformContext)
+        : platformContext(newPlatformContext)
 #if PLATFORM(GTK)
         , expose(0)
 #elif PLATFORM(WIN)
@@ -82,7 +83,6 @@ public:
 
     ~GraphicsContextPlatformPrivate()
     {
-        cairo_destroy(cr);
     }
 
 #if PLATFORM(WIN)
@@ -99,7 +99,7 @@ public:
     void setCTM(const AffineTransform&);
     void beginTransparencyLayer() { m_transparencyCount++; }
     void endTransparencyLayer() { m_transparencyCount--; }
-    void syncContext(PlatformGraphicsContext* cr);
+    void syncContext(cairo_t* cr);
 #else
     // On everything else, we do nothing.
     void save() {}
@@ -114,12 +114,11 @@ public:
     void setCTM(const AffineTransform&) {}
     void beginTransparencyLayer() {}
     void endTransparencyLayer() {}
-    void syncContext(PlatformGraphicsContext* cr) {}
+    void syncContext(cairo_t* cr) {}
 #endif
 
-    cairo_t* cr;
+    PlatformContextCairo* platformContext;
     Vector<float> layers;
-
     ContextShadow shadow;
     Vector<ContextShadow> shadowStack;
     Vector<ImageMaskInformation> maskImageStack;
@@ -133,6 +132,23 @@ public:
 #endif
 };
 
+// This is a specialized private section for the Cairo GraphicsContext, which knows how
+// to clean up the heap allocated PlatformContextCairo that we must use for the top-level
+// GraphicsContext.
+class GraphicsContextPlatformPrivateToplevel : public GraphicsContextPlatformPrivate {
+public:
+    GraphicsContextPlatformPrivateToplevel(PlatformContextCairo* platformContext)
+        : GraphicsContextPlatformPrivate(platformContext)
+    {
+    }
+
+    ~GraphicsContextPlatformPrivateToplevel()
+    {
+        delete platformContext;
+    }
+};
+
+
 } // namespace WebCore
 
 #endif // GraphicsContextPlatformPrivateCairo_h
index 9ee8a94..1d5d492 100644 (file)
@@ -37,7 +37,9 @@
 #include "MIMETypeRegistry.h"
 #include "NotImplemented.h"
 #include "Pattern.h"
+#include "PlatformContextCairo.h"
 #include "PlatformString.h"
+#include "RefPtrCairo.h"
 #include <cairo.h>
 #include <wtf/Vector.h>
 
@@ -66,6 +68,7 @@ namespace WebCore {
 
 ImageBufferData::ImageBufferData(const IntSize& size)
     : m_surface(0)
+    , m_platformContext(0)
 {
 }
 
@@ -80,9 +83,9 @@ ImageBuffer::ImageBuffer(const IntSize& size, ColorSpace, RenderingMode, bool& s
     if (cairo_surface_status(m_data.m_surface) != CAIRO_STATUS_SUCCESS)
         return;  // create will notice we didn't set m_initialized and fail.
 
-    cairo_t* cr = cairo_create(m_data.m_surface);
-    m_context.set(new GraphicsContext(cr));
-    cairo_destroy(cr);  // The context is now owned by the GraphicsContext.
+    RefPtr<cairo_t> cr = adoptRef(cairo_create(m_data.m_surface));
+    m_data.m_platformContext.setCr(cr.get());
+    m_context.set(new GraphicsContext(&m_data.m_platformContext));
     success = true;
 }
 
@@ -301,7 +304,7 @@ static cairo_status_t writeFunction(void* closure, const unsigned char* data, un
 
 String ImageBuffer::toDataURL(const String& mimeType, const double*) const
 {
-    cairo_surface_t* image = cairo_get_target(context()->platformContext());
+    cairo_surface_t* image = cairo_get_target(context()->platformContext()->cr());
     if (!image)
         return "data:,";
 
index 49f15df..42867d1 100644 (file)
@@ -26,7 +26,9 @@
 #ifndef ImageBufferData_h
 #define ImageBufferData_h
 
-#include "cairo.h"
+#include "PlatformContextCairo.h"
+
+typedef struct _cairo_surface cairo_surface_t;
 
 namespace WebCore {
 
@@ -37,6 +39,7 @@ public:
     ImageBufferData(const IntSize&);
 
     cairo_surface_t* m_surface;
+    PlatformContextCairo m_platformContext;
 };
 
 }  // namespace WebCore
index e51d65a..d3a52ce 100644 (file)
@@ -36,6 +36,7 @@
 #include "ContextShadow.h"
 #include "FloatRect.h"
 #include "GraphicsContext.h"
+#include "PlatformContextCairo.h"
 #include "ImageBuffer.h"
 #include "ImageObserver.h"
 #include "RefPtrCairo.h"
@@ -114,7 +115,7 @@ void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const Flo
 
     IntSize selfSize = size();
 
-    cairo_t* cr = context->platformContext();
+    cairo_t* cr = context->platformContext()->cr();
     context->save();
 
     // Set the compositing operation.
@@ -169,8 +170,7 @@ void Image::drawPattern(GraphicsContext* context, const FloatRect& tileRect, con
     if (!image) // If it's too early we won't have an image yet.
         return;
 
-    cairo_t* cr = context->platformContext();
-
+    cairo_t* cr = context->platformContext()->cr();
     drawPatternToCairoContext(cr, image, size(), tileRect, patternTransform, phase, toCairoOperator(op), destRect);
 
     if (imageObserver())
diff --git a/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp b/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp
new file mode 100644 (file)
index 0000000..ba75162
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "PlatformContextCairo.h"
+
+#include <cairo.h>
+
+namespace WebCore {
+
+PlatformContextCairo::PlatformContextCairo(cairo_t* cr)
+    : m_cr(cr)
+{
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h b/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h
new file mode 100644 (file)
index 0000000..c6cceda
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef PlatformContextCairo_h
+#define PlatformContextCairo_h
+
+#include "ContextShadow.h"
+#include "RefPtrCairo.h"
+
+namespace WebCore {
+
+// Much like PlatformContextSkia in the Skia port, this class holds information that
+// would normally be private to GraphicsContext, except that we want to allow access
+// to it in Font and Image code. This allows us to separate the concerns of Cairo-specific
+// code from the platform-independent GraphicsContext.
+
+class PlatformContextCairo {
+    WTF_MAKE_NONCOPYABLE(PlatformContextCairo);
+public:
+    PlatformContextCairo(cairo_t*);
+    cairo_t* cr() { return m_cr.get(); }
+    void setCr(cairo_t* cr) { m_cr = cr; }
+
+private:
+    RefPtr<cairo_t> m_cr;
+};
+
+} // namespace WebCore
+
+#endif // PlatformContextCairo_h
index 654adac..d14b052 100644 (file)
@@ -35,6 +35,7 @@
 
 #include "CairoUtilities.h"
 #include "ContextShadow.h"
+#include "PlatformContextCairo.h"
 #include "GraphicsContext.h"
 #include "NotImplemented.h"
 #include "SimpleFontData.h"
@@ -220,7 +221,7 @@ bool Font::canExpandAroundIdeographsInComplexText()
     return false;
 }
 
-static void drawGlyphsShadow(GraphicsContext* graphicsContext, cairo_t* context, const FloatPoint& point, PangoLayoutLine* layoutLine, PangoRegionType renderRegion)
+static void drawGlyphsShadow(GraphicsContext* graphicsContext, const FloatPoint& point, PangoLayoutLine* layoutLine, PangoRegionType renderRegion)
 {
     ContextShadow* shadow = graphicsContext->contextShadow();
     ASSERT(shadow);
@@ -232,6 +233,7 @@ static void drawGlyphsShadow(GraphicsContext* graphicsContext, cairo_t* context,
 
     // Optimize non-blurry shadows, by just drawing text without the ContextShadow.
     if (!shadow->mustUseContextShadow(graphicsContext)) {
+        cairo_t* context = graphicsContext->platformContext()->cr();
         cairo_save(context);
         cairo_translate(context, totalOffset.x(), totalOffset.y());
 
@@ -255,6 +257,7 @@ static void drawGlyphsShadow(GraphicsContext* graphicsContext, cairo_t* context,
         // because we don't want any bits and pieces of characters out of range to be
         // drawn. Since ContextShadow expects a consistent transform, we have to undo the
         // translation before calling endShadowLayer as well.
+        cairo_t* context = graphicsContext->platformContext()->cr();
         cairo_save(context);
         cairo_translate(context, totalOffset.x(), totalOffset.y());
         gdk_cairo_region(context, renderRegion);
@@ -275,7 +278,7 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F
     }
 #endif
 
-    cairo_t* cr = context->platformContext();
+    cairo_t* cr = context->platformContext()->cr();
     PangoLayout* layout = pango_cairo_create_layout(cr);
     setPangoAttributes(this, run, layout);
 
@@ -294,7 +297,7 @@ void Font::drawComplexText(GraphicsContext* context, const TextRun& run, const F
     int ranges[] = {start - utf8, end - utf8};
     partialRegion = gdk_pango_layout_line_get_clip_region(layoutLine, 0, 0, ranges, 1);
 
-    drawGlyphsShadow(context, cr, point, layoutLine, partialRegion);
+    drawGlyphsShadow(context, point, layoutLine, partialRegion);
 
     cairo_save(cr);
     cairo_translate(cr, point.x(), point.y());
index d56b52d..7fdc1f6 100644 (file)
@@ -33,9 +33,9 @@
 #include "GraphicsContext.h"
 #include "MIMETypeRegistry.h"
 #include "PassRefPtr.h"
-#include <wtf/text/CString.h>
-
+#include "PlatformContextCairo.h"
 #include <gtk/gtk.h>
+#include <wtf/text/CString.h>
 
 namespace WebCore {
 
@@ -117,7 +117,7 @@ void Icon::paint(GraphicsContext* context, const IntRect& rect)
         return;
 
     // TODO: Scale/clip the image if necessary.
-    cairo_t* cr = context->platformContext();
+    cairo_t* cr = context->platformContext()->cr();
     cairo_save(cr);
     gdk_cairo_set_source_pixbuf(cr, m_icon, rect.x(), rect.y());
     cairo_paint(cr);
index b2c702f..7ce7ee9 100644 (file)
@@ -72,18 +72,15 @@ GraphicsContext::GraphicsContext(HDC dc, bool hasAlpha)
 
 void GraphicsContext::platformInit(HDC dc, bool hasAlpha)
 {
-    m_data = new GraphicsContextPlatformPrivate;
-
-    if (dc) {
-        m_data->cr = createCairoContextWithHDC(dc, hasAlpha);
-        m_data->m_hdc = dc;
-    } else {
+    cairo_t* cr = 0;
+    if (dc)
+        cr = createCairoContextWithHDC(dc, hasAlpha);
+    else
         setPaintingDisabled(true);
-        m_data->cr = 0;
-        m_data->m_hdc = 0;
-    }
 
-    if (m_data->cr) {
+    m_data = new GraphicsContextPlatformPrivateTopLevel(new PlatformContextCairo(cr));
+    m_data->m_hdc = dc;
+    if (platformContext()->cr()) {
         // Make sure the context starts in sync with our state.
         setPlatformFillColor(fillColor(), fillColorSpace());
         setPlatformStrokeColor(strokeColor(), strokeColorSpace());
@@ -131,24 +128,25 @@ void GraphicsContext::releaseWindowsContext(HDC hdc, const IntRect& dstRect, boo
     // Scale the target surface to the new image size, and flip it
     // so that when we set the srcImage as the surface it will draw
     // right-side-up.
-    cairo_save(m_data->cr);
-    cairo_translate(m_data->cr, dstRect.x(), dstRect.height() + dstRect.y());
-    cairo_scale(m_data->cr, 1.0, -1.0);
-    cairo_set_source_surface(m_data->cr, image, 0, 0);
+    cairo_t* cr = platformContext()->cr();
+    cairo_save(cr);
+    cairo_translate(cr, dstRect.x(), dstRect.height() + dstRect.y());
+    cairo_scale(cr, 1, -1);
+    cairo_set_source_surface(cr, image, 0, 0);
 
     if (m_data->layers.size())
-        cairo_paint_with_alpha(m_data->cr, m_data->layers.last());
+        cairo_paint_with_alpha(cr, m_data->layers.last());
     else
-        cairo_paint(m_data->cr);
+        cairo_paint(cr);
      
     // Delete all our junk.
     cairo_surface_destroy(image);
     ::DeleteDC(hdc);
     ::DeleteObject(bitmap);
-    cairo_restore(m_data->cr);
+    cairo_restore(cr);
 }
 
-void GraphicsContextPlatformPrivate::syncContext(PlatformGraphicsContext* cr)
+void GraphicsContextPlatformPrivate::syncContext(cairo_t* cr)
 {
     if (!cr)
        return;
index 1e9f159..9b11c27 100644 (file)
@@ -34,6 +34,7 @@
 #include "HTMLNames.h"
 #include "MediaControlElements.h"
 #include "PaintInfo.h"
+#include "PlatformContextCairo.h"
 #include "RenderBox.h"
 #include "RenderObject.h"
 #include "TimeRanges.h"
@@ -234,7 +235,7 @@ static void paintGdkPixbuf(GraphicsContext* context, const GdkPixbuf* icon, cons
         icon = scaledIcon.get();
     }
 
-    cairo_t* cr = context->platformContext();
+    cairo_t* cr = context->platformContext()->cr();
     cairo_save(cr);
     gdk_cairo_set_source_pixbuf(cr, icon, iconRect.x(), iconRect.y());
     cairo_paint(cr);
index 9e640f6..6f7389d 100644 (file)
@@ -33,6 +33,7 @@
 
 #include "GraphicsContext.h"
 #include "GtkVersioning.h"
+#include "PlatformContextCairo.h"
 #include "RefPtrCairo.h"
 #include "RenderThemeGtk.h"
 #include "Timer.h"
@@ -128,7 +129,7 @@ WidgetRenderingContext::~WidgetRenderingContext()
     }
 
     // FIXME: It's unclear if it is necessary to preserve the current source here.
-    cairo_t* cairoContext = m_graphicsContext->platformContext();
+    cairo_t* cairoContext = m_graphicsContext->platformContext()->cr();
     RefPtr<cairo_pattern_t> previousSource(cairo_get_source(cairoContext));
 
     // The blit rectangle is the original target rectangle adjusted for any extra space.
index 75a51c5..58a4f2c 100644 (file)
@@ -48,6 +48,7 @@
 #include "KeyboardEvent.h"
 #include "MouseEvent.h"
 #include "Page.h"
+#include "PlatformContextCairo.h"
 #include "PlatformKeyboardEvent.h"
 #include "PlatformMouseEvent.h"
 #include "PluginDebug.h"
@@ -217,7 +218,7 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect)
             // avoid drawing artifacts.
 
             // This Would not work without double buffering, but we always use it.
-            cairo_set_source_surface(cr.get(), cairo_get_group_target(context->platformContext()),
+            cairo_set_source_surface(cr.get(), cairo_get_group_target(context->platformContext()->cr()),
                                      -m_windowRect.x(), -m_windowRect.y());
             cairo_set_operator(cr.get(), CAIRO_OPERATOR_SOURCE);
         } else
@@ -244,7 +245,7 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect)
     if (syncX)
         XSync(m_pluginDisplay, false); // sync changes by plugin
 
-    cairo_t* cr = context->platformContext();
+    cairo_t* cr = context->platformContext()->cr();
     cairo_save(cr);
 
     cairo_set_source_surface(cr, drawableSurface.get(), frameRect().x(), frameRect().y());
index 208121e..f575709 100644 (file)
@@ -83,6 +83,7 @@
 #endif
 
 #if PLATFORM(CAIRO)
+#include "PlatformContextCairo.h"
 #include <cairo-win32.h>
 #endif
 
@@ -572,8 +573,7 @@ void PluginView::paintWindowedPluginIntoContext(GraphicsContext* context, const
     // Must flush drawings up to this point to the backing metafile, otherwise the
     // plugin region will be overwritten with any clear regions specified in the
     // cairo-controlled portions of the rendering.
-    PlatformGraphicsContext* ctx = context->platformContext();
-    cairo_show_page(ctx);
+    cairo_show_page(context->platformContext()->cr());
 #endif
 
     HDC hdc = windowsContext.hdc();
index 05c15d4..88452c2 100644 (file)
@@ -1,3 +1,20 @@
+2011-03-30  Martin Robinson  <mrobinson@igalia.com>
+
+        Reviewed by Dirk Schulze.
+
+        [Cairo] Better separate the concerns of GraphicsContextCairo
+        https://bugs.webkit.org/show_bug.cgi?id=55150
+
+        Add a PlatformContextCairo which right now stores the cairo_t* for a
+        GraphicsContextCairo. Later patches will move logic for tracking ContextShadow
+        and image masking layers into this PlatformContextCairo class.
+
+        * webkit/webkitwebframe.cpp:
+        (draw_page_callback):
+        * webkit/webkitwebview.cpp:
+        (webkit_web_view_expose_event):
+        (webkit_web_view_draw):
+
 2011-03-29  Philippe Normand  <pnormand@igalia.com>
 
         Unreviewed, disable an assert in testwebview due to
index fd90a6c..a0e40b3 100644 (file)
@@ -44,6 +44,7 @@
 #include "JSDOMBinding.h"
 #include "JSDOMWindow.h"
 #include "JSElement.h"
+#include "PlatformContextCairo.h"
 #include "PrintContext.h"
 #include "RenderListItem.h"
 #include "RenderTreeAsText.h"
@@ -765,17 +766,17 @@ static void begin_print_callback(GtkPrintOperation* op, GtkPrintContext* context
     gtk_print_operation_set_n_pages(op, printContext->pageCount());
 }
 
-static void draw_page_callback(GtkPrintOperation* op, GtkPrintContext* context, gint page_nr, gpointer user_data)
+static void draw_page_callback(GtkPrintOperation*, GtkPrintContext* gtkPrintContext, gint pageNumber, PrintContext* corePrintContext)
 {
-    PrintContext* printContext = reinterpret_cast<PrintContext*>(user_data);
-
-    if (page_nr >= static_cast<gint>(printContext->pageCount()))
+    if (pageNumber >= static_cast<gint>(corePrintContext->pageCount()))
         return;
 
-    cairo_t* cr = gtk_print_context_get_cairo_context(context);
-    GraphicsContext ctx(cr);
-    float width = gtk_print_context_get_width(context);
-    printContext->spoolPage(ctx, page_nr, width);
+    cairo_t* cr = gtk_print_context_get_cairo_context(gtkPrintContext);
+    float pageWidth = gtk_print_context_get_width(gtkPrintContext);
+
+    PlatformContextCairo platformContext(cr);
+    GraphicsContext graphicsContext(&platformContext);
+    corePrintContext->spoolPage(graphicsContext, pageNumber, pageWidth);
 }
 
 static void end_print_callback(GtkPrintOperation* op, GtkPrintContext* context, gpointer user_data)
index 17637cc..bf74d7b 100644 (file)
@@ -710,8 +710,8 @@ static gboolean webkit_web_view_expose_event(GtkWidget* widget, GdkEventExpose*
         frame->view()->updateLayoutAndStyleIfNeededRecursive();
 
         RefPtr<cairo_t> cr = adoptRef(gdk_cairo_create(event->window));
-        GraphicsContext ctx(cr.get());
-        ctx.setGdkExposeEvent(event);
+        GraphicsContext gc(cr.get());
+        gc.setGdkExposeEvent(event);
 
         int rectCount;
         GOwnPtr<GdkRectangle> rects;
@@ -720,7 +720,7 @@ static gboolean webkit_web_view_expose_event(GtkWidget* widget, GdkEventExpose*
         for (int i = 0; i < rectCount; i++)
             paintRects.append(IntRect(rects.get()[i]));
 
-        paintWebView(frame, priv->transparent, ctx, static_cast<IntRect>(event->area), paintRects);
+        paintWebView(frame, priv->transparent, gc, static_cast<IntRect>(event->area), paintRects);
     }
 
     return FALSE;
@@ -737,7 +737,7 @@ static gboolean webkit_web_view_draw(GtkWidget* widget, cairo_t* cr)
 
     Frame* frame = core(webView)->mainFrame();
     if (frame->contentRenderer() && frame->view()) {
-        GraphicsContext ctx(cr);
+        GraphicsContext gc(cr);
         IntRect rect = clipRect;
         cairo_rectangle_list_t* rectList = cairo_copy_clip_rectangle_list(cr);
 
@@ -748,7 +748,7 @@ static gboolean webkit_web_view_draw(GtkWidget* widget, cairo_t* cr)
             for (int i = 0; i < rectList->num_rectangles; i++)
                 rects.append(enclosingIntRect(FloatRect(rectList->rectangles[i])));
         }
-        paintWebView(frame, priv->transparent, ctx, rect, rects);
+        paintWebView(frame, priv->transparent, gc, rect, rects);
 
         cairo_rectangle_list_destroy(rectList);
     }
index ae3c024..870b692 100644 (file)
@@ -1,3 +1,17 @@
+2011-03-30  Martin Robinson  <mrobinson@igalia.com>
+
+        Reviewed by Dirk Schulze.
+
+        [Cairo] Better separate the concerns of GraphicsContextCairo
+        https://bugs.webkit.org/show_bug.cgi?id=55150
+
+        * WebFrame.cpp:
+        (hdcFromContext): Modify this method to take PlatformContextCairo
+        instead of a cairo_t.
+        (WebFrame::spoolPage): Update to reflect new platform context.
+        (WebFrame::spoolPages): Ditto.
+        * WebFrame.h: Ditto.
+
 2011-03-30  Steve Falkenburg  <sfalken@apple.com>
 
         Reviewed by Adam Roben.
index 1ef3066..4b9e35d 100644 (file)
 #if PLATFORM(CG)
 #include <CoreGraphics/CoreGraphics.h>
 #elif PLATFORM(CAIRO)
+#include "PlatformContextCairo.h"
 #include <cairo-win32.h>
 #endif
 
@@ -2186,8 +2187,7 @@ static float scaleFactor(HDC printDC, const IntRect& marginRect, const IntRect&
 
 static HDC hdcFromContext(PlatformGraphicsContext* pctx)
 {
-    cairo_surface_t* surface = cairo_get_target(pctx);
-    return cairo_win32_surface_get_dc(surface);
+    return cairo_win32_surface_get_dc(cairo_get_target(pctx->cr()));
 }
 
 void WebFrame::drawHeader(PlatformGraphicsContext* pctx, IWebUIDelegate* ui, const IntRect& pageRect, float headerHeight)
@@ -2242,13 +2242,14 @@ void WebFrame::spoolPage(PlatformGraphicsContext* pctx, GraphicsContext* spoolCt
     XFORM original, scaled;
     GetWorldTransform(hdc, &original);
     
+    cairo_t* cr = pctx->cr();
     bool preview = (hdc != printDC);
     if (preview) {
         // If this is a preview, the Windows HDC was set to a non-scaled state so that Cairo will
         // draw correctly.  We need to retain the correct preview scale here for use when the Cairo
         // drawing completes so that we can scale our GDI-based header/footer calls. This is a
         // workaround for a bug in Cairo (see https://bugs.freedesktop.org/show_bug.cgi?id=28161)
-        scaled = buildXFORMFromCairo(hdc, pctx);
+        scaled = buildXFORMFromCairo(hdc, cr);
     }
 
     float scale = scaleFactor(printDC, marginRect, pageRect);
@@ -2258,13 +2259,13 @@ void WebFrame::spoolPage(PlatformGraphicsContext* pctx, GraphicsContext* spoolCt
 
     // We cannot scale the display HDC because the print surface also scales fonts,
     // resulting in invalid printing (and print preview)
-    cairo_scale(pctx, scale, scale);
-    cairo_translate(pctx, cairoMarginRect.x(), cairoMarginRect.y() + headerHeight);
+    cairo_scale(cr, scale, scale);
+    cairo_translate(cr, cairoMarginRect.x(), cairoMarginRect.y() + headerHeight);
 
     // Modify Cairo (only) to account for page position.
-    cairo_translate(pctx, -pageRect.x(), -pageRect.y());
+    cairo_translate(cr, -pageRect.x(), -pageRect.y());
     coreFrame->view()->paintContents(spoolCtx, pageRect);
-    cairo_translate(pctx, pageRect.x(), pageRect.y());
+    cairo_translate(cr, pageRect.x(), pageRect.y());
     
     if (preview) {
         // If this is a preview, the Windows HDC was set to a non-scaled state so that Cairo would
@@ -2285,8 +2286,8 @@ void WebFrame::spoolPage(PlatformGraphicsContext* pctx, GraphicsContext* spoolCt
 
     SetWorldTransform(hdc, &original);
 
-    cairo_show_page(pctx);
-    ASSERT(!cairo_status(pctx));
+    cairo_show_page(cr);
+    ASSERT(!cairo_status(cr));
     spoolCtx->restore();
 }
 
@@ -2338,17 +2339,21 @@ HRESULT STDMETHODCALLTYPE WebFrame::spoolPages(
     else
         printSurface = cairo_win32_printing_surface_create(targetDC); // metafile
     
-    PlatformGraphicsContext* pctx = (PlatformGraphicsContext*)cairo_create(printSurface);
-    if (!pctx) {
+    cairo_t* cr = cairo_create(printSurface);
+    if (!cr) {
         cairo_surface_destroy(printSurface);    
         return E_FAIL;
     }
-    
+
+    PlatformContextCairo platformContext(cr);
+    PlatformGraphicsContext* pctx = &platformContext;
+    cairo_destroy(cr);
+
     if (ctx) {
         // If this is a preview, the Windows HDC was sent with scaling information.
         // Retrieve it and reset it so that it draws properly.  This is a workaround
         // for a bug in Cairo (see https://bugs.freedesktop.org/show_bug.cgi?id=28161)
-        setCairoTransformToPreviewHDC(pctx, targetDC);
+        setCairoTransformToPreviewHDC(cr, targetDC);
     }
     
     cairo_surface_set_fallback_resolution(printSurface, 72.0, 72.0);
@@ -2392,7 +2397,6 @@ HRESULT STDMETHODCALLTYPE WebFrame::spoolPages(
         spoolPage(pctx, &spoolCtx, printDC, ui.get(), headerHeight, footerHeight, ii, pageCount);
 
 #if PLATFORM(CAIRO)
-    cairo_destroy(pctx);
     cairo_surface_finish(printSurface);
     ASSERT(!cairo_surface_status(printSurface));
     cairo_surface_destroy(printSurface);
index 742ed4f..9158fb3 100644 (file)
@@ -62,7 +62,10 @@ typedef struct OpaqueJSValue* JSObjectRef;
 #if PLATFORM(CG)
 typedef struct CGContext PlatformGraphicsContext;
 #elif PLATFORM(CAIRO)
-typedef struct _cairo PlatformGraphicsContext;
+namespace WebCore {
+class PlatformContextCairo;
+}
+typedef class WebCore::PlatformContextCairo PlatformGraphicsContext;
 #endif
 
 class WebFrame;