With the increasing popularity of high-resolution monitors, one of the biggest usability problems today is the display size of text and UI controls, because they appear smaller as the screen resolution increases. The recommended advice to overcome this is to increase the DPI (dots-per-inch) setting of the system, thereby enlarging these elements and making them easier to see and read. If you’ve been using Windows Vista and above you’ve probably already seen this Control Panel applet that allows you to easily change your DPI settings:
However, unless an application is designed to be DPI-aware this can result in some unsatisfactory results, such as over-large fonts, clipped controls and blurry windows. This is because many older Windows applications assume a constant DPI (96) when setting font and size coordinates and they do not apply any scaling to these values, thereby resulting in the aforementioned problems.
(NB. The “magic number” of 96 that you’ll see throughout this post is due to the fact that at 96 DPI one logical pixel is equal to one screen pixel – this is the “100%” setting in the Control Panel applet shown above).
In an effort to accommodate these applications Microsoft have introduced a couple of OS features over the years:
- On Windows XP the system fonts and some system UI elements are scaled up at runtime, but this leads to the common problem of text appearing larger and being clipped as the actual size of the bounding control is usually not scaled.
- On Windows Vista and above a feature called “DPI-virtualization” automatically scales windows belonging to an application not marked as “DPI-aware” – in effect they are rendered at 96 DPI to an off-screen bitmap, resized, and then drawn to the screen, but this can result in some blurry windows due to pixel stretching. OpenInsight 10 is marked as a DPI-aware application so will not be subjected to DPI-virtualization.
OpenInsight 10, High-DPI and automatic scaling.
OpenInsight 10 supports High-DPI by automatically scaling-up all GUI objects at runtime when created through the SYSTEM object’s CREATE method (formerly known as the “Utility CREATE service”). This affects the following two properties:
- Size coordinates
The actual scaling for coordinates is calculated by the following simple formula:
screenPixels = logicalPixels * ( currentDPI / 96 )
For example, if you create a control with a size of 200×100 and you are running at 144 DPI (i.e. 150% as per the Control Panel applet above) then the control will be created with an actual size of 300×150 pixels.
The font point size is similarly multiplied by the scaling factor (i.e. currentDPI / 96 ).
Supporting images under High-DPI
Another noticeable issue when running at high DPI settings are images, which are assumed to have been designed for 96 DPI and therefore have to be scaled up at runtime leading to a potential loss of quality due to the resize. To help with this the tool-set has been extended to allow repository BITMAP entities to specify multiple image files when being defined. The first will be used for 96 DPI (100%), the second for up to 120 DPI (125%), the third for up to 144 DPI (150%) the fourth for up to 192 DPI (200%) and so on, with further images being defined at 48 DPI (50%) increments (for future-proofing). When a control is created at runtime the system picks the appropriate image size and scales it as needed (preferably down where possible) before applying any other transformations.
Note that this does NOT apply to images set at runtime in code via the BITMAP property. In this case the developer is assumed to have selected the correct image file size regardless of the DPI setting.
Designing under High-DPI
If you design your forms when running under a High-DPI setting the Form Designer will save and compile all coordinate and font information as though you were developing at 96DPI, so the values will be scaled down appropriately.
Opting out of automatic scaling
Of course, we always try our best not to break existing applications so you can set an option in the RXI file to turn off the automatic DPI scaling if you wish (this option is exposed at runtime via the read-only SYSTEM DPISCALING property).
This same principle can also be applied to individual windows at design-time so you can use it selectively as needed (WINDOW objects also support the read-only DPISCALING property).
If you want to find out more information on this topic please see the following link to Microsoft’s documentation on MSDN:
Writing High-DPI Win32 Applications
(Disclaimer: This article is based on preliminary information and may be subject to change in the final release version of OpenInsight 10).
I would have thought that a simpler option was to provide for a much larger bitmap that scaled down to the size displayed. So, for example a 400×400 image would be scaled down to 100×100 display area. That way if the area increased to say 200×200 the original image would still be fine to scale down to the new size.
Of course, supporting a scale-able image format would be good too :-).
You can certainly do that, but with any sort of scaling the results aren’t always 100% accurate, So the option is there for you to use resolution specific images if you desire – it’s your call if you don’t and a “size-to-fit” approach is good enough for you 🙂
Pingback: OpenInsight and High-DPI – Part 2 | Building OpenInsight 10
Pingback: The SCALEFACTOR property | Building OpenInsight 10