diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/pdf/pdflistout.w')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/pdf/pdflistout.w | 641 |
1 files changed, 281 insertions, 360 deletions
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdflistout.w b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.w index c1764f49c0c..bf32cb8c629 100644 --- a/Build/source/texk/web2c/luatexdir/pdf/pdflistout.w +++ b/Build/source/texk/web2c/luatexdir/pdf/pdflistout.w @@ -20,12 +20,10 @@ \def\pdfTeX{pdf\TeX} @ @c - - #include "ptexlib.h" @ @c -pos_info_structure pos_info; /* to be accessed from Lua */ +pos_info_structure pos_info; /* to be accessed from Lua */ static backend_struct *backend = NULL; backend_function *backend_out, *backend_out_whatsit; @@ -44,10 +42,10 @@ static void missing_backend_function(PDF pdf, halfword p) else s = "node"; n = get_node_name(type(p), subtype(p)); - b = backend[pdf->o_mode].name; + b = backend[output_mode_used].name; snprintf(backend_string, strlen(b) + 10, "%s back-end", b); snprintf(err_string, 59, "no output function for \"%s\" %s", n, s); - pdf_error(backend_string, err_string); + normal_error(backend_string, err_string); } @ @c @@ -62,24 +60,22 @@ static void init_pdf_backend_functions(void) { backend_struct *p = &backend[OMODE_PDF]; p->name = strdup("PDF"); - p->node_fu[rule_node] = &pdf_place_rule; /* 2 */ - p->node_fu[glyph_node] = &pdf_place_glyph; /* 37 */ - p->whatsit_fu[special_node] = &pdf_special; /* 3 */ - p->whatsit_fu[pdf_literal_node] = &pdf_out_literal; /* 8 */ - p->whatsit_fu[pdf_refobj_node] = &pdf_ref_obj; /* 10 */ - p->whatsit_fu[pdf_refxform_node] = &pdf_place_form; /* 12 */ - p->whatsit_fu[pdf_refximage_node] = &pdf_place_image; /* 14 */ - p->whatsit_fu[pdf_annot_node] = &do_annot; /* 15 */ - p->whatsit_fu[pdf_start_link_node] = &do_link; /* 16 */ - p->whatsit_fu[pdf_end_link_node] = &end_link; /* 17 */ - p->whatsit_fu[pdf_dest_node] = &do_dest; /* 19 */ - p->whatsit_fu[pdf_thread_node] = &do_thread; /* 20 */ - p->whatsit_fu[pdf_end_thread_node] = &end_thread; /* 22 */ - p->whatsit_fu[late_lua_node] = &late_lua; /* 35 */ - p->whatsit_fu[pdf_colorstack_node] = &pdf_out_colorstack; /* 39 */ - p->whatsit_fu[pdf_setmatrix_node] = &pdf_out_setmatrix; /* 40 */ - p->whatsit_fu[pdf_save_node] = &pdf_out_save; /* 41 */ - p->whatsit_fu[pdf_restore_node] = &pdf_out_restore; /* 42 */ + p->node_fu[rule_node] = &pdf_place_rule; + p->node_fu[glyph_node] = &pdf_place_glyph; + p->whatsit_fu[special_node] = &pdf_special; + p->whatsit_fu[pdf_literal_node] = &pdf_out_literal; + p->whatsit_fu[pdf_refobj_node] = &pdf_ref_obj; + p->whatsit_fu[pdf_annot_node] = &do_annot; + p->whatsit_fu[pdf_start_link_node] = &do_link; + p->whatsit_fu[pdf_end_link_node] = &end_link; + p->whatsit_fu[pdf_dest_node] = &do_dest; + p->whatsit_fu[pdf_thread_node] = &do_thread; + p->whatsit_fu[pdf_end_thread_node] = &end_thread; + p->whatsit_fu[late_lua_node] = &late_lua; + p->whatsit_fu[pdf_colorstack_node] = &pdf_out_colorstack; + p->whatsit_fu[pdf_setmatrix_node] = &pdf_out_setmatrix; + p->whatsit_fu[pdf_save_node] = &pdf_out_save; + p->whatsit_fu[pdf_restore_node] = &pdf_out_restore; } @ @c @@ -87,21 +83,12 @@ static void init_dvi_backend_functions(void) { backend_struct *p = &backend[OMODE_DVI]; p->name = strdup("DVI"); - p->node_fu[rule_node] = &dvi_place_rule; /* 2 */ - p->node_fu[glyph_node] = &dvi_place_glyph; /* 37 */ - p->whatsit_fu[special_node] = &dvi_special; /* 3 */ - p->whatsit_fu[late_lua_node] = &late_lua; /* 35 */ + p->node_fu[rule_node] = &dvi_place_rule; + p->node_fu[glyph_node] = &dvi_place_glyph; + p->whatsit_fu[special_node] = &dvi_special; + p->whatsit_fu[late_lua_node] = &late_lua; } -@ @c -static void init_lua_backend_functions(void) -{ - backend_struct *p = &backend[OMODE_LUA]; - p->name = strdup("Lua"); - p->node_fu[rule_node] = &lua_place_rule; /* 2 */ - p->node_fu[glyph_node] = &lua_place_glyph; /* 37 */ - p->whatsit_fu[late_lua_node] = &late_lua; /* 35 */ -} @ @c void init_backend_functionpointers(output_mode o_mode) @@ -110,10 +97,8 @@ void init_backend_functionpointers(output_mode o_mode) if (backend == NULL) { backend = xmalloc((MAX_OMODE + 1) * sizeof(backend_struct)); for (i = 0; i <= MAX_OMODE; i++) { - backend[i].node_fu = - xmalloc((MAX_NODE_TYPE + 1) * sizeof(backend_function)); - backend[i].whatsit_fu = - xmalloc((MAX_WHATSIT_TYPE + 1) * sizeof(backend_function)); + backend[i].node_fu = xmalloc((MAX_NODE_TYPE + 1) * sizeof(backend_function)); + backend[i].whatsit_fu = xmalloc((MAX_WHATSIT_TYPE + 1) * sizeof(backend_function)); for (j = 0; j < MAX_NODE_TYPE + 1; j++) backend[i].node_fu[j] = &missing_backend_function; for (j = 0; j < MAX_WHATSIT_TYPE + 1; j++) @@ -122,7 +107,6 @@ void init_backend_functionpointers(output_mode o_mode) init_none_backend_functions(); init_dvi_backend_functions(); init_pdf_backend_functions(); - init_lua_backend_functions(); } backend_out = backend[o_mode].node_fu; backend_out_whatsit = backend[o_mode].whatsit_fu; @@ -153,6 +137,7 @@ static scaled simple_advance_width(halfword p) w += width(q); break; case disc_node: + /* hh: the frontend should append already */ if (vlink(no_break(q)) != null) w += simple_advance_width(no_break(q)); default: @@ -163,16 +148,13 @@ static scaled simple_advance_width(halfword p) } @ @c -static halfword calculate_width_to_enddir(halfword p, real cur_glue, - scaled cur_g, halfword this_box) +static halfword calculate_width_to_enddir(halfword p, real cur_glue, scaled cur_g, halfword this_box) { int dir_nest = 1; halfword q = p, enddir_ptr = p; scaled w = 0; - halfword g; /* this is normally a global variable, but that is just too hideous */ - /* to me, it looks like the next is needed. but Aleph doesn't do that, so let us not do it either */ - real glue_temp; /* glue value before rounding */ - /* |w:=w-cur_g; cur_glue:=0;| */ + halfword g; /* this is normally a global variable, but that is just too hideous */ + real glue_temp; /* glue value before rounding */ int g_sign = glue_sign(this_box); int g_order = glue_order(this_box); while ((q != null) && (vlink(q) != null)) { @@ -190,6 +172,15 @@ static halfword calculate_width_to_enddir(halfword p, real cur_glue, case kern_node: w += width(q); break; + case math_node: + /* begin mathskip code */ + if (glue_ptr(q) == zero_glue) { + w += surround(q); + break; + } else { + /* fall through: mathskip */ + } + /* end mathskip code */ case glue_node: g = glue_ptr(q); w += width(g) - cur_g; @@ -209,33 +200,28 @@ static halfword calculate_width_to_enddir(halfword p, real cur_glue, w += cur_g; break; case disc_node: + /* hh: the frontend should append already */ if (vlink(no_break(q)) != null) w += simple_advance_width(no_break(q)); break; - case math_node: - w += surround(q); - break; - case whatsit_node: - if (subtype(q) == dir_node) { - if (dir_dir(q) >= 0) - dir_nest++; - else - dir_nest--; - if (dir_nest == 0) { - enddir_ptr = q; - dir_cur_h(enddir_ptr) = w; - q = null; - } - } else if ((subtype(q) == pdf_refxform_node) - || (subtype(q) == pdf_refximage_node)) - w += width(q); + case dir_node: + if (dir_dir(q) >= 0) + dir_nest++; + else + dir_nest--; + if (dir_nest == 0) { + enddir_ptr = q; + dir_cur_h(enddir_ptr) = w; + q = null; + } break; default: break; } } } - if (enddir_ptr == p) /* no enddir found, just transport w by begindir */ + if (enddir_ptr == p) + /* no enddir found, just transport w by begindir */ dir_cur_h(enddir_ptr) = w; return enddir_ptr; } @@ -251,9 +237,9 @@ implementations, due to machine-dependent rounding in the glue calculations.) @c void out_what(PDF pdf, halfword p) { - int j; /* write stream number */ - switch (subtype(p)) { - /* function(pdf, p) */ + switch (subtype(p)) { /* function(pdf, p) */ + case special_node: /* |pdf_special(pdf, p)|; */ + case late_lua_node: /* |late_lua(pdf, p)|; */ case pdf_save_node: /* |pdf_out_save(pdf, p)|; */ case pdf_restore_node: /* |pdf_out_restore(pdf, p)|; */ case pdf_end_link_node: /* |end_link(pdf, p)|; */ @@ -261,43 +247,34 @@ void out_what(PDF pdf, halfword p) case pdf_literal_node: /* |pdf_out_literal(pdf, p)|; */ case pdf_colorstack_node: /* |pdf_out_colorstack(pdf, p)|; */ case pdf_setmatrix_node: /* |pdf_out_setmatrix(pdf, p)|; */ - case special_node: /* |pdf_special(pdf, p)|; */ - case late_lua_node: /* |late_lua(pdf, p)|; */ case pdf_refobj_node: /* |pdf_ref_obj(pdf, p)| */ backend_out_whatsit[subtype(p)] (pdf, p); break; case open_node: case write_node: case close_node: - /* Do some work that has been queued up for \.{\\write} */ + /* do some work that has been queued up for \.{\\write} */ if (!doing_leaders) { - j = write_stream(p); + int j = write_stream(p); if (subtype(p) == write_node) { write_out(p); - } else { - if (write_open[j]) - lua_a_close_out(write_file[j]); - if (subtype(p) == close_node) { - write_open[j] = false; - } else if (j < 16) { - char *fn; - cur_name = open_name(p); - cur_area = open_area(p); - cur_ext = open_ext(p); - if (cur_ext == get_nullstr()) - cur_ext = maketexstring(".tex"); - fn = pack_file_name(cur_name, cur_area, cur_ext); - while (!lua_a_open_out(&(write_file[j]), fn, (j + 1))) - fn = prompt_file_name("output file name", ".tex"); - write_open[j] = true; + } else if (subtype(p) == close_node) { + close_write_file(j); + } else if (valid_write_file(j)) { + char *fn; + close_write_file(j); + cur_name = open_name(p); + cur_area = open_area(p); + cur_ext = open_ext(p); + if (cur_ext == get_nullstr()) + cur_ext = maketexstring(".tex"); + fn = pack_file_name(cur_name, cur_area, cur_ext); + while (! open_write_file(j,fn)) { + fn = prompt_file_name("output file name", ".tex"); } } } break; - case dir_node: /* in a vlist */ - break; - case local_par_node: - case cancel_boundary_node: case user_defined_node: break; default: @@ -312,7 +289,6 @@ void hlist_out(PDF pdf, halfword this_box) posstructure localpos; /* the position structure local within this function */ posstructure *refpos; /* the list origin pos. on the page, provided by the caller */ - scaledpos cur = { 0, 0 }, tmpcur, basepoint; scaledpos size = { 0, 0 }; /* rule dimensions */ scaled effective_horizontal; @@ -333,6 +309,7 @@ void hlist_out(PDF pdf, halfword this_box) int i; /* index to scan |pdf_link_stack| */ int save_loc = 0; /* DVI! \.{DVI} byte location upon entry */ scaledpos save_dvi = { 0, 0 }; /* DVI! what |dvi| should pop to */ + int synctex = int_par(synctex_code) ; g_order = glue_order(this_box); g_sign = glue_sign(this_box); @@ -347,23 +324,21 @@ void hlist_out(PDF pdf, halfword this_box) if (cur_s > max_push) max_push = cur_s; - if (pdf->o_mode == OMODE_DVI) { - if (cur_s > 0) { /* DVI! */ - dvi_push(); /* DVI! */ - save_dvi = dvi; /* DVI! */ + if (output_mode_used == OMODE_DVI) { + if (cur_s > 0) { + dvi_push(); + save_dvi = dvi; } - save_loc = dvi_offset + dvi_ptr /* DVI! */ ; + save_loc = dvi_offset + dvi_ptr; } - /* Create link annotations for the current hbox if needed */ for (i = 1; i <= pdf->link_stack_ptr; i++) { assert(is_running(width(pdf->link_stack[i].link_node))); if (pdf->link_stack[i].nesting_level == cur_s) append_link(pdf, this_box, cur, (small_number) i); } - /* Start hlist {\sl Sync\TeX} information record */ - if (int_par(synctex_code)) + if (synctex) synctexhlist(this_box); while (p != null) { @@ -382,17 +357,13 @@ void hlist_out(PDF pdf, halfword this_box) synch_pos_with_cur(pdf->posstruct, refpos, cur); p = vlink(p); } while (is_char_node(p)); - /* Record current point {\sl Sync\TeX} information */ - if (int_par(synctex_code)) + if (synctex) synctexcurrent(); } else { - /* Output the non-|char_node| |p| for |hlist_out| - and move to the next node */ + /* output the non-|char_node| |p| for |hlist_out| and move to the next node */ switch (type(p)) { case hlist_node: case vlist_node: - /* (\pdfTeX) Output a box in an hlist */ - if (textdir_parallel(box_dir(p), localpos.dir)) { effective_horizontal = width(p); basepoint.v = 0; @@ -415,28 +386,27 @@ void hlist_out(PDF pdf, halfword this_box) } if (is_rotated(localpos.dir)) { if (partextdir_eq(localpos.dir, box_dir(p))) - basepoint.v = -width(p) / 2; /* `up' */ + basepoint.v = -width(p) / 2; /* up */ else - basepoint.v = width(p) / 2; /* `down' */ + basepoint.v = width(p) / 2; /* down */ } else if (is_mirrored(localpos.dir)) { if (partextdir_eq(localpos.dir, box_dir(p))) basepoint.v = 0; else - basepoint.v = width(p); /* `down' */ + basepoint.v = width(p); /* down */ } else { if (partextdir_eq(localpos.dir, box_dir(p))) - basepoint.v = -width(p); /* `up' */ + basepoint.v = -width(p); /* up */ else basepoint.v = 0; } } if (!is_mirrored(localpos.dir)) - basepoint.v = basepoint.v + shift_amount(p); /* shift the box `down' */ + basepoint.v = basepoint.v + shift_amount(p); /* shift the box down */ else - basepoint.v = basepoint.v - shift_amount(p); /* shift the box `up' */ + basepoint.v = basepoint.v - shift_amount(p); /* shift the box up */ if (list_ptr(p) == null) { - /* Record void list {\sl Sync\TeX} information */ - if (int_par(synctex_code)) { + if (synctex) { if (type(p) == vlist_node) synctexvoidvlist(p, this_box); else @@ -455,9 +425,10 @@ void hlist_out(PDF pdf, halfword this_box) cur.h += effective_horizontal; break; case disc_node: + /* hh: the frontend should append already */ if (vlink(no_break(p)) != null) { if (subtype(p) != select_disc) { - q = tail_of_list(vlink(no_break(p))); /* TODO, this should be a tlink */ + q = tail_of_list(vlink(no_break(p))); /* this could be a tlink */ vlink(q) = vlink(p); q = vlink(no_break(p)); vlink(no_break(p)) = null; @@ -479,11 +450,47 @@ void hlist_out(PDF pdf, halfword this_box) } goto FIN_RULE; break; + case dir_node: + /* output a reflection instruction if the direction has changed */ + if (dir_dir(p) >= 0) { + /* + Calculate the needed width to the matching |enddir|, return the + |enddir| node, with width info + */ + enddir_ptr = calculate_width_to_enddir(p, cur_glue, cur_g, this_box); + if (textdir_parallel(dir_dir(p), localpos.dir)) { + dir_cur_h(enddir_ptr) += cur.h; + if (textdir_opposite(dir_dir(p), localpos.dir)) + cur.h = dir_cur_h(enddir_ptr); + } else + dir_cur_h(enddir_ptr) = cur.h; + if (enddir_ptr != p) { + /* only if it is an enddir */ + dir_cur_v(enddir_ptr) = cur.v; + dir_refpos_h(enddir_ptr) = refpos->pos.h; + dir_refpos_v(enddir_ptr) = refpos->pos.v; + /* negative: mark it as |enddir| */ + dir_dir(enddir_ptr) = localpos.dir - dir_swap; + } + /* fake a nested |hlist_out| */ + synch_pos_with_cur(pdf->posstruct, refpos, cur); + refpos->pos = pdf->posstruct->pos; + localpos.dir = dir_dir(p); + cur.h = 0; + cur.v = 0; + } else { + refpos->pos.h = dir_refpos_h(p); + refpos->pos.v = dir_refpos_v(p); + localpos.dir = dir_dir(p) + dir_swap; + cur.h = dir_cur_h(p); + cur.v = dir_cur_v(p); + } + break; case whatsit_node: - /* Output the whatsit node |p| in |hlist_out| */ + /* output the whatsit node |p| in |hlist_out| */ switch (subtype(p)) { case save_pos_node: - pdf_last_pos = pdf->posstruct->pos; + last_position = pdf->posstruct->pos; pos_info.curpos = pdf->posstruct->pos; pos_info.boxpos.pos = refpos->pos; pos_info.boxpos.dir = localpos.dir; @@ -491,100 +498,50 @@ void hlist_out(PDF pdf, halfword this_box) pos_info.boxdim.ht = height(this_box); pos_info.boxdim.dp = depth(this_box); break; - /* |function(pdf, p, this_box, cur)|; too many args for |out_what()| */ - case pdf_annot_node: /* |do_annot(pdf, p, this_box, cur);| */ - case pdf_start_link_node: /* |do_link(pdf, p, this_box, cur);| */ - case pdf_dest_node: /* |do_dest(pdf, p, this_box, cur);| */ + case pdf_annot_node: + case pdf_start_link_node: + case pdf_dest_node: case pdf_start_thread_node: - case pdf_thread_node: /* |do_thread(pdf, p, this_box, cur);| */ + case pdf_thread_node: backend_out_whatsit[subtype(p)] (pdf, p, this_box, cur); break; - case pdf_refxform_node: /* |pdf_place_form(pdf, pdf_xform_objnum(p));| */ - case pdf_refximage_node: /* |pdf_place_image(pdf, pdf_ximage_idx(p));| */ - /* Output a Form node in a hlist */ - /* Output an Image node in a hlist */ - switch (localpos.dir) { - case dir_TLT: - pos_down(depth(p)); - break; - case dir_TRT: - pos_left(width(p)); - pos_down(depth(p)); - break; - case dir_LTL: - pos_left(height(p)); - pos_down(width(p)); - break; - case dir_RTT: - pos_left(depth(p)); - pos_down(width(p)); - break; - default: - assert(0); - } - backend_out_whatsit[subtype(p)] (pdf, p); - cur.h += width(p); - break; - case dir_node: - /* Output a reflection instruction if the direction has changed */ - if (dir_dir(p) >= 0) { - /* Calculate the needed width to the matching |enddir|, return the |enddir| node, - with width info */ - enddir_ptr = - calculate_width_to_enddir(p, cur_glue, cur_g, - this_box); - if (textdir_parallel(dir_dir(p), localpos.dir)) { - dir_cur_h(enddir_ptr) += cur.h; - if (textdir_opposite(dir_dir(p), localpos.dir)) - cur.h = dir_cur_h(enddir_ptr); - } else - dir_cur_h(enddir_ptr) = cur.h; - if (enddir_ptr != p) { /* only if it is an enddir */ - dir_cur_v(enddir_ptr) = cur.v; - dir_refpos_h(enddir_ptr) = refpos->pos.h; - dir_refpos_v(enddir_ptr) = refpos->pos.v; - dir_dir(enddir_ptr) = localpos.dir - 64; /* negative: mark it as |enddir| */ - } - /* fake a nested |hlist_out| */ - synch_pos_with_cur(pdf->posstruct, refpos, cur); - refpos->pos = pdf->posstruct->pos; - localpos.dir = dir_dir(p); - cur.h = 0; - cur.v = 0; - } else { - refpos->pos.h = dir_refpos_h(p); - refpos->pos.v = dir_refpos_v(p); - localpos.dir = dir_dir(p) + 64; - cur.h = dir_cur_h(p); - cur.v = dir_cur_v(p); - } - break; default: out_what(pdf, p); } break; + case math_node: + if (synctex) { + synctexmath(p, this_box); + } + /* begin mathskip code */ + if (glue_ptr(p) == zero_glue) { + cur.h += surround(p); + break; + } else { + /* fall through: mathskip */ + } + /* end mathskip code */ case glue_node: - /* (\pdfTeX) Move right or output leaders */ { - halfword 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(float_cast(glue_set(this_box)) * cur_glue); /* real multiplication */ + /* move right or output leaders, we use real multiplication */ + halfword 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(float_cast(glue_set(this_box)) * cur_glue); + cur_g = float_round(glue_temp); + } + } else if (shrink_order(g) == g_order) { + cur_glue = cur_glue - shrink(g); + vet_glue(float_cast(glue_set(this_box)) * cur_glue); cur_g = float_round(glue_temp); } - } else if (shrink_order(g) == g_order) { - cur_glue = cur_glue - shrink(g); - vet_glue(float_cast(glue_set(this_box)) * cur_glue); - cur_g = float_round(glue_temp); - } } rule.wd = rule.wd + cur_g; if (subtype(p) >= a_leaders) { - /* (\pdfTeX) Output leaders in an hlist, |goto fin_rule| if a rule - or to |next_p| if done */ + /* output leaders in an hlist, |goto fin_rule| if a rule or to |next_p| if done */ leader_box = leader_ptr(p); if (type(leader_box) == rule_node) { rule.ht = height(leader_box); @@ -599,9 +556,10 @@ void hlist_out(PDF pdf, halfword this_box) rule.wd = rule.wd + 10; /* compensate for floating-point rounding */ edge = cur.h + rule.wd; lx = 0; - /* Let |cur.h| be the position of the first box, and set |leader_wd+lx| - to the spacing between corresponding parts of boxes */ - + /* + let |cur.h| be the position of the first box, and set |leader_wd+lx| + to the spacing between corresponding parts of boxes + */ if (subtype(p) == g_leaders) { save_h = cur.h; switch (localpos.dir) { @@ -611,19 +569,15 @@ void hlist_out(PDF pdf, halfword this_box) cur.h -= refpos->pos.h - shipbox_refpos.h; break; case dir_TRT: - cur.h = - refpos->pos.h - shipbox_refpos.h - cur.h; + cur.h = refpos->pos.h - shipbox_refpos.h - cur.h; cur.h = leader_wd * (cur.h / leader_wd); - cur.h = - refpos->pos.h - shipbox_refpos.h - cur.h; + cur.h = refpos->pos.h - shipbox_refpos.h - cur.h; break; case dir_LTL: case dir_RTT: - cur.h = - refpos->pos.v - shipbox_refpos.v - cur.h; + cur.h = refpos->pos.v - shipbox_refpos.v - cur.h; cur.h = leader_wd * (cur.h / leader_wd); - cur.h = - refpos->pos.v - shipbox_refpos.v - cur.h; + cur.h = refpos->pos.v - shipbox_refpos.v - cur.h; break; default: assert(0); @@ -636,8 +590,8 @@ void hlist_out(PDF pdf, halfword this_box) if (cur.h < save_h) cur.h += leader_wd; } else { - lq = rule.wd / leader_wd; /* the number of box copies */ - lr = rule.wd % leader_wd; /* the remaining space */ + lq = rule.wd / leader_wd; /* the number of box copies */ + lr = rule.wd % leader_wd; /* the remaining space */ if (subtype(p) == c_leaders) { cur.h += lr / 2; } else { @@ -645,43 +599,35 @@ void hlist_out(PDF pdf, halfword this_box) cur.h += (lr - (lq - 1) * lx) / 2; } } - while (cur.h + leader_wd <= edge) { - /* (\pdfTeX) Output a leader box at |cur.h|, - then advance |cur.h| by |leader_wd+lx| */ - - if (pardir_parallel - (box_dir(leader_box), localpos.dir)) { + /* output a leader box at |cur.h|, then advance |cur.h| by |leader_wd+lx| */ + if (pardir_parallel(box_dir(leader_box), localpos.dir)) { basepoint.v = 0; - if (textdir_opposite - (box_dir(leader_box), localpos.dir)) + if (textdir_opposite(box_dir(leader_box), localpos.dir)) basepoint.h = width(leader_box); else basepoint.h = 0; } else { if (!is_mirrored(box_dir(leader_box))) { - if (partextdir_eq - (box_dir(leader_box), localpos.dir)) + if (partextdir_eq(box_dir(leader_box), localpos.dir)) basepoint.h = height(leader_box); else basepoint.h = depth(leader_box); } else { - if (partextdir_eq - (box_dir(leader_box), localpos.dir)) + if (partextdir_eq(box_dir(leader_box), localpos.dir)) basepoint.h = depth(leader_box); else basepoint.h = height(leader_box); } - if (partextdir_eq - (localpos.dir, box_dir(leader_box))) + if (partextdir_eq(localpos.dir, box_dir(leader_box))) basepoint.v = -(width(leader_box) / 2); else basepoint.v = (width(leader_box) / 2); } if (!is_mirrored(localpos.dir)) - basepoint.v = basepoint.v + shift_amount(leader_box); /* shift the box `down' */ + basepoint.v = basepoint.v + shift_amount(leader_box); /* shift the box down */ else - basepoint.v = basepoint.v - shift_amount(leader_box); /* shift the box `up' */ + basepoint.v = basepoint.v - shift_amount(leader_box); /* shift the box up */ assert(cur.v == 0); tmpcur.h = cur.h + basepoint.h; tmpcur.v = basepoint.v; @@ -706,28 +652,22 @@ void hlist_out(PDF pdf, halfword this_box) cur.h += width(p); break; case kern_node: - /* Record |kern_node| {\sl Sync\TeX} information */ - if (int_par(synctex_code)) + if (synctex) synctexkern(p, this_box); cur.h += width(p); break; - case math_node: - /* Record |math_node| {\sl Sync\TeX} information */ - if (int_par(synctex_code)) - synctexmath(p, this_box); - cur.h += surround(p); - break; default: break; } goto NEXTP; FIN_RULE: - /* (\pdfTeX) Output a rule in an hlist */ + /* output a rule in an hlist */ if (is_running(rule.ht)) rule.ht = height(this_box); if (is_running(rule.dp)) rule.dp = depth(this_box); - if ((rule.ht + rule.dp) > 0 && rule.wd > 0) { /* we don't output empty rules */ + /* we don't output empty rules */ + if ((rule.ht + rule.dp) > 0 && rule.wd > 0) { switch (localpos.dir) { case dir_TLT: size.h = rule.wd; @@ -755,12 +695,18 @@ void hlist_out(PDF pdf, halfword this_box) default: assert(0); } - backend_out[rule_node] (pdf, p, size); /* |pdf_place_rule(pdf, p, rule.ht + rule.dp, rule.wd);| */ + if (type(p) == glue_node) { + q = leader_ptr(p); + if ((q) && (type(q) == rule_node)) { + backend_out[rule_node] (pdf, q, size); + } + } else { + backend_out[rule_node] (pdf, p, size); + } } MOVE_PAST: cur.h += rule.wd; - /* Record horizontal |rule_node| or |glue_node| {\sl Sync\TeX} information */ - if (int_par(synctex_code)) { + if (synctex) { synch_pos_with_cur(pdf->posstruct, refpos, cur); synctexhorizontalruleorglue(p, this_box); } @@ -770,15 +716,14 @@ void hlist_out(PDF pdf, halfword this_box) } } - /* Finish hlist {\sl Sync\TeX} information record */ - if (int_par(synctex_code)) + if (synctex) synctextsilh(this_box); - if (pdf->o_mode == OMODE_DVI) { - prune_movements(save_loc); /* DVI! */ - if (cur_s > 0) { /* DVI! */ - dvi_pop(save_loc); /* DVI! */ - dvi = save_dvi; /* DVI! */ + if (output_mode_used == OMODE_DVI) { + prune_movements(save_loc); + if (cur_s > 0) { + dvi_pop(save_loc); + dvi = save_dvi; } } cur_s--; @@ -788,28 +733,30 @@ void hlist_out(PDF pdf, halfword this_box) @ @c void vlist_out(PDF pdf, halfword this_box) { - posstructure localpos; /* the position structure local within this function */ - posstructure *refpos; /* the list origin pos. on the page, provided by the caller */ + posstructure localpos; /* the position structure local within this function */ + posstructure *refpos; /* the list origin pos. on the page, provided by the caller */ scaledpos cur, tmpcur, basepoint; - scaledpos size = { 0, 0 }; /* rule dimensions */ + scaledpos size = { 0, 0 }; /* rule dimensions */ scaled effective_vertical; - scaled save_v; /* what |cur.v| should pop to */ - scaled top_edge; /* the top coordinate for this box */ - scaled edge; /* bottom boundary of leader space */ - glue_ord g_order; /* applicable order of infinity for glue */ - int g_sign; /* selects type of glue */ - halfword p; /* current position in the vlist */ - halfword leader_box; /* the leader box being replicated */ - scaled leader_ht; /* height of leader box being replicated */ - scaled lx; /* extra space between leader boxes */ - boolean outer_doing_leaders; /* were we doing leaders? */ - real glue_temp; /* glue value before rounding */ - real cur_glue = 0.0; /* glue seen so far */ - scaled cur_g = 0; /* rounded equivalent of |cur_glue| times the glue ratio */ + scaled save_v; /* what |cur.v| should pop to */ + scaled top_edge; /* the top coordinate for this box */ + scaled edge; /* bottom boundary of leader space */ + glue_ord g_order; /* applicable order of infinity for glue */ + int g_sign; /* selects type of glue */ + halfword p; /* current position in the vlist */ + halfword q; /* temp */ + halfword leader_box; /* the leader box being replicated */ + scaled leader_ht; /* height of leader box being replicated */ + scaled lx; /* extra space between leader boxes */ + boolean outer_doing_leaders; /* were we doing leaders? */ + real glue_temp; /* glue value before rounding */ + real cur_glue = 0.0; /* glue seen so far */ + scaled cur_g = 0; /* rounded equivalent of |cur_glue| times the glue ratio */ scaled_whd rule; - int save_loc = 0; /* DVI! \.{DVI} byte location upon entry */ - scaledpos save_dvi = { 0, 0 }; /* DVI! what |dvi| should pop to */ + int save_loc = 0; /* DVI byte location upon entry */ + scaledpos save_dvi = { 0, 0 }; /* DVI! what |dvi| should pop to */ + int synctex = int_par(synctex_code) ; g_order = (glue_ord) glue_order(this_box); g_sign = glue_sign(this_box); @@ -828,38 +775,38 @@ void vlist_out(PDF pdf, halfword this_box) if (cur_s > max_push) max_push = cur_s; - if (pdf->o_mode == OMODE_DVI) { - if (cur_s > 0) { /* DVI! */ - dvi_push(); /* DVI! */ - save_dvi = dvi; /* DVI! */ + if (output_mode_used == OMODE_DVI) { + if (cur_s > 0) { + dvi_push(); + save_dvi = dvi; } - save_loc = dvi_offset + dvi_ptr; /* DVI! */ + save_loc = dvi_offset + dvi_ptr; } - /* Start vlist {\sl Sync\TeX} information record */ - if (int_par(synctex_code)) + if (synctex) synctexvlist(this_box); - /* Create thread for the current vbox if needed */ + /* create thread for the current vbox if needed */ check_running_thread(pdf, this_box, cur); while (p != null) { if (is_char_node(p)) { - confusion("vlistout"); /* this can't happen */ + confusion("vlistout"); /* this can't happen */ } else { - /* Output the non-|char_node| |p| for |vlist_out| */ - + /* output the non-|char_node| |p| for |vlist_out| */ switch (type(p)) { case hlist_node: case vlist_node: - /* (\pdfTeX) Output a box in a vlist */ + /* + output a box in a vlist: + + todo: the direct test to switch between |width(p)| and |-width(p)| + is definately wrong, because it does not nest properly. But at least + it fixes a very obvious problem that otherwise occured with + \.{\\pardir TLT} in a document with \.{\\bodydir TRT}, and so it + will have to do for now. (hh: is this still true?) - /* TODO: the direct test to switch between |width(p)| and |-width(p)| - is definately wrong, because it does not nest properly. But at least - it fixes a very obvious problem that otherwise occured with - \.{\\pardir TLT} in a document with \.{\\bodydir TRT}, and so it - will have to do for now. - */ + */ if (pardir_parallel(box_dir(p), localpos.dir)) { effective_vertical = height(p) + depth(p); if ((type(p) == hlist_node) && is_mirrored(box_dir(p))) @@ -888,11 +835,10 @@ void vlist_out(PDF pdf, halfword this_box) else basepoint.v = width(p); } - basepoint.h = basepoint.h + shift_amount(p); /* shift the box `right' */ + basepoint.h = basepoint.h + shift_amount(p); /* shift the box right */ if (list_ptr(p) == null) { cur.v += effective_vertical; - /* Record void list {\sl Sync\TeX} information */ - if (int_par(synctex_code)) { + if (synctex) { synch_pos_with_cur(pdf->posstruct, refpos, cur); if (type(p) == vlist_node) synctexvoidvlist(p, this_box); @@ -926,10 +872,10 @@ void vlist_out(PDF pdf, halfword this_box) goto FIN_RULE; break; case whatsit_node: - /* Output the whatsit node |p| in |vlist_out| */ + /* output the whatsit node |p| in |vlist_out| */ switch (subtype(p)) { case save_pos_node: - pdf_last_pos = pdf->posstruct->pos; + last_position = pdf->posstruct->pos; pos_info.curpos = pdf->posstruct->pos; pos_info.boxpos.pos = refpos->pos; pos_info.boxpos.dir = localpos.dir; @@ -937,64 +883,38 @@ void vlist_out(PDF pdf, halfword this_box) pos_info.boxdim.ht = height(this_box); pos_info.boxdim.dp = depth(this_box); break; - /* |function(pdf, p, this_box, cur)|; too many args for |out_what()| */ - case pdf_annot_node: /* |do_annot(pdf, p, this_box, cur);| */ - case pdf_start_link_node: /* |do_link(pdf, p, this_box, cur);| */ - case pdf_dest_node: /* |do_dest(pdf, p, this_box, cur);| */ + case pdf_annot_node: + case pdf_start_link_node: + case pdf_dest_node: case pdf_start_thread_node: - case pdf_thread_node: /* |do_thread(pdf, p, this_box, cur);| */ + case pdf_thread_node: backend_out_whatsit[subtype(p)] (pdf, p, this_box, cur); break; - case pdf_refxform_node: /* |pdf_place_form(pdf, pdf_xform_objnum(p));| */ - case pdf_refximage_node: /* |pdf_place_image(pdf, pdf_ximage_idx(p));| */ - /* Output a Form node in a vlist */ - /* Output an Image node in a vlist */ - switch (localpos.dir) { - case dir_TLT: - pos_down(height(p) + depth(p)); - break; - case dir_TRT: - pos_left(width(p)); - pos_down(height(p) + depth(p)); - break; - case dir_LTL: - pos_down(width(p)); - break; - case dir_RTT: - pos_left(height(p) + depth(p)); - pos_down(width(p)); - break; - default: - assert(0); - } - backend_out_whatsit[subtype(p)] (pdf, p); - cur.v += height(p) + depth(p); - break; default: out_what(pdf, p); } break; case glue_node: - /* (\pdfTeX) Move down or output leaders */ { - halfword 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(float_cast(glue_set(this_box)) * cur_glue); /* real multiplication */ + /* move down or output leaders, we use real multiplication */ + halfword 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(float_cast(glue_set(this_box)) * cur_glue); + cur_g = float_round(glue_temp); + } + } else if (shrink_order(g) == g_order) { + cur_glue = cur_glue - shrink(g); + vet_glue(float_cast(glue_set(this_box)) * cur_glue); cur_g = float_round(glue_temp); } - } else if (shrink_order(g) == g_order) { - cur_glue = cur_glue - shrink(g); - vet_glue(float_cast(glue_set(this_box)) * cur_glue); - cur_g = float_round(glue_temp); - } } rule.ht = rule.ht + cur_g; if (subtype(p) >= a_leaders) { - /* (\pdfTeX) Output leaders in a vlist, |goto fin_rule| if a rule or to |next_p| if done */ + /* output leaders in a vlist, |goto fin_rulefin_rule| if a rule or to |next_p| if done */ leader_box = leader_ptr(p); if (type(leader_box) == rule_node) { rule.wd = width(leader_box); @@ -1006,9 +926,10 @@ void vlist_out(PDF pdf, halfword this_box) rule.ht = rule.ht + 10; /* compensate for floating-point rounding */ edge = cur.v + rule.ht; lx = 0; - /* Let |cur.v| be the position of the first box, and set |leader_ht+lx| - to the spacing between corresponding parts of boxes */ - + /* + let |cur.v| be the position of the first box, and set |leader_ht+lx| + to the spacing between corresponding parts of boxes + */ if (subtype(p) == g_leaders) { save_v = cur.v; switch (localpos.dir) { @@ -1018,19 +939,15 @@ void vlist_out(PDF pdf, halfword this_box) cur.v -= refpos->pos.h - shipbox_refpos.h; break; case dir_RTT: - cur.v = - refpos->pos.h - shipbox_refpos.h - cur.v; + cur.v = refpos->pos.h - shipbox_refpos.h - cur.v; cur.v = leader_ht * (cur.v / leader_ht); - cur.v = - refpos->pos.h - shipbox_refpos.h - cur.v; + cur.v = refpos->pos.h - shipbox_refpos.h - cur.v; break; case dir_TLT: case dir_TRT: - cur.v = - refpos->pos.v - shipbox_refpos.v - cur.v; + cur.v = refpos->pos.v - shipbox_refpos.v - cur.v; cur.v = leader_ht * (cur.v / leader_ht); - cur.v = - refpos->pos.v - shipbox_refpos.v - cur.v; + cur.v = refpos->pos.v - shipbox_refpos.v - cur.v; break; default: assert(0); @@ -1039,14 +956,12 @@ void vlist_out(PDF pdf, halfword this_box) cur.v += leader_ht; } else if (subtype(p) == a_leaders) { save_v = cur.v; - cur.v = - top_edge + - leader_ht * ((cur.v - top_edge) / leader_ht); + cur.v = top_edge + leader_ht * ((cur.v - top_edge) / leader_ht); if (cur.v < save_v) cur.v += leader_ht; } else { - lq = rule.ht / leader_ht; /* the number of box copies */ - lr = rule.ht % leader_ht; /* the remaining space */ + lq = rule.ht / leader_ht; /* the number of box copies */ + lr = rule.ht % leader_ht; /* the remaining space */ if (subtype(p) == c_leaders) { cur.v += lr / 2; } else { @@ -1056,8 +971,7 @@ void vlist_out(PDF pdf, halfword this_box) } while (cur.v + leader_ht <= edge) { - /* (\pdfTeX) Output a leader box at |cur.v|, - then advance |cur.v| by |leader_ht+lx| */ + /* output a leader box at |cur.v|, then advance |cur.v| by |leader_ht+lx| */ assert(cur.h == 0); tmpcur.h = shift_amount(leader_box); tmpcur.v = cur.v + height(leader_box); @@ -1086,10 +1000,11 @@ void vlist_out(PDF pdf, halfword this_box) } goto NEXTP; FIN_RULE: - /* (\pdfTeX) Output a rule in a vlist, |goto next_p| */ + /* output a rule in a vlist, |goto next_p| */ if (is_running(rule.wd)) rule.wd = width(this_box); - if ((rule.ht + rule.dp) > 0 && rule.wd > 0) { /* we don't output empty rules */ + /* we don't output empty rules */ + if ((rule.ht + rule.dp) > 0 && rule.wd > 0) { switch (localpos.dir) { case dir_TLT: size.h = rule.wd; @@ -1116,7 +1031,14 @@ void vlist_out(PDF pdf, halfword this_box) default: assert(0); } - backend_out[rule_node] (pdf, p, size); /* |pdf_place_rule(pdf, rule.ht, rule.wd);| */ + if (type(p) == glue_node) { + q = leader_ptr(p); + if ((q) && (type(q) == rule_node)) { + backend_out[rule_node] (pdf, q, size); + } + } else { + backend_out[rule_node] (pdf, p, size); + } } cur.v += rule.ht + rule.dp; goto NEXTP; @@ -1127,15 +1049,14 @@ void vlist_out(PDF pdf, halfword this_box) } synch_pos_with_cur(pdf->posstruct, refpos, cur); } - /* Finish vlist {\sl Sync\TeX} information record */ - if (int_par(synctex_code)) + if (synctex) synctextsilv(this_box); - if (pdf->o_mode == OMODE_DVI) { - prune_movements(save_loc); /* DVI! */ - if (cur_s > 0) { /* DVI! */ - dvi_pop(save_loc); /* DVI! */ - dvi = save_dvi; /* DVI! */ + if (output_mode_used == OMODE_DVI) { + prune_movements(save_loc); + if (cur_s > 0) { + dvi_pop(save_loc); + dvi = save_dvi; } } cur_s--; |