diff --git a/include/nana/gui/basis.hpp b/include/nana/gui/basis.hpp index 9cf8147c..a46835ad 100644 --- a/include/nana/gui/basis.hpp +++ b/include/nana/gui/basis.hpp @@ -71,30 +71,31 @@ namespace nana struct keyboard { - enum t{ + enum{ //Control Code for ASCII - select_all = 0x1, - end_of_text = 0x3, //Ctrl+C - backspace = 0x8, tab = 0x9, - enter_n = 0xA, enter = 0xD, enter_r = 0xD, - alt = 0x12, - sync_idel = 0x16, //Ctrl+V - cancel = 0x18, //Ctrl+X - end_of_medium = 0x19, //Ctrl+Y - substitute = 0x1A, //Ctrl+Z - escape = 0x1B, + start_of_headline = 0x1, //Ctrl+A + end_of_text = 0x3, //Ctrl+C + backspace = 0x8, tab = 0x9, + enter_n = 0xA, enter = 0xD, enter_r = 0xD, + alt = 0x12, + sync_idel = 0x16, //Ctrl+V + cancel = 0x18, //Ctrl+X + end_of_medium = 0x19, //Ctrl+Y + substitute = 0x1A, //Ctrl+Z + escape = 0x1B, //The following names are intuitive name of ASCII control codes - copy = 0x3, //end_of_text - paste = 0x16, //sync_idel - cut = 0x18, //cancel - redo = 0x19, //end_of_medium - undo = 0x1A, //substitue + select_all = start_of_headline, + copy = end_of_text, + paste = sync_idel, + cut = cancel, + redo = end_of_medium, + undo = substitute, //System Code for OS - os_pageup = 0x21, os_pagedown, - os_arrow_left = 0x25, os_arrow_up, os_arrow_right, os_arrow_down, - os_insert = 0x2D, os_del + os_pageup = 0x21, os_pagedown, + os_arrow_left = 0x25, os_arrow_up, os_arrow_right, os_arrow_down, + os_insert = 0x2D, os_del }; }; diff --git a/include/nana/paint/pixel_buffer.hpp b/include/nana/paint/pixel_buffer.hpp index acc52ea2..8de827a7 100644 --- a/include/nana/paint/pixel_buffer.hpp +++ b/include/nana/paint/pixel_buffer.hpp @@ -1,6 +1,7 @@ /* * Pixel Buffer Implementation - * Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com) + * Nana C++ Library(http://www.nanapro.org) + * Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -19,14 +20,14 @@ namespace nana{ namespace paint { ///@brief Seek a pixel address by using offset bytes ///@return the specified pixel address - inline pixel_argb_t * pixel_at(pixel_argb_t * p, std::size_t bytes) + inline pixel_color_t * pixel_at(pixel_color_t * p, std::size_t bytes) { - return reinterpret_cast(reinterpret_cast(p) + bytes); + return reinterpret_cast(reinterpret_cast(p)+bytes); } - inline const pixel_argb_t * pixel_at(const pixel_argb_t * p, std::size_t bytes) + inline const pixel_color_t * pixel_at(const pixel_color_t * p, std::size_t bytes) { - return reinterpret_cast(reinterpret_cast(p) + bytes); + return reinterpret_cast(reinterpret_cast(p)+bytes); } class pixel_buffer @@ -34,7 +35,7 @@ namespace nana{ namespace paint struct pixel_buffer_storage; typedef bool (pixel_buffer:: * unspecified_bool_t)() const; public: - pixel_buffer(); + pixel_buffer() = default; pixel_buffer(drawable_type, const nana::rectangle& want_rectangle); pixel_buffer(drawable_type, std::size_t top, std::size_t lines); pixel_buffer(std::size_t width, std::size_t height); @@ -60,9 +61,9 @@ namespace nana{ namespace paint std::size_t bytes_per_line() const; nana::size size() 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; + pixel_color_t * at(const point& pos) const; + pixel_color_t * raw_ptr(std::size_t row) const; + pixel_color_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,11 +71,10 @@ namespace nana{ namespace paint void line(const ::nana::point& pos_beg, const ::nana::point& pos_end, const ::nana::expr_color&, double fade_rate); void rectangle(const nana::rectangle&, const ::nana::expr_color&, double fade_rate, bool solid); - //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_argb_t pixel(int x, int y) const; - void pixel(int x, int y, pixel_argb_t); + pixel_color_t pixel(int x, int y) const; + void pixel(int x, int y, pixel_color_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/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 3574abbb..5c106f2a 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -1165,12 +1165,16 @@ namespace nana{ namespace widgets bool text_editor::respone_keyboard(nana::char_t key, bool enterable) //key is a character of ASCII code { - if (keyboard::end_of_text == key) + switch (key) { + case keyboard::end_of_text: copy(); return false; + case keyboard::select_all: + select(true); + return true; } - + if (attributes_.editable && enterable) { switch (key) @@ -1577,6 +1581,7 @@ namespace nana{ namespace widgets if(select_.b.y) --select_.b.y; select_.b.x = static_cast(textbase_.getline(select_.b.y).size()); select_.mode_selection = selection::mode_method_selected; + render(true); return true; } @@ -1939,6 +1944,7 @@ namespace nana{ namespace widgets void text_editor::move_left() { + bool do_render = false; if(_m_cancel_select(1) == false) { if(points_.caret.x) @@ -1952,23 +1958,19 @@ namespace nana{ namespace widgets if (attributes_.line_wrapped) adjust_y = behavior_->adjust_caret_into_screen(); - bool adjust_x = _m_move_offset_x_while_over_border(-2); - - if (adjust_x || adjust_y) - render(true); + do_render = (_m_move_offset_x_while_over_border(-2) || adjust_y); } else if(points_.caret.y) { //Move to previous line points_.caret.x = static_cast(textbase_.getline(-- points_.caret.y).size()); - if (behavior_->adjust_caret_into_screen()) - render(true); + do_render = behavior_->adjust_caret_into_screen(); } } else - { - behavior_->adjust_caret_into_screen(); + do_render = behavior_->adjust_caret_into_screen(); + + if (do_render) render(true); - } _m_scrollbar(); points_.xpos = points_.caret.x; @@ -1976,6 +1978,7 @@ namespace nana{ namespace widgets void text_editor::move_right() { + bool do_render = false; if(_m_cancel_select(2) == false) { nana::string lnstr = textbase_.getline(points_.caret.y); @@ -1987,23 +1990,20 @@ namespace nana{ namespace widgets ++points_.caret.x; #endif bool adjust_y = (attributes_.line_wrapped && behavior_->adjust_caret_into_screen()); - if (_m_move_offset_x_while_over_border(2) || adjust_y) - render(true); + do_render = (_m_move_offset_x_while_over_border(2) || adjust_y); } else if(textbase_.lines() && (points_.caret.y < textbase_.lines() - 1)) { //Move to next line points_.caret.x = 0; ++ points_.caret.y; - - if (behavior_->adjust_caret_into_screen()) - render(true); + do_render = behavior_->adjust_caret_into_screen(); } } else - { - if (behavior_->adjust_caret_into_screen()) - render(true); - } + do_render = behavior_->adjust_caret_into_screen(); + + if (do_render) + render(true); _m_scrollbar(); points_.xpos = points_.caret.x; diff --git a/source/gui/widgets/slider.cpp b/source/gui/widgets/slider.cpp index bc2e3f32..cad802dc 100644 --- a/source/gui/widgets/slider.cpp +++ b/source/gui/widgets/slider.cpp @@ -38,7 +38,7 @@ namespace nana } else { - graph.gradual_rectangle({ ad.fixedpos, ad.bound.x, upperblock, len }, clr_from, clr_trans, false); //deprecatd + graph.gradual_rectangle({ ad.fixedpos, ad.bound.x, upperblock, len }, clr_from, clr_trans, false); graph.gradual_rectangle({ ad.fixedpos + static_cast(upperblock), ad.bound.x, ad.block - upperblock, len }, clr_trans, clr_to, false); } } @@ -69,8 +69,10 @@ namespace nana class controller { public: - enum dir_t{DirHorizontal, DirVertical}; - enum where_t{WhereNone, WhereBar, WhereSlider}; + enum class style{horizontal, vertical}; + enum class parts{none, bar, slider}; + //enum dir_t{DirHorizontal, DirVertical}; //deprecated + //enum where_t{WhereNone, WhereBar, WhereSlider}; typedef drawer_trigger::graph_reference graph_reference; @@ -83,7 +85,7 @@ namespace nana proto_.renderer = pat::cloneable(interior_renderer()); attr_.skdir = seekdir::bilateral; - attr_.dir = this->DirHorizontal; + attr_.dir = style::horizontal; attr_.vcur = 0; attr_.vmax = 10; attr_.slider_scale = 8; @@ -142,7 +144,7 @@ namespace nana void vertical(bool v) { - dir_t dir = (v ? this->DirVertical : this->DirHorizontal); + auto dir = (v ? style::vertical : style::horizontal); if(dir != attr_.dir) { @@ -153,7 +155,7 @@ namespace nana bool vertical() const { - return (this->DirVertical == attr_.dir); + return (style::vertical == attr_.dir); } void vmax(unsigned m) @@ -203,56 +205,56 @@ namespace nana attr_.adorn_pos = attr_.pos; } - where_t seek_where(int x, int y) const + parts seek_where(::nana::point pos) const { nana::rectangle r = _m_bar_area(); - if(attr_.dir == this->DirVertical) + if(style::vertical == attr_.dir) { - std::swap(x, y); + std::swap(pos.x, pos.y); std::swap(r.width, r.height); } - int pos = _m_slider_pos(); - if(pos <= x && x < pos + static_cast(attr_.slider_scale)) - return WhereSlider; + int sdpos = _m_slider_pos(); + if (sdpos <= pos.x && pos.x < sdpos + static_cast(attr_.slider_scale)) + return parts::slider; - pos = static_cast(attr_.slider_scale) / 2; + sdpos = static_cast(attr_.slider_scale) / 2; - if(pos <= x && x < pos + static_cast(r.width)) + if (sdpos <= pos.x && pos.x < sdpos + static_cast(r.width)) { - if(y < r.y + static_cast(r.height)) - return WhereBar; + if(pos.y < r.y + static_cast(r.height)) + return parts::bar; } - return WhereNone; + return parts::none; } //set_slider_pos //move the slider to a position where a mouse click on WhereBar. - bool set_slider_pos(int x, int y) + bool set_slider_pos(::nana::point pos) { - if(this->DirVertical == attr_.dir) - std::swap(x, y); + if(style::vertical == attr_.dir) + std::swap(pos.x, pos.y); - x -= _m_slider_refpos(); - if(x < 0) + pos.x -= _m_slider_refpos(); + if(pos.x < 0) return false; - if(x > static_cast(_m_scale())) - x = static_cast(_m_scale()); + if(pos.x > static_cast(_m_scale())) + pos.x = static_cast(_m_scale()); - double pos = attr_.pos; - double dx = _m_evaluate_by_seekdir(x); + double attr_pos = attr_.pos; + double dx = _m_evaluate_by_seekdir(pos.x); attr_.pos = dx; attr_.adorn_pos = dx; _m_mk_slider_value_by_pos(); - return (attr_.pos != pos); + return (attr_.pos != attr_pos); } void set_slider_refpos(::nana::point pos) { - if(this->DirVertical == attr_.dir) + if(style::vertical == attr_.dir) std::swap(pos.x, pos.y); slider_state_.trace = slider_state_.TraceCapture; @@ -286,21 +288,21 @@ namespace nana return (slider_state_.trace == slider_state_.TraceCapture); } - bool move_slider(int x, int y) + bool move_slider(const ::nana::point& pos) { - int mpos = (this->DirHorizontal == attr_.dir ? x : y); - int pos = slider_state_.snap_pos + (mpos - slider_state_.refpos.x); + int mpos = (style::horizontal == attr_.dir ? pos.x : pos.y); + int adorn_pos = slider_state_.snap_pos + (mpos - slider_state_.refpos.x); - if(pos > 0) + if (adorn_pos > 0) { int scale = static_cast(_m_scale()); - if(pos > scale) - pos = scale; + if (adorn_pos > scale) + adorn_pos = scale; } else - pos = 0; + adorn_pos = 0; - double dstpos = _m_evaluate_by_seekdir(pos); + double dstpos = _m_evaluate_by_seekdir(adorn_pos); attr_.is_draw_adorn = true; if(dstpos != attr_.pos) @@ -312,15 +314,15 @@ namespace nana return false; } - bool move_adorn(int x, int y) + bool move_adorn(const ::nana::point& pos) { - double xpos = (this->DirHorizontal == attr_.dir ? x : y); + double xpos = (style::horizontal == attr_.dir ? pos.x : pos.y); xpos -= _m_slider_refpos(); if(xpos > static_cast(_m_scale())) xpos = static_cast(_m_scale()); - int pos = static_cast(attr_.adorn_pos); + int adorn_pos = static_cast(attr_.adorn_pos); xpos = _m_evaluate_by_seekdir(xpos); attr_.adorn_pos = xpos; @@ -329,7 +331,7 @@ namespace nana if(slider_state_.trace == slider_state_.TraceNone) slider_state_.trace = slider_state_.TraceOver; - return (pos != static_cast(xpos)); + return (adorn_pos != static_cast(xpos)); } unsigned move_step(bool forward) @@ -385,7 +387,7 @@ namespace nana { auto sz = other_.graph->size(); nana::rectangle r = sz; - if(this->DirHorizontal == attr_.dir) + if(style::horizontal == attr_.dir) { r.x = attr_.slider_scale / 2 - attr_.border; r.width = (static_cast(sz.width) > (r.x << 1) ? sz.width - (r.x << 1) : 0); @@ -401,7 +403,7 @@ namespace nana unsigned _m_scale() const { nana::rectangle r = _m_bar_area(); - return ((this->DirHorizontal == attr_.dir ? r.width : r.height) - attr_.border * 2); + return ((style::horizontal == attr_.dir ? r.width : r.height) - attr_.border * 2); } double _m_evaluate_by_seekdir(double pos) const @@ -465,7 +467,7 @@ namespace nana { renderer::bar_t bar; - bar.horizontal = (this->DirHorizontal == attr_.dir); + bar.horizontal = (style::horizontal == attr_.dir); bar.border_size = attr_.border; bar.r = _m_bar_area(); @@ -494,35 +496,23 @@ namespace nana nana::string str = proto_.provider->adorn_trace(attr_.vmax, vadorn); if(str.size()) { - nana::rectangle r; nana::size ts = other_.graph->text_extent_size(str); ts.width += 6; ts.height += 2; - r.width = ts.width; - r.height = ts.height; - + int x, y; const int room = static_cast(attr_.adorn_pos); if(bar.horizontal) { - r.y = adorn.fixedpos + static_cast(adorn.block - ts.height) / 2; - if(room > static_cast(ts.width + 2)) - r.x = room - static_cast(ts.width + 2); - else - r.x = room + 2; - - r.x += this->_m_slider_refpos(); + y = adorn.fixedpos + static_cast(adorn.block - ts.height) / 2; + x = (room > static_cast(ts.width + 2) ? room - static_cast(ts.width + 2) : room + 2) + _m_slider_refpos(); } else { - r.x = (other_.graph->width() - ts.width) / 2; - if(room > static_cast(ts.height + 2)) - r.y = room - static_cast(ts.height + 2); - else - r.y = room + 2; - r.y += this->_m_slider_refpos(); + x = (other_.graph->width() - ts.width) / 2; + y = (room > static_cast(ts.height + 2) ? room - static_cast(ts.height + 2) : room + 2) + _m_slider_refpos(); } - proto_.renderer->adorn_textbox(other_.wd, *other_.graph, str, r); + proto_.renderer->adorn_textbox(other_.wd, *other_.graph, str, {x, y, ts.width, ts.height}); } } } @@ -531,7 +521,7 @@ namespace nana { renderer::slider_t s; s.pos = static_cast(attr_.pos); - s.horizontal = (this->DirHorizontal == attr_.dir); + s.horizontal = (style::horizontal == attr_.dir); s.scale = attr_.slider_scale; s.border = attr_.border; proto_.renderer->slider(other_.wd, *other_.graph, s); @@ -553,7 +543,7 @@ namespace nana struct attr_tag { seekdir skdir; - dir_t dir; + style dir; unsigned border; unsigned vmax; unsigned vcur; @@ -607,10 +597,11 @@ namespace nana void trigger::mouse_down(graph_reference, const arg_mouse& arg) { - controller_t::where_t what = impl_->seek_where(arg.pos.x, arg.pos.y); - if(controller_t::WhereBar == what || controller_t::WhereSlider == what) + using parts = controller_t::parts; + auto what = impl_->seek_where(arg.pos); + if(parts::bar == what || parts::slider == what) { - bool mkdir = impl_->set_slider_pos(arg.pos.x, arg.pos.y); + bool mkdir = impl_->set_slider_pos(arg.pos); impl_->set_slider_refpos(arg.pos); if(mkdir) { @@ -635,13 +626,13 @@ namespace nana bool mkdraw = false; if(impl_->if_trace_slider()) { - mkdraw = impl_->move_slider(arg.pos.x, arg.pos.y); + mkdraw = impl_->move_slider(arg.pos); } else { - controller_t::where_t what = impl_->seek_where(arg.pos.x, arg.pos.y); - if(controller_t::WhereNone != what) - mkdraw = impl_->move_adorn(arg.pos.x, arg.pos.y); + auto what = impl_->seek_where(arg.pos); + if(controller_t::parts::none != what) + mkdraw = impl_->move_adorn(arg.pos); else mkdraw = impl_->reset_adorn(); } diff --git a/source/gui/widgets/treebox.cpp b/source/gui/widgets/treebox.cpp index 6e089c21..86121598 100644 --- a/source/gui/widgets/treebox.cpp +++ b/source/gui/widgets/treebox.cpp @@ -1225,9 +1225,7 @@ namespace nana if(pos_.y < item_pos_.y + static_cast(node_r.height)) { - int logic_x = pos_.x - item_pos_.x; - int logic_y = pos_.y - item_pos_.y; - + auto logic_pos = pos_ - item_pos_; node_ = &node; for(int comp = static_cast(component::begin); comp != static_cast(component::end); ++comp) @@ -1235,7 +1233,7 @@ namespace nana nana::rectangle r = node_r; if(comp_placer->locate(static_cast(comp), node_attr_, &r)) { - if(r.is_hit(logic_x, logic_y)) + if(r.is_hit(logic_pos)) { what_ = static_cast(comp); if(component::expender == what_ && (false == node_attr_.has_children)) @@ -1275,10 +1273,7 @@ namespace nana nana::rectangle trigger::item_locator::text_pos() const { - auto r = node_text_r_; - r.x += item_pos_.x; - r.y += item_pos_.y; - return r; + return{node_text_r_.x + item_pos_.x, node_text_r_.y + item_pos_.y, node_text_r_.width, node_text_r_.height}; } //end class item_locator @@ -1289,10 +1284,10 @@ namespace nana typedef tree_cont_type::node_type node_type; item_renderer(implement * impl, const nana::point& pos) - :impl_(impl), pos_(pos) + : impl_(impl), pos_(pos), + bgcolor_(impl->data.widget_ptr->bgcolor()), + fgcolor_(impl->data.widget_ptr->fgcolor()) { - bgcolor_ = impl_->data.widget_ptr->bgcolor(); - fgcolor_ = impl_->data.widget_ptr->fgcolor(); } //affect @@ -1762,7 +1757,6 @@ namespace nana unsigned trigger::node_width(const node_type *node) const { - //return (static_cast(impl_->data.graph->text_extent_size(node->value.second.text).width) + impl_->shape.text_offset * 2 + static_cast(impl_->shape.crook_pixels + impl_->shape.image_pixels)); node_attribute node_attr; impl_->assign_node_attr(node_attr, node); return impl_->data.comp_placer->item_width(*impl_->data.graph, node_attr); diff --git a/source/paint/gadget.cpp b/source/paint/gadget.cpp index 620bcec4..a1441929 100644 --- a/source/paint/gadget.cpp +++ b/source/paint/gadget.cpp @@ -1,6 +1,7 @@ /* * Graphics Gadget Implementation - * Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com) + * Nana C++ Library(http://www.nanapro.org) + * Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -260,60 +261,6 @@ namespace gadget } } - /* - void cross(graphics& graph, int x, int y, uint32_t size, uint32_t thickness, ::nana::color_t color) //deprecated - { - 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::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) diff --git a/source/paint/pixel_buffer.cpp b/source/paint/pixel_buffer.cpp index c7337a0a..6af6635a 100644 --- a/source/paint/pixel_buffer.cpp +++ b/source/paint/pixel_buffer.cpp @@ -1,6 +1,7 @@ /* * Pixel Buffer Implementation - * Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com) + * Nana C++ Library(http://www.nanapro.org) + * Copyright(C) 2003-2014 Jinhao(cnjinhao@hotmail.com) * * Distributed under the Boost Software License, Version 1.0. * (See accompanying file LICENSE_1_0.txt or copy at @@ -21,7 +22,6 @@ namespace nana{ namespace paint { - nana::rectangle valid_rectangle(const nana::size& s, const nana::rectangle& r) { nana::rectangle good_r; @@ -29,6 +29,21 @@ namespace nana{ namespace paint return good_r; } +#if defined(NANA_WINDOWS) + void assign_windows_bitmapinfo(const size& sz, BITMAPINFO& bi) + { + bi.bmiHeader.biSize = sizeof(bi.bmiHeader); + bi.bmiHeader.biWidth = sz.width; + bi.bmiHeader.biHeight = -static_cast(sz.height); + bi.bmiHeader.biPlanes = 1; + bi.bmiHeader.biBitCount = 32; + bi.bmiHeader.biCompression = BI_RGB; + bi.bmiHeader.biSizeImage = static_cast(sz.width * sz.height * sizeof(pixel_color_t)); + bi.bmiHeader.biClrUsed = 0; + bi.bmiHeader.biClrImportant = 0; + } +#endif + struct pixel_buffer::pixel_buffer_storage : private nana::noncopyable { @@ -36,9 +51,9 @@ namespace nana{ namespace paint const drawable_type drawable; //Attached handle const nana::rectangle valid_r; const nana::size pixel_size; - pixel_argb_t * raw_pixel_buffer; + pixel_color_t * raw_pixel_buffer; const std::size_t bytes_per_line; - bool alpha_channel; + bool alpha_channel{false}; #if defined(NANA_X11) struct x11_members { @@ -49,25 +64,20 @@ namespace nana{ namespace paint struct image_processor_tag { - paint::image_process::stretch_interface * stretch_receptacle; + paint::image_process::stretch_interface * stretch_receptacle{nullptr}; paint::image_process::stretch_interface * const * stretch; - paint::image_process::alpha_blend_interface * alpha_blend_receptacle; + paint::image_process::alpha_blend_interface * alpha_blend_receptacle{nullptr}; paint::image_process::alpha_blend_interface * const * alpha_blend; - paint::image_process::blend_interface * blend_receptacle; + paint::image_process::blend_interface * blend_receptacle{nullptr}; paint::image_process::blend_interface * const * blend; - paint::image_process::line_interface * line_receptacle; + paint::image_process::line_interface * line_receptacle{nullptr}; paint::image_process::line_interface * const * line; - paint::image_process::blur_interface * blur_receptacle; + paint::image_process::blur_interface * blur_receptacle{nullptr}; paint::image_process::blur_interface * const * blur; image_processor_tag() - : stretch_receptacle(nullptr), - alpha_blend_receptacle(nullptr), - blend_receptacle(nullptr), - line_receptacle(nullptr), - blur_receptacle(nullptr) { - detail::image_process_provider & provider = detail::image_process_provider::instance(); + auto & provider = detail::image_process_provider::instance(); stretch = provider.stretch(); alpha_blend = provider.alpha_blend(); blend = provider.blend(); @@ -80,9 +90,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_argb_t[width * height]), - bytes_per_line(width * sizeof(pixel_argb_t)), - alpha_channel(false) + raw_pixel_buffer(new pixel_color_t[width * height]), + bytes_per_line(width * sizeof(pixel_color_t)) { #if defined(NANA_X11) nana::detail::platform_spec & spec = nana::detail::platform_spec::instance(); @@ -109,13 +118,12 @@ 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)), - bytes_per_line(drawable->bytes_per_line), + 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_argb_t) * valid_r.width), + bytes_per_line(sizeof(pixel_color_t) * valid_r.width) #endif - alpha_channel(false) { #if defined(NANA_X11) nana::detail::platform_spec & spec = nana::detail::platform_spec::instance(); @@ -134,12 +142,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_argb_t[valid_r.width * valid_r.height]; + raw_pixel_buffer = new pixel_color_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,160 +178,126 @@ 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) { + if (!raw_pixel_buffer) + return; + auto rawptr = raw_pixel_buffer; - if(rawptr) + if(32 == bits_per_pixel) { - if(32 == bits_per_pixel) + if((pixel_size.width == width) && (pixel_size.height == height) && is_negative) { - if((pixel_size.width == width) && (pixel_size.height == height) && is_negative) - { - memcpy(rawptr, rawbits, (pixel_size.width * pixel_size.height) * 4); - } - else - { - 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; - - auto d = rawptr; - if(is_negative) - { - const unsigned char* s = rawbits; - for(std::size_t i = 0; i < height; ++i) - { - memcpy(d, s, line_bytes); - d += pixel_size.width; - s += bytes_per_line; - } - } - else - { - const unsigned char* s = rawbits + bytes_per_line * (height - 1); - for(std::size_t i = 0; i < height; ++i) - { - memcpy(d, s, line_bytes); - d += pixel_size.width; - s -= bytes_per_line; - } - } - } + memcpy(rawptr, rawbits, (pixel_size.width * pixel_size.height) * 4); } - else if(24 == bits_per_pixel) + else { - if(pixel_size.width < width) - width = pixel_size.width; + std::size_t line_bytes = (pixel_size.width < width ? pixel_size.width : width) * sizeof(pixel_color_t); if(pixel_size.height < height) height = pixel_size.height; auto d = rawptr; - if(is_negative) + const unsigned char* s; + int src_line_bytes; + + if (is_negative) { - const unsigned char* s = rawbits; - for(std::size_t i = 0; i < height; ++i) - { - 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->element.blue = s_p[0]; - p->element.green = s_p[1]; - p->element.red = s_p[2]; - s_index += 3; - } - d += pixel_size.width; - s += bytes_per_line; - } + s = rawbits; + src_line_bytes = -static_cast(bytes_per_line); } else { - const unsigned char* s = rawbits + bytes_per_line * (height - 1); - for(std::size_t i = 0; i < height; ++i) - { - auto p = d; - const auto end = p + width; - const unsigned char* s_p = s; - for(; p < end; ++p) - { - 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; - s -= bytes_per_line; - } + s = rawbits + bytes_per_line * (height - 1); + src_line_bytes = static_cast(bytes_per_line); + } + + for(std::size_t i = 0; i < height; ++i) + { + memcpy(d, s, line_bytes); + d += pixel_size.width; + s -= src_line_bytes; } } - else if(16 == bits_per_pixel) + } + else if(24 == bits_per_pixel) + { + if(pixel_size.width < width) + width = pixel_size.width; + + if(pixel_size.height < height) + height = pixel_size.height; + + auto d = rawptr; + const unsigned char* s; + int src_bytes_per_line; + + if (is_negative) { - if(pixel_size.width < width) - width = pixel_size.width; + s = rawbits; + src_bytes_per_line = -static_cast(bytes_per_line); + } + else + { + s = rawbits + bytes_per_line * (height - 1); + src_bytes_per_line = static_cast(bytes_per_line); + } - if(pixel_size.height < height) - height = pixel_size.height; - - auto d = rawptr; - - auto rgb_table = new unsigned char[32]; - - for(std::size_t i =0; i < 32; ++i) - rgb_table[i] = static_cast(i * 255 / 31); - - if(is_negative) + for(std::size_t i = 0; i < height; ++i) + { + auto p = d; + const auto end = p + width; + const unsigned char* s_p = s; + for(; p < end; ++p) { - //const unsigned short* s = reinterpret_cast(rawbits); - for(std::size_t i = 0; i < height; ++i) - { - auto p = d; - const auto end = p + width; - auto s_p = reinterpret_cast(rawbits); - for(; p < end; ++p) - { - p->element.red = rgb_table[(*s_p >> 11) & 0x1F]; -#if defined(NANA_X11) - p->element.green = (*s_p >> 5) & 0x3F; - p->element.blue = rgb_table[*s_p & 0x1F]; -#else - p->element.green = rgb_table[(*s_p>> 6) & 0x1F]; - p->element.blue = rgb_table[(*s_p >> 1) & 0x1F]; -#endif - ++s_p; - } - d += pixel_size.width; - rawbits += bytes_per_line; - } + p->element.blue = s_p[0]; + p->element.green = s_p[1]; + p->element.red = s_p[2]; + s_p += 3; } - else + d += pixel_size.width; + s -= bytes_per_line; + } + } + else if(16 == bits_per_pixel) + { + if(pixel_size.width < width) + width = pixel_size.width; + + if(pixel_size.height < height) + height = pixel_size.height; + + unsigned char rgb_table[32]; + for(std::size_t i =0; i < 32; ++i) + rgb_table[i] = static_cast(i * 255 / 31); + + int src_bytes_per_line; + if (!is_negative) + { + rawbits += bytes_per_line * (height - 1); + src_bytes_per_line = static_cast(bytes_per_line); + } + else + src_bytes_per_line = -static_cast(bytes_per_line); + + auto d = rawptr; + for (std::size_t i = 0; i < height; ++i) + { + auto p = d; + const auto end = p + width; + auto s_p = reinterpret_cast(rawbits); + for (; p < end; ++p) { - // const unsigned short* s = reinterpret_cast(rawbits + bytes_per_line * (height - 1)); - rawbits += bytes_per_line * (height - 1); - for(std::size_t i = 0; i < height; ++i) - { - auto p = d; - const auto end = p + width; - auto s_p = reinterpret_cast(rawbits); - for(; p < end; ++p) - { - p->element.red = rgb_table[(*s_p >> 11) & 0x1F]; + p->element.red = rgb_table[(*s_p >> 11) & 0x1F]; #if defined(NANA_X11) - p->element.green = ((*s_p >> 5) & 0x3F); - p->element.blue = rgb_table[*s_p & 0x1F]; + p->element.green = (*s_p >> 5) & 0x3F; + p->element.blue = rgb_table[*s_p & 0x1F]; #else - p->element.green = rgb_table[(*s_p & 0x7C0) >> 6]; - p->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; - } - d += pixel_size.width; - //s -= bytes_per_line; - rawbits -= bytes_per_line; - } + ++s_p; } - delete [] rgb_table; + d += pixel_size.width; + rawbits -= src_bytes_per_line; } } } @@ -343,7 +317,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_argb_t) * 8 == depth || 24 == depth) + if(sizeof(pixel_color_t) * 8 == depth || 24 == depth) { img->data = reinterpret_cast(raw_pixel_buffer); ::XPutImage(disp, dw, gc, @@ -397,9 +371,6 @@ namespace nana{ namespace paint #endif }; - pixel_buffer::pixel_buffer() - {} - pixel_buffer::pixel_buffer(drawable_type drawable, const nana::rectangle& want_rectangle) { open(drawable, want_rectangle); @@ -445,15 +416,7 @@ namespace nana{ namespace paint } BITMAPINFO bmpinfo; - bmpinfo.bmiHeader.biSize = sizeof(bmpinfo.bmiHeader); - bmpinfo.bmiHeader.biWidth = sz.width; - bmpinfo.bmiHeader.biHeight = -static_cast(sz.height); - bmpinfo.bmiHeader.biPlanes = 1; - bmpinfo.bmiHeader.biBitCount = 32; - bmpinfo.bmiHeader.biCompression = BI_RGB; - bmpinfo.bmiHeader.biSizeImage = static_cast(sz.width * sz.height * sizeof(pixel_argb_t)); - bmpinfo.bmiHeader.biClrUsed = 0; - bmpinfo.bmiHeader.biClrImportant = 0; + assign_windows_bitmapinfo(sz, bmpinfo); std::size_t read_lines = ::GetDIBits(drawable->context, drawable->pixmap, 0, static_cast(sz.height), sp->raw_pixel_buffer, &bmpinfo, DIB_RGB_COLORS); @@ -486,15 +449,7 @@ namespace nana{ namespace paint return false; #if defined(NANA_WINDOWS) BITMAPINFO bmpinfo; - bmpinfo.bmiHeader.biSize = sizeof(bmpinfo.bmiHeader); - bmpinfo.bmiHeader.biWidth = want_r.width; - bmpinfo.bmiHeader.biHeight = -static_cast(want_r.height); - 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_argb_t)); - bmpinfo.bmiHeader.biClrUsed = 0; - bmpinfo.bmiHeader.biClrImportant = 0; + assign_windows_bitmapinfo({want_r.width, want_r.height}, bmpinfo); bool need_dup = (r.width != sz.width || r.height != sz.height); @@ -627,7 +582,7 @@ namespace nana{ namespace paint { auto sp = storage_.get(); if(sp) - return sizeof(pixel_argb_t) * (static_cast(sp->pixel_size.width) * static_cast(sp->pixel_size.height)); + return sizeof(pixel_color_t) * (static_cast(sp->pixel_size.width) * static_cast(sp->pixel_size.height)); return 0; } @@ -641,26 +596,26 @@ namespace nana{ namespace paint return (storage_ ? storage_->pixel_size : nana::size()); } - pixel_argb_t * pixel_buffer::at(const point& pos) const + pixel_color_t * pixel_buffer::at(const point& pos) const { - pixel_buffer_storage * sp = storage_.get(); + auto 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_argb_t * pixel_buffer::raw_ptr(std::size_t row) const + pixel_color_t * pixel_buffer::raw_ptr(std::size_t row) const { - pixel_buffer_storage * sp = storage_.get(); + auto 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_argb_t * pixel_buffer::operator[](std::size_t row) const + pixel_color_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); + auto sp = storage_.get(); + 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 +624,20 @@ namespace nana{ namespace paint storage_->assign(rawbits, width, height, bits_per_pixel, bytes_per_line, is_negative); } - pixel_argb_t pixel_buffer::pixel(int x, int y) const + pixel_color_t pixel_buffer::pixel(int x, int y) const { - pixel_buffer_storage * sp = storage_.get(); + auto 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_argb_t(); + return pixel_color_t(); } - void pixel_buffer::pixel(int x, int y, pixel_argb_t px) + void pixel_buffer::pixel(int x, int y, pixel_color_t px) { - pixel_buffer_storage * sp = storage_.get(); + auto 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 @@ -693,7 +648,7 @@ namespace nana{ namespace paint void pixel_buffer::paste(const nana::rectangle& src_r, drawable_type drawable, int x, int y) const { - pixel_buffer_storage * sp = storage_.get(); + auto sp = storage_.get(); if(drawable && sp) { if(sp->alpha_channel) @@ -709,15 +664,7 @@ namespace nana{ namespace paint } #if defined(NANA_WINDOWS) BITMAPINFO bi; - bi.bmiHeader.biSize = sizeof(bi.bmiHeader); - 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_argb_t) * 8; - bi.bmiHeader.biCompression = BI_RGB; - 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; + assign_windows_bitmapinfo(sp->pixel_size, bi); ::SetDIBitsToDevice(drawable->context, x, y, src_r.width, src_r.height, @@ -731,22 +678,14 @@ namespace nana{ namespace paint void pixel_buffer::paste(native_window_type wd, int x, int y) const { - pixel_buffer_storage * sp = storage_.get(); + auto sp = storage_.get(); if(nullptr == wd || nullptr == sp) return; #if defined(NANA_WINDOWS) HDC handle = ::GetDC(reinterpret_cast(wd)); if(handle) { BITMAPINFO bi; - bi.bmiHeader.biSize = sizeof(bi.bmiHeader); - 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_argb_t) * 8; - bi.bmiHeader.biCompression = BI_RGB; - 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; + assign_windows_bitmapinfo(sp->pixel_size, bi); ::SetDIBitsToDevice(handle, x, y, sp->pixel_size.width, sp->pixel_size.height, @@ -760,25 +699,24 @@ namespace nana{ namespace paint Display * disp = spec.open_display(); sp->put(reinterpret_cast(wd), XDefaultGC(disp, XDefaultScreen(disp)), 0, 0, x, y, sp->pixel_size.width, sp->pixel_size.height); #endif - } void pixel_buffer::line(const std::string& name) { - pixel_buffer_storage * sp = storage_.get(); - if(sp && name.size()) + if (storage_ && name.size()) { - sp->img_pro.line_receptacle = detail::image_process_provider::instance().ref_line(name); - if(sp->img_pro.line_receptacle == *detail::image_process_provider::instance().line()) - sp->img_pro.line = detail::image_process_provider::instance().line(); + auto & img_pro = storage_->img_pro; + img_pro.line_receptacle = detail::image_process_provider::instance().ref_line(name); + if(img_pro.line_receptacle == *detail::image_process_provider::instance().line()) + img_pro.line = detail::image_process_provider::instance().line(); else - sp->img_pro.line = & sp->img_pro.line_receptacle; + img_pro.line = &img_pro.line_receptacle; } } void pixel_buffer::line(const point &pos_beg, const point &pos_end, const ::nana::expr_color& clr, double fade_rate) { - pixel_buffer_storage * sp = storage_.get(); + auto sp = storage_.get(); if(nullptr == sp) return; //Test if the line intersects the rectangle, and retrive the two points that @@ -790,7 +728,7 @@ namespace nana{ namespace paint void pixel_buffer::rectangle(const nana::rectangle &r, const ::nana::expr_color& clr, double fade_rate, bool solid) { - pixel_buffer_storage * sp = storage_.get(); + auto sp = storage_.get(); if((nullptr == sp) || (fade_rate == 1.0)) return; bool fade = (fade_rate != 0.0); @@ -798,7 +736,7 @@ namespace nana{ namespace paint std::unique_ptr autoptr; auto rgb_color = clr.px_color().value; - nana::pixel_argb_t rgb_imd; + nana::pixel_color_t rgb_imd; if(fade) { autoptr = detail::alloc_fade_table(1 - fade_rate); @@ -809,12 +747,12 @@ namespace nana{ namespace paint int xbeg = (0 <= r.x ? r.x : 0); int xend = static_cast(r.x + r.width < sp->pixel_size.width ? r.x + r.width : sp->pixel_size.width); - int ybeg = (0 <= r.y ? r.y : 0); + const int ybeg = (0 <= r.y ? r.y : 0); int yend = static_cast(r.y + r.height < sp->pixel_size.height ? r.y + r.height : sp->pixel_size.height); + const auto p_rgb = sp->raw_pixel_buffer + ybeg * sp->pixel_size.width; if (solid) { - auto p_rgb = sp->raw_pixel_buffer + ybeg * sp->pixel_size.width; auto lineptr = p_rgb + xbeg; auto end = p_rgb + xend; if (fade) @@ -845,7 +783,6 @@ namespace nana{ namespace paint if((ybeg == r.y) && (r.y + static_cast(r.height) == yend)) { - 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; @@ -870,7 +807,6 @@ namespace nana{ namespace paint { if(ybeg == r.y) { - auto p_rgb = sp->raw_pixel_buffer + ybeg * sp->pixel_size.width; auto i = p_rgb; auto end = p_rgb + xend; if(fade) @@ -906,7 +842,6 @@ namespace nana{ namespace paint if((xbeg == r.x) && (r.x + static_cast(r.width) == xend)) { - 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); @@ -942,7 +877,6 @@ namespace nana{ namespace paint { if(xbeg == r.x) { - 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) @@ -969,7 +903,6 @@ namespace nana{ namespace paint if(r.x + static_cast(r.width) == xend) { - 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) @@ -996,7 +929,7 @@ 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(); + auto sp = storage_.get(); if (nullptr == sp) return; nana::rectangle rct; @@ -1006,8 +939,8 @@ namespace nana{ namespace paint int deltapx = int(vertical ? rct.height : rct.width); if (sp && deltapx) { - auto beg = from.argb().value; - auto end = to.argb().value; + auto beg = from.px_color().value; + auto end = to.px_color().value; unsigned 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; @@ -1016,46 +949,40 @@ namespace nana{ namespace paint 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--) { - unsigned align_4 = (rct.width & ~3); - unsigned align_reset = rct.width & 3; - while (deltapx--) + nana::pixel_color_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) { - 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; + *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; + 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; - } + auto dpx_end = pxbuf + rct.height * sp->pixel_size.width; + for (; pxbuf != pxbuf_end; ++pxbuf) + { + nana::pixel_color_t px; + px.value = ((r += delta_r) & 0xFF0000) | (((g += delta_g) & 0xFF0000) >> 8) | (((b += delta_b) & 0xFF0000) >> 16); + for (auto dpx = pxbuf; dpx != dpx_end; dpx += sp->pixel_size.width) + *dpx = px; + ++dpx_end; } } } @@ -1064,21 +991,21 @@ namespace nana{ namespace paint //stretch void pixel_buffer::stretch(const std::string& name) { - pixel_buffer_storage * sp = storage_.get(); - if(sp && name.size()) + if (storage_ && name.size()) { + auto& img_pro = storage_->img_pro; auto op_default = detail::image_process_provider::instance().stretch(); - sp->img_pro.stretch_receptacle = detail::image_process_provider::instance().ref_stretch(name); - if(sp->img_pro.stretch_receptacle == *op_default) - sp->img_pro.stretch = op_default; + img_pro.stretch_receptacle = detail::image_process_provider::instance().ref_stretch(name); + if(img_pro.stretch_receptacle == *op_default) + img_pro.stretch = op_default; else - sp->img_pro.stretch = & sp->img_pro.stretch_receptacle; + img_pro.stretch = &img_pro.stretch_receptacle; } } void pixel_buffer::stretch(const nana::rectangle& src_r, drawable_type drawable, const nana::rectangle& r) const { - pixel_buffer_storage * sp = storage_.get(); + auto sp = storage_.get(); if(nullptr == sp) return; nana::rectangle good_src_r, good_dst_r; @@ -1093,21 +1020,21 @@ namespace nana{ namespace paint //blend void pixel_buffer::blend(const std::string& name) { - pixel_buffer_storage * sp = storage_.get(); - if(sp && name.size()) + if (storage_ && name.size()) { + auto& img_pro = storage_->img_pro; auto op_default = detail::image_process_provider::instance().blend(); - sp->img_pro.blend_receptacle = detail::image_process_provider::instance().ref_blend(name); - if(sp->img_pro.blend_receptacle == *op_default) - sp->img_pro.blend = op_default; + img_pro.blend_receptacle = detail::image_process_provider::instance().ref_blend(name); + if(img_pro.blend_receptacle == *op_default) + img_pro.blend = op_default; else - sp->img_pro.blend = & sp->img_pro.blend_receptacle; + img_pro.blend = &img_pro.blend_receptacle; } } void pixel_buffer::blend(const nana::rectangle& s_r, drawable_type dw_dst, const nana::point& d_pos, double fade_rate) const { - pixel_buffer_storage * sp = storage_.get(); + auto sp = storage_.get(); if(nullptr == sp) return; nana::rectangle s_good_r, d_good_r;