1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include "render_gdk.h"
25 static void begin_render(RendererGdk
*renderer
, DiagramData
*data
);
26 static void end_render(RendererGdk
*renderer
);
27 static void set_linewidth(RendererGdk
*renderer
, real linewidth
);
28 static void set_linecaps(RendererGdk
*renderer
, LineCaps mode
);
29 static void set_linejoin(RendererGdk
*renderer
, LineJoin mode
);
30 static void set_linestyle(RendererGdk
*renderer
, LineStyle mode
);
31 static void set_dashlength(RendererGdk
*renderer
, real length
);
32 static void set_fillstyle(RendererGdk
*renderer
, FillStyle mode
);
33 static void set_font(RendererGdk
*renderer
, Font
*font
, real height
);
34 static void draw_line(RendererGdk
*renderer
,
35 Point
*start
, Point
*end
,
37 static void draw_polyline(RendererGdk
*renderer
,
38 Point
*points
, int num_points
,
40 static void draw_polygon(RendererGdk
*renderer
,
41 Point
*points
, int num_points
,
43 static void fill_polygon(RendererGdk
*renderer
,
44 Point
*points
, int num_points
,
46 static void draw_rect(RendererGdk
*renderer
,
47 Point
*ul_corner
, Point
*lr_corner
,
49 static void fill_rect(RendererGdk
*renderer
,
50 Point
*ul_corner
, Point
*lr_corner
,
52 static void draw_arc(RendererGdk
*renderer
,
54 real width
, real height
,
55 real angle1
, real angle2
,
57 static void fill_arc(RendererGdk
*renderer
,
59 real width
, real height
,
60 real angle1
, real angle2
,
62 static void draw_ellipse(RendererGdk
*renderer
,
64 real width
, real height
,
66 static void fill_ellipse(RendererGdk
*renderer
,
68 real width
, real height
,
70 static void draw_bezier(RendererGdk
*renderer
,
74 static void fill_bezier(RendererGdk
*renderer
,
75 BezPoint
*points
, /* Last point must be same as first point */
78 static void draw_string(RendererGdk
*renderer
,
80 Point
*pos
, Alignment alignment
,
82 static void draw_image(RendererGdk
*renderer
,
84 real width
, real height
,
87 static real
get_text_width(RendererGdk
*renderer
,
88 const char *text
, int length
);
90 static void clip_region_clear(RendererGdk
*renderer
);
91 static void clip_region_add_rect(RendererGdk
*renderer
,
94 static void draw_pixel_line(RendererGdk
*renderer
,
98 static void draw_pixel_rect(RendererGdk
*renderer
,
100 int width
, int height
,
102 static void fill_pixel_rect(RendererGdk
*renderer
,
104 int width
, int height
,
107 static RenderOps GdkRenderOps
= {
108 (BeginRenderFunc
) begin_render
,
109 (EndRenderFunc
) end_render
,
111 (SetLineWidthFunc
) set_linewidth
,
112 (SetLineCapsFunc
) set_linecaps
,
113 (SetLineJoinFunc
) set_linejoin
,
114 (SetLineStyleFunc
) set_linestyle
,
115 (SetDashLengthFunc
) set_dashlength
,
116 (SetFillStyleFunc
) set_fillstyle
,
117 (SetFontFunc
) set_font
,
119 (DrawLineFunc
) draw_line
,
120 (DrawPolyLineFunc
) draw_polyline
,
122 (DrawPolygonFunc
) draw_polygon
,
123 (FillPolygonFunc
) fill_polygon
,
125 (DrawRectangleFunc
) draw_rect
,
126 (FillRectangleFunc
) fill_rect
,
128 (DrawArcFunc
) draw_arc
,
129 (FillArcFunc
) fill_arc
,
131 (DrawEllipseFunc
) draw_ellipse
,
132 (FillEllipseFunc
) fill_ellipse
,
134 (DrawBezierFunc
) draw_bezier
,
135 (FillBezierFunc
) fill_bezier
,
137 (DrawStringFunc
) draw_string
,
139 (DrawImageFunc
) draw_image
,
142 static InteractiveRenderOps GdkInteractiveRenderOps
= {
143 (GetTextWidthFunc
) get_text_width
,
145 (ClipRegionClearFunc
) clip_region_clear
,
146 (ClipRegionAddRectangleFunc
) clip_region_add_rect
,
148 (DrawPixelLineFunc
) draw_pixel_line
,
149 (DrawPixelRectangleFunc
) draw_pixel_rect
,
150 (FillPixelRectangleFunc
) fill_pixel_rect
,
154 new_gdk_renderer(DDisplay
*ddisp
)
156 RendererGdk
*renderer
;
158 renderer
= g_new(RendererGdk
, 1);
159 renderer
->renderer
.ops
= &GdkRenderOps
;
160 renderer
->renderer
.is_interactive
= 1;
161 renderer
->renderer
.interactive_ops
= &GdkInteractiveRenderOps
;
162 renderer
->ddisp
= ddisp
;
163 renderer
->render_gc
= NULL
;
165 renderer
->pixmap
= NULL
;
166 renderer
->renderer
.pixel_width
= 0;
167 renderer
->renderer
.pixel_height
= 0;
168 renderer
->clip_region
= NULL
;
170 renderer
->line_width
= 1;
171 renderer
->line_style
= GDK_LINE_SOLID
;
172 renderer
->cap_style
= GDK_CAP_BUTT
;
173 renderer
->join_style
= GDK_JOIN_MITER
;
175 renderer
->saved_line_style
= LINESTYLE_SOLID
;
176 renderer
->dash_length
= 10;
177 renderer
->dot_length
= 2;
183 destroy_gdk_renderer(RendererGdk
*renderer
)
185 if (renderer
->pixmap
!= NULL
)
186 gdk_pixmap_unref(renderer
->pixmap
);
188 if (renderer
->render_gc
!= NULL
)
189 gdk_gc_unref(renderer
->render_gc
);
191 if (renderer
->clip_region
!= NULL
)
192 gdk_region_destroy(renderer
->clip_region
);
198 gdk_renderer_set_size(RendererGdk
*renderer
, GdkWindow
*window
,
199 int width
, int height
)
202 if (renderer
->pixmap
!= NULL
) {
203 gdk_pixmap_unref(renderer
->pixmap
);
206 renderer
->pixmap
= gdk_pixmap_new(window
, width
, height
, -1);
207 renderer
->renderer
.pixel_width
= width
;
208 renderer
->renderer
.pixel_height
= height
;
210 if (renderer
->render_gc
== NULL
) {
211 renderer
->render_gc
= gdk_gc_new(renderer
->pixmap
);
213 gdk_gc_set_line_attributes(renderer
->render_gc
,
214 renderer
->line_width
,
215 renderer
->line_style
,
217 renderer
->join_style
);
222 renderer_gdk_copy_to_window(RendererGdk
*renderer
, GdkWindow
*window
,
223 int x
, int y
, int width
, int height
)
225 static GdkGC
*copy_gc
= NULL
;
227 if (copy_gc
== NULL
) {
228 copy_gc
= gdk_gc_new(window
);
231 gdk_draw_pixmap(window
,
240 begin_render(RendererGdk
*renderer
, DiagramData
*data
)
245 end_render(RendererGdk
*renderer
)
252 set_linewidth(RendererGdk
*renderer
, real linewidth
)
253 { /* 0 == hairline **/
254 renderer
->line_width
=
255 ddisplay_transform_length(renderer
->ddisp
, linewidth
);
257 if (renderer
->line_width
<=0)
258 renderer
->line_width
= 1; /* Minimum 1 pixel. */
260 gdk_gc_set_line_attributes(renderer
->render_gc
,
261 renderer
->line_width
,
262 renderer
->line_style
,
264 renderer
->join_style
);
268 set_linecaps(RendererGdk
*renderer
, LineCaps mode
)
272 renderer
->cap_style
= GDK_CAP_BUTT
;
275 renderer
->cap_style
= GDK_CAP_ROUND
;
277 case LINECAPS_PROJECTING
:
278 renderer
->cap_style
= GDK_CAP_PROJECTING
;
282 gdk_gc_set_line_attributes(renderer
->render_gc
,
283 renderer
->line_width
,
284 renderer
->line_style
,
286 renderer
->join_style
);
290 set_linejoin(RendererGdk
*renderer
, LineJoin mode
)
294 renderer
->cap_style
= GDK_JOIN_MITER
;
297 renderer
->cap_style
= GDK_JOIN_ROUND
;
300 renderer
->cap_style
= GDK_JOIN_BEVEL
;
304 gdk_gc_set_line_attributes(renderer
->render_gc
,
305 renderer
->line_width
,
306 renderer
->line_style
,
308 renderer
->join_style
);
312 set_linestyle(RendererGdk
*renderer
, LineStyle mode
)
317 renderer
->saved_line_style
= mode
;
319 case LINESTYLE_SOLID
:
320 renderer
->line_style
= GDK_LINE_SOLID
;
322 case LINESTYLE_DASHED
:
323 renderer
->line_style
= GDK_LINE_ON_OFF_DASH
;
324 dash_list
[0] = renderer
->dash_length
;
325 dash_list
[1] = renderer
->dash_length
;
326 gdk_gc_set_dashes(renderer
->render_gc
, 0, dash_list
, 2);
328 case LINESTYLE_DASH_DOT
:
329 renderer
->line_style
= GDK_LINE_ON_OFF_DASH
;
330 hole_width
= (renderer
->dash_length
- renderer
->dot_length
) / 2;
333 dash_list
[0] = renderer
->dash_length
;
334 dash_list
[1] = hole_width
;
335 dash_list
[2] = renderer
->dot_length
;
336 dash_list
[3] = hole_width
;
337 gdk_gc_set_dashes(renderer
->render_gc
, 0, dash_list
, 4);
339 case LINESTYLE_DASH_DOT_DOT
:
340 renderer
->line_style
= GDK_LINE_ON_OFF_DASH
;
341 hole_width
= (renderer
->dash_length
- 2*renderer
->dot_length
) / 3;
344 dash_list
[0] = renderer
->dash_length
;
345 dash_list
[1] = hole_width
;
346 dash_list
[2] = renderer
->dot_length
;
347 dash_list
[3] = hole_width
;
348 dash_list
[4] = renderer
->dot_length
;
349 dash_list
[5] = hole_width
;
350 gdk_gc_set_dashes(renderer
->render_gc
, 0, dash_list
, 6);
352 case LINESTYLE_DOTTED
:
353 renderer
->line_style
= GDK_LINE_ON_OFF_DASH
;
354 dash_list
[0] = renderer
->dot_length
;
355 dash_list
[1] = renderer
->dot_length
;
356 gdk_gc_set_dashes(renderer
->render_gc
, 0, dash_list
, 2);
359 gdk_gc_set_line_attributes(renderer
->render_gc
,
360 renderer
->line_width
,
361 renderer
->line_style
,
363 renderer
->join_style
);
367 set_dashlength(RendererGdk
*renderer
, real length
)
368 { /* dot = 10% of len */
372 ddisplay_transform_length(renderer
->ddisp
, length
);
374 renderer
->dash_length
= (int)floor(ddisp_len
+0.5);
375 renderer
->dot_length
= (int)floor(ddisp_len
*0.1+0.5);
377 if (renderer
->dash_length
<=0)
378 renderer
->dash_length
= 1;
379 if (renderer
->dash_length
>255)
380 renderer
->dash_length
= 255;
381 if (renderer
->dot_length
<=0)
382 renderer
->dot_length
= 1;
383 if (renderer
->dot_length
>255)
384 renderer
->dot_length
= 255;
385 set_linestyle(renderer
, renderer
->saved_line_style
);
389 set_fillstyle(RendererGdk
*renderer
, FillStyle mode
)
392 case FILLSTYLE_SOLID
:
395 message_error("gdk_renderer: Unsupported fill mode specified!\n");
400 set_font(RendererGdk
*renderer
, Font
*font
, real height
)
402 renderer
->font_height
=
403 ddisplay_transform_length(renderer
->ddisp
, height
);
405 renderer
->gdk_font
= font_get_gdkfont(font
, renderer
->font_height
);
409 draw_line(RendererGdk
*renderer
,
410 Point
*start
, Point
*end
,
413 DDisplay
*ddisp
= renderer
->ddisp
;
414 GdkGC
*gc
= renderer
->render_gc
;
418 ddisplay_transform_coords(ddisp
, start
->x
, start
->y
, &x1
, &y1
);
419 ddisplay_transform_coords(ddisp
, end
->x
, end
->y
, &x2
, &y2
);
421 color_convert(line_color
, &color
);
422 gdk_gc_set_foreground(gc
, &color
);
424 gdk_draw_line(renderer
->pixmap
, gc
,
429 draw_polyline(RendererGdk
*renderer
,
430 Point
*points
, int num_points
,
433 DDisplay
*ddisp
= renderer
->ddisp
;
434 GdkGC
*gc
= renderer
->render_gc
;
436 GdkPoint
*gdk_points
;
439 gdk_points
= g_new(GdkPoint
, num_points
);
441 for (i
=0;i
<num_points
;i
++) {
442 ddisplay_transform_coords(ddisp
, points
[i
].x
, points
[i
].y
, &x
, &y
);
447 color_convert(line_color
, &color
);
448 gdk_gc_set_foreground(gc
, &color
);
450 gdk_draw_lines(renderer
->pixmap
, gc
, gdk_points
, num_points
);
455 draw_polygon(RendererGdk
*renderer
,
456 Point
*points
, int num_points
,
459 DDisplay
*ddisp
= renderer
->ddisp
;
460 GdkGC
*gc
= renderer
->render_gc
;
462 GdkPoint
*gdk_points
;
465 gdk_points
= g_new(GdkPoint
, num_points
);
467 for (i
=0;i
<num_points
;i
++) {
468 ddisplay_transform_coords(ddisp
, points
[i
].x
, points
[i
].y
, &x
, &y
);
473 color_convert(line_color
, &color
);
474 gdk_gc_set_foreground(gc
, &color
);
476 gdk_draw_polygon(renderer
->pixmap
, gc
, FALSE
, gdk_points
, num_points
);
481 fill_polygon(RendererGdk
*renderer
,
482 Point
*points
, int num_points
,
485 DDisplay
*ddisp
= renderer
->ddisp
;
486 GdkGC
*gc
= renderer
->render_gc
;
488 GdkPoint
*gdk_points
;
491 gdk_points
= g_new(GdkPoint
, num_points
);
493 for (i
=0;i
<num_points
;i
++) {
494 ddisplay_transform_coords(ddisp
, points
[i
].x
, points
[i
].y
, &x
, &y
);
499 color_convert(line_color
, &color
);
500 gdk_gc_set_foreground(gc
, &color
);
502 gdk_draw_polygon(renderer
->pixmap
, gc
, TRUE
, gdk_points
, num_points
);
507 draw_rect(RendererGdk
*renderer
,
508 Point
*ul_corner
, Point
*lr_corner
,
511 DDisplay
*ddisp
= renderer
->ddisp
;
512 GdkGC
*gc
= renderer
->render_gc
;
514 gint top
, bottom
, left
, right
;
516 ddisplay_transform_coords(ddisp
, ul_corner
->x
, ul_corner
->y
,
518 ddisplay_transform_coords(ddisp
, lr_corner
->x
, lr_corner
->y
,
521 if ((left
>right
) || (top
>bottom
))
524 color_convert(color
, &gdkcolor
);
525 gdk_gc_set_foreground(gc
, &gdkcolor
);
527 gdk_draw_rectangle (renderer
->pixmap
,
535 fill_rect(RendererGdk
*renderer
,
536 Point
*ul_corner
, Point
*lr_corner
,
539 DDisplay
*ddisp
= renderer
->ddisp
;
540 GdkGC
*gc
= renderer
->render_gc
;
542 gint top
, bottom
, left
, right
;
544 ddisplay_transform_coords(ddisp
, ul_corner
->x
, ul_corner
->y
,
546 ddisplay_transform_coords(ddisp
, lr_corner
->x
, lr_corner
->y
,
549 if ((left
>right
) || (top
>bottom
))
552 color_convert(color
, &gdkcolor
);
553 gdk_gc_set_foreground(gc
, &gdkcolor
);
555 gdk_draw_rectangle (renderer
->pixmap
,
563 draw_arc(RendererGdk
*renderer
,
565 real width
, real height
,
566 real angle1
, real angle2
,
569 DDisplay
*ddisp
= renderer
->ddisp
;
570 GdkGC
*gc
= renderer
->render_gc
;
572 gint top
, left
, bottom
, right
;
575 ddisplay_transform_coords(ddisp
,
576 center
->x
- width
/2, center
->y
- height
/2,
578 ddisplay_transform_coords(ddisp
,
579 center
->x
+ width
/2, center
->y
+ height
/2,
582 if ((left
>right
) || (top
>bottom
))
585 color_convert(color
, &gdkcolor
);
586 gdk_gc_set_foreground(gc
, &gdkcolor
);
588 dangle
= angle2
-angle1
;
592 gdk_draw_arc(renderer
->pixmap
,
594 left
, top
, right
-left
, bottom
-top
,
595 (int) (angle1
*64.0), (int) (dangle
*64.0));
599 fill_arc(RendererGdk
*renderer
,
601 real width
, real height
,
602 real angle1
, real angle2
,
605 DDisplay
*ddisp
= renderer
->ddisp
;
606 GdkGC
*gc
= renderer
->render_gc
;
608 gint top
, left
, bottom
, right
;
611 ddisplay_transform_coords(ddisp
,
612 center
->x
- width
/2, center
->y
- height
/2,
614 ddisplay_transform_coords(ddisp
,
615 center
->x
+ width
/2, center
->y
+ height
/2,
618 if ((left
>right
) || (top
>bottom
))
621 color_convert(color
, &gdkcolor
);
622 gdk_gc_set_foreground(gc
, &gdkcolor
);
624 dangle
= angle2
-angle1
;
628 gdk_draw_arc(renderer
->pixmap
,
630 left
, top
, right
-left
, bottom
-top
,
631 (int) (angle1
*64), (int) (dangle
*64));
635 draw_ellipse(RendererGdk
*renderer
,
637 real width
, real height
,
640 draw_arc(renderer
, center
, width
, height
, 0.0, 360.0, color
);
644 fill_ellipse(RendererGdk
*renderer
,
646 real width
, real height
,
649 fill_arc(renderer
, center
, width
, height
, 0.0, 360.0, color
);
652 struct bezier_curve
{
653 GdkPoint
*gdk_points
;
658 #define BEZIER_SUBDIVIDE_LIMIT 0.03
659 #define BEZIER_SUBDIVIDE_LIMIT_SQ (BEZIER_SUBDIVIDE_LIMIT*BEZIER_SUBDIVIDE_LIMIT)
662 bezier_add_point(DDisplay
*ddisp
,
663 struct bezier_curve
*bezier
,
668 /* Grow if needed: */
669 if (bezier
->currpoint
== bezier
->numpoints
) {
670 bezier
->numpoints
+= 40;
671 bezier
->gdk_points
= g_realloc(bezier
->gdk_points
,
672 bezier
->numpoints
*sizeof(GdkPoint
));
675 ddisplay_transform_coords(ddisp
, point
->x
, point
->y
, &x
, &y
);
677 bezier
->gdk_points
[bezier
->currpoint
].x
= x
;
678 bezier
->gdk_points
[bezier
->currpoint
].y
= y
;
684 bezier_add_lines(DDisplay
*ddisp
,
686 struct bezier_curve
*bezier
)
695 /* Check if almost flat: */
697 point_sub(&u
, &points
[0]);
699 point_sub(&v
, &points
[0]);
701 v_len_sq
= point_dot(&v
,&v
);
702 if (isnan(v_len_sq
)) {
703 g_warning("v_len_sq is NaN while calculating bezier curve!");
706 if (v_len_sq
< 0.000001)
708 point_scale(&y
, point_dot(&u
,&v
)/v_len_sq
);
711 delta
= ddisplay_transform_length(ddisp
, point_dot(&x
,&x
));
712 if (delta
< BEZIER_SUBDIVIDE_LIMIT_SQ
) {
714 point_sub(&u
, &points
[3]);
716 point_sub(&v
, &points
[3]);
718 v_len_sq
= point_dot(&v
,&v
);
719 if (v_len_sq
< 0.000001)
721 point_scale(&y
, point_dot(&u
,&v
)/v_len_sq
);
724 delta
= ddisplay_transform_length(ddisp
, point_dot(&x
,&x
));
725 if (delta
< BEZIER_SUBDIVIDE_LIMIT_SQ
) { /* Almost flat, draw a line */
726 bezier_add_point(ddisp
, bezier
, &points
[3]);
730 /* Subdivide into two bezier curves: */
733 point_add(&middle
, &points
[2]);
734 point_scale(&middle
, 0.5);
739 point_add(&r
[1], &points
[1]);
740 point_scale(&r
[1], 0.5);
743 point_add(&r
[2], &middle
);
744 point_scale(&r
[2], 0.5);
749 point_add(&s
[2], &points
[3]);
750 point_scale(&s
[2], 0.5);
753 point_add(&s
[1], &middle
);
754 point_scale(&s
[1], 0.5);
757 point_add(&r
[3], &s
[1]);
758 point_scale(&r
[3], 0.5);
762 bezier_add_lines(ddisp
, r
, bezier
);
763 bezier_add_lines(ddisp
, s
, bezier
);
767 bezier_add_curve(DDisplay
*ddisp
,
769 struct bezier_curve
*bezier
)
771 /* Is the bezier curve malformed? */
772 if ( (distance_point_point(&points
[0], &points
[1]) < 0.00001) &&
773 (distance_point_point(&points
[2], &points
[3]) < 0.00001) &&
774 (distance_point_point(&points
[0], &points
[3]) < 0.00001)) {
775 bezier_add_point(ddisp
, bezier
, &points
[3]);
778 bezier_add_lines(ddisp
, points
, bezier
);
782 static struct bezier_curve bezier
= { NULL
, 0, 0 };
785 draw_bezier(RendererGdk
*renderer
,
790 DDisplay
*ddisp
= renderer
->ddisp
;
791 GdkGC
*gc
= renderer
->render_gc
;
796 if (bezier
.gdk_points
== NULL
) {
797 bezier
.numpoints
= 30;
798 bezier
.gdk_points
= g_malloc(bezier
.numpoints
*sizeof(GdkPoint
));
801 bezier
.currpoint
= 0;
803 if (points
[0].type
!= BEZ_MOVE_TO
)
804 g_warning("first BezPoint must be a BEZ_MOVE_TO");
805 curve
[3] = points
[0].p1
;
806 bezier_add_point(renderer
->ddisp
, &bezier
, &points
[0].p1
);
807 for (i
= 1; i
< numpoints
; i
++)
808 switch (points
[i
].type
) {
810 g_warning("only first BezPoint can be a BEZ_MOVE_TO");
811 curve
[3] = points
[i
].p1
;
814 bezier_add_point(renderer
->ddisp
, &bezier
, &points
[i
].p1
);
815 curve
[3] = points
[i
].p1
;
819 curve
[1] = points
[i
].p1
;
820 curve
[2] = points
[i
].p2
;
821 curve
[3] = points
[i
].p3
;
822 bezier_add_curve(ddisp
, curve
, &bezier
);
826 color_convert(color
, &gdk_color
);
827 gdk_gc_set_foreground(gc
, &gdk_color
);
829 gdk_gc_set_line_attributes(renderer
->render_gc
,
830 renderer
->line_width
,
831 renderer
->line_style
,
835 gdk_draw_lines(renderer
->pixmap
, gc
, bezier
.gdk_points
, bezier
.currpoint
);
837 gdk_gc_set_line_attributes(renderer
->render_gc
,
838 renderer
->line_width
,
839 renderer
->line_style
,
841 renderer
->join_style
);
845 fill_bezier(RendererGdk
*renderer
,
846 BezPoint
*points
, /* Last point must be same as first point */
847 int numpoints
, /* numpoints = 4+3*n, n=>0 */
850 DDisplay
*ddisp
= renderer
->ddisp
;
851 GdkGC
*gc
= renderer
->render_gc
;
856 if (bezier
.gdk_points
== NULL
) {
857 bezier
.numpoints
= 30;
858 bezier
.gdk_points
= g_malloc(bezier
.numpoints
*sizeof(GdkPoint
));
861 bezier
.currpoint
= 0;
863 if (points
[0].type
!= BEZ_MOVE_TO
)
864 g_warning("first BezPoint must be a BEZ_MOVE_TO");
865 curve
[3] = points
[0].p1
;
866 bezier_add_point(renderer
->ddisp
, &bezier
, &points
[0].p1
);
867 for (i
= 1; i
< numpoints
; i
++)
868 switch (points
[i
].type
) {
870 g_warning("only first BezPoint can be a BEZ_MOVE_TO");
871 curve
[3] = points
[i
].p1
;
874 bezier_add_point(renderer
->ddisp
, &bezier
, &points
[i
].p1
);
875 curve
[3] = points
[i
].p1
;
879 curve
[1] = points
[i
].p1
;
880 curve
[2] = points
[i
].p2
;
881 curve
[3] = points
[i
].p3
;
882 bezier_add_curve(ddisp
, curve
, &bezier
);
886 color_convert(color
, &gdk_color
);
887 gdk_gc_set_foreground(gc
, &gdk_color
);
889 gdk_draw_polygon(renderer
->pixmap
, gc
, TRUE
,
890 bezier
.gdk_points
, bezier
.currpoint
);
894 draw_string(RendererGdk
*renderer
,
896 Point
*pos
, Alignment alignment
,
899 DDisplay
*ddisp
= renderer
->ddisp
;
900 GdkGC
*gc
= renderer
->render_gc
;
905 ddisplay_transform_coords(ddisp
, pos
->x
, pos
->y
,
908 iwidth
= gdk_string_width(renderer
->gdk_font
, text
);
921 color_convert(color
, &gdkcolor
);
922 gdk_gc_set_foreground(gc
, &gdkcolor
);
924 gdk_draw_string(renderer
->pixmap
,
925 renderer
->gdk_font
, gc
,
930 draw_image(RendererGdk
*renderer
,
932 real width
, real height
,
935 int real_width
, real_height
, real_x
, real_y
;
937 real_width
= ddisplay_transform_length(renderer
->ddisp
, width
);
938 real_height
= ddisplay_transform_length(renderer
->ddisp
, height
);
939 ddisplay_transform_coords(renderer
->ddisp
, point
->x
, point
->y
,
942 dia_image_draw(image
, renderer
->pixmap
, real_x
, real_y
,
943 real_width
, real_height
);
947 get_text_width(RendererGdk
*renderer
,
948 const char *text
, int length
)
952 iwidth
= gdk_text_width(renderer
->gdk_font
, text
, length
);
954 return ddisplay_untransform_length(renderer
->ddisp
, (real
) iwidth
);
959 clip_region_clear(RendererGdk
*renderer
)
961 if (renderer
->clip_region
!= NULL
)
962 gdk_region_destroy(renderer
->clip_region
);
964 renderer
->clip_region
= gdk_region_new();
966 gdk_gc_set_clip_region(renderer
->render_gc
, renderer
->clip_region
);
970 clip_region_add_rect(RendererGdk
*renderer
,
973 DDisplay
*ddisp
= renderer
->ddisp
;
975 GdkRectangle clip_rect
;
979 ddisplay_transform_coords(ddisp
, rect
->left
, rect
->top
, &x1
, &y1
);
980 ddisplay_transform_coords(ddisp
, rect
->right
, rect
->bottom
, &x2
, &y2
);
984 clip_rect
.width
= x2
- x1
+ 1;
985 clip_rect
.height
= y2
- y1
+ 1;
987 old_reg
= renderer
->clip_region
;
989 renderer
->clip_region
=
990 gdk_region_union_with_rect( renderer
->clip_region
, &clip_rect
);
992 gdk_region_destroy(old_reg
);
994 gdk_gc_set_clip_region(renderer
->render_gc
, renderer
->clip_region
);
998 draw_pixel_line(RendererGdk
*renderer
,
1003 GdkGC
*gc
= renderer
->render_gc
;
1006 color_convert(color
, &gdkcolor
);
1007 gdk_gc_set_foreground(gc
, &gdkcolor
);
1009 gdk_draw_line(renderer
->pixmap
, gc
, x1
, y1
, x2
, y2
);
1013 draw_pixel_rect(RendererGdk
*renderer
,
1015 int width
, int height
,
1018 GdkGC
*gc
= renderer
->render_gc
;
1021 color_convert(color
, &gdkcolor
);
1022 gdk_gc_set_foreground(gc
, &gdkcolor
);
1024 gdk_draw_rectangle (renderer
->pixmap
, gc
, FALSE
,
1025 x
, y
, width
, height
);
1029 fill_pixel_rect(RendererGdk
*renderer
,
1031 int width
, int height
,
1034 GdkGC
*gc
= renderer
->render_gc
;
1037 color_convert(color
, &gdkcolor
);
1038 gdk_gc_set_foreground(gc
, &gdkcolor
);
1040 gdk_draw_rectangle (renderer
->pixmap
, gc
, TRUE
,
1041 x
, y
, width
, height
);