Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit b371af8

Browse files
livecode-vulcanIan Macphail
authored andcommitted
[[ emscripten ]] Add HiDPI support to emscripten engine
This patch adds support for rendering at high DPI, based on the JavaScript 'window.devicePixelRatio' property
1 parent cf0f24b commit b371af8

File tree

4 files changed

+72
-19
lines changed

4 files changed

+72
-19
lines changed

engine/src/em-dc.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
3333
#include "globals.h"
3434
#include "graphics_util.h"
3535

36+
#include <emscripten.h>
37+
3638
/* ================================================================
3739
* Helper Functions
3840
* ================================================================ */
@@ -258,6 +260,7 @@ bool MCScreenDC::platform_getdisplays(bool p_effective, MCDisplay *&r_displays,
258260
return false;
259261

260262
t_display->viewport = t_display->workarea = MCEmscriptenGetDisplayRect();
263+
t_display->pixel_scale = emscripten_get_device_pixel_ratio();
261264

262265
r_displays = t_display;
263266
r_count = 1;

engine/src/em-resolution.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,18 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
2929
* Resolution independence
3030
* ================================================================ */
3131

32-
/* FIXME use emscripten_get_device_pixel_ratio() */
32+
static MCGFloat s_emscripten_device_scale = 1.0;
3333

3434
void
3535
MCResPlatformInitPixelScaling()
3636
{
37+
s_emscripten_device_scale = emscripten_get_device_pixel_ratio();
3738
}
3839

3940
bool
4041
MCResPlatformSupportsPixelScaling()
4142
{
42-
return false;
43+
return true;
4344
}
4445

4546
bool
@@ -57,15 +58,13 @@ MCResPlatformCanSetPixelScale()
5758
MCGFloat
5859
MCResPlatformGetDefaultPixelScale()
5960
{
60-
MCEmscriptenNotImplemented();
61-
return NAN;
61+
return s_emscripten_device_scale;
6262
}
6363

6464
MCGFloat
6565
MCResPlatformGetUIDeviceScale()
6666
{
67-
MCEmscriptenNotImplemented();
68-
return NAN;
67+
return s_emscripten_device_scale;
6968
}
7069

7170
void

engine/src/em-stack.cpp

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
3232
#include "graphics_util.h"
3333
#include "globals.h"
3434

35+
#include "region.h"
36+
3537
/* ================================================================
3638
* Stack initialisation
3739
* ================================================================ */
@@ -109,34 +111,83 @@ MCStack::release_window_buffer()
109111
* View management
110112
* ================================================================ */
111113

114+
static MCStackUpdateCallback s_updatewindow_callback = nullptr;
115+
static void *s_updatewindow_context = nullptr;
116+
112117
bool MCStack::view_platform_dirtyviewonresize() const
113118
{
114119
return true;
115120
}
116121

117-
void
118-
MCStack::view_platform_updatewindow(MCRegionRef p_dirty_region)
122+
void MCStack::view_platform_updatewindowwithcallback(MCRegionRef p_region, MCStackUpdateCallback p_callback, void *p_context)
123+
{
124+
s_updatewindow_callback = p_callback;
125+
s_updatewindow_context = p_context;
126+
127+
view_platform_updatewindow(p_region);
128+
129+
s_updatewindow_callback = nil;
130+
s_updatewindow_context = nil;
131+
}
132+
133+
void MCStack::view_platform_updatewindow(MCRegionRef p_dirty_region)
119134
{
120-
/* FIXME implement HiDPI support */
135+
MCRegionRef t_scaled_region;
136+
t_scaled_region = nil;
137+
138+
MCRegionRef t_screen_region;
139+
t_screen_region = nil;
140+
141+
MCGFloat t_scale;
142+
t_scale = MCResGetPixelScale();
143+
144+
if (t_scale != 1.0)
145+
{
146+
/* UNCHECKED */ MCRegionTransform(p_dirty_region, MCGAffineTransformMakeScale(t_scale, t_scale), t_scaled_region);
147+
t_screen_region = t_scaled_region;
148+
}
149+
else
150+
t_screen_region = p_dirty_region;
151+
152+
view_device_updatewindow(t_screen_region);
153+
154+
if (t_scaled_region != nil)
155+
MCRegionDestroy(t_scaled_region);
156+
}
121157

158+
void MCStack::view_device_updatewindow(MCRegionRef p_region)
159+
{
122160
/* dirtyrect() calls that occur prior to configure() being called
123161
* for the first time will result in an update region being too
124162
* big. Restrict to a valid region. */
125163

126164
uint32_t t_window = reinterpret_cast<uint32_t>(window);
127165

128-
MCGRegionRef t_region = MCGRegionRef(p_dirty_region);
129-
MCRectangle t_valid = MCEmscriptenGetWindowRect(t_window);
130-
t_valid.x = t_valid.y = 0;
166+
MCRectangle t_window_rect = MCEmscriptenGetWindowRect(t_window);
167+
MCRectangle t_canvas_rect = MCRectangleGetScaledCeilingRect(t_window_rect, MCResGetPixelScale());
168+
t_canvas_rect.x = t_canvas_rect.y = 0;
131169

132-
MCGRegionIntersectRect(t_region, MCRectangleToMCGIntegerRectangle(t_valid));
170+
MCGRegionRef t_region = MCGRegionRef(p_region);
133171

134-
MCGIntegerRectangle t_rect = MCGRegionGetBounds(t_region);
172+
MCGRegionIntersectRect(t_region, MCRectangleToMCGIntegerRectangle(t_canvas_rect));
135173

136-
MCEmscriptenSyncCanvasSize(t_window, t_valid.width, t_valid.height);
137-
138-
MCHtmlCanvasStackSurface t_surface(t_window, t_rect);
139-
view_surface_redrawwindow(&t_surface, t_region);
174+
MCGIntegerRectangle t_rect = MCGRegionGetBounds(t_region);
175+
MCEmscriptenSyncCanvasSize(t_window, t_canvas_rect.width, t_canvas_rect.height);
176+
177+
// IM-2014-01-30: [[ HiDPI ]] Ensure stack backing scale is set
178+
view_setbackingscale(MCResGetPixelScale());
179+
180+
MCHtmlCanvasStackSurface t_surface(t_window, MCGRegionGetBounds(t_region));
181+
if (t_surface.Lock())
182+
{
183+
// IM-2014-01-31: [[ HiDPI ]] If a callback is given then use it to render to the surface
184+
if (s_updatewindow_callback != nil)
185+
s_updatewindow_callback(&t_surface, (MCRegionRef)t_region, s_updatewindow_context);
186+
else
187+
view_surface_redrawwindow(&t_surface, t_region);
188+
189+
t_surface.Unlock();
190+
}
140191
}
141192

142193
MCRectangle

engine/src/stack.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1029,7 +1029,7 @@ class MCStack : public MCObject, public MCMixinObjectHandle<MCStack>
10291029
uint32_t p_minwidth, uint32_t p_minheight,
10301030
uint32_t p_maxwidth, uint32_t p_maxheight);
10311031
void view_device_updatewindow(MCRegionRef p_region);
1032-
#elif defined(_MOBILE)
1032+
#elif defined(_MOBILE) || defined(__EMSCRIPTEN__)
10331033

10341034
// IM-2014-01-30: [[ HiDPI ]] platform-specific view device methods
10351035

0 commit comments

Comments
 (0)