char *(*canonify_fontname)(GtkWidget *widget, const char *name, int *size,
int *flags, int resolve_aliases);
char *(*scale_fontname)(GtkWidget *widget, const char *name, int size);
+ char *(*size_increment)(unifont *font, int increment);
/*
* `Static data members' of the `class'.
int resolve_aliases);
static char *x11font_scale_fontname(GtkWidget *widget, const char *name,
int size);
+static char *x11font_size_increment(unifont *font, int increment);
#ifdef DRAW_TEXT_CAIRO
struct cairo_cached_glyph {
x11font_enum_fonts,
x11font_canonify_fontname,
x11font_scale_fontname,
+ x11font_size_increment,
"server",
};
S(charset_encoding) \
/* end of list */
+/* Special value for int fields that xlfd_recompose will render as "*" */
+#define XLFD_INT_WILDCARD INT_MIN
+
struct xlfd_decomposed {
#define STR_FIELD(f) const char *f;
#define INT_FIELD(f) int f;
{
#define FMT_STR(f) "-%s"
#define ARG_STR(f) , dec->f
-#define FMT_INT(f) "-%d"
-#define ARG_INT(f) , dec->f
+#define FMT_INT(f) "%s%.*d"
+#define ARG_INT(f) \
+ , dec->f == XLFD_INT_WILDCARD ? "-*" : "-" \
+ , dec->f == XLFD_INT_WILDCARD ? 0 : 1 \
+ , dec->f == XLFD_INT_WILDCARD ? 0 : dec->f
return dupprintf(XLFD_STRING_PARTS_LIST(FMT_STR, FMT_INT)
XLFD_STRING_PARTS_LIST(ARG_STR, ARG_INT));
#undef FMT_STR
}
}
-static const XCharStruct *x11_char_struct(XFontStruct *xfs,
- int byte1, int byte2)
+static const XCharStruct *x11_char_struct(
+ XFontStruct *xfs, unsigned char byte1, unsigned char byte2)
{
int index;
return &xfs->per_char[index];
}
-static int x11_font_has_glyph(XFontStruct *xfs, int byte1, int byte2)
+static int x11_font_has_glyph(
+ XFontStruct *xfs, unsigned char byte1, unsigned char byte2)
{
/*
* Not to be confused with x11font_has_glyph, which is a method of
return NULL; /* shan't */
}
+static char *x11font_size_increment(unifont *font, int increment)
+{
+ struct x11font *xfont = (struct x11font *)font;
+ Display *disp = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
+ Atom fontprop = XInternAtom(disp, "FONT", False);
+ char *returned_name = NULL;
+ unsigned long ret;
+ if (XGetFontProperty(xfont->fonts[0].xfs, fontprop, &ret)) {
+ struct xlfd_decomposed *xlfd;
+ struct xlfd_decomposed *xlfd_best;
+ char *wc;
+ char **fontnames;
+ int nnames, i, max;
+
+ xlfd = xlfd_decompose(XGetAtomName(disp, (Atom)ret));
+ if (!xlfd)
+ return NULL;
+
+ /*
+ * Form a wildcard consisting of everything in the
+ * original XLFD except for the size-related fields.
+ */
+ {
+ struct xlfd_decomposed xlfd_wc = *xlfd; /* structure copy */
+ xlfd_wc.pixel_size = XLFD_INT_WILDCARD;
+ xlfd_wc.point_size = XLFD_INT_WILDCARD;
+ xlfd_wc.average_width = XLFD_INT_WILDCARD;
+ wc = xlfd_recompose(&xlfd_wc);
+ }
+
+ /*
+ * Fetch all the font names matching that wildcard.
+ */
+ max = 32768;
+ while (1) {
+ fontnames = XListFonts(disp, wc, max, &nnames);
+ if (nnames >= max) {
+ XFreeFontNames(fontnames);
+ max *= 2;
+ } else
+ break;
+ }
+
+ sfree(wc);
+
+ /*
+ * Iterate over those to find the one closest in size to the
+ * original font, in the correct direction.
+ */
+
+#define FLIPPED_SIZE(xlfd) \
+ (((xlfd)->pixel_size + (xlfd)->point_size) * \
+ (increment < 0 ? -1 : +1))
+
+ xlfd_best = NULL;
+ for (i = 0; i < nnames; i++) {
+ struct xlfd_decomposed *xlfd2 = xlfd_decompose(fontnames[i]);
+ if (!xlfd2)
+ continue;
+
+ if (xlfd2->pixel_size != 0 &&
+ FLIPPED_SIZE(xlfd2) > FLIPPED_SIZE(xlfd) &&
+ (!xlfd_best || FLIPPED_SIZE(xlfd2)<FLIPPED_SIZE(xlfd_best))) {
+ sfree(xlfd_best);
+ xlfd_best = xlfd2;
+ xlfd2 = NULL;
+ }
+
+ sfree(xlfd2);
+ }
+
+#undef FLIPPED_SIZE
+
+ if (xlfd_best) {
+ char *bare_returned_name = xlfd_recompose(xlfd_best);
+ returned_name = dupcat(
+ xfont->u.vt->prefix, ":", bare_returned_name,
+ (const char *)NULL);
+ sfree(bare_returned_name);
+ }
+
+ XFreeFontNames(fontnames);
+ sfree(xlfd);
+ sfree(xlfd_best);
+ }
+ return returned_name;
+}
+
#endif /* NOT_X_WINDOWS */
#if GTK_CHECK_VERSION(2,0,0)
int resolve_aliases);
static char *pangofont_scale_fontname(GtkWidget *widget, const char *name,
int size);
+static char *pangofont_size_increment(unifont *font, int increment);
struct pangofont {
struct unifont u;
pangofont_enum_fonts,
pangofont_canonify_fontname,
pangofont_scale_fontname,
+ pangofont_size_increment,
"client",
};
return retname;
}
+static char *pangofont_size_increment(unifont *font, int increment)
+{
+ struct pangofont *pfont = (struct pangofont *)font;
+ PangoFontDescription *desc;
+ int size;
+ char *newname, *retname;
+
+ desc = pango_font_description_copy_static(pfont->desc);
+
+ size = pango_font_description_get_size(desc);
+ size += PANGO_SCALE * increment;
+
+ if (size <= 0) {
+ retname = NULL;
+ } else {
+ pango_font_description_set_size(desc, size);
+ newname = pango_font_description_to_string(desc);
+ retname = dupcat(pfont->u.vt->prefix, ":",
+ newname, (const char *)NULL);
+ g_free(newname);
+ }
+
+ pango_font_description_free(desc);
+ return retname;
+}
+
#endif /* GTK_CHECK_VERSION(2,0,0) */
/* ----------------------------------------------------------------------
cellwidth);
}
+char *unifont_size_increment(unifont *font, int increment)
+{
+ return font->vt->size_increment(font, increment);
+}
+
/* ----------------------------------------------------------------------
* Multiple-font wrapper. This is a type of unifont which encapsulates
* up to two other unifonts, permitting missing glyphs in the main
int len, int wide, int bold,
int cellwidth);
static void multifont_destroy(unifont *font);
+static char *multifont_size_increment(unifont *font, int increment);
struct multifont {
struct unifont u;
NULL,
NULL,
NULL,
+ multifont_size_increment,
"client",
};
cellwidth, 0, unifont_draw_combining);
}
+static char *multifont_size_increment(unifont *font, int increment)
+{
+ struct multifont *mfont = (struct multifont *)font;
+ return unifont_size_increment(mfont->main, increment);
+}
+
#if GTK_CHECK_VERSION(2,0,0)
/* ----------------------------------------------------------------------