X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/0affbab4b5e2a5fac19b261c4f74ea868f138340..038ec85e825fc940c1387f64a88ae73b75f6822b:/unix/gtkfont.c diff --git a/unix/gtkfont.c b/unix/gtkfont.c index e80d7acb..d241db0e 100644 --- a/unix/gtkfont.c +++ b/unix/gtkfont.c @@ -41,6 +41,11 @@ * I haven't the energy. */ +#if !GLIB_CHECK_VERSION(1,3,7) +#define g_ascii_strcasecmp g_strcasecmp +#define g_ascii_strncasecmp g_strncasecmp +#endif + /* * Ad-hoc vtable mechanism to allow font structures to be * polymorphic. @@ -186,8 +191,10 @@ static char *x11_guess_derived_font_name(XFontStruct *xfs, int bold, int wide) p++; } - if (nstr < lenof(strings)) + if (nstr < lenof(strings)) { + sfree(dupname); return NULL; /* XLFD was malformed */ + } if (bold) strings[2] = "bold"; @@ -280,6 +287,9 @@ static int x11_font_has_glyph(XFontStruct *xfs, int byte1, int byte2) (xfs->max_char_or_byte2 - xfs->min_char_or_byte2 + 1))); } + if (!xfs->per_char) /* per_char NULL => everything in range exists */ + return TRUE; + return (xfs->per_char[index].ascent + xfs->per_char[index].descent > 0 || xfs->per_char[index].width > 0); } @@ -422,10 +432,11 @@ static int x11font_has_glyph(unifont *font, wchar_t glyph) char sbstring[2]; int sblen = wc_to_mb(xfont->real_charset, 0, &glyph, 1, sbstring, 2, "", NULL, NULL); - if (!sbstring[0]) + if (sblen == 0 || !sbstring[0]) return FALSE; /* not even in the charset */ - return x11_font_has_glyph(xfont->fonts[0], 0, sbstring[0]); + return x11_font_has_glyph(xfont->fonts[0], 0, + (unsigned char)sbstring[0]); } } @@ -657,21 +668,21 @@ static void x11font_enum_fonts(GtkWidget *widget, style = p; p += sprintf(p, "%s", components[2][0] ? components[2] : "regular"); - if (!g_strcasecmp(components[3], "i")) + if (!g_ascii_strcasecmp(components[3], "i")) p += sprintf(p, " italic"); - else if (!g_strcasecmp(components[3], "o")) + else if (!g_ascii_strcasecmp(components[3], "o")) p += sprintf(p, " oblique"); - else if (!g_strcasecmp(components[3], "ri")) + else if (!g_ascii_strcasecmp(components[3], "ri")) p += sprintf(p, " reverse italic"); - else if (!g_strcasecmp(components[3], "ro")) + else if (!g_ascii_strcasecmp(components[3], "ro")) p += sprintf(p, " reverse oblique"); - else if (!g_strcasecmp(components[3], "ot")) + else if (!g_ascii_strcasecmp(components[3], "ot")) p += sprintf(p, " other-slant"); - if (components[4][0] && g_strcasecmp(components[4], "normal")) + if (components[4][0] && g_ascii_strcasecmp(components[4], "normal")) p += sprintf(p, " %s", components[4]); - if (!g_strcasecmp(components[10], "m")) + if (!g_ascii_strcasecmp(components[10], "m")) p += sprintf(p, " [M]"); - if (!g_strcasecmp(components[10], "c")) + if (!g_ascii_strcasecmp(components[10], "c")) p += sprintf(p, " [C]"); if (components[5][0]) p += sprintf(p, " %s", components[5]); @@ -683,23 +694,23 @@ static void x11font_enum_fonts(GtkWidget *widget, */ p++; stylekey = p; - if (!g_strcasecmp(components[2], "medium") || - !g_strcasecmp(components[2], "regular") || - !g_strcasecmp(components[2], "normal") || - !g_strcasecmp(components[2], "book")) + if (!g_ascii_strcasecmp(components[2], "medium") || + !g_ascii_strcasecmp(components[2], "regular") || + !g_ascii_strcasecmp(components[2], "normal") || + !g_ascii_strcasecmp(components[2], "book")) weightkey = 0; - else if (!g_strncasecmp(components[2], "demi", 4) || - !g_strncasecmp(components[2], "semi", 4)) + else if (!g_ascii_strncasecmp(components[2], "demi", 4) || + !g_ascii_strncasecmp(components[2], "semi", 4)) weightkey = 1; else weightkey = 2; - if (!g_strcasecmp(components[3], "r")) + if (!g_ascii_strcasecmp(components[3], "r")) slantkey = 0; - else if (!g_strncasecmp(components[3], "r", 1)) + else if (!g_ascii_strncasecmp(components[3], "r", 1)) slantkey = 2; else slantkey = 1; - if (!g_strcasecmp(components[4], "normal")) + if (!g_ascii_strcasecmp(components[4], "normal")) setwidthkey = 0; else setwidthkey = 1; @@ -911,8 +922,8 @@ static int pangofont_check_desc_makes_sense(PangoContext *ctx, matched = FALSE; for (i = 0; i < nfamilies; i++) { - if (!g_strcasecmp(pango_font_family_get_name(families[i]), - pango_font_description_get_family(desc))) { + if (!g_ascii_strcasecmp(pango_font_family_get_name(families[i]), + pango_font_description_get_family(desc))) { matched = TRUE; break; } @@ -1114,34 +1125,42 @@ static void pangofont_draw_text(GdkDrawable *target, GdkGC *gc, unifont *font, clen++; n = 1; - /* - * See if that character has the width we expect. - */ - pango_layout_set_text(layout, utfptr, clen); - pango_layout_get_pixel_extents(layout, NULL, &rect); + /* + * If it's a right-to-left character, we must display it on + * its own, to stop Pango helpfully re-reversing our already + * reversed text. + */ + if (!is_rtl(string[0])) { - if (rect.width == cellwidth) { - /* - * Try extracting more characters, for as long as they - * stay well-behaved. - */ - while (clen < utflen) { - int oldclen = clen; - clen++; /* skip UTF-8 introducer byte */ - while (clen < utflen && - (unsigned char)utfptr[clen] >= 0x80 && - (unsigned char)utfptr[clen] < 0xC0) - clen++; - n++; - pango_layout_set_text(layout, utfptr, clen); - pango_layout_get_pixel_extents(layout, NULL, &rect); - if (rect.width != n * cellwidth) { - clen = oldclen; - n--; - break; - } - } - } + /* + * See if that character has the width we expect. + */ + pango_layout_set_text(layout, utfptr, clen); + pango_layout_get_pixel_extents(layout, NULL, &rect); + + if (rect.width == cellwidth) { + /* + * Try extracting more characters, for as long as they + * stay well-behaved. + */ + while (clen < utflen) { + int oldclen = clen; + clen++; /* skip UTF-8 introducer byte */ + while (clen < utflen && + (unsigned char)utfptr[clen] >= 0x80 && + (unsigned char)utfptr[clen] < 0xC0) + clen++; + n++; + pango_layout_set_text(layout, utfptr, clen); + pango_layout_get_pixel_extents(layout, NULL, &rect); + if (rect.width != n * cellwidth) { + clen = oldclen; + n--; + break; + } + } + } + } pango_layout_set_text(layout, utfptr, clen); pango_layout_get_pixel_extents(layout, NULL, &rect); @@ -1153,6 +1172,7 @@ static void pangofont_draw_text(GdkDrawable *target, GdkGC *gc, unifont *font, utflen -= clen; utfptr += clen; + string += n; x += n * cellwidth; } @@ -1554,6 +1574,7 @@ unifont *multifont_create(GtkWidget *widget, const char *name, if (!font) return NULL; + fallback = NULL; if (font->want_fallback) { for (i = 0; i < lenof(unifont_types); i++) { if (unifont_types[i]->create_fallback) { @@ -1699,7 +1720,7 @@ static int strnullcasecmp(const char *a, const char *b) /* * Otherwise, ordinary strcasecmp. */ - return g_strcasecmp(a, b); + return g_ascii_strcasecmp(a, b); } static int fontinfo_realname_compare(void *av, void *bv) @@ -2269,6 +2290,8 @@ static fontinfo *update_for_intended_size(unifontsel_internal *fs, */ below = findrelpos234(fs->fonts_by_selorder, &info2, NULL, REL234_LE, &pos); + if (!below) + pos = -1; above = index234(fs->fonts_by_selorder, pos+1); /* @@ -2276,7 +2299,7 @@ static fontinfo *update_for_intended_size(unifontsel_internal *fs, * case. If we have, it'll be in `below' and not `above', * because we did a REL234_LE rather than REL234_LT search. */ - if (!fontinfo_selorder_compare(&info2, below)) + if (below && !fontinfo_selorder_compare(&info2, below)) return below; /*