pre6 commit, just a day late:)
[dia.git] / plug-ins / gprint / diagnomeprintrenderer.c
blob82a1efb847557878ecada22d895f7cfd9e90630d
1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998, 1999 Alexander Larsson
4 * render_gnomeprint.[ch] -- gnome-print renderer for dia
5 * Copyright (C) 1999 James Henstridge
7 * diagnomeprintrenderer.[ch] - resurrection as plug-in and porting to
8 * DiaRenderer interface
9 * Copyright (C) 2004 Hans Breuer
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 #include <config.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <math.h>
32 #define G_LOG_DOMAIN "DiaGnomePrint"
33 #include <glib.h>
35 #include "intl.h"
36 #include "message.h"
37 #include "diagramdata.h"
38 #include "dia_image.h"
40 #ifndef P_
41 /* FIXME: how ? */
42 #define P_(s) s
43 #endif
45 #include "diagnomeprintrenderer.h"
46 #include <libgnomeprint/gnome-print-pango.h>
48 /* FIXME: I don't get it ;) */
49 static const real magic = 72.0 / 2.54;
51 /* DiaRenderer implementation */
52 static void
53 begin_render(DiaRenderer *self)
55 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
57 renderer->font = dia_font_new ("sans", 0, 0.8);
60 static void
61 end_render(DiaRenderer *self)
63 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
65 if (renderer->font)
66 g_object_unref(G_OBJECT(renderer->font));
67 renderer->font = NULL;
70 static void
71 set_linewidth(DiaRenderer *self, real linewidth)
73 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
75 /* 0 == hairline **/
76 gnome_print_setlinewidth(renderer->ctx, linewidth);
79 static void
80 set_linecaps(DiaRenderer *self, LineCaps mode)
82 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
83 int ps_mode;
85 switch(mode) {
86 case LINECAPS_BUTT:
87 ps_mode = 0;
88 break;
89 case LINECAPS_ROUND:
90 ps_mode = 1;
91 break;
92 case LINECAPS_PROJECTING:
93 ps_mode = 2;
94 break;
95 default:
96 ps_mode = 0;
99 gnome_print_setlinecap(renderer->ctx, ps_mode);
102 static void
103 set_linejoin(DiaRenderer *self, LineJoin mode)
105 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
106 int ps_mode;
108 switch(mode) {
109 case LINEJOIN_MITER:
110 ps_mode = 0;
111 break;
112 case LINEJOIN_ROUND:
113 ps_mode = 1;
114 break;
115 case LINEJOIN_BEVEL:
116 ps_mode = 2;
117 break;
118 default:
119 ps_mode = 0;
122 gnome_print_setlinejoin(renderer->ctx, ps_mode);
125 static void
126 set_linestyle(DiaRenderer *self, LineStyle mode)
128 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
129 real hole_width;
130 double dashes[6];
132 renderer->saved_line_style = mode;
134 switch(mode) {
135 case LINESTYLE_SOLID:
136 gnome_print_setdash(renderer->ctx, 0, dashes, 0);
137 break;
138 case LINESTYLE_DASHED:
139 dashes[0] = renderer->dash_length;
140 gnome_print_setdash(renderer->ctx, 1, dashes, 0);
141 break;
142 case LINESTYLE_DASH_DOT:
143 hole_width = (renderer->dash_length - renderer->dot_length) / 2.0;
144 dashes[0] = renderer->dash_length;
145 dashes[1] = hole_width;
146 dashes[2] = renderer->dot_length;
147 dashes[3] = hole_width;
148 gnome_print_setdash(renderer->ctx, 4, dashes, 0);
149 break;
150 case LINESTYLE_DASH_DOT_DOT:
151 hole_width = (renderer->dash_length - 2.0*renderer->dot_length) / 3.0;
152 dashes[0] = renderer->dash_length;
153 dashes[1] = hole_width;
154 dashes[2] = renderer->dot_length;
155 dashes[3] = hole_width;
156 dashes[4] = renderer->dot_length;
157 dashes[5] = hole_width;
158 gnome_print_setdash(renderer->ctx, 6, dashes, 0);
159 break;
160 case LINESTYLE_DOTTED:
161 dashes[0] = renderer->dot_length;
162 gnome_print_setdash(renderer->ctx, 1, dashes, 0);
163 break;
167 static void
168 set_dashlength(DiaRenderer *self, real length)
170 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
172 /* dot = 20% of len */
173 if (length<0.001)
174 length = 0.001;
176 renderer->dash_length = magic * length;
177 renderer->dot_length = magic * length*0.2;
179 set_linestyle(self, renderer->saved_line_style);
182 static void
183 set_fillstyle(DiaRenderer *self, FillStyle mode)
185 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
187 switch(mode) {
188 case FILLSTYLE_SOLID:
189 break;
190 default:
191 message_error("%s\nUnsupported fill mode specified!\n",
192 G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS(renderer)));
196 static void
197 set_font(DiaRenderer *self, DiaFont *font, real height)
199 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
201 if (renderer->font)
202 g_object_unref(G_OBJECT(renderer->font));
203 renderer->font = dia_font_copy (font);
204 dia_font_set_height (renderer->font, height);
207 static void
208 draw_line(DiaRenderer *self,
209 Point *start, Point *end,
210 Color *line_color)
212 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
214 gnome_print_setrgbcolor(renderer->ctx,
215 (double) line_color->red,
216 (double) line_color->green,
217 (double) line_color->blue);
219 gnome_print_newpath(renderer->ctx);
220 gnome_print_moveto(renderer->ctx, start->x, start->y);
221 gnome_print_lineto(renderer->ctx, end->x, end->y);
222 gnome_print_stroke(renderer->ctx);
225 static void
226 draw_polyline(DiaRenderer *self,
227 Point *points, int num_points,
228 Color *line_color)
230 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
231 int i;
233 gnome_print_setrgbcolor(renderer->ctx,
234 (double) line_color->red,
235 (double) line_color->green,
236 (double) line_color->blue);
238 gnome_print_newpath(renderer->ctx);
239 gnome_print_moveto(renderer->ctx, points[0].x, points[0].y);
241 for (i=1;i<num_points;i++) {
242 gnome_print_lineto(renderer->ctx, points[i].x, points[i].y);
245 gnome_print_stroke(renderer->ctx);
248 static void
249 draw_polygon(DiaRenderer *self,
250 Point *points, int num_points,
251 Color *line_color)
253 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
254 int i;
256 gnome_print_setrgbcolor(renderer->ctx,
257 (double) line_color->red,
258 (double) line_color->green,
259 (double) line_color->blue);
261 gnome_print_newpath(renderer->ctx);
262 gnome_print_moveto(renderer->ctx, points[0].x, points[0].y);
264 for (i=1;i<num_points;i++) {
265 gnome_print_lineto(renderer->ctx, points[i].x, points[i].y);
268 gnome_print_closepath(renderer->ctx);
269 gnome_print_stroke(renderer->ctx);
272 static void
273 fill_polygon(DiaRenderer *self,
274 Point *points, int num_points,
275 Color *line_color)
277 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
278 int i;
280 gnome_print_setrgbcolor(renderer->ctx,
281 (double) line_color->red,
282 (double) line_color->green,
283 (double) line_color->blue);
285 gnome_print_newpath(renderer->ctx);
286 gnome_print_moveto(renderer->ctx, points[0].x, points[0].y);
288 for (i=1;i<num_points;i++) {
289 gnome_print_lineto(renderer->ctx, points[i].x, points[i].y);
292 gnome_print_fill(renderer->ctx);
295 static void
296 draw_rect(DiaRenderer *self,
297 Point *ul_corner, Point *lr_corner,
298 Color *color)
300 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
302 gnome_print_setrgbcolor(renderer->ctx, (double)color->red,
303 (double)color->green, (double)color->blue);
305 gnome_print_newpath(renderer->ctx);
306 gnome_print_moveto(renderer->ctx, ul_corner->x, ul_corner->y);
307 gnome_print_lineto(renderer->ctx, ul_corner->x, lr_corner->y);
308 gnome_print_lineto(renderer->ctx, lr_corner->x, lr_corner->y);
309 gnome_print_lineto(renderer->ctx, lr_corner->x, ul_corner->y);
310 gnome_print_closepath(renderer->ctx);
311 gnome_print_stroke(renderer->ctx);
314 static void
315 fill_rect(DiaRenderer *self,
316 Point *ul_corner, Point *lr_corner,
317 Color *color)
319 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
321 gnome_print_setrgbcolor(renderer->ctx, (double)color->red,
322 (double)color->green, (double)color->blue);
324 gnome_print_newpath(renderer->ctx);
325 gnome_print_moveto(renderer->ctx, ul_corner->x, ul_corner->y);
326 gnome_print_lineto(renderer->ctx, ul_corner->x, lr_corner->y);
327 gnome_print_lineto(renderer->ctx, lr_corner->x, lr_corner->y);
328 gnome_print_lineto(renderer->ctx, lr_corner->x, ul_corner->y);
329 gnome_print_fill(renderer->ctx);
332 #define SEG_ANGLE (M_PI/4.0)
334 static void
335 draw_arc(DiaRenderer *self,
336 Point *center,
337 real width, real height,
338 real angle1, real angle2,
339 Color *color)
341 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
342 real arcangle;
343 int nsegs, i;
344 real theta, theta_2, sin_theta_2, cos_theta_2, x1, y1, rangle1, rangle2;
345 real w_2 = width/2, h_2 = height/2;
347 if (angle2 < angle1) angle2 += 360;
348 rangle1 = (360 - angle2) * M_PI / 180.0;
349 rangle2 = (360 - angle1) * M_PI / 180.0;
350 arcangle = rangle2 - rangle1;
351 nsegs = (int)ceil(arcangle / SEG_ANGLE); /* how many bezier segments? */
352 theta = arcangle / nsegs;
353 theta_2 = theta / 2;
354 sin_theta_2 = sin(theta_2);
355 cos_theta_2 = cos(theta_2);
356 x1 = (4 - cos_theta_2)/3; /* coordinates of control point */
357 y1 = (1 - cos_theta_2)*(cos_theta_2 - 3)/(3*sin_theta_2);
359 gnome_print_setrgbcolor(renderer->ctx, (double)color->red,
360 (double)color->green, (double)color->blue);
362 gnome_print_newpath(renderer->ctx);
363 gnome_print_moveto(renderer->ctx, center->x + w_2 * cos(rangle1),
364 center->y + h_2 * sin(rangle1));
365 for (i = 0; i < nsegs; i++) {
366 real phi = arcangle * i / nsegs + theta_2 + rangle1;
367 real sin_phi = sin(phi), cos_phi = cos(phi);
369 gnome_print_curveto(renderer->ctx,
370 w_2*(cos_phi*x1 - sin_phi*y1) + center->x,
371 h_2*(sin_phi*x1 + cos_phi*y1) + center->y,
372 w_2*(cos_phi*x1 + sin_phi*y1) + center->x,
373 h_2*(sin_phi*x1 - cos_phi*y1) + center->y,
374 w_2*(cos_phi*cos_theta_2 - sin_phi*sin_theta_2) + center->x,
375 h_2*(sin_phi*cos_theta_2 + cos_phi*sin_theta_2) + center->y);
377 gnome_print_stroke(renderer->ctx);
380 static void
381 fill_arc(DiaRenderer *self,
382 Point *center,
383 real width, real height,
384 real angle1, real angle2,
385 Color *color)
387 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
388 real arcangle;
389 int nsegs, i;
390 real theta, theta_2, sin_theta_2, cos_theta_2, x1, y1, rangle1, rangle2;
391 real w_2 = width/2, h_2 = height/2;
393 if (angle2 < angle1) angle2 += 360;
394 rangle1 = (360 - angle2) * M_PI / 180.0;
395 rangle2 = (360 - angle1) * M_PI / 180.0;
396 arcangle = rangle2 - rangle1;
397 nsegs = (int)ceil(arcangle / SEG_ANGLE); /* how many bezier segments? */
398 theta = arcangle / nsegs;
399 theta_2 = theta / 2;
400 sin_theta_2 = sin(theta_2);
401 cos_theta_2 = cos(theta_2);
402 x1 = (4 - cos_theta_2)/3; /* coordinates of control point */
403 y1 = (1 - cos_theta_2)*(cos_theta_2 - 3)/(3*sin_theta_2);
405 gnome_print_newpath(renderer->ctx);
406 gnome_print_moveto(renderer->ctx, center->x, center->y);
407 gnome_print_lineto(renderer->ctx, center->x + w_2 * cos(rangle1),
408 center->y + h_2 * sin(rangle1));
409 for (i = 0; i < nsegs; i++) {
410 real phi = arcangle * i / nsegs + theta_2 + rangle1;
411 real sin_phi = sin(phi), cos_phi = cos(phi);
413 gnome_print_curveto(renderer->ctx,
414 w_2*(cos_phi*x1 - sin_phi*y1) + center->x,
415 h_2*(sin_phi*x1 + cos_phi*y1) + center->y,
416 w_2*(cos_phi*x1 + sin_phi*y1) + center->x,
417 h_2*(sin_phi*x1 - cos_phi*y1) + center->y,
418 w_2*(cos_phi*cos_theta_2 - sin_phi*sin_theta_2) + center->x,
419 h_2*(sin_phi*cos_theta_2 + cos_phi*sin_theta_2) + center->y);
421 gnome_print_fill(renderer->ctx);
424 /* This constant is equal to sqrt(2)/3*(8*cos(pi/8) - 4 - 1/sqrt(2)) - 1.
425 * Its use should be quite obvious.
427 #define ELLIPSE_CTRL1 0.26521648984
428 /* this constant is equal to 1/sqrt(2)*(1-ELLIPSE_CTRL1).
429 * Its use should also be quite obvious.
431 #define ELLIPSE_CTRL2 0.519570402739
432 #define ELLIPSE_CTRL3 M_SQRT1_2
433 /* this constant is equal to 1/sqrt(2)*(1+ELLIPSE_CTRL1).
434 * Its use should also be quite obvious.
436 #define ELLIPSE_CTRL4 0.894643159635
438 static void
439 draw_ellipse(DiaRenderer *self,
440 Point *center,
441 real width, real height,
442 Color *color)
444 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
445 real x1 = center->x - width/2, x2 = center->x + width/2;
446 real y1 = center->y - height/2, y2 = center->y + height/2;
447 real cw1 = ELLIPSE_CTRL1 * width / 2, cw2 = ELLIPSE_CTRL2 * width / 2;
448 real cw3 = ELLIPSE_CTRL3 * width / 2, cw4 = ELLIPSE_CTRL4 * width / 2;
449 real ch1 = ELLIPSE_CTRL1 * height / 2, ch2 = ELLIPSE_CTRL2 * height / 2;
450 real ch3 = ELLIPSE_CTRL3 * height / 2, ch4 = ELLIPSE_CTRL4 * height / 2;
452 gnome_print_setrgbcolor(renderer->ctx, (double)color->red,
453 (double)color->green, (double)color->blue);
455 gnome_print_newpath(renderer->ctx);
456 gnome_print_moveto(renderer->ctx, x1, center->y);
457 gnome_print_curveto(renderer->ctx,
458 x1, center->y - ch1,
459 center->x - cw4, center->y - ch2,
460 center->x - cw3, center->y - ch3);
461 gnome_print_curveto(renderer->ctx,
462 center->x - cw2, center->y - ch4,
463 center->x - cw1, y1,
464 center->x, y1);
465 gnome_print_curveto(renderer->ctx,
466 center->x + cw1, y1,
467 center->x + cw2, center->y - ch4,
468 center->x + cw3, center->y - ch3);
469 gnome_print_curveto(renderer->ctx,
470 center->x + cw4, center->y - ch2,
471 x2, center->y - ch1,
472 x2, center->y);
473 gnome_print_curveto(renderer->ctx,
474 x2, center->y + ch1,
475 center->x + cw4, center->y + ch2,
476 center->x + cw3, center->y + ch3);
477 gnome_print_curveto(renderer->ctx,
478 center->x + cw2, center->y + ch4,
479 center->x + cw1, y2,
480 center->x, y2);
481 gnome_print_curveto(renderer->ctx,
482 center->x - cw1, y2,
483 center->x - cw2, center->y + ch4,
484 center->x - cw3, center->y + ch3);
485 gnome_print_curveto(renderer->ctx,
486 center->x - cw4, center->y + ch2,
487 x1, center->y + ch1,
488 x1, center->y);
489 gnome_print_closepath(renderer->ctx);
490 gnome_print_stroke(renderer->ctx);
493 static void
494 fill_ellipse(DiaRenderer *self,
495 Point *center,
496 real width, real height,
497 Color *color)
499 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
500 real x1 = center->x - width/2, x2 = center->x + width/2;
501 real y1 = center->y - height/2, y2 = center->y + height/2;
502 real cw1 = ELLIPSE_CTRL1 * width / 2, cw2 = ELLIPSE_CTRL2 * width / 2;
503 real cw3 = ELLIPSE_CTRL3 * width / 2, cw4 = ELLIPSE_CTRL4 * width / 2;
504 real ch1 = ELLIPSE_CTRL1 * height / 2, ch2 = ELLIPSE_CTRL2 * height / 2;
505 real ch3 = ELLIPSE_CTRL3 * height / 2, ch4 = ELLIPSE_CTRL4 * height / 2;
507 gnome_print_setrgbcolor(renderer->ctx, (double)color->red,
508 (double)color->green, (double)color->blue);
510 gnome_print_newpath(renderer->ctx);
511 gnome_print_moveto(renderer->ctx, x1, center->y);
512 gnome_print_curveto(renderer->ctx,
513 x1, center->y - ch1,
514 center->x - cw4, center->y - ch2,
515 center->x - cw3, center->y - ch3);
516 gnome_print_curveto(renderer->ctx,
517 center->x - cw2, center->y - ch4,
518 center->x - cw1, y1,
519 center->x, y1);
520 gnome_print_curveto(renderer->ctx,
521 center->x + cw1, y1,
522 center->x + cw2, center->y - ch4,
523 center->x + cw3, center->y - ch3);
524 gnome_print_curveto(renderer->ctx,
525 center->x + cw4, center->y - ch2,
526 x2, center->y - ch1,
527 x2, center->y);
528 gnome_print_curveto(renderer->ctx,
529 x2, center->y + ch1,
530 center->x + cw4, center->y + ch2,
531 center->x + cw3, center->y + ch3);
532 gnome_print_curveto(renderer->ctx,
533 center->x + cw2, center->y + ch4,
534 center->x + cw1, y2,
535 center->x, y2);
536 gnome_print_curveto(renderer->ctx,
537 center->x - cw1, y2,
538 center->x - cw2, center->y + ch4,
539 center->x - cw3, center->y + ch3);
540 gnome_print_curveto(renderer->ctx,
541 center->x - cw4, center->y + ch2,
542 x1, center->y + ch1,
543 x1, center->y);
544 gnome_print_fill(renderer->ctx);
547 static void
548 draw_bezier(DiaRenderer *self,
549 BezPoint *points,
550 int numpoints, /* numpoints = 4+3*n, n=>0 */
551 Color *color)
553 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
554 int i;
556 gnome_print_setrgbcolor(renderer->ctx, (double)color->red,
557 (double)color->green, (double)color->blue);
559 if (points[0].type != BEZ_MOVE_TO)
560 g_warning("first BezPoint must be a BEZ_MOVE_TO");
562 gnome_print_newpath(renderer->ctx);
563 gnome_print_moveto(renderer->ctx, points[0].p1.x, points[0].p1.y);
565 for (i = 1; i < numpoints; i++)
566 switch (points[i].type) {
567 case BEZ_MOVE_TO:
568 g_warning("only first BezPoint can be a BEZ_MOVE_TO");
569 break;
570 case BEZ_LINE_TO:
571 gnome_print_lineto(renderer->ctx, points[i].p1.x, points[i].p1.y);
572 break;
573 case BEZ_CURVE_TO:
574 gnome_print_curveto(renderer->ctx,
575 points[i].p1.x, points[i].p1.y,
576 points[i].p2.x, points[i].p2.y,
577 points[i].p3.x, points[i].p3.y);
578 break;
581 gnome_print_stroke(renderer->ctx);
584 static void
585 fill_bezier(DiaRenderer *self,
586 BezPoint *points, /* Last point must be same as first point */
587 int numpoints,
588 Color *color)
590 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
591 int i;
593 gnome_print_setrgbcolor(renderer->ctx, (double)color->red,
594 (double)color->green, (double)color->blue);
596 if (points[0].type != BEZ_MOVE_TO)
597 g_warning("first BezPoint must be a BEZ_MOVE_TO");
599 gnome_print_newpath(renderer->ctx);
600 gnome_print_moveto(renderer->ctx, points[0].p1.x, points[0].p1.y);
602 for (i = 1; i < numpoints; i++)
603 switch (points[i].type) {
604 case BEZ_MOVE_TO:
605 g_warning("only first BezPoint can be a BEZ_MOVE_TO");
606 break;
607 case BEZ_LINE_TO:
608 gnome_print_lineto(renderer->ctx, points[i].p1.x, points[i].p1.y);
609 break;
610 case BEZ_CURVE_TO:
611 gnome_print_curveto(renderer->ctx,
612 points[i].p1.x, points[i].p1.y,
613 points[i].p2.x, points[i].p2.y,
614 points[i].p3.x, points[i].p3.y);
615 break;
618 gnome_print_fill(renderer->ctx);
621 static void
622 draw_string(DiaRenderer *self,
623 const gchar *text,
624 Point *pos, Alignment alignment,
625 Color *color)
627 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
628 PangoLayout *layout;
629 int pango_width, pango_height;
630 PangoAttrList *list;
631 PangoAttribute *attr;
632 int len;
633 real width, height;
635 if (!text || strlen(text) < 1)
636 return;
638 len = strlen(text);
639 layout = gnome_print_pango_create_layout (renderer->ctx);
640 pango_layout_set_text (layout, text, len);
642 list = pango_attr_list_new ();
643 attr = pango_attr_font_desc_new (dia_font_get_description(renderer->font));
644 attr->start_index = 0;
645 attr->end_index = len;
646 pango_attr_list_insert (list, attr); /* eats attr */
647 pango_layout_set_attributes (layout, list);
648 pango_attr_list_unref (list);
650 pango_layout_set_indent (layout, 0);
651 pango_layout_set_justify (layout, FALSE);
652 pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
654 pango_layout_get_size (layout, &pango_width, &pango_height);
656 gnome_print_setrgbcolor(renderer->ctx, (double)color->red,
657 (double)color->green, (double)color->blue);
659 width = ((double) pango_width / PANGO_SCALE) / magic;
660 height = ((double) pango_height / PANGO_SCALE) / magic;
662 switch (alignment) {
663 case ALIGN_LEFT:
664 gnome_print_moveto(renderer->ctx, pos->x, pos->y - height);
665 break;
666 case ALIGN_CENTER:
667 gnome_print_moveto(renderer->ctx, pos->x - width / 2, pos->y - height);
668 break;
669 case ALIGN_RIGHT:
670 gnome_print_moveto(renderer->ctx, pos->x - width, pos->y - height);
671 break;
675 gnome_print_gsave(renderer->ctx);
676 gnome_print_scale(renderer->ctx, 1/magic, -1/magic);
678 gnome_print_pango_layout (renderer->ctx, layout);
679 g_object_unref (layout);
681 gnome_print_grestore(renderer->ctx);
684 static void
685 draw_image(DiaRenderer *self,
686 Point *point,
687 real width, real height,
688 DiaImage image)
690 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (self);
691 int w = dia_image_width(image);
692 int h = dia_image_height(image);
693 int rs = dia_image_rowstride(image);
695 gnome_print_gsave(renderer->ctx);
697 /* into unit square (0,0 - 1,1) in current coordinate system. */
698 gnome_print_translate(renderer->ctx, point->x, point->y + height);
699 gnome_print_scale(renderer->ctx, width, -height);
700 if (dia_image_rgba_data (image))
701 gnome_print_rgbaimage(renderer->ctx, dia_image_rgba_data (image), w, h, rs);
702 else
703 gnome_print_rgbimage(renderer->ctx, dia_image_rgb_data (image), w, h, rs);
704 gnome_print_grestore(renderer->ctx);
707 /* 'advanced' gobject stuff */
708 /* allow to get and set properties */
709 enum {
710 PROP_0,
711 PROP_CONFIG,
712 PROP_CONTEXT
715 static void
716 renderer_set_property (GObject *object,
717 guint prop_id,
718 const GValue *value,
719 GParamSpec *pspec)
721 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (object);
723 switch (prop_id)
725 case PROP_CONFIG:
726 renderer->config = g_value_get_object (value);
727 break;
728 case PROP_CONTEXT:
729 renderer->ctx = g_value_get_object (value);
730 break;
731 default:
732 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
733 break;
737 static void
738 renderer_get_property (GObject *object,
739 guint prop_id,
740 GValue *value,
741 GParamSpec *pspec)
743 DiaGnomePrintRenderer *renderer = DIA_GNOME_PRINT_RENDERER (object);
745 switch (prop_id)
747 case PROP_CONFIG:
748 g_value_set_object (value, renderer->config);
749 break;
750 case PROP_CONTEXT:
751 g_value_set_object (value, renderer->ctx);
752 break;
753 default:
754 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
755 break;
759 /* common gobject stuff */
760 static void dia_gnome_print_renderer_init (DiaGnomePrintRenderer *renderer, void *p);
761 static void dia_gnome_print_renderer_class_init (DiaGnomePrintRendererClass *klass);
763 static gpointer parent_class = NULL;
765 GType
766 dia_gnome_print_renderer_get_type (void)
768 static GType object_type = 0;
770 if (!object_type)
772 static const GTypeInfo object_info =
774 sizeof (DiaGnomePrintRendererClass),
775 (GBaseInitFunc) NULL,
776 (GBaseFinalizeFunc) NULL,
777 (GClassInitFunc) dia_gnome_print_renderer_class_init,
778 NULL, /* class_finalize */
779 NULL, /* class_data */
780 sizeof (DiaGnomePrintRenderer),
781 0, /* n_preallocs */
782 (GInstanceInitFunc)dia_gnome_print_renderer_init /* init */
785 object_type = g_type_register_static (DIA_TYPE_RENDERER,
786 "DiaGnomePrintRenderer",
787 &object_info, 0);
790 return object_type;
793 static void
794 dia_gnome_print_renderer_init (DiaGnomePrintRenderer *renderer, void *p)
796 renderer->ctx = NULL;
797 renderer->font = NULL;
799 renderer->dash_length = 1.0;
800 renderer->dot_length = 0.2;
801 renderer->saved_line_style = LINESTYLE_SOLID;
804 static void
805 dia_gnome_print_renderer_finalize (GObject *object)
807 G_OBJECT_CLASS (parent_class)->finalize (object);
810 static void
811 dia_gnome_print_renderer_class_init (DiaGnomePrintRendererClass *klass)
813 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
814 DiaRendererClass *renderer_class = DIA_RENDERER_CLASS (klass);
816 parent_class = g_type_class_peek_parent (klass);
818 gobject_class->finalize = dia_gnome_print_renderer_finalize;
819 gobject_class->set_property = renderer_set_property;
820 gobject_class->get_property = renderer_get_property;
822 /* install properties */
823 g_object_class_install_property (gobject_class,
824 PROP_CONFIG,
825 g_param_spec_object ("config",
826 P_("GNOME Print config to be used"),
827 P_("FIXME: not sure if this makes any sense"),
828 GNOME_TYPE_PRINT_CONFIG,
829 G_PARAM_READABLE | G_PARAM_WRITABLE));
830 g_object_class_install_property (gobject_class,
831 PROP_CONTEXT,
832 g_param_spec_object ("context",
833 P_("GNOME Print contex to be used"),
834 P_("The context does determine the output file format"),
835 GNOME_TYPE_PRINT_CONTEXT,
836 G_PARAM_READABLE | G_PARAM_WRITABLE));
839 /* renderer members */
840 renderer_class->begin_render = begin_render;
841 renderer_class->end_render = end_render;
843 renderer_class->set_linewidth = set_linewidth;
844 renderer_class->set_linecaps = set_linecaps;
845 renderer_class->set_linejoin = set_linejoin;
846 renderer_class->set_linestyle = set_linestyle;
847 renderer_class->set_dashlength = set_dashlength;
848 renderer_class->set_fillstyle = set_fillstyle;
850 renderer_class->set_font = set_font;
852 renderer_class->draw_line = draw_line;
853 renderer_class->fill_polygon = fill_polygon;
854 renderer_class->draw_rect = draw_rect;
855 renderer_class->fill_rect = fill_rect;
856 renderer_class->draw_arc = draw_arc;
857 renderer_class->fill_arc = fill_arc;
858 renderer_class->draw_ellipse = draw_ellipse;
859 renderer_class->fill_ellipse = fill_ellipse;
861 renderer_class->draw_string = draw_string;
862 renderer_class->draw_image = draw_image;
864 /* medium level functions */
865 renderer_class->draw_rect = draw_rect;
866 renderer_class->draw_polyline = draw_polyline;
867 renderer_class->draw_polygon = draw_polygon;
869 renderer_class->draw_bezier = draw_bezier;
870 renderer_class->fill_bezier = fill_bezier;
872 /* highest level functions */
873 #if 0 /* maybe these should be implemented by pathes, but why not in diarenderer.c ? */
874 renderer_class->draw_rounded_rect = draw_rounded_rect;
875 renderer_class->fill_rounded_rect = fill_rounded_rect;
876 #endif