mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-10 19:13:29 +00:00
Fix crashes editing composed unicode strings
This commit is contained in:
parent
d9245588d0
commit
482f3eed0e
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user