* TODO on fontsel
* ---------------
*
- * - start drawing X fonts one character at a time, at least if
- * they're not fixed-width? Now we have that helpful pangram,
- * we should make it work for everyone.
- *
* - think about points versus pixels, harder than I already have
*
* - generalised style and padding polish
* whether we use gdk_draw_text_wc() or gdk_draw_text().
*/
int sixteen_bit;
+ /*
+ * `variable' is true iff the font is non-fixed-pitch. This
+ * enables some code which takes greater care over character
+ * positioning during text drawing.
+ */
+ int variable;
/*
* Data passed in to unifont_create().
*/
if (sixteen_bit) {
XChar2b space;
space.byte1 = 0;
- space.byte2 = ' ';
+ space.byte2 = '0';
return gdk_text_width(font, (const gchar *)&space, 2);
} else {
- return gdk_char_width(font, ' ');
+ return gdk_char_width(font, '0');
}
}
GdkFont *font;
XFontStruct *xfs;
Display *disp;
- Atom charset_registry, charset_encoding;
- unsigned long registry_ret, encoding_ret;
- int pubcs, realcs, sixteen_bit;
+ Atom charset_registry, charset_encoding, spacing;
+ unsigned long registry_ret, encoding_ret, spacing_ret;
+ int pubcs, realcs, sixteen_bit, variable;
int i;
font = gdk_font_load(name);
pubcs = realcs = CS_NONE;
sixteen_bit = FALSE;
+ variable = TRUE;
if (XGetFontProperty(xfs, charset_registry, ®istry_ret) &&
XGetFontProperty(xfs, charset_encoding, &encoding_ret)) {
}
}
+ spacing = XInternAtom(disp, "SPACING", False);
+ if (XGetFontProperty(xfs, spacing, &spacing_ret)) {
+ char *spc;
+ spc = XGetAtomName(disp, (Atom)spacing_ret);
+
+ if (spc && strchr("CcMm", spc[0]))
+ variable = FALSE;
+ }
+
xfont = snew(struct x11font);
xfont->u.vt = &x11font_vtable;
xfont->u.width = x11_font_width(font, sixteen_bit);
xfont->fonts[0] = font;
xfont->allocated[0] = TRUE;
xfont->sixteen_bit = sixteen_bit;
+ xfont->variable = variable;
xfont->wide = wide;
xfont->bold = bold;
xfont->shadowoffset = shadowoffset;
sfree(derived_name);
}
+static void x11font_really_draw_text(GdkDrawable *target, GdkFont *font,
+ GdkGC *gc, int x, int y,
+ const gchar *string, int clen, int nchars,
+ int shadowbold, int shadowoffset,
+ int fontvariable, int cellwidth)
+{
+ int step = clen * nchars, nsteps = 1, centre = FALSE;
+
+ if (fontvariable) {
+ /*
+ * In a variable-pitch font, we draw one character at a
+ * time, and centre it in the character cell.
+ */
+ step = clen;
+ nsteps = nchars;
+ centre = TRUE;
+ }
+
+ while (nsteps-- > 0) {
+ int X = x;
+ if (centre)
+ X += (cellwidth - gdk_text_width(font, string, step)) / 2;
+
+ gdk_draw_text(target, font, gc, X, y, string, step);
+ if (shadowbold)
+ gdk_draw_text(target, font, gc, X + shadowoffset, y, string, step);
+
+ x += cellwidth;
+ string += step;
+ }
+}
+
static void x11font_draw_text(GdkDrawable *target, GdkGC *gc, unifont *font,
int x, int y, const char *string, int len,
int wide, int bold, int cellwidth)
struct x11font *xfont = (struct x11font *)font;
int sfid;
int shadowbold = FALSE;
+ int mult = (wide ? 2 : 1);
wide -= xfont->wide;
bold -= xfont->bold;
xcs[i].byte2 = wcs[i];
}
- gdk_draw_text(target, xfont->fonts[sfid], gc,
- x, y, (gchar *)xcs, nchars*2);
- if (shadowbold)
- gdk_draw_text(target, xfont->fonts[sfid], gc,
- x + xfont->shadowoffset, y, (gchar *)xcs, nchars*2);
+ x11font_really_draw_text(target, xfont->fonts[sfid], gc, x, y,
+ (gchar *)xcs, 2, nchars,
+ shadowbold, xfont->shadowoffset,
+ xfont->variable, cellwidth * mult);
sfree(xcs);
sfree(wcs);
} else {
- gdk_draw_text(target, xfont->fonts[sfid], gc, x, y, string, len);
- if (shadowbold)
- gdk_draw_text(target, xfont->fonts[sfid], gc,
- x + xfont->shadowoffset, y, string, len);
+ x11font_really_draw_text(target, xfont->fonts[sfid], gc, x, y,
+ string, 1, len,
+ shadowbold, xfont->shadowoffset,
+ xfont->variable, cellwidth * mult);
}
}