diff options
-rw-r--r-- | ui/gfx/canvas_paint_win.cc | 84 | ||||
-rw-r--r-- | ui/gfx/canvas_paint_win.h | 104 | ||||
-rw-r--r-- | ui/ui.gyp | 1 | ||||
-rw-r--r-- | ui/views/widget/native_widget_win.cc | 1 | ||||
-rw-r--r-- | ui/views/win/hwnd_message_handler.cc | 31 |
5 files changed, 86 insertions, 135 deletions
diff --git a/ui/gfx/canvas_paint_win.cc b/ui/gfx/canvas_paint_win.cc index 27898fc..661b297 100644 --- a/ui/gfx/canvas_paint_win.cc +++ b/ui/gfx/canvas_paint_win.cc @@ -8,51 +8,65 @@ #include "ui/gfx/canvas_skia_paint.h" #include "ui/gfx/rect.h" -namespace { - -#if !defined(USE_AURA) -class CanvasPaintWin : public gfx::CanvasPaint, public gfx::CanvasSkiaPaint { - public: - explicit CanvasPaintWin(gfx::NativeView view); - virtual ~CanvasPaintWin(); - - // Overridden from CanvasPaint: - virtual bool IsValid() const OVERRIDE; - virtual gfx::Rect GetInvalidRect() const OVERRIDE; - virtual gfx::Canvas* AsCanvas() OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(CanvasPaintWin); -}; - -CanvasPaintWin::CanvasPaintWin(gfx::NativeView view) - : gfx::CanvasSkiaPaint(view) {} +namespace gfx { -CanvasPaintWin::~CanvasPaintWin() {} +CanvasSkiaPaint::CanvasSkiaPaint(HWND hwnd, HDC dc, const PAINTSTRUCT& ps) + : hwnd_(hwnd), + paint_dc_(dc) { + memset(&ps_, 0, sizeof(ps_)); + ps_.rcPaint.left = ps.rcPaint.left; + ps_.rcPaint.right = ps.rcPaint.right; + ps_.rcPaint.top = ps.rcPaint.top; + ps_.rcPaint.bottom = ps.rcPaint.bottom; + Init(true); +} -bool CanvasPaintWin::IsValid() const { - return isEmpty(); +CanvasSkiaPaint::CanvasSkiaPaint(HDC dc, bool opaque, int x, int y, + int w, int h) + : hwnd_(NULL), + paint_dc_(dc) { + memset(&ps_, 0, sizeof(ps_)); + ps_.rcPaint.left = x; + ps_.rcPaint.right = x + w; + ps_.rcPaint.top = y; + ps_.rcPaint.bottom = y + h; + Init(opaque); } -gfx::Rect CanvasPaintWin::GetInvalidRect() const { - return gfx::Rect(paintStruct().rcPaint); +CanvasSkiaPaint::~CanvasSkiaPaint() { + if (!is_empty()) { + skia::PlatformCanvas* canvas = platform_canvas(); + canvas->restoreToCount(1); + // Commit the drawing to the screen + skia::DrawToNativeContext(canvas, paint_dc_, ps_.rcPaint.left, + ps_.rcPaint.top, NULL); + } } -gfx::Canvas* CanvasPaintWin::AsCanvas() { - return this; +gfx::Rect CanvasSkiaPaint::GetInvalidRect() const { + return gfx::Rect(paint_struct().rcPaint); } -#endif -} // namespace +void CanvasSkiaPaint::Init(bool opaque) { + // FIXME(brettw) for ClearType, we probably want to expand the bounds of + // painting by one pixel so that the boundaries will be correct (ClearType + // text can depend on the adjacent pixel). Then we would paint just the + // inset pixels to the screen. + const int width = ps_.rcPaint.right - ps_.rcPaint.left; + const int height = ps_.rcPaint.bottom - ps_.rcPaint.top; -namespace gfx { + RecreateBackingCanvas(gfx::Size(width, height), + ui::GetScaleFactorFromScale(ui::win::GetDeviceScaleFactor()), + opaque); + skia::PlatformCanvas* canvas = platform_canvas(); + + canvas->clear(SkColorSetARGB(0, 0, 0, 0)); -CanvasPaint* CanvasPaint::CreateCanvasPaint(gfx::NativeView view) { -#if !defined(USE_AURA) - return new CanvasPaintWin(view); -#else - return NULL; -#endif + // This will bring the canvas into the screen coordinate system for the + // dirty rect + canvas->translate( + -ps_.rcPaint.left / ui::win::GetDeviceScaleFactor(), + -ps_.rcPaint.top / ui::win::GetDeviceScaleFactor()); } } // namespace gfx diff --git a/ui/gfx/canvas_paint_win.h b/ui/gfx/canvas_paint_win.h index 613641a..d9326e30 100644 --- a/ui/gfx/canvas_paint_win.h +++ b/ui/gfx/canvas_paint_win.h @@ -8,15 +8,13 @@ #include "skia/ext/platform_canvas.h" #include "ui/base/win/dpi.h" #include "ui/gfx/canvas.h" -#include "ui/gfx/canvas_paint.h" #include "ui/gfx/size.h" namespace gfx { -// A class designed to help with WM_PAINT operations on Windows. It will -// do BeginPaint/EndPaint on init/destruction, and will create the bitmap and -// canvas with the correct size and transform for the dirty rect. The bitmap -// will be automatically painted to the screen on destruction. +// A class designed to help with WM_PAINT operations on Windows. It will create +// the bitmap and canvas with the correct size and transform for the dirty rect. +// The bitmap will be automatically painted to the screen on destruction. // // You MUST call isEmpty before painting to determine if anything needs // painting. Sometimes the dirty rect can actually be empty, and this makes @@ -25,112 +23,52 @@ namespace gfx { // // Therefore, all you need to do is: // case WM_PAINT: { -// gfx::PlatformCanvasPaint canvas(hwnd); +// PAINTSTRUCT ps; +// HDC hdc = BeginPaint(hwnd, &ps); +// gfx::CanvasSkiaPaint canvas(hwnd, hdc, ps); // if (!canvas.isEmpty()) { // ... paint to the canvas ... // } +// EndPaint(hwnd, &ps); // return 0; // } // Note: The created context is always inialized to (0, 0, 0, 0). class UI_EXPORT CanvasSkiaPaint : public Canvas { public: // This constructor assumes the canvas is opaque. - explicit CanvasSkiaPaint(HWND hwnd) : hwnd_(hwnd), paint_dc_(NULL), - for_paint_(true) { - memset(&ps_, 0, sizeof(ps_)); - initPaint(true); - } - - CanvasSkiaPaint(HWND hwnd, bool opaque) : hwnd_(hwnd), paint_dc_(NULL), - for_paint_(true) { - memset(&ps_, 0, sizeof(ps_)); - initPaint(opaque); - } + CanvasSkiaPaint(HWND hwnd, HDC dc, const PAINTSTRUCT& ps); + virtual ~CanvasSkiaPaint(); // Creates a CanvasSkiaPaint for the specified region that paints to the - // specified dc. This does NOT do BeginPaint/EndPaint. - CanvasSkiaPaint(HDC dc, bool opaque, int x, int y, int w, int h) - : hwnd_(NULL), - paint_dc_(dc), - for_paint_(false) { - memset(&ps_, 0, sizeof(ps_)); - ps_.rcPaint.left = x; - ps_.rcPaint.right = x + w; - ps_.rcPaint.top = y; - ps_.rcPaint.bottom = y + h; - init(opaque); - } + // specified dc. + CanvasSkiaPaint(HDC dc, bool opaque, int x, int y, int w, int h); - virtual ~CanvasSkiaPaint() { - if (!isEmpty()) { - skia::PlatformCanvas* canvas = platform_canvas(); - canvas->restoreToCount(1); - // Commit the drawing to the screen - skia::DrawToNativeContext(canvas, paint_dc_, ps_.rcPaint.left, - ps_.rcPaint.top, NULL); - } - if (for_paint_) - EndPaint(hwnd_, &ps_); - } + // Returns the rectangle that is invalid. + virtual gfx::Rect GetInvalidRect() const; // Returns true if the invalid region is empty. The caller should call this // function to determine if anything needs painting. - bool isEmpty() const { + bool is_empty() const { return ps_.rcPaint.right - ps_.rcPaint.left == 0 || ps_.rcPaint.bottom - ps_.rcPaint.top == 0; - } + }; // Use to access the Windows painting parameters, especially useful for // getting the bounding rect for painting: paintstruct().rcPaint - const PAINTSTRUCT& paintStruct() const { - return ps_; - } + const PAINTSTRUCT& paint_struct() const { return ps_; } // Returns the DC that will be painted to - HDC paintDC() const { - return paint_dc_; - } + HDC paint_dc() const { return paint_dc_; } + + private: + void Init(bool opaque); - protected: HWND hwnd_; HDC paint_dc_; PAINTSTRUCT ps_; - private: - void initPaint(bool opaque) { - paint_dc_ = BeginPaint(hwnd_, &ps_); - - init(opaque); - } - - void init(bool opaque) { - // FIXME(brettw) for ClearType, we probably want to expand the bounds of - // painting by one pixel so that the boundaries will be correct (ClearType - // text can depend on the adjacent pixel). Then we would paint just the - // inset pixels to the screen. - const int width = ps_.rcPaint.right - ps_.rcPaint.left; - const int height = ps_.rcPaint.bottom - ps_.rcPaint.top; - - RecreateBackingCanvas(gfx::Size(width, height), - ui::GetScaleFactorFromScale(ui::win::GetDeviceScaleFactor()), - opaque); - skia::PlatformCanvas* canvas = platform_canvas(); - - canvas->clear(SkColorSetARGB(0, 0, 0, 0)); - - // This will bring the canvas into the screen coordinate system for the - // dirty rect - canvas->translate( - -ps_.rcPaint.left/ui::win::GetDeviceScaleFactor(), - -ps_.rcPaint.top/ui::win::GetDeviceScaleFactor()); - } - - // If true, this canvas was created for a BeginPaint. - const bool for_paint_; - // Disallow copy and assign. - CanvasSkiaPaint(const CanvasSkiaPaint&); - CanvasSkiaPaint& operator=(const CanvasSkiaPaint&); + DISALLOW_COPY_AND_ASSIGN(CanvasSkiaPaint); }; } // namespace gfx @@ -415,7 +415,6 @@ 'gfx/canvas.h', 'gfx/canvas_android.cc', 'gfx/canvas_mac.mm', - 'gfx/canvas_paint.h', 'gfx/canvas_paint_gtk.h', 'gfx/canvas_paint_mac.h', 'gfx/canvas_paint_win.h', diff --git a/ui/views/widget/native_widget_win.cc b/ui/views/widget/native_widget_win.cc index 1f31349..d6ebdd6 100644 --- a/ui/views/widget/native_widget_win.cc +++ b/ui/views/widget/native_widget_win.cc @@ -29,7 +29,6 @@ #include "ui/base/win/mouse_wheel_util.h" #include "ui/base/win/shell.h" #include "ui/gfx/canvas.h" -#include "ui/gfx/canvas_paint.h" #include "ui/gfx/canvas_skia_paint.h" #include "ui/gfx/path.h" #include "ui/gfx/point_conversions.h" diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc index e766e20..f27ad8c 100644 --- a/ui/views/win/hwnd_message_handler.cc +++ b/ui/views/win/hwnd_message_handler.cc @@ -1858,26 +1858,27 @@ LRESULT HWNDMessageHandler::OnNotify(int w_param, NMHDR* l_param) { } void HWNDMessageHandler::OnPaint(HDC dc) { - RECT dirty_rect; + // Call BeginPaint()/EndPaint() around the paint handling, as that seems + // to do more to actually validate the window's drawing region. This only + // appears to matter for Windows that have the WS_EX_COMPOSITED style set + // but will be valid in general too. + PAINTSTRUCT ps; + HDC display_dc = BeginPaint(hwnd(), &ps); + CHECK(display_dc); + // Try to paint accelerated first. - if (GetUpdateRect(hwnd(), &dirty_rect, FALSE) && - !IsRectEmpty(&dirty_rect)) { - if (delegate_->HandlePaintAccelerated(gfx::Rect(dirty_rect))) { - ValidateRect(hwnd(), NULL); - } else { + if (!IsRectEmpty(&ps.rcPaint) && + !delegate_->HandlePaintAccelerated(gfx::Rect(ps.rcPaint))) { #if defined(USE_AURA) - delegate_->HandlePaint(NULL); + delegate_->HandlePaint(NULL); #else - scoped_ptr<gfx::CanvasPaint> canvas( - gfx::CanvasPaint::CreateCanvasPaint(hwnd())); - delegate_->HandlePaint(canvas->AsCanvas()); + scoped_ptr<gfx::CanvasSkiaPaint> canvas( + new gfx::CanvasSkiaPaint(hwnd(), display_dc, ps)); + delegate_->HandlePaint(canvas.get()); #endif - } - } else { - // TODO(msw): Find a better solution for this crbug.com/93530 workaround. - // Some scenarios otherwise fail to validate minimized app/popup windows. - ValidateRect(hwnd(), NULL); } + + EndPaint(hwnd(), &ps); } LRESULT HWNDMessageHandler::OnReflectedMessage(UINT message, |