In this article, we explain how to support high-resolution displays, commonly referred to as HiDPI or Retina displays. Both the Lightspeed view and the GXY view support HiDPI displays out-of-the-box, meaning that map features such as icons, line widths and font sizes are automatically scaled up in response to the DPI scale settings of the host operating system. These settings include a DPI scale factor that can be adjusted in the operating system to change the size of text, apps and other items.
The HiDPI support in LuciadLightspeed is largely transparent to the user, but you need to take care if you are using
ALspViewXYZWorldTransformation
to transform back and forth between pixel and world coordinates.
One such use case is the creation of a custom controller that interprets mouse events.
Impact of the DPI scaling factor on the UI and a Lightspeed map
The figure below illustrates the impact of the DPI scaling factor on UI components.
When using a DPI scaling factor other than 100%, the Java runtime environment essentially creates
an additional coordinate system. Let us refer to this system as "toolkit coordinates". Toolkit
coordinates correspond to screen pixels that have been scaled by the DPI scaling factor. If the
DPI scale is 150%, for instance, then the size of the window is equal to the size of screen divided by 1.5 for
both the X and Y axes. All UI components will express their dimensions and locations in toolkit coordinates.
This means that the width and height reported by, for instance, a JPanel
will be smaller than the panel’s size
in actual screen pixels. Note that other toolkits sometimes use the alternative term 'device independent coordinate' for
toolkit coordinate.
Lightspeed views will render themselves at full screen resolution, but will automatically use larger icons,
fonts, and so on, proportional to the DPI scaling factor. When you rely on the transformation methods
in ALspViewXYZWorldTransformation
, it is important to know that all coordinates reported
by UI components are toolkit coordinates. Lightspeed view coordinates correspond to toolkit coordinates
multiplied by the DPI scaling factor.
This means that any coordinates reported by a UI component, such as those obtained from a MouseEvent
,
need to be scaled up from toolkit coordinates to view coordinates before they can be transformed
to world coordinates. Likewise, view coordinates output by Lightspeed need to be scaled down to
toolkit coordinates before they can be correctly interpreted by the UI components.
The DPI scale factor can be retrieved through the getDPIScale
method in ILspView
or ILspContext
.
ALspViewXYZWorldTransformation
also provides a comprehensive set of methods for transforming points
between toolkit, view and world coordinates.
Impact on icon rendering
Image icons
To support high DPI rendering of image-based icons, TLcdImageIcon
adopts the @2x naming convention.
This convention consists of storing multiple icon versions at different resolutions, in order to visualize the appropriate
one according to the active resolution.
For instance, if an image.png
needs to be displayed at a DPI scale factor of 2.0, the scaled image image@2x.png
is
used if it is available.
This approach works seamlessly with OGC SLD / SE styling and the use of external graphic elements that refer to (but do not embed) images.
A similar solution is adopted by TLcdIconFactory
, which includes @2x
versions for the listed icon identifiers.
This approach benefits all components that rely on TLcdIconFactory
to create UI icons, such as Lucy and the samples.
For instance, the UI icons defined in Lucy’s configuration files are all loaded through TLcdIconFactory
;
consequently, the @2x
versions are automatically used if the DPI scale factor is 2.0 or higher.
Vector icons
Vector-based icons such as TLcdSymbol
or TLcdSVGIcon
automatically support high DPI rendering as long
as there is no buffering through an image, because the Graphics
instance supplied to the paintIcon
method
is already scaled appropriately.
Switching off display scaling
To switch off high DPI rendering, use the following system properties:
-
-Dsun.java2d.uiScale=1.0
for AWT/Swing (1.0 corresponds to 100%) -
-Dglass.win.uiScale=100%
for JavaFX
You can also use those properties to enforce a scaling factor other than the one configured in the host operating system.
Views and screen DPI
Though display scaling is usually enabled because a screen has a high DPI, it is largely independent from the DPI. For example, a 1-pixel-wide line will be rendered using two pixels if the display scale factor is 2.0, no matter if the view DPI is 72, 144, or 200.
However, some map content directly depends on the physical size of your display and its DPI value. Such map content includes:
-
Fractional paper map scales such as "1:100,000", used by
TLcdGXYScaleIndicator
,TLspScaleIndicator
,TLspFXScaleIndicator
,TLcdMapScale
, and the scale selection in Lucy -
Map data with screen-specific styling characteristics, such as line widths and icon sizes expressed in screen millimeters, used for example in charts and symbologies such as ECDIS, MGCP, and GeoSym
-
The display of print previews relative to the paper size. See
TLcdPrintPreview.setZoom
.
AWT/Swing based views rely on Toolkit.getDefaultToolkit().getScreenResolution()
to determine the DPI of a view.
JavaFX views use Screen.getPrimary().getDPI()
.
If you suspect that the detected value is not correct, you can override it by passing the correct DPI to the luciad.dpi
system property, for example -Dluciad.dpi=96
.