Adaptive Display

Howdy Folks,

I have used Corona SDK for a handful of years on gaming projects and have always been pleased with the results. In my day job, I work for a digital agency that builds business apps for very large Fortune 500 brands. Recently someone approached me about using Corona to build one of these apps. Up until now, we’ve always built two native apps, one for Android and one for iOS.

I like the idea of Corona because so much of what my company does is work with artists to produce very custom UI/UX anyhow so the limited number of widgets probably doesn’t matter. However, we didn’t get very far with our prototype before developers and artists were all asking me the same thing: how can we get pixel perfect positioning and size?

I did a bit of research, and came across this article: https://coronalabs.com/blog/2014/10/28/resolution-independence-adaptive-content-scaling-in-corona/. Which is great, and, the example image with the table views and rows is exactly what I’m looking for. That said, I’m not really understanding the nuance. I’ve set my scale to “adaptive”, but an imageRect for example that I set to 100x100 does not appear the same size across the various devices, at least on the emulator. On the Nexus One it looks like a postage stamp but on the iPad Pro it is like half the size in terms of inches.

Text is even more confusing as there seems great variance in the text height and width from one device to the next. The only way I’ve been successfully in getting relatively the same physical height across devices is to size everything as a percentage or ratio of the entire screen. This isn’t terrible in my mind, but its never going to be pixel perfect, and from the view of the artists who are blueprinting the screens, they want to know how units between native iOS (points) and Android (dp/sp) translate.

The fact is right now I have some blueprints in Zeplin that show for example a font as 65-sp and I really don’t have any idea how to achieve the result besides “eye-balling” it and making the height some percent of the screen height. Can someone out there give me some hints? I’d love to be able to use Corona for some of the stuff I’m currently doing native iOS and Android.

Thanks!

Hi.  I’ve experienced the same thing, where you get different results on the simulated devices.

I found that in order to get consistent results while testing in the simulator and while using ‘adaptive’ scaling, I needed to use ‘Custom Device’ and to set the display resolution I need for testing at the time.

Hope this helps.

thanks @roaminggamer–i will give that a try

does anyone know how i translate Points/DP/SP from an artist’s blueprint to the corona coordinate system? even with adaptive scaling i can say for certain that the SP number for example does not translate into corona pixels size

for example 

display.newText( “PROGRESS”, 0, 0, “AvenirNextCondensed-DemiBoldItalic.ttf”, 90 )

does not produce something that matches up with what a 90 SP font looks like in a native android layout

Have you seen:  https://material.google.com/layout/units-measurements.html#units-measurements-scaleable-pixels-sp

This gives most of the math you’re looking for.  Since Apple wants 320 content points, this works out to about 160 dpi for Android devices.

The display.newText() API font height is in Corona Content points.

Rob

Thanks, Rob. And I apologize in advance for my naivety here but is it possible for you or someone to give a real world example? Consider this. I have a font, that has been specified by the designer as 65-sp on Android and 65-pt on iOS. Simply setting the font size parameter to 65 does not yield a consistent result across all devices–regardless of scale mode.

So how do I use the adaptive mode and the display.contentScaleX/Y to first get something that is actually 65-pt on say an iPad mini where the scale is 1:1, and then, adjust itself so that on say an iPad Pro where the scale is .5:.5 it keeps the same physical measurement? I actually thought that this is what the “adaptive” setting was for in the config file but I don’t see that in my testing.

Am I making any sense?

Something like:

subtitle = display.newText( “APP BAKE-OFF”, 0, 0, “AvenirNextCondensed-DemiBoldItalic.ttf”, 65)

subtitle.xScale = 1 + (1-display.contentScaleX)

subtitle.yScale = 1 + (1-display.contentScaleY)

In my mind this would have got everything scaling to essentially 1:1 but clearly from what I am seeing on the simulator my understanding is flawed as the text is huge on an iPhone 4. 

I don’t know how helpful this will be. But I put this together:

