reduce GDI objects

This commit is contained in:
Jinhao 2017-08-13 15:48:57 +08:00
parent c8bbf03ebf
commit 6da703c8fb
3 changed files with 38 additions and 123 deletions

View File

@ -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};

View File

@ -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<int>(r.width) + 1, r.y + static_cast<int>(r.height) + 1, static_cast<int>(radius_x + 1), static_cast<int>(radius_y + 1));
}
}
//class platform_spec
platform_spec::co_initializer::co_initializer()
: ole32_(::LoadLibrary(L"OLE32.DLL"))

View File

@ -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<int>(radius_x * 2), static_cast<int>(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<int>(r.width) + 1, r.y + static_cast<int>(r.height) + 1, static_cast<int>(radius_x + 1), static_cast<int>(radius_y + 1));
::FrameRgn(impl_->handle->context, region, brush, 1, 1);
::DeleteObject(region);
::DeleteObject(brush);
}
if (impl_->changed == false) impl_->changed = true;