~ubuntu-branches/ubuntu/saucy/luatex/saucy

« back to all changes in this revision

Viewing changes to source/texk/web2c/luatexdir/pdf/pdflink.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Preining
  • Date: 2009-12-25 09:47:05 UTC
  • mfrom: (1.1.9 upstream) (4.2.3 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091225094705-y33rpflo8t4u9nag
Tags: 0.50.0-1
* new upstream release
* disable fix-hurd-ftbfs patch, included upstream
* disable upstram-fixes, included upstream
* disable ubuntu_libpoppler-0.11, not needed anymore

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* pdflink.c
 
2
   
 
3
   Copyright 2009 Taco Hoekwater <taco@luatex.org>
 
4
 
 
5
   This file is part of LuaTeX.
 
6
 
 
7
   LuaTeX is free software; you can redistribute it and/or modify it under
 
8
   the terms of the GNU General Public License as published by the Free
 
9
   Software Foundation; either version 2 of the License, or (at your
 
10
   option) any later version.
 
11
 
 
12
   LuaTeX is distributed in the hope that it will be useful, but WITHOUT
 
13
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
14
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 
15
   License for more details.
 
16
 
 
17
   You should have received a copy of the GNU General Public License along
 
18
   with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
 
19
 
 
20
#include "ptexlib.h"
 
21
 
 
22
 
 
23
 
 
24
static const char __svn_version[] =
 
25
    "$Id: pdflink.c 3261 2009-12-18 11:38:21Z taco $"
 
26
    "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.50.0/source/texk/web2c/luatexdir/pdf/pdflink.c $";
 
27
 
 
28
#define pdf_link_margin          dimen_par(pdf_link_margin_code)
 
29
 
 
30
/*
 
31
To implement nested link annotations, we need a stack to hold copy of
 
32
|pdf_start_link_node|'s that are being written out, together with their box
 
33
nesting level.
 
34
*/
 
35
 
 
36
void push_link_level(PDF pdf, halfword p)
 
37
{
 
38
    if (pdf->link_stack_ptr >= pdf_max_link_level)
 
39
        overflow("pdf link stack size", pdf_max_link_level);
 
40
    assert(((type(p) == whatsit_node) && (subtype(p) == pdf_start_link_node)));
 
41
    incr(pdf->link_stack_ptr);
 
42
    pdf->link_stack[pdf->link_stack_ptr].nesting_level = cur_s;
 
43
    pdf->link_stack[pdf->link_stack_ptr].link_node = copy_node_list(p);
 
44
    pdf->link_stack[pdf->link_stack_ptr].ref_link_node = p;
 
45
}
 
46
 
 
47
void pop_link_level(PDF pdf)
 
48
{
 
49
    assert(pdf->link_stack_ptr > 0);
 
50
    flush_node_list(pdf->link_stack[pdf->link_stack_ptr].link_node);
 
51
    decr(pdf->link_stack_ptr);
 
52
}
 
53
 
 
54
void do_link(PDF pdf, halfword p, halfword parent_box, scaledpos cur)
 
55
{
 
56
    scaled_whd alt_rule;
 
57
    if (type(p) == vlist_node)
 
58
        pdf_error("ext4", "\\pdfstartlink ended up in vlist");
 
59
    if (!is_shipping_page)
 
60
        pdf_error("ext4", "link annotations cannot be inside an XForm");
 
61
    assert(type(parent_box) == hlist_node);
 
62
    if (is_obj_scheduled(pdf, pdf_link_objnum(p)))
 
63
        pdf_link_objnum(p) = pdf_new_objnum(pdf);
 
64
    push_link_level(pdf, p);
 
65
    alt_rule.wd = width(p);
 
66
    alt_rule.ht = height(p);
 
67
    alt_rule.dp = depth(p);
 
68
    set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_link_margin);
 
69
    obj_annot_ptr(pdf, pdf_link_objnum(p)) = p; /* the reference for the pdf annot object must be set here */
 
70
    append_object_list(pdf, obj_type_link, pdf_link_objnum(p));
 
71
}
 
72
 
 
73
void end_link(PDF pdf, halfword p)
 
74
{
 
75
    halfword q;
 
76
    scaledpos pos = pdf->posstruct->pos;
 
77
    if (type(p) == vlist_node)
 
78
        pdf_error("ext4", "\\pdfendlink ended up in vlist");
 
79
    if (pdf->link_stack_ptr < 1)
 
80
        pdf_error("ext4",
 
81
                  "pdf link_stack empty, \\pdfendlink used without \\pdfstartlink?");
 
82
    if (pdf->link_stack[pdf->link_stack_ptr].nesting_level != cur_s)
 
83
        pdf_error("ext4",
 
84
                  "\\pdfendlink ended up in different nesting level than \\pdfstartlink");
 
85
 
 
86
    /* N.B.: test for running link must be done on |link_node| and not |ref_link_node|,
 
87
       as |ref_link_node| can be set by |do_link| or |append_link| already */
 
88
 
 
89
    if (is_running(width(pdf->link_stack[pdf->link_stack_ptr].link_node))) {
 
90
        q = pdf->link_stack[pdf->link_stack_ptr].ref_link_node;
 
91
        if (is_shipping_page && matrixused()) {
 
92
            matrixrecalculate(pos.h + pdf_link_margin);
 
93
            pdf_ann_left(q) = getllx() - pdf_link_margin;
 
94
            pdf_ann_top(q) = cur_page_size.v - getury() - pdf_link_margin;
 
95
            pdf_ann_right(q) = geturx() + pdf_link_margin;
 
96
            pdf_ann_bottom(q) = cur_page_size.v - getlly() + pdf_link_margin;
 
97
        } else {
 
98
            switch (pdf->posstruct->dir) {
 
99
            case dir_TLT:
 
100
                pdf_ann_right(q) = pos.h + pdf_link_margin;
 
101
                break;
 
102
            case dir_TRT:
 
103
                pdf_ann_left(q) = pos.h - pdf_link_margin;
 
104
                break;
 
105
            case dir_LTL:
 
106
            case dir_RTT:
 
107
                pdf_ann_bottom(q) = pos.v - pdf_link_margin;
 
108
                break;
 
109
            }
 
110
        }
 
111
    }
 
112
    pop_link_level(pdf);
 
113
}
 
114
 
 
115
/*
 
116
For ``running'' annotations we must append a new node when the end of
 
117
annotation is in other box than its start. The new created node is identical to
 
118
corresponding whatsit node representing the start of annotation,  but its
 
119
|info| field is |max_halfword|. We set |info| field just before destroying the
 
120
node, in order to use |flush_node_list| to do the job.
 
121
*/
 
122
 
 
123
/* append a new pdf annot to |pdf_link_list| */
 
124
 
 
125
void append_link(PDF pdf, halfword parent_box, scaledpos cur, small_number i)
 
126
{
 
127
    halfword p;
 
128
    scaled_whd alt_rule;
 
129
    assert(type(parent_box) == hlist_node);
 
130
    p = copy_node(pdf->link_stack[(int) i].link_node);
 
131
    pdf->link_stack[(int) i].ref_link_node = p;
 
132
    subtype(p) = pdf_link_data_node;    /* this node is not a normal link node */
 
133
    alt_rule.wd = width(p);
 
134
    alt_rule.ht = height(p);
 
135
    alt_rule.dp = depth(p);
 
136
    set_rect_dimens(pdf, p, parent_box, cur, alt_rule, pdf_link_margin);
 
137
    pdf_create_obj(pdf, obj_type_others, 0);
 
138
    obj_annot_ptr(pdf, pdf->obj_ptr) = p;
 
139
    append_object_list(pdf, obj_type_link, pdf->obj_ptr);
 
140
}
 
141
 
 
142
void scan_startlink(PDF pdf)
 
143
{
 
144
    int k;
 
145
    halfword r;
 
146
    if (abs(cur_list.mode_field) == vmode)
 
147
        pdf_error("ext1", "\\pdfstartlink cannot be used in vertical mode");
 
148
    k = pdf_new_objnum(pdf);
 
149
    new_annot_whatsit(pdf_start_link_node);
 
150
    set_pdf_link_attr(cur_list.tail_field, null);
 
151
    if (scan_keyword("attr")) {
 
152
        scan_pdf_ext_toks();
 
153
        set_pdf_link_attr(cur_list.tail_field, def_ref);
 
154
    }
 
155
    r = scan_action(pdf);
 
156
    set_pdf_link_action(cur_list.tail_field, r);
 
157
    set_pdf_link_objnum(cur_list.tail_field, k);
 
158
    pdf_last_link = k;
 
159
    /* N.B.: although it is possible to set |obj_annot_ptr(k) := tail| here, it
 
160
       is not safe if nodes are later copied/destroyed/moved; a better place
 
161
       to do this is inside |do_link|, when the whatsit node is written out */
 
162
}