From a87703d418f263c4068ef3efeec09d580404f602 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Wed, 31 May 2017 22:36:56 +0800 Subject: [PATCH] refactor functions --- include/nana/unicode_bidi.hpp | 7 +- source/gui/detail/bedrock_pi.cpp | 2 +- source/gui/detail/window_manager.cpp | 12 +-- source/gui/widgets/label.cpp | 4 +- source/gui/widgets/listbox.cpp | 58 ++++-------- source/gui/widgets/skeletons/text_editor.cpp | 54 +++++------ source/paint/graphics.cpp | 9 +- source/paint/text_renderer.cpp | 96 +++++++++++--------- source/unicode_bidi.cpp | 22 +++-- 9 files changed, 121 insertions(+), 143 deletions(-) diff --git a/include/nana/unicode_bidi.hpp b/include/nana/unicode_bidi.hpp index 71a5f882..72d65860 100644 --- a/include/nana/unicode_bidi.hpp +++ b/include/nana/unicode_bidi.hpp @@ -49,7 +49,7 @@ namespace nana unsigned level; }; - void linestr(const char_type*, std::size_t len, std::vector & reordered); + std::vector reorder(const char_type*, std::size_t len); private: static unsigned _m_paragraph_level(const char_type * begin, const char_type * end); @@ -65,13 +65,12 @@ namespace nana void _m_reordering_resolved_levels(std::vector & reordered); static bidi_category _m_bidi_category(bidi_char); static bidi_char _m_char_dir(char_type); - private: - void _m_output_levels() const; - void _m_output_bidi_char() const; private: std::vector levels_; }; + std::vector unicode_reorder(const wchar_t* text, std::size_t length); + } #include diff --git a/source/gui/detail/bedrock_pi.cpp b/source/gui/detail/bedrock_pi.cpp index ca36a92f..294c56f9 100644 --- a/source/gui/detail/bedrock_pi.cpp +++ b/source/gui/detail/bedrock_pi.cpp @@ -131,7 +131,7 @@ namespace nana if (((0 == thread_id) || (wd->thread_id == thread_id)) && (wd->root != root)) { root = wd->root; - if (roots.cend() == std::find(roots.cbegin(), roots.cend(), root)) + if (roots.end() == std::find(roots.begin(), roots.end(), root)) roots.emplace_back(root); } } diff --git a/source/gui/detail/window_manager.cpp b/source/gui/detail/window_manager.cpp index 7a8980e8..6d1ce3ca 100644 --- a/source/gui/detail/window_manager.cpp +++ b/source/gui/detail/window_manager.cpp @@ -1397,14 +1397,14 @@ namespace detail { auto & tabs = wd->root_widget->other.attribute.root->tabstop; - auto end = tabs.cend(); + auto end = tabs.end(); if (forward) { if (detail::tab_type::none == wd->flags.tab) return (tabs.front()); else if (detail::tab_type::tabstop & wd->flags.tab) { - auto i = std::find(tabs.cbegin(), end, wd); + auto i = std::find(tabs.begin(), end, wd); if (i != end) { ++i; @@ -1417,9 +1417,9 @@ namespace detail } else if (tabs.size() > 1) //at least 2 elments in tabs are required when moving backward. { - auto i = std::find(tabs.cbegin(), end, wd); + auto i = std::find(tabs.begin(), end, wd); if (i != end) - return (tabs.cbegin() == i ? tabs.back() : *(i - 1)); + return (tabs.begin() == i ? tabs.back() : *(i - 1)); } return nullptr; } @@ -1549,7 +1549,7 @@ namespace detail for (auto child : wd->children) { auto child_keys = shortkeys(child, true); - std::copy(child_keys.cbegin(), child_keys.cend(), std::back_inserter(result)); + std::copy(child_keys.begin(), child_keys.end(), std::back_inserter(result)); } } } @@ -1716,7 +1716,7 @@ namespace detail if (pa_children.size() > 1) { - for (auto i = pa_children.cbegin(), end = pa_children.cend(); i != end; ++i) + for (auto i = pa_children.begin(), end = pa_children.end(); i != end; ++i) { if (((*i)->index) > (wd->index)) { diff --git a/source/gui/widgets/label.cpp b/source/gui/widgets/label.cpp index a4a8cef1..1d436f68 100644 --- a/source/gui/widgets/label.cpp +++ b/source/gui/widgets/label.cpp @@ -519,9 +519,7 @@ namespace nana void _m_draw_block(graph_reference graph, const std::wstring& s, dstream::linecontainer::iterator block_start, render_status& rs) { - nana::unicode_bidi bidi; - std::vector reordered; - bidi.linestr(s.data(), s.length(), reordered); + auto const reordered = unicode_reorder(s.data(), s.length()); pixel_tag px = rs.pixels[rs.index]; diff --git a/source/gui/widgets/listbox.cpp b/source/gui/widgets/listbox.cpp index 3aa2262f..cc32afac 100644 --- a/source/gui/widgets/listbox.cpp +++ b/source/gui/widgets/listbox.cpp @@ -332,7 +332,8 @@ namespace nana unsigned ranged_px = 0; unsigned ranged_count = 0; - for (auto & col : cont_) + auto const & const_cont = cont_; + for (auto & col : const_cont) { if (col.visible_state) { @@ -486,27 +487,6 @@ namespace nana return{ left, 0 }; } - /* - /// Returns the left point position and width(in variable *pixels) of column originaly at position pos. - int position(size_type pos, unsigned * pixels) const - { - int left = 0; - for (auto & m : cont_) - { - if (m.index == pos) - { - if (pixels) - *pixels = m.width_px; - break; - } - - if (m.visible_state) - left += m.width_px; - } - return left; - } - */ - /// return the original index of the visible col currently before(in front of) or after the col originaly at index "index" size_type next(size_type index) const noexcept { @@ -548,11 +528,15 @@ namespace nana if ((from == to) || (from >= cont_.size()) || (to >= cont_.size())) return; +#ifdef _MSC_VER + for (auto i = cont_.cbegin(); i != cont_.cend(); ++i) +#else for (auto i = cont_.begin(); i != cont_.end(); ++i) +#endif { if (from == i->index) { - auto col_from = std::move(*i); + auto col_from = *i; cont_.erase(i); //A workaround for old libstdc++, that some operations of vector @@ -781,19 +765,6 @@ namespace nana std::string to_string(const export_options& exp_opt) const; - std::vector get_inline_pane(const index_pair& item_pos) - { - std::vector panes; - for (auto p : active_panes_) - { - if (p && (p->item_pos == item_pos)) - { - panes.emplace_back(p); - } - } - return panes; - } - void emit_cs(const index_pair& pos, bool for_selection) { item_proxy i(ess_, pos); @@ -806,13 +777,16 @@ namespace nana else events.checked.emit(arg, wd_ptr()->handle()); - auto panes = get_inline_pane(pos); - for (auto p : panes) + //notify the inline pane. An item may have multiple panes, each pane is for a column. + for (auto p : active_panes_) { - if(for_selection) - p->inline_ptr->notify_status(inline_widget_status::selecting, i.selected()); - else - p->inline_ptr->notify_status(inline_widget_status::checking, i.checked()); + if (p && (p->item_pos == pos)) + { + if (for_selection) + p->inline_ptr->notify_status(inline_widget_status::selecting, i.selected()); + else + p->inline_ptr->notify_status(inline_widget_status::checking, i.checked()); + } } } diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index 3129d71c..f1076238 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -407,11 +407,11 @@ namespace nana{ namespace widgets std::shared_ptr find(std::size_t pos) const { - for (auto i = colored_areas_.cbegin(); i != colored_areas_.cend(); ++i) + for (auto & sp : colored_areas_) { - if (i->get()->begin <= pos && pos < i->get()->begin + i->get()->count) - return *i; - else if (i->get()->begin > pos) + if (sp->begin <= pos && pos < sp->begin + sp->count) + return sp; + else if (sp->begin > pos) break; } return{}; @@ -623,7 +623,9 @@ namespace nana{ namespace widgets //textbase is implement by using deque, and the linemtr holds the text pointers //If the textbase is changed, it will check the text pointers. std::size_t line = 0; - for (auto & sct : this->sections_) + + auto const & const_sections = sections_; + for (auto & sct : const_sections) { auto const& text = editor_.textbase().getline(line); if (sct.begin < text.c_str() || (text.c_str() + text.size() < sct.begin)) @@ -646,7 +648,9 @@ namespace nana{ namespace widgets //textbase is implement by using deque, and the linemtr holds the text pointers //If the textbase is changed, it will check the text pointers. std::size_t line = 0; - for (auto & sct : this->sections_) + + auto const & const_sections = sections_; + for (auto & sct : const_sections) { if (line < pos || (pos + line_size) <= line) { @@ -664,8 +668,8 @@ namespace nana{ namespace widgets auto const & text = editor_.textbase().getline(pos); auto& txt_section = this->sections_[pos]; txt_section.begin = text.c_str(); - txt_section.end = text.c_str() + text.size(); - txt_section.pixels = editor_._m_text_extent_size(text.c_str(), text.size()).width; + txt_section.end = txt_section.begin + text.size(); + txt_section.pixels = editor_._m_text_extent_size(txt_section.begin, text.size()).width; } void pre_calc_lines(unsigned) override @@ -756,7 +760,9 @@ namespace nana{ namespace widgets //textbase is implement by using deque, and the linemtr holds the text pointers //If the textbase is changed, it will check the text pointers. std::size_t line = 0; - for (auto & mtr : linemtr_) + + auto const & const_linemtr = linemtr_; + for (auto & mtr : const_linemtr) { if (line < pos || (pos + lines) <= line) { @@ -2031,11 +2037,9 @@ namespace nana{ namespace widgets return; auto undo_ptr = std::unique_ptr(new undo_input_text(*this, std::wstring(1, '\n'))); - bool need_refresh = (select_.a != select_.b); undo_ptr->set_selected_text(); - if(need_refresh) - points_.caret = _m_erase_select(); + points_.caret = _m_erase_select(); undo_ptr->set_caret_pos(); @@ -2067,12 +2071,7 @@ namespace nana{ namespace widgets points_.caret.x = 0; auto origin = impl_->cview->origin(); - if (origin.x || (points_.caret.y < textbase.lines()) || textbase.getline(points_.caret.y).size()) - { - origin.x = -origin.x; - impl_->cview->move_origin(origin); - need_refresh = true; - } + origin.x = 0; if (impl_->indent.enabled) { @@ -2090,13 +2089,13 @@ namespace nana{ namespace widgets put(text); } } + else + _m_reset_content_size(); - impl_->cview->move_origin(origin - impl_->cview->origin()); + auto origin_moved = impl_->cview->move_origin(origin - impl_->cview->origin()); - if (this->_m_adjust_view() || need_refresh) + if (this->_m_adjust_view() || origin_moved) impl_->cview->sync(true); - - _m_reset_content_size(); } void text_editor::del() @@ -2630,8 +2629,7 @@ namespace nana{ namespace widgets text_ptr = mask_str.c_str(); } - std::vector reordered; - unicode_bidi{}.linestr(text_ptr, text_size, reordered); + auto const reordered = unicode_reorder(text_ptr, text_size); nana::upoint res(static_cast(real_str.begin - sections.front().begin), static_cast(row.first)); @@ -3333,8 +3331,7 @@ namespace nana{ namespace widgets const auto focused = API::is_focus_ready(window_); - std::vector reordered; - unicode_bidi{}.linestr(text_ptr, text_len, reordered); + auto const reordered = unicode_reorder(text_ptr, text_len); //Parse highlight keywords keyword_parser parser; @@ -3564,9 +3561,8 @@ namespace nana{ namespace widgets if (pos > lnstr.size()) return 0; - std::vector reordered; - unicode_bidi{}.linestr(lnstr.c_str(), lnstr.size(), reordered); - + auto const reordered = unicode_reorder(lnstr.c_str(), lnstr.size()); + auto target = lnstr.c_str() + pos; unsigned text_w = 0; diff --git a/source/paint/graphics.cpp b/source/paint/graphics.cpp index b3bedd40..075f8be1 100644 --- a/source/paint/graphics.cpp +++ b/source/paint/graphics.cpp @@ -509,9 +509,7 @@ namespace paint nana::size sz; if(impl_->handle && impl_->handle->context && str.size()) { - std::vector reordered; - unicode_bidi bidi; - bidi.linestr(str.c_str(), str.size(), reordered); + auto const reordered = unicode_reorder(str.c_str(), str.size()); for(auto & i: reordered) { nana::size t = text_extent_size(i.begin, i.end - i.begin); @@ -958,9 +956,8 @@ namespace paint unsigned graphics::bidi_string(const nana::point& pos, const wchar_t * str, std::size_t len) { auto moved_pos = pos; - unicode_bidi bidi; - std::vector reordered; - bidi.linestr(str, len, reordered); + + auto const reordered = unicode_reorder(str, len); for (auto & i : reordered) { string(moved_pos, i.begin, i.end - i.begin); diff --git a/source/paint/text_renderer.cpp b/source/paint/text_renderer.cpp index af206d40..07b71e0f 100644 --- a/source/paint/text_renderer.cpp +++ b/source/paint/text_renderer.cpp @@ -13,26 +13,23 @@ namespace nana template void for_each_line(const wchar_t * str, std::size_t len, int top, F & f) { - auto head = str; - auto end = str + len; + auto const end = str + len; for(auto i = str; i != end; ++i) { if(*i == '\n') { - top += static_cast(f(top, head, i - head)); - head = i + 1; + top += static_cast(f(top, str, i - str)); + str = i + 1; } } - if(head != end) - f(top, head, end - head); + if(str != end) + f(top, str, end - str); } struct draw_string { drawable_type dw; const int x, endpos; - nana::unicode_bidi bidi; - std::vector reordered; align text_align; draw_string(drawable_type dw, int x, int endpos, align ta) @@ -41,9 +38,13 @@ namespace nana unsigned operator()(const int top, const wchar_t * buf, std::size_t bufsize) { + auto const reordered = unicode_reorder(buf, bufsize); + if (reordered.empty()) + return 0; + nana::point pos{ x, top }; unsigned pixels = 0; - bidi.linestr(buf, bufsize, reordered); + switch(text_align) { case align::left: @@ -64,23 +65,28 @@ namespace nana case align::center: { unsigned lenpx = 0; - std::vector widths; + std::unique_ptr entity_pxs(new unsigned[reordered.size()]); + + auto ent_px = entity_pxs.get(); + for(auto & ent : reordered) { auto ts = detail::text_extent_size(dw, ent.begin, ent.end - ent.begin); if(ts.height > pixels) pixels = ts.height; lenpx += ts.width; - widths.emplace_back(ts.width); + *ent_px++ = ts.width; } pos.x += (endpos - pos.x - static_cast(lenpx))/2; - auto ipx = widths.begin(); + ent_px = entity_pxs.get(); + for(auto & ent : reordered) { - if(pos.x + static_cast(*ipx) > 0) + if (pos.x + static_cast(*ent_px) > 0) detail::draw_string(dw, pos, ent.begin, ent.end - ent.begin); - pos.x += static_cast(*ipx); + pos.x += static_cast(*ent_px++); + if(pos.x >= endpos) break; } @@ -90,7 +96,7 @@ namespace nana { int xend = endpos; std::swap(pos.x, xend); - for(auto i = reordered.rbegin(), end = reordered.rend(); i != end; ++i) + for(auto i = reordered.crbegin(); i != reordered.crend(); ++i) { auto & ent = *i; std::size_t len = ent.end - ent.begin; @@ -118,13 +124,11 @@ namespace nana graphics & graph; int x, endpos; unsigned omitted_pixels; - nana::unicode_bidi bidi; - std::vector reordered; draw_string_omitted(graphics& graph, int x, int endpos, bool omitted) : graph(graph), x(x), endpos(endpos) { - omitted_pixels = (omitted ? graph.text_extent_size(L"...", 3).width : 0); + omitted_pixels = (omitted ? graph.text_extent_size("...", 3).width : 0); if (endpos - x > static_cast(omitted_pixels)) this->endpos -= omitted_pixels; else @@ -136,7 +140,9 @@ namespace nana drawable_type dw = graph.handle(); ::nana::point pos{ x, top }; unsigned pixels = 0; - bidi.linestr(buf, bufsize, reordered); + + auto const reordered = unicode_reorder(buf, bufsize); + for(auto & i : reordered) { std::size_t len = i.end - i.begin; @@ -178,9 +184,6 @@ namespace nana { graphics & graph; int x, endpos; - nana::unicode_bidi bidi; - std::vector reordered; - std::vector ts_keeper; align text_align; draw_string_auto_changing_lines(graphics& graph, int x, int endpos, align ta) @@ -191,10 +194,13 @@ namespace nana { unsigned pixels = 0; - drawable_type dw = graph.handle(); + auto const dw = graph.handle(); unsigned str_w = 0; - ts_keeper.clear(); - bidi.linestr(buf, bufsize, reordered); + + std::vector ts_keeper; + + auto const reordered = unicode_reorder(buf, bufsize); + for(auto & i : reordered) { nana::size ts = detail::text_extent_size(dw, i.begin, i.end - i.begin); @@ -213,28 +219,33 @@ namespace nana auto i_ts_keeper = ts_keeper.cbegin(); for(auto & i : reordered) { - if(line_pixels < i_ts_keeper->height) + if(line_pixels < i_ts_keeper->height) line_pixels = i_ts_keeper->height; bool beyond_edge = (pos.x + static_cast(i_ts_keeper->width) > endpos); if(beyond_edge) { - std::size_t len = i.end - i.begin; + const std::size_t len = i.end - i.begin; if(len > 1) { - unsigned * pxbuf = new unsigned[len]; + std::unique_ptr pixel_buf(new unsigned[len]); + //Find the char that should be splitted - graph.glyph_pixels(i.begin, len, pxbuf); + graph.glyph_pixels(i.begin, len, pixel_buf.get()); std::size_t idx_head = 0, idx_splitted; do { + auto pxbuf = pixel_buf.get(); + idx_splitted = find_splitted(idx_head, len, pos.x, endpos, pxbuf); if(idx_splitted == len) { detail::draw_string(dw, pos, i.begin + idx_head, idx_splitted - idx_head); + for(std::size_t i = idx_head; i < len; ++i) pos.x += static_cast(pxbuf[i]); + break; } //Check the word whether it is splittable. @@ -243,7 +254,7 @@ namespace nana detail::draw_string(dw, pos, i.begin + idx_head, idx_splitted - idx_head); idx_head = idx_splitted; pos.x = x; - pos.y += line_pixels; + pos.y += static_cast(line_pixels); line_pixels = i_ts_keeper->height; } else @@ -283,18 +294,16 @@ namespace nana for(std::size_t k = idx_head; k < idx_head + splen; ++k) pos.x += static_cast(pxbuf[k]); + if (pos.x >= endpos) { pos.x = x; pos.y += static_cast(line_pixels); - line_pixels = i_ts_keeper->height; } idx_head += splen; } } }while(idx_head < len); - - delete [] pxbuf; } else { @@ -340,7 +349,7 @@ namespace nana { point pos{ endpos, top }; auto i_ts_keeper = ts_keeper.crbegin(); - for(auto i = reordered.crbegin(), end = reordered.crend(); i != end; ++i) + for(auto i = reordered.crbegin(); i != reordered.crend(); ++i) { auto & ent = *i; std::size_t len = ent.end - ent.begin; @@ -397,9 +406,6 @@ namespace nana { graphics & graph; int x, endpos; - nana::unicode_bidi bidi; - std::vector reordered; - std::vector ts_keeper; unsigned extents; extent_auto_changing_lines(graphics& graph, int x, int endpos) @@ -412,8 +418,10 @@ namespace nana drawable_type dw = graph.handle(); unsigned str_w = 0; - ts_keeper.clear(); - bidi.linestr(buf, bufsize, reordered); + std::vector ts_keeper; + + auto const reordered = unicode_reorder(buf, bufsize); + for(auto & i : reordered) { nana::size ts = detail::text_extent_size(dw, i.begin, i.end - i.begin); @@ -503,7 +511,6 @@ namespace nana { xpos = x; top += line_pixels; - line_pixels = i_ts_keeper->height; } idx_head += splen; } @@ -645,11 +652,9 @@ namespace nana substr_px += *p; } while (p != end); - pos.x += static_cast(width - ellipsis - substr_px); - - graph_.string(pos, "..."); - pos.x += ellipsis; + pos.x += static_cast(width - ellipsis - substr_px) + ellipsis; graph_.bidi_string(pos, text.c_str() + substr_len, text.size() - substr_len); + pos.x -= ellipsis; } else { @@ -669,8 +674,9 @@ namespace nana graph_.bidi_string(pos, text.c_str(), substr_len); pos.x += substr_px; - graph_.string(pos, "..."); } + + graph_.string(pos, "..."); } //end class string diff --git a/source/unicode_bidi.cpp b/source/unicode_bidi.cpp index 3da7d2f0..15b77d12 100644 --- a/source/unicode_bidi.cpp +++ b/source/unicode_bidi.cpp @@ -276,8 +276,7 @@ namespace nana if(ch <= 0x1CC7) return L; //N = 141 if(0x1CD3 == ch || 0x1CE1 == ch) return L; if(ch <= 0x1CE8) return NSM; //N = 7 - if(0x1CED == ch) return NSM; - if(0x1CF4 == ch) return NSM; + if(0x1CED == ch || 0x1CF4 == ch) return NSM; if(ch <= 0x1DBF) return L; //N = 203 if(ch <= 0x1DFF) return NSM; //N = 64 if(ch <= 0x1FBC) return L; //N = 445 @@ -504,21 +503,21 @@ namespace nana } //class unicode_bidi - void unicode_bidi::linestr(const char_type* str, std::size_t len, std::vector & reordered) + std::vector unicode_bidi::reorder(const char_type* str, std::size_t len) { levels_.clear(); const char_type * const end = str + len; std::vector stack; - - remember cur = {0, directional_override_status::neutral}; + + remember cur = { 0, directional_override_status::neutral }; cur.level = _m_paragraph_level(str, end); //First character type bidi_char begin_char_type = {}; const char_type * begin_character = nullptr; - for(const char_type * c = str; c < end; ++c) + for (const char_type * c = str; c < end; ++c) { if (PDF == *c) { @@ -579,13 +578,17 @@ namespace nana begin_character = c; } } - if(begin_character) + if (begin_character) _m_push_entity(begin_character, end, cur.level, begin_char_type); _m_resolve_weak_types(); _m_resolve_neutral_types(); _m_resolve_implicit_levels(); + + std::vector reordered; _m_reordering_resolved_levels(reordered); + + return reordered; } unsigned unicode_bidi::_m_paragraph_level(const char_type * begin, const char_type * end) @@ -938,4 +941,9 @@ namespace nana return static_cast(static_cast(type - bidi_charmap::B) + 0x2000); } //end class unicode_bidi + + std::vector unicode_reorder(const wchar_t* text, std::size_t length) + { + return unicode_bidi{}.reorder(text, length); + } }//end namespace nana