Closed Bug 227889 Opened 21 years ago Closed 13 years ago

[xft] font matching does not follow CSS matching algorithm

Categories

(Core Graveyard :: GFX: Gtk, defect)

x86
Linux
defect
Not set
normal

Tracking

(Not tracked)

RESOLVED INCOMPLETE

People

(Reporter: bryner, Unassigned)

References

Details

(Keywords: css2)

Attachments

(1 file)

With the following fonts installed on my system (fontconfig fc-list output): LucidaTypewriter:style=Bold:weight=200 LucidaTypewriter:style=Regular:weight=100 Verdana:style=Bold Italic:weight=200 Verdana:style=Bold:weight=200 Verdana:style=Regular:weight=100 Verdana:style=Italic:weight=100 and these CSS properties: font-family: LucidaTypewriter, Verdana; font-style: italic; the font matching does not follow http://www.w3.org/TR/CSS21/fonts.html#algorithm . In particular, the matching algorithm specifies that font-style must match as follows: 'italic' will be satisfied if there is either a face in the UA's font database labeled with the CSS keyword 'italic' (preferred) or 'oblique'. Otherwise the values must be matched exactly or font-style will fail. There is no italic style for LucidaTypewriter, so it should move on to Verdana and use that. Instead, it uses non-italic LucidaTypewriter.
Attached file testcase (deleted) —
Looking at the code, it's probably similarly not possible for a bitmapped font to be skipped if it's not available at the requested size (which the spec also says should happen).
The solution worked out for scalable fonts was to synthesize an oblique face when not available so that the font-style property would always match; this makes it essentially identical to all of the other properties which are secondary to the family name in match priority. So, the only remaining issues are with bitmap fonts. As bitmap fonts continue to grow less and less important, I think we should focus on conformance with the specification, rather than an ideal result. The UA is allowed discretion in the matching of bitmap font sizes (so that the current scheme which allows arbitrary error is conformant, if not ideal). But, font styles provide no wiggle room to claim conformance with the current implementation. It seems to me that the CSS specification requires an application-specified font-style to be of primary import, more important in fact than the family name when selecting a font. If so, I can add a new matching table entry which places strongly bound slant values above strongly bound family names, while leaving weakly bound slant values below weakly bound family names. That, and a bit of code to make slant comparisons equate italic and oblique should fix the problem. Let me know if this will suffice, and I'll add it to fontconfig which is scheduled to have a release (2.3) shortly. I was hoping to have localized family and style names ready for that release, but if this issue is blocking CSS conformance in Mozilla, I can make a release without that functionality and pend the family and style name changes until 2.4.
That's how I would read the spec... what you suggested sounds like it should fix the problem. Thanks.
Hmm. Well, the code was certainly easy to write, but now I'm getting a very undesireable result. Asking for 'bitstream vera serif:italic' yields another family (Times New Roman), because there is no "real" slanted form of Bitstream Vera Serif. The matching rules can't "look ahead" to see the rendering manipulation rules which construct a shear transformation to artifically oblique the font. So, unless I can figure out a way around this, I've got the choice between a version which works well with scalable fonts but is non-conformant with bitmap fonts and a version which is conformant with all fonts but works poorly with scalable fonts. I haven't thought of a way to reconcile these two versions and come up with something that can admit scalable fonts as being "obliquable" and yet skip over bitmap fonts. One possiblity would be to add artificial obliquing to bitmap fonts; it would be easy to add a slight slant when loading them. I'd rather sacrifice the experience with bitmap fonts than with scalable ones. Other suggestions would be welcome, and of course I'll keep thinking as well.
There's also the issue of aliases I was discussing with you today. Currently a match request of "helvetica,serif" will get expanded to "helvetica,<list of fonts in serif alias>,serif, <list of fonts in alias containing helvetica>,sans-serif". Without a helvetica font installed, the usual out-of-box case on linux, this will return a serif font while we would prefer a reasonable helvetica substitution.
Status: NEW → ASSIGNED
tor: We would?
hixie: I would certainly expect a page that specifies just helvetica (to which we add serif as the fallback) to display in a sans-serif font.
Why? If the author wanted to default to something other than the user's default, he would have said: font-family: Helvetica, sans-serif;
I like to make the reasably safe assumption that most web designers are idiots, and when they say "font-family: helvetica" they mean "a font without the twiddly bits".
Then you should suggest that to www-style@w3.org, but in the meantime, our doing that would be non-compliant.
I agree with Hixie. This is not a case where an alias exists for Helvetica itself. This is fontconfig appending sans-serif fonts to the end of the list so that if no families you gave in your pattern matched, it can come up with something close to one of them. What the author says explicitly should always be preferred. However, in the case tor is talking about, I'm wondering whether the 'serif' was specified in CSS, or if we just appended it to the pattern because no CSS generic font families were listed. If that's the case, we may want to examine that code, because I think we're defeating fontconfig's attempt to find a reasonable default font based on the font you wanted to match.
I'm talking about the case where only a single font was specified, ex: <font style="font-family: helvetica">Helvetica</font>
See http://lxr.mozilla.org/seamonkey/source/gfx/src/gtk/nsFontMetricsXft.cpp#462 and http://lxr.mozilla.org/seamonkey/source/gfx/src/gtk/nsFontMetricsXft.cpp#1193 for the code I think could be changed. It seems to me that if no generic font was specified in css, we should go ahead and call FcConfigSubst without appending 'serif' to the pattern. Then we could inspect the pattern to see if fallback fonts are in place... if not, we could then append serif and call FcConfigSubst again. Just an idea.
Ok, I had been assuming that the 'serif' entry in the pattern came from the document and not from the browser configuration. If you don't append 'serif', things will work as desired. Fontconfig will continue to ensure that as much of the Unicode space is covered as can be managed from the available fonts, the pattern only changes the order in which fonts are considered for inclusion. Seems like an opportunity to fix a bug by deleting code. Always the best outcome when it works.
Found what appear to be a couple bugs in our xft glue: * "serif" is being added to the font list before SetupFCPattern is called, where it could be handled by the generic font fallback. * if more than one generic is listed in the font list, only the mGeneric font will be added to the pattern.
Ok, so... back to the oblique problem. Could you not just check FC_SCALABLE and cause that to match an oblique style?
Fontconfig computes a 'distance' from the pattern to each available font; the list returned from FcFontSort is sorted based on that metric. Seemed like a good idea when I wrote the code, and it works really well most of the time. That overall distance is actually an ordered list of distances for each property in the font and pattern; each of these is computed without reference to the remaining pattern elements. What you need to do in this case is *reorder* the list of values depending on two things: 1) whether the font was scalable (FC_SCALABLE) and 2) whether the configuration contained instructions to take that scalable face and shear it when an oblique varient was requested. I'm having trouble figuring out how that can be managed, even assuming arbitrary modifications to the existing code (which I'm not averse to). I'll be the first to admit that fontconfig is probably too configurable; and that configurability makes solving problems like this harder. However, I've seen people find uses for most of the flexibility it offers, so I'd like to work within the current visible artifacts of the architecture (match/edit rules, multi-valued pattern elements). Again, I can "solve" this issue by shearing bitmap fonts where necessary. I think that violates the spirit of bitmap fonts, but I guess I wonder how hard we should work to enable people to continue to use such horrors anyways.
tor: I was responding to your comment 6, where you said "helvetica,serif". If the author just says "helvetica" then we should default to the user's default font selection.
Assignee: bryner → nobody
Status: ASSIGNED → NEW
QA Contact: ian → gtk
Does this bug still occur in a recent trunk build?
Product: Core → Core Graveyard
The current font-handling code bears very little resemblance to what it was at the time this bug was last discussed, and it rather sounds like it was a fontconfig issue rather than a bug in Firefox anyway. If there is still a problem here, please file a new bug in Core:Graphics with a self-contained testcase; if possible, use @font-face in this test case so everyone is looking at exactly the same font(s).
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → INCOMPLETE
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: