Increased line heights with DirectWrite (unlike in IE9)

NEW
Unassigned

Status

()

8 years ago
5 months ago

People

(Reporter: dao, Unassigned)

Tracking

(Depends on: 1 bug, Blocks: 3 bugs, {regression})

Trunk
All
Windows 7
regression
Points:
---
Dependency tree / graph

Firefox Tracking Flags

(firefox5-, firefox6-)

Details

Attachments

(2 attachments, 2 obsolete attachments)

(Reporter)

Description

8 years ago
Posted file testcase
Line heights are often larger when using hardware acceleration, letting Firefox be the odd one out. This seems like a significant obstacle for web designers. All other browsers seem to use consistent vertical metrics, including hardware-accelerated IE9.

Comment 2

8 years ago
FWIW, this has already been discussed in bugs #601152 and #628601. I think it would be better to mimic IE9 behaviour here and compensate, but I wholeheartedly agree that no web developer should rely on fixed/consistent font-metrics across platforms (and this is without taking font install base discrepancies into account) ...
Blocks: 635490
Reading http://msdn.microsoft.com/en-us/library/dd368074%28v=vs.85%29.aspx
and gfxDWriteFont::ComputeMetrics() leaves me a little confused.

The descriptions of DWRITE_FONT_METRICS::ascent/descent/lineGap make them sound like TypoAscender/TypoDescender/TypoLineGap in the OS/2 table.
http://www.microsoft.com/typography/otspec/os2.htm

If that is the case, the line heights calculated in gfxDWriteFont::ComputeMetrics() should be <= those calculated for a gfxGDIFont
(in the limit as size increases - see below).

However, gfxDWriteFont assigns the DWRITE_FONT_METRICS::ascent/descent (values that I would expect to closely correspond to gfxFont::Metrics::emAscent/emDescent) to gfxFont::Metrics::maxAscent/maxDescent, values to which gfxGDIFont has historically assigned WinAscent/WinDescent.
(This should not affect line-height; it just makes me wonder which metrics these DWRITE_FONT_METRICS really are.)

The other key difference is that gfxDWriteFont rounds *up* each of maxAscent/maxDescent/externalLeading (independently), which could increase line height by up to 3 pixels, depending on exactly what formula GDI used.
Does the difference reduce at larger font sizes?
(Reporter)

Comment 4

