[vte/wip/egmont/bidi: 12/107] mirror box drawing (dec private 2500)



commit 1b873f3b4802e475fe91a62a7810b1a7c1b7ce8f
Author: Egmont Koblinger <egmont gmail com>
Date:   Sun Aug 19 23:25:29 2018 +0200

    mirror box drawing (dec private 2500)

 src/modes-private.hh | 11 +++++++++++
 src/ring.hh          |  2 +-
 src/vte.cc           | 16 +++++++++-------
 src/vtedraw.cc       | 12 ++++++------
 src/vtedraw.hh       |  1 +
 src/vteinternal.hh   | 11 ++++++-----
 src/vterowdata.hh    |  2 +-
 src/vteseq.cc        |  3 +++
 8 files changed, 38 insertions(+), 20 deletions(-)
---
diff --git a/src/modes-private.hh b/src/modes-private.hh
index eb313823..2765bfdf 100644
--- a/src/modes-private.hh
+++ b/src/modes-private.hh
@@ -142,6 +142,17 @@ MODE(XTERM_READLINE_BRACKETED_PASTE, 2004)
 
 MODE(URXVT_MOUSE_EXT, 1015)
 
+/* VTE */
+
+/*
+ * Whether box drawing characters in the U+2500..U+257F range
+ * are to be mirrored in RTL context.
+ *
+ * The (temporary) choice of number 2500 is a misuse of hex 2500
+ * as a decimal number, but is supposed to be easily memorable.
+ */
+MODE(VTE_BOX_DRAWING_MIRROR, 2500)
+
 /* Not supported modes: */
 
 /* DEC */
diff --git a/src/ring.hh b/src/ring.hh
index f0f82fdd..06ed22fe 100644
--- a/src/ring.hh
+++ b/src/ring.hh
@@ -120,7 +120,7 @@ private:
                 size_t attr_start_offset;  /* offset of the first character's attributes */
                 int soft_wrapped: 1;      /* end of line is not '\n' */
                 int is_ascii: 1;          /* for rewrapping speedup: guarantees that line contains 32..126 
bytes only. Can be 0 even when ascii only. */
-                guint8 bidi_flags: 3;
+                guint8 bidi_flags: 4;
         } RowRecord;
 
         static_assert(std::is_pod<RowRecord>::value, "Ring::RowRecord is not POD");
