In this article, we explain how to support high-resolution displays, commonly referred to as HiDPI or Retina displays. The LuciadCPillar map has API that makes it easy to support HiDPI displays. It can scale up map features such as icons, line widths and font sizes in response to the display scale settings of the host operating system (OS). These settings include a display scale that can be adjusted in the operating system to change the size of text, apps, and other items.

The HiDPI support in LuciadCPillar is largely transparent to the user, but you must configure the DPI of your screen and the display scale setting of the host operating system on the map.

Configure the DPI and display scale on the map

To make the map aware of the screen DPI and the display scale setting of the host operating system, you can use these methods:

Impact of the display scale on the UI and on a LuciadCPillar map explains the effect of these settings in more detail.

The display scale can change, because of a change in the host OS settings, or because the application window has moved to a display with a different display scale. Whenever that happens, you must give that information to the Map. How to get the display scale and how to find out that it changed depends on the UI toolkit.

Some UI toolkits, such as Qt, help you detect the DPI of your screen. Others, such as WPF, don’t offer this information. Then it’s up to you to provide this information, and make sure to update it when needed.

The Qt and WPF integration code in the LuciadCPillar samples set the DPI and display scale out-of-the-box. If you’re integrating the map with your UI toolkit yourself, though, you still need to set them. The Qt integration article demonstrates how you can do that.

Impact of the display scale on the UI and on a LuciadCPillar map

If the display scale is anything other than 100%, LuciadCPillar essentially defines 2 coordinate systems:

  • Device-independent coordinates correspond to screen pixels that have been scaled by the display scale setting of the platform or the operating system. You can use these coordinates to reason about the map content without having to think about the display scale. They allow you to write applications that look and behave similarly on any screen.

  • Physical coordinates correspond to the actual physical pixels of the map on the screen.

Figure 1, “Effect of display scale on map size” illustrates how a display scale of 2 determines the device-independent map size of LuciadCPillar application. More formally, the display scale is the amount of physical pixels that are used to cover a logical pixel.

DPI scaling factor
Figure 1. Effect of display scale on map size

In the LuciadCPillar API, these sizes are always expressed in device-independent coordinates to abstract away the display scale:

  • Pixel sizes

  • The map size

  • Line sizes and icon sizes

  • Screen coordinates in input events

When you use transformation methods in Map::getViewMapTransformation, for example, it’s important to know that all pixel coordinates are device-independent coordinates.

Where the API expresses sizes in a device-independent coordinate system, LuciadCPillar renders the map in physical coordinates. To do so, LuciadCPillar automatically adjusts the rendering for the configured display scale:

  • It adapts line widths and font sizes.

  • It uses high-resolution icons if they’re available. See Impact on icon rendering for more information.

The result of these adjustments is a scaled, but still sharp and crisp visualization.

It’s possible that the display scale changes. That can happen if you move the LuciadCPillar application to another screen with a different display scale, for example, or if you change the display scale setting of your current screen. If the display scale changes, the LuciadCPillar map size in device-independent coordinates remains the same, give or take a few pixels. The physical size changes in accordance with the new display scale, though. LuciadCPillar adapts the line widths, icon sizes and text sizes.

The same goes for DPI changes. When moving the Map to a screen with a different DPI, it must be updated as well. Note that for these adaptations to take place, your UI integration code must re-configure the DPI and display scale in the event of a display scale change. This is the case in the included sample code.

Each UI framework may deal with display scales in another way. UI frameworks such as Qt and WPF also build on the idea of device-independent coordinates. If you integrate with such UI frameworks, you can pass MouseEvent coordinates directly to the LuciadCPillar API. If you use a framework that doesn’t use device-independent coordinates, WinForms for example, you must scale the coordinates yourself before passing them to the LuciadCPillar API.

Impact on icon rendering

When a display scale other than 1 is set on the map, icons are stretched out so that the physical size matches expectations on a high-DPI display. The resulting icons look blurry, though, or aren’t detailed enough.

This can be improved when you use an icon that can paint itself in multiple possible resolutions, depending on the display scale of your screen. The IIcon::createPainter method allows the map renderer to retrieve the IIconPainter with the best fit for a particular display scale.

Image icons

To support high-DPI rendering of image-based icons, ImageIcon adopts the @2x naming convention. This convention consists of storing multiple icon versions at different resolutions, to visualize the appropriate one according to the active resolution. For instance, if an image.png needs to be displayed at a display scale of 2.0, the scaled image image@2x.png is used if it’s available.

Vector icons

Examples of vector-based icons are:

  • SVG-based icons

  • Text icons

Vector-based icons are scalable to any resolution. This means that LuciadCPillar can paint these icons on the map without scaling. In other words, the pixels of these icons correspond perfectly to the physical pixels of the screen.

Views and screen DPI

Although the display scale setting is usually enabled because a screen has a high DPI, it’s largely independent of the DPI. A 1-pixel-wide line is rendered with two pixels if the display scale is 2.0, no matter if the view DPI is 72, 144, or 200. For example, a 4k screen on a 15" laptop has a much higher DPI than a 4k 32" desktop monitor.

This setting has a significant impact on API that uses map scales. People typically reason in terms of fractional paper map scales: 1:10000. If it’s necessary that 1 cm on the screen corresponds with 10 km, you must configure the DPI correctly.

LuciadCPillar makes use of such map scales in this API: