1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * diagdkrenderer.c - refactoring of the render to gdk facility
5 * Copyright (C) 2002 Hans Breuer
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 #define PANGO_ENABLE_ENGINE
30 #include <pango/pango-engine.h>
31 #include <pango/pango.h>
33 #include "diagdkrenderer.h"
34 #include "dia_image.h"
45 #include <pango/pango.h>
46 #include <pango/pangoft2.h>
49 static int get_width_pixels (DiaRenderer
*);
50 static int get_height_pixels (DiaRenderer
*);
52 static void begin_render (DiaRenderer
*);
53 static void end_render (DiaRenderer
*);
55 static void set_linewidth (DiaRenderer
*renderer
, real linewidth
);
56 static void set_linecaps (DiaRenderer
*renderer
, LineCaps mode
);
57 static void set_linejoin (DiaRenderer
*renderer
, LineJoin mode
);
58 static void set_linestyle (DiaRenderer
*renderer
, LineStyle mode
);
59 static void set_dashlength (DiaRenderer
*renderer
, real length
);
60 static void set_fillstyle (DiaRenderer
*renderer
, FillStyle mode
);
62 static void draw_line (DiaRenderer
*renderer
,
63 Point
*start
, Point
*end
,
65 static void fill_polygon (DiaRenderer
*renderer
,
66 Point
*points
, int num_points
,
68 static void draw_arc (DiaRenderer
*renderer
,
70 real width
, real height
,
71 real angle1
, real angle2
,
73 static void fill_arc (DiaRenderer
*renderer
,
75 real width
, real height
,
76 real angle1
, real angle2
,
78 static void draw_ellipse (DiaRenderer
*renderer
,
80 real width
, real height
,
82 static void fill_ellipse (DiaRenderer
*renderer
,
84 real width
, real height
,
86 static void draw_string (DiaRenderer
*renderer
,
91 static void draw_text_line (DiaRenderer
*renderer
,
95 static void draw_image (DiaRenderer
*renderer
,
97 real width
, real height
,
100 static void draw_rect (DiaRenderer
*renderer
,
101 Point
*ul_corner
, Point
*lr_corner
,
103 static void fill_rect (DiaRenderer
*renderer
,
104 Point
*ul_corner
, Point
*lr_corner
,
106 static void draw_fill_rect (DiaGdkRenderer
*renderer
,
107 Point
*ul_corner
, Point
*lr_corner
,
108 Color
*color
, gboolean fill
);
109 static void draw_polyline (DiaRenderer
*renderer
,
110 Point
*points
, int num_points
,
112 static void draw_polygon (DiaRenderer
*renderer
,
113 Point
*points
, int num_points
,
115 static void draw_object (DiaRenderer
*renderer
, DiaObject
*object
);
117 static real
get_text_width (DiaRenderer
*renderer
,
118 const gchar
*text
, int length
);
120 static void dia_gdk_renderer_class_init (DiaGdkRendererClass
*klass
);
121 static void renderer_init (DiaGdkRenderer
*renderer
, void*);
123 static gpointer parent_class
= NULL
;
125 /** Get the type object for the GdkRenderer.
126 * @return A static GType object describing GdkRenderers.
129 dia_gdk_renderer_get_type(void)
131 static GType object_type
= 0;
135 static const GTypeInfo object_info
=
137 sizeof (DiaGdkRendererClass
),
138 (GBaseInitFunc
) NULL
,
139 (GBaseFinalizeFunc
) NULL
,
140 (GClassInitFunc
) dia_gdk_renderer_class_init
,
141 NULL
, /* class_finalize */
142 NULL
, /* class_data */
143 sizeof (DiaGdkRenderer
),
145 (GInstanceInitFunc
)renderer_init
/* init */
148 object_type
= g_type_register_static (DIA_TYPE_RENDERER
,
156 /** Initialize a renderer object.
157 * @param renderer A renderer object to initialize.
158 * @param p Ignored, purpose unknown.
161 renderer_init(DiaGdkRenderer
*renderer
, void* p
)
163 renderer
->line_width
= 1;
164 renderer
->line_style
= GDK_LINE_SOLID
;
165 renderer
->cap_style
= GDK_CAP_BUTT
;
166 renderer
->join_style
= GDK_JOIN_ROUND
;
168 renderer
->saved_line_style
= LINESTYLE_SOLID
;
169 renderer
->dash_length
= 10;
170 renderer
->dot_length
= 2;
172 renderer
->highlight_color
= NULL
;
175 /** Clean up a renderer object after use.
176 * @param object Renderer object to free subobjects from.
179 renderer_finalize(GObject
*object
)
181 DiaGdkRenderer
*renderer
= DIA_GDK_RENDERER (object
);
183 if (renderer
->pixmap
!= NULL
)
184 gdk_pixmap_unref(renderer
->pixmap
);
186 if (renderer
->gc
!= NULL
)
187 gdk_gc_unref(renderer
->gc
);
189 if (renderer
->clip_region
!= NULL
)
190 gdk_region_destroy(renderer
->clip_region
);
192 if (renderer
->transform
)
193 g_object_unref (renderer
->transform
);
195 G_OBJECT_CLASS (parent_class
)->finalize (object
);
198 /** Initialize members of the renderer class object. This sets up a bunch
199 * of functions to call for various render functions.
200 * @param klass The class object to initialize.
203 dia_gdk_renderer_class_init(DiaGdkRendererClass
*klass
)
205 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
206 DiaRendererClass
*renderer_class
= DIA_RENDERER_CLASS (klass
);
208 parent_class
= g_type_class_peek_parent (klass
);
210 object_class
->finalize
= renderer_finalize
;
212 renderer_class
->get_width_pixels
= get_width_pixels
;
213 renderer_class
->get_height_pixels
= get_height_pixels
;
215 renderer_class
->begin_render
= begin_render
;
216 renderer_class
->end_render
= end_render
;
218 renderer_class
->set_linewidth
= set_linewidth
;
219 renderer_class
->set_linecaps
= set_linecaps
;
220 renderer_class
->set_linejoin
= set_linejoin
;
221 renderer_class
->set_linestyle
= set_linestyle
;
222 renderer_class
->set_dashlength
= set_dashlength
;
223 renderer_class
->set_fillstyle
= set_fillstyle
;
225 renderer_class
->draw_line
= draw_line
;
226 renderer_class
->fill_polygon
= fill_polygon
;
227 renderer_class
->draw_rect
= draw_rect
;
228 renderer_class
->fill_rect
= fill_rect
;
229 renderer_class
->draw_arc
= draw_arc
;
230 renderer_class
->fill_arc
= fill_arc
;
231 renderer_class
->draw_ellipse
= draw_ellipse
;
232 renderer_class
->fill_ellipse
= fill_ellipse
;
234 /* use <draw|fill>_bezier from DiaRenderer */
236 renderer_class
->draw_string
= draw_string
;
237 renderer_class
->draw_text_line
= draw_text_line
;
238 renderer_class
->draw_image
= draw_image
;
240 /* medium level functions */
241 renderer_class
->draw_rect
= draw_rect
;
242 renderer_class
->draw_polyline
= draw_polyline
;
243 renderer_class
->draw_polygon
= draw_polygon
;
244 renderer_class
->draw_object
= draw_object
;
246 /* Interactive functions */
247 renderer_class
->get_text_width
= get_text_width
;
250 /** Convert Dia color objects into GDK color objects.
251 * If the highlight color is set, that will be used instead. This allows
252 * rendering of an object to do highlight rendering.
253 * @param renderer The renderer to check for highlight color.
254 * @param col A color object to convert.
255 * @param gdk_col Resulting GDK convert.
258 renderer_color_convert(DiaGdkRenderer
*renderer
,
259 Color
*col
, GdkColor
*gdk_col
)
261 if (renderer
->highlight_color
!= NULL
) {
262 color_convert(renderer
->highlight_color
, gdk_col
);
264 color_convert(col
, gdk_col
);
269 begin_render (DiaRenderer
*object
)
274 end_render (DiaRenderer
*object
)
279 set_linewidth (DiaRenderer
*object
, real linewidth
)
281 DiaGdkRenderer
*renderer
= DIA_GDK_RENDERER (object
);
283 if (renderer
->highlight_color
!= NULL
) {
284 /* 6 pixels wide -> 3 pixels beyond normal obj */
285 real border
= dia_untransform_length(renderer
->transform
, 6);
290 renderer
->line_width
=
291 dia_transform_length(renderer
->transform
, linewidth
);
293 if (renderer
->line_width
<=0)
294 renderer
->line_width
= 1; /* Minimum 1 pixel. */
296 gdk_gc_set_line_attributes(renderer
->gc
,
297 renderer
->line_width
,
298 renderer
->line_style
,
300 renderer
->join_style
);
304 set_linecaps (DiaRenderer
*object
, LineCaps mode
)
306 DiaGdkRenderer
*renderer
= DIA_GDK_RENDERER (object
);
308 if (renderer
->highlight_color
!= NULL
) {
309 renderer
->cap_style
= GDK_CAP_ROUND
;
313 renderer
->cap_style
= GDK_CAP_BUTT
;
316 renderer
->cap_style
= GDK_CAP_ROUND
;
318 case LINECAPS_PROJECTING
:
319 renderer
->cap_style
= GDK_CAP_PROJECTING
;
324 gdk_gc_set_line_attributes(renderer
->gc
,
325 renderer
->line_width
,
326 renderer
->line_style
,
328 renderer
->join_style
);
332 set_linejoin (DiaRenderer
*object
, LineJoin mode
)
334 DiaGdkRenderer
*renderer
= DIA_GDK_RENDERER (object
);
336 if (renderer
->highlight_color
!= NULL
) {
337 renderer
->join_style
= GDK_JOIN_ROUND
;
341 renderer
->join_style
= GDK_JOIN_MITER
;
344 renderer
->join_style
= GDK_JOIN_ROUND
;
347 renderer
->join_style
= GDK_JOIN_BEVEL
;
350 /* invalid mode, just here to set a breakpoint */
351 renderer
->join_style
= GDK_JOIN_ROUND
;
356 gdk_gc_set_line_attributes(renderer
->gc
,
357 renderer
->line_width
,
358 renderer
->line_style
,
360 renderer
->join_style
);
363 /** Set the dashes for this renderer.
364 * offset determines where in the pattern the dashes will start.
365 * It is used by the grid in particular to make the grid dashes line up.
368 dia_gdk_renderer_set_dashes(DiaGdkRenderer
*renderer
, int offset
)
374 switch(renderer
->saved_line_style
) {
375 case LINESTYLE_SOLID
:
377 case LINESTYLE_DASHED
:
378 dash_list
[0] = renderer
->dash_length
;
379 dash_list
[1] = renderer
->dash_length
;
380 pattern_length
= renderer
->dash_length
*2;
381 gdk_gc_set_dashes(renderer
->gc
, offset
, dash_list
, 2);
383 case LINESTYLE_DASH_DOT
:
384 hole_width
= (renderer
->dash_length
- renderer
->dot_length
) / 2;
387 dash_list
[0] = renderer
->dash_length
;
388 dash_list
[1] = hole_width
;
389 dash_list
[2] = renderer
->dot_length
;
390 dash_list
[3] = hole_width
;
391 pattern_length
= renderer
->dash_length
+renderer
->dot_length
+2*hole_width
;
392 gdk_gc_set_dashes(renderer
->gc
, offset
, dash_list
, 4);
394 case LINESTYLE_DASH_DOT_DOT
:
395 hole_width
= (renderer
->dash_length
- 2*renderer
->dot_length
) / 3;
398 dash_list
[0] = renderer
->dash_length
;
399 dash_list
[1] = hole_width
;
400 dash_list
[2] = renderer
->dot_length
;
401 dash_list
[3] = hole_width
;
402 dash_list
[4] = renderer
->dot_length
;
403 dash_list
[5] = hole_width
;
404 pattern_length
= renderer
->dash_length
+2*renderer
->dot_length
+3*hole_width
;
405 gdk_gc_set_dashes(renderer
->gc
, offset
, dash_list
, 6);
407 case LINESTYLE_DOTTED
:
408 dash_list
[0] = renderer
->dot_length
;
409 dash_list
[1] = renderer
->dot_length
;
410 pattern_length
= renderer
->dot_length
;
411 gdk_gc_set_dashes(renderer
->gc
, offset
, dash_list
, 2);
418 set_linestyle (DiaRenderer
*object
, LineStyle mode
)
420 DiaGdkRenderer
*renderer
= DIA_GDK_RENDERER (object
);
422 renderer
->saved_line_style
= mode
;
424 case LINESTYLE_SOLID
:
425 renderer
->line_style
= GDK_LINE_SOLID
;
427 case LINESTYLE_DASHED
:
428 renderer
->line_style
= GDK_LINE_ON_OFF_DASH
;
429 dia_gdk_renderer_set_dashes(renderer
, 0);
431 case LINESTYLE_DASH_DOT
:
432 renderer
->line_style
= GDK_LINE_ON_OFF_DASH
;
433 dia_gdk_renderer_set_dashes(renderer
, 0);
435 case LINESTYLE_DASH_DOT_DOT
:
436 renderer
->line_style
= GDK_LINE_ON_OFF_DASH
;
437 dia_gdk_renderer_set_dashes(renderer
, 0);
439 case LINESTYLE_DOTTED
:
440 renderer
->line_style
= GDK_LINE_ON_OFF_DASH
;
441 dia_gdk_renderer_set_dashes(renderer
, 0);
444 gdk_gc_set_line_attributes(renderer
->gc
,
445 renderer
->line_width
,
446 renderer
->line_style
,
448 renderer
->join_style
);
452 set_dashlength (DiaRenderer
*object
, real length
)
454 DiaGdkRenderer
*renderer
= DIA_GDK_RENDERER (object
);
455 /* dot = 10% of len */
459 dia_transform_length(renderer
->transform
, length
);
461 renderer
->dash_length
= (int)floor(ddisp_len
+0.5);
462 renderer
->dot_length
= (int)floor(ddisp_len
*0.1+0.5);
464 if (renderer
->dash_length
<=0)
465 renderer
->dash_length
= 1;
466 if (renderer
->dash_length
>255)
467 renderer
->dash_length
= 255;
468 if (renderer
->dot_length
<=0)
469 renderer
->dot_length
= 1;
470 if (renderer
->dot_length
>255)
471 renderer
->dot_length
= 255;
472 set_linestyle(object
, renderer
->saved_line_style
);
476 set_fillstyle (DiaRenderer
*object
, FillStyle mode
)
479 case FILLSTYLE_SOLID
:
482 message_error("gdk_renderer: Unsupported fill mode specified!\n");
487 draw_line (DiaRenderer
*object
, Point
*start
, Point
*end
, Color
*line_color
)
489 DiaGdkRenderer
*renderer
= DIA_GDK_RENDERER (object
);
491 GdkGC
*gc
= renderer
->gc
;
495 dia_transform_coords(renderer
->transform
, start
->x
, start
->y
, &x1
, &y1
);
496 dia_transform_coords(renderer
->transform
, end
->x
, end
->y
, &x2
, &y2
);
498 renderer_color_convert(renderer
, line_color
, &color
);
499 gdk_gc_set_foreground(gc
, &color
);
501 gdk_draw_line(renderer
->pixmap
, gc
,
506 fill_polygon (DiaRenderer
*object
, Point
*points
, int num_points
, Color
*line_color
)
508 DiaGdkRenderer
*renderer
= DIA_GDK_RENDERER (object
);
509 GdkGC
*gc
= renderer
->gc
;
511 GdkPoint
*gdk_points
;
514 gdk_points
= g_new(GdkPoint
, num_points
);
516 for (i
=0;i
<num_points
;i
++) {
517 dia_transform_coords(renderer
->transform
, points
[i
].x
, points
[i
].y
, &x
, &y
);
522 renderer_color_convert(renderer
, line_color
, &color
);
523 gdk_gc_set_foreground(gc
, &color
);
525 gdk_draw_polygon(renderer
->pixmap
, gc
, TRUE
, gdk_points
, num_points
);
530 draw_fill_arc (DiaRenderer
*object
,
532 real width
, real height
,
533 real angle1
, real angle2
,
537 DiaGdkRenderer
*renderer
= DIA_GDK_RENDERER (object
);
538 GdkGC
*gc
= renderer
->gc
;
540 gint top
, left
, bottom
, right
;
543 dia_transform_coords(renderer
->transform
,
544 center
->x
- width
/2, center
->y
- height
/2,
546 dia_transform_coords(renderer
->transform
,
547 center
->x
+ width
/2, center
->y
+ height
/2,
550 if ((left
>right
) || (top
>bottom
))
553 renderer_color_convert(renderer
, color
, &gdkcolor
);
554 gdk_gc_set_foreground(gc
, &gdkcolor
);
556 dangle
= angle2
-angle1
;
560 gdk_draw_arc(renderer
->pixmap
,
562 left
, top
, right
-left
+(fill
?1:0), bottom
-top
+(fill
?1:0),
563 (int) (angle1
*64.0), (int) (dangle
*64.0));
566 draw_arc (DiaRenderer
*object
,
568 real width
, real height
,
569 real angle1
, real angle2
,
572 draw_fill_arc (object
, center
, width
, height
, angle1
, angle2
, color
, FALSE
);
576 fill_arc (DiaRenderer
*object
, Point
*center
,
577 real width
, real height
, real angle1
, real angle2
,
580 draw_fill_arc (object
, center
, width
, height
, angle1
, angle2
, color
, TRUE
);
584 draw_ellipse (DiaRenderer
*object
, Point
*center
,
585 real width
, real height
,
588 draw_arc(object
, center
, width
, height
, 0.0, 360.0, color
);
592 fill_ellipse (DiaRenderer
*object
, Point
*center
,
593 real width
, real height
, Color
*color
)
595 fill_arc(object
, center
, width
, height
, 0.0, 360.0, color
);
598 /* Draw a highlighted version of a string.
601 draw_highlighted_string(DiaGdkRenderer
*renderer
,
608 pango_layout_get_pixel_size(layout
, &width
, &height
);
610 gdk_gc_set_foreground(renderer
->gc
, color
);
612 gdk_draw_rectangle (renderer
->pixmap
,
619 draw_string (DiaRenderer
*object
,
620 const gchar
*text
, Point
*pos
, Alignment alignment
,
623 TextLine
*text_line
= text_line_new(text
, object
->font
, object
->font_height
);
624 Point realigned_pos
= *pos
;
625 realigned_pos
.x
-= text_line_get_alignment_adjustment(text_line
, alignment
);
626 draw_text_line(object
, text_line
, &realigned_pos
, color
);
631 initialize_ft_bitmap(FT_Bitmap
*ftbitmap
, int width
, int height
)
633 int rowstride
= 32*((width
+31)/31);
634 guint8
*graybitmap
= (guint8
*)g_new0(guint8
, height
*rowstride
);
636 ftbitmap
->rows
= height
;
637 ftbitmap
->width
= width
;
638 ftbitmap
->pitch
= rowstride
;
639 ftbitmap
->buffer
= graybitmap
;
640 ftbitmap
->num_grays
= 256;
641 ftbitmap
->pixel_mode
= ft_pixel_mode_grays
;
642 ftbitmap
->palette_mode
= 0;
643 ftbitmap
->palette
= 0;
646 typedef struct _FreetypeCacheData
{
655 free_freetype_cache_data(gpointer data
) {
656 FreetypeCacheData
*ftdata
= (FreetypeCacheData
*) data
;
658 g_object_unref(ftdata
->rgba
);
663 /** Draw a TextLine object.
664 * @param object The renderer object to use for transform and output
665 * @param text_line The TextLine to render, including font and height.
666 * @param pos The position to render it at.
667 * @param color The color to render it with.
670 draw_text_line (DiaRenderer
*object
, TextLine
*text_line
,
671 Point
*pos
, Color
*color
)
673 DiaGdkRenderer
*renderer
= DIA_GDK_RENDERER (object
);
677 PangoLayout
* layout
= NULL
;
678 const gchar
*text
= text_line_get_string(text_line
);
680 real font_height
= text_line_get_height(text_line
);
681 real scale
= dia_transform_length(renderer
->transform
, 1.0);
683 if (text
== NULL
|| *text
== '\0') return; /* Don't render empty strings. */
685 point_copy(&start_pos
,pos
);
687 renderer_color_convert(renderer
, color
, &gdkcolor
);
689 height_pixels
= dia_transform_length(renderer
->transform
, font_height
);
690 if (height_pixels
< 2) { /* "Greeking" instead of making tiny font */
691 int width_pixels
= dia_transform_length(renderer
->transform
,
692 text_line_get_width(text_line
));
693 gdk_gc_set_foreground(renderer
->gc
, &gdkcolor
);
694 gdk_gc_set_dashes(renderer
->gc
, 0, "\1\2", 2);
695 dia_transform_coords(renderer
->transform
, start_pos
.x
, start_pos
.y
, &x
, &y
);
696 gdk_draw_line(renderer
->pixmap
, renderer
->gc
, x
, y
, x
+ width_pixels
, y
);
701 adjust
= text_line_get_ascent(text_line
);
702 start_pos
.y
-= adjust
;
704 dia_transform_coords(renderer
->transform
,
705 start_pos
.x
, start_pos
.y
, &x
, &y
);
707 layout
= dia_font_build_layout(text
, text_line
->font
,
708 dia_transform_length(renderer
->transform
, text_line
->height
)/20.0);
710 text_line_adjust_layout_line(text_line
, pango_layout_get_line(layout
, 0),
712 if (renderer
->highlight_color
!= NULL
) {
713 draw_highlighted_string(renderer
, layout
, x
, y
, &gdkcolor
);
715 #if defined HAVE_FREETYPE
719 GdkPixbuf
*rgba
= NULL
;
721 width
= dia_transform_length(renderer
->transform
,
722 text_line_get_width(text_line
));
723 height
= dia_transform_length(renderer
->transform
,
724 text_line_get_height(text_line
));
731 FreetypeCacheData
*cache
;
733 initialize_ft_bitmap(&ftbitmap
, width
, height
);
734 pango_ft2_render_layout(&ftbitmap
, layout
, 0, 0);
736 graybitmap
= ftbitmap
.buffer
;
738 rgba
= gdk_pixbuf_new(GDK_COLORSPACE_RGB
, TRUE
, 8, width
, height
);
739 stride
= gdk_pixbuf_get_rowstride(rgba
);
740 pixels
= gdk_pixbuf_get_pixels(rgba
);
741 for (i
= 0; i
< height
; i
++) {
742 for (j
= 0; j
< width
; j
++) {
743 pixels
[i
*stride
+j
*4] = gdkcolor
.red
>>8;
744 pixels
[i
*stride
+j
*4+1] = gdkcolor
.green
>>8;
745 pixels
[i
*stride
+j
*4+2] = gdkcolor
.blue
>>8;
746 pixels
[i
*stride
+j
*4+3] = graybitmap
[i
*ftbitmap
.pitch
+j
];
751 gdk_draw_pixbuf(renderer
->pixmap
, renderer
->gc
, rgba
, 0, 0, x
, y
, width
, height
, GDK_RGB_DITHER_NONE
, 0, 0);
753 g_object_unref(G_OBJECT(rgba
));
757 gdk_gc_set_foreground(renderer
->gc
, &gdkcolor
);
759 gdk_draw_layout(renderer
->pixmap
, renderer
->gc
, x
, y
, layout
);
761 g_object_unref(G_OBJECT(layout
));
766 /* Get the width of the given text in cm */
768 get_text_width(DiaRenderer
*object
,
769 const gchar
*text
, int length
)
771 DiaGdkRenderer
*renderer
= DIA_GDK_RENDERER (object
);
775 if (length
!= strlen(text
)) {
778 /* A couple UTF8-chars: æblegrød Š Ť Ž ę ć ń уфхцНОПРЄ є Ґ Њ Ћ Џ */
779 ulen
= g_utf8_offset_to_pointer(text
, length
)-text
;
780 if (!g_utf8_validate(text
, ulen
, NULL
)) {
781 g_warning ("Text at char %d not valid\n", length
);
783 othertx
= g_strndup(text
, ulen
);
784 text_line
= text_line_new(othertx
, object
->font
, object
->font_height
);
786 text_line
= text_line_new(text
, object
->font
, object
->font_height
);
788 result
= text_line_get_width(text_line
);
789 text_line_destroy(text_line
);
794 draw_image (DiaRenderer
*object
,
796 real width
, real height
,
799 DiaGdkRenderer
*renderer
= DIA_GDK_RENDERER (object
);
800 if (renderer
->highlight_color
!= NULL
) {
802 DiaRendererClass
*self_class
= DIA_RENDERER_GET_CLASS (object
);
807 self_class
->fill_rect(object
, point
, &lr
, renderer
->highlight_color
);
809 int real_width
, real_height
, real_x
, real_y
;
811 real_width
= dia_transform_length(renderer
->transform
, width
);
812 real_height
= dia_transform_length(renderer
->transform
, height
);
813 dia_transform_coords(renderer
->transform
, point
->x
, point
->y
,
816 dia_image_draw(image
, renderer
->pixmap
, real_x
, real_y
,
817 real_width
, real_height
);
822 * medium level functions
825 draw_fill_rect (DiaGdkRenderer
*renderer
,
826 Point
*ul_corner
, Point
*lr_corner
,
827 Color
*color
, gboolean fill
)
829 GdkGC
*gc
= renderer
->gc
;
831 gint top
, bottom
, left
, right
;
833 dia_transform_coords(renderer
->transform
,
834 ul_corner
->x
, ul_corner
->y
, &left
, &top
);
835 dia_transform_coords(renderer
->transform
,
836 lr_corner
->x
, lr_corner
->y
, &right
, &bottom
);
838 if ((left
>right
) || (top
>bottom
))
841 renderer_color_convert(renderer
, color
, &gdkcolor
);
842 gdk_gc_set_foreground(gc
, &gdkcolor
);
844 gdk_draw_rectangle (renderer
->pixmap
,
852 draw_rect (DiaRenderer
*object
,
853 Point
*ul_corner
, Point
*lr_corner
,
856 DiaGdkRenderer
*renderer
= DIA_GDK_RENDERER (object
);
858 draw_fill_rect (renderer
, ul_corner
, lr_corner
, color
, FALSE
);
862 fill_rect (DiaRenderer
*object
,
863 Point
*ul_corner
, Point
*lr_corner
,
866 DiaGdkRenderer
*renderer
= DIA_GDK_RENDERER (object
);
868 draw_fill_rect (renderer
, ul_corner
, lr_corner
, color
, TRUE
);
872 draw_polyline (DiaRenderer
*self
,
873 Point
*points
, int num_points
,
876 DiaGdkRenderer
*renderer
= DIA_GDK_RENDERER (self
);
877 GdkGC
*gc
= renderer
->gc
;
879 GdkPoint
*gdk_points
;
882 gdk_points
= g_new(GdkPoint
, num_points
);
884 for (i
=0;i
<num_points
;i
++) {
885 dia_transform_coords(renderer
->transform
, points
[i
].x
, points
[i
].y
, &x
, &y
);
890 renderer_color_convert(renderer
, line_color
, &color
);
891 gdk_gc_set_foreground(gc
, &color
);
893 gdk_draw_lines(renderer
->pixmap
, gc
, gdk_points
, num_points
);
898 draw_polygon (DiaRenderer
*self
,
899 Point
*points
, int num_points
,
902 DiaGdkRenderer
*renderer
= DIA_GDK_RENDERER (self
);
903 GdkGC
*gc
= renderer
->gc
;
905 GdkPoint
*gdk_points
;
908 gdk_points
= g_new(GdkPoint
, num_points
);
910 for (i
=0;i
<num_points
;i
++) {
911 dia_transform_coords(renderer
->transform
, points
[i
].x
, points
[i
].y
, &x
, &y
);
916 renderer_color_convert(renderer
, line_color
, &color
);
917 gdk_gc_set_foreground(gc
, &color
);
919 gdk_draw_polygon(renderer
->pixmap
, gc
, FALSE
, gdk_points
, num_points
);
924 draw_object (DiaRenderer
*renderer
, DiaObject
*object
)
926 if (renderer
->is_interactive
&&
927 object
->highlight_color
!= NULL
) {
928 DiaGdkRenderer
*gdk_rend
= DIA_GDK_RENDERER(renderer
);
929 gdk_rend
->highlight_color
= object
->highlight_color
;
930 object
->ops
->draw(object
, renderer
);
931 gdk_rend
->highlight_color
= NULL
;
933 object
->ops
->draw(object
, renderer
);
937 get_width_pixels (DiaRenderer
*object
)
939 DiaGdkRenderer
*renderer
= DIA_GDK_RENDERER (object
);
942 if (renderer
->pixmap
)
943 gdk_drawable_get_size (GDK_DRAWABLE (renderer
->pixmap
), &width
, NULL
);
949 get_height_pixels (DiaRenderer
*object
)
951 DiaGdkRenderer
*renderer
= DIA_GDK_RENDERER (object
);
954 if (renderer
->pixmap
)
955 gdk_drawable_get_size (GDK_DRAWABLE (renderer
->pixmap
), NULL
, &height
);