From 74c09eb9b35b586a0b4299359a3d07c57b6cf2d8 Mon Sep 17 00:00:00 2001 From: cnjinhao Date: Sun, 14 Dec 2014 10:15:19 +0800 Subject: [PATCH] Defined a new color class The new color class is temporarily named expr_color for experiment. --- include/nana/basic_types.hpp | 87 +++++- .../nana/detail/linux_X11/platform_spec.hpp | 21 +- include/nana/detail/win32/platform_spec.hpp | 14 +- include/nana/gui/basis.hpp | 2 +- include/nana/gui/detail/basic_window.hpp | 12 +- include/nana/gui/detail/effects_renderer.hpp | 6 +- include/nana/gui/element.hpp | 10 +- include/nana/gui/programming_interface.hpp | 20 +- include/nana/gui/widgets/button.hpp | 12 +- include/nana/gui/widgets/listbox.hpp | 20 +- include/nana/gui/widgets/treebox.hpp | 12 +- include/nana/gui/widgets/widget.hpp | 15 +- include/nana/paint/detail/image_bmp.hpp | 122 ++++---- include/nana/paint/detail/image_png.hpp | 32 +- include/nana/paint/detail/image_processor.hpp | 212 ++++++------- .../paint/detail/native_paint_interface.hpp | 10 +- include/nana/paint/gadget.hpp | 3 +- include/nana/paint/graphics.hpp | 18 +- include/nana/paint/pixel_buffer.hpp | 21 +- include/nana/paint/text_renderer.hpp | 2 + source/basic_types.cpp | 118 +++++++ source/detail/linux_X11/platform_spec.cpp | 69 ++++- source/detail/win32/platform_spec.cpp | 38 ++- source/gui/detail/basic_window.cpp | 9 +- source/gui/element.cpp | 61 ++-- source/gui/programming_interface.cpp | 109 ++++++- source/gui/widgets/button.cpp | 92 +++--- source/gui/widgets/checkbox.cpp | 2 +- source/gui/widgets/listbox.cpp | 119 ++++---- source/gui/widgets/menu.cpp | 2 +- source/gui/widgets/treebox.cpp | 62 ++-- source/gui/widgets/widget.cpp | 44 ++- .../paint/detail/native_paint_interface.cpp | 59 ++-- source/paint/gadget.cpp | 67 +++- source/paint/graphics.cpp | 243 +++++++++++++-- source/paint/pixel_buffer.cpp | 287 +++++++++++------- source/paint/text_renderer.cpp | 137 +++++---- 37 files changed, 1495 insertions(+), 674 deletions(-) diff --git a/include/nana/basic_types.hpp b/include/nana/basic_types.hpp index 05088e89..16dcbbdc 100644 --- a/include/nana/basic_types.hpp +++ b/include/nana/basic_types.hpp @@ -103,22 +103,85 @@ namespace nana const color_t null_color = 0xFFFFFFFF; - struct pixel_rgb_t + union pixel_argb_t { - union + struct element_tag { - struct element_tag - { - unsigned int blue:8; - unsigned int green:8; - unsigned int red:8; - unsigned int alpha_channel:8; - }element; - - color_t color; - }u; + unsigned int blue:8; + unsigned int green:8; + unsigned int red:8; + unsigned int alpha_channel:8; + }element; + color_t value; }; + union pixel_rgba_t + { + struct element_tag + { + unsigned int alpha_channel : 8; + unsigned int blue : 8; + unsigned int green : 8; + unsigned int red : 8; + }element; + color_t value; + }; + + using pixel_color_t = pixel_argb_t; + + //http://www.w3.org/TR/2011/REC-css3-color-20110607/ + //4.3. Extended color keywords + enum class colors + { + black = 0x0, + blue = 0x0000FF, + + gray = 0x808080, + green = 0x00FF00, + red = 0xFF0000, + white = 0xFFFFFF, + + button_face_shadow_start = 0xF5F4F2, + button_face_shadow_end = 0xD5D2CA, + button_face = 0xD4D0C8, + dark_border = 0x404040, + gray_border = 0x808080, + highlight = 0x1CC4F7 + }; + + class expr_color + { + public: + expr_color() = default; + expr_color(colors); + expr_color(colors, double alpha); + expr_color(unsigned red, unsigned green, unsigned blue); + expr_color(unsigned red, unsigned green, unsigned blue, double alpha); + + void blend(const expr_color& bgcolor, bool ignore_bgcolor_alpha); + + ///< Blends two colors with the specified alpha, and the alpha values that come with these two colors are both ignored. + void blend(const expr_color& bgcolor, double alpha); + + bool invisible() const; + pixel_argb_t argb() const; + pixel_rgba_t rgba() const; + + const double& r() const; + const double& g() const; + const double& b() const; + const double& a() const; + + bool operator==(const expr_color& other) const; + bool operator!=(const expr_color& other) const; + private: + double r_; + double g_; + double b_; + double a_{ 0.0 }; + }; + + struct rectangle; struct point diff --git a/include/nana/detail/linux_X11/platform_spec.hpp b/include/nana/detail/linux_X11/platform_spec.hpp index f9914ecd..4ce16e22 100644 --- a/include/nana/detail/linux_X11/platform_spec.hpp +++ b/include/nana/detail/linux_X11/platform_spec.hpp @@ -84,11 +84,6 @@ namespace detail { typedef std::shared_ptr font_ptr_t; - drawable_impl_type(); - ~drawable_impl_type(); - - void fgcolor(unsigned color); - Pixmap pixmap; GC context; font_ptr_t font; @@ -104,11 +99,23 @@ namespace detail #if defined(NANA_UNICODE) XftDraw * xftdraw; XftColor xft_fgcolor; - XftColor xft_bgcolor; + //XftColor xft_bgcolor; //deprecated const std::string charset(const nana::string& str, const std::string& strcode); #endif + drawable_impl_type(); + ~drawable_impl_type(); + + void fgcolor(nana::color_t); //deprecated + void set_color(nana::color_t); + void set_text_color(nana::color_t); + + void update_color(); + void update_text_color(); private: - unsigned fgcolor_; + unsigned current_color_{ 0xFFFFFF }; + unsigned color_{ 0xFFFFFFFF }; + unsigned text_color_{ 0xFFFFFFFF }; + #if defined(NANA_UNICODE) struct conv_tag { diff --git a/include/nana/detail/win32/platform_spec.hpp b/include/nana/detail/win32/platform_spec.hpp index cb4be1fd..e10814b3 100644 --- a/include/nana/detail/win32/platform_spec.hpp +++ b/include/nana/detail/win32/platform_spec.hpp @@ -91,8 +91,8 @@ namespace detail HDC context; HBITMAP pixmap; - pixel_rgb_t* pixbuf_ptr; - std::size_t bytes_per_line; + pixel_argb_t* pixbuf_ptr{nullptr}; + std::size_t bytes_per_line{0}; font_ptr_t font; struct pen_spec @@ -136,9 +136,15 @@ namespace detail drawable_impl_type(); ~drawable_impl_type(); - void fgcolor(nana::color_t); + void fgcolor(nana::color_t); //deprecated + void set_color(nana::color_t); + void set_text_color(nana::color_t); + + void update_pen(); + void update_brush(); private: - unsigned fgcolor_; + unsigned color_{ 0xffffffff }; + unsigned text_color_{0xffffffff}; }; class platform_spec diff --git a/include/nana/gui/basis.hpp b/include/nana/gui/basis.hpp index aade6c38..bdaa3a91 100644 --- a/include/nana/gui/basis.hpp +++ b/include/nana/gui/basis.hpp @@ -98,7 +98,7 @@ namespace nana }; }; - namespace color + namespace color //deprecated { enum { diff --git a/include/nana/gui/detail/basic_window.hpp b/include/nana/gui/detail/basic_window.hpp index f84e3692..418d557a 100644 --- a/include/nana/gui/detail/basic_window.hpp +++ b/include/nana/gui/detail/basic_window.hpp @@ -177,10 +177,14 @@ namespace detail struct { - color_t foreground; - color_t background; - color_t active; - }color; + color_t foreground; //deprecated + color_t background; //deprecated + color_t active; //deprecated + + expr_color fgcolor; + expr_color bgcolor; + expr_color activated; + }colors; struct { diff --git a/include/nana/gui/detail/effects_renderer.hpp b/include/nana/gui/detail/effects_renderer.hpp index a3eb42c6..29eb43d4 100644 --- a/include/nana/gui/detail/effects_renderer.hpp +++ b/include/nana/gui/detail/effects_renderer.hpp @@ -110,7 +110,7 @@ namespace nana{ auto graph = wd->root_graph; nana::paint::pixel_buffer pixbuf(graph->handle(), r); - pixel_rgb_t px0, px1, px2, px3; + pixel_argb_t px0, px1, px2, px3; px0 = pixbuf.pixel(0, 0); px1 = pixbuf.pixel(r.width - 1, 0); @@ -120,12 +120,12 @@ namespace nana{ good_r.x = good_r.y = 1; good_r.width = r.width - 2; good_r.height = r.height - 2; - pixbuf.rectangle(good_r, wd->color.active, 0.95, false); + pixbuf.rectangle(good_r, wd->colors.active, 0.95, false); good_r.x = good_r.y = 0; good_r.width = r.width; good_r.height = r.height; - pixbuf.rectangle(good_r, wd->color.active, 0.4, false); + pixbuf.rectangle(good_r, wd->colors.active, 0.4, false); pixbuf.pixel(0, 0, px0); pixbuf.pixel(r.width - 1, 0, px1); diff --git a/include/nana/gui/element.hpp b/include/nana/gui/element.hpp index 121e7ce6..170aefb8 100644 --- a/include/nana/gui/element.hpp +++ b/include/nana/gui/element.hpp @@ -35,7 +35,7 @@ namespace nana virtual ~element_interface() {} - virtual bool draw(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const nana::rectangle&, element_state) = 0; + virtual bool draw(graph_reference, const nana::expr_color& bgcolor, const nana::expr_color& fgcolor, const nana::rectangle&, element_state) = 0; }; class crook_interface @@ -53,7 +53,7 @@ namespace nana virtual ~crook_interface() {} - virtual bool draw(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const nana::rectangle&, element_state, const data&) = 0; + virtual bool draw(graph_reference, const nana::expr_color& bgcolor, const nana::expr_color& fgcolor, const nana::rectangle&, element_state, const data&) = 0; }; class provider @@ -122,7 +122,7 @@ namespace nana void switch_to(const char*); public: //Implement element_interface - bool draw(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const nana::rectangle& r, element_state) override; + bool draw(graph_reference, const nana::expr_color& bgcolor, const nana::expr_color& fgcolor, const nana::rectangle& r, element_state) override; private: element::crook_interface::data data_; element::crook_interface* const * keeper_; @@ -144,7 +144,7 @@ namespace nana void set(const cloneable_element&); void set(const char*); - bool draw(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const nana::rectangle&, element_state); + bool draw(graph_reference, const nana::expr_color& bgcolor, const nana::expr_color& fgcolor, const nana::rectangle&, element_state); private: cloneable_element holder_; element_interface * place_ptr_; @@ -174,7 +174,7 @@ namespace nana void stretch_parts(unsigned left, unsigned top, unsigned right, unsigned bottom); //Implement the methods of element_interface. - virtual bool draw(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const nana::rectangle&, element_state); + virtual bool draw(graph_reference, const nana::expr_color& bgcolor, const nana::expr_color& fgcolor, const nana::rectangle&, element_state); private: struct draw_method; struct draw_image; diff --git a/include/nana/gui/programming_interface.hpp b/include/nana/gui/programming_interface.hpp index 2fcb4b15..bc45110c 100644 --- a/include/nana/gui/programming_interface.hpp +++ b/include/nana/gui/programming_interface.hpp @@ -201,12 +201,20 @@ namespace API void capture_ignore_children(bool ignore); ///< Enables or disables the captured window whether redirects the mouse input to its children if the mouse is over its children. void modal_window(window); ///< Blocks the routine til the specified window is closed. void wait_for(window); - color_t foreground(window); - color_t foreground(window, color_t); - color_t background(window); - color_t background(window, color_t); - color_t active(window); - color_t active(window, color_t); + + color_t foreground(window); //deprecated + color_t foreground(window, color_t); //deprecated + color_t background(window); //deprecated + color_t background(window, color_t); //deprecated + color_t active(window); //deprecated + color_t active(window, color_t); //deprecated + + expr_color fgcolor(window); + expr_color fgcolor(window, const expr_color&); + expr_color bgcolor(window); + expr_color bgcolor(window, const expr_color&); + expr_color activated_color(window); + expr_color activated_color(window, const expr_color&); void create_caret(window, unsigned width, unsigned height); void destroy_caret(window); diff --git a/include/nana/gui/widgets/button.hpp b/include/nana/gui/widgets/button.hpp index f6d67d9b..b2a7ff64 100644 --- a/include/nana/gui/widgets/button.hpp +++ b/include/nana/gui/widgets/button.hpp @@ -53,10 +53,10 @@ namespace nana{ void _m_draw_background(graph_reference); void _m_draw_border(graph_reference); private: - widget* widget_; - paint::graphics* graph_; + widget* wdg_{nullptr}; + paint::graphics* graph_{nullptr}; - element::cite_bground cite_; + element::cite_bground cite_{"button"}; struct attr_tag { @@ -68,8 +68,10 @@ namespace nana{ bool enable_pushed; bool focus_color; paint::image * icon; - color_t bgcolor; - color_t fgcolor; + //color_t bgcolor; //deprecated + //color_t fgcolor; + ::nana::expr_color bgcolor; + ::nana::expr_color fgcolor; }attr_; }; }//end namespace button diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 691e83c5..c481c12b 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -33,10 +33,14 @@ namespace nana { struct format { - ::nana::color_t bgcolor; - ::nana::color_t fgcolor; + //::nana::color_t bgcolor; + //::nana::color_t fgcolor; - format(color_t bgcolor = 0xFF000000, color_t fgcolor = 0xFF000000); + ::nana::expr_color bgcolor; + ::nana::expr_color fgcolor; + + format() = default; + format(const ::nana::expr_color& bgcolor, const ::nana::expr_color& fgcolor); }; using format_ptr = std::unique_ptr < format > ; @@ -49,7 +53,7 @@ namespace nana cell(cell&&); cell(nana::string); cell(nana::string, const format&); - cell(nana::string, color_t bgcolor, color_t fgcolor); + cell(nana::string, const ::nana::expr_color& bgcolor, const ::nana::expr_color& fgcolor); cell& operator=(const cell&); cell& operator=(cell&&); @@ -212,11 +216,11 @@ namespace nana item_proxy & select(bool); bool selected() const; - item_proxy & bgcolor(nana::color_t); - nana::color_t bgcolor() const; + item_proxy & bgcolor(const nana::expr_color&); + nana::expr_color bgcolor() const; - item_proxy& fgcolor(nana::color_t); - nana::color_t fgcolor() const; + item_proxy& fgcolor(const nana::expr_color&); + nana::expr_color fgcolor() const; index_pair pos() const; diff --git a/include/nana/gui/widgets/treebox.hpp b/include/nana/gui/widgets/treebox.hpp index a5235880..c4a768e5 100644 --- a/include/nana/gui/widgets/treebox.hpp +++ b/include/nana/gui/widgets/treebox.hpp @@ -74,11 +74,13 @@ namespace nana virtual ~renderer_interface() {} - virtual void bground(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const compset_interface *) const = 0; - virtual void expander(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const compset_interface *) const = 0; - virtual void crook(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const compset_interface *) const = 0; - virtual void icon(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const compset_interface *) const = 0; - virtual void text(graph_reference, nana::color_t bgcolor, nana::color_t fgcolor, const compset_interface *) const = 0; + virtual void set_color(const nana::expr_color& bgcolor, const nana::expr_color& fgcolor) = 0; + + virtual void bground(graph_reference, const compset_interface *) const = 0; + virtual void expander(graph_reference, const compset_interface *) const = 0; + virtual void crook(graph_reference, const compset_interface *) const = 0; + virtual void icon(graph_reference, const compset_interface *) const = 0; + virtual void text(graph_reference, const compset_interface *) const = 0; }; class item_proxy; diff --git a/include/nana/gui/widgets/widget.hpp b/include/nana/gui/widgets/widget.hpp index ce11aeec..53e10b70 100644 --- a/include/nana/gui/widgets/widget.hpp +++ b/include/nana/gui/widgets/widget.hpp @@ -73,11 +73,16 @@ namespace nana void move(int x, int y); void move(const rectangle&); - void foreground(nana::color_t); + void foreground(nana::color_t); //deprecated nana::color_t foreground() const; void background(nana::color_t); nana::color_t background() const; + void fgcolor(const nana::expr_color&); //deprecated + nana::expr_color fgcolor() const; + void bgcolor(const nana::expr_color&); + nana::expr_color bgcolor() const; + general_events& events() const; void umake_event(event_handle eh) const; ///< Deletes an event callback by a handle. @@ -106,10 +111,10 @@ namespace nana virtual void _m_typeface(const nana::paint::font& font); virtual nana::paint::font _m_typeface() const; - virtual void _m_foreground(nana::color_t); - virtual nana::color_t _m_foreground() const; - virtual void _m_background(nana::color_t); - virtual nana::color_t _m_background() const; + virtual void _m_fgcolor(const nana::expr_color&); + virtual nana::expr_color _m_fgcolor() const; + virtual void _m_bgcolor(const nana::expr_color&); + virtual nana::expr_color _m_bgcolor() const; }; /// Base class of all the classes defined as a widget window. Defaultly a widget_tag diff --git a/include/nana/paint/detail/image_bmp.hpp b/include/nana/paint/detail/image_bmp.hpp index a329628a..e7b27c35 100644 --- a/include/nana/paint/detail/image_bmp.hpp +++ b/include/nana/paint/detail/image_bmp.hpp @@ -102,7 +102,7 @@ namespace nana{ namespace paint pixbuf_.open(info->bmiHeader.biWidth, height_pixels); - pixel_rgb_t * d = pixbuf_.raw_ptr(0); + auto d = pixbuf_.raw_ptr(0); if(16 <= info->bmiHeader.biBitCount) { @@ -110,23 +110,23 @@ namespace nana{ namespace paint } else if(8 == info->bmiHeader.biBitCount) { - const pixel_rgb_t * const lend = d + info->bmiHeader.biWidth * height_pixels; + const auto lend = d + info->bmiHeader.biWidth * height_pixels; if(info->bmiHeader.biHeight < 0) { - const unsigned char* s = bits; + auto s = bits; while(d < lend) { - pixel_rgb_t * d_p = d; - pixel_rgb_t * const dpend = d_p + info->bmiHeader.biWidth; - const unsigned char * s_p = s; + auto d_p = d; + auto dpend = d_p + info->bmiHeader.biWidth; + auto s_p = s; while(d_p != dpend) { rgb_quad & rgb = info->bmiColors[*s_p++]; - d_p->u.element.red = rgb.rgbRed; - d_p->u.element.green = rgb.rgbGreen; - d_p->u.element.blue = rgb.rgbBlue; - d_p->u.element.alpha_channel = rgb.rgbReserved; + d_p->element.red = rgb.rgbRed; + d_p->element.green = rgb.rgbGreen; + d_p->element.blue = rgb.rgbBlue; + d_p->element.alpha_channel = rgb.rgbReserved; ++d_p; } d = dpend; @@ -135,19 +135,19 @@ namespace nana{ namespace paint } else { - const unsigned char* s = bits + bytes_per_line * (height_pixels - 1); + const auto* s = bits + bytes_per_line * (height_pixels - 1); while(d < lend) { - pixel_rgb_t * d_p = d; - pixel_rgb_t * const dpend = d_p + info->bmiHeader.biWidth; - const unsigned char * s_p = s; + auto d_p = d; + auto* const dpend = d_p + info->bmiHeader.biWidth; + const auto * s_p = s; while(d_p != dpend) { rgb_quad & rgb = info->bmiColors[*s_p++]; - d_p->u.element.red = rgb.rgbRed; - d_p->u.element.green = rgb.rgbGreen; - d_p->u.element.blue = rgb.rgbBlue; - d_p->u.element.alpha_channel = rgb.rgbReserved; + d_p->element.red = rgb.rgbRed; + d_p->element.green = rgb.rgbGreen; + d_p->element.blue = rgb.rgbBlue; + d_p->element.alpha_channel = rgb.rgbReserved; ++d_p; } d = dpend; @@ -157,23 +157,23 @@ namespace nana{ namespace paint } else if(4 == info->bmiHeader.biBitCount) { - const pixel_rgb_t * const lend = d + info->bmiHeader.biWidth * height_pixels; + const auto * const lend = d + info->bmiHeader.biWidth * height_pixels; if(info->bmiHeader.biHeight < 0) { const unsigned char* s = bits; while(d < lend) { - pixel_rgb_t * d_p = d; - pixel_rgb_t * const dpend = d_p + info->bmiHeader.biWidth; + auto d_p = d; + auto * const dpend = d_p + info->bmiHeader.biWidth; unsigned index = 0; while(d_p != dpend) { rgb_quad & rgb = info->bmiColors[(index & 1) ? (s[index >> 1] & 0xF) : (s[index >> 1] & 0xF0) >> 4]; - d_p->u.element.red = rgb.rgbRed; - d_p->u.element.green = rgb.rgbGreen; - d_p->u.element.blue = rgb.rgbBlue; - d_p->u.element.alpha_channel = rgb.rgbReserved; + d_p->element.red = rgb.rgbRed; + d_p->element.green = rgb.rgbGreen; + d_p->element.blue = rgb.rgbBlue; + d_p->element.alpha_channel = rgb.rgbReserved; ++d_p; ++index; } @@ -183,21 +183,21 @@ namespace nana{ namespace paint } else { - const unsigned char* s = bits + bytes_per_line * (height_pixels - 1); + const auto* s = bits + bytes_per_line * (height_pixels - 1); while(d < lend) { - pixel_rgb_t * d_p = d; - pixel_rgb_t * const dpend = d_p + info->bmiHeader.biWidth; + auto d_p = d; + auto * const dpend = d_p + info->bmiHeader.biWidth; unsigned index = 0; while(d_p != dpend) { rgb_quad & rgb = info->bmiColors[(index & 1) ? (s[index >> 1] & 0xF) : (s[index >> 1] & 0xF0) >> 4]; - d_p->u.element.red = rgb.rgbRed; - d_p->u.element.green = rgb.rgbGreen; - d_p->u.element.blue = rgb.rgbBlue; - d_p->u.element.alpha_channel = rgb.rgbReserved; + d_p->element.red = rgb.rgbRed; + d_p->element.green = rgb.rgbGreen; + d_p->element.blue = rgb.rgbBlue; + d_p->element.alpha_channel = rgb.rgbReserved; ++d_p; ++index; } @@ -208,24 +208,24 @@ namespace nana{ namespace paint } else if(2 == info->bmiHeader.biBitCount) { - const pixel_rgb_t * const lend = d + info->bmiHeader.biWidth * height_pixels; + const auto * const lend = d + info->bmiHeader.biWidth * height_pixels; if(info->bmiHeader.biHeight < 0) { const unsigned char* s = bits; while(d < lend) { - pixel_rgb_t * d_p = d; - pixel_rgb_t * const dpend = d_p + info->bmiHeader.biWidth; + auto d_p = d; + auto * const dpend = d_p + info->bmiHeader.biWidth; unsigned index = 0; while(d_p != dpend) { unsigned shift = (3 - (index & 0x3)) << 1; // (index % 4) * 2 rgb_quad& rgb = info->bmiColors[(s[index >> 2] & (0x3 << shift))>>shift]; - d_p->u.element.red = rgb.rgbRed; - d_p->u.element.green = rgb.rgbGreen; - d_p->u.element.blue = rgb.rgbBlue; - d_p->u.element.alpha_channel = rgb.rgbReserved; + d_p->element.red = rgb.rgbRed; + d_p->element.green = rgb.rgbGreen; + d_p->element.blue = rgb.rgbBlue; + d_p->element.alpha_channel = rgb.rgbReserved; ++d_p; ++index; } @@ -235,11 +235,11 @@ namespace nana{ namespace paint } else { - const unsigned char* s = bits + bytes_per_line * (height_pixels - 1); + const auto* s = bits + bytes_per_line * (height_pixels - 1); while(d < lend) { - pixel_rgb_t * d_p = d; - pixel_rgb_t * const dpend = d_p + info->bmiHeader.biWidth; + auto d_p = d; + auto * const dpend = d_p + info->bmiHeader.biWidth; unsigned index = 0; while(d_p != dpend) @@ -247,10 +247,10 @@ namespace nana{ namespace paint unsigned shift = (3 - (index & 0x3)) << 1; // (index % 4) * 2 rgb_quad& rgb = info->bmiColors[(s[index >> 2] & (0x3 << shift))>>shift]; - d_p->u.element.red = rgb.rgbRed; - d_p->u.element.green = rgb.rgbGreen; - d_p->u.element.blue = rgb.rgbBlue; - d_p->u.element.alpha_channel = rgb.rgbReserved; + d_p->element.red = rgb.rgbRed; + d_p->element.green = rgb.rgbGreen; + d_p->element.blue = rgb.rgbBlue; + d_p->element.alpha_channel = rgb.rgbReserved; ++d_p; ++index; } @@ -261,24 +261,24 @@ namespace nana{ namespace paint } else if(1 == info->bmiHeader.biBitCount) { - const pixel_rgb_t * const lend = d + info->bmiHeader.biWidth * height_pixels; + const auto * const lend = d + info->bmiHeader.biWidth * height_pixels; if(info->bmiHeader.biHeight < 0) { - const unsigned char* s = bits; + const auto* s = bits; while(d < lend) { - pixel_rgb_t * d_p = d; - pixel_rgb_t * const dpend = d_p + info->bmiHeader.biWidth; + auto d_p = d; + auto * const dpend = d_p + info->bmiHeader.biWidth; unsigned index = 0; while(d_p != dpend) { unsigned bi = (7 - (index & 7)); //(index % 8) rgb_quad & rgb = info->bmiColors[(s[index >> 3] & (1 << bi)) >> bi]; - d_p->u.element.red = rgb.rgbRed; - d_p->u.element.green = rgb.rgbGreen; - d_p->u.element.blue = rgb.rgbBlue; - d_p->u.element.alpha_channel = rgb.rgbReserved; + d_p->element.red = rgb.rgbRed; + d_p->element.green = rgb.rgbGreen; + d_p->element.blue = rgb.rgbBlue; + d_p->element.alpha_channel = rgb.rgbReserved; ++d_p; ++index; } @@ -288,11 +288,11 @@ namespace nana{ namespace paint } else { - const unsigned char* s = bits + bytes_per_line * (height_pixels - 1); + const auto* s = bits + bytes_per_line * (height_pixels - 1); while(d < lend) { - pixel_rgb_t * d_p = d; - pixel_rgb_t * const dpend = d_p + info->bmiHeader.biWidth; + auto d_p = d; + auto * const dpend = d_p + info->bmiHeader.biWidth; unsigned index = 0; while(d_p != dpend) @@ -300,10 +300,10 @@ namespace nana{ namespace paint unsigned bi = (7 - (index & 7)); rgb_quad & rgb = info->bmiColors[(s[index >> 3] & (1 << bi)) >> bi]; - d_p->u.element.red = rgb.rgbRed; - d_p->u.element.green = rgb.rgbGreen; - d_p->u.element.blue = rgb.rgbBlue; - d_p->u.element.alpha_channel = rgb.rgbReserved; + d_p->element.red = rgb.rgbRed; + d_p->element.green = rgb.rgbGreen; + d_p->element.blue = rgb.rgbBlue; + d_p->element.alpha_channel = rgb.rgbReserved; ++d_p; ++index; } diff --git a/include/nana/paint/detail/image_png.hpp b/include/nana/paint/detail/image_png.hpp index ef61df1f..9f54e8ef 100644 --- a/include/nana/paint/detail/image_png.hpp +++ b/include/nana/paint/detail/image_png.hpp @@ -72,7 +72,7 @@ namespace nana const bool is_alpha_enabled = ((PNG_COLOR_MASK_ALPHA & color_type) != 0); pixbuf_.alpha_channel(is_alpha_enabled); - if(is_alpha_enabled && (png_rowbytes == png_width * sizeof(pixel_rgb_t))) + if(is_alpha_enabled && (png_rowbytes == png_width * sizeof(pixel_argb_t))) { for(int i = 0; i < png_height; ++i) row_ptrs[i] = reinterpret_cast(pixbuf_.raw_ptr(i)); @@ -85,9 +85,9 @@ namespace nana auto p = pixbuf_.raw_ptr(i); for (int u = 0; u < png_width; ++u) { - auto t = p[u].u.element.red; - p[u].u.element.red = p[u].u.element.blue; - p[u].u.element.blue = t; + auto t = p[u].element.red; + p[u].element.red = p[u].element.blue; + p[u].element.blue = t; } } } @@ -103,32 +103,32 @@ namespace nana std::size_t png_pixel_bytes = png_rowbytes / png_width; - pixel_rgb_t * rgb_row_ptr = pixbuf_.raw_ptr(0); + pixel_argb_t * rgb_row_ptr = pixbuf_.raw_ptr(0); for(int y = 0; y < png_height; ++y) { png_bytep png_ptr = row_ptrs[y]; - pixel_rgb_t * rgb_end = rgb_row_ptr + png_width; + pixel_argb_t * rgb_end = rgb_row_ptr + png_width; if(is_alpha_enabled) { - for(pixel_rgb_t * i = rgb_row_ptr; i < rgb_end; ++i) + for(pixel_argb_t * i = rgb_row_ptr; i < rgb_end; ++i) { - i->u.element.red = png_ptr[0]; - i->u.element.green = png_ptr[1]; - i->u.element.blue = png_ptr[2]; - i->u.element.alpha_channel = png_ptr[3]; + i->element.red = png_ptr[0]; + i->element.green = png_ptr[1]; + i->element.blue = png_ptr[2]; + i->element.alpha_channel = png_ptr[3]; png_ptr += png_pixel_bytes; } } else { - for(pixel_rgb_t * i = rgb_row_ptr; i < rgb_end; ++i) + for(pixel_argb_t * i = rgb_row_ptr; i < rgb_end; ++i) { - i->u.element.red = png_ptr[0]; - i->u.element.green = png_ptr[1]; - i->u.element.blue = png_ptr[2]; - i->u.element.alpha_channel = 255; + i->element.red = png_ptr[0]; + i->element.green = png_ptr[1]; + i->element.blue = png_ptr[2]; + i->element.alpha_channel = 255; png_ptr += png_pixel_bytes; } } diff --git a/include/nana/paint/detail/image_processor.hpp b/include/nana/paint/detail/image_processor.hpp index 44129682..bd6dc9dc 100644 --- a/include/nana/paint/detail/image_processor.hpp +++ b/include/nana/paint/detail/image_processor.hpp @@ -38,32 +38,32 @@ namespace detail double rate_x = double(r_src.width) / r_dst.width; double rate_y = double(r_src.height) / r_dst.height; - pixel_rgb_t * s_raw_pixbuf = s_pixbuf.raw_ptr(0); + pixel_argb_t * s_raw_pixbuf = s_pixbuf.raw_ptr(0); if(s_pixbuf.alpha_channel()) { for(std::size_t row = 0; row < r_dst.height; ++row) { - const pixel_rgb_t * s_line = pixel_at(s_raw_pixbuf, (static_cast(row * rate_y) + r_src.y) * bytes_per_line); - pixel_rgb_t * i = pixbuf.raw_ptr(r_dst.y + row); + const pixel_argb_t * s_line = pixel_at(s_raw_pixbuf, (static_cast(row * rate_y) + r_src.y) * bytes_per_line); + pixel_argb_t * i = pixbuf.raw_ptr(r_dst.y + row); for(std::size_t x = 0; x < r_dst.width; ++x, ++i) { - const pixel_rgb_t * s = s_line + static_cast(x * rate_x) + r_src.x; - if(0 == s->u.element.alpha_channel) + const pixel_argb_t * s = s_line + static_cast(x * rate_x) + r_src.x; + if(0 == s->element.alpha_channel) continue; - if(s->u.element.alpha_channel != 255) + if(s->element.alpha_channel != 255) { - i->u.element.red = unsigned(i->u.element.red * (255 - s->u.element.alpha_channel) + s->u.element.red * s->u.element.alpha_channel) / 255; - i->u.element.green = unsigned(i->u.element.green * (255 - s->u.element.alpha_channel) + s->u.element.green * s->u.element.alpha_channel) / 255; - i->u.element.blue = unsigned(i->u.element.blue * (255 - s->u.element.alpha_channel) + s->u.element.blue * s->u.element.alpha_channel) / 255; + i->element.red = unsigned(i->element.red * (255 - s->element.alpha_channel) + s->element.red * s->element.alpha_channel) / 255; + i->element.green = unsigned(i->element.green * (255 - s->element.alpha_channel) + s->element.green * s->element.alpha_channel) / 255; + i->element.blue = unsigned(i->element.blue * (255 - s->element.alpha_channel) + s->element.blue * s->element.alpha_channel) / 255; } else { - unsigned alpha_chn = i->u.element.alpha_channel; + unsigned alpha_chn = i->element.alpha_channel; *i = *s; - i->u.element.alpha_channel = alpha_chn; + i->element.alpha_channel = alpha_chn; } } } @@ -72,8 +72,8 @@ namespace detail { for(std::size_t row = 0; row < r_dst.height; ++row) { - const pixel_rgb_t * s_line = pixel_at(s_raw_pixbuf, (static_cast(row * rate_y) + r_src.y) * bytes_per_line); - pixel_rgb_t * i = pixbuf.raw_ptr(r_dst.y + row); + const pixel_argb_t * s_line = pixel_at(s_raw_pixbuf, (static_cast(row * rate_y) + r_src.y) * bytes_per_line); + pixel_argb_t * i = pixbuf.raw_ptr(r_dst.y + row); for(std::size_t x = 0; x < r_dst.width; ++x, ++i) *i = s_line[static_cast(x * rate_x) + r_src.x]; @@ -105,7 +105,7 @@ namespace detail const int right_bound = static_cast(r_src.width) - 1 + r_src.x; - const nana::pixel_rgb_t * s_raw_pixel_buffer = s_pixbuf.raw_ptr(0); + const nana::pixel_argb_t * s_raw_pixel_buffer = s_pixbuf.raw_ptr(0); const int bottom = r_src.y + static_cast(r_src.height - 1); @@ -151,15 +151,15 @@ namespace detail std::size_t iv = static_cast(v * coef); const std::size_t iv_minus_coef = coef - iv; - const nana::pixel_rgb_t * s_line = pixel_at(s_raw_pixel_buffer, sy * s_bytes_per_line); - const nana::pixel_rgb_t * next_s_line = pixel_at(s_line, (sy < bottom ? s_bytes_per_line : 0)); + const nana::pixel_argb_t * s_line = pixel_at(s_raw_pixel_buffer, sy * s_bytes_per_line); + const nana::pixel_argb_t * next_s_line = pixel_at(s_line, (sy < bottom ? s_bytes_per_line : 0)); - nana::pixel_rgb_t col0; - nana::pixel_rgb_t col1; - nana::pixel_rgb_t col2; - nana::pixel_rgb_t col3; + nana::pixel_argb_t col0; + nana::pixel_argb_t col1; + nana::pixel_argb_t col2; + nana::pixel_argb_t col3; - pixel_rgb_t * i = pixbuf.raw_ptr(row + r_dst.y) + r_dst.x; + pixel_argb_t * i = pixbuf.raw_ptr(row + r_dst.y) + r_dst.x; if(is_alpha_channel) { @@ -186,24 +186,24 @@ namespace detail std::size_t coef2 = el.iu * iv_minus_coef; std::size_t coef3 = el.iu * iv; - unsigned alpha_chn = static_cast((coef0 * col0.u.element.alpha_channel + coef1 * col1.u.element.alpha_channel + (coef2 * col2.u.element.alpha_channel + coef3 * col3.u.element.alpha_channel)) >> double_shift_size); - unsigned s_red = static_cast((coef0 * col0.u.element.red + coef1 * col1.u.element.red + (coef2 * col2.u.element.red + coef3 * col3.u.element.red)) >> double_shift_size); - unsigned s_green = static_cast((coef0 * col0.u.element.green + coef1 * col1.u.element.green + (coef2 * col2.u.element.green + coef3 * col3.u.element.green)) >> double_shift_size); - unsigned s_blue = static_cast((coef0 * col0.u.element.blue + coef1 * col1.u.element.blue + (coef2 * col2.u.element.blue + coef3 * col3.u.element.blue)) >> double_shift_size); + unsigned alpha_chn = static_cast((coef0 * col0.element.alpha_channel + coef1 * col1.element.alpha_channel + (coef2 * col2.element.alpha_channel + coef3 * col3.element.alpha_channel)) >> double_shift_size); + unsigned s_red = static_cast((coef0 * col0.element.red + coef1 * col1.element.red + (coef2 * col2.element.red + coef3 * col3.element.red)) >> double_shift_size); + unsigned s_green = static_cast((coef0 * col0.element.green + coef1 * col1.element.green + (coef2 * col2.element.green + coef3 * col3.element.green)) >> double_shift_size); + unsigned s_blue = static_cast((coef0 * col0.element.blue + coef1 * col1.element.blue + (coef2 * col2.element.blue + coef3 * col3.element.blue)) >> double_shift_size); if(alpha_chn) { if(alpha_chn != 255) { - i->u.element.red = unsigned(i->u.element.red * (255 - alpha_chn) + s_red * alpha_chn) / 255; - i->u.element.green = unsigned(i->u.element.green * (255 - alpha_chn) + s_green * alpha_chn) / 255; - i->u.element.blue = unsigned(i->u.element.blue * (255 - alpha_chn) + s_blue * alpha_chn) / 255; + i->element.red = unsigned(i->element.red * (255 - alpha_chn) + s_red * alpha_chn) / 255; + i->element.green = unsigned(i->element.green * (255 - alpha_chn) + s_green * alpha_chn) / 255; + i->element.blue = unsigned(i->element.blue * (255 - alpha_chn) + s_blue * alpha_chn) / 255; } else { - i->u.element.red = s_red; - i->u.element.green = s_green; - i->u.element.blue = s_blue; + i->element.red = s_red; + i->element.green = s_green; + i->element.blue = s_blue; } } } @@ -233,9 +233,9 @@ namespace detail std::size_t coef2 = el.iu * iv_minus_coef; std::size_t coef3 = el.iu * iv; - i->u.element.red = static_cast((coef0 * col0.u.element.red + coef1 * col1.u.element.red + (coef2 * col2.u.element.red + coef3 * col3.u.element.red)) >> double_shift_size); - i->u.element.green = static_cast((coef0 * col0.u.element.green + coef1 * col1.u.element.green + (coef2 * col2.u.element.green + coef3 * col3.u.element.green)) >> double_shift_size); - i->u.element.blue = static_cast((coef0 * col0.u.element.blue + coef1 * col1.u.element.blue + (coef2 * col2.u.element.blue + coef3 * col3.u.element.blue)) >> double_shift_size); + i->element.red = static_cast((coef0 * col0.element.red + coef1 * col1.element.red + (coef2 * col2.element.red + coef3 * col3.element.red)) >> double_shift_size); + i->element.green = static_cast((coef0 * col0.element.green + coef1 * col1.element.green + (coef2 * col2.element.green + coef3 * col3.element.green)) >> double_shift_size); + i->element.blue = static_cast((coef0 * col0.element.blue + coef1 * col1.element.blue + (coef2 * col2.element.blue + coef3 * col3.element.blue)) >> double_shift_size); } } } @@ -250,83 +250,83 @@ namespace detail //process virtual void process(const paint::pixel_buffer& s_pixbuf, const nana::rectangle& s_r, paint::pixel_buffer& d_pixbuf, const nana::point& d_pos) const { - nana::pixel_rgb_t * d_rgb = d_pixbuf.at(d_pos); - nana::pixel_rgb_t * s_rgb = s_pixbuf.raw_ptr(s_r.y) + s_r.x; + auto d_rgb = d_pixbuf.at(d_pos); + auto s_rgb = s_pixbuf.raw_ptr(s_r.y) + s_r.x; if(d_rgb && s_rgb) { const unsigned rest = s_r.width & 0x3; const unsigned length_align4 = s_r.width - rest; - std::size_t d_step_bytes = d_pixbuf.bytes_per_line() - (s_r.width - rest) * sizeof(pixel_rgb_t); - std::size_t s_step_bytes = s_pixbuf.bytes_per_line() - (s_r.width - rest) * sizeof(pixel_rgb_t); + std::size_t d_step_bytes = d_pixbuf.bytes_per_line() - (s_r.width - rest) * sizeof(pixel_argb_t); + std::size_t s_step_bytes = s_pixbuf.bytes_per_line() - (s_r.width - rest) * sizeof(pixel_argb_t); for(unsigned line = 0; line < s_r.height; ++line) { - pixel_rgb_t* end = d_rgb + length_align4; + const auto end = d_rgb + length_align4; for(; d_rgb < end; d_rgb += 4, s_rgb += 4) { //0 - if(s_rgb->u.element.alpha_channel) + if(s_rgb->element.alpha_channel) { - if(s_rgb->u.element.alpha_channel != 255) + if(s_rgb->element.alpha_channel != 255) { - d_rgb->u.element.red = unsigned(d_rgb->u.element.red * (255 - s_rgb[0].u.element.alpha_channel) + s_rgb[0].u.element.red * s_rgb[0].u.element.alpha_channel) / 255; - d_rgb->u.element.green = unsigned(d_rgb->u.element.green * (255 - s_rgb[0].u.element.alpha_channel) + s_rgb[0].u.element.green * s_rgb[0].u.element.alpha_channel) / 255; - d_rgb->u.element.blue = unsigned(d_rgb->u.element.blue * (255 - s_rgb[0].u.element.alpha_channel) + s_rgb[0].u.element.blue * s_rgb[0].u.element.alpha_channel) / 255; + d_rgb->element.red = unsigned(d_rgb->element.red * (255 - s_rgb[0].element.alpha_channel) + s_rgb[0].element.red * s_rgb[0].element.alpha_channel) / 255; + d_rgb->element.green = unsigned(d_rgb->element.green * (255 - s_rgb[0].element.alpha_channel) + s_rgb[0].element.green * s_rgb[0].element.alpha_channel) / 255; + d_rgb->element.blue = unsigned(d_rgb->element.blue * (255 - s_rgb[0].element.alpha_channel) + s_rgb[0].element.blue * s_rgb[0].element.alpha_channel) / 255; } else *d_rgb = *s_rgb; } //1 - if(s_rgb[1].u.element.alpha_channel) + if(s_rgb[1].element.alpha_channel) { - if(s_rgb[1].u.element.alpha_channel != 255) + if(s_rgb[1].element.alpha_channel != 255) { - d_rgb[1].u.element.red = unsigned(d_rgb[1].u.element.red * (255 - s_rgb[1].u.element.alpha_channel) + s_rgb[1].u.element.red * s_rgb[1].u.element.alpha_channel) / 255; - d_rgb[1].u.element.green = unsigned(d_rgb[1].u.element.green * (255 - s_rgb[1].u.element.alpha_channel) + s_rgb[1].u.element.green * s_rgb[1].u.element.alpha_channel) / 255; - d_rgb[1].u.element.blue = unsigned(d_rgb[1].u.element.blue * (255 - s_rgb[1].u.element.alpha_channel) + s_rgb[1].u.element.blue * s_rgb[1].u.element.alpha_channel) / 255; + d_rgb[1].element.red = unsigned(d_rgb[1].element.red * (255 - s_rgb[1].element.alpha_channel) + s_rgb[1].element.red * s_rgb[1].element.alpha_channel) / 255; + d_rgb[1].element.green = unsigned(d_rgb[1].element.green * (255 - s_rgb[1].element.alpha_channel) + s_rgb[1].element.green * s_rgb[1].element.alpha_channel) / 255; + d_rgb[1].element.blue = unsigned(d_rgb[1].element.blue * (255 - s_rgb[1].element.alpha_channel) + s_rgb[1].element.blue * s_rgb[1].element.alpha_channel) / 255; } else d_rgb[1] = s_rgb[1]; } //2 - if(s_rgb[2].u.element.alpha_channel) + if(s_rgb[2].element.alpha_channel) { - if(s_rgb[2].u.element.alpha_channel != 255) + if(s_rgb[2].element.alpha_channel != 255) { - d_rgb[2].u.element.red = unsigned(d_rgb[2].u.element.red * (255 - s_rgb[2].u.element.alpha_channel) + s_rgb[2].u.element.red * s_rgb[2].u.element.alpha_channel) / 255; - d_rgb[2].u.element.green = unsigned(d_rgb[2].u.element.green * (255 - s_rgb[2].u.element.alpha_channel) + s_rgb[2].u.element.green * s_rgb[2].u.element.alpha_channel) / 255; - d_rgb[2].u.element.blue = unsigned(d_rgb[2].u.element.blue * (255 - s_rgb[2].u.element.alpha_channel) + s_rgb[2].u.element.blue * s_rgb[2].u.element.alpha_channel) / 255; + d_rgb[2].element.red = unsigned(d_rgb[2].element.red * (255 - s_rgb[2].element.alpha_channel) + s_rgb[2].element.red * s_rgb[2].element.alpha_channel) / 255; + d_rgb[2].element.green = unsigned(d_rgb[2].element.green * (255 - s_rgb[2].element.alpha_channel) + s_rgb[2].element.green * s_rgb[2].element.alpha_channel) / 255; + d_rgb[2].element.blue = unsigned(d_rgb[2].element.blue * (255 - s_rgb[2].element.alpha_channel) + s_rgb[2].element.blue * s_rgb[2].element.alpha_channel) / 255; } else d_rgb[2] = s_rgb[2]; } //3 - if(s_rgb[3].u.element.alpha_channel) + if(s_rgb[3].element.alpha_channel) { - if(s_rgb[3].u.element.alpha_channel != 255) + if(s_rgb[3].element.alpha_channel != 255) { - d_rgb[3].u.element.red = unsigned(d_rgb[3].u.element.red * (255 - s_rgb[3].u.element.alpha_channel) + s_rgb[3].u.element.red * s_rgb[3].u.element.alpha_channel) / 255; - d_rgb[3].u.element.green = unsigned(d_rgb[3].u.element.green * (255 - s_rgb[3].u.element.alpha_channel) + s_rgb[3].u.element.green * s_rgb[3].u.element.alpha_channel) / 255; - d_rgb[3].u.element.blue = unsigned(d_rgb[3].u.element.blue * (255 - s_rgb[3].u.element.alpha_channel) + s_rgb[3].u.element.blue * s_rgb[3].u.element.alpha_channel) / 255; + d_rgb[3].element.red = unsigned(d_rgb[3].element.red * (255 - s_rgb[3].element.alpha_channel) + s_rgb[3].element.red * s_rgb[3].element.alpha_channel) / 255; + d_rgb[3].element.green = unsigned(d_rgb[3].element.green * (255 - s_rgb[3].element.alpha_channel) + s_rgb[3].element.green * s_rgb[3].element.alpha_channel) / 255; + d_rgb[3].element.blue = unsigned(d_rgb[3].element.blue * (255 - s_rgb[3].element.alpha_channel) + s_rgb[3].element.blue * s_rgb[3].element.alpha_channel) / 255; } else d_rgb[3] = s_rgb[3]; } } - const pixel_rgb_t * s_end = s_rgb + rest; + const pixel_argb_t * s_end = s_rgb + rest; for(auto i = s_rgb; i != s_end; ++i) { - if(i->u.element.alpha_channel) + if(i->element.alpha_channel) { - if(i->u.element.alpha_channel != 255) + if(i->element.alpha_channel != 255) { - d_rgb[3].u.element.red = unsigned(d_rgb[3].u.element.red * (255 - i->u.element.alpha_channel) + i->u.element.red * i->u.element.alpha_channel) / 255; - d_rgb[3].u.element.green = unsigned(d_rgb[3].u.element.green * (255 - i->u.element.alpha_channel) + i->u.element.green * i->u.element.alpha_channel) / 255; - d_rgb[3].u.element.blue = unsigned(d_rgb[3].u.element.blue * (255 - i->u.element.alpha_channel) + i->u.element.blue * i->u.element.alpha_channel) / 255; + d_rgb[3].element.red = unsigned(d_rgb[3].element.red * (255 - i->element.alpha_channel) + i->element.red * i->element.alpha_channel) / 255; + d_rgb[3].element.green = unsigned(d_rgb[3].element.green * (255 - i->element.alpha_channel) + i->element.green * i->element.alpha_channel) / 255; + d_rgb[3].element.blue = unsigned(d_rgb[3].element.blue * (255 - i->element.alpha_channel) + i->element.blue * i->element.alpha_channel) / 255; } else d_rgb[3] = *i; @@ -347,8 +347,8 @@ namespace detail //process virtual void process(const paint::pixel_buffer& s_pixbuf, const nana::rectangle& s_r, paint::pixel_buffer& d_pixbuf, const nana::point& d_pos, double fade_rate) const { - nana::pixel_rgb_t * d_rgb = d_pixbuf.raw_ptr(d_pos.y) + d_pos.x; - nana::pixel_rgb_t * s_rgb = s_pixbuf.raw_ptr(s_r.y) + s_r.x; + auto d_rgb = d_pixbuf.raw_ptr(d_pos.y) + d_pos.x; + auto s_rgb = s_pixbuf.raw_ptr(s_r.y) + s_r.x; if(d_rgb && s_rgb) { @@ -359,39 +359,39 @@ namespace detail const unsigned rest = s_r.width & 0x3; const unsigned length_align4 = s_r.width - rest; - std::size_t d_step_bytes = d_pixbuf.bytes_per_line() - (s_r.width - rest) * sizeof(pixel_rgb_t); - std::size_t s_step_bytes = s_pixbuf.bytes_per_line() - (s_r.width - rest) * sizeof(pixel_rgb_t); + std::size_t d_step_bytes = d_pixbuf.bytes_per_line() - (s_r.width - rest) * sizeof(pixel_argb_t); + std::size_t s_step_bytes = s_pixbuf.bytes_per_line() - (s_r.width - rest) * sizeof(pixel_argb_t); for(unsigned line = 0; line < s_r.height; ++line) { - pixel_rgb_t* end = d_rgb + length_align4; + const auto end = d_rgb + length_align4; for(; d_rgb < end; d_rgb += 4, s_rgb += 4) { //0 - d_rgb[0].u.element.red = unsigned(d_table[d_rgb[0].u.element.red] + s_table[s_rgb[0].u.element.red]); - d_rgb[0].u.element.green = unsigned(d_table[d_rgb[0].u.element.green] + s_table[s_rgb[0].u.element.green]); - d_rgb[0].u.element.blue = unsigned(d_table[d_rgb[0].u.element.blue] + s_table[s_rgb[0].u.element.blue]); + d_rgb[0].element.red = unsigned(d_table[d_rgb[0].element.red] + s_table[s_rgb[0].element.red]); + d_rgb[0].element.green = unsigned(d_table[d_rgb[0].element.green] + s_table[s_rgb[0].element.green]); + d_rgb[0].element.blue = unsigned(d_table[d_rgb[0].element.blue] + s_table[s_rgb[0].element.blue]); //1 - d_rgb[1].u.element.red = unsigned(d_table[d_rgb[1].u.element.red] + s_table[s_rgb[1].u.element.red]); - d_rgb[1].u.element.green = unsigned(d_table[d_rgb[1].u.element.green] + s_table[s_rgb[1].u.element.green]); - d_rgb[1].u.element.blue = unsigned(d_table[d_rgb[1].u.element.blue] + s_table[s_rgb[1].u.element.blue]); + d_rgb[1].element.red = unsigned(d_table[d_rgb[1].element.red] + s_table[s_rgb[1].element.red]); + d_rgb[1].element.green = unsigned(d_table[d_rgb[1].element.green] + s_table[s_rgb[1].element.green]); + d_rgb[1].element.blue = unsigned(d_table[d_rgb[1].element.blue] + s_table[s_rgb[1].element.blue]); //2 - d_rgb[2].u.element.red = unsigned(d_table[d_rgb[2].u.element.red] + s_table[s_rgb[2].u.element.red]); - d_rgb[2].u.element.green = unsigned(d_table[d_rgb[2].u.element.green] + s_table[s_rgb[2].u.element.green]); - d_rgb[2].u.element.blue = unsigned(d_table[d_rgb[2].u.element.blue] + s_table[s_rgb[2].u.element.blue]); + d_rgb[2].element.red = unsigned(d_table[d_rgb[2].element.red] + s_table[s_rgb[2].element.red]); + d_rgb[2].element.green = unsigned(d_table[d_rgb[2].element.green] + s_table[s_rgb[2].element.green]); + d_rgb[2].element.blue = unsigned(d_table[d_rgb[2].element.blue] + s_table[s_rgb[2].element.blue]); //3 - d_rgb[3].u.element.red = unsigned(d_table[d_rgb[3].u.element.red] + s_table[s_rgb[3].u.element.red]); - d_rgb[3].u.element.green = unsigned(d_table[d_rgb[3].u.element.green] + s_table[s_rgb[3].u.element.green]); - d_rgb[3].u.element.blue = unsigned(d_table[d_rgb[3].u.element.blue] + s_table[s_rgb[3].u.element.blue]); + d_rgb[3].element.red = unsigned(d_table[d_rgb[3].element.red] + s_table[s_rgb[3].element.red]); + d_rgb[3].element.green = unsigned(d_table[d_rgb[3].element.green] + s_table[s_rgb[3].element.green]); + d_rgb[3].element.blue = unsigned(d_table[d_rgb[3].element.blue] + s_table[s_rgb[3].element.blue]); } for(unsigned i = 0; i < rest; ++i) { - d_rgb[i].u.element.red = unsigned(d_table[d_rgb[i].u.element.red] + s_table[s_rgb[i].u.element.red]); - d_rgb[i].u.element.green = unsigned(d_table[d_rgb[i].u.element.green] + s_table[s_rgb[i].u.element.green]); - d_rgb[i].u.element.blue = unsigned(d_table[d_rgb[i].u.element.blue] + s_table[s_rgb[i].u.element.blue]); + d_rgb[i].element.red = unsigned(d_table[d_rgb[i].element.red] + s_table[s_rgb[i].element.red]); + d_rgb[i].element.green = unsigned(d_table[d_rgb[i].element.green] + s_table[s_rgb[i].element.green]); + d_rgb[i].element.blue = unsigned(d_table[d_rgb[i].element.blue] + s_table[s_rgb[i].element.blue]); } d_rgb = pixel_at(d_rgb, d_step_bytes); s_rgb = pixel_at(s_rgb, s_step_bytes); @@ -409,15 +409,15 @@ namespace detail { const std::size_t bytes_pl = pixbuf.bytes_per_line(); unsigned char * fade_table = nullptr; - nana::pixel_rgb_t rgb_imd; + nana::pixel_argb_t rgb_imd; if(fade_rate != 0.0) { fade_table = detail::alloc_fade_table(1 - fade_rate); - rgb_imd.u.color = color; + rgb_imd.value = color; rgb_imd = detail::fade_color_intermedia(rgb_imd, fade_table); } - nana::pixel_rgb_t * i = pixel_at(pixbuf.raw_ptr(0), pos_beg.y * bytes_pl) + pos_beg.x; + auto i = pixel_at(pixbuf.raw_ptr(0), pos_beg.y * bytes_pl) + pos_beg.x; auto delta = pos_end - pos_beg; @@ -432,7 +432,7 @@ namespace detail if(delta.x == delta.y) { - step_bytes += sizeof(pixel_rgb_t); + step_bytes += sizeof(pixel_argb_t); ++delta.x; if(fade_table) @@ -447,7 +447,7 @@ namespace detail { for(int x = 0; x < delta.x; ++x) { - i->u.color = color; + i->value = color; i = pixel_at(i, step_bytes); } } @@ -479,7 +479,7 @@ namespace detail { for(int x = 0; x < delta.x; ++x) { - i->u.color = color; + i->value = color; if(error >= 0) { error -= dx_2; @@ -513,7 +513,7 @@ namespace detail { for (int y = 0; y < delta.y; ++y) { - i->u.color = color; + i->value = color; if(error >= 0) { error -= dy_2; @@ -579,20 +579,20 @@ namespace detail { for(int i = - radius; i <= radius; ++i) { - nana::pixel_rgb_t px = linepix[(i > 0 ? i : 0)]; - sum_r += px.u.element.red; - sum_g += px.u.element.green; - sum_b += px.u.element.blue; + auto px = linepix[(i > 0 ? i : 0)]; + sum_r += px.element.red; + sum_g += px.element.green; + sum_b += px.element.blue; } } else { for(int i = - radius; i <= radius; ++i) { - nana::pixel_rgb_t px = linepix[std::min(wm, (i > 0 ? i : 0))]; - sum_r += px.u.element.red; - sum_g += px.u.element.green; - sum_b += px.u.element.blue; + auto px = linepix[std::min(wm, (i > 0 ? i : 0))]; + sum_r += px.element.red; + sum_g += px.element.green; + sum_b += px.element.blue; } } @@ -608,12 +608,12 @@ namespace detail vmax[x] = std::max(x - radius, 0); } - nana::pixel_rgb_t p1 = linepix[vmin[x]]; - nana::pixel_rgb_t p2 = linepix[vmax[x]]; + auto p1 = linepix[vmin[x]]; + auto p2 = linepix[vmax[x]]; - sum_r += p1.u.element.red - p2.u.element.red; - sum_g += p1.u.element.green - p2.u.element.green; - sum_b += p1.u.element.blue - p2.u.element.blue; + sum_r += p1.element.red - p2.element.red; + sum_g += p1.element.green - p2.element.green; + sum_b += p1.element.blue - p2.element.blue; ++yi; } linepix = pixbuf.raw_ptr(area.y + y) + area.x; @@ -649,7 +649,7 @@ namespace detail for(int y = 0; y < h; ++y) { - linepix->u.color = 0xFF000000 | (dv[sum_r] << 16) | (dv[sum_g] << 8) | dv[sum_b]; + linepix->value = 0xFF000000 | (dv[sum_r] << 16) | (dv[sum_g] << 8) | dv[sum_b]; if(x == 0) { vmin[y] = std::min(y + radius + 1, hm) * w; diff --git a/include/nana/paint/detail/native_paint_interface.hpp b/include/nana/paint/detail/native_paint_interface.hpp index 91f47b4d..424e59fe 100644 --- a/include/nana/paint/detail/native_paint_interface.hpp +++ b/include/nana/paint/detail/native_paint_interface.hpp @@ -25,16 +25,16 @@ namespace detail void free_fade_table(const unsigned char*); //color = bgcolor * fade_rate + fgcolor * (1 - fade_rate); - nana::pixel_rgb_t fade_color(nana::pixel_rgb_t bgcolor, nana::pixel_rgb_t fgcolor, double fade_rate); - nana::pixel_rgb_t fade_color(nana::pixel_rgb_t bgcolor, nana::pixel_rgb_t fgcolor, const unsigned char* const fade_table); - nana::pixel_rgb_t fade_color_intermedia(nana::pixel_rgb_t fgcolor, const unsigned char* fade_table); - nana::pixel_rgb_t fade_color_by_intermedia(nana::pixel_rgb_t bgcolor, nana::pixel_rgb_t fgcolor_intermedia, const unsigned char* const fade_table); + //nana::pixel_color_t fade_color(nana::pixel_color_t bgcolor, nana::pixel_color_t fgcolor, double fade_rate); //deprecated + nana::pixel_color_t fade_color(nana::pixel_color_t bgcolor, nana::pixel_color_t fgcolor, const unsigned char* const fade_table); + nana::pixel_color_t fade_color_intermedia(nana::pixel_color_t fgcolor, const unsigned char* fade_table); + nana::pixel_color_t fade_color_by_intermedia(nana::pixel_color_t bgcolor, nana::pixel_color_t fgcolor_intermedia, const unsigned char* const fade_table); void blend(drawable_type dw, const nana::rectangle& r, nana::color_t, double fade_rate); nana::size raw_text_extent_size(drawable_type, const nana::char_t*, std::size_t len); nana::size text_extent_size(drawable_type, const nana::char_t*, std::size_t len); - void draw_string(drawable_type, int x, int y, const nana::char_t *, std::size_t len); + void draw_string(drawable_type, const nana::point&, const nana::char_t *, std::size_t len); }//end namespace detail }//end namespace paint }//end namespace nana diff --git a/include/nana/paint/gadget.hpp b/include/nana/paint/gadget.hpp index d7e4e3d7..3aab2e44 100644 --- a/include/nana/paint/gadget.hpp +++ b/include/nana/paint/gadget.hpp @@ -28,7 +28,8 @@ namespace gadget void arrow_16_pixels(nana::paint::graphics&, int x, int y, unsigned color, uint32_t style, directions::t direction); void close_16_pixels(nana::paint::graphics&, int x, int y, uint32_t style, uint32_t color); - void cross(nana::paint::graphics&, int x, int y, uint32_t size, uint32_t thickness, nana::color_t color); + void cross(nana::paint::graphics&, int x, int y, uint32_t size, uint32_t thickness, nana::color_t color); //deprecated + void cross(nana::paint::graphics&, int x, int y, uint32_t size, uint32_t thickness, const nana::expr_color&); }//end namespace gadget diff --git a/include/nana/paint/graphics.hpp b/include/nana/paint/graphics.hpp index e1ca70b5..e063e335 100644 --- a/include/nana/paint/graphics.hpp +++ b/include/nana/paint/graphics.hpp @@ -112,7 +112,8 @@ namespace nana void rectangle_line(const ::nana::rectangle&, color_t left, color_t top, color_t right, color_t bottom); void round_rectangle(int x, int y, unsigned width, unsigned height, unsigned radius_x, unsigned radius_y, color_t, bool solid, color_t color_if_solid); void round_rectangle(const ::nana::rectangle&, unsigned radius_x, unsigned radius_y, color_t, bool solid, color_t color_if_solid); - void shadow_rectangle(const ::nana::rectangle&, color_t beg_color, color_t end_color, bool vertical); + + void shadow_rectangle(const ::nana::rectangle&, color_t beg_color, color_t end_color, bool vertical); //deprecated void shadow_rectangle(int x, int y, unsigned width, unsigned height, color_t beg_color, color_t end_color, bool vertical); ///< Draws a width and height rectangle at (x, y) and the color in range of [begin, end] void line(int x1, int y1, int x2, int y2, color_t); ///< Draws a line from point (x1, y1) to point (x2, y2) in the specified color. @@ -151,7 +152,20 @@ namespace nana void release(); void save_as_file(const char*); - static color_t mix(color_t colorX, color_t colorY, double persent); + static color_t mix(color_t colorX, color_t colorY, double persent); //deprecated + + void set_color(const ::nana::expr_color&); + void set_text_color(const ::nana::expr_color&); + + unsigned bidi_string(const nana::point&, const char_t *, std::size_t len); + void string(nana::point, const char_t*, std::size_t len); + void string(const nana::point&, const char_t*); + void string(const nana::point&, const nana::string&); + + void line(const nana::point&, const nana::point&); + void rectangle(const ::nana::rectangle&, bool solid); + + void gradual_rectangle(const ::nana::rectangle&, const ::nana::expr_color& from, const ::nana::expr_color& to, bool vertical); private: std::shared_ptr< ::nana::detail::drawable_impl_type> dwptr_; font font_shadow_; diff --git a/include/nana/paint/pixel_buffer.hpp b/include/nana/paint/pixel_buffer.hpp index 9d9dc7fa..41518bdd 100644 --- a/include/nana/paint/pixel_buffer.hpp +++ b/include/nana/paint/pixel_buffer.hpp @@ -19,14 +19,14 @@ namespace nana{ namespace paint { ///@brief Seek a pixel address by using offset bytes ///@return the specified pixel address - inline pixel_rgb_t * pixel_at(pixel_rgb_t * p, std::size_t bytes) + inline pixel_argb_t * pixel_at(pixel_argb_t * p, std::size_t bytes) { - return reinterpret_cast(reinterpret_cast(p) + bytes); + return reinterpret_cast(reinterpret_cast(p) + bytes); } - inline const pixel_rgb_t * pixel_at(const pixel_rgb_t * p, std::size_t bytes) + inline const pixel_argb_t * pixel_at(const pixel_argb_t * p, std::size_t bytes) { - return reinterpret_cast(reinterpret_cast(p) + bytes); + return reinterpret_cast(reinterpret_cast(p) + bytes); } class pixel_buffer @@ -60,9 +60,9 @@ namespace nana{ namespace paint std::size_t bytes_per_line() const; nana::size size() const; - pixel_rgb_t * at(const point& pos) const; - pixel_rgb_t * raw_ptr(std::size_t row) const; - pixel_rgb_t * operator[](std::size_t row) const; + pixel_argb_t * at(const point& pos) const; + pixel_argb_t * raw_ptr(std::size_t row) const; + pixel_argb_t * operator[](std::size_t row) const; void put(const unsigned char* rawbits, std::size_t width, std::size_t height, std::size_t bits_per_pixel, std::size_t bytes_per_line, bool is_negative); @@ -70,10 +70,11 @@ namespace nana{ namespace paint void line(const nana::point& pos_beg, const nana::point& pos_end, nana::color_t color, double fade_rate); void rectangle(const nana::rectangle&, nana::color_t, double fade_rate, bool solid); - void shadow_rectangle(const nana::rectangle&, nana::color_t beg, nana::color_t end, double fade_rate, bool vertical); + void shadow_rectangle(const nana::rectangle&, nana::color_t beg, nana::color_t end, double fade_rate, bool vertical); //deprecated + void gradual_rectangle(const ::nana::rectangle&, const ::nana::expr_color& from, const ::nana::expr_color& to, double fade_rate, bool vertical); - pixel_rgb_t pixel(int x, int y) const; - void pixel(int x, int y, pixel_rgb_t); + pixel_argb_t pixel(int x, int y) const; + void pixel(int x, int y, pixel_argb_t); void paste(drawable_type, int x, int y) const; void paste(const nana::rectangle& s_r, drawable_type, int x, int y) const; diff --git a/include/nana/paint/text_renderer.hpp b/include/nana/paint/text_renderer.hpp index 7f8ce910..1b488702 100644 --- a/include/nana/paint/text_renderer.hpp +++ b/include/nana/paint/text_renderer.hpp @@ -18,6 +18,8 @@ namespace nana void render(int x, int y, nana::color_t, const nana::char_t*, std::size_t len, unsigned restricted_pixels); nana::size extent_size(int x, int y, const nana::char_t*, std::size_t len, unsigned restricted_pixels) const; + + void render(const nana::point&, const nana::char_t*, std::size_t len, unsigned restricted_pixels, bool omiited); private: graph_reference graph_; align text_align_; diff --git a/source/basic_types.cpp b/source/basic_types.cpp index e4cf6acf..357e7fa4 100644 --- a/source/basic_types.cpp +++ b/source/basic_types.cpp @@ -13,6 +13,124 @@ namespace nana { + //class color + + expr_color::expr_color(colors col) + : expr_color((static_cast(col)& 0xFF0000) >> 16, (static_cast(col)& 0xFF00) >> 8, static_cast(col)& 0xFF) + { + } + + expr_color::expr_color(colors col, double alpha) + : expr_color((static_cast(col)& 0xFF0000) >> 16, (static_cast(col)& 0xFF00) >> 8, static_cast(col)& 0xFF, alpha) + { + } + + expr_color::expr_color(unsigned red, unsigned green, unsigned blue) + : a_(1.0), r_(red), g_(green), b_(blue) + { + } + + expr_color::expr_color(unsigned red, unsigned green, unsigned blue, double alpha) + : a_(alpha), r_(red), g_(green), b_(blue) + { + if (alpha < 0.0) + a_ = 0.0; + else if (alpha > 1.0) + a_ = 1.0; + } + + void expr_color::blend(const expr_color& bgcolor, bool ignore_bgcolor_alpha) + { + if (a_ < 1.0) + { + if (0.0 < a_) + { + if (ignore_bgcolor_alpha || (1.0 == bgcolor.b_)) + { + r_ = r_ * a_ + bgcolor.r_ * (1.0 - a_); + g_ = g_ * a_ + bgcolor.g_ * (1.0 - a_); + b_ = b_ * a_ + bgcolor.b_ * (1.0 - a_); + a_ = 1.0; + } + else + { + r_ = r_ * a_ + bgcolor.r_ * bgcolor.a_ * (1.0 - a_); + g_ = g_ * a_ + bgcolor.g_ * bgcolor.a_ * (1.0 - a_); + b_ = b_ * a_ + bgcolor.b_ * bgcolor.a_ * (1.0 - a_); + a_ = a_ + (bgcolor.a_ * (1.0 - a_)); + } + } + else + { + r_ = bgcolor.r_; + g_ = bgcolor.g_; + b_ = bgcolor.b_; + a_ = (ignore_bgcolor_alpha ? 1.0 : bgcolor.a_); + } + } + } + + void expr_color::blend(const expr_color& bgcolor, double alpha) + { + r_ = r_ * alpha + bgcolor.r_ * (1.0 - alpha); + g_ = g_ * alpha + bgcolor.g_ * (1.0 - alpha); + b_ = b_ * alpha + bgcolor.b_ * (1.0 - alpha); + a_ = 1.0; + } + + bool expr_color::invisible() const + { + return (a_ == 0.0); + } + + pixel_argb_t expr_color::argb() const + { + pixel_argb_t argb; + argb.element.red = static_cast(r_); + argb.element.green = static_cast(g_); + argb.element.blue = static_cast(b_); + argb.element.alpha_channel = static_cast(a_ * 255); + return argb; + } + + pixel_rgba_t expr_color::rgba() const + { + pixel_rgba_t rgba; + rgba.element.red = static_cast(r_); + rgba.element.green = static_cast(g_); + rgba.element.blue = static_cast(b_); + rgba.element.alpha_channel = static_cast(a_ * 255); + return rgba; + } + + const double& expr_color::r() const + { + return r_; + } + const double& expr_color::g() const + { + return g_; + } + const double& expr_color::b() const + { + return b_; + } + + const double& expr_color::a() const + { + return a_; + } + + bool expr_color::operator==(const expr_color& other) const + { + return (r_ == other.r_ && g_ == other.g_ && b_ == other.b_ && a_ == other.a_); + } + bool expr_color::operator!=(const expr_color& other) const + { + return (r_ != other.r_ || g_ == other.g_ || b_ == other.b_ || a_ == other.a_); + } + + //end class color //struct point point::point():x(0), y(0){} point::point(int x, int y):x(x), y(y){} diff --git a/source/detail/linux_X11/platform_spec.cpp b/source/detail/linux_X11/platform_spec.cpp index 38301911..c6b469ba 100644 --- a/source/detail/linux_X11/platform_spec.cpp +++ b/source/detail/linux_X11/platform_spec.cpp @@ -283,7 +283,6 @@ namespace detail }; drawable_impl_type::drawable_impl_type() - : fgcolor_(0xFFFFFFFF) { string.tab_length = 4; string.tab_pixels = 0; @@ -302,14 +301,76 @@ namespace detail #endif } - void drawable_impl_type::fgcolor(unsigned color) + void drawable_impl_type::set_color(nana::color_t col) { - if(color != fgcolor_) + color_ = col; + } + + void drawable_impl_type::set_text_color(nana::color_t col) + { + text_color_ = col; + update_text_color(); + } + + void drawable_impl_type::update_color() + { + if (color_ != current_color_) + { + auto & spec = nana::detail::platform_spec::instance(); + platform_scope_guard lock; + + current_color_ = color_; + auto col = color_; + switch (spec.screen_depth()) + { + case 16: + col = ((((col >> 16) & 0xFF) * 31 / 255) << 11) | + ((((col >> 8) & 0xFF) * 63 / 255) << 5) | + (col & 0xFF) * 31 / 255; + break; + } + ::XSetForeground(spec.open_display(), context, col); + ::XSetBackground(spec.open_display(), context, col); + } + } + + void drawable_impl_type::update_text_color() + { + if (text_color_ != current_color_) + { + auto & spec = nana::detail::platform_spec::instance(); + platform_scope_guard lock; + + current_color_ = text_color_; + auto col = text_color_; + switch (spec.screen_depth()) + { + case 16: + col = ((((col >> 16) & 0xFF) * 31 / 255) << 11) | + ((((col >> 8) & 0xFF) * 63 / 255) << 5) | + (col & 0xFF) * 31 / 255; + break; + } + ::XSetForeground(spec.open_display(), context, col); + ::XSetBackground(spec.open_display(), context, col); + +#if defined(NANA_UNICODE) + xft_fgcolor.color.red = ((0xFF0000 & col) >> 16) * 0x101; + xft_fgcolor.color.green = ((0xFF00 & col) >> 8) * 0x101; + xft_fgcolor.color.blue = (0xFF & col) * 0x101; + xft_fgcolor.color.alpha = 0xFFFF; +#endif + } + } + + void drawable_impl_type::fgcolor(nana::color_t color) + { + if (color != current_color_) { auto & spec = nana::detail::platform_spec::instance(); platform_scope_guard psg; - fgcolor_ = color; + current_color_ = color; switch(spec.screen_depth()) { case 16: diff --git a/source/detail/win32/platform_spec.cpp b/source/detail/win32/platform_spec.cpp index 84ed07d4..bf4dafd2 100644 --- a/source/detail/win32/platform_spec.cpp +++ b/source/detail/win32/platform_spec.cpp @@ -21,17 +21,15 @@ namespace nana namespace detail { drawable_impl_type::drawable_impl_type() - : pixbuf_ptr(nullptr), bytes_per_line(0), - fgcolor_(0xFFFFFFFF) { pen.handle = nullptr; - pen.color = nana::null_color; + pen.color = 0xffffffff; pen.style = -1; pen.width = -1; brush.handle = nullptr; brush.style = brush_spec::Solid; - brush.color = nana::null_color; + brush.color = 0xffffffff; round_region.handle = nullptr; round_region.radius_x = round_region.radius_y = 0; @@ -52,14 +50,40 @@ namespace detail void drawable_impl_type::fgcolor(nana::color_t col) { - if(this->fgcolor_ != col) + set_text_color(col); + } + + void drawable_impl_type::set_color(nana::color_t col) + { + color_ = col; + } + + void drawable_impl_type::set_text_color(nana::color_t col) + { + if(text_color_ != col) { ::SetTextColor(context, NANA_RGB(col)); - fgcolor_ = col; + text_color_ = col; } } - void drawable_impl_type::pen_spec::set(HDC context, int style, int width, nana::color_t color) + 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, nana::color_t color) //deprecated { if(this->color != color || this->width != width || this->style != style) { diff --git a/source/gui/detail/basic_window.cpp b/source/gui/detail/basic_window.cpp index 6487eefb..22480840 100644 --- a/source/gui/detail/basic_window.cpp +++ b/source/gui/detail/basic_window.cpp @@ -347,9 +347,12 @@ namespace nana visible = false; - color.foreground = 0x0; - color.background = nana::color::button_face; - color.active = 0x60C8FD; + colors.foreground = 0x0; //deprecated + colors.background = nana::color::button_face; + colors.active = 0x60C8FD; + colors.fgcolor = ::nana::expr_color(::nana::colors::black); + colors.bgcolor = ::nana::expr_color(static_cast<::nana::colors>(nana::color::button_face)); + colors.activated = ::nana::expr_color(0x60, 0xc8, 0xfd); effect.edge_nimbus = effects::edge_nimbus::none; effect.bground = nullptr; diff --git a/source/gui/element.cpp b/source/gui/element.cpp index e7eb758c..c4d59616 100644 --- a/source/gui/element.cpp +++ b/source/gui/element.cpp @@ -19,7 +19,7 @@ namespace nana class crook : public crook_interface { - bool draw(graph_reference graph, nana::color_t bgcolor, nana::color_t fgcolor, const nana::rectangle& r, element_state es, const data& crook_data) override + bool draw(graph_reference graph, const nana::expr_color& bgcolor, const nana::expr_color& fgcolor, const nana::rectangle& r, element_state es, const data& crook_data) override { if(crook_data.radio) { @@ -129,21 +129,28 @@ namespace nana } else { - const nana::color_t highlighted = 0x5EB6F7; - + //const nana::color_t highlighted = 0x5EB6F7; //deprecated + nana::expr_color highlighted(0x5e, 0xb6, 0xf7); + auto bld_bgcolor = bgcolor; + auto bld_fgcolor = fgcolor; switch(es) { case element_state::hovered: case element_state::focus_hovered: - bgcolor = graph.mix(bgcolor, highlighted, 0.8); - fgcolor = graph.mix(fgcolor, highlighted, 0.8); + bld_bgcolor.blend(highlighted, 0.8); + bld_fgcolor.blend(highlighted, 0.8); + //bgcolor = graph.mix(bgcolor, highlighted, 0.8); //deprecated + //fgcolor = graph.mix(fgcolor, highlighted, 0.8); break; case element_state::pressed: - bgcolor = graph.mix(bgcolor, highlighted, 0.4); - fgcolor = graph.mix(fgcolor, highlighted, 0.4); + bld_bgcolor.blend(highlighted, 0.4); + bld_fgcolor.blend(highlighted, 0.4); + //bgcolor = graph.mix(bgcolor, highlighted, 0.4); //deprecated + //fgcolor = graph.mix(fgcolor, highlighted, 0.4); break; case element_state::disabled: - bgcolor = fgcolor = 0xB2B7BC; + bld_bgcolor = bld_fgcolor = nana::expr_color(0xb2, 0xb7, 0xbc); + //bgcolor = fgcolor = 0xB2B7BC; //deprecated break; default: //Leave things as they are @@ -152,8 +159,11 @@ namespace nana const int x = r.x + 1; const int y = r.y + 1; - graph.rectangle(x, y, 13, 13, fgcolor, false); - graph.rectangle(x + 1, y + 1, 11, 11, bgcolor, true); + graph.set_color(bld_bgcolor); + graph.rectangle(rectangle{ x + 1, y + 1, 11, 11 }, true); + + graph.set_color(bld_fgcolor); + graph.rectangle(rectangle{ x, y, 13, 13 }, false); switch(crook_data.check_state) { @@ -166,19 +176,19 @@ namespace nana { sx++; sy++; - graph.line(sx, sy, sx, sy + 3, fgcolor); + graph.line(point{ sx, sy }, point{ sx, sy + 3 }); } for(int i = 0; i < 4; i++) { sx++; sy--; - graph.line(sx, sy, sx, sy + 3, fgcolor); + graph.line(point{ sx, sy }, point{ sx, sy + 3 }); } } break; case state::partial: - graph.rectangle(x + 2, y + 2, 9, 9, fgcolor, true); + graph.rectangle(rectangle{ x + 2, y + 2, 9, 9 }, true); break; default: break; @@ -191,7 +201,7 @@ namespace nana class menu_crook : public crook_interface { - bool draw(graph_reference graph, nana::color_t, nana::color_t fgcolor, const nana::rectangle& r, element_state es, const data& crook_data) override + bool draw(graph_reference graph, const ::nana::expr_color&, const ::nana::expr_color& fgcolor, const nana::rectangle& r, element_state es, const data& crook_data) override { if(crook_data.check_state == state::unchecked) return true; @@ -228,14 +238,27 @@ namespace nana int x = r.x + (static_cast(r.width) - 16) / 2; int y = r.y + (static_cast(r.height) - 16) / 2; - nana::color_t light = graph.mix(fgcolor, 0xFFFFFF, 0.5); + ::nana::expr_color light(colors::white); + light.blend(fgcolor, 0.5); - graph.line(x + 3, y + 7, x + 6, y + 10, fgcolor); + graph.set_color(fgcolor); + graph.line(point{ x + 3, y + 7 }, point{ x + 6, y + 10 }); + graph.line(point{ x + 7, y + 9 }, point{ x + 12, y + 4 }); + + graph.set_color(light); + graph.line(point{ x + 3, y + 8 }, point{ x + 6, y + 11 }); + graph.line(point{ x + 7, y + 10 }, point{ x + 12, y + 5 }); + graph.line(point{ x + 4, y + 7 }, point{ x + 6, y + 9 }); + graph.line(point{ x + 7, y + 8 }, point{ x + 11, y + 4 }); + //nana::color_t light = graph.mix(fgcolor, 0xFFFFFF, 0.5); //deprecated + /* + graph.line(point{ x + 3, y + 7 }, point{ x + 6, y + 10 }, fgcolor); //deprecated graph.line(x + 7, y + 9, x + 12, y + 4, fgcolor); graph.line(x + 3, y + 8, x + 6, y + 11, light); graph.line(x + 7, y + 10, x + 12, y + 5, light); graph.line(x + 4, y + 7, x + 6, y + 9, light); graph.line(x + 7, y + 8, x + 11, y + 4, light); + */ } return true; } @@ -433,7 +456,7 @@ namespace nana keeper_ = element::provider().keeper_crook(name); } - bool facade::draw(graph_reference graph, nana::color_t bgcol, nana::color_t fgcol, const nana::rectangle& r, element_state es) + bool facade::draw(graph_reference graph, const ::nana::expr_color& bgcol, const ::nana::expr_color& fgcol, const nana::rectangle& r, element_state es) { return (*keeper_)->draw(graph, bgcol, fgcol, r, es, data_); } @@ -470,7 +493,7 @@ namespace nana ref_ptr_ = detail::bedrock::instance().get_element_store().bground(name); } - bool cite_bground::draw(graph_reference dst, nana::color_t bgcolor, nana::color_t fgcolor, const nana::rectangle& r, element_state state) + bool cite_bground::draw(graph_reference dst, const ::nana::expr_color& bgcolor, const ::nana::expr_color& fgcolor, const nana::rectangle& r, element_state state) { if (ref_ptr_ && *ref_ptr_) return (*ref_ptr_)->draw(dst, bgcolor, fgcolor, r, state); @@ -656,7 +679,7 @@ namespace nana } //Implement the methods of bground_interface. - bool bground::draw(graph_reference dst, nana::color_t bgcolor, nana::color_t fgcolor, const nana::rectangle& to_r, element_state state) + bool bground::draw(graph_reference dst, const ::nana::expr_color&, const ::nana::expr_color&, const nana::rectangle& to_r, element_state state) { if (nullptr == method_) return false; diff --git a/source/gui/programming_interface.cpp b/source/gui/programming_interface.cpp index 5830b458..c36e75ca 100644 --- a/source/gui/programming_interface.cpp +++ b/source/gui/programming_interface.cpp @@ -157,7 +157,7 @@ namespace API if(restrict::window_manager.available(iwd)) { iwd->drawer.graphics.make(iwd->dimension.width, iwd->dimension.height); - iwd->drawer.graphics.rectangle(iwd->color.background, true); + iwd->drawer.graphics.rectangle(iwd->colors.background, true); iwd->drawer.attached(wd, dr); iwd->drawer.refresh(); //Always redrawe no matter it is visible or invisible. This can make the graphics data correctly. } @@ -790,24 +790,24 @@ namespace API restrict::bedrock.pump_event(wd, false); } - nana::color_t foreground(window wd) + nana::color_t foreground(window wd) //deprecated { internal_scope_guard lock; if(restrict::window_manager.available(reinterpret_cast(wd))) - return reinterpret_cast(wd)->color.foreground; + return reinterpret_cast(wd)->colors.foreground; return 0; } - color_t foreground(window wd, color_t col) + color_t foreground(window wd, color_t col) //deprecated { auto iwd = reinterpret_cast(wd); internal_scope_guard lock; if(restrict::window_manager.available(iwd)) { - color_t prev = iwd->color.foreground; + color_t prev = iwd->colors.foreground; if(prev != col) { - iwd->color.foreground = col; + iwd->colors.foreground = col; restrict::window_manager.update(iwd, true, false); } return prev; @@ -815,24 +815,24 @@ namespace API return 0; } - color_t background(window wd) + color_t background(window wd) //deprecated { internal_scope_guard lock; if(restrict::window_manager.available(reinterpret_cast(wd))) - return reinterpret_cast(wd)->color.background; + return reinterpret_cast(wd)->colors.background; return 0; } - color_t background(window wd, color_t col) + color_t background(window wd, color_t col) //deprecated { auto iwd = reinterpret_cast(wd); internal_scope_guard lock; if(restrict::window_manager.available(iwd)) { - color_t prev = iwd->color.background; + color_t prev = iwd->colors.background; if(prev != col) { - iwd->color.background = col; + iwd->colors.background = col; restrict::window_manager.update(iwd, true, false); } return prev; @@ -840,24 +840,24 @@ namespace API return 0; } - color_t active(window wd) + color_t active(window wd) //deprecated { internal_scope_guard lock; if(restrict::window_manager.available(reinterpret_cast(wd))) - return reinterpret_cast(wd)->color.active; + return reinterpret_cast(wd)->colors.active; return 0; } - color_t active(window wd, color_t col) + color_t active(window wd, color_t col) //deprecated { auto iwd = reinterpret_cast(wd); internal_scope_guard lock; if(restrict::window_manager.available(iwd)) { - color_t prev = iwd->color.active; + color_t prev = iwd->colors.active; if(prev != col) { - iwd->color.active = col; + iwd->colors.active = col; restrict::window_manager.update(iwd, true, false); } return prev; @@ -866,6 +866,83 @@ namespace API return 0; } + + expr_color fgcolor(window wd) + { + internal_scope_guard lock; + if (restrict::window_manager.available(reinterpret_cast(wd))) + return reinterpret_cast(wd)->colors.fgcolor; + return{}; + } + + expr_color fgcolor(window wd, const expr_color& col) + { + auto iwd = reinterpret_cast(wd); + internal_scope_guard lock; + if (restrict::window_manager.available(iwd)) + { + auto prev = iwd->colors.fgcolor; + if (prev != col) + { + iwd->colors.fgcolor = col; + restrict::window_manager.update(iwd, true, false); + } + return prev; + } + return{}; + } + + expr_color bgcolor(window wd) + { + internal_scope_guard lock; + if (restrict::window_manager.available(reinterpret_cast(wd))) + return reinterpret_cast(wd)->colors.bgcolor; + return{}; + } + + expr_color bgcolor(window wd, const expr_color& col) + { + auto iwd = reinterpret_cast(wd); + internal_scope_guard lock; + if (restrict::window_manager.available(iwd)) + { + auto prev = iwd->colors.bgcolor; + if (prev != col) + { + iwd->colors.bgcolor = col; + restrict::window_manager.update(iwd, true, false); + } + return prev; + } + return{}; + } + + expr_color activated_color(window wd) + { + internal_scope_guard lock; + if (restrict::window_manager.available(reinterpret_cast(wd))) + return reinterpret_cast(wd)->colors.activated; + return{}; + } + + expr_color activated_color(window wd, const expr_color& col) + { + auto iwd = reinterpret_cast(wd); + internal_scope_guard lock; + if (restrict::window_manager.available(iwd)) + { + auto prev = iwd->colors.activated; + if (prev != col) + { + iwd->colors.activated = col; + restrict::window_manager.update(iwd, true, false); + } + return prev; + } + + return{}; + } + void create_caret(window wd, unsigned width, unsigned height) { auto iwd = reinterpret_cast(wd); diff --git a/source/gui/widgets/button.cpp b/source/gui/widgets/button.cpp index 4c106182..f37dc23e 100644 --- a/source/gui/widgets/button.cpp +++ b/source/gui/widgets/button.cpp @@ -20,12 +20,8 @@ namespace nana{ namespace drawerbase //trigger //@brief: draw the button trigger::trigger() - : widget_(nullptr), - graph_(nullptr), - cite_("button") { attr_.e_state = element_state::normal; - attr_.omitted = attr_.focused = attr_.pushed = attr_.enable_pushed = attr_.keep_pressed = false; attr_.focus_color = true; attr_.icon = nullptr; @@ -40,7 +36,7 @@ namespace nana{ namespace drawerbase { graph_ = &graph; - widget_ = &widget; + wdg_ = &widget; window wd = widget; API::tabstop(wd); @@ -61,7 +57,7 @@ namespace nana{ namespace drawerbase attr_.pushed = pshd; if(false == pshd) { - if (API::find_window(API::cursor_position()) == widget_->handle()) + if (API::find_window(API::cursor_position()) == wdg_->handle()) attr_.e_state = element_state::hovered; else attr_.e_state = element_state::normal; @@ -128,13 +124,13 @@ namespace nana{ namespace drawerbase attr_.keep_pressed = true; _m_draw(graph); - API::capture_window(*widget_, true); + API::capture_window(*wdg_, true); API::lazy_refresh(); } void trigger::mouse_up(graph_reference graph, const arg_mouse&) { - API::capture_window(*widget_, false); + API::capture_window(*wdg_, false); attr_.keep_pressed = false; if(attr_.enable_pushed && (false == attr_.pushed)) { @@ -173,7 +169,7 @@ namespace nana{ namespace drawerbase default: return; } - API::move_tabstop(widget_->handle(), ch_tabstop_next); + API::move_tabstop(*wdg_, ch_tabstop_next); } void trigger::focus(graph_reference graph, const arg_focus& arg) @@ -185,7 +181,7 @@ namespace nana{ namespace drawerbase void trigger::_m_draw_title(graph_reference graph, bool enabled) { - nana::string text = widget_->caption(); + nana::string text = wdg_->caption(); nana::string::value_type shortkey; nana::string::size_type shortkey_pos; @@ -201,11 +197,14 @@ namespace nana{ namespace drawerbase icon_sz.width += 5; } - int x = (static_cast(gsize.width - 1 - ts.width) >> 1); - int y = (static_cast(gsize.height - 1 - ts.height) >> 1); + //int x = (static_cast(gsize.width - 1 - ts.width) >> 1); //deprecated + //int y = (static_cast(gsize.height - 1 - ts.height) >> 1); + nana::point pos{ + static_cast(gsize.width - 1 - ts.width) >> 1, static_cast(gsize.height - 1 - ts.height) >> 1 + }; - if(x < static_cast(icon_sz.width)) - x = static_cast(icon_sz.width); + if(pos.x < static_cast(icon_sz.width)) + pos.x = static_cast(icon_sz.width); unsigned omitted_pixels = gsize.width - icon_sz.width; std::size_t txtlen = str.size(); @@ -217,35 +216,53 @@ namespace nana{ namespace drawerbase { if (element_state::pressed == attr_.e_state) { - ++x; - ++y; + ++pos.x; + ++pos.y; } - color_t fgcolor = (attr_.focus_color ? (attr_.focused ? 0xFF : attr_.fgcolor) : attr_.fgcolor); + //color_t fgcolor = (attr_.focus_color ? (attr_.focused ? 0xFF : attr_.fgcolor) : attr_.fgcolor); + auto fgcolor = attr_.fgcolor; + if (attr_.focus_color && attr_.focused) + fgcolor = ::nana::expr_color(colors::blue); + + graph.set_text_color(fgcolor); + + /* if(attr_.omitted) - tr.render(x, y, fgcolor, txtptr, txtlen, omitted_pixels, true); + tr.render(x, y, fgcolor.argb().value, txtptr, txtlen, omitted_pixels, true); //deprecated else graph.bidi_string(x, y, fgcolor, txtptr, txtlen); + */ + + if (attr_.omitted) + tr.render(pos, txtptr, txtlen, omitted_pixels, true); //deprecated + else + graph.bidi_string(pos, txtptr, txtlen); if(shortkey) { unsigned off_w = (shortkey_pos ? graph.text_extent_size(str, static_cast(shortkey_pos)).width : 0); nana::size shortkey_size = graph.text_extent_size(txtptr + shortkey_pos, 1); - x += off_w; - y += shortkey_size.height; - graph.line(x, y, x + shortkey_size.width - 1, y, 0x0); + pos.x += off_w; + pos.y += static_cast(shortkey_size.height); + //graph.line(x, y, x + shortkey_size.width - 1, y, 0x0); //deprecated + graph.set_color(::nana::expr_color(colors::black)); + graph.line(pos, point{ pos.x + static_cast(shortkey_size.width) - 1, pos.y }); } } else { + graph.set_text_color(::nana::expr_color(colors::white)); if(attr_.omitted) { - tr.render(x + 1, y + 1, 0xFFFFFF, txtptr, txtlen, omitted_pixels, true); - tr.render(x, y, 0x808080, txtptr, txtlen, omitted_pixels, true); + tr.render(point{ pos.x + 1, pos.y + 1 }, txtptr, txtlen, omitted_pixels, true); + graph.set_text_color(::nana::expr_color(colors::gray)); + tr.render(pos, txtptr, txtlen, omitted_pixels, true); } else { - graph.bidi_string(x + 1, y + 1, 0xFFFFFF, txtptr, txtlen); - graph.bidi_string(x, y, 0x808080, txtptr, txtlen); + graph.bidi_string(point{ pos.x + 1, pos.y + 1 }, txtptr, txtlen); + graph.set_text_color(::nana::expr_color(colors::gray)); + graph.bidi_string(pos, txtptr, txtlen); } } } @@ -256,11 +273,10 @@ namespace nana{ namespace drawerbase void trigger::_m_draw(graph_reference graph) { - window wd = widget_->handle(); - bool eb = API::window_enabled(wd); + bool eb = wdg_->enabled();; - attr_.bgcolor = API::background(wd); - attr_.fgcolor = API::foreground(wd); + attr_.bgcolor = wdg_->bgcolor(); + attr_.fgcolor = wdg_->fgcolor(); element_state e_state = attr_.e_state; if (eb) @@ -278,7 +294,7 @@ namespace nana{ namespace drawerbase if (false == cite_.draw(graph, attr_.bgcolor, attr_.fgcolor, graph.size(), e_state)) { - if (bground_mode::basic != API::effects_bground_mode(wd)) + if (bground_mode::basic != API::effects_bground_mode(wdg_->handle())) { _m_draw_background(graph); _m_draw_border(graph); @@ -291,15 +307,21 @@ namespace nana{ namespace drawerbase { nana::rectangle r(graph.size()); r.pare_off(1); - nana::color_t color_start = nana::paint::graphics::mix(attr_.bgcolor, 0xFFFFFF, 0.2); - nana::color_t color_end = nana::paint::graphics::mix(attr_.bgcolor, 0x0, 0.95); + + //nana::color_t color_start = nana::paint::graphics::mix(attr_.bgcolor.argb().value, 0xFFFFFF, 0.2); //deprecated + //nana::color_t color_end = nana::paint::graphics::mix(attr_.bgcolor.argb().value, 0x0, 0.95); + ::nana::expr_color from(colors::white); + from.blend(attr_.bgcolor, 0.8); + ::nana::expr_color to(colors::black); + to.blend(attr_.bgcolor, 0.05); if (element_state::pressed == attr_.e_state) { r.x = r.y = 2; - std::swap(color_start, color_end); + std::swap(from, to); } - graph.shadow_rectangle(r, color_start, color_end, true); + //graph.shadow_rectangle(r, color_start, color_end, true); //deprecated + graph.gradual_rectangle(r, from, to, true); } void trigger::_m_draw_border(graph_reference graph) @@ -329,7 +351,7 @@ namespace nana{ namespace drawerbase { arg_mouse arg; arg.evt_code = event_code::click; - arg.window_handle = widget_->handle(); + arg.window_handle = wdg_->handle(); arg.ctrl = arg.shift = false; arg.mid_button = arg.right_button = false; arg.left_button = true; diff --git a/source/gui/widgets/checkbox.cpp b/source/gui/widgets/checkbox.cpp index 6beee6ee..f2ba9989 100644 --- a/source/gui/widgets/checkbox.cpp +++ b/source/gui/widgets/checkbox.cpp @@ -93,7 +93,7 @@ namespace checkbox void drawer::_m_draw_checkbox(graph_reference graph, unsigned first_line_height) { - impl_->crook.draw(graph, widget_->background(), widget_->foreground(), rectangle(0, first_line_height > 16 ? (first_line_height - 16) / 2 : 0, 16, 16), API::element_state(*widget_)); + impl_->crook.draw(graph, widget_->bgcolor(), widget_->fgcolor(), rectangle(0, first_line_height > 16 ? (first_line_height - 16) / 2 : 0, 16, 16), API::element_state(*widget_)); } void drawer::_m_draw_title(graph_reference graph) diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index fb37ecb8..63b006cc 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -28,7 +28,7 @@ namespace nana namespace listbox { //struct cell - cell::format::format(color_t bgcolor, color_t fgcolor) + cell::format::format(const ::nana::expr_color& bgcolor, const ::nana::expr_color& fgcolor) : bgcolor{ bgcolor }, fgcolor{ fgcolor } {} @@ -53,7 +53,7 @@ namespace nana custom_format(new format{ fmt }) //make_unique {} - cell::cell(nana::string text, color_t bgcolor, color_t fgcolor) + cell::cell(nana::string text, const ::nana::expr_color& bgcolor, const ::nana::expr_color& fgcolor) : text(std::move(text)), custom_format{ new format{ bgcolor, fgcolor } } //make_unique {} @@ -577,8 +577,10 @@ namespace nana typedef std::vector container; container cells; - color_t bgcolor{0xFF000000}; - color_t fgcolor{0xFF000000}; + //color_t bgcolor{0xFF000000}; //deprecated + //color_t fgcolor{0xFF000000}; + nana::expr_color bgcolor; + nana::expr_color fgcolor; paint::image img; nana::size img_show_size; @@ -616,7 +618,7 @@ namespace nana cells.emplace_back(std::move(s)); } - item_t(nana::string&& s, color_t bg, color_t fg) + item_t(nana::string&& s, const nana::expr_color& bg, const nana::expr_color& fg) : bgcolor(bg), fgcolor(fg) { @@ -2343,12 +2345,15 @@ namespace nana size_type n = essence_->number_of_lister_items(true); if(0 == n)return; widget * wdptr = essence_->lister.wd_ptr(); - nana::color_t bgcolor = wdptr->background(); - nana::color_t txtcolor = wdptr->foreground(); + //nana::color_t bgcolor = wdptr->background(); + //nana::color_t txtcolor = wdptr->foreground(); //deprecated + auto bgcolor = wdptr->bgcolor(); + auto fgcolor = wdptr->fgcolor(); unsigned header_w = essence_->header.pixels(); + essence_->graph->set_color(bgcolor); if(header_w - essence_->scroll.offset_x < rect.width) - essence_->graph->rectangle(rect.x + header_w - essence_->scroll.offset_x, rect.y, rect.width - (header_w - essence_->scroll.offset_x), rect.height, bgcolor, true); + essence_->graph->rectangle(rectangle{ rect.x + static_cast(header_w)-essence_->scroll.offset_x, rect.y, rect.width - (header_w - essence_->scroll.offset_x), rect.height }, true); es_lister & lister = essence_->lister; //The Tracker indicates the item where mouse placed. @@ -2391,7 +2396,7 @@ namespace nana if(n-- == 0) break; state = (tracker == idx ? essence_t::state_t::highlighted : essence_t::state_t::normal); - _m_draw_item(i_categ->items[lister.absolute(index_pair(idx.cat, offs))], x, y, txtoff, header_w, rect, subitems, bgcolor, txtcolor, state); + _m_draw_item(i_categ->items[lister.absolute(index_pair(idx.cat, offs))], x, y, txtoff, header_w, rect, subitems, bgcolor,fgcolor, state); y += essence_->item_size; } } @@ -2402,7 +2407,7 @@ namespace nana if(n-- == 0) break; state = (tracker == idx ? essence_t::state_t::highlighted : essence_t::state_t::normal); - _m_draw_item(*i, x, y, txtoff, header_w, rect, subitems, bgcolor, txtcolor, state); + _m_draw_item(*i, x, y, txtoff, header_w, rect, subitems, bgcolor, fgcolor, state); y += essence_->item_size; } } @@ -2431,7 +2436,7 @@ namespace nana if(n-- == 0) break; state = (idx == tracker ? essence_t::state_t::highlighted : essence_t::state_t::normal); - _m_draw_item(i_categ->items[lister.absolute(index_pair(idx.cat, pos))], x, y, txtoff, header_w, rect, subitems, bgcolor, txtcolor, state); + _m_draw_item(i_categ->items[lister.absolute(index_pair(idx.cat, pos))], x, y, txtoff, header_w, rect, subitems, bgcolor, fgcolor, state); y += essence_->item_size; ++idx.item; } @@ -2444,7 +2449,7 @@ namespace nana state = (idx == tracker ? essence_t::state_t::highlighted : essence_t::state_t::normal); - _m_draw_item(m, x, y, txtoff, header_w, rect, subitems, bgcolor, txtcolor, state); + _m_draw_item(m, x, y, txtoff, header_w, rect, subitems, bgcolor, fgcolor, state); y += essence_->item_size; ++idx.item; @@ -2452,21 +2457,25 @@ namespace nana } } - if(y < rect.y + static_cast(rect.height)) - essence_->graph->rectangle(rect.x, y, rect.width, rect.y + rect.height - y, bgcolor, true); + if (y < rect.y + static_cast(rect.height)) + { + essence_->graph->set_color(bgcolor); + essence_->graph->rectangle(rectangle{ rect.x, y, rect.width, rect.y + rect.height - y }, true); + } } private: - void _m_draw_categ(const category_t& categ, int x, int y, int txtoff, unsigned width, const nana::rectangle& r, nana::color_t bgcolor, essence_t::state_t state) const + void _m_draw_categ(const category_t& categ, int x, int y, int txtoff, unsigned width, const nana::rectangle& r, nana::expr_color bgcolor, essence_t::state_t state) const { bool sel = categ.selected(); if(sel && (categ.expand == false)) - bgcolor = 0xD5EFFC; + bgcolor = nana::expr_color(0xD5, 0xEF, 0xFC); - if(state == essence_t::state_t::highlighted) - bgcolor = essence_->graph->mix(bgcolor, 0x99DEFD, 0.8); + if (state == essence_t::state_t::highlighted) + bgcolor.blend(::nana::expr_color(0x99, 0xde, 0xfd), 0.8); auto graph = essence_->graph; - graph->rectangle(x, y, width, essence_->item_size, bgcolor, true); + graph->set_color(bgcolor); + graph->rectangle(rectangle{ x, y, width, essence_->item_size }, true); nana::paint::gadget::arrow_16_pixels(*graph, x + 5, y + (essence_->item_size - 16) /2, 0x3399, 2, (categ.expand ? nana::paint::gadget::directions::to_north : nana::paint::gadget::directions::to_south)); nana::size text_s = graph->text_extent_size(categ.text); @@ -2491,25 +2500,26 @@ namespace nana } } - void _m_draw_item(const item_t& item, int x, int y, int txtoff, unsigned width, const nana::rectangle& r, const std::vector& seqs, nana::color_t bgcolor, nana::color_t txtcolor, essence_t::state_t state) const + void _m_draw_item(const item_t& item, int x, int y, int txtoff, unsigned width, const nana::rectangle& r, const std::vector& seqs, nana::expr_color bgcolor, nana::expr_color fgcolor, essence_t::state_t state) const { if(item.flags.selected) - bgcolor = 0xD5EFFC; - else if ((item.bgcolor & 0xFF000000) == 0) + bgcolor = nana::expr_color(0xD5, 0xEF, 0xFC); + else if (!item.bgcolor.invisible()) bgcolor = item.bgcolor; - if((item.fgcolor & 0xFF000000) == 0) - txtcolor = item.fgcolor; + if(!item.fgcolor.invisible()) + fgcolor = item.fgcolor; auto graph = essence_->graph; - if(essence_t::state_t::highlighted == state) - bgcolor = graph->mix(bgcolor, 0x99DEFD, 0.8); + if (essence_t::state_t::highlighted == state) + bgcolor.blend(::nana::expr_color(0x99, 0xde, 0xfd), 0.8);// = graph->mix(bgcolor, 0x99DEFD, 0.8); //deprecated unsigned show_w = width - essence_->scroll.offset_x; if(show_w >= r.width) show_w = r.width; //draw the background - graph->rectangle(r.x, y, show_w, essence_->item_size, bgcolor, true); + graph->set_color(bgcolor); + graph->rectangle(rectangle{ r.x, y, show_w, essence_->item_size }, true); int item_xpos = x; bool first = true; @@ -2541,7 +2551,7 @@ namespace nana typedef std::remove_reference::type::state state; crook_renderer_.check(item.flags.checked ? state::checked : state::unchecked); - crook_renderer_.draw(*graph, bgcolor, txtcolor, essence_->checkarea(item_xpos, y), estate); + crook_renderer_.draw(*graph, bgcolor, fgcolor, essence_->checkarea(item_xpos, y), estate); } auto & m_cell = item.cells[index]; @@ -2559,32 +2569,37 @@ namespace nana ext_w += 18; } - auto cell_txtcolor = txtcolor; - if (m_cell.custom_format) + auto cell_txtcolor = fgcolor; + if (m_cell.custom_format && (!m_cell.custom_format->bgcolor.invisible())) { - if (!item.flags.selected && !(m_cell.custom_format->bgcolor & 0xFF000000)) + if (!item.flags.selected) { auto cell_bgcolor = m_cell.custom_format->bgcolor; if (essence_t::state_t::highlighted == state) - cell_bgcolor = graph->mix(cell_bgcolor, 0x99DEFD, 0.8); - graph->rectangle(item_xpos, y, header.pixels, essence_->item_size, cell_bgcolor, true); + cell_bgcolor.blend(::nana::expr_color(0x99, 0xde, 0xfd), 0.8); //= graph->mix(cell_bgcolor, 0x99DEFD, 0.8); //deprecated + graph->set_color(cell_bgcolor); + graph->rectangle(rectangle{ item_xpos, y, header.pixels, essence_->item_size }, true); } - if (!(m_cell.custom_format->bgcolor & 0xFF000000)) - cell_txtcolor = m_cell.custom_format->fgcolor; + cell_txtcolor = m_cell.custom_format->fgcolor; } - graph->string(item_xpos + ext_w, y + txtoff, cell_txtcolor, m_cell.text); + graph->set_text_color(cell_txtcolor); + graph->string(point{ item_xpos + ext_w, y + txtoff }, m_cell.text); - if(ts.width + ext_w > header.pixels) + if (ts.width + ext_w > header.pixels) { //The text is painted over the next subitem int xpos = item_xpos + header.pixels - essence_->suspension_width; - graph->rectangle(xpos, y + 2, essence_->suspension_width, essence_->item_size - 4, bgcolor, true); - graph->string(xpos, y + 2, txtcolor, STR("...")); + + graph->set_color(bgcolor); + graph->rectangle(rectangle{ xpos, y + 2, essence_->suspension_width, essence_->item_size - 4 }, true); + graph->set_text_color(fgcolor); + graph->string(point{ xpos, y + 2 }, STR("...")); //Erase the part that over the next subitem. - auto erase_bgcolor = index + 1 < seqs.size() ? bgcolor : item.bgcolor; - graph->rectangle(item_xpos + header.pixels, y + 2, ts.width + ext_w - header.pixels, essence_->item_size - 4, erase_bgcolor, true); + if (index + 1 >= seqs.size()) + graph->set_color(item.bgcolor); + graph->rectangle(rectangle{item_xpos + static_cast(header.pixels), y + 2, ts.width + ext_w - header.pixels, essence_->item_size - 4}, true); } } @@ -3021,26 +3036,26 @@ namespace nana return cat_->items.at(pos_.item).flags.selected; } - item_proxy & item_proxy::bgcolor(nana::color_t col) + item_proxy & item_proxy::bgcolor(const nana::expr_color& col) { - cat_->items.at(pos_.item).flags.selected; + cat_->items.at(pos_.item).bgcolor = col; ess_->update(); return *this; } - nana::color_t item_proxy::bgcolor() const + nana::expr_color item_proxy::bgcolor() const { return cat_->items.at(pos_.item).bgcolor; } - item_proxy& item_proxy::fgcolor(nana::color_t col) + item_proxy& item_proxy::fgcolor(const nana::expr_color& col) { cat_->items.at(pos_.item).fgcolor = col; ess_->update(); return *this; } - nana::color_t item_proxy::fgcolor() const + nana::expr_color item_proxy::fgcolor() const { return cat_->items.at(pos_.item).fgcolor; } @@ -3265,8 +3280,8 @@ namespace nana if(wd && !(API::empty_window(wd->handle()))) { auto & m = cat_->items.back(); - m.bgcolor = wd->background(); - m.fgcolor = wd->foreground(); + m.bgcolor = wd->bgcolor(); + m.fgcolor = wd->fgcolor(); ess_->update(); } } @@ -3425,8 +3440,8 @@ namespace nana if (wd && !(API::empty_window(wd->handle()))) { auto & m = cat_->items.back(); - m.bgcolor = wd->background(); - m.fgcolor = wd->foreground(); + m.bgcolor = wd->bgcolor(); + m.fgcolor = wd->fgcolor(); ess_->update(); } } @@ -3534,8 +3549,8 @@ namespace nana if (false == API::empty_window(wd)) { auto & item = ess.lister.at(pos); - item.bgcolor = API::background(wd); - item.fgcolor = API::foreground(wd); + item.bgcolor = bgcolor(); + item.fgcolor = fgcolor(); ess.update(); } } diff --git a/source/gui/widgets/menu.cpp b/source/gui/widgets/menu.cpp index 8be62a7a..2539cd7c 100644 --- a/source/gui/widgets/menu.cpp +++ b/source/gui/widgets/menu.cpp @@ -136,7 +136,7 @@ namespace nana nana::rectangle crook_r = r; crook_r.width = 16; crook_.radio(at.check_style == checks::option); - crook_.draw(graph, 0xE6EFF4, 0x0, crook_r, element_state::normal); + crook_.draw(graph, ::nana::expr_color(0xE6, 0xEF, 0xF4), colors::black, crook_r, element_state::normal); } } diff --git a/source/gui/widgets/treebox.cpp b/source/gui/widgets/treebox.cpp index 9135e364..eaefa1bb 100644 --- a/source/gui/widgets/treebox.cpp +++ b/source/gui/widgets/treebox.cpp @@ -1078,7 +1078,16 @@ namespace nana class internal_renderer : public renderer_interface { - void bground(graph_reference graph, nana::color_t bgcolor, nana::color_t fgcolor, const compset_interface * compset) const override + nana::expr_color bgcolor_; + nana::expr_color fgcolor_; + + void set_color(const nana::expr_color & bgcolor, const nana::expr_color& fgcolor) override + { + bgcolor_ = bgcolor; + fgcolor_ = fgcolor; + } + + void bground(graph_reference graph, const compset_interface * compset) const override { comp_attribute_t attr; @@ -1108,7 +1117,7 @@ namespace nana } } - void expander(graph_reference graph, nana::color_t bgcolor, nana::color_t fgcolor, const compset_interface * compset) const override + void expander(graph_reference graph, const compset_interface * compset) const override { comp_attribute_t attr; if(compset->comp_attribute(component::expender, attr)) @@ -1126,18 +1135,18 @@ namespace nana } } - void crook(graph_reference graph, nana::color_t bgcolor, nana::color_t fgcolor, const compset_interface * compset) const override + void crook(graph_reference graph, const compset_interface * compset) const override { comp_attribute_t attr; if(compset->comp_attribute(component::crook, attr)) { attr.area.y += (attr.area.height - 16) / 2; crook_.check(compset->item_attribute().checked); - crook_.draw(graph, bgcolor, fgcolor, attr.area, attr.mouse_pointed ? element_state::hovered : element_state::normal); + crook_.draw(graph, bgcolor_, fgcolor_, attr.area, attr.mouse_pointed ? element_state::hovered : element_state::normal); } } - virtual void icon(graph_reference graph, nana::color_t bgcolor, nana::color_t fgcolor, const compset_interface * compset) const override + virtual void icon(graph_reference graph, const compset_interface * compset) const override { comp_attribute_t attr; if(compset->comp_attribute(component::icon, attr)) @@ -1170,11 +1179,14 @@ namespace nana } } - virtual void text(graph_reference graph, nana::color_t bgcolor, nana::color_t fgcolor, const compset_interface * compset) const override + virtual void text(graph_reference graph, const compset_interface * compset) const override { comp_attribute_t attr; - if(compset->comp_attribute(component::text, attr)) - graph.string(attr.area.x, attr.area.y + 3, fgcolor, compset->item_attribute().text); + if (compset->comp_attribute(component::text, attr)) + { + graph.set_text_color(fgcolor_); + graph.string(point{ attr.area.x, attr.area.y + 3 }, compset->item_attribute().text); + } } private: @@ -1279,8 +1291,8 @@ namespace nana item_renderer(implement * impl, const nana::point& pos) :impl_(impl), pos_(pos) { - bgcolor_ = impl_->data.widget_ptr->background(); - fgcolor_ = impl_->data.widget_ptr->foreground(); + bgcolor_ = impl_->data.widget_ptr->bgcolor(); + fgcolor_ = impl_->data.widget_ptr->fgcolor(); } //affect @@ -1310,11 +1322,12 @@ namespace nana node_r_.height = comp_placer->item_height(*impl_->data.graph); auto renderer = draw_impl->data.renderer; - renderer->bground(*draw_impl->data.graph, bgcolor_, fgcolor_, this); - renderer->expander(*draw_impl->data.graph, bgcolor_, fgcolor_, this); - renderer->crook(*draw_impl->data.graph, bgcolor_, fgcolor_, this); - renderer->icon(*draw_impl->data.graph, bgcolor_, fgcolor_, this); - renderer->text(*draw_impl->data.graph, bgcolor_, fgcolor_, this); + renderer->set_color(bgcolor_, fgcolor_); + renderer->bground(*draw_impl->data.graph, this); + renderer->expander(*draw_impl->data.graph, this); + renderer->crook(*draw_impl->data.graph, this); + renderer->icon(*draw_impl->data.graph, this); + renderer->text(*draw_impl->data.graph, this); pos_.y += node_r_.height; @@ -1343,8 +1356,10 @@ namespace nana } private: trigger::implement * impl_; - nana::color_t bgcolor_; - nana::color_t fgcolor_; + //nana::color_t bgcolor_; //deprecated + //nana::color_t fgcolor_; + nana::expr_color bgcolor_; + nana::expr_color fgcolor_; nana::point pos_; const node_type * iterated_node_; item_attribute_t node_attr_; @@ -1386,13 +1401,12 @@ namespace nana nana::paint::graphics item_graph(item_r_.width, item_r_.height); item_graph.typeface(graph_->typeface()); - auto bgcolor = widget_->background(); - auto fgcolor = widget_->foreground(); - renderer_->bground(item_graph, bgcolor, fgcolor, this); - renderer_->expander(item_graph, bgcolor, fgcolor, this); - renderer_->crook(item_graph, bgcolor, fgcolor, this); - renderer_->icon(item_graph, bgcolor, fgcolor, this); - renderer_->text(item_graph, bgcolor, fgcolor, this); + renderer_->set_color(widget_->bgcolor(), widget_->fgcolor()); + renderer_->bground(item_graph, this); + renderer_->expander(item_graph, this); + renderer_->crook(item_graph, this); + renderer_->icon(item_graph, this); + renderer_->text(item_graph, this); item_graph.paste(attr.area, *graph_, 1, 1); graph_->rectangle(0x0, false); diff --git a/source/gui/widgets/widget.cpp b/source/gui/widgets/widget.cpp index 4e1b2c2b..8efa77f9 100644 --- a/source/gui/widgets/widget.cpp +++ b/source/gui/widgets/widget.cpp @@ -143,22 +143,42 @@ namespace nana void widget::foreground(nana::color_t value) { - _m_foreground(value); + _m_fgcolor(expr_color(static_cast(value))); } nana::color_t widget::foreground() const { - return _m_foreground(); + return _m_fgcolor().argb().value; } void widget::background(nana::color_t value) { - _m_background(value); + _m_bgcolor(expr_color(static_cast(value))); } nana::color_t widget::background() const { - return _m_background(); + return _m_bgcolor().argb().value; + } + + void widget::fgcolor(const nana::expr_color& col) + { + _m_fgcolor(col); + } + + nana::expr_color widget::fgcolor() const + { + return _m_fgcolor(); + } + + void widget::bgcolor(const nana::expr_color& col) + { + _m_bgcolor(col); + } + + nana::expr_color widget::bgcolor() const + { + return _m_bgcolor(); } general_events& widget::events() const @@ -261,24 +281,24 @@ namespace nana return API::typeface(handle()); } - void widget::_m_foreground(nana::color_t value) + void widget::_m_fgcolor(const nana::expr_color& col) { - API::foreground(handle(), value); + API::fgcolor(handle(), col); } - nana::color_t widget::_m_foreground() const + nana::expr_color widget::_m_fgcolor() const { - return API::foreground(handle()); + return API::fgcolor(handle()); } - void widget::_m_background(nana::color_t value) + void widget::_m_bgcolor(const nana::expr_color& col) { - API::background(handle(), value); + API::bgcolor(handle(), col); } - nana::color_t widget::_m_background() const + nana::expr_color widget::_m_bgcolor() const { - return API::background(handle()); + return API::bgcolor(handle()); } //end class widget diff --git a/source/paint/detail/native_paint_interface.cpp b/source/paint/detail/native_paint_interface.cpp index aff60b44..eb326aae 100644 --- a/source/paint/detail/native_paint_interface.cpp +++ b/source/paint/detail/native_paint_interface.cpp @@ -83,43 +83,44 @@ namespace detail { delete [] table; } - - nana::pixel_rgb_t fade_color(nana::pixel_rgb_t bgcolor, nana::pixel_rgb_t fgcolor, double fade_rate) + /* + nana::pixel_color_t fade_color(nana::pixel_color_t bgcolor, nana::pixel_color_t fgcolor, double fade_rate) //deprecated { - pixel_rgb_t ret; + pixel_color_t ret; double lrate = 1.0 - fade_rate; - ret.u.element.red = static_cast(bgcolor.u.element.red * fade_rate + fgcolor.u.element.red * lrate); - ret.u.element.green = static_cast(bgcolor.u.element.green * fade_rate + fgcolor.u.element.green * lrate); - ret.u.element.blue = static_cast(bgcolor.u.element.blue * fade_rate + fgcolor.u.element.blue * lrate); - ret.u.element.alpha_channel = 0; + ret.element.red = static_cast(bgcolor.element.red * fade_rate + fgcolor.element.red * lrate); + ret.element.green = static_cast(bgcolor.element.green * fade_rate + fgcolor.element.green * lrate); + ret.element.blue = static_cast(bgcolor.element.blue * fade_rate + fgcolor.element.blue * lrate); + ret.element.alpha_channel = 0; return ret; } - nana::pixel_rgb_t fade_color(nana::pixel_rgb_t bgcolor, nana::pixel_rgb_t fgcolor, const unsigned char* const fade_table) + nana::pixel_color_t fade_color(nana::pixel_color_t bgcolor, nana::pixel_color_t fgcolor, const unsigned char* const fade_table) //deprecated { const unsigned char * const s_fade_table = fade_table + 0x100; - bgcolor.u.element.red = fade_table[bgcolor.u.element.red] + s_fade_table[fgcolor.u.element.red]; - bgcolor.u.element.green = fade_table[bgcolor.u.element.green] + s_fade_table[fgcolor.u.element.green]; - bgcolor.u.element.blue = fade_table[bgcolor.u.element.blue] + s_fade_table[fgcolor.u.element.blue]; + bgcolor.element.red = fade_table[bgcolor.element.red] + s_fade_table[fgcolor.element.red]; + bgcolor.element.green = fade_table[bgcolor.element.green] + s_fade_table[fgcolor.element.green]; + bgcolor.element.blue = fade_table[bgcolor.element.blue] + s_fade_table[fgcolor.element.blue]; return bgcolor; } + */ - nana::pixel_rgb_t fade_color_intermedia(nana::pixel_rgb_t fgcolor, const unsigned char* fade_table) + nana::pixel_color_t fade_color_intermedia(nana::pixel_color_t fgcolor, const unsigned char* fade_table) { fade_table += 0x100; - fgcolor.u.element.red = fade_table[fgcolor.u.element.red]; - fgcolor.u.element.green = fade_table[fgcolor.u.element.green]; - fgcolor.u.element.blue = fade_table[fgcolor.u.element.blue]; + fgcolor.element.red = fade_table[fgcolor.element.red]; + fgcolor.element.green = fade_table[fgcolor.element.green]; + fgcolor.element.blue = fade_table[fgcolor.element.blue]; return fgcolor; } - nana::pixel_rgb_t fade_color_by_intermedia(nana::pixel_rgb_t bgcolor, nana::pixel_rgb_t fgcolor_intermedia, const unsigned char* const fade_table) + nana::pixel_color_t fade_color_by_intermedia(nana::pixel_color_t bgcolor, nana::pixel_color_t fgcolor_intermedia, const unsigned char* const fade_table) { - bgcolor.u.element.red = fade_table[bgcolor.u.element.red] + fgcolor_intermedia.u.element.red; - bgcolor.u.element.green = fade_table[bgcolor.u.element.green] + fgcolor_intermedia.u.element.green; - bgcolor.u.element.blue = fade_table[bgcolor.u.element.blue] + fgcolor_intermedia.u.element.blue; + bgcolor.element.red = fade_table[bgcolor.element.red] + fgcolor_intermedia.element.red; + bgcolor.element.green = fade_table[bgcolor.element.green] + fgcolor_intermedia.element.green; + bgcolor.element.blue = fade_table[bgcolor.element.blue] + fgcolor_intermedia.element.blue; return bgcolor; } @@ -141,14 +142,14 @@ namespace detail for(std::size_t row = 0; row < r.height; ++row) { - nana::pixel_rgb_t * i = pixbuf.raw_ptr(row) + r.x; - const nana::pixel_rgb_t * const end = i + r.width; + auto i = pixbuf.raw_ptr(row) + r.x; + const auto end = i + r.width; for(; i < end; ++i) { - unsigned px_r = ((static_cast((i->u.color & 0xFF0000) * lrate) + red) & 0xFF0000); - unsigned px_g = ((static_cast((i->u.color & 0xFF00) * lrate) + green) & 0xFF00); - unsigned px_b = ((static_cast((i->u.color & 0xFF) * lrate) + blue) & 0xFF); - i->u.color = (px_r | px_g | px_b); + unsigned px_r = ((static_cast((i->value & 0xFF0000) * lrate) + red) & 0xFF0000); + unsigned px_g = ((static_cast((i->value & 0xFF00) * lrate) + green) & 0xFF00); + unsigned px_b = ((static_cast((i->value & 0xFF) * lrate) + blue) & 0xFF); + i->value = (px_r | px_g | px_b); } } pixbuf.paste(nana::rectangle(r.x, 0, r.width, r.height), dw, r.x, r.y); @@ -195,15 +196,15 @@ namespace detail return extents; } - void draw_string(drawable_type dw, int x, int y, const nana::char_t * str, std::size_t len) + void draw_string(drawable_type dw, const nana::point& pos, const nana::char_t * str, std::size_t len) { #if defined(NANA_WINDOWS) - ::TextOut(dw->context, x, y, str, static_cast(len)); + ::TextOut(dw->context, pos.x, pos.y, str, static_cast(len)); #elif defined(NANA_X11) #if defined(NANA_UNICODE) std::string utf8str = nana::charset(nana::string(str, len)); XftFont * fs = reinterpret_cast(dw->font->handle); - ::XftDrawStringUtf8(dw->xftdraw, &(dw->xft_fgcolor), fs, x, y + fs->ascent, + ::XftDrawStringUtf8(dw->xftdraw, &(dw->xft_fgcolor), fs, pos.x, pos.y + fs->ascent, reinterpret_cast(const_cast(utf8str.c_str())), utf8str.size()); #else XFontSet fs = reinterpret_cast(dw->font->handle); @@ -221,7 +222,7 @@ namespace detail if(descent < (*i)->descent) descent = (*i)->descent; } - XmbDrawString(display, dw->pixmap, reinterpret_cast(dw->font->handle), dw->context, x, y + ascent + descent, buf, len); + XmbDrawString(display, dw->pixmap, reinterpret_cast(dw->font->handle), dw->context, pos.x, pos.y + ascent + descent, buf, len); #endif #endif } diff --git a/source/paint/gadget.cpp b/source/paint/gadget.cpp index 9e2d5a38..ca5031ee 100644 --- a/source/paint/gadget.cpp +++ b/source/paint/gadget.cpp @@ -259,9 +259,9 @@ namespace gadget } } - void cross(graphics& graph, int x, int y, uint32_t size, uint32_t thickness, nana::color_t color) + void cross(graphics& graph, int x, int y, uint32_t size, uint32_t thickness, ::nana::color_t color) //deprecated { - if(thickness + 2 <= size) + if (thickness + 2 <= size) { int gap = (size - thickness) / 2; @@ -300,15 +300,72 @@ namespace gadget ps[11].x = x + gap; ps[11].y = y + gap; - nana::color_t dkcolor = graph.mix(color, 0x0, 0.5); - for(int i = 0; i < 11; ++i) + nana::color_t dkcolor = graph.mix(color, 0x0, 0.5); //deprecated + + for (int i = 0; i < 11; ++i) graph.line(ps[i], ps[i + 1], dkcolor); graph.line(ps[11], ps[0], dkcolor); graph.rectangle(ps[10].x + 1, ps[10].y + 1, (gap << 1) + thickness - 2, thickness - 2, color, true); graph.rectangle(ps[0].x + 1, ps[0].y + 1, thickness - 2, (gap << 1) + thickness - 2, color, true); - } + + } + + void cross(graphics& graph, int x, int y, uint32_t size, uint32_t thickness, const ::nana::expr_color& color) + { + if (thickness + 2 <= size) + { + int gap = (size - thickness) / 2; + + nana::point ps[12]; + ps[0].x = x + gap; + ps[1].x = ps[0].x + thickness - 1; + ps[1].y = ps[0].y = y; + + ps[2].x = ps[1].x; + ps[2].y = y + gap; + + ps[3].x = ps[2].x + gap; + ps[3].y = ps[2].y; + + ps[4].x = ps[3].x; + ps[4].y = ps[3].y + thickness - 1; + + ps[5].x = ps[1].x; + ps[5].y = ps[4].y; + + ps[6].x = ps[5].x; + ps[6].y = ps[5].y + gap; + + ps[7].x = x + gap; + ps[7].y = ps[6].y; + + ps[8].x = ps[7].x; + ps[8].y = ps[4].y; + + ps[9].x = x; + ps[9].y = ps[4].y; + + ps[10].x = x; + ps[10].y = y + gap; + + ps[11].x = x + gap; + ps[11].y = y + gap; + + ::nana::expr_color darker(0, 0, 0); + darker.blend(color, true); + graph.set_color(darker); + + for (int i = 0; i < 11; ++i) + graph.line(ps[i], ps[i + 1]); + graph.line(ps[11], ps[0]); + + graph.set_color(color); + graph.rectangle(rectangle{ ps[10].x + 1, ps[10].y + 1, (gap << 1) + thickness - 2, thickness - 2 }, true); + graph.rectangle(rectangle{ ps[0].x + 1, ps[0].y + 1, thickness - 2, (gap << 1) + thickness - 2 }, true); + + } } }//end namespace gadget diff --git a/source/paint/graphics.cpp b/source/paint/graphics.cpp index 2d5ba66d..586a5e72 100644 --- a/source/paint/graphics.cpp +++ b/source/paint/graphics.cpp @@ -318,9 +318,13 @@ namespace paint #endif if(dw) { - dw->fgcolor(0); + //dw->fgcolor(0); + dw->set_color(0x0); + dw->set_text_color(0x0); #if defined(NANA_WINDOWS) - dw->bytes_per_line = width * sizeof(pixel_rgb_t); + dw->bytes_per_line = width * sizeof(pixel_argb_t); +#else + dw->update_text_color(); #endif dwptr_ = std::shared_ptr(dw, detail::drawable_deleter()); handle_ = dw; @@ -547,7 +551,8 @@ namespace paint { if(handle_ && str && len) { - handle_->fgcolor(color); + handle_->set_text_color(color); + const nana::char_t * end = str + len; const nana::char_t * i = std::find(str, end, '\t'); if(i != end) @@ -559,7 +564,7 @@ namespace paint if(len) { //Render a part that does not contains a tab - detail::draw_string(handle_, x, y, str, len); + detail::draw_string(handle_, point{ x, y }, str, len); x += detail::raw_text_extent_size(handle_, str, len).width; } @@ -578,7 +583,7 @@ namespace paint } } else - detail::draw_string(handle_, x, y, str, len); + detail::draw_string(handle_, point{ x, y }, str, len); if(changed_ == false) changed_ = true; } } @@ -755,10 +760,12 @@ namespace paint void graphics::line(int x1, int y1, int x2, int y2, color_t color) { if(!handle_) return; + handle_->set_color(color); #if defined(NANA_WINDOWS) if(x1 != x2 || y1 != y2) { - handle_->pen.set(handle_->context, PS_SOLID, 1, color); + handle_->update_pen(); + //handle_->pen.set(handle_->context, PS_SOLID, 1, color); //deprecated ::MoveToEx(handle_->context, x1, y1, 0); ::LineTo(handle_->context, x2, y2); @@ -766,7 +773,8 @@ namespace paint ::SetPixel(handle_->context, x2, y2, NANA_RGB(color)); #elif defined(NANA_X11) Display* disp = nana::detail::platform_spec::instance().open_display(); - handle_->fgcolor(color); + //handle_->fgcolor(color); //deprecated + handle_->update_color(); ::XDrawLine(disp, handle_->pixmap, handle_->context, x1, y1, x2, y2); #endif if(changed_ == false) changed_ = true; @@ -962,7 +970,7 @@ namespace paint pixel_buffer pixbuf(handle_, 0, 0); - nana::pixel_rgb_t * pixels = pixbuf.raw_ptr(0); + auto pixels = pixbuf.raw_ptr(0); const nana::size sz = paint::detail::drawable_size(handle_); const int rest = sz.width % 4; @@ -970,28 +978,28 @@ namespace paint for(unsigned y = 0; y < sz.height; ++y) { - pixel_rgb_t * end = pixels + length_align4; + const auto end = pixels + length_align4; for(; pixels < end; pixels += 4) { - unsigned char gray = static_cast(table_red[pixels[0].u.element.red] + table_green[pixels[0].u.element.green] + table_blue[pixels[0].u.element.blue] + 0.5f); - pixels[0].u.color = gray << 16 | gray << 8| gray; + unsigned char gray = static_cast(table_red[pixels[0].element.red] + table_green[pixels[0].element.green] + table_blue[pixels[0].element.blue] + 0.5f); + pixels[0].value = gray << 16 | gray << 8| gray; - gray = static_cast(table_red[pixels[1].u.element.red] + table_green[pixels[1].u.element.green] + table_blue[pixels[1].u.element.blue] + 0.5f); - pixels[1].u.color = gray << 16 | gray << 8| gray; + gray = static_cast(table_red[pixels[1].element.red] + table_green[pixels[1].element.green] + table_blue[pixels[1].element.blue] + 0.5f); + pixels[1].value = gray << 16 | gray << 8 | gray; - gray = static_cast(table_red[pixels[2].u.element.red] + table_green[pixels[2].u.element.green] + table_blue[pixels[2].u.element.blue] + 0.5f); - pixels[2].u.color = gray << 16 | gray << 8| gray; + gray = static_cast(table_red[pixels[2].element.red] + table_green[pixels[2].element.green] + table_blue[pixels[2].element.blue] + 0.5f); + pixels[2].value = gray << 16 | gray << 8 | gray; - gray = static_cast(table_red[pixels[3].u.element.red] + table_green[pixels[3].u.element.green] + table_blue[pixels[3].u.element.blue] + 0.5f); - pixels[3].u.color = gray << 16 | gray << 8| gray; + gray = static_cast(table_red[pixels[3].element.red] + table_green[pixels[3].element.green] + table_blue[pixels[3].element.blue] + 0.5f); + pixels[3].value = gray << 16 | gray << 8 | gray; } for(int i = 0; i < rest; ++i) { - unsigned char gray = static_cast(table_red[pixels[i].u.element.red] + table_green[pixels[i].u.element.green] + table_blue[pixels[i].u.element.blue] + 0.5f); - pixels[i].u.element.red = gray; - pixels[i].u.element.green = gray; - pixels[i].u.element.blue = gray; + unsigned char gray = static_cast(table_red[pixels[i].element.red] + table_green[pixels[i].element.green] + table_blue[pixels[i].element.blue] + 0.5f); + pixels[i].element.red = gray; + pixels[i].element.green = gray; + pixels[i].element.blue = gray; } pixels += rest; @@ -1169,19 +1177,192 @@ namespace paint #endif } } - - color_t graphics::mix(color_t a, color_t b, double fade_rate) + + color_t graphics::mix(color_t a, color_t b, double fade_rate) //deprecated { - pixel_rgb_t pa, pb, ret; - ret.u.color = 0; - pa.u.color = a; - pb.u.color = b; + pixel_argb_t pa, pb, ret; + ret.value = 0; + pa.value = a; + pb.value = b; - ret.u.element.red = static_cast(pa.u.element.red * fade_rate + pb.u.element.red * (1 - fade_rate)); - ret.u.element.green = static_cast(pa.u.element.green * fade_rate + pb.u.element.green * (1 - fade_rate)); - ret.u.element.blue = static_cast(pa.u.element.blue * fade_rate + pb.u.element.blue * (1 - fade_rate)); + ret.element.red = static_cast(pa.element.red * fade_rate + pb.element.red * (1 - fade_rate)); + ret.element.green = static_cast(pa.element.green * fade_rate + pb.element.green * (1 - fade_rate)); + ret.element.blue = static_cast(pa.element.blue * fade_rate + pb.element.blue * (1 - fade_rate)); - return ret.u.color; + return ret.value; + } + + void graphics::set_color(const ::nana::expr_color& col) + { + if (handle_) + handle_->set_color(col.argb().value); + } + + void graphics::set_text_color(const ::nana::expr_color& col) + { + if (handle_) + handle_->set_text_color(col.argb().value); + } + + unsigned graphics::bidi_string(const nana::point& pos, const char_t * str, std::size_t len) + { + auto moved_pos = pos; + unicode_bidi bidi; + std::vector reordered; + bidi.linestr(str, len, reordered); + for (auto & i : reordered) + { + string(moved_pos, i.begin, i.end - i.begin); + moved_pos.x += static_cast(text_extent_size(i.begin, i.end - i.begin).width); + } + return static_cast(moved_pos.x - pos.x); + } + + void graphics::string(nana::point pos, const char_t* str, std::size_t len) + { + if (handle_ && str && len) + { + const nana::char_t * end = str + len; + const nana::char_t * i = std::find(str, end, '\t'); +#if defined(NANA_LINUX) + handle_->update_text_color(); +#endif + if (i != end) + { + std::size_t tab_pixels = handle_->string.tab_length * handle_->string.tab_pixels; + while (true) + { + len = i - str; + if (len) + { + //Render a part that does not contains a tab + detail::draw_string(handle_, pos, str, len); + pos.x += detail::raw_text_extent_size(handle_, str, len).width; + } + + str = i; + while (str != end && (*str == '\t')) + ++str; + + if (str != end) + { + //Now i_tab is not a tab, but a non-tab character following the previous tabs + pos.x += static_cast(tab_pixels * (str - i)); + i = std::find(str, end, '\t'); + } + else + break; + } + } + else + detail::draw_string(handle_, pos, str, len); + if (changed_ == false) changed_ = true; + } + } + + void graphics::string(const nana::point& pos, const char_t* str) + { + string(pos, str, nana::strlen(str)); + } + + void graphics::string(const nana::point& pos, const nana::string& str) + { + string(pos, str.data(), str.size()); + } + + void graphics::line(const nana::point& pos1, const nana::point& pos2) + { + if ((!handle_) || (pos1 == pos2)) return; +#if defined(NANA_WINDOWS) + handle_->update_pen(); + + ::MoveToEx(handle_->context, pos1.x, pos1.y, 0); + ::LineTo(handle_->context, pos2.x, pos2.y); + + ::SetPixel(handle_->context, pos2.x, pos2.y, NANA_RGB(handle_->pen.color)); +#elif defined(NANA_X11) + Display* disp = nana::detail::platform_spec::instance().open_display(); + handle_->update_color(); + ::XDrawLine(disp, handle_->pixmap, handle_->context, pos1.x, pos1.y, pos2.x, pos2.y); +#endif + if (changed_ == false) changed_ = true; + } + + void graphics::rectangle(const ::nana::rectangle& r, bool solid) + { + if (r.width && r.height && handle_ && r.right() > 0 && r.bottom() > 0) + { +#if defined(NANA_WINDOWS) + ::RECT native_r = { r.x, r.y, r.right(), r.bottom()}; + handle_->update_brush(); + (solid ? ::FillRect : ::FrameRect)(handle_->context, &native_r, handle_->brush.handle); +#elif defined(NANA_X11) + Display* disp = nana::detail::platform_spec::instance().open_display(); + handle_->update_color(); + if (solid) + ::XFillRectangle(disp, handle_->pixmap, handle_->context, r.x, r.y, r.width, r.height); + else + ::XDrawRectangle(disp, handle_->pixmap, handle_->context, r.x, r.y, r.width - 1, r.height - 1); +#endif + if (changed_ == false) changed_ = true; + } + } + + void graphics::gradual_rectangle(const ::nana::rectangle& r, const ::nana::expr_color& from, const ::nana::expr_color& to, bool vertical) + { +#if defined(NANA_WINDOWS) + if (pxbuf_.open(handle_)) + { + pxbuf_.gradual_rectangle(r, from, to, 0.0, vertical); + pxbuf_.paste(handle_, 0, 0); + } +#elif defined(NANA_X11) + if (nullptr == handle_) return; + + double deltapx = double(vertical ? height : width); + double r, g, b; + const double delta_r = (to.r() - (r = from.r())) / deltapx; + const double delta_g = (to.g() - (g = from.g())) / deltapx; + const double delta_b = (to.b() - (b = from.b())) / deltapx; + + unsigned last_color = (int(r) << 16) | (int(g) << 8) | int(b); + + Display * disp = nana::detail::platform_spec::instance().open_display(); + handle_->fgcolor(last_color); + const int endpos = deltapx + (vertical ? y : x); + if (endpos > 0) + { + if (vertical) + { + int x1 = x, x2 = x + static_cast(width); + for (; y < endpos; ++y) + { + ::XDrawLine(disp, handle_->pixmap, handle_->context, x1, y, x2, y); + unsigned new_color = (int(r += delta_r) << 16) | (int(g += delta_g) << 8) | int(b += delta_b); + if (new_color != last_color) + { + last_color = new_color; + handle_->fgcolor(last_color); + } + } + } + else + { + int y1 = y, y2 = y + static_cast(height); + for (; x < endpos; ++x) + { + ::XDrawLine(disp, handle_->pixmap, handle_->context, x, y1, x, y2); + unsigned new_color = (int(r += delta_r) << 16) | (int(g += delta_g) << 8) | int(b += delta_b); + if (new_color != last_color) + { + last_color = new_color; + handle_->fgcolor(last_color); + } + } + } + } +#endif + if (changed_ == false) changed_ = true; } //end class graphics diff --git a/source/paint/pixel_buffer.cpp b/source/paint/pixel_buffer.cpp index ea8590d9..5da40f8d 100644 --- a/source/paint/pixel_buffer.cpp +++ b/source/paint/pixel_buffer.cpp @@ -36,7 +36,7 @@ namespace nana{ namespace paint const drawable_type drawable; //Attached handle const nana::rectangle valid_r; const nana::size pixel_size; - pixel_rgb_t * raw_pixel_buffer; + pixel_argb_t * raw_pixel_buffer; const std::size_t bytes_per_line; bool alpha_channel; #if defined(NANA_X11) @@ -80,8 +80,8 @@ namespace nana{ namespace paint : drawable(nullptr), valid_r(0, 0, static_cast(width), static_cast(height)), pixel_size(static_cast(width), static_cast(height)), - raw_pixel_buffer(new pixel_rgb_t[width * height]), - bytes_per_line(width * sizeof(pixel_rgb_t)), + raw_pixel_buffer(new pixel_argb_t[width * height]), + bytes_per_line(width * sizeof(pixel_argb_t)), alpha_channel(false) { #if defined(NANA_X11) @@ -109,11 +109,11 @@ namespace nana{ namespace paint valid_r(valid_rectangle(paint::detail::drawable_size(drawable), want_r)), pixel_size(valid_r), #if defined(NANA_WINDOWS) - raw_pixel_buffer(reinterpret_cast(reinterpret_cast(drawable->pixbuf_ptr + valid_r.x) + drawable->bytes_per_line * valid_r.y)), + raw_pixel_buffer(reinterpret_cast(reinterpret_cast(drawable->pixbuf_ptr + valid_r.x) + drawable->bytes_per_line * valid_r.y)), bytes_per_line(drawable->bytes_per_line), #else raw_pixel_buffer(nullptr), - bytes_per_line(sizeof(pixel_rgb_t) * valid_r.width), + bytes_per_line(sizeof(pixel_argb_t) * valid_r.width), #endif alpha_channel(false) { @@ -134,12 +134,12 @@ namespace nana{ namespace paint XDestroyImage(x11.image); throw std::runtime_error("Nana.pixel_buffer: Invalid pixel buffer context."); } - raw_pixel_buffer = reinterpret_cast(x11.image->data); + raw_pixel_buffer = reinterpret_cast(x11.image->data); } else if(16 == x11.image->depth) { //565 to 32 - raw_pixel_buffer = new pixel_rgb_t[valid_r.width * valid_r.height]; + raw_pixel_buffer = new pixel_argb_t[valid_r.width * valid_r.height]; assign(reinterpret_cast(x11.image->data), valid_r.width, valid_r.height, 16, x11.image->bytes_per_line, false); } else @@ -170,7 +170,7 @@ namespace nana{ namespace paint void assign(const unsigned char* rawbits, std::size_t width, std::size_t height, std::size_t bits_per_pixel, std::size_t bytes_per_line, bool is_negative) { - pixel_rgb_t * rawptr = raw_pixel_buffer; + auto rawptr = raw_pixel_buffer; if(rawptr) { if(32 == bits_per_pixel) @@ -181,12 +181,12 @@ namespace nana{ namespace paint } else { - std::size_t line_bytes = (pixel_size.width < width ? pixel_size.width : width) * sizeof(pixel_rgb_t); + std::size_t line_bytes = (pixel_size.width < width ? pixel_size.width : width) * sizeof(pixel_argb_t); if(pixel_size.height < height) height = pixel_size.height; - pixel_rgb_t * d = rawptr; + auto d = rawptr; if(is_negative) { const unsigned char* s = rawbits; @@ -217,21 +217,21 @@ namespace nana{ namespace paint if(pixel_size.height < height) height = pixel_size.height; - pixel_rgb_t * d = rawptr; + auto d = rawptr; if(is_negative) { const unsigned char* s = rawbits; for(std::size_t i = 0; i < height; ++i) { - pixel_rgb_t * p = d; - pixel_rgb_t * end = p + width; + auto p = d; + const auto end = p + width; std::size_t s_index = 0; for(; p < end; ++p) { const unsigned char * s_p = s + s_index; - p->u.element.blue = s_p[0]; - p->u.element.green = s_p[1]; - p->u.element.red = s_p[2]; + p->element.blue = s_p[0]; + p->element.green = s_p[1]; + p->element.red = s_p[2]; s_index += 3; } d += pixel_size.width; @@ -243,14 +243,14 @@ namespace nana{ namespace paint const unsigned char* s = rawbits + bytes_per_line * (height - 1); for(std::size_t i = 0; i < height; ++i) { - pixel_rgb_t * p = d; - pixel_rgb_t * end = p + width; + auto p = d; + const auto end = p + width; const unsigned char* s_p = s; for(; p < end; ++p) { - p->u.element.blue = s_p[0]; - p->u.element.green = s_p[1]; - p->u.element.red = s_p[2]; + p->element.blue = s_p[0]; + p->element.green = s_p[1]; + p->element.red = s_p[2]; s_p += 3; } d += pixel_size.width; @@ -266,9 +266,9 @@ namespace nana{ namespace paint if(pixel_size.height < height) height = pixel_size.height; - pixel_rgb_t * d = rawptr; + auto d = rawptr; - unsigned char * rgb_table = new unsigned char[32]; + auto rgb_table = new unsigned char[32]; for(std::size_t i =0; i < 32; ++i) rgb_table[i] = static_cast(i * 255 / 31); @@ -278,18 +278,18 @@ namespace nana{ namespace paint //const unsigned short* s = reinterpret_cast(rawbits); for(std::size_t i = 0; i < height; ++i) { - pixel_rgb_t * p = d; - const pixel_rgb_t * const end = p + width; - const unsigned short* s_p = reinterpret_cast(rawbits); + auto p = d; + const auto end = p + width; + auto s_p = reinterpret_cast(rawbits); for(; p < end; ++p) { - p->u.element.red = rgb_table[(*s_p >> 11) & 0x1F]; + p->element.red = rgb_table[(*s_p >> 11) & 0x1F]; #if defined(NANA_X11) - p->u.element.green = (*s_p >> 5) & 0x3F; - p->u.element.blue = rgb_table[*s_p & 0x1F]; + p->element.green = (*s_p >> 5) & 0x3F; + p->element.blue = rgb_table[*s_p & 0x1F]; #else - p->u.element.green = rgb_table[(*s_p>> 6) & 0x1F]; - p->u.element.blue = rgb_table[(*s_p >> 1) & 0x1F]; + p->element.green = rgb_table[(*s_p>> 6) & 0x1F]; + p->element.blue = rgb_table[(*s_p >> 1) & 0x1F]; #endif ++s_p; } @@ -303,18 +303,18 @@ namespace nana{ namespace paint rawbits += bytes_per_line * (height - 1); for(std::size_t i = 0; i < height; ++i) { - pixel_rgb_t * p = d; - const pixel_rgb_t * const end = p + width; - const unsigned short* s_p = reinterpret_cast(rawbits); + auto p = d; + const auto end = p + width; + auto s_p = reinterpret_cast(rawbits); for(; p < end; ++p) { - p->u.element.red = rgb_table[(*s_p >> 11) & 0x1F]; + p->element.red = rgb_table[(*s_p >> 11) & 0x1F]; #if defined(NANA_X11) - p->u.element.green = ((*s_p >> 5) & 0x3F); - p->u.element.blue = rgb_table[*s_p & 0x1F]; + p->element.green = ((*s_p >> 5) & 0x3F); + p->element.blue = rgb_table[*s_p & 0x1F]; #else - p->u.element.green = rgb_table[(*s_p & 0x7C0) >> 6]; - p->u.element.blue = rgb_table[(*s_p >> 1) & 0x1F]; + p->element.green = rgb_table[(*s_p & 0x7C0) >> 6]; + p->element.blue = rgb_table[(*s_p >> 1) & 0x1F]; #endif ++s_p; } @@ -343,7 +343,7 @@ namespace nana{ namespace paint const int depth = spec.screen_depth(); XImage* img = ::XCreateImage(disp, spec.screen_visual(), depth, ZPixmap, 0, 0, pixel_size.width, pixel_size.height, (16 == depth ? 16 : 32), 0); - if(sizeof(pixel_rgb_t) * 8 == depth || 24 == depth) + if(sizeof(pixel_argb_t) * 8 == depth || 24 == depth) { img->data = reinterpret_cast(raw_pixel_buffer); ::XPutImage(disp, dw, gc, @@ -366,7 +366,7 @@ namespace nana{ namespace paint { for(auto i = raw_pixel_buffer, end = raw_pixel_buffer + length; i != end; ++i) { - *(pixbuf_16bits++) = (fast_table[i->u.element.red] << 11) | ( (i->u.element.green * 63 / 255) << 6) | fast_table[i->u.element.blue]; + *(pixbuf_16bits++) = (fast_table[i->element.red] << 11) | ( (i->element.green * 63 / 255) << 6) | fast_table[i->element.blue]; } } else if(height) @@ -379,7 +379,7 @@ namespace nana{ namespace paint { for(auto i = sp, end = sp + width; i != end; ++i) { - *(pixbuf_16bits++) = (fast_table[i->u.element.red] << 11) | ((i->u.element.green * 63 / 255) << 6) | fast_table[i->u.element.blue]; + *(pixbuf_16bits++) = (fast_table[i->element.red] << 11) | ((i->element.green * 63 / 255) << 6) | fast_table[i->element.blue]; } if(++top < height) @@ -451,7 +451,7 @@ namespace nana{ namespace paint bmpinfo.bmiHeader.biPlanes = 1; bmpinfo.bmiHeader.biBitCount = 32; bmpinfo.bmiHeader.biCompression = BI_RGB; - bmpinfo.bmiHeader.biSizeImage = static_cast(sz.width * sz.height * sizeof(pixel_rgb_t)); + bmpinfo.bmiHeader.biSizeImage = static_cast(sz.width * sz.height * sizeof(pixel_argb_t)); bmpinfo.bmiHeader.biClrUsed = 0; bmpinfo.bmiHeader.biClrImportant = 0; @@ -492,7 +492,7 @@ namespace nana{ namespace paint bmpinfo.bmiHeader.biPlanes = 1; bmpinfo.bmiHeader.biBitCount = 32; bmpinfo.bmiHeader.biCompression = BI_RGB; - bmpinfo.bmiHeader.biSizeImage = static_cast(want_r.width * want_r.height * sizeof(pixel_rgb_t)); + bmpinfo.bmiHeader.biSizeImage = static_cast(want_r.width * want_r.height * sizeof(pixel_argb_t)); bmpinfo.bmiHeader.biClrUsed = 0; bmpinfo.bmiHeader.biClrImportant = 0; @@ -532,7 +532,7 @@ namespace nana{ namespace paint XImage * image = ::XGetImage(spec.open_display(), drawable->pixmap, r.x, r.y, r.width, r.height, AllPlanes, ZPixmap); storage_ = std::make_shared(want_r.width, want_r.height); - pixel_rgb_t * pixbuf = storage_->raw_pixel_buffer; + auto pixbuf = storage_->raw_pixel_buffer; if(image->depth == 32 || (image->depth == 24 && image->bitmap_pad == 32)) { if(want_r.width != static_cast(image->width) || want_r.height != static_cast(image->height)) @@ -567,10 +567,10 @@ namespace nana{ namespace paint for(int x = 0; x < image->width; ++x) { - pixbuf[x].u.element.red = fast_table[(px_data[x] >> 11) & 0x1F]; - pixbuf[x].u.element.green = (px_data[x] >> 5) & 0x3F; - pixbuf[x].u.element.blue = fast_table[px_data[x] & 0x1F]; - pixbuf[x].u.element.alpha_channel = 0; + pixbuf[x].element.red = fast_table[(px_data[x] >> 11) & 0x1F]; + pixbuf[x].element.green = (px_data[x] >> 5) & 0x3F; + pixbuf[x].element.blue = fast_table[px_data[x] & 0x1F]; + pixbuf[x].element.alpha_channel = 0; } img_data += image->bytes_per_line; pixbuf += want_r.width; @@ -627,7 +627,7 @@ namespace nana{ namespace paint { auto sp = storage_.get(); if(sp) - return sizeof(pixel_rgb_t) * (static_cast(sp->pixel_size.width) * static_cast(sp->pixel_size.height)); + return sizeof(pixel_argb_t) * (static_cast(sp->pixel_size.width) * static_cast(sp->pixel_size.height)); return 0; } @@ -641,26 +641,26 @@ namespace nana{ namespace paint return (storage_ ? storage_->pixel_size : nana::size()); } - pixel_rgb_t * pixel_buffer::at(const point& pos) const + pixel_argb_t * pixel_buffer::at(const point& pos) const { pixel_buffer_storage * sp = storage_.get(); if (sp && (pos.y < static_cast(sp->pixel_size.height) + sp->valid_r.y)) - return reinterpret_cast(reinterpret_cast(sp->raw_pixel_buffer) + sp->bytes_per_line * (pos.y - sp->valid_r.y)) + (pos.x - sp->valid_r.x); + return reinterpret_cast(reinterpret_cast(sp->raw_pixel_buffer) + sp->bytes_per_line * (pos.y - sp->valid_r.y)) + (pos.x - sp->valid_r.x); return nullptr; } - pixel_rgb_t * pixel_buffer::raw_ptr(std::size_t row) const + pixel_argb_t * pixel_buffer::raw_ptr(std::size_t row) const { pixel_buffer_storage * sp = storage_.get(); if(sp && (row < sp->pixel_size.height)) - return reinterpret_cast(reinterpret_cast(sp->raw_pixel_buffer) + sp->bytes_per_line * row); + return reinterpret_cast(reinterpret_cast(sp->raw_pixel_buffer) + sp->bytes_per_line * row); return nullptr; } - pixel_rgb_t * pixel_buffer::operator[](std::size_t row) const + pixel_argb_t * pixel_buffer::operator[](std::size_t row) const { pixel_buffer_storage * sp = storage_.get(); - return reinterpret_cast(reinterpret_cast(sp->raw_pixel_buffer) + sp->bytes_per_line * row); + return reinterpret_cast(reinterpret_cast(sp->raw_pixel_buffer) + sp->bytes_per_line * row); } void pixel_buffer::put(const unsigned char* rawbits, std::size_t width, std::size_t height, std::size_t bits_per_pixel, std::size_t bytes_per_line, bool is_negative) @@ -669,20 +669,20 @@ namespace nana{ namespace paint storage_->assign(rawbits, width, height, bits_per_pixel, bytes_per_line, is_negative); } - pixel_rgb_t pixel_buffer::pixel(int x, int y) const + pixel_argb_t pixel_buffer::pixel(int x, int y) const { pixel_buffer_storage * sp = storage_.get(); if(sp && 0 <= x && x < static_cast(sp->pixel_size.width) && 0 <= y && y < static_cast(sp->pixel_size.height)) - return *reinterpret_cast(reinterpret_cast(sp->raw_pixel_buffer + x) + y * sp->bytes_per_line); + return *reinterpret_cast(reinterpret_cast(sp->raw_pixel_buffer + x) + y * sp->bytes_per_line); - return pixel_rgb_t(); + return pixel_argb_t(); } - void pixel_buffer::pixel(int x, int y, pixel_rgb_t px) + void pixel_buffer::pixel(int x, int y, pixel_argb_t px) { pixel_buffer_storage * sp = storage_.get(); if(sp && 0 <= x && x < static_cast(sp->pixel_size.width) && 0 <= y && y < static_cast(sp->pixel_size.height)) - *reinterpret_cast(reinterpret_cast(sp->raw_pixel_buffer + x) + y * sp->bytes_per_line) = px; + *reinterpret_cast(reinterpret_cast(sp->raw_pixel_buffer + x) + y * sp->bytes_per_line) = px; } void pixel_buffer::paste(drawable_type drawable, int x, int y) const @@ -713,9 +713,9 @@ namespace nana{ namespace paint bi.bmiHeader.biWidth = sp->pixel_size.width; bi.bmiHeader.biHeight = -static_cast(sp->pixel_size.height); bi.bmiHeader.biPlanes = 1; - bi.bmiHeader.biBitCount = sizeof(pixel_rgb_t) * 8; + bi.bmiHeader.biBitCount = sizeof(pixel_argb_t) * 8; bi.bmiHeader.biCompression = BI_RGB; - bi.bmiHeader.biSizeImage = static_cast(sizeof(pixel_rgb_t) * sp->pixel_size.width * sp->pixel_size.height); + bi.bmiHeader.biSizeImage = static_cast(sizeof(pixel_argb_t) * sp->pixel_size.width * sp->pixel_size.height); bi.bmiHeader.biClrUsed = 0; bi.bmiHeader.biClrImportant = 0; @@ -742,9 +742,9 @@ namespace nana{ namespace paint bi.bmiHeader.biWidth = sp->pixel_size.width; bi.bmiHeader.biHeight = -static_cast(sp->pixel_size.height); bi.bmiHeader.biPlanes = 1; - bi.bmiHeader.biBitCount = sizeof(pixel_rgb_t) * 8; + bi.bmiHeader.biBitCount = sizeof(pixel_argb_t) * 8; bi.bmiHeader.biCompression = BI_RGB; - bi.bmiHeader.biSizeImage = static_cast(sizeof(pixel_rgb_t) * sp->pixel_size.width * sp->pixel_size.height); + bi.bmiHeader.biSizeImage = static_cast(sizeof(pixel_argb_t) * sp->pixel_size.width * sp->pixel_size.height); bi.bmiHeader.biClrUsed = 0; bi.bmiHeader.biClrImportant = 0; @@ -795,11 +795,11 @@ namespace nana{ namespace paint bool fade = (fade_rate != 0.0); unsigned char * fade_table = nullptr; - nana::pixel_rgb_t rgb_imd; + nana::pixel_argb_t rgb_imd; if(fade) { fade_table = detail::alloc_fade_table(1 - fade_rate); - rgb_imd.u.color = col; + rgb_imd.value = col; rgb_imd = detail::fade_color_intermedia(rgb_imd, fade_table); } @@ -810,7 +810,7 @@ namespace nana{ namespace paint if (solid) { - nana::pixel_rgb_t * p_rgb = sp->raw_pixel_buffer + ybeg * sp->pixel_size.width; + auto p_rgb = sp->raw_pixel_buffer + ybeg * sp->pixel_size.width; auto lineptr = p_rgb + xbeg; auto end = p_rgb + xend; if (fade) @@ -830,9 +830,8 @@ namespace nana{ namespace paint for (int top = ybeg; top < yend; ++top) { for (auto i = lineptr; i != end; ++i) - { - i->u.color = col; - } + i->value = col; + lineptr += sp->pixel_size.width; end = lineptr + (xend - xbeg); } @@ -842,10 +841,10 @@ namespace nana{ namespace paint if((ybeg == r.y) && (r.y + static_cast(r.height) == yend)) { - nana::pixel_rgb_t * p_rgb = sp->raw_pixel_buffer + ybeg * sp->pixel_size.width; - nana::pixel_rgb_t * i = p_rgb + xbeg; - nana::pixel_rgb_t * end = p_rgb + xend; - nana::pixel_rgb_t * i_other = sp->raw_pixel_buffer + (yend - 1) * sp->pixel_size.width + xbeg; + auto p_rgb = sp->raw_pixel_buffer + ybeg * sp->pixel_size.width; + auto i = p_rgb + xbeg; + auto end = p_rgb + xend; + auto i_other = sp->raw_pixel_buffer + (yend - 1) * sp->pixel_size.width + xbeg; if(fade) { for(;i != end; ++i, ++i_other) @@ -858,8 +857,8 @@ namespace nana{ namespace paint { for(;i != end; ++i, ++i_other) { - i->u.color = col; - i_other->u.color = col; + i->value = col; + i_other->value = col; } } } @@ -867,9 +866,9 @@ namespace nana{ namespace paint { if(ybeg == r.y) { - nana::pixel_rgb_t * p_rgb = sp->raw_pixel_buffer + ybeg * sp->pixel_size.width; - nana::pixel_rgb_t * i = p_rgb; - nana::pixel_rgb_t * end = p_rgb + xend; + auto p_rgb = sp->raw_pixel_buffer + ybeg * sp->pixel_size.width; + auto i = p_rgb; + auto end = p_rgb + xend; if(fade) { for(; i != end; ++i) @@ -878,15 +877,15 @@ namespace nana{ namespace paint else { for(;i != end; ++i) - i->u.color = col; + i->value = col; } } if(r.y + static_cast(r.height) == yend) { - nana::pixel_rgb_t * p_rgb = sp->raw_pixel_buffer + (yend - 1) * sp->pixel_size.width; - nana::pixel_rgb_t * i = p_rgb; - nana::pixel_rgb_t * end = p_rgb + xend; + auto p_rgb = sp->raw_pixel_buffer + (yend - 1) * sp->pixel_size.width; + auto i = p_rgb; + auto end = p_rgb + xend; if(fade) { @@ -896,18 +895,17 @@ namespace nana{ namespace paint else { for(;i != end; ++i) - i->u.color = col; + i->value = col; } } } if((xbeg == r.x) && (r.x + static_cast(r.width) == xend)) { - nana::pixel_rgb_t * p_rgb = sp->raw_pixel_buffer + ybeg * sp->pixel_size.width; - nana::pixel_rgb_t * i = p_rgb + xbeg; - nana::pixel_rgb_t * end = sp->raw_pixel_buffer + (yend - 1) * sp->pixel_size.width + xbeg; - - nana::pixel_rgb_t * i_other = p_rgb + (xend - 1); + auto p_rgb = sp->raw_pixel_buffer + ybeg * sp->pixel_size.width; + auto i = p_rgb + xbeg; + auto end = sp->raw_pixel_buffer + (yend - 1) * sp->pixel_size.width + xbeg; + auto i_other = p_rgb + (xend - 1); if(fade) { @@ -926,8 +924,8 @@ namespace nana{ namespace paint { while(true) { - i->u.color = col; - i_other->u.color = col; + i->value = col; + i_other->value = col; if(i == end) break; @@ -940,9 +938,9 @@ namespace nana{ namespace paint { if(xbeg == r.x) { - nana::pixel_rgb_t * p_rgb = sp->raw_pixel_buffer + ybeg * sp->pixel_size.width; - nana::pixel_rgb_t * i = p_rgb + xbeg; - nana::pixel_rgb_t * end = sp->raw_pixel_buffer + (yend - 1) * sp->pixel_size.width + xbeg; + auto p_rgb = sp->raw_pixel_buffer + ybeg * sp->pixel_size.width; + auto i = p_rgb + xbeg; + auto end = sp->raw_pixel_buffer + (yend - 1) * sp->pixel_size.width + xbeg; if(fade) { while(true) @@ -957,7 +955,7 @@ namespace nana{ namespace paint { while(true) { - i->u.color = col; + i->value = col; if(i == end) break; i += sp->pixel_size.width; @@ -967,9 +965,9 @@ namespace nana{ namespace paint if(r.x + static_cast(r.width) == xend) { - nana::pixel_rgb_t * p_rgb = sp->raw_pixel_buffer + ybeg * sp->pixel_size.width; - nana::pixel_rgb_t * i = p_rgb + (xend - 1); - nana::pixel_rgb_t * end = sp->raw_pixel_buffer + (yend - 1) * sp->pixel_size.width + (xend - 1); + auto p_rgb = sp->raw_pixel_buffer + ybeg * sp->pixel_size.width; + auto i = p_rgb + (xend - 1); + auto end = sp->raw_pixel_buffer + (yend - 1) * sp->pixel_size.width + (xend - 1); if(fade) { while(true) @@ -983,7 +981,7 @@ namespace nana{ namespace paint { while(true) { - i->u.color = col; + i->value = col; if(i == end) break; i += sp->pixel_size.width; } @@ -1011,7 +1009,7 @@ namespace nana{ namespace paint const int delta_g = (int((end & 0xFF00) << 8) - int(g = ((beg & 0xFF00) << 8))) / deltapx; const int delta_b = (int((end & 0xFF) << 16 ) - int(b = ((beg & 0xFF)<< 16))) / deltapx; - nana::pixel_rgb_t * pxbuf = sp->raw_pixel_buffer + rct.x + rct.y * sp->pixel_size.width; + auto pxbuf = sp->raw_pixel_buffer + rct.x + rct.y * sp->pixel_size.width; if(vertical) { if(deltapx + rct.y > 0) @@ -1020,12 +1018,12 @@ namespace nana{ namespace paint unsigned align_reset = rct.width & 3; while(deltapx--) { - nana::pixel_rgb_t px; + nana::pixel_argb_t px; - px.u.color = ((r += delta_r) & 0xFF0000) | (((g += delta_g) & 0xFF0000) >> 8) | (((b += delta_b) & 0xFF0000) >> 16); + px.value = ((r += delta_r) & 0xFF0000) | (((g += delta_g) & 0xFF0000) >> 8) | (((b += delta_b) & 0xFF0000) >> 16); - nana::pixel_rgb_t * dpx = pxbuf; - for(nana::pixel_rgb_t *dpx_end = pxbuf + align_4; dpx != dpx_end; dpx += 4) + auto dpx = pxbuf; + for(auto dpx_end = pxbuf + align_4; dpx != dpx_end; dpx += 4) { *dpx = px; dpx[1] = px; @@ -1033,7 +1031,7 @@ namespace nana{ namespace paint dpx[3] = px; } - for(nana::pixel_rgb_t * dpx_end = dpx + align_reset; dpx != dpx_end; ++dpx) + for(auto dpx_end = dpx + align_reset; dpx != dpx_end; ++dpx) *dpx = px; pxbuf += sp->pixel_size.width; @@ -1044,14 +1042,14 @@ namespace nana{ namespace paint { if(deltapx + rct.x > 0) { - nana::pixel_rgb_t * pxbuf_end = pxbuf + rct.width; + auto pxbuf_end = pxbuf + rct.width; for(; pxbuf != pxbuf_end; ++pxbuf) { - nana::pixel_rgb_t px; - px.u.color = ((r += delta_r) & 0xFF0000) | (((g += delta_g) & 0xFF0000) >> 8) | (((b += delta_b) & 0xFF0000) >> 16); - nana::pixel_rgb_t * dpx_end = pxbuf + rct.height * sp->pixel_size.width; - for(nana::pixel_rgb_t * dpx = pxbuf; dpx != dpx_end; dpx += sp->pixel_size.width) + nana::pixel_argb_t px; + px.value = ((r += delta_r) & 0xFF0000) | (((g += delta_g) & 0xFF0000) >> 8) | (((b += delta_b) & 0xFF0000) >> 16); + auto dpx_end = pxbuf + rct.height * sp->pixel_size.width; + for(auto dpx = pxbuf; dpx != dpx_end; dpx += sp->pixel_size.width) *dpx = px; } } @@ -1059,6 +1057,73 @@ namespace nana{ namespace paint } } + void pixel_buffer::gradual_rectangle(const ::nana::rectangle& draw_rct, const ::nana::expr_color& from, const ::nana::expr_color& to, double fade_rate, bool vertical) + { + pixel_buffer_storage * sp = storage_.get(); + if (nullptr == sp) return; + + nana::rectangle rct; + if (false == overlap(nana::rectangle(sp->pixel_size), draw_rct, rct)) + return; + + int deltapx = int(vertical ? rct.height : rct.width); + if (sp && deltapx) + { + auto beg = from.argb().value; + auto end = to.argb().value; + nana::color_t r, g, b; + const int delta_r = (int(end & 0xFF0000) - int(r = (beg & 0xFF0000))) / deltapx; + const int delta_g = (int((end & 0xFF00) << 8) - int(g = ((beg & 0xFF00) << 8))) / deltapx; + const int delta_b = (int((end & 0xFF) << 16) - int(b = ((beg & 0xFF) << 16))) / deltapx; + + auto pxbuf = sp->raw_pixel_buffer + rct.x + rct.y * sp->pixel_size.width; + if (vertical) + { + if (deltapx + rct.y > 0) + { + unsigned align_4 = (rct.width & ~3); + unsigned align_reset = rct.width & 3; + while (deltapx--) + { + nana::pixel_argb_t px; + + px.value = ((r += delta_r) & 0xFF0000) | (((g += delta_g) & 0xFF0000) >> 8) | (((b += delta_b) & 0xFF0000) >> 16); + + auto dpx = pxbuf; + for (auto dpx_end = pxbuf + align_4; dpx != dpx_end; dpx += 4) + { + *dpx = px; + dpx[1] = px; + dpx[2] = px; + dpx[3] = px; + } + + for (auto dpx_end = dpx + align_reset; dpx != dpx_end; ++dpx) + *dpx = px; + + pxbuf += sp->pixel_size.width; + } + } + } + else + { + if (deltapx + rct.x > 0) + { + auto pxbuf_end = pxbuf + rct.width; + + for (; pxbuf != pxbuf_end; ++pxbuf) + { + nana::pixel_argb_t px; + px.value = ((r += delta_r) & 0xFF0000) | (((g += delta_g) & 0xFF0000) >> 8) | (((b += delta_b) & 0xFF0000) >> 16); + auto dpx_end = pxbuf + rct.height * sp->pixel_size.width; + for (auto dpx = pxbuf; dpx != dpx_end; dpx += sp->pixel_size.width) + *dpx = px; + } + } + } + } + } + //stretch void pixel_buffer::stretch(const std::string& name) { diff --git a/source/paint/text_renderer.cpp b/source/paint/text_renderer.cpp index 005a3edb..0831c58f 100644 --- a/source/paint/text_renderer.cpp +++ b/source/paint/text_renderer.cpp @@ -40,9 +40,9 @@ namespace nana : dw(dw), x(x), endpos(endpos), text_align(ta) {} - unsigned operator()(int top, const nana::char_t * buf, std::size_t bufsize) + unsigned operator()(const int top, const nana::char_t * buf, std::size_t bufsize) { - int xpos = x; + nana::point pos{ x, top }; unsigned pixels = 0; bidi.linestr(buf, bufsize, reordered); switch(text_align) @@ -54,11 +54,11 @@ namespace nana nana::size ts = detail::text_extent_size(dw, ent.begin, len); if(ts.height > pixels) pixels = ts.height; - if(xpos + static_cast(ts.width) > 0) - detail::draw_string(dw, xpos, top, ent.begin, len); + if(pos.x + static_cast(ts.width) > 0) + detail::draw_string(dw, pos, ent.begin, len); - xpos += static_cast(ts.width); - if(xpos >= endpos) + pos.x += static_cast(ts.width); + if(pos.x >= endpos) break; } break; @@ -74,15 +74,15 @@ namespace nana widths.push_back(ts.width); } - xpos += (endpos - xpos - static_cast(lenpx))/2; + pos.x += (endpos - pos.x - static_cast(lenpx))/2; auto ipx = widths.begin(); for(auto & ent : reordered) { - if(xpos + static_cast(*ipx) > 0) - detail::draw_string(dw, xpos, top, ent.begin, ent.end - ent.begin); + if(pos.x + static_cast(*ipx) > 0) + detail::draw_string(dw, pos, ent.begin, ent.end - ent.begin); - xpos += static_cast(*ipx); - if(xpos >= endpos) + pos.x += static_cast(*ipx); + if(pos.x >= endpos) break; } } @@ -90,7 +90,7 @@ namespace nana case align::right: { int xend = endpos; - std::swap(xpos, xend); + std::swap(pos.x, xend); for(auto i = reordered.rbegin(), end = reordered.rend(); i != end; ++i) { auto & ent = *i; @@ -98,13 +98,13 @@ namespace nana nana::size ts = detail::text_extent_size(dw, ent.begin, len); if(ts.height > pixels) pixels = ts.height; - if(xpos > xend) + if(pos.x > xend) { - xpos -= static_cast(ts.width); - detail::draw_string(dw, xpos, top, i->begin, len); + pos.x -= static_cast(ts.width); + detail::draw_string(dw, pos, i->begin, len); } - if(xpos <= xend || xpos <= 0) + if(pos.x <= xend || pos.x <= 0) break; } } @@ -118,7 +118,7 @@ namespace nana { graphics & graph; int x, endpos; - nana::color_t color; + nana::color_t color; //deprecated unsigned omitted_pixels; nana::unicode_bidi bidi; std::vector reordered; @@ -133,10 +133,20 @@ namespace nana this->endpos = x; } - unsigned operator()(int top, const nana::char_t * buf, std::size_t bufsize) + draw_string_omitted(graphics& graph, int x, int endpos, bool omitted) + : graph(graph), x(x), endpos(endpos) + { + omitted_pixels = (omitted ? graph.text_extent_size(STR("..."), 3).width : 0); + if (endpos - x > static_cast(omitted_pixels)) + this->endpos -= omitted_pixels; + else + this->endpos = x; + } + + unsigned operator()(const int top, const nana::char_t * buf, std::size_t bufsize) { drawable_type dw = graph.handle(); - int xpos = x; + ::nana::point pos{ x, top }; unsigned pixels = 0; bidi.linestr(buf, bufsize, reordered); for(auto & i : reordered) @@ -145,27 +155,27 @@ namespace nana nana::size ts = detail::text_extent_size(dw, i.begin, len); if(ts.height > pixels) pixels = ts.height; - if(xpos + static_cast(ts.width) <= endpos) + if(pos.x + static_cast(ts.width) <= endpos) { - detail::draw_string(dw, xpos, top, i.begin, len); - xpos += static_cast(ts.width); + detail::draw_string(dw, pos, i.begin, len); + pos.x += static_cast(ts.width); } else { nana::rectangle r; - r.width = endpos - xpos; + r.width = endpos - pos.x; r.height = ts.height; nana::paint::graphics dum_graph(r.width, r.height); - dum_graph.bitblt(r, graph, nana::point(xpos, top)); + dum_graph.bitblt(r, graph, pos); dum_graph.string(0, 0, color, i.begin, len); - r.x = xpos; + r.x = pos.x; r.y = top; graph.bitblt(r, dum_graph); if(omitted_pixels) - detail::draw_string(dw, endpos, top, STR("..."), 3); + detail::draw_string(dw, point{ endpos, top }, STR("..."), 3); break; } } @@ -187,7 +197,7 @@ namespace nana : graph(graph), x(x), endpos(endpos), text_align(ta) {} - unsigned operator()(int top, const nana::char_t * buf, std::size_t bufsize) + unsigned operator()(const int top, const nana::char_t * buf, std::size_t bufsize) { unsigned pixels = 0; @@ -208,7 +218,7 @@ namespace nana { pixels = 0; unsigned line_pixels = 0; - int xpos = x; + nana::point pos{ x, top }; int orig_top = top; auto i_ts_keeper = ts_keeper.cbegin(); for(auto & i : reordered) @@ -216,7 +226,7 @@ namespace nana if(line_pixels < i_ts_keeper->height) line_pixels = i_ts_keeper->height; - bool beyond_edge = (xpos + static_cast(i_ts_keeper->width) > endpos); + bool beyond_edge = (pos.x + static_cast(i_ts_keeper->width) > endpos); if(beyond_edge) { std::size_t len = i.end - i.begin; @@ -229,21 +239,21 @@ namespace nana do { - idx_splitted = find_splitted(idx_head, len, xpos, endpos, pxbuf); + idx_splitted = find_splitted(idx_head, len, pos.x, endpos, pxbuf); if(idx_splitted == len) { - detail::draw_string(dw, xpos, top, i.begin + idx_head, idx_splitted - idx_head); + detail::draw_string(dw, pos, i.begin + idx_head, idx_splitted - idx_head); for(std::size_t i = idx_head; i < len; ++i) - xpos += static_cast(pxbuf[i]); + pos.x += static_cast(pxbuf[i]); break; } //Check the word whether it is splittable. if(splittable(i.begin, idx_splitted)) { - detail::draw_string(dw, xpos, top, i.begin + idx_head, idx_splitted - idx_head); + detail::draw_string(dw, pos, i.begin + idx_head, idx_splitted - idx_head); idx_head = idx_splitted; - xpos = x; - top += line_pixels; + pos.x = x; + pos.y += line_pixels; line_pixels = i_ts_keeper->height; } else @@ -260,10 +270,10 @@ namespace nana if(u != head) { - detail::draw_string(dw, xpos, top, head, u - head); + detail::draw_string(dw, pos, head, u - head); idx_head += u - head; - xpos = x; - top += line_pixels; + pos.x = x; + pos.y += static_cast(line_pixels); line_pixels = i_ts_keeper->height; } else @@ -276,17 +286,17 @@ namespace nana break; } std::size_t splen = u - head; - top += line_pixels; - xpos = x; - detail::draw_string(dw, x, top, head, splen); + pos.y += static_cast(line_pixels); + pos.x = x; + detail::draw_string(dw, pos, head, splen); line_pixels = i_ts_keeper->height; for(std::size_t k = idx_head; k < idx_head + splen; ++k) - xpos += static_cast(pxbuf[k]); - if(xpos >= endpos) + pos.x += static_cast(pxbuf[k]); + if (pos.x >= endpos) { - xpos = x; - top += line_pixels; + pos.x = x; + pos.y += static_cast(line_pixels); line_pixels = i_ts_keeper->height; } idx_head += splen; @@ -298,15 +308,17 @@ namespace nana } else { - detail::draw_string(dw, x, top += static_cast(line_pixels), i.begin, 1); - xpos = x + static_cast(i_ts_keeper->width); + pos.x = x; + pos.y += static_cast(line_pixels); + detail::draw_string(dw, pos, i.begin, 1); + pos.x += static_cast(i_ts_keeper->width); } line_pixels = 0; } else { - detail::draw_string(dw, xpos, top, i.begin, i.end - i.begin); - xpos += static_cast(i_ts_keeper->width); + detail::draw_string(dw, pos, i.begin, i.end - i.begin); + pos.x += static_cast(i_ts_keeper->width); } ++i_ts_keeper; @@ -319,24 +331,24 @@ namespace nana //The text could be drawn in a line. if((align::left == text_align) || (align::center == text_align)) { - int xpos = x; + point pos{ x, top }; if(align::center == text_align) - xpos += (endpos - x - static_cast(str_w)) / 2; + pos.x += (endpos - x - static_cast(str_w)) / 2; auto i_ts_keeper = ts_keeper.cbegin(); for(auto & ent : reordered) { const nana::size & ts = *i_ts_keeper; - if(xpos + static_cast(ts.width) > 0) - detail::draw_string(dw, xpos, top, ent.begin, ent.end - ent.begin); + if (pos.x + static_cast(ts.width) > 0) + detail::draw_string(dw, pos, ent.begin, ent.end - ent.begin); - xpos += static_cast(ts.width); + pos.x += static_cast(ts.width); ++i_ts_keeper; } } else if(align::right == text_align) { - int xpos = endpos; + point pos{ endpos, top }; auto i_ts_keeper = ts_keeper.crbegin(); for(auto i = reordered.crbegin(), end = reordered.crend(); i != end; ++i) { @@ -344,9 +356,9 @@ namespace nana std::size_t len = ent.end - ent.begin; const nana::size & ts = *i_ts_keeper; - xpos -= ts.width; - if(xpos >= 0) - detail::draw_string(dw, xpos, top, ent.begin, len); + pos.x -= static_cast(ts.width); + if (pos.x >= 0) + detail::draw_string(dw, pos, ent.begin, len); ++i_ts_keeper; } } @@ -583,6 +595,15 @@ namespace nana } return extents; } + + void text_renderer::render(const nana::point& pos, const nana::char_t* str, std::size_t len, unsigned restricted_pixels, bool omitted) + { + if (graph_) + { + helper::draw_string_omitted dso(graph_, pos.x, pos.x + static_cast(restricted_pixels), omitted); + helper::for_each_line(str, len, pos.y, dso); + } + } //end class text_renderer