Calculating actual boundaries of your application and device screen size

Posted by mmagrilov, Posted on January 13, 2012, Last updated February 16, 2012

5 votes
GitHub URL: 
https://github.com/mmagrilov/Boundaries

When you develop some Corona application, you most probably use some content scaling option specified in your config.lua file. Content scaling is described perfectly in this blog post:

http://blog.anscamobile.com/2010/11/content-scaling-made-easy/

As you can see from this post, the most “popular” scaling mode is letterbox: “When in doubt, the mode you will probably want is “letterbox”, which is guaranteed to neither crop nor distort your main content region. This scaling mode is named “letterbox” because the effect is similar to playing a widescreen movie on an older TV set: all onstage content is visible, but there may be extra screen area beyond it.”

Moreover, you can use this extra screen area just as any other area of the screen: “unlike the movie example, these extra areas do not have to be black bars, and are not cropped or masked. Instead, they can be filled with any Corona elements you like. To borrow a printshop term, there may be extra “bleed” area around your main content region, either at the top and bottom or on the sides.”

But when you want to know the exact boundaries of what you are going to see on the screen, you discover that there isn’t any direct way to do it.

It can be important, for example, if you want to place your controls in the corners of the screen. But what are X/Y coordinates of those corners? You don’t know. And what, by the way, is the size of the screen on your device? This esoteric knowledge is also hidden from you for some unclear reason.

Of course, there are display.viewableContentHeight and display.viewableContentWidth properties but in the case of letterbox scaling mode they return values equal to the application width and height as defined in config.lua (because all this area is “viewable”) and don’t take into account any visible extra area.

In order to figure out the size of this extra area you should use other methods. The overall size of the screen is still unknown but you can use display.screenOriginX and display.screenOriginY to determine where the upper and left boundaries of the screen are. For example, if height value in config.lua is 480 and screen size (that you don’t know) is, say, 550, then display.screenOriginY will be -(550-480)/2 = -35. This value is Y coordinate of the upper edge of the actual visible area of your application – let’s call it minVisibleY.

A remark: this calculation of screenOriginY is true only when yAlign parameter in config.lua is equal to "center" (or not specified) and the “bleed” area is therefore distributed evenly above and below the “height” defined in config.lua. There are two other yAlign options (“top” and “bottom”) but “center” is default and I don’t see any reason to use alternative options.

Anyway, if yAlign = “bottom”, display.screenOriginY = -(550-480) = 70;
if yAlign = “top”, display.screenOriginY = 0;

minVisibleY is always equal to display.screenOriginY.

The situation is similar for X coordinate: minVisibleX value is equal to display.screenOriginX and there are three options for xAlign setting: “center”, “right” and “left”, “center” being the default value.

Now you know coordinates of upper and left boundaries of your screen. Is there any way to calculate them for bottom and right boundaries?

If yAlign = “center”, there are two equal “margins”, above and below.
Then:

1
maxVisibleY = display.viewableContentHeight + -1* display.screenOriginY

("minus" – because display.screenOriginY is negative).

If yAlign = “bottom” , there is only one “margin”, above the application height defined in config.lua.
Then:

1
 maxVisibleY = display.viewableContentHeight

If yAlign = “top” … well, then all the “bleed area” is below the “height” and there is no way to calculate its size because display.screenOriginY = 0.

For X coordinate:

If xAlign = “center” , there are two equal “margins”, left and right.
Then:

1
maxVisibleX = display.viewableContentWidth + -1* display.screenOriginX

If xAlign = “right” , there is only one “margin”, left to the application width defined in config.lua.
Then:

1
maxVisibleX = display.viewableContentWidth

If xAlign = “left” you cannot calculate maxVisibleX.

Now you can place your buttons at the actual corners of the screen and you can even calculate its size:

1
2
screenHeight = maxVisibleY - display.screenOriginY
screenWidth  = maxVisibleX - display.screenOriginX

Of course, these values are calculated in “application” pixels and don’t take into account any scaling, so we can call them screenHeightAppPix and screenWidthAppPix.

In order to calculate physical size of the screen (I mean pixels, not inches), use

display.contentScaleX/Y:

1
2
screenHeightPhysPix  = math.floor(screenHeightAppPix / display.contentScaleY + 0.51)
screenWidthPhysPix   = math.floor(screenWidthAppPix / display.contentScaleX + 0.51)

Of course, because of rounding errors there may be always a difference of pixel or two between these calculated values and actual size of the screen; I used 0.51 instead of 0.5 in order to minimize it but you cannot totally eliminate it when your application size as defined in config.lua is much smaller than the real size of the screen.

In order to illustrate these methods I wrote a small application (“Boundaries”) that you can download from Github.
All the above calculations are packed there as methods of DynResManager module whose main function is handling dynamic resolution images with no need to specify size of each image (see this post: http://developer.anscamobile.com/code/different-way-managing-dynamic-image-resolution-and-scaling-font-size ). Size/boundaries calculations in this module are more complicated than in the above text because they take into account scaling mode and yAlign / xAlign parameters so that you can use them for “zoomeven” scaling mode, ”bottom” option of yAlign and ”right” option of xAlign.

Here you can see some screenshots of the example application:


Replies

Naomi's picture
Naomi
User offline. Last seen 15 min 1 sec ago. Offline
Joined: 6 Jun 2011

Wow, @mmagrilov, thank you for sharing this!

Naomi

canupa.com's picture
canupa.com
User offline. Last seen 5 hours 49 min ago. Offline
Joined: 20 Jun 2011

I will definitely take a look into the sample project. thanks for sharing!

-finefin

mmagrilov
User offline. Last seen 2 days 18 hours ago. Offline
Joined: 3 May 2011

Hi Naomi & finefin, thank you for your responses!

Michael

anders.j
User offline. Last seen 1 day 13 hours ago. Offline
Joined: 9 May 2011

Thanks Michael - perfect explanation, certainly saved me some time!

eduardo.pinheiro
User offline. Last seen 17 weeks 19 hours ago. Offline
Joined: 10 Jan 2012

[removed]

RegieC's picture
RegieC
User offline. Last seen 1 week 1 day ago. Offline
Joined: 27 Jan 2012

Thanks! very helpful and great post!

dutchottie
User offline. Last seen 12 hours 30 min ago. Offline
Joined: 1 Feb 2012

Excellent!
This really makes all the scaling and fitting easier.
Thanks.