texfont.h /size: 36 Kb    last modification: 2024-01-16 10:22
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 These are for specific (script) anchoring. */
125    scaled    top_left_kern;
126    scaled    bottom_left_kern;
127    scaled    top_right_kern;
128    scaled    bottom_right_kern;
129    /*tex These four are used in accents. */
130    scaled    left_margin;
131    scaled    right_margin;
132    scaled    top_margin;
133    scaled    bottom_margin;
134    /*tex As are the following. */
135    scaled    top_overshoot;
136    scaled    bottom_overshoot;
137    /*tex These are for degrees in radicals. */
138    scaled    inner_x_offset; 
139    scaled    inner_y_offset; 
140} mathinfo;
141
142typedef struct charinfo {
143    /*tex
144        This is what \TEX\ uses when it calculates the dimensions needed for building boxes and
145        breaking paragraphs into lines. The italic correction is part of that as it has a primitive
146        that needs the value.
147    */
148    scaled        width;
149    scaled        height;
150    scaled        depth;
151    scaled        italic;
152    /*tex
153        The next three variables relate to expansion and protrusion, properties introduced in the
154        \PDFTEX\ engine. Handling of protrusion and expansion is the only features that we inherit
155        from this important extension to traditional \TEX. 
156
157        We can make the next four into a a pointer which saves on large fonts and only a subset 
158        of characters has protrusion or expansion, if used at all. That way we delegate some memory 
159        consumption to usage (of course allocated blobs also have overhead).  
160    */
161    scaled        expansion;    
162    scaled        compression;
163    scaled        leftprotrusion;
164    scaled        rightprotrusion;
165    /*tex
166        The tag and remainder are used in a \TFM\ file for signaling ligatures. They are also used 
167        for math extensions in traditional \TEX\ fonts. We used to pack the tag and remainder
168        in an integer: 2 bits is enough for the tag (but we get some more) and the remainder (aka 
169        next) fits in 21 bits. So we had |tagrem| for quite a while. 
170
171        But we now use a 32 bit tag field and use proper next field that has been moved to the math 
172        blob so that we can have a compression field here without padding. 
173    */
174    halfword      tag; 
175    /*tex
176        Traditional \TEX\ fonts use these two lists for ligature building and inter-character
177        kerning and these are now optional (via pointers). By also using an indirect structure for
178        math data we save quite a bit of memory when we have no math font.
179
180        We could combine math and ligatures and save two slots but then we cannot have a hybrid base
181        font so ... not now. 
182    */
183    kerninfo     *kerns;
184    mathinfo     *math;       
185    ligatureinfo *ligatures;  
186} charinfo;
187
188/*
189    An option is to make this a pointer to a structure but then we also waste a slot. When we 
190    never support it in math then we can actually go smaller: 
191    
192    charinfo: 8 * 4 : width height depth italic tag *[text or math] *kerns padding 
193    textinfo: 4 * 4 : expansion leftprotrusion rightprotrusion *ligatures
194    mathinfo: 2 * 4 : next padding ... n * 4 
195
196    But ... given the amount of fields that \CONTEXT\ adds to the basic character data anyway 
197    there is no real reason to spend much time in saving some bytes here.  
198
199*/
200
201/*tex
202    We can just abuse the token setters and getters here.
203*/
204
205//define charinfo_tag    token_cmd
206//define charinfo_rem    token_chr
207//define charinfo_tagrem token_val
208
209/*tex
210
211    For a font instance we only store the bits that are used by the engine itself. Of course more
212    data can (and normally will be) be kept at the \TEX\ cq.\ \LUA\ end.
213
214    We could store a scale (/1000) and avoid copying a font but then we also need to multiply
215    width, height, etc. when queried (extra overhead). A bit tricky is then dealing with (virtual)
216    commands. It is not that big a deal in \CONTEXT\ so I might actually add this feature but only
217    very few documents use many font instances so in the end the gain is neglectable (we only save
218    some memory). Also, we then need to adapt the math processing quite a bit which is always kind
219    of tricky.
220
221    Again, compared to \LUATEX\ there is less data stored here because we don't need to control the
222    backend. Of course in \CONTEXT\ we keep plenty of data at the \LUA\ end, but we did that already
223    anyway.
224
225*/
226
227typedef struct texfont {
228    /*tex the range of (allocated) characters */
229    int         first_character;
230    int         last_character;
231    /*tex the (sparse) character (glyph) array */
232    sa_tree     characters;
233    charinfo   *chardata;
234    int         chardata_count;
235    int         chardata_size;
236    /*tex properties used in messages */
237    int         size;
238    int         design_size;
239    char       *name;
240    char       *original;
241    /*tex this controls the engine */
242    int         mathcontrol;
243    int         textcontrol;
244    /*tex expansion */
245    int         max_shrink;
246    int         max_stretch;
247    int         step;
248    /*tex for experimental new thingies */
249    int         compactmath;  /* This can go away, just always test. */ 
250    /*tex saves calculations */
251    double      weight; 
252    /*tex all parameters, although only some are used */
253    int         parameter_count;
254    scaled     *parameter_base;
255    /*tex also special */
256    charinfo   *left_boundary;
257    charinfo   *right_boundary;
258    /*tex all math parameters */
259    scaled     *math_parameter_base;
260    int         math_parameter_count;
261    /* zero is alignment */
262    int         mathscales[3];
263    /*tex special characters, see \TEX book */
264    int         hyphen_char;
265    int         skew_char;
266} texfont;
267
268/*tex
269
270    Instead of global variables we store some properties that are shared between the different components
271    in a dedicated struct.
272
273*/
274
275typedef struct font_state_info {
276    texfont     **fonts;
277    halfword      adjust_stretch;
278    halfword      adjust_shrink;
279    halfword      adjust_step;
280    int           padding;
281    memory_data   font_data;
282} font_state_info ;
283
284extern font_state_info lmt_font_state;
285
286# define font_size(a)                   lmt_font_state.fonts[a]->size
287# define font_name(a)                   lmt_font_state.fonts[a]->name
288# define font_original(a)               lmt_font_state.fonts[a]->original
289# define font_design_size(a)            lmt_font_state.fonts[a]->design_size
290# define font_first_character(a)        lmt_font_state.fonts[a]->first_character
291# define font_last_character(a)         lmt_font_state.fonts[a]->last_character
292# define font_compactmath(a)            lmt_font_state.fonts[a]->compactmath
293# define font_mathcontrol(a)            lmt_font_state.fonts[a]->mathcontrol
294# define font_textcontrol(a)            lmt_font_state.fonts[a]->textcontrol
295# define font_hyphen_char(a)            lmt_font_state.fonts[a]->hyphen_char
296# define font_skew_char(a)              lmt_font_state.fonts[a]->skew_char
297# define font_max_shrink(a)             (lmt_font_state.adjust_step > 0 ? lmt_font_state.adjust_shrink  : lmt_font_state.fonts[a]->max_shrink)
298# define font_max_stretch(a)            (lmt_font_state.adjust_step > 0 ? lmt_font_state.adjust_stretch : lmt_font_state.fonts[a]->max_stretch)
299# define font_step(a)                   (lmt_font_state.adjust_step > 0 ? lmt_font_state.adjust_step    : lmt_font_state.fonts[a]->step)
300# define font_mathscale(a,b)            lmt_font_state.fonts[a]->mathscales[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/*tex
322    These are bound to a font. There might be a few more in the future. An example is collapsing
323    hyphens. One can do that using (in context speak) tlig feature but actually it is some very
324    \TEX\ thing, that happened to be implemented using ligatures. In \LUAMETATEX\ it's also a bit
325    special because, although it is not really dependent on a language, hyphen handling in \TEX\
326    is very present in the hyphenator (also sequences of them). So, naturally it moved there. But
327    users who don't want it can disable it per font.
328*/
329
330typedef enum text_control_codes {
331    text_control_collapse_hyphens = 0x0001,
332    text_control_base_ligaturing  = 0x0002,
333    text_control_base_kerning     = 0x0004,
334    text_control_none_protected   = 0x0008,
335    text_control_has_italics      = 0x0010,
336    text_control_auto_italics     = 0x0020,
337    /* these are private */
338    text_control_quality_set      = 0x0100,
339    text_control_expansion        = 0x0200,
340    text_control_left_protrusion  = 0x0400,
341    text_control_right_protrusion = 0x0800,
342} text_control_codes;
343
344# define has_font_text_control(f,c)  ((font_textcontrol(f) & c) == c)
345# define set_font_text_control(f,c)  font_textcontrol(f) |= (c)
346
347/*tex
348    These are special codes that are used in the traditional ligature builder. In \OPENTYPE\
349    fonts we don't see these. Maybe this will be dropped at some point. 
350*/
351
352typedef enum boundarychar_codes {
353    left_boundary_char  = -1,
354    right_boundary_char = -2,
355    non_boundary_char   = -3,
356} boundarychar_codes;
357
358# define font_left_boundary(a)        lmt_font_state.fonts[a]->left_boundary
359# define font_right_boundary(a)       lmt_font_state.fonts[a]->right_boundary
360
361# define font_has_left_boundary(a)    (font_left_boundary(a))
362# define font_has_right_boundary(a)   (font_right_boundary(a))
363
364# define set_font_left_boundary(a,b)  { if (font_left_boundary(a))  { lmt_memory_free(font_left_boundary(a));  } font_left_boundary(a)  = b; }
365# define set_font_right_boundary(a,b) { if (font_right_boundary(a)) { lmt_memory_free(font_right_boundary(a)); } font_right_boundary(a) = b; }
366
367/*tex
368    The math engine can benefit from these properties. For instance we use them for optimizing 
369    the positioning of the degree in a (left) radical. These properties are not stored in the 
370    tag (for a short while we had a variable).
371*/
372
373/*tex
374    In traditional \TEX\ there are just over a handful of font specific parameters for text fonts
375    and some more in math fonts. Actually, these parameters were stored in a way that permitted
376    adding  more at runtime, something that made no real sense, but can be abused for creeating
377    more dimensions than the 256 that traditional \TEX\ provides.
378*/
379
380# define font_parameter_count(a)           lmt_font_state.fonts[a]->parameter_count
381# define font_parameter_base(a)            lmt_font_state.fonts[a]->parameter_base
382# define font_parameter(a,b)               lmt_font_state.fonts[a]->parameter_base[b]
383
384# define font_math_parameter_count(a)      lmt_font_state.fonts[a]->math_parameter_count
385# define font_math_parameter_base(a)       lmt_font_state.fonts[a]->math_parameter_base
386# define font_math_parameter(a,b)          lmt_font_state.fonts[a]->math_parameter_base[b]
387
388# define set_font_parameter_base(a,b)      lmt_font_state.fonts[a]->parameter_base = b;
389# define set_font_math_parameter_base(a,b) lmt_font_state.fonts[a]->math_parameter_base = b;
390
391/*tex
392    These font parameters could be adapted at runtime but one should really wonder if that is such
393    a good idea nowadays.
394 */
395
396//define set_font_parameter(f,n,b)         { if (font_parameter_count(f)      < n) { tex_set_font_parameters(f, n);      } font_parameter(f, n)      = b; }
397// # 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; }
398
399extern void tex_set_font_parameters      (halfword f, int b);
400extern void tex_set_font_math_parameters (halfword f, int b);
401extern int  tex_get_font_max_id          (void);
402extern int  tex_get_font_max_id          (void);
403
404extern halfword tex_checked_font_adjust (
405    halfword adjust_spacing,
406    halfword adjust_spacing_step,
407    halfword adjust_spacing_shrink,
408    halfword adjust_spacing_stretch
409);
410
411/*tex
412    Font parameters are sometimes referred to as |slant(f)|, |space(f)|, etc. These numbers are
413    also the font dimen numbers.
414*/
415
416typedef enum font_parameter_codes {
417    slant_code = 1,
418    space_code,
419    space_stretch_code,
420    space_shrink_code,
421    ex_height_code,
422    em_width_code,
423    extra_space_code,
424} font_parameter_codes;
425
426extern scaled   tex_get_font_slant            (halfword f);
427extern scaled   tex_get_font_space            (halfword f);
428extern scaled   tex_get_font_space_stretch    (halfword f);
429extern scaled   tex_get_font_space_shrink     (halfword f);
430extern scaled   tex_get_font_ex_height        (halfword f);
431extern scaled   tex_get_font_em_width         (halfword f);
432extern scaled   tex_get_font_extra_space      (halfword f);
433extern scaled   tex_get_font_parameter        (halfword f, halfword code);
434extern void     tex_set_font_parameter        (halfword f, halfword code, scaled v);
435                
436extern scaled   tex_get_scaled_slant          (halfword f);
437extern scaled   tex_get_scaled_space          (halfword f);
438extern scaled   tex_get_scaled_space_stretch  (halfword f);
439extern scaled   tex_get_scaled_space_shrink   (halfword f);
440extern scaled   tex_get_scaled_ex_height      (halfword f);
441extern scaled   tex_get_scaled_em_width       (halfword f);
442extern scaled   tex_get_scaled_extra_space    (halfword f);
443extern scaled   tex_get_scaled_parameter      (halfword f, halfword code);
444extern void     tex_set_scaled_parameter      (halfword f, halfword code, scaled v);
445
446extern halfword tex_get_scaled_glue           (halfword f);
447extern halfword tex_get_scaled_parameter_glue (quarterword p, quarterword s);
448extern halfword tex_get_parameter_glue        (quarterword p, quarterword s);
449
450extern halfword tex_get_font_identifier       (halfword fs);
451
452/*tex
453    The \OPENTYPE\ math fonts have four edges and reference points for kerns. Here we go:
454*/
455
456typedef enum font_math_kern_codes {
457    top_right_kern = 1,
458    bottom_right_kern,
459    bottom_left_kern,
460    top_left_kern,
461} font_math_kern_codes;
462
463extern charinfo *tex_get_charinfo     (halfword f, int c);
464extern int       tex_char_exists      (halfword f, int c);
465extern void      tex_char_process     (halfword f, int c);
466extern int       tex_math_char_exists (halfword f, int c, int size);
467extern int       tex_get_math_char    (halfword f, int c, int size, scaled *scale, int direction);
468
469/*tex 
470    These used to be small integers, bit 22 upto 31, but now we have a 32 bit set. We actually don't 
471    really need the granularity but by having these flags we can actually add a bit of control, like 
472    having kerns but still blocking them. The numbers here are no longer reflective of what a tfm 
473    file provides. We assume tfm files to be converted anyway. 
474
475    Not all are needed but at least we now can keep some state. We can actually use them to something
476    if we really want to (like when we runt tests). However, that is a rather drastic measure for 
477    shared fonts. Tracing is another application and at some point it will be used for this. 
478
479    Todo, a compact mode only feature: 
480
481      expansion_checked_tag   = 0x40000, 
482      protrusion_checked_tag  = 0x80000, 
483
484    when not yet checked, we call out to lua and get the values. That way we don't need to initialize 
485    the fonts at load time. 
486
487*/
488
489typedef enum char_tag_codes {
490    no_tag               = 0x0000000, /*tex vanilla character */
491    ligatures_tag        = 0x0000001, /*tex character has a ligature program, not used */ 
492    kerns_tag            = 0x0000002, /*tex character has a kerning program, not used */ 
493    list_tag             = 0x0000004, /*tex character has a successor in a charlist */  
494    callback_tag         = 0x0000010,
495    extensible_tag       = 0x0000020, /*tex character is extensible, we can unset it in order to block */
496    horizontal_tag       = 0x0000040, /*tex horizontal extensible */
497    vertical_tag         = 0x0000080, /*tex vertical extensible */
498    inner_left_tag       = 0x0000100, /*tex anchoring */
499    inner_right_tag      = 0x0000200, /*tex anchoring */
500    inner_top_tag        = 0x0000400, /*tex anchoring */ 
501    inner_bottom_tag     = 0x0000800, /*tex anchoring */ 
502    extend_last_tag      = 0x0001000, /*tex auto scale last variant */
503    italic_tag           = 0x0002000, 
504    n_ary_tag            = 0x0004000, 
505    radical_tag          = 0x0008000, 
506    punctuation_tag      = 0x0010000, 
507    keep_base_tag        = 0x0020000, 
508    expansion_tag        = 0x0040000,
509    protrusion_tag       = 0x0080000,
510    above_baseline_tag   = 0x0100000,
511    below_baseline_tag   = 0x0200000,
512    force_extensible_tag = 0x0400000,
513} char_tag_codes;
514
515/*tex
516    These low level setters are not publis and used in helpers. They might become functions
517    when I feel the need.
518*/
519
520# define set_charinfo_width(ci,val)                        ci->width  = val;
521# define set_charinfo_height(ci,val)                       ci->height = val;
522# define set_charinfo_depth(ci,val)                        ci->depth  = val;
523# define set_charinfo_italic(ci,val)                       ci->italic = val;
524# define set_charinfo_expansion(ci,val)                    ci->expansion = val;
525# define set_charinfo_compression(ci,val)                  ci->compression = val;
526# define set_charinfo_leftprotrusion(ci,val)               ci->leftprotrusion = val;
527# define set_charinfo_rightprotrusion(ci,val)              ci->rightprotrusion = val;
528
529# define set_charinfo_tag(ci,val)                          ci->tag |= val;
530# define set_charinfo_next(ci,val)                         if (ci->math) { ci->math->next = val; }
531
532# define has_charinfo_tag(ci,p)                            (((ci->tag) & (p)) == (p)) 
533# define get_charinfo_tag(ci)                              ci->tag
534
535# define set_charinfo_ligatures(ci,val)                    { lmt_memory_free(ci->ligatures); ci->ligatures = val; }
536# define set_charinfo_kerns(ci,val)                        { lmt_memory_free(ci->kerns);     ci->kerns     = val; }
537# define set_charinfo_math(ci,val)                         { lmt_memory_free(ci->math);      ci->math      = val; }
538
539# 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; }
540# 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; }
541# 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; }
542# 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; }
543
544//define set_charinfo_options(ci,val)                      if (ci->math) { ci->math->options = val; }
545
546# define set_ligature_item(f,b,c,d)                        { f.type = b; f.adjacent = c; f.ligature = d; }
547# define set_kern_item(f,b,c)                              { f.adjacent = b; f.kern = c; }
548
549# define set_charinfo_left_margin(ci,val)                  if (ci->math) { ci->math->left_margin = val; }
550# define set_charinfo_right_margin(ci,val)                 if (ci->math) { ci->math->right_margin = val; }
551# define set_charinfo_top_margin(ci,val)                   if (ci->math) { ci->math->top_margin = val; }
552# define set_charinfo_bottom_margin(ci,val)                if (ci->math) { ci->math->bottom_margin = val; }
553
554# define set_charinfo_smaller(ci,val)                      if (ci->math) { ci->math->smaller = val; }
555# define set_charinfo_mirror(ci,val)                       if (ci->math) { ci->math->mirror = val; }
556# define set_charinfo_extensible_italic(ci,val)            if (ci->math) { ci->math->extensible_italic = val; }
557# define set_charinfo_top_anchor(ci,val)                   if (ci->math) { ci->math->top_anchor = val; }
558# define set_charinfo_bottom_anchor(ci,val)                if (ci->math) { ci->math->bottom_anchor = val; }
559# define set_charinfo_flat_accent(ci,val)                  if (ci->math) { ci->math->flat_accent = val; }
560
561# define set_charinfo_inner_x_offset(ci,val)               if (ci->math) { ci->math->inner_x_offset = val; }
562# define set_charinfo_inner_y_offset(ci,val)               if (ci->math) { ci->math->inner_y_offset = val; }
563
564# define set_charinfo_top_left_kern(ci,val)                if (ci->math) { ci->math->top_left_kern = val; }
565# define set_charinfo_top_right_kern(ci,val)               if (ci->math) { ci->math->top_right_kern = val; }
566# define set_charinfo_bottom_left_kern(ci,val)             if (ci->math) { ci->math->bottom_left_kern = val; }
567# define set_charinfo_bottom_right_kern(ci,val)            if (ci->math) { ci->math->bottom_right_kern = val; }
568
569# define set_charinfo_top_overshoot(ci,val)                if (ci->math) { ci->math->top_overshoot = val; }
570# define set_charinfo_bottom_overshoot(ci,val)             if (ci->math) { ci->math->bottom_overshoot = val; }
571
572# define proper_char_index(f, c) (c >= font_first_character(f) && c <= font_last_character(f))
573
574/*tex Setters: */
575
576void             tex_set_lpcode_in_font                 (halfword f, halfword c, halfword i);
577void             tex_set_rpcode_in_font                 (halfword f, halfword c, halfword i);
578void             tex_set_efcode_in_font                 (halfword f, halfword c, halfword i);
579void             tex_set_cfcode_in_font                 (halfword f, halfword c, halfword i);
580
581extern void      tex_add_charinfo_math_kern             (charinfo *ci, int type, scaled ht, scaled krn);
582extern int       tex_get_charinfo_math_kerns            (charinfo *ci, int id);
583extern void      tex_set_charinfo_extensible_recipe     (charinfo *ci, extinfo *ext);
584extern void      tex_append_charinfo_extensible_recipe  (charinfo *ci, int glyph, int startconnect, int endconnect, int advance, int repeater);
585
586/*tex Checkers: */
587
588int              tex_char_has_math                      (halfword f, halfword c);
589int              tex_has_ligature                       (halfword f, halfword c);
590int              tex_has_kern                           (halfword f, halfword c);
591
592/*tex Getters: */
593
594# define MATH_KERN_NOT_FOUND 0x7FFFFFFF
595
596extern scaled    tex_font_x_scaled                      (scaled v);
597extern scaled    tex_font_y_scaled                      (scaled v);
598
599extern scaled    tex_char_width_from_font               (halfword f, halfword c); /* math + maincontrol */
600extern scaled    tex_char_height_from_font              (halfword f, halfword c); /* math + maincontrol */
601extern scaled    tex_char_depth_from_font               (halfword f, halfword c); /* math + maincontrol */
602extern scaled    tex_char_total_from_font               (halfword f, halfword c); /* math */
603extern scaledwhd tex_char_whd_from_font                 (halfword f, halfword c); /* math + maincontrol */
604extern scaled    tex_char_italic_from_font              (halfword f, halfword c); /* math + maincontrol */
605extern scaled    tex_char_ef_from_font                  (halfword f, halfword c); /* packaging + maincontrol */
606extern scaled    tex_char_cf_from_font                  (halfword f, halfword c); /* packaging + maincontrol */
607extern scaled    tex_char_lp_from_font                  (halfword f, halfword c); /* packaging + maincontrol */
608extern scaled    tex_char_rp_from_font                  (halfword f, halfword c); /* packaging + maincontrol */
609extern halfword  tex_char_tag_from_font                 (halfword f, halfword c); /* math */
610extern halfword  tex_char_next_from_font                (halfword f, halfword c); /* math */
611extern halfword  tex_char_has_tag_from_font             (halfword f, halfword c, halfword tag); 
612extern void      tex_char_reset_tag_from_font           (halfword f, halfword c, halfword tag); 
613extern int       tex_char_checked_tag                   (halfword tag);
614extern scaled    tex_char_inner_x_offset_from_font      (halfword f, halfword c);
615extern scaled    tex_char_inner_y_offset_from_font      (halfword f, halfword c);
616extern scaled    tex_char_top_left_kern_from_font       (halfword f, halfword c); /* math */
617extern scaled    tex_char_top_right_kern_from_font      (halfword f, halfword c); /* math */
618extern scaled    tex_char_bottom_left_kern_from_font    (halfword f, halfword c); /* math */
619extern scaled    tex_char_bottom_right_kern_from_font   (halfword f, halfword c); /* math */
620extern halfword  tex_char_extensible_italic_from_font   (halfword f, halfword c);
621extern halfword  tex_char_flat_accent_from_font         (halfword f, halfword c);
622extern halfword  tex_char_top_anchor_from_font          (halfword f, halfword c);
623extern halfword  tex_char_bottom_anchor_from_font       (halfword f, halfword c);
624extern scaled    tex_char_left_margin_from_font         (halfword f, halfword c);
625extern scaled    tex_char_right_margin_from_font        (halfword f, halfword c);
626extern scaled    tex_char_top_margin_from_font          (halfword f, halfword c);
627extern scaled    tex_char_bottom_margin_from_font       (halfword f, halfword c);
628extern scaled    tex_char_top_overshoot_from_font       (halfword f, halfword c);
629extern scaled    tex_char_bottom_overshoot_from_font    (halfword f, halfword c);
630extern extinfo  *tex_char_extensible_recipe_from_font   (halfword f, halfword c);
631extern extinfo  *tex_char_extensible_recipe_front_last  (halfword f, halfword c);
632
633extern halfword  tex_char_unchecked_top_anchor_from_font    (halfword f, halfword c);
634extern halfword  tex_char_unchecked_bottom_anchor_from_font (halfword f, halfword c);
635
636extern scaled    tex_char_width_from_glyph              (halfword g); /* x/y scaled */
637extern scaled    tex_char_height_from_glyph             (halfword g); /* x/y scaled */
638extern scaled    tex_char_depth_from_glyph              (halfword g); /* x/y scaled */
639extern scaled    tex_char_total_from_glyph              (halfword g); /* x/y scaled */
640extern scaled    tex_char_italic_from_glyph             (halfword g); /* x/y scaled */
641extern scaled    tex_char_width_italic_from_glyph       (halfword g); /* x/y scaled */
642extern scaledwhd tex_char_whd_from_glyph                (halfword g); /* x/y scaled */
643extern scaled    tex_char_left_protrusion_from_glyph    (halfword g); /* x/y scaled */
644extern scaled    tex_char_right_protrusion_from_glyph   (halfword g); /* x/y scaled */
645extern scaledkrn tex_char_corner_kerns_from_glyph       (halfword g); /* x/y scaled */
646                                                       
647extern int       tex_valid_kern                         (halfword left, halfword right);            /* returns kern */
648extern int       tex_valid_ligature                     (halfword left, halfword right, int *slot); /* returns type */
649                                                       
650extern scaled    tex_calculated_char_width              (halfword f, halfword c, halfword ex);
651extern scaled    tex_calculated_glyph_width             (halfword g, halfword ex); /* scale */
652
653/*tex
654    Kerns: the |otherchar| value signals \quote {stop}. These are not really public and only
655    to be used in the helpers. But we keep them as reference.
656*/
657
658# define end_kern            0x7FFFFF
659
660# define charinfo_kern(b,c)  b->kerns[c]
661
662# define kern_char(b)       (b).adjacent
663# define kern_kern(b)       (b).kern
664# define kern_end(b)        ((b).adjacent == end_kern)
665# define kern_disabled(b)   ((b).adjacent > end_kern)
666
667/*tex
668    Ligatures: the |otherchar| value signals \quote {stop}. These are not really public and only
669    to be used in the helpers. But we keep them as reference.
670*/
671
672# define end_of_ligature_code    0x7FFFFF
673
674# define charinfo_ligature(b,c)  b->ligatures[c]
675
676# define ligature_is_valid(a)    ((a).type != 0)
677# define ligature_type(a)        ((a).type >> 1)
678# define ligature_char(a)        (a).adjacent
679# define ligature_replacement(a) (a).ligature
680# define ligature_end(a)         ((a).adjacent == end_of_ligature_code)
681# define ligature_disabled(a)    ((a).adjacent > end_of_ligature_code)
682
683/*tex Extension specific: */
684
685typedef enum math_extension_modes {
686    math_extension_normal,
687    math_extension_repeat,
688} math_extension_modes;
689
690/*tex Expansion and protrusion: */
691
692typedef enum adjust_spacing_modes {
693    adjust_spacing_off,
694    adjust_spacing_unused, 
695    adjust_spacing_full,   /* glyphs and kerns */
696    adjust_spacing_font,   /* glyphs */
697} adjust_spacing_modes;
698
699typedef enum protrude_chars_modes {
700    protrude_chars_off,
701    protrude_chars_unused,
702    protrude_chars_normal,
703    protrude_chars_advanced,
704} protrude_chars_modes;
705
706/*
707typedef enum math_extension_locations {
708    extension_top,
709    extension_bottom,
710    extension_middle,
711    extension_repeat,
712} math_extension_locations;
713*/
714
715extern halfword      tex_checked_font          (halfword f);
716extern int           tex_is_valid_font         (halfword f);
717extern int           tex_raw_get_kern          (halfword f, int lc, int rc);
718extern int           tex_get_kern              (halfword f, int lc, int rc);
719extern ligatureinfo  tex_get_ligature          (halfword f, int lc, int rc);
720extern int           tex_new_font              (void);
721extern int           tex_new_font_id           (void);
722extern void          tex_font_malloc_charinfo  (halfword f, int num);
723extern void          tex_char_malloc_mathinfo  (charinfo *ci);
724extern void          tex_dump_font_data        (dumpstream f);
725extern void          tex_undump_font_data      (dumpstream f);
726extern void          tex_create_null_font      (void);
727extern void          tex_delete_font           (int id);
728extern int           tex_read_font_info        (char *cnom, scaled s);
729extern int           tex_fix_expand_value      (halfword f, int e);
730
731extern halfword      tex_handle_glyphrun       (halfword head, halfword group, halfword direction);
732extern halfword      tex_handle_ligaturing     (halfword head, halfword tail);
733extern halfword      tex_handle_kerning        (halfword head, halfword tail);
734
735extern void          tex_set_cur_font          (halfword g, halfword f);
736extern int           tex_tex_def_font          (int a);
737
738extern void          tex_char_warning          (halfword f, int c);
739
740extern void          tex_initialize_fonts      (void);
741
742extern void          tex_set_font_name         (halfword f, const char *s);
743extern void          tex_set_font_original     (halfword f, const char *s);
744
745extern scaled        tex_get_math_font_scale   (halfword f, halfword size);
746extern scaled        tex_get_math_font_factor  (halfword size);
747
748extern void          tex_run_font_spec         (void);
749
750# endif
751