Xft

  • From: Tor Andersson <tor.andersson@xxxxxxxxxxx>
  • To: wilyfans@xxxxxxxxxxxxx
  • Date: Mon, 15 Jul 2002 18:12:08 +0200

Hi all,

Is there any active development going on?
Is ftp://ftp.cs.yorku.ca/pub/wily/src/old/wily-0.13.41.tgz the latest version?

Anyway, here's my wish list:

* Different colors in window, tag line, resize-buttons and scrollbars.
* A third font for tag lines.
* Antialiased, sub-pixel positioned text with kerning.

I've browsed the source for a bit, and it appears that adding color
support would break very many assumptions. Maybe it's time for a
reworking of the graphics layer? Anyway, I hacked together a quick-fix
to draw anti-aliased fonts using Xft. It seems to work, but it is not fast.
Choose which font by setting WILYPROP and WILYFIXED environment
variables to a fontconfig pattern. Only latin-1 for now...

To install Xft on machines that do not have the XRender extension,
download the fcpackage from http://keithp.com/fonts/.

export WILYFIXED="Courier:size=10"
export WILYPROP="Times:size=12" 
wily

See screenshot at http://spacecow.df.lth.se/wily-xft.png

/tor


diff -ruNwb wily-0.13.41/include/libg.h wily-new/include/libg.h
--- wily-0.13.41/include/libg.h Mon Apr  6 05:49:05 1998
+++ wily-new/include/libg.h     Mon Jul 15 14:16:10 2002
@@ -100,7 +100,7 @@
        unsigned char   height; /* height of bitmap */
        char            ascent; /* top of bitmap to baseline */
        Fontchar        *info;  /* n+1 character descriptors */
-       int             id;     /* of font */
+       void            *id;    /* of font (XftFont/NULL) */
 };
 
 struct Cachesubf
diff -ruNwb wily-0.13.41/libXg/libgint.h wily-new/libXg/libgint.h
--- wily-0.13.41/libXg/libgint.h        Wed Dec 11 09:46:09 1996
+++ wily-new/libXg/libgint.h    Mon Jul 15 17:10:08 2002
@@ -28,6 +28,8 @@
 #include <X11/Xatom.h>
 #include <X11/Xutil.h>
 
+#include <X11/Xft/Xft.h>
+
 #undef Cursor
 #undef Font
 #undef Event
@@ -45,10 +47,12 @@
 
 /* X Display for this application's connection */
 extern Display *_dpy;
+extern XftDraw *_xftdraw;
 
 /* screen depth foreground and background for this application */
 extern unsigned long   _fgpixel, _bgpixel;
 extern XColor          _fgcolor, _bgcolor;
+extern XftColor                _xfgcolor, _xbgcolor;
 
 /* indexed by log depth (0 <= ld <= 5), to give depth and planemask */
 extern int             _ld2d[];
diff -ruNwb wily-0.13.41/libXg/string.c wily-new/libXg/string.c
--- wily-0.13.41/libXg/string.c Tue Jan 16 11:01:28 1996
+++ wily-new/libXg/string.c     Mon Jul 15 17:48:47 2002
@@ -3,7 +3,67 @@
 #include <libg.h>
 #include "libgint.h"
 
-enum   { Max = 128 };
+//enum { Max = 128 };
+enum   { Max = 1 };
+
+static Drawable _lastdrawable = 0;
+
+Point
+string(Bitmap *b, Point p, Font *ft, char *s, Fcode f)
+{
+       int x, y, wid, i, j, n, nti, cf;
+       unsigned short cbuf[Max];
+       unsigned short fbuf[Max];
+       Rune r;
+       XftFont *font;
+
+       x = p.x;
+       y = p.y;
+       if (b->flag&SHIFT){
+               x -= b->r.min.x;
+               y -= b->r.min.y;
+       }
+       y += ft->ascent;
+
+       //g = _getfillgc(f, b, ~0); // FIXME
+
+       if (_xftdraw == 0) {
+               _xftdraw = XftDrawCreate(_dpy,
+                               (Drawable)b->id,
+                               DefaultVisual(_dpy, DefaultScreen(_dpy)),
+                               DefaultColormap(_dpy, DefaultScreen(_dpy)));
+               _lastdrawable = (Drawable)b->id;
+       }
+       if (_lastdrawable != (Drawable)b->id) {
+               XftDrawChange(_xftdraw, (Drawable)b->id);
+               _lastdrawable = (Drawable)b->id;
+       }
+
+       while (*s) {
+               n = cachechars(ft, &s, cbuf, Max, &wid, fbuf);
+               if (n <= 0) {
+                       s += chartorune(&r, s);
+                       continue;
+               }
+               cf = fbuf[0];                   /* first font */
+               font = (XftFont*)ft->subf[cf].f->id;
+               for (i = 0; i < n; i++) {
+                       if (fbuf[i] != cf) {    /* font change */
+                               cf = fbuf[i];
+                               font = (XftFont*)ft->subf[cf].f->id;
+                       }
+                       XftDrawString16(_xftdraw, &_xfgcolor, font,
+                                       x, y,
+                                       &cbuf[i], 1);
+                       // FIXME, x += wid??? when n > 1
+               }
+               x += wid;
+       }
+       p.x = (b->flag&SHIFT) ? x + b->r.min.x : x;
+       return p;
+}
+
+#if 0
 
 Point
 string(Bitmap *b, Point p, Font *ft, char *s, Fcode f)
