Closed Bug 835204 Opened 11 years ago Closed 7 years ago

"Segoe UI Light" not recognized as a font-family name (was: Font will not display)

Categories

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

18 Branch
x86_64
Windows 8
defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla57
Tracking Status
firefox57 --- fixed

People

(Reporter: sheldonjuncker, Assigned: jfkthame)

References

(Depends on 1 open bug, )

Details

(Keywords: fonts)

Attachments

(5 files, 1 obsolete file)

Attached file ultrabytepc.html
User Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.56 Safari/537.17

Steps to reproduce:

I just created a simple website. I tested it in the latest versions of Opera and Chrome, IE9, and Firefox 18.


Actual results:

The website looked fine in all of the browsers except Firefox. First of all, the logo font (Segoe UI Light) did not show up in Firefox, but the system default font was used instead.


Expected results:

The font should have shown up (and did in all of the other browsers).
Keywords: fonts
Component: General → Layout: Text
The only work-around that I could find was to use font-family:"segoe ui"; and set the font-weight to "lighter". However, this gave different results in different browsers, which were not close enough to be acceptable.
Component: Layout: Text → General
Your problem is that Windows has two different font subsystems: GDI and DirectWrite.

DirectWrite thinks this is a lighter-weight font in the "segoe ui" family.

GDI thinks it's a font in the "segoe ui light" family.

How a browser reacts here will depend on which font subsystem it's using.

Per spec, the DirectWrite behavior is actually the correct one, last I checked.
Component: General → Layout: Text
Okay, so what do I have to do to force the browser to find the correct font?
There's some chance that using:

  font-family: "segoe ui", "segoe ui lighter";
  font-weight: lighter;

might do the right thing, depending on what UAs using GDI end up doing with that font-weight..
To chime in, what Boris suggests is the right way to address this, simply include the GDI font family name as a fallback.  This is a general problem with large font families on Windows, GDI restricts font families to the basic four faces (regular, bold, italic, bold italic).  DirectWrite tries to remedy this in a way that makes sense but authors unfortunately still have to deal with both flavors.  GDI also compounds the problem by recognizing *face* names (e.g. "Arial Bold") which shouldn't be matched as font *family* names.  Firefox handles this while older versions (i.e. IE8 and before) don't.  

That's part of a larger problem of what user agents accept as a "family" name (e.g. OSX Webkit browsers accept Postscript names such as 'Arial-ItalicMT').

