summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJaakko Keränen <jaakko.keranen@iki.fi>2021-04-07 08:19:24 +0300
committerJaakko Keränen <jaakko.keranen@iki.fi>2021-04-07 08:19:24 +0300
commite2f05937ad8e49e8cdb553bd1e6110f4cb0a71e4 (patch)
tree8d6737d7c2f0613d3edb912b7ef610f53e57f0a0 /src
parent81d4d93d5e258e4808f27648c6c9d2157ac19c4e (diff)
Window: Pixel ratio and display scaling
IssueID #239
Diffstat (limited to 'src')
-rw-r--r--src/ui/metrics.c8
-rw-r--r--src/ui/metrics.h2
-rw-r--r--src/ui/window.c53
-rw-r--r--src/ui/window.h3
4 files changed, 41 insertions, 25 deletions
diff --git a/src/ui/metrics.c b/src/ui/metrics.c
index 2405eae4..32561ed7 100644
--- a/src/ui/metrics.c
+++ b/src/ui/metrics.c
@@ -32,14 +32,14 @@ int gap_UI = defaultGap_Metrics;
32iInt2 gap2_UI = { defaultGap_Metrics, defaultGap_Metrics }; 32iInt2 gap2_UI = { defaultGap_Metrics, defaultGap_Metrics };
33int fontSize_UI = defaultFontSize_Metrics; 33int fontSize_UI = defaultFontSize_Metrics;
34 34
35void setPixelRatio_Metrics(float pixelRatio) { 35void setScale_Metrics(float scale) {
36#if defined (iPlatformAppleMobile) 36#if defined (iPlatformAppleMobile)
37 /* iPad needs a bit larger UI elements as the viewing distance is generally longer.*/ 37 /* iPad needs a bit larger UI elements as the viewing distance is generally longer.*/
38 if (deviceType_App() == tablet_AppDeviceType) { 38 if (deviceType_App() == tablet_AppDeviceType) {
39 pixelRatio *= 1.1f; 39 scale *= 1.1f;
40 } 40 }
41#endif 41#endif
42 gap_UI = iRound(defaultGap_Metrics * pixelRatio); 42 gap_UI = iRound(defaultGap_Metrics * scale);
43 gap2_UI = init1_I2(gap_UI); 43 gap2_UI = init1_I2(gap_UI);
44 fontSize_UI = iRound(defaultFontSize_Metrics * pixelRatio); 44 fontSize_UI = iRound(defaultFontSize_Metrics * scale);
45} 45}
diff --git a/src/ui/metrics.h b/src/ui/metrics.h
index 207dd59d..b314f65a 100644
--- a/src/ui/metrics.h
+++ b/src/ui/metrics.h
@@ -28,4 +28,4 @@ extern int gap_UI;
28extern int fontSize_UI; 28extern int fontSize_UI;
29extern iInt2 gap2_UI; 29extern iInt2 gap2_UI;
30 30
31void setPixelRatio_Metrics (float pixelRatio); 31void setScale_Metrics (float scale);
diff --git a/src/ui/window.c b/src/ui/window.c
index 21864dce..88ede747 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -1276,19 +1276,30 @@ void drawWhileResizing_Window(iWindow *d, int w, int h) {
1276} 1276}
1277 1277
1278static float pixelRatio_Window_(const iWindow *d) { 1278static float pixelRatio_Window_(const iWindow *d) {
1279 int dx, x;
1280 SDL_GetRendererOutputSize(d->render, &dx, NULL);
1281 SDL_GetWindowSize(d->win, &x, NULL);
1282 return (float) dx / (float) x;
1283}
1284
1285#if defined (iPlatformApple)
1286# define baseDPI_Window 113.5f
1287#else
1288# define baseDPI_Window 96.0f
1289#endif
1290
1291static float displayScale_Window_(const iWindow *d) {
1279#if defined (iPlatformMsys) 1292#if defined (iPlatformMsys)
1280 iUnused(d); 1293 iUnused(d);
1281 return desktopDPI_Win32(); 1294 return desktopDPI_Win32();
1282#elif defined (iPlatformLinux) 1295#else
1283 float vdpi = 0.0f; 1296 float vdpi = 0.0f;
1284 SDL_GetDisplayDPI(SDL_GetWindowDisplayIndex(d->win), NULL, NULL, &vdpi); 1297 SDL_GetDisplayDPI(SDL_GetWindowDisplayIndex(d->win), NULL, NULL, &vdpi);
1285 const float factor = vdpi / 96.0f; 1298 const float factor = vdpi / baseDPI_Window / pixelRatio_Window_(d);
1286 return iMax(1.0f, factor); 1299 if (factor < 0.75f) {
1287#else 1300 return 1.0f; /* seems invalid */
1288 int dx, x; 1301 }
1289 SDL_GetRendererOutputSize(d->render, &dx, NULL); 1302 return iMax(0.75f, factor);
1290 SDL_GetWindowSize(d->win, &x, NULL);
1291 return (float) dx / (float) x;
1292#endif 1303#endif
1293} 1304}
1294 1305
@@ -1443,14 +1454,15 @@ void init_Window(iWindow *d, iRect rect) {
1443#endif 1454#endif
1444 } 1455 }
1445 drawBlank_Window_(d); 1456 drawBlank_Window_(d);
1446 d->uiScale = initialUiScale_; 1457 d->pixelRatio = pixelRatio_Window_(d); /* point/pixel conversion */
1447 d->pixelRatio = pixelRatio_Window_(d); 1458 d->displayScale = displayScale_Window_(d);
1448 setPixelRatio_Metrics(d->pixelRatio * d->uiScale); 1459 d->uiScale = initialUiScale_;
1460 setScale_Metrics(d->pixelRatio * d->displayScale * d->uiScale);
1449#if defined (iPlatformMsys) 1461#if defined (iPlatformMsys)
1450 SDL_Rect usable; 1462 SDL_Rect usable;
1451 SDL_GetDisplayUsableBounds(0, &usable); 1463 SDL_GetDisplayUsableBounds(0, &usable);
1452 SDL_SetWindowMaximumSize(d->win, usable.w, usable.h); 1464 SDL_SetWindowMaximumSize(d->win, usable.w, usable.h);
1453 SDL_SetWindowMinimumSize(d->win, minSize.x * d->pixelRatio, minSize.y * d->pixelRatio); 1465 SDL_SetWindowMinimumSize(d->win, minSize.x * d->displayScale, minSize.y * d->displayScale);
1454 useExecutableIconResource_SDLWindow(d->win); 1466 useExecutableIconResource_SDLWindow(d->win);
1455#endif 1467#endif
1456#if defined (iPlatformLinux) 1468#if defined (iPlatformLinux)
@@ -1581,15 +1593,24 @@ static iBool unsnap_Window_(iWindow *d, const iInt2 *newPos) {
1581 1593
1582static void notifyMetricsChange_Window_(const iWindow *d) { 1594static void notifyMetricsChange_Window_(const iWindow *d) {
1583 /* Dynamic UI metrics change. Widgets need to update themselves. */ 1595 /* Dynamic UI metrics change. Widgets need to update themselves. */
1584 setPixelRatio_Metrics(d->pixelRatio * d->uiScale); 1596 setScale_Metrics(d->pixelRatio * d->displayScale * d->uiScale);
1585 resetFonts_Text(); 1597 resetFonts_Text();
1586 postCommand_App("metrics.changed"); 1598 postCommand_App("metrics.changed");
1587} 1599}
1588 1600
1589static void checkPixelRatioChange_Window_(iWindow *d) { 1601static void checkPixelRatioChange_Window_(iWindow *d) {
1602 iBool wasChanged = iFalse;
1590 const float ratio = pixelRatio_Window_(d); 1603 const float ratio = pixelRatio_Window_(d);
1591 if (iAbs(ratio - d->pixelRatio) > 0.001f) { 1604 if (iAbs(ratio - d->pixelRatio) > 0.001f) {
1592 d->pixelRatio = ratio; 1605 d->pixelRatio = ratio;
1606 wasChanged = iTrue;
1607 }
1608 const float scale = displayScale_Window_(d);
1609 if (iAbs(scale - d->displayScale) > 0.001f) {
1610 d->displayScale = scale;
1611 wasChanged = iTrue;
1612 }
1613 if (wasChanged) {
1593 notifyMetricsChange_Window_(d); 1614 notifyMetricsChange_Window_(d);
1594 } 1615 }
1595} 1616}
@@ -1993,13 +2014,7 @@ iInt2 visibleRootSize_Window(const iWindow *d) {
1993} 2014}
1994 2015
1995iInt2 coord_Window(const iWindow *d, int x, int y) { 2016iInt2 coord_Window(const iWindow *d, int x, int y) {
1996#if defined (iPlatformMsys) || defined (iPlatformLinux)
1997 /* On Windows, surface coordinates are in pixels. */
1998 return init_I2(x, y);
1999#else
2000 /* Coordinates are in points. */
2001 return mulf_I2(init_I2(x, y), d->pixelRatio); 2017 return mulf_I2(init_I2(x, y), d->pixelRatio);
2002#endif
2003} 2018}
2004 2019
2005iInt2 mouseCoord_Window(const iWindow *d) { 2020iInt2 mouseCoord_Window(const iWindow *d) {
diff --git a/src/ui/window.h b/src/ui/window.h
index 6960e03e..e3d8b22b 100644
--- a/src/ui/window.h
+++ b/src/ui/window.h
@@ -67,7 +67,8 @@ struct Impl_Window {
67 uint32_t focusGainedAt; 67 uint32_t focusGainedAt;
68 SDL_Renderer *render; 68 SDL_Renderer *render;
69 iWidget * root; 69 iWidget * root;
70 float pixelRatio; 70 float pixelRatio; /* conversion between points and pixels, e.g., coords, window size */
71 float displayScale; /* DPI-based scaling factor of current display, affects uiScale only */
71 float uiScale; 72 float uiScale;
72 uint32_t frameTime; 73 uint32_t frameTime;
73 double presentTime; 74 double presentTime;