2 * Grace - GRaphing, Advanced Computation and Exploration of data
4 * Home page: http://plasma-gate.weizmann.ac.il/Grace/
6 * Copyright (c) 1996-2004 Grace Development Team
8 * Maintained by Evgeny Stambulchik
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
44 #define CANVAS_BACKEND_API
45 #include "grace/canvas.h"
54 # include "motifinc.h"
60 unsigned long page_scale
;
74 PDFCompatibility compat
;
75 PDFColorSpace colorspace
;
79 int kerning_supported
;
83 OptionStructure
*compat_item
;
84 SpinStructure
*compression_item
;
85 SpinStructure
*fpprec_item
;
86 OptionStructure
*colorspace_item
;
90 static void pdf_error_handler(PDF
*p
, int type
, const char* msg
);
92 static PDF_data
*init_pdf_data(void)
96 /* we need to perform the allocations */
97 data
= xmalloc(sizeof(PDF_data
));
102 memset(data
, 0, sizeof(PDF_data
));
104 data
->compat
= PDF_1_4
;
105 data
->colorspace
= DEFAULT_COLORSPACE
;
106 data
->compression
= 4;
112 static void pdf_data_free(void *data
)
114 PDF_data
*pdfdata
= (PDF_data
*) data
;
117 xfree(pdfdata
->font_ids
);
118 xfree(pdfdata
->pattern_ids
);
123 int register_pdf_drv(Canvas
*canvas
)
130 data
= init_pdf_data();
135 d
= device_new("PDF", DEVICE_FILE
, TRUE
, data
, pdf_data_free
);
141 device_set_fext(d
, "pdf");
143 device_set_dpi(d
, 300.0);
159 return register_device(canvas
, d
);
162 static char *pdf_builtin_fonts
[] =
171 "Helvetica-BoldOblique",
175 "Courier-BoldOblique",
180 static int number_of_pdf_builtin_fonts
= sizeof(pdf_builtin_fonts
)/sizeof(char *);
182 static int pdf_builtin_font(const char *fname
)
185 for (i
= 0; i
< number_of_pdf_builtin_fonts
; i
++) {
186 if (strcmp(pdf_builtin_fonts
[i
], fname
) == 0) {
193 static size_t pdf_writeproc(PDF
*p
, void *data
, size_t size
)
195 FILE *fp
= PDF_get_opaque(p
);
196 return fwrite(data
, 1, size
, fp
);
199 int pdf_initgraphics(const Canvas
*canvas
, void *data
, const CanvasStats
*cstats
)
201 PDF_data
*pdfdata
= (PDF_data
*) data
;
206 pg
= get_page_geometry(canvas
);
208 pdfdata
->page_scale
= MIN2(pg
->height
, pg
->width
);
209 pdfdata
->pixel_size
= 1.0/pdfdata
->page_scale
;
210 pdfdata
->page_scalef
= (float) pdfdata
->page_scale
*72.0/pg
->dpi
;
212 /* undefine all graphics state parameters */
214 pdfdata
->pattern
= -1;
215 pdfdata
->linew
= -1.0;
217 pdfdata
->linecap
= -1;
218 pdfdata
->linejoin
= -1;
220 pdfdata
->phandle
= PDF_new2(pdf_error_handler
,
221 NULL
, NULL
, NULL
, canvas_get_prstream(canvas
));
222 if (pdfdata
->phandle
== NULL
) {
223 return RETURN_FAILURE
;
226 PDF_set_parameter(pdfdata
->phandle
, "fontwarning", "false");
228 /* check PDFlib capabilities */
229 if (!strcmp(PDF_get_parameter(pdfdata
->phandle
, "pdi", 0), "true")) {
230 pdfdata
->kerning_supported
= TRUE
;
232 pdfdata
->kerning_supported
= FALSE
;
235 switch (pdfdata
->compat
) {
249 PDF_set_parameter(pdfdata
->phandle
, "compatibility", s
);
251 PDF_begin_document_callback(pdfdata
->phandle
, pdf_writeproc
, "");
253 PDF_set_value(pdfdata
->phandle
, "compress", (float) pdfdata
->compression
);
254 PDF_set_value(pdfdata
->phandle
, "floatdigits", (float) pdfdata
->fpprec
);
256 PDF_set_info(pdfdata
->phandle
, "Creator", bi_version_string());
257 PDF_set_info(pdfdata
->phandle
, "Author", canvas_get_username(canvas
));
258 PDF_set_info(pdfdata
->phandle
, "Title", canvas_get_docname(canvas
));
260 pdfdata
->font_ids
= xmalloc(number_of_fonts(canvas
)*SIZEOF_INT
);
261 for (i
= 0; i
< number_of_fonts(canvas
); i
++) {
262 pdfdata
->font_ids
[i
] = -1;
264 for (i
= 0; i
< cstats
->nfonts
; i
++) {
266 char buf
[GR_MAXPATHLEN
];
267 char *fontname
, *encscheme
;
271 font
= cstats
->fonts
[i
].font
;
273 fontname
= get_fontalias(canvas
, font
);
275 if (pdf_builtin_font(fontname
)) {
276 embedstr
= "embedding=false";
278 sprintf(buf
, "%s==%s",
279 fontname
, get_afmfilename(canvas
, font
, TRUE
));
280 PDF_set_parameter(pdfdata
->phandle
, "FontAFM", buf
);
281 sprintf(buf
, "%s==%s",
282 fontname
, get_fontfilename(canvas
, font
, TRUE
));
283 PDF_set_parameter(pdfdata
->phandle
, "FontOutline", buf
);
285 embedstr
= "embedding=false";
288 encscheme
= get_encodingscheme(canvas
, font
);
289 if (strcmp(encscheme
, "FontSpecific") == 0) {
290 pdflibenc
= "builtin";
292 pdflibenc
= "winansi";
295 pdfdata
->font_ids
[font
] =
296 PDF_load_font(pdfdata
->phandle
, fontname
, 0,
297 pdflibenc
, embedstr
);
299 if (pdfdata
->font_ids
[font
] < 0) {
300 errmsg(PDF_get_errmsg(pdfdata
->phandle
));
304 pdfdata
->pattern_ids
= xmalloc(number_of_patterns(canvas
)*SIZEOF_INT
);
305 for (i
= 0; i
< cstats
->npatterns
; i
++) {
306 int patno
= cstats
->patterns
[i
];
307 Pattern
*pat
= canvas_get_pattern(canvas
, patno
);
308 /* Unfortunately, there is no way to open a _masked_ image from memory */
311 pdfdata
->pattern_ids
[i
] = PDF_begin_pattern(pdfdata
->phandle
,
312 pat
->width
, pat
->height
, pat
->width
, pat
->height
, 2);
313 im
= PDF_open_image(pdfdata
->phandle
, "raw", "memory",
314 (const char *) pat_bits
[i
], pat
->width
*pat
->height
/8,
315 pat
->width
, pat
->height
, 1, 1, "");
316 PDF_place_image(pdfdata
->phandle
, im
, 0.0, 0.0, 1.0);
317 PDF_close_image(pdfdata
->phandle
, im
);
318 PDF_end_pattern(pdfdata
->phandle
);
321 pdfdata
->pattern_ids
[patno
] = PDF_begin_pattern(pdfdata
->phandle
,
322 pat
->width
, pat
->height
, pat
->width
, pat
->height
, 2);
323 for (j
= 0; j
< 256; j
++) {
326 if ((pat
->bits
[j
/8] >> (j
%8)) & 0x01) {
328 PDF_rect(pdfdata
->phandle
, (float) k
, (float) l
, 1.0, 1.0);
329 PDF_fill(pdfdata
->phandle
);
332 PDF_end_pattern(pdfdata
->phandle
);
336 PDF_begin_page_ext(pdfdata
->phandle
,
337 pg
->width
*72.0/pg
->dpi
, pg
->height
*72.0/pg
->dpi
, "");
339 s
= canvas_get_description(canvas
);
341 if (!is_empty_string(s
)) {
342 PDF_set_border_style(pdfdata
->phandle
, "dashed", 3.0);
343 PDF_set_border_dash(pdfdata
->phandle
, 5.0, 1.0);
344 PDF_set_border_color(pdfdata
->phandle
, 1.0, 0.0, 0.0);
346 PDF_add_note(pdfdata
->phandle
,
347 20.0, 50.0, 320.0, 100.0, s
, "Project description", "note", 0);
350 PDF_scale(pdfdata
->phandle
, pdfdata
->page_scalef
, pdfdata
->page_scalef
);
352 return RETURN_SUCCESS
;
355 void pdf_setpen(const Canvas
*canvas
, const Pen
*pen
, PDF_data
*pdfdata
)
357 if (pen
->color
!= pdfdata
->color
|| pen
->pattern
!= pdfdata
->pattern
) {
358 float c1
, c2
, c3
, c4
;
360 switch (pdfdata
->colorspace
) {
361 case COLORSPACE_GRAYSCALE
:
365 c1
= (float) get_colorintensity(canvas
, pen
->color
);
369 case COLORSPACE_CMYK
:
375 get_fcmyk(canvas
, pen
->color
, &fcmyk
);
376 c1
= (float) fcmyk
.cyan
;
377 c2
= (float) fcmyk
.magenta
;
378 c3
= (float) fcmyk
.yellow
;
379 c4
= (float) fcmyk
.black
;
389 get_frgb(canvas
, pen
->color
, &frgb
);
390 c1
= (float) frgb
.red
;
391 c2
= (float) frgb
.green
;
392 c3
= (float) frgb
.blue
;
398 PDF_setcolor(pdfdata
->phandle
, "both", cstype
, c1
, c2
, c3
, c4
);
399 if (pen
->pattern
> 1 && pdfdata
->pattern_ids
[pen
->pattern
] >= 0) {
400 PDF_setcolor(pdfdata
->phandle
, "both", "pattern",
401 (float) pdfdata
->pattern_ids
[pen
->pattern
], 0.0, 0.0, 0.0);
403 pdfdata
->color
= pen
->color
;
404 pdfdata
->pattern
= pen
->pattern
;
408 void pdf_setdrawbrush(const Canvas
*canvas
, PDF_data
*pdfdata
)
416 getpen(canvas
, &pen
);
417 pdf_setpen(canvas
, &pen
, pdfdata
);
419 ls
= getlinestyle(canvas
);
420 lw
= MAX2(getlinewidth(canvas
), pdfdata
->pixel_size
);
422 if (ls
!= pdfdata
->lines
|| lw
!= pdfdata
->linew
) {
423 PDF_setlinewidth(pdfdata
->phandle
, lw
);
425 if (ls
== 0 || ls
== 1) {
426 PDF_setdash(pdfdata
->phandle
, 0, 0);
428 LineStyle
*linestyle
= canvas_get_linestyle(canvas
, ls
);
429 darray
= xmalloc(linestyle
->length
*SIZEOF_FLOAT
);
430 for (i
= 0; i
< linestyle
->length
; i
++) {
431 darray
[i
] = lw
*linestyle
->array
[i
];
433 PDF_setpolydash(pdfdata
->phandle
, darray
, linestyle
->length
);
441 void pdf_setlineprops(const Canvas
*canvas
, PDF_data
*pdfdata
)
445 lc
= getlinecap(canvas
);
446 lj
= getlinejoin(canvas
);
448 if (lc
!= pdfdata
->linecap
) {
451 PDF_setlinecap(pdfdata
->phandle
, 0);
454 PDF_setlinecap(pdfdata
->phandle
, 1);
457 PDF_setlinecap(pdfdata
->phandle
, 2);
460 pdfdata
->linecap
= lc
;
463 if (lj
!= pdfdata
->linejoin
) {
466 PDF_setlinejoin(pdfdata
->phandle
, 0);
469 PDF_setlinejoin(pdfdata
->phandle
, 1);
472 PDF_setlinejoin(pdfdata
->phandle
, 2);
475 pdfdata
->linejoin
= lj
;
479 void pdf_drawpixel(const Canvas
*canvas
, void *data
, const VPoint
*vp
)
481 PDF_data
*pdfdata
= (PDF_data
*) data
;
484 getpen(canvas
, &pen
);
485 pdf_setpen(canvas
, &pen
, pdfdata
);
487 if (pdfdata
->linew
!= pdfdata
->pixel_size
) {
488 PDF_setlinewidth(pdfdata
->phandle
, pdfdata
->pixel_size
);
489 pdfdata
->linew
= pdfdata
->pixel_size
;
491 if (pdfdata
->linecap
!= LINECAP_ROUND
) {
492 PDF_setlinecap(pdfdata
->phandle
, 1);
493 pdfdata
->linecap
= LINECAP_ROUND
;
495 if (pdfdata
->lines
!= 1) {
496 PDF_setdash(pdfdata
->phandle
, 0, 0);
500 PDF_moveto(pdfdata
->phandle
, (float) vp
->x
, (float) vp
->y
);
501 PDF_lineto(pdfdata
->phandle
, (float) vp
->x
, (float) vp
->y
);
502 PDF_stroke(pdfdata
->phandle
);
505 void pdf_poly_path(const VPoint
*vps
, int n
, PDF_data
*pdfdata
)
509 PDF_moveto(pdfdata
->phandle
, (float) vps
[0].x
, (float) vps
[0].y
);
510 for (i
= 1; i
< n
; i
++) {
511 PDF_lineto(pdfdata
->phandle
, (float) vps
[i
].x
, (float) vps
[i
].y
);
515 void pdf_drawpolyline(const Canvas
*canvas
, void *data
,
516 const VPoint
*vps
, int n
, int mode
)
518 PDF_data
*pdfdata
= (PDF_data
*) data
;
519 if (getlinestyle(canvas
) == 0) {
523 pdf_setdrawbrush(canvas
, pdfdata
);
524 pdf_setlineprops(canvas
, pdfdata
);
526 pdf_poly_path(vps
, n
, pdfdata
);
528 if (mode
== POLYLINE_CLOSED
) {
529 PDF_closepath_stroke(pdfdata
->phandle
);
531 PDF_stroke(pdfdata
->phandle
);
535 void pdf_fillpolygon(const Canvas
*canvas
, void *data
,
536 const VPoint
*vps
, int nc
)
538 PDF_data
*pdfdata
= (PDF_data
*) data
;
541 getpen(canvas
, &pen
);
543 if (pen
.pattern
== 0) {
547 if (getfillrule(canvas
) == FILLRULE_WINDING
) {
548 PDF_set_parameter(pdfdata
->phandle
, "fillrule", "winding");
550 PDF_set_parameter(pdfdata
->phandle
, "fillrule", "evenodd");
553 if (pen
.pattern
> 1) {
555 solid_pen
.color
= getbgcolor(canvas
);
556 solid_pen
.pattern
= 1;
558 pdf_setpen(canvas
, &solid_pen
, pdfdata
);
559 pdf_poly_path(vps
, nc
, pdfdata
);
560 PDF_fill(pdfdata
->phandle
);
563 getpen(canvas
, &pen
);
564 pdf_setpen(canvas
, &pen
, pdfdata
);
565 pdf_poly_path(vps
, nc
, pdfdata
);
566 PDF_fill(pdfdata
->phandle
);
569 void pdf_arc_path(const VPoint
*vp1
, const VPoint
*vp2
,
570 double a1
, double a2
, int mode
, PDF_data
*pdfdata
)
575 vpc
.x
= (vp1
->x
+ vp2
->x
)/2;
576 vpc
.y
= (vp1
->y
+ vp2
->y
)/2;
577 rx
= fabs(vp2
->x
- vp1
->x
)/2;
578 ry
= fabs(vp2
->y
- vp1
->y
)/2;
580 if (rx
== 0.0 || ry
== 0.0) {
584 PDF_scale(pdfdata
->phandle
, 1.0, ry
/rx
);
585 PDF_moveto(pdfdata
->phandle
, (float) vpc
.x
+ rx
*cos(a1
*M_PI
/180.0),
586 (float) rx
/ry
*vpc
.y
+ rx
*sin(a1
*M_PI
/180.0));
588 PDF_arcn(pdfdata
->phandle
, (float) vpc
.x
, (float) rx
/ry
*vpc
.y
, rx
,
589 (float) a1
, (float) (a1
+ a2
));
591 PDF_arc(pdfdata
->phandle
, (float) vpc
.x
, (float) rx
/ry
*vpc
.y
, rx
,
592 (float) a1
, (float) (a1
+ a2
));
595 if (mode
== ARCFILL_PIESLICE
) {
596 PDF_lineto(pdfdata
->phandle
, (float) vpc
.x
, (float) rx
/ry
*vpc
.y
);
600 void pdf_drawarc(const Canvas
*canvas
, void *data
,
601 const VPoint
*vp1
, const VPoint
*vp2
, double a1
, double a2
)
603 PDF_data
*pdfdata
= (PDF_data
*) data
;
605 if (getlinestyle(canvas
) == 0) {
609 pdf_setdrawbrush(canvas
, pdfdata
);
610 PDF_save(pdfdata
->phandle
);
611 pdf_arc_path(vp1
, vp2
, a1
, a2
, ARCFILL_CHORD
, pdfdata
);
612 PDF_stroke(pdfdata
->phandle
);
613 PDF_restore(pdfdata
->phandle
);
616 void pdf_fillarc(const Canvas
*canvas
, void *data
,
617 const VPoint
*vp1
, const VPoint
*vp2
, double a1
, double a2
, int mode
)
619 PDF_data
*pdfdata
= (PDF_data
*) data
;
622 getpen(canvas
, &pen
);
624 if (pen
.pattern
== 0) {
628 if (pen
.pattern
> 1) {
630 solid_pen
.color
= getbgcolor(canvas
);
631 solid_pen
.pattern
= 1;
633 pdf_setpen(canvas
, &solid_pen
, pdfdata
);
634 PDF_save(pdfdata
->phandle
);
635 pdf_arc_path(vp1
, vp2
, a1
, a2
, mode
, pdfdata
);
636 PDF_fill(pdfdata
->phandle
);
637 PDF_restore(pdfdata
->phandle
);
640 pdf_setpen(canvas
, &pen
, pdfdata
);
641 PDF_save(pdfdata
->phandle
);
642 pdf_arc_path(vp1
, vp2
, a1
, a2
, mode
, pdfdata
);
643 PDF_fill(pdfdata
->phandle
);
644 PDF_restore(pdfdata
->phandle
);
647 /* TODO: transparent pixmaps */
648 void pdf_putpixmap(const Canvas
*canvas
, void *data
,
649 const VPoint
*vp
, const CPixmap
*pm
)
651 PDF_data
*pdfdata
= (PDF_data
*) data
;
661 buf
= xmalloc(pm
->width
*pm
->height
*components
);
663 errmsg("xmalloc failed in pdf_putpixmap()");
669 paddedW
= PADBITS(pm
->width
, pm
->pad
);
670 get_rgb(canvas
, getcolor(canvas
), &fg
);
671 get_rgb(canvas
, getbgcolor(canvas
), &bg
);
672 for (k
= 0; k
< pm
->height
; k
++) {
673 for (j
= 0; j
< paddedW
/pm
->pad
; j
++) {
674 for (i
= 0; i
< pm
->pad
&& j
*pm
->pad
+ i
< pm
->width
; i
++) {
675 if (bin_dump(&(pm
->bits
)[k
*paddedW
/pm
->pad
+ j
], i
, pm
->pad
)) {
676 *bp
++ = (char) fg
.red
;
677 *bp
++ = (char) fg
.green
;
678 *bp
++ = (char) fg
.blue
;
680 *bp
++ = (char) bg
.red
;
681 *bp
++ = (char) bg
.green
;
682 *bp
++ = (char) bg
.blue
;
688 for (k
= 0; k
< pm
->height
; k
++) {
689 for (j
= 0; j
< pm
->width
; j
++) {
690 cindex
= (pm
->bits
)[k
*pm
->width
+ j
];
691 get_rgb(canvas
, cindex
, &fg
);
692 *bp
++ = (char) fg
.red
;
693 *bp
++ = (char) fg
.green
;
694 *bp
++ = (char) fg
.blue
;
699 image
= PDF_open_image(pdfdata
->phandle
, "raw", "memory",
700 buf
, pm
->width
*pm
->height
*components
,
701 pm
->width
, pm
->height
, components
, GRACE_BPP
, "");
703 errmsg("Not enough memory for image!");
708 PDF_place_image(pdfdata
->phandle
,
709 image
, vp
->x
, vp
->y
- pm
->height
*pdfdata
->pixel_size
, pdfdata
->pixel_size
);
710 PDF_close_image(pdfdata
->phandle
, image
);
715 void pdf_puttext(const Canvas
*canvas
, void *data
,
716 const VPoint
*vp
, const char *s
, int len
, int font
, const TextMatrix
*tm
,
717 int underline
, int overline
, int kerning
)
719 PDF_data
*pdfdata
= (PDF_data
*) data
;
722 if (pdfdata
->font_ids
[font
] < 0) {
726 getpen(canvas
, &pen
);
727 pdf_setpen(canvas
, &pen
, pdfdata
);
729 PDF_save(pdfdata
->phandle
);
731 PDF_setfont(pdfdata
->phandle
, pdfdata
->font_ids
[font
], 1.0);
733 PDF_set_parameter(pdfdata
->phandle
, "underline", true_or_false(underline
));
734 PDF_set_parameter(pdfdata
->phandle
, "overline", true_or_false(overline
));
735 if (pdfdata
->kerning_supported
) {
736 PDF_set_parameter(pdfdata
->phandle
,
737 "kerning", kerning
? "true":"false");
739 PDF_concat(pdfdata
->phandle
, (float) tm
->cxx
, (float) tm
->cyx
,
740 (float) tm
->cxy
, (float) tm
->cyy
,
743 PDF_show2(pdfdata
->phandle
, s
, len
);
745 PDF_restore(pdfdata
->phandle
);
748 void pdf_leavegraphics(const Canvas
*canvas
, void *data
,
749 const CanvasStats
*cstats
)
751 PDF_data
*pdfdata
= (PDF_data
*) data
;
755 PDF_set_value(pdfdata
->phandle
, "CropBox/llx", pdfdata
->page_scalef
*v
.xv1
);
756 PDF_set_value(pdfdata
->phandle
, "CropBox/lly", pdfdata
->page_scalef
*v
.yv1
);
757 PDF_set_value(pdfdata
->phandle
, "CropBox/urx", pdfdata
->page_scalef
*v
.xv2
);
758 PDF_set_value(pdfdata
->phandle
, "CropBox/ury", pdfdata
->page_scalef
*v
.yv2
);
760 PDF_end_page_ext(pdfdata
->phandle
, "");
761 PDF_end_document(pdfdata
->phandle
, "");
762 PDF_delete(pdfdata
->phandle
);
763 xfree(pdfdata
->font_ids
);
764 XCFREE(pdfdata
->pattern_ids
);
767 static void pdf_error_handler(PDF
*p
, int type
, const char *msg
)
772 case PDF_NonfatalError
:
773 /* continue on a non-fatal error */
774 s
= "PDFlib warning: ";
777 s
= "PDFlib error: ";
778 /* give up in all other cases */
781 buf
= xmalloc(strlen(msg
) + strlen(s
) + 1);
783 sprintf(buf
, "%s%s", s
, msg
);
789 int pdf_op_parser(const Canvas
*canvas
, void *data
, const char *opstring
)
791 PDF_data
*pdfdata
= (PDF_data
*) data
;
793 if (!strcmp(opstring
, "compatibility:PDF-1.3")) {
794 pdfdata
->compat
= PDF_1_3
;
795 return RETURN_SUCCESS
;
797 if (!strcmp(opstring
, "compatibility:PDF-1.4")) {
798 pdfdata
->compat
= PDF_1_4
;
799 return RETURN_SUCCESS
;
801 if (!strcmp(opstring
, "compatibility:PDF-1.5")) {
802 pdfdata
->compat
= PDF_1_5
;
803 return RETURN_SUCCESS
;
805 if (!strncmp(opstring
, "compression:", 12)) {
807 bufp
= strchr(opstring
, ':');
809 if (!is_empty_string(bufp
)) {
810 pdfdata
->compression
= atoi(bufp
);
811 return RETURN_SUCCESS
;
813 return RETURN_FAILURE
;
816 if (!strncmp(opstring
, "fpprecision:", 12)) {
818 bufp
= strchr(opstring
, ':');
820 if (!is_empty_string(bufp
)) {
821 pdfdata
->fpprec
= atoi(bufp
);
822 return RETURN_SUCCESS
;
824 return RETURN_FAILURE
;
827 if (!strcmp(opstring
, "colorspace:grayscale")) {
828 pdfdata
->colorspace
= COLORSPACE_GRAYSCALE
;
829 return RETURN_SUCCESS
;
831 if (!strcmp(opstring
, "colorspace:rgb")) {
832 pdfdata
->colorspace
= COLORSPACE_RGB
;
833 return RETURN_SUCCESS
;
835 if (!strcmp(opstring
, "colorspace:cmyk")) {
836 pdfdata
->colorspace
= COLORSPACE_CMYK
;
837 return RETURN_SUCCESS
;
839 return RETURN_FAILURE
;
845 static void update_pdf_setup_frame(PDF_data
*pdfdata
);
846 static int set_pdf_setup_proc(void *data
);
848 void pdf_gui_setup(const Canvas
*canvas
, void *data
)
850 PDF_data
*pdfdata
= (PDF_data
*) data
;
854 if (pdfdata
->frame
== NULL
) {
856 OptionItem compat_op_items
[3] = {
857 {PDF_1_3
, "PDF-1.3"},
858 {PDF_1_4
, "PDF-1.4"},
861 OptionItem colorspace_op_items
[3] = {
862 {COLORSPACE_GRAYSCALE
, "Grayscale"},
863 {COLORSPACE_RGB
, "RGB" },
864 {COLORSPACE_CMYK
, "CMYK" }
867 pdfdata
->frame
= CreateDialogForm(app_shell
, "PDF options");
869 fr
= CreateFrame(pdfdata
->frame
, "PDF options");
870 rc
= CreateVContainer(fr
);
871 pdfdata
->compat_item
=
872 CreateOptionChoice(rc
, "Compatibility:", 1, 3, compat_op_items
);
873 pdfdata
->colorspace_item
=
874 CreateOptionChoice(rc
, "Colorspace:", 1, 3, colorspace_op_items
);
875 pdfdata
->compression_item
= CreateSpinChoice(rc
,
876 "Compression:", 1, SPIN_TYPE_INT
, 0.0, 9.0, 1.0);
877 pdfdata
->fpprec_item
= CreateSpinChoice(rc
,
878 "FP precision:", 1, SPIN_TYPE_INT
, 4.0, 6.0, 1.0);
880 CreateAACDialog(pdfdata
->frame
, fr
, set_pdf_setup_proc
, pdfdata
);
882 update_pdf_setup_frame(pdfdata
);
883 RaiseWindow(GetParent(pdfdata
->frame
));
887 static void update_pdf_setup_frame(PDF_data
*pdfdata
)
889 if (pdfdata
->frame
) {
890 SetOptionChoice(pdfdata
->compat_item
, pdfdata
->compat
);
891 SetOptionChoice(pdfdata
->colorspace_item
, pdfdata
->colorspace
);
892 SetSpinChoice(pdfdata
->compression_item
, (double) pdfdata
->compression
);
893 SetSpinChoice(pdfdata
->fpprec_item
, (double) pdfdata
->fpprec
);
897 static int set_pdf_setup_proc(void *data
)
899 PDF_data
*pdfdata
= (PDF_data
*) data
;
901 pdfdata
->compat
= GetOptionChoice(pdfdata
->compat_item
);
902 pdfdata
->colorspace
= GetOptionChoice(pdfdata
->colorspace_item
);
903 pdfdata
->compression
= (int) GetSpinChoice(pdfdata
->compression_item
);
904 pdfdata
->fpprec
= (int) GetSpinChoice(pdfdata
->fpprec_item
);
906 return RETURN_SUCCESS
;
911 #else /* No PDFlib */
912 void _pdfdrv_c_dummy_func(void) {}