I am trying xterm-153 to see how its Xft option works.  Mr. Keith Packard
added the support since Patch #148.  I want to display Chinese with TrueType
font and anti-aliasing.  Since the current Patch #153 only uses
XftDrawString8(), I have to modified it a little bit.

My system:

RedHat 7.0 with freeytype-2.0.1 and XFree86 4.0.3 from rawhide.
simsun.ttf TrueType font.
xterm-153 from ftp://dickey.his.com/xterm/xterm.tar.gz.

The result is marvelous.  You have to see it yourself to understand
what I mean.

Since simsun.ttf is a proportional font and contains CJK glyphs, the 
max_advance_width is twice as wide as the ascii characters.  So I make 
the column width (f_width) half of the max_advance_width returned from 
Xft (fontutils.c).

In drawXtermText() (util.c), I uses my_wcwidth() to position each glyphs.
I cannot rely on Xft to display the string because the font is proportional.  
I know it is not efficient but I think xterm is column based and we can 
make use any proportional font this way.

I have noticed one problem with this:  characters like U+300A, U+300B and
U+201C, U+201D are single column according to my_wcwidth(), but simsun.ttf 
display them as double column.  Especially U+300A and U+201C, when it is 
displayed, it is overwritten by the character following it.

Another thing is that if the anti-aliased font is displayed reversed (black
background), it looks not as good as black text on white background.  This 
could have something to do with the gray levels chosen by Xft.

The following is the changes I made:

xterm-153.patch:
==========================================================================
diff -uNr xterm-153.orig/configure xterm-153/configure
--- xterm-153.orig/configure    Wed Feb 14 20:29:04 2001
+++ xterm-153/configure Sat Mar 31 01:17:45 2001
@@ -5404,6 +5404,9 @@
 #line 5405 "configure"
 #include "confdefs.h"
 
+#include <X11/Xdefs.h>
+#include <X11/Xlib.h>
+
 #include <X11/extensions/Xrender.h>
 #include <X11/Xft/Xft.h>
 int main() {
diff -uNr xterm-153.orig/fontutils.c xterm-153/fontutils.c
--- xterm-153.orig/fontutils.c  Wed Jan 24 18:43:31 2001
+++ xterm-153/fontutils.c       Sun Apr  1 14:52:03 2001
@@ -890,6 +890,7 @@
     if (screen->renderFont)
     {
        win->f_width = screen->renderFont->max_advance_width;
+       win->f_width /= 2;
        win->f_height = screen->renderFont->height;
        win->f_ascent = screen->renderFont->ascent;
        win->f_descent = screen->renderFont->descent;
diff -uNr xterm-153.orig/util.c xterm-153/util.c
--- xterm-153.orig/util.c       Mon Mar 12 20:12:13 2001
+++ xterm-153/util.c    Sun Apr  1 14:55:50 2001
@@ -1438,12 +1438,31 @@
     int real_length = len;
     int draw_len;
 
+#if OPT_WIDE_CHARS
+       /*
+        * It's simpler to pass in a null pointer for text2 in places where
+        * we only use codes through 255.  Fix text2 here so we can increment
+        * it, etc.
+        */
+       if (text2 == 0) {
+               static Char *dbuf;
+               static unsigned dlen;
+               if (dlen <= len) {
+                       dlen = (len + 1) * 2;
+                       dbuf = (Char *)XtRealloc((char *)dbuf, dlen);
+                       memset(dbuf, 0, dlen);
+               }
+               text2 = dbuf;
+       }
+#endif
 #ifdef XRENDERFONT
     if (screen->renderFont)
     {
        Display         *dpy = screen->display;
        XftFont         *font;
        XGCValues       values;
+       int             i;
+       int             xd;
        
        if (!screen->renderDraw)
        {
@@ -1467,30 +1486,36 @@
                     len * FontWidth(screen), FontHeight(screen));
                        
        y += font->ascent;
+#if OPT_WIDE_CHARS
+       xd = 0;
+       for (i = 0; i < len; i++) {
+            XftChar16  c16;
+            int                cs;
+
+            c16 = (text2[i]<<8) | text[i];
+            cs = my_wcwidth(c16);
+            if (cs > 0) {
+               XftDrawString16 (screen->renderDraw,
+                                 getColor (values.foreground),
+                                 font,
+                                 x+xd, y, &c16, 1);
+               if (cs == 1) {
+                    xd += cs * FontWidth(screen);
+               } else {
+                    xd += cs * FontWidth(screen)/2;
+               }
+            }
+       }
+#else
        XftDrawString8 (screen->renderDraw,
                        getColor (values.foreground),
                        font,
                        x, y, (unsigned char *) text, len);
+       xd = len * FontWidth(screen);
+#endif
 
-       return x + len * FontWidth(screen);
+       return x + xd;
     }
-#endif
-#if OPT_WIDE_CHARS
-       /*
-        * It's simpler to pass in a null pointer for text2 in places where
-        * we only use codes through 255.  Fix text2 here so we can increment
-        * it, etc.
-        */
-       if (text2 == 0) {
-               static Char *dbuf;
-               static unsigned dlen;
-               if (dlen <= len) {
-                       dlen = (len + 1) * 2;
-                       dbuf = (Char *)XtRealloc((char *)dbuf, dlen);
-                       memset(dbuf, 0, dlen);
-               }
-               text2 = dbuf;
-       }
 #endif
 #if OPT_DEC_CHRSET
        if (CSET_DOUBLE(chrset)) {
-
Linux-UTF8:   i18n of Linux on all levels
Archive:      http://mail.nl.linux.org/lists/

Reply via email to