mathtext examples

Michael, I'm finally getting around to running the new mathtext
examples in mathtext_examples.py. Wow.

As before, I noticed a few things that don't look quite right -- as
usual, some of this may be bakoma font problems, and some may be
correct but just look funny to me, but I'll mention them briefly

    - r'$\Delta_i^j$' : the j looks too far to the right

    - \frac and \sqrt overbar: the horizontal line appears too thick,
can we make this thinner? THe look pretty good in PS, but too thick
in Agg.
The recursive frac examples are very cool!

   - r"$\sqrt[3]{\frac{X_2}{Y}}=5$", I would think the Y should be
under the X, but it is centered under the whole of X_2. Is this how
TeX does it?

  - Hinting: you mentioned that the fonts looked so bad because they
lacked hinting. Is this something entirely missing from the fonts or
are we just not making use of it? With hinting, we would have a very
serviceable set of fonts, at least until the STIX fonts come out in
2018

  - Kerning -- I may have mentioned this before. I have thought about
implementing autokerning by using the ink extent of the renderered
glyph in the freetype pixel buffer. This would enable us to properly
kern sin(2\pi) for example, if the ) char is in a different font file
than \pi. Over the vertical extent of the \pi, you could locate the
left most pixel ink of the ')' and kern it to the left a bit. Do you
think this is something worth doing, or do you have an alternative?
In the worst case scenario, one could use the spacing operators to fix
stuff up manually for publication, I suppose.

Anyway, very nice work.

JDH

John Hunter wrote:

Michael, I'm finally getting around to running the new mathtext
examples in mathtext_examples.py. Wow.

As before, I noticed a few things that don't look quite right -- as
usual, some of this may be bakoma font problems, and some may be
correct but just look funny to me, but I'll mention them briefly

    - r'$\Delta_i^j$' : the j looks too far to the right

You're right. That's a bug that crept in. The other difference (that I just noticed now), is that the \Delta is slanted, where it isn't in TeX. The rules as to when a Greek character is italicized are a little unclear to me. (Only when lowercase?)

    - \frac and \sqrt overbar: the horizontal line appears too thick,
can we make this thinner? THe look pretty good in PS, but too thick
in Agg.

With Agg (and by extension Cairo) the lines are drawn as filled rectangles rounded to the nearest integral pixel coordinates in FT2Font, rather than by using the line drawing functionality of Agg. The planned backend refactorings will make that easier, but there's probably ways to make it work now, I just haven't gotten around to it.

On a related note, the Agg backend suffers a little bit from the lack of subpixel character placement. The spacing of symbols can look slightly incorrect because of that (since their placement is rounded to the nearest integer), particularly at the smaller sizes. I haven't gotten around to experimenting with rounding vs. truncating to see if that alone makes it look any better.

The recursive frac examples are very cool!

   - r"$\sqrt[3]{\frac{X_2}{Y}}=5$", I would think the Y should be
under the X, but it is centered under the whole of X_2. Is this how
TeX does it?

Yes, that's how TeX does it. If you're curious, you can run "mathtext_examples.py --latex", which will produce a LaTeX file of all the examples and run it through pdflatex. That's what I've been using as a point of comparison as I go. Things don't match up perfectly -- tweaking is still ongoing. In general, with tons of due respect to TeX/LaTeX, while it's a good goal to emulate it as close as possible, if there are some things that we can improve on (within the much narrower context of matplotlib), I don't think we should shy away. Personally, I'm more concerned with getting the *semantics* as equivalent as possible, rather than the actual results. That goes along with my general weariness of exposing too many low-level commands, as that's where the real differences in the implementations lie. (But I may be totally off-base on those assumptions... I'd like to hear from heavy mathtext users about that).

  - Hinting: you mentioned that the fonts looked so bad because they
lacked hinting. Is this something entirely missing from the fonts or
are we just not making use of it? With hinting, we would have a very
serviceable set of fonts, at least until the STIX fonts come out in
2018

That's something I haven't looked into very deeply, and it was just conjecture based on the fact that the fonts look much more "even" at higher resolutions. I don't know if the disabled hinting bytecodes in freetype are the cause. It definitely warrants further investigation.

  - Kerning -- I may have mentioned this before. I have thought about
implementing autokerning by using the ink extent of the renderered
glyph in the freetype pixel buffer. This would enable us to properly
kern sin(2\pi) for example, if the ) char is in a different font file
than \pi. Over the vertical extent of the \pi, you could locate the
left most pixel ink of the ')' and kern it to the left a bit. Do you
think this is something worth doing, or do you have an alternative?

The cop-out answer is that TeX doesn't seem to do any kerning in math mode. Try the following: "AVA $AVA$", "({\it f}) $(f)$", for example. But that's not a reason to not do it.

That said, IMHO, we might get more mileage out of looking into ways to improve the low-level glyph rendering. The fonts look much better in acroread, for instance, than in ghostscript, with the same PDF file. Which leads me to believe it's not so much the quality of the font, but the rendering engine (or the way it's being used). I am not running the latest-and-greatest freetype2 library -- I don't know if that will make a difference.

The other thing that bothers me (but maybe not anyone else), is the font sizing. In TeX, when the font shrinks into a subscript, the characters get shorter, and the line widths stay relatively constant, rather than being uniformly scaled. The Bakoma fonts are actually available in a variety of sizes:

http://www.ctan.org/tex-archive/fonts/cm/ps-type1/bakoma/ttf/

so it is doable -- it's just a matter of writing the machinery that selects fonts based on the level of logical font size. It would mean distributing a lot more fonts with matplotlib, but with the font subsetting stuff working, it shouldn't have a significant impact on resulting file sizes.

In the worst case scenario, one could use the spacing operators to fix
stuff up manually for publication, I suppose.

True.

Cheers,
Mike

An interesting article by the author of AGG on the intricacies of font
rendering:

http://antigrain.com/research/font_rasterization/index.html

Cheers
Stéfan

···

On Fri, Aug 03, 2007 at 03:13:01PM -0400, Michael Droettboom wrote:

On a related note, the Agg backend suffers a little bit from the lack of
subpixel character placement. The spacing of symbols can look slightly
incorrect because of that (since their placement is rounded to the
nearest integer), particularly at the smaller sizes. I haven't gotten
around to experimenting with rounding vs. truncating to see if that
alone makes it look any better.

Stefan van der Walt wrote:

On a related note, the Agg backend suffers a little bit from the lack of subpixel character placement. The spacing of symbols can look slightly incorrect because of that (since their placement is rounded to the nearest integer), particularly at the smaller sizes. I haven't gotten around to experimenting with rounding vs. truncating to see if that alone makes it look any better.

An interesting article by the author of AGG on the intricacies of font
rendering:

http://antigrain.com/research/font_rasterization/index.html

Very illuminating read.

I've put the results of some of my own experiments up at:

  ftp://ftp.stsci.edu/tmp/mdroe

I've chosen to ignore subpixel anti-aliasing on LCD issue (aka ClearType) since you definitely wouldn't want that for a plot whose ultimate destination is a printer or even the web. (Besides, trying that out in matplotlib would require significant refactoring of ft2font to support color bitmaps internally.)

1) mathtext_example_default_hinting.png - Uses freetype's default hinting which uses hinting information in the file along with auto-hinting to get around some patents. This is what matplotlib was using when I got here.

2) mathtext_example_light.png - Uses freetype's "light" hinting.

3) mathtext_example_nohint.png - All hinting off.

4) mathtext_example_vert_hinting.png - This follows the suggestion in Maxim's article to hint only in the vertical direction. Since freetype doesn't support that natively, it uses a hack where you set the x-dpi to be much higher than the y-dpi, thereby hinting the x-direction to a much finer grid. When the glyph is copied from freetype's bitmap into matplotlib's bitmap, it is resampled back to the correct aspect ratio.

If you look at the examples, the character rendering differences are most pronounced, IMO, on the italic i's and y's. I think 3) looks the best and it is theoretically the most "accurate", but I imagine some will find it too blurry. Unfortunately, however, there are places where the lack of y-hinting make the text appear to have a wandering baseline (see #20 especially). 4) effectively solves that problem, at the expense of a hack.

I'm happy to commit the code for 4), however, I have reservations, since it really uglifies the code in ft2font.cpp. Once you start using freetype in "stretched space", all the metrics it returns etc. are also stretched and need to be unstretched when returning values to the caller (of ft2font). It isn't good enough to work in unstretched space and only stretch prior to rendering since the hinting causes the width of the glyphs to change based on the resolution of the grid they're being drawn on. It's not insurmountable (in fact I've already worked through most of the places where the division needs to occur), and it's completely hidden from *users* of ft2font, it just adds something fairly obscure and hackish to worry about the next time that code is modified. Are there plans to use Agg itself for font rendering in the future (and thereby push this issue downward?)

Cheers,
Mike

···

On Fri, Aug 03, 2007 at 03:13:01PM -0400, Michael Droettboom wrote:

agg 2.5, and any enhancements Maxim makes to support fonts, will be
GPL and not usable by us, sadly.

JDH

···

On 8/6/07, Michael Droettboom <mdroe@...31...> wrote:

obscure and hackish to worry about the next time that code is modified.
  Are there plans to use Agg itself for font rendering in the future
(and thereby push this issue downward?)

1) mathtext_example_default_hinting.png - Uses freetype's default
hinting which uses hinting information in the file along with
auto-hinting to get around some patents. This is what matplotlib was
using when I got here.

I am still a bit confused here -- since the bakoma cm fonts presumably
include hinting, why is it so bad? Is it just that the hinting
information in them is not good, and some of the autohinting
approaches below are simply better? I initially thought the problem
was that they didn't include hinting...

2) mathtext_example_light.png - Uses freetype's "light" hinting.

To my eyes, the biggest problems are in plain roman text, eg \sin, and
I think 1 and 2 both fail this case pretty badly (eg example 10 in
your output). TO my eyes, no hinting looks better than light hinting
for these examples (and 4 is best)

3) mathtext_example_nohint.png - All hinting off.

4) mathtext_example_vert_hinting.png - This follows the suggestion in
Maxim's article to hint only in the vertical direction. Since freetype
doesn't support that natively, it uses a hack where you set the x-dpi to
be much higher than the y-dpi, thereby hinting the x-direction to a much

I guess beauty is in the eye of the holder, but at screen resolution I
am not seeing too much difference in the italic 'i' and 'y'. But for
roman text, eg the "c" in "braces" in example 7 and "sin" in example
10, I think 3 and 4 are the best two, with 4 getting the nod.

If it is simply a case where the bakoma hinting is bad, and another
set of fonts with better hinting will solve the problem using default
hinting, we could opt to turn hinting off until we get a better set of
fonts. As for uglifying ft2font, presumably we could encapsulate the
ugliness into a helper class so we could say things like
o.get_metrics_unstretched() and o.get_metrics_stretched() and the rest
of the code would remain non-uglified..... But I'm just arm-chair
quarterbacking here....

JDH

···

On 8/6/07, Michael Droettboom <mdroe@...31...> wrote:

John Hunter wrote:

1) mathtext_example_default_hinting.png - Uses freetype's default
hinting which uses hinting information in the file along with
auto-hinting to get around some patents. This is what matplotlib was
using when I got here.

I am still a bit confused here -- since the bakoma cm fonts presumably
include hinting, why is it so bad? Is it just that the hinting
information in them is not good, and some of the autohinting
approaches below are simply better? I initially thought the problem
was that they didn't include hinting...

I haven't been able to find a way to determine if a font has embedded hinting information. However, I should have mentioned that Freetype by default will use the embedded hinting or fallback on auto-hinting. There is also an option, FT_LOAD_FORCE_AUTOHINT that will ignore the embedded hinting. It produced identical results to FT_LOAD_DEFAULT, so I presume the fonts have no embedded hinting, which sort of makes sense, given their pedigree. However, I'm flying blind on that, so if anyone can suggest a way to prove that, let me know.

My original conjecture (which I admit wasn't worded very carefully) was that if they included manually-tweaked hinting, they might look better than if they were auto-hinted. Since no one is about to add manual hinting to the font, we'll probably never know :wink:

2) mathtext_example_light.png - Uses freetype's "light" hinting.

To my eyes, the biggest problems are in plain roman text, eg \sin, and
I think 1 and 2 both fail this case pretty badly (eg example 10 in
your output). TO my eyes, no hinting looks better than light hinting
for these examples (and 4 is best)

3) mathtext_example_nohint.png - All hinting off.

4) mathtext_example_vert_hinting.png - This follows the suggestion in
Maxim's article to hint only in the vertical direction. Since freetype
doesn't support that natively, it uses a hack where you set the x-dpi to
be much higher than the y-dpi, thereby hinting the x-direction to a much

I guess beauty is in the eye of the holder, but at screen resolution I
am not seeing too much difference in the italic 'i' and 'y'.

It's subjective, but the hook in the upper-left corner of 'y' looks really anemic to me in 1) and 2). Likewise the hooks on the 'i' get too thin.

But for
roman text, eg the "c" in "braces" in example 7 and "sin" in example
10, I think 3 and 4 are the best two, with 4 getting the nod.

I think you and I are seeing the same thing: a general thinness or unevenness.

If it is simply a case where the bakoma hinting is bad, and another
set of fonts with better hinting will solve the problem using default
hinting, we could opt to turn hinting off until we get a better set of
fonts.

That's the easy solution. Unfortunately, Vera Sans looks pretty wobbly without vertical hinting.

As for uglifying ft2font, presumably we could encapsulate the
ugliness into a helper class so we could say things like
o.get_metrics_unstretched() and o.get_metrics_stretched() and the rest
of the code would remain non-uglified..... But I'm just arm-chair
quarterbacking here....

Unfortunately, it's a lot more pervasive than just that one function. But if all calls to get freetype metrics were encapsulated, that could probably be reduced. I'll think on it some more.

Cheers,
Mike

···

On 8/6/07, Michael Droettboom <mdroe@...31...> wrote: