mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-04-17 19:18:06 -05:00
When the user switches between fonts using the font family or style
selectors, preserve their most recent size selection as faithfully as possible. We do this by having a secondary size variable indicating what they _intend_, so we can come back to their intended size even after going through a font which doesn't include it. [originally from svn r7947]
This commit is contained in:
parent
d173eb52ea
commit
6e6eae2506
146
unix/gtkfont.c
146
unix/gtkfont.c
@ -27,20 +27,19 @@
|
|||||||
* TODO on fontsel
|
* TODO on fontsel
|
||||||
* ---------------
|
* ---------------
|
||||||
*
|
*
|
||||||
|
* - add a third line of sample text containing digits and punct
|
||||||
|
*
|
||||||
|
* - start drawing X fonts one character at a time, at least if
|
||||||
|
* they're not fixed-width? Now we have that helpful pangram,
|
||||||
|
* we should make it work for everyone.
|
||||||
|
*
|
||||||
* - think about points versus pixels, harder than I already have
|
* - think about points versus pixels, harder than I already have
|
||||||
*
|
*
|
||||||
* - work out why the list boxes don't go all the way to the RHS
|
|
||||||
* of the dialog box
|
|
||||||
*
|
|
||||||
* - consistency and updating issues:
|
|
||||||
* + we should attempt to preserve font size when switching
|
|
||||||
* font family and style (it's currently OK as long as we're
|
|
||||||
* moving between scalable fonts but falls down badly
|
|
||||||
* otherwise)
|
|
||||||
*
|
|
||||||
* - generalised style and padding polish
|
* - generalised style and padding polish
|
||||||
* + gtk_scrolled_window_set_shadow_type(foo, GTK_SHADOW_IN);
|
* + gtk_scrolled_window_set_shadow_type(foo, GTK_SHADOW_IN);
|
||||||
* might be worth considering
|
* might be worth considering
|
||||||
|
* + work out why the list boxes don't go all the way to the
|
||||||
|
* RHS of the dialog box
|
||||||
*
|
*
|
||||||
* - big testing and shakedown!
|
* - big testing and shakedown!
|
||||||
*/
|
*/
|
||||||
@ -1169,7 +1168,7 @@ typedef struct unifontsel_internal {
|
|||||||
int filter_flags;
|
int filter_flags;
|
||||||
tree234 *fonts_by_realname, *fonts_by_selorder;
|
tree234 *fonts_by_realname, *fonts_by_selorder;
|
||||||
fontinfo *selected;
|
fontinfo *selected;
|
||||||
int selsize;
|
int selsize, intendedsize;
|
||||||
int inhibit_response; /* inhibit callbacks when we change GUI controls */
|
int inhibit_response; /* inhibit callbacks when we change GUI controls */
|
||||||
} unifontsel_internal;
|
} unifontsel_internal;
|
||||||
|
|
||||||
@ -1445,7 +1444,7 @@ static void unifontsel_draw_preview_text(unifontsel_internal *fs)
|
|||||||
font = info->fontclass->create(GTK_WIDGET(fs->u.window),
|
font = info->fontclass->create(GTK_WIDGET(fs->u.window),
|
||||||
sizename ? sizename : info->realname,
|
sizename ? sizename : info->realname,
|
||||||
FALSE, FALSE, 0, 0);
|
FALSE, FALSE, 0, 0);
|
||||||
if (font && fs->preview_pixmap) {
|
if (fs->preview_pixmap) {
|
||||||
GdkGC *gc = gdk_gc_new(fs->preview_pixmap);
|
GdkGC *gc = gdk_gc_new(fs->preview_pixmap);
|
||||||
gdk_gc_set_foreground(gc, &fs->preview_bg);
|
gdk_gc_set_foreground(gc, &fs->preview_bg);
|
||||||
gdk_draw_rectangle(fs->preview_pixmap, gc, 1, 0, 0,
|
gdk_draw_rectangle(fs->preview_pixmap, gc, 1, 0, 0,
|
||||||
@ -1471,25 +1470,28 @@ static void unifontsel_draw_preview_text(unifontsel_internal *fs)
|
|||||||
* effort of selecting their font and _then_ realise it
|
* effort of selecting their font and _then_ realise it
|
||||||
* was a mistake.
|
* was a mistake.
|
||||||
*/
|
*/
|
||||||
info->fontclass->draw_text(fs->preview_pixmap, gc, font,
|
if (font) {
|
||||||
0, font->ascent,
|
info->fontclass->draw_text(fs->preview_pixmap, gc, font,
|
||||||
"bankrupt jilted showmen quiz convex fogey",
|
0, font->ascent,
|
||||||
41, FALSE, FALSE, font->width);
|
"bankrupt jilted showmen quiz convex fogey",
|
||||||
info->fontclass->draw_text(fs->preview_pixmap, gc, font,
|
41, FALSE, FALSE, font->width);
|
||||||
0, font->ascent + font->height,
|
info->fontclass->draw_text(fs->preview_pixmap, gc, font,
|
||||||
"BANKRUPT JILTED SHOWMEN QUIZ CONVEX FOGEY",
|
0, font->ascent + font->height,
|
||||||
41, FALSE, FALSE, font->width);
|
"BANKRUPT JILTED SHOWMEN QUIZ CONVEX FOGEY",
|
||||||
|
41, FALSE, FALSE, font->width);
|
||||||
|
}
|
||||||
gdk_gc_unref(gc);
|
gdk_gc_unref(gc);
|
||||||
gdk_window_invalidate_rect(fs->preview_area->window, NULL, FALSE);
|
gdk_window_invalidate_rect(fs->preview_area->window, NULL, FALSE);
|
||||||
}
|
}
|
||||||
|
if (font)
|
||||||
info->fontclass->destroy(font);
|
info->fontclass->destroy(font);
|
||||||
|
|
||||||
sfree(sizename);
|
sfree(sizename);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unifontsel_select_font(unifontsel_internal *fs,
|
static void unifontsel_select_font(unifontsel_internal *fs,
|
||||||
fontinfo *info, int size, int leftlist)
|
fontinfo *info, int size, int leftlist,
|
||||||
|
int size_is_explicit)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
int minval, maxval;
|
int minval, maxval;
|
||||||
@ -1500,6 +1502,8 @@ static void unifontsel_select_font(unifontsel_internal *fs,
|
|||||||
|
|
||||||
fs->selected = info;
|
fs->selected = info;
|
||||||
fs->selsize = size;
|
fs->selsize = size;
|
||||||
|
if (size_is_explicit)
|
||||||
|
fs->intendedsize = size;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find the index of this fontinfo in the selorder list.
|
* Find the index of this fontinfo in the selorder list.
|
||||||
@ -1701,6 +1705,79 @@ static void unifontsel_add_entry(void *ctx, const char *realfontname,
|
|||||||
add234(fs->fonts_by_selorder, info);
|
add234(fs->fonts_by_selorder, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fontinfo *update_for_intended_size(unifontsel_internal *fs,
|
||||||
|
fontinfo *info)
|
||||||
|
{
|
||||||
|
fontinfo info2, *below, *above;
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the info structure. This doesn't copy its dynamic
|
||||||
|
* string fields, but that's unimportant because all we're
|
||||||
|
* going to do is to adjust the size field and use it in one
|
||||||
|
* tree search.
|
||||||
|
*/
|
||||||
|
info2 = *info;
|
||||||
|
info2.size = fs->intendedsize;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Search in the tree to find the fontinfo structure which
|
||||||
|
* best approximates the size the user last requested.
|
||||||
|
*/
|
||||||
|
below = findrelpos234(fs->fonts_by_selorder, &info2, NULL,
|
||||||
|
REL234_LE, &pos);
|
||||||
|
above = index234(fs->fonts_by_selorder, pos+1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See if we've found it exactly, which is an easy special
|
||||||
|
* 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))
|
||||||
|
return below;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now we've either found two suitable fonts, one smaller and
|
||||||
|
* one larger, or we're at one or other extreme end of the
|
||||||
|
* scale. Find out which, by NULLing out either of below and
|
||||||
|
* above if it differs from this one in any respect but size
|
||||||
|
* (and the disambiguating index field). Bear in mind, also,
|
||||||
|
* that either one might _already_ be NULL if we're at the
|
||||||
|
* extreme ends of the font list.
|
||||||
|
*/
|
||||||
|
if (below) {
|
||||||
|
info2.size = below->size;
|
||||||
|
info2.index = below->index;
|
||||||
|
if (fontinfo_selorder_compare(&info2, below))
|
||||||
|
below = NULL;
|
||||||
|
}
|
||||||
|
if (above) {
|
||||||
|
info2.size = above->size;
|
||||||
|
info2.index = above->index;
|
||||||
|
if (fontinfo_selorder_compare(&info2, above))
|
||||||
|
above = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now return whichever of above and below is non-NULL, if
|
||||||
|
* that's unambiguous.
|
||||||
|
*/
|
||||||
|
if (!above)
|
||||||
|
return below;
|
||||||
|
if (!below)
|
||||||
|
return above;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* And now we really do have to make a choice about whether to
|
||||||
|
* round up or down. We'll do it by rounding to nearest,
|
||||||
|
* breaking ties by rounding up.
|
||||||
|
*/
|
||||||
|
if (above->size - fs->intendedsize <= fs->intendedsize - below->size)
|
||||||
|
return above;
|
||||||
|
else
|
||||||
|
return below;
|
||||||
|
}
|
||||||
|
|
||||||
static void family_changed(GtkTreeSelection *treeselection, gpointer data)
|
static void family_changed(GtkTreeSelection *treeselection, gpointer data)
|
||||||
{
|
{
|
||||||
unifontsel_internal *fs = (unifontsel_internal *)data;
|
unifontsel_internal *fs = (unifontsel_internal *)data;
|
||||||
@ -1717,7 +1794,13 @@ static void family_changed(GtkTreeSelection *treeselection, gpointer data)
|
|||||||
|
|
||||||
gtk_tree_model_get(treemodel, &treeiter, 1, &minval, -1);
|
gtk_tree_model_get(treemodel, &treeiter, 1, &minval, -1);
|
||||||
info = (fontinfo *)index234(fs->fonts_by_selorder, minval);
|
info = (fontinfo *)index234(fs->fonts_by_selorder, minval);
|
||||||
unifontsel_select_font(fs, info, info->size ? info->size : fs->selsize, 1);
|
info = update_for_intended_size(fs, info);
|
||||||
|
if (!info)
|
||||||
|
return; /* _shouldn't_ happen unless font list is completely funted */
|
||||||
|
if (!info->size)
|
||||||
|
fs->selsize = fs->intendedsize; /* font is scalable */
|
||||||
|
unifontsel_select_font(fs, info, info->size ? info->size : fs->selsize,
|
||||||
|
1, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void style_changed(GtkTreeSelection *treeselection, gpointer data)
|
static void style_changed(GtkTreeSelection *treeselection, gpointer data)
|
||||||
@ -1738,7 +1821,13 @@ static void style_changed(GtkTreeSelection *treeselection, gpointer data)
|
|||||||
if (minval < 0)
|
if (minval < 0)
|
||||||
return; /* somehow a charset heading got clicked */
|
return; /* somehow a charset heading got clicked */
|
||||||
info = (fontinfo *)index234(fs->fonts_by_selorder, minval);
|
info = (fontinfo *)index234(fs->fonts_by_selorder, minval);
|
||||||
unifontsel_select_font(fs, info, info->size ? info->size : fs->selsize, 2);
|
info = update_for_intended_size(fs, info);
|
||||||
|
if (!info)
|
||||||
|
return; /* _shouldn't_ happen unless font list is completely funted */
|
||||||
|
if (!info->size)
|
||||||
|
fs->selsize = fs->intendedsize; /* font is scalable */
|
||||||
|
unifontsel_select_font(fs, info, info->size ? info->size : fs->selsize,
|
||||||
|
2, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void size_changed(GtkTreeSelection *treeselection, gpointer data)
|
static void size_changed(GtkTreeSelection *treeselection, gpointer data)
|
||||||
@ -1757,7 +1846,7 @@ static void size_changed(GtkTreeSelection *treeselection, gpointer data)
|
|||||||
|
|
||||||
gtk_tree_model_get(treemodel, &treeiter, 1, &minval, 2, &size, -1);
|
gtk_tree_model_get(treemodel, &treeiter, 1, &minval, 2, &size, -1);
|
||||||
info = (fontinfo *)index234(fs->fonts_by_selorder, minval);
|
info = (fontinfo *)index234(fs->fonts_by_selorder, minval);
|
||||||
unifontsel_select_font(fs, info, info->size ? info->size : size, 3);
|
unifontsel_select_font(fs, info, info->size ? info->size : size, 3, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void size_entry_changed(GtkEditable *ed, gpointer data)
|
static void size_entry_changed(GtkEditable *ed, gpointer data)
|
||||||
@ -1774,7 +1863,7 @@ static void size_entry_changed(GtkEditable *ed, gpointer data)
|
|||||||
|
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
assert(fs->selected->size == 0);
|
assert(fs->selected->size == 0);
|
||||||
unifontsel_select_font(fs, fs->selected, size, 3);
|
unifontsel_select_font(fs, fs->selected, size, 3, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1804,7 +1893,8 @@ static void alias_resolve(GtkTreeView *treeview, GtkTreePath *path,
|
|||||||
if (newinfo == info)
|
if (newinfo == info)
|
||||||
return; /* didn't change under canonification => not an alias */
|
return; /* didn't change under canonification => not an alias */
|
||||||
unifontsel_select_font(fs, newinfo,
|
unifontsel_select_font(fs, newinfo,
|
||||||
newinfo->size ? newinfo->size : newsize, 1);
|
newinfo->size ? newinfo->size : newsize,
|
||||||
|
1, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2170,7 +2260,7 @@ void unifontsel_set_name(unifontsel *fontsel, const char *fontname)
|
|||||||
* know everything we need to fill in all the fields in the
|
* know everything we need to fill in all the fields in the
|
||||||
* dialog.
|
* dialog.
|
||||||
*/
|
*/
|
||||||
unifontsel_select_font(fs, info, size, 0);
|
unifontsel_select_font(fs, info, size, 0, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *unifontsel_get_name(unifontsel *fontsel)
|
char *unifontsel_get_name(unifontsel *fontsel)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user