gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Missing text in gui apps on Kubuntu


From: Josh Freeman
Subject: Re: Missing text in gui apps on Kubuntu
Date: Wed, 10 Jun 2020 03:30:50 -0400

Got yesterday's KDE Neon release installed successfully [1], and the missing-text issue Patryk found on Neon/Aarch64 also affects Neon/ x86_64: GNUstep gui apps are missing all UI text characters except digits.

Running the fc-pattern-check tool on Neon (attached output: fcpc_out_kdeneon.txt) shows the same issue as on Kubuntu: The second FcFontMatch() call returns a match for the "Noto Color Emoji" font.

Cheers,

Josh

Attachment: fcpc_out_kdeneon.txt
Description: Text document




[1] Earlier install problems were due to running the KDE Neon installer under BIOS; KDE Neon requires UEFI.


On May 30, 2020, at 5:27 PM, Fred Kiefer wrote:

Thank you Josh for this excellent analysis. My impression is that this is somewhat of a Kubuntu bug, still it is better to fix it in our code especially if this results in a speed up. Such a speed up is really needed for slower machines.

I will look through the details of the patch tomorrow and apply it.

Cheers,
Fred

Am 30.05.2020 um 21:37 schrieb Josh Freeman <gnustep_lists@twilightedge.com >:

Some users of Kubuntu (official flavor of Ubuntu with the KDE Plasma desktop) reported that PikoPixel's missing most of its UI text; Numbers are the only characters displayed:
https://old.reddit.com/r/Kubuntu/comments/gas88l/pikopixel_strange_graphics_bug_any_suggestions_on/

I can reproduce this on Kubuntu 20.04, and the missing-text issue affects all GNUstep gui apps, whether the apps & GNUstep are from packages or from current sources.

This might be the same issue that Patryk found last August with KDE Neon:
https://lists.gnu.org/archive/html/gnustep-dev/2019-08/msg00019.html
(I couldn't test this, because the current x86_64 builds of KDE Neon fail to install on a VirtualBox VM, and older versions don't seem to be available).

Manually installing a different desktop on Kubuntu doesn't fix the issue; Text is still missing on GS gui apps when run under GNOME or Window Maker, however, switching GS's backend from Cairo to Art fixes the text.

Text displays correctly on Ubuntu 20.04 - even under Plasma - and also on a daily build of Ubuntu Studio 20.10 (Plasma is Studio's installed desktop as of 20.10).

 The issue's caused by a combination of two factors:

A) The Cairo backend sets up fontconfig patterns for font matching by calling the fontconfig library's Fc...Substitute() functions twice on each pattern instead of once: The backend's FCFaceInfo class has two methods, matchedPattern & characterSet, that each call FcConfigSubstitute() & FcDefaultSubstitute(), passing the FCFaceInfo instance member, _pattern, to be modified. Both methods in turn are called from within a single method, -[CairoFontInfo setupAttributes] (itself called from the FcFontInfo initializer): 1. [CairoFontInfo setupAttributes]:[FcFontInfo (super) setupAttributes]:[FCFaceInfo characterSet] 2. [CairoFontInfo setupAttributes]:[CairoFaceInfo fontFace]: [FCFaceInfo matchedPattern] Note that the font face is only generated after the second set of Fc...Substitute() calls.

B) The fontconfig library's font-matching functionality behaves differently on Kubuntu vs. other distros (even with the same version installed - Kubuntu 20.04 & Ubuntu 20.04 both have libfontconfig1 2.13.1-2ubuntu3).


Alone, neither factor causes the issue, however calling the Fc...Substitute() functions twice on the same pattern on Kubuntu leaves a modified pattern that - when passed to FcFontMatch() - always resolves to the "Noto Color Emoji" font. (That font has no alphabet characters, but does have digits, which explains why only numbers appear in the above linked screenshots).

To demonstrate this, the attached C file, fc-pattern-check.c, builds a standalone diagnostic tool using only the fontconfig library - no GNUstep. It creates a fontconfig pattern for matching the "DejaVu Sans" font and makes two sets of calls to Fc...Substitute() & FcFontMatch(), duplicating the calls made by the Cairo backend. After each call, the resulting pattern is printed.

The attached textfiles, fcpc_out_kubuntu.txt & fcpc_out_ubuntu.txt, are the outputs from running the fc-pattern- check tool on Kubuntu 20.04 & Ubuntu 20.04.

Comparing the two output files, the first difference comes after the first call to FcConfigSubstitute(): On Kubuntu, the pattern has a "rgba" (pixel-format) field inserted - this may not contribute to the incorrect match, but it already shows a different behavior between Kubuntu & Ubuntu.

Following the first set of Fc...Substitute() calls, the first call to FcFontMatch() correctly returns a resolved pattern for the "DejaVu Sans" font on both Ubuntu & Kubuntu. When these same first calls are made by the Cairo backend, the resolved pattern's used only to get the font's character set, not to generate the font face for drawing.

After the second call to FcConfigSubstitute() on Kubuntu, the pattern's "lang" field for some reason now contains "und- zsye" (emoji locale) before its earlier value, "en" (english). The pattern now also contains a "color" field with a value of "True" (requiring a match to a font that contains color information). With those field values present, the second call to FcFontMatch() returns a resolved pattern for "Noto Color Emoji"; On Ubuntu, its second FcConfigSubstitute() call doesn't add those "lang" & "color" values to the pattern, and its second call to FcFontMatch() correctly returns a "Deja Vu Sans" resolved pattern.


The attached patch, libs-back_fontconfig_pattern_fix.diff, fixes the missing text by limiting FCFaceInfo's Fc...Substitute() & FcFontMatch() calls to once per pattern. The resolved pattern returned by FcFontMatch() is now stored in FcFaceInfo's _pattern member (which previously only held a pre-matched pattern), and a new bool member, _patternIsResolved, keeps track of _pattern's pre- matched/resolved state.

The characterSet method now gets the resolved pattern by calling the matchedPattern method instead of calling the fontconfig functions directly; Outside of the initializer, dealloc, & matchedPattern methods, the _pattern member is now only accessed by the displayName method (which just reads the pattern's fullname, postscriptname, & style fields - if those were present in the pre- matched pattern, they should remain in the resolved pattern), so there should be no side-effects from storing a resolved pattern instead of a pre-matched pattern in the _pattern member.

Loading a large set of fonts will probably also go faster now, as FcFontMatch() is only called half as often.

Cheers,

Josh


<fc-pattern-check.c> <fcpc_out_kubuntu.txt> <fcpc_out_ubuntu.txt> <libs-back_fontconfig_pattern_fix.diff>





reply via email to

[Prev in Thread] Current Thread [Next in Thread]