Fix crashes editing composed unicode strings

This commit is contained in:
David Capello 2017-03-08 13:54:21 -03:00
parent d9245588d0
commit 482f3eed0e
2 changed files with 13 additions and 24 deletions

View File

@ -22,17 +22,18 @@ namespace ft {
, m_unicodeFuncs(hb_buffer_get_unicode_funcs(face.buffer())) { , m_unicodeFuncs(hb_buffer_get_unicode_funcs(face.buffer())) {
} }
bool initialize(const base::utf8_const_iterator& it, bool initialize(const base::utf8_const_iterator& begin,
const base::utf8_const_iterator& end) { const base::utf8_const_iterator& end) {
m_begin = m_it = it;
m_end = end;
m_index = 0; m_index = 0;
if (begin == end)
return false;
hb_buffer_t* buf = m_face.buffer(); hb_buffer_t* buf = m_face.buffer();
hb_buffer_reset(buf); hb_buffer_reset(buf);
for (auto it=m_it; it!=end; ++it) for (auto it=begin; it!=end; ++it)
hb_buffer_add(buf, *it, 0); hb_buffer_add(buf, *it, it - begin);
hb_buffer_set_cluster_level(buf, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS);
hb_buffer_set_content_type(buf, HB_BUFFER_CONTENT_TYPE_UNICODE); hb_buffer_set_content_type(buf, HB_BUFFER_CONTENT_TYPE_UNICODE);
hb_buffer_set_direction(buf, HB_DIRECTION_LTR); hb_buffer_set_direction(buf, HB_DIRECTION_LTR);
hb_buffer_guess_segment_properties(buf); hb_buffer_guess_segment_properties(buf);
@ -45,18 +46,16 @@ namespace ft {
} }
bool nextChar() { bool nextChar() {
advanceIterator(m_it);
++m_index; ++m_index;
return (m_index < m_glyphCount); return (m_index < m_glyphCount);
} }
int unicodeChar() const { int unicodeChar() const {
auto it = m_it; return m_glyphInfo[m_index].codepoint;
return advanceIterator(it);
} }
int charIndex() { int charIndex() {
return m_it - m_begin; return m_glyphInfo[m_index].cluster;
} }
unsigned int glyphIndex() const { unsigned int glyphIndex() const {
@ -74,25 +73,11 @@ namespace ft {
} }
private: private:
hb_codepoint_t advanceIterator(base::utf8_const_iterator& it) const {
hb_codepoint_t chr = *it;
hb_codepoint_t newChr = 0;
++it;
while (it != m_end) {
if (!hb_unicode_compose(m_unicodeFuncs, chr, *it, &newChr))
break;
chr = newChr;
++it;
}
return chr;
}
HBFace& m_face; HBFace& m_face;
hb_glyph_info_t* m_glyphInfo; hb_glyph_info_t* m_glyphInfo;
hb_glyph_position_t* m_glyphPos; hb_glyph_position_t* m_glyphPos;
unsigned int m_glyphCount; unsigned int m_glyphCount;
int m_index; unsigned int m_index;
base::utf8_const_iterator m_begin, m_end, m_it;
hb_unicode_funcs_t* m_unicodeFuncs; hb_unicode_funcs_t* m_unicodeFuncs;
}; };

View File

@ -850,6 +850,10 @@ void Entry::recalcCharBoxes(const std::string& text)
gfx::ColorNone, gfx::ColorNone, 0, 0, &delegate); gfx::ColorNone, gfx::ColorNone, 0, 0, &delegate);
m_boxes = delegate.boxes(); m_boxes = delegate.boxes();
if (!m_boxes.empty()) {
m_boxes.back().to = lastTextIndex;
}
// A last box for the last position // A last box for the last position
CharBox box; CharBox box;
box.codepoint = 0; box.codepoint = 0;