| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2009 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 SKIA_EXT_CANVAS_PAINT_WIN_H_ |
| 6 #define SKIA_EXT_CANVAS_PAINT_WIN_H_ |
| 7 |
| 8 #include "skia/ext/platform_canvas.h" |
| 9 |
| 10 namespace skia { |
| 11 |
| 12 // A class designed to help with WM_PAINT operations on Windows. It will |
| 13 // do BeginPaint/EndPaint on init/destruction, and will create the bitmap and |
| 14 // canvas with the correct size and transform for the dirty rect. The bitmap |
| 15 // will be automatically painted to the screen on destruction. |
| 16 // |
| 17 // You MUST call isEmpty before painting to determine if anything needs |
| 18 // painting. Sometimes the dirty rect can actually be empty, and this makes |
| 19 // the bitmap functions we call unhappy. The caller should not paint in this |
| 20 // case. |
| 21 // |
| 22 // Therefore, all you need to do is: |
| 23 // case WM_PAINT: { |
| 24 // gfx::PlatformCanvasPaint canvas(hwnd); |
| 25 // if (!canvas.isEmpty()) { |
| 26 // ... paint to the canvas ... |
| 27 // } |
| 28 // return 0; |
| 29 // } |
| 30 template <class T> |
| 31 class CanvasPaintT : public T { |
| 32 public: |
| 33 // This constructor assumes the canvas is opaque. |
| 34 explicit CanvasPaintT(HWND hwnd) : hwnd_(hwnd), paint_dc_(NULL), |
| 35 for_paint_(true) { |
| 36 memset(&ps_, 0, sizeof(ps_)); |
| 37 initPaint(true); |
| 38 } |
| 39 |
| 40 CanvasPaintT(HWND hwnd, bool opaque) : hwnd_(hwnd), paint_dc_(NULL), |
| 41 for_paint_(true) { |
| 42 memset(&ps_, 0, sizeof(ps_)); |
| 43 initPaint(opaque); |
| 44 } |
| 45 |
| 46 // Creates a CanvasPaintT for the specified region that paints to the |
| 47 // specified dc. This does NOT do BeginPaint/EndPaint. |
| 48 CanvasPaintT(HDC dc, bool opaque, int x, int y, int w, int h) |
| 49 : hwnd_(NULL), |
| 50 paint_dc_(dc), |
| 51 for_paint_(false) { |
| 52 memset(&ps_, 0, sizeof(ps_)); |
| 53 ps_.rcPaint.left = x; |
| 54 ps_.rcPaint.right = x + w; |
| 55 ps_.rcPaint.top = y; |
| 56 ps_.rcPaint.bottom = y + h; |
| 57 init(opaque); |
| 58 } |
| 59 |
| 60 virtual ~CanvasPaintT() { |
| 61 if (!isEmpty()) { |
| 62 restoreToCount(1); |
| 63 // Commit the drawing to the screen |
| 64 getTopPlatformDevice().drawToHDC(paint_dc_, |
| 65 ps_.rcPaint.left, ps_.rcPaint.top, |
| 66 NULL); |
| 67 } |
| 68 if (for_paint_) |
| 69 EndPaint(hwnd_, &ps_); |
| 70 } |
| 71 |
| 72 // Returns true if the invalid region is empty. The caller should call this |
| 73 // function to determine if anything needs painting. |
| 74 bool isEmpty() const { |
| 75 return ps_.rcPaint.right - ps_.rcPaint.left == 0 || |
| 76 ps_.rcPaint.bottom - ps_.rcPaint.top == 0; |
| 77 } |
| 78 |
| 79 // Use to access the Windows painting parameters, especially useful for |
| 80 // getting the bounding rect for painting: paintstruct().rcPaint |
| 81 const PAINTSTRUCT& paintStruct() const { |
| 82 return ps_; |
| 83 } |
| 84 |
| 85 // Returns the DC that will be painted to |
| 86 HDC paintDC() const { |
| 87 return paint_dc_; |
| 88 } |
| 89 |
| 90 protected: |
| 91 HWND hwnd_; |
| 92 HDC paint_dc_; |
| 93 PAINTSTRUCT ps_; |
| 94 |
| 95 private: |
| 96 void initPaint(bool opaque) { |
| 97 paint_dc_ = BeginPaint(hwnd_, &ps_); |
| 98 |
| 99 init(opaque); |
| 100 } |
| 101 |
| 102 void init(bool opaque) { |
| 103 // FIXME(brettw) for ClearType, we probably want to expand the bounds of |
| 104 // painting by one pixel so that the boundaries will be correct (ClearType |
| 105 // text can depend on the adjacent pixel). Then we would paint just the |
| 106 // inset pixels to the screen. |
| 107 const int width = ps_.rcPaint.right - ps_.rcPaint.left; |
| 108 const int height = ps_.rcPaint.bottom - ps_.rcPaint.top; |
| 109 if (!initialize(width, height, opaque, NULL)) { |
| 110 // Cause a deliberate crash; |
| 111 *(char*) 0 = 0; |
| 112 } |
| 113 |
| 114 // This will bring the canvas into the screen coordinate system for the |
| 115 // dirty rect |
| 116 translate(SkIntToScalar(-ps_.rcPaint.left), |
| 117 SkIntToScalar(-ps_.rcPaint.top)); |
| 118 } |
| 119 |
| 120 // If true, this canvas was created for a BeginPaint. |
| 121 const bool for_paint_; |
| 122 |
| 123 // Disallow copy and assign. |
| 124 CanvasPaintT(const CanvasPaintT&); |
| 125 CanvasPaintT& operator=(const CanvasPaintT&); |
| 126 }; |
| 127 |
| 128 typedef CanvasPaintT<PlatformCanvas> PlatformCanvasPaint; |
| 129 |
| 130 } // namespace skia |
| 131 |
| 132 #endif // SKIA_EXT_CANVAS_PAINT_WIN_H_ |
| OLD | NEW |