1 // Copyright (c) 2011 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.
5 #ifndef UI_GFX_CANVAS_PAINT_WIN_H_
6 #define UI_GFX_CANVAS_PAINT_WIN_H_
8 #include "skia/ext/platform_canvas.h"
9 #include "ui/gfx/canvas.h"
10 #include "ui/gfx/canvas_paint.h"
11 #include "ui/gfx/size.h"
15 // A class designed to help with WM_PAINT operations on Windows. It will
16 // do BeginPaint/EndPaint on init/destruction, and will create the bitmap and
17 // canvas with the correct size and transform for the dirty rect. The bitmap
18 // will be automatically painted to the screen on destruction.
20 // You MUST call isEmpty before painting to determine if anything needs
21 // painting. Sometimes the dirty rect can actually be empty, and this makes
22 // the bitmap functions we call unhappy. The caller should not paint in this
25 // Therefore, all you need to do is:
27 // gfx::PlatformCanvasPaint canvas(hwnd);
28 // if (!canvas.isEmpty()) {
29 // ... paint to the canvas ...
33 // Note: The created context is always inialized to (0, 0, 0, 0).
34 class UI_EXPORT CanvasSkiaPaint
: public Canvas
{
36 // This constructor assumes the canvas is opaque.
37 explicit CanvasSkiaPaint(HWND hwnd
) : hwnd_(hwnd
), paint_dc_(NULL
),
39 memset(&ps_
, 0, sizeof(ps_
));
43 CanvasSkiaPaint(HWND hwnd
, bool opaque
) : hwnd_(hwnd
), paint_dc_(NULL
),
45 memset(&ps_
, 0, sizeof(ps_
));
49 // Creates a CanvasSkiaPaint for the specified region that paints to the
50 // specified dc. This does NOT do BeginPaint/EndPaint.
51 CanvasSkiaPaint(HDC dc
, bool opaque
, int x
, int y
, int w
, int h
)
55 memset(&ps_
, 0, sizeof(ps_
));
57 ps_
.rcPaint
.right
= x
+ w
;
59 ps_
.rcPaint
.bottom
= y
+ h
;
63 virtual ~CanvasSkiaPaint() {
65 skia::PlatformCanvas
* canvas
= platform_canvas();
66 canvas
->restoreToCount(1);
67 // Commit the drawing to the screen
68 skia::DrawToNativeContext(canvas
, paint_dc_
, ps_
.rcPaint
.left
,
69 ps_
.rcPaint
.top
, NULL
);
72 EndPaint(hwnd_
, &ps_
);
75 // Returns true if the invalid region is empty. The caller should call this
76 // function to determine if anything needs painting.
77 bool isEmpty() const {
78 return ps_
.rcPaint
.right
- ps_
.rcPaint
.left
== 0 ||
79 ps_
.rcPaint
.bottom
- ps_
.rcPaint
.top
== 0;
82 // Use to access the Windows painting parameters, especially useful for
83 // getting the bounding rect for painting: paintstruct().rcPaint
84 const PAINTSTRUCT
& paintStruct() const {
88 // Returns the DC that will be painted to
99 void initPaint(bool opaque
) {
100 paint_dc_
= BeginPaint(hwnd_
, &ps_
);
105 void init(bool opaque
) {
106 // FIXME(brettw) for ClearType, we probably want to expand the bounds of
107 // painting by one pixel so that the boundaries will be correct (ClearType
108 // text can depend on the adjacent pixel). Then we would paint just the
109 // inset pixels to the screen.
110 const int width
= ps_
.rcPaint
.right
- ps_
.rcPaint
.left
;
111 const int height
= ps_
.rcPaint
.bottom
- ps_
.rcPaint
.top
;
113 RecreateBackingCanvas(gfx::Size(width
, height
), ui::SCALE_FACTOR_100P
,
115 skia::PlatformCanvas
* canvas
= platform_canvas();
117 canvas
->clear(SkColorSetARGB(0, 0, 0, 0));
119 // This will bring the canvas into the screen coordinate system for the
121 canvas
->translate(SkIntToScalar(-ps_
.rcPaint
.left
),
122 SkIntToScalar(-ps_
.rcPaint
.top
));
125 // If true, this canvas was created for a BeginPaint.
126 const bool for_paint_
;
128 // Disallow copy and assign.
129 CanvasSkiaPaint(const CanvasSkiaPaint
&);
130 CanvasSkiaPaint
& operator=(const CanvasSkiaPaint
&);
135 #endif // UI_GFX_CANVAS_PAINT_WIN_H_