/* nodes.h Copyright 2006-2008 Taco Hoekwater This file is part of LuaTeX. LuaTeX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. LuaTeX is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU General Public License along with LuaTeX; if not, see . */ /* $Id: texnodes.h 4090 2011-02-28 08:51:20Z taco $ */ #include #ifndef __NODES_H__ # define __NODES_H__ /* these are in texlang.c */ # define set_vlink(a,b) vlink(a)=b # define get_vlink(a) vlink(a) # define get_character(a) character(a) extern halfword insert_discretionary(halfword t, halfword pre, halfword post, halfword replace); extern halfword insert_syllable_discretionary(halfword t, lang_variables * lan); extern halfword insert_word_discretionary(halfword t, lang_variables * lan); extern halfword insert_complex_discretionary(halfword t, lang_variables * lan, halfword pre, halfword post, halfword replace); extern halfword insert_character(halfword t, int n); extern void set_disc_field(halfword f, halfword t); # define varmemcast(a) (memory_word *)(a) extern memory_word *volatile varmem; extern halfword var_mem_max; extern halfword get_node(int s); extern void free_node(halfword p, int s); extern void init_node_mem(int s); extern void dump_node_mem(void); extern void undump_node_mem(void); # define max_halfword 0x3FFFFFFF # define max_dimen 0x3FFFFFFF # ifndef null # define null 0 # endif # define null_flag -0x40000000 # define zero_glue 0 # define normal 0 # define vinfo(a) varmem[(a)].hh.v.LH # define vlink(a) varmem[(a)].hh.v.RH # define type(a) varmem[(a)].hh.u.B0 # define subtype(a) varmem[(a)].hh.u.B1 # define node_attr(a) vinfo((a)+1) # define alink(a) vlink((a)+1) # define node_size(a) varmem[(a)].hh.v.LH # define rlink(a) vlink((a)+1) /* aka alink() */ # define llink(a) vinfo((a)+1) /* overlaps with node_attr() */ # define add_glue_ref(a) glue_ref_count(a)++ /* new reference to a glue spec */ /* really special head node pointers that only need links */ # define temp_node_size 2 /* attribute lists */ # define UNUSED_ATTRIBUTE -0x7FFFFFFF /* as low as it goes */ /* it is convenient to have attribute list nodes and attribute node * be the same size */ # define attribute_node_size 2 # define attr_list_ref(a) vinfo((a)+1) /* the reference count */ # define attribute_id(a) vinfo((a)+1) # define attribute_value(a) vlink((a)+1) # define cache_disabled max_halfword # define add_node_attr_ref(a) { if (a!=null) attr_list_ref((a))++; } # define replace_attribute_list(a,b) do { \ delete_attribute_ref(node_attr(a)); \ node_attr(a)=b; \ } while (0) extern void update_attribute_cache(void); extern halfword copy_attribute_list(halfword n); extern halfword do_set_attribute(halfword p, int i, int val); /* a glue spec */ # define glue_spec_size 4 # define stretch(a) vlink((a)+1) /* width == a+2 */ # define shrink(a) vinfo((a)+1) # define stretch_order(a) type((a)+3) # define shrink_order(a) subtype((a)+3) # define glue_ref_count(a) vlink((a)+3) # define width_offset 2 # define depth_offset 3 # define height_offset 4 # define list_offset 6 typedef enum { cond_math_glue = 98, /* special |subtype| to suppress glue in the next node */ mu_glue, /* |subtype| for math glue */ a_leaders, /* |subtype| for aligned leaders */ c_leaders, /* |subtype| for centered leaders */ x_leaders, /* |subtype| for expanded leaders */ g_leaders /* |subtype| for global (page) leaders */ } glue_subtype_codes; /* normal nodes */ # define inf_bad 10000 /* infinitely bad value */ # define inf_penalty inf_bad /*``infinite'' penalty value */ # define eject_penalty -(inf_penalty) /*``negatively infinite'' penalty value */ # define penalty_node_size 3 # define penalty(a) vlink((a)+2) # define glue_node_size 4 # define glue_ptr(a) vinfo((a)+2) # define leader_ptr(a) vlink((a)+2) # define synctex_tag_glue(a) vinfo((a)+3) # define synctex_line_glue(a) vlink((a)+3) /* disc nodes could eventually be smaller, because the indirect pointers are not really needed (8 instead of 10). */ # define disc_node_size 10 typedef enum { discretionary_disc = 0, explicit_disc, automatic_disc, syllable_disc, init_disc, /* first of a duo of syllable_discs */ select_disc, /* second of a duo of syllable_discs */ } discretionary_types; # define pre_break_head(a) ((a)+4) # define post_break_head(a) ((a)+6) # define no_break_head(a) ((a)+8) # define pre_break(a) vinfo((a)+2) # define post_break(a) vlink((a)+2) # define no_break(a) vlink((a)+3) # define tlink llink # define vlink_pre_break(a) vlink(pre_break_head(a)) # define vlink_post_break(a) vlink(post_break_head(a)) # define vlink_no_break(a) vlink(no_break_head(a)) # define tlink_pre_break(a) tlink(pre_break_head(a)) # define tlink_post_break(a) tlink(post_break_head(a)) # define tlink_no_break(a) tlink(no_break_head(a)) # define kern_node_size 5 # define explicit 1 /*|subtype| of kern nodes from \.{\\kern} and \.{\\/} */ # define acc_kern 2 /*|subtype| of kern nodes from accents */ # define synctex_tag_kern(a) vinfo((a)+3) # define synctex_line_kern(a) vlink((a)+3) # define ex_kern(a) vinfo((a)+4) /* expansion factor (hz) */ # define box_node_size 9 # define HLIST_SUBTYPE_UNKNOWN 0 # define HLIST_SUBTYPE_LINE 1 /* paragraph lines */ # define HLIST_SUBTYPE_HBOX 2 /* \.{\\hbox} */ # define HLIST_SUBTYPE_INDENT 3 /* indentation box */ # define HLIST_SUBTYPE_ALIGNROW 4 /* row from a \.{\\halign} or \.{\\valign} */ # define HLIST_SUBTYPE_ALIGNCELL 5 /* cell from a \.{\\halign} or \.{\\valign} */ # define width(a) varmem[(a)+2].cint # define depth(a) varmem[(a)+3].cint # define height(a) varmem[(a)+4].cint # define shift_amount(a) vlink((a)+5) # define box_dir(a) vinfo((a)+5) # define list_ptr(a) vlink((a)+6) # define glue_order(a) subtype((a)+6) # define glue_sign(a) type((a)+6) # define glue_set(a) varmem[(a)+7].gr # define synctex_tag_box(a) vinfo((a)+8) # define synctex_line_box(a) vlink((a)+8) /* unset nodes */ # define glue_stretch(a) varmem[(a)+7].cint # define glue_shrink shift_amount # define span_count subtype # define rule_node_size 7 # define rule_dir(a) vlink((a)+5) # define synctex_tag_rule(a) vinfo((a)+6) # define synctex_line_rule(a) vlink((a)+6) # define mark_node_size 3 # define mark_ptr(a) vlink((a)+2) # define mark_class(a) vinfo((a)+2) # define adjust_node_size 3 # define adjust_pre subtype # define adjust_ptr(a) vlink(a+2) # define glyph_node_size 6 # define character(a) vinfo((a)+2) # define font(a) vlink((a)+2) # define lang_data(a) vinfo((a)+3) # define lig_ptr(a) vlink((a)+3) # define x_displace(a) vinfo((a)+4) # define y_displace(a) vlink((a)+4) # define ex_glyph(a) vinfo((a)+5) /* expansion factor (hz) */ # define is_char_node(a) (a!=null && type(a)==glyph_node) # define char_lang(a) ((const int)(signed short)(((signed int)((unsigned)lang_data(a)&0x7FFF0000)<<1)>>17)) # define char_lhmin(a) ((const int)(((unsigned)lang_data(a) & 0x0000FF00)>>8)) # define char_rhmin(a) ((const int)(((unsigned)lang_data(a) & 0x000000FF))) # define char_uchyph(a) ((const int)(((unsigned)lang_data(a) & 0x80000000)>>31)) # define make_lang_data(a,b,c,d) (a>0 ? (1<<31): 0)+ \ (b<<16)+ (((c>0 && c<256) ? c : 255)<<8)+(((d>0 && d<256) ? d : 255)) # define init_lang_data(a) lang_data(a)=256+1 # define set_char_lang(a,b) lang_data(a)=make_lang_data(char_uchyph(a),b,char_lhmin(a),char_rhmin(a)) # define set_char_lhmin(a,b) lang_data(a)=make_lang_data(char_uchyph(a),char_lang(a),b,char_rhmin(a)) # define set_char_rhmin(a,b) lang_data(a)=make_lang_data(char_uchyph(a),char_lang(a),char_lhmin(a),b) # define set_char_uchyph(a,b) lang_data(a)=make_lang_data(b,char_lang(a),char_lhmin(a),char_rhmin(a)) # define margin_kern_node_size 4 # define margin_char(a) vlink((a)+3) /*@# {|subtype| of marginal kerns}*/ # define left_side 0 # define right_side 1 # define math_node_size 4 # define surround(a) vlink((a)+2) # define before 0 /*|subtype| for math node that introduces a formula */ # define after 1 /*|subtype| for math node that winds up a formula */ # define synctex_tag_math(a) vinfo((a)+3) # define synctex_line_math(a) vlink((a)+3) # define ins_node_size 6 # define float_cost(a) varmem[(a)+2].cint # define ins_ptr(a) vinfo((a)+5) # define split_top_ptr(a) vlink((a)+5) # define page_ins_node_size 5 /* height = 4 */ typedef enum { hlist_node = 0, vlist_node = 1, rule_node, ins_node, mark_node, adjust_node, /* 6 used to be ligatures */ disc_node = 7, whatsit_node, math_node, glue_node, /* 10 */ kern_node, penalty_node, unset_node, style_node, choice_node, /* 15 */ simple_noad, old_op_noad, old_bin_noad, old_rel_noad, old_open_noad, /* 20 */ old_close_noad, old_punct_noad, old_inner_noad, radical_noad, fraction_noad, /* 25 */ old_under_noad, old_over_noad, accent_noad, old_vcenter_noad, fence_noad, /* 30 */ math_char_node, /* kernel fields */ sub_box_node, sub_mlist_node, math_text_char_node, delim_node, /* shield fields */ margin_kern_node, glyph_node, align_record_node, pseudo_file_node, pseudo_line_node, /* 40 */ inserting_node, split_up_node, expr_node, nesting_node, span_node, /* 45 */ attribute_node, glue_spec_node, attribute_list_node, action_node, temp_node, /* 50 */ align_stack_node, movement_node, if_node, unhyphenated_node, hyphenated_node, /* 55 */ delta_node, passive_node, shape_node, } node_types; # define MAX_NODE_TYPE 58 # define last_known_node temp_node /* used by \lastnodetype */ # define movement_node_size 3 # define expr_node_size 3 # define if_node_size 2 # define align_stack_node_size 6 # define nesting_node_size 2 # define span_node_size 3 # define span_span(a) vlink((a)+1) # define span_link(a) vinfo((a)+1) # define pseudo_file_node_size 2 # define pseudo_lines(a) vlink((a)+1) # define nodetype_has_attributes(t) (((t)<=glyph_node) && ((t)!=unset_node)) # define nodetype_has_subtype(t) ((t)!=action_node && (t)!=attribute_list_node && (t)!=attribute_node && (t)!=glue_spec_node) # define nodetype_has_prev(t) nodetype_has_subtype((t)) /* style and choice nodes */ /* style nodes can be smaller, the information is encoded in |subtype|, but choice nodes are on-the-spot converted to style nodes */ # define style_node_size 4 /* number of words in a style node */ # define display_mlist(a) vinfo((a)+2) /* mlist to be used in display style */ # define text_mlist(a) vlink((a)+2) /* mlist to be used in text style */ # define script_mlist(a) vinfo((a)+3) /* mlist to be used in script style */ # define script_script_mlist(a) vlink((a)+3) /* mlist to be used in scriptscript style */ /* regular noads */ # define noad_size 4 /* number of words in a normal noad */ # define new_hlist(a) vlink((a)+2) /* the translation of an mlist */ # define nucleus(a) vinfo((a)+2) /* the |nucleus| field of a noad */ # define supscr(a) vlink((a)+3) /* the |supscr| field of a noad */ # define subscr(a) vinfo((a)+3) /* the |subscr| field of a noad */ /* accent noads */ /* like a regular noad, but with two extra fields. */ # define accent_noad_size 5 /*number of |mem| words in an accent noad */ # define accent_chr(a) vinfo((a)+4) /* the |accent_chr| field of an accent noad */ # define bot_accent_chr(a) vlink((a)+4) /* the |bot_accent_chr| field of an accent noad */ /* left and right noads */ # define fence_noad_size 3 # define delimiter(a) vlink((a)+2) /* |delimiter| field in left and right noads */ /* subtype of fence noads */ # define left_noad_side 1 # define middle_noad_side 2 # define right_noad_side 3 /* fraction noads */ # define fraction_noad_size 5 /*number of |mem| words in a fraction noad */ # define thickness(a) vlink((a)+2) /* |thickness| field in a fraction noad */ # define numerator(a) vlink((a)+3) /*|numerator| field in a fraction noad */ # define denominator(a) vinfo((a)+3) /*|denominator| field in a fraction noad */ # define left_delimiter(a) vlink((a)+4) /* first delimiter field of a noad */ # define right_delimiter(a) vinfo((a)+4) /* second delimiter field of a fraction noad */ /* radical noads */ /* this is like a fraction, but it only stores a |left_delimiter| */ # define radical_noad_size 5 /*number of |mem| words in a radical noad */ # define degree(a) vinfo((a)+4) /* the root degree in a radical noad */ # define math_kernel_node_size 3 /* accessors for the |nucleus|-style node fields */ # define math_fam(a) vinfo((a)+2) # define math_character(a) vlink((a)+2) # define math_list(a) vlink((a)+2) /* accessors for the |delimiter|-style two-word subnode fields */ # define math_shield_node_size 4 /* not used yet */ # define small_fam(A) vinfo((A)+2) /* |fam| for ``small'' delimiter */ # define small_char(A) vlink((A)+2) /* |character| for ``small'' delimiter */ # define large_fam(A) vinfo((A)+3) /* |fam| for ``large'' delimiter */ # define large_char(A) vlink((A)+3) /* |character| for ``large'' delimiter */ typedef enum { open_node = 0, write_node, close_node, special_node, language_node, set_language_code, local_par_node, dir_node, pdf_literal_node, pdf_obj_code, pdf_refobj_node, /* 10 */ pdf_xform_code, pdf_refxform_node, pdf_ximage_code, pdf_refximage_node, pdf_annot_node, pdf_start_link_node, pdf_end_link_node, pdf_outline_code, pdf_dest_node, pdf_thread_node, /* 20 */ pdf_start_thread_node, pdf_end_thread_node, pdf_save_pos_node, pdf_thread_data_node, pdf_link_data_node, pdf_names_code, pdf_font_attr_code, pdf_include_chars_code, pdf_map_file_code, pdf_map_line_code, /* 30 */ pdf_trailer_code, pdf_font_expand_code, set_random_seed_code, pdf_glyph_to_unicode_code, late_lua_node, /* 35 */ close_lua_node, save_cat_code_table_code, init_cat_code_table_code, pdf_colorstack_node, pdf_setmatrix_node, /* 40 */ pdf_save_node, pdf_restore_node, cancel_boundary_node, user_defined_node /* 44 */ } whatsit_types; # define MAX_WHATSIT_TYPE 44 # define get_node_size(i,j) (i!=whatsit_node ? node_data[i].size : whatsit_node_data[j].size) # define get_node_name(i,j) (i!=whatsit_node ? node_data[i].name : whatsit_node_data[j].name) # define pdf_info_code pdf_thread_data_node # define pdf_catalog_code pdf_link_data_node # define GLYPH_CHARACTER (1 << 0) # define GLYPH_LIGATURE (1 << 1) # define GLYPH_GHOST (1 << 2) # define GLYPH_LEFT (1 << 3) # define GLYPH_RIGHT (1 << 4) # define is_character(p) ((subtype(p)) & GLYPH_CHARACTER) # define is_ligature(p) ((subtype(p)) & GLYPH_LIGATURE ) # define is_ghost(p) ((subtype(p)) & GLYPH_GHOST ) # define is_simple_character(p) (is_character(p) && !is_ligature(p) && !is_ghost(p)) # define is_leftboundary(p) (is_ligature(p) && ((subtype(p)) & GLYPH_LEFT )) # define is_rightboundary(p) (is_ligature(p) && ((subtype(p)) & GLYPH_RIGHT )) # define is_leftghost(p) (is_ghost(p) && ((subtype(p)) & GLYPH_LEFT )) # define is_rightghost(p) (is_ghost(p) && ((subtype(p)) & GLYPH_RIGHT )) # define set_is_glyph(p) subtype(p) = (quarterword) (subtype(p) & ~GLYPH_CHARACTER) # define set_is_character(p) subtype(p) = (quarterword) (subtype(p) | GLYPH_CHARACTER) # define set_is_ligature(p) subtype(p) = (quarterword) (subtype(p) | GLYPH_LIGATURE) # define set_is_ghost(p) subtype(p) = (quarterword) (subtype(p) |GLYPH_GHOST) # define set_to_glyph(p) subtype(p) = (quarterword)(subtype(p) & 0xFF00) # define set_to_character(p) subtype(p) = (quarterword)((subtype(p) & 0xFF00) | GLYPH_CHARACTER) # define set_to_ligature(p) subtype(p) = (quarterword)((subtype(p) & 0xFF00) | GLYPH_LIGATURE) # define set_to_ghost(p) subtype(p) = (quarterword)((subtype(p) & 0xFF00) | GLYPH_GHOST) # define set_is_leftboundary(p) { set_to_ligature(p); subtype(p) |= GLYPH_LEFT; } # define set_is_rightboundary(p) { set_to_ligature(p); subtype(p) |= GLYPH_RIGHT; } # define set_is_leftghost(p) { set_to_ghost(p); subtype(p) |= GLYPH_LEFT; } # define set_is_rightghost(p) { set_to_ghost(p); subtype(p) |= GLYPH_RIGHT; } # define special_node_size 3 # define dir_node_size 6 # define dir_dir(a) vinfo((a)+2) # define dir_level(a) vlink((a)+2) # define dir_dvi_ptr(a) vinfo((a)+3) # define dir_dvi_h(a) vlink((a)+3) /* obsolete */ # define dir_refpos_h(a) vinfo((a)+4) # define dir_refpos_v(a) vlink((a)+4) # define dir_cur_h(a) vinfo((a)+5) # define dir_cur_v(a) vlink((a)+5) # define write_node_size 3 # define close_node_size 3 # define write_tokens(a) vlink(a+2) # define write_stream(a) vinfo(a+2) # define open_node_size 4 # define open_name(a) vlink((a)+2) # define open_area(a) vinfo((a)+3) # define open_ext(a) vlink((a)+3) # define late_lua_node_size 4 # define late_lua_data(a) vlink((a)+2) # define late_lua_reg(a) vinfo((a)+2) # define late_lua_name(a) vlink((a)+3) # define late_lua_type(a) subtype((a)+3) # define local_par_size 6 # define local_pen_inter(a) vinfo((a)+2) # define local_pen_broken(a) vlink((a)+2) # define local_box_left(a) vlink((a)+3) # define local_box_left_width(a) vinfo((a)+3) # define local_box_right(a) vlink((a)+4) # define local_box_right_width(a) vinfo((a)+4) # define local_par_dir(a) vinfo((a)+5) /* type of literal data */ # define lua_refid_literal 1 /* not a |normal| string */ /* literal ctm types */ typedef enum { set_origin = 0, direct_page, direct_always, scan_special, } ctm_transform_modes; # define pdf_refobj_node_size 3 # define pdf_obj_objnum(a) vinfo((a) + 2) # define pdf_refxform_node_size 6 # define pdf_refximage_node_size 6 # define pdf_annot_node_size 8 # define pdf_dest_node_size 8 # define pdf_thread_node_size 8 /* when a whatsit node representing annotation is created, words |1..3| are width, height and depth of this annotation; after shipping out words |1..4| are rectangle specification of annotation. For whatsit node representing destination |pdf_ann_left| and |pdf_ann_top| are used for some types of destinations */ /* coordinates of destinations/threads/annotations (in whatsit node) */ # define pdf_ann_left(a) varmem[(a) + 2].cint # define pdf_ann_top(a) varmem[(a) + 3].cint # define pdf_ann_right(a) varmem[(a) + 4].cint # define pdf_ann_bottom(a) varmem[(a) + 5].cint # define pdf_literal_data(a) vlink((a)+2) # define pdf_literal_mode(a) type((a)+2) # define pdf_literal_type(a) subtype((a)+2) # define pdf_ximage_index(a) vinfo((a) + 5) /* /Im* number and image index in array */ # define pdf_ximage_transform(a) vlink((a) + 5) # define pdf_xform_objnum(a) vinfo((a) + 5) # define pdf_xform_transform(a) vlink((a) + 5) # define pdf_annot_data(a) vinfo((a) + 6) # define pdf_link_attr(a) vinfo((a) + 6) # define pdf_link_action(a) vlink((a) + 6) # define pdf_annot_objnum(a) varmem[(a) + 7].cint # define pdf_link_objnum(a) varmem[(a) + 7].cint # define pdf_dest_type(a) type((a) + 6) # define pdf_dest_named_id(a) subtype((a) + 6) # define pdf_dest_id(a) vlink((a) + 6) # define pdf_dest_xyz_zoom(a) vinfo((a) + 7) # define pdf_dest_objnum(a) vlink((a) + 7) # define pdf_thread_named_id(a) subtype((a) + 6) # define pdf_thread_id(a) vlink((a) + 6) # define pdf_thread_attr(a) vinfo((a) + 7) # define pdf_end_link_node_size 3 # define pdf_end_thread_node_size 3 # define pdf_save_pos_node_size 3 # define pdf_colorstack_node_size 4 # define pdf_setmatrix_node_size 3 # define pdf_colorstack_stack(a) vlink((a)+2) # define pdf_colorstack_cmd(a) vinfo((a)+2) # define pdf_colorstack_data(a) vlink((a)+3) # define pdf_setmatrix_data(a) vlink((a)+2) # define pdf_save_node_size 3 # define pdf_restore_node_size 3 typedef enum { colorstack_set = 0, colorstack_push, colorstack_pop, colorstack_current } colorstack_commands; # define colorstack_data colorstack_push /* last value where data field is set */ # define user_defined_node_size 4 # define user_node_type(a) vinfo((a)+2) # define user_node_id(a) vlink((a)+2) # define user_node_value(a) vinfo((a)+3) # define cancel_boundary_size 3 # define active_node_size 4 /*number of words in extended active nodes */ # define fitness subtype /*|very_loose_fit..tight_fit| on final line for this break */ # define break_node(a) vlink((a)+1) /*pointer to the corresponding passive node */ # define line_number(a) vinfo((a)+1) /*line that begins at this breakpoint */ # define total_demerits(a) varmem[(a)+2].cint /* the quantity that \TeX\ minimizes */ # define active_short(a) vinfo(a+3) /* |shortfall| of this line */ # define active_glue(a) vlink(a+3) /*corresponding glue stretch or shrink */ # define passive_node_size 7 # define cur_break(a) vlink((a)+1) /*in passive node, points to position of this breakpoint */ # define prev_break(a) vinfo((a)+1) /*points to passive node that should precede this one */ # define passive_pen_inter(a) vinfo((a)+2) # define passive_pen_broken(a) vlink((a)+2) # define passive_left_box(a) vlink((a)+3) # define passive_left_box_width(a) vinfo((a)+3) # define passive_last_left_box(a) vlink((a)+4) # define passive_last_left_box_width(a) vinfo((a)+4) # define passive_right_box(a) vlink((a)+5) # define passive_right_box_width(a) vinfo((a)+5) # define serial(a) vlink((a)+6) /* serial number for symbolic identification */ # define delta_node_size 10 /* 8 fields, stored in a+1..9 */ # define couple_nodes(a,b) {assert(b!=null);vlink(a)=b;alink(b)=a;} # define try_couple_nodes(a,b) if (b==null) vlink(a)=b; else {couple_nodes(a,b);} # define uncouple_node(a) {assert(a!=null);vlink(a)=null;alink(a)=null;} # define cache_disabled max_halfword extern void delete_attribute_ref(halfword b); extern void build_attribute_list(halfword b); extern int unset_attribute(halfword n, int c, int w); extern void set_attribute(halfword n, int c, int w); extern int has_attribute(halfword n, int c, int w); extern halfword new_span_node(halfword n, int c, scaled w); extern void print_short_node_contents(halfword n); extern void show_node_list(int i); extern pointer actual_box_width(pointer r, scaled base_width); /* TH: these two defines still need checking. The node ordering in luatex is not quite the same as in tex82 */ # define precedes_break(a) (type((a))