diff options
author | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2014-07-14 08:30:12 +0000 |
---|---|---|
committer | Matthieu Herrb <matthieu@cvs.openbsd.org> | 2014-07-14 08:30:12 +0000 |
commit | 6518ce5cf01755374e22ff2d69aa1ee0e0a4aeb9 (patch) | |
tree | a9709c5164f467c00c8b90d524461ad512e62b36 /app/xterm/fontutils.c | |
parent | 8126a298d120522d6d2e12e1070085274eee8206 (diff) |
Update to xterm-309. Version 308 tested by several people including
naddy@ who found a small regression, fixed in 309.
Diffstat (limited to 'app/xterm/fontutils.c')
-rw-r--r-- | app/xterm/fontutils.c | 453 |
1 files changed, 351 insertions, 102 deletions
diff --git a/app/xterm/fontutils.c b/app/xterm/fontutils.c index 42a959865..1221ef89c 100644 --- a/app/xterm/fontutils.c +++ b/app/xterm/fontutils.c @@ -1,4 +1,4 @@ -/* $XTermId: fontutils.c,v 1.405 2014/05/03 10:49:26 tom Exp $ */ +/* $XTermId: fontutils.c,v 1.440 2014/07/13 00:34:40 Ross.Combs Exp $ */ /* * Copyright 1998-2013,2014 by Thomas E. Dickey @@ -51,6 +51,12 @@ #include <stdio.h> #include <ctype.h> +#define ALLOC_STRING(name) \ + if (name != 0) \ + name = x_strdup(name) +#define FREE_STRING(name) \ + free_string(name) + #define SetFontWidth(screen,dst,src) (dst)->f_width = (src) #define SetFontHeight(screen,dst,src) (dst)->f_height = dimRound((screen)->scale_height * (float) (src)) @@ -89,31 +95,43 @@ } \ } +#define FREE_FNAME(field) \ + if (fonts == 0 || myfonts.field != fonts->field) { \ + FREE_STRING(myfonts.field); \ + myfonts.field = 0; \ + } + /* * A structure to hold the relevant properties from a font * we need to make a well formed font name for it. */ typedef struct { /* registry, foundry, family */ - char *beginning; + const char *beginning; /* weight */ - char *weight; + const char *weight; /* slant */ - char *slant; + const char *slant; /* wideness */ - char *wideness; + const char *wideness; /* add style */ - char *add_style; + const char *add_style; int pixel_size; - char *point_size; + const char *point_size; int res_x; int res_y; - char *spacing; + const char *spacing; int average_width; /* charset registry, charset encoding */ char *end; } FontNameProperties; +static void +free_string(String value) +{ + free((void *) value); +} + #if OPT_RENDERFONT static void fillInFaceSize(XtermWidget, int); #endif @@ -197,7 +215,7 @@ setupPackedFonts(XtermWidget xw) /* * 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 + * function will modify the source, putting '\0's in the appropriate place and * moving the beginning forward to after the '\0' * * This will NOT work for the last field (but we won't need it). @@ -211,16 +229,18 @@ n_fields(char **source, int start, int stop) /* * find the start-1th dash */ - for (i = start - 1, str = *source; i; i--, str++) + for (i = start - 1, str = *source; i; i--, str++) { if ((str = strchr(str, '-')) == 0) return 0; + } /* * find the stopth dash */ - for (i = stop - start + 1, str1 = str; i; i--, str1++) + for (i = stop - start + 1, str1 = str; i; i--, str1++) { if ((str1 = strchr(str1, '-')) == 0) return 0; + } /* * put a \0 at the end of the fields @@ -444,6 +464,16 @@ bold_font_name(FontNameProperties *props, int use_average_width) return derive_font_name(props, "bold", use_average_width, props->end); } +#if OPT_WIDE_ATTRS +static char * +italic_font_name(FontNameProperties *props, int use_average_width) +{ + FontNameProperties myprops = *props; + myprops.slant = "o"; + return derive_font_name(&myprops, props->weight, use_average_width, props->end); +} +#endif + #if OPT_WIDE_CHARS #define derive_wide_font(props, weight) \ derive_font_name(props, weight, props->average_width * 2, "ISO10646-1") @@ -470,7 +500,7 @@ widebold_font_name(FontNameProperties *props) * fonts we double the pixel-size and Y-resolution */ char * -xtermSpecialFont(TScreen *screen, unsigned atts, unsigned chrset) +xtermSpecialFont(TScreen *screen, unsigned attr_flags, unsigned draw_flags, unsigned chrset) { #if OPT_TRACE static char old_spacing[80]; @@ -490,7 +520,7 @@ xtermSpecialFont(TScreen *screen, unsigned atts, unsigned chrset) pixel_size = props->pixel_size; res_x = props->res_x; res_y = props->res_y; - if (atts & BOLD) + if (attr_flags & BOLD) weight = "bold"; else weight = props->weight; @@ -508,7 +538,8 @@ xtermSpecialFont(TScreen *screen, unsigned atts, unsigned chrset) || old_props.res_x != res_y || old_props.pixel_size != pixel_size || strcmp(old_props.spacing, props->spacing)) { - TRACE(("xtermSpecialFont(atts = %#x, chrset = %#x)\n", atts, chrset)); + TRACE(("xtermSpecialFont(atts = %#x, draw = %#x, chrset = %#x)\n", + attr_flags, draw_flags, chrset)); TRACE(("res_x = %d\n", res_x)); TRACE(("res_y = %d\n", res_y)); TRACE(("point_size = %s\n", props->point_size)); @@ -529,8 +560,8 @@ xtermSpecialFont(TScreen *screen, unsigned atts, unsigned chrset) append_fontname_str(&result, props->add_style); append_fontname_num(&result, pixel_size); append_fontname_str(&result, props->point_size); - append_fontname_num(&result, (atts & NORESOLUTION) ? -1 : res_x); - append_fontname_num(&result, (atts & NORESOLUTION) ? -1 : res_y); + append_fontname_num(&result, (draw_flags & NORESOLUTION) ? -1 : res_x); + append_fontname_num(&result, (draw_flags & NORESOLUTION) ? -1 : res_y); append_fontname_str(&result, props->spacing); append_fontname_str(&result, 0); append_fontname_str(&result, props->end); @@ -599,6 +630,36 @@ got_bold_font(Display *dpy, XFontStruct *fs, String requested) } /* + * Check normal/bold (or wide/wide-bold) font pairs to see if we will be able + * to check for missing glyphs in a comparable manner. + */ +static int +comparable_metrics(XFontStruct *normal, XFontStruct *bold) +{ +#define DATA "comparable_metrics: " + int result = 0; + + if (normal->all_chars_exist) { + if (bold->all_chars_exist) { + result = 1; + } else { + TRACE((DATA "all chars exist in normal font, but not in bold\n")); + } + } else if (normal->per_char != 0) { + if (bold->per_char != 0) { + result = 1; + } else { + TRACE((DATA "normal font has per-char metrics, but not bold\n")); + } + } else { + TRACE((DATA "normal font is not very good!\n")); + result = 1; /* give in (we're not going in reverse) */ + } + return result; +#undef DATA +} + +/* * If the font server tries to adjust another font, it may not adjust it * properly. Check that the bounding boxes are compatible. Otherwise we'll * leave trash on the display when we mix normal and bold fonts. @@ -723,8 +784,7 @@ const VTFontNames * xtermFontName(const char *normal) { static VTFontNames data; - if (data.f_n) - free((void *) data.f_n); + FREE_STRING(data.f_n); memset(&data, 0, sizeof(data)); data.f_n = x_strdup(normal); return &data; @@ -734,10 +794,10 @@ static void cache_menu_font_name(TScreen *screen, int fontnum, int which, const char *name) { if (name != 0) { - char *last = (char *) screen->menu_font_names[fontnum][which]; + String last = screen->menu_font_names[fontnum][which]; if (last != 0) { if (strcmp(last, name)) { - free(last); + FREE_STRING(last); TRACE(("caching menu fontname %d.%d %s\n", fontnum, which, name)); screen->menu_font_names[fontnum][which] = x_strdup(name); } @@ -883,7 +943,6 @@ reportOneVTFont(const char *tag, { if (!IsEmpty(fnt->fn)) { XFontStruct *fs = fnt->fs; - unsigned missing = 0; unsigned first_char = 0; unsigned last_char = 0; unsigned ch; @@ -896,12 +955,6 @@ reportOneVTFont(const char *tag, last_char = (fs->max_byte1 * 256) + fs->max_char_or_byte2; } - for (ch = first_char; ch <= last_char; ++ch) { - if (xtermMissingChar(ch, fnt)) { - ++missing; - } - } - printf("\t%s: %s\n", tag, NonNull(fnt->fn)); printf("\t\tall chars: %s\n", fs->all_chars_exist ? "yes" : "no"); printf("\t\tdefault char: %d\n", fs->default_char); @@ -911,8 +964,19 @@ reportOneVTFont(const char *tag, printf("\t\tfirst char: %u\n", first_char); printf("\t\tlast char: %u\n", last_char); printf("\t\tmaximum-chars: %u\n", countGlyphs(fs)); - printf("\t\tmissing-chars: %u\n", missing); - printf("\t\tpresent-chars: %u\n", countGlyphs(fs) - missing); + if (FontLacksMetrics(fnt)) { + printf("\t\tmissing-chars: ?\n"); + printf("\t\tpresent-chars: ?\n"); + } else { + unsigned missing = 0; + for (ch = first_char; ch <= last_char; ++ch) { + if (xtermMissingChar(ch, fnt)) { + ++missing; + } + } + printf("\t\tmissing-chars: %u\n", missing); + printf("\t\tpresent-chars: %u\n", countGlyphs(fs) - missing); + } printf("\t\tmin_byte1: %d\n", fs->min_byte1); printf("\t\tmax_byte1: %d\n", fs->max_byte1); printf("\t\tproperties: %d\n", fs->n_properties); @@ -943,6 +1007,66 @@ reportVTFontInfo(XtermWidget xw, int fontnum) } #endif +void +xtermUpdateFontGCs(XtermWidget xw, XTermFonts * fnts) +{ + TScreen *screen = TScreenOf(xw); + VTwin *win = WhichVWin(screen); + Pixel new_normal = getXtermForeground(xw, xw->flags, xw->cur_foreground); + Pixel new_revers = getXtermBackground(xw, xw->flags, xw->cur_background); + + setCgsFore(xw, win, gcNorm, new_normal); + setCgsBack(xw, win, gcNorm, new_revers); + setCgsFont(xw, win, gcNorm, &(fnts[fNorm])); + + copyCgs(xw, win, gcBold, gcNorm); + setCgsFont(xw, win, gcBold, &(fnts[fBold])); + + setCgsFore(xw, win, gcNormReverse, new_revers); + setCgsBack(xw, win, gcNormReverse, new_normal); + setCgsFont(xw, win, gcNormReverse, &(fnts[fNorm])); + + copyCgs(xw, win, gcBoldReverse, gcNormReverse); + setCgsFont(xw, win, gcBoldReverse, &(fnts[fBold])); + + if_OPT_WIDE_CHARS(screen, { + if (fnts[fWide].fs != 0 + && fnts[fWBold].fs != 0) { + setCgsFore(xw, win, gcWide, new_normal); + setCgsBack(xw, win, gcWide, new_revers); + setCgsFont(xw, win, gcWide, &(fnts[fWide])); + + copyCgs(xw, win, gcWBold, gcWide); + setCgsFont(xw, win, gcWBold, &(fnts[fWBold])); + + setCgsFore(xw, win, gcWideReverse, new_revers); + setCgsBack(xw, win, gcWideReverse, new_normal); + setCgsFont(xw, win, gcWideReverse, &(fnts[fWide])); + + copyCgs(xw, win, gcWBoldReverse, gcWideReverse); + setCgsFont(xw, win, gcWBoldReverse, &(fnts[fWBold])); + } + }); +} + +#if OPT_TRACE +static void +show_font_misses(const char *name, XTermFonts * fp) +{ + if (fp->fs != 0) { + if (FontLacksMetrics(fp)) { + TRACE(("%s font lacks metrics\n", name)); + } else if (FontIsIncomplete(fp)) { + TRACE(("%s font is incomplete\n", name)); + } else { + TRACE(("%s font is complete\n", name)); + } + } else { + TRACE(("%s font is missing\n", name)); + } +} +#endif + int xtermLoadFont(XtermWidget xw, const VTFontNames * fonts, @@ -955,8 +1079,6 @@ xtermLoadFont(XtermWidget xw, VTFontNames myfonts; FontNameProperties *fp; XTermFonts fnts[fMAX]; - Pixel new_normal; - Pixel new_revers; char *tmpname = NULL; char *normal = NULL; Boolean proportional = False; @@ -1032,8 +1154,10 @@ xtermLoadFont(XtermWidget xw, warn[fBold] = fwAlways; fp = get_font_name_props(screen->display, fnts[fNorm].fs, &normal); if (fp != 0) { + FREE_FNAME(f_b); myfonts.f_b = bold_font_name(fp, fp->average_width); if (!xtermOpenFont(xw, myfonts.f_b, &fnts[fBold], fwAlways, False)) { + FREE_FNAME(f_b); myfonts.f_b = bold_font_name(fp, -1); xtermOpenFont(xw, myfonts.f_b, &fnts[fBold], fwAlways, False); } @@ -1042,7 +1166,8 @@ xtermLoadFont(XtermWidget xw, if (fp == 0 || fnts[fBold].fs == 0) { xtermCopyFontInfo(&fnts[fBold], &fnts[fNorm]); TRACE(("...cannot load a matching bold font\n")); - } else if (same_font_size(xw, fnts[fNorm].fs, fnts[fBold].fs) + } else if (comparable_metrics(fnts[fNorm].fs, fnts[fBold].fs) + && same_font_size(xw, fnts[fNorm].fs, fnts[fBold].fs) && got_bold_font(screen->display, fnts[fBold].fs, myfonts.f_b)) { TRACE(("...got a matching bold font\n")); cache_menu_font_name(screen, fontnum, fBold, myfonts.f_b); @@ -1071,6 +1196,7 @@ xtermLoadFont(XtermWidget xw, if (check_fontname(myfonts.f_w)) { cache_menu_font_name(screen, fontnum, fWide, myfonts.f_w); } else if (screen->utf8_fonts && !is_double_width_font(fnts[fNorm].fs)) { + FREE_FNAME(f_w); fp = get_font_name_props(screen->display, fnts[fNorm].fs, &normal); if (fp != 0) { myfonts.f_w = wide_font_name(fp); @@ -1112,14 +1238,15 @@ xtermLoadFont(XtermWidget xw, xtermCloseFont(xw, &fnts[fWBold]); } if (fnts[fWBold].fs == 0) { + FREE_FNAME(f_wb); if (IsEmpty(myfonts.f_w)) { - myfonts.f_wb = myfonts.f_b; + myfonts.f_wb = x_strdup(myfonts.f_b); warn[fWBold] = fwAlways; xtermCopyFontInfo(&fnts[fWBold], &fnts[fBold]); TRACE(("...cannot load wide-bold, use bold %s\n", NonNull(myfonts.f_b))); } else { - myfonts.f_wb = myfonts.f_w; + myfonts.f_wb = x_strdup(myfonts.f_w); warn[fWBold] = fwAlways; xtermCopyFontInfo(&fnts[fWBold], &fnts[fWide]); TRACE(("...cannot load wide-bold, use wide %s\n", @@ -1167,8 +1294,10 @@ xtermLoadFont(XtermWidget xw, if_OPT_WIDE_CHARS(screen, { if (fnts[fWide].fs != 0 && fnts[fWBold].fs != 0 - && !same_font_size(xw, fnts[fWide].fs, fnts[fWBold].fs) - && (is_fixed_font(fnts[fWide].fs) && is_fixed_font(fnts[fWBold].fs))) { + && (!comparable_metrics(fnts[fWide].fs, fnts[fWBold].fs) + || (!same_font_size(xw, fnts[fWide].fs, fnts[fWBold].fs) + && is_fixed_font(fnts[fWide].fs) + && is_fixed_font(fnts[fWBold].fs)))) { TRACE(("...ignoring mismatched normal/bold wide fonts\n")); xtermCloseFont(xw, &fnts[fWBold]); xtermCopyFontInfo(&fnts[fWBold], &fnts[fWide]); @@ -1214,6 +1343,10 @@ xtermLoadFont(XtermWidget xw, * XLoadQueryFont call allocates a new XFontStruct. */ xtermCloseFonts(xw, screen->fnts); +#if OPT_WIDE_ATTRS + xtermCloseFonts(xw, screen->ifnts); + screen->ifnts_ok = False; +#endif xtermCopyFontInfo(&(screen->fnts[fNorm]), &fnts[fNorm]); xtermCopyFontInfo(&(screen->fnts[fBold]), &fnts[fBold]); @@ -1224,41 +1357,7 @@ xtermLoadFont(XtermWidget xw, xtermCopyFontInfo(&(screen->fnts[fWBold]), &fnts[fWBold]); #endif - new_normal = getXtermForeground(xw, xw->flags, xw->cur_foreground); - new_revers = getXtermBackground(xw, xw->flags, xw->cur_background); - - setCgsFore(xw, win, gcNorm, new_normal); - setCgsBack(xw, win, gcNorm, new_revers); - setCgsFont(xw, win, gcNorm, &(screen->fnts[fNorm])); - - copyCgs(xw, win, gcBold, gcNorm); - setCgsFont(xw, win, gcBold, &(screen->fnts[fBold])); - - setCgsFore(xw, win, gcNormReverse, new_revers); - setCgsBack(xw, win, gcNormReverse, new_normal); - setCgsFont(xw, win, gcNormReverse, &(screen->fnts[fNorm])); - - copyCgs(xw, win, gcBoldReverse, gcNormReverse); - setCgsFont(xw, win, gcBoldReverse, &(screen->fnts[fBold])); - - if_OPT_WIDE_CHARS(screen, { - if (screen->fnts[fWide].fs != 0 - && screen->fnts[fWBold].fs != 0) { - setCgsFore(xw, win, gcWide, new_normal); - setCgsBack(xw, win, gcWide, new_revers); - setCgsFont(xw, win, gcWide, &(screen->fnts[fWide])); - - copyCgs(xw, win, gcWBold, gcWide); - setCgsFont(xw, win, gcWBold, &(screen->fnts[fWBold])); - - setCgsFore(xw, win, gcWideReverse, new_revers); - setCgsBack(xw, win, gcWideReverse, new_normal); - setCgsFont(xw, win, gcWideReverse, &(screen->fnts[fWide])); - - copyCgs(xw, win, gcWBoldReverse, gcWideReverse); - setCgsFont(xw, win, gcWBoldReverse, &(screen->fnts[fWBold])); - } - }); + xtermUpdateFontGCs(xw, screen->fnts); #if OPT_BOX_CHARS screen->allow_packing = proportional; @@ -1269,7 +1368,7 @@ xtermLoadFont(XtermWidget xw, #if OPT_BOX_CHARS /* - * Xterm uses character positions 1-31 of a font for the line-drawing + * xterm uses character positions 1-31 of a font for the line-drawing * characters. Check that they are all present. The null character * (0) is special, and is not used. */ @@ -1285,10 +1384,15 @@ xtermLoadFont(XtermWidget xw, { unsigned ch; - TRACE(("normal font is %scomplete\n", - FontIsIncomplete(&fnts[fNorm]) ? "in" : "")); - TRACE(("bold font is %scomplete\n", - FontIsIncomplete(&fnts[fBold]) ? "in" : "")); +#if OPT_TRACE +#define TRACE_MISS(index) show_font_misses(#index, &fnts[index]) + TRACE_MISS(fNorm); + TRACE_MISS(fBold); +#if OPT_WIDE_CHARS + TRACE_MISS(fWide); + TRACE_MISS(fWBold); +#endif +#endif for (ch = 1; ch < 32; ch++) { unsigned n = ch; @@ -1330,7 +1434,7 @@ xtermLoadFont(XtermWidget xw, set_menu_font(True); if (tmpname) { /* if setting escape or sel */ if (screen->MenuFontName(fontnum)) - free((void *) screen->MenuFontName(fontnum)); + FREE_STRING(screen->MenuFontName(fontnum)); screen->MenuFontName(fontnum) = tmpname; if (fontnum == fontMenu_fontescape) { SetItemSensitivity(fontMenuEntries[fontMenu_fontescape].widget, @@ -1348,6 +1452,22 @@ xtermLoadFont(XtermWidget xw, #if OPT_REPORT_FONTS reportVTFontInfo(xw, fontnum); #endif + FREE_FNAME(f_n); + FREE_FNAME(f_b); +#if OPT_WIDE_CHARS + FREE_FNAME(f_w); + FREE_FNAME(f_wb); +#endif + if (fnts[fNorm].fn == fnts[fBold].fn) { + free(fnts[fNorm].fn); + } else { + free(fnts[fNorm].fn); + free(fnts[fBold].fn); + } +#if OPT_WIDE_CHARS + free(fnts[fWide].fn); + free(fnts[fWBold].fn); +#endif return 1; bad: @@ -1389,6 +1509,59 @@ xtermLoadFont(XtermWidget xw, return 0; } +#if OPT_WIDE_ATTRS +/* + * (Attempt to) load matching italics for the current normal/bold/etc fonts. + * If the attempt fails for a given style, use the non-italic font. + */ +void +xtermLoadItalics(XtermWidget xw) +{ + TScreen *screen = TScreenOf(xw); + FontNameProperties *fp; + char *name; + int n; + + if (!screen->ifnts_ok) { + screen->ifnts_ok = True; + for (n = 0; n < fMAX; ++n) { + /* + * FIXME - need to handle font-leaks + */ + screen->ifnts[n].fs = 0; + if (screen->fnts[n].fs != 0 && + (fp = get_font_name_props(screen->display, + screen->fnts[n].fs, + 0)) != 0) { + if ((name = italic_font_name(fp, fp->average_width)) != 0) { + TRACE(("xtermLoadItalics #%d %s\n", n, name)); + (void) xtermOpenFont(xw, + name, + &(screen->ifnts[n]), + fwResource, + False); +#if OPT_TRACE + { + XFontStruct *fs = + screen->ifnts[n].fs; + if (fs != 0) { + TRACE(("...actual size %dx%d (ascent %d, descent %d)\n", + fs->ascent + + fs->descent, + fs->max_bounds.width, + fs->ascent, + fs->descent)); + } + } +#endif + free(name); + } + } + } + } +} +#endif + #if OPT_LOAD_VTFONTS || OPT_WIDE_CHARS /* * Collect font-names that we can modify with the load-vt-fonts() action. @@ -1396,7 +1569,7 @@ xtermLoadFont(XtermWidget xw, #define MERGE_SUBFONT(src,dst,name) \ if (IsEmpty(dst.name)) { \ TRACE(("MERGE_SUBFONT " #dst "." #name " merge %s\n", NonNull(src.name))); \ - dst.name = src.name; \ + dst.name = x_strdup(src.name); \ } else { \ TRACE(("MERGE_SUBFONT " #dst "." #name " found %s\n", NonNull(dst.name))); \ } @@ -1409,15 +1582,39 @@ xtermLoadFont(XtermWidget xw, TRACE(("INFER_SUBFONT " #dst "." #name " found %s\n", NonNull(dst.name))); \ } +#define FREE_MENU_FONTS(dst) \ + TRACE(("FREE_MENU_FONTS " #dst "\n")); \ + for (n = fontMenu_default; n <= fontMenu_lastBuiltin; ++n) { \ + for (m = 0; m < fMAX; ++m) { \ + FREE_STRING(dst.menu_font_names[n][m]); \ + dst.menu_font_names[n][m] = 0; \ + } \ + } + #define COPY_MENU_FONTS(src,dst) \ TRACE(("COPY_MENU_FONTS " #src " to " #dst "\n")); \ for (n = fontMenu_default; n <= fontMenu_lastBuiltin; ++n) { \ for (m = 0; m < fMAX; ++m) { \ + FREE_STRING(dst.menu_font_names[n][m]); \ dst.menu_font_names[n][m] = x_strdup(src.menu_font_names[n][m]); \ } \ TRACE((".. " #dst ".menu_fonts_names[%d] = %s\n", n, dst.menu_font_names[n][fNorm])); \ } +#define COPY_DEFAULT_FONTS(target, source) \ + xtermCopyVTFontNames(&target.default_font, &source.default_font) + +static void +xtermCopyVTFontNames(VTFontNames * target, VTFontNames * source) +{ + target->f_n = x_strdup(source->f_n); + target->f_b = x_strdup(source->f_b); +#if OPT_WIDE_CHARS + target->f_w = x_strdup(source->f_w); + target->f_wb = x_strdup(source->f_wb); +#endif +} + void xtermSaveVTFonts(XtermWidget xw) { @@ -1428,7 +1625,7 @@ xtermSaveVTFonts(XtermWidget xw) screen->savedVTFonts = True; TRACE(("xtermSaveVTFonts saving original\n")); - screen->cacheVTFonts.default_font = xw->misc.default_font; + COPY_DEFAULT_FONTS(screen->cacheVTFonts, xw->misc); COPY_MENU_FONTS(xw->screen, screen->cacheVTFonts); } } @@ -1504,11 +1701,9 @@ xtermLoadVTFonts(XtermWidget xw, String myName, String myClass) if (IsEmpty(myName)) { TRACE(("xtermLoadVTFonts restoring original\n")); - xw->misc.default_font = screen->cacheVTFonts.default_font; + COPY_DEFAULT_FONTS(xw->misc, screen->cacheVTFonts); + FREE_MENU_FONTS(xw->screen); COPY_MENU_FONTS(screen->cacheVTFonts, xw->screen); - for (n = 0; n < XtNumber(screen->cacheVTFonts.menu_font_names); ++n) { - screen->MenuFontName(n) = screen->cacheVTFonts.MenuFontName(n); - } } else { TRACE(("xtermLoadVTFonts(%s, %s)\n", myName, myClass)); @@ -1530,6 +1725,20 @@ xtermLoadVTFonts(XtermWidget xw, String myName, String myClass) screen->mergedVTFonts = True; /* + * To make it simple, reallocate the strings returned by + * XtGetSubresources. We can free our own strings, but not theirs. + */ + ALLOC_STRING(subresourceRec.default_font.f_n); + ALLOC_STRING(subresourceRec.default_font.f_b); +#if OPT_WIDE_CHARS + ALLOC_STRING(subresourceRec.default_font.f_w); + ALLOC_STRING(subresourceRec.default_font.f_wb); +#endif + for (n = fontMenu_font1; n <= fontMenu_lastBuiltin; ++n) { + ALLOC_STRING(subresourceRec.MenuFontName(n)); + } + + /* * If a particular resource value was not found, use the original. */ MERGE_SUBFONT(xw->misc, subresourceRec, default_font.f_n); @@ -1538,20 +1747,39 @@ xtermLoadVTFonts(XtermWidget xw, String myName, String myClass) INFER_SUBFONT(xw->misc, subresourceRec, default_font.f_w); INFER_SUBFONT(xw->misc, subresourceRec, default_font.f_wb); #endif - for (n = fontMenu_font1; n <= fontMenu_lastBuiltin; ++n) + for (n = fontMenu_font1; n <= fontMenu_lastBuiltin; ++n) { MERGE_SUBFONT(xw->screen, subresourceRec, MenuFontName(n)); + } /* * Finally, copy the subresource data to the widget. */ - xw->misc.default_font = subresourceRec.default_font; + COPY_DEFAULT_FONTS(xw->misc, subresourceRec); + FREE_MENU_FONTS(xw->screen); COPY_MENU_FONTS(subresourceRec, xw->screen); + + FREE_STRING(screen->MenuFontName(fontMenu_default)); + FREE_STRING(screen->menu_font_names[0][fBold]); screen->MenuFontName(fontMenu_default) = x_strdup(xw->misc.default_font.f_n); screen->menu_font_names[0][fBold] = x_strdup(xw->misc.default_font.f_b); #if OPT_WIDE_CHARS + FREE_STRING(screen->menu_font_names[0][fWide]); + FREE_STRING(screen->menu_font_names[0][fWBold]); screen->menu_font_names[0][fWide] = x_strdup(xw->misc.default_font.f_w); screen->menu_font_names[0][fWBold] = x_strdup(xw->misc.default_font.f_wb); #endif + /* + * And remove our copies of strings. + */ + FREE_STRING(subresourceRec.default_font.f_n); + FREE_STRING(subresourceRec.default_font.f_b); +#if OPT_WIDE_CHARS + FREE_STRING(subresourceRec.default_font.f_w); + FREE_STRING(subresourceRec.default_font.f_wb); +#endif + for (n = fontMenu_font1; n <= fontMenu_lastBuiltin; ++n) { + FREE_STRING(subresourceRec.MenuFontName(n)); + } } else { TRACE(("...no resources found\n")); status = False; @@ -1661,8 +1889,9 @@ HandleLoadVTFonts(Widget w, int font_number = screen->menu_font_number; if (font_number > fontMenu_lastBuiltin) font_number = fontMenu_lastBuiltin; - for (n = 0; n < NMENUFONTS; ++n) + for (n = 0; n < NMENUFONTS; ++n) { screen->menu_font_sizes[n] = 0; + } SetVTFont(xw, font_number, True, ((font_number == fontMenu_default) ? &(xw->misc.default_font) @@ -1722,7 +1951,7 @@ xtermXftFirstChar(XftFont *xft) int i; first = FcCharSetFirstPage(xft->charset, map, &next); - for (i = 0; i < FC_CHARSET_MAP_SIZE; i++) + for (i = 0; i < FC_CHARSET_MAP_SIZE; i++) { if (map[i]) { FcChar32 bits = map[i]; first += (FcChar32) i *32; @@ -1732,6 +1961,7 @@ xtermXftFirstChar(XftFont *xft) } break; } + } return first; } @@ -1745,7 +1975,7 @@ xtermXftLastChar(XftFont *xft) while ((this = FcCharSetNextPage(xft->charset, map, &next)) != FC_CHARSET_DONE) last = this; last &= (FcChar32) ~ 0xff; - for (i = FC_CHARSET_MAP_SIZE - 1; i >= 0; i--) + for (i = FC_CHARSET_MAP_SIZE - 1; i >= 0; i--) { if (map[i]) { FcChar32 bits = map[i]; last += (FcChar32) i *32 + 31; @@ -1755,6 +1985,7 @@ xtermXftLastChar(XftFont *xft) } break; } + } return (long) last; } @@ -1841,7 +2072,7 @@ reportXftFonts(XtermWidget xw, FcChar32 ch; unsigned missing = 0; - printf("Loaded XftFonts(%s:%s)\n", name, tag); + printf("Loaded XftFonts(%s[%s])\n", name, tag); for (ch = first_char; ch <= last_char; ++ch) { if (xtermXftMissing(xw, fp, ch)) { @@ -2109,6 +2340,16 @@ xtermComputeFontInfo(XtermWidget xw, XFT_SLANT, XftTypeInteger, XFT_SLANT_ITALIC, \ XFT_CHAR_WIDTH, XftTypeInteger, norm->max_advance_width +#if OPT_WIDE_ATTRS +#define HAVE_ITALICS 1 +#define FIND_ITALICS ((pat = XftNameParse(face_name)) != 0) +#elif OPT_ISO_COLORS +#define HAVE_ITALICS 1 +#define FIND_ITALICS (screen->italicULMode && (pat = XftNameParse(face_name)) != 0) +#else +#define HAVE_ITALICS 0 +#endif + if ((pat = XftNameParse(face_name)) != 0) { #define OPEN_XFT(tag) xtermOpenXft(xw, face_name, pat, tag) XftPatternBuild(pat, @@ -2122,16 +2363,15 @@ xtermComputeFontInfo(XtermWidget xw, (void *) 0); bold = OPEN_XFT("bold"); -#if OPT_ISO_COLORS - if (screen->italicULMode - && (pat = XftNameParse(face_name)) != 0) { +#if HAVE_ITALICS + if (FIND_ITALICS) { XftPatternBuild(pat, NormXftPattern, ItalXftPattern(norm), (void *) 0); ital = OPEN_XFT("italic"); } -#endif /* OPT_ISO_COLORS */ +#endif #undef OPEN_XFT /* @@ -2193,9 +2433,8 @@ xtermComputeFontInfo(XtermWidget xw, (void *) 0); wbold = OPEN_XFT("wide-bold"); -#if OPT_ISO_COLORS - if (screen->italicULMode - && (pat = XftNameParse(face_name)) != 0) { +#if HAVE_ITALICS + if (FIND_ITALICS) { XftPatternBuild(pat, WideXftPattern, ItalXftPattern(wnorm), @@ -2390,7 +2629,8 @@ xtermMissingChar(unsigned ch, XTermFonts * font) void xtermDrawBoxChar(XtermWidget xw, unsigned ch, - unsigned flags, + unsigned attr_flags, + unsigned draw_flags, GC gc, int x, int y, @@ -2575,8 +2815,10 @@ xtermDrawBoxChar(XtermWidget xw, CgsEnum cgsId = (ch == 2) ? gcDots : gcLine; VTwin *cgsWin = WhichVWin(screen); const short *p; - unsigned font_width = (unsigned) (((flags & DOUBLEWFONT) ? 2 : 1) * screen->fnt_wide); - unsigned font_height = (unsigned) (((flags & DOUBLEHFONT) ? 2 : 1) * screen->fnt_high); + unsigned font_width = (unsigned) (((draw_flags & DOUBLEWFONT) ? 2 : 1) + * screen->fnt_wide); + unsigned font_height = (unsigned) (((draw_flags & DOUBLEHFONT) ? 2 : 1) + * screen->fnt_high); if (cells > 1) font_width *= (unsigned) cells; @@ -2595,7 +2837,7 @@ xtermDrawBoxChar(XtermWidget xw, unsigned n; for (n = 1; n < 32; n++) { if (dec2ucs(n) == ch - && !((flags & BOLD) + && !((attr_flags & BOLD) ? IsXtermMissingChar(screen, n, &screen->fnts[fBold]) : IsXtermMissingChar(screen, n, &screen->fnts[fNorm]))) { TRACE(("...use xterm-style linedrawing\n")); @@ -2623,7 +2865,7 @@ xtermDrawBoxChar(XtermWidget xw, } gc2 = getCgsGC(xw, cgsWin, cgsId); - if (!(flags & NOBACKGROUND)) { + if (!(draw_flags & NOBACKGROUND)) { XFillRectangle(screen->display, VDrawable(screen), gc2, x, y, font_width, font_height); @@ -2635,7 +2877,7 @@ xtermDrawBoxChar(XtermWidget xw, gc2 = getCgsGC(xw, cgsWin, cgsId); XSetLineAttributes(screen->display, gc2, - (flags & BOLD) + (attr_flags & BOLD) ? ((font_height > 12) ? font_height / 12 : 1) @@ -3311,6 +3553,7 @@ SetVTFont(XtermWidget xw, || strcmp(screen->menu_font_names[which][name], myfonts.field)) { \ TRACE(("updating menu_font_names[%d][" #name "] to %s\n", \ which, myfonts.field)); \ + FREE_STRING(screen->menu_font_names[which][name]); \ screen->menu_font_names[which][name] = x_strdup(myfonts.field); \ } \ } @@ -3340,6 +3583,12 @@ SetVTFont(XtermWidget xw, doresize, oldFont); Bell(xw, XkbBI_MinorError, 0); } + FREE_FNAME(f_n); + FREE_FNAME(f_b); +#if OPT_WIDE_CHARS + FREE_FNAME(f_w); + FREE_FNAME(f_wb); +#endif } } else { Bell(xw, XkbBI_MinorError, 0); |