fixed dia_image_rgb_data() for non-alpha images
[dia.git] / app / diapsrenderer.c
blob906674c82116ba136b2aed31b83278657914d09e
1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * diapsrenderer.c -- implements the base class for Postscript rendering
5 * It is mostly refactoring of render_eps.c (some stuff not from the
6 * latest version but from 1.24) before PS rendering became multi-pass
7 * and text rendering became (necessary) complicated.
8 * Refatoring: Copyright (C) 2002 Hans Breuer
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.
25 #include <config.h>
27 #include <string.h>
28 #include <time.h>
30 #include "diapsrenderer.h"
31 #include "message.h"
32 #include "dia_image.h"
33 #include "font.h"
35 void
36 lazy_setcolor(DiaPsRenderer *renderer,
37 Color *color)
39 if (!color_equals(color, &(renderer->lcolor))) {
40 renderer->lcolor = *color;
41 fprintf(renderer->file, "%f %f %f srgb\n",
42 (double) color->red,
43 (double) color->green,
44 (double) color->blue);
48 static void
49 begin_render(DiaRenderer *self)
51 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
52 time_t time_now;
54 g_assert (renderer->file != NULL);
56 time_now = time(NULL);
58 if (renderer->is_eps)
59 fprintf(renderer->file,
60 "%%!PS-Adobe-2.0 EPSF-2.0\n");
61 else
62 fprintf(renderer->file,
63 "%%!PS-Adobe-2.0\n");
64 fprintf(renderer->file,
65 "%%%%Title: %s\n"
66 "%%%%Creator: Dia v%s\n"
67 "%%%%CreationDate: %s"
68 "%%%%For: %s\n"
69 "%%%%Orientation: %s\n",
70 renderer->title ? renderer->title : "(NULL)" ,
71 VERSION,
72 ctime(&time_now),
73 g_get_user_name(),
74 renderer->is_portrait ? "Portrait" : "Landscape");
76 if (renderer->is_eps)
77 fprintf(renderer->file,
78 "%%%%Magnification: 1.0000\n"
79 "%%%%BoundingBox: 0 0 %d %d\n",
80 (int) ceil( (renderer->extent.right - renderer->extent.left)
81 * renderer->scale),
82 (int) ceil( (renderer->extent.bottom - renderer->extent.top)
83 * renderer->scale) );
85 else
86 fprintf(renderer->file,
87 "%%%%DocumentPaperSizes: %s\n",
88 renderer->paper ? renderer->paper : "(NULL)");
90 fprintf(renderer->file,
91 "%%%%BeginSetup\n");
92 fprintf(renderer->file,
93 "%%%%EndSetup\n"
94 "%%%%EndComments\n");
96 DIA_PS_RENDERER_GET_CLASS(self)->begin_prolog(renderer);
97 /* get our font definitions */
98 DIA_PS_RENDERER_GET_CLASS(self)->dump_fonts(renderer);
99 /* done it */
100 DIA_PS_RENDERER_GET_CLASS(self)->end_prolog(renderer);
103 static void
104 end_render(DiaRenderer *self)
106 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
108 if (renderer->is_eps)
109 fprintf(renderer->file, "showpage\n");
112 static void
113 set_linewidth(DiaRenderer *self, real linewidth)
114 { /* 0 == hairline **/
115 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
117 /* Adobe's advice: Set to very small but fixed size, to avoid changes
118 * due to different resolution output. */
119 /* .01 cm becomes <5 dots on 1200 DPI */
120 if (linewidth == 0.0) linewidth=.01;
121 fprintf(renderer->file, "%f slw\n", (double) linewidth);
124 static void
125 set_linecaps(DiaRenderer *self, LineCaps mode)
127 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
128 int ps_mode;
130 switch(mode) {
131 case LINECAPS_BUTT:
132 ps_mode = 0;
133 break;
134 case LINECAPS_ROUND:
135 ps_mode = 1;
136 break;
137 case LINECAPS_PROJECTING:
138 ps_mode = 2;
139 break;
140 default:
141 ps_mode = 0;
144 fprintf(renderer->file, "%d slc\n", ps_mode);
147 static void
148 set_linejoin(DiaRenderer *self, LineJoin mode)
150 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
151 int ps_mode;
153 switch(mode) {
154 case LINEJOIN_MITER:
155 ps_mode = 0;
156 break;
157 case LINEJOIN_ROUND:
158 ps_mode = 1;
159 break;
160 case LINEJOIN_BEVEL:
161 ps_mode = 2;
162 break;
163 default:
164 ps_mode = 0;
167 fprintf(renderer->file, "%d slj\n", ps_mode);
170 static void
171 set_linestyle(DiaRenderer *self, LineStyle mode)
173 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
174 real hole_width;
176 renderer->saved_line_style = mode;
178 switch(mode) {
179 case LINESTYLE_SOLID:
180 fprintf(renderer->file, "[] 0 sd\n");
181 break;
182 case LINESTYLE_DASHED:
183 fprintf(renderer->file, "[%f] 0 sd\n", renderer->dash_length);
184 break;
185 case LINESTYLE_DASH_DOT:
186 hole_width = (renderer->dash_length - renderer->dot_length) / 2.0;
187 fprintf(renderer->file, "[%f %f %f %f] 0 sd\n",
188 renderer->dash_length,
189 hole_width,
190 renderer->dot_length,
191 hole_width );
192 break;
193 case LINESTYLE_DASH_DOT_DOT:
194 hole_width = (renderer->dash_length - 2.0*renderer->dot_length) / 3.0;
195 fprintf(renderer->file, "[%f %f %f %f %f %f] 0 sd\n",
196 renderer->dash_length,
197 hole_width,
198 renderer->dot_length,
199 hole_width,
200 renderer->dot_length,
201 hole_width );
202 break;
203 case LINESTYLE_DOTTED:
204 fprintf(renderer->file, "[%f] 0 sd\n", renderer->dot_length);
205 break;
209 static void
210 set_dashlength(DiaRenderer *self, real length)
211 { /* dot = 20% of len */
212 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
214 if (length<0.001)
215 length = 0.001;
217 renderer->dash_length = length;
218 renderer->dot_length = length*0.2;
220 set_linestyle(self, renderer->saved_line_style);
223 static void
224 set_fillstyle(DiaRenderer *self, FillStyle mode)
226 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
228 switch(mode) {
229 case FILLSTYLE_SOLID:
230 break;
231 default:
232 message_error("%s : Unsupported fill mode specified!\n",
233 G_OBJECT_CLASS_NAME (G_OBJECT_GET_CLASS (self)));
237 static void
238 set_font(DiaRenderer *self, DiaFont *font, real height)
240 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
242 fprintf(renderer->file, "/%s-latin1 ff %f scf sf\n",
243 dia_font_get_psfontname(font), (double)height);
246 static void
247 draw_line(DiaRenderer *self,
248 Point *start, Point *end,
249 Color *line_color)
251 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
253 lazy_setcolor(renderer,line_color);
255 fprintf(renderer->file, "n %f %f m %f %f l s\n",
256 start->x, start->y, end->x, end->y);
259 static void
260 draw_polyline(DiaRenderer *self,
261 Point *points, int num_points,
262 Color *line_color)
264 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
265 int i;
267 lazy_setcolor(renderer,line_color);
269 fprintf(renderer->file, "n %f %f m ",
270 points[0].x, points[0].y);
272 for (i=1;i<num_points;i++) {
273 fprintf(renderer->file, "%f %f l ",
274 points[i].x, points[i].y);
277 fprintf(renderer->file, "s\n");
280 static void
281 draw_polygon(DiaRenderer *self,
282 Point *points, int num_points,
283 Color *line_color)
285 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
286 int i;
288 lazy_setcolor(renderer,line_color);
290 fprintf(renderer->file, "n %f %f m ",
291 points[0].x, points[0].y);
293 for (i=1;i<num_points;i++) {
294 fprintf(renderer->file, "%f %f l ",
295 points[i].x, points[i].y);
298 fprintf(renderer->file, "cp s\n");
301 static void
302 fill_polygon(DiaRenderer *self,
303 Point *points, int num_points,
304 Color *fill_color)
306 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
307 int i;
309 lazy_setcolor(renderer,fill_color);
311 fprintf(renderer->file, "n %f %f m ",
312 points[0].x, points[0].y);
314 for (i=1;i<num_points;i++) {
315 fprintf(renderer->file, "%f %f l ",
316 points[i].x, points[i].y);
319 fprintf(renderer->file, "f\n");
322 static void
323 draw_rect(DiaRenderer *self,
324 Point *ul_corner, Point *lr_corner,
325 Color *color)
327 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
329 lazy_setcolor(renderer,color);
331 fprintf(renderer->file, "n %f %f m %f %f l %f %f l %f %f l cp s\n",
332 (double) ul_corner->x, (double) ul_corner->y,
333 (double) ul_corner->x, (double) lr_corner->y,
334 (double) lr_corner->x, (double) lr_corner->y,
335 (double) lr_corner->x, (double) ul_corner->y );
338 static void
339 fill_rect(DiaRenderer *self,
340 Point *ul_corner, Point *lr_corner,
341 Color *color)
343 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
345 lazy_setcolor(renderer,color);
347 fprintf(renderer->file, "n %f %f m %f %f l %f %f l %f %f l f\n",
348 (double) ul_corner->x, (double) ul_corner->y,
349 (double) ul_corner->x, (double) lr_corner->y,
350 (double) lr_corner->x, (double) lr_corner->y,
351 (double) lr_corner->x, (double) ul_corner->y );
354 static void
355 draw_arc(DiaRenderer *self,
356 Point *center,
357 real width, real height,
358 real angle1, real angle2,
359 Color *color)
361 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
363 lazy_setcolor(renderer,color);
365 fprintf(renderer->file, "n %f %f %f %f %f %f ellipse s\n",
366 (double) center->x, (double) center->y,
367 (double) width/2.0, (double) height/2.0,
368 (double) 360.0 - angle2, (double) 360.0 - angle1 );
371 static void
372 fill_arc(DiaRenderer *self,
373 Point *center,
374 real width, real height,
375 real angle1, real angle2,
376 Color *color)
378 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
380 lazy_setcolor(renderer,color);
382 fprintf(renderer->file, "n %f %f m %f %f %f %f %f %f ellipse f\n",
383 (double) center->x, (double) center->y,
384 (double) center->x, (double) center->y,
385 (double) width/2.0, (double) height/2.0,
386 (double) 360.0 - angle2, (double) 360.0 - angle1 );
389 static void
390 draw_ellipse(DiaRenderer *self,
391 Point *center,
392 real width, real height,
393 Color *color)
395 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
397 lazy_setcolor(renderer,color);
399 fprintf(renderer->file, "n %f %f %f %f 0 360 ellipse cp s\n",
400 (double) center->x, (double) center->y,
401 (double) width/2.0, (double) height/2.0 );
404 static void
405 fill_ellipse(DiaRenderer *self,
406 Point *center,
407 real width, real height,
408 Color *color)
410 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
412 lazy_setcolor(renderer,color);
414 fprintf(renderer->file, "n %f %f %f %f 0 360 ellipse f\n",
415 (double) center->x, (double) center->y,
416 (double) width/2.0, (double) height/2.0 );
419 static void
420 draw_bezier(DiaRenderer *self,
421 BezPoint *points,
422 int numpoints, /* numpoints = 4+3*n, n=>0 */
423 Color *color)
425 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
426 int i;
428 lazy_setcolor(renderer,color);
430 if (points[0].type != BEZ_MOVE_TO)
431 g_warning("first BezPoint must be a BEZ_MOVE_TO");
433 fprintf(renderer->file, "n %f %f m",
434 (double) points[0].p1.x, (double) points[0].p1.y);
436 for (i = 1; i < numpoints; i++)
437 switch (points[i].type) {
438 case BEZ_MOVE_TO:
439 g_warning("only first BezPoint can be a BEZ_MOVE_TO");
440 break;
441 case BEZ_LINE_TO:
442 fprintf(renderer->file, " %f %f l",
443 (double) points[i].p1.x, (double) points[i].p1.y);
444 break;
445 case BEZ_CURVE_TO:
446 fprintf(renderer->file, " %f %f %f %f %f %f c",
447 (double) points[i].p1.x, (double) points[i].p1.y,
448 (double) points[i].p2.x, (double) points[i].p2.y,
449 (double) points[i].p3.x, (double) points[i].p3.y );
450 break;
453 fprintf(renderer->file, " s\n");
456 static void
457 fill_bezier(DiaRenderer *self,
458 BezPoint *points, /* Last point must be same as first point */
459 int numpoints,
460 Color *color)
462 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
463 int i;
465 lazy_setcolor(renderer,color);
467 if (points[0].type != BEZ_MOVE_TO)
468 g_warning("first BezPoint must be a BEZ_MOVE_TO");
470 fprintf(renderer->file, "n %f %f m",
471 (double) points[0].p1.x, (double) points[0].p1.y);
473 for (i = 1; i < numpoints; i++)
474 switch (points[i].type) {
475 case BEZ_MOVE_TO:
476 g_warning("only first BezPoint can be a BEZ_MOVE_TO");
477 break;
478 case BEZ_LINE_TO:
479 fprintf(renderer->file, " %f %f l",
480 (double) points[i].p1.x, (double) points[i].p1.y);
481 break;
482 case BEZ_CURVE_TO:
483 fprintf(renderer->file, " %f %f %f %f %f %f c",
484 (double) points[i].p1.x, (double) points[i].p1.y,
485 (double) points[i].p2.x, (double) points[i].p2.y,
486 (double) points[i].p3.x, (double) points[i].p3.y );
487 break;
490 fprintf(renderer->file, " f\n");
493 static void
494 draw_string(DiaRenderer *self,
495 const char *text,
496 Point *pos, Alignment alignment,
497 Color *color)
499 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
500 char *buffer;
501 const char *str;
502 int len;
504 if (1 > strlen(text))
505 return;
507 lazy_setcolor(renderer,color);
509 /* TODO: Use latin-1 encoding */
511 /* Escape all '(' and ')': */
512 buffer = g_malloc(2*strlen(text)+1);
513 *buffer = 0;
514 str = text;
515 while (*str != 0) {
516 len = strcspn(str,"()\\");
517 strncat(buffer, str, len);
518 str += len;
519 if (*str != 0) {
520 strcat(buffer,"\\");
521 strncat(buffer, str, 1);
522 str++;
525 fprintf(renderer->file, "(%s) ", buffer);
526 g_free(buffer);
528 switch (alignment) {
529 case ALIGN_LEFT:
530 fprintf(renderer->file, "%f %f m", pos->x, pos->y);
531 break;
532 case ALIGN_CENTER:
533 fprintf(renderer->file, "dup sw 2 div %f ex sub %f m",
534 pos->x, pos->y);
535 break;
536 case ALIGN_RIGHT:
537 fprintf(renderer->file, "dup sw %f ex sub %f m",
538 pos->x, pos->y);
539 break;
542 fprintf(renderer->file, " gs 1 -1 sc sh gr\n");
545 static void
546 draw_image(DiaRenderer *self,
547 Point *point,
548 real width, real height,
549 DiaImage image)
551 DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
552 int img_width, img_height, img_rowstride;
553 int v;
554 int x, y;
555 real ratio;
556 guint8 *rgb_data;
557 guint8 *mask_data;
559 img_width = dia_image_width(image);
560 img_rowstride = dia_image_rowstride(image);
561 img_height = dia_image_height(image);
563 rgb_data = dia_image_rgb_data(image);
564 mask_data = dia_image_mask_data(image);
566 ratio = height/width;
568 fprintf(renderer->file, "gs\n");
570 /* color output only */
571 fprintf(renderer->file, "/pix %i string def\n", img_width * 3);
572 fprintf(renderer->file, "%i %i 8\n", img_width, img_height);
573 fprintf(renderer->file, "%f %f tr\n", point->x, point->y);
574 fprintf(renderer->file, "%f %f sc\n", width, height);
575 fprintf(renderer->file, "[%i 0 0 %i 0 0]\n", img_width, img_height);
577 fprintf(renderer->file, "{currentfile pix readhexstring pop}\n");
578 fprintf(renderer->file, "false 3 colorimage\n");
579 fprintf(renderer->file, "\n");
581 if (mask_data) {
582 for (y = 0; y < img_width; y++) {
583 for (x = 0; x < img_height; x++) {
584 int i = y*img_height+x;
585 fprintf(renderer->file, "%02x", 255-(mask_data[i]*(255-rgb_data[i*3])/255));
586 fprintf(renderer->file, "%02x", 255-(mask_data[i]*(255-rgb_data[i*3+1])/255));
587 fprintf(renderer->file, "%02x", 255-(mask_data[i]*(255-rgb_data[i*3+2])/255));
589 fprintf(renderer->file, "\n");
591 } else {
592 guint8 *ptr = rgb_data;
593 for (y = 0; y < img_width; y++) {
594 for (x = 0; x < img_height; x++) {
595 fprintf(renderer->file, "%02x", (int)(*ptr++));
596 fprintf(renderer->file, "%02x", (int)(*ptr++));
597 fprintf(renderer->file, "%02x", (int)(*ptr++));
599 fprintf(renderer->file, "\n");
602 fprintf(renderer->file, "gr\n");
603 fprintf(renderer->file, "\n");
605 g_free(rgb_data);
606 g_free(mask_data);
609 static void
610 begin_prolog (DiaPsRenderer *renderer)
612 g_assert(renderer->file != NULL);
614 fprintf(renderer->file, "%%%%BeginProlog\n");
615 fprintf(renderer->file,
616 "[ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"
617 "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"
618 "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"
619 "/.notdef /.notdef /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright\n"
620 "/parenleft /parenright /asterisk /plus /comma /hyphen /period /slash /zero /one\n"
621 "/two /three /four /five /six /seven /eight /nine /colon /semicolon\n"
622 "/less /equal /greater /question /at /A /B /C /D /E\n"
623 "/F /G /H /I /J /K /L /M /N /O\n"
624 "/P /Q /R /S /T /U /V /W /X /Y\n"
625 "/Z /bracketleft /backslash /bracketright /asciicircum /underscore /quoteleft /a /b /c\n"
626 "/d /e /f /g /h /i /j /k /l /m\n"
627 "/n /o /p /q /r /s /t /u /v /w\n"
628 "/x /y /z /braceleft /bar /braceright /asciitilde /.notdef /.notdef /.notdef\n"
629 "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"
630 "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"
631 "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"
632 "/space /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright\n"
633 "/ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron /degree /plusminus /twosuperior /threesuperior\n"
634 "/acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf\n"
635 "/threequarters /questiondown /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla\n"
636 "/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde\n"
637 "/Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex\n"
638 "/Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring\n"
639 "/ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis\n"
640 "/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave\n"
641 "/uacute /ucircumflex /udieresis /yacute /thorn /ydieresis] /isolatin1encoding exch def\n");
643 fprintf(renderer->file,
644 "/cp {closepath} bind def\n"
645 "/c {curveto} bind def\n"
646 "/f {fill} bind def\n"
647 "/a {arc} bind def\n"
648 "/ef {eofill} bind def\n"
649 "/ex {exch} bind def\n"
650 "/gr {grestore} bind def\n"
651 "/gs {gsave} bind def\n"
652 "/sa {save} bind def\n"
653 "/rs {restore} bind def\n"
654 "/l {lineto} bind def\n"
655 "/m {moveto} bind def\n"
656 "/rm {rmoveto} bind def\n"
657 "/n {newpath} bind def\n"
658 "/s {stroke} bind def\n"
659 "/sh {show} bind def\n"
660 "/slc {setlinecap} bind def\n"
661 "/slj {setlinejoin} bind def\n"
662 "/slw {setlinewidth} bind def\n"
663 "/srgb {setrgbcolor} bind def\n"
664 "/rot {rotate} bind def\n"
665 "/sc {scale} bind def\n"
666 "/sd {setdash} bind def\n"
667 "/ff {findfont} bind def\n"
668 "/sf {setfont} bind def\n"
669 "/scf {scalefont} bind def\n"
670 "/sw {stringwidth pop} bind def\n"
671 "/tr {translate} bind def\n"
673 "\n/ellipsedict 8 dict def\n"
674 "ellipsedict /mtrx matrix put\n"
675 "/ellipse\n"
676 "{ ellipsedict begin\n"
677 " /endangle exch def\n"
678 " /startangle exch def\n"
679 " /yrad exch def\n"
680 " /xrad exch def\n"
681 " /y exch def\n"
682 " /x exch def"
683 " /savematrix mtrx currentmatrix def\n"
684 " x y tr xrad yrad sc\n"
685 " 0 0 1 startangle endangle arc\n"
686 " savematrix setmatrix\n"
687 " end\n"
688 "} def\n\n"
689 "/mergeprocs {\n"
690 "dup length\n"
691 "3 -1 roll\n"
692 "dup\n"
693 "length\n"
694 "dup\n"
695 "5 1 roll\n"
696 "3 -1 roll\n"
697 "add\n"
698 "array cvx\n"
699 "dup\n"
700 "3 -1 roll\n"
701 "0 exch\n"
702 "putinterval\n"
703 "dup\n"
704 "4 2 roll\n"
705 "putinterval\n"
706 "} bind def\n");
710 /* helper function */
711 static void
712 print_reencode_font(FILE *file, char *fontname)
714 /* Don't reencode the Symbol font, as it doesn't work in latin1 encoding.
715 * Instead, just define Symbol-latin1 to be the same as Symbol. */
716 if (!strcmp(fontname, "Symbol"))
717 fprintf(file,
718 "/%s-latin1\n"
719 " /%s findfont\n"
720 "definefont pop\n", fontname, fontname);
721 else
722 fprintf(file,
723 "/%s-latin1\n"
724 " /%s findfont\n"
725 " dup length dict begin\n"
726 " {1 index /FID ne {def} {pop pop} ifelse} forall\n"
727 " /Encoding isolatin1encoding def\n"
728 " currentdict end\n"
729 "definefont pop\n", fontname, fontname);
732 static void
733 dump_fonts (DiaPsRenderer *renderer)
735 print_reencode_font(renderer->file, "Times-Roman");
736 print_reencode_font(renderer->file, "Times-Italic");
737 print_reencode_font(renderer->file, "Times-Bold");
738 print_reencode_font(renderer->file, "Times-BoldItalic");
739 print_reencode_font(renderer->file, "AvantGarde-Book");
740 print_reencode_font(renderer->file, "AvantGarde-BookOblique");
741 print_reencode_font(renderer->file, "AvantGarde-Demi");
742 print_reencode_font(renderer->file, "AvantGarde-DemiOblique");
743 print_reencode_font(renderer->file, "Bookman-Light");
744 print_reencode_font(renderer->file, "Bookman-LightItalic");
745 print_reencode_font(renderer->file, "Bookman-Demi");
746 print_reencode_font(renderer->file, "Bookman-DemiItalic");
747 print_reencode_font(renderer->file, "Courier");
748 print_reencode_font(renderer->file, "Courier-Oblique");
749 print_reencode_font(renderer->file, "Courier-Bold");
750 print_reencode_font(renderer->file, "Courier-BoldOblique");
751 print_reencode_font(renderer->file, "Helvetica");
752 print_reencode_font(renderer->file, "Helvetica-Oblique");
753 print_reencode_font(renderer->file, "Helvetica-Bold");
754 print_reencode_font(renderer->file, "Helvetica-BoldOblique");
755 print_reencode_font(renderer->file, "Helvetica-Narrow");
756 print_reencode_font(renderer->file, "Helvetica-Narrow-Oblique");
757 print_reencode_font(renderer->file, "Helvetica-Narrow-Bold");
758 print_reencode_font(renderer->file, "Helvetica-Narrow-BoldOblique");
759 print_reencode_font(renderer->file, "NewCenturySchoolbook-Roman");
760 print_reencode_font(renderer->file, "NewCenturySchoolbook-Italic");
761 print_reencode_font(renderer->file, "NewCenturySchoolbook-Bold");
762 print_reencode_font(renderer->file, "NewCenturySchoolbook-BoldItalic");
763 print_reencode_font(renderer->file, "Palatino-Roman");
764 print_reencode_font(renderer->file, "Palatino-Italic");
765 print_reencode_font(renderer->file, "Palatino-Bold");
766 print_reencode_font(renderer->file, "Palatino-BoldItalic");
767 print_reencode_font(renderer->file, "Symbol");
768 print_reencode_font(renderer->file, "ZapfChancery-MediumItalic");
769 print_reencode_font(renderer->file, "ZapfDingbats");
772 static void
773 end_prolog (DiaPsRenderer *renderer)
775 if (renderer->is_eps) {
776 fprintf(renderer->file,
777 "%f %f scale\n", renderer->scale, -renderer->scale);
778 fprintf(renderer->file,
779 "%f %f translate\n", -renderer->extent.left, -renderer->extent.bottom);
780 } else {
781 /* done by BoundingBox above */
784 fprintf(renderer->file,
785 "%%%%EndProlog\n\n\n");
788 /* constructor */
789 static void
790 ps_renderer_init (GTypeInstance *instance, gpointer g_class)
792 DiaPsRenderer *renderer = DIA_PS_RENDERER (instance);
794 renderer->file = NULL;
796 renderer->lcolor.red = -1.0;
798 renderer->dash_length = 1.0;
799 renderer->dot_length = 0.2;
800 renderer->saved_line_style = LINESTYLE_SOLID;
801 renderer->is_portrait = TRUE;
803 renderer->scale = 28.346;
806 /* GObject stuff */
807 static void dia_ps_renderer_class_init (DiaPsRendererClass *klass);
809 static gpointer parent_class = NULL;
811 GType
812 dia_ps_renderer_get_type (void)
814 static GType object_type = 0;
816 if (!object_type)
818 static const GTypeInfo object_info =
820 sizeof (DiaPsRendererClass),
821 (GBaseInitFunc) NULL,
822 (GBaseFinalizeFunc) NULL,
823 (GClassInitFunc) dia_ps_renderer_class_init,
824 NULL, /* class_finalize */
825 NULL, /* class_data */
826 sizeof (DiaPsRenderer),
827 0, /* n_preallocs */
828 ps_renderer_init /* init */
831 object_type = g_type_register_static (DIA_TYPE_RENDERER,
832 "DiaPsRenderer",
833 &object_info, 0);
836 return object_type;
839 static void
840 dia_ps_renderer_finalize (GObject *object)
842 DiaPsRenderer *renderer = DIA_PS_RENDERER (object);
844 g_free(renderer->title);
845 /* fclose(renderer->file);*/
847 G_OBJECT_CLASS (parent_class)->finalize (object);
850 static void
851 dia_ps_renderer_class_init (DiaPsRendererClass *klass)
853 GObjectClass *object_class = G_OBJECT_CLASS (klass);
854 DiaRendererClass *renderer_class = DIA_RENDERER_CLASS (klass);
855 DiaPsRendererClass *ps_renderer_class = DIA_PS_RENDERER_CLASS (klass);
857 parent_class = g_type_class_peek_parent (klass);
859 object_class->finalize = dia_ps_renderer_finalize;
861 renderer_class->begin_render = begin_render;
862 renderer_class->end_render = end_render;
864 renderer_class->set_linewidth = set_linewidth;
865 renderer_class->set_linecaps = set_linecaps;
866 renderer_class->set_linejoin = set_linejoin;
867 renderer_class->set_linestyle = set_linestyle;
868 renderer_class->set_dashlength = set_dashlength;
869 renderer_class->set_fillstyle = set_fillstyle;
870 renderer_class->set_font = set_font;
872 renderer_class->draw_line = draw_line;
873 renderer_class->fill_polygon = fill_polygon;
874 renderer_class->draw_arc = draw_arc;
875 renderer_class->fill_arc = fill_arc;
876 renderer_class->draw_ellipse = draw_ellipse;
877 renderer_class->fill_ellipse = fill_ellipse;
878 renderer_class->draw_string = draw_string;
879 renderer_class->draw_image = draw_image;
881 /* medium level functions */
882 renderer_class->draw_bezier = draw_bezier;
883 renderer_class->fill_bezier = fill_bezier;
884 renderer_class->draw_rect = draw_rect;
885 renderer_class->fill_rect = fill_rect;
886 renderer_class->draw_polyline = draw_polyline;
887 renderer_class->draw_polygon = draw_polygon;
889 /* ps specific */
890 ps_renderer_class->begin_prolog = begin_prolog;
891 ps_renderer_class->dump_fonts = dump_fonts;
892 ps_renderer_class->end_prolog = end_prolog;