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

OPT_WIDE_CHARS XRENDERFONT patch for xterm-157 (again)



Hi,

I just find out xterm-157 has added OPT_WIDE_CHARS to the XRENDERFONT
section.  After I test it with my favorite true-type font, SimSun, it
turns out that it doesn't look right.  So I modified it again.

A little bit background information about SimSun: it is the most widely
used true-type font among mainland Chinese.  It contains ASCII, all
the CJK Unified Ideographs, and others.  It is a proportional font.
CJK ideographs are much wider than ASCII characters.

The changes I made are listed below.  Only two files are involved:

1.  fontutils.c

The column width can not be max_advance_width of the font if double
width characters are present in the font.  To see if there is any
double width character, I check if U+4E00 is present or not.  This
at least works for most CJK font.

If there are double width characters, the column width should be
half of the max_advance_width.

2.  util.c

For proportional font, one character is drawn at a time and the placement
is controlled by my_wcwidth().  There is one catch here: for some reason,
when a double width character string are send to drawXtermText(),

	"U+4E00U+4E01U+4E02"

for example, the actual string really is

	"U+4E00U+FFFFU+4E01U+FFFFU+4E02U+FFFF"

That is to say, somewhere in the code U+FFFF is padded to each charater.
Unfortunately, my_wcwidth() reports U+FFFF as width 1 which is wrong.
That is why I have to check this U+FFFF special case to make sure it is
not causing any gap between characters.

These are the steps I use to test it:

1.  Install SimSun true type font

	cp simsun.ttf /usr/share/fonts/default/TrueType/

Create file /usr/share/fonts/default/TrueType/XftConfig:

	DIR "."
	MATCH face = "SimSun"			EDIT file = "simsun.ttf"

Append the following line to /etc/X11/XftConfig:

	dir "/usr/share/fonts/default/TrueType"

2.  Run the patched xterm-157:

	LANG=en_US.UTF-8 xterm -fa simsun

I've found cat, more, vim60m works well within the patched xterm-157.

The system I am using is RedHat 7.1.

Regards,

Yao Zhang


--- xterm-157.orig/fontutils.c	Mon Jun 18 15:09:26 2001
+++ xterm-157/fontutils.c	Fri Jul  6 22:42:25 2001
@@ -887,7 +887,15 @@
     }
     if (screen->renderFont)
     {
+	XftChar16 c16;
+	XGlyphInfo gi;
+
+	c16 = 0x4E00;
+	XftTextExtents16(dpy, screen->renderFont, &c16, 1, &gi);
 	win->f_width = screen->renderFont->max_advance_width;
+	if (gi.width > 0) {
+	    win->f_width /= 2;
+	}
 	win->f_height = screen->renderFont->height;
 	win->f_ascent = screen->renderFont->ascent;
 	win->f_descent = screen->renderFont->descent;


--- xterm-157.orig/util.c	Mon Jun 18 15:09:27 2001
+++ xterm-157/util.c	Fri Jul  6 22:47:46 2001
@@ -1444,6 +1444,7 @@
 	Display		*dpy = screen->display;
 	XftFont		*font;
 	XGCValues	values;
+	unsigned	n;
 	
 	if (!screen->renderDraw)
 	{
@@ -1470,32 +1471,53 @@
 #if OPT_WIDE_CHARS
 	if (text2)
 	{
-	    static XftChar16    *sbuf;
-	    static unsigned	slen;
-	    unsigned		n;
+	    XftChar16	c16;
+	    int		cs;
 
-	    if (slen < len)
-	    {
-		slen = (len + 1) * 2;
-		sbuf = (XftChar16 *) XtRealloc ((char *) sbuf, slen * sizeof (XftChar16));
+	    draw_len = 0;
+	    for (n = 0; n < len; n++) {
+		c16 = *text++| (*text2++ << 8);
+		cs = my_wcwidth(c16);
+		if (c16 == 0xFFFF) {
+		    cs = 0;
+		}
+		switch (cs) {
+		case 1:
+		    XftDrawString16 (screen->renderDraw,
+				     getColor (values.foreground),
+				     font,
+				     x+draw_len*FontWidth(screen),
+				     y, &c16, 1);
+		    draw_len++;
+		    break;
+		case 2:
+		    XftDrawString16 (screen->renderDraw,
+				     getColor (values.foreground),
+				     font,
+				     x+draw_len*FontWidth(screen),
+				     y, &c16, 1);
+		    draw_len += 2;
+		    break;
+		default:
+		    break;
+		}
 	    }
-	    for (n = 0; n < len; n++)
-		sbuf[n] = *text++| (*text2++ << 8);
-	    XftDrawString16 (screen->renderDraw,
-			     getColor (values.foreground),
-			     font,
-			     x, y, sbuf, len);
 	}
 	else
 #endif
 	{
-	    XftDrawString8 (screen->renderDraw,
-			    getColor (values.foreground),
-			    font,
-			    x, y, (unsigned char *) text, len);
+	    draw_len = 0;
+	    for (n = 0; n < len; n++) {
+		XftDrawString8 (screen->renderDraw,
+				getColor (values.foreground),
+				font,
+				x+draw_len*FontWidth(screen), y,
+				(unsigned char *) text+n, 1);
+		draw_len++;
+	    }
 	}
 
-	return x + len * FontWidth(screen);
+	return x + draw_len * FontWidth(screen);
     }
 #endif
 #if OPT_WIDE_CHARS
-
Linux-UTF8:   i18n of Linux on all levels
Archive:      http://mail.nl.linux.org/linux-utf8/