| // Copyright (c) 2012 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. |
| |
| #include "base/basictypes.h" |
| #include "base/compiler_specific.h" |
| #include "ui/gfx/canvas.h" |
| #include "ui/gfx/canvas_skia_paint.h" |
| #include "ui/gfx/rect.h" |
| |
| namespace gfx { |
| |
| // CanvasSkiaPaint |
| |
| CanvasSkiaPaint::CanvasSkiaPaint(GdkEventExpose* event) |
| : context_(NULL), |
| window_(event->window), |
| region_(gdk_region_copy(event->region)), |
| composite_alpha_(false) { |
| Init(true); |
| } |
| |
| CanvasSkiaPaint::CanvasSkiaPaint(GdkEventExpose* event, bool opaque) |
| : context_(NULL), |
| window_(event->window), |
| region_(gdk_region_copy(event->region)), |
| composite_alpha_(false) { |
| Init(opaque); |
| } |
| |
| CanvasSkiaPaint::~CanvasSkiaPaint() { |
| if (!is_empty()) { |
| platform_canvas()->restoreToCount(1); |
| |
| // Blit the dirty rect to the window. |
| CHECK(window_); |
| cairo_t* cr = gdk_cairo_create(window_); |
| CHECK(cr); |
| if (composite_alpha_) |
| cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); |
| cairo_surface_t* source_surface = cairo_get_target(context_); |
| CHECK(source_surface); |
| // Flush cairo's cache of the surface. |
| cairo_surface_mark_dirty(source_surface); |
| GdkRectangle bounds = rectangle(); |
| cairo_set_source_surface(cr, source_surface, bounds.x, bounds.y); |
| gdk_cairo_region(cr, region_); |
| cairo_fill(cr); |
| cairo_destroy(cr); |
| } |
| |
| gdk_region_destroy(region_); |
| } |
| |
| void CanvasSkiaPaint::Init(bool opaque) { |
| GdkRectangle bounds = rectangle(); |
| RecreateBackingCanvas(Size(bounds.width, bounds.height), 1.0f, opaque); |
| |
| skia::PlatformCanvas* canvas = platform_canvas(); |
| |
| // Need to translate so that the dirty region appears at the origin of the |
| // surface. |
| canvas->translate(-SkIntToScalar(bounds.x), -SkIntToScalar(bounds.y)); |
| |
| context_ = skia::BeginPlatformPaint(canvas); |
| } |
| |
| // CanvasSkiaPaintCairo |
| |
| CanvasSkiaPaintCairo::CanvasSkiaPaintCairo(cairo_t* cairo, |
| Size size, |
| bool opaque) |
| : context_(NULL), |
| dest_(cairo), |
| size_(size), |
| composite_alpha_(false) { |
| CHECK(dest_); |
| Init(opaque); |
| } |
| |
| CanvasSkiaPaintCairo::~CanvasSkiaPaintCairo() { |
| if (!is_empty()) { |
| platform_canvas()->restoreToCount(1); |
| |
| // Blit the dirty rect to the window. |
| if (composite_alpha_) |
| cairo_set_operator(dest_, CAIRO_OPERATOR_SOURCE); |
| cairo_surface_t* source_surface = cairo_get_target(context_); |
| CHECK(source_surface); |
| // Flush cairo's cache of the surface. |
| cairo_surface_mark_dirty(source_surface); |
| cairo_set_source_surface(dest_, source_surface, 0, 0); |
| GdkRectangle bounds = {0, 0, size_.width(), size_.height()}; |
| gdk_cairo_rectangle(dest_, &bounds); |
| cairo_fill(dest_); |
| } |
| } |
| |
| void CanvasSkiaPaintCairo::Init(bool opaque) { |
| RecreateBackingCanvas(size_, 1.0f, opaque); |
| |
| context_ = skia::BeginPlatformPaint(platform_canvas()); |
| } |
| |
| } // namespace gfx |
| |
| |