• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
11 namespace gfx {
12 
13 // CanvasSkiaPaint
14 
CanvasSkiaPaint(GdkEventExpose * event)15 CanvasSkiaPaint::CanvasSkiaPaint(GdkEventExpose* event)
16     : context_(NULL),
17       window_(event->window),
18       region_(gdk_region_copy(event->region)),
19       composite_alpha_(false) {
20   Init(true);
21 }
22 
CanvasSkiaPaint(GdkEventExpose * event,bool opaque)23 CanvasSkiaPaint::CanvasSkiaPaint(GdkEventExpose* event, bool opaque)
24     : context_(NULL),
25       window_(event->window),
26       region_(gdk_region_copy(event->region)),
27       composite_alpha_(false) {
28   Init(opaque);
29 }
30 
~CanvasSkiaPaint()31 CanvasSkiaPaint::~CanvasSkiaPaint() {
32   if (!is_empty()) {
33     platform_canvas()->restoreToCount(1);
34 
35     // Blit the dirty rect to the window.
36     CHECK(window_);
37     cairo_t* cr = gdk_cairo_create(window_);
38     CHECK(cr);
39     if (composite_alpha_)
40       cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
41     cairo_surface_t* source_surface = cairo_get_target(context_);
42     CHECK(source_surface);
43     // Flush cairo's cache of the surface.
44     cairo_surface_mark_dirty(source_surface);
45     GdkRectangle bounds = rectangle();
46     cairo_set_source_surface(cr, source_surface, bounds.x, bounds.y);
47     gdk_cairo_region(cr, region_);
48     cairo_fill(cr);
49     cairo_destroy(cr);
50   }
51 
52   gdk_region_destroy(region_);
53 }
54 
Init(bool opaque)55 void CanvasSkiaPaint::Init(bool opaque) {
56   GdkRectangle bounds = rectangle();
57   RecreateBackingCanvas(Size(bounds.width, bounds.height), 1.0f, opaque);
58 
59   skia::PlatformCanvas* canvas = platform_canvas();
60 
61   // Need to translate so that the dirty region appears at the origin of the
62   // surface.
63   canvas->translate(-SkIntToScalar(bounds.x), -SkIntToScalar(bounds.y));
64 
65   context_ = skia::BeginPlatformPaint(canvas);
66 }
67 
68 // CanvasSkiaPaintCairo
69 
CanvasSkiaPaintCairo(cairo_t * cairo,Size size,bool opaque)70 CanvasSkiaPaintCairo::CanvasSkiaPaintCairo(cairo_t* cairo,
71                                            Size size,
72                                            bool opaque)
73     : context_(NULL),
74       dest_(cairo),
75       size_(size),
76       composite_alpha_(false) {
77   CHECK(dest_);
78   Init(opaque);
79 }
80 
~CanvasSkiaPaintCairo()81 CanvasSkiaPaintCairo::~CanvasSkiaPaintCairo() {
82   if (!is_empty()) {
83     platform_canvas()->restoreToCount(1);
84 
85     // Blit the dirty rect to the window.
86     if (composite_alpha_)
87       cairo_set_operator(dest_, CAIRO_OPERATOR_SOURCE);
88     cairo_surface_t* source_surface = cairo_get_target(context_);
89     CHECK(source_surface);
90     // Flush cairo's cache of the surface.
91     cairo_surface_mark_dirty(source_surface);
92     cairo_set_source_surface(dest_, source_surface, 0, 0);
93     GdkRectangle bounds = {0, 0, size_.width(), size_.height()};
94     gdk_cairo_rectangle(dest_, &bounds);
95     cairo_fill(dest_);
96   }
97 }
98 
Init(bool opaque)99 void CanvasSkiaPaintCairo::Init(bool opaque) {
100   RecreateBackingCanvas(size_, 1.0f, opaque);
101 
102   context_ = skia::BeginPlatformPaint(platform_canvas());
103 }
104 
105 } // namespace gfx
106 
107 
108