void tex::delete_last () { int m; ptr p=0, q; if (mode == VMODE && tail == head) { if (cur_chr != GLUE_NODE || last_glue != null) { you_cant(); if (cur_chr == KERN_NODE) { help_delete_last_kern(); } else if (cur_chr == GLUE_NODE) { help_delete_last_skip(); } else { help_delete_last_pen(); } error(); } } else if (!is_char_node(tail) && type(tail) == cur_chr) { for (q = head; q != tail; q = link(p)) { p = q; if (!is_char_node(q) && type(q) == DISC_NODE) { for (m = 1; m <= replace_count(q); incr(m)) p = link(p); if (p == tail) return; } } link(p) = null; flush_node_list(tail); tail = p; } }
void tex::flush_discretionary(ptr p) { begin_diagnostic(); print_nl("The following discretionary sublist has been deleted:"); show_box(p); end_diagnostic(TRUE); flush_node_list(p); }
void tex::box_error(int n) { error(); begin_diagnostic(); print_nl("The following box has been deleted:"); show_box(box(n)); end_diagnostic(TRUE); flush_node_list(box(n)); box(n) = null; }
ptr tex::prune_page_top(ptr p) { mcell m; ptr prev_p; ptr q, s, t; t = (ptr)&m; prev_p = t; link(t) = p; while (p != null) { switch (type(p)) { case HLIST_NODE: case VLIST_NODE: case RULE_NODE: q = new_skip_param(SPLIT_TOP_SKIP_CODE); link(prev_p) = q; link(q) = p; s = glue_ptr(q); if (glue_width(s) > box_height(p)) { glue_width(s) -= box_height(p); } else { glue_width(s) = 0; } p = null; break; case WHATSIT_NODE: case MARK_NODE: case INS_NODE: prev_p = p; p = link(p); break; case GLUE_NODE: case KERN_NODE: case PENALTY_NODE: q = p; p = link(p); link(q) = null; link(prev_p) = p; flush_node_list(q); break; default: confusion("pruning"); break; } } return (link(t)); }
void do_extension(int immediate) { halfword p; if(cur_cmd==extension_cmd){ switch(cur_chr){ case open_code: p= tail; new_write_whatsit(open_node_size,1); scan_optional_equals(); scan_file_name(); open_name(tail)= cur_name; open_area(tail)= cur_area; open_ext(tail)= cur_ext; if(immediate){ out_what(static_pdf,tail); flush_node_list(tail); tail= p; vlink(p)= null; } break; case write_code: p= tail; new_write_whatsit(write_node_size,0); cur_cs= write_stream(tail); scan_toks(false,false); write_tokens(tail)= def_ref; if(immediate){ out_what(static_pdf,tail); flush_node_list(tail); tail= p; vlink(p)= null; } break; case close_code: p= tail; new_write_whatsit(close_node_size,1); write_tokens(tail)= null; if(immediate){ out_what(static_pdf,tail); flush_node_list(tail); tail= p; vlink(p)= null; } break; case special_code: new_whatsit(special_node); write_stream(tail)= null; p= scan_toks(false,true); write_tokens(tail)= def_ref; break; case immediate_code: get_x_token(); do_extension(1); break; case use_box_resource_code: case use_image_resource_code: case save_box_resource_code: case save_image_resource_code: switch(get_o_mode()){ case OMODE_DVI: do_resource_dvi(immediate,cur_chr); break; case OMODE_PDF: do_resource_pdf(immediate,cur_chr); break; default: break; } break; case dvi_extension_code: if(get_o_mode()==OMODE_DVI) do_extension_dvi(immediate); break; case pdf_extension_code: if(get_o_mode()==OMODE_PDF) do_extension_pdf(immediate); break; default: if(immediate){ back_input(); }else{ confusion("invalid extension"); } break; } }else{ back_input(); } }
void hyphenate () { str t, u; ptr q, r, s; ptr hyf_node; int bchar; int c_loc; int r_count; ptr major_tail; ptr minor_tail; int c, h, i, j, l, v, z; for (j = 0; j <= hn; incr(j)) hyf[j] = 0; h = hc[1]; incr(hn); hc[hn] = cur_lang; for (j = 2; j <= hn; incr(j)) h = (h + h + hc[j]) % HYPH_SIZE; loop { t = hyph_word[h]; if (t == null_str) goto not_found; l = hyph_len[h]; if (l < hn) goto not_found; if (l == hn) { j = 1; u = t; while (j <= hn) { if (*u < hc[j]) goto not_found; if (*u > hc[j]) goto done; incr(u); incr(j); } for (s = hyph_list[h]; s != null; s = link(s)) hyf[info(s)] = 1; decr(hn); goto found; } done: if (h > 0) { decr(h); } else { h = HYPH_SIZE; } } not_found: decr(hn); if (trie_char(cur_lang + 1) != cur_lang) return; hc[0] = 0; hc[hn + 1] = 0; hc[hn + 2] = 256; for (j = 0; j <= hn - r_hyf + 1; incr(j)) { z = trie_link(cur_lang + 1) + hc[j]; l = j; while (hc[l] == trie_char(z)) { if (v = trie_op(z)) { while (v) { v += op_start[cur_lang]; i = l - hyf_distance[v]; if (hyf_num[v] > hyf[i]) hyf[i] = hyf_num[v]; v = hyf_next[v]; } } incr(l); z = trie_link(z) + hc[l]; } } found: for (j = 0; j < l_hyf; incr(j)) { hyf[j] = 0; } for (j = 0; j < r_hyf; incr(j)) { hyf[hn - j] = 0; } for (j = l_hyf; j <= hn - r_hyf; incr(j)) if (odd(hyf[j])) goto found1; return; found1: q = link(hb); link(hb) = null; r = link(ha); link(ha) = null; bchar = NON_CHAR; if (type(hb) == LIGATURE_NODE && odd(subtype(hb))) { bchar = font_bchar(hf); } if (is_char_node(ha)) { if (font(ha) != hf) { goto found2; } else { init_list = ha; init_lig = FALSE; hu[0] = character(ha); } } else if (type(ha) == LIGATURE_NODE) { if (font(lig_char(ha)) != hf) { goto found2; } else { init_list = lig_ptr(ha); init_lig = TRUE; init_lft = subtype(ha) > 1; hu[0] = character(lig_char(ha)); if (init_list == null && init_lft) { hu[0] = 256; init_lig = FALSE; } free_node(ha, SMALL_NODE_SIZE); } } else { if (type(r) == LIGATURE_NODE && subtype(r) > 1) { goto found2; } j = 1; s = ha; init_list = null; goto common_end; } s = cur_p; while (link(s) != ha) s = link(s); j = 0; goto common_end; found2: s = ha; j = 0; hu[0] = 256; init_lig = FALSE; init_list = null; common_end: flush_node_list(r); #define advance_major_tail() \ { major_tail = link(major_tail); \ incr(r_count); \ } #define put_pre_break() \ { minor_tail = null; \ pre_break(r) = null; \ hyf_node = new_character(hf, hyf_char); \ if (hyf_node != null) { \ incr(i); \ c = hu[i]; \ hu[i] = hyf_char; \ free_avail(hyf_node); \ } \ while (l <= i) { \ l = reconstitute(l, i, font_bchar(hf), NON_CHAR) + 1; \ if (link(hold_head) == null) { \ continue; \ } \ if (minor_tail == null) { \ pre_break(r) = link(hold_head); \ } else { \ link(minor_tail) = link(hold_head); \ } \ minor_tail = link(hold_head); \ while (link(minor_tail) != null) \ minor_tail = link(minor_tail); \ } \ if (hyf_node != null) { \ hu[i] = c; \ l = i; \ decr(i); \ } \ } #define put_post_break() \ { minor_tail = null; \ post_break(r) = null; \ c_loc = 0; \ if (bchar_label(hf) != NON_ADDRESS) { \ decr(l); \ c = hu[l]; \ c_loc = l; \ hu[l] = 256; \ } \ while (l < j) { \ do { \ l = reconstitute(l, hn, bchar, NON_CHAR) + 1; \ if (c_loc > 0) { \ hu[c_loc] = c; \ c_loc = 0; \ } \ if (link(hold_head) == null) { \ continue; \ } \ if (minor_tail == null) { \ post_break(r) = link(hold_head); \ } else { \ link(minor_tail) = link(hold_head); \ } \ minor_tail = link(hold_head); \ while (link(minor_tail) != null) \ minor_tail = link(minor_tail); \ } while (l < j); \ while (l > j) { \ j = reconstitute(j, hn, bchar, NON_CHAR) + 1; \ link(major_tail) = link(hold_head); \ while (link(major_tail) != null) { \ advance_major_tail(); \ } \ } \ } \ } do { l = j; j = reconstitute(j, hn, bchar, hyf_char) + 1; if (hyphen_passed == 0) { link(s) = link(hold_head); while (link(s) != null) s = link(s); if (odd(hyf[j - 1])) { l = j; hyphen_passed = j - 1; link(hold_head) = null; } } if (hyphen_passed > 0) { do { r = new_node(SMALL_NODE_SIZE); link(r) = link(hold_head); type(r) = DISC_NODE; major_tail = r; r_count = 0; while (link(major_tail) != null) { advance_major_tail(); } i = hyphen_passed; hyf[i] = 0; put_pre_break(); put_post_break(); if (r_count > 127) { link(s) = link(r); link(r) = null; flush_node_list(r); } else { link(s) = r; replace_count(r) = r_count; } s = major_tail; hyphen_passed = j - 1; link(hold_head) = null; } while (odd(hyf[j - 1])); } } while (j <= hn); link(s) = q; flush_list(init_list); }
void pdf_ship_out (pointer p) { integer page_loc; char j, k; if (tracing_output > 0) { print_nl(""); print_ln(); prints("Completed box being shipped out"); } if (term_offset > max_print_line - 9) print_ln(); else if ((term_offset > 0) || (file_offset > 0)) print_char(' '); print_char('['); j = 9; while ((count(j) == 0) && (j > 0)) decr(j); for (k = 0; k <= j; k++) { print_int(count(k)); if (k < j) print_char('.'); } update_terminal(); if (tracing_output > 0) { print_char(']'); begin_diagnostic(); show_box(p); end_diagnostic(true); } if ((height(p) > max_dimen) || (depth(p) > max_dimen) || (height(p) + depth(p) + v_offset > max_dimen) || (width(p) + h_offset > max_dimen)) { print_err("Huge page cannot be shipped out"); help2("The page just created is more than 18 feet tall or", "more than 18 feet wide, so I suspect something went wrong."); error(); if (tracing_output <= 0) { begin_diagnostic(); print_nl("The following box has been deleted:"); show_box(p); end_diagnostic(true); } goto done; } if (height(p) + depth(p) + v_offset > max_v) max_v = height(p) + depth(p) + v_offset; if (width(p) + h_offset > max_h) max_h = width(p) + h_offset; dvi_h = 0; dvi_v = 0; cur_h = h_offset; dvi_f = null_font; ensure_pdf_open(); if (total_pages == 0) { pdf_set_version(5); pdf_set_compression(9); pdf_init_fontmaps(); read_config_file("dvipdfmx.cfg"); pdf_doc_set_producer("Y&YTeX 2.3.0"); pdf_doc_set_creator("TeX"); pdf_files_init(); pdf_init_device(0.000015202, 2, 0); // TODO: pdfTeX's page width and height. // page_width = pdf_page_width != 0 ? <- : width(p) + 2 * (pdf_h_origin + h_offset); // page_height = pdf_page_height != 0 ? <- : height(p) + depth(p) + 2 * (pdf_v_origin + v_offset); pdf_open_document(pdf_file_name, 0, 595.0, 842.0, 0, 0, (1 << 4)); spc_exec_at_begin_document(); } page_loc = dvi_offset + dvi_ptr; pdf_doc_begin_page(1.0, 72.0, 770.0); spc_exec_at_begin_page(); last_bop = page_loc; cur_v = height(p) + v_offset; temp_ptr = p; if (type(p) == vlist_node) pdf_vlist_out(); else pdf_hlist_out(); spc_exec_at_end_page(); pdf_doc_end_page(); incr(total_pages); cur_s = -1; done: if (tracing_output <= 0) print_char(']'); dead_cycles = 0; update_terminal(); #ifdef STAT if (tracing_stats > 1) { print_nl("Memory usage before: "); print_int(var_used); print_char('&'); print_int(dyn_used); print_char(';'); } #endif flush_node_list(p); #ifdef STAT if (tracing_stats > 1) { prints(" after: "); print_int(var_used); print_char('&'); print_int(dyn_used); prints("; still utouched: "); print_int(hi_mem_min - lo_mem_max - 1); print_ln(); } #endif }
void tex::build_page () { int pi=0, b, c; ptr p, q, r; #define INF_SHRINK_PAGE "Infinite glue shrinkage found on current page" if (link(contrib_head) == null || output_active) return; do { p = link(contrib_head); if (last_glue != null) delete_glue_ref(last_glue); last_penalty = 0; last_kern = 0; if (type(p) == GLUE_NODE) { last_glue = glue_ptr(p); add_glue_ref(last_glue); } else { last_glue = null; if (type(p) == PENALTY_NODE) { last_penalty = penalty(p); } else if (type(p) == KERN_NODE) { last_kern = kern_width(p); } } switch (type(p)) { case HLIST_NODE: case VLIST_NODE: case RULE_NODE: if (page_contents < BOX_THERE) { if (page_contents == EMPTY) { freeze_page_specs(BOX_THERE); } else { page_contents = BOX_THERE; } q = new_skip_param(TOP_SKIP_CODE); link(q) = p; link(contrib_head) = q; r = glue_ptr(q); if (glue_width(r) > box_height(p)) { glue_width(r) -= box_height(p); } else { glue_width(r) = 0; } continue; } else { page_total += page_depth + box_height(p); page_depth = box_depth(p); goto contribute; } case GLUE_NODE: if (page_contents < BOX_THERE) { goto done; } else if (precedes_break(page_tail)) { pi = 0; } else { goto update_heights; } break; case KERN_NODE: if (page_contents < BOX_THERE) { goto done; } else if (link(p) == null) { return; } else if (type(link(p)) == GLUE_NODE) { pi = 0; } else { goto update_heights; } break; case PENALTY_NODE: if (page_contents < BOX_THERE) { goto done; } else { pi = penalty(p); } break; case WHATSIT_NODE: goto contribute; case MARK_NODE: goto contribute; case INS_NODE: insert_page(p); goto contribute; default: confusion("page"); break; } if (pi < INF_PENALTY) { b = page_badness(); if (b < AWFUL_BAD) { if (pi <= EJECT_PENALTY) { c = pi; } else if (b < INF_BAD) { c = b + pi + insert_penalties; } else { c = DEPLORABLE; } } else { c = b; } if (insert_penalties >= 10000) c = AWFUL_BAD; if (tracing_pages > 0) show_page_stats(b, pi, c); if (c <= least_page_cost) { best_page_break = p; best_size = page_goal; least_page_cost = c; r = link(page_ins_head); while (r != page_ins_head) { best_ins_ptr(r) = last_ins_ptr(r); r = link(r); } } if (c == AWFUL_BAD || pi <= EJECT_PENALTY) { fire_up(p); if (output_active) return; continue; } } if (type(p) < GLUE_NODE || type(p) > KERN_NODE) { goto contribute; } update_heights: if (type(p) == KERN_NODE) { page_total += page_depth + kern_width(p); } else { q = glue_ptr(p); page_so_far[2 + stretch_order(q)] += stretch(q); page_shrink += shrink(q); if (shrink_order(q) != NORMAL && shrink(q) != 0) { print_err(INF_SHRINK_PAGE); help_inf_shrink_page(); error(); r = new_spec(q); shrink_order(r) = NORMAL; delete_glue_ref(q); q = glue_ptr(p) = r; } page_total += page_depth + glue_width(q); } page_depth = 0; contribute: if (page_depth > page_max_depth) { page_total = page_total + page_depth - page_max_depth; page_depth = page_max_depth; } page_tail = link(page_tail) = p; link(contrib_head) = link(p); link(p) = null; continue; done: link(contrib_head) = link(p); link(p) = null; flush_node_list(p); } while (link(contrib_head) != null); if (nest_ptr == nest) { tail = contrib_head; } else { contrib_tail = contrib_head; } }
void tex::build_discretionary () { int n; ptr p, q; unsave(); q = head; p = link(q); n = 0; while (p != null) { if (!is_char_node(p) && type(p) > RULE_NODE && type(p) != KERN_NODE && type(p) != LIGATURE_NODE) { print_err("Improper discretionary list"); help_discretionary(); error(); flush_discretionary(p); link(q) = null; break; } q = p; p = link(q); incr(n); } p = link(head); pop_nest(); switch (saved(-1)) { case 0: pre_break(tail) = p; break; case 1: post_break(tail) = p; break; case 2: if (n > 0 && abs(mode) == MMODE) { print_err("Illegal math "); print_esc("discretionary"); help_math_disc(); flush_node_list(p); n = 0; error(); } else { link(tail) = p; } if (n <= MAX_QUARTERWORD) { replace_count(tail) = n; } else { print_err("Discretionary list is too long"); help_disc(); error(); } if (n > 0) tail = q; decr(save_ptr); return; } incr(saved(-1)); scan_left_brace(); new_save_level(DISC_GROUP); push_nest(); mode = -HMODE; space_factor = 1000; }
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); } } }
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; } }