local cw = display.newText("contentWidth: " ..display.contentWidth, 10, 20, native.systemFontBold, 12 ) local ch = display.newText("contentHeight: " ..display.contentHeight, 10, 35, native.systemFontBold, 12 ) local acw = display.newText("actualContentWidth: " ..display.contentWidth, 10, 50, native.systemFontBold, 12 ) local ach = display.newText("actualContentHeight: " ..display.contentHeight, 10, 65, native.systemFontBold, 12 ) local csX = display.newText("contentScaleX: " ..display.contentScaleX, 10, 80, native.systemFontBold, 12 ) local csY = display.newText("contentScaleY: " ..display.contentScaleY, 10, 95, native.systemFontBold, 12 ) cw.anchorX = 0 ch.anchorX = 0 acw.anchorX = 0 ach.anchorX = 0 csX.anchorX = 0 csY.anchorX = 0 local guage = display.newLine( display.contentCenterX + 103, 0, display.contentCenterX + 103, display.contentHeight) local lines = {} local values = {} for i = 0, display.contentHeight, 5 do local w = 3 if i % 10 == 0 then w = 6 end if i % 50 == 0 then w = 9 values[i] = display.newText( i, display.contentCenterX + 120, i, native.systemFont, 8) end lines[i+1] = display.newLine( display.contentCenterX - w + 103, i, display.contentCenterX + w + 103, i) end box = display.newRect( display.contentCenterX, display.contentCenterY, 200, 60 ) box:setFillColor( 0, 0, 0.75) subtitle = display.newText( "APP BAKE-OFF", display.contentCenterX, display.contentCenterY, "AvenirNextCondensed-DemiBoldItalic.ttf", 60) --subtitle.xScale = 1 + (1-display.contentScaleX) --subtitle.yScale = 1 + (1-display.contentScaleY)

I made the font and box 60 px so the box wouldn’t be on half pixels when centered. I also commented out the last two lines. If you look at these two screen shots:  iPad + iPhone that I have scaled on the screen to be about the same real size and the Kindle Fire 9" and a Android phone skin. You will see that the box is 60 points high across all the platforms. The text is pretty close. I’ll talk more about that in a bit (I didn’t have your font!).

Adaptive should give you the same size box/text on the different devices presuming we get the right information from the device and with Android that’s not always the case.  The two screen shots should show this. The objects are all the same size you just get more real-estate on the tablets.

Now on to Fonts. Corona is dependent on the operating system’s font rendering. Android won’t generate the same text that iOS does even with the same font. macOS won’t generate the same font as Windows (which impacts the simulators) and macOS won’t generate the same image iOS does. They will all be a little bit different. Android likes to render more white space at the top and bottom of the text than others do. If you use 3rd party fonts, your mileage will vary. Free fonts have more way metrics errors than paid for fonts from the big font foundries and you may find the spacing way off.

Does this help?

@Rob–this is perfect. It definitely spells things out and helped me wrap my head around a few concepts I was missing. If you ever come to Dallas hit me up and I’ll buy you a beer!

Glad to help.

Hi.  I’ve experienced the same thing, where you get different results on the simulated devices.

I found that in order to get consistent results while testing in the simulator and while using ‘adaptive’ scaling, I needed to use ‘Custom Device’ and to set the display resolution I need for testing at the time.

Hope this helps.

thanks @roaminggamer–i will give that a try

does anyone know how i translate Points/DP/SP from an artist’s blueprint to the corona coordinate system? even with adaptive scaling i can say for certain that the SP number for example does not translate into corona pixels size

for example 

display.newText( “PROGRESS”, 0, 0, “AvenirNextCondensed-DemiBoldItalic.ttf”, 90 )

does not produce something that matches up with what a 90 SP font looks like in a native android layout

Have you seen:  https://material.google.com/layout/units-measurements.html#units-measurements-scaleable-pixels-sp

This gives most of the math you’re looking for.  Since Apple wants 320 content points, this works out to about 160 dpi for Android devices.

The display.newText() API font height is in Corona Content points.

Rob

Thanks, Rob. And I apologize in advance for my naivety here but is it possible for you or someone to give a real world example? Consider this. I have a font, that has been specified by the designer as 65-sp on Android and 65-pt on iOS. Simply setting the font size parameter to 65 does not yield a consistent result across all devices–regardless of scale mode.

