revUp - Updates and news for the LiveCode community
Issue 157 | September 20th 2013 Contact the Editor | How to Contribute

Resolution Independence
Check out the latest 6.5 dp 1 developer test release to see this important new feature in action

By Michael McCreary

In just under a year the people of Scotland will go to the polls to vote in the Scottish independence referendum. We at RunRev headquarters however, have been busy fighting a much more important campaign. The campaign for Resolution Independence. For too long have the points been ruled over by the pixels. It's time they were set free. We're not going to lie, it's been an arduous battle with many a below belt shot being thrown. But we got there in the end. And this is the story of how...

Resolution Independence

What is Resolution Independence?
So what is resolution independence? In spite of what is written above, it's not the battle to set the ancient nation of resolution free. It's so much more than that. In a nutshell, resolution independence means that an app can be designed using an abstract pixel density and then have that automatically map to the pixel density of the display with no loss of quality.

Traditionally, the programmer has been more concerned with the resolution of a device, be it a desktop computer or a mobile phone, rather than it's pixel density. The resolution of a device is simply the number of pixels wide and high it is. For example 1024x768 or 960x640. The pixel density is the number of pixels the device packs in to an area, measured in pixels per inch (PPI).

Whilst it's important for the programmer to take these numbers into consideration, it's often not the best way to do things. For example, I'm sure many of you will have experienced writing an app designed for a non-retina iPhone only to find everything at half the size when run on a retina device, in spite of the physical dimensions of the device being the same.

The doubling in resolution between non-retina and retina devices is not to give the programmer more screen real estate to work with but rather to improve the crispness and quality of the display. Notionally both device types have the same dimensions, it's just the pixel density is doubled on retina devices. And that's the way the programmer should think of things. Rather than being concerned with the specific density and resolution, the programmer should layout their apps for an abstract density and resolution, letting LiveCode and the device's operating system take care of all the scaling.

This means that the app you designed for non-retina devices will now automatically scale up to fit nicely on retina devices whilst taking advantage of the extra quality the higher density device offers. And this doesn't just apply to iPhones. Android devices as well as most desktop OSs now all support a variety of different pixel densities.

It's important to note that whilst resolution independence will take care of the scaling of your app, it won't position controls for devices with different aspect ratios. That's a different problem and one that currently the programmer must take care of.

So how do I use it?
A good way to think about things is to divorce yourself from the notion of pixels and think about things in points. Rather than thinking of your stack as having dimensions in pixels at a specific density, think of its dimensions in points at an abstract density, with this abstract density being the "natural density" of the OS.

So, for iOS, the natural density is that of the non-retina resolutions. The programmer should think of their stack as a set of points at non-retina resolutions. When it comes to running the stack on retina devices (which are at twice the density), LiveCode will take care of all the scaling.

This notion of "natural density" and "hi-density" applies to most OSs:

  • iOS screens are either retina or non-retina, with the natural density being the non-retina resolutions. Retina screens are twice the density of non-retina.
  • Android screens fall in to one of four density categories - low (0.75x), medium (1x), high (1.5x), extra-high (2x). Medium is considered to be the natural density. Some devices have a "TV" screen density, at 1.33x scale.
  • Hi-density support was added to Windows in Vista. The density of the display from the application's point of view can be adjusted, with the natural density being 96dpi.
  • Mac has a similar hi-density support to Windows Vista, with the natural density of the Mac screen being 72dpi.

But what do I need to do?
By this point you are most likely wondering how this newfound independence affects the programmer? Well, apart from greater economic prosperity and a more integrated public transport system, programming wise very little has changed. Indeed, coding for multiple densities is an entirely invisible process. From the point of view of the app everything appears as if the screen is the "natural" density. In particular:

  • import / export snapshot work in points, not pixels - i.e they produce images at point resolution
  • imageData (maskData/alphaData) of images work in points, not pixels
  • intersections work in points
  • hit detection works in points
  • the screenRect properties and stack rect are given in points

What about images?
Okay, not everything has remained the same. Whilst text and vector operations scale naturally, this is not true of images. To take full advantage of hi-density displays, images should be provided at appropriate sizes for different densities. The programmer can do this by having multiple image files in the same location named appropriately (with the image object referencing the image file at the natural density). The naming convention is as follows:

  • <image>@ultra-low.<ex> - 0.25x
  • <image>@extra-low.<ext> - 0.5x
  • <image>@low.<ext> - 0.75x
  • <image>@medium.<ext> / <image>.<ext> - 1x
  • <image>@high.<ext> - 1.5x
  • <image>@extra-high.<ext> / <image>@2x - 2x
  • <image>@ultra-high.<ext> - 4x

When an image is required, the current scale factor is rounded up to the nearest standard density (one of 0.25, 0.5, 0.75, 1, 1.5, 2 and 4). The image with the lowest scale factor that is greater or equal to the nearest standard density is then selected. For example, if the scale factor is 1.75 and there is an 'extra-high' image available that is used.

What about displays with different aspect ratios?
As mentioned, resolution independence only takes care of scaling. The positioning of controls within a stack remains the same. However, if you are making a full screen app there is some assistance to be had in the form of a new full screen scaling mode. (note, this feature is not present in 6.5 DP1 but will be added to future releases.)

The scaling mode can be one of the following:

  • empty (default) - the existing behaviour - the stack is resized (not scaled) to fit the screen.
  • "exact fit" - scale the stack to fill the screen. This will stretch the stack if the aspect ratio of the screen does not match that of the stack.
  • "show all" - scale the stack preserving aspect ratio so all content is visible. Some blank space may remain if the screen & stack aspect ratios do not match.
  • "no border" - scale the stack to fill the screen preserving aspect ratio. If the stack & screen aspect ratios do not match, the left / right or top / bottom extremes of the stack will not be visible.
  • "no scale" - the stack will not be scaled, being centred on the screen instead.

Potentially most interesting is the "no border" mode. This allows developers to produce their app with a core viewable area that will be visible on all devices. The contents outside of this core area can be thought of as just background that will be clipped on certain devices where the aspect ratio of screen does not match that of the stack.

What's In 6.5 DP1?
6.5 DP1 is the first developer preview offering support for resolution independence. Currently only the mobile platforms are supported. The plan is to add support for full screen scaling and the desktop platforms in future releases.

We urge all those interested to try these early releases out. Though on the surface, not much has changed, internally a lot of restructuring has gone on. This is full independence, not devolution max! The more people that test it on the widest range of devices possible, the better.

Specifically, LiveCode's graphics layer has been completely re-written, including both image and text rendering. As such, nearly every one of LiveCode's drawing routines have been touched. Where possible, we've tried to match previous behavior as closely as possible, but we do expect some rendering glitches in early DPs. Please report any you find, in our Quality Center, and we'll get right on to addressing them so that the final release of 6.5 is as solid and stable as possible.

Though the primary reason for the update is to support resolution independence, we do get the side benefits of having a modern 2D graphics library. This includes a clean developer API allowing for easy integration into other modules, potential performance improvements, transparent pattern support and support for graphic rendering on the server platforms (planned for a future release).

So there you have it, independence has been achieved. The points have been set free. But this is only the beginning. Much has changed and we need your help to make sure we get everything right.

Michael McCreary

About the Author

Michael McCreary is Technical Lead on the LiveCode Development Team.

 

Main Menu

What's New


App To Market