From ae62eaeb01088430162fa96e8cca35f721ff376d Mon Sep 17 00:00:00 2001 From: simon Date: Sat, 1 Oct 2011 17:38:59 +0000 Subject: [PATCH] Change the semantics of 'FontSpec' so that it's a dynamically allocated type. The main reason for this is to stop it from taking up a fixed large amount of space in every 'struct value' subunion in conf.c, although that makes little difference so far because Filename is still doing the same thing (and is therefore next on my list). However, the removal of its arbitrary length limit is not to be sneezed at. git-svn-id: svn://svn.tartarus.org/sgt/putty@9314 cda61777-01e9-0310-a592-d414129be87e --- conf.c | 28 ++++++++++++++-------------- config.c | 9 ++++----- dialog.h | 4 ++-- putty.h | 21 +++++++++++++++++++-- settings.c | 17 +++++++++-------- storage.h | 4 ++-- unix/gtkdlg.c | 10 ++++------ unix/gtkwin.c | 40 +++++++++++++++++++--------------------- unix/unix.h | 3 ++- unix/uxmisc.c | 32 ++++++++++++++++++++++++++++++++ unix/uxplink.c | 6 ++---- unix/uxsftp.c | 6 ++---- unix/uxstore.c | 21 ++++++++++----------- windows/winctrls.c | 53 ++++++++++++++++++++++++++--------------------------- windows/windefs.c | 16 +++++----------- windows/window.c | 2 +- windows/winmisc.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ windows/winstore.c | 35 ++++++++++++++++------------------- windows/winstuff.h | 4 +++- 19 files changed, 220 insertions(+), 139 deletions(-) diff --git a/conf.c b/conf.c index 32684499..e3ce258f 100644 --- a/conf.c +++ b/conf.c @@ -44,7 +44,7 @@ struct value { int intval; char *stringval; Filename fileval; - FontSpec fontval; + FontSpec *fontval; } u; }; @@ -125,6 +125,8 @@ static void free_value(struct value *val, int type) { if (type == TYPE_STR) sfree(val->u.stringval); + else if (type == TYPE_FONT) + fontspec_free(val->u.fontval); } /* @@ -144,7 +146,7 @@ static void copy_value(struct value *to, struct value *from, int type) to->u.fileval = from->u.fileval; break; case TYPE_FONT: - to->u.fontval = from->u.fontval; + to->u.fontval = fontspec_copy(from->u.fontval); break; } } @@ -343,7 +345,7 @@ FontSpec *conf_get_fontspec(Conf *conf, int primary) key.primary = primary; entry = find234(conf->tree, &key, NULL); assert(entry); - return &entry->value.u.fontval; + return entry->value.u.fontval; } void conf_set_int(Conf *conf, int primary, int value) @@ -427,7 +429,7 @@ void conf_set_fontspec(Conf *conf, int primary, const FontSpec *value) assert(subkeytypes[primary] == TYPE_NONE); assert(valuetypes[primary] == TYPE_FONT); entry->key.primary = primary; - entry->value.u.fontval = *value; /* structure copy */ + entry->value.u.fontval = fontspec_copy(value); conf_insert(conf, entry); } @@ -458,7 +460,7 @@ int conf_serialised_size(Conf *conf) size += sizeof(entry->value.u.fileval); break; case TYPE_FONT: - size += sizeof(entry->value.u.fontval); + size += fontspec_serialise(entry->value.u.fontval, NULL); break; } } @@ -507,9 +509,7 @@ void conf_serialise(Conf *conf, void *vdata) data += sizeof(entry->value.u.fileval); break; case TYPE_FONT: - memcpy(data, &entry->value.u.fontval, - sizeof(entry->value.u.fontval)); - data += sizeof(entry->value.u.fontval); + data += fontspec_serialise(entry->value.u.fontval, data); break; } } @@ -522,7 +522,7 @@ int conf_deserialise(Conf *conf, void *vdata, int maxsize) unsigned char *data = (unsigned char *)vdata; unsigned char *start = data; struct conf_entry *entry; - int primary; + int primary, used; unsigned char *zero; while (maxsize >= 4) { @@ -592,16 +592,16 @@ int conf_deserialise(Conf *conf, void *vdata, int maxsize) maxsize -= sizeof(entry->value.u.fileval); break; case TYPE_FONT: - if (maxsize < sizeof(entry->value.u.fontval)) { + entry->value.u.fontval = + fontspec_deserialise(data, maxsize, &used); + if (!entry->value.u.fontval) { if (subkeytypes[entry->key.primary] == TYPE_STR) sfree(entry->key.secondary.s); sfree(entry); goto done; } - memcpy(&entry->value.u.fontval, data, - sizeof(entry->value.u.fontval)); - data += sizeof(entry->value.u.fontval); - maxsize -= sizeof(entry->value.u.fontval); + data += used; + maxsize -= used; break; } conf_insert(conf, entry); diff --git a/config.c b/config.c index a03116b9..a7236d19 100644 --- a/config.c +++ b/config.c @@ -147,12 +147,11 @@ void conf_fontsel_handler(union control *ctrl, void *dlg, Conf *conf = (Conf *)data; if (event == EVENT_REFRESH) { - dlg_fontsel_set(ctrl, dlg, *conf_get_fontspec(conf, key)); + dlg_fontsel_set(ctrl, dlg, conf_get_fontspec(conf, key)); } else if (event == EVENT_VALCHANGE) { - FontSpec fontspec; - dlg_fontsel_get(ctrl, dlg, &fontspec); - conf_set_fontspec(conf, key, &fontspec); - /* If FontSpecs ever become dynamic, free this one. */ + FontSpec *fontspec = dlg_fontsel_get(ctrl, dlg); + conf_set_fontspec(conf, key, fontspec); + fontspec_free(fontspec); } } diff --git a/dialog.h b/dialog.h index fb89b6bb..eb7ce0e9 100644 --- a/dialog.h +++ b/dialog.h @@ -567,8 +567,8 @@ void dlg_listbox_select(union control *ctrl, void *dlg, int index); void dlg_text_set(union control *ctrl, void *dlg, char const *text); void dlg_filesel_set(union control *ctrl, void *dlg, Filename fn); void dlg_filesel_get(union control *ctrl, void *dlg, Filename *fn); -void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec fn); -void dlg_fontsel_get(union control *ctrl, void *dlg, FontSpec *fn); +void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec *fn); +FontSpec *dlg_fontsel_get(union control *ctrl, void *dlg); /* * Bracketing a large set of updates in these two functions will * cause the front end (if possible) to delay updating the screen diff --git a/putty.h b/putty.h index 377bf6b5..b1c30c8b 100644 --- a/putty.h +++ b/putty.h @@ -859,7 +859,7 @@ int conf_get_int_int(Conf *conf, int key, int subkey); char *conf_get_str(Conf *conf, int key); /* result still owned by conf */ char *conf_get_str_str(Conf *conf, int key, const char *subkey); Filename *conf_get_filename(Conf *conf, int key); -FontSpec *conf_get_fontspec(Conf *conf, int key); +FontSpec *conf_get_fontspec(Conf *conf, int key); /* still owned by conf */ /* Optional accessor function: return NULL if key does not exist. */ char *conf_get_str_str_opt(Conf *conf, int key, const char *subkey); /* Accessor function to step through a string-subkeyed list. @@ -884,6 +884,20 @@ void conf_serialise(Conf *conf, void *data); int conf_deserialise(Conf *conf, void *data, int maxsize);/*returns size used*/ /* + * Functions to copy, free, serialise and deserialise FontSpecs. + * Provided per-platform, to go with the platform's idea of a + * FontSpec's contents. + * + * fontspec_serialise returns the number of bytes written, and can + * handle data==NULL without crashing. So you can call it once to find + * out a size, then again once you've allocated a buffer. + */ +FontSpec *fontspec_copy(const FontSpec *f); +void fontspec_free(FontSpec *f); +int fontspec_serialise(FontSpec *f, void *data); +FontSpec *fontspec_deserialise(void *data, int maxsize, int *used); + +/* * Exports from noise.c. */ void noise_get_heavy(void (*func) (void *, int)); @@ -917,11 +931,14 @@ void registry_cleanup(void); * function is perfectly all right returning NULL, of course. The * Filename and FontSpec functions are _not allowed_ to fail to * return, since these defaults _must_ be per-platform.) + * + * The 'FontSpec *' returned by platform_default_fontspec has + * ownership transferred to the caller, and must be freed. */ char *platform_default_s(const char *name); int platform_default_i(const char *name, int def); Filename platform_default_filename(const char *name); -FontSpec platform_default_fontspec(const char *name); +FontSpec *platform_default_fontspec(const char *name); /* * Exports from terminal.c. diff --git a/settings.c b/settings.c index af5a1b20..7a2bd37c 100644 --- a/settings.c +++ b/settings.c @@ -108,10 +108,11 @@ static void gpps(void *handle, const char *name, const char *def, */ static void gppfont(void *handle, const char *name, Conf *conf, int primary) { - FontSpec result; - if (!read_setting_fontspec(handle, name, &result)) - result = platform_default_fontspec(name); - conf_set_fontspec(conf, primary, &result); + FontSpec *result = read_setting_fontspec(handle, name); + if (!result) + result = platform_default_fontspec(name); + conf_set_fontspec(conf, primary, result); + fontspec_free(result); } static void gppfile(void *handle, const char *name, Conf *conf, int primary) { @@ -553,7 +554,7 @@ void save_open_settings(void *sesskey, Conf *conf) write_setting_s(sesskey, "WinTitle", conf_get_str(conf, CONF_wintitle)); write_setting_i(sesskey, "TermWidth", conf_get_int(conf, CONF_width)); write_setting_i(sesskey, "TermHeight", conf_get_int(conf, CONF_height)); - write_setting_fontspec(sesskey, "Font", *conf_get_fontspec(conf, CONF_font)); + write_setting_fontspec(sesskey, "Font", conf_get_fontspec(conf, CONF_font)); write_setting_i(sesskey, "FontQuality", conf_get_int(conf, CONF_font_quality)); write_setting_i(sesskey, "FontVTMode", conf_get_int(conf, CONF_vtmode)); write_setting_i(sesskey, "UseSystemColours", conf_get_int(conf, CONF_system_colour)); @@ -621,9 +622,9 @@ void save_open_settings(void *sesskey, Conf *conf) write_setting_i(sesskey, "StampUtmp", conf_get_int(conf, CONF_stamp_utmp)); write_setting_i(sesskey, "LoginShell", conf_get_int(conf, CONF_login_shell)); write_setting_i(sesskey, "ScrollbarOnLeft", conf_get_int(conf, CONF_scrollbar_on_left)); - write_setting_fontspec(sesskey, "BoldFont", *conf_get_fontspec(conf, CONF_boldfont)); - write_setting_fontspec(sesskey, "WideFont", *conf_get_fontspec(conf, CONF_widefont)); - write_setting_fontspec(sesskey, "WideBoldFont", *conf_get_fontspec(conf, CONF_wideboldfont)); + write_setting_fontspec(sesskey, "BoldFont", conf_get_fontspec(conf, CONF_boldfont)); + write_setting_fontspec(sesskey, "WideFont", conf_get_fontspec(conf, CONF_widefont)); + write_setting_fontspec(sesskey, "WideBoldFont", conf_get_fontspec(conf, CONF_wideboldfont)); write_setting_i(sesskey, "ShadowBold", conf_get_int(conf, CONF_shadowbold)); write_setting_i(sesskey, "ShadowBoldOffset", conf_get_int(conf, CONF_shadowboldoffset)); write_setting_s(sesskey, "SerialLine", conf_get_str(conf, CONF_serline)); diff --git a/storage.h b/storage.h index 01cfb034..f7fe613a 100644 --- a/storage.h +++ b/storage.h @@ -32,7 +32,7 @@ void *open_settings_w(const char *sessionname, char **errmsg); void write_setting_s(void *handle, const char *key, const char *value); void write_setting_i(void *handle, const char *key, int value); void write_setting_filename(void *handle, const char *key, Filename value); -void write_setting_fontspec(void *handle, const char *key, FontSpec font); +void write_setting_fontspec(void *handle, const char *key, FontSpec *font); void close_settings_w(void *handle); /* @@ -56,7 +56,7 @@ void *open_settings_r(const char *sessionname); char *read_setting_s(void *handle, const char *key); int read_setting_i(void *handle, const char *key, int defvalue); int read_setting_filename(void *handle, const char *key, Filename *value); -int read_setting_fontspec(void *handle, const char *key, FontSpec *font); +FontSpec *read_setting_fontspec(void *handle, const char *key); void close_settings_r(void *handle); /* diff --git a/unix/gtkdlg.c b/unix/gtkdlg.c index ec7ae432..84c9d3a4 100644 --- a/unix/gtkdlg.c +++ b/unix/gtkdlg.c @@ -926,24 +926,22 @@ void dlg_filesel_get(union control *ctrl, void *dlg, Filename *fn) fn->path[lenof(fn->path)-1] = '\0'; } -void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec fs) +void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec *fs) { struct dlgparam *dp = (struct dlgparam *)dlg; struct uctrl *uc = dlg_find_byctrl(dp, ctrl); assert(uc->ctrl->generic.type == CTRL_FONTSELECT); assert(uc->entry != NULL); - gtk_entry_set_text(GTK_ENTRY(uc->entry), fs.name); + gtk_entry_set_text(GTK_ENTRY(uc->entry), fs->name); } -void dlg_fontsel_get(union control *ctrl, void *dlg, FontSpec *fs) +FontSpec *dlg_fontsel_get(union control *ctrl, void *dlg) { struct dlgparam *dp = (struct dlgparam *)dlg; struct uctrl *uc = dlg_find_byctrl(dp, ctrl); assert(uc->ctrl->generic.type == CTRL_FONTSELECT); assert(uc->entry != NULL); - strncpy(fs->name, gtk_entry_get_text(GTK_ENTRY(uc->entry)), - lenof(fs->name)); - fs->name[lenof(fs->name)-1] = '\0'; + return fontspec_new(gtk_entry_get_text(GTK_ENTRY(uc->entry))); } /* diff --git a/unix/gtkwin.c b/unix/gtkwin.c index c9455a5c..996e424d 100644 --- a/unix/gtkwin.c +++ b/unix/gtkwin.c @@ -151,14 +151,12 @@ void connection_fatal(void *frontend, char *p, ...) /* * Default settings that are specific to pterm. */ -FontSpec platform_default_fontspec(const char *name) +FontSpec *platform_default_fontspec(const char *name) { - FontSpec ret; if (!strcmp(name, "Font")) - strcpy(ret.name, "server:fixed"); + return fontspec_new("server:fixed"); else - *ret.name = '\0'; - return ret; + return fontspec_new(""); } Filename platform_default_filename(const char *name) @@ -2541,36 +2539,36 @@ int do_cmdline(int argc, char **argv, int do_everything, int *allow_launch, } if (!strcmp(p, "-fn") || !strcmp(p, "-font")) { - FontSpec fs; + FontSpec *fs; EXPECTS_ARG; SECOND_PASS_ONLY; - strncpy(fs.name, val, sizeof(fs.name)); - fs.name[sizeof(fs.name)-1] = '\0'; - conf_set_fontspec(conf, CONF_font, &fs); + fs = fontspec_new(val); + conf_set_fontspec(conf, CONF_font, fs); + fontspec_free(fs); } else if (!strcmp(p, "-fb")) { - FontSpec fs; + FontSpec *fs; EXPECTS_ARG; SECOND_PASS_ONLY; - strncpy(fs.name, val, sizeof(fs.name)); - fs.name[sizeof(fs.name)-1] = '\0'; - conf_set_fontspec(conf, CONF_boldfont, &fs); + fs = fontspec_new(val); + conf_set_fontspec(conf, CONF_font, fs); + fontspec_free(fs); } else if (!strcmp(p, "-fw")) { - FontSpec fs; + FontSpec *fs; EXPECTS_ARG; SECOND_PASS_ONLY; - strncpy(fs.name, val, sizeof(fs.name)); - fs.name[sizeof(fs.name)-1] = '\0'; - conf_set_fontspec(conf, CONF_widefont, &fs); + fs = fontspec_new(val); + conf_set_fontspec(conf, CONF_font, fs); + fontspec_free(fs); } else if (!strcmp(p, "-fwb")) { - FontSpec fs; + FontSpec *fs; EXPECTS_ARG; SECOND_PASS_ONLY; - strncpy(fs.name, val, sizeof(fs.name)); - fs.name[sizeof(fs.name)-1] = '\0'; - conf_set_fontspec(conf, CONF_wideboldfont, &fs); + fs = fontspec_new(val); + conf_set_fontspec(conf, CONF_font, fs); + fontspec_free(fs); } else if (!strcmp(p, "-cs")) { EXPECTS_ARG; diff --git a/unix/unix.h b/unix/unix.h index faf56008..aa44c9b8 100644 --- a/unix/unix.h +++ b/unix/unix.h @@ -18,8 +18,9 @@ struct Filename { FILE *f_open(struct Filename, char const *, int); struct FontSpec { - char name[256]; + char *name; /* may be "" to indicate no selected font at all */ }; +struct FontSpec *fontspec_new(const char *name); typedef void *Context; /* FIXME: probably needs changing */ diff --git a/unix/uxmisc.c b/unix/uxmisc.c index dd04e6f5..222d5590 100644 --- a/unix/uxmisc.c +++ b/unix/uxmisc.c @@ -150,3 +150,35 @@ FILE *f_open(struct Filename filename, char const *mode, int is_private) return fdopen(fd, mode); } } + +FontSpec *fontspec_new(const char *name) +{ + FontSpec *f = snew(FontSpec); + f->name = dupstr(name); + return f; +} +FontSpec *fontspec_copy(const FontSpec *f) +{ + return fontspec_new(f->name); +} +void fontspec_free(FontSpec *f) +{ + sfree(f->name); + sfree(f); +} +int fontspec_serialise(FontSpec *f, void *data) +{ + int len = strlen(f->name); + if (data) + strcpy(data, f->name); + return len + 1; /* include trailing NUL */ +} +FontSpec *fontspec_deserialise(void *vdata, int maxsize, int *used) +{ + char *data = (char *)vdata; + char *end = memchr(data, '\0', maxsize); + if (!end) + return NULL; + *used = end - data + 1; + return fontspec_new(data); +} diff --git a/unix/uxplink.c b/unix/uxplink.c index aeb37f69..fc8100c0 100644 --- a/unix/uxplink.c +++ b/unix/uxplink.c @@ -125,11 +125,9 @@ int platform_default_i(const char *name, int def) return def; } -FontSpec platform_default_fontspec(const char *name) +FontSpec *platform_default_fontspec(const char *name) { - FontSpec ret; - *ret.name = '\0'; - return ret; + return fontspec_new(""); } Filename platform_default_filename(const char *name) diff --git a/unix/uxsftp.c b/unix/uxsftp.c index 651047e9..c19df124 100644 --- a/unix/uxsftp.c +++ b/unix/uxsftp.c @@ -53,11 +53,9 @@ int platform_default_i(const char *name, int def) return def; } -FontSpec platform_default_fontspec(const char *name) +FontSpec *platform_default_fontspec(const char *name) { - FontSpec ret; - *ret.name = '\0'; - return ret; + return fontspec_new(""); } Filename platform_default_filename(const char *name) diff --git a/unix/uxstore.c b/unix/uxstore.c index 8d49e484..d9f60133 100644 --- a/unix/uxstore.c +++ b/unix/uxstore.c @@ -357,7 +357,7 @@ int read_setting_i(void *handle, const char *key, int defvalue) return atoi(val); } -int read_setting_fontspec(void *handle, const char *name, FontSpec *result) +FontSpec *read_setting_fontspec(void *handle, const char *name) { /* * In GTK1-only PuTTY, we used to store font names simply as a @@ -375,25 +375,24 @@ int read_setting_fontspec(void *handle, const char *name, FontSpec *result) char *tmp; if ((tmp = read_setting_s(handle, suffname)) != NULL) { - strncpy(result->name, tmp, sizeof(result->name)-1); - result->name[sizeof(result->name)-1] = '\0'; + FontSpec *fs = fontspec_new(tmp); sfree(suffname); sfree(tmp); - return TRUE; /* got new-style name */ + return fs; /* got new-style name */ } sfree(suffname); /* Fall back to old-style name. */ tmp = read_setting_s(handle, name); if (tmp && *tmp) { - strcpy(result->name, "server:"); - strncpy(result->name + 7, tmp, sizeof(result->name) - 8); - result->name[sizeof(result->name)-1] = '\0'; + char *tmp2 = dupcat("server:", tmp, NULL); + FontSpec *fs = fontspec_new(tmp2); + sfree(tmp2); sfree(tmp); - return TRUE; + return fs; } else { sfree(tmp); - return FALSE; + return NULL; } } int read_setting_filename(void *handle, const char *name, Filename *result) @@ -408,7 +407,7 @@ int read_setting_filename(void *handle, const char *name, Filename *result) return FALSE; } -void write_setting_fontspec(void *handle, const char *name, FontSpec result) +void write_setting_fontspec(void *handle, const char *name, FontSpec *fs) { /* * read_setting_fontspec had to handle two cases, but when @@ -416,7 +415,7 @@ void write_setting_fontspec(void *handle, const char *name, FontSpec result) * new-style name. */ char *suffname = dupcat(name, "Name", NULL); - write_setting_s(handle, suffname, result.name); + write_setting_s(handle, suffname, fs->name); sfree(suffname); } void write_setting_filename(void *handle, const char *name, Filename result) diff --git a/windows/winctrls.c b/windows/winctrls.c index 8453e2e6..4afd3d01 100644 --- a/windows/winctrls.c +++ b/windows/winctrls.c @@ -1639,8 +1639,8 @@ void winctrl_layout(struct dlgparam *dp, struct winctrls *wc, shortcuts[nshortcuts++] = ctrl->fontselect.shortcut; statictext(&pos, escaped, 1, base_id); staticbtn(&pos, "", base_id+1, "Change...", base_id+2); + data = fontspec_new("", 0, 0, 0); sfree(escaped); - data = snew(FontSpec); break; default: assert(!"Can't happen"); @@ -1934,21 +1934,21 @@ int winctrl_handle_command(struct dlgparam *dp, UINT msg, CHOOSEFONT cf; LOGFONT lf; HDC hdc; - FontSpec fs = *(FontSpec *)c->data; - + FontSpec *fs = (FontSpec *)c->data; + hdc = GetDC(0); - lf.lfHeight = -MulDiv(fs.height, + lf.lfHeight = -MulDiv(fs->height, GetDeviceCaps(hdc, LOGPIXELSY), 72); ReleaseDC(0, hdc); lf.lfWidth = lf.lfEscapement = lf.lfOrientation = 0; lf.lfItalic = lf.lfUnderline = lf.lfStrikeOut = 0; - lf.lfWeight = (fs.isbold ? FW_BOLD : 0); - lf.lfCharSet = fs.charset; + lf.lfWeight = (fs->isbold ? FW_BOLD : 0); + lf.lfCharSet = fs->charset; lf.lfOutPrecision = OUT_DEFAULT_PRECIS; lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; lf.lfQuality = DEFAULT_QUALITY; lf.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE; - strncpy(lf.lfFaceName, fs.name, + strncpy(lf.lfFaceName, fs->name, sizeof(lf.lfFaceName) - 1); lf.lfFaceName[sizeof(lf.lfFaceName) - 1] = '\0'; @@ -1959,13 +1959,11 @@ int winctrl_handle_command(struct dlgparam *dp, UINT msg, CF_FORCEFONTEXIST | CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS; if (ChooseFont(&cf)) { - strncpy(fs.name, lf.lfFaceName, - sizeof(fs.name) - 1); - fs.name[sizeof(fs.name) - 1] = '\0'; - fs.isbold = (lf.lfWeight == FW_BOLD); - fs.charset = lf.lfCharSet; - fs.height = cf.iPointSize / 10; + fs = fontspec_new(lf.lfFaceName, (lf.lfWeight == FW_BOLD), + cf.iPointSize / 10, lf.lfCharSet); dlg_fontsel_set(ctrl, dp, fs); + fontspec_free(fs); + ctrl->generic.handler(ctrl, dp, dp->data, EVENT_VALCHANGE); } } @@ -2313,34 +2311,35 @@ void dlg_filesel_get(union control *ctrl, void *dlg, Filename *fn) fn->path[lenof(fn->path)-1] = '\0'; } -void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec fs) +void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec *fs) { char *buf, *boldstr; struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); assert(c && c->ctrl->generic.type == CTRL_FONTSELECT); - *(FontSpec *)c->data = fs; /* structure copy */ + fontspec_free((FontSpec *)c->data); + c->data = fontspec_copy(fs); - boldstr = (fs.isbold ? "bold, " : ""); - if (fs.height == 0) - buf = dupprintf("Font: %s, %sdefault height", fs.name, boldstr); + boldstr = (fs->isbold ? "bold, " : ""); + if (fs->height == 0) + buf = dupprintf("Font: %s, %sdefault height", fs->name, boldstr); else - buf = dupprintf("Font: %s, %s%d-%s", fs.name, boldstr, - (fs.height < 0 ? -fs.height : fs.height), - (fs.height < 0 ? "pixel" : "point")); + buf = dupprintf("Font: %s, %s%d-%s", fs->name, boldstr, + (fs->height < 0 ? -fs->height : fs->height), + (fs->height < 0 ? "pixel" : "point")); SetDlgItemText(dp->hwnd, c->base_id+1, buf); sfree(buf); dlg_auto_set_fixed_pitch_flag(dp); } -void dlg_fontsel_get(union control *ctrl, void *dlg, FontSpec *fs) +FontSpec *dlg_fontsel_get(union control *ctrl, void *dlg) { struct dlgparam *dp = (struct dlgparam *)dlg; struct winctrl *c = dlg_findbyctrl(dp, ctrl); assert(c && c->ctrl->generic.type == CTRL_FONTSELECT); - *fs = *(FontSpec *)c->data; /* structure copy */ + return fontspec_copy((FontSpec *)c->data); } /* @@ -2482,7 +2481,7 @@ void dlg_auto_set_fixed_pitch_flag(void *dlg) { struct dlgparam *dp = (struct dlgparam *)dlg; Conf *conf = (Conf *)dp->data; - FontSpec *font; + FontSpec *fs; int quality; HFONT hfont; HDC hdc; @@ -2500,14 +2499,14 @@ void dlg_auto_set_fixed_pitch_flag(void *dlg) */ quality = conf_get_int(conf, CONF_font_quality); - font = conf_get_fontspec(conf, CONF_font); + fs = conf_get_fontspec(conf, CONF_font); hfont = CreateFont(0, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, FONT_QUALITY(quality), - FIXED_PITCH | FF_DONTCARE, font->name); + FIXED_PITCH | FF_DONTCARE, fs->name); hdc = GetDC(NULL); - if (font && hdc && SelectObject(hdc, hfont) && GetTextMetrics(hdc, &tm)) { + if (hdc && SelectObject(hdc, hfont) && GetTextMetrics(hdc, &tm)) { /* Note that the TMPF_FIXED_PITCH bit is defined upside down :-( */ is_var = (tm.tmPitchAndFamily & TMPF_FIXED_PITCH); } else { diff --git a/windows/windefs.c b/windows/windefs.c index 6fd6f0c9..4296bb01 100644 --- a/windows/windefs.c +++ b/windows/windefs.c @@ -6,18 +6,12 @@ #include -FontSpec platform_default_fontspec(const char *name) +FontSpec *platform_default_fontspec(const char *name) { - FontSpec ret; - if (!strcmp(name, "Font")) { - strcpy(ret.name, "Courier New"); - ret.isbold = 0; - ret.charset = ANSI_CHARSET; - ret.height = 10; - } else { - ret.name[0] = '\0'; - } - return ret; + if (!strcmp(name, "Font")) + return fontspec_new("Courier New", 0, 10, ANSI_CHARSET); + else + return fontspec_new("", 0, 0, 0); } Filename platform_default_filename(const char *name) diff --git a/windows/window.c b/windows/window.c index 04661fd6..fabf96ec 100644 --- a/windows/window.c +++ b/windows/window.c @@ -2315,7 +2315,7 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, { FontSpec *font = conf_get_fontspec(conf, CONF_font); FontSpec *prev_font = conf_get_fontspec(prev_conf, - CONF_font); + CONF_font); if (!strcmp(font->name, prev_font->name) || !strcmp(conf_get_str(conf, CONF_line_codepage), diff --git a/windows/winmisc.c b/windows/winmisc.c index d05a07ab..a7ac0e58 100644 --- a/windows/winmisc.c +++ b/windows/winmisc.c @@ -379,3 +379,51 @@ void *minefield_c_realloc(void *p, size_t size) } #endif /* MINEFIELD */ + +FontSpec *fontspec_new(const char *name, + int bold, int height, int charset) +{ + FontSpec *f = snew(FontSpec); + f->name = dupstr(name); + f->isbold = bold; + f->height = height; + f->charset = charset; + return f; +} +FontSpec *fontspec_copy(const FontSpec *f) +{ + return fontspec_new(f->name, f->isbold, f->height, f->charset); +} +void fontspec_free(FontSpec *f) +{ + sfree(f->name); + sfree(f); +} +int fontspec_serialise(FontSpec *f, void *vdata) +{ + char *data = (char *)vdata; + int len = strlen(f->name) + 1; /* include trailing NUL */ + if (data) { + strcpy(data, f->name); + PUT_32BIT_MSB_FIRST(data + len, f->isbold); + PUT_32BIT_MSB_FIRST(data + len + 4, f->height); + PUT_32BIT_MSB_FIRST(data + len + 8, f->charset); + } + return len + 12; /* also include three 4-byte ints */ +} +FontSpec *fontspec_deserialise(void *vdata, int maxsize, int *used) +{ + char *data = (char *)vdata; + char *end; + if (maxsize < 13) + return NULL; + end = memchr(data, '\0', maxsize-12); + if (!end) + return NULL; + end++; + *used = end - data + 12; + return fontspec_new(data, + GET_32BIT_MSB_FIRST(end), + GET_32BIT_MSB_FIRST(end + 4), + GET_32BIT_MSB_FIRST(end + 8)); +} diff --git a/windows/winstore.c b/windows/winstore.c index 12d6cdda..c1656762 100644 --- a/windows/winstore.c +++ b/windows/winstore.c @@ -186,50 +186,47 @@ int read_setting_i(void *handle, const char *key, int defvalue) return val; } -int read_setting_fontspec(void *handle, const char *name, FontSpec *result) +FontSpec *read_setting_fontspec(void *handle, const char *name) { char *settingname; - FontSpec ret; char *fontname; + int isbold, height, charset; fontname = read_setting_s(handle, name); if (!fontname) - return 0; - strncpy(ret.name, fontname, sizeof(ret.name)-1); - ret.name[sizeof(ret.name)-1] = '\0'; - sfree(fontname); + return NULL; settingname = dupcat(name, "IsBold", NULL); - ret.isbold = read_setting_i(handle, settingname, -1); + isbold = read_setting_i(handle, settingname, -1); sfree(settingname); - if (ret.isbold == -1) return 0; + if (isbold == -1) return NULL; settingname = dupcat(name, "CharSet", NULL); - ret.charset = read_setting_i(handle, settingname, -1); + charset = read_setting_i(handle, settingname, -1); sfree(settingname); - if (ret.charset == -1) return 0; + if (charset == -1) return NULL; settingname = dupcat(name, "Height", NULL); - ret.height = read_setting_i(handle, settingname, INT_MIN); + height = read_setting_i(handle, settingname, INT_MIN); sfree(settingname); - if (ret.height == INT_MIN) return 0; - *result = ret; - return 1; + if (height == INT_MIN) return NULL; + + return fontspec_new(fontname, isbold, height, charset); } -void write_setting_fontspec(void *handle, const char *name, FontSpec font) +void write_setting_fontspec(void *handle, const char *name, FontSpec *font) { char *settingname; - write_setting_s(handle, name, font.name); + write_setting_s(handle, name, font->name); settingname = dupcat(name, "IsBold", NULL); - write_setting_i(handle, settingname, font.isbold); + write_setting_i(handle, settingname, font->isbold); sfree(settingname); settingname = dupcat(name, "CharSet", NULL); - write_setting_i(handle, settingname, font.charset); + write_setting_i(handle, settingname, font->charset); sfree(settingname); settingname = dupcat(name, "Height", NULL); - write_setting_i(handle, settingname, font.height); + write_setting_i(handle, settingname, font->height); sfree(settingname); } diff --git a/windows/winstuff.h b/windows/winstuff.h index 8738ccf2..e23ed4ed 100644 --- a/windows/winstuff.h +++ b/windows/winstuff.h @@ -21,11 +21,13 @@ struct Filename { #define f_open(filename, mode, isprivate) ( fopen((filename).path, (mode)) ) struct FontSpec { - char name[64]; + char *name; int isbold; int height; int charset; }; +struct FontSpec *fontspec_new(const char *name, + int bold, int height, int charset); #ifndef CLEARTYPE_QUALITY #define CLEARTYPE_QUALITY 5 -- 2.11.0