fix getsup (HH)
[luatex.git] / source / texk / web2c / luatexdir / pdf / pdfliteral.w
blob64a36dc67bfaffa5e31aa311baa0660a058ff482
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 case direct_raw:
70 pdf_end_string_nl(pdf);
71 break;
72 default:
73 normal_error("pdf backend","bad literal mode");
74 break;
76 lua_pdf_literal(pdf, pdf_literal_data(p));
80 @ test equality of start of strings
82 static boolean str_in_cstr(str_number s, const char *r, unsigned i)
84 const unsigned char *k, *l;
85 if ((unsigned) str_length(s) < i + strlen(r))
86 return false;
87 k = (const unsigned char *) r;
88 l = str_string(s) + i;
89 while ((*l) && (*k)) {
90 if (*l++ != *k++)
91 return false;
93 return true;
96 @ @c
97 void pdf_literal(PDF pdf, str_number s, int literal_mode, boolean warn)
99 unsigned char *ss;
100 size_t l;
101 pool_pointer j = 0; /* current character code position, initialized to make the compiler happy */
102 pdfstructure *p = pdf->pstruct;
103 if (s >= STRING_OFFSET) {
104 /* needed for |out_save| */
105 j = 0;
106 /* the next is obsolete, in fact, specials are obsolete in pdf mode */
107 if (literal_mode == scan_special) {
108 if (!(str_in_cstr(s, "PDF:", 0) || str_in_cstr(s, "pdf:", 0))) {
109 if (warn && ((!(str_in_cstr(s, "SRC:", 0) || str_in_cstr(s, "src:", 0))) || (str_length(s) == 0)))
110 tprint_nl("Non-PDF special ignored!");
111 return;
113 j = j + (pool_pointer) strlen("PDF:");
114 if (str_in_cstr(s, "direct:", strlen("PDF:"))) {
115 j = j + (pool_pointer) strlen("direct:");
116 literal_mode = direct_always;
117 } else if (str_in_cstr(s, "page:", strlen("PDF:"))) {
118 j = j + (pool_pointer) strlen("page:");
119 literal_mode = direct_page;
120 } else if (str_in_cstr(s, "raw:", strlen("PDF:"))) {
121 j = j + (pool_pointer) strlen("raw:");
122 literal_mode = direct_raw;
123 } else {
124 literal_mode = set_origin;
128 switch (literal_mode) {
129 case set_origin:
130 pdf_goto_pagemode(pdf);
131 pdf_set_pos(pdf, pdf->posstruct->pos);
132 break;
133 case direct_page:
134 pdf_goto_pagemode(pdf);
135 break;
136 case direct_always:
137 pdf_end_string_nl(pdf);
138 p->need_tm = true;
139 break;
140 case direct_raw:
141 pdf_end_string_nl(pdf);
142 break;
143 default:
144 normal_error("pdf backend","bad literal mode");
145 break;
147 if (s >= STRING_OFFSET) {
148 ss = str_string(s);
149 l = str_length(s) - (size_t) j;
150 pdf_out_block(pdf, (const char *) (ss + j), l);
151 } else {
152 pdf_out(pdf, s);
154 pdf_out(pdf, '\n');