Search code examples
fontsembeddedqt5

Text displayed incorrectly - characters are squares - suspect fonts not found


I have an embedded ARM system running Linux. I've successfully built and installed Qt 5.3.1 onto my target, and I'm able to build Qt applications and run/debug them. Note that my target does not have X installed, and the QPA that is being used is eglfs (if that matters).

Any text that is displayed on screen is displayed as a sequence of square characters. I suspect that the font is not being located/loaded properly. I can't find much decent documentation of the subject.

  • If I create a QFontDatabase object and query it, I have fixed width, serif, and sans serif font families available at a variety of point sizes (or so I guess from what I see, see below for my code and its output).
  • I put a copy of my Windows machine's Arial.ttf onto the target in the directory I believe Qt is searching for fonts, to no avail.

The unfortunate thing is there is no error message to use to troubleshoot this! So, I have the following questions:

  • Is there a way to get more information (like debug messages) from Qt about where it's looking for fonts, when it can't find them, etc.?
  • Is there some sort of font fallback scheme? I don't know much about the subject, but if Arial.ttf is the only font available and the application tries to load Helvetica, does it choose the "closest font", or does it simply give up and put boxes on the screen?
  • I'm mainly testing with the Qt examples. Is there a tool to report the variety of fonts that a particular application requires so that I can ensure they're on the target?
  • ...? Perhaps someone who knows more might be able to provide other helpful information.

Here is some code I ran to see if I could learn anything about what Qt thinks it has for available fonts:

QFontDatabase db;
foreach (const QString &fam, db.families()) {
    foreach (const QString &style, db.styles(fam)) {
        std::cout << fam.toStdString() << std::endl;
        QString sizes;
        foreach (int points, db.smoothSizes(fam, style))
            sizes += QString::number(points) + " ";
        std::cout << sizes.trimmed().toStdString() << std::endl;
    }
}

And the output:

Monospace
Normal
6 7 8 9 10 11 12 14 16 18 20 22 24 26 28 36 48 72
Italic
6 7 8 9 10 11 12 14 16 18 20 22 24 26 28 36 48 72
Oblique
6 7 8 9 10 11 12 14 16 18 20 22 24 26 28 36 48 72
Sans Serif
Normal
6 7 8 9 10 11 12 14 16 18 20 22 24 26 28 36 48 72
Italic
6 7 8 9 10 11 12 14 16 18 20 22 24 26 28 36 48 72
Oblique
6 7 8 9 10 11 12 14 16 18 20 22 24 26 28 36 48 72
Serif
Normal
6 7 8 9 10 11 12 14 16 18 20 22 24 26 28 36 48 72
Italic
6 7 8 9 10 11 12 14 16 18 20 22 24 26 28 36 48 72
Oblique
6 7 8 9 10 11 12 14 16 18 20 22 24 26 28 36 48 72

Solution

  • It seems you lack the font rendering engine.

    Where is Qt looking for fonts?

    According to Qt embedded reference document on fonts,

    If fontconfig is not available, e.g. in dedicated embedded systems ..., Qt will fall back to using QBasicFontDatabase. In this case, Qt applications will look for fonts in Qt's lib/fonts/ directory

    As you are able to list them It seems those fonts are indeed in the lib/fonts/ subdirectory of Qt.

    Now You need to make sure you have FreeType 2 font engine, which is used by Qt for font rendering. Did you compile with -qt-freetype enabled? Look at the configure page for more info.

    Is there some sort of font fallback scheme?... does it choose the "closest font"?

    There is no such thing as a font "distance". I expect the fonts to be loaded with some kind of priority as long as they are found.

    Is there a tool to report the variety of fonts that a particular application requires so that I can ensure they're on the target?

    I am not sure whether it is possible or not. But you can look at the available fonts, using the QConfig tool in a the "tool" subdirectory of Qt source. QConfig snapshot