summaryrefslogtreecommitdiff
path: root/app/xterm/fontutils.c
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2009-10-31 14:11:58 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2009-10-31 14:11:58 +0000
commit93c5456a54893a8e648cd803abf202e80e9a93b0 (patch)
treea522a3e8ef59cfadb54bef4eb060e452464ec1a9 /app/xterm/fontutils.c
parent80408f471074022f7300901bf92a1533dae3f8da (diff)
Update to xterm 250
Diffstat (limited to 'app/xterm/fontutils.c')
-rw-r--r--app/xterm/fontutils.c172
1 files changed, 162 insertions, 10 deletions
diff --git a/app/xterm/fontutils.c b/app/xterm/fontutils.c
index 9eb94a251..ed1cf71c9 100644
--- a/app/xterm/fontutils.c
+++ b/app/xterm/fontutils.c
@@ -1,4 +1,4 @@
-/* $XTermId: fontutils.c,v 1.307 2009/08/07 23:22:32 tom Exp $ */
+/* $XTermId: fontutils.c,v 1.319 2009/10/12 22:29:42 tom Exp $ */
/************************************************************
@@ -158,6 +158,37 @@ compatibleWideCounts(XFontStruct * wfs, XFontStruct * wbfs)
}
#endif /* OPT_WIDE_CHARS */
+#if OPT_BOX_CHARS
+static void
+setupPackedFonts(XtermWidget xw)
+{
+ TScreen *screen = TScreenOf(xw);
+ Bool value = False;
+
+#if OPT_RENDERFONT
+#define MIXED(name) screen->name[fontnum].map.mixed
+ if (xw->misc.render_font) {
+ int fontnum = screen->menu_font_number;
+
+ screen->allow_packing = (Boolean) (MIXED(renderFontNorm)
+ || MIXED(renderFontBold)
+ || MIXED(renderFontItal)
+#if OPT_RENDERWIDE
+ || MIXED(renderWideNorm)
+ || MIXED(renderWideBold)
+ || MIXED(renderWideItal)
+#endif
+ );
+#undef MIXED
+ }
+#endif /* OPT_RENDERFONT */
+
+ value = screen->allow_packing;
+
+ SetItemSensitivity(fontMenuEntries[fontMenu_font_packedfont].widget, value);
+}
+#endif
+
/*
* Returns the fields from start to stop in a dash- separated string. This
* function will modify the source, putting '\0's in the appropiate place and
@@ -342,7 +373,7 @@ alloca_fontname(char **result, size_t next)
}
static void
-append_fontname_str(char **result, char *value)
+append_fontname_str(char **result, const char *value)
{
if (value == 0)
value = "*";
@@ -374,9 +405,9 @@ append_fontname_num(char **result, int value)
*/
static char *
derive_font_name(FontNameProperties * props,
- char *use_weight,
+ const char *use_weight,
int use_average_width,
- char *use_encoding)
+ const char *use_encoding)
{
char *result = 0;
@@ -436,7 +467,7 @@ xtermSpecialFont(TScreen * screen, unsigned atts, unsigned chrset)
#endif
FontNameProperties *props;
char *result = 0;
- char *weight;
+ const char *weight;
int pixel_size;
int res_x;
int res_y;
@@ -1090,7 +1121,11 @@ xtermLoadFont(XtermWidget xw,
}
});
- screen->fnt_prop = proportional;
+#if OPT_BOX_CHARS
+ screen->allow_packing = proportional;
+ setupPackedFonts(xw);
+#endif
+ screen->fnt_prop = (Boolean) (proportional && !(screen->force_packed));
screen->fnt_boxes = True;
#if OPT_BOX_CHARS
@@ -1206,7 +1241,7 @@ typedef struct {
* correspond to the VT100 resources.
*/
static Bool
-xtermLoadVTFonts(XtermWidget xw, char *myName, char *myClass)
+xtermLoadVTFonts(XtermWidget xw, String myName, String myClass)
{
static Bool initialized = False;
static SubResourceRec original, referenceRec, subresourceRec;
@@ -1293,7 +1328,7 @@ xtermLoadVTFonts(XtermWidget xw, char *myName, char *myClass)
#if OPT_WIDE_CHARS
static Bool
-isWideFont(XFontStruct * fp, char *tag, Bool nullOk)
+isWideFont(XFontStruct * fp, const char *tag, Bool nullOk)
{
Bool result = False;
@@ -1438,6 +1473,87 @@ xtermSetCursorBox(TScreen * screen)
#if OPT_RENDERFONT
+#if OPT_TRACE > 1
+static FcChar32
+xtermXftFirstChar(XftFont * xft)
+{
+ FcChar32 map[FC_CHARSET_MAP_SIZE];
+ FcChar32 next;
+ FcChar32 first;
+ int i;
+
+ first = FcCharSetFirstPage(xft->charset, map, &next);
+ for (i = 0; i < FC_CHARSET_MAP_SIZE; i++)
+ if (map[i]) {
+ FcChar32 bits = map[i];
+ first += i * 32;
+ while (!(bits & 0x1)) {
+ bits >>= 1;
+ first++;
+ }
+ break;
+ }
+ return first;
+}
+
+static FcChar32
+xtermXftLastChar(XftFont * xft)
+{
+ FcChar32 this, last, next;
+ FcChar32 map[FC_CHARSET_MAP_SIZE];
+ int i;
+ last = FcCharSetFirstPage(xft->charset, map, &next);
+ while ((this = FcCharSetNextPage(xft->charset, map, &next)) != FC_CHARSET_DONE)
+ last = this;
+ last &= ~0xff;
+ for (i = FC_CHARSET_MAP_SIZE - 1; i >= 0; i--)
+ if (map[i]) {
+ FcChar32 bits = map[i];
+ last += i * 32 + 31;
+ while (!(bits & 0x80000000)) {
+ last--;
+ bits <<= 1;
+ }
+ break;
+ }
+ return (long) last;
+}
+
+static void
+dumpXft(XtermWidget xw, XTermXftFonts * data)
+{
+ XftFont *xft = data->font;
+ TScreen *screen = TScreenOf(xw);
+ VTwin *win = WhichVWin(screen);
+
+ FcChar32 c;
+ FcChar32 first = xtermXftFirstChar(xft);
+ FcChar32 last = xtermXftLastChar(xft);
+ unsigned count = 0;
+ unsigned outside = 0;
+
+ TRACE(("dumpXft {{\n"));
+ TRACE((" data range %#6x..%#6x\n", first, last));
+ for (c = first; c <= last; ++c) {
+ if (FcCharSetHasChar(xft->charset, c)) {
+ int width = my_wcwidth((int) c);
+ XGlyphInfo extents;
+
+ XftTextExtents32(XtDisplay(xw), xft, &c, 1, &extents);
+ TRACE(("%#6x %2d %.1f\n", c, width,
+ ((double) extents.width) / win->f_width));
+ if (extents.width > win->f_width)
+ ++outside;
+ ++count;
+ }
+ }
+ TRACE(("}} %u total, %u outside\n", count, outside));
+}
+#define DUMP_XFT(xw, data) dumpXft(xw, data)
+#else
+#define DUMP_XFT(xw, data) /* nothing */
+#endif
+
static void
checkXft(XtermWidget xw, XTermXftFonts * data, XftFont * xft)
{
@@ -1448,13 +1564,23 @@ checkXft(XtermWidget xw, XTermXftFonts * data, XftFont * xft)
data->map.min_width = 0;
data->map.max_width = (Dimension) xft->max_advance_width;
+ /*
+ * For each ASCII or ISO-8859-1 printable code, ask what its width is.
+ * Given the maximum width for those, we have a reasonable estimate of
+ * the single-column width.
+ *
+ * Ignore control characters - their extent information is misleading.
+ */
for (c = 32; c < 256; ++c) {
+ if (c >= 127 && c <= 159)
+ continue;
if (FcCharSetHasChar(xft->charset, c)) {
XGlyphInfo extents;
XftTextExtents32(XtDisplay(xw), xft, &c, 1, &extents);
- if (width < extents.width)
+ if (width < extents.width && extents.width <= data->map.max_width) {
width = extents.width;
+ }
}
}
data->map.min_width = width;
@@ -1576,6 +1702,15 @@ setRenderFontsize(TScreen * screen, VTwin * win, XftFont * font, const char *tag
}
#endif
+static void
+checkFontInfo(int value, const char *tag)
+{
+ if (value == 0) {
+ fprintf(stderr, "Selected font has no non-zero %s for ISO-8859-1 encoding\n", tag);
+ exit(1);
+ }
+}
+
/*
* Compute useful values for the font/window sizes
*/
@@ -1805,6 +1940,20 @@ xtermComputeFontInfo(XtermWidget xw,
setRenderFontsize(screen, win, norm, NULL);
setRenderFontsize(screen, win, bold, "bold");
setRenderFontsize(screen, win, ital, "ital");
+#if OPT_BOX_CHARS
+ setupPackedFonts(xw);
+
+ if (screen->force_packed) {
+ XTermXftFonts *use = &(screen->renderFontNorm[fontnum]);
+ win->f_height = use->font->ascent + use->font->descent;
+ win->f_width = use->map.min_width;
+ TRACE(("...packed TrueType font %dx%d vs %d\n",
+ win->f_height,
+ win->f_width,
+ use->map.max_width));
+ }
+#endif
+ DUMP_XFT(xw, &(screen->renderFontNorm[fontnum]));
}
}
/*
@@ -1813,7 +1962,7 @@ xtermComputeFontInfo(XtermWidget xw,
if (!xw->misc.render_font || IsIconWin(screen, win))
#endif /* OPT_RENDERFONT */
{
- if (is_double_width_font(font)) {
+ if (is_double_width_font(font) && !(screen->fnt_prop)) {
win->f_width = (font->min_bounds.width);
} else {
win->f_width = (font->max_bounds.width);
@@ -1840,6 +1989,9 @@ xtermComputeFontInfo(XtermWidget xw,
win->f_width,
win->f_ascent,
win->f_descent));
+
+ checkFontInfo(win->f_height, "height");
+ checkFontInfo(win->f_width, "width");
}
/* save this information as a side-effect for double-sized characters */