From 1e8169ea94da3c37fc8fbe38ccb8120ae540743a Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Thu, 27 Oct 2022 22:37:31 +0100 Subject: [PATCH] js: Take device pixel ratio into account when setting default size This is a bit of a hack. When setting the puzzle to its default size, either at startup or from a right-click on the resize handle, we now scale the default size from midend_size() by the device pixel ratio, and then pass that back to midend_size(). This does more or less the right thing, in that the puzzle now starts up at a size that scales with the font size. There are still some slight inconsistencies, where sequences of DPR changes and puzzle parameter changes can have order-dependent effects on the size of the puzzle. Happily these effects are small and fairly hard to observe. --- emcc.c | 35 ++++++++++++++++++++++++++++------- emcclib.js | 9 +++++++++ 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/emcc.c b/emcc.c index 605938b..651fc5a 100644 --- a/emcc.c +++ b/emcc.c @@ -83,6 +83,7 @@ extern void js_canvas_make_statusbar(void); extern void js_canvas_set_statusbar(const char *text); extern void js_canvas_set_size(int w, int h); extern void js_canvas_set_nominal_size(); +extern double js_get_device_pixel_ratio(); extern void js_dialog_init(const char *title); extern void js_dialog_string(int i, const char *title, const char *initvalue); @@ -183,12 +184,32 @@ void timer_callback(double tplus) */ static int canvas_w, canvas_h; -/* Called when we resize as a result of changing puzzle settings */ -static void resize(void) +/* + * Called when we resize as a result of changing puzzle settings. + * "initial" is true if this is the first call, or the first call + * since a midend_reset_tilesize(). In that case, we might want to + * adjust the size to compensate for the device pixel ratio. + */ +static void resize(bool initial) { int w, h; + double dpr; w = h = INT_MAX; midend_size(me, &w, &h, false); + if (initial) { + dpr = js_get_device_pixel_ratio(); + if (dpr != 1.0) { + /* + * The default w and h are probably in units of + * sensible-sized pixels (~0.25 mm). Scale them to the + * actual device pixels and then ask for a size near + * that. + */ + w *= dpr; + h *= dpr; + midend_size(me, &w, &h, true); + } + } js_canvas_set_size(w, h); js_canvas_set_nominal_size(); canvas_w = w; @@ -218,7 +239,7 @@ void resize_puzzle(int w, int h) void restore_puzzle_size(int w, int h) { midend_reset_tilesize(me); - resize(); + resize(true); midend_force_redraw(me); } @@ -713,7 +734,7 @@ static void cfg_end(bool use_results) */ select_appropriate_preset(); midend_new_game(me); - resize(); + resize(false); midend_redraw(me); free_cfg(cfg); js_dialog_cleanup(); @@ -770,7 +791,7 @@ void command(int n) assert(i < npresets); midend_set_params(me, presets[i]); midend_new_game(me); - resize(); + resize(false); midend_redraw(me); update_undo_redo(); js_focus_canvas(); @@ -894,7 +915,7 @@ void load_game(const char *buffer, int len) js_error_box(err); } else { select_appropriate_preset(); - resize(); + resize(false); midend_redraw(me); update_permalinks(); update_undo_redo(); @@ -936,7 +957,7 @@ int main(int argc, char **argv) * canvas size appropriately. */ midend_new_game(me); - resize(); + resize(true); /* * Create a status bar, if needed. diff --git a/emcclib.js b/emcclib.js index 1fb3a90..95ded9f 100644 --- a/emcclib.js +++ b/emcclib.js @@ -569,6 +569,15 @@ mergeInto(LibraryManager.library, { nominal_height = onscreen_canvas.height / dpr; }, + /* + * double js_get_device_pixel_ratio(); + * + * Return the current device pixel ratio. + */ + js_get_device_pixel_ratio: function() { + return window.devicePixelRatio || 1; + }, + /* * void js_dialog_init(const char *title); *