Skip to content
This repository was archived by the owner on Aug 31, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/notes/bugfix-21615.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Add HiDPI scaling support to HTML5 engine
3 changes: 3 additions & 0 deletions engine/src/em-dc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
#include "globals.h"
#include "graphics_util.h"

#include <emscripten.h>

/* ================================================================
* Helper Functions
* ================================================================ */
Expand Down Expand Up @@ -258,6 +260,7 @@ bool MCScreenDC::platform_getdisplays(bool p_effective, MCDisplay *&r_displays,
return false;

t_display->viewport = t_display->workarea = MCEmscriptenGetDisplayRect();
t_display->pixel_scale = emscripten_get_device_pixel_ratio();

r_displays = t_display;
r_count = 1;
Expand Down
14 changes: 14 additions & 0 deletions engine/src/em-event.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ mergeInto(LibraryManager.library, {
tInput.addEventListener(type, handler);
});

// Add listener for changes to device pixel ratio
var matchQuery = `(resolution: ${window.devicePixelRatio}dppx)`;
window.matchMedia(matchQuery).addListener(LiveCodeEvents._handleDevicePixelRatioChanged);

LiveCodeEvents._initialised = true;
},

Expand Down Expand Up @@ -892,6 +896,16 @@ mergeInto(LibraryManager.library, {
// UI events
// ----------------------------------------------------------------

_handleDevicePixelRatioChanged: function() {
LiveCodeAsync.delay(function() {
Module.ccall('MCEmscriptenHandleDevicePixelRatioChanged',
'number', /* bool */
[],
[])
});
LiveCodeAsync.resume();
},

// prevent context menu popup on right-click
_handleContextMenu: function(e) {
e.preventDefault()
Expand Down
37 changes: 30 additions & 7 deletions engine/src/em-resolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,41 @@ for more details.
You should have received a copy of the GNU General Public License
along with LiveCode. If not see <http://www.gnu.org/licenses/>. */

#include "globdefs.h"
#include "filedefs.h"
#include "osspec.h"
#include "typedefs.h"
#include "parsedef.h"
#include "objdefs.h"

#include "globals.h"

#include "em-util.h"

#include "sysdefs.h"

#include "graphics.h"
#include "resolution.h"
#include "stacklst.h"

#include <emscripten.h>

/* ================================================================
* Resolution independence
* ================================================================ */

/* FIXME use emscripten_get_device_pixel_ratio() */
static MCGFloat s_emscripten_device_scale = 1.0;

void
MCResPlatformInitPixelScaling()
{
s_emscripten_device_scale = emscripten_get_device_pixel_ratio();
}

bool
MCResPlatformSupportsPixelScaling()
{
return false;
return true;
}

bool
Expand All @@ -57,19 +68,31 @@ MCResPlatformCanSetPixelScale()
MCGFloat
MCResPlatformGetDefaultPixelScale()
{
MCEmscriptenNotImplemented();
return NAN;
return s_emscripten_device_scale;
}

MCGFloat
MCResPlatformGetUIDeviceScale()
{
MCEmscriptenNotImplemented();
return NAN;
return s_emscripten_device_scale;
}

void
MCResPlatformHandleScaleChange()
{
MCEmscriptenNotImplemented();
// Global use-pixel-scaling value has been updated, so now we just need to reopen any open stack windows
MCstacks->reopenallstackwindows();
}

Comment thread
livecodeian marked this conversation as resolved.
extern "C" MC_DLLEXPORT_DEF bool
MCEmscriptenHandleDevicePixelRatioChanged()
{
MCGFloat t_scale = emscripten_get_device_pixel_ratio();
if (t_scale != s_emscripten_device_scale)
{
s_emscripten_device_scale = t_scale;
MCResPlatformHandleScaleChange();
}

return true;
}
75 changes: 63 additions & 12 deletions engine/src/em-stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
#include "graphics_util.h"
#include "globals.h"

#include "region.h"

/* ================================================================
* Stack initialisation
* ================================================================ */
Expand Down Expand Up @@ -109,34 +111,83 @@ MCStack::release_window_buffer()
* View management
* ================================================================ */

static MCStackUpdateCallback s_updatewindow_callback = nullptr;
static void *s_updatewindow_context = nullptr;

bool MCStack::view_platform_dirtyviewonresize() const
{
return true;
}

void
MCStack::view_platform_updatewindow(MCRegionRef p_dirty_region)
void MCStack::view_platform_updatewindowwithcallback(MCRegionRef p_region, MCStackUpdateCallback p_callback, void *p_context)
{
s_updatewindow_callback = p_callback;
s_updatewindow_context = p_context;

view_platform_updatewindow(p_region);

s_updatewindow_callback = nil;
s_updatewindow_context = nil;
}

void MCStack::view_platform_updatewindow(MCRegionRef p_dirty_region)
{
/* FIXME implement HiDPI support */
MCRegionRef t_scaled_region;
t_scaled_region = nil;

MCRegionRef t_screen_region;
t_screen_region = nil;

MCGFloat t_scale;
t_scale = MCResGetPixelScale();

if (t_scale != 1.0)
{
/* UNCHECKED */ MCRegionTransform(p_dirty_region, MCGAffineTransformMakeScale(t_scale, t_scale), t_scaled_region);
t_screen_region = t_scaled_region;
}
else
t_screen_region = p_dirty_region;

view_device_updatewindow(t_screen_region);

if (t_scaled_region != nil)
MCRegionDestroy(t_scaled_region);
}

void MCStack::view_device_updatewindow(MCRegionRef p_region)
Comment thread
livecodeian marked this conversation as resolved.
{
/* dirtyrect() calls that occur prior to configure() being called
* for the first time will result in an update region being too
* big. Restrict to a valid region. */

uint32_t t_window = reinterpret_cast<uint32_t>(window);

MCGRegionRef t_region = MCGRegionRef(p_dirty_region);
MCRectangle t_valid = MCEmscriptenGetWindowRect(t_window);
t_valid.x = t_valid.y = 0;
MCRectangle t_window_rect = MCEmscriptenGetWindowRect(t_window);
MCRectangle t_canvas_rect = MCRectangleGetScaledCeilingRect(t_window_rect, MCResGetPixelScale());
t_canvas_rect.x = t_canvas_rect.y = 0;

MCGRegionIntersectRect(t_region, MCRectangleToMCGIntegerRectangle(t_valid));
MCGRegionRef t_region = MCGRegionRef(p_region);

MCGIntegerRectangle t_rect = MCGRegionGetBounds(t_region);
MCGRegionIntersectRect(t_region, MCRectangleToMCGIntegerRectangle(t_canvas_rect));

MCEmscriptenSyncCanvasSize(t_window, t_valid.width, t_valid.height);

MCHtmlCanvasStackSurface t_surface(t_window, t_rect);
view_surface_redrawwindow(&t_surface, t_region);
MCGIntegerRectangle t_rect = MCGRegionGetBounds(t_region);
MCEmscriptenSyncCanvasSize(t_window, t_canvas_rect.width, t_canvas_rect.height);

// IM-2014-01-30: [[ HiDPI ]] Ensure stack backing scale is set
view_setbackingscale(MCResGetPixelScale());

MCHtmlCanvasStackSurface t_surface(t_window, MCGRegionGetBounds(t_region));
if (t_surface.Lock())
{
// IM-2014-01-31: [[ HiDPI ]] If a callback is given then use it to render to the surface
if (s_updatewindow_callback != nil)
s_updatewindow_callback(&t_surface, (MCRegionRef)t_region, s_updatewindow_context);
else
view_surface_redrawwindow(&t_surface, t_region);

t_surface.Unlock();
}
}

MCRectangle
Expand Down
2 changes: 1 addition & 1 deletion engine/src/stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -1029,7 +1029,7 @@ class MCStack : public MCObject, public MCMixinObjectHandle<MCStack>
uint32_t p_minwidth, uint32_t p_minheight,
uint32_t p_maxwidth, uint32_t p_maxheight);
void view_device_updatewindow(MCRegionRef p_region);
#elif defined(_MOBILE)
#elif defined(_MOBILE) || defined(__EMSCRIPTEN__)

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

Expand Down