diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-04-07 08:19:24 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-04-07 08:19:24 +0300 |
commit | e2f05937ad8e49e8cdb553bd1e6110f4cb0a71e4 (patch) | |
tree | 8d6737d7c2f0613d3edb912b7ef610f53e57f0a0 /src | |
parent | 81d4d93d5e258e4808f27648c6c9d2157ac19c4e (diff) |
Window: Pixel ratio and display scaling
IssueID #239
Diffstat (limited to 'src')
-rw-r--r-- | src/ui/metrics.c | 8 | ||||
-rw-r--r-- | src/ui/metrics.h | 2 | ||||
-rw-r--r-- | src/ui/window.c | 53 | ||||
-rw-r--r-- | src/ui/window.h | 3 |
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; | |||
32 | iInt2 gap2_UI = { defaultGap_Metrics, defaultGap_Metrics }; | 32 | iInt2 gap2_UI = { defaultGap_Metrics, defaultGap_Metrics }; |
33 | int fontSize_UI = defaultFontSize_Metrics; | 33 | int fontSize_UI = defaultFontSize_Metrics; |
34 | 34 | ||
35 | void setPixelRatio_Metrics(float pixelRatio) { | 35 | void 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; | |||
28 | extern int fontSize_UI; | 28 | extern int fontSize_UI; |
29 | extern iInt2 gap2_UI; | 29 | extern iInt2 gap2_UI; |
30 | 30 | ||
31 | void setPixelRatio_Metrics (float pixelRatio); | 31 | void 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 | ||
1278 | static float pixelRatio_Window_(const iWindow *d) { | 1278 | static 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 | |||
1291 | static 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 | ||
1582 | static void notifyMetricsChange_Window_(const iWindow *d) { | 1594 | static 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 | ||
1589 | static void checkPixelRatioChange_Window_(iWindow *d) { | 1601 | static 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 | ||
1995 | iInt2 coord_Window(const iWindow *d, int x, int y) { | 2016 | iInt2 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 | ||
2005 | iInt2 mouseCoord_Window(const iWindow *d) { | 2020 | iInt2 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; |