beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / pdf / pdfliteral.w
blob3c6b6f6efbfb9880ec629df0ee12bb7c897bbb58
1 % pdfliteral.w
3 % Copyright 2009-2010 Taco Hoekwater <taco@@luatex.org>
5 % This file is part of LuaTeX.
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.
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.
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/>.
20 @ @c
22 #include "ptexlib.h"
24 @ @c
25 void pdf_special(PDF pdf, halfword p)
27 int old_setting = selector;
28 str_number s;
29 selector = new_string;
30 show_token_list(token_link(write_tokens(p)), null, -1);
31 selector = old_setting;
32 s = make_string();
33 pdf_literal(pdf, s, scan_special, true);
34 flush_str(s);
37 @ To ship out a \TeX\ box to PDF page description we need to implement
38 |hlist_out|, |vlist_out| and |ship_out|, which are equivalent to the \TeX'
39 original |hlist_out|, |vlist_out| and |ship_out| resp. But first we need to
40 declare some procedures needed in |hlist_out| and |vlist_out|.
43 void pdf_out_literal(PDF pdf, halfword p)
45 int old_setting; /* holds print |selector| */
46 str_number s;
47 pdfstructure *ps = pdf->pstruct;
48 if (pdf_literal_type(p) == normal) {
49 old_setting = selector;
50 selector = new_string;
51 show_token_list(token_link(pdf_literal_data(p)), null, -1);
52 selector = old_setting;
53 s = make_string();
54 pdf_literal(pdf, s, pdf_literal_mode(p), false);
55 flush_str(s);
56 } else {
57 switch (pdf_literal_mode(p)) {
58 case set_origin:
59 pdf_goto_pagemode(pdf);
60 pdf_set_pos(pdf, pdf->posstruct->pos);
61 break;
62 case direct_page:
63 pdf_goto_pagemode(pdf);
64 break;
65 case direct_always:
66 pdf_end_string_nl(pdf);
67 ps->need_tm = true;
68 break;
69 default:
70 normal_error("pdf backend","bad literal mode");
71 break;
73 lua_pdf_literal(pdf, pdf_literal_data(p));
77 @ test equality of start of strings
79 static boolean str_in_cstr(str_number s, const char *r, unsigned i)
81 const unsigned char *k, *l;
82 if ((unsigned) str_length(s) < i + strlen(r))
83 return false;
84 k = (const unsigned char *) r;
85 l = str_string(s) + i;
86 while ((*l) && (*k)) {
87 if (*l++ != *k++)
88 return false;
90 return true;
93 @ @c
94 void pdf_literal(PDF pdf, str_number s, int literal_mode, boolean warn)
96 unsigned char *ss;
97 size_t l;
98 pool_pointer j = 0; /* current character code position, initialized to make the compiler happy */
99 pdfstructure *p = pdf->pstruct;
100 if (s >= STRING_OFFSET) {
101 /* needed for |out_save| */
102 j = 0;
103 /* the next is obsolete, in fact, specials are obsolete in pdf mode */
104 if (literal_mode == scan_special) {
105 if (!(str_in_cstr(s, "PDF:", 0) || str_in_cstr(s, "pdf:", 0))) {
106 if (warn && ((!(str_in_cstr(s, "SRC:", 0) || str_in_cstr(s, "src:", 0))) || (str_length(s) == 0)))
107 tprint_nl("Non-PDF special ignored!");
108 return;
110 j = j + (pool_pointer) strlen("PDF:");
111 if (str_in_cstr(s, "direct:", strlen("PDF:"))) {
112 j = j + (pool_pointer) strlen("direct:");
113 literal_mode = direct_always;
114 } else if (str_in_cstr(s, "page:", strlen("PDF:"))) {
115 j = j + (pool_pointer) strlen("page:");
116 literal_mode = direct_page;
117 } else {
118 literal_mode = set_origin;
122 switch (literal_mode) {
123 case set_origin:
124 pdf_goto_pagemode(pdf);
125 pdf_set_pos(pdf, pdf->posstruct->pos);
126 break;
127 case direct_page:
128 pdf_goto_pagemode(pdf);
129 break;
130 case direct_always:
131 pdf_end_string_nl(pdf);
132 p->need_tm = true;
133 break;
134 default:
135 normal_error("pdf backend","bad literal mode");
136 break;
138 if (s >= STRING_OFFSET) {
139 ss = str_string(s);
140 l = str_length(s) - (size_t) j;
141 pdf_out_block(pdf, (const char *) (ss + j), l);
142 } else {
143 pdf_out(pdf, s);
145 pdf_out(pdf, '\n');