texfont.h /size: 37 Kb    last modification: 2025-02-21 11:03
1/*
2    See license.txt in the root of this project.
3*/
4
5# ifndef LMT_TEXFONT_H
6# define LMT_TEXFONT_H
7
8# include "tex/textypes.h"
9
10/*tex
11
12    In the \WEBC\ infrastructrure there is code that deals with endianness of the machine but in
13    \LUAMETATEX\ we don't need this. In \LUATEX\ sharing the format file was already dropped, simply
14    because we can also store \LUA\ bytecode in the format. In the other engines font data can end
15    up in the format file and that in turn then also can be endian dependent. But in \LUAMETATEX\
16    we no longer stored font data, and that is yet another reason why there is no endian related
17    code here.
18
19    The ligature and kern structures are for traditional \TEX\ fonts, thise that are handles by the
20    built in reference handlers. Although \OPENTYPE\ is more versatile, we should not forget that
21    for many (latin) scripts these so called base fonts are quite adequate and efficient. We could
22    of course implement base support in \LUA\ but although \LUAMETATEX\ can delegate a lot, we also
23    keep the reference implementation available: it is well documented, was for a long time the best
24    one could get and doesn't take that much code. So, here come the basic structures:
25
26*/
27
28typedef struct ligatureinfo {
29    int type;
30    int ligature;
31    int adjacent;
32    /* alignment */
33    int padding;
34} ligatureinfo;
35
36typedef struct kerninfo {
37    int kern;
38    int adjacent;
39} kerninfo;
40
41/*tex
42
43    In \LUAMETATEX, at runtime, after a font is loaded via a callback, we only store the little
44    information that is needed for basic ligature building and kerning, math rendering (like
45    extensibles), and par building which includes protrusion and expansion. We don't need anything
46    related to the backend because outpout is delegated to \LUA.
47
48    The most extensive data structures are those related to \OPENTYPE\ math. When passing a font we
49    can save memory by using the |hasmath| directive. In \LUAMETATEX\ we can then have a different
50    |struct| with 15 fields less than in \LUATEX\ which, combined with other savings, saves some 60
51    bytes. The disadvantage is that accessors of those fields also need to act upon that flag, which
52    involves more testing. However, because in practice math font access is not that prominent so
53    the gain outweights this potential performance hit. For an average \CJK\ font with 5000
54    characters we saves 300000 bytes. Because a complete Latin font with various features also can
55    have thousands of glyphs, it can save some memory there too. It's changes like this that give
56    \LUAMETATEX\ a much smaller memory footprint than its predecessor.
57
58    The next record relates to math extensibles. It is good to realize that traditional \TEX\ fonts
59    are handled differently in the math subengine than \OPENTYPE\ math fonts. However, we use the
60    more extensive \OPENTYPE\ structure for both type of fonts.
61
62*/
63
64typedef struct extinfo {
65    struct extinfo *next;
66    int             glyph;
67    int             start_overlap;
68    int             end_overlap;
69    int             advance;
70    int             extender;
71    /* alignment */
72    int             padding;
73} extinfo;
74
75/*tex 
76    We have dedicated fields for hparts and vparts and their italics. Only avery few fonts actually
77    set the italic on the extensible which is why the engine can use the regular italic, which in 
78    that case is then the last in the variant list because that is where we put the recipe. Keep in
79    mind that in an \OPENTYPE\ fonts we have a base glyph that has a variant list and part recipe 
80    while in the engine (in good \TEX\ tradition) we chain the variants (with the next field)) so by 
81    the time we arrive at the last one we look at the (h,v) italic there. No fonts (so far) have a 
82    horizontal extensible with a set italic correction. 
83    
84    Actually, because the specification is rather explicit about glyphs only having horizontal or
85    vertical extensibles we now have collapsed the two categories into one.
86*/
87
88typedef struct mathinfo {
89    /*tex
90       Optional code points for next smaller in size, right2left and flat accent glyphs.
91    */
92    halfword  smaller;     
93    halfword  mirror;      
94    halfword  flat_accent; 
95    halfword  next;
96    /*tex 
97        The top anchor is provides by the font and is also known as topaccent while the bottom 
98        anchor is one set by (in our case) \CONTEXT.  
99    */
100    scaled    top_anchor;              
101    scaled    bottom_anchor;           
102    /*tex 
103        A set of pointers to variable size arrays which is why we also have the number of slots 
104        stored. 
105
106        These four might go away because in practice they are incomplete or even in accurate and
107        we (need and therefore) have an alternative and more generic approach anyway.
108    */
109    int       top_left_math_kerns;        
110    int       top_right_math_kerns;       
111    int       bottom_right_math_kerns;    
112    int       bottom_left_math_kerns;     
113    scaled   *top_left_math_kern_array;       
114    scaled   *top_right_math_kern_array;      
115    scaled   *bottom_right_math_kern_array;   
116    scaled   *bottom_left_math_kern_array;    
117    /*tex 
118        Here come the extensible recipes. Because we haven't seen both in one glyph we can share 
119        the pointer and put a h/v flag in the tag field. For the moment we keep them both because
120        we might want to play with a two dimensional extensible some day. 
121    */
122    extinfo  *extensible_recipe;        
123    scaled    extensible_italic;        
124    /*tex We could have a list or array here too but gain little.: */
125 /* halfword *variant_list; */
126    /*tex These are for specific (script) anchoring. */
127    scaled    top_left_kern;
128    scaled    bottom_left_kern;
129    scaled    top_right_kern;
130    scaled    bottom_right_kern;
131    /*tex These four are used in accents. */
132    scaled    left_margin;
133    scaled    right_margin;
134    scaled    top_margin;
135    scaled    bottom_margin;
136    /*tex As are the following. */
137    scaled    top_overshoot;
138    scaled    bottom_overshoot;
139    /*tex These are for degrees in radicals. */
140    scaled    inner_x_offset; 
141    scaled    inner_y_offset; 
142} mathinfo;
143
144typedef struct charinfo {
145    /*tex
146        This is what \TEX\ uses when it calculates the dimensions needed for building boxes and
147        breaking paragraphs into lines. The italic correction is part of that as it has a primitive
148        that needs the value.
149    */
150    scaled        width;
151    scaled        height;
152    scaled        depth;
153    scaled        italic;
154    /*tex
155        The next three variables relate to expansion and protrusion, properties introduced in the
156        \PDFTEX\ engine. Handling of protrusion and expansion is the only features that we inherit
157        from this important extension to traditional \TEX. 
158
159        We can make the next four into a a pointer which saves on large fonts and only a subset 
160        of characters has protrusion or expansion, if used at all. That way we delegate some memory 
161        consumption to usage (of course allocated blobs also have overhead).  
162    */
163    scaled        expansion;    
164    scaled        compression;
165    scaled        leftprotrusion;
166    scaled        rightprotrusion;
167    /*tex
168        The tag and remainder are used in a \TFM\ file for signaling ligatures. They are also used 
169        for math extensions in traditional \TEX\ fonts. We used to pack the tag and remainder
170        in an integer: 2 bits is enough for the tag (but we get some more) and the remainder (aka 
171        next) fits in 21 bits. So we had |tagrem| for quite a while. 
172
173        But we now use a 32 bit tag field and use proper next field that has been moved to the math 
174        blob so that we can have a compression field here without padding. 
175    */
176    halfword      tag; 
177    /*tex
178        Traditional \TEX\ fonts use these two lists for ligature building and inter-character
179        kerning and these are now optional (via pointers). By also using an indirect structure for
180        math data we save quite a bit of memory when we have no math font.
181
182        We could combine math and ligatures and save two slots but then we cannot have a hybrid base
183        font so ... not now. 
184    */
185    kerninfo     *kerns;
186    mathinfo     *math;       
187    ligatureinfo *ligatures;  
188} charinfo;
189
190/*
191    An option is to make this a pointer to a structure but then we also waste a slot. When we 
192    never support it in math then we can actually go smaller: 
193    
194    charinfo: 8 * 4 : width height depth italic tag *[text or math] *kerns padding 
195    textinfo: 4 * 4 : expansion leftprotrusion rightprotrusion *ligatures
196    mathinfo: 2 * 4 : next padding ... n * 4 
197
198    But ... given the amount of fields that \CONTEXT\ adds to the basic character data anyway 
199    there is no real reason to spend much time in saving some bytes here.  
200
201*/
202
203/*tex
204    We can just abuse the token setters and getters here.
205*/
206
207//define charinfo_tag    token_cmd
208//define charinfo_rem    token_chr
209//define charinfo_tagrem token_val
210
211/*tex
212
213    For a font instance we only store the bits that are used by the engine itself. Of course more
214    data can (and normally will be) be kept at the \TEX\ cq.\ \LUA\ end.
215
216    We could store a scale (/1000) and avoid copying a font but then we also need to multiply
217    width, height, etc. when queried (extra overhead). A bit tricky is then dealing with (virtual)
218    commands. It is not that big a deal in \CONTEXT\ so I might actually add this feature but only
219    very few documents use many font instances so in the end the gain is neglectable (we only save
220    some memory). Also, we then need to adapt the math processing quite a bit which is always kind
221    of tricky.
222
223    Again, compared to \LUATEX\ there is less data stored here because we don't need to control the
224    backend. Of course in \CONTEXT\ we keep plenty of data at the \LUA\ end, but we did that already
225    anyway.
226
227*/
228
229typedef struct texfont {
230    /*tex the range of (allocated) characters */
231    int         first_character;
232    int         last_character;
233    /*tex the (sparse) character (glyph) array */
234    sa_tree     characters;
235    charinfo   *chardata;
236    int         chardata_count;
237    int         chardata_size;
238    /*tex properties used in messages */
239    int         size;
240    int         design_size;
241    char       *name;
242    char       *original;
243    /*tex this controls the engine */
244    int         mathcontrol;
245    int         textcontrol;
246    /*tex for experimental new thingies */
247    int         compactmath;  /* This can go away, just always test. */ 
248    /*tex saves calculations */
249    double      weight; 
250    /*tex all parameters, although only some are used */
251    int         parameter_count;
252    scaled     *parameter_base;
253    /*tex also special */
254    charinfo   *left_boundary;
255    charinfo   *right_boundary;
256    /*tex all math parameters */
257    scaled     *math_parameter_base;
258    int         math_parameter_count;
259    /* zero is alignment */
260    int         mathscales[3];
261    int         mathxscales[3];
262    int         mathyscales[3];
263    int         mathweights[3];
264    /*tex special characters, see \TEX book */
265    int         hyphen_char;
266    int         skew_char;
267} texfont;
268
269/*tex
270
271    Instead of global variables we store some properties that are shared between the different components
272    in a dedicated struct.
273
274*/
275
276typedef struct font_state_info {
277    texfont     **fonts;
278    halfword      adjust_stretch;
279    halfword      adjust_shrink;
280    halfword      adjust_step;
281    int           padding;
282    memory_data   font_data;
283} font_state_info ;
284
285extern font_state_info lmt_font_state;
286
287# define font_size(a)                   lmt_font_state.fonts[a]->size
288# define font_name(a)                   lmt_font_state.fonts[a]->name
289# define font_original(a)               lmt_font_state.fonts[a]->original
290# define font_design_size(a)            lmt_font_state.fonts[a]->design_size
291# define font_first_character(a)        lmt_font_state.fonts[a]->first_character
292# define font_last_character(a)         lmt_font_state.fonts[a]->last_character
293# define font_compactmath(a)            lmt_font_state.fonts[a]->compactmath
294# define font_mathcontrol(a)            lmt_font_state.fonts[a]->mathcontrol
295# define font_textcontrol(a)            lmt_font_state.fonts[a]->textcontrol
296# define font_hyphen_char(a)            lmt_font_state.fonts[a]->hyphen_char
297# define font_skew_char(a)              lmt_font_state.fonts[a]->skew_char
298# define font_mathscale(a,b)            lmt_font_state.fonts[a]->mathscales[b]
299# define font_mathxscale(a,b)           lmt_font_state.fonts[a]->mathxscales[b]
300# define font_mathyscale(a,b)           lmt_font_state.fonts[a]->mathyscales[b]
301
302# define set_font_size(a,b)             lmt_font_state.fonts[a]->size = b
303# define set_font_name(a,b)             lmt_font_state.fonts[a]->name = b
304# define set_font_original(a,b)         lmt_font_state.fonts[a]->original = b
305# define set_font_design_size(a,b)      lmt_font_state.fonts[a]->design_size = b
306# define set_font_first_character(a,b)  lmt_font_state.fonts[a]->first_character = b
307# define set_font_last_character(a,b)   lmt_font_state.fonts[a]->last_character = b
308# define set_font_compactmath(a,b)      lmt_font_state.fonts[a]->compactmath = b
309# define set_font_mathcontrol(a,b)      lmt_font_state.fonts[a]->mathcontrol = b
310# define set_font_textcontrol(a,b)      lmt_font_state.fonts[a]->textcontrol = b
311# define set_font_hyphen_char(a,b)      lmt_font_state.fonts[a]->hyphen_char = b
312# define set_font_skew_char(a,b)        lmt_font_state.fonts[a]->skew_char = b
313# define set_font_max_shrink(a,b)       lmt_font_state.fonts[a]->max_shrink = b
314# define set_font_max_stretch(a,b)      lmt_font_state.fonts[a]->max_stretch = b
315# define set_font_step(a,b)             lmt_font_state.fonts[a]->step = b
316
317# define set_font_textsize(a,b)         lmt_font_state.fonts[a]->mathscales[0] = b
318# define set_font_scriptsize(a,b)       lmt_font_state.fonts[a]->mathscales[1] = b
319# define set_font_scriptscriptsize(a,b) lmt_font_state.fonts[a]->mathscales[2] = b
320
321# define set_font_x_textsize(a,b)         lmt_font_state.fonts[a]->mathxscales[0] = b
322# define set_font_x_scriptsize(a,b)       lmt_font_state.fonts[a]->mathxscales[1] = b
323# define set_font_x_scriptscriptsize(a,b) lmt_font_state.fonts[a]->mathxscales[2] = b
324
325# define set_font_y_textsize(a,b)         lmt_font_state.fonts[a]->mathyscales[0] = b
326# define set_font_y_scriptsize(a,b)       lmt_font_state.fonts[a]->mathyscales[1] = b
327# define set_font_y_scriptscriptsize(a,b) lmt_font_state.fonts[a]->mathyscales[2] = b
328 
329# define set_font_textweight(a,b)         lmt_font_state.fonts[a]->mathweights[0] = b
330# define set_font_scriptweight(a,b)       lmt_font_state.fonts[a]->mathweights[1] = b
331# define set_font_scriptscriptweight(a,b) lmt_font_state.fonts[a]->mathweights[2] = b
332
333/*tex
334    These are bound to a font. There might be a few more in the future. An example is collapsing
335    hyphens. One can do that using (in context speak) tlig feature but actually it is some very
336    \TEX\ thing, that happened to be implemented using ligatures. In \LUAMETATEX\ it's also a bit
337    special because, although it is not really dependent on a language, hyphen handling in \TEX\
338    is very present in the hyphenator (also sequences of them). So, naturally it moved there. But
339    users who don't want it can disable it per font.
340*/
341
342typedef enum text_control_codes {
343    text_control_collapse_hyphens   = 0x0001,
344    text_control_base_ligaturing    = 0x0002,
345    text_control_base_kerning       = 0x0004,
346    text_control_none_protected     = 0x0008,
347    text_control_has_italics        = 0x0010,
348    text_control_auto_italics       = 0x0020,
349    text_control_replace_apostrophe = 0x0040,
350    /* these are private */
351    text_control_quality_set        = 0x0100,
352    text_control_expansion          = 0x0200,
353    text_control_left_protrusion    = 0x0400,
354    text_control_right_protrusion   = 0x0800,
355} text_control_codes;
356
357# define has_font_text_control(f,c)  ((font_textcontrol(f) & c) == c)
358# define set_font_text_control(f,c)  font_textcontrol(f) |= (c)
359
360/*tex
361    These are special codes that are used in the traditional ligature builder. In \OPENTYPE\
362    fonts we don't see these. Maybe this will be dropped at some point. 
363*/
364
365typedef enum boundarychar_codes {
366    left_boundary_char  = -1,
367    right_boundary_char = -2,
368    non_boundary_char   = -3,
369} boundarychar_codes;
370
371# define font_left_boundary(a)        lmt_font_state.fonts[a]->left_boundary
372# define font_right_boundary(a)       lmt_font_state.fonts[a]->right_boundary
373
374# define font_has_left_boundary(a)    (font_left_boundary(a))
375# define font_has_right_boundary(a)   (font_right_boundary(a))
376
377# define set_font_left_boundary(a,b)  { if (font_left_boundary(a))  { lmt_memory_free(font_left_boundary(a));  } font_left_boundary(a)  = b; }
378# define set_font_right_boundary(a,b) { if (font_right_boundary(a)) { lmt_memory_free(font_right_boundary(a)); } font_right_boundary(a) = b; }
379
380/*tex
381    The math engine can benefit from these properties. For instance we use them for optimizing 
382    the positioning of the degree in a (left) radical. These properties are not stored in the 
383    tag (for a short while we had a variable).
384*/
385
386/*tex
387    In traditional \TEX\ there are just over a handful of font specific parameters for text fonts
388    and some more in math fonts. Actually, these parameters were stored in a way that permitted
389    adding  more at runtime, something that made no real sense, but can be abused for creeating
390    more dimensions than the 256 that traditional \TEX\ provides.
391*/
392
393# define font_parameter_count(a)           lmt_font_state.fonts[a]->parameter_count
394# define font_parameter_base(a)            lmt_font_state.fonts[a]->parameter_base
395# define font_parameter(a,b)               lmt_font_state.fonts[a]->parameter_base[b]
396
397# define font_math_parameter_count(a)      lmt_font_state.fonts[a]->math_parameter_count
398# define font_math_parameter_base(a)       lmt_font_state.fonts[a]->math_parameter_base
399# define font_math_parameter(a,b)          lmt_font_state.fonts[a]->math_parameter_base[b]
400
401# define set_font_parameter_base(a,b)      lmt_font_state.fonts[a]->parameter_base = b;
402# define set_font_math_parameter_base(a,b) lmt_font_state.fonts[a]->math_parameter_base = b;
403
404/*tex
405    These font parameters could be adapted at runtime but one should really wonder if that is such
406    a good idea nowadays.
407 */
408
409//define set_font_parameter(f,n,b)         { if (font_parameter_count(f)      < n) { tex_set_font_parameters(f, n);      } font_parameter(f, n)      = b; }
410// # define set_font_math_parameter(f,n,b)    { if (font_math_parameter_count(f) < n) { tex_set_font_math_parameters(f, n); } font_math_parameter(f, n) = b; }
411
412extern void tex_set_font_parameters      (halfword f, int b);
413extern void tex_set_font_math_parameters (halfword f, int b);
414extern int  tex_get_font_max_id          (void);
415extern int  tex_get_font_max_id          (void);
416
417extern halfword tex_checked_font_adjust (
418    halfword adjust_spacing,
419    halfword adjust_spacing_step,
420    halfword adjust_spacing_shrink,
421    halfword adjust_spacing_stretch
422);
423
424/*tex
425    Font parameters are sometimes referred to as |slant(f)|, |space(f)|, etc. These numbers are
426    also the font dimen numbers.
427*/
428
429typedef enum font_parameter_codes {
430    slant_code = 1,
431    space_code,
432    space_stretch_code,
433    space_shrink_code,
434    ex_height_code,
435    em_width_code,
436    extra_space_code,
437} font_parameter_codes;
438
439extern scaled   tex_get_font_slant            (halfword f);
440extern scaled   tex_get_font_space            (halfword f);
441extern scaled   tex_get_font_space_stretch    (halfword f);
442extern scaled   tex_get_font_space_shrink     (halfword f);
443extern scaled   tex_get_font_ex_height        (halfword f);
444extern scaled   tex_get_font_em_width         (halfword f);
445extern scaled   tex_get_font_extra_space      (halfword f);
446extern scaled   tex_get_font_parameter        (halfword f, halfword code);
447extern void     tex_set_font_parameter        (halfword f, halfword code, scaled v);
448                
449extern scaled   tex_get_scaled_slant          (halfword f);
450extern scaled   tex_get_scaled_space          (halfword f);
451extern scaled   tex_get_scaled_space_stretch  (halfword f);
452extern scaled   tex_get_scaled_space_shrink   (halfword f);
453extern scaled   tex_get_scaled_ex_height      (halfword f);
454extern scaled   tex_get_scaled_em_width       (halfword f);
455extern scaled   tex_get_scaled_extra_space    (halfword f);
456extern scaled   tex_get_scaled_parameter      (halfword f, halfword code);
457extern void     tex_set_scaled_parameter      (halfword f, halfword code, scaled v);
458
459extern halfword tex_get_scaled_glue           (halfword f);
460extern halfword tex_get_scaled_parameter_glue (quarterword p, quarterword s);
461extern halfword tex_get_parameter_glue        (quarterword p, quarterword s);
462
463extern halfword tex_get_font_identifier       (halfword fs);
464
465/*tex
466    The \OPENTYPE\ math fonts have four edges and reference points for kerns. Here we go:
467*/
468
469typedef enum font_math_kern_codes {
470    top_right_kern = 1,
471    bottom_right_kern,
472    bottom_left_kern,
473    top_left_kern,
474} font_math_kern_codes;
475
476extern charinfo *tex_get_charinfo     (halfword f, int c);
477extern int       tex_char_exists      (halfword f, int c);
478extern void      tex_char_process     (halfword f, int c);
479extern int       tex_math_char_exists (halfword f, int c, int size);
480extern int       tex_get_math_char    (halfword f, int c, int size, scaled *scale, scaled *xscale, scaled *ysale, scaled *weight, int direction);
481
482/*tex 
483    These used to be small integers, bit 22 upto 31, but now we have a 32 bit set. We actually don't 
484    really need the granularity but by having these flags we can actually add a bit of control, like 
485    having kerns but still blocking them. The numbers here are no longer reflective of what a tfm 
486    file provides. We assume tfm files to be converted anyway. 
487
488    Not all are needed but at least we now can keep some state. We can actually use them to something
489    if we really want to (like when we runt tests). However, that is a rather drastic measure for 
490    shared fonts. Tracing is another application and at some point it will be used for this. 
491
492    Todo, a compact mode only feature: 
493
494      expansion_checked_tag   = 0x40000, 
495      protrusion_checked_tag  = 0x80000, 
496
497    when not yet checked, we call out to lua and get the values. That way we don't need to initialize 
498    the fonts at load time. 
499
500*/
501
502typedef enum char_tag_codes {
503    no_tag               = 0x0000000, /*tex vanilla character */
504    ligatures_tag        = 0x0000001, /*tex character has a ligature program, not used */ 
505    kerns_tag            = 0x0000002, /*tex character has a kerning program, not used */ 
506    list_tag             = 0x0000004, /*tex character has a successor in a charlist */  
507    callback_tag         = 0x0000010,
508    extensible_tag       = 0x0000020, /*tex character is extensible, we can unset it in order to block */
509    horizontal_tag       = 0x0000040, /*tex horizontal extensible */
510    vertical_tag         = 0x0000080, /*tex vertical extensible */
511    inner_left_tag       = 0x0000100, /*tex anchoring */
512    inner_right_tag      = 0x0000200, /*tex anchoring */
513    inner_top_tag        = 0x0000400, /*tex anchoring */ 
514    inner_bottom_tag     = 0x0000800, /*tex anchoring */ 
515    extend_last_tag      = 0x0001000, /*tex auto scale last variant */
516    italic_tag           = 0x0002000, 
517    n_ary_tag            = 0x0004000, 
518    radical_tag          = 0x0008000, 
519    punctuation_tag      = 0x0010000, 
520    keep_base_tag        = 0x0020000, 
521    expansion_tag        = 0x0040000,
522    protrusion_tag       = 0x0080000,
523    above_baseline_tag   = 0x0100000,
524    below_baseline_tag   = 0x0200000,
525    force_extensible_tag = 0x0400000,
526} char_tag_codes;
527
528/*tex
529    These low level setters are not public and used in helpers. They might become functions
530    when I feel the need.
531*/
532
533# define set_charinfo_width(ci,val)                        ci->width  = val;
534# define set_charinfo_height(ci,val)                       ci->height = val;
535# define set_charinfo_depth(ci,val)                        ci->depth  = val;
536# define set_charinfo_italic(ci,val)                       ci->italic = val;
537# define set_charinfo_expansion(ci,val)                    ci->expansion = val;
538# define set_charinfo_compression(ci,val)                  ci->compression = val;
539# define set_charinfo_leftprotrusion(ci,val)               ci->leftprotrusion = val;
540# define set_charinfo_rightprotrusion(ci,val)              ci->rightprotrusion = val;
541
542# define set_charinfo_tag(ci,val)                          ci->tag |= val;
543# define set_charinfo_next(ci,val)                         if (ci->math) { ci->math->next = val; }
544
545# define has_charinfo_tag(ci,p)                            (((ci->tag) & (p)) == (p)) 
546# define get_charinfo_tag(ci)                              ci->tag
547
548# define set_charinfo_ligatures(ci,val)                    { lmt_memory_free(ci->ligatures); ci->ligatures = val; }
549# define set_charinfo_kerns(ci,val)                        { lmt_memory_free(ci->kerns);     ci->kerns     = val; }
550# define set_charinfo_math(ci,val)                         { lmt_memory_free(ci->math);      ci->math      = val; }
551
552# define set_charinfo_top_left_math_kern_array(ci,val)     if (ci->math) { lmt_memory_free(ci->math->top_left_math_kern_array);     ci->math->top_left_math_kern_array = val; }
553# define set_charinfo_top_right_math_kern_array(ci,val)    if (ci->math) { lmt_memory_free(ci->math->top_right_math_kern_array);    ci->math->top_left_math_kern_array = val; }
554# define set_charinfo_bottom_right_math_kern_array(ci,val) if (ci->math) { lmt_memory_free(ci->math->bottom_right_math_kern_array); ci->math->top_left_math_kern_array = val; }
555# define set_charinfo_bottom_left_math_kern_array(ci,val)  if (ci->math) { lmt_memory_free(ci->math->bottom_left_math_kern_array);  ci->math->top_left_math_kern_array = val; }
556
557//define set_charinfo_options(ci,val)                      if (ci->math) { ci->math->options = val; }
558
559# define set_ligature_item(f,b,c,d)                        { f.type = b; f.adjacent = c; f.ligature = d; }
560# define set_kern_item(f,b,c)                              { f.adjacent = b; f.kern = c; }
561
562# define set_charinfo_left_margin(ci,val)                  if (ci->math) { ci->math->left_margin = val; }
563# define set_charinfo_right_margin(ci,val)                 if (ci->math) { ci->math->right_margin = val; }
564# define set_charinfo_top_margin(ci,val)                   if (ci->math) { ci->math->top_margin = val; }
565# define set_charinfo_bottom_margin(ci,val)                if (ci->math) { ci->math->bottom_margin = val; }
566
567# define set_charinfo_smaller(ci,val)                      if (ci->math) { ci->math->smaller = val; }
568# define set_charinfo_mirror(ci,val)                       if (ci->math) { ci->math->mirror = val; }
569# define set_charinfo_extensible_italic(ci,val)            if (ci->math) { ci->math->extensible_italic = val; }
570# define set_charinfo_top_anchor(ci,val)                   if (ci->math) { ci->math->top_anchor = val; }
571# define set_charinfo_bottom_anchor(ci,val)                if (ci->math) { ci->math->bottom_anchor = val; }
572# define set_charinfo_flat_accent(ci,val)                  if (ci->math) { ci->math->flat_accent = val; }
573
574# define set_charinfo_inner_x_offset(ci,val)               if (ci->math) { ci->math->inner_x_offset = val; }
575# define set_charinfo_inner_y_offset(ci,val)               if (ci->math) { ci->math->inner_y_offset = val; }
576
577# define set_charinfo_top_left_kern(ci,val)                if (ci->math) { ci->math->top_left_kern = val; }
578# define set_charinfo_top_right_kern(ci,val)               if (ci->math) { ci->math->top_right_kern = val; }
579# define set_charinfo_bottom_left_kern(ci,val)             if (ci->math) { ci->math->bottom_left_kern = val; }
580# define set_charinfo_bottom_right_kern(ci,val)            if (ci->math) { ci->math->bottom_right_kern = val; }
581
582# define set_charinfo_top_overshoot(ci,val)                if (ci->math) { ci->math->top_overshoot = val; }
583# define set_charinfo_bottom_overshoot(ci,val)             if (ci->math) { ci->math->bottom_overshoot = val; }
584
585# define proper_char_index(f, c) (c >= font_first_character(f) && c <= font_last_character(f))
586
587/*tex Setters: */
588
589void             tex_set_lpcode_in_font                 (halfword f, halfword c, halfword i);
590void             tex_set_rpcode_in_font                 (halfword f, halfword c, halfword i);
591void             tex_set_efcode_in_font                 (halfword f, halfword c, halfword i);
592void             tex_set_cfcode_in_font                 (halfword f, halfword c, halfword i);
593
594extern void      tex_add_charinfo_math_kern             (charinfo *ci, int type, scaled ht, scaled krn);
595extern int       tex_get_charinfo_math_kerns            (charinfo *ci, int id);
596extern void      tex_set_charinfo_extensible_recipe     (charinfo *ci, extinfo *ext);
597extern void      tex_append_charinfo_extensible_recipe  (charinfo *ci, int glyph, int startconnect, int endconnect, int advance, int repeater);
598
599/*tex Checkers: */
600
601int              tex_char_has_math                      (halfword f, halfword c);
602int              tex_has_ligature                       (halfword f, halfword c);
603int              tex_has_kern                           (halfword f, halfword c);
604
605/*tex Getters: */
606
607# define MATH_KERN_NOT_FOUND 0x7FFFFFFF
608
609extern scaled    tex_font_x_scaled                      (scaled v);
610extern scaled    tex_font_y_scaled                      (scaled v);
611
612extern scaled    tex_char_width_from_font               (halfword f, halfword c); /* math + maincontrol */
613extern scaled    tex_char_height_from_font              (halfword f, halfword c); /* math + maincontrol */
614extern scaled    tex_char_depth_from_font               (halfword f, halfword c); /* math + maincontrol */
615extern scaled    tex_char_total_from_font               (halfword f, halfword c); /* math */
616extern scaledwhd tex_char_whd_from_font                 (halfword f, halfword c); /* math + maincontrol */
617extern scaled    tex_char_italic_from_font              (halfword f, halfword c); /* math + maincontrol */
618extern scaled    tex_char_ef_from_font                  (halfword f, halfword c); /* packaging + maincontrol */
619extern scaled    tex_char_cf_from_font                  (halfword f, halfword c); /* packaging + maincontrol */
620extern scaled    tex_char_lp_from_font                  (halfword f, halfword c); /* packaging + maincontrol */
621extern scaled    tex_char_rp_from_font                  (halfword f, halfword c); /* packaging + maincontrol */
622extern halfword  tex_char_tag_from_font                 (halfword f, halfword c); /* math */
623extern halfword  tex_char_next_from_font                (halfword f, halfword c); /* math */
624extern halfword  tex_char_has_tag_from_font             (halfword f, halfword c, halfword tag); 
625extern void      tex_char_reset_tag_from_font           (halfword f, halfword c, halfword tag); 
626extern int       tex_char_checked_tag                   (halfword tag);
627extern scaled    tex_char_inner_x_offset_from_font      (halfword f, halfword c);
628extern scaled    tex_char_inner_y_offset_from_font      (halfword f, halfword c);
629extern scaled    tex_char_top_left_kern_from_font       (halfword f, halfword c); /* math */
630extern scaled    tex_char_top_right_kern_from_font      (halfword f, halfword c); /* math */
631extern scaled    tex_char_bottom_left_kern_from_font    (halfword f, halfword c); /* math */
632extern scaled    tex_char_bottom_right_kern_from_font   (halfword f, halfword c); /* math */
633extern halfword  tex_char_extensible_italic_from_font   (halfword f, halfword c);
634extern halfword  tex_char_flat_accent_from_font         (halfword f, halfword c);
635extern halfword  tex_char_top_anchor_from_font          (halfword f, halfword c);
636extern halfword  tex_char_bottom_anchor_from_font       (halfword f, halfword c);
637extern scaled    tex_char_left_margin_from_font         (halfword f, halfword c);
638extern scaled    tex_char_right_margin_from_font        (halfword f, halfword c);
639extern scaled    tex_char_top_margin_from_font          (halfword f, halfword c);
640extern scaled    tex_char_bottom_margin_from_font       (halfword f, halfword c);
641extern scaled    tex_char_top_overshoot_from_font       (halfword f, halfword c);
642extern scaled    tex_char_bottom_overshoot_from_font    (halfword f, halfword c);
643extern extinfo  *tex_char_extensible_recipe_from_font   (halfword f, halfword c);
644extern extinfo  *tex_char_extensible_recipe_front_last  (halfword f, halfword c);
645
646extern halfword  tex_char_unchecked_top_anchor_from_font    (halfword f, halfword c);
647extern halfword  tex_char_unchecked_bottom_anchor_from_font (halfword f, halfword c);
648
649extern scaled    tex_char_width_from_glyph              (halfword g); /* x/y scaled */
650extern scaled    tex_char_height_from_glyph             (halfword g); /* x/y scaled */
651extern scaled    tex_char_depth_from_glyph              (halfword g); /* x/y scaled */
652extern scaled    tex_char_total_from_glyph              (halfword g); /* x/y scaled */
653extern scaled    tex_char_italic_from_glyph             (halfword g); /* x/y scaled */
654extern scaled    tex_char_width_italic_from_glyph       (halfword g); /* x/y scaled */
655extern scaledwhd tex_char_whd_from_glyph                (halfword g); /* x/y scaled */
656extern scaled    tex_char_left_protrusion_from_glyph    (halfword g); /* x/y scaled */
657extern scaled    tex_char_right_protrusion_from_glyph   (halfword g); /* x/y scaled */
658extern scaledkrn tex_char_corner_kerns_from_glyph       (halfword g); /* x/y scaled */
659                                                       
660extern int       tex_valid_kern                         (halfword left, halfword right);            /* returns kern */
661extern int       tex_valid_ligature                     (halfword left, halfword right, int *slot); /* returns type */
662                                                       
663extern scaled    tex_calculated_char_width              (halfword f, halfword c, halfword ex);
664extern scaled    tex_calculated_glyph_width             (halfword g, halfword ex); /* scale */
665
666/*tex
667    Kerns: the |otherchar| value signals \quote {stop}. These are not really public and only
668    to be used in the helpers. But we keep them as reference.
669*/
670
671# define end_kern            0x7FFFFF
672
673# define charinfo_kern(b,c)  b->kerns[c]
674
675# define kern_char(b)       (b).adjacent
676# define kern_kern(b)       (b).kern
677# define kern_end(b)        ((b).adjacent == end_kern)
678# define kern_disabled(b)   ((b).adjacent > end_kern)
679
680/*tex
681    Ligatures: the |otherchar| value signals \quote {stop}. These are not really public and only
682    to be used in the helpers. But we keep them as reference.
683*/
684
685# define end_of_ligature_code    0x7FFFFF
686
687# define charinfo_ligature(b,c)  b->ligatures[c]
688
689# define ligature_is_valid(a)    ((a).type != 0)
690# define ligature_type(a)        ((a).type >> 1)
691# define ligature_char(a)        (a).adjacent
692# define ligature_replacement(a) (a).ligature
693# define ligature_end(a)         ((a).adjacent == end_of_ligature_code)
694# define ligature_disabled(a)    ((a).adjacent > end_of_ligature_code)
695
696/*tex Extension specific: */
697
698typedef enum math_extension_modes {
699    math_extension_normal,
700    math_extension_repeat,
701} math_extension_modes;
702
703/*tex Expansion and protrusion: */
704
705typedef enum adjust_spacing_modes {
706    adjust_spacing_off,
707    adjust_spacing_unused, 
708    adjust_spacing_full,   /* glyphs and kerns */
709    adjust_spacing_font,   /* glyphs */
710} adjust_spacing_modes;
711
712typedef enum protrude_chars_modes {
713    protrude_chars_off,
714    protrude_chars_unused,
715    protrude_chars_normal,
716    protrude_chars_advanced,
717} protrude_chars_modes;
718
719/*
720typedef enum math_extension_locations {
721    extension_top,
722    extension_bottom,
723    extension_middle,
724    extension_repeat,
725} math_extension_locations;
726*/
727
728typedef enum missing_character_locations {
729    missing_character_text_glyph  = 0x01,
730    missing_character_math_glyph  = 0x02,
731    missing_character_math_kernel = 0x03,
732} missing_character_locations;
733
734extern halfword      tex_checked_font          (halfword f);
735extern int           tex_is_valid_font         (halfword f);
736extern int           tex_raw_get_kern          (halfword f, int lc, int rc);
737extern int           tex_get_kern              (halfword f, int lc, int rc);
738extern ligatureinfo  tex_get_ligature          (halfword f, int lc, int rc);
739extern int           tex_new_font              (void);
740extern int           tex_new_font_id           (void);
741extern void          tex_font_malloc_charinfo  (halfword f, int num);
742extern void          tex_char_malloc_mathinfo  (charinfo *ci);
743extern void          tex_dump_font_data        (dumpstream f);
744extern void          tex_undump_font_data      (dumpstream f);
745extern void          tex_create_null_font      (void);
746extern void          tex_delete_font           (int id);
747extern int           tex_read_font_info        (char *cnom, scaled s);
748
749extern halfword      tex_handle_glyphrun       (halfword head, halfword group, halfword direction);
750extern halfword      tex_handle_ligaturing     (halfword head, halfword tail);
751extern halfword      tex_handle_kerning        (halfword head, halfword tail);
752
753extern void          tex_set_cur_font          (halfword g, halfword f);
754extern int           tex_tex_def_font          (int a);
755
756extern void          tex_missing_character     (halfword n, halfword f, halfword c, halfword where);
757
758extern void          tex_initialize_fonts      (void);
759
760extern void          tex_set_font_name         (halfword f, const char *s);
761extern void          tex_set_font_original     (halfword f, const char *s);
762
763extern scaled        tex_get_math_font_scale   (halfword f, halfword size);
764extern scaled        tex_get_math_font_x_scale (halfword f, halfword size);
765extern scaled        tex_get_math_font_y_scale (halfword f, halfword size);
766extern scaled        tex_get_math_font_weight  (halfword f, halfword size);
767
768//     scaled        tex_raw_math_font_scale   (halfword f, halfword size);
769//     scaled        tex_raw_math_font_x_scale (halfword f, halfword size);
770//     scaled        tex_raw_math_font_y_scale (halfword f, halfword size);
771
772extern scaled        tex_get_math_font_factor  (halfword size);
773
774extern void          tex_run_font_spec         (void);
775
776# endif
777