Les polices de caractères TeXmacs |
The way TeXmacs handles fonts is quite different from classical text editors and even from TeX. Let us first analyze some classical ways of conceiving fonts.
Clearly, among all these methods, TeX provides the largest flexibility. However, philosophically speaking, we think that it also has some drawbacks:
Actually, in TeX, the notion of “the current font” is ill-defined: it is merely the superposition of all character generating commands.
Philosophically speaking, we think that a font should be characterized by the following two essential properties:
By a word, we either mean a word in a natural language, or a sequence of mathematical, technical or artistic symbols.
This way of viewing fonts has several advantages:
Notice finally that the “graphical meaning” of a word might be more than just a bitmap: it might also contain some information about a logical bounding box, appropriate places for scripts, etc. Similarly, the “coherence of the association” should be interpreted in its broadest sense: the font might contain additional information for the global typesetting of the words on a page, like the recommended distance between lines, the height of a fraction bar, etc.
All text strings in TeXmacs consist of sequences of either specific or universal symbols. A specific symbol is a character, different from '\0', '<' and '>'. Its meaning may depend on the particular font which is being used. A universal symbol is a string starting with '<', followed by an arbitrary sequence of characters different from '\0', '<' and '>', and ending with '>'. The meaning of universal characters does not depend on the particular font which is used, but different fonts may render them in a different way.
Universal symbols can also be used to represent mathematical symbols of variable sizes like large brackets. The point here is that the shapes of such symbols depend on certain size parameters, which can not conveniently be thought of as font parameters. This problem is solved by letting the extra parameters be part of the symbol. For instance, "<left-(-1>" would be usual bracket and "<left-(-2>" a slightly larger one.
The main abstract font class is defined in font.hpp:
struct font_rep: rep<font> {
display dis; // underlying display
encoding enc; // underlying encoding of the font
SI design_size; // design size in points/256
SI display_size; // display size in points/PIXEL
double slope; // italic slope
space spc; // usual space between words
space extra; // extra space at end of words
SI y1; // bottom y position
SI y2; // top y position
SI yfrac; // vertical position fraction bar
SI ysub; // base line for subscripts
SI ysup; // base line for superscripts
SI wpt; // width of one point in font
SI wquad; // wpt * design size in points
SI wunit; // unit width for extendable fonts
SI wfrac; // width fraction bar
SI wsqrt; // width horzontal line in square root
SI wneg; // width of negation line
font_rep (display dis, string name);
font_rep (display dis, string name, font fn);
void copy_math_pars (font fn);
virtual void get_extents (string s, text_extents& ex) = 0;
virtual void draw (ps_device dev, string s, SI x, SI y) = 0;
virtual SI get_sub_base (string s);
virtual SI get_sup_base (string s);
virtual double get_left_slope (string s);
virtual double get_right_slope (string s);
virtual SI get_left_correction (string s);
virtual SI get_right_correction (string s);
virtual SI get_lsub_correction (string s, double level);
virtual SI get_lsup_correction (string s, double level);
virtual SI get_rsub_correction (string s, double level);
virtual SI get_rsup_correction (string s, double level);
void var_get_extents (string s, text_extents& ex);
void var_draw (ps_device dev, string s, SI x, SI y);
virtual bitmap_char get_bitmap (string s);
};
The main abstract routines are get_extents and draw. The first routine determines the logical and physical bounding boxes of a graphical representation of a word, the second one draws the string on the the screen.
The additional data are used for global typesetting using the font. The other virtual routines are used for determening additional properties of typesetted strings.
Several types of concrete fonts have been implemented in TeXmacs:
In most cases, the lowest layer of the implementation consists of a collection of bitmaps, together with some font metric information. The font is responsable for putting these bitmaps together on the screen using some appropriate spacing. The ps_device class comes with a method to display bitmaps in a nice, anti-aliased way, or to print them out.
After having implemented fonts themselves, an important remaining
issue is the selection of the appropriate font as a function of a
certain number of parameters, such as its name, series, shape and
size. For optimal flexibility, TeXmacs comes with a powerful
macro-based font-selection scheme (using the
At the lowest level, we provide a fixed number of macros which directly correspond to the above types of concrete fonts. For instance, the macro
(tex $name $size $dpi)
corresponds to the constructor
font tex_font (display dis, string fam, int size, int dpi, int dsize=10);
of a TeX text font.
At the middle level, it is possible to specify some rewriting rules like
((roman rm medium right $s $d) (ec ecrm $s $d))
((avant-garde rm medium right $s $d) (tex rpagk $s $d 0))
((x-times rm medium right $s $d) (ps adobe-times-medium-r-normal $s $d))
When a left hand pattern is matched, it is recursively substituted by the right hand side. The files in the directory progs/fonts contain a large number of rewriting rules.
At the top level, TeXmacs calls a macro of the form
($name $family $series $shape $size $dpi)
as a function of the current environment in the text. In the future, the top level macro call might change in order to enable the user to let the font depend on other environment variables.