From 6da703c8fb2d7d2def077e48e6122535efb384cc Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 13 Aug 2017 15:48:57 +0800 Subject: [PATCH] reduce GDI objects --- source/detail/mswin/platform_spec.hpp | 34 ----------- source/detail/platform_spec_windows.cpp | 79 +------------------------ source/paint/graphics.cpp | 48 +++++++++++---- 3 files changed, 38 insertions(+), 123 deletions(-) diff --git a/source/detail/mswin/platform_spec.hpp b/source/detail/mswin/platform_spec.hpp index ed4b0d9a..30bc8b84 100644 --- a/source/detail/mswin/platform_spec.hpp +++ b/source/detail/mswin/platform_spec.hpp @@ -100,37 +100,6 @@ namespace detail font_type font; - struct pen_spec - { - HPEN handle; - unsigned color; - int style; - int width; - - void set(HDC context, int style, int width,unsigned color); - }pen; - - struct brush_spec - { - enum t{Solid, HatchBDiagonal}; - - HBRUSH handle; - t style; - unsigned color; - - void set(HDC context, t style, unsigned color); - }brush; - - struct round_region_spec - { - HRGN handle; - nana::rectangle r; - unsigned radius_x; - unsigned radius_y; - - void set(const nana::rectangle& r, unsigned radius_x, unsigned radius_y); - }round_region; - struct string_spec { unsigned tab_length; @@ -148,9 +117,6 @@ namespace detail unsigned get_text_color() const; void set_color(const ::nana::color&); void set_text_color(const ::nana::color&); - - void update_pen(); - void update_brush(); private: unsigned color_{ 0xffffffff }; unsigned text_color_{0xffffffff}; diff --git a/source/detail/platform_spec_windows.cpp b/source/detail/platform_spec_windows.cpp index 4bc09546..a3dc0b2a 100644 --- a/source/detail/platform_spec_windows.cpp +++ b/source/detail/platform_spec_windows.cpp @@ -1,7 +1,7 @@ /** * Platform Specification Implementation * Nana C++ Library(http://www.nanapro.org) - * Copyright(C) 2003-2016 Jinhao(cnjinhao@hotmail.com) + * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -31,18 +31,6 @@ namespace detail { drawable_impl_type::drawable_impl_type() { - pen.handle = nullptr; - pen.color = 0xffffffff; - pen.style = -1; - pen.width = -1; - - brush.handle = nullptr; - brush.style = brush_spec::Solid; - brush.color = 0xffffffff; - - round_region.handle = nullptr; - round_region.radius_x = round_region.radius_y = 0; - string.tab_length = 4; string.tab_pixels = 0; string.whitespace_pixels = 0; @@ -52,9 +40,6 @@ namespace detail { ::DeleteDC(context); ::DeleteObject(pixmap); - ::DeleteObject(pen.handle); - ::DeleteObject(brush.handle); - ::DeleteObject(round_region.handle); } unsigned drawable_impl_type::get_color() const @@ -82,68 +67,6 @@ namespace detail } } - void drawable_impl_type::update_pen() - { - if (pen.color != color_) - { - pen.handle = ::CreatePen(PS_SOLID, 1, NANA_RGB(color_)); - ::DeleteObject(::SelectObject(context, pen.handle)); - pen.color = color_; - } - } - - void drawable_impl_type::update_brush() - { - if (brush.color != color_) - brush.set(context, brush.style, color_); - } - - void drawable_impl_type::pen_spec::set(HDC context, int style, int width, unsigned clr) - { - if (this->color != clr || this->width != width || this->style != style) - { - this->color = clr; - this->width = width; - this->style = style; - this->handle = ::CreatePen(style, width, NANA_RGB(clr)); - ::DeleteObject(::SelectObject(context, this->handle)); - } - } - - void drawable_impl_type::brush_spec::set(HDC context, drawable_impl_type::brush_spec::t style, unsigned rgb) - { - if (this->color != rgb || this->style != style) - { - this->color = rgb; - this->style = style; - switch(style) - { - case brush_spec::HatchBDiagonal: - this->handle = ::CreateHatchBrush(HS_BDIAGONAL, NANA_RGB(rgb)); - break; - case brush_spec::Solid: - default: - this->style = brush_spec::Solid; - this->handle = ::CreateSolidBrush(NANA_RGB(color)); - break; - } - ::DeleteObject(::SelectObject(context, this->handle)); - } - } - - void drawable_impl_type::round_region_spec::set(const nana::rectangle& r, unsigned radius_x, unsigned radius_y) - { - if(this->r != r || this->radius_x != radius_x || this->radius_y != radius_y) - { - if(handle) - ::DeleteObject(this->handle); - this->r = r; - this->radius_x = radius_x; - this->radius_y = radius_y; - handle = ::CreateRoundRectRgn(r.x, r.y, r.x + static_cast(r.width) + 1, r.y + static_cast(r.height) + 1, static_cast(radius_x + 1), static_cast(radius_y + 1)); - } - } - //class platform_spec platform_spec::co_initializer::co_initializer() : ole32_(::LoadLibrary(L"OLE32.DLL")) diff --git a/source/paint/graphics.cpp b/source/paint/graphics.cpp index 7fdadcea..e4f6e78f 100644 --- a/source/paint/graphics.cpp +++ b/source/paint/graphics.cpp @@ -332,7 +332,6 @@ namespace paint dw->context = cdc; dw->pixmap = bmp; ::SetBkMode(cdc, TRANSPARENT); - dw->brush.set(cdc, dw->brush.Solid, 0xFFFFFF); } else { @@ -1075,13 +1074,17 @@ namespace paint { if (!impl_->handle) return; #if defined(NANA_WINDOWS) - impl_->handle->update_pen(); if (pos1 != pos2) { + auto pen = ::CreatePen(PS_SOLID, 1, NANA_RGB(impl_->handle->get_color())); + ::DeleteObject(::SelectObject(impl_->handle->context, pen)); + ::MoveToEx(impl_->handle->context, pos1.x, pos1.y, 0); ::LineTo(impl_->handle->context, pos2.x, pos2.y); + + DeleteObject(pen); } - ::SetPixel(impl_->handle->context, pos2.x, pos2.y, NANA_RGB(impl_->handle->pen.color)); + ::SetPixel(impl_->handle->context, pos2.x, pos2.y, NANA_RGB(impl_->handle->get_color())); #elif defined(NANA_X11) Display* disp = nana::detail::platform_spec::instance().open_display(); impl_->handle->update_color(); @@ -1107,8 +1110,12 @@ namespace paint { if (!impl_->handle) return; #if defined(NANA_WINDOWS) - impl_->handle->update_pen(); + auto pen = ::CreatePen(PS_SOLID, 1, NANA_RGB(impl_->handle->get_color())); + ::DeleteObject(::SelectObject(impl_->handle->context, pen)); + ::LineTo(impl_->handle->context, pos.x, pos.y); + + DeleteObject(pen); #elif defined(NANA_X11) Display* disp = nana::detail::platform_spec::instance().open_display(); impl_->handle->update_color(); @@ -1136,9 +1143,14 @@ namespace paint if (r.width && r.height && impl_->handle && r.right() > 0 && r.bottom() > 0) { #if defined(NANA_WINDOWS) + + auto brush = ::CreateSolidBrush(NANA_RGB(impl_->handle->get_color())); + ::RECT native_r = { r.x, r.y, r.right(), r.bottom()}; - impl_->handle->update_brush(); - (solid ? ::FillRect : ::FrameRect)(impl_->handle->context, &native_r, impl_->handle->brush.handle); + + (solid ? ::FillRect : ::FrameRect)(impl_->handle->context, &native_r, brush); + + ::DeleteObject(brush); #elif defined(NANA_X11) Display* disp = nana::detail::platform_spec::instance().open_display(); impl_->handle->update_color(); @@ -1263,17 +1275,31 @@ namespace paint { #if defined(NANA_WINDOWS) impl_->handle->set_color(clr); + if (solid) { - impl_->handle->update_pen(); - impl_->handle->brush.set(impl_->handle->context, impl_->handle->brush.Solid, solid_clr.px_color().value); + auto pen = ::CreatePen(PS_SOLID, 1, NANA_RGB(impl_->handle->get_color())); + ::DeleteObject(::SelectObject(impl_->handle->context, pen)); + + auto brush = ::CreateSolidBrush(solid_clr.px_color().value); + auto pr_brush = ::SelectObject(impl_->handle->context, brush); + ::RoundRect(impl_->handle->context, r.x, r.y, r.right(), r.bottom(), static_cast(radius_x * 2), static_cast(radius_y * 2)); + + ::DeleteObject(::SelectObject(impl_->handle->context, pr_brush)); + + DeleteObject(pen); } else { - impl_->handle->update_brush(); - impl_->handle->round_region.set(r, radius_x, radius_y); - ::FrameRgn(impl_->handle->context, impl_->handle->round_region.handle, impl_->handle->brush.handle, 1, 1); + auto brush = ::CreateSolidBrush(NANA_RGB(impl_->handle->get_color())); + + auto region = ::CreateRoundRectRgn(r.x, r.y, r.x + static_cast(r.width) + 1, r.y + static_cast(r.height) + 1, static_cast(radius_x + 1), static_cast(radius_y + 1)); + + ::FrameRgn(impl_->handle->context, region, brush, 1, 1); + + ::DeleteObject(region); + ::DeleteObject(brush); } if (impl_->changed == false) impl_->changed = true;