So how do I use the adaptive mode and the display.contentScaleX/Y to first get something that is actually 65-pt on say an iPad mini where the scale is 1:1, and then, adjust itself so that on say an iPad Pro where the scale is .5:.5 it keeps the same physical measurement? I actually thought that this is what the “adaptive” setting was for in the config file but I don’t see that in my testing.

Am I making any sense?

Something like:

subtitle = display.newText( “APP BAKE-OFF”, 0, 0, “AvenirNextCondensed-DemiBoldItalic.ttf”, 65)

subtitle.xScale = 1 + (1-display.contentScaleX)

subtitle.yScale = 1 + (1-display.contentScaleY)

In my mind this would have got everything scaling to essentially 1:1 but clearly from what I am seeing on the simulator my understanding is flawed as the text is huge on an iPhone 4. 

I don’t know how helpful this will be. But I put this together:

local cw = display.newText("contentWidth: " ..display.contentWidth, 10, 20, native.systemFontBold, 12 ) local ch = display.newText("contentHeight: " ..display.contentHeight, 10, 35, native.systemFontBold, 12 ) local acw = display.newText("actualContentWidth: " ..display.contentWidth, 10, 50, native.systemFontBold, 12 ) local ach = display.newText("actualContentHeight: " ..display.contentHeight, 10, 65, native.systemFontBold, 12 ) local csX = display.newText("contentScaleX: " ..display.contentScaleX, 10, 80, native.systemFontBold, 12 ) local csY = display.newText("contentScaleY: " ..display.contentScaleY, 10, 95, native.systemFontBold, 12 ) cw.anchorX = 0 ch.anchorX = 0 acw.anchorX = 0 ach.anchorX = 0 csX.anchorX = 0 csY.anchorX = 0 local guage = display.newLine( display.contentCenterX + 103, 0, display.contentCenterX + 103, display.contentHeight) local lines = {} local values = {} for i = 0, display.contentHeight, 5 do local w = 3 if i % 10 == 0 then w = 6 end if i % 50 == 0 then w = 9 values[i] = display.newText( i, display.contentCenterX + 120, i, native.systemFont, 8) end lines[i+1] = display.newLine( display.contentCenterX - w + 103, i, display.contentCenterX + w + 103, i) end box = display.newRect( display.contentCenterX, display.contentCenterY, 200, 60 ) box:setFillColor( 0, 0, 0.75) subtitle = display.newText( "APP BAKE-OFF", display.contentCenterX, display.contentCenterY, "AvenirNextCondensed-DemiBoldItalic.ttf", 60) --subtitle.xScale = 1 + (1-display.contentScaleX) --subtitle.yScale = 1 + (1-display.contentScaleY)

I made the font and box 60 px so the box wouldn’t be on half pixels when centered. I also commented out the last two lines. If you look at these two screen shots:  iPad + iPhone that I have scaled on the screen to be about the same real size and the Kindle Fire 9" and a Android phone skin. You will see that the box is 60 points high across all the platforms. The text is pretty close. I’ll talk more about that in a bit (I didn’t have your font!).

Adaptive should give you the same size box/text on the different devices presuming we get the right information from the device and with Android that’s not always the case.  The two screen shots should show this. The objects are all the same size you just get more real-estate on the tablets.

Now on to Fonts. Corona is dependent on the operating system’s font rendering. Android won’t generate the same text that iOS does even with the same font. macOS won’t generate the same font as Windows (which impacts the simulators) and macOS won’t generate the same image iOS does. They will all be a little bit different. Android likes to render more white space at the top and bottom of the text than others do. If you use 3rd party fonts, your mileage will vary. Free fonts have more way metrics errors than paid for fonts from the big font foundries and you may find the spacing way off.

Does this help?

@Rob–this is perfect. It definitely spells things out and helped me wrap my head around a few concepts I was missing. If you ever come to Dallas hit me up and I’ll buy you a beer!

Glad to help.