From http://www.jwz.org/xscreensaver/xscreensaver-5.31.tar.gz
[xscreensaver] / hacks / noseguy.c
index 2e0782714791f302c92ad72e3963c63b8c3e3f09..b491224be11fec30373d2fd40113a93540dc2ebe 100644 (file)
@@ -17,6 +17,7 @@
 #include "screenhack.h"
 #include "xpm-pixmap.h"
 #include "textclient.h"
+#include "xft.h"
 
 #ifdef HAVE_COCOA
 # define HAVE_XPM
@@ -31,7 +32,10 @@ struct state {
   int Width, Height;
   GC fg_gc, bg_gc, text_fg_gc, text_bg_gc;
   int x, y;
-  XFontStruct *font;
+
+  XftFont  *xftfont;
+  XftColor  xftcolor;
+  XftDraw  *xftdraw;
 
   unsigned long interval;
   Pixmap left1, left2, right1, right2;
@@ -376,10 +380,15 @@ talk (struct state *st, int force_erase)
 
     if (!(p2 = strchr(p, '\n')) || !p2[1])
       {
+        XGlyphInfo extents;
+
        total = strlen (st->words);
        strncpy (args[0], st->words, LINELEN);
        args[0][LINELEN - 1] = 0;
-       width = XTextWidth(st->font, st->words, total);
+        XftTextExtentsUtf8 (st->dpy, st->xftfont, 
+                            (FcChar8 *) st->words, total,
+                            &extents);
+        width = extents.xOff;
        height = 0;
       }
     else
@@ -387,9 +396,16 @@ talk (struct state *st, int force_erase)
       for (height = 0; p; height++)
        {
          int             w;
+          XGlyphInfo extents;
          *p2 = 0;
-         if ((w = XTextWidth(st->font, p, p2 - p)) > width)
-           width = w;
+
+          XftTextExtentsUtf8 (st->dpy, st->xftfont, 
+                              (FcChar8 *) p, p2 - p,
+                              &extents);
+          w = extents.xOff;
+         if (w > width)
+            width = w;
+
          total += p2 - p;      /* total chars; count to determine reading
                                 * time */
          (void) strncpy(args[height], p, LINELEN);
@@ -410,7 +426,7 @@ talk (struct state *st, int force_erase)
      * new box by 15 pixels on the sides (30 total) top and bottom.
      */
     st->s_rect.width = width + 30;
-    st->s_rect.height = height * font_height(st->font) + 30;
+    st->s_rect.height = height * font_height(st->xftfont) + 30;
     if (st->x - st->s_rect.width - 10 < 5)
        st->s_rect.x = 5;
     else if ((st->s_rect.x = st->x + 32 - (st->s_rect.width + 15) / 2)
@@ -433,7 +449,7 @@ talk (struct state *st, int force_erase)
         st->s_rect.x + 7, st->s_rect.y + 7, st->s_rect.width - 15, st->s_rect.height - 15);
 
     st->X = 15;
-    st->Y = 15 + font_height(st->font);
+    st->Y = 15 + font_height(st->xftfont);
 
     /* now print each string in reverse order (start at bottom of box) */
     for (Z = 0; Z < height; Z++)
@@ -442,9 +458,11 @@ talk (struct state *st, int force_erase)
         /* If there are continuous new lines, L can be 0 */
         if (L && (args[Z][L-1] == '\r' || args[Z][L-1] == '\n'))
           args[Z][--L] = 0;
-       XDrawString(st->dpy, st->window, st->text_fg_gc, st->s_rect.x + st->X, st->s_rect.y + st->Y,
-                   args[Z], L);
-       st->Y += font_height(st->font);
+        XftDrawStringUtf8 (st->xftdraw, &st->xftcolor, st->xftfont,
+                           st->s_rect.x + st->X, st->s_rect.y + st->Y,
+                           (FcChar8 *) args[Z], L);
+
+       st->Y += font_height(st->xftfont);
     }
     st->interval = (total / 15) * 1000;
     if (st->interval < 2000) st->interval = 2000;
@@ -523,7 +541,7 @@ static const char *noseguy_defaults [] = {
   "*fpsSolid:   true",
   "*program:    xscreensaver-text",
   "*usePty:      False",
-  ".font:       -*-new century schoolbook-*-r-*-*-*-180-*-*-*-*-*-*",
+  ".font:       -*-helvetica-medium-r-*-*-*-140-*-*-*-*-*-*",
   0
 };
 
@@ -566,13 +584,15 @@ noseguy_init (Display *d, Window w)
 
   init_images(st);
 
-  if (!fontname || !*fontname)
-    fprintf (stderr, "%s: no font specified.\n", progname);
-  st->font = XLoadQueryFont(st->dpy, fontname);
-  if (!st->font) {
-    fprintf (stderr, "%s: could not load font %s.\n", progname, fontname);
-    exit(1);
-  }
+  st->xftfont = XftFontOpenXlfd (st->dpy, screen_number (xgwa.screen),
+                                 fontname);
+  XftColorAllocName (st->dpy, xgwa.visual, xgwa.colormap,
+                     get_string_resource (st->dpy,
+                                          "textForeground", "Foreground"),
+                     &st->xftcolor);
+  st->xftdraw = XftDrawCreate (st->dpy, st->window, xgwa.visual,
+                               xgwa.colormap);
+
 
   fg = get_pixel_resource (st->dpy, cmap, "foreground", "Foreground");
   bg = get_pixel_resource (st->dpy, cmap, "background", "Background");
@@ -584,26 +604,25 @@ noseguy_init (Display *d, Window w)
   if (! get_string_resource (st->dpy, "textBackground", "Background"))
     text_bg = fg;
 
-  gcvalues.font = st->font->fid;
   gcvalues.foreground = fg;
   gcvalues.background = bg;
   st->fg_gc = XCreateGC (st->dpy, st->window,
-                         GCForeground|GCBackground|GCFont,
+                         GCForeground|GCBackground,
                     &gcvalues);
   gcvalues.foreground = bg;
   gcvalues.background = fg;
   st->bg_gc = XCreateGC (st->dpy, st->window,
-                         GCForeground|GCBackground|GCFont,
+                         GCForeground|GCBackground,
                     &gcvalues);
   gcvalues.foreground = text_fg;
   gcvalues.background = text_bg;
   st->text_fg_gc = XCreateGC (st->dpy, st->window,
-                              GCForeground|GCBackground|GCFont,
+                              GCForeground|GCBackground,
                          &gcvalues);
   gcvalues.foreground = text_bg;
   gcvalues.background = text_fg;
   st->text_bg_gc = XCreateGC (st->dpy, st->window, 
-                              GCForeground|GCBackground|GCFont,
+                              GCForeground|GCBackground,
                          &gcvalues);
   st->x = st->Width / 2;
   st->y = st->Height / 2;