canvas_paint_gtk.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/basictypes.h"
6#include "base/compiler_specific.h"
7#include "ui/gfx/canvas.h"
8#include "ui/gfx/canvas_skia_paint.h"
9#include "ui/gfx/rect.h"
10
11namespace gfx {
12
13CanvasSkiaPaint::CanvasSkiaPaint(GdkEventExpose* event)
14    : context_(NULL),
15      window_(event->window),
16      region_(gdk_region_copy(event->region)),
17      composite_alpha_(false) {
18  Init(true);
19}
20
21CanvasSkiaPaint::CanvasSkiaPaint(GdkEventExpose* event, bool opaque)
22    : context_(NULL),
23      window_(event->window),
24      region_(gdk_region_copy(event->region)),
25      composite_alpha_(false) {
26  Init(opaque);
27}
28
29CanvasSkiaPaint::~CanvasSkiaPaint() {
30  if (!is_empty()) {
31    platform_canvas()->restoreToCount(1);
32
33    // Blit the dirty rect to the window.
34    CHECK(window_);
35    cairo_t* cr = gdk_cairo_create(window_);
36    CHECK(cr);
37    if (composite_alpha_)
38      cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
39    cairo_surface_t* source_surface = cairo_get_target(context_);
40    CHECK(source_surface);
41    // Flush cairo's cache of the surface.
42    cairo_surface_mark_dirty(source_surface);
43    GdkRectangle bounds = rectangle();
44    cairo_set_source_surface(cr, source_surface, bounds.x, bounds.y);
45    gdk_cairo_region(cr, region_);
46    cairo_fill(cr);
47    cairo_destroy(cr);
48  }
49
50  gdk_region_destroy(region_);
51}
52
53void CanvasSkiaPaint::Init(bool opaque) {
54  GdkRectangle bounds = rectangle();
55  skia::PlatformCanvas* canvas = platform_canvas();
56  if (!canvas->initialize(bounds.width, bounds.height, opaque, NULL)) {
57    // Cause a deliberate crash;
58    CHECK(false);
59  }
60  // No need to clear the canvas, because cairo automatically performs the
61  // clear.
62
63  // Need to translate so that the dirty region appears at the origin of the
64  // surface.
65  canvas->translate(-SkIntToScalar(bounds.x), -SkIntToScalar(bounds.y));
66
67  context_ = skia::BeginPlatformPaint(canvas);
68}
69
70} // namespace gfx
71
72
73