|
|
@@ -1411,6 +1411,10 @@ assemble_row(TextAssembler::TextRow &row,
|
|
|
PN_stdfloat xpos = 0.0f;
|
|
|
align = TextProperties::A_left;
|
|
|
|
|
|
+ TextProperties::Direction dir = TextProperties::D_ltr;
|
|
|
+ size_t rtl_begin = 0;
|
|
|
+ PN_stdfloat rtl_begin_xpos = 0.0f;
|
|
|
+
|
|
|
// Remember previous character, for kerning.
|
|
|
int prev_char = -1;
|
|
|
|
|
|
@@ -1472,6 +1476,8 @@ assemble_row(TextAssembler::TextRow &row,
|
|
|
// Shape the buffer accumulated so far.
|
|
|
shape_buffer(harfbuff, placed_glyphs, xpos, prev_cprops->_properties);
|
|
|
hb_buffer_reset(harfbuff);
|
|
|
+ rtl_begin = placed_glyphs.size();
|
|
|
+ rtl_begin_xpos = xpos;
|
|
|
|
|
|
} else if (harfbuff == nullptr && text_use_harfbuzz &&
|
|
|
font->is_of_type(DynamicTextFont::get_class_type())) {
|
|
|
@@ -1486,6 +1492,29 @@ assemble_row(TextAssembler::TextRow &row,
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
+ // When not using harfbuzz, check if the direction was set explicitly.
|
|
|
+ if (properties->has_direction() && properties->get_direction() != dir) {
|
|
|
+ if (dir == TextProperties::D_rtl) {
|
|
|
+ // Flip the preceding characters.
|
|
|
+ PN_stdfloat xpos2 = xpos;
|
|
|
+ size_t i = placed_glyphs.size();
|
|
|
+ while (i > rtl_begin) {
|
|
|
+ --i;
|
|
|
+ PN_stdfloat new_xpos = rtl_begin_xpos + (xpos - xpos2);
|
|
|
+ xpos2 = placed_glyphs[i]._xpos;
|
|
|
+ placed_glyphs[i]._xpos = new_xpos;
|
|
|
+ }
|
|
|
+ dir = TextProperties::D_ltr;
|
|
|
+ }
|
|
|
+ else if (dir == TextProperties::D_ltr) {
|
|
|
+ // When switching to right-to-left, keep track of the first glyph that
|
|
|
+ // was RTL so that we can later offset the X positions.
|
|
|
+ dir = TextProperties::D_rtl;
|
|
|
+ rtl_begin = placed_glyphs.size();
|
|
|
+ rtl_begin_xpos = xpos;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (character == ' ') {
|
|
|
// A space is a special case.
|
|
|
xpos += properties->get_glyph_scale() * properties->get_text_scale() * font->get_space_advance();
|
|
|
@@ -1651,6 +1680,18 @@ assemble_row(TextAssembler::TextRow &row,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (dir == TextProperties::D_rtl) {
|
|
|
+ // Flip the preceding characters.
|
|
|
+ PN_stdfloat xpos2 = xpos;
|
|
|
+ size_t i = placed_glyphs.size();
|
|
|
+ while (i > rtl_begin) {
|
|
|
+ --i;
|
|
|
+ PN_stdfloat new_xpos = rtl_begin_xpos + (xpos - xpos2);
|
|
|
+ xpos2 = placed_glyphs[i]._xpos;
|
|
|
+ placed_glyphs[i]._xpos = new_xpos;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
#ifdef HAVE_HARFBUZZ
|
|
|
if (harfbuff != nullptr && hb_buffer_get_length(harfbuff) > 0) {
|
|
|
shape_buffer(harfbuff, placed_glyphs, xpos, prev_cprops->_properties);
|