Closed Bug 18814 Opened 25 years ago Closed 24 years ago

Support real 'x-height' for ex units

Categories

(Core :: CSS Parsing and Computation, enhancement, P3)

enhancement

Tracking

()

VERIFIED FIXED

People

(Reporter: ian, Assigned: kmcclusk)

References

()

Details

(Keywords: css1, fonts, Whiteboard: [nsbeta2-])

Attachments

(2 files)

According to rbs@maths.uq.edu.au: > Work was done for MathML to enable precise measurements of > characters and strings -- see bug 16579. This work could > be used to get an accurate x-height. Currently we approximate the x-height to be 0.5 or 0.56 * font-ascent. If the above is correct, then we should be able to use the actual height of the 'x' character to determine the ex-height.
An improvement is indeed possible. Bug 19024 shows how MathML uses precise measurements of glyphs in order to build stretchy characters of larger size. In particular, the x-height can be obtained (and cached in GFX) with a call to GetBoundingMetrics(). Specifically for the record, the code could like: char x = 'x'; nsBoundingMetrics bm; rv = GetBoundingMetrics(&x, PRUint32(1), bm); if (NS_SUCCEEDED(rv) && 0 < bm.ascent - bm.descent) xheight = bm.ascent - bm.descent; else { // fallback to hacks... } Notice however that GetBoundingMetrics() is not part of the build, it is presently confined in #ifdef MOZ_MATHML.
Assignee: pierre → kmcclusk
Severity: minor → enhancement
This issue is very similar to what we have in bug 9640, assigned to kmcclusk. Marking as "Enhancement" because it doesn't seem to present any problem for now (or at least, none has been described). We have some platform-specific considerations here. For instance, I'm not sure we can get the height of a specific character on the Mac (the width, yes).
Status: NEW → ASSIGNED
Target Milestone: M16
Keywords: css1
Migrating from {css1} to css1 keyword. The {css1}, {css2}, {css3} and {css-moz} radars should now be considered deprecated in favour of keywords. I am *really* sorry about the spam...
I just checked a code section in nsFontMetricsWin::RealizeFont() to return the real x-height that we need for precise MathML positioning. The code is in #ifdef MOZ_MATHML, but I think that particular code section has to become part of the default build ASAP. Otherwise some authors could design their pages with the approximate value (believing that it is the real x-height), and could complain when the real code is switched on. For clarity the code section is enclosed in begin-end comments. Also, in terms of PP, the code will make Mozilla Win32 match was is done with Linux's XGetFontProperty(fontInfo, XA_X_HEIGHT, &pr).
Summary: {css1} Support real 'x-height' for ex units → Support real 'x-height' for ex units
This bug is reported in http://richinstyle.com/bugs/mozilla.html: <quote> Section B - Bugs with units Exes Bug 1: support unreliable Although Mozilla's ex is in some measure commensurate to the x-height of the font, it does not always seem to represent the true x-height. See one of RichInStyle.com's test pages for a demonstration. <http://richinstyle.com/test/keyconcepts/ex.html> </quote>
Todd Fahrner says at http://www.eu.microsoft.com/mac/IE/Testimonials/fahrner.asp that Mac IE5 "nails" all of CSS1, including the ex unit - which apparently means that is has proper support. We don't want to be worse than MS here, do we? :-)
Moving to M17
Target Milestone: M16 → M17
Changing Platform/OS to All/All since this is most probably a cross-platform bug, and adding 'fonts' keyword.
Keywords: fonts
OS: Windows 98 → All
Hardware: PC → All
rbs, any chance you could take this on? Marking helpwanted. Nom. nsbeta2, recc. nsbeta2+ [some lenient date-], falling through to nsbeta3+ [some lenient date-] if not fixed during nsbeta2. Motivations: (a) don't want content developers to design content making it dependent on an incorrect sizing (which will create a forward migration issue for the content if the bug's fixed post-FCS), and (b) want to match IE5 Mac's reported correctness on this.
OK I will look at this on Win32. The code is already there (we have been using it for MathML purposes for quite some time). I will consolidate things and get in touch with Kevin and Erik for review/comments.
[nsbeta2-] but we'd certainly love to have a patch from Roger through mozilla.org
Whiteboard: [nsbeta2-]
Keywords: patch
Added on the status whiteboard that the fix is ready.
Whiteboard: [nsbeta2-] → [nsbeta2-] have fix, awaiting clearance to checkin
Roger, I reviewed the code, and it looks good. Thanks for your help. Kevin, are we clear to check in?
In your capacity of text-owner, I guess your review seems ok with Kevin, right? Do I have a=waterson for check-in?
Nit: use an enum (not an int) for nsGlyphAgent::mState. If Erik is okay with it, then I am too.
I'm OK with changing mState from an int to an enum. I don't know whether Kevin approves with the changes. Although I own text layout, Kevin still owns the GFX public APIs and the Windows implementation of GFX. Kevin?
Updated the patch to use enum an checked in given that Kevin has expressed no particular reservations. Marking FIXED to clear the radar.
Status: ASSIGNED → RESOLVED
Closed: 24 years ago
Resolution: --- → FIXED
The test case -- http://richinstyle.com/test/keyconcepts/ex.html -- is useless since it is invalid HTML. And we can't even change it to check that it works, since the licence it is published under says we are not allowed to touch it. Woohoo. So, I made my own. http://www.bath.ac.uk/%7Epy8ieh/internet/projects/mozilla/ex.html What I found is that we define the height of the 'ex' unit as exactly equal to the bounding box of an 'x' character. This is mostly fine, except in special cases where the 'x' character is not based on the baseline. The x-height, according to the specs, is the distance from the baseline to the top of the lowercase glyphs in the font. [1] In these cases, an image that is '1ex' in height will overshoot the top of lowercase glyphs if it is aligned on the baseline. This is particularly visible when using the Ahem font. But of course this is a very rare edge case. (I hope.) Conclusion: Our current implementation is therefore not 100% perfect, but a damn sight better than the 1ex = 0.5em approximation we used to have. VERIFIED FIXED. [1] http://www.w3.org/TR/REC-CSS2/fonts.html#xht
Status: RESOLVED → VERIFIED
Keywords: helpwanted
Whiteboard: [nsbeta2-] have fix, awaiting clearance to checkin → [nsbeta2-]
So, it means we should be using the 'ascent' of x (not the full 'height' :-) We also have the ascent information in the gylph metrics. Here is the patch to fix this. Seeking a=waterson to correct this misinterpretation of the spec. Index: nsFontMetricsWin.cpp =================================================================== RCS file: /cvsroot/mozilla/gfx/src/windows/nsFontMetricsWin.cpp,v retrieving revision 3.86 diff -u -r3.86 nsFontMetricsWin.cpp --- nsFontMetricsWin.cpp 2000/07/18 21:54:33 3.86 +++ nsFontMetricsWin.cpp 2000/07/25 02:24:36 @@ -2796,9 +2796,9 @@ // Begin -- section of code to get the real x-height with GetGlyphOutline() GLYPHMETRICS gm; DWORD len = gGlyphAgent.GetGlyphMetrics(dc, PRUnichar('x'), 0, &gm); - if (GDI_ERROR != len && gm.gmBlackBoxY > 0) + if (GDI_ERROR != len && gm.gmptGlyphOrigin.y > 0) { - mXHeight = NSToCoordRound(gm.gmBlackBoxY * dev2app); + mXHeight = NSToCoordRound(gm.gmptGlyphOrigin.y * dev2app); } // End -- getting x-height
Roger, my respect for you increases by orders of magnitude on a daily basis. :-) What exactly is the 'ascent'? Would it give the right answer for '1ex' in the following case? ------------------ top of em square --\---/----------- top of lowercase glyphs --- \ / | 1ex X | ---/-\------------ baseline --- / \ ------------------ bottom of em square I guess we'd better reopen the bug, since you are fixing it. :-)
Status: VERIFIED → REOPENED
Keywords: approval
Resolution: FIXED → ---
Yes, it will give the information you described: the vertical distance from the origin (baseline) to the top-most pixel of the drawn string. (These are the metrics that we use for precise MathML type-setting and that's why it is painstaking, and would be overkill if used for all normal HTML :-)
That's excellent Roger. You rock. :-)
rbs: I'm looking at http://msdn.microsoft.com/library/psdk/gdi/fontext_48he.htm and trying to understand what the difference between gmptGlyphOrigin and gmBlackBoxY. I presume that this code makes it so that you're getting the 'x' character's ascent, and not it's total height? If so, is it the case that we call "ascent" as "height"? After all, you are assigning this value to mXHeight, no? Confused, but willing to learn...
gmBlackBoxY that we were using before is the height of the smallest rectangle that exactly encloses the entire glyph. But, in their convention noted by Ian, CSS people (i.e., clients of mXHeight) meant only the height of that part that extends above the baseline :-)
got it. r,a=waterson
Checked-in.
Status: REOPENED → RESOLVED
Closed: 24 years ago24 years ago
Resolution: --- → FIXED
I notice the bug was marked on all platforms, but only a Win32 patch was created. Does this mean Mac/Linux are uneffected and have been right all along?
Taking QA. VERIFIED FIXED on Win2K using commercial build 2000072520. Nice on Roger! I need to checked this on Mac and Linux as well.
QA Contact: chrisd → py8ieh=bugzilla
VERIFIED. It works fine with scaled fonts. With the bitmapped fonts that come up as 'fantasy' and 'cursive' on my X server it seems ascent/descent information in the font was wrong, because the 'ex' ended at the top of the background. But then those fonts are way broken anyway.
Status: RESOLVED → VERIFIED
Did this ever get tested on Mac? It appears to not work entirely right; see bug 154007.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: