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.
This commit is contained in:
Ben Harris
2022-10-27 22:37:31 +01:00
parent fa58dd85b7
commit 1e8169ea94
2 changed files with 37 additions and 7 deletions

35
emcc.c
View File

@ -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_statusbar(const char *text);
extern void js_canvas_set_size(int w, int h); extern void js_canvas_set_size(int w, int h);
extern void js_canvas_set_nominal_size(); 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_init(const char *title);
extern void js_dialog_string(int i, const char *title, const char *initvalue); 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; 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; int w, h;
double dpr;
w = h = INT_MAX; w = h = INT_MAX;
midend_size(me, &w, &h, false); 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_size(w, h);
js_canvas_set_nominal_size(); js_canvas_set_nominal_size();
canvas_w = w; canvas_w = w;
@ -218,7 +239,7 @@ void resize_puzzle(int w, int h)
void restore_puzzle_size(int w, int h) void restore_puzzle_size(int w, int h)
{ {
midend_reset_tilesize(me); midend_reset_tilesize(me);
resize(); resize(true);
midend_force_redraw(me); midend_force_redraw(me);
} }
@ -713,7 +734,7 @@ static void cfg_end(bool use_results)
*/ */
select_appropriate_preset(); select_appropriate_preset();
midend_new_game(me); midend_new_game(me);
resize(); resize(false);
midend_redraw(me); midend_redraw(me);
free_cfg(cfg); free_cfg(cfg);
js_dialog_cleanup(); js_dialog_cleanup();
@ -770,7 +791,7 @@ void command(int n)
assert(i < npresets); assert(i < npresets);
midend_set_params(me, presets[i]); midend_set_params(me, presets[i]);
midend_new_game(me); midend_new_game(me);
resize(); resize(false);
midend_redraw(me); midend_redraw(me);
update_undo_redo(); update_undo_redo();
js_focus_canvas(); js_focus_canvas();
@ -894,7 +915,7 @@ void load_game(const char *buffer, int len)
js_error_box(err); js_error_box(err);
} else { } else {
select_appropriate_preset(); select_appropriate_preset();
resize(); resize(false);
midend_redraw(me); midend_redraw(me);
update_permalinks(); update_permalinks();
update_undo_redo(); update_undo_redo();
@ -936,7 +957,7 @@ int main(int argc, char **argv)
* canvas size appropriately. * canvas size appropriately.
*/ */
midend_new_game(me); midend_new_game(me);
resize(); resize(true);
/* /*
* Create a status bar, if needed. * Create a status bar, if needed.

View File

@ -569,6 +569,15 @@ mergeInto(LibraryManager.library, {
nominal_height = onscreen_canvas.height / dpr; 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); * void js_dialog_init(const char *title);
* *