tex::glue_t::glue_t(glue_t *q) { tex::type(this) = GLUE_NODE; tex::subtype(this) = NORMAL; leader_ptr(this) = 0; glue_ptr(this) = q; incr(glue_ref_count(q)); }
void tex::show_leaders(ptr p) { print_esc(null_str); if (tex::subtype(p) == C_LEADERS) print("c"); else if (tex::subtype(p) == X_LEADERS) print("x"); print("leaders "); print_spec(glue_ptr(p), null_str); node_list_display(leader_ptr(p)); }
void pdf_vlist_out (void) { scaled left_edge; scaled top_edge; scaled save_h, save_v; pointer this_box; // glue_ord g_order; int g_order; // char g_sign; int g_sign; pointer p; integer save_loc; pointer leader_box; scaled leader_ht; scaled lx; boolean outer_doing_leaders; scaled edge; real glue_temp; real cur_glue; scaled cur_g; cur_g = 0; cur_glue = 0.0; this_box = temp_ptr; g_order = glue_order(this_box); g_sign = glue_sign(this_box); p = list_ptr(this_box); incr(cur_s); if (cur_s > max_push) max_push = cur_s; save_loc = dvi_offset + dvi_ptr; left_edge = cur_h; cur_v = cur_v - height(this_box); top_edge = cur_v; while (p != 0) { if (is_char_node(p)) { confusion("vlistout"); return; } else { switch (type(p)) { case hlist_node: case vlist_node: if (list_ptr(p) == 0) cur_v = cur_v + height(p) + depth(p); else { cur_v = cur_v + height(p); pdf_synch_v(); save_h = dvi_h; save_v = dvi_v; cur_h = left_edge + shift_amount(p); temp_ptr = p; if (type(p) == vlist_node) pdf_vlist_out(); else pdf_hlist_out(); dvi_h = save_h; dvi_v = save_v; cur_v = save_v + depth(p); cur_h = left_edge; } break; case rule_node: { rule_ht = height(p); rule_dp = depth(p); rule_wd = width(p); goto fin_rule; } break; case whatsit_node: out_what(p); break; case glue_node: { g = glue_ptr(p); rule_ht = width(g) - cur_g; if (g_sign != normal) { if (g_sign == stretching) { if (stretch_order(g) == g_order) { cur_glue = cur_glue + stretch(g); vet_glue(glue_set(this_box) * cur_glue); cur_g = round(glue_temp); } } else if (shrink_order(g) == g_order) /* BUG FIX !!! */ { cur_glue = cur_glue - shrink(g); vet_glue(glue_set(this_box) * cur_glue); cur_g = round(glue_temp); } } rule_ht = rule_ht + cur_g; if (subtype(p) >= a_leaders) { leader_box = leader_ptr(p); if (type(leader_box) == rule_node) { rule_wd = width(leader_box); rule_dp = 0; goto fin_rule; } leader_ht = height(leader_box) + depth(leader_box); if ((leader_ht > 0) && (rule_ht > 0)) { rule_ht = rule_ht + 10; edge = cur_v + rule_ht; lx = 0; if (subtype(p) == a_leaders) { save_v = cur_v; cur_v = top_edge + leader_ht * ((cur_v - top_edge) / leader_ht); if (cur_v < save_v) cur_v = cur_v + leader_ht; } else { lq = rule_ht / leader_ht; lr = rule_ht % leader_ht; if (subtype(p) == c_leaders) cur_v = cur_v + (lr / 2); else { lx = (2 * lr + lq + 1) / (2 * lq + 2); cur_v = cur_v + ((lr - (lq - 1) * lx) / 2); } } while (cur_v + leader_ht <= edge) { cur_h = left_edge + shift_amount(leader_box); pdf_synch_h(); save_h = dvi_h; cur_v = cur_v + height(leader_box); pdf_synch_v(); save_v = dvi_v; temp_ptr = leader_box; outer_doing_leaders = doing_leaders; doing_leaders = true; if (type(leader_box) == vlist_node) pdf_vlist_out(); else pdf_hlist_out(); doing_leaders = outer_doing_leaders; dvi_v = save_v; dvi_h = save_h; cur_h = left_edge; cur_v = save_v - height(leader_box) + leader_ht + lx; } cur_v = edge - 10; goto next_p; } } goto move_past; } break; case kern_node: cur_v = cur_v + width(p); break; default: break; } goto next_p; fin_rule: if (is_running(rule_wd)) rule_wd = width(this_box); rule_ht = rule_ht + rule_dp; cur_v = cur_v + rule_ht; if ((rule_ht > 0) && (rule_wd > 0)) { pdf_synch_h(); pdf_synch_v(); pdf_dev_set_rule(dvi_h, -dvi_v, rule_wd, rule_ht); } goto next_p; move_past: cur_v = cur_v + rule_ht; } next_p: p = link(p); } prune_movements(save_loc); decr(cur_s); }
void pdf_hlist_out (void) { scaled base_line; scaled left_edge; scaled save_h, save_v; pointer this_box; // glue_ord g_order; int g_order; // char g_sign; int g_sign; pointer p; integer save_loc; pointer leader_box; scaled leader_wd; scaled lx; boolean outer_doing_leaders; scaled edge; real glue_temp; real cur_glue; scaled cur_g; cur_g = 0; cur_glue = 0.0; this_box = temp_ptr; g_order = glue_order(this_box); g_sign = glue_sign(this_box); p = list_ptr(this_box); incr(cur_s); if (cur_s > max_push) max_push = cur_s; save_loc = dvi_offset + dvi_ptr; base_line = cur_v; left_edge = cur_h; while (p != 0) reswitch: if (is_char_node(p)) { pdf_synch_h(); pdf_synch_v(); do { f = font(p); c = character(p); if (f != dvi_f) { if (!font_used[f]) { font_used[f] = true; font_id[f] = pdf_get_font_id(f); } dvi_f = f; } pdf_out_char(dvi_f, c); cur_h = cur_h + char_width(f, char_info(f, c)); p = link(p); } while (!(!is_char_node(p))); dvi_h = cur_h; } else { switch (type(p)) { case hlist_node: case vlist_node: if (list_ptr(p) == 0) cur_h = cur_h + width(p); else { save_h = dvi_h; save_v = dvi_v; cur_v = base_line + shift_amount(p); temp_ptr = p; edge = cur_h; if (type(p) == vlist_node) pdf_vlist_out(); else pdf_hlist_out(); dvi_h = save_h; dvi_v = save_v; cur_h = edge + width(p); cur_v = base_line; } break; case rule_node: { rule_ht = height(p); rule_dp = depth(p); rule_wd = width(p); goto fin_rule; } break; case whatsit_node: out_what(p); break; case glue_node: { g = glue_ptr(p); rule_wd = width(g) - cur_g; if (g_sign != normal) { if (g_sign == stretching) { if (stretch_order(g) == g_order) { cur_glue = cur_glue + stretch(g); vet_glue(glue_set(this_box) * cur_glue); cur_g = round(glue_temp); } } else if (shrink_order(g) == g_order) { cur_glue = cur_glue - shrink(g); vet_glue(glue_set(this_box) * cur_glue); cur_g = round(glue_temp); } } rule_wd = rule_wd + cur_g; if (subtype(p) >= a_leaders) { leader_box = leader_ptr(p); if (type(leader_box) == rule_node) { rule_ht = height(leader_box); rule_dp = depth(leader_box); goto fin_rule; } leader_wd = width(leader_box); if ((leader_wd > 0) && (rule_wd > 0)) { rule_wd = rule_wd + 10; edge = cur_h + rule_wd; lx = 0; if (subtype(p) == a_leaders) { save_h = cur_h; cur_h = left_edge + leader_wd * ((cur_h - left_edge) / leader_wd); if (cur_h < save_h) cur_h = cur_h + leader_wd; } else { lq = rule_wd / leader_wd; lr = rule_wd % leader_wd; if (subtype(p) == c_leaders) cur_h = cur_h + (lr / 2); else { lx = (2 * lr + lq + 1) / (2 * lq + 2); cur_h = cur_h + ((lr - (lq - 1)* lx) / 2); } } while (cur_h + leader_wd <= edge) { cur_v = base_line + shift_amount(leader_box); pdf_synch_v(); save_v = dvi_v; pdf_synch_h(); save_h = dvi_h; temp_ptr = leader_box; outer_doing_leaders = doing_leaders; doing_leaders = true; if (type(leader_box) == vlist_node) pdf_vlist_out(); else pdf_hlist_out(); doing_leaders = outer_doing_leaders; dvi_v = save_v; dvi_h = save_h; cur_v = base_line; cur_h = save_h + leader_wd + lx; } cur_h = edge - 10; goto next_p; } } goto move_past; } break; case kern_node: case math_node: cur_h = cur_h + width(p); break; case ligature_node: { mem[lig_trick] = mem[lig_char(p)]; link(lig_trick) = link(p); p = lig_trick; goto reswitch; } break; default: break; } goto next_p; fin_rule: if (is_running(rule_ht)) rule_ht = height(this_box); if (is_running(rule_dp)) rule_dp = depth(this_box); rule_ht = rule_ht + rule_dp; if ((rule_ht > 0) && (rule_wd > 0)) { pdf_synch_h(); cur_v = base_line + rule_dp; pdf_synch_v(); pdf_dev_set_rule(dvi_h, -dvi_v, rule_wd, rule_ht); cur_v = base_line; dvi_h = dvi_h + rule_wd; } move_past: cur_h = cur_h + rule_wd; next_p: p = link(p); } prune_movements(save_loc); decr(cur_s); }
void tex::box_end(int box_context) { ptr p; #define LEADERS "Leaders not followed by proper glue" if (box_context < BOX_FLAG) { if (cur_box != null) { shift_amount(cur_box) = box_context; if (abs(mode) == VMODE) { append_to_vlist(cur_box); if (tex::adjust_tail != null) { if (tex::adjust_head != tex::adjust_tail) { link(tail) = link(tex::adjust_head); tail = tex::adjust_tail; } tex::adjust_tail = null; } if (mode > 0) build_page(); } else { if (abs(mode) == HMODE) { space_factor = 1000; } else { p = new_noad(); math_type(nucleus(p)) = SUB_BOX; info(nucleus(p)) = cur_box; cur_box = p; } tail_append(cur_box); } } } else if (box_context < SHIP_OUT_FLAG) { if (box_context < BOX_FLAG + 256) { reg_define(box_reg[box_context - BOX_FLAG], BOX_REG, cur_box); } else { reg_gdefine(box_reg[box_context - BOX_FLAG - 256], BOX_REG, cur_box); } } else if (cur_box != null) { if (box_context > SHIP_OUT_FLAG) { get_nbrx_token(); if (cur_cmd == HSKIP && abs(mode) != VMODE || cur_cmd == VSKIP && abs(mode) == VMODE || cur_cmd == MSKIP && abs(mode) == MMODE) { append_glue(); leader_ptr(tail) = cur_box; subtype(tail) = box_context - (LEADER_FLAG - A_LEADERS); } else { print_err(LEADERS); help_leaders(); back_error(); flush_node_list(cur_box); } } else { ship_out(cur_box); } } }
ptr tex::copy_node_list(ptr p) { ptr h; ptr q; ptr r=0; h = q = new_avail(); while (p != null) { if (is_char_node(p)) { r = new_avail(); font(r) = font(p); character(r) = character(p); } else { switch (type(p)) { case HLIST_NODE: case VLIST_NODE: case UNSET_NODE: r = tex::new_node(BOX_NODE_SIZE); memcpy((void *)r, (void *)p, BOX_NODE_SIZE); list_ptr(r) = copy_node_list(list_ptr(p)); break; case RULE_NODE: r = tex::new_node(RULE_NODE_SIZE); memcpy((void *)r, (void *)p, RULE_NODE_SIZE); break; case INS_NODE: r = tex::new_node(INS_NODE_SIZE); memcpy((void *)r, (void *)p, INS_NODE_SIZE); add_glue_ref(split_top_ptr(p)); ins_ptr(r) = copy_node_list(ins_ptr(p)); break; case WHATSIT_NODE: r = copy_whatsit(p); break; case GLUE_NODE: r = tex::new_node(SMALL_NODE_SIZE); memcpy((void *)r, (void *)p, SMALL_NODE_SIZE); add_glue_ref(glue_ptr(p)); glue_ptr(r) = glue_ptr(p); leader_ptr(r) = copy_node_list(leader_ptr(p)); break; case KERN_NODE: case MATH_NODE: case PENALTY_NODE: r = tex::new_node(SMALL_NODE_SIZE); memcpy((void *)r, (void *)p, SMALL_NODE_SIZE); break; case LIGATURE_NODE: r = tex::new_node(SMALL_NODE_SIZE); memcpy((void *)r, (void *)p, SMALL_NODE_SIZE); lig_ptr(r) = copy_node_list(lig_ptr(p)); break; case DISC_NODE: r = tex::new_node(SMALL_NODE_SIZE); memcpy((void *)r, (void *)p, SMALL_NODE_SIZE); pre_break(r) = copy_node_list(pre_break(p)); post_break(r) = copy_node_list(post_break(p)); break; case MARK_NODE: r = tex::new_node(SMALL_NODE_SIZE); memcpy((void *)r, (void *)p, SMALL_NODE_SIZE); add_token_ref(mark_ptr(p)); break; case ADJUST_NODE: r = tex::new_node(SMALL_NODE_SIZE); memcpy((void *)r, (void *)p, SMALL_NODE_SIZE); adjust_ptr(r) = copy_node_list(adjust_ptr(p)); break; default: confusion("copying"); break; } } q = link(q) = r; p = link(p); } link(q) = null; q = link(h); free_avail(h); return q; }
void tex::flush_node_list(ptr p) { ptr q; while (p != null) { q = link(p); if (is_char_node(p)) { free_avail(p); } else { switch (type(p)) { case HLIST_NODE: case VLIST_NODE: case UNSET_NODE: flush_node_list(list_ptr(p)); free_node(p, BOX_NODE_SIZE); goto done; case RULE_NODE: free_node(p, RULE_NODE_SIZE); goto done; case INS_NODE: flush_node_list(ins_ptr(p)); delete_glue_ref(split_top_ptr(p)); free_node(p, INS_NODE_SIZE); goto done; case WHATSIT_NODE: free_whatsit(p); goto done; case GLUE_NODE: fast_delete_glue_ref(glue_ptr(p)); if (leader_ptr(p) != null) flush_node_list(leader_ptr(p)); break; case KERN_NODE: case MATH_NODE: case PENALTY_NODE: break; case LIGATURE_NODE: flush_node_list(lig_ptr(p)); break; case MARK_NODE: delete_token_ref(mark_ptr(p)); break; case DISC_NODE: flush_node_list(pre_break(p)); flush_node_list(post_break(p)); break; case ADJUST_NODE: flush_node_list(adjust_ptr(p)); break; case STYLE_NODE: free_node(p, STYLE_NODE_SIZE); goto done; case CHOICE_NODE: flush_node_list(display_mlist(p)); flush_node_list(text_mlist(p)); flush_node_list(script_mlist(p)); flush_node_list(script_script_mlist(p)); free_node(p, STYLE_NODE_SIZE); goto done; case ORD_NOAD: case OP_NOAD: case BIN_NOAD: case REL_NOAD: case OPEN_NOAD: case CLOSE_NOAD: case PUNCT_NOAD: case INNER_NOAD: case RADICAL_NOAD: case OVER_NOAD: case UNDER_NOAD: case VCENTER_NOAD: case ACCENT_NOAD: if (math_type(nucleus(p)) >= SUB_BOX) flush_node_list(math_link(nucleus(p))); if (math_type(supscr(p)) >= SUB_BOX) flush_node_list(math_link(supscr(p))); if (math_type(subscr(p)) >= SUB_BOX) flush_node_list(math_link(subscr(p))); if (type(p) == RADICAL_NOAD) free_node(p, RADICAL_NOAD_SIZE); else if (type(p) == ACCENT_NOAD) free_node(p, ACCENT_NOAD_SIZE); else free_node(p, NOAD_SIZE); goto done; case LEFT_NOAD: case RIGHT_NOAD: free_node(p, NOAD_SIZE); goto done; case FRACTION_NOAD: flush_node_list(math_link(numerator(p))); flush_node_list(math_link(denominator(p))); free_node(p, FRACTION_NOAD_SIZE); goto done; default: confusion("flushing"); break; } free_node(p, SMALL_NODE_SIZE); done:; } p = q; } }