Testcase:
http://people.mozilla.org/~jdaggett/tests/arialvariations.html
(In reply to Boris Zbarsky (:bz) from comment #4)

>   font-family: "segoe ui", "segoe ui lighter";
>   font-weight: lighter;

Minor edit, this should be:

  font-family: "segoe ui light", "segoe ui";
  font-weight: 300;
Summary: Font will not display → "Segoe UI Light" not recognized as a font-family name (was: Font will not display)
A Mozillian posted on our (Mozilla Kenya Facebook page) about an error with the Segoe UI font. I hope the attached screenshot has the info needed to accord him assistance needed to display font correctly. Lemme know should more info be needed.
I hope someone can clear up a few things.

1. This report is still unconfirmed, while identical ones about other fonts are New (bug 644385, bug 584769). Is this recognized as a valid issue or not?

2. Why are both bug 584769 and bug 644385 New? Don't they describe the exact same problem? It seems like if there was a distinction to make, it would be between condensed/stretched fonts and light/bold ones. Unless this is actually going to be handled on a per-font basis, in which case a meta bug would be useful to group the various reports together.

2. When hardware acceleration is disabled, Firefox doesn't recognize DejaVu Sans ExtraLight [1], Ubuntu Medium [2] and various Roboto [3] font faces. The wrong font face is applied, like Roboto Bold instead of Roboto Black.
I couldn't find a report about this. Does anyone happen to know if one exists, or should I file one?

[1] http://dejavu-fonts.org/wiki/Download
[2] http://font.ubuntu.com
[3] http://www.fontsquirrel.com/fonts/roboto
Flags: needinfo?(jfkthame)
(In reply to Gingerbread Man from comment #9)
> I hope someone can clear up a few things.
> 
> 1. This report is still unconfirmed, while identical ones about other fonts
> are New (bug 644385, bug 584769). Is this recognized as a valid issue or not?

As explained (here, by Boris and John, as well as elsewhere) this is not really a bug, it is behaving as designed, given that we're dealing with two different font platforms - GDI and DirectWrite - that present different font family structures.

I guess the bugs haven't simply been closed as INVALID because there's been some discussion of possibly adding hacks to deal with some of the common author confusion here. But there's not been any clear decision as to exactly what (if anything) to do. (See bug 584769 comments 14 - 15.)

> 
> 2. Why are both bug 584769 and bug 644385 New? Don't they describe the exact
> same problem? It seems like if there was a distinction to make, it would be
> between condensed/stretched fonts and light/bold ones. Unless this is
> actually going to be handled on a per-font basis, in which case a meta bug
> would be useful to group the various reports together.

Yes, we have several reports that are really the same underlying issue. If and when we decide on a resolution, it should apply to them all. I just don't think anyone has been focusing on the issue for the time being, beyond recognizing that it exists and that it's really a case of authors misunderstanding the font family model(s). If we do add a font-family-compatibility hack of some kind, we can probably resolve these reports as duplicates.

> 
> 2. When hardware acceleration is disabled, Firefox doesn't recognize DejaVu
> Sans ExtraLight [1], Ubuntu Medium [2] and various Roboto [3] font faces.
> The wrong font face is applied, like Roboto Bold instead of Roboto Black.
> I couldn't find a report about this. Does anyone happen to know if one
> exists, or should I file one?
> 
> [1] http://dejavu-fonts.org/wiki/Download
> [2] http://font.ubuntu.com
> [3] http://www.fontsquirrel.com/fonts/roboto

Do you mean that under GDI rendering, something like
  font-family: Roboto;
  font-weight: 900;
will give you Roboto Bold rather than Black? If so, that's expected - it's simply the same issue, in reverse. GDI doesn't recognize Roboto Black as belonging to the Roboto family, and so font-weight can't find it. You'd need to use
  font-family: Roboto Black;
to get the Black face under GDI (I assume - have not tested); and to get Roboto Black across both platforms, something like
  font-family: Roboto Black, Roboto;
  font-weight: 900;
would probably work.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Flags: needinfo?(jfkthame)
(In reply to Jonathan Kew (:jfkthame) from comment #10)
> I guess the bugs haven't simply been closed as INVALID because there's been
> some discussion of possibly adding hacks to deal with some of the common
> author confusion here. But there's not been any clear decision as to exactly
> what (if anything) to do. (See bug 584769 comments 14 - 15.)

Thank you for the explanation.

> I just don't think anyone has been focusing on the issue for the time being,
> beyond recognizing that it exists and that it's really a case of authors
> misunderstanding the font family model(s).

Whether or not a change will be implemented, this situation should be clearly explained in the MDN font and font-family articles (and maybe font-weight and font-stretch as well).
 
> Do you mean that under GDI rendering, […]
>   font-family: Roboto Black;

The font is not applied. The default font, Times New Roman is used instead.

> to get Roboto Black across both platforms, something like
>   font-family: Roboto Black, Roboto;
>   font-weight: 900;
> would probably work.

That applies Roboto Bold.
Attached image roboto-black-gdi.png
(In reply to Gingerbread Man from comment #11)
> > Do you mean that under GDI rendering, […]
> >   font-family: Roboto Black;
> 
> The font is not applied. The default font, Times New Roman is used instead.
> 
> > to get Roboto Black across both platforms, something like
> >   font-family: Roboto Black, Roboto;
> >   font-weight: 900;
> > would probably work.
> 
> That applies Roboto Bold.

It works for me; see attached (this is the GDI rendering, i.e. without h/w accel; under DirectWrite, the "Hello world" text renders the same, using the Roboto Black face, but the inspector's Fonts pane reports that it was "Used as: Roboto" because it is treated as part of that family).

I've no idea why it isn't working for you.
font-family: "Roboto Black"; (with quote)?
Bug 1019232 — about the font problem mentioned at the bottom of comment 9. So as not to derail this report any further, I've replied to comments 12 and 13 there.
• Bug 1019234 — about the documentation problem mentioned in the middle of comment 11.
This is still affecting sites like the Windows sub-Reddit, which is only specifying "Segoe UI Light" rather than it and "Segoe UI". IIRC these days Chrome also uses DirectWrite, yet it seems to select the correct font in this case. Perhaps they have a work-around which we could also use?
Flags: needinfo?(bzbarsky)
Flags: needinfo?(bzbarsky) → needinfo?(jfkthame)
I believe they do some heuristics to look for legacy GDI-style family names that include a style suffix, and munge them to the appropriate base family + style for DirectWrite. E.g. see https://src.chromium.org/viewvc/blink/trunk/Source/platform/fonts/win/FontCacheSkiaWin.cpp?r1=181493&r2=181492&pathrev=181493 where some such code was added.

Maybe we should do something similar; or maybe we should tell authors to use the modern family names and style properties correctly.
Flags: needinfo?(jfkthame)
Since this is essentially a web compat issue, I think we'd be better off deciding if Chrome should remove this work around (which resolved four bug reports), or it it ought to be formalized somehow in a spec.
Chrome's workaround has an interesting side-effect, in that it results in spurious "fake" font-family names being recognized:

  data:text/html,<div style="font-family: times new roman black, sans-serif">Hello

results in Chrome using the Times New Roman *Bold* face (note that there is no *Black* face of TNR).

However, specifying

  data:text/html,<div style="font-family: times new roman bold, sans-serif">Hello

does NOT use Times New Roman Bold, it falls back to the 'sans-serif' generic. This is quite counter-intuitive, IMO.

It's also interesting to note that Chrome does this family-name hacking on Windows/DirectWrite only, which means that if the exact same set of fonts (e.g. the full Roboto family) is installed on both Windows and macOS machines, it will behave differently: on macOS, "family" names such as "Roboto Thin" or "Roboto Black" are NOT recognized, whereas they are on Windows. This seems like an unfortunate inconsistency, and tends to limit the webcompat utility of the workaround: sites that rely on such legacy GDI-style names may still fail on other platforms.
I've been experimenting with some possible approaches here, and I think I have a patch that works reasonably well.

The basic idea is:

* If the CSS font-family property calls for a family name that isn't found, we check if the name includes a space.

* If so, it's possible this is a "styled family" name (like "Arial Black" or "Fira Sans Heavy" or "Segoe UI Light"). Strip the last word off the font-family name to give a candidate "base family name", and see if that is available.

* If it is, then iterate over the faces in the base family, and check the 'name' table of each to see if it has a legacy family name (like "Arial Black") that differs from the preferred family name ("Arial").

* Add new gfxFontFamily objects for any such legacy families to the gfxPlatformFontList, and then re-try the original font-family search.

We set a flag on gfxFontFamily to say when the search for legacy family names has been done, so that we won't repeat it; and once it has been done, the legacy families are known to the font list (in the mOtherFamilyNames hash) and so they'll be found immediately on any future usage.

This avoids the issue (bug) in Chrome's implementation, as described in comment 18, as it doesn't hard-code the idea that a "Black" suffix (for example) means we take the base font-family and apply a large font-weight; rather, it looks for the actual legacy family names that GDI would have used. So "font-family: times new roman black" will trigger a (one-time) legacy-family search in the Times New Roman family, but as no legacy family named Times New Roman Black actually exists, it won't match and fallback will continue to operate as expected.

Note that this does not mean *any* font face can be directly accessed via font-family (e.g. "font-family: arial bold"), which would conflict with the CSS Fonts spec requirements (the font-family property specifies a list of family names, NOT face names). Styled names will only work if the face has a styled family name in the legacy family name record (ID 1) in the 'name' table, so that it would have been exposed as a separate family under GDI.
Not really sure who should review this, as it's kinda straddling the intersection between gfx-level platform implementations of font management and how we handle the CSS font-family property. :heycam, can you have a look and see if it seems reasonable?
Attachment #8892655 - Flags: review?(cam)
Assignee: nobody → jfkthame
Status: NEW → ASSIGNED
The approach you describe in comment 19 sounds reasonable to me.  The patch would time me some effort to review, especially the gfxFontEntry.cpp changes.  How urgent is this?  (Are you want it to get in 57?)  If not, then I may need to de-prioritize this.
Flags: needinfo?(jfkthame)
Well, it's a long-standing issue (we've been getting bug reports that are basically this ever since we first implemented DirectWrite fonts...), but given that we're making a big splash about 57, and this is a very visible webcompat issue when it comes up, I admit I was hoping to fix it for that release.

We could try to find someone else to review, if you're not able to get to it, though no doubt everyone else is busy too...
Flags: needinfo?(jfkthame)
OK, you can leave it in my queue, and I'll take a look when I get a chance.
Updated patch on top of bug 1368531, which just landed to inbound. As both that patch and this one wanted to add a boolean parameter to FindAndAddFamilies, I changed it to use a Flags param instead of multiple separate bools, which can become error-prone and hard to read. (Functionally, this remains the same as the previous version.)
Attachment #8893465 - Flags: review?(cam)
Attachment #8892655 - Attachment is obsolete: true
Attachment #8892655 - Flags: review?(cam)
:heycam - just a friendly ping :) if you can find time to look at the review here sometime soonish, that would be awesome - thx!
Flags: needinfo?(cam)
Comment on attachment 8893465 [details] [diff] [review]
Accept styled font-family names as used in the legacy GDI model, for compatibility with content that assumes GDI-style font naming

Review of attachment 8893465 [details] [diff] [review]:
-----------------------------------------------------------------

Sorry for the horrible delay here.

::: gfx/thebes/gfxFontEntry.cpp
@@ +1660,5 @@
>  }
>  
> +static bool
> +LookForLegacyFamilyName(const nsAString& aCanonicalName,
> +                        const char *aNameData,

Various nits about "*" positions in this function, but I guess it's code copy/pasted from ReadOtherFamilyNamesForFace.  Actually, it would be nice if we could factor out the the iteration over the entries in the name table, and have a callback function / lambda we could pass into it.  Feel free to do that if you think it's worthwhile.

One day we'll rewrite this in Rust and it'll be easier to write iterators over parsed data structures like this. :-)

@@ +1672,5 @@
> +    if (nameCount * sizeof(gfxFontUtils::NameRecord) > aDataLength) {
> +        NS_WARNING("invalid font (name records)");
> +        return false;
> +    }
> +    

Nit: trailing space.

@@ +1724,5 @@
> +            continue;
> +        }
> +        nsAutoString legacyName;
> +        uint32_t dataLength;
> +        const char *nameData = hb_blob_get_data(nameTable, &dataLength);

Nit: "*" next to type.

::: gfx/thebes/gfxFontEntry.h
@@ +111,5 @@
> +    // Create a new entry that refers to the same font as this, but without
> +    // additional state that may have been set up (such as family name).
> +    // (This is only to be used for system fonts in the platform font list,
> +    // not user fonts.)
> +    virtual gfxFontEntry* Clone() const

Just make this a pure virtual function?

@@ +624,5 @@
>  
>      virtual void LocalizedName(nsAString& aLocalizedName);
>      virtual bool HasOtherFamilyNames();
> +
> +    bool CheckForLegacyFamilyNames(gfxPlatformFontList* aFontList);

Can you add a comment here, or above the mCheckedForLegacyFamilyNames field, describing what this is for?

::: gfx/thebes/gfxPlatformFontList.cpp
@@ +262,5 @@
> +                                    // faces, we're adding them directly here
> +        mOtherFamilyNames.Put(key, family);
> +        added = true;
> +    }
> +    family->AddFontEntry(aFontEntry->Clone());

