| 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 |