tex::lig_t::lig_t(int f, int c, ptr q) { tex::type(this) = LIGATURE_NODE; tex::subtype(this) = 0; font(lig_char(this)) = f; character(lig_char(this)) = c; lig_ptr(this) = q; }
void tex::show_ligature(ptr p) { print_font_and_char(lig_char(p)); print(" (ligature "); if (subtype(p) > 1) print("|"); font_in_short_display = font(lig_char(p)); short_display(lig_ptr(p)); if (odd(subtype(p))) print("|"); print(")"); }
liginfo get_ligature (internal_font_number f, integer lc, integer rc) { liginfo t, u; charinfo * co; t.lig = 0; t.type = 0; t.adj = 0; if (lc == non_boundarychar || rc == non_boundarychar || (!has_lig(f,lc)) ) return t; k = 0; co = char_info(f,lc); while (1) { u = charinfo_ligature(co,k); if (lig_end(u)) break; if (lig_char(u) == rc) { if (lig_disabled(u)) { return t; } else { return u; } } k++; } return t; }
void tex::append_italic_correction () { ptr p; fnt f; if (tail != head) { if (is_char_node(tail)) p = tail; else if (type(tail) == LIGATURE_NODE) p = lig_char(tail); else return; f = font(p); tail = link(tail) = new_kern(char_italic(f, char_info(f, character(p)))); subtype(tail) = EXPLICIT; } }
void try_hyph () { int c, j; ptr prev_p, p, q; prev_p = cur_p; p = link(cur_p); if (p != null) { loop { if (is_char_node(p)) { c = character(p); hf = font(p); } else if (type(p) == LIGATURE_NODE) { if (lig_ptr(p) == null) goto contin; q = lig_ptr(p); c = character(q); hf = font(q); } else if (type(p) == KERN_NODE && subtype(p) == NORMAL) { goto contin; } else if (type(p) == WHATSIT_NODE) { try_hyph_whatsit(p); goto contin; } else { goto done1; } if (lc_code(c) != 0) { if (lc_code(c) == c || uc_hyph > 0) { goto done2; } else { goto done1; } } contin: prev_p = p; p = link(p); } done2: hyf_char = hyphen_char(hf); if (hyf_char < 0 || hyf_char > 255) goto done1; ha = prev_p; if (l_hyf + r_hyf > 63) goto done1; hn = 0; loop { if (is_char_node(p)) { if (font(p) != hf) goto done3; c = character(p); if (lc_code(c) == 0 || hn == 63) goto done3; hb = p; incr(hn); hu[hn] = c; hc[hn] = lc_code(c); } else if (type(p) == LIGATURE_NODE) { if (font(lig_char(p)) != hf) goto done3; j = hn; q = lig_ptr(p); while (q != null) { c = character(q); if (lc_code(c) == 0 || j == 63) goto done3; incr(j); hu[j] = c; hc[j] = lc_code(c); q = link(q); } hb = p; hn = j; } else if (type(p) != KERN_NODE || subtype(p) != NORMAL) { goto done3; } p = link(p); } done3: if (hn < l_hyf + r_hyf) goto done1; loop { if (!is_char_node(p)) { switch (type(p)) { case LIGATURE_NODE: break; case KERN_NODE: if (subtype(p) != NORMAL) goto done4; break; case WHATSIT_NODE: case GLUE_NODE: case PENALTY_NODE: case INS_NODE: case ADJUST_NODE: case MARK_NODE: goto done4; default: goto done1; } } p = link(p); } done4: hyphenate(); }
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_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); }