OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef BASE_GFX_PLATFORM_CANVAS_WIN_H_ | 5 #ifndef BASE_GFX_PLATFORM_CANVAS_WIN_H_ |
6 #define BASE_GFX_PLATFORM_CANVAS_WIN_H_ | 6 #define BASE_GFX_PLATFORM_CANVAS_WIN_H_ |
7 | 7 |
8 #include "base/gfx/platform_device_win.h" | 8 // TODO(brettw) this file should be removed and the includes changed to this |
9 #include "base/basictypes.h" | 9 // new location. |
10 | 10 #include "webkit/port/platform/graphics/skia/public/PlatformCanvasWin.h" |
11 #include "SkCanvas.h" | |
12 | |
13 namespace gfx { | |
14 | |
15 // This class is a specialization of the regular SkCanvas that is designed to | |
16 // work with a gfx::PlatformDevice to manage platform-specific drawing. It | |
17 // allows using both Skia operations and platform-specific operations. | |
18 class PlatformCanvasWin : public SkCanvas { | |
19 public: | |
20 // Set is_opaque if you are going to erase the bitmap and not use | |
21 // transparency: this will enable some optimizations. The shared_section | |
22 // parameter is passed to gfx::PlatformDevice::create. See it for details. | |
23 // | |
24 // If you use the version with no arguments, you MUST call initialize() | |
25 PlatformCanvasWin(); | |
26 PlatformCanvasWin(int width, int height, bool is_opaque); | |
27 PlatformCanvasWin(int width, int height, bool is_opaque, | |
28 HANDLE shared_section); | |
29 virtual ~PlatformCanvasWin(); | |
30 | |
31 // For two-part init, call if you use the no-argument constructor above. Note | |
32 // that we want this to optionally match the Linux initialize if you only | |
33 // pass 3 arguments, hence the evil default argument. | |
34 bool initialize(int width, int height, bool is_opaque, | |
35 HANDLE shared_section = NULL); | |
36 | |
37 // These calls should surround calls to platform drawing routines, the DC | |
38 // returned by beginPlatformPaint is the DC that can be used to draw into. | |
39 // Call endPlatformPaint when you are done and want to use Skia operations | |
40 // again; this will synchronize the bitmap to Windows. | |
41 virtual HDC beginPlatformPaint(); | |
42 virtual void endPlatformPaint(); | |
43 | |
44 // Returns the platform device pointer of the topmost rect with a non-empty | |
45 // clip. In practice, this is usually either the top layer or nothing, since | |
46 // we usually set the clip to new layers when we make them. | |
47 // | |
48 // If there is no layer that is not all clipped out, this will return a | |
49 // dummy device so callers do not have to check. If you are concerned about | |
50 // performance, check the clip before doing any painting. | |
51 // | |
52 // This is different than SkCanvas' getDevice, because that returns the | |
53 // bottommost device. | |
54 // | |
55 // Danger: the resulting device should not be saved. It will be invalidated | |
56 // by the next call to save() or restore(). | |
57 PlatformDeviceWin& getTopPlatformDevice() const; | |
58 | |
59 protected: | |
60 // Creates a device store for use by the canvas. We override this so that | |
61 // the device is always our own so we know that we can use GDI operations | |
62 // on it. Simply calls into createPlatformDevice(). | |
63 virtual SkDevice* createDevice(SkBitmap::Config, int width, int height, | |
64 bool is_opaque, bool isForLayer); | |
65 | |
66 // Creates a device store for use by the canvas. By default, it creates a | |
67 // BitmapPlatformDeviceWin. Can be overridden to change the object type. | |
68 virtual SkDevice* createPlatformDevice(int width, int height, bool is_opaque, | |
69 HANDLE shared_section); | |
70 | |
71 private: | |
72 // Unimplemented. | |
73 virtual SkDevice* setBitmapDevice(const SkBitmap& bitmap); | |
74 | |
75 DISALLOW_COPY_AND_ASSIGN(PlatformCanvasWin); | |
76 }; | |
77 | |
78 // A class designed to help with WM_PAINT operations on Windows. It will | |
79 // do BeginPaint/EndPaint on init/destruction, and will create the bitmap and | |
80 // canvas with the correct size and transform for the dirty rect. The bitmap | |
81 // will be automatically painted to the screen on destruction. | |
82 // | |
83 // You MUST call isEmpty before painting to determine if anything needs | |
84 // painting. Sometimes the dirty rect can actually be empty, and this makes | |
85 // the bitmap functions we call unhappy. The caller should not paint in this | |
86 // case. | |
87 // | |
88 // Therefore, all you need to do is: | |
89 // case WM_PAINT: { | |
90 // gfx::PlatformCanvasWinPaint canvas(hwnd); | |
91 // if (!canvas.isEmpty()) { | |
92 // ... paint to the canvas ... | |
93 // } | |
94 // return 0; | |
95 // } | |
96 template <class T> | |
97 class CanvasPaintT : public T { | |
98 public: | |
99 CanvasPaintT(HWND hwnd) : hwnd_(hwnd), paint_dc_(NULL), for_paint_(true) { | |
100 memset(&ps_, 0, sizeof(ps_)); | |
101 initPaint(true); | |
102 } | |
103 | |
104 CanvasPaintT(HWND hwnd, bool opaque) : hwnd_(hwnd), paint_dc_(NULL), | |
105 for_paint_(true) { | |
106 memset(&ps_, 0, sizeof(ps_)); | |
107 initPaint(opaque); | |
108 } | |
109 | |
110 // Creates a CanvasPaintT for the specified region that paints to the | |
111 // specified dc. This does NOT do BeginPaint/EndPaint. | |
112 CanvasPaintT(HDC dc, bool opaque, int x, int y, int w, int h) | |
113 : hwnd_(NULL), | |
114 paint_dc_(dc), | |
115 for_paint_(false) { | |
116 memset(&ps_, 0, sizeof(ps_)); | |
117 ps_.rcPaint.left = x; | |
118 ps_.rcPaint.right = x + w; | |
119 ps_.rcPaint.top = y; | |
120 ps_.rcPaint.bottom = y + h; | |
121 init(opaque); | |
122 } | |
123 | |
124 | |
125 virtual ~CanvasPaintT() { | |
126 if (!isEmpty()) { | |
127 restoreToCount(1); | |
128 // Commit the drawing to the screen | |
129 getTopPlatformDevice().drawToHDC(paint_dc_, | |
130 ps_.rcPaint.left, ps_.rcPaint.top, | |
131 NULL); | |
132 } | |
133 if (for_paint_) | |
134 EndPaint(hwnd_, &ps_); | |
135 } | |
136 | |
137 // Returns true if the invalid region is empty. The caller should call this | |
138 // function to determine if anything needs painting. | |
139 bool isEmpty() const { | |
140 return ps_.rcPaint.right - ps_.rcPaint.left == 0 || | |
141 ps_.rcPaint.bottom - ps_.rcPaint.top == 0; | |
142 } | |
143 | |
144 // Use to access the Windows painting parameters, especially useful for | |
145 // getting the bounding rect for painting: paintstruct().rcPaint | |
146 const PAINTSTRUCT& paintStruct() const { | |
147 return ps_; | |
148 } | |
149 | |
150 // Returns the DC that will be painted to | |
151 HDC paintDC() const { | |
152 return paint_dc_; | |
153 } | |
154 | |
155 protected: | |
156 HWND hwnd_; | |
157 HDC paint_dc_; | |
158 PAINTSTRUCT ps_; | |
159 | |
160 private: | |
161 void initPaint(bool opaque) { | |
162 paint_dc_ = BeginPaint(hwnd_, &ps_); | |
163 | |
164 init(opaque); | |
165 } | |
166 | |
167 void init(bool opaque) { | |
168 // FIXME(brettw) for ClearType, we probably want to expand the bounds of | |
169 // painting by one pixel so that the boundaries will be correct (ClearType | |
170 // text can depend on the adjacent pixel). Then we would paint just the | |
171 // inset pixels to the screen. | |
172 const int width = ps_.rcPaint.right - ps_.rcPaint.left; | |
173 const int height = ps_.rcPaint.bottom - ps_.rcPaint.top; | |
174 if (!initialize(width, height, opaque, NULL)) { | |
175 // Cause a deliberate crash; | |
176 *(char*) 0 = 0; | |
177 } | |
178 | |
179 // This will bring the canvas into the screen coordinate system for the | |
180 // dirty rect | |
181 translate(SkIntToScalar(-ps_.rcPaint.left), | |
182 SkIntToScalar(-ps_.rcPaint.top)); | |
183 } | |
184 | |
185 // If true, this canvas was created for a BeginPaint. | |
186 const bool for_paint_; | |
187 | |
188 DISALLOW_COPY_AND_ASSIGN(CanvasPaintT); | |
189 }; | |
190 | |
191 typedef CanvasPaintT<PlatformCanvasWin> PlatformCanvasWinPaint; | |
192 | |
193 } // namespace gfx | |
194 | 11 |
195 #endif // BASE_GFX_PLATFORM_CANVAS_WIN_H_ | 12 #endif // BASE_GFX_PLATFORM_CANVAS_WIN_H_ |
196 | 13 |
OLD | NEW |