1 /*
2 Copyright (c) 2001 Martin Kroeker All rights reserved.
3
4 Distributed by Free Software Foundation, Inc.
5
6 This file is part of HP2xx.
7
8 HP2xx is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
10 to anyone for the consequences of using it or for whether it serves any
11 particular purpose or works at all, unless he says so in writing. Refer
12 to the GNU General Public License, Version 2 or later, for full details.
13
14 Everyone is granted permission to copy, modify and redistribute
15 HP2xx, but only under the conditions described in the GNU General Public
16 License. A copy of this license is supposed to have been
17 given to you along with HP2xx so you can know your rights and
18 responsibilities. It should be in a file named COPYING. Among other
19 things, the copyright notice and this notice must be preserved on all
20 copies.
21
22 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
23 */
24
25 /** to_pdf.c: Converter to Adobe Portable Document (PDF) Format using pdflib
26 **
27 ** 01/06/19 V 1.00 MK derived from to_eps.c
28 **/
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <time.h>
34 #include <math.h>
35 #include <pdflib.h>
36 #include "bresnham.h"
37 #include "hp2xx.h"
38 #include "pendef.h"
39 #include "lindef.h"
40
41
42 static int linecount = 0;
43 static float xcoord2mm, ycoord2mm;
44 static float xmin, ymin;
45
46
47 int to_pdf (const GEN_PAR *, const OUT_PAR *);
48 void pdf_init (const GEN_PAR *, const OUT_PAR *, PDF *, PEN_W);
49 void pdf_set_linewidth (double, HPGL_Pt *, PDF *);
50 void pdf_set_linecap( LineEnds type,double pensize, PDF *fd);
51 void pdf_set_linejoin( LineJoins type, LineLimit limit, double pensize, PDF *fd);
52 void pdf_set_color (double, double, double, HPGL_Pt *, PDF *);
53 void pdf_end(PDF *);
54
55
56
57 /**
58 ** Close graphics file
59 **/
pdf_end(PDF * fd)60 void pdf_end (PDF *fd)
61 {
62 PDF_end_page(fd);
63 PDF_close(fd);
64 PDF_delete(fd);
65 PDF_shutdown();
66 linecount = 0;
67 }
68
69
70 /**
71 ** Set line width
72 **/
pdf_set_linewidth(double width,HPGL_Pt * ppt,PDF * fd)73 void pdf_set_linewidth (double width, HPGL_Pt *ppt, PDF *fd)
74 {
75 PDF_setlinewidth(fd, width);
76 }
77
78
79 /**
80 ** Set line Ends
81 **/
pdf_set_linecap(LineEnds type,double pensize,PDF * fd)82 void pdf_set_linecap( LineEnds type,double pensize, PDF *fd) {
83
84 static int lastcap = -1;
85 int newcap;
86
87 if ( pensize > 0.35 ) {
88 switch (type) {
89 case LAE_butt:
90 newcap=0;
91 break;
92 case LAE_triangular: /* triangular not implemented in PS/PDF */
93 newcap=1;
94 break;
95 case LAE_round:
96 newcap=1;
97 break;
98 case LAE_square:
99 newcap=2;
100 break;
101 default:
102 newcap=0;
103 break;
104 }
105 } else {
106 newcap=1;
107 }
108
109 if(newcap != lastcap) {
110 PDF_setlinecap(fd,newcap);
111 lastcap=newcap;
112 }
113 }
114
115
116 /**
117 ** Set line Joins
118 **/
pdf_set_linejoin(LineJoins type,LineLimit limit,double pensize,PDF * fd)119 void pdf_set_linejoin( LineJoins type, LineLimit limit, double pensize, PDF *fd) {
120
121 static int lastcap = -1;
122 static int lastlimit = -1;
123 int newcap;
124 int newlimit = lastlimit;
125
126
127 if ( pensize > 0.35 ) {
128 switch (type) {
129 case LAJ_plain_miter:
130 newcap=0;
131 newlimit = 100; /* arbitrary value */
132 break;
133 case LAJ_bevel_miter: /* not available */
134 newcap=0;
135 newlimit = limit;
136 break;
137 case LAJ_triangular: /* not available */
138 newcap=1;
139 break;
140 case LAJ_round:
141 newcap=1;
142 break;
143 case LAJ_bevelled:
144 newcap=2;
145 break;
146 case LAJ_nojoin: /* not available */
147 newcap=1;
148 break;
149 default:
150 newcap=0;
151 newlimit = 100; /* arbitrary value */
152 break;
153 }
154 } else {
155 newcap=1;
156 }
157
158 if(newcap != lastcap) {
159 PDF_setlinejoin(fd,newcap);
160 lastcap=newcap;
161 }
162 if(newlimit != lastlimit) {
163 PDF_setmiterlimit(fd,newlimit);
164 lastlimit=newlimit;
165 }
166 }
167
168
169 /**
170 ** Set RGB color
171 **/
pdf_set_color(double red,double green,double blue,HPGL_Pt * ppt,PDF * fd)172 void pdf_set_color (double red, double green, double blue,
173 HPGL_Pt *ppt, PDF *fd)
174 {
175 PDF_setrgbcolor(fd,red,green,blue);
176 }
177
178
179 /**
180 ** basic PDF definitions
181 **/
182
pdf_init(const GEN_PAR * pg,const OUT_PAR * po,PDF * fd,PEN_W pensize)183 void pdf_init (const GEN_PAR *pg, const OUT_PAR *po, PDF *fd,
184 PEN_W pensize)
185 {
186 long left, right, low, high;
187 double hmxpenw;
188
189 hmxpenw = pg->maxpensize / 20.0; /* Half max. pen width, in mm */
190
191 left = (long) floor(abs(po->xoff-hmxpenw) * 2.834646);
192 low = (long) floor(abs(po->yoff-hmxpenw)* 2.834646);
193 right = (long) ceil ((po->xoff + po->width+hmxpenw) * 2.834646);
194 high = (long) ceil ((po->yoff+po->height+hmxpenw) * 2.834646);
195
196 PDF_begin_page(fd, right,high);
197 PDF_setlinewidth(fd, pensize);
198 pdf_set_linecap(CurrentLineAttr.End,pensize,fd);
199 pdf_set_linejoin(CurrentLineAttr.Join,CurrentLineAttr.Limit,pensize,fd);
200 }
201
202
203
204 /**
205 ** Higher-level interface: Output Portable Document Format
206 **/
207
208 int
to_pdf(const GEN_PAR * pg,const OUT_PAR * po)209 to_pdf (const GEN_PAR *pg, const OUT_PAR *po)
210 {
211 PlotCmd cmd;
212 PDF *md;
213 HPGL_Pt pt1 = {0};
214 int pen_no=0, pencolor=0, err;
215 int openpath;
216 PEN_W pensize;
217
218 PDF_boot();
219
220 err = 0;
221 if (!pg->quiet)
222 Eprintf ("\n\n- Writing PDF code to \"%s\"\n",
223 *po->outfile == '-' ? "stdout" : po->outfile);
224
225 /* Init. of PDF file: */
226
227 md=PDF_new();
228 if (PDF_open_file(md, po->outfile) == -1) {
229 PError("hp2xx (pdf)");
230 return ERROR;
231 }
232
233 /* header */
234
235 pensize = pt.width[DEFAULT_PEN_NO]; /* Default pen */
236 pdf_init (pg, po, md, pensize);
237
238
239 /* Factor for transformation of HP coordinates to mm */
240
241 xcoord2mm = po->width / (po->xmax - po->xmin) * 2.834646;
242 ycoord2mm = po->height / (po->ymax - po->ymin) * 2.834646;
243 xmin = po->xmin;
244 ymin = po->ymin;
245
246 /**
247 ** Command loop: While temporary file not empty: process command.
248 **/
249 openpath=0;
250 while ((cmd = PlotCmd_from_tmpfile()) != CMD_EOF)
251 {
252 switch (cmd)
253 {
254 case NOP:
255 break;
256 case SET_PEN:
257 if ((pen_no = fgetc(pg->td)) == EOF)
258 {
259 PError("Unexpected end of temp. file: ");
260 err = ERROR;
261 goto PDF_exit;
262 }
263 pensize = pt.width[pen_no];
264 pencolor = pt.color[pen_no];
265 if(openpath==1){PDF_stroke(md);
266 openpath=0;
267 }
268 if (pensize != 0)
269 pdf_set_linewidth ((double) pensize, &pt1, md);
270 pdf_set_linecap(CurrentLineAttr.End,(double) pensize,md);
271 pdf_set_linejoin(CurrentLineAttr.Join,CurrentLineAttr.Limit,(double) pensize,md);
272 pdf_set_color ( pt.clut[pencolor][0]/255.0,
273 pt.clut[pencolor][1]/255.0,
274 pt.clut[pencolor][2]/255.0,
275 &pt1, md);
276 break;
277 case DEF_PW:
278 if(!load_pen_width_table(pg->td)) {
279 PError("Unexpected end of temp. file");
280 err = ERROR;
281 goto PDF_exit;
282 }
283 break;
284 case DEF_PC:
285 err=load_pen_color_table(pg->td);
286 if (err<0) {
287 PError("Unexpected end of temp. file");
288 err = ERROR;
289 goto PDF_exit;
290 }
291 if (err==pencolor) pencolor *=-1; /*current pen changed*/
292 break;
293 case DEF_LA:
294 if(load_line_attr(pg->td) <0) {
295 PError("Unexpected end of temp. file");
296 err = ERROR;
297 goto PDF_exit;
298 }
299 break;
300 case MOVE_TO:
301 if (openpath==1) {
302 PDF_stroke(md);
303 openpath=0;
304 }
305 if(fabs(pensize-pt.width[pen_no]) >= 0.01) {
306 pensize=pt.width[pen_no];
307 if (pensize != 0){
308 pdf_set_linewidth ((double) pensize, &pt1, md);
309 pdf_set_linecap(CurrentLineAttr.End,(double) pensize,md);
310 pdf_set_linejoin(CurrentLineAttr.Join,CurrentLineAttr.Limit,(double) pensize,md);
311 }
312 }
313 if(pencolor <0) {
314 pencolor=pt.color[pen_no];
315 pdf_set_color(pt.clut[pencolor][0]/255.0,
316 pt.clut[pencolor][1]/255.0,
317 pt.clut[pencolor][2]/255.0,
318 &pt1, md);
319 }
320
321 HPGL_Pt_from_tmpfile (&pt1);
322 if(pensize != 0){
323 PDF_moveto(md,(pt1.x-xmin)*xcoord2mm,(pt1.y-ymin)*ycoord2mm);
324 }
325 break;
326 case DRAW_TO:
327 if(fabs(pensize-pt.width[pen_no]) >= 0.01) {
328 pensize=pt.width[pen_no];
329 if(pensize != 0){
330 pdf_set_linewidth ((double) pensize, &pt1, md);
331 pdf_set_linecap(CurrentLineAttr.End,(double) pensize,md);
332 pdf_set_linejoin(CurrentLineAttr.Join,CurrentLineAttr.Limit,(double) pensize,md);
333 }
334 }
335 if(pencolor <0) {
336 pencolor=pt.color[pen_no];
337 pdf_set_color(pt.clut[pencolor][0]/255.0,
338 pt.clut[pencolor][1]/255.0,
339 pt.clut[pencolor][2]/255.0,
340 &pt1, md);
341 }
342 HPGL_Pt_from_tmpfile (&pt1);
343 if(pensize != 0){
344 PDF_lineto(md,(pt1.x-xmin)*xcoord2mm,(pt1.y-ymin)*ycoord2mm);
345 openpath=1;
346 }
347 break;
348 case PLOT_AT:
349 /* if (openpath==1){
350 PDF_stroke(md);
351 openpath=0;
352 }*/
353 if(fabs(pensize-pt.width[pen_no]) >= 0.01) {
354 pensize=pt.width[pen_no];
355 if(pensize != 0){
356 pdf_set_linewidth ((double) pensize, &pt1, md);
357 pdf_set_linecap(CurrentLineAttr.End,(double) pensize,md);
358 pdf_set_linejoin(CurrentLineAttr.Join,CurrentLineAttr.Limit,(double) pensize,md);
359 }
360 }
361 if(pencolor<0) {
362 pencolor=pt.color[pen_no];
363 pdf_set_color(pt.clut[pencolor][0]/255.0,
364 pt.clut[pencolor][1]/255.0,
365 pt.clut[pencolor][2]/255.0,
366 &pt1, md);
367 }
368 HPGL_Pt_from_tmpfile (&pt1);
369 if(pensize != 0) {
370 PDF_moveto(md,(pt1.x-xmin)*xcoord2mm,(pt1.y-ymin)*ycoord2mm);
371 PDF_lineto(md,(pt1.x-xmin)*xcoord2mm+1,(pt1.y-ymin)*ycoord2mm+1);
372 /* PDF_stroke(md);*/
373 openpath=1;
374 }
375 break;
376 default:
377 Eprintf ("Illegal cmd in temp. file!");
378 err = ERROR;
379 goto PDF_exit;
380 }
381 }
382
383 /* Finish up */
384 if (openpath==1) PDF_stroke(md);
385 pdf_end (md);
386
387 PDF_exit:
388 /* if (md != stdout)
389 fclose (md);
390 */
391 if (!pg->quiet)
392 Eprintf ("\n");
393 return err;
394 }
395
396