diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2009-10-31 14:11:58 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2009-10-31 14:11:58 +0000 |
commit | 93c5456a54893a8e648cd803abf202e80e9a93b0 (patch) | |
tree | a522a3e8ef59cfadb54bef4eb060e452464ec1a9 /app/xterm/fontutils.c | |
parent | 80408f471074022f7300901bf92a1533dae3f8da (diff) |
Update to xterm 250
Diffstat (limited to 'app/xterm/fontutils.c')
-rw-r--r-- | app/xterm/fontutils.c | 172 |
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 */ |