@@ -52,3 +112,6 @@
        p.x = (b->flag&SHIFT) ? x + b->r.min.x : x;
        return p;
 }
+
+#endif
+
diff -ruNwb wily-0.13.41/libXg/xtbinit.c wily-new/libXg/xtbinit.c
--- wily-0.13.41/libXg/xtbinit.c        Thu May 16 20:05:46 1996
+++ wily-new/libXg/xtbinit.c    Mon Jul 15 17:46:08 2002
@@ -37,8 +37,10 @@
 /* implementation globals */
 Display                *_dpy;
 Widget         _toplevel;
+XftDraw                *_xftdraw;
 unsigned long  _fgpixel, _bgpixel;
 XColor         _fgcolor, _bgcolor;
+XftColor       _xfgcolor, _xbgcolor;
 int            _ld2d[6] = { 1, 2, 4, 8, 16, 24 };
 unsigned long  _ld2dmask[6] = { 0x1, 0x3, 0xF, 0xFF, 0xFFFF, 0x00FFFFFF };
 Colormap       _libg_cmap;
@@ -81,13 +83,13 @@
 static int Stimer = -1;
 static XtIntervalId    timerid;
 
-static Font *  initfont(char *,        XFontStruct *, char *);
+static Font *  initfont(char *,        XftFont *, char *);
 static void    reshaped(int, int, int, int);
 static void    gotchar(int);
 static void    gotmouse(Gwinmouse *);
 static int     log2(int);
 static void    pixtocolor(Pixel, XColor *);
-static Subfont *XFontStructtoSubfont(XFontStruct *);
+static Subfont *XFontStructtoSubfont(XftFont *);
 static Ebuf    *ebread(Esrc *);
 static Ebuf    *ebadd(Esrc *);
 static void    focinit(Widget);
@@ -132,7 +134,7 @@
 {
        int n;
        unsigned int depth;
-       XFontStruct *xf;
+       XftFont *xf;
        String fontname;
        String fixedname;
        Arg args[10];
@@ -168,7 +170,7 @@
        XtSetArg(args[n], XtNforeground, &_fgpixel);    n++;
        XtSetArg(args[n], XtNbackground, &_bgpixel);    n++;
        XtSetArg(args[n], XtNdepth, &depth);            n++;
-       XtSetArg(args[n], XtNfont, &xf);                n++;
+       //FIXME XtSetArg(args[n], XtNfont, &xf);                n++;
        XtSetArg(args[n], XtNp9font, &fontname);        n++;
        XtSetArg(args[n], XtNp9fixed, &fixedname);      n++;
        XtSetArg(args[n], XtNcomposeMod, &compose);     n++;
@@ -194,8 +196,14 @@
                screen.flag |= BL1;
        if(depth == 1)
                screen.flag |= DP1;
-       font = initfont(fontname, xf, "variable");
-       fixed = initfont(fixedname, 0, "fixed");
+       {
+               char *varfn = getenv("WILYPROP");
+               char *fixfn = getenv("WILYFIXED");
+               if (varfn == 0) varfn = "Nimbus Roman No9 L:size=10";
+               if (fixfn == 0) fixfn = "Nimbus Mono L:size=10";
+               font = initfont(fontname, xf, varfn);
+               fixed = initfont(fixedname, 0, fixfn);
+       }
        /* leave screen rect at all zeros until reshaped() sets it */
        while(!exposed) {
                XFlush(_dpy);
@@ -203,14 +211,28 @@
        }
        XFlush(_dpy);
        focinit(_toplevel);
+
+       _xftdraw = 0;
+
+       _xbgcolor.pixel = _bgpixel;
+       _xbgcolor.color.red = _bgcolor.red;
+       _xbgcolor.color.green = _bgcolor.green;
+       _xbgcolor.color.blue = _bgcolor.blue;
+       _xbgcolor.color.alpha = 0xffff;
+
+       _xfgcolor.pixel = _fgpixel;
+       _xfgcolor.color.red = _fgcolor.red;
+       _xfgcolor.color.green = _fgcolor.green;
+       _xfgcolor.color.blue = _fgcolor.blue;
+       _xfgcolor.color.alpha = 0xffff;
 }
 
 static Font *
