diff options
Diffstat (limited to 'source/luametatex/source/tex/texfont.h')
-rw-r--r-- | source/luametatex/source/tex/texfont.h | 667 |
1 files changed, 667 insertions, 0 deletions
diff --git a/source/luametatex/source/tex/texfont.h b/source/luametatex/source/tex/texfont.h new file mode 100644 index 000000000..a13c6e13d --- /dev/null +++ b/source/luametatex/source/tex/texfont.h @@ -0,0 +1,667 @@ +/* + See license.txt in the root of this project. +*/ + +# ifndef LMT_TEXFONT_H +# define LMT_TEXFONT_H + +# include "tex/textypes.h" + +/*tex + + In the \WEBC\ infrastructrure there is code that deals with endianness of the machine but in + \LUAMETATEX\ we don't need this. In \LUATEX\ sharing the format file was already dropped, simply + because we can also store \LUA\ bytecode in the format. In the other engines font data can end + up in the format file and that in turn then also can be endian dependent. But in \LUAMETATEX\ + we no longer stored font data, and that is yet another reason why there is no endian related + code here. + + The ligature and kern structures are for traditional \TEX\ fonts, thise that are handles by the + built in reference handlers. Although \OPENTYPE\ is more versatile, we should not forget that + for many (latin) scripts these so called base fonts are quite adequate and efficient. We could + of course implement base support in \LUA\ but although \LUAMETATEX\ can delegate a lot, we also + keep the reference implementation available: it is well documented, was for a long time the best + one could get and doesn't take that much code. So, here come the basic structures: + +*/ + +typedef struct ligatureinfo { + int type; + int ligature; + int adjacent; + /* alignment */ + int padding; +} ligatureinfo; + +typedef struct kerninfo { + int kern; + int adjacent; +} kerninfo; + +/*tex + + In \LUAMETATEX, at runtime, after a font is loaded via a callback, we only store the little + information that is needed for basic ligature building and kerning, math rendering (like + extensibles), and par building which includes protrusion and expansion. We don't need anything + related to the backend because outpout is delegated to \LUA. + + The most extensive data structures are those related to \OPENTYPE\ math. When passing a font we + can save memory by using the |hasmath| directive. In \LUAMETATEX\ we can then have a different + |struct| with 15 fields less than in \LUATEX\ which, combined with other savings, saves some 60 + bytes. The disadvantage is that accessors of those fields also need to act upon that flag, which + involves more testing. However, because in practice math font access is not that prominent so + the gain outweights this potential performance hit. For an average \CJK\ font with 5000 + characters we saves 300000 bytes. Because a complete Latin font with various features also can + have thousands of glyphs, it can save some memory there too. It's changes like this that give + \LUAMETATEX\ a much smaller memory footprint than its predecessor. + + The next record relates to math extensibles. It is good to realize that traditional \TEX\ fonts + are handled differently in the math subengine than \OPENTYPE\ math fonts. However, we use the + more extensive \OPENTYPE\ structure for both type of fonts. + +*/ + +typedef struct extinfo { + struct extinfo *next; + int glyph; + int start_overlap; + int end_overlap; + int advance; + int extender; + /* alignment */ + int padding; +} extinfo; + +// typedef enum math_font_options { +// math_font_ignore_italic_option = 0x01, +// } math_font_options; +// +// # define math_font_option(options,option) ((options & option) == option) + +typedef struct mathinfo { + scaled vertical_italic; + scaled top_accent; + scaled bottom_accent; + int smaller; + scaled scale; + int flat_accent; + int top_left_math_kerns; + int top_right_math_kerns; + int bottom_right_math_kerns; + int bottom_left_math_kerns; + extinfo *horizontal_parts; + extinfo *vertical_parts; + scaled *top_left_math_kern_array; + scaled *top_right_math_kern_array; + scaled *bottom_right_math_kern_array; + scaled *bottom_left_math_kern_array; + /* these are for specific (script) anchoring */ + scaled top_left_kern; + scaled bottom_left_kern; + scaled top_right_kern; + scaled bottom_right_kern; + scaled left_margin; + scaled right_margin; + scaled top_margin; + scaled bottom_margin; +} mathinfo; + +typedef struct charinfo { + /*tex + This is what \TEX\ uses when it calculates the dimensions needed for building boxes and + breaking paragraphs into lines. The italic correction is part of that as it has a primitive + that needs the value. + */ + scaled width; + scaled height; + scaled depth; + scaled italic; + /*tex + The next three variables relate to expansion and protrusion, properties introduced in the + \PDFTEX\ engine. Handling of protrusion and expansion is the only features that we inherit + from this important extension to traditional \TEX. + */ + scaled expansion; + scaled leftprotrusion; + scaled rightprotrusion; + /* halfword padding; */ /* when we pack |tag| and |remainder| we can safe 4 bytes */ + /*tex + These two are used in a \TFM\ file for signaling ligatures. They are also used for math + extensions in traditional \TEX\ fonts, so we just keep them. + */ + /* halfword tag; */ /* 2 bits is enough (flags) */ + /* halfword remainder; */ /* 21 bits is enough (unicode) */ + halfword tagrem; /* just an integer, less (arm) alignment hassle that way */ + /*tex + Traditional \TEX\ fonts use these two lists for ligature building and inter-character + kerning and these are now optional (via pointers). By also using an indirect structure for + math data we save quite a bit of memory when we have no math font. + */ + ligatureinfo *ligatures; + kerninfo *kerns; + mathinfo *math; +} charinfo; + +/*tex + We can just abuse the token setters and getters here. +*/ + +# define charinfo_tag token_cmd +# define charinfo_rem token_chr +# define charinfo_tagrem token_val + +/*tex + + For a font instance we only store the bits that are used by the engine itself. Of course more + data can (and normally will be) be kept at the \TEX\ cq.\ \LUA\ end. + + We could store a scale (/1000) and avoid copying a font but then we also need to multiply + width, height, etc. when queried (extra overhead). A bit tricky is then dealing with (virtual) + commands. It is not that big a deal in \CONTEXT\ so I might actually add this feature but only + very few documents use many font instances so in the end the gain is neglectable (we only save + some memory). Also, we then need to adapt the math processing quite a bit which is always kind + of tricky. + + Again, compared to \LUATEX\ there is less data stored here because we don't need to control the + backend. Of course in \CONTEXT\ we keep plenty of data at the \LUA\ end, but we did that already + anyway. + +*/ + +typedef struct texfont { + /*tex the range of (allocated) characters */ + int first_character; + int last_character; + /*tex the (sparse) character (glyph) array */ + sa_tree characters; + charinfo *chardata; + int chardata_count; + int chardata_size; + /*tex properties used in messages */ + int size; + int design_size; + char *name; + char *original; + /*tex for experimental new thingies */ + int compactmath; + /*tex default to false when MathConstants not seen */ + int oldmath; + /*tex this controls the engine */ + int mathcontrol; + int textcontrol; + /*tex expansion */ + int max_shrink; + int max_stretch; + int step; + /*tex special characters, see \TEX book */ + int hyphen_char; + int skew_char; + /*tex all parameters, although only some are used */ + int parameter_count; + scaled *parameter_base; + /* */ + int padding; + /*tex also special */ + charinfo *left_boundary; + charinfo *right_boundary; + /*tex all math parameters */ + scaled *math_parameter_base; + int math_parameter_count; + /* zero is alignment */ + int mathscales[3]; +} texfont; + +/*tex + + Instead of global variables we store some properties that are shared between the different components + in a dedicated struct. + +*/ + +typedef struct font_state_info { + texfont **fonts; + halfword adjust_stretch; + halfword adjust_shrink; + halfword adjust_step; + int padding; + memory_data font_data; +} font_state_info ; + +extern font_state_info lmt_font_state; + +# define font_size(a) lmt_font_state.fonts[a]->size +# define font_name(a) lmt_font_state.fonts[a]->name +# define font_original(a) lmt_font_state.fonts[a]->original +# define font_design_size(a) lmt_font_state.fonts[a]->design_size +# define font_first_character(a) lmt_font_state.fonts[a]->first_character +# define font_last_character(a) lmt_font_state.fonts[a]->last_character +/*define font_touched(a) font_state.fonts[a]->touched */ +# define font_oldmath(a) lmt_font_state.fonts[a]->oldmath +# define font_compactmath(a) lmt_font_state.fonts[a]->compactmath +# define font_mathcontrol(a) lmt_font_state.fonts[a]->mathcontrol +# define font_textcontrol(a) lmt_font_state.fonts[a]->textcontrol +# define font_hyphen_char(a) lmt_font_state.fonts[a]->hyphen_char +# define font_skew_char(a) lmt_font_state.fonts[a]->skew_char +# define font_max_shrink(a) (lmt_font_state.adjust_step > 0 ? lmt_font_state.adjust_shrink : lmt_font_state.fonts[a]->max_shrink) +# define font_max_stretch(a) (lmt_font_state.adjust_step > 0 ? lmt_font_state.adjust_stretch : lmt_font_state.fonts[a]->max_stretch) +# define font_step(a) (lmt_font_state.adjust_step > 0 ? lmt_font_state.adjust_step : lmt_font_state.fonts[a]->step) +# define font_mathscale(a,b) lmt_font_state.fonts[a]->mathscales[b] + +# define set_font_size(a,b) lmt_font_state.fonts[a]->size = b +# define set_font_name(a,b) lmt_font_state.fonts[a]->name = b +# define set_font_original(a,b) lmt_font_state.fonts[a]->original = b +# define set_font_design_size(a,b) lmt_font_state.fonts[a]->design_size = b +# define set_font_first_character(a,b) lmt_font_state.fonts[a]->first_character = b +# define set_font_last_character(a,b) lmt_font_state.fonts[a]->last_character = b +/*define set_font_touched(a,b) font_state.fonts[a]->touched = b */ +# define set_font_oldmath(a,b) lmt_font_state.fonts[a]->oldmath = b +# define set_font_compactmath(a,b) lmt_font_state.fonts[a]->compactmath = b +# define set_font_mathcontrol(a,b) lmt_font_state.fonts[a]->mathcontrol = b +# define set_font_textcontrol(a,b) lmt_font_state.fonts[a]->textcontrol = b +# define set_font_hyphen_char(a,b) lmt_font_state.fonts[a]->hyphen_char = b +# define set_font_skew_char(a,b) lmt_font_state.fonts[a]->skew_char = b +# define set_font_max_shrink(a,b) lmt_font_state.fonts[a]->max_shrink = b +# define set_font_max_stretch(a,b) lmt_font_state.fonts[a]->max_stretch = b +# define set_font_step(a,b) lmt_font_state.fonts[a]->step = b + +# define set_font_textsize(a,b) lmt_font_state.fonts[a]->mathscales[0] = b +# define set_font_scriptsize(a,b) lmt_font_state.fonts[a]->mathscales[1] = b +# define set_font_scriptscriptsize(a,b) lmt_font_state.fonts[a]->mathscales[2] = b + +/*tex + These are bound to a font. There might be a few more in the future. An example is collapsing + hyphens. One can do that using (in context speak) tlig feature but actually it is some very + \TEX\ thing, that happened to be implemented using ligatures. In \LUAMETATEX\ it's also a bit + special because, although it is not really dependent on a language, hyphen handling in \TEX\ + is very present in the hyphenator (also sequences of them). So, naturally it moved there. But + users who don't want it can disable it per font. +*/ + +typedef enum text_control_codes { + text_control_collapse_hyphens = 0x00001, +} text_control_codes; + +# define has_font_text_control(f,c) ((font_textcontrol(f) & c) == c) + +/*tex + + These are special codes that are used in the traditional ligature builder. In \OPENTYPE\ + fonts we don't see these. + +*/ + +typedef enum boundarychar_codes { + left_boundary_char = -1, + right_boundary_char = -2, + non_boundary_char = -3, +} boundarychar_codes; + +/*tex These are pointers, so: |NULL| */ + +# define font_left_boundary(a) lmt_font_state.fonts[a]->left_boundary +# define font_right_boundary(a) lmt_font_state.fonts[a]->right_boundary + +# define font_has_left_boundary(a) (font_left_boundary(a)) +# define font_has_right_boundary(a) (font_right_boundary(a)) + +# define set_font_left_boundary(a,b) { if (font_left_boundary(a)) { lmt_memory_free(font_left_boundary(a)); } font_left_boundary(a) = b; } +# define set_font_right_boundary(a,b) { if (font_right_boundary(a)) { lmt_memory_free(font_right_boundary(a)); } font_right_boundary(a) = b; } + +/*tex + + In traditional \TEX\ there are just over a handful of font specific parameters for text fonts + and some more in math fonts. Actually, these parameters were stored in a way that permitted + adding more at runtime, something that made no real sense, but can be abused for creeating + more dimensions than the 256 that traditional \TEX\ provides. + +*/ + +# define font_parameter_count(a) lmt_font_state.fonts[a]->parameter_count +# define font_parameter_base(a) lmt_font_state.fonts[a]->parameter_base +# define font_parameter(a,b) lmt_font_state.fonts[a]->parameter_base[b] + +# define font_math_parameter_count(a) lmt_font_state.fonts[a]->math_parameter_count +# define font_math_parameter_base(a) lmt_font_state.fonts[a]->math_parameter_base +# define font_math_parameter(a,b) lmt_font_state.fonts[a]->math_parameter_base[b] + +# define set_font_parameter_base(a,b) lmt_font_state.fonts[a]->parameter_base = b; +# define set_font_math_parameter_base(a,b) lmt_font_state.fonts[a]->math_parameter_base = b; + +/*tex + + These font parameters could be adapted at runtime but one should really wonder if that is such + a good idea nowadays. + + */ + +//define set_font_parameter(f,n,b) { if (font_parameter_count(f) < n) { tex_set_font_parameters(f, n); } font_parameter(f, n) = b; } +// # 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; } + +extern void tex_set_font_parameters (halfword f, int b); +extern void tex_set_font_math_parameters (halfword f, int b); +extern int tex_get_font_max_id (void); +extern int tex_get_font_max_id (void); + +extern halfword tex_checked_font_adjust ( + halfword adjust_spacing, + halfword adjust_spacing_step, + halfword adjust_spacing_shrink, + halfword adjust_spacing_stretch +); + +/*tex + + Font parameters are sometimes referred to as |slant(f)|, |space(f)|, etc. These numbers are + also the font dimen numbers. + +*/ + +typedef enum font_parameter_codes { + slant_code = 1, + space_code, + space_stretch_code, + space_shrink_code, + ex_height_code, + em_width_code, + extra_space_code, +} font_parameter_codes; + +extern scaled tex_get_font_slant (halfword f); +extern scaled tex_get_font_space (halfword f); +extern scaled tex_get_font_space_stretch (halfword f); +extern scaled tex_get_font_space_shrink (halfword f); +extern scaled tex_get_font_ex_height (halfword f); +extern scaled tex_get_font_em_width (halfword f); +extern scaled tex_get_font_extra_space (halfword f); +extern scaled tex_get_font_parameter (halfword f, halfword code); +extern void tex_set_font_parameter (halfword f, halfword code, scaled v); + +extern scaled tex_get_scaled_space (halfword f); +extern scaled tex_get_scaled_space_stretch (halfword f); +extern scaled tex_get_scaled_space_shrink (halfword f); +extern scaled tex_get_scaled_ex_height (halfword f); +extern scaled tex_get_scaled_em_width (halfword f); +extern scaled tex_get_scaled_extra_space (halfword f); +extern scaled tex_get_scaled_parameter (halfword f, halfword code); +extern void tex_set_scaled_parameter (halfword f, halfword code, scaled v); + +extern halfword tex_get_scaled_glue (halfword f); +extern halfword tex_get_scaled_parameter_glue (quarterword p, quarterword s); +extern halfword tex_get_parameter_glue (quarterword p, quarterword s); + +extern halfword tex_get_font_identifier (halfword fs); + +/*tex + + The \OPENTYPE\ math fonts have four edges and reference points for kerns. Here we go: + +*/ + +typedef enum font_math_kern_codes { + top_right_kern = 1, + bottom_right_kern, + bottom_left_kern, + top_left_kern, +} font_math_kern_codes; + +extern charinfo *tex_get_charinfo (halfword f, int c); +extern int tex_char_exists (halfword f, int c); +extern void tex_char_process (halfword f, int c); +extern int tex_math_char_exists (halfword f, int c, int size); +extern int tex_get_math_char (halfword f, int c, int size, scaled *scale); + +/*tex + + Here is a quick way to test if a glyph exists, when you are already certain the font |f| exists, + and that the |c| is a regular glyph id, not one of the two special boundary objects. Contrary + to traditional \TEX\ we store character information in a hash table instead of an array. Keep + in mind that we talk \UNICODE: plenty of characters in the code space, but less so in a font, + so we can best be sparse. + +*/ + +# define quick_char_exists(f,c) (sa_get_item_4(lmt_font_state.fonts[f]->characters,c).int_value) + +/*tex + These low level setters are not publis and used in helpers. They might become functions + when I feel the need. +*/ + +# define set_charinfo_width(ci,val) ci->width = val; +# define set_charinfo_height(ci,val) ci->height = val; +# define set_charinfo_depth(ci,val) ci->depth = val; +# define set_charinfo_italic(ci,val) ci->italic = val; +# define set_charinfo_expansion(ci,val) ci->expansion = val; +# define set_charinfo_leftprotrusion(ci,val) ci->leftprotrusion = val; +# define set_charinfo_rightprotrusion(ci,val) ci->rightprotrusion = val; + +# define set_charinfo_tag(ci,tag) ci->tagrem = charinfo_tagrem(charinfo_tag(ci->tagrem) | tag,charinfo_rem(ci->tagrem)); +# define set_charinfo_remainder(ci,rem) ci->tagrem = charinfo_tagrem(charinfo_tag(ci->tagrem),rem); + +# define has_charinfo_tag(ci,p) (charinfo_tag(ci->tagrem) & (p) == (p)) +# define get_charinfo_tag(ci) charinfo_tag(ci->tagrem) + +# define set_charinfo_ligatures(ci,val) { lmt_memory_free(ci->ligatures); ci->ligatures = val; } +# define set_charinfo_kerns(ci,val) { lmt_memory_free(ci->kerns); ci->kerns = val; } +# define set_charinfo_math(ci,val) { lmt_memory_free(ci->math); ci->math = val; } + +# 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; } +# 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; } +# 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; } +# 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; } + +//define set_charinfo_options(ci,val) if (ci->math) { ci->math->options = val; } + +# define set_ligature_item(f,b,c,d) { f.type = b; f.adjacent = c; f.ligature = d; } +# define set_kern_item(f,b,c) { f.adjacent = b; f.kern = c; } + +# define set_charinfo_left_margin(ci,val) if (ci->math) { ci->math->left_margin = val; } +# define set_charinfo_right_margin(ci,val) if (ci->math) { ci->math->right_margin = val; } +# define set_charinfo_top_margin(ci,val) if (ci->math) { ci->math->top_margin = val; } +# define set_charinfo_bottom_margin(ci,val) if (ci->math) { ci->math->bottom_margin = val; } + +# define set_charinfo_smaller(ci,val) if (ci->math) { ci->math->smaller = val; } +# define set_charinfo_vertical_italic(ci,val) if (ci->math) { ci->math->vertical_italic = val; } +# define set_charinfo_top_accent(ci,val) if (ci->math) { ci->math->top_accent = val; } +# define set_charinfo_bottom_accent(ci,val) if (ci->math) { ci->math->bottom_accent = val; } +# define set_charinfo_flat_accent(ci,val) if (ci->math) { ci->math->flat_accent = val; } + +# define set_charinfo_top_left_kern(ci,val) if (ci->math) { ci->math->top_left_kern = val; } +# define set_charinfo_top_right_kern(ci,val) if (ci->math) { ci->math->top_right_kern = val; } +# define set_charinfo_bottom_left_kern(ci,val) if (ci->math) { ci->math->bottom_left_kern = val; } +# define set_charinfo_bottom_right_kern(ci,val) if (ci->math) { ci->math->bottom_right_kern = val; } + +/*tex Setters: */ + +void tex_set_lpcode_in_font (halfword f, halfword c, halfword i); +void tex_set_rpcode_in_font (halfword f, halfword c, halfword i); +void tex_set_efcode_in_font (halfword f, halfword c, halfword i); + +extern void tex_set_charinfo_extensible (charinfo *ci, int top, int bottom, int middle, int extender); +extern void tex_add_charinfo_math_kern (charinfo *ci, int type, scaled ht, scaled krn); +extern int tex_get_charinfo_math_kerns (charinfo *ci, int id); +extern void tex_set_charinfo_horizontal_parts (charinfo *ci, extinfo *ext); +extern void tex_set_charinfo_vertical_parts (charinfo *ci, extinfo *ext); +extern void tex_add_charinfo_vertical_part (charinfo *ci, extinfo *ext); +extern void tex_add_charinfo_horizontal_part (charinfo *ci, extinfo *ext); +extern extinfo *tex_new_charinfo_part (int glyph, int startconnect, int endconnect, int advance, int repeater); + +/*tex Checkers: */ + +int tex_char_has_math (halfword f, halfword c); +int tex_has_ligature (halfword f, halfword c); +int tex_has_kern (halfword f, halfword c); + +/*tex Getters: */ + +# define MATH_KERN_NOT_FOUND 0x7FFFFFFF + +extern scaled tex_char_width_from_font (halfword f, halfword c); /* math + maincontrol */ +extern scaled tex_char_height_from_font (halfword f, halfword c); /* math + maincontrol */ +extern scaled tex_char_depth_from_font (halfword f, halfword c); /* math + maincontrol */ +extern scaled tex_char_total_from_font (halfword f, halfword c); /* math */ +extern scaled tex_char_italic_from_font (halfword f, halfword c); /* math + maincontrol */ +// halfword tex_char_options_from_font (halfword f, halfword c); +extern scaled tex_char_ef_from_font (halfword f, halfword c); /* packaging + maincontrol */ +extern scaled tex_char_lp_from_font (halfword f, halfword c); /* packaging + maincontrol */ +extern scaled tex_char_rp_from_font (halfword f, halfword c); /* packaging + maincontrol */ +extern halfword tex_char_tag_from_font (halfword f, halfword c); /* math */ +extern halfword tex_char_remainder_from_font (halfword f, halfword c); /* math */ +extern halfword tex_char_has_tag_from_font (halfword f, halfword c, halfword tag); +extern void tex_char_reset_tag_from_font (halfword f, halfword c, halfword tag); +// int tex_char_has_option_from_font (halfword g, halfword c, int option); + +extern scaled tex_char_top_left_kern_from_font (halfword f, halfword c); /* math */ +extern scaled tex_char_top_right_kern_from_font (halfword f, halfword c); /* math */ +extern scaled tex_char_bottom_left_kern_from_font (halfword f, halfword c); /* math */ +extern scaled tex_char_bottom_right_kern_from_font (halfword f, halfword c); /* math */ + +extern scaledwhd tex_char_whd_from_font (halfword f, halfword c); /* math + maincontrol */ + +extern scaled tex_font_x_scaled (scaled v); +extern scaled tex_font_y_scaled (scaled v); + +extern scaled tex_char_width_from_glyph (halfword g); /* x/y scaled */ +extern scaled tex_char_height_from_glyph (halfword g); /* x/y scaled */ +extern scaled tex_char_depth_from_glyph (halfword g); /* x/y scaled */ +extern scaled tex_char_total_from_glyph (halfword g); /* x/y scaled */ +extern scaled tex_char_italic_from_glyph (halfword g); /* x/y scaled */ +// int tex_char_options_from_glyph (halfword g); +extern scaled tex_char_width_italic_from_glyph (halfword g); /* x/y scaled */ +// int tex_char_has_option_from_glyph (halfword g, int option); + +extern scaledwhd tex_char_whd_from_glyph (halfword g); /* x/y scaled */ + +extern halfword tex_char_vertical_italic_from_font (halfword f, halfword c); +extern halfword tex_char_top_accent_from_font (halfword f, halfword c); +extern halfword tex_char_bot_accent_from_font (halfword f, halfword c); +extern halfword tex_char_flat_accent_from_font (halfword f, halfword c); + +extern halfword tex_char_top_anchor_from_font (halfword f, halfword c); +extern halfword tex_char_bot_anchor_from_font (halfword f, halfword c); + +extern scaled tex_char_left_margin_from_font (halfword f, halfword c); +extern scaled tex_char_right_margin_from_font (halfword f, halfword c); +extern scaled tex_char_top_margin_from_font (halfword f, halfword c); +extern scaled tex_char_bottom_margin_from_font (halfword f, halfword c); + +extern extinfo *tex_char_vertical_parts_from_font (halfword f, halfword c); +extern extinfo *tex_char_horizontal_parts_from_font (halfword f, halfword c); + +/* scaled tex_math_kern_at (halfword f, int c, int side, int v); */ +/* scaled tex_find_math_kern (halfword l_f, int l_c, halfword r_f, int r_c, int cmd, scaled shift); */ + +extern int tex_valid_kern (halfword left, halfword right); /* returns kern */ +extern int tex_valid_ligature (halfword left, halfword right, int *slot); /* returns type */ + +extern scaled tex_calculated_char_width (halfword f, halfword c, halfword ex); +extern scaled tex_calculated_glyph_width (halfword g, halfword ex); /* scale */ + +/* + Kerns: the |otherchar| value signals \quote {stop}. These are not really public and only + to be used in the helpers. But we keep them as reference. +*/ + +# define end_kern 0x7FFFFF + +# define charinfo_kern(b,c) b->kerns[c] + +# define kern_char(b) (b).adjacent +# define kern_kern(b) (b).kern +# define kern_end(b) ((b).adjacent == end_kern) +# define kern_disabled(b) ((b).adjacent > end_kern) + +/* + Ligatures: the |otherchar| value signals \quote {stop}. These are not really public and only + to be used in the helpers. But we keep them as reference. +*/ + +# define end_of_ligature_code 0x7FFFFF + +# define charinfo_ligature(b,c) b->ligatures[c] + +# define ligature_is_valid(a) ((a).type != 0) +# define ligature_type(a) ((a).type >> 1) +# define ligature_char(a) (a).adjacent +# define ligature_replacement(a) (a).ligature +# define ligature_end(a) ((a).adjacent == end_of_ligature_code) +# define ligature_disabled(a) ((a).adjacent > end_of_ligature_code) + +/* Remainders and related flags: */ + +typedef enum math_extension_modes { + math_extension_normal, + math_extension_repeat, +} math_extension_modes; + +/* Expansion */ + +typedef enum adjust_spacing_modes { + adjust_spacing_off, + adjust_spacing_unused, + adjust_spacing_full, + adjust_spacing_font, +} adjust_spacing_modes; + +typedef enum protrude_chars_modes { + protrude_chars_off, + protrude_chars_unused, + protrude_chars_normal, + protrude_chars_advanced, +} protrude_chars_modes; + +/* +typedef enum math_extension_locations { + extension_top, + extension_bottom, + extension_middle, + extension_repeat, +} math_extension_locations; +*/ + +/* Tags: */ + +typedef enum tag_codes { + no_tag = 0x00, /*tex vanilla character */ + ligature_tag = 0x01, /*tex character has a ligature/kerning program */ + list_tag = 0x02, /*tex character has a successor in a charlist */ + extension_tag = 0x04, /*tex character is extensible */ + callback_tag = 0x08, + extend_last_tag = 0x10, +} tag_codes; + +extern halfword tex_checked_font (halfword f); +extern int tex_is_valid_font (halfword f); +extern int tex_raw_get_kern (halfword f, int lc, int rc); +extern int tex_get_kern (halfword f, int lc, int rc); +extern ligatureinfo tex_get_ligature (halfword f, int lc, int rc); +extern int tex_new_font (void); +extern int tex_new_font_id (void); +extern void tex_font_malloc_charinfo (halfword f, int num); +extern void tex_char_malloc_mathinfo (charinfo * ci); +extern void tex_dump_font_data (dumpstream f); +extern void tex_undump_font_data (dumpstream f); +extern void tex_create_null_font (void); +extern void tex_delete_font (int id); +extern int tex_read_font_info (char *cnom, scaled s); +extern int tex_fix_expand_value (halfword f, int e); + +extern halfword tex_handle_glyphrun (halfword head, halfword group, halfword direction); +extern halfword tex_handle_ligaturing (halfword head, halfword tail); +extern halfword tex_handle_kerning (halfword head, halfword tail); + +extern void tex_set_cur_font (halfword g, halfword f); +extern int tex_tex_def_font (int a); + +extern void tex_char_warning (halfword f, int c); + +extern void tex_initialize_fonts (void); + +extern void tex_set_font_name (halfword f, const char *s); +extern void tex_set_font_original (halfword f, const char *s); + +extern scaled tex_get_math_font_scale (halfword f, halfword size); + +extern void tex_run_font_spec (void); + +# endif |