Closed Bug 16579 Opened 25 years ago Closed 24 years ago

GFX needs to expose the exact font metrics

Categories

(Core :: MathML, defect, P3)

defect

Tracking

()

RESOLVED FIXED

People

(Reporter: rbs, Assigned: mahamud)

Details

Shyjan Mahamud wrote: > > mathml requires precise positioning of characters in certain situations, > most importantly when building new glyphs from parts. the current > font api only gives overall metrics for the font as a whole. > i think one can easily extend it to get the exact metrics for > an individual character in a cross-platform manner. it is simply an > extension of the nsIRenderingContext::GetWidth () interface. > i have implemented the changes to linux and things come out as expected. What might be useful next would be to extend what you did to a string, and provide a method (and its variants) in the nsIRenderingContext API. This way, all platforms who care about having a beautiful MathML engine would have to implement the method and its variants. Over to you shiyan...
Status: NEW → ASSIGNED
The GetBoundingMetrics() interface and code have landed in GFX. In conjunction with this landing, the support for the Symbol font that Erik did on windows was landed and is now available. (On Linux, the symbol font is still in #ifdef MOZ_MATHML -- over to Erik to default it, the CSS font-family bug fix has to be defaulted as well). Do a search for GetBoundingMetrics in LXR to see how it is entangled in GFX. The support for the Symbol font on Windows is a big work which is best appreciated through a diff (Bonsai). The log messages on Tinderbox read: Summary: GetBoundingMetrics() added in nsIRenderingContext and associated changes elsewhere (patform-specific) to support its implementation. Fixes for existing bugs discovered while doing the implementation. Details for gfx/public: * API of the GetBoundingMetrics() method for accurate measurements of a string in order to allow precise positionning when processing MathML. review: Erik, Shyjan. Details for gfx/src/ps: * Empty hooks to make the code compile while awaiting implementation. Details for gfx/src/gtk: * Shyjan Mahamud <mahamud@cs.cmu.edu>'s changes to enable the symbol font on Linux, as well as the fix for the CSS font-family bug, and the computation of the bounding metrics. review: Erik, rbs. Details for gfx/src/windows: * Erik van der Poel <erik@netscape.com>'s code for the support of the Symbol font. review: Shyjan, rbs. * My changes to DrawString to use the baseline as the reference point and changes aimed at computing the bounding metrics. review: Erik, Shyjan
No bug was explicitly entered in Bugzilla for the CSS font-family bug. Here is a n.p.m.mathml's post from Shyjan that describes the issue in great detail. From: Shyjan Mahamud <mahamud@cs.cmu.edu> <snip...> i will briefly describe the problem and then give a bug fix. in the course of doing so, i unconvered another serious bug this time solely due to the FindFont ('a') hack where in some cases, the order of fonts specified in the font-family is not respected. i believe i also have a bug fix for this, but i need feedback from erik and frank to be sure. here's what happens : i specify {font-family : symbol; } in my CSS property list. however, as discussed at length in this thread, the first thing that the font machinery does is to get an ascii font by calling FindFont ('a'). So it tries to find 'a' in the symbol font (since that is what we specified) which ofcourse it does not contain. next, as erik points out above, it tries to find out an 'a' in the global font list (that is ALL the fonts installed on your computer). it manages to do that and returns with an ascii font. so far things are going fine. but there is an important side effect : because the font machinery could not find an 'a' in the symbol font, it did not actually load it up. more precisely, IS_REPRESENTABLE and all the other data structures are properly set up, but IS_REPRESENTABLE fails on 'a' (the correct behaviour) and hence the symbol font does not actually get loaded up, i.e. it does not get inserted into nsFontGTK::mLoadedFonts. Also for good reasons, since the font-family list has been exhausted now (it only had symbol in our example), the font-family list is never traversed again. [for the skeptics who need more proof, traversing the font-family list is controlled by the while (mFontsIndex < mFontsCount) {...} loop in FindFont () which always increments mFontsIndex, which is never reset anywhere else (for good reasons that i won't go into now)]. after some time the mathml engine is processing the mathml fragment and requests the font machinery for the metrics for a character in the say &alpha; (which the symbol font contains). As discussed above, the font-family list will never be traversed again and hence the font machinery goes back to looking for &alpha; in the global list. now is where frank's observation comes into play. in the global font list we are not just restricting ourselves to symbol fonts. any font that has an adobe-fontspecific charset encoding will be thought to have a symbol encoding but that is not what we want for our case. as discussed elsewhere by erik and frank the font machinery currently looks at only the charset encoding field of a font to decide what converter to load for the font. this works most of the time as when the encoding is iso8859-1. in such a case ALL fonts that have iso8859-1 as its encoding label will have the same unicode to font index converter and hence can be determined uniquely by just knowing the encoding label (iso8859-1 in this case). but when the encoding is something like "adobe-fontspecific" the converter can in general be different for different fonts that have the same "adobe-fontspecific" as its encoding label. hence the font machinery needs to know more than just the label for the font to decide on a converter in this case. However, currently it doesn't try to get additional information to disambiguate. Continuing our example, with the current setup, while searching through the global font list, all the fonts with adobe-fontspecific encoding label are considered to represent the same set of unicode characters. since the converter for the adobe-fontspecific encoding has been set to that for the symbol, the very first font (irrespective of whether it was a symbol font or not) that has the adobe-fontspecic encoding label is wrongly thought to encode &alpha; (all other fonts with encoding labels different from "adobe-fontspecific" are filtered away since they have non-overlapping encodings). hence the first adobe-fontspecific font on my system (which happens not to be symbol) is thus returned and as far as the font machinery is concerned, it is indistinguishable from the the actual symbol font we are after. remember, we would never have got to this situation of searching the global font list had it not been for the FindFont ('a'), since otherwise we would only be searching for all the fonts in the symbol family list. the proposed solution by frank and erik was to use a combination of family name (like symbol) *and* the encoding label (adobe-fontspecific) to figure out the converter for the font. this was easily done by a simple indirection patterned after how the &Ignore charSetInfo in GetFontNames is handled. i define another charSetInfo &Special and when this tag is detected, the family name is also used to figure out the converter through an (encoding label -> converter) table patterned after the gCharSetMap table. i believe the code functions correctly, but ofcourse i need feedback from erik and frank to be sure. (To erik and frank: in the patch there is also some code to filter out true type symbol fonts, ignore that for now since that is a peculiarity of my setup). the result, not only is the symbol font loaded correctly, but i also no longer even need to specify any font including symbol or an ascii font on the CSS font-family list. the font machinery nicely takes care of everything. and ofcourse, this fix should correctly handle the zapf dingbat font. (i don't have it on my system so frank may want to test it out after adding the relevant converter info in the various tables). however, we are not completely out of the woods yet regarding the FindFont ('a') hack. having fixed the above bug, i uncovered another one which affects the correct processing of the CSS font-family list. having gone through the relevant parts of the font machinery in some detail above, i can quickly describe what the new bug is. suppose we specify { font-family : symbol, helvetica }, the intention is to always search the symbol font first and then helvetica. this is important for math since some common operators like '+' is present in both and we want the ones from symbol to override those in the ascii font helvetica since the former are well matched to the rest of the symbol glyphs. see the screen shot below, in the first the '+' come from symbol, in the second from helvetica. the second ones look fat and don't fit well with the rest. (people who have grown up being used to tex math rendering are very picky about such things!). in any case, the claim is that even after specifying the order above for the font-family, because of the FindFont ('a') hack we in fact get the reverse order ! here's why : the first thing that gets done is FindFont ('a'). The font machinery goes through the list in order : symbol first and then helvetica. symbol does not contain 'a', and as explained above it does not get loaded in mLoadedFonts. helvetica does contain 'a' and so it does get loaded as the *first* font in mLoadedFonts. whatever happens from now on, during search for other characters including symbol characters, the symbol font will only get loaded after helvetica on mLoadedFonts font array. The order in mLoadedFonts is what's actually used by the font machinery to determine priority, not the original order in font-family list (and as far as i can tell that's not easy to fix). In fact i can show something more general (this might actually pique the interest of people on this list who do math for a living :), i can construct a set of fonts that overlap for most of the glyphs but each font also contains a set of "distinguishing glyphs" that is not contained in any other font, then if you specify *any* order for these fonts on the font-family list, i can construct a document containing among other things the "distinuishing glyphs" in a particular order, which will force font machinery to change the order of the font-family list to any order I want! a bug fix for this is also in the patch, this needs much more scrutiny from erik and frank since it can affect other assumptions that i don't know about. all the code is #ifdef'ed in any case. <snip...> - shyjan
This bug has not been touched for more than nine months. In most cases, that means it has "slipped through the net". Please could the owner take a moment to add a comment to the bug with current status, and/or close it. Thank you :-) Gerv
Resolved as FIXED. GetBoundingMetrics() is now supported on Linux/Win32, and the bug about the ordering of the font-family list has been fixed as well. The remaining issues (such as the support of GetBoundingMetrics() on the Mac) may get different bugs later.
Status: ASSIGNED → RESOLVED
Closed: 24 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.