зеркало из https://github.com/github/putty.git
In the new unified font handling, my strategy so far for combining
client- and server-side fonts into a single namespace was mainly to hope there would naturally be no collisions, and to provide disambiguating "client:" and "server:" prefixes for manual use in emergencies. Jacob points out, however, that his system not only has a namespace clash but worse still the clash is at the name "fixed", which is our default font! So, modify my namespace policy to use the disambiguating prefixes everywhere by default, and use _unprefixed_ names only if the user types one in by hand. In particular, I've changed the keys used to store font names in Unix saved session files. Font names read from the new keys will be passed straight to the new unifont framework; font names read from the old keys will have "server:" prepended. So any existing configuration file for GTK1 PuTTY should now work reliably in GTK2 PuTTY and select the same font, even if that font is one on which your system (rather, your client+server combination) has a font namespace clash. [originally from svn r7973]
This commit is contained in:
Родитель
2503cd1861
Коммит
8ac9896853
131
unix/gtkfont.c
131
unix/gtkfont.c
|
@ -26,6 +26,10 @@
|
|||
/*
|
||||
* Future work:
|
||||
*
|
||||
* - it would be nice to have a display of the current font name,
|
||||
* and in particular whether it's client- or server-side,
|
||||
* during the progress of the font selector.
|
||||
*
|
||||
* - all the GDK font functions used in the x11font subclass are
|
||||
* deprecated, so one day they may go away. When this happens -
|
||||
* or before, if I'm feeling proactive - it oughtn't to be too
|
||||
|
@ -59,6 +63,8 @@
|
|||
#define FONTFLAG_SERVERALIAS 0x0004
|
||||
#define FONTFLAG_NONMONOSPACED 0x0008
|
||||
|
||||
#define FONTFLAG_SORT_MASK 0x0007 /* used to disambiguate font families */
|
||||
|
||||
typedef void (*fontsel_add_entry)(void *ctx, const char *realfontname,
|
||||
const char *family, const char *charset,
|
||||
const char *style, const char *stylekey,
|
||||
|
@ -78,7 +84,7 @@ struct unifont_vtable {
|
|||
void (*enum_fonts)(GtkWidget *widget,
|
||||
fontsel_add_entry callback, void *callback_ctx);
|
||||
char *(*canonify_fontname)(GtkWidget *widget, const char *name, int *size,
|
||||
int resolve_aliases);
|
||||
int *flags, int resolve_aliases);
|
||||
char *(*scale_fontname)(GtkWidget *widget, const char *name, int size);
|
||||
|
||||
/*
|
||||
|
@ -101,7 +107,8 @@ static void x11font_destroy(unifont *font);
|
|||
static void x11font_enum_fonts(GtkWidget *widget,
|
||||
fontsel_add_entry callback, void *callback_ctx);
|
||||
static char *x11font_canonify_fontname(GtkWidget *widget, const char *name,
|
||||
int *size, int resolve_aliases);
|
||||
int *size, int *flags,
|
||||
int resolve_aliases);
|
||||
static char *x11font_scale_fontname(GtkWidget *widget, const char *name,
|
||||
int size);
|
||||
|
||||
|
@ -144,7 +151,7 @@ static const struct unifont_vtable x11font_vtable = {
|
|||
x11font_enum_fonts,
|
||||
x11font_canonify_fontname,
|
||||
x11font_scale_fontname,
|
||||
"server"
|
||||
"server",
|
||||
};
|
||||
|
||||
char *x11_guess_derived_font_name(GdkFont *font, int bold, int wide)
|
||||
|
@ -617,7 +624,8 @@ static void x11font_enum_fonts(GtkWidget *widget,
|
|||
}
|
||||
|
||||
static char *x11font_canonify_fontname(GtkWidget *widget, const char *name,
|
||||
int *size, int resolve_aliases)
|
||||
int *size, int *flags,
|
||||
int resolve_aliases)
|
||||
{
|
||||
/*
|
||||
* When given an X11 font name to try to make sense of for a
|
||||
|
@ -654,6 +662,12 @@ static char *x11font_canonify_fontname(GtkWidget *widget, const char *name,
|
|||
if (XGetFontProperty(xfs, fontprop2, &fsize) && fsize > 0) {
|
||||
*size = fsize;
|
||||
gdk_font_unref(font);
|
||||
if (flags) {
|
||||
if (name[0] == '-' || resolve_aliases)
|
||||
*flags = FONTFLAG_SERVERSIDE;
|
||||
else
|
||||
*flags = FONTFLAG_SERVERALIAS;
|
||||
}
|
||||
return dupstr(name[0] == '-' || resolve_aliases ?
|
||||
newname : name);
|
||||
}
|
||||
|
@ -686,7 +700,8 @@ static void pangofont_destroy(unifont *font);
|
|||
static void pangofont_enum_fonts(GtkWidget *widget, fontsel_add_entry callback,
|
||||
void *callback_ctx);
|
||||
static char *pangofont_canonify_fontname(GtkWidget *widget, const char *name,
|
||||
int *size, int resolve_aliases);
|
||||
int *size, int *flags,
|
||||
int resolve_aliases);
|
||||
static char *pangofont_scale_fontname(GtkWidget *widget, const char *name,
|
||||
int size);
|
||||
|
||||
|
@ -714,7 +729,7 @@ static const struct unifont_vtable pangofont_vtable = {
|
|||
pangofont_enum_fonts,
|
||||
pangofont_canonify_fontname,
|
||||
pangofont_scale_fontname,
|
||||
"client"
|
||||
"client",
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1062,7 +1077,8 @@ static void pangofont_enum_fonts(GtkWidget *widget, fontsel_add_entry callback,
|
|||
}
|
||||
|
||||
static char *pangofont_canonify_fontname(GtkWidget *widget, const char *name,
|
||||
int *size, int resolve_aliases)
|
||||
int *size, int *flags,
|
||||
int resolve_aliases)
|
||||
{
|
||||
/*
|
||||
* When given a Pango font name to try to make sense of for a
|
||||
|
@ -1292,19 +1308,10 @@ struct fontinfo {
|
|||
const struct unifont_vtable *fontclass;
|
||||
};
|
||||
|
||||
static int fontinfo_realname_compare(void *av, void *bv)
|
||||
{
|
||||
fontinfo *a = (fontinfo *)av;
|
||||
fontinfo *b = (fontinfo *)bv;
|
||||
return g_strcasecmp(a->realname, b->realname);
|
||||
}
|
||||
|
||||
static int fontinfo_realname_find(void *av, void *bv)
|
||||
{
|
||||
const char *a = (const char *)av;
|
||||
fontinfo *b = (fontinfo *)bv;
|
||||
return g_strcasecmp(a, b->realname);
|
||||
}
|
||||
struct fontinfo_realname_find {
|
||||
const char *realname;
|
||||
int flags;
|
||||
};
|
||||
|
||||
static int strnullcasecmp(const char *a, const char *b)
|
||||
{
|
||||
|
@ -1329,6 +1336,34 @@ static int strnullcasecmp(const char *a, const char *b)
|
|||
return g_strcasecmp(a, b);
|
||||
}
|
||||
|
||||
static int fontinfo_realname_compare(void *av, void *bv)
|
||||
{
|
||||
fontinfo *a = (fontinfo *)av;
|
||||
fontinfo *b = (fontinfo *)bv;
|
||||
int i;
|
||||
|
||||
if ((i = strnullcasecmp(a->realname, b->realname)) != 0)
|
||||
return i;
|
||||
if ((a->flags & FONTFLAG_SORT_MASK) != (b->flags & FONTFLAG_SORT_MASK))
|
||||
return ((a->flags & FONTFLAG_SORT_MASK) <
|
||||
(b->flags & FONTFLAG_SORT_MASK) ? -1 : +1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fontinfo_realname_find(void *av, void *bv)
|
||||
{
|
||||
struct fontinfo_realname_find *a = (struct fontinfo_realname_find *)av;
|
||||
fontinfo *b = (fontinfo *)bv;
|
||||
int i;
|
||||
|
||||
if ((i = strnullcasecmp(a->realname, b->realname)) != 0)
|
||||
return i;
|
||||
if ((a->flags & FONTFLAG_SORT_MASK) != (b->flags & FONTFLAG_SORT_MASK))
|
||||
return ((a->flags & FONTFLAG_SORT_MASK) <
|
||||
(b->flags & FONTFLAG_SORT_MASK) ? -1 : +1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fontinfo_selorder_compare(void *av, void *bv)
|
||||
{
|
||||
fontinfo *a = (fontinfo *)av;
|
||||
|
@ -1336,6 +1371,13 @@ static int fontinfo_selorder_compare(void *av, void *bv)
|
|||
int i;
|
||||
if ((i = strnullcasecmp(a->family, b->family)) != 0)
|
||||
return i;
|
||||
/*
|
||||
* Font class comes immediately after family, so that fonts
|
||||
* from different classes with the same family
|
||||
*/
|
||||
if ((a->flags & FONTFLAG_SORT_MASK) != (b->flags & FONTFLAG_SORT_MASK))
|
||||
return ((a->flags & FONTFLAG_SORT_MASK) <
|
||||
(b->flags & FONTFLAG_SORT_MASK) ? -1 : +1);
|
||||
if ((i = strnullcasecmp(a->charset, b->charset)) != 0)
|
||||
return i;
|
||||
if ((i = strnullcasecmp(a->stylekey, b->stylekey)) != 0)
|
||||
|
@ -1354,6 +1396,7 @@ static void unifontsel_setup_familylist(unifontsel_internal *fs)
|
|||
GtkTreeIter iter;
|
||||
int i, listindex, minpos = -1, maxpos = -1;
|
||||
char *currfamily = NULL;
|
||||
int currflags = -1;
|
||||
fontinfo *info;
|
||||
|
||||
gtk_list_store_clear(fs->family_model);
|
||||
|
@ -1376,7 +1419,8 @@ static void unifontsel_setup_familylist(unifontsel_internal *fs)
|
|||
info->familyindex = -1;
|
||||
continue; /* we're filtering out this font */
|
||||
}
|
||||
if (!info || strnullcasecmp(currfamily, info->family)) {
|
||||
if (!info || strnullcasecmp(currfamily, info->family) ||
|
||||
currflags != (info->flags & FONTFLAG_SORT_MASK)) {
|
||||
/*
|
||||
* We've either finished a family, or started a new
|
||||
* one, or both.
|
||||
|
@ -1390,6 +1434,7 @@ static void unifontsel_setup_familylist(unifontsel_internal *fs)
|
|||
if (info) {
|
||||
minpos = i;
|
||||
currfamily = info->family;
|
||||
currflags = info->flags & FONTFLAG_SORT_MASK;
|
||||
}
|
||||
}
|
||||
if (!info)
|
||||
|
@ -1999,10 +2044,16 @@ static void alias_resolve(GtkTreeView *treeview, GtkTreePath *path,
|
|||
gtk_tree_model_get(GTK_TREE_MODEL(fs->family_model), &iter, 1,&minval, -1);
|
||||
info = (fontinfo *)index234(fs->fonts_by_selorder, minval);
|
||||
if (info) {
|
||||
int flags;
|
||||
struct fontinfo_realname_find f;
|
||||
|
||||
newname = info->fontclass->canonify_fontname
|
||||
(GTK_WIDGET(fs->u.window), info->realname, &newsize, TRUE);
|
||||
newinfo = find234(fs->fonts_by_realname, (char *)newname,
|
||||
fontinfo_realname_find);
|
||||
(GTK_WIDGET(fs->u.window), info->realname, &newsize, &flags, TRUE);
|
||||
|
||||
f.realname = newname;
|
||||
f.flags = flags;
|
||||
newinfo = find234(fs->fonts_by_realname, &f, fontinfo_realname_find);
|
||||
|
||||
sfree(newname);
|
||||
if (!newinfo)
|
||||
return; /* font name not in our index */
|
||||
|
@ -2359,7 +2410,7 @@ void unifontsel_destroy(unifontsel *fontsel)
|
|||
void unifontsel_set_name(unifontsel *fontsel, const char *fontname)
|
||||
{
|
||||
unifontsel_internal *fs = (unifontsel_internal *)fontsel;
|
||||
int i, start, end, size;
|
||||
int i, start, end, size, flags;
|
||||
const char *fontname2 = NULL;
|
||||
fontinfo *info;
|
||||
|
||||
|
@ -2367,7 +2418,7 @@ void unifontsel_set_name(unifontsel *fontsel, const char *fontname)
|
|||
* Provide a default if given an empty or null font name.
|
||||
*/
|
||||
if (!fontname || !*fontname)
|
||||
fontname = "fixed"; /* Pango zealots might prefer "Monospace 12" */
|
||||
fontname = "server:fixed";
|
||||
|
||||
/*
|
||||
* Call the canonify_fontname function.
|
||||
|
@ -2375,7 +2426,7 @@ void unifontsel_set_name(unifontsel *fontsel, const char *fontname)
|
|||
fontname = unifont_do_prefix(fontname, &start, &end);
|
||||
for (i = start; i < end; i++) {
|
||||
fontname2 = unifont_types[i]->canonify_fontname
|
||||
(GTK_WIDGET(fs->u.window), fontname, &size, FALSE);
|
||||
(GTK_WIDGET(fs->u.window), fontname, &size, &flags, FALSE);
|
||||
if (fontname2)
|
||||
break;
|
||||
}
|
||||
|
@ -2385,8 +2436,12 @@ void unifontsel_set_name(unifontsel *fontsel, const char *fontname)
|
|||
/*
|
||||
* Now look up the canonified font name in our index.
|
||||
*/
|
||||
info = find234(fs->fonts_by_realname, (char *)fontname2,
|
||||
fontinfo_realname_find);
|
||||
{
|
||||
struct fontinfo_realname_find f;
|
||||
f.realname = fontname2;
|
||||
f.flags = flags;
|
||||
info = find234(fs->fonts_by_realname, &f, fontinfo_realname_find);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we've found the font, and its size field is either
|
||||
|
@ -2395,8 +2450,11 @@ void unifontsel_set_name(unifontsel *fontsel, const char *fontname)
|
|||
* font name instead.
|
||||
*/
|
||||
if (!info || (info->size != size && info->size != 0)) {
|
||||
info = find234(fs->fonts_by_realname, (char *)fontname,
|
||||
fontinfo_realname_find);
|
||||
struct fontinfo_realname_find f;
|
||||
f.realname = fontname;
|
||||
f.flags = flags;
|
||||
|
||||
info = find234(fs->fonts_by_realname, &f, fontinfo_realname_find);
|
||||
if (!info || info->size != size)
|
||||
return; /* font name not in our index */
|
||||
}
|
||||
|
@ -2420,11 +2478,16 @@ char *unifontsel_get_name(unifontsel *fontsel)
|
|||
if (fs->selected->size == 0) {
|
||||
name = fs->selected->fontclass->scale_fontname
|
||||
(GTK_WIDGET(fs->u.window), fs->selected->realname, fs->selsize);
|
||||
if (name)
|
||||
return name;
|
||||
if (name) {
|
||||
char *ret = dupcat(fs->selected->fontclass->prefix, ":",
|
||||
name, NULL);
|
||||
sfree(name);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return dupstr(fs->selected->realname);
|
||||
return dupcat(fs->selected->fontclass->prefix, ":",
|
||||
fs->selected->realname, NULL);
|
||||
}
|
||||
|
||||
#endif /* GTK_CHECK_VERSION(2,0,0) */
|
||||
|
|
|
@ -134,7 +134,7 @@ FontSpec platform_default_fontspec(const char *name)
|
|||
{
|
||||
FontSpec ret;
|
||||
if (!strcmp(name, "Font"))
|
||||
strcpy(ret.name, "fixed");
|
||||
strcpy(ret.name, "server:fixed");
|
||||
else
|
||||
*ret.name = '\0';
|
||||
return ret;
|
||||
|
|
|
@ -362,7 +362,35 @@ int read_setting_i(void *handle, const char *key, int defvalue)
|
|||
|
||||
int read_setting_fontspec(void *handle, const char *name, FontSpec *result)
|
||||
{
|
||||
return !!read_setting_s(handle, name, result->name, sizeof(result->name));
|
||||
/*
|
||||
* In GTK1-only PuTTY, we used to store font names simply as a
|
||||
* valid X font description string (logical or alias), under a
|
||||
* bare key such as "Font".
|
||||
*
|
||||
* In GTK2 PuTTY, we have a prefix system where "client:"
|
||||
* indicates a Pango font and "server:" an X one; existing
|
||||
* configuration needs to be reinterpreted as having the
|
||||
* "server:" prefix, so we change the storage key from the
|
||||
* provided name string (e.g. "Font") to a suffixed one
|
||||
* ("FontName").
|
||||
*/
|
||||
char *suffname = dupcat(name, "Name", NULL);
|
||||
if (read_setting_s(handle, suffname, result->name, sizeof(result->name))) {
|
||||
sfree(suffname);
|
||||
return TRUE; /* got new-style name */
|
||||
}
|
||||
sfree(suffname);
|
||||
|
||||
/* Fall back to old-style name. */
|
||||
memcpy(result->name, "server:", 7);
|
||||
if (!read_setting_s(handle, name,
|
||||
result->name + 7, sizeof(result->name) - 7) ||
|
||||
!result->name[7]) {
|
||||
result->name[0] = '\0';
|
||||
return FALSE;
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
int read_setting_filename(void *handle, const char *name, Filename *result)
|
||||
{
|
||||
|
@ -371,7 +399,14 @@ int read_setting_filename(void *handle, const char *name, Filename *result)
|
|||
|
||||
void write_setting_fontspec(void *handle, const char *name, FontSpec result)
|
||||
{
|
||||
write_setting_s(handle, name, result.name);
|
||||
/*
|
||||
* read_setting_fontspec had to handle two cases, but when
|
||||
* writing our settings back out we simply always generate the
|
||||
* new-style name.
|
||||
*/
|
||||
char *suffname = dupcat(name, "Name", NULL);
|
||||
write_setting_s(handle, suffname, result.name);
|
||||
sfree(suffname);
|
||||
}
|
||||
void write_setting_filename(void *handle, const char *name, Filename result)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче