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.
30 #include "diapsrenderer.h"
32 #include "dia_image.h"
35 #define DTOSTR_BUF_SIZE G_ASCII_DTOSTR_BUF_SIZE
36 #define psrenderer_dtostr(buf,d) \
37 g_ascii_formatd(buf, sizeof(buf), "%f", d)
39 /* Returns TRUE if this file is an encapsulated postscript file
40 * (including e.g. epsi).
42 static gboolean
renderer_is_eps(DiaPsRenderer
*renderer
) {
43 return renderer
->pstype
== PSTYPE_EPS
||
44 renderer
->pstype
== PSTYPE_EPSI
;
47 /** Returns TRUE if this file is an EPSI file */
48 static gboolean
renderer_is_epsi(DiaPsRenderer
*renderer
) {
49 return renderer
->pstype
== PSTYPE_EPSI
;
53 lazy_setcolor(DiaPsRenderer
*renderer
,
56 gchar r_buf
[DTOSTR_BUF_SIZE
];
57 gchar g_buf
[DTOSTR_BUF_SIZE
];
58 gchar b_buf
[DTOSTR_BUF_SIZE
];
60 if (!color_equals(color
, &(renderer
->lcolor
))) {
61 renderer
->lcolor
= *color
;
62 fprintf(renderer
->file
, "%s %s %s srgb\n",
63 psrenderer_dtostr(r_buf
, (gdouble
) color
->red
),
64 psrenderer_dtostr(g_buf
, (gdouble
) color
->green
),
65 psrenderer_dtostr(b_buf
, (gdouble
) color
->blue
) );
70 begin_render(DiaRenderer
*self
)
72 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
75 g_assert (renderer
->file
!= NULL
);
77 time_now
= time(NULL
);
79 if (renderer_is_eps(renderer
))
80 fprintf(renderer
->file
,
81 "%%!PS-Adobe-2.0 EPSF-2.0\n");
83 fprintf(renderer
->file
,
85 fprintf(renderer
->file
,
87 "%%%%Creator: Dia v%s\n"
88 "%%%%CreationDate: %s"
90 "%%%%Orientation: %s\n",
91 renderer
->title
? renderer
->title
: "(NULL)" ,
95 renderer
->is_portrait
? "Portrait" : "Landscape");
97 if (renderer_is_epsi(renderer
)) {
98 g_assert(!"Preview image not implmented");
99 /* but it *may* belong here ... */
101 if (renderer_is_eps(renderer
))
102 fprintf(renderer
->file
,
103 "%%%%Magnification: 1.0000\n"
104 "%%%%BoundingBox: 0 0 %d %d\n",
105 (int) ceil( (renderer
->extent
.right
- renderer
->extent
.left
)
107 (int) ceil( (renderer
->extent
.bottom
- renderer
->extent
.top
)
108 * renderer
->scale
) );
111 fprintf(renderer
->file
,
112 "%%%%DocumentPaperSizes: %s\n",
113 renderer
->paper
? renderer
->paper
: "(NULL)");
115 fprintf(renderer
->file
,
117 fprintf(renderer
->file
,
119 "%%%%EndComments\n");
121 DIA_PS_RENDERER_GET_CLASS(self
)->begin_prolog(renderer
);
122 /* get our font definitions */
123 DIA_PS_RENDERER_GET_CLASS(self
)->dump_fonts(renderer
);
125 DIA_PS_RENDERER_GET_CLASS(self
)->end_prolog(renderer
);
129 end_render(DiaRenderer
*self
)
131 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
133 if (renderer_is_eps(renderer
))
134 fprintf(renderer
->file
, "showpage\n");
138 set_linewidth(DiaRenderer
*self
, real linewidth
)
139 { /* 0 == hairline **/
140 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
141 gchar lw_buf
[DTOSTR_BUF_SIZE
];
143 /* Adobe's advice: Set to very small but fixed size, to avoid changes
144 * due to different resolution output. */
145 /* .01 cm becomes <5 dots on 1200 DPI */
146 if (linewidth
== 0.0) linewidth
=.01;
147 fprintf(renderer
->file
, "%s slw\n",
148 psrenderer_dtostr(lw_buf
, (gdouble
) linewidth
) );
152 set_linecaps(DiaRenderer
*self
, LineCaps mode
)
154 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
164 case LINECAPS_PROJECTING
:
171 fprintf(renderer
->file
, "%d slc\n", ps_mode
);
175 set_linejoin(DiaRenderer
*self
, LineJoin mode
)
177 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
194 fprintf(renderer
->file
, "%d slj\n", ps_mode
);
198 set_linestyle(DiaRenderer
*self
, LineStyle mode
)
200 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
202 gchar dashl_buf
[DTOSTR_BUF_SIZE
];
203 gchar dotl_buf
[DTOSTR_BUF_SIZE
];
204 gchar holew_buf
[DTOSTR_BUF_SIZE
];
206 renderer
->saved_line_style
= mode
;
209 case LINESTYLE_SOLID
:
210 fprintf(renderer
->file
, "[] 0 sd\n");
212 case LINESTYLE_DASHED
:
213 fprintf(renderer
->file
, "[%s] 0 sd\n",
214 psrenderer_dtostr(dashl_buf
, renderer
->dash_length
) );
216 case LINESTYLE_DASH_DOT
:
217 hole_width
= (renderer
->dash_length
- renderer
->dot_length
) / 2.0;
218 psrenderer_dtostr(holew_buf
, hole_width
);
219 psrenderer_dtostr(dashl_buf
, renderer
->dash_length
);
220 psrenderer_dtostr(dotl_buf
, renderer
->dot_length
);
221 fprintf(renderer
->file
, "[%s %s %s %s] 0 sd\n",
227 case LINESTYLE_DASH_DOT_DOT
:
228 hole_width
= (renderer
->dash_length
- 2.0*renderer
->dot_length
) / 3.0;
229 psrenderer_dtostr(holew_buf
, hole_width
);
230 psrenderer_dtostr(dashl_buf
, renderer
->dash_length
);
231 psrenderer_dtostr(dotl_buf
, renderer
->dot_length
);
232 fprintf(renderer
->file
, "[%s %s %s %s %s %s] 0 sd\n",
240 case LINESTYLE_DOTTED
:
241 fprintf(renderer
->file
, "[%s] 0 sd\n",
242 psrenderer_dtostr(dotl_buf
, renderer
->dot_length
) );
248 set_dashlength(DiaRenderer
*self
, real length
)
249 { /* dot = 20% of len */
250 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
255 renderer
->dash_length
= length
;
256 renderer
->dot_length
= length
*0.2;
258 set_linestyle(self
, renderer
->saved_line_style
);
262 set_fillstyle(DiaRenderer
*self
, FillStyle mode
)
264 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
267 case FILLSTYLE_SOLID
:
270 message_error("%s : Unsupported fill mode specified!\n",
271 G_OBJECT_CLASS_NAME (G_OBJECT_GET_CLASS (renderer
)));
276 set_font(DiaRenderer
*self
, DiaFont
*font
, real height
)
278 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
279 gchar h_buf
[DTOSTR_BUF_SIZE
];
281 fprintf(renderer
->file
, "/%s-latin1 ff %s scf sf\n",
282 dia_font_get_psfontname(font
),
283 psrenderer_dtostr(h_buf
, (gdouble
) height
*0.7) );
287 draw_line(DiaRenderer
*self
,
288 Point
*start
, Point
*end
,
291 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
292 gchar sx_buf
[DTOSTR_BUF_SIZE
];
293 gchar sy_buf
[DTOSTR_BUF_SIZE
];
294 gchar ex_buf
[DTOSTR_BUF_SIZE
];
295 gchar ey_buf
[DTOSTR_BUF_SIZE
];
297 lazy_setcolor(renderer
,line_color
);
299 fprintf(renderer
->file
, "n %s %s m %s %s l s\n",
300 psrenderer_dtostr(sx_buf
, start
->x
),
301 psrenderer_dtostr(sy_buf
, start
->y
),
302 psrenderer_dtostr(ex_buf
, end
->x
),
303 psrenderer_dtostr(ey_buf
, end
->y
) );
307 draw_polyline(DiaRenderer
*self
,
308 Point
*points
, int num_points
,
311 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
313 gchar px_buf
[DTOSTR_BUF_SIZE
];
314 gchar py_buf
[DTOSTR_BUF_SIZE
];
316 lazy_setcolor(renderer
,line_color
);
318 fprintf(renderer
->file
, "n %s %s m ",
319 psrenderer_dtostr(px_buf
, points
[0].x
),
320 psrenderer_dtostr(py_buf
, points
[0].y
) );
322 for (i
=1;i
<num_points
;i
++) {
323 fprintf(renderer
->file
, "%s %s l ",
324 psrenderer_dtostr(px_buf
, points
[i
].x
),
325 psrenderer_dtostr(py_buf
, points
[i
].y
) );
328 fprintf(renderer
->file
, "s\n");
332 psrenderer_polygon(DiaPsRenderer
*renderer
,
339 gchar px_buf
[DTOSTR_BUF_SIZE
];
340 gchar py_buf
[DTOSTR_BUF_SIZE
];
342 lazy_setcolor(renderer
, line_color
);
344 fprintf(renderer
->file
, "n %s %s m ",
345 psrenderer_dtostr(px_buf
, points
[0].x
),
346 psrenderer_dtostr(py_buf
, points
[0].y
) );
349 for (i
=1;i
<num_points
;i
++) {
350 fprintf(renderer
->file
, "%s %s l ",
351 psrenderer_dtostr(px_buf
, points
[i
].x
),
352 psrenderer_dtostr(py_buf
, points
[i
].y
) );
355 fprintf(renderer
->file
, "ef\n");
357 fprintf(renderer
->file
, "cp s\n");
361 draw_polygon(DiaRenderer
*self
,
362 Point
*points
, int num_points
,
365 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
366 psrenderer_polygon(renderer
, points
, num_points
, line_color
, FALSE
);
370 fill_polygon(DiaRenderer
*self
,
371 Point
*points
, int num_points
,
374 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
375 psrenderer_polygon(renderer
, points
, num_points
, fill_color
, TRUE
);
379 psrenderer_rect(DiaPsRenderer
*renderer
,
385 gchar ulx_buf
[DTOSTR_BUF_SIZE
];
386 gchar uly_buf
[DTOSTR_BUF_SIZE
];
387 gchar lrx_buf
[DTOSTR_BUF_SIZE
];
388 gchar lry_buf
[DTOSTR_BUF_SIZE
];
390 lazy_setcolor(renderer
,color
);
392 psrenderer_dtostr(ulx_buf
, (gdouble
) ul_corner
->x
);
393 psrenderer_dtostr(uly_buf
, (gdouble
) ul_corner
->y
);
394 psrenderer_dtostr(lrx_buf
, (gdouble
) lr_corner
->x
);
395 psrenderer_dtostr(lry_buf
, (gdouble
) lr_corner
->y
);
397 fprintf(renderer
->file
, "n %s %s m %s %s l %s %s l %s %s l %s\n",
402 filled
? "f" : "cp s" );
406 draw_rect(DiaRenderer
*self
,
407 Point
*ul_corner
, Point
*lr_corner
,
410 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
411 psrenderer_rect(renderer
, ul_corner
, lr_corner
, color
, FALSE
);
415 fill_rect(DiaRenderer
*self
,
416 Point
*ul_corner
, Point
*lr_corner
,
419 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
420 psrenderer_rect(renderer
, ul_corner
, lr_corner
, color
, TRUE
);
424 psrenderer_arc(DiaPsRenderer
*renderer
,
426 real width
, real height
,
427 real angle1
, real angle2
,
431 gchar cx_buf
[DTOSTR_BUF_SIZE
];
432 gchar cy_buf
[DTOSTR_BUF_SIZE
];
433 gchar a1_buf
[DTOSTR_BUF_SIZE
];
434 gchar a2_buf
[DTOSTR_BUF_SIZE
];
435 gchar w_buf
[DTOSTR_BUF_SIZE
];
436 gchar h_buf
[DTOSTR_BUF_SIZE
];
438 lazy_setcolor(renderer
, color
);
440 psrenderer_dtostr(cx_buf
, (gdouble
) center
->x
);
441 psrenderer_dtostr(cy_buf
, (gdouble
) center
->y
);
442 psrenderer_dtostr(a1_buf
, (gdouble
) 360.0 - angle1
);
443 psrenderer_dtostr(a2_buf
, (gdouble
) 360.0 - angle2
);
444 psrenderer_dtostr(w_buf
, (gdouble
) width
/ 2.0);
445 psrenderer_dtostr(h_buf
, (gdouble
) height
/ 2.0);
447 fprintf(renderer
->file
, "n ");
450 fprintf(renderer
->file
, "%s %s m ", cx_buf
, cy_buf
);
452 fprintf(renderer
->file
, "%s %s %s %s %s %s ellipse %s\n",
453 cx_buf
, cy_buf
, w_buf
, h_buf
, a2_buf
, a1_buf
,
454 filled
? "f" : "s" );
459 draw_arc(DiaRenderer
*self
,
461 real width
, real height
,
462 real angle1
, real angle2
,
465 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
466 psrenderer_arc(renderer
, center
, width
, height
, angle1
, angle2
, color
, FALSE
);
470 fill_arc(DiaRenderer
*self
,
472 real width
, real height
,
473 real angle1
, real angle2
,
476 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
477 psrenderer_arc(renderer
, center
, width
, height
, angle1
, angle2
, color
, TRUE
);
481 psrenderer_ellipse(DiaPsRenderer
*renderer
,
483 real width
, real height
,
487 gchar cx_buf
[DTOSTR_BUF_SIZE
];
488 gchar cy_buf
[DTOSTR_BUF_SIZE
];
489 gchar w_buf
[DTOSTR_BUF_SIZE
];
490 gchar h_buf
[DTOSTR_BUF_SIZE
];
492 lazy_setcolor(renderer
,color
);
494 fprintf(renderer
->file
, "n %s %s %s %s 0 360 ellipse %s\n",
495 psrenderer_dtostr(cx_buf
, (gdouble
) center
->x
),
496 psrenderer_dtostr(cy_buf
, (gdouble
) center
->y
),
497 psrenderer_dtostr(w_buf
, (gdouble
) width
/ 2.0),
498 psrenderer_dtostr(h_buf
, (gdouble
) height
/ 2.0),
499 filled
? "f" : "cp s" );
503 draw_ellipse(DiaRenderer
*self
,
505 real width
, real height
,
508 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
509 psrenderer_ellipse(renderer
, center
, width
, height
, color
, FALSE
);
513 fill_ellipse(DiaRenderer
*self
,
515 real width
, real height
,
518 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
519 psrenderer_ellipse(renderer
, center
, width
, height
, color
, TRUE
);
523 psrenderer_bezier(DiaPsRenderer
*renderer
,
530 gchar p1x_buf
[DTOSTR_BUF_SIZE
];
531 gchar p1y_buf
[DTOSTR_BUF_SIZE
];
532 gchar p2x_buf
[DTOSTR_BUF_SIZE
];
533 gchar p2y_buf
[DTOSTR_BUF_SIZE
];
534 gchar p3x_buf
[DTOSTR_BUF_SIZE
];
535 gchar p3y_buf
[DTOSTR_BUF_SIZE
];
537 lazy_setcolor(renderer
,color
);
539 if (points
[0].type
!= BEZ_MOVE_TO
)
540 g_warning("first BezPoint must be a BEZ_MOVE_TO");
542 fprintf(renderer
->file
, "n %s %s m",
543 psrenderer_dtostr(p1x_buf
, (gdouble
) points
[0].p1
.x
),
544 psrenderer_dtostr(p1y_buf
, (gdouble
) points
[0].p1
.y
) );
546 for (i
= 1; i
< numpoints
; i
++)
547 switch (points
[i
].type
) {
549 g_warning("only first BezPoint can be a BEZ_MOVE_TO");
552 fprintf(renderer
->file
, " %s %s l",
553 psrenderer_dtostr(p1x_buf
, (gdouble
) points
[i
].p1
.x
),
554 psrenderer_dtostr(p1y_buf
, (gdouble
) points
[i
].p1
.y
) );
557 fprintf(renderer
->file
, " %s %s %s %s %s %s c",
558 psrenderer_dtostr(p1x_buf
, (gdouble
) points
[i
].p1
.x
),
559 psrenderer_dtostr(p1y_buf
, (gdouble
) points
[i
].p1
.y
),
560 psrenderer_dtostr(p2x_buf
, (gdouble
) points
[i
].p2
.x
),
561 psrenderer_dtostr(p2y_buf
, (gdouble
) points
[i
].p2
.y
),
562 psrenderer_dtostr(p3x_buf
, (gdouble
) points
[i
].p3
.x
),
563 psrenderer_dtostr(p3y_buf
, (gdouble
) points
[i
].p3
.y
) );
568 fprintf(renderer
->file
, " ef\n");
570 fprintf(renderer
->file
, " s\n");
574 draw_bezier(DiaRenderer
*self
,
576 int numpoints
, /* numpoints = 4+3*n, n=>0 */
579 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
580 psrenderer_bezier(renderer
, points
, numpoints
, color
, FALSE
);
584 fill_bezier(DiaRenderer
*self
,
585 BezPoint
*points
, /* Last point must be same as first point */
589 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
590 psrenderer_bezier(renderer
, points
, numpoints
, color
, TRUE
);
594 draw_string(DiaRenderer
*self
,
596 Point
*pos
, Alignment alignment
,
599 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
602 gchar px_buf
[DTOSTR_BUF_SIZE
];
603 gchar py_buf
[DTOSTR_BUF_SIZE
];
606 GError
* error
= NULL
;
608 if (1 > strlen(text
))
611 lazy_setcolor(renderer
,color
);
613 localestr
= g_convert(text
, -1, "LATIN1", "UTF-8", NULL
, NULL
, &error
);
615 if (localestr
== NULL
) {
616 message_error("Can't convert string %s: %s\n", text
, error
->message
);
617 localestr
= g_strdup(text
);
620 /* Escape all '(' and ')': */
621 buffer
= g_malloc(2*strlen(localestr
)+1);
625 len
= strcspn(str
,"()\\");
626 strncat(buffer
, str
, len
);
630 strncat(buffer
, str
, 1);
634 fprintf(renderer
->file
, "(%s) ", buffer
);
640 fprintf(renderer
->file
, "%s %s m",
641 psrenderer_dtostr(px_buf
, pos
->x
),
642 psrenderer_dtostr(py_buf
, pos
->y
) );
645 fprintf(renderer
->file
, "dup sw 2 div %s ex sub %s m",
646 psrenderer_dtostr(px_buf
, pos
->x
),
647 psrenderer_dtostr(py_buf
, pos
->y
) );
650 fprintf(renderer
->file
, "dup sw %s ex sub %s m",
651 psrenderer_dtostr(px_buf
, pos
->x
),
652 psrenderer_dtostr(py_buf
, pos
->y
) );
656 fprintf(renderer
->file
, " gs 1 -1 sc sh gr\n");
660 draw_image(DiaRenderer
*self
,
662 real width
, real height
,
665 DiaPsRenderer
*renderer
= DIA_PS_RENDERER(self
);
666 int img_width
, img_height
, img_rowstride
;
671 gchar d1_buf
[DTOSTR_BUF_SIZE
];
672 gchar d2_buf
[DTOSTR_BUF_SIZE
];
674 img_width
= dia_image_width(image
);
675 img_rowstride
= dia_image_rowstride(image
);
676 img_height
= dia_image_height(image
);
678 rgb_data
= dia_image_rgb_data(image
);
679 mask_data
= dia_image_mask_data(image
);
681 ratio
= height
/width
;
683 fprintf(renderer
->file
, "gs\n");
685 /* color output only */
686 fprintf(renderer
->file
, "/pix %i string def\n", img_width
* 3);
687 fprintf(renderer
->file
, "%i %i 8\n", img_width
, img_height
);
688 fprintf(renderer
->file
, "%s %s tr\n",
689 psrenderer_dtostr(d1_buf
, point
->x
),
690 psrenderer_dtostr(d2_buf
, point
->y
) );
691 fprintf(renderer
->file
, "%s %s sc\n",
692 psrenderer_dtostr(d1_buf
, width
),
693 psrenderer_dtostr(d2_buf
, height
) );
694 fprintf(renderer
->file
, "[%i 0 0 %i 0 0]\n", img_width
, img_height
);
696 fprintf(renderer
->file
, "{currentfile pix readhexstring pop}\n");
697 fprintf(renderer
->file
, "false 3 colorimage\n");
698 fprintf(renderer
->file
, "\n");
701 for (y
= 0; y
< img_height
; y
++) {
702 for (x
= 0; x
< img_width
; x
++) {
703 int i
= y
*img_rowstride
+x
*3;
704 int m
= y
*img_width
+x
;
705 fprintf(renderer
->file
, "%02x", 255-(mask_data
[m
]*(255-rgb_data
[i
])/255));
706 fprintf(renderer
->file
, "%02x", 255-(mask_data
[m
]*(255-rgb_data
[i
+1])/255));
707 fprintf(renderer
->file
, "%02x", 255-(mask_data
[m
]*(255-rgb_data
[i
+2])/255));
709 fprintf(renderer
->file
, "\n");
712 for (y
= 0; y
< img_height
; y
++) {
713 for (x
= 0; x
< img_width
; x
++) {
714 int i
= y
*img_rowstride
+x
*3;
715 fprintf(renderer
->file
, "%02x", (int)(rgb_data
[i
]));
716 fprintf(renderer
->file
, "%02x", (int)(rgb_data
[i
+1]));
717 fprintf(renderer
->file
, "%02x", (int)(rgb_data
[i
+2]));
719 fprintf(renderer
->file
, "\n");
722 fprintf(renderer
->file
, "gr\n");
723 fprintf(renderer
->file
, "\n");
730 begin_prolog (DiaPsRenderer
*renderer
)
732 g_assert(renderer
->file
!= NULL
);
734 fprintf(renderer
->file
, "%%%%BeginProlog\n");
735 fprintf(renderer
->file
,
736 "[ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"
737 "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"
738 "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"
739 "/.notdef /.notdef /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright\n"
740 "/parenleft /parenright /asterisk /plus /comma /hyphen /period /slash /zero /one\n"
741 "/two /three /four /five /six /seven /eight /nine /colon /semicolon\n"
742 "/less /equal /greater /question /at /A /B /C /D /E\n"
743 "/F /G /H /I /J /K /L /M /N /O\n"
744 "/P /Q /R /S /T /U /V /W /X /Y\n"
745 "/Z /bracketleft /backslash /bracketright /asciicircum /underscore /quoteleft /a /b /c\n"
746 "/d /e /f /g /h /i /j /k /l /m\n"
747 "/n /o /p /q /r /s /t /u /v /w\n"
748 "/x /y /z /braceleft /bar /braceright /asciitilde /.notdef /.notdef /.notdef\n"
749 "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"
750 "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"
751 "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"
752 "/space /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright\n"
753 "/ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron /degree /plusminus /twosuperior /threesuperior\n"
754 "/acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf\n"
755 "/threequarters /questiondown /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla\n"
756 "/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde\n"
757 "/Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex\n"
758 "/Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring\n"
759 "/ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis\n"
760 "/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave\n"
761 "/uacute /ucircumflex /udieresis /yacute /thorn /ydieresis] /isolatin1encoding exch def\n");
763 fprintf(renderer
->file
,
764 "/cp {closepath} bind def\n"
765 "/c {curveto} bind def\n"
766 "/f {fill} bind def\n"
767 "/a {arc} bind def\n"
768 "/ef {eofill} bind def\n"
769 "/ex {exch} bind def\n"
770 "/gr {grestore} bind def\n"
771 "/gs {gsave} bind def\n"
772 "/sa {save} bind def\n"
773 "/rs {restore} bind def\n"
774 "/l {lineto} bind def\n"
775 "/m {moveto} bind def\n"
776 "/rm {rmoveto} bind def\n"
777 "/n {newpath} bind def\n"
778 "/s {stroke} bind def\n"
779 "/sh {show} bind def\n"
780 "/slc {setlinecap} bind def\n"
781 "/slj {setlinejoin} bind def\n"
782 "/slw {setlinewidth} bind def\n"
783 "/srgb {setrgbcolor} bind def\n"
784 "/rot {rotate} bind def\n"
785 "/sc {scale} bind def\n"
786 "/sd {setdash} bind def\n"
787 "/ff {findfont} bind def\n"
788 "/sf {setfont} bind def\n"
789 "/scf {scalefont} bind def\n"
790 "/sw {stringwidth pop} bind def\n"
791 "/tr {translate} bind def\n"
793 "\n/ellipsedict 8 dict def\n"
794 "ellipsedict /mtrx matrix put\n"
796 "{ ellipsedict begin\n"
797 " /endangle exch def\n"
798 " /startangle exch def\n"
803 " /savematrix mtrx currentmatrix def\n"
804 " x y tr xrad yrad sc\n"
805 " 0 0 1 startangle endangle arc\n"
806 " savematrix setmatrix\n"
830 /* helper function */
832 print_reencode_font(FILE *file
, char *fontname
)
834 /* Don't reencode the Symbol font, as it doesn't work in latin1 encoding.
835 * Instead, just define Symbol-latin1 to be the same as Symbol. */
836 if (!strcmp(fontname
, "Symbol"))
840 "definefont pop\n", fontname
, fontname
);
845 " dup length dict begin\n"
846 " {1 index /FID ne {def} {pop pop} ifelse} forall\n"
847 " /Encoding isolatin1encoding def\n"
849 "definefont pop\n", fontname
, fontname
);
853 dump_fonts (DiaPsRenderer
*renderer
)
855 print_reencode_font(renderer
->file
, "Times-Roman");
856 print_reencode_font(renderer
->file
, "Times-Italic");
857 print_reencode_font(renderer
->file
, "Times-Bold");
858 print_reencode_font(renderer
->file
, "Times-BoldItalic");
859 print_reencode_font(renderer
->file
, "AvantGarde-Book");
860 print_reencode_font(renderer
->file
, "AvantGarde-BookOblique");
861 print_reencode_font(renderer
->file
, "AvantGarde-Demi");
862 print_reencode_font(renderer
->file
, "AvantGarde-DemiOblique");
863 print_reencode_font(renderer
->file
, "Bookman-Light");
864 print_reencode_font(renderer
->file
, "Bookman-LightItalic");
865 print_reencode_font(renderer
->file
, "Bookman-Demi");
866 print_reencode_font(renderer
->file
, "Bookman-DemiItalic");
867 print_reencode_font(renderer
->file
, "Courier");
868 print_reencode_font(renderer
->file
, "Courier-Oblique");
869 print_reencode_font(renderer
->file
, "Courier-Bold");
870 print_reencode_font(renderer
->file
, "Courier-BoldOblique");
871 print_reencode_font(renderer
->file
, "Helvetica");
872 print_reencode_font(renderer
->file
, "Helvetica-Oblique");
873 print_reencode_font(renderer
->file
, "Helvetica-Bold");
874 print_reencode_font(renderer
->file
, "Helvetica-BoldOblique");
875 print_reencode_font(renderer
->file
, "Helvetica-Narrow");
876 print_reencode_font(renderer
->file
, "Helvetica-Narrow-Oblique");
877 print_reencode_font(renderer
->file
, "Helvetica-Narrow-Bold");
878 print_reencode_font(renderer
->file
, "Helvetica-Narrow-BoldOblique");
879 print_reencode_font(renderer
->file
, "NewCenturySchoolbook-Roman");
880 print_reencode_font(renderer
->file
, "NewCenturySchoolbook-Italic");
881 print_reencode_font(renderer
->file
, "NewCenturySchoolbook-Bold");
882 print_reencode_font(renderer
->file
, "NewCenturySchoolbook-BoldItalic");
883 print_reencode_font(renderer
->file
, "Palatino-Roman");
884 print_reencode_font(renderer
->file
, "Palatino-Italic");
885 print_reencode_font(renderer
->file
, "Palatino-Bold");
886 print_reencode_font(renderer
->file
, "Palatino-BoldItalic");
887 print_reencode_font(renderer
->file
, "Symbol");
888 print_reencode_font(renderer
->file
, "ZapfChancery-MediumItalic");
889 print_reencode_font(renderer
->file
, "ZapfDingbats");
893 end_prolog (DiaPsRenderer
*renderer
)
895 gchar d1_buf
[DTOSTR_BUF_SIZE
];
896 gchar d2_buf
[DTOSTR_BUF_SIZE
];
898 if (renderer_is_eps(renderer
)) {
899 fprintf(renderer
->file
,
901 psrenderer_dtostr(d1_buf
, renderer
->scale
),
902 psrenderer_dtostr(d2_buf
, -renderer
->scale
) );
903 fprintf(renderer
->file
,
905 psrenderer_dtostr(d1_buf
, -renderer
->extent
.left
),
906 psrenderer_dtostr(d2_buf
, -renderer
->extent
.bottom
) );
908 /* done by BoundingBox above */
911 fprintf(renderer
->file
,
912 "%%%%EndProlog\n\n\n");
917 ps_renderer_init (GTypeInstance
*instance
, gpointer g_class
)
919 DiaPsRenderer
*renderer
= DIA_PS_RENDERER (instance
);
921 renderer
->file
= NULL
;
923 renderer
->lcolor
.red
= -1.0;
925 renderer
->dash_length
= 1.0;
926 renderer
->dot_length
= 0.2;
927 renderer
->saved_line_style
= LINESTYLE_SOLID
;
928 renderer
->is_portrait
= TRUE
;
930 renderer
->scale
= 28.346;
934 static void dia_ps_renderer_class_init (DiaPsRendererClass
*klass
);
936 static gpointer parent_class
= NULL
;
939 dia_ps_renderer_get_type (void)
941 static GType object_type
= 0;
945 static const GTypeInfo object_info
=
947 sizeof (DiaPsRendererClass
),
948 (GBaseInitFunc
) NULL
,
949 (GBaseFinalizeFunc
) NULL
,
950 (GClassInitFunc
) dia_ps_renderer_class_init
,
951 NULL
, /* class_finalize */
952 NULL
, /* class_data */
953 sizeof (DiaPsRenderer
),
955 ps_renderer_init
/* init */
958 object_type
= g_type_register_static (DIA_TYPE_RENDERER
,
967 dia_ps_renderer_finalize (GObject
*object
)
969 DiaPsRenderer
*renderer
= DIA_PS_RENDERER (object
);
971 g_free(renderer
->title
);
972 /* fclose(renderer->file);*/
974 G_OBJECT_CLASS (parent_class
)->finalize (object
);
978 dia_ps_renderer_class_init (DiaPsRendererClass
*klass
)
980 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
981 DiaRendererClass
*renderer_class
= DIA_RENDERER_CLASS (klass
);
982 DiaPsRendererClass
*ps_renderer_class
= DIA_PS_RENDERER_CLASS (klass
);
984 parent_class
= g_type_class_peek_parent (klass
);
986 object_class
->finalize
= dia_ps_renderer_finalize
;
988 renderer_class
->begin_render
= begin_render
;
989 renderer_class
->end_render
= end_render
;
991 renderer_class
->set_linewidth
= set_linewidth
;
992 renderer_class
->set_linecaps
= set_linecaps
;
993 renderer_class
->set_linejoin
= set_linejoin
;
994 renderer_class
->set_linestyle
= set_linestyle
;
995 renderer_class
->set_dashlength
= set_dashlength
;
996 renderer_class
->set_fillstyle
= set_fillstyle
;
997 renderer_class
->set_font
= set_font
;
999 renderer_class
->draw_line
= draw_line
;
1000 renderer_class
->fill_polygon
= fill_polygon
;
1001 renderer_class
->draw_arc
= draw_arc
;
1002 renderer_class
->fill_arc
= fill_arc
;
1003 renderer_class
->draw_ellipse
= draw_ellipse
;
1004 renderer_class
->fill_ellipse
= fill_ellipse
;
1005 renderer_class
->draw_string
= draw_string
;
1006 renderer_class
->draw_image
= draw_image
;
1008 /* medium level functions */
1009 renderer_class
->draw_bezier
= draw_bezier
;
1010 renderer_class
->fill_bezier
= fill_bezier
;
1011 renderer_class
->draw_rect
= draw_rect
;
1012 renderer_class
->fill_rect
= fill_rect
;
1013 renderer_class
->draw_polyline
= draw_polyline
;
1014 renderer_class
->draw_polygon
= draw_polygon
;
1017 ps_renderer_class
->begin_prolog
= begin_prolog
;
1018 ps_renderer_class
->dump_fonts
= dump_fonts
;
1019 ps_renderer_class
->end_prolog
= end_prolog
;