From: Youhei SASAKI <uwabami@gfd-dennou.org>
Date: Wed, 10 Dec 2025 15:08:56 +0900
Subject: Apply: enable-wide-glyphs.patch

Signed-off-by: Youhei SASAKI <uwabami@gfd-dennou.org>
---
 config.h.in     |  3 +++
 configure       | 17 ++++++++++++++++
 configure.ac    | 11 ++++++++++
 src/command.C   |  2 ++
 src/rxvtfont.C  |  9 +++++++++
 src/screen.C    | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/xdefaults.C |  3 +++
 7 files changed, 106 insertions(+), 2 deletions(-)

diff --git a/config.h.in b/config.h.in
index 934b2f8..909b82c 100644
--- a/config.h.in
+++ b/config.h.in
@@ -18,6 +18,9 @@
 /* Define if you want your background to use the parent window background */
 #undef ENABLE_TRANSPARENCY
 
+/* Define if you want to display wide glyphs */
+#undef ENABLE_WIDE_GLYPHS
+
 /* Define if you want european extended codesets */
 #undef ENCODING_EU
 
diff --git a/configure b/configure
index 55b8796..d32dc68 100755
--- a/configure
+++ b/configure
@@ -739,6 +739,7 @@ enable_unicode3
 enable_combining
 enable_xft
 enable_font_styles
+enable_wide_glyphs
 enable_pixbuf
 enable_startup_notification
 enable_transparency
@@ -1414,6 +1415,7 @@ Optional Features:
   --enable-combining      enable composition of base and combining characters
   --enable-xft            enable xft support on systems that have it
   --enable-font-styles    enable bold and italic support
+  --enable-wide-glyphs    enable displaying of wide glyphs
   --enable-pixbuf         enable integration with gdk-pixbuf for background images
   --enable-startup-notification  enable freedesktop startup notification support
   --enable-transparency   enable transparent backgrounds
@@ -5025,6 +5027,7 @@ then :
        support_8bitctrls=no
        support_iso14755=no
        support_styles=no
+       support_wide_glyphs=no
        support_perl=no
        codesets=
     fi
@@ -5050,6 +5053,7 @@ then :
        #support_8bitctrls=yes
        support_iso14755=yes
        support_styles=yes
+       support_wide_glyphs=yes
        support_perl=yes
        codesets=all
     fi
@@ -5182,6 +5186,14 @@ then :
 fi
 
 
+# Check whether --enable-wide-glyphs was given.
+if test "${enable_wide_glyphs+set}" = set; then :
+  enableval=$enable_wide_glyphs; if test x$enableval = xyes -o x$enableval = xno; then
+    support_wide_glyphs=$enableval
+  fi
+fi
+
+
 # Check whether --enable-pixbuf was given.
 if test ${enable_pixbuf+y}
 then :
@@ -7726,6 +7738,11 @@ if test x$support_mouseslipwheel = xyes; then
 
 printf "%s\n" "#define MOUSE_SLIP_WHEELING 1" >>confdefs.h
 
+fi
+if test x$support_wide_glyphs = xyes; then
+
+printf "%s\n" "#define ENABLE_WIDE_GLYPHS 1" >>confdefs.h
+
 fi
 
 scrolltypes=plain
