OSDN Git Service

ae8ee12e4214a256f90f666373b239a32773a33d
[putex/putex.git] / src / dvipdfmx-pu / src / spc_misc.c
1 /*  
2     
3     This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks.
4
5     Copyright (C) 2002-2012 by Jin-Hwan Cho and Shunsaku Hirata,
6     the dvipdfmx project team.
7     
8     Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu>
9
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.
14     
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.
19     
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.
23 */
24
25 #if HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <string.h>
30
31 #include "system.h"
32 #include "mem.h"
33 #include "error.h"
34
35 #include "mfileio.h"
36
37 #include "pdfparse.h"
38 #include "pdfobj.h"
39
40 #include "pdfcolor.h"
41 #include "pdfdraw.h"
42 #include "pdfximage.h"
43 #include "pdfdev.h"
44
45 #include "mpost.h"
46
47 #include "specials.h"
48
49 #include "spc_util.h"
50 #include "spc_misc.h"
51
52 static int
53 spc_handler_postscriptbox (struct spc_env *spe, struct spc_arg *ap)
54 {
55   int            form_id, len;
56   transform_info ti;
57   char           filename[256], *fullname;
58   char           buf[512];
59   FILE          *fp;
60
61   ASSERT(spe && ap);
62
63   if (ap->curptr >= ap->endptr) {
64     spc_warn(spe, "No width/height/filename given for postscriptbox special.");
65     return  -1;
66   }
67
68   /* input is not NULL terminated */
69   len = (int) (ap->endptr - ap->curptr);
70   len = MIN(511, len);
71   memcpy(buf, ap->curptr, len);
72   buf[len] = '\0';
73
74   transform_info_clear(&ti);
75
76   spc_warn(spe, buf);
77   if (sscanf(buf, "{%lfpt}{%lfpt}{%255[^}]}",
78       &ti.width, &ti.height, filename) != 3) {
79     spc_warn(spe, "Syntax error in postscriptbox special?");
80     return  -1;
81   }
82   ap->curptr = ap->endptr;
83
84   ti.width  *= 72.0 / 72.27;
85   ti.height *= 72.0 / 72.27;
86
87   fullname = kpse_find_pict(filename);
88   if (!fullname) {
89     spc_warn(spe, "Image file \"%s\" not found.", filename);
90     return  -1;
91   }
92
93   fp = MFOPEN(fullname, FOPEN_R_MODE);
94   if (!fp) {
95     spc_warn(spe, "Could not open image file: %s", fullname);
96     RELEASE(fullname);
97     return  -1;
98   }
99   RELEASE(fullname);
100
101   ti.flags |= (INFO_HAS_WIDTH|INFO_HAS_HEIGHT);
102
103   for (;;) {
104     const char *p = mfgets(buf, 512, fp);
105     if (!p)
106       break;
107     if (mps_scan_bbox(&p, p + strlen(p), &ti.bbox) >= 0) {
108       ti.flags |= INFO_HAS_USER_BBOX;
109       break;
110     }
111   }
112   MFCLOSE(fp);
113
114   form_id = pdf_ximage_findresource(filename, 0, NULL);
115   if (form_id < 0) {
116     spc_warn(spe, "Failed to load image file: %s", filename);
117     return  -1;
118   }
119
120   pdf_dev_put_image(form_id, &ti, spe->x_user, spe->y_user);
121
122   return  0;
123 }
124
125 static int
126 spc_handler_null (struct spc_env *spe, struct spc_arg *args)
127 {
128   args->curptr = args->endptr;
129
130   return 0;
131 }
132
133 static struct spc_handler misc_handlers[] = {
134   {"postscriptbox", spc_handler_postscriptbox},
135   {"landscape",     spc_handler_null}, /* handled at bop */
136   {"papersize",     spc_handler_null}, /* handled at bop */
137   {"src:",          spc_handler_null}, /* simply ignore  */
138   {"pos:",          spc_handler_null}, /* simply ignore  */
139   {"om:",           spc_handler_null}  /* simply ignore  */
140 };
141
142
143 int
144 spc_misc_check_special (const char *buffer, long size)
145 {
146   const char *p, *endptr;
147   int    i;
148
149   p      = buffer;
150   endptr = p + size;
151
152   skip_white(&p, endptr);
153   size   = (long) (endptr - p);
154   for (i = 0;
155        i < sizeof(misc_handlers)/sizeof(struct spc_handler); i++) {
156     if (size >= strlen(misc_handlers[i].key) &&
157         !strncmp(p, misc_handlers[i].key,
158                  strlen(misc_handlers[i].key))) {
159       return 1;
160     }
161   }
162
163   return 0;
164 }
165
166 int
167 spc_misc_setup_handler (struct spc_handler *handle,
168                         struct spc_env *spe, struct spc_arg *args)
169 {
170   const char *key;
171   int    i, keylen;
172
173   ASSERT(handle && spe && args);
174
175   skip_white(&args->curptr, args->endptr);
176
177   key = args->curptr;
178   while (args->curptr < args->endptr &&
179          isalpha(args->curptr[0])) {
180     args->curptr++;
181   }
182
183   if (args->curptr < args->endptr &&
184       args->curptr[0] == ':') {
185     args->curptr++;
186   }
187
188   keylen = (int) (args->curptr - key);
189   if (keylen < 1) {
190     return -1;
191   }
192
193   for (i = 0;
194        i < sizeof(misc_handlers)/sizeof(struct spc_handler); i++) {
195     if (keylen == strlen(misc_handlers[i].key) &&
196         !strncmp(key, misc_handlers[i].key, keylen)) {
197
198       skip_white(&args->curptr, args->endptr);
199
200       args->command = misc_handlers[i].key;
201
202       handle->key   = "???:";
203       handle->exec  = misc_handlers[i].exec;
204
205       return 0;
206     }
207   }
208
209   return -1;
210 }