Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
This repository was archived by the owner on Aug 31, 2021. It is now read-only.

Commit 1e56ae3

Browse filesBrowse files
Merge pull request #7387 from livecodeian/bugfix-21615
[[ Bug 21615 ]] Implement HiDPI scaling in emscripten engine
2 parents a714e96 + a63f956 commit 1e56ae3
Copy full SHA for 1e56ae3

File tree

6 files changed

+112
-20
lines changed
Filter options

6 files changed

+112
-20
lines changed

‎docs/notes/bugfix-21615.md

Copy file name to clipboard
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Add HiDPI scaling support to HTML5 engine

‎engine/src/em-dc.cpp

Copy file name to clipboardExpand all lines: engine/src/em-dc.cpp
+3Lines 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-event.js

Copy file name to clipboardExpand all lines: engine/src/em-event.js
+14Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ mergeInto(LibraryManager.library, {
130130
tInput.addEventListener(type, handler);
131131
});
132132

133+
// Add listener for changes to device pixel ratio
134+
var matchQuery = `(resolution: ${window.devicePixelRatio}dppx)`;
135+
window.matchMedia(matchQuery).addListener(LiveCodeEvents._handleDevicePixelRatioChanged);
136+
133137
LiveCodeEvents._initialised = true;
134138
},
135139

@@ -892,6 +896,16 @@ mergeInto(LibraryManager.library, {
892896
// UI events
893897
// ----------------------------------------------------------------
894898

899+
_handleDevicePixelRatioChanged: function() {
900+
LiveCodeAsync.delay(function() {
901+
Module.ccall('MCEmscriptenHandleDevicePixelRatioChanged',
902+
'number', /* bool */
903+
[],
904+
[])
905+
});
906+
LiveCodeAsync.resume();
907+
},
908+
895909
// prevent context menu popup on right-click
896910
_handleContextMenu: function(e) {
897911
e.preventDefault()

‎engine/src/em-resolution.cpp

Copy file name to clipboardExpand all lines: engine/src/em-resolution.cpp
+30-7Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,41 @@ for more details.
1616
You should have received a copy of the GNU General Public License
1717
along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
1818

19+
#include "globdefs.h"
20+
#include "filedefs.h"
21+
#include "osspec.h"
22+
#include "typedefs.h"
23+
#include "parsedef.h"
24+
#include "objdefs.h"
25+
26+
#include "globals.h"
27+
1928
#include "em-util.h"
2029

2130
#include "sysdefs.h"
2231

2332
#include "graphics.h"
2433
#include "resolution.h"
34+
#include "stacklst.h"
2535

2636
#include <emscripten.h>
2737

2838
/* ================================================================
2939
* Resolution independence
3040
* ================================================================ */
3141

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

3444
void
3545
MCResPlatformInitPixelScaling()
3646
{
47+
s_emscripten_device_scale = emscripten_get_device_pixel_ratio();
3748
}
3849

3950
bool
4051
MCResPlatformSupportsPixelScaling()
4152
{
42-
return false;
53+
return true;
4354
}
4455

4556
bool
@@ -57,19 +68,31 @@ MCResPlatformCanSetPixelScale()
5768
MCGFloat
5869
MCResPlatformGetDefaultPixelScale()
5970
{
60-
MCEmscriptenNotImplemented();
61-
return NAN;
71+
return s_emscripten_device_scale;
6272
}
6373

6474
MCGFloat
6575
MCResPlatformGetUIDeviceScale()
6676
{
67-
MCEmscriptenNotImplemented();
68-
return NAN;
77+
return s_emscripten_device_scale;
6978
}
7079

7180
void
7281
MCResPlatformHandleScaleChange()
7382
{
74-
MCEmscriptenNotImplemented();
83+
// Global use-pixel-scaling value has been updated, so now we just need to reopen any open stack windows
84+
MCstacks->reopenallstackwindows();
85+
}
86+
87+
extern "C" MC_DLLEXPORT_DEF bool
88+
MCEmscriptenHandleDevicePixelRatioChanged()
89+
{
90+
MCGFloat t_scale = emscripten_get_device_pixel_ratio();
91+
if (t_scale != s_emscripten_device_scale)
92+
{
93+
s_emscripten_device_scale = t_scale;
94+
MCResPlatformHandleScaleChange();
95+
}
96+
97+
return true;
7598
}

‎engine/src/em-stack.cpp

Copy file name to clipboardExpand all lines: engine/src/em-stack.cpp
+63-12Lines 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

Copy file name to clipboardExpand all lines: engine/src/stack.h
+1-1Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.