+ const char *fn2 = "fixed";
+ s->metrics_xftfont =
+ XftFontOpenName (s->dpy, screen_number(s->xgwa.screen), fn2);
+ if (s->metrics_xftfont)
+ fn = fn2;
+ else
+ {
+ fprintf (stderr, "%s: XftFontOpen failed on \"%s\" and \"%s\"\n",
+ progname, fn, fn2);
+ exit (1);
+ }
+ }
+ }
+
+ strcpy (fn2, fn);
+# ifdef HAVE_JWXYZ
+ {
+ float ss;
+ const char *n = jwxyz_nativeFontName (s->metrics_xftfont->xfont->fid, &ss);
+ sprintf (fn2, "%s %.1f", n, ss);
+ }
+# endif
+
+ xftdraw = XftDrawCreate (s->dpy, dest, s->xgwa.visual,
+ s->xgwa.colormap);
+ XftColorAllocName (s->dpy, s->xgwa.visual, s->xgwa.colormap, "white",
+ &xftcolor);
+ XftTextExtentsUtf8 (s->dpy, s->metrics_xftfont,
+ (FcChar8 *) utxt, strlen(utxt),
+ &extents);
+
+
+ XTextExtents (s->metrics_font1, txt, strlen(txt),
+ &dir, &ascent, &descent, &overall);
+ c = ((s->debug_metrics_p >= s->metrics_font1->min_char_or_byte2 &&
+ s->debug_metrics_p <= s->metrics_font1->max_char_or_byte2)
+ ? s->metrics_font1->per_char[s->debug_metrics_p -
+ s->metrics_font1->min_char_or_byte2]
+ : overall);
+
+ XSetForeground (s->dpy, gc, BlackPixelOfScreen (s->xgwa.screen));
+ XFillRectangle (s->dpy, dest, gc, 0, 0, s->xgwa.width, s->xgwa.height);
+
+ XSetForeground (s->dpy, gc, WhitePixelOfScreen (s->xgwa.screen));
+ XSetFont (s->dpy, gc, s->metrics_font2->fid);
+ XDrawString (s->dpy, dest, gc,
+ s->xgwa.width / 2,
+ s->xgwa.height - 5,
+ fn2, strlen(fn2));
+
+# ifdef HAVE_JWXYZ
+ {
+ char *name =
+ jwxyz_unicode_character_name (s->metrics_font1->fid, s->debug_metrics_p);
+ if (!name || !*name) name = strdup("unknown character name");
+ XDrawString (s->dpy, dest, gc,
+ 10,
+ 10 + 2 * (s->metrics_font2->ascent +
+ s->metrics_font2->descent),
+ name, strlen(name));
+ free (name);
+ }
+# endif
+
+ /* i 0, j 0: top left, XDrawString, char metrics
+ i 1, j 0: bot left, XDrawString, overall metrics, ink escape
+ i 0, j 1: top right, XftDrawStringUtf8, utf8 metrics
+ i 1, j 1: bot right, XDrawString16, 16 metrics, ink escape
+ */
+ for (j = 0; j < 2; j++) {
+ Bool xft_p = (j != 0);
+ int ww = s->xgwa.width / 2 - 20;
+ int xoff = (j == 0 ? 0 : ww + 20);
+
+ /* XDrawString only does 8-bit characters, so skip it outside Latin-1. */
+ if (s->debug_metrics_p >= 256)
+ {
+ if (!xft_p)
+ continue;
+ xoff = 0;
+ ww = s->xgwa.width;
+ }
+
+ x = (ww - overall.width) / 2;
+
+ for (i = 0; i < 2; i++)
+ {
+ XCharStruct cc;
+ int x1 = xoff + ww * 0.18;
+ int x2 = xoff + ww * 0.82;
+ int x3 = xoff + ww;
+ int pixw, pixh;
+ Pixmap p;
+
+ y = 80;
+ {
+ int h = sc * (ascent + descent);
+ int min = (ascent + descent) * 4;
+ if (h < min) h = min;
+ if (i == 1) h *= 3;
+ y += h;
+ }
+
+ memset (&fake_c, 0, sizeof(fake_c));
+
+ if (!xft_p && i == 0)
+ cc = c;
+ else if (!xft_p && i == 1)
+ cc = overall;
+ else if (xft_p && i == 0)
+ {
+ /* Measure the glyph in the Xft way */
+ XGlyphInfo extents;
+ XftTextExtentsUtf8 (s->dpy,
+ s->metrics_xftfont,
+ (FcChar8 *) utxt, strlen(utxt),
+ &extents);
+ XGlyphInfo_to_XCharStruct (extents, fake_c);
+ cc = fake_c;
+ }
+ else if (xft_p)
+ {
+ /* Measure the glyph in the 16-bit way */
+ int dir, ascent, descent;
+ XTextExtents16 (s->metrics_font1, txt3, 1, &dir, &ascent, &descent,
+ &fake_c);
+ cc = fake_c;
+ }
+
+ pixw = margin * 2 + cc.rbearing - cc.lbearing;
+ pixh = margin * 2 + cc.ascent + cc.descent;
+ p = (pixw > 0 && pixh > 0
+ ? XCreatePixmap (s->dpy, dest, pixw, pixh, s->xgwa.depth)
+ : 0);
+
+ if (p)
+ {
+ Pixmap p2;
+ GC gc2 = XCreateGC (s->dpy, p, 0, 0);
+# ifdef HAVE_JWXYZ
+ jwxyz_XSetAntiAliasing (s->dpy, gc2, False);
+# endif
+ XSetFont (s->dpy, gc2, s->metrics_font1->fid);
+ XSetForeground (s->dpy, gc2, BlackPixelOfScreen (s->xgwa.screen));
+ XFillRectangle (s->dpy, p, gc2, 0, 0, pixw, pixh);
+ XSetForeground (s->dpy, gc, WhitePixelOfScreen (s->xgwa.screen));
+ XSetForeground (s->dpy, gc2, WhitePixelOfScreen (s->xgwa.screen));
+# ifdef HAVE_JWXYZ
+ jwxyz_XSetAntiAliasing (s->dpy, gc2,
+ s->debug_metrics_antialiasing_p);
+# endif
+
+ if (xft_p && i == 0)
+ {
+ XftDraw *xftdraw2 = XftDrawCreate (s->dpy, p, s->xgwa.visual,
+ s->xgwa.colormap);
+ XftDrawStringUtf8 (xftdraw2, &xftcolor,
+ s->metrics_xftfont,
+ -cc.lbearing + margin,
+ cc.ascent + margin,
+ (FcChar8 *) utxt, strlen(utxt));
+ XftDrawDestroy (xftdraw2);
+ }
+ else if (xft_p)
+ XDrawString16 (s->dpy, p, gc2,
+ -cc.lbearing + margin,
+ cc.ascent + margin,
+ txt3, 1);
+ else
+ XDrawString (s->dpy, p, gc2,
+ -cc.lbearing + margin,
+ cc.ascent + margin,
+ txt, strlen(txt));
+
+ {
+ unsigned x2, y2;
+ XImage *img = XGetImage (s->dpy, p, 0, 0, pixw, pixh,
+ ~0L, ZPixmap);
+ XImage *img2;
+
+ if (i == 1)
+ {
+ unsigned w = pixw - margin * 2, h = pixh - margin * 2;
+
+ if (margin > 0)
+ {
+ /* Check for ink escape. */
+ unsigned long ink = 0;
+ for (y2 = 0; y2 != pixh; ++y2)
+ for (x2 = 0; x2 != pixw; ++x2)
+ {
+ /* Sloppy... */
+ if (! (x2 >= margin &&
+ x2 < pixw - margin &&
+ y2 >= margin &&
+ y2 < pixh - margin))
+ ink |= XGetPixel (img, x2, y2);
+ }
+
+ if (ink & 0xFFFFFF)
+ {
+ XSetFont (s->dpy, gc, s->metrics_font2->fid);
+ XDrawString (s->dpy, dest, gc,
+ xoff + 10, 40,
+ "Ink escape!", 11);
+ }
+ }
+
+ /* ...And wasted space. */
+ if (w && h)
+ {
+ if (check_edge (s->dpy, dest, gc, 120, 60, "left",
+ img, margin, margin, 1, h) |
+ check_edge (s->dpy, dest, gc, 160, 60, "right",
+ img, margin + w - 1, margin, 1, h) |
+ check_edge (s->dpy, dest, gc, 200, 60, "top",
+ img, margin, margin, 0, w) |
+ check_edge (s->dpy, dest, gc, 240, 60, "bottom",
+ img, margin, margin + h - 1, 0, w))
+ {
+ XSetFont (s->dpy, gc, s->metrics_font2->fid);
+ XDrawString (s->dpy, dest, gc,
+ xoff + 10, 60,
+ "Wasted space: ", 14);
+ }
+ }
+ }