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