Closed
Bug 16579
Opened 25 years ago
Closed 24 years ago
GFX needs to expose the exact font metrics
Categories
(Core :: MathML, defect, P3)
Core
MathML
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...
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 α (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 α 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 α (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
Comment 3•24 years ago
|
||
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.
Description
•