1% pdfliteral.w 2% 3% Copyright 2009-2010 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@ @c 21 22 23#include "ptexlib.h" 24 25@ @c 26void pdf_special(PDF pdf, halfword p) 27{ 28 int old_setting; /* holds print |selector| */ 29 str_number s; 30 old_setting = selector; 31 selector = new_string; 32 show_token_list(token_link(write_tokens(p)), null, -1); 33 selector = old_setting; 34 s = make_string(); 35 pdf_literal(pdf, s, scan_special, true); 36 flush_str(s); 37} 38 39 40@ To ship out a \TeX\ box to PDF page description we need to implement 41|hlist_out|, |vlist_out| and |ship_out|, which are equivalent to 42the \TeX' original |hlist_out|, |vlist_out| and |ship_out| resp. But first we 43need to declare some procedures needed in |hlist_out| and |vlist_out|. 44 45@c 46void pdf_out_literal(PDF pdf, halfword p) 47{ 48 int old_setting; /* holds print |selector| */ 49 str_number s; 50 pdfstructure *ps = pdf->pstruct; 51 if (pdf_literal_type(p) == normal) { 52 old_setting = selector; 53 selector = new_string; 54 show_token_list(token_link(pdf_literal_data(p)), null, -1); 55 selector = old_setting; 56 s = make_string(); 57 pdf_literal(pdf, s, pdf_literal_mode(p), false); 58 flush_str(s); 59 } else { 60 assert(pdf_literal_mode(p) != scan_special); 61 switch (pdf_literal_mode(p)) { 62 case set_origin: 63 pdf_goto_pagemode(pdf); 64 pdf_set_pos(pdf, pdf->posstruct->pos); 65 break; 66 case direct_page: 67 pdf_goto_pagemode(pdf); 68 break; 69 case direct_always: 70 pdf_end_string_nl(pdf); 71 ps->need_tm = true; 72 break; 73 default: 74 confusion("literal1"); 75 break; 76 } 77 lua_pdf_literal(pdf, pdf_literal_data(p)); 78 } 79} 80 81@ test equality of start of strings 82@c 83static boolean str_in_cstr(str_number s, const char *r, unsigned i) 84{ 85 const unsigned char *k, *l; 86 if ((unsigned) str_length(s) < i + strlen(r)) 87 return false; 88 k = (const unsigned char *) r; 89 l = str_string(s) + i; 90 while ((*l) && (*k)) { 91 if (*l++ != *k++) 92 return false; 93 } 94 return true; 95} 96 97@ @c 98void pdf_literal(PDF pdf, str_number s, int literal_mode, boolean warn) 99{ 100 unsigned char *ss; 101 size_t l; 102 pool_pointer j = 0; /* current character code position, initialized to make the compiler happy */ 103 pdfstructure *p = pdf->pstruct; 104 if (s >= STRING_OFFSET) { /* needed for |out_save| */ 105 j = 0; 106 if (literal_mode == scan_special) { 107 if (!(str_in_cstr(s, "PDF:", 0) || str_in_cstr(s, "pdf:", 0))) { 108 if (warn 109 && 110 ((!(str_in_cstr(s, "SRC:", 0) || str_in_cstr(s, "src:", 0))) 111 || (str_length(s) == 0))) 112 tprint_nl("Non-PDF special ignored!"); 113 return; 114 } 115 j = j + (pool_pointer) strlen("PDF:"); 116 if (str_in_cstr(s, "direct:", strlen("PDF:"))) { 117 j = j + (pool_pointer) strlen("direct:"); 118 literal_mode = direct_always; 119 } else if (str_in_cstr(s, "page:", strlen("PDF:"))) { 120 j = j + (pool_pointer) strlen("page:"); 121 literal_mode = direct_page; 122 } else { 123 literal_mode = set_origin; 124 } 125 } 126 } 127 switch (literal_mode) { 128 case set_origin: 129 pdf_goto_pagemode(pdf); 130 pdf_set_pos(pdf, pdf->posstruct->pos); 131 break; 132 case direct_page: 133 pdf_goto_pagemode(pdf); 134 break; 135 case direct_always: 136 pdf_end_string_nl(pdf); 137 p->need_tm = true; 138 break; 139 default: 140 confusion("literal1"); 141 break; 142 } 143 if (s >= STRING_OFFSET) { 144 ss = str_string(s); 145 l = str_length(s) - (size_t) j; 146 pdf_out_block(pdf, (const char *) (ss + j), l); 147 } else { 148 assert(s < 256); 149 pdf_out(pdf, s); 150 } 151 pdf_out(pdf, '\n'); 152} 153