From 0fd8a4507c2d5e28767e12c76b0e04defbef8925 Mon Sep 17 00:00:00 2001 From: Alexandre Wilhelm Date: Wed, 17 Sep 2014 10:27:26 -0700 Subject: [PATCH] New: possibility to draw automatically in high DPI in canvas2D Previously, Cappuccino didn't handle retina device when drawing for canvas2D. Now it does. To do that, Cappuccino will firstly calculate the pixel ratio of the current device, then it needs to change the css style of the canvas by multiply it by the current pixel ratio and finally scale the canvas by this pixel ratio. More information about high DPI drawing here : http://www.html5rocks.com/en/tutorials/canvas/hidpi/ Added the method `setAllowsHighDPIDrawing:` and `allowsHighDPIDrawing` to deactivate or activate this feature. Fixed #2175 --- AppKit/CPCompatibility.j | 9 +++++++++ AppKit/CPView.j | 28 ++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/AppKit/CPCompatibility.j b/AppKit/CPCompatibility.j index c471c1408..09de88aff 100644 --- a/AppKit/CPCompatibility.j +++ b/AppKit/CPCompatibility.j @@ -434,3 +434,12 @@ function CPBrowserCSSProperty(aProperty) return browserProperty.toLowerCase(); } + +function CPBrowserBackingStorePixelRatio(context) +{ + return context.webkitBackingStorePixelRatio || + context.mozBackingStorePixelRatio || + context.msBackingStorePixelRatio || + context.oBackingStorePixelRatio || + context.backingStorePixelRatio || 1; +} diff --git a/AppKit/CPView.j b/AppKit/CPView.j index 3ceb92f6e..2e37d2c3b 100644 --- a/AppKit/CPView.j +++ b/AppKit/CPView.j @@ -126,6 +126,8 @@ var CPViewFlags = { }, CPViewHasCustomDrawRect = 1 << 0, CPViewHasCustomLayoutSubviews = 1 << 1; +var CPViewAllowsHighDPIDrawing = YES; + /*! @ingroup appkit @@ -261,6 +263,24 @@ var CPViewFlags = { }, return [super _binderClassForBinding:aBinding]; } +/*! + Controls wheter the high DPI drawing is actived or not. By default YES. + @param isActive YES to allow the high DPI drawing, otherwise NO. +*/ ++ (void)setAllowsHighDPIDrawing:(BOOL)isActive +{ + CPViewAllowsHighDPIDrawing = isActive; +} + +/*! + Return YES if the high DPI drawing is actived or not, otherwise NO. + @return BOOL - YES if the high DPI drawing is actived or not, otherwise NO. +*/ ++ (BOOL)allowsHighDPIDrawing +{ + return CPViewAllowsHighDPIDrawing; +} + - (void)_setupViewFlags { var theClass = [self class], @@ -2456,7 +2476,10 @@ setBoundsOrigin: #if PLATFORM(DOM) var width = CGRectGetWidth(_frame), - height = CGRectGetHeight(_frame); + height = CGRectGetHeight(_frame), + devicePixelRatio = window.devicePixelRatio || 1, + backingStoreRatio = CPBrowserBackingStorePixelRatio(graphicsPort), + ratio = CPViewAllowsHighDPIDrawing ? (devicePixelRatio / backingStoreRatio) : 1; _DOMContentsElement = graphicsPort.DOMElement; @@ -2466,7 +2489,7 @@ setBoundsOrigin: _DOMContentsElement.style.position = "absolute"; _DOMContentsElement.style.visibility = "visible"; - CPDOMDisplayServerSetSize(_DOMContentsElement, width, height); + CPDOMDisplayServerSetSize(_DOMContentsElement, width * ratio, height * ratio); CPDOMDisplayServerSetStyleLeftTop(_DOMContentsElement, NULL, 0.0, 0.0); CPDOMDisplayServerSetStyleSize(_DOMContentsElement, width, height); @@ -2476,6 +2499,7 @@ setBoundsOrigin: if (CPPlatformHasBug(CPCanvasParentDrawErrorsOnMovementBug)) _DOMElement.style.webkitTransform = 'translateX(0)'; + CGContextScaleCTM(graphicsPort, ratio, ratio); CPDOMDisplayServerAppendChild(_DOMElement, _DOMContentsElement); #endif _graphicsContext = [CPGraphicsContext graphicsContextWithGraphicsPort:graphicsPort flipped:YES];