diff --git a/configure.ac b/configure.ac
index e1e9416..a97c861 100644
--- a/configure.ac
+++ b/configure.ac
@@ -123,6 +123,7 @@ AC_ARG_ENABLE(everything,
        support_8bitctrls=no
        support_iso14755=no
        support_styles=no
+       support_wide_glyphs=no
        support_perl=no
        codesets=
     fi
@@ -148,6 +149,7 @@ AC_ARG_ENABLE(everything,
        #support_8bitctrls=yes
        support_iso14755=yes
        support_styles=yes
+       support_wide_glyphs=yes
        support_perl=yes
        codesets=all
     fi
@@ -231,6 +233,12 @@ AC_ARG_ENABLE(font-styles,
     support_styles=$enableval
   fi])
 
+AC_ARG_ENABLE(wide-glyphs,
+  [  --enable-wide-glyphs    enable displaying of wide glyphs],
+  [if test x$enableval = xyes -o x$enableval = xno; then
+    support_wide_glyphs=$enableval
+  fi])
+
 AC_ARG_ENABLE(pixbuf,
   [  --enable-pixbuf         enable integration with gdk-pixbuf for background images],
   [if test x$enableval = xyes -o x$enableval = xno; then
@@ -653,6 +661,9 @@ fi
 if test x$support_styles = xyes; then
   AC_DEFINE(ENABLE_STYLES, 1, Define if you want bold and italic support)
 fi
+if test x$support_wide_glyphs = xyes; then
+  AC_DEFINE(ENABLE_WIDE_GLYPHS, 1, Define if you want to display wide glyphs)
+fi
 if test x$support_iso14755 = xyes; then
   AC_DEFINE(ISO_14755, 1, Define if you want ISO 14755 extended support)
 fi
diff --git a/src/command.C b/src/command.C
index f8acee9..fa7f1f9 100644
--- a/src/command.C
+++ b/src/command.C
@@ -237,7 +237,9 @@ rxvt_term::iso14755_51 (unicode_t ch, rend_t r, int x, int y, int y2)
 # endif
       scr_overlay_set (11, y + 1, ch, r);
 
+#if !ENABLE_WIDE_GLYPHS
       if (WCWIDTH (ch) >= 2)
+#endif
         scr_overlay_set (12, y + 1, NOCHAR, r);
     }
 
diff --git a/src/rxvtfont.C b/src/rxvtfont.C
index 42565d7..8be4fa1 100644
--- a/src/rxvtfont.C
+++ b/src/rxvtfont.C
@@ -471,6 +471,7 @@ rxvt_font_default::draw (rxvt_drawable &d, int x, int y,
       else
         switch (t)
           {
+            case ' ':
             case '\t':
             case ZERO_WIDTH_CHAR:
             case NOCHAR:
@@ -1038,8 +1039,10 @@ rxvt_font_x11::has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &car
 
   careful = xcs->lbearing < 0 || xcs->rbearing > prop->width * wcw;
 
+#if !ENABLE_WIDE_GLYPHS
   if (careful && !OVERLAP_OK (w, wcw, prop))
     return false;
+#endif
 
   return true;
 }
@@ -1410,12 +1413,14 @@ rxvt_font_xft::has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &car
 
   careful = g.x > 0 || w > cwidth;
 
+#if !ENABLE_WIDE_GLYPHS
   if (careful && !OVERLAP_OK (w, wcw, prop))
     return false;
 
   // this weeds out _totally_ broken fonts, or glyphs
   if (!OVERLAP_OK (g.xOff, wcw, prop))
     return false;
+#endif
 
   return true;
 }
@@ -1496,6 +1501,10 @@ rxvt_font_xft::draw (rxvt_drawable &d, int x, int y,
 
           ep->glyph = glyph;
           ep->x = x_;
+#if ENABLE_WIDE_GLYPHS
+          /* Left-align to bounding box, do not overlap to the left. */
+          max_it(ep->x, x_);
+#endif
           ep->y = y_ + ascent;
 
           // the xft font cell might differ from the terminal font cell,
diff --git a/src/screen.C b/src/screen.C
index fb3981e..aa3992c 100644
--- a/src/screen.C
+++ b/src/screen.C
@@ -976,7 +976,61 @@ rxvt_term::scr_add_lines (const wchar_t *str, int len, int minlines) noexcept
 # endif
 #endif
 
-          rend_t rend = SET_FONT (rstyle, FONTSET (rstyle)->find_font (c));
+          rend_t rend;
+#if ENABLE_WIDE_GLYPHS
+          // Re-use previous font for space characters.
+          // This allows for better display of wider chars with regard to
+          // backtracking (which uses RS_SAME).
+          if (c != ' ')
+            {
+#endif
+            rend = SET_FONT (rstyle, FONTSET (rstyle)->find_font (c));
+#if ENABLE_WIDE_GLYPHS
+
+            }
+          else
+            {
+              // Code taken from ENABLE_COMBINING - might get refactored.
+              line_t *linep;
+              text_t *tp;
+              rend_t *rp = NULL;
+
+              if (screen.cur.col > 0)
+                {
+                  linep = line;
+                  tp = line->t + screen.cur.col - 1;
+                  rp = line->r + screen.cur.col - 1;
+                }
+              else if (screen.cur.row > 0
+                       && ROW(screen.cur.row - 1).is_longer ())
+                {
+                  linep = &ROW(screen.cur.row - 1);
+                  tp = linep->t + ncol - 1;
+                  rp = linep->r + ncol - 1;
+                }
+
+              if (rp)
+                {
+                  // XXX: this font does not show up in iso-14755 mode for the space!?
+                  if (*tp == NOCHAR)
+                    {
+                      while (*tp == NOCHAR && tp > linep->t)
+                        tp--, rp--;
+
+                      // first try to find a precomposed character
+                      unicode_t n = rxvt_compose (*tp, c);
+                      if (n == NOCHAR)
+                        n = rxvt_composite.compose (*tp, c);
+
+                      *tp = n;
+                      *rp = SET_FONT (*rp, FONTSET (*rp)->find_font (*tp));
+                    }
+                  rend = SET_FONT (rstyle, GET_FONT(*rp));
+                }
+              else
+                rend = SET_FONT (rstyle, FONTSET (rstyle)->find_font (c));
+            }
+#endif
 
           // if the character doesn't fit into the remaining columns...
           if (ecb_unlikely (screen.cur.col > ncol - width && ncol >= width))
@@ -2435,7 +2489,12 @@ rxvt_term::scr_refresh () noexcept
                 text--, count++, xpixel -= fwidth;
 
               // force redraw after "careful" characters to avoid pixel droppings
-              for (int i = 0; srp[col + i] & RS_Careful && col + i < ncol - 1; i++)
+              for (int i = 0; srp[col + i] & RS_Careful && col + i < ncol - 1
+#if ENABLE_WIDE_GLYPHS
+              // But not for spaces.
+                      && stp[col + i + 1] != ' '
+#endif
+                      ; i++)
                 drp[col + i + 1] = srp[col + i + 1] ^ RS_redraw;
 
               // force redraw before "careful" characters to avoid pixel droppings
diff --git a/src/xdefaults.C b/src/xdefaults.C
index cede5c0..5a8510d 100644
--- a/src/xdefaults.C
+++ b/src/xdefaults.C
@@ -299,6 +299,9 @@ static const char optionsstring[] = "options: "
 #if ENABLE_STYLES
                                     "styles,"
 #endif
+#if ENABLE_WIDE_GLYPHS
+                                    "wide-glyphs,"
+#endif
 #if ENABLE_COMBINING
                                     "combining,"
 #endif
