void MCStack::setacceleratedrendering(bool p_value) { // If we are turning accelerated rendering off, then destroy the tilecache. if (!p_value) { MCTileCacheDestroy(m_tilecache); m_tilecache = nil; // MW-2012-03-15: [[ Bug ]] Make sure we dirty the stack to ensure all the // layer mode attrs are rest. dirtyall(); return; } // If we are turning accelerated rendering on, and we already have a tile- // cache, then do nothing. if (m_tilecache != nil) return; // Otherwise, we configure based on platform settings. int32_t t_tile_size; int32_t t_cache_limit; MCTileCacheCompositorType t_compositor_type; #ifdef _MAC_DESKTOP t_compositor_type = kMCTileCacheCompositorCoreGraphics; t_tile_size = 32; t_cache_limit = 32 * 1024 * 1024; #elif defined(_WINDOWS_DESKTOP) || defined(_LINUX_DESKTOP) t_compositor_type = kMCTileCacheCompositorSoftware; t_tile_size = 32; t_cache_limit = 32 * 1024 * 1024; #elif defined(_IOS_MOBILE) || defined(_ANDROID_MOBILE) t_compositor_type = kMCTileCacheCompositorStaticOpenGL; const MCDisplay *t_display; MCscreen -> getdisplays(t_display, false); MCRectangle t_viewport; t_viewport = t_display -> viewport; bool t_small_screen, t_medium_screen; t_small_screen = MCMin(t_viewport . width, t_viewport . height) <= 480 && MCMax(t_viewport . width, t_viewport . height) <= 640; t_medium_screen = MCMin(t_viewport . width, t_viewport . height) <= 768 && MCMax(t_viewport . width, t_viewport . height) <= 1024; if (t_small_screen) t_tile_size = 32, t_cache_limit = 16 * 1024 * 1024; else if (t_medium_screen) t_tile_size = 64, t_cache_limit = 32 * 1024 * 1024; else t_tile_size = 64, t_cache_limit = 64 * 1024 * 1024; #endif MCTileCacheCreate(t_tile_size, t_cache_limit, m_tilecache); MCTileCacheSetViewport(m_tilecache, curcard -> getrect()); MCTileCacheSetCompositor(m_tilecache, t_compositor_type); dirtyall(); }
static bool MCTextLayoutFontWithLink(MCTextLayoutFont *p_base, MCTextLayoutLinkedFontEntry *p_link, MCTextLayoutFont*& r_font) { LOGFONTA t_logfont; t_logfont = p_base -> info; MCMemoryCopy(&t_logfont . lfFaceName, p_link -> face, MCMax(MCCStringLength(p_link -> face) + 1, sizeof(t_logfont . lfFaceName))); MCTextLayoutFont *t_font; t_font = MCTextLayoutFontFind(t_logfont); if (t_font != nil) { r_font = t_font; return true; } HFONT t_hfont; t_hfont = CreateFontIndirectA(&t_logfont); if (t_hfont == nil) return false; bool t_success; t_success = MCTextLayoutFontFromHFONT(t_hfont, t_font); DeleteObject(t_hfont); r_font = t_font; return t_success; }
// IM-2014-01-28: [[ HiDPI ]] Return the DPI scale factor of the main screen. // This gives us the pixelscale for system-DPI-aware applications. MCGFloat MCWin32GetLogicalToScreenScale(void) { // TODO - determine the correct value on Win8.1 - this may depend on the display in question uint32_t t_x, t_y; /* UNCHECKED */ MCWin32GetScreenDPI(t_x, t_y); return (MCGFloat) MCMax(t_x, t_y) / NORMAL_DENSITY; }
// IM-2014-01-28: [[ HiDPI ]] Return the DPI scale factor of the given monitor. // For system-DPI-aware applications this will be the global system DPI value. // For Per-Monitor-DPI-aware applications, this will be the effective DPI scale of the given monitor bool MCWin32GetMonitorPixelScale(HMONITOR p_monitor, MCGFloat &r_pixel_scale) { uint32_t t_xdpi, t_ydpi; // try to get per-monitor DPI setting if (!MCWin32GetDPIForMonitor(p_monitor, t_xdpi, t_ydpi) && // fallback to the global system DPI setting !MCWin32GetScreenDPI(t_xdpi, t_ydpi)) return false; r_pixel_scale = (MCGFloat)MCMax(t_xdpi, t_ydpi) / NORMAL_DENSITY; return true; }
// IM-2014-01-28: [[ HiDPI ]] Return the DPI scale factor of the main screen. // This gives us the pixelscale for system-DPI-aware applications. MCGFloat MCWin32GetLogicalToScreenScale(void) { // TODO - determine the correct value on Win8.1 - this may depend on the display in question // IM-2014-08-08: [[ Bug 12372 ]] If pixel scaling is disabled, then // we don't need to scale from logical -> screen. if (!MCResGetUsePixelScaling()) return 1.0; uint32_t t_x, t_y; /* UNCHECKED */ MCWin32GetScreenDPI(t_x, t_y); return (MCGFloat) MCMax(t_x, t_y) / NORMAL_DENSITY; }
bool MCResampledImageRep::LoadImageFrames(MCBitmapFrame *&r_frames, uindex_t &r_frame_count, bool &r_frames_premultiplied) { uindex_t t_src_width, t_src_height; if (!m_source->GetGeometry(t_src_width, t_src_height)) return false; bool t_success = true; MCBitmapFrame *t_frames = nil; uindex_t t_frame_count = 0; t_frame_count = m_source->GetFrameCount(); // IM-2013-07-03: [[ Bug 11018 ]] fail here if the source has no frames t_success = t_frame_count != 0; if (t_success) t_success = MCMemoryNewArray(t_frame_count, t_frames); MCGFloat t_scale; t_scale = MCMax(m_target_width / (float)t_src_width, m_target_height / (float)t_src_height); for (uindex_t i = 0; t_success && i < t_frame_count; i++) { MCBitmapFrame *t_src_frame = nil; t_success = m_source->LockBitmapFrame(i, t_scale, t_src_frame); if (t_success) { t_frames[i].duration = t_src_frame->duration; t_success = MCImageScaleBitmap(t_src_frame->image, m_target_width, m_target_height, INTERPOLATION_BICUBIC, t_frames[i].image); if (t_success) MCImageFlipBitmapInPlace(t_frames[i].image, m_h_flip, m_v_flip); } m_source->UnlockBitmapFrame(i, t_src_frame); } if (t_success) { r_frames = t_frames; r_frame_count = t_frame_count; r_frames_premultiplied = false; } else MCImageFreeFrames(t_frames, t_frame_count); return t_success; }
MCGAffineTransform view_get_stack_transform(MCStackFullscreenMode p_mode, MCRectangle p_stack_rect, MCRectangle p_screen_rect) { MCGFloat t_scale; MCGAffineTransform t_transform; switch (p_mode) { case kMCStackFullscreenModeNone: return MCGAffineTransformMakeIdentity(); case kMCStackFullscreenResize: return MCGAffineTransformMakeIdentity(); case kMCStackFullscreenExactFit: return MCGAffineTransformMakeScale((MCGFloat)p_screen_rect.width / (MCGFloat)p_stack_rect.width, (MCGFloat)p_screen_rect.height / (MCGFloat)p_stack_rect.height); case kMCStackFullscreenLetterbox: case kMCStackFullscreenShowAll: t_scale = MCMin((MCGFloat)p_screen_rect.width / (MCGFloat)p_stack_rect.width, (MCGFloat)p_screen_rect.height / (MCGFloat)p_stack_rect.height); t_transform = MCGAffineTransformMakeTranslation(-(MCGFloat)p_stack_rect.width / 2.0, -(MCGFloat)p_stack_rect.height / 2.0); t_transform = MCGAffineTransformPreScale(t_transform, t_scale, t_scale); t_transform = MCGAffineTransformPreTranslate(t_transform, (MCGFloat)p_screen_rect.width / 2.0, (MCGFloat)p_screen_rect.height / 2.0); return t_transform; case kMCStackFullscreenNoBorder: t_scale = MCMax((MCGFloat)p_screen_rect.width / (MCGFloat)p_stack_rect.width, (MCGFloat)p_screen_rect.height / (MCGFloat)p_stack_rect.height); t_transform = MCGAffineTransformMakeTranslation(-(MCGFloat)p_stack_rect.width / 2.0, -(MCGFloat)p_stack_rect.height / 2.0); t_transform = MCGAffineTransformPreScale(t_transform, t_scale, t_scale); t_transform = MCGAffineTransformPreTranslate(t_transform, (MCGFloat)p_screen_rect.width / 2.0, (MCGFloat)p_screen_rect.height / 2.0); return t_transform; case kMCStackFullscreenNoScale: // offset so stack is centered in screen MCRectangle t_rect; t_rect = MCU_center_rect(p_screen_rect, p_stack_rect); // IM-2013-12-19: [[ Bug 11590 ]] Adjust for screen rect origins other than 0,0 return MCGAffineTransformMakeTranslation(t_rect.x - p_screen_rect.x, t_rect.y - p_screen_rect.y); default: MCUnreachableReturn(MCGAffineTransformMakeIdentity()); } }
// IM-2014-01-28: [[ HiDPI ]] Return the DPI scale factor of the given monitor. // For system-DPI-aware applications this will be the global system DPI value. // For Per-Monitor-DPI-aware applications, this will be the effective DPI scale of the given monitor bool MCWin32GetMonitorPixelScale(HMONITOR p_monitor, MCGFloat &r_pixel_scale) { UINT t_xdpi, t_ydpi; HRESULT t_result; // try to get per-monitor DPI setting if (!MCWin32GetDPIForMonitor(t_result, p_monitor, kMCWin32MDTDefault, &t_xdpi, &t_ydpi) || t_result != S_OK) { // fallback to the global system DPI setting uint32_t t_screen_xdpi, t_screen_ydpi; if (!MCWin32GetScreenDPI(t_screen_xdpi, t_screen_ydpi)) return false; t_xdpi = t_screen_xdpi; t_ydpi = t_screen_ydpi; } r_pixel_scale = (MCGFloat)MCMax(t_xdpi, t_ydpi) / NORMAL_DENSITY; return true; }
void MCStack::view_setacceleratedrendering(bool p_value) { #ifdef _SERVER // We don't have accelerated rendering on Server return; #else // If we are turning accelerated rendering off, then destroy the tilecache. if (!p_value) { MCTileCacheDestroy(m_view_tilecache); m_view_tilecache = nil; // MW-2012-03-15: [[ Bug ]] Make sure we dirty the stack to ensure all the // layer mode attrs are rest. dirtyall(); return; } // If we are turning accelerated rendering on, and we already have a tile- // cache, then do nothing. if (m_view_tilecache != nil) return; // Otherwise, we configure based on platform settings. int32_t t_tile_size; int32_t t_cache_limit; MCTileCacheCompositorType t_compositor_type; #ifdef _MAC_DESKTOP t_compositor_type = kMCTileCacheCompositorCoreGraphics; t_tile_size = 32; t_cache_limit = 32 * 1024 * 1024; #elif defined(_WINDOWS_DESKTOP) || defined(_LINUX_DESKTOP) || defined(__EMSCRIPTEN__) t_compositor_type = kMCTileCacheCompositorSoftware; t_tile_size = 32; t_cache_limit = 32 * 1024 * 1024; #elif defined(_IOS_MOBILE) || defined(_ANDROID_MOBILE) t_compositor_type = kMCTileCacheCompositorStaticOpenGL; const MCDisplay *t_display; MCscreen -> getdisplays(t_display, false); MCRectangle t_viewport; t_viewport = t_display -> viewport; // IM-2014-01-30: [[ HiDPI ]] Use backing-surface size to determine small, medium, or large t_viewport = MCRectangleGetScaledBounds(t_viewport, view_getbackingscale()); bool t_small_screen, t_medium_screen; t_small_screen = MCMin(t_viewport . width, t_viewport . height) <= 480 && MCMax(t_viewport . width, t_viewport . height) <= 640; t_medium_screen = MCMin(t_viewport . width, t_viewport . height) <= 768 && MCMax(t_viewport . width, t_viewport . height) <= 1024; if (t_small_screen) t_tile_size = 32, t_cache_limit = 16 * 1024 * 1024; else if (t_medium_screen) t_tile_size = 64, t_cache_limit = 32 * 1024 * 1024; else t_tile_size = 64, t_cache_limit = 64 * 1024 * 1024; #else # error "No tile cache implementation defined for this platform" #endif MCTileCacheCreate(t_tile_size, t_cache_limit, m_view_tilecache); view_updatetilecacheviewport(); MCTileCacheSetCompositor(m_view_tilecache, t_compositor_type); dirtyall(); #endif /* !_SERVER */ }