Closed Bug 563023 Opened 14 years ago Closed 14 years ago

Different font chosen for font-family: stack than for series of local() in @font-face

Categories

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

x86
Linux
defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: zwol, Unassigned)

References

Details

Attachments

(2 files, 2 obsolete files)

I tripped over this on a very new Linux installation.  If you have the Liberation and DejaVu font families installed, and do *not* have the Windows XP "core font" set installed (Arial etc) then the reftest font-face/src-list-local-fallback.html will fail *even if* you edit it so that the font-family: list in the reference precisely matches the chain of local()s in the @font-face rules in the test.  It appears (from eyeball comparison - I couldn't find any way to get Firefox to tell me what font was actually in use) that the local() chain selects Liberation Sans, whereas the font-family: list selects DejaVu Sans.

Attachment is the edit I made to the reference, which I think should probably go in regardless of what the resolution to this bug ends up being.
Attachment #442783 - Flags: review?(jdaggett)
Comment on attachment 442783 [details] [diff] [review]
make reference list match local() lists in test

The DejaVu Sans issue looks like a recent regression; the Futura vs. Futura Medium and omission of Bitstream Vera Sans Roman have been there from the start.  But this looks fine, so r=dbaron
Attachment #442783 - Flags: review?(jdaggett) → review+
Blocks: fedora-oranges
No longer blocks: 554394
http://hg.mozilla.org/mozilla-central/rev/09a936531466

This does not resolve this bug, though; there is still a reftest failure observable with the right set of system fonts.

Also, I note that there are several other test pairs in this directory where a local() chain in the test doesn't match up with a font-family: list in the reference, but some of those might be intentional and none of them are failing for me, so I'm leaving them alone for now.
Thanks for taking care of that, David, and sorry for disappearing.  (Why is it always the patch that seems totally safe that winds up needing to be reverted?)

I'll dig a bit deeper next week when I am back in the same city as my Mac.
I think this is what you meant.  Not sure why you changed Futura to Futura-Medium, the former is a family name the latter a Postscript name.  Same for Bitstream Vera Sans Roman, that's a fullname not a family name.  Just adding DejaVu Sans to the family list should fix the problem you ran into.
Attachment #444328 - Flags: review?(zweinberg)
> I think this is what you meant.  Not sure why you changed Futura to
> Futura-Medium, the former is a family name the latter a Postscript name.  Same
> for Bitstream Vera Sans Roman, that's a fullname not a family name.

I'm not familiar with the distinctions you are making here, and I'm not sure I should have to be.  It seems to me that 'src: local(something)' should always, without exception, select the same system-installed typeface that 'font-family: something' does, and vice versa.  This is evidently not what the current code does.  Can you explain, please?

> Just adding DejaVu Sans to the family list should fix the problem you ran into.

There are in fact three different problems here; I should probably have filed three bugs.

One problem is that in bug 554934 ctalbert added 'DejaVu Sans' to the src: lists in this and a bunch of other tests without also adding them to the font-family: lists in the respective references.  That's what my patch, and your revision, addresses (although it should probably be expanded to the others).

Another problem is that there seem to be intentional differences between the src: lists in these tests and the font-family: lists in the references, perhaps because the invariant I suggested above is not honored at present.  I want to understand why this is necessary before I ok anything.

A third problem is what I said in the original description: even with the above two ironed out, with certain combinations of system fonts we get different font choices for a src: list than its matching font-family: list.
> I'm not familiar with the distinctions you are making here, and I'm
> not sure I should have to be.  It seems to me that 'src:
> local(something)' should always, without exception, select the same
> system-installed typeface that 'font-family: something' does, and
> vice versa.  This is evidently not what the current code does.  Can
> you explain, please?

The src:local(something) syntax identifies a single face within a
family, using a name that is not always going to be the same as the
font family name which identifies a *set* of faces.  Thus "Arial"
identifies a font family called Arial or the normal face of Arial
while "Arial Bold" identifies a single face within the Arial family.
Arial Bold is not a font family.

The spec description is here, read the second and third paragraphs
following Example VIII:

http://dev.w3.org/csswg/css3-fonts/#src-desc

So it looks like the fix on bug 554934 is wrong (the reference tests
weren't updated).  The larger problem is that we need to have *some*
set of fonts that always exist on our test boxes.
DejaVu Sans probably needs to be before Arial (in both files) as Liberation Sans is designed to mimic Arial, and so probably used for font-family: Arial, but not local("Arial").
(In reply to comment #7)
> 
> The src:local(something) syntax identifies a single face within a
> family, using a name that is not always going to be the same as the
> font family name which identifies a *set* of faces.  Thus "Arial"
> identifies a font family called Arial or the normal face of Arial
> while "Arial Bold" identifies a single face within the Arial family.
> Arial Bold is not a font family.

Hm.  Can we at least have it that src:local(something) behaves the same as font-family:something if 'something' could match as a family name?  And then src:, but not font-family:, falls back to matching face names if no family name applies.

Then we could make sure that the test only used family names, not face names, and mooks like me could have some more confidence that they know how to modify these tests if necessary.

> So it looks like the fix on bug 554934 is wrong (the reference tests
> weren't updated).  The larger problem is that we need to have *some*
> set of fonts that always exist on our test boxes.

Yeah, there should be a documented list of fonts expected to exist, and perhaps also fonts expected *not* to exist.

I'm going to r- your patch since we agree it's incomplete; can you prepare a more complete patch, or should I?
Attachment #444328 - Flags: review?(zweinberg) → review-
Attachment #442783 - Attachment is obsolete: true
> Hm.  Can we at least have it that src:local(something) behaves the
> same as font-family:something if 'something' could match as a family
> name?  And then src:, but not font-family:, falls back to matching
> face names if no family name applies.

That's not dictated by us but by the font data, "something" needs to
match a name listed in the font data. What you describe is generally
the pattern (i.e. fullname equals the family name for the normal face)
but that's not guaranteed.  For OpenType fonts, it's based on name
table info:

  http://www.microsoft.com/typography/otspec/name.htm

Scroll down to the "Name IDs" section.  Name ID 1 is the family name,
Name ID 4 is the fullname and Name ID 6 is the Postscript name.

> I'm going to r- your patch since we agree it's incomplete; can you
> prepare a more complete patch, or should I?

Fair enough, I'll set up a new patch tomorrow.  I'll ping some of the
build guys to see who should discuss required font lists.
(In reply to comment #10)
> > Hm.  Can we at least have it that src:local(something) behaves the
> > same as font-family:something if 'something' could match as a family
> > name?  And then src:, but not font-family:, falls back to matching
> > face names if no family name applies.
> 
> That's not dictated by us but by the font data, "something" needs to
> match a name listed in the font data.

I think you misunderstand: I'm suggesting that local() first apply the existing code used for mapping a font-family: declaration to a system font, and only if that fails do we look at face names.
> I think you misunderstand: I'm suggesting that local() first apply
> the existing code used for mapping a font-family: declaration to a
> system font, and only if that fails do we look at face names.

A font family name maps to a family; the particular face chosen is
selected using other style properties (weight, style, etc.).  src
local() selects a single face using a name unique to that *face*.  The
two are not the same.
What I am trying to get across here is that this

  @font-face { font-family: "MyHelvetica"; src:local(Helvetica); }
  #foo { font-family: MyHelvetica; }

should be one hundred per cent equivalent to this

  #foo { font-family: Helvetica; }

except that if 'font-family:Helvetica;' happens to not resolve to a system font family, then the former can go look for a specific face as well.

And if the spec disagrees with me, then I respectfully submit that the spec is wrong.
It will be if and only if the fullname for Helvetica is "Helvetica".  If the font data is not, it won't.

An @font-face rule is defining a single face within a family, maybe that's the source of your confusion.
There is no confusion.  I am trying to tell you that I think the spec needs to be changed here!
And I'm telling you the spec defines something very specific and what you're describing is not.  A family name maps to a *set* of fonts with different styles and weights.  A given face is selected using the name specified for the font-family property *and* other font properties (i.e. font-weight, font-style, etc.).  There are mapping rules for which face is chosen when the exact style combination is missing.

Consider the "Hiragino Kaku Gothic Pro" family on OSX which has faces with weights 300 and 600.

  @font-face { font-family: MyHiragino; src: local(Hiragino Kaku Gothic Pro); }
  body { font-family: MyHiragino, Helvetica; }

Under your defintion of src local, which font is used for body text?
(In reply to comment #16)
> Consider the "Hiragino Kaku Gothic Pro" family on OSX which has faces with
> weights 300 and 600.
> 
>   @font-face { font-family: MyHiragino; src: local(Hiragino Kaku Gothic Pro); }
>   body { font-family: MyHiragino, Helvetica; }
> 
> Under your defintion of src local, which font is used for body text?

The same font that would have been chosen if the style had been

  body { font-family: "Hiragino Kaku Gothic Pro", Helvetica; }

I think the point of confusion is that you're insisting on @font-face always defining a single face, whereas I would like it to define an entire family if possible.  I think that's going to be what authors actually want for most uses of @font-face local().

Lemme throw a hypothetical at you: what does this do (assume the given local() strings do in fact select specific weights of Hiragino Kaku Gothic Pro, and the .otf files are consistent)

    @font-face { font-family: MyHiragino; font-weight: 300;
                 src: local(Hiragino Kaku Gothic Pro-300), url("HKGP-300.otf") }
    @font-face { font-family: MyHiragino; font-weight: 600;
                 src: local(Hiragino Kaku Gothic Pro-600), url("HKGP-600.otf") }

    #a { font-family: MyHiragino; font-weight: 300 }
    #b { font-family: MyHiragino; font-weight: 600 }

And if it *doesn't* behave exactly the same as

    #a { font-family: Hiragino Kaku Gothic Pro; font-weight: 300 }
    #b { font-family: Hiragino Kaku Gothic Pro; font-weight: 600 }

on a system with the appropriate font, why the hell not?
Yes, that does exactly what you expect (as far as I understand it). You're using @font-face to define TWO faces for your MyHiragino family, and giving them appropriate weight descriptors and sources, so now you have a user-defined family that will behave the same as the standard Hiragino Kaku Gothic Pro family.

But that doesn't address the problem of which specific FACE should be used if you were to give the font FAMILY name in an @font-face local() rule.
(In reply to comment #18)
> 
> But that doesn't address the problem of which specific FACE should be used if
> you were to give the font FAMILY name in an @font-face local() rule.

No specific face! It should act exactly like giving the family name in a font-family property! Why is this so alien a notion?
Here's another example.  As I understand it, OTF can bundle several faces into one physical file.  So suppose that 'Helvetica.otf' is a complete Helvetica family in itself, containing (at the least) normal, boldface, italic, and bold italic faces, and is properly licensed for @font-face use.  Then a designer who wants to be very sure they get Helvetica might write something like

    @font-face {
        font-family: DefinitelyHelvetica;
        src: local(Helvetica), url("Helvetica.otf");
    }

and would then go on to use DefinitelyHelvetica in font-family properties throughout their stylesheet.  They would, quite reasonably IMO, expect to be able to select bold and/or italic in the usual way regardless of whether the local() or the url() source was selected.  But if @font-face defines a single face rather than an entire family, this won't work.  Therefore IMO @font-face must define an entire family when possible.
(In reply to comment #19)
> (In reply to comment #18)
> > 
> > But that doesn't address the problem of which specific FACE should be used if
> > you were to give the font FAMILY name in an @font-face local() rule.
> 
> No specific face! It should act exactly like giving the family name in a
> font-family property! Why is this so alien a notion?

It's alien to the idea of @font-face, which (as its name suggests) is intended to define a specific face, not a family.

If you want to give the family name and hope the browser will do "the right thing" with it, just use the font-family property and forget about @font-face.
(In reply to comment #20)
> Here's another example.  As I understand it, OTF can bundle several faces into
> one physical file.

No, it doesn't. That would be possible using TrueType Collection (.ttc) files, but those are not widely used except for some specific use-cases with large Asian fonts (and AFAIK the .ttc file format is not supported by @font-face, at least in Gecko).

There are also some platform-specific file types on Mac OS X (.dfont, and the old "classic" font suitcases) that bundle multiple faces in a single file, but again, those aren't supported by @font-face.

>  So suppose that 'Helvetica.otf' is a complete Helvetica
> family in itself, containing (at the least) normal, boldface, italic, and bold
> italic faces, and is properly licensed for @font-face use.  Then a designer who
> wants to be very sure they get Helvetica might write something like
> 
>     @font-face {
>         font-family: DefinitelyHelvetica;
>         src: local(Helvetica), url("Helvetica.otf");
>     }
> 
> and would then go on to use DefinitelyHelvetica in font-family properties
> throughout their stylesheet.  They would, quite reasonably IMO, expect to be
> able to select bold and/or italic in the usual way regardless of whether the
> local() or the url() source was selected.  But if @font-face defines a single
> face rather than an entire family, this won't work.  Therefore IMO @font-face
> must define an entire family when possible.

No, Helvetica would be supplied as a set of .otf files, each containing a single face. Your hypothetical designer who wants to use Helvetica should do something like

@font-face {
    font-family: DefinitelyHelvetica;
    font-weight: normal;
    src: local(Helvetica), url("Helvetica.otf");
}
@font-face {
    font-family: DefinitelyHelvetica;
    font-weight: bold;
    src: local(Helvetica-Bold), url("HelveticaBold.otf");
}

...and so on, for as many faces as are wanted in the DefinitelyHelvetica family.
(In reply to comment #21)
> (In reply to comment #19)
> > 
> > No specific face! It should act exactly like giving the family name in a
> > font-family property! Why is this so alien a notion?
> 
> It's alien to the idea of @font-face, which (as its name suggests) is intended
> to define a specific face, not a family.

Why is that non-negotiable?

The name of the @-rule is not really important, in my view; the critical thing is that you use 'font-family:' to define the stylesheet-local name of the font being imported, and 'font-family:' to reference it from style rules; also, you can attach many individual faces to the same stylesheet-local name, and select them with font-weight, font-style, etc. as usual.  The *behavior* is as if it defined a family.  Authors will think of it as defining a family.

On this view, having local() pick out a single face from a system font family is a behavioral wart which should be eliminated.

(In reply to comment #22)
> (In reply to comment #20)
> > Here's another example.  As I understand it, OTF can bundle several
> > faces into one physical file.
> 
> No, it doesn't. That would be possible using TrueType Collection (.ttc) files,
> but those are not widely used except for some specific use-cases with large
> Asian fonts (and AFAIK the .ttc file format is not supported by @font-face, at
> least in Gecko).
> 
> There are also some platform-specific file types on Mac OS X (.dfont, and the
> old "classic" font suitcases) that bundle multiple faces in a single file, but
> again, those aren't supported by @font-face.

Ok, I stand corrected.  However, it seems to me that bundling several faces in one HTTP resource would be desirable for downloadable fonts, for the same reason that people are talking about resource packages (i.e. fewer HTTP round-trips); also to reduce style sheet verbosity.  The @font-face spec should allow for the possibility, at least.
(In reply to comment #22)
> Your hypothetical designer who wants to use Helvetica should do
> something like
> 
> @font-face {
>     font-family: DefinitelyHelvetica;
>     font-weight: normal;
>     src: local(Helvetica), url("Helvetica.otf");
> }
> @font-face {
>     font-family: DefinitelyHelvetica;
>     font-weight: bold;
>     src: local(Helvetica-Bold), url("HelveticaBold.otf");
> }
> 
> ...and so on, for as many faces as are wanted in the DefinitelyHelvetica
> family.

Another approach, btw, would be to use @font-face only for the case where the family isn't available locally, as in:

@font-face {
    font-family: DownloadedHelvetica;
    font-weight: normal;
    src: url("Helvetica.otf");
}
@font-face {
    font-family: DownloadedHelvetica;
    font-weight: bold;
    src: url("HelveticaBold.otf");
}

body {
    font-family: Helvetica, DownloadedHelvetica, sans-serif;
}
(In reply to comment #23)
> The name of the @-rule is not really important, in my view; the critical thing
> is that you use 'font-family:' to define the stylesheet-local name of the font
> being imported, and 'font-family:' to reference it from style rules; also, you
> can attach many individual faces to the same stylesheet-local name, and select
> them with font-weight, font-style, etc. as usual.  The *behavior* is as if it
> defined a family.  Authors will think of it as defining a family.

The behavior is that it defines a single face within a family - as evidenced by the fact that it assigns specific values of weight, style, etc to it. You can define a family containing multiple faces, but you do so one face at a time.

It seems like you want @font-face to be able to magically define a whole family IF the source happens to be a system font-family name, even though it defines an individual face if the source is a downloadable file. Sorry, I can't see how that is going to work in a sensible way. If anything, you'd need the (hypothetical) rule

@font-family: {
    font-family: foobar;
    src: local(MyLocalFamilyName);
}

where @font-family does NOT have descriptors such as font-weight and font-style, but automatically defines whatever faces are available in MyLocalFamilyName. But then why not use MyLocalFamilyName directly in the font-family property of your elements?
(In reply to comment #25)
> The behavior is that it defines a single face within a family - as 
> evidenced by the fact that it assigns specific values of weight, 
> style, etc to it.  You can define a family containing multiple faces,
> but you do so one face at a time.

Only because it happens not to support anything broader at the moment.  I think this model is too limited.

> It seems like you want @font-face to be able to magically define a whole
> family IF the source happens to be a system font-family name

Or if the source happens to be a downloadable file containing more than one face, in the hypothetical future scenario that such file formats are supported.  I think the spec should allow for that possibility in advance of any such support, because then browsers can just go ahead and do it.

I see no magic here.  My revised semantics are simply that @font-face adds *at least* one face to the local family named in its font-family descriptor.  If the selected element of the src: property describes a resource containing more than one face, then all of those faces are added.  The font-property descriptors (if present) would override the relevant properties in the font metadata for each face, just as they do now.

Example:  "FancyScriptFont.ttc" contains several weights of a script-style font, but the font metadata calls them roman.

   @font-face {
      font-family: DecorativeItalic;
      src: url("FancyScriptFont.ttc");
      font-style: italic;
   }
   .decorated { font-family: DecorativeItalic, serif; }

DecorativeItalic is used for font-style:italic within class="decorated", the normal serif font is used for font-style:normal.  The weight metadata from the font collection is honored.

> But then why not use MyLocalFamilyName directly in the
> font-family property of your elements?

Well, in the instant case, because we're trying to test local(), and having to know what the face names are cross-platform is a headache. :)  But I hope the above example motivates on-Web use sufficiently.
(In reply to comment #26)
> Well, in the instant case, because we're trying to test local(), and having to
> know what the face names are cross-platform is a headache. :)

We know how to fix the test in question (the v.0.2 patch should do it). So let's do that and move on.

>  But I hope the
> above example motivates on-Web use sufficiently.

If you want to advocate changes to the semantics of @font-face, I think that discussion needs to happen on the relevant W3C mailing lists, in the CSS working group, etc; this bug isn't the place for it.
(In reply to comment #27)
> (In reply to comment #26)
> > Well, in the instant case, because we're trying to test local(), and having to
> > know what the face names are cross-platform is a headache. :)
> 
> We know how to fix the test in question (the v.0.2 patch should do it). So
> let's do that and move on.

In comment 10, John Daggett said he was going to prepare a more thorough patch.  I agree this bug has gotten pretty seriously sidetracked...

> >  But I hope the
> > above example motivates on-Web use sufficiently.
> 
> If you want to advocate changes to the semantics of @font-face, I think that
> discussion needs to happen on the relevant W3C mailing lists, in the CSS
> working group, etc; this bug isn't the place for it.

... and I'm happy to write up a formal proposal for www-style, but I would rather not have a public disagreement with you and jtd on the mailing list, so can we find some common ground between the three of us privately first?
This is the same as John's v0.2 patch, except that it also adds DejaVu to src-list-local-full-ref.html. Basically, this is what should have been done in bug 554934 when the testcases were modified; sorry I missed it in the review there.

I believe this should fix the current test issues; specifying particular fonts that are (or are not) required to be installed on test systems is a discussion that probably belongs elsewhere.
Attachment #444328 - Attachment is obsolete: true
Attachment #445438 - Flags: review?(zweinberg)
(In reply to comment #28)
> ... and I'm happy to write up a formal proposal for www-style, but I would
> rather not have a public disagreement with you and jtd on the mailing list, so
> can we find some common ground between the three of us privately first?

Let's move that discussion to email rather than extending the comments on this bug.
Comment on attachment 445438 [details] [diff] [review]
patch, v0.3 - add DejaVu to font-family lists (missed in bug 554934)

Per comment 8, could you please also move DejaVu Sans ahead of Arial in both the tests and the references?

r=zwol with that
Attachment #445438 - Flags: review?(zweinberg) → review+
(In reply to comment #30)
> (In reply to comment #28)
> > ... and I'm happy to write up a formal proposal for www-style, but I would
> > rather not have a public disagreement with you and jtd on the mailing list, so
> > can we find some common ground between the three of us privately first?
> 
> Let's move that discussion to email rather than extending the comments on this
> bug.

Ok; i'll write something up and send it around.  Probably won't get to it till next week.
Pushed to trunk, with Arial moved to the end of the font lists:
http://hg.mozilla.org/mozilla-central/rev/0d770349f17f
Status: NEW → RESOLVED
Closed: 14 years ago
Resolution: --- → FIXED
Missed one.  The font lists in 'src-list-local-ps.html' are out of sync with the reference testcase, which I bumped into because I had FreeSans installed on my Windows box.  I would add a follow-on patch but I'm unsure of what the PS names are for the revised font list.
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Blocks: 531405
The PostScript names  of the "Free Sans", "Free Sans Bold", and "Free Sans Oblique" fonts that I have here are "FreeSans", "FreeSansBold", and "FreeSansOblique".
Now that we have DejaVu Sans in the list, I wonder whether we need to have FreeSans in there, though its peculiar full names might test something on some systems.
Add in the Postscript names for FreeSans and DejaVu Sans faces, so that the Postscript local reftest matches the reference.

Not sure what the names are for SwissA, leaving those commented out for now.
Attachment #457794 - Flags: review?(jfkthame)
Attachment #457794 - Attachment is patch: true
Attachment #457794 - Attachment mime type: application/octet-stream → text/plain
Comment on attachment 457794 [details] [diff] [review]
fixup patch, add Postscript names to match the reference

Re SwissA: do we know what systems/devices have this? AFAIK, it exists on some mobile devices as a bitmap font... in which case it may not have a "postscript name". But maybe there's also a PS or TT version somewhere?
Attachment #457794 - Flags: review?(jfkthame) → review+
Pushed to trunk
http://hg.mozilla.org/mozilla-central/rev/bafc956d254d

Mark Finkle helped me track down the SwissA font, it's used on the N800/810 series phones.  Postscript names are SwissA, SwissA-Bold and SwissA-Italic.  Updated the test with those names.
Status: REOPENED → RESOLVED
Closed: 14 years ago14 years ago
Resolution: --- → FIXED
Depends on: 1309405
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: