As a final suggestion, we could have the Text object
> initialize the fontfamily attribute to a sans-serif font
> list, e.g. the one given above, since that seems to be a
> popular font family for many users.
I think all of the suggestions are good ones. I wasn't aware of the
CSS standards, but GTK (which provided the matplotlib font model) is
very close to it, including the use of xxlarge, etc.
> Please let me know what you think about this suggestion and
> if you have any changes to the design.
I think font handling should be factored out of the Text class into a
dedicated class.
class Font:
pass
class Text(dpi, bbox, font, etc...):
pass
AFAIK, noone is directly instantiating Text instances in their code so
I don't think we'll have many API complaints. Then the respective
font finders (ttf and afm) can use the font instance in combination
with the CSS algorithm to find the fonts.
This won't be too hard on the backends since most of them are already
using the font finders to get the ttf or afm filenames, so most of
these changes will be insulated except for changing the arguments of a
few functional calls. The major overhaul will be in matplotlib.text
and in the classes that instantiate text (Axis, Axes, Figure). I like
the idea of using relative sizes in all these classes.
For user API compatibility, the critical thing is to preserve the
getters and setters of Text, since the following is legal code
t = title('hi mom', fontname='Courier', fontsize=12)
which calls text.set_fontname and text.fontsize under the hood.
But the setters and getters can just forward the call to the new font
instance as necessary.
Vis-a-vis backends:
GTKAgg, Agg, TkAgg, GD, Paint: no problems here as they all use
ttf_font_finder
PS: As far as the finder algorithm is concerned, it would be nice if
it was sufficiently generic that backend_ps could use it too. If
you define an API that the algorithm needs vis-a-vis font
properties, we modify the AFM and FT2Font classes to provide
these.
GTK: I think with minor changes we can make GTK play nicely with any
ttf font on the system. I have to do a little more research.
If not, the GTK font setup is so close to the CSS one that I can
do the mapping pretty easily.
WX: There is a standard set of WX fonts. I'm not sure how to map the
generic ideas you put forth to the concrete fonts wx knows about,
other than extending the fontnames dictionary to handle as many
of the typical font names as possible and/or having users set the
wx fontnames in matplotlibrc.
It would also help to provide some helper functions which map
numeric font weights to one of normal|bold|heavy|etc and the
string font sizes to points (eg 'medium'->12pt) for the backends
that don't know about these newfangled options.
That way in backend_wx we could do
s = font.get_weight_as_string()
weight = self.fontweights[s] # this dict already exists in WX and GTK
size = font.get_size_in_points()
...etc...
In addition, Jeremy has indicated an interest in implementing
WXAgg backend, which would get the new font handling for free.
Division of labor: if you want to make the required changes to
text.Text, ttf_font_finder and (optionally) matplotlibrc I'm all for
it. Once you have a prototype, I can help with all the text
instantiators if you like, or you can do this too. Whichever way, I
can definitely help with the backend ports once the above issues are
resolved.
I've already been planning to refactor the backend text API, that
would have required a font instance anyway. For all the other
attributes (lines, rectangles, etc), the backends don't know about the
matplotlib objects. eg, we say draw_line(x1,y1, x2,y2), not
draw_line(lineObject). But I am currently passing a text instance in
to draw_text.
I realized this was a problem when I wanted to fix newline handling
across backends. The best way to do this is for the Text class to
split strings on newlines, do the layout in the front end, and then
call draw_text(x,y,s,font) for all the newline split strings in the
original string. Likewise, most of the text layout stuff like
alignment that is currently done in the backend should be moved to the
Text class. So I'll work on these changes in parallel.
JDH