summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/pdf/pdfthread.w
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/pdf/pdfthread.w')
-rw-r--r--Build/source/texk/web2c/luatexdir/pdf/pdfthread.w290
1 files changed, 290 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/pdf/pdfthread.w b/Build/source/texk/web2c/luatexdir/pdf/pdfthread.w
new file mode 100644
index 00000000000..e788a3cdf4f
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/pdf/pdfthread.w
@@ -0,0 +1,290 @@
+% pdfthread.w
+
+% Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
+
+% 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 <http://www.gnu.org/licenses/>.
+
+@ @c
+static const char _svn_version[] =
+ "$Id: pdfthread.w 3571 2010-04-02 13:50:45Z taco $"
+ "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/pdf/pdfthread.w $";
+
+#include "ptexlib.h"
+
+@ @c
+#define pdf_thread_margin dimen_par(pdf_thread_margin_code)
+#define page_width dimen_par(page_width_code)
+#define page_height dimen_par(page_height_code)
+
+@ Threads are handled in similar way as link annotations
+@c
+void append_bead(PDF pdf, halfword p)
+{
+ int a, b, c, t;
+ if (!is_shipping_page)
+ pdf_error("ext4", "threads cannot be inside an XForm");
+ t = get_obj(pdf, obj_type_thread, pdf_thread_id(p), pdf_thread_named_id(p));
+ b = pdf_new_objnum(pdf);
+ obj_bead_ptr(pdf, b) = pdf_get_mem(pdf, pdfmem_bead_size);
+ set_obj_bead_page(pdf, b, pdf->last_page);
+ set_obj_bead_data(pdf, b, p);
+ if (pdf_thread_attr(p) != null)
+ set_obj_bead_attr(pdf, b, tokens_to_string(pdf_thread_attr(p)));
+ else
+ set_obj_bead_attr(pdf, b, 0);
+ if (obj_thread_first(pdf, t) == 0) {
+ obj_thread_first(pdf, t) = b;
+ set_obj_bead_next(pdf, b, b);
+ set_obj_bead_prev(pdf, b, b);
+ } else {
+ a = obj_thread_first(pdf, t);
+ c = obj_bead_prev(pdf, a);
+ set_obj_bead_prev(pdf, b, c);
+ set_obj_bead_next(pdf, b, a);
+ set_obj_bead_prev(pdf, a, b);
+ set_obj_bead_next(pdf, c, b);
+ }
+ addto_page_resources(pdf, obj_type_bead, b);
+}
+
+@ @c
+void do_thread(PDF pdf, halfword p, halfword parent_box, scaledpos cur)
+{
+ scaled_whd alt_rule;
+ if ((type(p) == hlist_node) && (subtype(p) == pdf_start_thread_node))
+ pdf_error("ext4", "\\pdfstartthread ended up in hlist");
+ if (doing_leaders)
+ return;
+ if (subtype(p) == pdf_start_thread_node) {
+ pdf->thread.wd = width(p);
+ pdf->thread.ht = height(p);
+ pdf->thread.dp = depth(p);
+ pdf->last_thread_id = pdf_thread_id(p);
+ pdf->last_thread_named_id = (pdf_thread_named_id(p) > 0);
+ if (pdf->last_thread_named_id)
+ add_token_ref(pdf_thread_id(p));
+ pdf->thread_level = cur_s;
+ }
+ alt_rule.wd = width(p);
+ alt_rule.ht = height(p);
+ alt_rule.dp = depth(p);
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_thread_margin);
+ append_bead(pdf, p);
+ pdf->last_thread = p;
+}
+
+@ @c
+void append_thread(PDF pdf, halfword parent_box, scaledpos cur)
+{
+ halfword p;
+ scaled_whd alt_rule;
+ p = new_node(whatsit_node, pdf_thread_data_node);
+ width(p) = pdf->thread.wd;
+ height(p) = pdf->thread.ht;
+ depth(p) = pdf->thread.dp;
+ pdf_thread_attr(p) = null;
+ pdf_thread_id(p) = pdf->last_thread_id;
+ if (pdf->last_thread_named_id) {
+ add_token_ref(pdf_thread_id(p));
+ pdf_thread_named_id(p) = 1;
+ } else {
+ pdf_thread_named_id(p) = 0;
+ }
+ alt_rule.wd = width(p);
+ alt_rule.ht = height(p);
+ alt_rule.dp = depth(p);
+ set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_thread_margin);
+ append_bead(pdf, p);
+ pdf->last_thread = p;
+}
+
+@ @c
+void end_thread(PDF pdf, halfword p)
+{
+ scaledpos pos = pdf->posstruct->pos;
+ if (type(p) == hlist_node)
+ pdf_error("ext4", "\\pdfendthread ended up in hlist");
+ if (pdf->thread_level != cur_s)
+ pdf_error("ext4",
+ "\\pdfendthread ended up in different nesting level than \\pdfstartthread");
+ if (is_running(pdf->thread.dp) && (pdf->last_thread != null)) {
+ switch (pdf->posstruct->dir) {
+ case dir_TLT:
+ case dir_TRT:
+ pdf_ann_bottom(pdf->last_thread) = pos.v - pdf_thread_margin;
+ break;
+ case dir_LTL:
+ pdf_ann_right(pdf->last_thread) = pos.h + pdf_thread_margin;
+ break;
+ case dir_RTT:
+ pdf_ann_left(pdf->last_thread) = pos.h - pdf_thread_margin;
+ break;
+ }
+ }
+ if (pdf->last_thread_named_id)
+ delete_token_ref(pdf->last_thread_id);
+ pdf->last_thread = null;
+}
+
+@ The following function are needed for outputing article thread.
+@c
+void thread_title(PDF pdf, int t)
+{
+ pdf_printf(pdf, "/Title (");
+ if (obj_info(pdf, t) < 0)
+ pdf_print(pdf, -obj_info(pdf, t));
+ else
+ pdf_print_int(pdf, obj_info(pdf, t));
+ pdf_printf(pdf, ")\n");
+}
+
+void pdf_fix_thread(PDF pdf, int t)
+{
+ halfword a;
+ pdf_warning("thread", "destination", false, false);
+ if (obj_info(pdf, t) < 0) {
+ tprint("name{");
+ print(-obj_info(pdf, t));
+ tprint("}");
+ } else {
+ tprint("num");
+ print_int(obj_info(pdf, t));
+ }
+ tprint(" has been referenced but does not exist, replaced by a fixed one");
+ print_ln();
+ print_ln();
+ pdf_new_dict(pdf, obj_type_others, 0, 0);
+ a = pdf->obj_ptr;
+ pdf_indirect_ln(pdf, "T", t);
+ pdf_indirect_ln(pdf, "V", a);
+ pdf_indirect_ln(pdf, "N", a);
+ pdf_indirect_ln(pdf, "P", pdf->last_page);
+ pdf_printf(pdf, "/R [0 0 ");
+ pdf_print_bp(pdf, page_width);
+ pdf_out(pdf, ' ');
+ pdf_print_bp(pdf, page_height);
+ pdf_printf(pdf, "]\n");
+ pdf_end_dict(pdf);
+ pdf_begin_dict(pdf, t, 1);
+ pdf_printf(pdf, "/I << \n");
+ thread_title(pdf, t);
+ pdf_printf(pdf, ">>\n");
+ pdf_indirect_ln(pdf, "F", a);
+ pdf_end_dict(pdf);
+}
+
+void out_thread(PDF pdf, int t)
+{
+ halfword a, b;
+ int last_attr;
+ if (obj_thread_first(pdf, t) == 0) {
+ pdf_fix_thread(pdf, t);
+ return;
+ }
+ pdf_begin_dict(pdf, t, 1);
+ a = obj_thread_first(pdf, t);
+ b = a;
+ last_attr = 0;
+ do {
+ if (obj_bead_attr(pdf, a) != 0)
+ last_attr = obj_bead_attr(pdf, a);
+ a = obj_bead_next(pdf, a);
+ } while (a != b);
+ if (last_attr != 0) {
+ pdf_print_ln(pdf, last_attr);
+ } else {
+ pdf_printf(pdf, "/I << \n");
+ thread_title(pdf, t);
+ pdf_printf(pdf, ">>\n");
+ }
+ pdf_indirect_ln(pdf, "F", a);
+ pdf_end_dict(pdf);
+ do {
+ pdf_begin_dict(pdf, a, 1);
+ if (a == b)
+ pdf_indirect_ln(pdf, "T", t);
+ pdf_indirect_ln(pdf, "V", obj_bead_prev(pdf, a));
+ pdf_indirect_ln(pdf, "N", obj_bead_next(pdf, a));
+ pdf_indirect_ln(pdf, "P", obj_bead_page(pdf, a));
+ pdf_indirect_ln(pdf, "R", obj_bead_rect(pdf, a));
+ pdf_end_dict(pdf);
+ a = obj_bead_next(pdf, a);
+ } while (a != b);
+}
+
+
+@ @c
+void scan_thread_id(void)
+{
+ if (scan_keyword("num")) {
+ scan_int();
+ if (cur_val <= 0)
+ pdf_error("ext1", "num identifier must be positive");
+ if (cur_val > max_halfword)
+ pdf_error("ext1", "number too big");
+ set_pdf_thread_id(cur_list.tail_field, cur_val);
+ set_pdf_thread_named_id(cur_list.tail_field, 0);
+ } else if (scan_keyword("name")) {
+ scan_pdf_ext_toks();
+ set_pdf_thread_id(cur_list.tail_field, def_ref);
+ set_pdf_thread_named_id(cur_list.tail_field, 1);
+ } else {
+ pdf_error("ext1", "identifier type missing");
+ }
+}
+
+void check_running_thread(PDF pdf, halfword this_box, scaledpos cur)
+{
+ if ((pdf->last_thread != null) && is_running(pdf->thread.dp)
+ && (pdf->thread_level == cur_s))
+ append_thread(pdf, this_box, cur);
+}
+
+@ @c
+void print_beads_list(PDF pdf)
+{
+ pdf_object_list *k;
+ if ((k = get_page_resources_list(pdf, obj_type_bead)) != NULL) {
+ pdf_printf(pdf, "/B [ ");
+ while (k != NULL) {
+ pdf_print_int(pdf, k->info);
+ pdf_printf(pdf, " 0 R ");
+ k = k->link;
+ }
+ pdf_printf(pdf, "]\n");
+ }
+}
+
+@ @c
+void print_bead_rectangles(PDF pdf)
+{
+ halfword i;
+ pdf_object_list *k;
+ if ((k = get_page_resources_list(pdf, obj_type_bead)) != NULL) {
+ while (k != NULL) {
+ pdf_new_obj(pdf, obj_type_others, 0, 1);
+ pdf_out(pdf, '[');
+ i = obj_bead_data(pdf, k->info); /* pointer to a whatsit or whatsit-like node */
+ pdf_print_rect_spec(pdf, i);
+ if (subtype(i) == pdf_thread_data_node) /* thanh says it mis be destroyed here */
+ flush_node(i);
+ pdf_printf(pdf, "]\n");
+ set_obj_bead_rect(pdf, k->info, pdf->obj_ptr); /* rewrite |obj_bead_data| */
+ pdf_end_obj(pdf);
+ k = k->link;
+ }
+ }
+}