refactor functions
This commit is contained in:
parent
5746fc33f6
commit
a87703d418
@ -49,7 +49,7 @@ namespace nana
|
|||||||
unsigned level;
|
unsigned level;
|
||||||
};
|
};
|
||||||
|
|
||||||
void linestr(const char_type*, std::size_t len, std::vector<entity> & reordered);
|
std::vector<entity> reorder(const char_type*, std::size_t len);
|
||||||
private:
|
private:
|
||||||
static unsigned _m_paragraph_level(const char_type * begin, const char_type * end);
|
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<entity> & reordered);
|
void _m_reordering_resolved_levels(std::vector<entity> & reordered);
|
||||||
static bidi_category _m_bidi_category(bidi_char);
|
static bidi_category _m_bidi_category(bidi_char);
|
||||||
static bidi_char _m_char_dir(char_type);
|
static bidi_char _m_char_dir(char_type);
|
||||||
private:
|
|
||||||
void _m_output_levels() const;
|
|
||||||
void _m_output_bidi_char() const;
|
|
||||||
private:
|
private:
|
||||||
std::vector<entity> levels_;
|
std::vector<entity> levels_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::vector<unicode_bidi::entity> unicode_reorder(const wchar_t* text, std::size_t length);
|
||||||
|
|
||||||
}
|
}
|
||||||
#include <nana/pop_ignore_diagnostic>
|
#include <nana/pop_ignore_diagnostic>
|
||||||
|
|
||||||
|
|||||||
@ -131,7 +131,7 @@ namespace nana
|
|||||||
if (((0 == thread_id) || (wd->thread_id == thread_id)) && (wd->root != root))
|
if (((0 == thread_id) || (wd->thread_id == thread_id)) && (wd->root != root))
|
||||||
{
|
{
|
||||||
root = wd->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);
|
roots.emplace_back(root);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1397,14 +1397,14 @@ namespace detail
|
|||||||
{
|
{
|
||||||
auto & tabs = wd->root_widget->other.attribute.root->tabstop;
|
auto & tabs = wd->root_widget->other.attribute.root->tabstop;
|
||||||
|
|
||||||
auto end = tabs.cend();
|
auto end = tabs.end();
|
||||||
if (forward)
|
if (forward)
|
||||||
{
|
{
|
||||||
if (detail::tab_type::none == wd->flags.tab)
|
if (detail::tab_type::none == wd->flags.tab)
|
||||||
return (tabs.front());
|
return (tabs.front());
|
||||||
else if (detail::tab_type::tabstop & wd->flags.tab)
|
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)
|
if (i != end)
|
||||||
{
|
{
|
||||||
++i;
|
++i;
|
||||||
@ -1417,9 +1417,9 @@ namespace detail
|
|||||||
}
|
}
|
||||||
else if (tabs.size() > 1) //at least 2 elments in tabs are required when moving backward.
|
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)
|
if (i != end)
|
||||||
return (tabs.cbegin() == i ? tabs.back() : *(i - 1));
|
return (tabs.begin() == i ? tabs.back() : *(i - 1));
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -1549,7 +1549,7 @@ namespace detail
|
|||||||
for (auto child : wd->children)
|
for (auto child : wd->children)
|
||||||
{
|
{
|
||||||
auto child_keys = shortkeys(child, true);
|
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)
|
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))
|
if (((*i)->index) > (wd->index))
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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)
|
void _m_draw_block(graph_reference graph, const std::wstring& s, dstream::linecontainer::iterator block_start, render_status& rs)
|
||||||
{
|
{
|
||||||
nana::unicode_bidi bidi;
|
auto const reordered = unicode_reorder(s.data(), s.length());
|
||||||
std::vector<nana::unicode_bidi::entity> reordered;
|
|
||||||
bidi.linestr(s.data(), s.length(), reordered);
|
|
||||||
|
|
||||||
pixel_tag px = rs.pixels[rs.index];
|
pixel_tag px = rs.pixels[rs.index];
|
||||||
|
|
||||||
|
|||||||
@ -332,7 +332,8 @@ namespace nana
|
|||||||
unsigned ranged_px = 0;
|
unsigned ranged_px = 0;
|
||||||
unsigned ranged_count = 0;
|
unsigned ranged_count = 0;
|
||||||
|
|
||||||
for (auto & col : cont_)
|
auto const & const_cont = cont_;
|
||||||
|
for (auto & col : const_cont)
|
||||||
{
|
{
|
||||||
if (col.visible_state)
|
if (col.visible_state)
|
||||||
{
|
{
|
||||||
@ -486,27 +487,6 @@ namespace nana
|
|||||||
return{ left, 0 };
|
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"
|
/// 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
|
size_type next(size_type index) const noexcept
|
||||||
{
|
{
|
||||||
@ -548,11 +528,15 @@ namespace nana
|
|||||||
if ((from == to) || (from >= cont_.size()) || (to >= cont_.size()))
|
if ((from == to) || (from >= cont_.size()) || (to >= cont_.size()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
for (auto i = cont_.cbegin(); i != cont_.cend(); ++i)
|
||||||
|
#else
|
||||||
for (auto i = cont_.begin(); i != cont_.end(); ++i)
|
for (auto i = cont_.begin(); i != cont_.end(); ++i)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
if (from == i->index)
|
if (from == i->index)
|
||||||
{
|
{
|
||||||
auto col_from = std::move(*i);
|
auto col_from = *i;
|
||||||
cont_.erase(i);
|
cont_.erase(i);
|
||||||
|
|
||||||
//A workaround for old libstdc++, that some operations of vector
|
//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::string to_string(const export_options& exp_opt) const;
|
||||||
|
|
||||||
std::vector<inline_pane*> get_inline_pane(const index_pair& item_pos)
|
|
||||||
{
|
|
||||||
std::vector<inline_pane*> 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)
|
void emit_cs(const index_pair& pos, bool for_selection)
|
||||||
{
|
{
|
||||||
item_proxy i(ess_, pos);
|
item_proxy i(ess_, pos);
|
||||||
@ -806,13 +777,16 @@ namespace nana
|
|||||||
else
|
else
|
||||||
events.checked.emit(arg, wd_ptr()->handle());
|
events.checked.emit(arg, wd_ptr()->handle());
|
||||||
|
|
||||||
auto panes = get_inline_pane(pos);
|
//notify the inline pane. An item may have multiple panes, each pane is for a column.
|
||||||
for (auto p : panes)
|
for (auto p : active_panes_)
|
||||||
{
|
{
|
||||||
if(for_selection)
|
if (p && (p->item_pos == pos))
|
||||||
p->inline_ptr->notify_status(inline_widget_status::selecting, i.selected());
|
{
|
||||||
else
|
if (for_selection)
|
||||||
p->inline_ptr->notify_status(inline_widget_status::checking, i.checked());
|
p->inline_ptr->notify_status(inline_widget_status::selecting, i.selected());
|
||||||
|
else
|
||||||
|
p->inline_ptr->notify_status(inline_widget_status::checking, i.checked());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -407,11 +407,11 @@ namespace nana{ namespace widgets
|
|||||||
|
|
||||||
std::shared_ptr<colored_area_type> find(std::size_t pos) const
|
std::shared_ptr<colored_area_type> 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)
|
if (sp->begin <= pos && pos < sp->begin + sp->count)
|
||||||
return *i;
|
return sp;
|
||||||
else if (i->get()->begin > pos)
|
else if (sp->begin > pos)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return{};
|
return{};
|
||||||
@ -623,7 +623,9 @@ namespace nana{ namespace widgets
|
|||||||
//textbase is implement by using deque, and the linemtr holds the text pointers
|
//textbase is implement by using deque, and the linemtr holds the text pointers
|
||||||
//If the textbase is changed, it will check the text pointers.
|
//If the textbase is changed, it will check the text pointers.
|
||||||
std::size_t line = 0;
|
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);
|
auto const& text = editor_.textbase().getline(line);
|
||||||
if (sct.begin < text.c_str() || (text.c_str() + text.size() < sct.begin))
|
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
|
//textbase is implement by using deque, and the linemtr holds the text pointers
|
||||||
//If the textbase is changed, it will check the text pointers.
|
//If the textbase is changed, it will check the text pointers.
|
||||||
std::size_t line = 0;
|
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)
|
if (line < pos || (pos + line_size) <= line)
|
||||||
{
|
{
|
||||||
@ -664,8 +668,8 @@ namespace nana{ namespace widgets
|
|||||||
auto const & text = editor_.textbase().getline(pos);
|
auto const & text = editor_.textbase().getline(pos);
|
||||||
auto& txt_section = this->sections_[pos];
|
auto& txt_section = this->sections_[pos];
|
||||||
txt_section.begin = text.c_str();
|
txt_section.begin = text.c_str();
|
||||||
txt_section.end = text.c_str() + text.size();
|
txt_section.end = txt_section.begin + text.size();
|
||||||
txt_section.pixels = editor_._m_text_extent_size(text.c_str(), text.size()).width;
|
txt_section.pixels = editor_._m_text_extent_size(txt_section.begin, text.size()).width;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pre_calc_lines(unsigned) override
|
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
|
//textbase is implement by using deque, and the linemtr holds the text pointers
|
||||||
//If the textbase is changed, it will check the text pointers.
|
//If the textbase is changed, it will check the text pointers.
|
||||||
std::size_t line = 0;
|
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)
|
if (line < pos || (pos + lines) <= line)
|
||||||
{
|
{
|
||||||
@ -2031,11 +2037,9 @@ namespace nana{ namespace widgets
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
auto undo_ptr = std::unique_ptr<undo_input_text>(new undo_input_text(*this, std::wstring(1, '\n')));
|
auto undo_ptr = std::unique_ptr<undo_input_text>(new undo_input_text(*this, std::wstring(1, '\n')));
|
||||||
bool need_refresh = (select_.a != select_.b);
|
|
||||||
|
|
||||||
undo_ptr->set_selected_text();
|
undo_ptr->set_selected_text();
|
||||||
if(need_refresh)
|
points_.caret = _m_erase_select();
|
||||||
points_.caret = _m_erase_select();
|
|
||||||
|
|
||||||
undo_ptr->set_caret_pos();
|
undo_ptr->set_caret_pos();
|
||||||
|
|
||||||
@ -2067,12 +2071,7 @@ namespace nana{ namespace widgets
|
|||||||
points_.caret.x = 0;
|
points_.caret.x = 0;
|
||||||
|
|
||||||
auto origin = impl_->cview->origin();
|
auto origin = impl_->cview->origin();
|
||||||
if (origin.x || (points_.caret.y < textbase.lines()) || textbase.getline(points_.caret.y).size())
|
origin.x = 0;
|
||||||
{
|
|
||||||
origin.x = -origin.x;
|
|
||||||
impl_->cview->move_origin(origin);
|
|
||||||
need_refresh = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (impl_->indent.enabled)
|
if (impl_->indent.enabled)
|
||||||
{
|
{
|
||||||
@ -2090,13 +2089,13 @@ namespace nana{ namespace widgets
|
|||||||
put(text);
|
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);
|
impl_->cview->sync(true);
|
||||||
|
|
||||||
_m_reset_content_size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void text_editor::del()
|
void text_editor::del()
|
||||||
@ -2630,8 +2629,7 @@ namespace nana{ namespace widgets
|
|||||||
text_ptr = mask_str.c_str();
|
text_ptr = mask_str.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<unicode_bidi::entity> reordered;
|
auto const reordered = unicode_reorder(text_ptr, text_size);
|
||||||
unicode_bidi{}.linestr(text_ptr, text_size, reordered);
|
|
||||||
|
|
||||||
nana::upoint res(static_cast<unsigned>(real_str.begin - sections.front().begin), static_cast<unsigned>(row.first));
|
nana::upoint res(static_cast<unsigned>(real_str.begin - sections.front().begin), static_cast<unsigned>(row.first));
|
||||||
|
|
||||||
@ -3333,8 +3331,7 @@ namespace nana{ namespace widgets
|
|||||||
|
|
||||||
const auto focused = API::is_focus_ready(window_);
|
const auto focused = API::is_focus_ready(window_);
|
||||||
|
|
||||||
std::vector<unicode_bidi::entity> reordered;
|
auto const reordered = unicode_reorder(text_ptr, text_len);
|
||||||
unicode_bidi{}.linestr(text_ptr, text_len, reordered);
|
|
||||||
|
|
||||||
//Parse highlight keywords
|
//Parse highlight keywords
|
||||||
keyword_parser parser;
|
keyword_parser parser;
|
||||||
@ -3564,9 +3561,8 @@ namespace nana{ namespace widgets
|
|||||||
if (pos > lnstr.size())
|
if (pos > lnstr.size())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
std::vector<unicode_bidi::entity> reordered;
|
auto const reordered = unicode_reorder(lnstr.c_str(), lnstr.size());
|
||||||
unicode_bidi{}.linestr(lnstr.c_str(), lnstr.size(), reordered);
|
|
||||||
|
|
||||||
auto target = lnstr.c_str() + pos;
|
auto target = lnstr.c_str() + pos;
|
||||||
|
|
||||||
unsigned text_w = 0;
|
unsigned text_w = 0;
|
||||||
|
|||||||
@ -509,9 +509,7 @@ namespace paint
|
|||||||
nana::size sz;
|
nana::size sz;
|
||||||
if(impl_->handle && impl_->handle->context && str.size())
|
if(impl_->handle && impl_->handle->context && str.size())
|
||||||
{
|
{
|
||||||
std::vector<unicode_bidi::entity> reordered;
|
auto const reordered = unicode_reorder(str.c_str(), str.size());
|
||||||
unicode_bidi bidi;
|
|
||||||
bidi.linestr(str.c_str(), str.size(), reordered);
|
|
||||||
for(auto & i: reordered)
|
for(auto & i: reordered)
|
||||||
{
|
{
|
||||||
nana::size t = text_extent_size(i.begin, i.end - i.begin);
|
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)
|
unsigned graphics::bidi_string(const nana::point& pos, const wchar_t * str, std::size_t len)
|
||||||
{
|
{
|
||||||
auto moved_pos = pos;
|
auto moved_pos = pos;
|
||||||
unicode_bidi bidi;
|
|
||||||
std::vector<unicode_bidi::entity> reordered;
|
auto const reordered = unicode_reorder(str, len);
|
||||||
bidi.linestr(str, len, reordered);
|
|
||||||
for (auto & i : reordered)
|
for (auto & i : reordered)
|
||||||
{
|
{
|
||||||
string(moved_pos, i.begin, i.end - i.begin);
|
string(moved_pos, i.begin, i.end - i.begin);
|
||||||
|
|||||||
@ -13,26 +13,23 @@ namespace nana
|
|||||||
template<typename F>
|
template<typename F>
|
||||||
void for_each_line(const wchar_t * str, std::size_t len, int top, F & f)
|
void for_each_line(const wchar_t * str, std::size_t len, int top, F & f)
|
||||||
{
|
{
|
||||||
auto head = str;
|
auto const end = str + len;
|
||||||
auto end = str + len;
|
|
||||||
for(auto i = str; i != end; ++i)
|
for(auto i = str; i != end; ++i)
|
||||||
{
|
{
|
||||||
if(*i == '\n')
|
if(*i == '\n')
|
||||||
{
|
{
|
||||||
top += static_cast<int>(f(top, head, i - head));
|
top += static_cast<int>(f(top, str, i - str));
|
||||||
head = i + 1;
|
str = i + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(head != end)
|
if(str != end)
|
||||||
f(top, head, end - head);
|
f(top, str, end - str);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct draw_string
|
struct draw_string
|
||||||
{
|
{
|
||||||
drawable_type dw;
|
drawable_type dw;
|
||||||
const int x, endpos;
|
const int x, endpos;
|
||||||
nana::unicode_bidi bidi;
|
|
||||||
std::vector<nana::unicode_bidi::entity> reordered;
|
|
||||||
align text_align;
|
align text_align;
|
||||||
|
|
||||||
draw_string(drawable_type dw, int x, int endpos, align ta)
|
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)
|
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 };
|
nana::point pos{ x, top };
|
||||||
unsigned pixels = 0;
|
unsigned pixels = 0;
|
||||||
bidi.linestr(buf, bufsize, reordered);
|
|
||||||
switch(text_align)
|
switch(text_align)
|
||||||
{
|
{
|
||||||
case align::left:
|
case align::left:
|
||||||
@ -64,23 +65,28 @@ namespace nana
|
|||||||
case align::center:
|
case align::center:
|
||||||
{
|
{
|
||||||
unsigned lenpx = 0;
|
unsigned lenpx = 0;
|
||||||
std::vector<unsigned> widths;
|
std::unique_ptr<unsigned[]> entity_pxs(new unsigned[reordered.size()]);
|
||||||
|
|
||||||
|
auto ent_px = entity_pxs.get();
|
||||||
|
|
||||||
for(auto & ent : reordered)
|
for(auto & ent : reordered)
|
||||||
{
|
{
|
||||||
auto ts = detail::text_extent_size(dw, ent.begin, ent.end - ent.begin);
|
auto ts = detail::text_extent_size(dw, ent.begin, ent.end - ent.begin);
|
||||||
if(ts.height > pixels) pixels = ts.height;
|
if(ts.height > pixels) pixels = ts.height;
|
||||||
lenpx += ts.width;
|
lenpx += ts.width;
|
||||||
widths.emplace_back(ts.width);
|
*ent_px++ = ts.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos.x += (endpos - pos.x - static_cast<int>(lenpx))/2;
|
pos.x += (endpos - pos.x - static_cast<int>(lenpx))/2;
|
||||||
auto ipx = widths.begin();
|
ent_px = entity_pxs.get();
|
||||||
|
|
||||||
for(auto & ent : reordered)
|
for(auto & ent : reordered)
|
||||||
{
|
{
|
||||||
if(pos.x + static_cast<int>(*ipx) > 0)
|
if (pos.x + static_cast<int>(*ent_px) > 0)
|
||||||
detail::draw_string(dw, pos, ent.begin, ent.end - ent.begin);
|
detail::draw_string(dw, pos, ent.begin, ent.end - ent.begin);
|
||||||
|
|
||||||
pos.x += static_cast<int>(*ipx);
|
pos.x += static_cast<int>(*ent_px++);
|
||||||
|
|
||||||
if(pos.x >= endpos)
|
if(pos.x >= endpos)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -90,7 +96,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
int xend = endpos;
|
int xend = endpos;
|
||||||
std::swap(pos.x, xend);
|
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;
|
auto & ent = *i;
|
||||||
std::size_t len = ent.end - ent.begin;
|
std::size_t len = ent.end - ent.begin;
|
||||||
@ -118,13 +124,11 @@ namespace nana
|
|||||||
graphics & graph;
|
graphics & graph;
|
||||||
int x, endpos;
|
int x, endpos;
|
||||||
unsigned omitted_pixels;
|
unsigned omitted_pixels;
|
||||||
nana::unicode_bidi bidi;
|
|
||||||
std::vector<nana::unicode_bidi::entity> reordered;
|
|
||||||
|
|
||||||
draw_string_omitted(graphics& graph, int x, int endpos, bool omitted)
|
draw_string_omitted(graphics& graph, int x, int endpos, bool omitted)
|
||||||
: graph(graph), x(x), endpos(endpos)
|
: 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<int>(omitted_pixels))
|
if (endpos - x > static_cast<int>(omitted_pixels))
|
||||||
this->endpos -= omitted_pixels;
|
this->endpos -= omitted_pixels;
|
||||||
else
|
else
|
||||||
@ -136,7 +140,9 @@ namespace nana
|
|||||||
drawable_type dw = graph.handle();
|
drawable_type dw = graph.handle();
|
||||||
::nana::point pos{ x, top };
|
::nana::point pos{ x, top };
|
||||||
unsigned pixels = 0;
|
unsigned pixels = 0;
|
||||||
bidi.linestr(buf, bufsize, reordered);
|
|
||||||
|
auto const reordered = unicode_reorder(buf, bufsize);
|
||||||
|
|
||||||
for(auto & i : reordered)
|
for(auto & i : reordered)
|
||||||
{
|
{
|
||||||
std::size_t len = i.end - i.begin;
|
std::size_t len = i.end - i.begin;
|
||||||
@ -178,9 +184,6 @@ namespace nana
|
|||||||
{
|
{
|
||||||
graphics & graph;
|
graphics & graph;
|
||||||
int x, endpos;
|
int x, endpos;
|
||||||
nana::unicode_bidi bidi;
|
|
||||||
std::vector<nana::unicode_bidi::entity> reordered;
|
|
||||||
std::vector<nana::size> ts_keeper;
|
|
||||||
align text_align;
|
align text_align;
|
||||||
|
|
||||||
draw_string_auto_changing_lines(graphics& graph, int x, int endpos, align ta)
|
draw_string_auto_changing_lines(graphics& graph, int x, int endpos, align ta)
|
||||||
@ -191,10 +194,13 @@ namespace nana
|
|||||||
{
|
{
|
||||||
unsigned pixels = 0;
|
unsigned pixels = 0;
|
||||||
|
|
||||||
drawable_type dw = graph.handle();
|
auto const dw = graph.handle();
|
||||||
unsigned str_w = 0;
|
unsigned str_w = 0;
|
||||||
ts_keeper.clear();
|
|
||||||
bidi.linestr(buf, bufsize, reordered);
|
std::vector<nana::size> ts_keeper;
|
||||||
|
|
||||||
|
auto const reordered = unicode_reorder(buf, bufsize);
|
||||||
|
|
||||||
for(auto & i : reordered)
|
for(auto & i : reordered)
|
||||||
{
|
{
|
||||||
nana::size ts = detail::text_extent_size(dw, i.begin, i.end - i.begin);
|
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();
|
auto i_ts_keeper = ts_keeper.cbegin();
|
||||||
for(auto & i : reordered)
|
for(auto & i : reordered)
|
||||||
{
|
{
|
||||||
if(line_pixels < i_ts_keeper->height)
|
if(line_pixels < i_ts_keeper->height)
|
||||||
line_pixels = i_ts_keeper->height;
|
line_pixels = i_ts_keeper->height;
|
||||||
|
|
||||||
bool beyond_edge = (pos.x + static_cast<int>(i_ts_keeper->width) > endpos);
|
bool beyond_edge = (pos.x + static_cast<int>(i_ts_keeper->width) > endpos);
|
||||||
if(beyond_edge)
|
if(beyond_edge)
|
||||||
{
|
{
|
||||||
std::size_t len = i.end - i.begin;
|
const std::size_t len = i.end - i.begin;
|
||||||
if(len > 1)
|
if(len > 1)
|
||||||
{
|
{
|
||||||
unsigned * pxbuf = new unsigned[len];
|
std::unique_ptr<unsigned[]> pixel_buf(new unsigned[len]);
|
||||||
|
|
||||||
//Find the char that should be splitted
|
//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;
|
std::size_t idx_head = 0, idx_splitted;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
auto pxbuf = pixel_buf.get();
|
||||||
|
|
||||||
idx_splitted = find_splitted(idx_head, len, pos.x, endpos, pxbuf);
|
idx_splitted = find_splitted(idx_head, len, pos.x, endpos, pxbuf);
|
||||||
if(idx_splitted == len)
|
if(idx_splitted == len)
|
||||||
{
|
{
|
||||||
detail::draw_string(dw, pos, 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)
|
for(std::size_t i = idx_head; i < len; ++i)
|
||||||
pos.x += static_cast<int>(pxbuf[i]);
|
pos.x += static_cast<int>(pxbuf[i]);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
//Check the word whether it is splittable.
|
//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);
|
detail::draw_string(dw, pos, i.begin + idx_head, idx_splitted - idx_head);
|
||||||
idx_head = idx_splitted;
|
idx_head = idx_splitted;
|
||||||
pos.x = x;
|
pos.x = x;
|
||||||
pos.y += line_pixels;
|
pos.y += static_cast<int>(line_pixels);
|
||||||
line_pixels = i_ts_keeper->height;
|
line_pixels = i_ts_keeper->height;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -283,18 +294,16 @@ namespace nana
|
|||||||
|
|
||||||
for(std::size_t k = idx_head; k < idx_head + splen; ++k)
|
for(std::size_t k = idx_head; k < idx_head + splen; ++k)
|
||||||
pos.x += static_cast<int>(pxbuf[k]);
|
pos.x += static_cast<int>(pxbuf[k]);
|
||||||
|
|
||||||
if (pos.x >= endpos)
|
if (pos.x >= endpos)
|
||||||
{
|
{
|
||||||
pos.x = x;
|
pos.x = x;
|
||||||
pos.y += static_cast<int>(line_pixels);
|
pos.y += static_cast<int>(line_pixels);
|
||||||
line_pixels = i_ts_keeper->height;
|
|
||||||
}
|
}
|
||||||
idx_head += splen;
|
idx_head += splen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}while(idx_head < len);
|
}while(idx_head < len);
|
||||||
|
|
||||||
delete [] pxbuf;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -340,7 +349,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
point pos{ endpos, top };
|
point pos{ endpos, top };
|
||||||
auto i_ts_keeper = ts_keeper.crbegin();
|
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;
|
auto & ent = *i;
|
||||||
std::size_t len = ent.end - ent.begin;
|
std::size_t len = ent.end - ent.begin;
|
||||||
@ -397,9 +406,6 @@ namespace nana
|
|||||||
{
|
{
|
||||||
graphics & graph;
|
graphics & graph;
|
||||||
int x, endpos;
|
int x, endpos;
|
||||||
nana::unicode_bidi bidi;
|
|
||||||
std::vector<nana::unicode_bidi::entity> reordered;
|
|
||||||
std::vector<nana::size> ts_keeper;
|
|
||||||
unsigned extents;
|
unsigned extents;
|
||||||
|
|
||||||
extent_auto_changing_lines(graphics& graph, int x, int endpos)
|
extent_auto_changing_lines(graphics& graph, int x, int endpos)
|
||||||
@ -412,8 +418,10 @@ namespace nana
|
|||||||
|
|
||||||
drawable_type dw = graph.handle();
|
drawable_type dw = graph.handle();
|
||||||
unsigned str_w = 0;
|
unsigned str_w = 0;
|
||||||
ts_keeper.clear();
|
std::vector<nana::size> ts_keeper;
|
||||||
bidi.linestr(buf, bufsize, reordered);
|
|
||||||
|
auto const reordered = unicode_reorder(buf, bufsize);
|
||||||
|
|
||||||
for(auto & i : reordered)
|
for(auto & i : reordered)
|
||||||
{
|
{
|
||||||
nana::size ts = detail::text_extent_size(dw, i.begin, i.end - i.begin);
|
nana::size ts = detail::text_extent_size(dw, i.begin, i.end - i.begin);
|
||||||
@ -503,7 +511,6 @@ namespace nana
|
|||||||
{
|
{
|
||||||
xpos = x;
|
xpos = x;
|
||||||
top += line_pixels;
|
top += line_pixels;
|
||||||
line_pixels = i_ts_keeper->height;
|
|
||||||
}
|
}
|
||||||
idx_head += splen;
|
idx_head += splen;
|
||||||
}
|
}
|
||||||
@ -645,11 +652,9 @@ namespace nana
|
|||||||
substr_px += *p;
|
substr_px += *p;
|
||||||
} while (p != end);
|
} while (p != end);
|
||||||
|
|
||||||
pos.x += static_cast<int>(width - ellipsis - substr_px);
|
pos.x += static_cast<int>(width - ellipsis - substr_px) + ellipsis;
|
||||||
|
|
||||||
graph_.string(pos, "...");
|
|
||||||
pos.x += ellipsis;
|
|
||||||
graph_.bidi_string(pos, text.c_str() + substr_len, text.size() - substr_len);
|
graph_.bidi_string(pos, text.c_str() + substr_len, text.size() - substr_len);
|
||||||
|
pos.x -= ellipsis;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -669,8 +674,9 @@ namespace nana
|
|||||||
graph_.bidi_string(pos, text.c_str(), substr_len);
|
graph_.bidi_string(pos, text.c_str(), substr_len);
|
||||||
|
|
||||||
pos.x += substr_px;
|
pos.x += substr_px;
|
||||||
graph_.string(pos, "...");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
graph_.string(pos, "...");
|
||||||
}
|
}
|
||||||
|
|
||||||
//end class string
|
//end class string
|
||||||
|
|||||||
@ -276,8 +276,7 @@ namespace nana
|
|||||||
if(ch <= 0x1CC7) return L; //N = 141
|
if(ch <= 0x1CC7) return L; //N = 141
|
||||||
if(0x1CD3 == ch || 0x1CE1 == ch) return L;
|
if(0x1CD3 == ch || 0x1CE1 == ch) return L;
|
||||||
if(ch <= 0x1CE8) return NSM; //N = 7
|
if(ch <= 0x1CE8) return NSM; //N = 7
|
||||||
if(0x1CED == ch) return NSM;
|
if(0x1CED == ch || 0x1CF4 == ch) return NSM;
|
||||||
if(0x1CF4 == ch) return NSM;
|
|
||||||
if(ch <= 0x1DBF) return L; //N = 203
|
if(ch <= 0x1DBF) return L; //N = 203
|
||||||
if(ch <= 0x1DFF) return NSM; //N = 64
|
if(ch <= 0x1DFF) return NSM; //N = 64
|
||||||
if(ch <= 0x1FBC) return L; //N = 445
|
if(ch <= 0x1FBC) return L; //N = 445
|
||||||
@ -504,21 +503,21 @@ namespace nana
|
|||||||
}
|
}
|
||||||
|
|
||||||
//class unicode_bidi
|
//class unicode_bidi
|
||||||
void unicode_bidi::linestr(const char_type* str, std::size_t len, std::vector<entity> & reordered)
|
std::vector<unicode_bidi::entity> unicode_bidi::reorder(const char_type* str, std::size_t len)
|
||||||
{
|
{
|
||||||
levels_.clear();
|
levels_.clear();
|
||||||
const char_type * const end = str + len;
|
const char_type * const end = str + len;
|
||||||
|
|
||||||
std::vector<remember> stack;
|
std::vector<remember> stack;
|
||||||
|
|
||||||
remember cur = {0, directional_override_status::neutral};
|
remember cur = { 0, directional_override_status::neutral };
|
||||||
cur.level = _m_paragraph_level(str, end);
|
cur.level = _m_paragraph_level(str, end);
|
||||||
|
|
||||||
//First character type
|
//First character type
|
||||||
bidi_char begin_char_type = {};
|
bidi_char begin_char_type = {};
|
||||||
const char_type * begin_character = nullptr;
|
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)
|
if (PDF == *c)
|
||||||
{
|
{
|
||||||
@ -579,13 +578,17 @@ namespace nana
|
|||||||
begin_character = c;
|
begin_character = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(begin_character)
|
if (begin_character)
|
||||||
_m_push_entity(begin_character, end, cur.level, begin_char_type);
|
_m_push_entity(begin_character, end, cur.level, begin_char_type);
|
||||||
|
|
||||||
_m_resolve_weak_types();
|
_m_resolve_weak_types();
|
||||||
_m_resolve_neutral_types();
|
_m_resolve_neutral_types();
|
||||||
_m_resolve_implicit_levels();
|
_m_resolve_implicit_levels();
|
||||||
|
|
||||||
|
std::vector<unicode_bidi::entity> reordered;
|
||||||
_m_reordering_resolved_levels(reordered);
|
_m_reordering_resolved_levels(reordered);
|
||||||
|
|
||||||
|
return reordered;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned unicode_bidi::_m_paragraph_level(const char_type * begin, const char_type * end)
|
unsigned unicode_bidi::_m_paragraph_level(const char_type * begin, const char_type * end)
|
||||||
@ -938,4 +941,9 @@ namespace nana
|
|||||||
return static_cast<bidi_char>(static_cast<int>(type - bidi_charmap::B) + 0x2000);
|
return static_cast<bidi_char>(static_cast<int>(type - bidi_charmap::B) + 0x2000);
|
||||||
}
|
}
|
||||||
//end class unicode_bidi
|
//end class unicode_bidi
|
||||||
|
|
||||||
|
std::vector<unicode_bidi::entity> unicode_reorder(const wchar_t* text, std::size_t length)
|
||||||
|
{
|
||||||
|
return unicode_bidi{}.reorder(text, length);
|
||||||
|
}
|
||||||
}//end namespace nana
|
}//end namespace nana
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user