[vte/wip/egmont/bidi: 5/10] widget, bidi: Shift Arabic ligatures by half cell to the right



commit 88b3a2bb8131bdff7608a0df119eed8bee64473f
Author: Egmont Koblinger <egmont gmail com>
Date:   Thu Jun 6 11:56:43 2019 +0200

    widget,bidi: Shift Arabic ligatures by half cell to the right

 src/vte.cc | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)
---
diff --git a/src/vte.cc b/src/vte.cc
index 97094449..a0f65081 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -9362,6 +9362,32 @@ Terminal::draw_rows(VteScreen *screen_,
                                 }
                         }
 
+                        /* There are certain mandatory ligatures in Arabic, e.g.
+                         * LAM U+0644 (on the right) + ALEF U+0627 (on the left)
+                         * needs to become a single symbol (U+FEFB or U+FEFC in the
+                         * legacy presentation form characters).
+                         * FriBidi replaces the first (right) character with ZWNBSP U+FEFF and
+                         * the second (left) character with the desired presentation form.
+                         * Detect if we're about to render this glyph, and shift by half a cell
+                         * to the right. */
+                        // FIXME Get FriBidi devs document this behavior.
+                        // FIXME Check what Arabic monospace fonts do. Is there any where these
+                        // ligated glyphs are wide, thus we now break their positioning?
+                        vteunistr c_shaped = bidirow->vis_get_shaped_char(vcol, c);
+                        int xoff = 0;
+                        if (G_UNLIKELY (c_shaped != c && vcol < column_count - 1)) {
+                                int vcol2 = vcol + 1;
+                                int lcol2 = bidirow->vis2log(vcol2);
+                                const VteCell *cell2 = _vte_row_data_get (row_data, lcol2);
+                                if (cell2 != nullptr) {
+                                        vteunistr c2 = cell2->c;
+                                        vteunistr c2_shaped = bidirow->vis_get_shaped_char(vcol2, c2);
+                                        if (c2 != 0xFEFF && c2_shaped == 0xFEFF) {
+                                                xoff = column_width / 2;
+                                        }
+                                }
+                        }
+
                         attr = nattr;
                         fore = nfore;
                         back = nback;
@@ -9370,9 +9396,9 @@ Terminal::draw_rows(VteScreen *screen_,
                         hilite = nhilite;
 
                         g_assert_cmpint (item_count, <, column_count);
-                        items[item_count].c = bidirow->vis_get_shaped_char(vcol, c);
+                        items[item_count].c = c_shaped;
                         items[item_count].columns = j - lcol;
-                        items[item_count].x = (vcol - (bidirow->vis_is_rtl(vcol) ? items[item_count].columns 
- 1 : 0)) * column_width ;
+                        items[item_count].x = (vcol - (bidirow->vis_is_rtl(vcol) ? items[item_count].columns 
- 1 : 0)) * column_width + xoff;
                         items[item_count].y = y;
                         items[item_count].mirror = bidirow->vis_is_rtl(vcol);
                         items[item_count].box_mirror = !!(row_data->attr.bidi_flags & 
VTE_BIDI_FLAG_BOX_MIRROR);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]