summaryrefslogtreecommitdiff
path: root/app/xterm/fontutils.c
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2014-07-14 08:30:12 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2014-07-14 08:30:12 +0000
commit6518ce5cf01755374e22ff2d69aa1ee0e0a4aeb9 (patch)
treea9709c5164f467c00c8b90d524461ad512e62b36 /app/xterm/fontutils.c
parent8126a298d120522d6d2e12e1070085274eee8206 (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.c453
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);