Closed Bug 1407114 Opened 3 years ago Closed 3 years ago

Tamil fonts (in bold) have issues on Firefox Linux


(Core :: Layout: Text and Fonts, enhancement)

57 Branch
Not set



Tracking Status
firefox58 --- fixed


(Reporter: karlcow, Assigned: jfkthame)



(Whiteboard: [webcompat] )


(4 files)

In Webcompat during the sprint we had a big number of reports of users under Linux having issues with Tamil fonts. Sometimes the full page, sometimes just some specific type of sentences. Often it seems that when the font was being bold, the browser would display squares instead of the actual characters.
See for duplicates. Added in the seeAlso
Flags: webcompat?
See Also: →,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
It would be helpful if someone experiencing this problem could use the Element Inspector to see what font the browser is trying to use here -- i.e. not the list from the CSS font-family property, but the actual font(s) as shown in the Fonts panel at the right-hand side of the Inspector. (Beyond the Layout and Animations tabs; the Fonts may not be visible at all, depending on width, but is accessible from the drop-down arrow at the far right.)

For a specific page that exhibits the problem, such as, I'd like to know what fonts the Inspector reports both for Tamil text that displays OK, and for the elements that fail.
Karl, can you try to get someone who experiences this issue to look into the fonts involved, per comment 2? Thanks.
Flags: needinfo?(kdubost)
Flags: needinfo?(kdubost)
Jonathan, someone is willing to help.
I gave instructions.
Thanks, that may help give us some clues. Please update here when more details are available.

ok here at the details from

The user is using Linux Ubuntu 16.04 LTS.
From the font panel
* A (Failing text): Arial Bold Italic
* B (Working text): FreeSerif, Times New Roman Bold

Checking FreeSerif, I see:

  with no missing characters.

On macOs for me and on the same spots than the user tests.
* A: Arial Bold Italic, InaiMathi Bold
* B: InaiMathi Bold, Times New Roman Bold

The font is specified on the body element as

For exhibit A (failing text)

```css {
	font: italic bold 14px Arial, Tahoma, Helvetica, FreeSans, sans-serif;

for exhibit B (working text)

body {
	font: normal bold 14px 'Times New Roman', Times, FreeSerif, serif;
	color: #0000ff;

Checking FreeSans
No tamil characters are supported.

Firefox is not falling back on FreeSerif. 
Is it because it is said sans-serif? Though it does on macOs. :)
Flags: needinfo?(jfkthame)
OK, I'm beginning to understand what's happening here. The trouble is (I think) that FreeSerif supports Tamil characters only in its Regular face; it comes with distinct Bold and Italic faces as well, but those faces have a less extensive characters set (and in particular, no Tamil; a bunch of Indic and other scripts are similarly affected).

In principle, this is a legitimate design choice the font developer can make. The trouble we're having here, though, is that the Firefox font fallback code is finding the FreeSerif family for the Tamil text in these examples; and then if the style of the text calls for bold and/or italic, we select the corresponding styled face from the FreeSerif family. But that face doesn't have the necessary Tamil characters; hence, missing glyphs.

What we need to do is to ensure that the specific *face* we choose within the fallback family can actually support the characters involved; if necessary, applying fake-italic and/or fake-bold effects to the more complete Regular face, if the real styled faces don't support the characters.

(A workaround for users would probably be to install a package such as noto-fonts, which provides a Tamil font that doesn't have this quirk of mismatched character repertoires in different styles. At least, that works on my Linux machine. But clearly this is a bug we need to fix in Gecko so that users don't run into these unexpected missing-glyph boxes just because FreeSerif happens to be the only font family they have that supports Tamil.)
Flags: needinfo?(jfkthame)
Assignee: nobody → jfkthame
It turns out we had three chances to find the right font here, and flunked all of them: the FreeSerif font (which has Tamil characters available in its Regular face) is offered by fontconfig when resolving the CSS generics; if that fails, we try "common" fallback fonts known by the platform, and gfxPlatformGtk includes FreeSerif in that list; and if all else fails, the global search of all available font families should find it.

But in each case, when style resolution leads us to the Bold or Italic face of FreeSerif, we lose because those faces don't include the Tamil characters.

For fonts explicitly names in font-family, we have code that will do fallback within the family to handle cases like this, so we'll end up using (for example) the Regular face with a synthetic slant if the italic face doesn't include the target character. But we fail to do that at the other stages of the font-matching algorithm.

In my testing, therefore, any one of parts 2-4 here will fix the problem, so that the Tamil characters render using (synthetically-styled) FreeSerif instead of as hexboxes; but we should fix it in all three places for completeness.
Thanks for the explanations Jonathan. enlightening!
Attachment #8922068 - Flags: review?(jmuizelaar) → review+
Attachment #8922071 - Flags: review?(jmuizelaar) → review+
Comment on attachment 8922070 [details] [diff] [review]
part 3 - Handle fallback from styled to regular face if necessary when checking the platform's common fallback fonts

Review of attachment 8922070 [details] [diff] [review]:

::: gfx/thebes/gfxPlatformFontList.cpp
@@ +632,5 @@
> +            // If we requested a styled font (bold and/or italic), and the char
> +            // was not available, check other faces of the family.
> +            if (!fontEntry->IsUpright() ||
> +                fontEntry->Weight() != NS_FONT_WEIGHT_NORMAL ||
> +                fontEntry->Stretch() != NS_FONT_STRETCH_NORMAL) {

Can you give this condition a name put it in a function and avoid duplicating it across the three files.
Attachment #8922070 - Flags: review?(jmuizelaar) → review+
Attachment #8922069 - Flags: review?(jmuizelaar) → review+
(In reply to Jeff Muizelaar [:jrmuizel] from comment #14)
> Can you give this condition a name put it in a function and avoid
> duplicating it across the three files.

Makes sense. I've added it as an (inline) helper method gfxFontEntry::IsNormalStyle() in the first patch to encapsulate this, and then used !fontEntry->IsNormalStyle() in place of the three-part condition in the subsequent patches.
Pushed by
part 1 - preliminary cleanup - Remove the (unused) runScript member from the GlobalFontMatch struct, and introduce gfxFontEntry::IsNormalStyle() helper method. r=jrmuizel
part 2 - Handle fallback from styled to regular face if necessary during global font fallback, to handle cases where some styled faces may have a reduced character repertoire. r=jrmuizel
part 3 - Handle fallback from styled to regular face if necessary when checking the platform's common fallback fonts. r=jrmuizel
part 4 - Handle fallback from styled to regular face if necessary when using font-families from preferences. r=jrmuizel
You need to log in before you can comment on or make changes to this bug.