Path: blob/main/test/browser/test_glfw3_css_scaling.c
4150 views
/*1* Copyright 2024 The Emscripten Authors. All rights reserved.2* Emscripten is available under two separate licenses, the MIT license and the3* University of Illinois/NCSA Open Source License. Both these licenses can be4* found in the LICENSE file.5*/67#include <GLFW/glfw3.h>8#include <assert.h>9#include <emscripten/html5.h>10#include <stdio.h>1112/*13* History:14* - This test was added after the issue #22847 was reported (November 2024).15* - For historical reasons, the JavaScript GLFW implementation includes a feature: the ability to scale the canvas via CSS.16* - Note that this feature is not part of GLFW as GLFW does not offer any API to scale the window.17* - Being undocumented/untested, this feature was accidentally removed when HiDPI support was added (in 3.1.51 / December 2023).18* - This test was added to document this feature and ensure proper behavior.19*20* What does this feature do?21* - if there is a CSS rule that specifies the size of the canvas (ex: `#canvas { width: 100%;}`), then the canvas22* will be scaled to match this value. Note that from a GLFW point of view, the size of the window remains what23* gets specified in `glfwCreateWindow` and/or `glfwSetWindowSize`24* - only global CSS rules apply, as setting a CSS rule on the canvas itself is removed (ex: `<canvas style="width:100%;">` is ignored)25*26* In HiDPI mode, (`glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE)`), this feature cannot work and as a result is disabled (because the canvas27* is sized using `devicePixelRatio` as the factor and CSS is used to scale it at the desired size).28*/2930/**31* As explained above, this function adds a global CSS rule instead of setting the CSS style directly on the canvas32* because it gets ignored otherwise. */33EM_JS(void, addCSSScalingRule, (), {34const style = document.createElement('style');35style.appendChild(document.createTextNode("#canvas { width: 700px; height: 500px; }"));36document.head.appendChild(style);37})3839/**40* Since it is unclear in which browser/resolution this test will run we compute the actual ratio used by the test.41* This has the neat effect that the test can be run manually on a HiDPI screen.42*/43EM_JS(double, getDevicePixelRatio, (), {return (typeof devicePixelRatio == 'number' && devicePixelRatio) || 1.0;})4445/**46* Checks window size and framebuffer size according to ratio */47static void checkWindowSize(GLFWwindow *window, int expectedWidth, int expectedHeight, float ratio) {48// first check the window size49int w, h;50glfwGetWindowSize(window, &w, &h);51printf("windowSize => %d == %d && %d == %d\n", w, expectedWidth, h, expectedHeight);52assert(w == expectedWidth && h == expectedHeight);5354// second check the frame buffer size55int fbw, fbh;56glfwGetFramebufferSize(window, &fbw, &fbh);57printf("framebufferSize => %d == %d && %d == %d\n", fbw, (int) (expectedWidth * ratio), fbh, (int) (expectedHeight * ratio));58assert(fbw == (int) (expectedWidth * ratio) && fbh == (int) (expectedHeight * ratio));59}6061// Create a window without HiDPI support and without CSS rule => expected sizes to match62void use_case_1() {63printf("Use case #1\n");64GLFWwindow* window = glfwCreateWindow(640, 480, "test_glfw3_css_scaling.c", NULL, NULL);65assert(window);66checkWindowSize(window, 640, 480, 1.0);67double w, h;68emscripten_get_element_css_size("#canvas", &w, &h);69printf("CSS Size=%.0fx%.0f\n", w, h);70assert(w == 640 && h == 480);71glfwDestroyWindow(window);72}7374// Create a window without HiDPI support, and with CSS rule =>75// the window size should match the creation size, but the CSS size should match the rule.76void use_case_2() {77printf("Use case #2\n");78GLFWwindow* window = glfwCreateWindow(640, 480, "test_glfw3_css_scaling.c", NULL, NULL);79assert(window);80checkWindowSize(window, 640, 480, 1.0);81double w, h;82emscripten_get_element_css_size("#canvas", &w, &h);83printf("CSS Size=%.0fx%.0f\n", w, h);84assert(w == 700 && h == 500); // Rule is "#canvas { width: 700px; height: 500px; }"85glfwDestroyWindow(window);86}8788// Create a window with HiDPI support, and with CSS rule =>89// the window size and framebuffer size should match the creation size (CSS rule is ignored)90void use_case_3() {91printf("Use case #3\n");92glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);93GLFWwindow* window = glfwCreateWindow(640, 480, "test_glfw3_css_scaling.c", NULL, NULL);94assert(window);95double dpr = getDevicePixelRatio();96printf("devicePixelRatio=%.0f\n", dpr);97checkWindowSize(window, 640, 480, dpr);98double w, h;99emscripten_get_element_css_size("#canvas", &w, &h);100printf("CSS Size=%.0fx%.0f\n", w, h);101assert(w == 640 && h == 480);102glfwDestroyWindow(window);103}104105int main() {106assert(glfwInit() == GLFW_TRUE);107108use_case_1();109110// Add CSS rule for the following use cases111addCSSScalingRule();112113use_case_2();114use_case_3();115116printf("All tests complete\n");117glfwTerminate();118return 0;119}120121122