3 This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
5 Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata,
6 the dvipdfmx project team.
8 Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
43 #include "pdfximage.h"
51 #include "spc_dvips.h"
54 static int block_pending = 0;
55 static double pending_x = 0.0;
56 static double pending_y = 0.0;
57 static int position_set = 0;
60 parse_filename (const char **pp, const char *endptr)
63 const char *q = NULL, *p = *pp;
67 if (!p || p >= endptr)
69 else if (*p == '\"' || *p == '\'')
74 for (n = 0, q = p; p < endptr && *p != qchar; n++, p++);
86 for (i = 0; i < n && isprint(q[i]); i++);
88 WARN("Non printable char in filename string...");
94 memcpy(r, q, n); r[n] = '\0';
102 spc_handler_ps_file (struct spc_env *spe, struct spc_arg *args)
110 skip_white(&args->curptr, args->endptr);
111 if (args->curptr + 1 >= args->endptr ||
112 args->curptr[0] != '=') {
113 spc_warn(spe, "No filename specified for PSfile special.");
118 filename = parse_filename(&args->curptr, args->endptr);
120 spc_warn(spe, "No filename specified for PSfile special.");
124 transform_info_clear(&ti);
125 if (spc_util_read_dimtrns(spe, &ti, args, NULL, 1) < 0) {
130 form_id = pdf_ximage_findresource(filename, 1, NULL);
132 spc_warn(spe, "Failed to read image file: %s", filename);
138 pdf_dev_put_image(form_id, &ti, spe->x_user, spe->y_user);
143 /* This isn't correct implementation but dvipdfm supports... */
145 spc_handler_ps_plotfile (struct spc_env *spe, struct spc_arg *args)
154 spc_warn(spe, "\"ps: plotfile\" found (not properly implemented)");
156 skip_white(&args->curptr, args->endptr);
157 filename = parse_filename(&args->curptr, args->endptr);
159 spc_warn(spe, "Expecting filename but not found...");
163 form_id = pdf_ximage_findresource(filename, 1, NULL);
165 spc_warn(spe, "Could not open PS file: %s", filename);
168 transform_info_clear(&p);
169 p.matrix.d = -1.0; /* xscale = 1.0, yscale = -1.0 */
171 /* I don't know how to treat this... */
172 pdf_dev_put_image(form_id, &p,
173 block_pending ? pending_x : spe->x_user,
174 block_pending ? pending_y : spe->y_user);
176 pdf_dev_put_image(form_id, &p, 0, 0);
184 spc_handler_ps_literal (struct spc_env *spe, struct spc_arg *args)
187 int st_depth, gs_depth;
188 double x_user, y_user;
190 ASSERT(spe && args && args->curptr <= args->endptr);
192 if (args->curptr + strlen(":[begin]") <= args->endptr &&
193 !strncmp(args->curptr, ":[begin]", strlen(":[begin]"))) {
197 x_user = pending_x = spe->x_user;
198 y_user = pending_y = spe->y_user;
199 args->curptr += strlen(":[begin]");
200 } else if (args->curptr + strlen(":[end]") <= args->endptr &&
201 !strncmp(args->curptr, ":[end]", strlen(":[end]"))) {
202 if (block_pending <= 0) {
203 spc_warn(spe, "No corresponding ::[begin] found.");
212 args->curptr += strlen(":[end]");
213 } else if (args->curptr < args->endptr &&
214 args->curptr[0] == ':') {
215 x_user = position_set ? pending_x : spe->x_user;
216 y_user = position_set ? pending_y : spe->y_user;
220 x_user = pending_x = spe->x_user;
221 y_user = pending_y = spe->y_user;
224 skip_white(&args->curptr, args->endptr);
225 if (args->curptr < args->endptr) {
227 st_depth = mps_stack_depth();
228 gs_depth = pdf_dev_current_depth();
230 error = mps_exec_inline(&args->curptr,
234 spc_warn(spe, "Interpreting PS code failed!!! Output might be broken!!!");
235 pdf_dev_grestore_to(gs_depth);
236 } else if (st_depth != mps_stack_depth()) {
237 spc_warn(spe, "Stack not empty after execution of inline PostScript code.");
238 spc_warn(spe, ">> Your macro package makes some assumption on internal behaviour of DVI drivers.");
239 spc_warn(spe, ">> It may not compatible with dvipdfmx.");
247 spc_handler_ps_default (struct spc_env *spe, struct spc_arg *args)
250 int st_depth, gs_depth;
256 st_depth = mps_stack_depth();
257 gs_depth = pdf_dev_current_depth();
261 M.a = M.d = 1.0; M.b = M.c = 0.0; M.e = spe->x_user; M.f = spe->y_user;
263 error = mps_exec_inline(&args->curptr,
265 spe->x_user, spe->y_user);
266 M.e = -spe->x_user; M.f = -spe->y_user;
270 spc_warn(spe, "Interpreting PS code failed!!! Output might be broken!!!");
272 if (st_depth != mps_stack_depth()) {
273 spc_warn(spe, "Stack not empty after execution of inline PostScript code.");
274 spc_warn(spe, ">> Your macro package makes some assumption on internal behaviour of DVI drivers.");
275 spc_warn(spe, ">> It may not compatible with dvipdfmx.");
279 pdf_dev_grestore_to(gs_depth);
285 static struct spc_handler dvips_handlers[] = {
286 {"PSfile", spc_handler_ps_file},
287 {"psfile", spc_handler_ps_file},
288 {"ps: plotfile ", spc_handler_ps_plotfile},
289 {"PS: plotfile ", spc_handler_ps_plotfile},
290 {"PS:", spc_handler_ps_literal},
291 {"ps:", spc_handler_ps_literal},
292 {"\" ", spc_handler_ps_default}
296 spc_dvips_at_end_page (void)
303 spc_dvips_check_special (const char *buf, long len)
305 const char *p, *endptr;
311 skip_white(&p, endptr);
315 len = (long) (endptr - p);
317 i < sizeof(dvips_handlers)/sizeof(struct spc_handler); i++) {
318 if (len >= strlen(dvips_handlers[i].key) &&
319 !memcmp(p, dvips_handlers[i].key,
320 strlen(dvips_handlers[i].key))) {
329 spc_dvips_setup_handler (struct spc_handler *handle,
330 struct spc_env *spe, struct spc_arg *args)
335 ASSERT(handle && spe && args);
337 skip_white(&args->curptr, args->endptr);
340 while (args->curptr < args->endptr &&
341 isalpha(args->curptr[0])) {
344 /* Test for "ps:". The "ps::" special is subsumed under this case. */
345 if (args->curptr < args->endptr &&
346 args->curptr[0] == ':') {
348 if (args->curptr+strlen(" plotfile ") <= args->endptr &&
349 !strncmp(args->curptr, " plotfile ", strlen(" plotfile "))) {
350 args->curptr += strlen(" plotfile ");
352 } else if (args->curptr+1 < args->endptr &&
353 args->curptr[0] == '"' && args->curptr[1] == ' ') {
357 keylen = (int) (args->curptr - key);
359 spc_warn(spe, "Not ps: special???");
364 i < sizeof(dvips_handlers) / sizeof(struct spc_handler); i++) {
365 if (keylen == strlen(dvips_handlers[i].key) &&
366 !strncmp(key, dvips_handlers[i].key, keylen)) {
368 skip_white(&args->curptr, args->endptr);
370 args->command = dvips_handlers[i].key;
373 handle->exec = dvips_handlers[i].exec;