C
Qt Quick Ultralite font_quality Example
Demonstrates how to control font quality in an application.
Overview
This example demonstrates how to use the CMake and QML APIs to control font quality in an application. It shows how these APIs affect text rendering with optimal memory footprint.
The example's UI has multiple Text
items rendered with different font quality settings.
Target platforms
- EK-RA6M3G
- MCIMX93-EVK
- MIMXRT1050
- MIMXRT1060
- MIMXRT1064
- MIMXRT1170
- STM32F469I
- STM32F769i
- STM32H750b
- RH850 D1M1A
Project structure
CMake project file
The example contains two executable targets that share the same QML code. These targets use different settings for the MCU.Config.autoGenerateGlyphs target property:
font_quality_all_glyphs
- has MCU.Config.autoGenerateGlyphs set totrue
, which is the default value.font_quality
- has MCU.Config.autoGenerateGlyphs set tofalse
.
This setting affects the set of glyphs that are generated for each font.
Both are using MCU.Config.defaultFontQuality target property set to "VeryLow". This results in using low quality fonts by default, when not explicitly set using QML API. autoGenerateGlyphs enabled:
... MCU.Config { autoGenerateGlyphs: false defaultFontQuality: "VeryLow" } ...
autoGenerateGlyphs disabled:
... MCU.Config { autoGenerateGlyphs: true defaultFontQuality: "VeryLow" } ...
Application UI
The application UI is defined in font_quality.qml
file. It uses two fonts, a lowQualityLatinFont
font with default quality (which is set to "VeryLow"), and a highQualityDigits
font with higher quality.
The low quality font has the font.unicodeCoverage set to BasicLatin
unicode block.
readonly property font lowQualityLatinFont: Qt.font({ pixelSize: 30, unicodeCoverage: [Font.UnicodeBlock_BasicLatin] // quality set Font.QualityVeryLow by defualy // using \l MCU.Config.defaultFontQuality QmlProject property })
Whereas, the high quality font has the font.unicodeCoverage set to contain digits from 0
to 9
and the :
colon character.
readonly property font highQualityDigits: Qt.font({ pixelSize: 60, unicodeCoverage: [[0x30,0x3A]], // 0-9: quality: Font.QualityVeryHigh })
Next, text items are created, one for rendering arbitrary low quality Latin text:
Text { anchors.horizontalCenter: parent.horizontalCenter id: lowQualityText font: lowQualityLatinFont text: "VeryLow 123" }
Another for rendering the high quality digits:
Text { anchors.centerIn: parent font: highQualityDigits text: "13:59" }
At the very end, a text that shows result of binding the text
properties of these two Text
items with different font qualities:
Text { anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: parent.bottom font: highQualityDigits // Glyps may be missing if \l MCU.Config.autoGenerateGlyphs is set to \c false text: lowQualityText.text }
Notice that the glyphs may be missing in this text item, depending on the MCU.Config.autoGenerateGlyphs property value. See Missing glyphs for more information.
Memory footprint
Font family combined with other font properties such as: weight, size, italics, and quality uniquely defines so called "font configuration".
Using font.unicodeCoverage affects the memory footprint and rendering output when used with the MCU.Config.autoGenerateGlyphs property.
By default, this property is set to ON
and glyphs for all used characters in qml file are generated for every font configuration that is used by the application. This is convenient, as you don't need to check if all the glyphs are present, before creating bindings between the properties of Text
items with different font configurations. This convinience comes at a cost, as it increases the binary size and the runtime memory footprint.
To optimize binary size and the footprint, you can set MCU.Config.autoGenerateGlyphs to OFF
. This disables automatic generation of all the glyphs and relies on the font.unicodeCoverage setting to generate only the glyphs that are needed. This enusres that each font configuration gets glyphs based on the font.unicodeCoverage property, resulting in optimal memory footprint. Although it sounds simple, it requires careful application design to ensure that all font configurations contains all glyphs that are needed.
Note: The text items are rendered with place holder boxes for the missing glyphs, if the font.unicodeCoverage is not set to an appropriate value when MCU.Config.autoGenerateGlyphs is set to OFF
.
Missing glyphs
Although setting MCU.Config.autoGenerateGlyphs to OFF
and specifying font.unicodeCoverage for each font configuration results in an optimal binary size and lower memory footprint, you must carefully design your application.
Let's take a look at the QML code where low quality text is assigned to the high quality one:
Text { anchors.horizontalCenter: parent.horizontalCenter anchors.bottom: parent.bottom font: highQualityDigits // Glyps may be missing if \l MCU.Config.autoGenerateGlyphs is set to \c false text: lowQualityText.text }
Although this is completely fine with MCU.Config.autoGenerateGlyphs set to ON
, it will result in missing glyphs while rendering the texts with the auto-generation set to OFF
.
You can see in the earlier image that highQualityDigits
font contains only glyphs for characters with the font.unicodeCoverage specified (which are 0-9
and :
). The glyphs needed for rending lowQualityText
are not generated for this font configuration.
Files:
See also font.quality, MCU.Config.autoGenerateGlyphs, and MCU.config.defaultFontQuality.
Available under certain Qt licenses.
Find out more.