-initfont(char *name,   XFontStruct *xf, char *backupname)
+initfont(char *name,   XftFont *xf, char *backupname)
 {
        /* Given (in order of preference)
         * 'name' which may be the name of a font file,
-        * 'backupfont' which may be an XFontStruct,
+        * 'backupfont' which may be an XftFont,
         * and 'backupname', which is the name of an X font.
         */
        Font    *f;
@@ -519,60 +541,78 @@
 Subfont *
 getsubfont(char *s)
 {
-       XFontStruct *fp;
+       XftFont *fp;
 
        if(!s)
                return 0;
-       fp = XLoadQueryFont(_dpy, s);
+       fp = XftFontOpenName(_dpy, DefaultScreen(_dpy), s);
+printf("XftFontOpenName('%s') -> %p\n", s, fp);
        if(!fp)
                return 0;
        return XFontStructtoSubfont(fp);
 }
 
 static Subfont *
-XFontStructtoSubfont(XFontStruct *fp)
+XFontStructtoSubfont(XftFont *fp)
 {
-       XCharStruct *cp;
+       XGlyphInfo cp;
        Subfont *f;
        int min, max;
        int i;
+       XftChar16 ch;
 
        if(!fp)
                berror("no font");
        f = (Subfont *)malloc(sizeof(Subfont));
        if(!f)
                berror("XFontStructtoSubfont malloc");
-        min = fp->min_byte1;
-        max = fp->max_byte1;
-       f->minrow = min;
-       f->mincol = fp->min_char_or_byte2;
-       f->width = fp->max_char_or_byte2-fp->min_char_or_byte2+1;
+
+       /*
+       min = 65535;
+       max = 0;
+       for (i = 0; i < 65535; i++) {
+               if (FcCharSetHasChar(fp->charset, i)) {
+                       if (i < min) min = i;
+                       if (i > max) max = i;
+               }
+       }
+
+       f->minrow = min / 256;
+       f->mincol = min % 256;
+       f->width = (max%256) - (min%256) + 1;
        f->n = f->width;
        f->minchar = 0;
-       f->maxchar = fp->max_char_or_byte2;
-       if (min || max) {
-               f->maxchar |= (max<<8);
-               f->n *= (max-min+1);
-       }
-       f->id = fp->fid;
-       f->height = fp->max_bounds.ascent + fp->max_bounds.descent;
-       f->ascent = fp->max_bounds.ascent;
+       f->maxchar = max % 256;
+       if (min > 255 || max > 255) {
+               f->maxchar |= (max & 0xff00);
+               f->n *= ((max%256)-(min%256)+1);
+       }
+       */
+
+       f->minrow = 0;
+       f->mincol = 0;
+       f->width = 256;
+       f->n = 256;
+       f->minchar = 0;
+       f->maxchar = 255;
+
+       f->id = (void*)fp;
+       f->height = fp->height;
+       f->ascent = fp->ascent;
+
        f->info = (Fontchar *)malloc((f->n+1)*sizeof(Fontchar));
        if(!f->info)
                berror("getsubfont malloc");
        memset((void*)f->info, 0, (f->n+1)*sizeof(Fontchar));
        for(i = 0; i < f->n; i++){
-               if(fp->per_char)
-                       cp = fp->per_char + i;
-               else
-                       cp = &fp->max_bounds;
-               f->info[i].left = cp->lbearing;
-               f->info[i].cwidth = cp->rbearing - cp->lbearing;
-               f->info[i].width = cp->width;
+               ch = i + f->minchar;
+               XftTextExtents16(_dpy, fp, &ch, 1, &cp);
+               f->info[i].left = cp.x;
+               f->info[i].cwidth = cp.width;
+               f->info[i].width = cp.xOff;
                f->info[i].top = 0;
                f->info[i].bottom = f->height;
        }
-       XFreeFontInfo(0, fp, 0);
        return f;
 }
 
  • Follow-Ups:

Other related posts: