summaryrefslogtreecommitdiff
path: root/source/luametatex/source/tex
diff options
context:
space:
mode:
Diffstat (limited to 'source/luametatex/source/tex')
-rw-r--r--source/luametatex/source/tex/texbuildpage.c2
-rw-r--r--source/luametatex/source/tex/texcommands.c2
-rw-r--r--source/luametatex/source/tex/texcommands.h9
-rw-r--r--source/luametatex/source/tex/texconditional.c67
-rw-r--r--source/luametatex/source/tex/texdumpdata.h9
-rw-r--r--source/luametatex/source/tex/texequivalents.c17
-rw-r--r--source/luametatex/source/tex/texequivalents.h13
-rw-r--r--source/luametatex/source/tex/texerrors.c2
-rw-r--r--source/luametatex/source/tex/texexpand.c25
-rw-r--r--source/luametatex/source/tex/texfont.c249
-rw-r--r--source/luametatex/source/tex/texfont.h288
-rw-r--r--source/luametatex/source/tex/texinputstack.c23
-rw-r--r--source/luametatex/source/tex/texinserts.c3
-rw-r--r--source/luametatex/source/tex/texlanguage.c63
-rw-r--r--source/luametatex/source/tex/texmaincontrol.c17
-rw-r--r--source/luametatex/source/tex/texmarks.c4
-rw-r--r--source/luametatex/source/tex/texmath.c134
-rw-r--r--source/luametatex/source/tex/texmath.h30
-rw-r--r--source/luametatex/source/tex/texmathcodes.c7
-rw-r--r--source/luametatex/source/tex/texmlist.c237
-rw-r--r--source/luametatex/source/tex/texnodes.c12
-rw-r--r--source/luametatex/source/tex/texnodes.h163
-rw-r--r--source/luametatex/source/tex/texpackaging.c102
-rw-r--r--source/luametatex/source/tex/texprimitive.c8
-rw-r--r--source/luametatex/source/tex/texprinting.c58
-rw-r--r--source/luametatex/source/tex/texscanning.c54
-rw-r--r--source/luametatex/source/tex/textoken.c24
27 files changed, 925 insertions, 697 deletions
diff --git a/source/luametatex/source/tex/texbuildpage.c b/source/luametatex/source/tex/texbuildpage.c
index 0e2883305..0cf8b70e9 100644
--- a/source/luametatex/source/tex/texbuildpage.c
+++ b/source/luametatex/source/tex/texbuildpage.c
@@ -1011,8 +1011,8 @@ static void tex_aux_fire_up(halfword c)
wait = 1;
}
}
+ split_best_insert(r) = null;
{
- split_best_insert(r) = null;
/*tex
We need this juggling in order to also set the old school box
when we're in traditional mode.
diff --git a/source/luametatex/source/tex/texcommands.c b/source/luametatex/source/tex/texcommands.c
index f0949b9ab..5a4cc48b3 100644
--- a/source/luametatex/source/tex/texcommands.c
+++ b/source/luametatex/source/tex/texcommands.c
@@ -138,6 +138,7 @@ void tex_initialize_commands(void)
tex_primitive(tex_command, "exhyphenchar", internal_int_cmd, ex_hyphen_char_code, internal_int_base);
tex_primitive(tex_command, "exhyphenpenalty", internal_int_cmd, ex_hyphen_penalty_code, internal_int_base);
tex_primitive(tex_command, "fam", internal_int_cmd, family_code, internal_int_base);
+ tex_primitive(luatex_command, "variablefam", internal_int_cmd, variable_family_code, internal_int_base);
tex_primitive(tex_command, "finalhyphendemerits", internal_int_cmd, final_hyphen_demerits_code, internal_int_base);
tex_primitive(tex_command, "floatingpenalty", internal_int_cmd, floating_penalty_code, internal_int_base);
tex_primitive(tex_command, "globaldefs", internal_int_cmd, global_defs_code, internal_int_base);
@@ -743,6 +744,7 @@ void tex_initialize_commands(void)
tex_primitive(tex_command, "hyphenchar", set_font_property_cmd, font_hyphen_code, 0);
tex_primitive(tex_command, "skewchar", set_font_property_cmd, font_skew_code, 0);
tex_primitive(luatex_command, "efcode", set_font_property_cmd, font_ef_code, 0);
+ tex_primitive(luatex_command, "cfcode", set_font_property_cmd, font_cf_code, 0);
tex_primitive(luatex_command, "lpcode", set_font_property_cmd, font_lp_code, 0);
tex_primitive(luatex_command, "rpcode", set_font_property_cmd, font_rp_code, 0);
tex_primitive(tex_command, "fontdimen", set_font_property_cmd, font_dimen_code, 0);
diff --git a/source/luametatex/source/tex/texcommands.h b/source/luametatex/source/tex/texcommands.h
index 792e23662..6d85f1ed7 100644
--- a/source/luametatex/source/tex/texcommands.h
+++ b/source/luametatex/source/tex/texcommands.h
@@ -462,12 +462,16 @@ typedef enum convert_codes {
# define first_convert_code number_code
# define last_convert_code luatex_banner_code
+/*tex
+ At some point we might make |token_input_code| behave like |tex_token_input_code| and get rid
+ of |\everyeof| which is a quite useless feature that does more harm than good.
+*/
+
typedef enum input_codes {
normal_input_code,
end_of_input_code,
token_input_code,
tex_token_input_code,
- /* for now private */
tokenized_code,
retokenized_code,
quit_loop_code,
@@ -577,6 +581,7 @@ typedef enum font_property_codes {
font_lp_code,
font_rp_code,
font_ef_code,
+ font_cf_code,
font_dimen_code,
scaled_font_dimen_code,
} font_property_codes;
@@ -1067,7 +1072,7 @@ typedef enum math_styles {
# define first_math_style display_style
# define last_math_style all_cramped_styles
-# define is_valid_math_style(n) (n >= display_style && n <= cramped_script_script_style)
+# define is_valid_math_style(n) (n >= display_style && n <= cramped_script_script_style)
# define are_valid_math_styles(n) (n >= all_display_styles && n <= all_cramped_styles)
inline static halfword tex_math_style_to_size(halfword s)
diff --git a/source/luametatex/source/tex/texconditional.c b/source/luametatex/source/tex/texconditional.c
index b25bdfbbe..be68a8d6d 100644
--- a/source/luametatex/source/tex/texconditional.c
+++ b/source/luametatex/source/tex/texconditional.c
@@ -349,16 +349,19 @@ static void tex_aux_show_if_state(halfword code, halfword case_value)
{
tex_begin_diagnostic();
switch (code) {
- case if_chk_int_code : tex_print_format("{chknum %i}", case_value); break;
- case if_val_int_code : tex_print_format("{numval %i}", case_value); break;
- case if_cmp_int_code : tex_print_format("{cmpnum %i}", case_value); break;
- case if_chk_dim_code : tex_print_format("{chkdim %i}", case_value); break;
- case if_val_dim_code : tex_print_format("{dimval %i}", case_value); break;
- case if_cmp_dim_code : tex_print_format("{cmpdim %i}", case_value); break;
- case if_case_code : tex_print_format("{case %i}", case_value); break;
- case if_math_style_code: tex_print_format("{mathstyle %i}", case_value); break;
- case if_arguments_code : tex_print_format("{arguments %i}", case_value); break;
- default : tex_print_format("{todo %i}", case_value); break;
+ case if_chk_int_code : tex_print_format("{chknum %i}", case_value); break;
+ case if_val_int_code : tex_print_format("{numval %i}", case_value); break;
+ case if_cmp_int_code : tex_print_format("{cmpnum %i}", case_value); break;
+ case if_chk_dim_code : tex_print_format("{chkdim %i}", case_value); break;
+ case if_val_dim_code : tex_print_format("{dimval %i}", case_value); break;
+ case if_cmp_dim_code : tex_print_format("{cmpdim %i}", case_value); break;
+ case if_case_code : tex_print_format("{case %i}", case_value); break;
+ case if_math_parameter_code: tex_print_format("{mathparameter %i}", case_value); break;
+ case if_math_style_code : tex_print_format("{mathstyle %i}", case_value); break;
+ case if_arguments_code : tex_print_format("{arguments %i}", case_value); break;
+ case if_parameters_code : tex_print_format("{parameter %i}", case_value); break;
+ case if_parameter_code : tex_print_format("{parameters %i}", case_value); break;
+ default : tex_print_format("{todo %i}", case_value); break;
}
tex_end_diagnostic();
}
@@ -776,38 +779,44 @@ void tex_conditional_if(halfword code, int unless)
goto RESULT;
case if_flags_code:
{
- singleword flag, fl;
+ halfword cs;
+ singleword flag;
tex_get_r_token();
- flag = eq_flag(cur_cs);
+ cs = cur_cs;
+ flag = eq_flag(cs);
/* todo: each prefix */
tex_get_token();
if (cur_cmd == prefix_cmd) {
switch (cur_chr) {
- case permanent_code : result = is_permanent (flag); break;
- case immutable_code : result = is_immutable (flag); break;
- case mutable_code : result = is_mutable (flag); break;
- case noaligned_code : result = is_noaligned (flag); break;
- case instance_code : result = is_instance (flag); break;
- case untraced_code : result = is_untraced (flag); break;
- case global_code : result = is_global (flag); break;
- case tolerant_code : result = is_tolerant (flag); break;
- case protected_code : result = is_protected (flag); break;
- case overloaded_code : result = is_overloaded (flag); break;
- case aliased_code : result = is_aliased (flag); break;
- case immediate_code : result = is_immediate (flag); break;
- case semiprotected_code : result = is_semiprotected(flag); break;
+ /*tex We check flags: */
+ case frozen_code : result = is_frozen (flag); break;
+ case permanent_code : result = is_permanent(flag); break;
+ case immutable_code : result = is_immutable(flag); break;
+ /* case primitive_code : result = is_primitive(flag); break; */
+ case mutable_code : result = is_mutable (flag); break;
+ case noaligned_code : result = is_noaligned(flag); break;
+ case instance_code : result = is_instance (flag); break;
+ case untraced_code : result = is_untraced (flag); break;
+ /*tex We check cmd: */
+ case global_code : result = eq_level(cs) == level_one;; break;
+ case tolerant_code : result = is_tolerant_cmd(eq_type(cs)); break;
+ case protected_code : result = is_protected_cmd(eq_type(cs)); break;
+ case semiprotected_code : result = is_semi_protected_cmd(eq_type(cs)); break;
}
} else {
+ int fl;
tex_back_input(cur_tok);
- fl = (singleword) tex_scan_int(1, NULL); /* maybe some checking or masking is needed here */
+ fl = tex_scan_int(1, NULL);
result = (flag & fl) == fl;
if (! result) {
if (is_protected(fl)) {
- result = is_protected_cmd(eq_type(cur_cs));
+ result = is_protected_cmd(eq_type(cs));
+ } else if (is_semiprotected(fl)) {
+ result = is_semi_protected_cmd(eq_type(cs));
} else if (is_tolerant(fl)) {
- result = is_tolerant_cmd(eq_type(cur_cs));
+ result = is_tolerant_cmd(eq_type(cs));
} else if (is_global(fl)) {
- result = eq_level(cur_cs) == level_one;
+ result = eq_level(cs) == level_one;
}
}
}
diff --git a/source/luametatex/source/tex/texdumpdata.h b/source/luametatex/source/tex/texdumpdata.h
index bea80869d..e6f51d323 100644
--- a/source/luametatex/source/tex/texdumpdata.h
+++ b/source/luametatex/source/tex/texdumpdata.h
@@ -55,7 +55,7 @@
*/
-# define luametatex_format_fingerprint 674
+# define luametatex_format_fingerprint 675
/* These end up in the string pool. */
@@ -71,8 +71,11 @@ extern int tex_load_fmt_file (void);
extern int tex_fatal_undump_error (const char *s);
extern void tex_initialize_dump_state (void);
-# define dump_items(f,p,item_size,nitems) fwrite((void *) p, (size_t) item_size, (size_t) nitems, f)
-# define undump_items(f,p,item_size,nitems) { if (fread ((void *) p, (size_t) item_size, (size_t) nitems, f)) { } }
+//define dump_items(f,p,item_size,nitems) fwrite((void *) p, (size_t) item_size, (size_t) nitems, f)
+//define undump_items(f,p,item_size,nitems) { if (fread ((void *) p, (size_t) item_size, (size_t) nitems, f)) { } }
+
+# define dump_items(f,p,item_size,nitems) fwrite((void *) p, (size_t) item_size, (size_t) nitems, f)
+# define undump_items(f,p,item_size,nitems) fread ((void *) p, (size_t) item_size, (size_t) nitems, f)
# define dump_things(f,base,len) dump_items(f, (char *) &(base), sizeof (base), (int) (len))
# define undump_things(f,base,len) undump_items(f, (char *) &(base), sizeof (base), (int) (len))
diff --git a/source/luametatex/source/tex/texequivalents.c b/source/luametatex/source/tex/texequivalents.c
index aa434d8fd..4de7617c9 100644
--- a/source/luametatex/source/tex/texequivalents.c
+++ b/source/luametatex/source/tex/texequivalents.c
@@ -711,8 +711,8 @@ void tex_show_save_groups(void)
FOUND1:
{
/*tex Show the box packaging info. */
- tex_print_str_esc(package);
halfword packing, amount;
+ tex_print_str_esc(package);
if (tex_aux_saved_box_spec(&packing, &amount)) {
tex_print_str(packing == packing_exactly ? " to " : " spread ");
tex_print_dimension(amount, pt_unit);
@@ -1970,3 +1970,18 @@ int tex_located_save_value(int id)
}
return 0;
}
+
+extern int tex_cs_state(halfword p)
+{
+ if (p == null_cs) {
+ return cs_null_error;
+ } else if (p < hash_base) {
+ return cs_below_base_error;
+ } else if (p == undefined_control_sequence) {
+ return cs_undefined_error;
+ } else if (eqtb_out_of_range(p)) {
+ return cs_out_of_range_error;
+ } else {
+ return cs_no_error;
+ }
+}
diff --git a/source/luametatex/source/tex/texequivalents.h b/source/luametatex/source/tex/texequivalents.h
index 24a1729f9..2feab6858 100644
--- a/source/luametatex/source/tex/texequivalents.h
+++ b/source/luametatex/source/tex/texequivalents.h
@@ -571,6 +571,7 @@ typedef enum int_codes {
alignment_wrap_source_code,
/* page_boundary_penalty_code, */
line_break_criterium_code,
+ variable_family_code,
/* those below these are not interfaced via primitives */
internal_par_state_code,
internal_dir_state_code,
@@ -1347,6 +1348,7 @@ extern void tex_forced_word_define (int g, halfword p, singleword flag, halfword
# define split_top_skip_par glue_parameter(split_top_skip_code)
# define cur_fam_par count_parameter(family_code)
+# define variable_family_par count_parameter(variable_family_code)
# define pre_display_direction_par count_parameter(pre_display_direction_code)
# define pre_display_penalty_par count_parameter(pre_display_penalty_code)
# define post_display_penalty_par count_parameter(post_display_penalty_code)
@@ -1705,6 +1707,7 @@ extern halfword tex_explicit_disc_penalty (halfword mode);
# define update_tex_glyph_state(a,v) tex_word_define(a, internal_int_location(glyph_state_code), v)
# define update_tex_glyph_script(a,v) tex_word_define(a, internal_int_location(glyph_script_code), v)
# define update_tex_family(a,v) tex_word_define(a, internal_int_location(family_code), v)
+# define update_tex_variable_family(a,v) tex_word_define(a, internal_int_location(variable_family_code), v)
# define update_tex_language(a,v) tex_word_define(a, internal_int_location(language_code), v)
# define update_tex_font(a,v) tex_word_define(a, internal_int_location(font_code), v)
@@ -1766,4 +1769,14 @@ extern halfword tex_explicit_disc_penalty (halfword mode);
# define insert_maxheight(A) dimen_register(A)
# define insert_distance(A) skip_register(A)
+typedef enum cs_errors {
+ cs_no_error,
+ cs_null_error,
+ cs_below_base_error,
+ cs_undefined_error,
+ cs_out_of_range_error,
+} cs_errors;
+
+extern int tex_cs_state(halfword p) ;
+
# endif
diff --git a/source/luametatex/source/tex/texerrors.c b/source/luametatex/source/tex/texerrors.c
index bcc581f21..1d1e83dc9 100644
--- a/source/luametatex/source/tex/texerrors.c
+++ b/source/luametatex/source/tex/texerrors.c
@@ -610,7 +610,7 @@ extern void tex_handle_error(error_types type, const char *format, ...)
va_list args;
va_start(args, format); /* hm, weird, no number */
tex_aux_start_error();
- tex_print_format_args(format, args);
+ str = tex_print_format_args(format, args);
tex_aux_update_help_text(str);
tex_aux_do_handle_error_type(type);
va_end(args);
diff --git a/source/luametatex/source/tex/texexpand.c b/source/luametatex/source/tex/texexpand.c
index a0416d118..e74a9c08d 100644
--- a/source/luametatex/source/tex/texexpand.c
+++ b/source/luametatex/source/tex/texexpand.c
@@ -528,13 +528,22 @@ void tex_expand_current_token(void)
default:
/* Maybe ... or maybe an option */
// if (lmt_expand_state.cs_name_level == 0) {
- /*tex Complain about an undefined macro */
- tex_handle_error(
- normal_error_type,
- "Undefined control sequence %m", cur_cs,
- "The control sequence at the end of the top line of your error message was never\n"
- "\\def'ed. You can just continue as I'll forget about whatever was undefined."
- );
+ if (tex_cs_state(cur_cs) == cs_undefined_error) {
+ /*tex Complain about an undefined macro */
+ tex_handle_error(
+ normal_error_type,
+ "Undefined control sequence %m", cur_cs,
+ "The control sequence at the end of the top line of your error message was never\n"
+ "\\def'ed. You can just continue as I'll forget about whatever was undefined."
+ );
+ } else {
+ /*tex We ended up in a situation that is unlikely to happen in traditional \TEX. */
+ tex_handle_error(
+ normal_error_type,
+ "Control sequence expected instead of %C", cur_cmd, cur_chr,
+ "You injected something that confused the parser, maybe by using some Lua call."
+ );
+ }
// }
break;
}
@@ -1027,7 +1036,7 @@ static void tex_aux_macro_call(halfword cs, halfword cmd, halfword chr)
s = null;
goto BAD;
}
- break;
+ // break;
case thrash_match_token:
match = 0;
thrash = 1;
diff --git a/source/luametatex/source/tex/texfont.c b/source/luametatex/source/tex/texfont.c
index 605d6ff75..4aad8f495 100644
--- a/source/luametatex/source/tex/texfont.c
+++ b/source/luametatex/source/tex/texfont.c
@@ -134,33 +134,18 @@ void tex_undump_font_data(dumpstream f) {
lmt_font_state.font_data.ptr = 0;
}
-void tex_set_charinfo_vertical_parts(charinfo *ci, extinfo *ext)
+void tex_set_charinfo_extensible_recipe(charinfo *ci, extinfo *ext)
{
if (ci->math) {
- if (ci->math->vertical_parts) {
- extinfo *lst = ci->math->vertical_parts;
+ extinfo *lst = ci->math->extensible_recipe;
+ if (lst) {
while (lst) {
extinfo *c = lst->next;
lmt_memory_free(lst);
lst = c;
}
}
- ci->math->vertical_parts = ext;
- }
-}
-
-void tex_set_charinfo_horizontal_parts(charinfo *ci, extinfo *ext)
-{
- if (ci->math) {
- if (ci->math->horizontal_parts) {
- extinfo *lst = ci->math->horizontal_parts;
- while (lst) {
- extinfo *c = lst->next;
- lmt_memory_free(lst);
- lst = c;
- }
- }
- ci->math->horizontal_parts = ext;
+ ci->math->extensible_recipe = ext;
}
}
@@ -245,8 +230,8 @@ void tex_char_malloc_mathinfo(charinfo *ci)
int size = sizeof(mathinfo);
mathinfo *mi = lmt_memory_calloc(1, (size_t) size);
if (mi) {
- mi->horizontal_parts = NULL;
- mi->vertical_parts = NULL;
+ mi->extensible_recipe = NULL;
+ /* */
mi->top_left_math_kern_array = NULL;
mi->top_right_math_kern_array = NULL;
mi->bottom_right_math_kern_array = NULL;
@@ -256,6 +241,7 @@ void tex_char_malloc_mathinfo(charinfo *ci)
mi->top_right_kern = 0;
mi->bottom_left_kern = 0;
mi->bottom_right_kern = 0;
+ /* */
mi->left_margin = 0;
mi->right_margin = 0;
mi->top_margin = 0;
@@ -265,8 +251,7 @@ void tex_char_malloc_mathinfo(charinfo *ci)
mi->bottom_overshoot = INT_MIN;
if (ci->math) {
/*tex This seldom or probably never happens. */
- tex_set_charinfo_vertical_parts(ci, NULL);
- tex_set_charinfo_horizontal_parts(ci, NULL);
+ tex_set_charinfo_extensible_recipe(ci, NULL);
set_charinfo_top_left_math_kern_array(ci, NULL);
set_charinfo_top_right_math_kern_array(ci, NULL);
set_charinfo_bottom_right_math_kern_array(ci, NULL);
@@ -281,12 +266,19 @@ void tex_char_malloc_mathinfo(charinfo *ci)
}
}
-# define find_charinfo_id(f,c) (sa_get_item_4(lmt_font_state.fonts[f]->characters,c).int_value)
+inline int aux_find_charinfo_id(halfword f, int c)
+{
+ sa_tree_item item;
+ sa_get_item_4(lmt_font_state.fonts[f]->characters, c, &item);
+ return (int) item.int_value;
+}
charinfo *tex_get_charinfo(halfword f, int c)
{
if (proper_char_index(f, c)) {
- int glyph = sa_get_item_4(lmt_font_state.fonts[f]->characters, c).int_value;
+ sa_tree_item item;
+ sa_get_item_4(lmt_font_state.fonts[f]->characters, c, &item);
+ int glyph = (int) item.int_value;
if (! glyph) {
sa_tree_item sa_value = { 0 };
int tglyph = ++lmt_font_state.fonts[f]->chardata_count;
@@ -334,7 +326,7 @@ static charinfo *tex_aux_char_info(halfword f, int c)
if (f > lmt_font_state.font_data.ptr) {
return NULL;
} else if (proper_char_index(f, c)) {
- return &(lmt_font_state.fonts[f]->chardata[(int) find_charinfo_id(f, c)]);
+ return &(lmt_font_state.fonts[f]->chardata[(int) aux_find_charinfo_id(f, c)]);
} else if (c == left_boundary_char) {
if (font_left_boundary(f)) {
return font_left_boundary(f);
@@ -363,7 +355,7 @@ int tex_char_exists(halfword f, int c)
if (f > lmt_font_state.font_data.ptr) {
return 0;
} else if (proper_char_index(f, c)) {
- return (int) find_charinfo_id(f, c);
+ return (int) aux_find_charinfo_id(f, c);
} else if (c == left_boundary_char) {
if (font_has_left_boundary(f)) {
return 1;
@@ -384,7 +376,7 @@ static int check_math_char(halfword f, int c, int size)
if (callback_id > 0) {
halfword s = c;
lmt_run_callback(lua_state.lua_instance, callback_id, "ddd->d", f, c, size, &s);
- if (s && proper_char_index(f, s) && find_charinfo_id(f, s)) {
+ if (s && proper_char_index(f, s) && aux_find_charinfo_id(f, s)) {
return s;
}
}
@@ -405,7 +397,7 @@ int tex_math_char_exists(halfword f, int c, int size)
int tex_get_math_char(halfword f, int c, int size, scaled *scale, int direction)
{
- int id = find_charinfo_id(f, c);
+ int id = aux_find_charinfo_id(f, c);
texfont *tf = lmt_font_state.fonts[f];
if (id) {
/* */
@@ -413,7 +405,7 @@ int tex_get_math_char(halfword f, int c, int size, scaled *scale, int direction)
charinfo *ci = &tf->chardata[id];
int m = ci->math->mirror;
if (m && proper_char_index(f, m)) {
- int mid = find_charinfo_id(f, m);
+ int mid = aux_find_charinfo_id(f, m);
if (mid) {
id = mid;
c = m;
@@ -427,7 +419,7 @@ int tex_get_math_char(halfword f, int c, int size, scaled *scale, int direction)
if (ci->math) {
int s = ci->math->smaller;
if (s && proper_char_index(f, s)) {
- id = find_charinfo_id(f, s);
+ id = aux_find_charinfo_id(f, s);
if (id) {
/* todo: trace */
c = s;
@@ -452,58 +444,33 @@ int tex_get_math_char(halfword f, int c, int size, scaled *scale, int direction)
return c;
}
-extinfo *tex_new_charinfo_part(int glyph, int startconnect, int endconnect, int advance, int extender)
-{
- int size = sizeof(extinfo);
- extinfo *ext = lmt_memory_malloc((size_t) size);
- if (ext) {
- ext->next = NULL;
- ext->glyph = glyph;
- ext->start_overlap = startconnect;
- ext->end_overlap = endconnect;
- ext->advance = advance;
- ext->extender = extender;
- } else {
- tex_overflow_error("font", size);
- }
- return ext;
-}
-
-void tex_add_charinfo_vertical_part(charinfo *ci, extinfo *ext)
-{
- if (ci->math) {
- if (ci->math->vertical_parts) {
- extinfo *lst = ci->math->vertical_parts;
- while (lst->next)
- lst = lst->next;
- lst->next = ext;
- } else {
- ci->math->vertical_parts = ext;
- }
- }
-}
-
-void tex_add_charinfo_horizontal_part(charinfo *ci, extinfo *ext)
+void tex_append_charinfo_extensible_recipe(charinfo *ci, int glyph, int startconnect, int endconnect, int advance, int extender)
{
if (ci->math) {
- if (ci->math->horizontal_parts) {
- extinfo *lst = ci->math->horizontal_parts;
- while (lst->next) {
- lst = lst->next;
+ int size = sizeof(extinfo);
+ extinfo *ext = lmt_memory_malloc((size_t) size);
+ if (ext) {
+ extinfo *lst = ci->math->extensible_recipe;
+ ext->next = NULL;
+ ext->glyph = glyph;
+ ext->start_overlap = startconnect;
+ ext->end_overlap = endconnect;
+ ext->advance = advance;
+ ext->extender = extender;
+ if (lst) {
+ while (lst->next) {
+ lst = lst->next;
+ }
+ lst->next = ext;
+ } else {
+ ci->math->extensible_recipe = ext;
}
- lst->next = ext;
} else {
- ci->math->horizontal_parts = ext;
+ tex_overflow_error("font", size);
}
}
}
-/*tex
-
- Note that many more small things like this are implemented as macros in the header file.
-
-*/
-
int tex_get_charinfo_math_kerns(charinfo *ci, int id)
{
/*tex All callers check for |result > 0|. */
@@ -598,43 +565,43 @@ void tex_add_charinfo_math_kern(charinfo *ci, int id, scaled ht, scaled krn)
A small complication arises if |rep| is the only non-zero: it needs to be doubled as a
non-repeatable to avoid mayhem.
-*/
-
-void tex_set_charinfo_extensible(charinfo *ci, int top, int bottom, int middle, int extender)
-{
- if (ci->math) {
- extinfo *ext;
- /*tex Clear old data: */
- tex_set_charinfo_vertical_parts(ci, NULL);
- if (bottom == 0 && top == 0 && middle == 0 && extender != 0) {
- ext = tex_new_charinfo_part(extender, 0, 0, 0, math_extension_normal);
- tex_add_charinfo_vertical_part(ci, ext);
- ext = tex_new_charinfo_part(extender, 0, 0, 0, math_extension_repeat);
- tex_add_charinfo_vertical_part(ci, ext);
- } else {
- if (bottom) {
- ext = tex_new_charinfo_part(bottom, 0, 0, 0, math_extension_normal);
- tex_add_charinfo_vertical_part(ci, ext);
- }
- if (extender) {
- ext = tex_new_charinfo_part(extender, 0, 0, 0, math_extension_repeat);
- tex_add_charinfo_vertical_part(ci, ext);
- }
- if (middle) {
- ext = tex_new_charinfo_part(middle, 0, 0, 0, math_extension_normal);
- tex_add_charinfo_vertical_part(ci, ext);
+ \starttyping
+ void tex_set_charinfo_extensible(charinfo *ci, int top, int bottom, int middle, int extender)
+ {
+ if (ci->math) {
+ extinfo *ext;
+ tex_set_charinfo_extensible_recipe(ci, NULL);
+ if (bottom == 0 && top == 0 && middle == 0 && extender != 0) {
+ ext = tex_new_charinfo_extensible_step(extender, 0, 0, 0, math_extension_normal);
+ tex_add_charinfo_extensible_step(ci, ext);
+ ext = tex_new_charinfo_extensible_step(extender, 0, 0, 0, math_extension_repeat);
+ tex_add_charinfo_extensible_step(ci, ext);
+ } else {
+ if (bottom) {
+ ext = tex_new_charinfo_extensible_step(bottom, 0, 0, 0, math_extension_normal);
+ tex_add_charinfo_extensible_step(ci, ext);
+ }
if (extender) {
- ext = tex_new_charinfo_part(extender, 0, 0, 0, math_extension_repeat);
- tex_add_charinfo_vertical_part(ci, ext);
+ ext = tex_new_charinfo_extensible_step(extender, 0, 0, 0, math_extension_repeat);
+ tex_add_charinfo_extensible_step(ci, ext);
+ }
+ if (middle) {
+ ext = tex_new_charinfo_extensible_step(middle, 0, 0, 0, math_extension_normal);
+ tex_add_charinfo_extensible_step(ci, ext);
+ if (extender) {
+ ext = tex_new_charinfo_extensible_step(extender, 0, 0, 0, math_extension_repeat);
+ tex_add_charinfo_extensible_step(ci, ext);
+ }
+ }
+ if (top) {
+ ext = tex_new_charinfo_extensible_step(top, 0, 0, 0, math_extension_normal);
+ tex_add_charinfo_extensible_step(ci, ext);
}
- }
- if (top) {
- ext = tex_new_charinfo_part(top, 0, 0, 0, math_extension_normal);
- tex_add_charinfo_vertical_part(ci, ext);
}
}
}
-}
+ \stoptyping
+*/
/*tex why not just preallocate for all math otf parameters */
@@ -667,13 +634,12 @@ void tex_delete_font(int f)
set_font_left_boundary(f, NULL);
set_font_right_boundary(f, NULL);
for (int i = font_first_character(f); i <= font_last_character(f); i++) {
- if (quick_char_exists(f, i)) {
+ if (tex_char_exists(f, i)) {
charinfo *co = tex_aux_char_info(f, i);
set_charinfo_kerns(co, NULL);
set_charinfo_ligatures(co, NULL);
if (co->math) {
- tex_set_charinfo_vertical_parts(co, NULL);
- tex_set_charinfo_horizontal_parts(co, NULL);
+ tex_set_charinfo_extensible_recipe(co, NULL);
set_charinfo_top_left_math_kern_array(co, NULL);
set_charinfo_top_right_math_kern_array(co, NULL);
set_charinfo_bottom_right_math_kern_array(co, NULL);
@@ -1119,11 +1085,6 @@ static halfword tex_aux_handle_ligature_nesting(halfword root, halfword cur)
have (any kind of) discretionaries. It is still on my agenda to look into nested discretionaries
i.e. discs nodes in disc fields but it might never result in useable code.
- Remark: there is now a patch for \LUATEX\ that fixes some long pending issue with select discs but
- still it's kind of fuzzy. It also complicates the par builder in a way that I don't really want
- (at least in \CONTEXT). It was anyway a good reason for removing traces of these special disc nodes
- in \LUAMETATEX.
-
*/
static halfword tex_aux_handle_ligature_word(halfword cur)
@@ -1327,7 +1288,6 @@ static halfword tex_aux_handle_ligature_word(halfword cur)
return cur;
}
-
/*tex The return value is the new tail, head should be a dummy: */
halfword tex_handle_ligaturing(halfword head, halfword tail)
@@ -1725,6 +1685,11 @@ scaled tex_char_ef_from_font(halfword f, halfword c)
return tex_aux_char_info(f, c)->expansion;
}
+scaled tex_char_cf_from_font(halfword f, halfword c)
+{
+ return tex_aux_char_info(f, c)->compression;
+}
+
scaled tex_char_lp_from_font(halfword f, halfword c)
{
return tex_aux_char_info(f, c)->leftprotrusion;
@@ -1737,32 +1702,35 @@ scaled tex_char_rp_from_font(halfword f, halfword c)
halfword tex_char_has_tag_from_font(halfword f, halfword c, halfword tag)
{
- return (charinfo_tag(tex_aux_char_info(f, c)->tagrem) & tag) == tag;
+ return (tex_aux_char_info(f, c)->tag & tag) == tag;
}
void tex_char_reset_tag_from_font(halfword f, halfword c, halfword tag)
{
charinfo *ci = tex_aux_char_info(f, c);
- // tag = charinfo_tag(ci->tagrem) & ~(tag | charinfo_tag(ci->tagrem));
- tag = charinfo_tag(ci->tagrem) & ~(tag);
- ci->tagrem = charinfo_tagrem(tag,charinfo_rem(ci->tagrem));
-
+ ci->tag = ci->tag & ~(tag);
}
halfword tex_char_tag_from_font(halfword f, halfword c)
{
- return charinfo_tag(tex_aux_char_info(f, c)->tagrem);
+ return tex_aux_char_info(f, c)->tag;
+}
+
+int tex_char_checked_tag(halfword tag)
+{
+ return tag & (horizontal_tag | vertical_tag | extend_last_tag | italic_tag | n_ary_tag | radical_tag | punctuation_tag);
}
-halfword tex_char_remainder_from_font(halfword f, halfword c)
+halfword tex_char_next_from_font(halfword f, halfword c)
{
- return charinfo_rem(tex_aux_char_info(f, c)->tagrem);
+ charinfo *ci = tex_aux_char_info(f, c);
+ return ci->math ? ci->math->next : -1;
}
-halfword tex_char_vertical_italic_from_font(halfword f, halfword c)
+halfword tex_char_extensible_italic_from_font(halfword f, halfword c)
{
charinfo *ci = tex_aux_char_info(f, c);
- return ci->math ? ci->math->vertical_italic : INT_MIN;
+ return ci->math ? ci->math->extensible_italic : INT_MIN;
}
halfword tex_char_unchecked_top_anchor_from_font(halfword f, halfword c)
@@ -1819,16 +1787,10 @@ scaled tex_char_bottom_right_kern_from_font(halfword f, halfword c)
return ci->math ? ci->math->bottom_right_kern : 0;
}
-extinfo *tex_char_vertical_parts_from_font(halfword f, halfword c)
-{
- charinfo *ci = tex_aux_char_info(f, c);
- return ci->math ? ci->math->vertical_parts : NULL;
-}
-
-extinfo *tex_char_horizontal_parts_from_font(halfword f, halfword c)
+extinfo *tex_char_extensible_recipe_from_font(halfword f, halfword c)
{
charinfo *ci = tex_aux_char_info(f, c);
- return ci->math ? ci->math->horizontal_parts : NULL;
+ return ci->math ? ci->math->extensible_recipe : NULL;
}
scaled tex_char_left_margin_from_font(halfword f, halfword c)
@@ -1867,6 +1829,18 @@ scaled tex_char_bottom_overshoot_from_font(halfword f, halfword c)
return ci->math ? ci->math->bottom_overshoot : 0;
}
+scaled tex_char_inner_x_offset_from_font(halfword f, halfword c)
+{
+ charinfo *ci = tex_aux_char_info(f, c);
+ return ci->math ? ci->math->inner_x_offset : 0;
+}
+
+scaled tex_char_inner_y_offset_from_font(halfword f, halfword c)
+{
+ charinfo *ci = tex_aux_char_info(f, c);
+ return ci->math ? ci->math->inner_y_offset : 0;
+}
+
/* Nodes */
scaled tex_char_width_from_glyph(halfword g)
@@ -1992,6 +1966,13 @@ void tex_set_efcode_in_font(halfword f, halfword c, halfword i) {
}
}
+void tex_set_cfcode_in_font(halfword f, halfword c, halfword i) {
+ charinfo *ci = tex_aux_char_info(f, c);
+ if (ci) {
+ ci->compression = i;
+ }
+}
+
void tex_set_font_name(halfword f, const char *s)
{
if (font_name(f)) {
diff --git a/source/luametatex/source/tex/texfont.h b/source/luametatex/source/tex/texfont.h
index e5365a0be..d3722f9ad 100644
--- a/source/luametatex/source/tex/texfont.h
+++ b/source/luametatex/source/tex/texfont.h
@@ -72,42 +72,68 @@ typedef struct extinfo {
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)
+/*tex
+ We have dedicated fields for hparts and vparts and their italics. Only avery few fonts actually
+ set the italic on the extensible which is why the engine can use the regular italic, which in
+ that case is then the last in the variant list because that is where we put the recipe. Keep in
+ mind that in an \OPENTYPE\ fonts we have a base glyph that has a variant list and part recipe
+ while in the engine (in good \TEX\ tradition) we chain the variants (with the next field)) so by
+ the time we arrive at the last one we look at the (h,v) italic there. No fonts (so far) have a
+ horizontal extensible with a set italic correction.
+
+ Actually, because the specification is rather explicit about glyphs only having horizontal or
+ vertical extensibles we now have collapsed the two categories into one.
+*/
typedef struct mathinfo {
- scaled vertical_italic;
- scaled top_anchor; /* provided by the font, aka topaccent */
- scaled bottom_anchor; /* provided by context */
- int smaller;
- scaled scale;
- int flat_accent; /* flac feature code point */
- int top_left_math_kerns; /* size of array */
- int top_right_math_kerns; /* size of array */
- int bottom_right_math_kerns; /* size of array */
- int bottom_left_math_kerns; /* size of array */
- extinfo *horizontal_parts;
- extinfo *vertical_parts;
- scaled *top_left_math_kern_array;
+ /*tex
+ Optional code points for next smaller in size, right2left and flat accent glyphs.
+ */
+ halfword smaller;
+ halfword mirror;
+ halfword flat_accent;
+ halfword next;
+ /*tex
+ The top anchor is provides by the font and is also known as topaccent while the bottom
+ anchor is one set by (in our case) \CONTEXT.
+ */
+ scaled top_anchor;
+ scaled bottom_anchor;
+ /*tex
+ A set of pointers to variable size arrays which is why we also have the number of slots
+ stored.
+ */
+ int top_left_math_kerns;
+ int top_right_math_kerns;
+ int bottom_right_math_kerns;
+ int bottom_left_math_kerns;
+ 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;
- scaled top_overshoot;
- scaled bottom_overshoot;
- int mirror;
- int padding;
+ /*tex
+ Here come the extensible recipes. Because we haven't seen both in one glyph we can share
+ the pointer and put a h/v flag in the tag field. For the moment we keep them both because
+ we might want to play with a two dimensional extensible some day.
+ */
+ extinfo *extensible_recipe;
+ scaled extensible_italic;
+ /*tex These are for specific (script) anchoring. */
+ scaled top_left_kern;
+ scaled bottom_left_kern;
+ scaled top_right_kern;
+ scaled bottom_right_kern;
+ /*tex These four are used in accents. */
+ scaled left_margin;
+ scaled right_margin;
+ scaled top_margin;
+ scaled bottom_margin;
+ /*tex As are the following. */
+ scaled top_overshoot;
+ scaled bottom_overshoot;
+ /*tex These are for degrees in radicals. */
+ scaled inner_x_offset;
+ scaled inner_y_offset;
} mathinfo;
typedef struct charinfo {
@@ -123,36 +149,59 @@ typedef struct charinfo {
/*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.
+ from this important extension to traditional \TEX.
+
+ We can make the next four into a a pointer which saves on large fonts and only a subset
+ of characters has protrusion or expansion, if used at all. That way we delegate some memory
+ consumption to usage (of course allocated blobs also have overhead).
*/
- scaled expansion;
+ scaled expansion;
+ scaled compression;
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.
+ The tag and remainder are used in a \TFM\ file for signaling ligatures. They are also used
+ for math extensions in traditional \TEX\ fonts. We used to pack the tag and remainder
+ in an integer: 2 bits is enough for the tag (but we get some more) and the remainder (aka
+ next) fits in 21 bits. So we had |tagrem| for quite a while.
+
+ But we now use a 32 bit tag field and use proper next field that has been moved to the math
+ blob so that we can have a compression field here without padding.
*/
- /* 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 */
+ halfword tag;
/*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.
+
+ We could combine math and ligatures and save two slots but then we cannot have a hybrid base
+ font so ... not now.
*/
- ligatureinfo *ligatures;
kerninfo *kerns;
- mathinfo *math;
+ mathinfo *math;
+ ligatureinfo *ligatures;
} charinfo;
+/*
+ An option is to make this a pointer to a structure but then we also waste a slot. When we
+ never support it in math then we can actually go smaller:
+
+ charinfo: 8 * 4 : width height depth italic tag *[text or math] *kerns padding
+ textinfo: 4 * 4 : expansion leftprotrusion rightprotrusion *ligatures
+ mathinfo: 2 * 4 : next padding ... n * 4
+
+ But ... given the amount of fields that \CONTEXT\ adds to the basic character data anyway
+ there is no real reason to spend much time in saving some bytes here.
+
+*/
+
/*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
+//define charinfo_tag token_cmd
+//define charinfo_rem token_chr
+//define charinfo_tagrem token_val
/*tex
@@ -280,10 +329,8 @@ typedef enum 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.
-
+ fonts we don't see these. Maybe this will be dropped at some point.
*/
typedef enum boundarychar_codes {
@@ -292,8 +339,6 @@ typedef enum boundarychar_codes {
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
@@ -304,12 +349,16 @@ typedef enum boundarychar_codes {
# 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
+ The math engine can benefit from these properties. For instance we use them for optimizing
+ the positioning of the degree in a (left) radical. These properties are not stored in the
+ tag (for a short while we had a variable).
+*/
+/*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
@@ -324,10 +373,8 @@ typedef enum boundarychar_codes {
# 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; }
@@ -346,10 +393,8 @@ extern halfword tex_checked_font_adjust (
);
/*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 {
@@ -372,6 +417,7 @@ 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_slant (halfword f);
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);
@@ -388,9 +434,7 @@ 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 {
@@ -406,17 +450,34 @@ 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, int direction);
-/*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.
+/*tex
+ These used to be small integers, bit 22 upto 31, but now we have a 32 bit set. We actually don't
+ really need the granularity but by having these flags we can actually add a bit of control, like
+ having kerns but still blocking them. The numbers here are no longer reflective of what a tfm
+ file provides. We assume tfm files to be converted anyway.
+ Not all are needed but at least we now can keep some state. We can actually use them to something
+ if we really want to (like when we runt tests). However, that is a rather drastic measure for
+ shared fonts. Tracing is another application and at some point it will be used for this.
*/
-# define quick_char_exists(f,c) (sa_get_item_4(lmt_font_state.fonts[f]->characters,c).int_value)
+typedef enum char_tag_codes {
+ no_tag = 0x0000, /*tex vanilla character */
+ ligatures_tag = 0x0001, /*tex character has a ligature program, not used */
+ kerns_tag = 0x0002, /*tex character has a kerning program, not used */
+ list_tag = 0x0004, /*tex character has a successor in a charlist */
+ callback_tag = 0x0010,
+ extensible_tag = 0x0020, /*tex character is extensible, we can unset it in order to block */
+ horizontal_tag = 0x0040, /*tex horizontal extensible */
+ vertical_tag = 0x0080, /*tex vertical extensible */
+ extend_last_tag = 0x0100, /*tex auto scale last variant */
+ inner_left_tag = 0x0200, /*tex anchoring */
+ inner_right_tag = 0x0400, /*tex anchoring */
+ italic_tag = 0x0800,
+ n_ary_tag = 0x1000,
+ radical_tag = 0x2000,
+ punctuation_tag = 0x4000,
+} char_tag_codes;
/*tex
These low level setters are not publis and used in helpers. They might become functions
@@ -428,14 +489,15 @@ extern int tex_get_math_char (halfword f, int c, int size, scaled *scal
# 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_compression(ci,val) ci->compression = 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 set_charinfo_tag(ci,val) ci->tag |= val;
+# define set_charinfo_next(ci,val) if (ci->math) { ci->math->next = val; }
-# define has_charinfo_tag(ci,p) (charinfo_tag(ci->tagrem) & (p) == (p))
-# define get_charinfo_tag(ci) charinfo_tag(ci->tagrem)
+# define has_charinfo_tag(ci,p) (ci->tag) & (p) == (p))
+# define get_charinfo_tag(ci) ci->tag
# 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; }
@@ -458,11 +520,14 @@ extern int tex_get_math_char (halfword f, int c, int size, scaled *scal
# define set_charinfo_smaller(ci,val) if (ci->math) { ci->math->smaller = val; }
# define set_charinfo_mirror(ci,val) if (ci->math) { ci->math->mirror = val; }
-# define set_charinfo_vertical_italic(ci,val) if (ci->math) { ci->math->vertical_italic = val; }
+# define set_charinfo_extensible_italic(ci,val) if (ci->math) { ci->math->extensible_italic = val; }
# define set_charinfo_top_anchor(ci,val) if (ci->math) { ci->math->top_anchor = val; }
# define set_charinfo_bottom_anchor(ci,val) if (ci->math) { ci->math->bottom_anchor = val; }
# define set_charinfo_flat_accent(ci,val) if (ci->math) { ci->math->flat_accent = val; }
+# define set_charinfo_inner_x_offset(ci,val) if (ci->math) { ci->math->inner_x_offset = val; }
+# define set_charinfo_inner_y_offset(ci,val) if (ci->math) { ci->math->inner_y_offset = 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; }
@@ -476,15 +541,12 @@ extern int tex_get_math_char (halfword f, int c, int size, scaled *scal
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);
+void tex_set_cfcode_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);
+extern void tex_set_charinfo_extensible_recipe (charinfo *ci, extinfo *ext);
+extern void tex_append_charinfo_extensible_recipe (charinfo *ci, int glyph, int startconnect, int endconnect, int advance, int repeater);
/*tex Checkers: */
@@ -496,63 +558,54 @@ int tex_has_kern (halfword f, halfword c)
# define MATH_KERN_NOT_FOUND 0x7FFFFFFF
+extern scaled tex_font_x_scaled (scaled v);
+extern scaled tex_font_y_scaled (scaled v);
+
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 scaledwhd tex_char_whd_from_font (halfword f, halfword c); /* math + maincontrol */
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_cf_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_next_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 int tex_char_checked_tag (halfword tag);
+extern scaled tex_char_inner_x_offset_from_font (halfword f, halfword c);
+extern scaled tex_char_inner_y_offset_from_font (halfword f, halfword c);
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_unchecked_top_anchor_from_font (halfword f, halfword c);
-extern halfword tex_char_unchecked_bottom_anchor_from_font (halfword f, halfword c);
-
-extern halfword tex_char_vertical_italic_from_font (halfword f, halfword c);
+extern halfword tex_char_extensible_italic_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_bottom_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 scaled tex_char_top_overshoot_from_font (halfword f, halfword c);
extern scaled tex_char_bottom_overshoot_from_font (halfword f, halfword c);
+extern scaled tex_char_inner_x_offset_from_font (halfword f, halfword c);
+extern scaled tex_char_inner_y_offset_from_font (halfword f, halfword c);
+extern extinfo *tex_char_extensible_recipe_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 halfword tex_char_unchecked_top_anchor_from_font (halfword f, halfword c);
+extern halfword tex_char_unchecked_bottom_anchor_from_font (halfword f, halfword c);
+
+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 */
+extern scaled tex_char_width_italic_from_glyph (halfword g); /* x/y scaled */
+extern scaledwhd tex_char_whd_from_glyph (halfword g); /* x/y scaled */
extern int tex_valid_kern (halfword left, halfword right); /* returns kern */
extern int tex_valid_ligature (halfword left, halfword right, int *slot); /* returns type */
@@ -560,7 +613,7 @@ extern int tex_valid_ligature (halfword left, halfword
extern scaled tex_calculated_char_width (halfword f, halfword c, halfword ex);
extern scaled tex_calculated_glyph_width (halfword g, halfword ex); /* scale */
-/*
+/*tex
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.
*/
@@ -574,7 +627,7 @@ extern scaled tex_calculated_glyph_width (halfword g, halfword ex
# define kern_end(b) ((b).adjacent == end_kern)
# define kern_disabled(b) ((b).adjacent > end_kern)
-/*
+/*tex
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.
*/
@@ -590,14 +643,14 @@ extern scaled tex_calculated_glyph_width (halfword g, halfword ex
# define ligature_end(a) ((a).adjacent == end_of_ligature_code)
# define ligature_disabled(a) ((a).adjacent > end_of_ligature_code)
-/* Remainders and related flags: */
+/*tex Extension specific: */
typedef enum math_extension_modes {
math_extension_normal,
math_extension_repeat,
} math_extension_modes;
-/* Expansion */
+/*tex Expansion and protrusion: */
typedef enum adjust_spacing_modes {
adjust_spacing_off,
@@ -622,17 +675,6 @@ typedef enum math_extension_locations {
} 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);
@@ -641,7 +683,7 @@ 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_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);
diff --git a/source/luametatex/source/tex/texinputstack.c b/source/luametatex/source/tex/texinputstack.c
index 9823fe137..e73451226 100644
--- a/source/luametatex/source/tex/texinputstack.c
+++ b/source/luametatex/source/tex/texinputstack.c
@@ -392,14 +392,16 @@ static void tex_aux_print_current_input_state(void)
} else {
switch (lmt_input_state.cur_input.name) {
case io_initial_input_code:
- tex_print_str("initial");
+ tex_print_str("initial input");
break;
case io_lua_input_code:
- tex_print_str("lua output");
+ tex_print_str("lua input");
break;
case io_token_input_code:
+ tex_print_str("token input");
+ break;
case io_token_eof_input_code:
- tex_print_str("scantokens");
+ tex_print_str("token eof input");
break;
case io_tex_macro_code:
case io_file_input_code:
@@ -841,11 +843,12 @@ void tex_cleanup_input_state(void)
break;
case macro_text:
{
+ int ptr, start;
/*tex Using a simple version for no arguments has no gain. */
tex_delete_token_reference(lmt_input_state.cur_input.start);
/*tex Parameters must be flushed: */
- int ptr = lmt_input_state.parameter_stack_data.ptr;
- int start = lmt_input_state.cur_input.parameter_start;
+ ptr = lmt_input_state.parameter_stack_data.ptr;
+ start = lmt_input_state.cur_input.parameter_start;
while (ptr > start) {
--ptr;
if (lmt_input_state.parameter_stack[ptr]) {
@@ -1063,9 +1066,15 @@ void tex_initialize_inputstack(void)
lmt_input_state.align_state = 1000000;
}
+/*tex
+ Currently |iotype| can be |io_token_input_code| or |io_token_eof_input_code| but the idea
+ was to get rid of the eof variant. However, it seems that there are still use cases (not
+ in \CONTEXT).
+*/
+
void tex_tex_string_start(int iotype, int cattable)
{
- (void) iotype;
+ /* (void) iotype; */
{
halfword head = tex_scan_general_text(NULL);
int saved_selector = lmt_print_state.selector;
@@ -1082,7 +1091,7 @@ void tex_tex_string_start(int iotype, int cattable)
lmt_input_state.input_line = 0;
lmt_input_state.cur_input.limit = lmt_input_state.cur_input.start;
lmt_input_state.cur_input.loc = lmt_input_state.cur_input.limit + 1;
- lmt_input_state.cur_input.name = io_token_input_code;
+ lmt_input_state.cur_input.name = iotype; /* io_token_input_code; */
lmt_cstring_start();
}
}
diff --git a/source/luametatex/source/tex/texinserts.c b/source/luametatex/source/tex/texinserts.c
index 27b979e0f..dbd164926 100644
--- a/source/luametatex/source/tex/texinserts.c
+++ b/source/luametatex/source/tex/texinserts.c
@@ -424,10 +424,11 @@ void tex_dump_insert_data(dumpstream f) {
}
void tex_undump_insert_data(dumpstream f) {
+ insert_record *tmp;
undump_int(f, lmt_insert_state.mode);
undump_int(f, lmt_insert_state.insert_data.ptr);
undump_int(f, lmt_insert_state.insert_data.top);
- insert_record *tmp = aux_allocate_clear_array(sizeof(insert_record), lmt_insert_state.insert_data.top, 1);
+ tmp = aux_allocate_clear_array(sizeof(insert_record), lmt_insert_state.insert_data.top, 1);
if (tmp) {
lmt_insert_state.inserts = tmp;
lmt_insert_state.insert_data.allocated = lmt_insert_state.insert_data.top * sizeof(insert_record);
diff --git a/source/luametatex/source/tex/texlanguage.c b/source/luametatex/source/tex/texlanguage.c
index 22627ee58..0fcd3b243 100644
--- a/source/luametatex/source/tex/texlanguage.c
+++ b/source/luametatex/source/tex/texlanguage.c
@@ -525,6 +525,7 @@ void tex_load_hyphenation(struct tex_language *lang, const unsigned char *buff)
}
}
}
+ lua_pop(L, 1);
}
}
@@ -627,44 +628,6 @@ static char *tex_aux_hyphenation_exception(int exceptions, char *w)
return ret;
}
-/*tex Kept as reference: */
-
-/*
-char *get_exception_strings(struct tex_language *lang)
-{
- char *ret = NULL;
- if (lang && lang->exceptions) {
- lua_State *L = lua_state.lua_instance;
- if (lua_rawgeti(L, LUA_REGISTRYINDEX, lang->exceptions) == LUA_TTABLE) {
- size_t size = 0;
- size_t current = 0;
- lua_pushnil(L);
- while (lua_next(L, -2)) {
- size_t l = 0;
- const char *value = lua_tolstring(L, -1, &l);
- if (current + l + 2 > size) {
- size_t new = (size + size/5) + current + l + 1024;
- char *tmp = lmt_memory_realloc(ret, new);
- if (tmp) {
- ret = tmp;
- size = new;
- } else {
- overflow_error("exceptions", (int) size);
- }
- }
- if (ret) {
- ret[current] = ' ';
- strcpy(&ret[current + 1], value);
- current += l + 1;
- }
- lua_pop(L, 1);
- }
- }
- }
- return ret;
-}
-*/
-
/*tex
The sequence from |wordstart| to |r| can contain only normal characters it could be faster to
@@ -997,8 +960,6 @@ static void tex_aux_do_exception(halfword wordstart, halfword r, char *replaceme
*/
-// # define is_hyphen_char(chr) (get_hc_code(chr) || chr == ex_hyphen_char_par)
-
inline static halfword tex_aux_is_hyphen_char(halfword chr)
{
if (tex_get_hc_code(chr)) {
@@ -1013,7 +974,6 @@ inline static halfword tex_aux_is_hyphen_char(halfword chr)
static halfword tex_aux_find_next_wordstart(halfword r, halfword first_language)
{
int start_ok = 1;
- int mathlevel = 1;
halfword lastglyph = r;
while (r) {
switch (node_type(r)) {
@@ -1038,15 +998,18 @@ static halfword tex_aux_find_next_wordstart(halfword r, halfword first_language)
start_ok = 1;
break;
case math_node:
- while (mathlevel > 0) {
- r = node_next(r);
- if (! r) {
- return r;
- } else if (node_type(r) == math_node) {
- if (node_subtype(r) == begin_inline_math) {
- mathlevel++;
- } else {
- mathlevel--;
+ if (node_subtype(r) == begin_inline_math) {
+ int mathlevel = 1;
+ while (mathlevel > 0) {
+ r = node_next(r);
+ if (! r) {
+ return r;
+ } else if (node_type(r) == math_node) {
+ if (node_subtype(r) == begin_inline_math) {
+ mathlevel++;
+ } else {
+ mathlevel--;
+ }
}
}
}
diff --git a/source/luametatex/source/tex/texmaincontrol.c b/source/luametatex/source/tex/texmaincontrol.c
index 5e0bb2f92..f3d91ffe0 100644
--- a/source/luametatex/source/tex/texmaincontrol.c
+++ b/source/luametatex/source/tex/texmaincontrol.c
@@ -1594,8 +1594,7 @@ int tex_main_control(void)
return cur_chr == dump_code;
}
}
- /*tex not reached */
- return 0;
+ return 0; /* unreachable */
}
/*tex
@@ -2242,9 +2241,9 @@ static void tex_aux_run_discretionary(void)
case explicit_discretionary_code:
/*tex |\-| */
if (hyphenation_permitted(hyphenation_mode_par, explicit_hyphenation_mode)) {
+ int c = tex_get_pre_hyphen_char(cur_lang_par);
halfword d = tex_new_disc_node(explicit_discretionary_code);
tex_tail_append(d);
- int c = tex_get_pre_hyphen_char(cur_lang_par);
if (c > 0) {
tex_set_disc_field(d, pre_break_code, tex_new_char_node(glyph_unset_subtype, cur_font_par, c, 1));
}
@@ -2259,10 +2258,10 @@ static void tex_aux_run_discretionary(void)
case mathematics_discretionary_code:
/*tex |-| */
if (hyphenation_permitted(hyphenation_mode_par, automatic_hyphenation_mode)) {
+ halfword c = tex_get_pre_exhyphen_char(cur_lang_par);
halfword d = tex_new_disc_node(automatic_discretionary_code);
tex_tail_append(d);
/*tex As done in hyphenator: */
- halfword c = tex_get_pre_exhyphen_char(cur_lang_par);
if (c <= 0) {
c = ex_hyphen_char_par;
}
@@ -4353,6 +4352,14 @@ static void tex_aux_set_font_property(void)
tex_set_efcode_in_font(fnt, chr, val);
break;
}
+ case font_cf_code:
+ {
+ halfword fnt = tex_scan_font_identifier(NULL);
+ halfword chr = tex_scan_char_number(0);
+ halfword val = tex_scan_int(1, NULL);
+ tex_set_cfcode_in_font(fnt, chr, val);
+ break;
+ }
case font_dimen_code:
{
tex_set_font_dimen();
@@ -5958,7 +5965,7 @@ static void tex_aux_run_show_whatever(void)
int online = 0;
int max = 0;
while (1) {
- switch (tex_scan_character("ocdnaOCDNA", 0, 0, 0)) {
+ switch (tex_scan_character("ocdnaOCDNA", 0, 1, 0)) {
case 'a': case 'A':
if (tex_scan_mandate_keyword("all", 1)) {
max = 1;
diff --git a/source/luametatex/source/tex/texmarks.c b/source/luametatex/source/tex/texmarks.c
index 060c5f579..01e002fbd 100644
--- a/source/luametatex/source/tex/texmarks.c
+++ b/source/luametatex/source/tex/texmarks.c
@@ -67,12 +67,12 @@ void tex_reset_mark(halfword m)
size = m;
}
if (size <= lmt_mark_state.mark_data.maximum) {
- mark_record *tmp = aux_reallocate_array(lmt_mark_state.data, sizeof(mark_record), (size_t) size, 1);
+ mark_record *tmp = aux_reallocate_array(lmt_mark_state.data, sizeof(mark_record), size, 1);
if (tmp) {
lmt_mark_state.data = tmp;
memset(&lmt_mark_state.data[lmt_mark_state.mark_data.top], 0, sizeof(mark_record) * (size - lmt_mark_state.mark_data.top));
lmt_mark_state.mark_data.top = size;
- lmt_mark_state.mark_data.allocated = sizeof(mark_record) * ((size_t) size);
+ lmt_mark_state.mark_data.allocated = sizeof(mark_record) * size;
} else {
tex_overflow_error("marks", size);
}
diff --git a/source/luametatex/source/tex/texmath.c b/source/luametatex/source/tex/texmath.c
index 3f452b1ff..f650704cd 100644
--- a/source/luametatex/source/tex/texmath.c
+++ b/source/luametatex/source/tex/texmath.c
@@ -243,7 +243,6 @@ halfword tex_size_of_style(halfword style)
case script_script_style:
case cramped_script_script_style:
return script_script_size;
- break;
default:
return text_size;
}
@@ -372,7 +371,9 @@ static void tex_aux_print_fam(const char *what, halfword size, halfword fam)
int tex_fam_fnt(int fam, int size)
{
- return (int) sa_get_item_4(lmt_math_state.fam_head, fam + (256 * size)).int_value;
+ sa_tree_item item;
+ sa_get_item_4(lmt_math_state.fam_head, fam + (256 * size), &item);
+ return (int) item.int_value;
}
void tex_def_fam_fnt(int fam, int size, int fnt, int level)
@@ -413,7 +414,7 @@ void tex_def_math_parameter(int style, int param, scaled value, int level, int i
int different = 1;
if (level <= 1) {
if (math_parameter_value_type(param) == math_muglue_parameter) {
- item1 = sa_get_item_8(lmt_math_state.par_head, (param + (math_parameter_max_range * style)), &item2);
+ sa_get_item_8(lmt_math_state.par_head, (param + (math_parameter_max_range * style)), &item1, &item2);
if (item2.int_value == indirect_math_regular && item1.int_value > thick_mu_skip_code) {
if (lmt_node_memory_state.nodesizes[item1.int_value]) {
tex_free_node(item1.int_value, glue_spec_size);
@@ -422,7 +423,7 @@ void tex_def_math_parameter(int style, int param, scaled value, int level, int i
}
} else {
/*tex Less tracing at the cost of a lookup. */
- item1 = sa_get_item_8(lmt_math_state.par_head, (param + (math_parameter_max_range * style)), &item2);
+ sa_get_item_8(lmt_math_state.par_head, (param + (math_parameter_max_range * style)), &item1, &item2);
different = item1.int_value != value || item2.int_value != indirect;
}
// if (different) { // maybe
@@ -440,8 +441,8 @@ void tex_def_math_parameter(int style, int param, scaled value, int level, int i
scaled tex_get_math_parameter(int style, int param, halfword *type)
{
halfword indirect, value;
- sa_tree_item v2;
- sa_tree_item v1 = sa_get_item_8(lmt_math_state.par_head, (param + (math_parameter_max_range * style)), &v2);
+ sa_tree_item v1, v2;
+ sa_get_item_8(lmt_math_state.par_head, (param + (math_parameter_max_range * style)), &v1, &v2);
indirect = v2.int_value == lmt_math_state.par_head->dflt.int_value ? indirect_math_unset : v2.uint_value;
value = v1.int_value;
switch (indirect) {
@@ -662,8 +663,8 @@ scaled tex_get_math_parameter(int style, int param, halfword *type)
int tex_has_math_parameter(int style, int param)
{
- sa_tree_item v2;
- sa_get_item_8(lmt_math_state.par_head, (param + (math_parameter_max_range * style)), &v2);
+ sa_tree_item v1, v2;
+ sa_get_item_8(lmt_math_state.par_head, (param + (math_parameter_max_range * style)), &v1, &v2);
return v2.int_value == lmt_math_state.par_head->dflt.int_value ? indirect_math_unset : v2.uint_value;
}
@@ -675,9 +676,9 @@ static void tex_aux_unsave_math_parameter_data(int gl)
if (item.level > 0) {
int param = item.code % math_parameter_max_range;
int style = item.code / math_parameter_max_range;
- sa_tree_item item1, item2;
if (math_parameter_value_type(param) == math_muglue_parameter) {
- item1 = sa_get_item_8(lmt_math_state.par_head, item.code, &item2);
+ sa_tree_item item1, item2;
+ sa_get_item_8(lmt_math_state.par_head, item.code, &item1, &item2);
if (item2.int_value == indirect_math_regular && item1.int_value > thick_mu_skip_code) {
/* if (tex_valid_node(item1.int_value)) { */
if (lmt_node_memory_state.nodesizes[item1.int_value]) {
@@ -788,13 +789,17 @@ halfword tex_new_sub_box(halfword curbox)
return noad;
}
-quarterword tex_aux_set_math_char(halfword target, mathcodeval *mval, mathdictval *dval)
+static quarterword tex_aux_set_math_char(halfword target, mathcodeval *mval, mathdictval *dval)
{
halfword hmcode = tex_get_hm_code(mval->character_value);
kernel_math_character(target) = mval->character_value;
if (mval->class_value == math_use_current_family_code) {
kernel_math_family(target) = cur_fam_par_in_range ? cur_fam_par : mval->family_value;
node_subtype(target) = ordinary_noad_subtype;
+ } else if (mval->family_value == variable_family_par) {
+ /*tex For CMS chairman MS, so that he can answer a ltx question someplace. */
+ kernel_math_family(target) = cur_fam_par_in_range ? cur_fam_par : mval->family_value;
+ node_subtype(target) = mval->class_value;
} else {
kernel_math_family(target) = mval->family_value;
node_subtype(target) = mval->class_value;
@@ -1121,13 +1126,19 @@ static void tex_aux_display_fence_noad(halfword n, int threshold, int max)
if (noad_depth(n)) {
tex_print_format(", depth %D", noad_depth(n), pt_unit);
}
- if (get_noad_main_class(n) >= 0) {
+ if (fence_top_overshoot(n)) {
+ tex_print_format(", top %D", fence_top_overshoot(n), pt_unit);
+ }
+ if (fence_bottom_overshoot(n)) {
+ tex_print_format(", top %D", fence_bottom_overshoot(n), pt_unit);
+ }
+ if (get_noad_main_class(n) != unset_noad_class) {
tex_print_format(", class %i", get_noad_main_class(n));
}
- if (get_noad_left_class(n) >= 0) {
+ if (get_noad_left_class(n) != unset_noad_class) {
tex_print_format(", leftclass %i", get_noad_left_class(n));
}
- if (get_noad_right_class(n) >= 0) {
+ if (get_noad_right_class(n) != unset_noad_class) {
tex_print_format(", rightclass %i", get_noad_right_class(n));
}
if (noad_source(n) != 0) {
@@ -1976,11 +1987,34 @@ int tex_scan_math_cmd_val(mathcodeval *mval, mathdictval *dval)
return 0;
}
break;
- case letter_cmd:
- case other_char_cmd:
- mval->character_value = cur_chr;
+ case delimiter_number_cmd:
+ switch (cur_chr) {
+ case math_delimiter_code:
+ *mval = tex_scan_delimiter_as_mathchar(tex_mathcode);
+ break;
+ case math_udelimiter_code:
+ *mval = tex_scan_delimiter_as_mathchar(umath_mathcode);
+ break;
+ default:
+ /* no message yet */
+ return 0;
+ }
break;
+ /*tex
+ This is/was an experiment but could work out ambigiuous in some cases so when I bring it
+ back it will be under more strict control. So, for instance a register would make us
+ enter the default branch but a direct number the other case. In the meantiem we no longer
+ use the direct char approach (for delimiters mostly) so we can comment it.
+ */
+ // case letter_cmd:
+ // case other_char_cmd:
+ // mval->character_value = cur_chr;
+ // break;
default:
+ /*tex
+ We could do a fast |tex_scan_something_internal| here but this branch is not that
+ critical.
+ */
{
halfword n = 0;
tex_back_input(cur_tok);
@@ -2718,7 +2752,7 @@ void tex_run_math_accent(void)
case math_uaccent_code:
/*tex |\Umathaccent| */
while (1) {
- switch (tex_scan_character("ansfASFN", 0, 0, 0)) {
+ switch (tex_scan_character("ansfASFN", 0, 1, 0)) {
case 'a': case 'A':
if (tex_scan_mandate_keyword("attr", 1)) {
attrlist = tex_scan_attribute(attrlist);
@@ -3707,8 +3741,10 @@ void tex_finish_math_group(void)
void tex_run_math_fence(void)
{
- halfword ht = 0;
- halfword dp = 0;
+ scaled ht = 0;
+ scaled dp = 0;
+ scaled top = 0;
+ scaled bottom = 0;
halfword options = 0;
halfword mainclass = unset_noad_class;
halfword leftclass = unset_noad_class;
@@ -3738,19 +3774,9 @@ void tex_run_math_fence(void)
}
while (1) {
/* todo: break down */
- switch (tex_scan_character("hdanlevpcrsuHDANLEVPCRSU", 0, 1, 0)) {
+ switch (tex_scan_character("hdanlevpcrsutbHDANLEVPCRSUTB", 0, 1, 0)) {
case 0:
goto CHECK_PAIRING;
- case 'h': case 'H':
- if (tex_scan_mandate_keyword("height", 1)) {
- ht = tex_scan_dimen(0, 0, 0, 0, NULL);
- }
- break;
- case 'd': case 'D':
- if (tex_scan_mandate_keyword("depth", 1)) {
- dp = tex_scan_dimen(0, 0, 0, 0, NULL);
- }
- break;
case 'a': case 'A':
switch (tex_scan_character("uxtUXT", 0, 0, 0)) {
case 'u': case 'U':
@@ -3773,6 +3799,21 @@ void tex_run_math_fence(void)
goto CHECK_PAIRING;
}
break;
+ case 'b': case 'B':
+ if (tex_scan_mandate_keyword("bottom", 1)) {
+ bottom = tex_scan_dimen(0, 0, 0, 0, NULL);
+ }
+ break;
+ case 'd': case 'D':
+ if (tex_scan_mandate_keyword("depth", 1)) {
+ dp = tex_scan_dimen(0, 0, 0, 0, NULL);
+ }
+ break;
+ case 'h': case 'H':
+ if (tex_scan_mandate_keyword("height", 1)) {
+ ht = tex_scan_dimen(0, 0, 0, 0, NULL);
+ }
+ break;
case 'n': case 'N':
switch (tex_scan_character("oO", 0, 0, 0)) {
case 'o': case 'O':
@@ -3863,6 +3904,11 @@ void tex_run_math_fence(void)
source = tex_scan_int(0, NULL);
}
break;
+ case 't': case 'T':
+ if (tex_scan_mandate_keyword("top", 1)) {
+ top = tex_scan_dimen(0, 0, 0, 0, NULL);
+ }
+ break;
default:
goto CHECK_PAIRING;
}
@@ -3930,6 +3976,9 @@ void tex_run_math_fence(void)
}
noad_italic(fence) = 0;
noad_source(fence) = source;
+ /* */
+ fence_top_overshoot(fence) = top;
+ fence_bottom_overshoot(fence) = bottom;
/*tex
By setting this here, we can get rid of the hard coded values in |mlist_to_hlist| which
sort of interfere (or at least confuse) things there. When set, the |leftclass| and
@@ -4643,6 +4692,27 @@ static void tex_aux_define_dis_math_parameters(int size, int param, scaled value
}
}
+/*tex
+ In principle we could save some storage in the format file with:
+
+ \starttyping
+ static void tex_aux_define_all_math_parameters(int size, int param, scaled value, int level)
+ {
+ tex_def_math_parameter(all_math_styles, param, value, level, indirect_math_regular);
+ }
+ \stoptyping
+
+ and then do this (we also need to move |all_math_styles| up in the enum to keep ranges compact):
+
+ \starttyping
+ if (! sa_get_item_8(lmt_math_state.par_head, (param + (math_parameter_max_range * style)), &item1, &item2)) {
+ sa_get_item_8(lmt_math_state.par_head, (param + (math_parameter_max_range * all_math_styles)), &item1, &item2);
+ }
+ \stoptyping
+
+ but in practice we actually get a bit larger file.
+*/
+
static void tex_aux_define_all_math_parameters(int size, int param, scaled value, int level)
{
switch (size) {
@@ -4756,7 +4826,7 @@ inline static scaled tex_aux_get_font_math_quantity(scaled scale, halfword v)
/*tex
The next function is called when we define a family, but first we define a few helpers
- for identifying traditional math fonts. Watch the hard codes family check!
+ for identifying traditional math fonts. Watch the hard codes family check (gone now)!
*/
void tex_fixup_math_parameters(int fam, int size, int f, int level)
diff --git a/source/luametatex/source/tex/texmath.h b/source/luametatex/source/tex/texmath.h
index cc7aa7e7f..b97b1e8f2 100644
--- a/source/luametatex/source/tex/texmath.h
+++ b/source/luametatex/source/tex/texmath.h
@@ -663,20 +663,22 @@ typedef enum math_control_codes {
math_control_accent_skew_apply = 0x000040,
math_control_apply_ordinary_kern_pair = 0x000080,
math_control_apply_vertical_italic_kern = 0x000100,
- math_control_apply_ordinary_italic_kern = 0x000200,
- math_control_apply_char_italic_kern = 0x000400, /* traditional */
- math_control_rebox_char_italic_kern = 0x000800, /* traditional */
- math_control_apply_boxed_italic_kern = 0x001000,
- math_control_staircase_kern = 0x002000,
- math_control_apply_text_italic_kern = 0x004000,
- math_control_check_text_italic_kern = 0x008000,
- math_control_check_space_italic_kern = 0x010000,
- math_control_apply_script_italic_kern = 0x020000,
- math_control_analyze_script_nucleus_char = 0x040000,
- math_control_analyze_script_nucleus_list = 0x080000,
- math_control_analyze_script_nucleus_box = 0x100000,
- math_control_accent_top_skew_with_offset = 0x200000,
- math_control_ignore_kern_dimensions = 0x400000, /* for bad fonts (like xits fence depths) */
+ math_control_apply_ordinary_italic_kern = 0x0000200,
+ math_control_apply_char_italic_kern = 0x0000400, /* traditional */
+ math_control_rebox_char_italic_kern = 0x0000800, /* traditional */
+ math_control_apply_boxed_italic_kern = 0x0001000,
+ math_control_staircase_kern = 0x0002000,
+ math_control_apply_text_italic_kern = 0x0004000,
+ math_control_check_text_italic_kern = 0x0008000,
+ math_control_check_space_italic_kern = 0x0010000,
+ math_control_apply_script_italic_kern = 0x0020000,
+ math_control_analyze_script_nucleus_char = 0x0040000,
+ math_control_analyze_script_nucleus_list = 0x0080000,
+ math_control_analyze_script_nucleus_box = 0x0100000,
+ math_control_accent_top_skew_with_offset = 0x0200000,
+ math_control_ignore_kern_dimensions = 0x0400000, /* for bad fonts (like xits fence depths) */
+ math_control_ignore_flat_accents = 0x0800000,
+ math_control_extend_accents = 0x1000000,
} math_control_codes;
/*tex This is what we use for \OPENTYPE\ in \CONTEXT: */
diff --git a/source/luametatex/source/tex/texmathcodes.c b/source/luametatex/source/tex/texmathcodes.c
index 545013264..f19cde91c 100644
--- a/source/luametatex/source/tex/texmathcodes.c
+++ b/source/luametatex/source/tex/texmathcodes.c
@@ -164,8 +164,9 @@ void tex_set_math_code(int n, mathcodeval v, int level)
mathcodeval tex_get_math_code(int n)
{
- sa_tree_item item = sa_get_item_4(lmt_mathcode_state.mathcode_head, n);
+ sa_tree_item item;
mathcodeval m = { 0, 0, 0 };
+ sa_get_item_4(lmt_mathcode_state.mathcode_head, n, &item);
if (item.uint_value == MATHCODEDEFAULT) {
m.character_value = n;
} else if (item.uint_value == MATHCODEACTIVE) {
@@ -267,9 +268,9 @@ delcodeval tex_no_del_code(void)
delcodeval tex_get_del_code(int n)
{
- sa_tree_item v2;
- sa_tree_item v1 = sa_get_item_8(lmt_mathcode_state.delcode_head, n, &v2);
+ sa_tree_item v1, v2;
delcodeval d = { { 0, -1, 0 }, { 0, 0, 0} };
+ sa_get_item_8(lmt_mathcode_state.delcode_head, n, &v1, &v2);
if (v1.uint_value != DELCODEDEFAULT) {
d.small.class_value = (short) v1.math_code_value.class_value;
d.small.family_value = (short) v1.math_code_value.family_value;
diff --git a/source/luametatex/source/tex/texmlist.c b/source/luametatex/source/tex/texmlist.c
index ddc3f0a6e..0ea1f82e8 100644
--- a/source/luametatex/source/tex/texmlist.c
+++ b/source/luametatex/source/tex/texmlist.c
@@ -178,7 +178,8 @@ static void tex_aux_prepend_hkern_to_box_list(halfword q, scaled delta, halfword
\startitem
|FlattenedAccentBaseHeight|: This is based on the |flac| |GSUB| feature. It would not
be hard to support that, but proper math accent placements cf.\ |MATH| needs support
- for |MathTopAccentAttachment| table to be implemented first.
+ for |MathTopAccentAttachment| table to be implemented first. We actually do support
+ it in \LUAMETATEX.
\stopitem
\stopitemize
@@ -188,10 +189,10 @@ static void tex_aux_prepend_hkern_to_box_list(halfword q, scaled delta, halfword
Occasionally I visit this file and make some variables more verbose.
- In the meantime some experimental and in the meantime obsolete code has been removed but it can
- be found in the development repository if really needed. It makes no sense to keep code around
- that has been replaced or improved otherwise. Some code we keep commented for a while before it
- is flushed out.
+ In the meantime some experimental and obsolete code has been removed but it can be found in
+ the development repository if really needed. It makes no sense to keep code around that has
+ been replaced or improved otherwise. Some code we keep commented for a while before it is
+ flushed out.
*/
@@ -297,7 +298,7 @@ inline static void tex_aux_make_style(halfword current, halfword *current_style,
}
tex_aux_set_current_math_size(style);
if (current_mu) {
- *current_mu = scaledround(tex_get_math_quad_style(style) / 18.0);
+ *current_mu = scaledround((double) tex_get_math_quad_style(style) / 18.0);
}
}
break;
@@ -311,7 +312,7 @@ void tex_set_math_text_font(halfword style, int usetextfont)
halfword scale = tex_get_math_font_scale(font, size);
switch (usetextfont) {
case math_atom_text_font_option:
- scale = scaledround((double) scale * lmt_font_state.fonts[font]->size / lmt_font_state.fonts[cur_font_par]->size);
+ scale = scaledround((double) scale * (double) lmt_font_state.fonts[font]->size / (double) lmt_font_state.fonts[cur_font_par]->size);
break;
case math_atom_math_font_option:
update_tex_font(0, font);
@@ -858,11 +859,13 @@ static halfword tex_aux_char_box(halfword fnt, int chr, halfword att, scaled *ic
} else if (ic) {
*ic = 0;
}
- if (target && whd.wd < target && tex_char_has_tag_from_font(fnt, chr, extend_last_tag)) {
+ if (target && whd.wd > 0 && whd.wd < target && tex_aux_math_engine_control(fnt, math_control_extend_accents) && tex_char_has_tag_from_font(fnt, chr, extend_last_tag)) {
scaled margin = tex_get_math_x_parameter_default(style, math_parameter_accent_extend_margin, 0);
scaled amount = target - 2 * margin;
- glyph_x_scale(glyph) = lround((double) glyph_x_scale(glyph) * amount/whd.wd);
- glyph_x_offset(glyph) = (whd.wd - amount)/2;
+ if (amount > 0) {
+ glyph_x_scale(glyph) = lround((double) glyph_x_scale(glyph) * amount/whd.wd);
+ glyph_x_offset(glyph) = (whd.wd - amount)/2;
+ }
}
return box;
}
@@ -1016,7 +1019,6 @@ halfword tex_make_extensible(halfword fnt, halfword chr, scaled target, scaled m
scaled max_natural = 0;
/*tex amount of possible shrink in the stack */
scaled max_shrink = 0;
- extinfo *extensible = NULL;
scaled overlap;
/*tex a temporary counter number of extensible pieces */
int pieces = 0;
@@ -1026,15 +1028,10 @@ halfword tex_make_extensible(halfword fnt, halfword chr, scaled target, scaled m
int with_extenders = -1;
int n_of_extenders = 0;
int n_of_normal = 0;
+ extinfo *extensible = tex_char_extensible_recipe_from_font(fnt, chr);
if (minoverlap < 0) {
minoverlap = 0;
}
- /* chr = math_char_exists(fnt, chr, math_state.size); */
- if (horizontal) {
- extensible = tex_char_horizontal_parts_from_font(fnt, chr);
- } else {
- extensible = tex_char_vertical_parts_from_font(fnt, chr);
- }
tex_attach_attribute_list_attribute(box, att);
for (extinfo *e = extensible; e; e = e->next) {
if (! tex_char_exists(fnt, e->glyph)) {
@@ -1135,13 +1132,13 @@ halfword tex_make_extensible(halfword fnt, halfword chr, scaled target, scaled m
if (overlap < initial) {
initial = overlap;
}
- if (advance == 0) {
- /*tex for tfm fonts (so no need for scaling) */
- advance = tex_aux_math_x_size_scaled(fnt, tex_char_width_from_font(fnt, e->glyph), size); /* todo: combine */
+ // if (advance == 0) {
+ // /*tex for tfm fonts (so no need for scaling) */
+ // advance = tex_aux_math_x_size_scaled(fnt, tex_char_width_from_font(fnt, e->glyph), size); /* todo: combine */
if (advance <= 0) {
tex_formatted_error("fonts", "bad horizontal extensible character %i in font %i", chr, fnt);
}
- }
+ // }
max_natural += advance - initial;
overlap = tex_aux_math_x_size_scaled(fnt, e->end_overlap, size);
} else {
@@ -1155,13 +1152,13 @@ halfword tex_make_extensible(halfword fnt, halfword chr, scaled target, scaled m
if (overlap < initial) {
initial = overlap;
}
- if (advance == 0) {
- /*tex for tfm fonts (so no need for scaling) */
- advance = tex_aux_math_x_size_scaled(fnt, tex_char_width_from_font(fnt, e->glyph), size); /* todo: combine */
+ // if (advance == 0) {
+ // /*tex for tfm fonts (so no need for scaling) */
+ // advance = tex_aux_math_x_size_scaled(fnt, tex_char_width_from_font(fnt, e->glyph), size); /* todo: combine */
if (advance <= 0) {
tex_formatted_error("fonts", "bad horizontal extensible character %i in font %i", chr, fnt);
}
- }
+ // }
max_natural += advance - initial;
overlap = tex_aux_math_x_size_scaled(fnt, e->end_overlap, size);
pieces--;
@@ -1179,12 +1176,12 @@ halfword tex_make_extensible(halfword fnt, halfword chr, scaled target, scaled m
if (overlap < initial) {
initial = overlap;
}
- if (advance == 0) {
- advance = tex_aux_math_y_size_scaled(fnt, tex_char_total_from_font(fnt, e->glyph), size); /* todo: combine */
+ // if (advance == 0) {
+ // advance = tex_aux_math_y_size_scaled(fnt, tex_char_total_from_font(fnt, e->glyph), size); /* todo: combine */
if (advance <= 0) {
tex_formatted_error("fonts", "bad vertical extensible character %i in font %i", chr, fnt);
}
- }
+ // }
max_natural += advance - initial;
overlap = tex_aux_math_y_size_scaled(fnt, e->end_overlap, size);
} else {
@@ -1198,12 +1195,12 @@ halfword tex_make_extensible(halfword fnt, halfword chr, scaled target, scaled m
if (overlap < initial) {
initial = overlap;
}
- if (advance == 0) {
- advance = tex_aux_math_y_size_scaled(fnt, tex_char_total_from_font(fnt, e->glyph), size); /* todo: combine */
+ // if (advance == 0) {
+ // advance = tex_aux_math_y_size_scaled(fnt, tex_char_total_from_font(fnt, e->glyph), size); /* todo: combine */
if (advance <= 0) {
tex_formatted_error("fonts", "bad vertical extensible character %i in font %i", chr, fnt);
}
- }
+ // }
max_natural += advance - initial;
overlap = tex_aux_math_y_size_scaled(fnt, e->end_overlap, size);
pieces--;
@@ -1263,15 +1260,37 @@ halfword tex_make_extensible(halfword fnt, halfword chr, scaled target, scaled m
}
/*tex Set glue so as to stretch the connections if needed. */
if (target > max_natural && max_shrink > 0) {
- scaled delta = target - max_natural;
- /*tex Don't stretch more than |s_max|. */
- if (delta > max_shrink) {
- delta = max_shrink;
- }
- box_glue_order(box) = normal_glue_order;
- box_glue_sign(box) = stretching_glue_sign;
- box_glue_set(box) = (glueratio) (delta / (glueratio) max_shrink);
- max_natural += delta;
+ // if (1) {
+ // halfword b;
+ // if (horizontal) {
+ // b = tex_hpack(box_list(box), target, packing_exactly, (singleword) math_direction_par, holding_none_option);
+ // } else {
+ // b = tex_vpack(box_list(box), target, packing_exactly, max_dimen, (singleword) math_direction_par, holding_none_option);
+ // }
+ // box_glue_order(box) = box_glue_order(b);
+ // box_glue_sign(box) = box_glue_sign(b);
+ // box_glue_set(box) = box_glue_set(b);
+ // box_list(b) = null;
+ // tex_flush_node(b);
+ // max_natural = target;
+ // } else {
+ scaled delta = target - max_natural;
+ /*tex Don't stretch more than |s_max|. */
+ if (delta > max_shrink) {
+ if (tracing_math_par >= 1) {
+ tex_begin_diagnostic();
+ tex_print_format("[math: extensible clipped, target %D, natural %D, shrink %D, clip %D]",
+ target, pt_unit, max_natural, pt_unit, max_shrink, pt_unit, delta - max_shrink, pt_unit
+ );
+ tex_end_diagnostic();
+ }
+ delta = max_shrink;
+ }
+ box_glue_order(box) = normal_glue_order;
+ box_glue_sign(box) = stretching_glue_sign;
+ box_glue_set(box) = (glueratio) (delta / (glueratio) max_shrink);
+ max_natural += delta;
+ // }
}
if (horizontal) {
box_width(box) = max_natural;
@@ -1402,7 +1421,7 @@ static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int
goto FOUND;
}
}
- if (tex_char_has_tag_from_font(curfnt, curchr, extension_tag)) {
+ if (tex_char_has_tag_from_font(curfnt, curchr, extensible_tag)) {
fnt = curfnt;
chr = curchr;
do_parts = 1;
@@ -1413,7 +1432,7 @@ static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int
} else if (tex_char_has_tag_from_font(curfnt, curchr, list_tag)) {
prvfnt = curfnt;
prvchr = curchr;
- curchr = tex_char_remainder_from_font(curfnt, curchr);
+ curchr = tex_char_next_from_font(curfnt, curchr);
goto CONTINUE;
}
}
@@ -1444,17 +1463,14 @@ static halfword tex_aux_make_delimiter(halfword target, halfword delimiter, int
When the following code is executed, |do_parts| will be true if a built-up symbol is
supposed to be returned.
*/
- extinfo *ext = NULL;
- if (do_parts) {
- /* tex_char_process(fnt, chr); */ /* in case we realloc */
- ext = flat ? tex_char_horizontal_parts_from_font(fnt, chr) : tex_char_vertical_parts_from_font(fnt, chr);
- }
+ extinfo *ext = do_parts ? tex_char_extensible_recipe_from_font(fnt, chr) : NULL;
if (ext) {
scaled minoverlap = flat ? tex_get_math_x_parameter_default(style, math_parameter_connector_overlap_min, 0) : tex_get_math_y_parameter_default(style, math_parameter_connector_overlap_min, 0);;
result = tex_aux_get_delimiter_box(fnt, chr, targetsize, minoverlap, flat, att);
if (delta) {
+ /*tex Not yet done: horizontal italics. */
if (tex_aux_math_engine_control(fnt, math_control_apply_vertical_italic_kern)) {
- *delta = tex_aux_math_x_size_scaled(fnt, tex_char_vertical_italic_from_font(fnt, nxtchr), size);
+ *delta = tex_aux_math_x_size_scaled(fnt, tex_char_extensible_italic_from_font(fnt, nxtchr), size);
} else {
*delta = tex_aux_math_x_size_scaled(fnt, tex_char_italic_from_font(fnt, nxtchr), size);
}
@@ -2303,6 +2319,8 @@ static void tex_aux_make_root_radical(halfword target, int style, int size, kern
halfword companion = leftdelimiter ? rightdelimiter : null;
halfword radical = null;
delimiterextremes extremes = { .tfont = null_font, .tchar = 0, .bfont = null_font, .bchar = 0, .height = 0, .depth = 0 };
+ scaled innerx = INT_MIN;
+ scaled innery = INT_MIN;
noad_new_hlist(target) = null;
/*tex
We can take the rule width from the fam/style of the delimiter or use the most recent math
@@ -2321,6 +2339,15 @@ static void tex_aux_make_root_radical(halfword target, int style, int size, kern
theta = tex_get_math_y_parameter_checked(style, math_parameter_fraction_rule); /* a bit weird this one */
}
delimiter = tex_aux_make_delimiter(target, delimiter, size, box_total(nucleus) + clearance + theta, 0, style, 1, NULL, NULL, 0, has_noad_option_nooverflow(target), &extremes, 0);
+ if (radical_degree(target)) {
+ if (tex_char_has_tag_from_font(extremes.bfont, extremes.bchar, inner_left_tag)) {
+ innerx = tex_char_inner_x_offset_from_font(extremes.bfont, extremes.bchar);
+ innery = tex_char_inner_y_offset_from_font(extremes.bfont, extremes.bchar);
+ } else if (tex_char_has_tag_from_font(extremes.tfont, extremes.tchar, inner_left_tag)) {
+ innerx = tex_char_inner_x_offset_from_font(extremes.tfont, extremes.tchar);
+ innery = tex_char_inner_y_offset_from_font(extremes.tfont, extremes.tchar);
+ }
+ }
if (companion) {
/*tex For now we assume symmetry and same height and depth! */
companion = tex_aux_make_delimiter(target, companion, size, box_total(nucleus) + clearance + theta, 0, style, 1, NULL, NULL, 0, has_noad_option_nooverflow(target), &extremes, 0);
@@ -2385,6 +2412,10 @@ static void tex_aux_make_root_radical(halfword target, int style, int size, kern
scaled before = tex_get_math_x_parameter_checked(style, math_parameter_radical_degree_before);
scaled after = tex_get_math_x_parameter_checked(style, math_parameter_radical_degree_after);
scaled raise = tex_get_math_parameter_checked(style, math_parameter_radical_degree_raise);
+ if (innerx != INT_MIN) {
+ tex_aux_append_hkern_to_box_list(degree, innerx, horizontal_math_kern_subtype, "bad degree");
+ width += innerx;
+ }
if (-after > width) {
before += -after - width;
}
@@ -2396,7 +2427,11 @@ static void tex_aux_make_root_radical(halfword target, int style, int size, kern
} else {
nucleus = radical;
}
- box_shift_amount(degree) = - (tex_xn_over_d(total, raise, 100) - box_depth(radical) - box_shift_amount(radical));
+ if (innery != INT_MIN) {
+ box_shift_amount(degree) = - innery + box_depth(radical) + box_shift_amount(radical);
+ } else {
+ box_shift_amount(degree) = - (tex_xn_over_d(total, raise, 100) - box_depth(radical) - box_shift_amount(radical));
+ }
tex_couple_nodes(degree, nucleus);
if (before) {
halfword kern = tex_new_kern_node(before, horizontal_math_kern_subtype);
@@ -2876,8 +2911,8 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal
target = tex_xn_over_d(target, fraction, 1000);
}
while (1) {
- if (tex_char_has_tag_from_font(accentfnt, accentchr, extension_tag)) {
- extended = tex_char_horizontal_parts_from_font(accentfnt, accentchr);
+ if (tex_char_has_tag_from_font(accentfnt, accentchr, extensible_tag)) {
+ extended = tex_char_extensible_recipe_from_font(accentfnt, accentchr);
}
if (extended) {
/*tex
@@ -2891,19 +2926,19 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal
} else if (! tex_char_has_tag_from_font(accentfnt, accentchr, list_tag)) {
break;
} else {
- halfword remainder = tex_char_remainder_from_font(accentfnt, accentchr);
- if (! tex_char_exists(accentfnt, remainder)) {
+ halfword next = tex_char_next_from_font(accentfnt, accentchr);
+ if (! tex_char_exists(accentfnt, next)) {
break;
} else if (flags & overlay_accent_code) {
- if (tex_aux_math_y_size_scaled(accentfnt, tex_char_height_from_font(accentfnt, remainder), size) > target) {
+ if (tex_aux_math_y_size_scaled(accentfnt, tex_char_height_from_font(accentfnt, next), size) > target) {
break;
}
} else {
- if (tex_aux_math_x_size_scaled(accentfnt, tex_char_width_from_font(accentfnt, remainder), size) > target) {
+ if (tex_aux_math_x_size_scaled(accentfnt, tex_char_width_from_font(accentfnt, next), size) > target) {
break;
}
}
- accentchr = remainder;
+ accentchr = next;
}
}
/*tex
@@ -2914,24 +2949,23 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal
/*tex Italic gets added to width for traditional fonts (no italic anyway): */
accent = tex_aux_char_box(accentfnt, accentchr, attrlist, NULL, glyph_math_accent_subtype, basewidth, style); // usedwidth
}
- if (accenttotal) {
- *accenttotal = box_total(accent);
- }
if (flags & top_accent_code) {
scaled b = tex_get_math_y_parameter(style, math_parameter_accent_base_height);
- scaled f = tex_get_math_y_parameter(style, math_parameter_flattened_accent_base_height);
scaled u = tex_get_math_y_parameter(style, stretch ? math_parameter_flattened_accent_top_shift_up : math_parameter_accent_top_shift_up);
- if (f != undefined_math_parameter && baseheight > f) {
- halfword flatchr = tex_char_flat_accent_from_font(accentfnt, accentchr);
- if (flatchr != INT_MIN && flatchr != accentchr) {
- tex_flush_node(accent);
- accent = tex_aux_char_box(accentfnt, flatchr, attrlist, NULL, glyph_math_accent_subtype, usedwidth, style);
- if (tracing_math_par >= 2) {
- tex_begin_diagnostic();
- tex_print_format("[math: flattening accent, old %x, new %x]", accentchr, flatchr);
- tex_end_diagnostic();
+ if (! tex_aux_math_engine_control(accentfnt, math_control_ignore_flat_accents)) {
+ scaled f = tex_get_math_y_parameter(style, math_parameter_flattened_accent_base_height);
+ if (f != undefined_math_parameter && baseheight > f) {
+ halfword flatchr = tex_char_flat_accent_from_font(accentfnt, accentchr);
+ if (flatchr != INT_MIN && flatchr != accentchr) {
+ tex_flush_node(accent);
+ accent = tex_aux_char_box(accentfnt, flatchr, attrlist, NULL, glyph_math_accent_subtype, usedwidth, style);
+ if (tracing_math_par >= 2) {
+ tex_begin_diagnostic();
+ tex_print_format("[math: flattening accent, old %x, new %x]", accentchr, flatchr);
+ tex_end_diagnostic();
+ }
+ accentchr = flatchr;
}
- accentchr = flatchr;
}
}
if (b != undefined_math_parameter) {
@@ -2956,6 +2990,9 @@ static void tex_aux_do_make_math_accent(halfword target, halfword accentfnt, hal
/*tex Center the accent vertically around base: */
delta = tex_half_scaled(box_total(accent) + box_total(base));
}
+ if (accenttotal) {
+ *accenttotal = box_total(accent);
+ }
if (node_type(nucleus) != math_char_node) {
/*tex We have a molecule, not a simple atom. */
} else if (noad_has_following_scripts(target)) {
@@ -3151,11 +3188,11 @@ static void tex_aux_wrap_fraction_result(halfword target, int style, int size, h
halfword left = null;
halfword right = null;
halfword delta = tex_get_math_y_parameter(style, math_parameter_fraction_del_size);
+ delimiterextremes extremes = { .tfont = null_font, .tchar = 0, .bfont = null_font, .bchar = 0, .height = 0, .depth = 0 };
if (delta == undefined_math_parameter) {
delta = tex_aux_get_delimiter_height(box_height(fraction), box_depth(fraction), 1, size, style);
}
/*tex Watch out: there can be empty delimiter boxes but with width. */
- delimiterextremes extremes = { .tfont = null_font, .tchar = 0, .bfont = null_font, .bchar = 0, .height = 0, .depth = 0 };
left = tex_aux_make_delimiter(target, left_delimiter, size, delta, 0, style, 1, NULL, NULL, 0, has_noad_option_nooverflow(target), NULL, 0);
right = tex_aux_make_delimiter(target, right_delimiter, size, delta, 0, style, 1, NULL, NULL, 0, has_noad_option_nooverflow(target), &extremes, 0);
if (kerns && extremes.tfont) {
@@ -3895,9 +3932,9 @@ static scaled tex_aux_op_wrapup(halfword target, int style, int size, int italic
}
*/
while (tex_char_has_tag_from_font(fnt, chr, list_tag) && tex_char_total_from_font(fnt, chr) < opsize) {
- halfword rem = tex_char_remainder_from_font(fnt, chr);
- if (chr != rem && tex_char_exists(fnt, rem)) {
- chr = rem;
+ halfword next = tex_char_next_from_font(fnt, chr);
+ if (chr != next && tex_char_exists(fnt, next)) {
+ chr = next;
kernel_math_character(noad_nucleus(target)) = chr;
} else {
break;
@@ -4054,11 +4091,11 @@ static halfword tex_aux_check_ord(halfword current, halfword size, halfword next
}
case math_char_node:
{
+ halfword curchr = null;
+ halfword curfnt = null;
if (! next) {
next = node_next(current);
}
- halfword curchr = null;
- halfword curfnt = null;
tex_aux_fetch(nucleus, "ordinal", &curfnt, &curchr);
if (curfnt && curchr) {
halfword kern = 0;
@@ -4439,7 +4476,6 @@ static scaled tex_aux_math_kern_at(halfword fnt, int chr, int side, int value)
return tex_char_top_left_kern_from_font(fnt, chr);
case bottom_left_kern:
return tex_char_bottom_left_kern_from_font(fnt, chr);
- break;
case top_right_kern:
return tex_char_top_right_kern_from_font(fnt, chr);
case bottom_right_kern:
@@ -5336,6 +5372,22 @@ static void tex_aux_make_scripts(halfword target, halfword kernel, scaled italic
*/
+// static inline int tex_aux_is_extensible(halfword result)
+// {
+// if (result) {
+// switch (node_type(result)) {
+// case hlist_node:
+// case vlist_node:
+// switch (node_subtype(result)) {
+// case math_h_delimiter_list:
+// case math_v_delimiter_list:
+// return 1;
+// }
+// }
+// }
+// return 0;
+// }
+
static halfword tex_aux_make_left_right(halfword target, int style, scaled max_d, scaled max_h, int size, delimiterextremes *extremes)
{
halfword tmp;
@@ -5347,6 +5399,8 @@ static halfword tex_aux_make_left_right(halfword target, int style, scaled max_d
scaled height = tex_aux_math_given_y_scaled(noad_height(target));
scaled depth = tex_aux_math_given_y_scaled(noad_depth(target));
int leftoperator = node_type(target) == fence_noad && node_subtype(target) == left_operator_side;
+ max_h += fence_top_overshoot(target);
+ max_d += fence_bottom_overshoot(target);
if (extremes) {
extremes->tfont = null_font;
extremes->bfont = null_font;
@@ -5365,6 +5419,15 @@ static halfword tex_aux_make_left_right(halfword target, int style, scaled max_d
/*tex
Beware, a stacked delimiter has a shift but no corrected height/depth (yet).
*/
+/* or do we need has_noad_option_check(target) */
+if (! stack && has_noad_option_exact(target)) {
+ if (extremes && extremes->height < height) {
+ height = extremes->height;
+ }
+ if (extremes && extremes->depth < depth) {
+ depth = extremes->depth;
+ }
+}
if (stack) {
box_shift_amount(tmp) = depth;
}
@@ -5373,10 +5436,15 @@ static halfword tex_aux_make_left_right(halfword target, int style, scaled max_d
depth = box_depth(tmp) + box_shift_amount(tmp);
}
if (has_noad_option_axis(target)) {
- halfword axis = tex_aux_math_axis(size);
- height += axis;
- depth -= axis;
- box_shift_amount(tmp) -= axis;
+ // if (has_noad_option_noaxis(target) && tex_aux_is_extensible(tmp)) {
+ if (has_noad_option_noaxis(target) && stack) {
+ /*tex A sort of special case: see sized integrals in ctx examples. */
+ } else {
+ halfword axis = tex_aux_math_axis(size);
+ height += axis;
+ depth -= axis;
+ box_shift_amount(tmp) -= axis;
+ }
}
lst = tex_new_node(hlist_node, 0);
tex_attach_attribute_list_copy(lst, target);
@@ -5392,7 +5460,7 @@ static halfword tex_aux_make_left_right(halfword target, int style, scaled max_d
if (leftoperator && has_noad_option_auto(target)) {
/*tex Todo: option for skipping this. */
if (style < text_style) {
- scaled s = scaledround(tex_get_math_parameter(style, math_parameter_operator_size, NULL));
+ scaled s = scaledround((double) tex_get_math_parameter(style, math_parameter_operator_size, NULL));
if (s > max_h + max_d) {
max_h = scaledround(s / 2.0);
max_d = max_h;
@@ -5703,6 +5771,7 @@ static halfword tex_aux_check_nucleus_complexity(halfword target, scaled *italic
halfword fnt = null;
if (tex_aux_fetch(nucleus, "(text) char", &fnt, &chr)) {
/*tex We make a math glyph from an ordinary one. */
+ halfword glyph;
quarterword subtype = 0;
switch (node_subtype(nucleus)) {
case ordinary_noad_subtype: subtype = glyph_math_ordinary_subtype; break;
@@ -5736,7 +5805,7 @@ static halfword tex_aux_check_nucleus_complexity(halfword target, scaled *italic
break;
}
- halfword glyph = tex_aux_new_math_glyph(fnt, chr, subtype);
+ glyph = tex_aux_new_math_glyph(fnt, chr, subtype);
tex_attach_attribute_list_copy(glyph, nucleus);
if (node_type(nucleus) == math_char_node) {
glyph_properties(glyph) = kernel_math_properties(nucleus);
@@ -6050,7 +6119,7 @@ static halfword tex_aux_unroll_noad(halfword tail, halfword l, quarterword s)
while (l) {
halfword n = node_next(l);
node_next(l) = null;
- if (node_type(l) == hlist_node && (s < 0 || node_subtype(l) == s) && ! box_source_anchor(l)) {
+ if (node_type(l) == hlist_node && (node_subtype(l) == s) && ! box_source_anchor(l)) {
if (box_list(l)) {
tex_couple_nodes(tail, box_list(l));
tail = tex_tail_of_node_list(tail);
diff --git a/source/luametatex/source/tex/texnodes.c b/source/luametatex/source/tex/texnodes.c
index c627a07cb..0134eb419 100644
--- a/source/luametatex/source/tex/texnodes.c
+++ b/source/luametatex/source/tex/texnodes.c
@@ -2451,7 +2451,7 @@ const char *tex_aux_subtype_str(halfword n)
*/
-void tex_print_specnode(halfword v, int unit)
+static void tex_print_specnode(halfword v, int unit) /* for now local */
{
if (tracing_nodes_par > 2) {
tex_print_format("<%i>", v);
@@ -2766,7 +2766,7 @@ void tex_show_node_list(halfword p, int threshold, int max)
if (tex_par_state_is_set(p, par_pre_tolerance_code) ) { v = par_pre_tolerance(p) ; if (v) { tex_print_str(", pretolerance "); tex_print_int (v); } }
if (tex_par_state_is_set(p, par_tolerance_code) ) { v = par_tolerance(p) ; if (v) { tex_print_str(", tolerance "); tex_print_int (v); } }
if (tex_par_state_is_set(p, par_looseness_code) ) { v = par_looseness(p) ; if (v) { tex_print_str(", looseness "); tex_print_int (v); } }
- if (tex_par_state_is_set(p, par_adjust_spacing_code) ) { v = par_adjust_spacing(p) ; if (v) { tex_print_str(", adjustaspacing "); tex_print_int (v); } }
+ if (tex_par_state_is_set(p, par_adjust_spacing_code) ) { v = par_adjust_spacing(p) ; if (v) { tex_print_str(", adjustspacing "); tex_print_int (v); } }
if (tex_par_state_is_set(p, par_adj_demerits_code) ) { v = par_adj_demerits(p) ; if (v) { tex_print_str(", adjdemerits "); tex_print_int (v); } }
if (tex_par_state_is_set(p, par_protrude_chars_code) ) { v = par_protrude_chars(p) ; if (v) { tex_print_str(", protrudechars "); tex_print_int (v); } }
if (tex_par_state_is_set(p, par_line_penalty_code) ) { v = par_line_penalty(p) ; if (v) { tex_print_str(", linepenalty "); tex_print_int (v); } }
@@ -3356,7 +3356,7 @@ scaled tex_glyph_depth(halfword p) /* not used */
scaledwhd tex_glyph_dimensions(halfword p)
{
- scaledwhd whd = { 0, 0, 0 };
+ scaledwhd whd = { 0, 0, 0, 0 };
scaled x = glyph_x_offset(p);
scaled y = glyph_y_offset(p);
whd.ht = tex_char_height_from_glyph(p) + glyph_raise(p);
@@ -3380,7 +3380,7 @@ scaledwhd tex_glyph_dimensions(halfword p)
scaledwhd tex_glyph_dimensions_ex(halfword p)
{
- scaledwhd whd = { 0, 0, 0 };
+ scaledwhd whd = { 0, 0, 0, 0 };
scaled x = glyph_x_offset(p);
scaled y = glyph_y_offset(p);
whd.ht = tex_char_height_from_glyph(p) + glyph_raise(p);
@@ -3451,7 +3451,7 @@ halfword tex_kern_dimension_ex(halfword p)
scaledwhd tex_pack_dimensions(halfword p)
{
- scaledwhd whd = { 0, 0, 0 };
+ scaledwhd whd = { 0, 0, 0, 0 };
whd.ht = box_height(p);
whd.dp = box_depth(p);
whd.wd = box_width(p);
@@ -4331,13 +4331,13 @@ void tex_check_disc_field(halfword n)
void tex_set_discpart(halfword d, halfword h, halfword t, halfword code)
{
+ halfword c = h;
switch (node_subtype(d)) {
case automatic_discretionary_code:
case mathematics_discretionary_code:
code = glyph_discpart_always;
break;
}
- halfword c = h;
while (c) {
if (node_type(c) == glyph_node) {
set_glyph_discpart(c, code);
diff --git a/source/luametatex/source/tex/texnodes.h b/source/luametatex/source/tex/texnodes.h
index a20117ff8..9e24ada27 100644
--- a/source/luametatex/source/tex/texnodes.h
+++ b/source/luametatex/source/tex/texnodes.h
@@ -1555,36 +1555,36 @@ typedef enum simple_choice_subtypes {
\starttabulate[|l|l|l|l|l|l|]
\FL
- \BC \BC noad \BC accent \BC fraction \BC radical \NC fence \NC \NR
- \ML \NC
- \NC vlink 2 \NC new_hlist \NC \NC \NC \NC \NC \NR
- \ML \NC
- \NC vinfo 2 \NC nucleus \NC \NC \NC \NC \NC \NR
- \NC vlink 3 \NC supscr \NC \NC numerator \NC \NC \NC \NR
- \NC vinfo 3 \NC subscr \NC \NC denominator \NC \NC \NC \NR
- \NC vlink 4 \NC supprescr \NC \NC \NC \NC \NC \NR
- \NC vinfo 4 \NC subprescr \NC \NC \NC \NC \NC \NR
- \ML \NC
- \NC vlink 5 \NC italic \NC \NC \NC \NC \NC \NR
- \NC vinfo 5 \NC width \NC \NC \NC \NC \NC \NR
- \NC vlink 6 \NC height \NC \NC \NC \NC \NC \NR
- \NC vinfo 6 \NC depth \NC \NC \NC \NC \NC \NR
- \ML \NC
- \NC vlink 7 \NC options \NC \NC \NC \NC \NC \NR
- \NC vinfo 7 \NC style \NC \NC \NC \NC \NC \NR
- \NC vlink 8 \NC family \NC \NC \NC \NC \NC \NR
- \NC vinfo 8 \NC class \NC \NC \NC \NC \NC \NR
- \NC vlink 9 \NC source \NC \NC \NC \NC \NC \NR
- \NC vinfo 9 \NC prime \NC \NC \NC \NC \NC \NR
- \NC vlink 10 \NC leftslack \NC \NC \NC \NC \NC \NR
- \NC vinfo 10 \NC rightslack \NC \NC \NC \NC \NC \NR
- \ML \NC
- \NC vlink 11 \NC extra_1 \NC top_character \NC rule_thickness \NC degree \NC list \NC \NR
- \NC vinfo 11 \NC extra_2 \NC bot_character \NC left_delimiter \NC left_delimiter \NC source \NC \NR
- \NC vlink 12 \NC extra_3 \NC overlay_character \NC right_delimiter \NC right_delimiter \NC top \NC \NR
- \NC vinfo 12 \NC extra_4 \NC fraction \NC middle_delimiter \NC \NC bottom \NC \NR
- \NC vlink 13 \NC extra_5 \NC topovershoot \NC \NC height \NC \NC \NR
- \NC vinfo 13 \NC extra_6 \NC botovershoot \NC \NC depth \NC \NC \NR
+ \BC \BC noad \BC accent \BC fraction \BC radical \NC fence \NC \NR
+ \ML \NC
+ \NC vlink 2 \NC new_hlist \NC \NC \NC \NC \NC \NR
+ \ML \NC
+ \NC vinfo 2 \NC nucleus \NC \NC \NC \NC \NC \NR
+ \NC vlink 3 \NC supscr \NC \NC numerator \NC \NC \NC \NR
+ \NC vinfo 3 \NC subscr \NC \NC denominator \NC \NC \NC \NR
+ \NC vlink 4 \NC supprescr \NC \NC \NC \NC \NC \NR
+ \NC vinfo 4 \NC subprescr \NC \NC \NC \NC \NC \NR
+ \ML \NC
+ \NC vlink 5 \NC italic \NC \NC \NC \NC \NC \NR
+ \NC vinfo 5 \NC width \NC \NC \NC \NC \NC \NR
+ \NC vlink 6 \NC height \NC \NC \NC \NC \NC \NR
+ \NC vinfo 6 \NC depth \NC \NC \NC \NC \NC \NR
+ \ML \NC
+ \NC vlink 7 \NC options \NC \NC \NC \NC \NC \NR
+ \NC vinfo 7 \NC style \NC \NC \NC \NC \NC \NR
+ \NC vlink 8 \NC family \NC \NC \NC \NC \NC \NR
+ \NC vinfo 8 \NC class \NC \NC \NC \NC \NC \NR
+ \NC vlink 9 \NC source \NC \NC \NC \NC \NC \NR
+ \NC vinfo 9 \NC prime \NC \NC \NC \NC \NC \NR
+ \NC vlink 10 \NC leftslack \NC \NC \NC \NC \NC \NR
+ \NC vinfo 10 \NC rightslack \NC \NC \NC \NC \NC \NR
+ \ML \NC
+ \NC vlink 11 \NC extra_1 \NC top_character \NC rule_thickness \NC degree \NC list \NC \NR
+ \NC vinfo 11 \NC extra_2 \NC bot_character \NC left_delimiter \NC left_delimiter \NC source \NC \NR
+ \NC vlink 12 \NC extra_3 \NC overlay_character \NC right_delimiter \NC right_delimiter \NC top \NC \NR
+ \NC vinfo 12 \NC extra_4 \NC fraction \NC middle_delimiter \NC \NC bottom \NC \NR
+ \NC vlink 13 \NC extra_5 \NC topovershoot \NC \NC height \NC topovershoot \NC \NR
+ \NC vinfo 13 \NC extra_6 \NC botovershoot \NC \NC depth \NC botovershoot \NC \NR
\LL
\stoptabulate
@@ -1767,10 +1767,10 @@ inline int has_noad_no_script_option(halfword n, halfword option)
return 0;
}
-# define has_noad_option_nosubscript(a) has_noad_no_script_option(a, noad_option_no_sub_script)
-# define has_noad_option_nosupscript(a) has_noad_no_script_option(a, noad_option_no_super_script)
-# define has_noad_option_nosubprescript(a) has_noad_no_script_option(a, noad_option_no_sub_pre_script)
-# define has_noad_option_nosupprescript(a) has_noad_no_script_option(a, noad_option_no_super_pre_script)
+# define has_noad_option_nosubscript(a) has_noad_no_script_option(a, noad_option_no_sub_script)
+# define has_noad_option_nosupscript(a) has_noad_no_script_option(a, noad_option_no_super_script)
+# define has_noad_option_nosubprescript(a) has_noad_no_script_option(a, noad_option_no_sub_pre_script)
+# define has_noad_option_nosupprescript(a) has_noad_no_script_option(a, noad_option_no_super_pre_script)
# define has_noad_option_shiftedsubscript(a) (has_option(noad_options(a), noad_option_shifted_sub_script))
# define has_noad_option_shiftedsupscript(a) (has_option(noad_options(a), noad_option_shifted_super_script))
@@ -1906,8 +1906,8 @@ typedef enum math_accent_subtypes {
# define fence_delimiter_list noad_extra_1 // not really a list
# define fence_delimiter_top noad_extra_3
# define fence_delimiter_bottom noad_extra_4
-//define fence_delimiter_first noad_extra_5
-//define fence_delimiter_last noad_extra_6
+# define fence_top_overshoot noad_extra_5
+# define fence_bottom_overshoot noad_extra_6
typedef enum fence_subtypes {
unset_fence_side,
@@ -2004,14 +2004,14 @@ typedef enum math_kernel_options {
math_kernel_has_italic_shape = 0x0080,
} math_kernel_options;
-# define math_kernel_node_size 5
-# define kernel_math_family(a) vinfo(a,2)
-# define kernel_math_character(a) vlink(a,2)
-# define kernel_math_options(a) vinfo(a,3)
-# define kernel_math_list(a) vlink(a,3)
-# define kernel_math_properties(a) vinfo0(a,4) /* for characters */
-# define kernel_math_group(a) vinfo1(a,4) /* for characters */
-# define kernel_math_index(a) vlink(a,4) /* for characters */
+# define math_kernel_node_size 5
+# define kernel_math_family(a) vinfo(a,2)
+# define kernel_math_character(a) vlink(a,2)
+# define kernel_math_options(a) vinfo(a,3)
+# define kernel_math_list(a) vlink(a,3)
+# define kernel_math_properties(a) vinfo0(a,4) /* for characters */
+# define kernel_math_group(a) vinfo1(a,4) /* for characters */
+# define kernel_math_index(a) vlink(a,4) /* for characters */
# define math_kernel_node_has_option(a,b) ((kernel_math_options(a) & b) == b)
# define math_kernel_node_set_option(a,b) kernel_math_options(a) = (kernel_math_options(a) | b)
@@ -2021,6 +2021,26 @@ typedef enum math_kernel_options {
in traditional \TEX\ fonts where a base character can come from one font, and the extensible
from another, but in \OPENTYPE\ math font that doesn't happen.
*/
+
+/* It could be: */
+
+// # define math_delimiter_node_size 4
+// # define delimiter_small_family(a) vinfo00(a,2)
+// # define delimiter_large_family(a) vinfo01(a,2)
+// # define delimiter_reserved_1 vinfo02(a,2)
+// # define delimiter_reserved_2 vinfo03(a,2)
+// # define delimiter_reserved_3 vlink(a,2)
+// # define delimiter_small_character(a) vinfo(a,3)
+// # define delimiter_large_character(a) vlink(a,3)
+
+/* And some day (we then even assume traditionally to be mapped onto wide): */
+
+// # define math_delimiter_node_size 3
+// # define delimiter_family(a) vinfo00(a,2)
+// # define delimiter_reserved_1 vinfo01(a,2)
+// # define delimiter_reserved_2 vinfo02(a,2)
+// # define delimiter_reserved_3 vinfo03(a,2)
+// # define delimiter_character(a) vlink(a,2)
# define math_delimiter_node_size 4
# define delimiter_small_family(a) vinfo(a,2) /*tex |family| for small delimiter */
@@ -2538,15 +2558,20 @@ inline static void tex_attach_attribute_list_attribute(halfword target, halfword
is used in the \LUA\ interface is stored alongside.
*/
-extern void tex_print_short_node_contents (halfword n);
-extern void tex_show_node_list (halfword n, int threshold, int max);
-extern halfword tex_actual_box_width (halfword r, scaled base_width);
-extern void tex_print_name (halfword p, const char *what);
-extern void tex_print_node_list (halfword n, const char *what, int threshold, int max);
-/* void tex_print_node_and_details (halfword p); */
-/* void tex_print_subtype_and_attributes_info (halfword p, halfword s, node_info *data); */
-extern void tex_print_extended_subtype (halfword p, quarterword s);
-extern void tex_aux_show_dictionary (halfword p, halfword properties, halfword group, halfword index, halfword font, halfword character);
+extern void tex_print_short_node_contents (halfword n);
+extern const char *tex_aux_subtype_str (halfword n);
+extern void tex_show_node_list (halfword n, int threshold, int max);
+extern halfword tex_actual_box_width (halfword r, scaled base_width);
+extern void tex_print_name (halfword p, const char *what);
+extern void tex_print_node_list (halfword n, const char *what, int threshold, int max);
+/* void tex_print_node_and_details (halfword p); */
+/* void tex_print_subtype_and_attributes_info (halfword p, halfword s, node_info *data); */
+extern void tex_print_extended_subtype (halfword p, quarterword s);
+extern void tex_aux_show_dictionary (halfword p, halfword properties, halfword group, halfword index, halfword font, halfword character);
+
+/*tex
+ Basic node management:
+*/
extern halfword tex_new_node (quarterword i, quarterword j);
extern void tex_flush_node_list (halfword n);
@@ -2596,23 +2621,8 @@ typedef enum glue_signs {
# define normal_glue_multiplier 0.0
-inline halfword tex_checked_glue_sign(halfword sign)
-{
- if ((sign < min_glue_sign) || (sign > max_glue_sign)) {
- return normal_glue_sign;
- } else {
- return sign;
- }
-}
-
-inline halfword tex_checked_glue_order(halfword order)
-{
- if ((order < min_glue_order) || (order > max_glue_order)) {
- return normal_glue_order;
- } else {
- return order;
- }
-}
+inline halfword tex_checked_glue_sign (halfword sign) { return ((sign < min_glue_sign ) || (sign > max_glue_sign )) ? normal_glue_sign : sign ; }
+inline halfword tex_checked_glue_order (halfword order) { return ((order < min_glue_order) || (order > max_glue_order)) ? normal_glue_order : order; }
/*tex
These are reserved nodes that sit at the start of main memory. We could actually just allocate
@@ -2626,7 +2636,6 @@ inline halfword tex_checked_glue_order(halfword order)
Changing this to real nodes makes sense but is also tricky due to initializations ... some day
(we need to store stuff in teh states then and these are not saved!).
-
*/
# define fi_glue (zero_glue + glue_spec_size) /*tex These are constants */
@@ -2683,6 +2692,8 @@ extern scaledwhd tex_glyph_dimensions_ex (halfword p); /* x/y scaled, expansion
extern halfword tex_kern_dimension (halfword p);
extern halfword tex_kern_dimension_ex (halfword p); /* expansion included */
+extern scaled tex_effective_glue (halfword parent, halfword glue);
+
extern scaledwhd tex_pack_dimensions (halfword p);
extern halfword tex_list_node_mem_usage (void);
@@ -2723,13 +2734,9 @@ typedef enum special_node_list_types { /* not in sycn with the above .. maybe ad
// best_page_break_type
} special_node_list_types;
-extern int tex_is_special_node_list (halfword n, int *istail);
-extern halfword tex_get_special_node_list (special_node_list_types list, halfword *tail);
-extern void tex_set_special_node_list (special_node_list_types list, halfword head);
-
-extern scaled tex_effective_glue (halfword parent, halfword glue);
-
-extern const char *tex_aux_subtype_str (halfword n );
+extern int tex_is_special_node_list (halfword n, int *istail);
+extern halfword tex_get_special_node_list (special_node_list_types list, halfword *tail);
+extern void tex_set_special_node_list (special_node_list_types list, halfword head);
# endif
diff --git a/source/luametatex/source/tex/texpackaging.c b/source/luametatex/source/tex/texpackaging.c
index b2286cd71..796c3c1b7 100644
--- a/source/luametatex/source/tex/texpackaging.c
+++ b/source/luametatex/source/tex/texpackaging.c
@@ -422,11 +422,11 @@ scaled tex_char_stretch(halfword p) /* todo: move this to texfont.c and make it
halfword m = font_max_stretch(f);
if (m > 0) {
halfword c = glyph_character(p);
- halfword ef = tex_char_ef_from_font(f, c);
- if (ef > 0) {
+ scaled e = tex_char_ef_from_font(f, c);
+ if (e > 0) {
scaled dw = tex_calculated_glyph_width(p, m) - tex_char_width_from_glyph(p);
if (dw > 0) {
- return tex_round_xn_over_d(dw, ef, 1000);
+ return tex_round_xn_over_d(dw, e, 1000);
}
}
}
@@ -441,11 +441,11 @@ scaled tex_char_shrink(halfword p) /* todo: move this to texfont.c and make it m
halfword m = font_max_shrink(f);
if (m > 0) {
halfword c = glyph_character(p);
- halfword ef = tex_char_ef_from_font(f, c);
- if (ef > 0) {
+ scaled e = tex_char_cf_from_font(f, c);
+ if (e > 0) {
scaled dw = tex_char_width_from_glyph(p) - tex_calculated_glyph_width(p, -m);
if (dw > 0) {
- return tex_round_xn_over_d(dw, ef, 1000);
+ return tex_round_xn_over_d(dw, e, 1000);
}
}
}
@@ -482,7 +482,7 @@ scaled tex_kern_shrink(halfword p)
if (l && node_type(l) == glyph_node && ! tex_has_glyph_option(l, glyph_option_no_expansion)) {
halfword m = font_max_shrink(glyph_font(l));
if (m > 0) {
- halfword e = tex_char_ef_from_font(glyph_font(l), glyph_character(l));
+ scaled e = tex_char_cf_from_font(glyph_font(l), glyph_character(l));
if (e > 0) {
scaled dw = tex_round_xn_over_d(w, 1000 - m, 1000) - w;
if (dw > 0) {
@@ -503,20 +503,23 @@ static void tex_aux_set_kern_expansion(halfword p, halfword ex_ratio)
if (l && node_type(l) == glyph_node && ! tex_has_glyph_option(l, glyph_option_no_expansion)) {
halfword f = glyph_font(l);
halfword c = glyph_character(l);
- halfword ef = tex_char_ef_from_font(f, c);
- if (ef == 0) {
- return;
- } else if (ex_ratio > 0) {
- halfword m = font_max_stretch(f);
- if (m > 0) {
- halfword ex_stretch = tex_ext_xn_over_d(ex_ratio * ef, m, 1000000);
- kern_expansion(p) = tex_fix_expand_value(f, ex_stretch) * 1000;
+ if (ex_ratio > 0) {
+ scaled e = tex_char_ef_from_font(f, c);
+ if (e > 0) {
+ halfword m = font_max_stretch(f);
+ if (m > 0) {
+ e = tex_ext_xn_over_d(ex_ratio * e, m, 1000000);
+ kern_expansion(p) = tex_fix_expand_value(f, e) * 1000;
+ }
}
} else if (ex_ratio < 0) {
- halfword m = font_max_shrink(f);
- if (m > 0) {
- halfword ex_shrink = tex_ext_xn_over_d(ex_ratio * ef, m, 1000000);
- kern_expansion(p) = tex_fix_expand_value(f, ex_shrink) * 1000;
+ scaled e = tex_char_cf_from_font(f, c);
+ if (e > 0) {
+ halfword m = font_max_shrink(f);
+ if (m > 0) {
+ e = tex_ext_xn_over_d(ex_ratio * e, m, 1000000);
+ kern_expansion(p) = tex_fix_expand_value(f, e) * 1000;
+ }
}
}
}
@@ -528,22 +531,27 @@ static void tex_aux_set_glyph_expansion(halfword p, int ex_ratio)
switch (node_type(p)) {
case glyph_node:
if (! tex_has_glyph_option(p, glyph_option_no_expansion)) {
- halfword f = glyph_font(p);
- halfword c = glyph_character(p);
- halfword ef = tex_char_ef_from_font(f, c);
- if (ef == 0) {
- return;
- } else if (ex_ratio > 0) {
- halfword m = font_max_stretch(f);
- if (m > 0) {
- halfword ex_stretch = tex_ext_xn_over_d(ex_ratio * ef, m, 1000000);
- glyph_expansion(p) = tex_fix_expand_value(f, ex_stretch) * 1000;
+ if (ex_ratio > 0) {
+ halfword f = glyph_font(p);
+ halfword c = glyph_character(p);
+ scaled e = tex_char_ef_from_font(f, c);
+ if (e > 0) {
+ halfword m = font_max_stretch(f);
+ if (m > 0) {
+ e = tex_ext_xn_over_d(ex_ratio * e, m, 1000000);
+ glyph_expansion(p) = tex_fix_expand_value(f, e) * 1000;
+ }
}
} else if (ex_ratio < 0) {
- halfword m = font_max_shrink(f);
- if (m > 0) {
- halfword ex_shrink = tex_ext_xn_over_d(ex_ratio * ef, m, 1000000);
- glyph_expansion(p) = tex_fix_expand_value(f, ex_shrink) * 1000;
+ halfword f = glyph_font(p);
+ halfword c = glyph_character(p);
+ scaled e = tex_char_cf_from_font(f, c);
+ if (e > 0) {
+ halfword m = font_max_shrink(f);
+ if (m > 0) {
+ e = tex_ext_xn_over_d(ex_ratio * e, m, 1000000);
+ glyph_expansion(p) = tex_fix_expand_value(f, e) * 1000;
+ }
}
}
}
@@ -1039,7 +1047,7 @@ halfword tex_hpack(halfword p, scaled w, int m, singleword pack_direction, int r
/*tex natural width */
scaled x = 0;
/*tex the current direction */
- singleword hpack_dir = pack_direction == direction_unknown ? text_direction_par : pack_direction;
+ singleword hpack_dir = pack_direction == direction_unknown ?(singleword) text_direction_par : pack_direction;
int disc_level = 0;
halfword pack_interrupt[8];
scaled font_stretch = 0;
@@ -1126,11 +1134,11 @@ halfword tex_hpack(halfword p, scaled w, int m, singleword pack_direction, int r
break;
}
case packing_substitute:
- {
- lmt_packaging_state.previous_char_ptr = p;
+ lmt_packaging_state.previous_char_ptr = p;
+ if (lmt_packaging_state.font_expansion_ratio != 0) {
tex_aux_set_glyph_expansion(p, lmt_packaging_state.font_expansion_ratio);
- break;
}
+ break;
}
}
whd = tex_glyph_dimensions_ex(p);
@@ -1256,10 +1264,10 @@ halfword tex_hpack(halfword p, scaled w, int m, singleword pack_direction, int r
break;
}
case packing_substitute:
- {
+ if (lmt_packaging_state.font_expansion_ratio != 0) {
tex_aux_set_kern_expansion(p, lmt_packaging_state.font_expansion_ratio);
- break;
}
+ break;
}
}
x += tex_kern_dimension_ex(p);
@@ -1274,7 +1282,9 @@ halfword tex_hpack(halfword p, scaled w, int m, singleword pack_direction, int r
*/
break;
case packing_substitute:
- tex_aux_set_glyph_expansion(p, lmt_packaging_state.font_expansion_ratio);
+ if (lmt_packaging_state.font_expansion_ratio != 0) {
+ tex_aux_set_glyph_expansion(p, lmt_packaging_state.font_expansion_ratio);
+ }
break;
}
}
@@ -1575,7 +1585,7 @@ halfword tex_hpack(halfword p, scaled w, int m, singleword pack_direction, int r
halfword tex_filtered_hpack(halfword p, halfword qt, scaled w, int m, int grp, halfword d, int just_pack, halfword attr, int state, int retain)
{
halfword head;
- singleword direction = checked_direction_value(d);
+ singleword direction = (singleword) checked_direction_value(d);
(void) state; /*tex Why do we pass it? Probably a left-over from an experiment. */
if (just_pack) {
head = node_next(p);
@@ -1603,7 +1613,7 @@ halfword tex_filtered_hpack(halfword p, halfword qt, scaled w, int m, int grp, h
scaledwhd tex_natural_hsizes(halfword p, halfword pp, glueratio g_mult, int g_sign, int g_order)
{
- scaledwhd siz = { 0, 0, 0 };
+ scaledwhd siz = { 0, 0, 0, 0 };
scaled gp = 0;
scaled gm = 0;
while (p && p != pp) {
@@ -1757,7 +1767,7 @@ scaledwhd tex_natural_hsizes(halfword p, halfword pp, glueratio g_mult, int g_si
scaledwhd tex_natural_vsizes(halfword p, halfword pp, glueratio g_mult, int g_sign, int g_order)
{
- scaledwhd siz = { 0, 0, 0 };
+ scaledwhd siz = { 0, 0, 0, 0 };
scaled gp = 0;
scaled gm = 0;
while (p && p != pp) {
@@ -1974,7 +1984,7 @@ halfword tex_natural_hsize(halfword p, halfword *correction)
halfword tex_natural_vsize(halfword p)
{
- scaledwhd siz = { 0, 0, 0 };
+ scaledwhd siz = { 0, 0, 0, 0 };
while (p) {
switch (node_type(p)) {
case hlist_node:
@@ -2293,7 +2303,7 @@ halfword tex_filtered_vpack(halfword p, scaled h, int m, scaled maxdepth, int gr
if (! just_pack) {
q = lmt_vpack_filter_callback(q, h, m, maxdepth, grp, direction, attr);
}
- q = tex_vpack(q, h, m, maxdepth, checked_direction_value(direction), retain);
+ q = tex_vpack(q, h, m, maxdepth, (singleword) checked_direction_value(direction), retain);
if (q && normalize_par_mode_permitted(normalize_par_mode_par, flatten_v_leaders_mode) && ! is_box_package_state(state, package_u_leader_delayed)) {
tex_flatten_leaders(q, NULL);
}
@@ -3111,7 +3121,7 @@ halfword tex_vert_break(halfword p, scaled h, scaled d)
prev_p = p;
p = node_next(prev_p);
}
- return best_place;
+ return best_place; /* unreachable */
}
/*tex
diff --git a/source/luametatex/source/tex/texprimitive.c b/source/luametatex/source/tex/texprimitive.c
index 42344af15..d5f2b0927 100644
--- a/source/luametatex/source/tex/texprimitive.c
+++ b/source/luametatex/source/tex/texprimitive.c
@@ -182,7 +182,7 @@ static int tex_aux_room_in_hash(void)
*/
-inline static halfword tex_aux_compute_hash(const char *j, int l)
+inline static halfword tex_aux_compute_hash(const char *j, unsigned l)
{
halfword h = (unsigned const char) j[0];
for (unsigned k = 1; k < l; k++) {
@@ -504,7 +504,7 @@ static halfword tex_aux_insert_id(halfword p, const unsigned char *j, unsigned i
halfword tex_id_locate(int j, int l, int create)
{
/*tex The index in |hash| array: */
- halfword h = tex_aux_compute_hash((char *) (lmt_fileio_state.io_buffer + j), l);
+ halfword h = tex_aux_compute_hash((char *) (lmt_fileio_state.io_buffer + j), (unsigned) l);
/*tex We start searching here. Note that |0 <= h < hash_prime|: */
halfword p = h + hash_base;
/*tex The next one in a list: */
@@ -536,7 +536,7 @@ halfword tex_id_locate(int j, int l, int create)
halfword tex_string_locate(const char *s, size_t l, int create)
{
/*tex The hash code: */
- halfword h = tex_aux_compute_hash(s, (int) l);
+ halfword h = tex_aux_compute_hash(s, (unsigned) l);
/*tex The index in |hash| array. We start searching here. Note that |0 <= h < hash_prime|: */
halfword p = h + hash_base;
while (1) {
@@ -702,7 +702,7 @@ void tex_print_cmd_flags(halfword cs, halfword cmd, int flags, int escaped)
if (is_instance (flags)) { (escaped ? tex_print_str_esc : tex_print_str)("instance " ); }
if (is_untraced (flags)) { (escaped ? tex_print_str_esc : tex_print_str)("untraced " ); }
}
- if (is_tolerant_cmd (cmd)) {
+ if (is_tolerant_cmd(cmd)) {
(escaped ? tex_print_str_esc : tex_print_str)("tolerant " );
}
if (is_protected_cmd(cmd)) {
diff --git a/source/luametatex/source/tex/texprinting.c b/source/luametatex/source/tex/texprinting.c
index deabb4b72..860ff6731 100644
--- a/source/luametatex/source/tex/texprinting.c
+++ b/source/luametatex/source/tex/texprinting.c
@@ -590,10 +590,6 @@ void tex_print_hex(int sn)
unsigned int n = (unsigned int) sn;
int k = 0;
unsigned char digits[24];
- if (n < 0) {
- tex_print_char('-');
- n = -n;
- }
do {
unsigned char d = (unsigned char) (n % 16);
if (d < 10) {
@@ -695,30 +691,38 @@ void tex_print_current_string(void)
void tex_print_cs_checked(halfword p)
{
- if (p == null_cs) {
- tex_print_str_esc("csname");
- tex_print_str_esc("endcsname");
- tex_print_char(' ');
- } else if (p < hash_base) {
- tex_print_str(error_string_impossible(11));
- } else if (p == undefined_control_sequence) {
- tex_print_str_esc("undefined");
- tex_print_char(' ');
- } else if (eqtb_out_of_range(p)) {
- tex_print_str(error_string_impossible(12));
- } else {
- strnumber t = cs_text(p);
- if (t < 0 || t >= lmt_string_pool_state.string_pool_data.ptr) {
- tex_print_str(error_string_nonexistent(13));
- } else if (tex_is_active_cs(t)) {
- tex_print_tex_str(active_cs_value(t));
- } else {
- tex_print_tex_str_esc(t);
- if (! tex_single_letter(t) || (tex_get_cat_code(cat_code_table_par, aux_str2uni(str_string(t))) == letter_cmd)) {
- tex_print_char(' ');
+ switch (tex_cs_state(p)) {
+ case cs_no_error:
+ {
+ strnumber t = cs_text(p);
+ if (t < 0 || t >= lmt_string_pool_state.string_pool_data.ptr) {
+ tex_print_str(error_string_nonexistent(13));
+ } else if (tex_is_active_cs(t)) {
+ tex_print_tex_str(active_cs_value(t));
+ } else {
+ tex_print_tex_str_esc(t);
+ if (! tex_single_letter(t) || (tex_get_cat_code(cat_code_table_par, aux_str2uni(str_string(t))) == letter_cmd)) {
+ tex_print_char(' ');
+ }
+ }
}
- }
- }
+ break;
+ case cs_null_error:
+ tex_print_str_esc("csname");
+ tex_print_str_esc("endcsname");
+ tex_print_char(' ');
+ break;
+ case cs_below_base_error:
+ tex_print_str(error_string_impossible(11));
+ break;
+ case cs_undefined_error:
+ tex_print_str_esc("undefined");
+ tex_print_char(' ');
+ break;
+ case cs_out_of_range_error:
+ tex_print_str(error_string_impossible(12));
+ break;
+ }
}
/*tex
diff --git a/source/luametatex/source/tex/texscanning.c b/source/luametatex/source/tex/texscanning.c
index fec04356b..5480910dc 100644
--- a/source/luametatex/source/tex/texscanning.c
+++ b/source/luametatex/source/tex/texscanning.c
@@ -668,7 +668,7 @@ static int tex_aux_set_cur_val_by_some_cmd(int code)
case math_char_class_code:
case math_char_fam_code:
case math_char_slot_code:
- /* we actually need two commands or we need to look ahead */
+ /* we actually need two commands or we need to look ahead */
{
mathcodeval mval = { 0, 0, 0 };
mathdictval dval = { 0, 0, 0 };
@@ -1594,6 +1594,14 @@ static halfword tex_aux_scan_something_internal(halfword cmd, halfword chr, int
cur_val_level = int_val_level;
break;
}
+ case font_cf_code:
+ {
+ halfword fnt = tex_scan_font_identifier(NULL);
+ halfword chr = tex_scan_char_number(0);
+ cur_val = tex_char_cf_from_font(fnt, chr);
+ cur_val_level = int_val_level;
+ break;
+ }
case font_dimen_code:
{
cur_val = tex_get_font_dimen();
@@ -1975,8 +1983,8 @@ halfword tex_scan_int(int optional_equal, int *radix)
*radix = 8;
}
while (1) {
- tex_get_x_token();
unsigned d = 0;
+ tex_get_x_token();
if ((cur_tok >= zero_token) && (cur_tok <= seven_token)) {
d = cur_tok - zero_token;
} else {
@@ -1997,7 +2005,7 @@ halfword tex_scan_int(int optional_equal, int *radix)
}
}
}
- break;
+ // break;
}
case hex_token:
{
@@ -2005,8 +2013,8 @@ halfword tex_scan_int(int optional_equal, int *radix)
*radix = 16;
}
while (1) {
- tex_get_x_token();
unsigned d = 0;
+ tex_get_x_token();
if ((cur_tok >= zero_token) && (cur_tok <= nine_token)) {
d = cur_tok - zero_token;
} else if ((cur_tok >= A_token_l) && (cur_tok <= F_token_l)) {
@@ -2031,7 +2039,7 @@ halfword tex_scan_int(int optional_equal, int *radix)
}
}
}
- break;
+ // break;
}
default:
{
@@ -2061,7 +2069,7 @@ halfword tex_scan_int(int optional_equal, int *radix)
}
tex_get_x_token();
}
- break;
+ // break;
}
}
DONE:
@@ -2099,8 +2107,8 @@ int tex_scan_cardinal(unsigned *value, int dontbark)
case octal_token:
{
while (1) {
- tex_get_x_token();
unsigned d = 0;
+ tex_get_x_token();
if ((cur_tok >= zero_token) && (cur_tok <= seven_token)) {
d = cur_tok - zero_token;
} else {
@@ -2112,13 +2120,13 @@ int tex_scan_cardinal(unsigned *value, int dontbark)
result = max_cardinal;
}
}
- break;
+ // break;
}
case hex_token:
{
while (1) {
- tex_get_x_token();
unsigned d = 0;
+ tex_get_x_token();
if ((cur_tok >= zero_token) && (cur_tok <= nine_token)) {
d = cur_tok - zero_token;
} else if ((cur_tok >= A_token_l) && (cur_tok <= F_token_l)) {
@@ -2134,7 +2142,7 @@ int tex_scan_cardinal(unsigned *value, int dontbark)
result = max_cardinal;
}
}
- break;
+ // break;
}
default:
{
@@ -2152,7 +2160,7 @@ int tex_scan_cardinal(unsigned *value, int dontbark)
}
tex_get_x_token();
}
- break;
+ // break;
}
}
DONE:
@@ -2304,6 +2312,7 @@ typedef enum scanned_unit {
static int tex_aux_scan_unit(halfword *num, halfword *denom, halfword *value, halfword *order)
{
+ AGAIN: /* only for true */
do {
tex_get_x_token();
} while (cur_cmd == spacer_cmd);
@@ -2327,7 +2336,6 @@ static int tex_aux_scan_unit(halfword *num, halfword *denom, halfword *value, ha
goto BACK_TWO;
}
cur_cs = save_cur_cs;
- AGAIN:
switch (chrone) {
case 'p': case 'P':
switch (chrtwo) {
@@ -2405,7 +2413,7 @@ static int tex_aux_scan_unit(halfword *num, halfword *denom, halfword *value, ha
switch (chrtwo) {
case 'r': case 'R':
if (tex_scan_mandate_keyword("true", 2)) {
- /*tex This is now a bogus prefix! */
+ /*tex This is now a bogus prefix that might get dropped! */
goto AGAIN;
}
}
@@ -4178,7 +4186,7 @@ static void tex_aux_scan_expr(halfword level)
node_subtype(t) = 0;
/* */
node_next(t) = top;
- expression_type(t) = (quarterword) level;
+ expression_type(t) = (singleword) level;
expression_state(t) = (singleword) state;
expression_result(t) = (singleword) result;
expression_expression(t) = expression;
@@ -4576,7 +4584,7 @@ static const char *bit_expression_names[] = {
variant that only uses doubles: |dimenexpression| and |numberexpression|.
*/
-# define factor 1000
+# define factor 1 // 256, 1000 : wrong results so needs a fix
typedef struct stack_info {
halfword head;
@@ -4879,8 +4887,8 @@ static halfword tex_scan_bit_int(int *radix)
*radix = 8;
}
while (1) {
- tex_get_x_token();
unsigned d = 0;
+ tex_get_x_token();
if ((cur_tok >= zero_token) && (cur_tok <= seven_token)) {
d = cur_tok - zero_token;
} else {
@@ -4896,7 +4904,7 @@ static halfword tex_scan_bit_int(int *radix)
}
}
}
- break;
+ // break;
}
case hex_token:
{
@@ -4904,8 +4912,8 @@ static halfword tex_scan_bit_int(int *radix)
*radix = 16;
}
while (1) {
- tex_get_x_token();
unsigned d = 0;
+ tex_get_x_token();
if ((cur_tok >= zero_token) && (cur_tok <= nine_token)) {
d = cur_tok - zero_token;
} else if ((cur_tok >= A_token_l) && (cur_tok <= F_token_l)) {
@@ -4925,7 +4933,7 @@ static halfword tex_scan_bit_int(int *radix)
}
}
}
- break;
+ // break;
}
default:
{
@@ -4950,7 +4958,7 @@ static halfword tex_scan_bit_int(int *radix)
}
tex_get_x_token();
}
- break;
+ // break;
}
}
DONE:
@@ -5066,6 +5074,8 @@ static void tex_aux_trace_expression(stack_info stack, halfword level, halfword
tex_end_diagnostic();
}
+/* This one is not yet okay ... work in progress. */
+
static void tex_aux_scan_expression(int level)
{
stack_info operators = tex_aux_new_stack();
@@ -5521,7 +5531,7 @@ static void tex_aux_scan_expression(int level)
break;
case bit_expression_multiply:
{
- double d = va * vb;
+ double d = (double) va * (double) vb;
if (sa == bit_expression_float) {
d = d / (65536 * factor);
} else if (sb == bit_expression_float) {
@@ -5687,7 +5697,7 @@ int tex_scan_tex_value(halfword level, halfword *value)
quarterword tex_scan_direction(int optional_equal)
{
int i = tex_scan_int(optional_equal, NULL);
- return checked_direction_value(i);
+ return (quarterword) checked_direction_value(i);
}
halfword tex_scan_geometry(int optional_equal)
diff --git a/source/luametatex/source/tex/textoken.c b/source/luametatex/source/tex/textoken.c
index 93bf3913a..7dd9c888b 100644
--- a/source/luametatex/source/tex/textoken.c
+++ b/source/luametatex/source/tex/textoken.c
@@ -161,13 +161,12 @@ void tex_compact_tokens(void)
{
int nc = 0;
// memoryword *target = allocate_array(sizeof(memoryword), (size_t) token_memory_state.tokens_data.allocated, 0);
- memoryword *target = aux_allocate_clear_array(sizeof(memoryword), (size_t) lmt_token_memory_state.tokens_data.allocated, 0);
- halfword *mapper = aux_allocate_array(sizeof(halfword), (size_t) lmt_token_memory_state.tokens_data.allocated, 0);
+ memoryword *target = aux_allocate_clear_array(sizeof(memoryword), lmt_token_memory_state.tokens_data.allocated, 0);
+ halfword *mapper = aux_allocate_array(sizeof(halfword), lmt_token_memory_state.tokens_data.allocated, 0);
int nofluacmds = 0;
if (target && mapper) {
- // memset((void *) target, 0, ((size_t) token_memory_state.tokens_data.allocated) * sizeof(memoryword));
- memset((void *) mapper, -1, ((size_t) lmt_token_memory_state.tokens_data.allocated) * sizeof(halfword));
memoryword *tokens = lmt_token_memory_state.tokens;
+ memset((void *) mapper, -1, ((size_t) lmt_token_memory_state.tokens_data.allocated) * sizeof(halfword));
/* also reset available */
for (int cs = 0; cs < (eqtb_size + lmt_hash_state.hash_data.ptr + 1); cs++) {
switch (eq_type(cs)) {
@@ -579,8 +578,6 @@ static const char *tex_aux_special_cmd_string(halfword cmd, halfword chr, const
}
}
-halfword nn = 0;
-
halfword tex_show_token_list(halfword p, halfword q, int l, int asis)
{
if (p) {
@@ -794,7 +791,6 @@ halfword tex_scan_character(const char *s, int left_brace, int skip_space, int s
} else {
goto DONE;
}
- break;
case relax_cmd:
if (skip_relax) {
break;
@@ -3082,6 +3078,13 @@ char *tex_tokenlist_to_tstring(int pp, int inhibit_par, int *siz, int skippreamb
/*tex We need to go beyond the reference. */
int p = token_link(pp);
if (p) {
+ int e = escape_char_par; /*tex The serialization of the escape, normally a backlash. */
+ int n = '0'; /*tex The character after |#|, so |#0| upto |#9| */
+ int min = 0;
+ int max = lmt_token_memory_state.tokens_data.top;
+ int skip = 0;
+ int tail = p;
+ int count = 0;
if (lmt_token_state.bufmax > default_buffer_size) {
/* Let's start fresh and small. */
aux_deallocate_array(lmt_token_state.buffer);
@@ -3093,13 +3096,6 @@ char *tex_tokenlist_to_tstring(int pp, int inhibit_par, int *siz, int skippreamb
lmt_token_state.bufmax = default_buffer_size;
}
lmt_token_state.bufloc = 0;
- int e = escape_char_par; /*tex The serialization of the escape, normally a backlash. */
- int n = '0'; /*tex The character after |#|, so |#0| upto |#9| */
- int min = 0;
- int max = lmt_token_memory_state.tokens_data.top;
- int skip = 0;
- int tail = p;
- int count = 0;
if (skippreamble) {
skip = get_token_parameters(pp);
}