summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-04 16:21:25 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-04 16:21:25 +0000
commitd1f72ed6e0c95e8437de2d914a7a97183d4aa443 (patch)
tree14c2ccbd157ff6e373df274b63f9a02bce174721
parent78117b9c3b21847aee5373b3d936bb7213216ce6 (diff)
downloadchromium_src-d1f72ed6e0c95e8437de2d914a7a97183d4aa443.zip
chromium_src-d1f72ed6e0c95e8437de2d914a7a97183d4aa443.tar.gz
chromium_src-d1f72ed6e0c95e8437de2d914a7a97183d4aa443.tar.bz2
Fixes two Linux canvas related bugs.
. The platform paint was allocating at a size bigger than necessary. . ChromeCanvas::DrawStringInt was not taking into account the matrix on the canvas, which means the text could be drawn at the wrong location. BUG=none TEST=none Review URL: http://codereview.chromium.org/99279 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15205 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/common/gfx/chrome_canvas.h11
-rw-r--r--chrome/common/gfx/chrome_canvas_linux.cc16
-rw-r--r--skia/ext/platform_canvas_linux.h13
3 files changed, 33 insertions, 7 deletions
diff --git a/chrome/common/gfx/chrome_canvas.h b/chrome/common/gfx/chrome_canvas.h
index a16f9da..72db8a5 100644
--- a/chrome/common/gfx/chrome_canvas.h
+++ b/chrome/common/gfx/chrome_canvas.h
@@ -19,6 +19,10 @@ namespace gfx {
class Rect;
}
+#if defined(OS_LINUX)
+typedef struct _cairo cairo_t;
+#endif
+
// ChromeCanvas is the SkCanvas used by Views for all painting. It
// provides a handful of methods for the common operations used throughout
// Views. With few exceptions, you should NOT create a ChromeCanvas directly,
@@ -179,6 +183,13 @@ class ChromeCanvas : public skia::PlatformCanvas {
// Extracts a bitmap from the contents of this canvas.
SkBitmap ExtractBitmap();
+#if defined(OS_LINUX)
+ // Applies current matrix on the canvas to the cairo context. This should be
+ // invoked anytime you plan on drawing directly to the cairo context. Be
+ // sure and set the matrix back to the identity when done.
+ void ApplySkiaMatrixToCairoContext(cairo_t* cr);
+#endif
+
// Compute the size required to draw some text with the provided font.
// Attempts to fit the text with the provided width and height. Increases
// height and then width as needed to make the text fit. This method
diff --git a/chrome/common/gfx/chrome_canvas_linux.cc b/chrome/common/gfx/chrome_canvas_linux.cc
index 93a32f7..5f8b430 100644
--- a/chrome/common/gfx/chrome_canvas_linux.cc
+++ b/chrome/common/gfx/chrome_canvas_linux.cc
@@ -58,6 +58,18 @@ void ChromeCanvas::SizeStringInt(const std::wstring& text,
NOTIMPLEMENTED();
}
+void ChromeCanvas::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 ChromeCanvas::DrawStringInt(const std::wstring& text,
const ChromeFont& font,
@@ -65,6 +77,10 @@ void ChromeCanvas::DrawStringInt(const std::wstring& text,
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);
PangoLayout* layout = pango_cairo_create_layout(cr);
cairo_set_source_rgb(cr,
diff --git a/skia/ext/platform_canvas_linux.h b/skia/ext/platform_canvas_linux.h
index 686ad0a..1f237d7 100644
--- a/skia/ext/platform_canvas_linux.h
+++ b/skia/ext/platform_canvas_linux.h
@@ -95,7 +95,7 @@ class CanvasPaintT : public T {
// Blit the dirty rect to the window.
cairo_t* cr = gdk_cairo_create(window_);
- cairo_set_source_surface(cr, surface_, 0.0, 0.0);
+ cairo_set_source_surface(cr, surface_, rectangle_.x, rectangle_.y);
cairo_rectangle(cr, rectangle_.x, rectangle_.y,
rectangle_.width, rectangle_.height);
cairo_fill(cr);
@@ -115,16 +115,15 @@ class CanvasPaintT : public T {
private:
void init(bool opaque) {
- // In order to be most optimal, we could allocate just the damaged rect and
- // set a translation so it's at the origin. However, since that would be
- // ignored when we draw on the cairo surface, this currently won't work.
- // Allocate the minimal bitmap from the origin to damage rect.
- if (!T::initialize(rectangle_.x + rectangle_.width,
- rectangle_.y + rectangle_.height, opaque, NULL)) {
+ if (!T::initialize(rectangle_.width, rectangle_.height, opaque, NULL)) {
// Cause a deliberate crash;
*(char*) 0 = 0;
}
+ // Need to translate so that the dirty region appears at the origin of the
+ // surface.
+ T::translate(-SkIntToScalar(rectangle_.x), -SkIntToScalar(rectangle_.y));
+
surface_ = T::getTopPlatformDevice().beginPlatformPaint();
}