Browse Source

Merge pull request #45920 from Faless/js/4.x_dpi

[HTML5] Detect screen scale and DPI.
Rémi Verschelde 4 years ago
parent
commit
dbddf52c12

+ 7 - 2
platform/javascript/display_server_javascript.cpp

@@ -845,7 +845,8 @@ Size2i DisplayServerJavaScript::screen_get_size(int p_screen) const {
 	EmscriptenFullscreenChangeEvent ev;
 	EMSCRIPTEN_RESULT result = emscripten_get_fullscreen_status(&ev);
 	ERR_FAIL_COND_V(result != EMSCRIPTEN_RESULT_SUCCESS, Size2i());
-	return Size2i(ev.screenWidth, ev.screenHeight);
+	double scale = godot_js_display_pixel_ratio_get();
+	return Size2i(ev.screenWidth * scale, ev.screenHeight * scale);
 }
 
 Rect2i DisplayServerJavaScript::screen_get_usable_rect(int p_screen) const {
@@ -855,7 +856,11 @@ Rect2i DisplayServerJavaScript::screen_get_usable_rect(int p_screen) const {
 }
 
 int DisplayServerJavaScript::screen_get_dpi(int p_screen) const {
-	return 96; // TODO maybe check pixel ratio via window.devicePixelRatio * 96? Inexact.
+	return godot_js_display_screen_dpi_get();
+}
+
+float DisplayServerJavaScript::screen_get_scale(int p_screen) const {
+	return godot_js_display_pixel_ratio_get();
 }
 
 Vector<DisplayServer::WindowID> DisplayServerJavaScript::get_window_list() const {

+ 1 - 0
platform/javascript/display_server_javascript.h

@@ -136,6 +136,7 @@ public:
 	Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
 	Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
 	int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
+	float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
 
 	// windows
 	Vector<DisplayServer::WindowID> get_window_list() const override;

+ 1 - 0
platform/javascript/godot_js.h

@@ -51,6 +51,7 @@ extern int godot_js_os_execute(const char *p_json);
 extern void godot_js_os_shell_open(const char *p_uri);
 
 // Display
+extern int godot_js_display_screen_dpi_get();
 extern double godot_js_display_pixel_ratio_get();
 extern void godot_js_display_alert(const char *p_text);
 extern int godot_js_display_touchscreen_is_available();

+ 26 - 0
platform/javascript/js/libs/library_godot_display.js

@@ -405,6 +405,27 @@ const GodotDisplay = {
 	$GodotDisplay__deps: ['$GodotConfig', '$GodotRuntime', '$GodotDisplayCursor', '$GodotDisplayListeners', '$GodotDisplayDragDrop', '$GodotDisplayGamepads'],
 	$GodotDisplay: {
 		window_icon: '',
+		findDPI: function () {
+			function testDPI(dpi) {
+				return window.matchMedia(`(max-resolution: ${dpi}dpi)`).matches;
+			}
+			function bisect(low, high, func) {
+				const mid = parseInt(((high - low) / 2) + low, 10);
+				if (high - low <= 1) {
+					return func(high) ? high : low;
+				}
+				if (func(mid)) {
+					return bisect(low, mid, func);
+				}
+				return bisect(mid, high, func);
+			}
+			try {
+				const dpi = bisect(0, 800, testDPI);
+				return dpi >= 96 ? dpi : 96;
+			} catch (e) {
+				return 96;
+			}
+		},
 	},
 
 	godot_js_display_is_swap_ok_cancel__sig: 'i',
@@ -422,6 +443,11 @@ const GodotDisplay = {
 		window.alert(GodotRuntime.parseString(p_text)); // eslint-disable-line no-alert
 	},
 
+	godot_js_display_screen_dpi_get__sig: 'i',
+	godot_js_display_screen_dpi_get: function () {
+		return GodotDisplay.findDPI();
+	},
+
 	godot_js_display_pixel_ratio_get__sig: 'f',
 	godot_js_display_pixel_ratio_get: function () {
 		return window.devicePixelRatio || 1;