summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-17 20:39:38 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-17 20:39:38 +0000
commit777f996eab1610f9676ee62ee478cc97687c56cd (patch)
tree0b5df00b507bf0d0de8ba292541d7b0987f7f3ab
parent6e9f27f9b6839b7a07e44a6299bfa48579fe5ba2 (diff)
downloadchromium_src-777f996eab1610f9676ee62ee478cc97687c56cd.zip
chromium_src-777f996eab1610f9676ee62ee478cc97687c56cd.tar.gz
chromium_src-777f996eab1610f9676ee62ee478cc97687c56cd.tar.bz2
Reverting 20516 by re-landing this previous patch.
Keep the cairo clipping region in sync with the Skia one. The PlatformCanvas now tracks this, so we don't need to have the similar code in gfx::Canvas. I moved most references of cairo_surface_t to cairo_t since the cairo_t has a transform and clip but the surface does not. Review URL: http://codereview.chromium.org/149409 Review URL: http://codereview.chromium.org/155700 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20992 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--app/gfx/canvas_linux.cc21
-rw-r--r--base/gfx/native_widget_types.h4
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.cc13
-rw-r--r--skia/ext/bitmap_platform_device_linux.cc119
-rw-r--r--skia/ext/bitmap_platform_device_linux.h8
-rw-r--r--skia/ext/bitmap_platform_device_win.h3
-rw-r--r--skia/ext/canvas_paint_linux.h11
-rw-r--r--skia/ext/platform_canvas_linux.cc2
-rw-r--r--skia/ext/platform_device_linux.h6
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl_gtk.cc20
-rw-r--r--webkit/tools/test_shell/webwidget_host_gtk.cc7
11 files changed, 146 insertions, 68 deletions
diff --git a/app/gfx/canvas_linux.cc b/app/gfx/canvas_linux.cc
index 7e561c6..cf7352d 100644
--- a/app/gfx/canvas_linux.cc
+++ b/app/gfx/canvas_linux.cc
@@ -95,29 +95,11 @@ void Canvas::SizeStringInt(const std::wstring& text,
cairo_surface_destroy(surface);
}
-void Canvas::ApplySkiaMatrixToCairoContext(cairo_t* cr) {
- const SkMatrix& skia_matrix = getTotalMatrix();
- cairo_matrix_t cairo_matrix;
- cairo_matrix_init(&cairo_matrix,
- SkScalarToFloat(skia_matrix.getScaleX()),
- SkScalarToFloat(skia_matrix.getSkewY()),
- SkScalarToFloat(skia_matrix.getSkewX()),
- SkScalarToFloat(skia_matrix.getScaleY()),
- SkScalarToFloat(skia_matrix.getTranslateX()),
- SkScalarToFloat(skia_matrix.getTranslateY()));
- cairo_set_matrix(cr, &cairo_matrix);
-}
-
void Canvas::DrawStringInt(const std::wstring& text,
const gfx::Font& font,
const SkColor& color, int x, int y, int w, int h,
int flags) {
- cairo_surface_t* surface = beginPlatformPaint();
- cairo_t* cr = cairo_create(surface);
- // We're going to draw onto the surface directly. This circumvents the matrix
- // installed by Skia. Apply the matrix from skia to cairo so they align and
- // we draw at the right place.
- ApplySkiaMatrixToCairoContext(cr);
+ cairo_t* cr = beginPlatformPaint();
PangoLayout* layout = pango_cairo_create_layout(cr);
cairo_set_source_rgb(cr,
@@ -169,7 +151,6 @@ void Canvas::DrawStringInt(const std::wstring& text,
pango_cairo_show_layout(cr, layout);
g_object_unref(layout);
- cairo_destroy(cr);
// NOTE: beginPlatformPaint returned its surface, we shouldn't destroy it.
}
diff --git a/base/gfx/native_widget_types.h b/base/gfx/native_widget_types.h
index d165cd4a..08bf76f 100644
--- a/base/gfx/native_widget_types.h
+++ b/base/gfx/native_widget_types.h
@@ -50,7 +50,7 @@ class NSTextField;
typedef struct _GdkCursor GdkCursor;
typedef struct _GtkWidget GtkWidget;
typedef struct _GtkWindow GtkWindow;
-typedef struct _cairo_surface cairo_surface_t;
+typedef struct _cairo cairo_t;
#endif
namespace gfx {
@@ -73,7 +73,7 @@ typedef void* NativeMenu;
typedef GtkWidget* NativeView;
typedef GtkWindow* NativeWindow;
typedef GtkWidget* NativeEditView;
-typedef cairo_surface_t* NativeDrawingContext;
+typedef cairo_t* NativeDrawingContext;
typedef GdkCursor* NativeCursor;
typedef GtkWidget* NativeMenu;
#endif
diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc
index a5423ac..45a98bf 100644
--- a/chrome/renderer/webplugin_delegate_proxy.cc
+++ b/chrome/renderer/webplugin_delegate_proxy.cc
@@ -932,16 +932,9 @@ void WebPluginDelegateProxy::PaintSadPlugin(gfx::NativeDrawingContext context,
skia::PlatformDevice& device = canvas.getTopPlatformDevice();
device.drawToHDC(context, plugin_rect_.x(), plugin_rect_.y(), NULL);
#elif defined(OS_LINUX)
- // Though conceptually we've been handed a cairo_surface_t* and we
- // could've just hooked up the canvas to draw directly onto it, our
- // canvas implementation currently uses cairo as a dumb pixel buffer
- // and would have done the following copy anyway.
- // TODO(evanm): revisit when we have printing hooked up, as that might
- // change our usage of cairo.
- skia::PlatformDevice& device = canvas.getTopPlatformDevice();
- cairo_t* cairo = cairo_create(context);
- cairo_surface_t* source_surface = device.beginPlatformPaint();
- cairo_set_source_surface(cairo, source_surface, plugin_rect_.x(), plugin_rect_.y());
+ cairo_t* cairo = canvas.getTopPlatformDevice().beginPlatformPaint();
+ cairo_set_source_surface(cairo, cairo_get_target(context),
+ plugin_rect_.x(), plugin_rect_.y());
cairo_paint(cairo);
// We have no endPlatformPaint() on the Linux PlatformDevice.
// The cairo_t* is owned by the device.
diff --git a/skia/ext/bitmap_platform_device_linux.cc b/skia/ext/bitmap_platform_device_linux.cc
index 1b061b0..a74ec83 100644
--- a/skia/ext/bitmap_platform_device_linux.cc
+++ b/skia/ext/bitmap_platform_device_linux.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,6 +8,33 @@
namespace skia {
+namespace {
+
+void LoadMatrixToContext(cairo_t* context, const SkMatrix& matrix) {
+ cairo_matrix_t cairo_matrix;
+ cairo_matrix_init(&cairo_matrix,
+ SkScalarToFloat(matrix.getScaleX()),
+ SkScalarToFloat(matrix.getSkewY()),
+ SkScalarToFloat(matrix.getSkewX()),
+ SkScalarToFloat(matrix.getScaleY()),
+ SkScalarToFloat(matrix.getTranslateX()),
+ SkScalarToFloat(matrix.getTranslateY()));
+ cairo_set_matrix(context, &cairo_matrix);
+}
+
+void LoadClipToContext(cairo_t* context, const SkRegion& clip) {
+ cairo_reset_clip(context);
+
+ // TODO(brettw) support non-rect clips.
+ SkIRect bounding = clip.getBounds();
+ cairo_rectangle(context, bounding.fLeft, bounding.fTop,
+ bounding.fRight - bounding.fLeft,
+ bounding.fBottom - bounding.fTop);
+ cairo_clip(context);
+}
+
+} // namespace
+
// -----------------------------------------------------------------------------
// These objects are reference counted and own a Cairo surface. The surface is
// the backing store for a Skia bitmap and we reference count it so that we can
@@ -17,18 +44,39 @@ namespace skia {
class BitmapPlatformDevice::BitmapPlatformDeviceData
: public base::RefCounted<BitmapPlatformDeviceData> {
public:
- explicit BitmapPlatformDeviceData(cairo_surface_t* surface)
- : surface_(surface) { }
+ explicit BitmapPlatformDeviceData(cairo_surface_t* surface);
- cairo_surface_t* surface() const { return surface_; }
+ cairo_t* GetContext();
+ cairo_surface_t* GetSurface();
+
+ // Sets the transform and clip operations. This will not update the Cairo
+ // surface, but will mark the config as dirty. The next call of LoadConfig
+ // will pick up these changes.
+ void SetMatrixClip(const SkMatrix& transform, const SkRegion& region);
protected:
+ friend class base::RefCounted<BitmapPlatformDeviceData>;
+
+ ~BitmapPlatformDeviceData();
+
+ void LoadConfig();
+
+ // The Cairo surface inside this DC.
+ cairo_t* context_;
cairo_surface_t *const surface_;
- friend class base::RefCounted<BitmapPlatformDeviceData>;
- ~BitmapPlatformDeviceData() {
- cairo_surface_destroy(surface_);
- }
+ // True when there is a transform or clip that has not been set to the
+ // surface. The surface is retrieved for every text operation, and the
+ // transform and clip do not change as much. We can save time by not loading
+ // the clip and transform for every one.
+ bool config_dirty_;
+
+ // Translation assigned to the DC: we need to keep track of this separately
+ // so it can be updated even if the DC isn't created yet.
+ SkMatrix transform_;
+
+ // The current clipping
+ SkRegion clip_region_;
// Disallow copy & assign.
BitmapPlatformDeviceData(const BitmapPlatformDeviceData&);
@@ -36,6 +84,52 @@ class BitmapPlatformDevice::BitmapPlatformDeviceData
const BitmapPlatformDeviceData&);
};
+BitmapPlatformDevice::BitmapPlatformDeviceData::BitmapPlatformDeviceData(
+ cairo_surface_t* surface)
+ : surface_(surface),
+ config_dirty_(true) { // Want to load the config next time.
+ context_ = cairo_create(surface);
+}
+
+BitmapPlatformDevice::BitmapPlatformDeviceData::~BitmapPlatformDeviceData() {
+ cairo_destroy(context_);
+ cairo_surface_destroy(surface_);
+}
+
+cairo_t* BitmapPlatformDevice::BitmapPlatformDeviceData::GetContext() {
+ LoadConfig();
+ return context_;
+}
+
+void BitmapPlatformDevice::BitmapPlatformDeviceData::SetMatrixClip(
+ const SkMatrix& transform,
+ const SkRegion& region) {
+ transform_ = transform;
+ clip_region_ = region;
+ config_dirty_ = true;
+}
+
+cairo_surface_t*
+BitmapPlatformDevice::BitmapPlatformDeviceData::GetSurface() {
+ // TODO(brettw) this function should be removed.
+ LoadConfig();
+ return surface_;
+}
+
+void BitmapPlatformDevice::BitmapPlatformDeviceData::LoadConfig() {
+ if (!config_dirty_ || !context_)
+ return; // Nothing to do.
+ config_dirty_ = false;
+
+ // Load the identity matrix since this is what our clip is relative to.
+ cairo_matrix_t cairo_matrix;
+ cairo_matrix_init_identity(&cairo_matrix);
+ cairo_set_matrix(context_, &cairo_matrix);
+
+ LoadClipToContext(context_, clip_region_);
+ LoadMatrixToContext(context_, transform_);
+}
+
// We use this static factory function instead of the regular constructor so
// that we can create the pixel data before calling the constructor. This is
// required so that we can call the base class' constructor with the pixel
@@ -98,8 +192,13 @@ BitmapPlatformDevice::BitmapPlatformDevice(
BitmapPlatformDevice::~BitmapPlatformDevice() {
}
-cairo_surface_t* BitmapPlatformDevice::surface() const {
- return data_->surface();
+cairo_t* BitmapPlatformDevice::beginPlatformPaint() {
+ return data_->GetContext();
+}
+
+void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform,
+ const SkRegion& region) {
+ data_->SetMatrixClip(transform, region);
}
BitmapPlatformDevice& BitmapPlatformDevice::operator=(
diff --git a/skia/ext/bitmap_platform_device_linux.h b/skia/ext/bitmap_platform_device_linux.h
index a40986c..eb6ffa9 100644
--- a/skia/ext/bitmap_platform_device_linux.h
+++ b/skia/ext/bitmap_platform_device_linux.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -85,9 +85,11 @@ class BitmapPlatformDevice : public PlatformDevice {
// If someone wants to paint on a Cairo surface version of our
// buffer, then give them the surface we're already using.
- virtual cairo_surface_t* beginPlatformPaint() { return surface(); }
+ virtual cairo_t* beginPlatformPaint();
- cairo_surface_t* surface() const;
+ // Loads the given transform and clipping region into the HDC. This is
+ // overridden from SkDevice.
+ virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region);
private:
scoped_refptr<BitmapPlatformDeviceData> data_;
diff --git a/skia/ext/bitmap_platform_device_win.h b/skia/ext/bitmap_platform_device_win.h
index b37792a..7093ff1 100644
--- a/skia/ext/bitmap_platform_device_win.h
+++ b/skia/ext/bitmap_platform_device_win.h
@@ -64,6 +64,9 @@ class BitmapPlatformDevice : public PlatformDevice {
// Retrieves the bitmap DC, which is the memory DC for our bitmap data. The
// bitmap DC is lazy created.
virtual HDC getBitmapDC();
+
+ // Loads the given transform and clipping region into the HDC. This is
+ // overridden from SkDevice.
virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region);
virtual void drawToHDC(HDC dc, int x, int y, const RECT* src_rect);
diff --git a/skia/ext/canvas_paint_linux.h b/skia/ext/canvas_paint_linux.h
index b69dd5a..0f03603 100644
--- a/skia/ext/canvas_paint_linux.h
+++ b/skia/ext/canvas_paint_linux.h
@@ -21,7 +21,7 @@ class CanvasPaintT : public T {
public:
// This constructor assumes the result is opaque.
explicit CanvasPaintT(GdkEventExpose* event)
- : surface_(NULL),
+ : context_(NULL),
window_(event->window),
rectangle_(event->area),
composite_alpha_(false) {
@@ -29,7 +29,7 @@ class CanvasPaintT : public T {
}
CanvasPaintT(GdkEventExpose* event, bool opaque)
- : surface_(NULL),
+ : context_(NULL),
window_(event->window),
rectangle_(event->area),
composite_alpha_(false) {
@@ -44,7 +44,8 @@ class CanvasPaintT : public T {
cairo_t* cr = gdk_cairo_create(window_);
if (composite_alpha_)
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_set_source_surface(cr, surface_, rectangle_.x, rectangle_.y);
+ cairo_surface_t* source_surface = cairo_get_target(context_);
+ cairo_set_source_surface(cr, source_surface, rectangle_.x, rectangle_.y);
cairo_rectangle(cr, rectangle_.x, rectangle_.y,
rectangle_.width, rectangle_.height);
cairo_fill(cr);
@@ -80,10 +81,10 @@ class CanvasPaintT : public T {
// surface.
T::translate(-SkIntToScalar(rectangle_.x), -SkIntToScalar(rectangle_.y));
- surface_ = T::getTopPlatformDevice().beginPlatformPaint();
+ context_ = T::getTopPlatformDevice().beginPlatformPaint();
}
- cairo_surface_t* surface_;
+ cairo_t* context_;
GdkWindow* window_;
GdkRectangle rectangle_;
// See description above setter.
diff --git a/skia/ext/platform_canvas_linux.cc b/skia/ext/platform_canvas_linux.cc
index 61e8404..109b232 100644
--- a/skia/ext/platform_canvas_linux.cc
+++ b/skia/ext/platform_canvas_linux.cc
@@ -42,7 +42,7 @@ bool PlatformCanvas::initialize(int width, int height, bool is_opaque,
return true;
}
-cairo_surface_t* PlatformCanvas::beginPlatformPaint() {
+cairo_t* PlatformCanvas::beginPlatformPaint() {
return getTopPlatformDevice().beginPlatformPaint();
}
diff --git a/skia/ext/platform_device_linux.h b/skia/ext/platform_device_linux.h
index c23a4d8..2a08cc8 100644
--- a/skia/ext/platform_device_linux.h
+++ b/skia/ext/platform_device_linux.h
@@ -7,19 +7,19 @@
#include "third_party/skia/include/core/SkDevice.h"
-typedef struct _cairo_surface cairo_surface_t;
+typedef struct _cairo cairo_t;
namespace skia {
// Blindly copying the mac hierarchy.
class PlatformDevice : public SkDevice {
public:
- typedef cairo_surface_t* PlatformSurface;
+ typedef cairo_t* PlatformSurface;
// Returns if the preferred rendering engine is vectorial or bitmap based.
virtual bool IsVectorial() = 0;
- virtual cairo_surface_t* beginPlatformPaint() = 0;
+ virtual PlatformSurface beginPlatformPaint() = 0;
protected:
// Forwards |bitmap| to SkDevice's constructor.
diff --git a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
index de4a60f..7176642 100644
--- a/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
+++ b/webkit/glue/plugins/webplugin_delegate_impl_gtk.cc
@@ -174,13 +174,13 @@ void WebPluginDelegateImpl::UpdateGeometry(
}
}
-void WebPluginDelegateImpl::Paint(cairo_surface_t* context,
+void WebPluginDelegateImpl::Paint(cairo_t* context,
const gfx::Rect& rect) {
if (windowless_)
WindowlessPaint(context, rect);
}
-void WebPluginDelegateImpl::Print(cairo_surface_t* context) {
+void WebPluginDelegateImpl::Print(cairo_t* context) {
NOTIMPLEMENTED();
}
@@ -399,7 +399,7 @@ void DrawDebugRectangle(cairo_surface_t* surface,
} // namespace
#endif
-void WebPluginDelegateImpl::WindowlessPaint(cairo_surface_t* context,
+void WebPluginDelegateImpl::WindowlessPaint(cairo_t* context,
const gfx::Rect& damage_rect) {
// Compare to:
// http://mxr.mozilla.org/firefox/source/layout/generic/nsObjectFrame.cpp:
@@ -526,7 +526,8 @@ void WebPluginDelegateImpl::WindowlessPaint(cairo_surface_t* context,
// Copy the current image into the pixmap, so the plugin can draw over
// this background.
cairo_t* cairo = gdk_cairo_create(pixmap_);
- cairo_set_source_surface(cairo, context, offset_x, offset_y);
+ cairo_set_source_surface(cairo, cairo_get_target(context),
+ offset_x, offset_y);
cairo_rectangle(cairo, draw_rect.x() + offset_x, draw_rect.y() + offset_y,
draw_rect.width(), draw_rect.height());
cairo_clip(cairo);
@@ -551,13 +552,12 @@ void WebPluginDelegateImpl::WindowlessPaint(cairo_surface_t* context,
DCHECK_EQ(err, NPERR_NO_ERROR);
// Now copy the rendered image pixmap back into the drawing buffer.
- cairo = cairo_create(context);
- gdk_cairo_set_source_pixmap(cairo, pixmap_, -offset_x, -offset_y);
- cairo_rectangle(cairo, draw_rect.x(), draw_rect.y(),
+ gdk_cairo_set_source_pixmap(context, pixmap_, -offset_x, -offset_y);
+ cairo_rectangle(context, draw_rect.x(), draw_rect.y(),
draw_rect.width(), draw_rect.height());
- cairo_clip(cairo);
- cairo_paint(cairo);
- cairo_destroy(cairo);
+ cairo_clip(context);
+ cairo_paint(context);
+ cairo_destroy(context);
#ifdef DEBUG_RECTANGLES
// Draw some debugging rectangles.
diff --git a/webkit/tools/test_shell/webwidget_host_gtk.cc b/webkit/tools/test_shell/webwidget_host_gtk.cc
index 432f661..46b72e3 100644
--- a/webkit/tools/test_shell/webwidget_host_gtk.cc
+++ b/webkit/tools/test_shell/webwidget_host_gtk.cc
@@ -357,11 +357,10 @@ void WebWidgetHost::Paint() {
gdk_window_begin_paint_rect(window, &grect);
// BitBlit to the gdk window.
- skia::PlatformDevice& platdev = canvas_->getTopPlatformDevice();
- skia::BitmapPlatformDevice* const bitdev =
- static_cast<skia::BitmapPlatformDevice*>(&platdev);
+ cairo_t* source_surface = canvas_->beginPlatformPaint();
cairo_t* cairo_drawable = gdk_cairo_create(window);
- cairo_set_source_surface(cairo_drawable, bitdev->surface(), 0, 0);
+ cairo_set_source_surface(cairo_drawable, cairo_get_target(source_surface),
+ 0, 0);
cairo_paint(cairo_drawable);
cairo_destroy(cairo_drawable);