(AddFontEntry should probably take an already_AddRefed<gfxFontEntry>, which then Clone() could return, to avoid the extra refcounting here.  But that's an improvement for another day.)

::: gfx/thebes/gfxPlatformFontList.h
@@ +134,5 @@
>                            const gfxFontStyle* aStyle);
>  
> +    enum class FindFamiliesFlags {
> +        eForceOtherFamilyNamesLoading = 1 << 0,
> +        eNoSearchForLegacyFamilyNames = 1 << 1

Add some comments about these?

::: layout/reftests/bugs/481948-2-ref.html
@@ +2,5 @@
>  <head>
>  <style type="text/css">
>  body {
>    /* try for some likely fonts that might implement the "fi" ligature */
> +  font-family: Times, Calibri, PalatinoLinotype, DejaVuSerif, serif;

Why is this change needed?
Attachment #8893465 - Flags: review?(cam) → review+
Flags: needinfo?(cam)
(In reply to Cameron McCormack (:heycam) from comment #26)

> ::: layout/reftests/bugs/481948-2-ref.html
> @@ +2,5 @@
> >  <head>
> >  <style type="text/css">
> >  body {
> >    /* try for some likely fonts that might implement the "fi" ligature */
> > +  font-family: Times, Calibri, PalatinoLinotype, DejaVuSerif, serif;
> 
> Why is this change needed?

Good question..... I think that's left-over from a workaround used when I was still having some issues with an earlier version of the patch. It shouldn't be relevant any longer; I'll just remove it.
Pushed by jkew@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/c31c7c652024
Accept styled font-family names as used in the legacy GDI model, for compatibility with content that assumes GDI-style font naming. r=heycam
https://hg.mozilla.org/mozilla-central/rev/c31c7c652024
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla57
Depends on: 1397238
Depends on: 1397724
Depends on: 1400245
Depends on: 1458003
You need to log in before you can comment on or make changes to this bug.