diff --git a/src/vte.cc b/src/vte.cc
index c700d9a2..05f5b40b 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -434,7 +434,7 @@ Terminal::find_charcell(vte::grid::column_t col,
 VteCell const*
 Terminal::find_charcell_bidi(vte::grid::column_t col,
                                   vte::grid::row_t row,
-                                  gboolean *rtl) const
+                                  guint8 *bidi_flags) const
 {
        VteRowData const* rowdata;
        VteCell const* ret = nullptr;
@@ -442,7 +442,7 @@ Terminal::find_charcell_bidi(vte::grid::column_t col,
        if (_vte_ring_contains(m_screen->row_data, row)) {
                rowdata = _vte_ring_index(m_screen->row_data, row);
                ret = _vte_row_data_get (rowdata, col);
-               *rtl = rowdata->attr.bidi_flags & VTE_BIDI_RTL;
+               *bidi_flags = rowdata->attr.bidi_flags;
        }
        return ret;
 }
@@ -3025,7 +3025,8 @@ Terminal::get_bidi_flags()
 {
         return (m_modes_ecma.BDSM() ? VTE_BIDI_IMPLICIT : 0) |
                (m_bidi_rtl ? VTE_BIDI_RTL : 0) |
-               (m_bidi_auto ? VTE_BIDI_AUTO : 0);
+               (m_bidi_auto ? VTE_BIDI_AUTO : 0) |
+               (m_modes_private.VTE_BOX_DRAWING_MIRROR() ? VTE_BIDI_BOX_MIRROR : 0);
 }
 
 /* Apply the BiDi parameters on the current paragraph if the cursor
@@ -3061,7 +3062,7 @@ Terminal::maybe_apply_bidi_attributes()
                 if (rowdata == nullptr)
                         return;
                 rowdata->attr.bidi_flags = get_bidi_flags();
-                invalidate_cells(0, m_column_count, row, 1);
+                invalidate_row(row);
                 if (!rowdata->attr.soft_wrapped)
                         return;
                 row++;
@@ -9094,6 +9095,7 @@ Terminal::draw_rows(VteScreen *screen_,
                         items[item_count].columns = j - col;
                         items[item_count].x = col * column_width;
                         items[item_count].y = y;
+                        items[item_count].mirror = ((row_data->attr.bidi_flags & (VTE_BIDI_RTL | 
VTE_BIDI_BOX_MIRROR)) == (VTE_BIDI_RTL | VTE_BIDI_BOX_MIRROR));  // FIXME
                         item_count++;
 
                         g_assert_cmpint (j, >, col);
@@ -9149,8 +9151,8 @@ Terminal::paint_cursor()
 
         /* Find the first cell of the character "under" the cursor.
          * This is for CJK.  For TAB, paint the cursor where it really is. */
-        gboolean rtl = FALSE;
-       auto cell = find_charcell_bidi(col, drow, &rtl);
+        guint8 bidi_flags = 0;
+       auto cell = find_charcell_bidi(col, drow, &bidi_flags);
         while (cell != NULL && cell->attr.fragment() && cell->c != '\t' && col > 0) {
                col--;
                cell = find_charcell(col, drow);
@@ -9159,7 +9161,7 @@ Terminal::paint_cursor()
        /* Draw the cursor. */
        item.c = (cell && cell->c) ? cell->c : ' ';
        item.columns = item.c == '\t' ? 1 : cell ? cell->attr.columns() : 1;
-       item.x = (rtl ? m_column_count - 1 - col : col) * width;
+       item.x = ((bidi_flags & VTE_BIDI_RTL) ? m_column_count - 1 - col : col) * width;
        item.y = row_to_pixel(drow);
        if (cell && cell->c != 0) {
                style = _vte_draw_get_style(cell->attr.bold(), cell->attr.italic());
diff --git a/src/vtedraw.cc b/src/vtedraw.cc
index 215e27ee..d88a5f72 100644
--- a/src/vtedraw.cc
+++ b/src/vtedraw.cc
@@ -1009,7 +1009,7 @@ _vte_draw_unichar_is_local_graphic(vteunistr c)
 /* Draw the graphic representation of a line-drawing or special graphics
  * character. */
 static void
-_vte_draw_terminal_draw_graphic(struct _vte_draw *draw, vteunistr c, vte::color::rgb const* fg,
+_vte_draw_terminal_draw_graphic(struct _vte_draw *draw, vteunistr c, gboolean mirror, vte::color::rgb const* 
fg,
                                 gint x, gint y,
                                 gint font_width, gint columns, gint font_height)
 {
@@ -1180,7 +1180,7 @@ _vte_draw_terminal_draw_graphic(struct _vte_draw *draw, vteunistr c, vte::color:
                 int xi, yi;
                 cairo_set_line_width(cr, 0);
                 for (yi = 4; yi >= 0; yi--) {
-                        for (xi = 4; xi >= 0; xi--) {
+                        for (xi = mirror ? 0 : 4; xi >= 0 && xi <= 4; mirror ? xi++ : xi--) {
                                 if (bitmap & 1) {
                                         cairo_rectangle(cr,
                                                         x + xboundaries[xi],
@@ -1258,7 +1258,7 @@ _vte_draw_terminal_draw_graphic(struct _vte_draw *draw, vteunistr c, vte::color:
         case 0x256f: /* box drawings light arc up and left */
         case 0x2570: /* box drawings light arc up and right */
         {
-                const guint v = c - 0x256d;
+                const guint v = (c - 0x256d) ^ (mirror ? 1 : 0);
                 int line_width;
                 int radius;
 
@@ -1308,12 +1308,12 @@ _vte_draw_terminal_draw_graphic(struct _vte_draw *draw, vteunistr c, vte::color:
                 cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
                 cairo_set_line_width(cr, light_line_width);
                 adjust = light_line_width / 2.;
-                if (c != 0x2571) {
+                if (c != (mirror ? 0x2572 : 0x2571)) {
                         cairo_move_to(cr, x + adjust, y + adjust);
                         cairo_line_to(cr, xright - adjust, ybottom - adjust);
                         cairo_stroke(cr);
                 }
-                if (c != 0x2572) {
+                if (c != (mirror ? 0x2571 : 0x2572)) {
                         cairo_move_to(cr, xright - adjust, y + adjust);
                         cairo_line_to(cr, x + adjust, ybottom - adjust);
                         cairo_stroke(cr);
@@ -1496,7 +1496,7 @@ _vte_draw_text_internal (struct _vte_draw *draw,
                 y = requests[i].y + draw->char_spacing.top + font->ascent;
 
                 if (_vte_draw_unichar_is_local_graphic(c)) {
-                        _vte_draw_terminal_draw_graphic(draw, c, color,
+                        _vte_draw_terminal_draw_graphic(draw, c, requests[i].mirror, color,
                                                         requests[i].x, requests[i].y,
                                                         font->width, requests[i].columns, font->height);
                         continue;
diff --git a/src/vtedraw.hh b/src/vtedraw.hh
index 7352d376..54cae5f2 100644
--- a/src/vtedraw.hh
+++ b/src/vtedraw.hh
@@ -44,6 +44,7 @@ struct _vte_draw;
 struct _vte_draw_text_request {
        vteunistr c;
        gshort x, y, columns;
+       guint8 mirror : 1;
 };
 
 guint _vte_draw_get_style(gboolean bold, gboolean italic);
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index a892cc7c..d6b0d14d 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -87,9 +87,10 @@ enum {
 };
 
 enum {
-        VTE_BIDI_IMPLICIT = 1 << 0,
-        VTE_BIDI_RTL      = 1 << 1,
-        VTE_BIDI_AUTO     = 1 << 2,
+        VTE_BIDI_IMPLICIT   = 1 << 0,
+        VTE_BIDI_RTL        = 1 << 1,
+        VTE_BIDI_AUTO       = 1 << 2,
+        VTE_BIDI_BOX_MIRROR = 1 << 3,
 };
 
 struct vte_regex_and_flags {
@@ -614,7 +615,7 @@ public:
         const char *m_hyperlink_hover_uri; /* data is owned by the ring */
         long m_hyperlink_auto_id;
 
-        /* BiDi */
+        /* BiDi parameters outside of ECMA and DEC private modes */
         guint m_bidi_rtl  : 1;
         guint m_bidi_auto : 1;
 
@@ -631,7 +632,7 @@ public:
                                             vte::grid::row_t row) const;
         inline VteCell const* find_charcell_bidi(vte::grid::column_t col,
                                             vte::grid::row_t row,
-                                            gboolean *rtl) const;
+                                            guint8 *bidi_flags) const;
         inline vte::grid::column_t find_start_column(vte::grid::column_t col,
                                                      vte::grid::row_t row) const;
         inline vte::grid::column_t find_end_column(vte::grid::column_t col,
diff --git a/src/vterowdata.hh b/src/vterowdata.hh
index 9e43e796..12cbf311 100644
--- a/src/vterowdata.hh
+++ b/src/vterowdata.hh
@@ -37,7 +37,7 @@ G_BEGIN_DECLS
 
 typedef struct _VteRowAttr {
         guint8 soft_wrapped  : 1;
-        guint8 bidi_flags    : 3;
+        guint8 bidi_flags    : 4;
 } VteRowAttr;
 static_assert(sizeof (VteRowAttr) == 1, "VteRowAttr has wrong size");
 
diff --git a/src/vteseq.cc b/src/vteseq.cc
index 18b21ac8..8bf0c970 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -593,6 +593,9 @@ Terminal::set_mode_private(int mode,
                         feed_focus_event_initial();
                 break;
 
+        case vte::terminal::modes::Private::eVTE_BOX_DRAWING_MIRROR:
+                maybe_apply_bidi_attributes();
+
         default:
                 break;
         }


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