8 years ago
(In reply to comment #3)
> The other key difference is that gfxDWriteFont rounds *up* each of
> maxAscent/maxDescent/externalLeading (independently), which could increase line
> height by up to 3 pixels, depending on exactly what formula GDI used.
> Does the difference reduce at larger font sizes?

I changed the font size from 20 to 50, the difference in height of the colored boxes remains 2px.

Comment 5

8 years ago
Related bug:
https://bugzilla.mozilla.org/show_bug.cgi?id=628601

This really needs fixing, you cant expect designers to specify a line-height for every single use of font-size :(
(Reporter)

Updated

8 years ago
blocking-fx: --- → ?
Uh... why do they need to specify a line-height at all?
(Reporter)

Comment 7

8 years ago
They wouldn't normally specify a line-height; doing so is the obvious workaround for this bug.

Comment 8

8 years ago
Could this be done in the useragent css making it compatible with previous versions?
No.  The UA style is "line-height: normal"; the exact ratio of line-height to font-size then depends on the font in use.

Comment 10

8 years ago
But that's exactly the point its not based on the font, its based on the font + render and as the renderer has been changed its caused this issue, the font is not changing here.

Not sure if its feasible / practical / workable but something like "normal" = 1.1em or something like that then at least its predictable, which is the main issue.
(Reporter)

Updated

8 years ago
Blocks: 640490

Updated

8 years ago
blocking-fx: ? → ---
(Reporter)

Updated

8 years ago
tracking-firefox5: --- → ?
tracking-firefox6: --- → ?
Is this only an issue with 'line-height: normal', or is there also a difference between GDI and DirectWrite with line-height: 1.2 or 1.0?

Also, which of the GDI or DirectWrite behavior is more similar to what happens on other platforms (using the same font)?
(discussed in triage meeting)

This is something we shipped in 4, and I don't see enough here to say that we wouldn't pull from aurora to beta without a fix for this.

But more data (e.g., answers to my previous comment) might change that.  Please renominate if you think there's information that should cause us to reconsider.
tracking-firefox5: ? → -
tracking-firefox6: ? → -

Comment 13

8 years ago
It's only an issue with line-height: normal, every other value is consistent (Doesn't line-height use font-size for it's measurement? so "normal" would use the font metrics but any other value will be a multiple of the specified font-size?)

And the rendering with DirectWrite matches the rendering on OS X at least, so this has always been "broken" in that regard.
Assignee: nobody → karlt
Status: NEW → RESOLVED
Last Resolved: 8 years ago
Resolution: --- → FIXED
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Status: REOPENED → ASSIGNED
(In reply to comment #3)
> The descriptions of DWRITE_FONT_METRICS::ascent/descent/lineGap make them
> sound like TypoAscender/TypoDescender/TypoLineGap in the OS/2 table.
> http://www.microsoft.com/typography/otspec/os2.htm

They only reflect OS/2 typo metrics when the USE_TYPO_METRICS bit in fsSelection is set to say "it is strongly recommended to use OS/2.sTypoAscender - OS/2.sTypoDescender+ OS/2.sTypoLineGap as a value for default line spacing for this font."
http://www.microsoft.com/typography/otspec/os2.htm#fss

When that bit is not set (and it is not set for Tahoma) DWrite seems to be using a legacy compatibility mode where ascent and descent come from winAscent/winDescent (same as GDI) and line height comes from the hhea metrics, apparently applying a minimum of 0 to lineGap (consistent with GDI).
Depends on: 657864
I added a patch to bug 657864 to correct rounding when the line-height comes from the font line-height metrics.  That doesn't help this bug because the line-height comes from the ascent and descent metrics.

I see two possible ways to fix this bug:

1. Round maxAscent/Descent to nearest pixel (instead of rounding up), or

2. Let the line-height be smaller than maxAscent + maxDescent.

   To avoid regressing bug 548964, ComputeDescentLimitForSelectionUnderline
   should be modified to limit to the line-height rather than the maxDescent.
   http://hg.mozilla.org/mozilla-central/annotate/eb3239a968ac/layout/generic/nsTextFrameThebes.cpp#l4449

Both approaches are quite reasonable in my opinion.
A possible complication with approach 1 is that some overflow of glyphs outside the ascent/descent may cause rendering turds.  (The overloading of layout metrics and glyph bounding boxes is unfortunate.)

I've spent more time on this than expected, which is more than I should right now, so I may not get back to this soon.
Assignee: karlt → nobody
Our quirky behavior (even when not in quirks mode) where line-heights are increased to maxAscent + maxDescent (only) when line-height is "normal" may cause problems for text areas when they calculate their height from a line-height is less than maxAscent + maxDescent.

http://hg.mozilla.org/mozilla-central/annotate/f5dbf215f9ea/layout/generic/nsLineLayout.cpp#l1954
I expect we could safely round maxAscent/Descent to nearest when it is greater than the line-height (which would show as zero lineGap in DWRITE_FONT_METRICS).
In this situation, ascent/descent most likely come from winAscent/winDescent, which is often overly generous.

We could continue to round up when maxAscent + maxDescent is less than the line height.  In this situation ascent/descent most likely come from typo metrics and could do with a bit of padding to include taller glyphs and to make text selection backgrounds and caret appear as expected.

Comment 19

7 years ago
Hi Karl et al.

I don't quite understand some of your remarks here, but they are familiar.  Let me put in my 2 cents.

Do not do any calculation of line height and spacing based on the placement of glyphs in the font (or maxAscent/maxDescent).  It is purely wrong to do so: you will screw up display of many fonts that way.  (If you're worried about ****, clip -- dont' mess with metrics.)

The font designer has the metrics and (perhaps naïvely) expects them to be adhered to.

The 'OS/2' usWinAscent/usWinDescent describe *clipping* regions (see the TrueType Reference Manual).  They ought not to have anything to do with line height.  This is made very clear in the OpenType specs.

The disparity between the specs and the usual implementation, especially on Windows, is an old problem.  Unfortunately on Windows, many apps take the usWin* metrics as line height metrics.  As you pointed out, the USE_TYPO_METRICS bit was intended to resolve this: if that is set, there should be no question.  The line height and clipping regions are clear.

In case USE_TYPO_METRICS isn't set, and the other metrics are inconsistent, there are various ad-hoc recommendations.  It's unfortunate.

In no case use should the positions of the glyphs in the font be consulted in these calculations, however.
This is based on the WIP patch from bug 598900. It switches us to using the same 'sfnt' metrics (where available) on GDI and Mac, and incorporates similar rounding to the DWrite patch. With this, the line-height test works consistently across platforms, and the Cambria Math problem from bug 598900 is also resolved.
Attachment #8369396 - Flags: review?(karlt)
Comment on attachment 8369396 [details] [diff] [review]
use more consistent and properly-rounded line-height metrics for GDI and Mac font backends.

Oops, wrong bug - meant to attach that patch to 657864.
Attachment #8369396 - Attachment is obsolete: true
Attachment #8369396 - Flags: review?(karlt)
Here's the DWrite patch, rebased to trunk; this is the only piece relevant to Win8/Metro.
Comment on attachment 8369403 [details] [diff] [review]
be more careful about rounding metrics so as to preserve line-heights  * *

Wrong again :( - moved to bug 657864.
Attachment #8369403 - Attachment is obsolete: true
Keywords: regression

Updated

5 years ago
Blocks: 997384
Blocks: 868495

Comment 25

5 years ago
I just wanted to note that DirectWrite is currently set to be enabled by default in Chrome 37[1], and so far it doesn't show the same line-height issues as Firefox.
At least I haven't noticed any problems on sites and testcases which are problematic with Firefox.

[1] http://www.chromestatus.com/features/4725550652325888

Updated

4 years ago
Blocks: 703625

Updated

4 years ago
Duplicate of this bug: 1205724
Comment hidden (spam)
Comment hidden (spam)
Comment hidden (spam)
You need to log in before you can comment on or make changes to this bug.