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. @@ -883,6 +883,20 @@ int conf_serialised_size(Conf *conf); 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. */ @@ -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