ref: 1e8169ea94da3c37fc8fbe38ccb8120ae540743a
parent: fa58dd85b7ee06fed8d7a5ecc14fda8146f7521b
author: Ben Harris <bjh21@bjh21.me.uk>
date: Thu Oct 27 18:37:31 EDT 2022
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.
--- a/emcc.c
+++ b/emcc.c
@@ -83,6 +83,7 @@
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 @@
*/
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 restore_puzzle_size(int w, int h)
{
midend_reset_tilesize(me);
- resize();
+ resize(true);
midend_force_redraw(me);
}
@@ -713,7 +734,7 @@
*/
select_appropriate_preset();
midend_new_game(me);
- resize();
+ resize(false);
midend_redraw(me);
free_cfg(cfg);
js_dialog_cleanup();
@@ -770,7 +791,7 @@
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 @@
js_error_box(err);
} else {
select_appropriate_preset();
- resize();
+ resize(false);
midend_redraw(me);
update_permalinks();
update_undo_redo();
@@ -936,7 +957,7 @@
* canvas size appropriately.
*/
midend_new_game(me);
- resize();
+ resize(true);
/*
* Create a status bar, if needed.
--- a/emcclib.js
+++ b/emcclib.js
@@ -570,6 +570,15 @@
},
/*
+ * 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);
*
* Begin constructing a 'dialog box' which will be popped up in an