Auto scaling for high DPI


My goal is to have a particular rectangle and piece of text be about an inch wide regardless of the screen DPI of the machine my app is running on.

It seems like my only option right now is to set allow-high-dpi="true" in project.xml and remember to scale every component by stage.window.scale

Here’s my code:


import openfl.display.Bitmap;
import openfl.display.Sprite;
import openfl.Assets;
import openfl.text.TextField;
import openfl.text.TextFormat;
import openfl.text.TextFormatAlign;
import openfl.system.System;
import openfl.system.Capabilities;

class Main extends Sprite {
    public function new() {

        // Scale
        trace('stage.window.scale ${stage.window.scale}');
        trace('Capabilities.screenDPI ${Capabilities.screenDPI}');

        var bold14Font = new TextFormat("Arial", 14, 0xff0000);

        var navbarBackground = new Sprite();
        addChild(navbarBackground);;, 0, 100, 100);
        // navbarBackground.scaleX = stage.window.scale;
        // navbarBackground.scaleY = stage.window.scale;

        var text2 = new TextField();
        text2.defaultTextFormat = bold14Font;
        text2.text = 'Inside container';
        // text2.scaleX = stage.window.scale;
        // text2.scaleY = stage.window.scale;

        var text1 = new TextField();
        text1.defaultTextFormat = bold14Font;
        text1.text = 'Floating text';
        text1.x = 100;
        // text1.scaleX = stage.window.scale;
        // text1.scaleY = stage.window.scale;

This produces an image where everything is half as big as I want (use the traffic lights for reference):


If I uncomment all those .scaleX and .scaleY lines, then I get the following. The blue square is the expected size, but the “Floating text”'s left side is no longer at the right edge of the blue square. Also, the “Inside container” text got double the scaling (inheriting some from the parent Sprite).


To get it to look how I’d like, then, I have to do the following:

navbarBackground.scaleX = stage.window.scale;
navbarBackground.scaleY = stage.window.scale;

text2.scaleX = stage.window.scale / text2.parent.scaleX;
text2.scaleY = stage.window.scale / text2.parent.scaleY;

text1.x = 100 * stage.window.scale;
text1.scaleX = stage.window.scale;
text1.scaleY = stage.window.scale;

With the above code, the high DPI version looks like this:


And the low DPI version looks like this:


Is there a way to globally scale the whole coordinate system so that I don’t have to individually scale every component (especially once I have a deep tree of nested components)?

Edit: I should mention that I’m NOT targeting HTML5. I’m targeting iOS/Android/Mac/Linux/Windows