X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/puzzles/blobdiff_plain/be8d5aa175777c6b6b5a90342afbd8f77c615911..30861651545725962a99ff36dbedddd33b8cd3f6:/gtk.c diff --git a/gtk.c b/gtk.c index 3c777af..b85cfa9 100644 --- a/gtk.c +++ b/gtk.c @@ -14,6 +14,11 @@ #include #include +#if GTK_CHECK_VERSION(2,0,0) && !defined HAVE_SENSIBLE_ABSOLUTE_SIZE_FUNCTION +#include +#include +#endif + #include "puzzles.h" /* ---------------------------------------------------------------------- @@ -153,11 +158,60 @@ void draw_text(frontend *fe, int x, int y, int fonttype, int fontsize, fe->fonts[i].type = fonttype; fe->fonts[i].size = fontsize; +#if GTK_CHECK_VERSION(2,0,0) /* - * FIXME: Really I should make at least _some_ effort to - * pick the correct font. + * Use Pango to find the closest match to the requested + * font. */ - fe->fonts[i].font = gdk_font_load("variable"); + { + PangoFontDescription *fd; + + fd = pango_font_description_new(); + /* `Monospace' and `Sans' are meta-families guaranteed to exist */ + pango_font_description_set_family(fd, fonttype == FONT_FIXED ? + "Monospace" : "Sans"); + pango_font_description_set_weight(fd, PANGO_WEIGHT_BOLD); + /* + * I found some online Pango documentation which + * described a function called + * pango_font_description_set_absolute_size(), which is + * _exactly_ what I want here. Unfortunately, none of + * my local Pango installations have it (presumably + * they're too old), so I'm going to have to hack round + * it by figuring out the point size myself. This + * limits me to X and probably also breaks in later + * Pango installations, so ideally I should add another + * CHECK_VERSION type ifdef and use set_absolute_size + * where available. All very annoying. + */ +#ifdef HAVE_SENSIBLE_ABSOLUTE_SIZE_FUNCTION + pango_font_description_set_absolute_size(fd, PANGO_SCALE*fontsize); +#else + { + Display *d = GDK_DISPLAY(); + int s = DefaultScreen(d); + double resolution = + (PANGO_SCALE * 72.27 / 25.4) * + ((double) DisplayWidthMM(d, s) / DisplayWidth (d, s)); + pango_font_description_set_size(fd, resolution * fontsize); + } +#endif + fe->fonts[i].font = gdk_font_from_description(fd); + pango_font_description_free(fd); + } + + if (!fe->fonts[i].font) +#endif + /* + * In GTK 1.2, I don't know of any plausible way to + * pick a suitable font, so I'm just going to be + * tedious. + * + * This is also fallback code called if the Pango + * approach fails to find an appropriate font. + */ + fe->fonts[i].font = gdk_font_load(fonttype == FONT_FIXED ? + "fixed" : "variable"); } /* @@ -166,11 +220,24 @@ void draw_text(frontend *fe, int x, int y, int fonttype, int fontsize, { int lb, rb, wid, asc, desc; - gdk_string_extents(fe->fonts[i].font, text, + /* + * Measure vertical string extents with respect to the same + * string always... + */ + gdk_string_extents(fe->fonts[i].font, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ", &lb, &rb, &wid, &asc, &desc); if (align & ALIGN_VCENTRE) y += asc - (asc+desc)/2; + /* + * ... but horizontal extents with respect to the provided + * string. This means that multiple pieces of text centred + * on the same y-coordinate don't have different baselines. + */ + gdk_string_extents(fe->fonts[i].font, text, + &lb, &rb, &wid, &asc, &desc); + if (align & ALIGN_HCENTRE) x -= wid / 2; else if (align & ALIGN_HRIGHT) @@ -965,14 +1032,70 @@ int main(int argc, char **argv) char *pname = argv[0]; char *error; - gtk_init(&argc, &argv); + /* + * Special standalone mode for generating puzzle IDs on the + * command line. Useful for generating puzzles to be printed + * out and solved offline (for puzzles where that even makes + * sense - Solo, for example, is a lot more pencil-and-paper + * friendly than Net!) + * + * Usage: + * + * --generate [ []] + * + * , if present, is the number of puzzle IDs to generate. + * , if present, is the same type of parameter string + * you would pass to the puzzle when running it in GUI mode, + * including optional extras such as the expansion factor in + * Rectangles and the difficulty level in Solo. + * + * If you specify , you must also specify (although + * you may specify it to be 1). Sorry; that was the + * simplest-to-parse command-line syntax I came up with. + */ + if (argc > 1 && !strcmp(argv[1], "--generate")) { + int n = 1; + char *params = NULL; + game_params *par; + random_state *rs; + char *parstr; + + { + void *seed; + int seedlen; + get_random_seed(&seed, &seedlen); + rs = random_init(seed, seedlen); + } - if (!new_window(argc > 1 ? argv[1] : NULL, &error)) { - fprintf(stderr, "%s: %s\n", pname, error); - return 1; - } + if (argc > 2) + n = atoi(argv[2]); + if (argc > 3) + params = argv[3]; + + if (params) + par = thegame.decode_params(params); + else + par = thegame.default_params(); + parstr = thegame.encode_params(par); + + while (n-- > 0) { + char *seed = thegame.new_seed(par, rs); + printf("%s:%s\n", parstr, seed); + sfree(seed); + } - gtk_main(); + return 0; + } else { + + gtk_init(&argc, &argv); + + if (!new_window(argc > 1 ? argv[1] : NULL, &error)) { + fprintf(stderr, "%s: %s\n", pname, error); + return 1; + } + + gtk_main(); + } return 0; }