static void set_linestyle (DiaRenderer *object, LineStyle mode) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); renderer->saved_line_style = mode; switch(mode) { case LINESTYLE_SOLID: renderer->line_style = GDK_LINE_SOLID; break; case LINESTYLE_DASHED: renderer->line_style = GDK_LINE_ON_OFF_DASH; dia_gdk_renderer_set_dashes(renderer, 0); break; case LINESTYLE_DASH_DOT: renderer->line_style = GDK_LINE_ON_OFF_DASH; dia_gdk_renderer_set_dashes(renderer, 0); break; case LINESTYLE_DASH_DOT_DOT: renderer->line_style = GDK_LINE_ON_OFF_DASH; dia_gdk_renderer_set_dashes(renderer, 0); break; case LINESTYLE_DOTTED: renderer->line_style = GDK_LINE_ON_OFF_DASH; dia_gdk_renderer_set_dashes(renderer, 0); break; } gdk_gc_set_line_attributes(renderer->gc, renderer->line_width, renderer->line_style, renderer->cap_style, renderer->join_style); }
static void draw_polygon (DiaRenderer *object, Point *points, int num_points, Color *fill, Color *stroke) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); GdkGC *gc = renderer->gc; GdkColor color; GdkPoint *gdk_points; int i,x,y; gdk_points = g_new(GdkPoint, num_points); for (i=0;i<num_points;i++) { dia_transform_coords(renderer->transform, points[i].x, points[i].y, &x, &y); gdk_points[i].x = x; gdk_points[i].y = y; } if (fill && fill->alpha > 0.0) { renderer_color_convert(renderer, fill, &color); gdk_gc_set_foreground(gc, &color); gdk_draw_polygon(renderer->pixmap, gc, TRUE, gdk_points, num_points); } if (stroke && stroke->alpha > 0.0) { renderer_color_convert(renderer, stroke, &color); gdk_gc_set_foreground(gc, &color); gdk_draw_polygon(renderer->pixmap, gc, FALSE, gdk_points, num_points); } g_free(gdk_points); }
static void set_linecaps (DiaRenderer *object, LineCaps mode) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); if (renderer->highlight_color != NULL) { renderer->cap_style = GDK_CAP_ROUND; } else { switch(mode) { case LINECAPS_DEFAULT: case LINECAPS_BUTT: renderer->cap_style = GDK_CAP_BUTT; break; case LINECAPS_ROUND: renderer->cap_style = GDK_CAP_ROUND; break; case LINECAPS_PROJECTING: renderer->cap_style = GDK_CAP_PROJECTING; break; } } gdk_gc_set_line_attributes(renderer->gc, renderer->line_width, renderer->line_style, renderer->cap_style, renderer->join_style); }
static void draw_object_highlighted (DiaRenderer *renderer, DiaObject *object, DiaHighlightType type) { DiaGdkRenderer *gdk_rend = DIA_GDK_RENDERER(renderer); Color *color = NULL; switch (type) { case DIA_HIGHLIGHT_CONNECTIONPOINT: color = &cp_color; break; case DIA_HIGHLIGHT_CONNECTIONPOINT_MAIN: color = &cp_main_color; break; case DIA_HIGHLIGHT_TEXT_EDIT: color = &text_edit_color; break; case DIA_HIGHLIGHT_NONE: color = NULL; break; } if( color ) { gdk_rend->highlight_color = color; object->ops->draw(object, renderer); gdk_rend->highlight_color = NULL; } object->ops->draw(object, renderer); }
static void fill_pixel_rect(DiaRenderer *object, int x, int y, int width, int height, Color *color) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); GdkGC *gc = renderer->gc; GdkColor gdkcolor; int target_width, target_height; gdk_drawable_get_size (GDK_DRAWABLE (renderer->pixmap), &target_width, &target_height); if (x + width < 0 || y + height < 0 || x > target_width || y > target_height) return; /* clip early rather than failing in Gdk */ color_convert(color, &gdkcolor); gdk_gc_set_foreground(gc, &gdkcolor); /* reset stippling (alpha emulation) */ gdk_gc_set_fill(gc, GDK_SOLID); renderer->current_alpha = 1.0; gdk_draw_rectangle (renderer->pixmap, gc, TRUE, x, y, width, height); }
static void draw_pixel_line(DiaRenderer *object, int x1, int y1, int x2, int y2, Color *color) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); GdkGC *gc = renderer->gc; GdkColor gdkcolor; int target_width, target_height; dia_gdk_renderer_set_dashes(renderer, x1+y1); gdk_drawable_get_size (GDK_DRAWABLE (renderer->pixmap), &target_width, &target_height); if ( (x1 < 0 && x2 < 0) || (y1 < 0 && y2 < 0) || (x1 > target_width && x2 > target_width) || (y1 > target_height && y2 > target_height)) return; /* clip early rather than failing in Gdk */ color_convert(color, &gdkcolor); gdk_gc_set_foreground(gc, &gdkcolor); /* reset stippling (alpha emulation) */ gdk_gc_set_fill(gc, GDK_SOLID); renderer->current_alpha = 1.0; gdk_draw_line(renderer->pixmap, gc, x1, y1, x2, y2); }
static void set_linejoin (DiaRenderer *object, LineJoin mode) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); if (renderer->highlight_color != NULL) { renderer->join_style = GDK_JOIN_ROUND; } else { switch(mode) { case LINEJOIN_DEFAULT: case LINEJOIN_MITER: renderer->join_style = GDK_JOIN_MITER; break; case LINEJOIN_ROUND: renderer->join_style = GDK_JOIN_ROUND; break; case LINEJOIN_BEVEL: renderer->join_style = GDK_JOIN_BEVEL; break; default : /* invalid mode, just here to set a breakpoint */ renderer->join_style = GDK_JOIN_ROUND; break; } } gdk_gc_set_line_attributes(renderer->gc, renderer->line_width, renderer->line_style, renderer->cap_style, renderer->join_style); }
static void clip_region_clear(DiaRenderer *object) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); if (renderer->clip_region != NULL) gdk_region_destroy(renderer->clip_region); renderer->clip_region = gdk_region_new(); gdk_gc_set_clip_region(renderer->gc, renderer->clip_region); }
static void dia_gdk_interactive_renderer_init(DiaGdkInteractiveRenderer *object) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER(object); DiaRenderer *dia_renderer = DIA_RENDERER(object); dia_renderer->is_interactive = 1; renderer->gc = NULL; renderer->pixmap = NULL; renderer->clip_region = NULL; }
static void set_linestyle (DiaRenderer *object, LineStyle mode, real length) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); /* dot = 10% of len */ real ddisp_len; ddisp_len = dia_transform_length(renderer->transform, length); renderer->dash_length = (int)floor(ddisp_len+0.5); renderer->dot_length = (int)floor(ddisp_len*0.1+0.5); if (renderer->dash_length<=0) renderer->dash_length = 1; if (renderer->dash_length>255) renderer->dash_length = 255; if (renderer->dot_length<=0) renderer->dot_length = 1; if (renderer->dot_length>255) renderer->dot_length = 255; renderer->saved_line_style = mode; switch(mode) { case LINESTYLE_DEFAULT: case LINESTYLE_SOLID: renderer->line_style = GDK_LINE_SOLID; break; case LINESTYLE_DASHED: renderer->line_style = GDK_LINE_ON_OFF_DASH; dia_gdk_renderer_set_dashes(renderer, 0); break; case LINESTYLE_DASH_DOT: renderer->line_style = GDK_LINE_ON_OFF_DASH; dia_gdk_renderer_set_dashes(renderer, 0); break; case LINESTYLE_DASH_DOT_DOT: renderer->line_style = GDK_LINE_ON_OFF_DASH; dia_gdk_renderer_set_dashes(renderer, 0); break; case LINESTYLE_DOTTED: renderer->line_style = GDK_LINE_ON_OFF_DASH; dia_gdk_renderer_set_dashes(renderer, 0); break; } gdk_gc_set_line_attributes(renderer->gc, renderer->line_width, renderer->line_style, renderer->cap_style, renderer->join_style); }
static void copy_to_window (DiaRenderer *object, gpointer window, int x, int y, int width, int height) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); static GdkGC *copy_gc = NULL; if (!copy_gc) copy_gc = gdk_gc_new(window); gdk_draw_drawable (GDK_WINDOW(window), copy_gc, renderer->pixmap, x, y, x, y, width, height); }
static void draw_fill_arc (DiaRenderer *object, Point *center, real width, real height, real angle1, real angle2, Color *color, gboolean fill) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); GdkGC *gc = renderer->gc; GdkColor gdkcolor; gint top, left, bottom, right; real dangle; gboolean counter_clockwise = angle2 > angle1; if (color->alpha == 0.0) return; dia_transform_coords(renderer->transform, center->x - width/2, center->y - height/2, &left, &top); dia_transform_coords(renderer->transform, center->x + width/2, center->y + height/2, &right, &bottom); if ((left>right) || (top>bottom)) return; renderer_color_convert(renderer, color, &gdkcolor); gdk_gc_set_foreground(gc, &gdkcolor); /* GDK wants it always counter-clockwise */ if (counter_clockwise) dangle = angle2-angle1; else dangle = angle1-angle2; if (dangle<0) dangle += 360.0; gdk_draw_arc(renderer->pixmap, gc, fill, left, top, right-left, bottom-top, (int) (counter_clockwise ? angle1 : angle2) * 64.0, (int) (dangle * 64.0)); }
static void draw_line (DiaRenderer *object, Point *start, Point *end, Color *line_color) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); GdkGC *gc = renderer->gc; GdkColor color; int x1,y1,x2,y2; dia_transform_coords(renderer->transform, start->x, start->y, &x1, &y1); dia_transform_coords(renderer->transform, end->x, end->y, &x2, &y2); renderer_color_convert(renderer, line_color, &color); gdk_gc_set_foreground(gc, &color); gdk_draw_line(renderer->pixmap, gc, x1, y1, x2, y2); }
/** Clean up a renderer object after use. * @param object Renderer object to free subobjects from. */ static void renderer_finalize(GObject *object) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); if (renderer->pixmap != NULL) g_object_unref(renderer->pixmap); if (renderer->gc != NULL) g_object_unref(renderer->gc); if (renderer->clip_region != NULL) gdk_region_destroy(renderer->clip_region); if (renderer->transform) g_object_unref (renderer->transform); G_OBJECT_CLASS (parent_class)->finalize (object); }
static void clip_region_add_rect(DiaRenderer *object, Rectangle *rect) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); GdkRectangle clip_rect; int x1,y1; int x2,y2; dia_transform_coords(renderer->transform, rect->left, rect->top, &x1, &y1); dia_transform_coords(renderer->transform, rect->right, rect->bottom, &x2, &y2); clip_rect.x = x1; clip_rect.y = y1; clip_rect.width = x2 - x1 + 1; clip_rect.height = y2 - y1 + 1; gdk_region_union_with_rect( renderer->clip_region, &clip_rect ); gdk_gc_set_clip_region(renderer->gc, renderer->clip_region); }
static void fill_polygon (DiaRenderer *object, Point *points, int num_points, Color *line_color) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); GdkGC *gc = renderer->gc; GdkColor color; GdkPoint *gdk_points; int i,x,y; gdk_points = g_new(GdkPoint, num_points); for (i=0;i<num_points;i++) { dia_transform_coords(renderer->transform, points[i].x, points[i].y, &x, &y); gdk_points[i].x = x; gdk_points[i].y = y; } renderer_color_convert(renderer, line_color, &color); gdk_gc_set_foreground(gc, &color); gdk_draw_polygon(renderer->pixmap, gc, TRUE, gdk_points, num_points); g_free(gdk_points); }
static void set_dashlength (DiaRenderer *object, real length) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); /* dot = 10% of len */ real ddisp_len; ddisp_len = dia_transform_length(renderer->transform, length); renderer->dash_length = (int)floor(ddisp_len+0.5); renderer->dot_length = (int)floor(ddisp_len*0.1+0.5); if (renderer->dash_length<=0) renderer->dash_length = 1; if (renderer->dash_length>255) renderer->dash_length = 255; if (renderer->dot_length<=0) renderer->dot_length = 1; if (renderer->dot_length>255) renderer->dot_length = 255; set_linestyle(object, renderer->saved_line_style); }
static void set_size(DiaRenderer *object, gpointer window, int width, int height) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); if (renderer->pixmap != NULL) g_object_unref(renderer->pixmap); if (window) renderer->pixmap = gdk_pixmap_new(GDK_WINDOW(window), width, height, -1); else /* the integrated UI insist to call us too early */ renderer->pixmap = gdk_pixmap_new(NULL, width, height, 24); if (renderer->gc == NULL) { renderer->gc = gdk_gc_new(renderer->pixmap); gdk_gc_set_line_attributes(renderer->gc, renderer->line_width, renderer->line_style, renderer->cap_style, renderer->join_style); } }
static void set_linewidth (DiaRenderer *object, real linewidth) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); if (renderer->highlight_color != NULL) { /* 6 pixels wide -> 3 pixels beyond normal obj */ real border = dia_untransform_length(renderer->transform, 6); linewidth += border; } /* 0 == hairline **/ renderer->line_width = dia_transform_length(renderer->transform, linewidth); if (renderer->line_width<=0) renderer->line_width = 1; /* Minimum 1 pixel. */ gdk_gc_set_line_attributes(renderer->gc, renderer->line_width, renderer->line_style, renderer->cap_style, renderer->join_style); }
static void draw_pixel_rect(DiaRenderer *object, int x, int y, int width, int height, Color *color) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); GdkGC *gc = renderer->gc; GdkColor gdkcolor; int target_width, target_height; dia_gdk_renderer_set_dashes(renderer, x+y); gdk_drawable_get_size (GDK_DRAWABLE (renderer->pixmap), &target_width, &target_height); if (x + width < 0 || y + height < 0 || x > target_width || y > target_height) return; /* clip early rather than failing in Gdk */ color_convert(color, &gdkcolor); gdk_gc_set_foreground(gc, &gdkcolor); gdk_draw_rectangle (renderer->pixmap, gc, FALSE, x, y, width, height); }
/** Draw a TextLine object. * @param object The renderer object to use for transform and output * @param text_line The TextLine to render, including font and height. * @param pos The position to render it at. * @param color The color to render it with. */ static void draw_text_line (DiaRenderer *object, TextLine *text_line, Point *pos, Alignment alignment, Color *color) { DiaGdkRenderer *renderer = DIA_GDK_RENDERER (object); GdkColor gdkcolor; int x,y; Point start_pos; PangoLayout* layout = NULL; const gchar *text = text_line_get_string(text_line); int height_pixels; real font_height = text_line_get_height(text_line); real scale = dia_transform_length(renderer->transform, 1.0); if (text == NULL || *text == '\0') return; /* Don't render empty strings. */ point_copy(&start_pos,pos); renderer_color_convert(renderer, color, &gdkcolor); height_pixels = dia_transform_length(renderer->transform, font_height); if (height_pixels < 2) { /* "Greeking" instead of making tiny font */ int width_pixels = dia_transform_length(renderer->transform, text_line_get_width(text_line)); gdk_gc_set_foreground(renderer->gc, &gdkcolor); gdk_gc_set_dashes(renderer->gc, 0, (gint8*)"\1\2", 2); dia_transform_coords(renderer->transform, start_pos.x, start_pos.y, &x, &y); gdk_draw_line(renderer->pixmap, renderer->gc, x, y, x + width_pixels, y); return; } else { start_pos.y -= text_line_get_ascent(text_line); start_pos.x -= text_line_get_alignment_adjustment (text_line, alignment); dia_transform_coords(renderer->transform, start_pos.x, start_pos.y, &x, &y); layout = dia_font_build_layout(text, text_line->font, dia_transform_length(renderer->transform, text_line->height)/20.0); #if defined(PANGO_VERSION_ENCODE) # if (PANGO_VERSION >= PANGO_VERSION_ENCODE(1,16,0)) /* I'd say the former Pango API was broken, i.e. leaky */ # define HAVE_pango_layout_get_line_readonly # endif #endif text_line_adjust_layout_line (text_line, #if defined(HAVE_pango_layout_get_line_readonly) pango_layout_get_line_readonly(layout, 0), #else pango_layout_get_line(layout, 0), #endif scale/20.0); if (renderer->highlight_color != NULL) { draw_highlighted_string(renderer, layout, x, y, &gdkcolor); } else { #if defined HAVE_FREETYPE { FT_Bitmap ftbitmap; int width, height; GdkPixbuf *rgba = NULL; width = dia_transform_length(renderer->transform, text_line_get_width(text_line)); height = dia_transform_length(renderer->transform, text_line_get_height(text_line)); if (width > 0) { int stride; guchar* pixels; int i,j; guint8 *graybitmap; initialize_ft_bitmap(&ftbitmap, width, height); pango_ft2_render_layout(&ftbitmap, layout, 0, 0); graybitmap = ftbitmap.buffer; rgba = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height); stride = gdk_pixbuf_get_rowstride(rgba); pixels = gdk_pixbuf_get_pixels(rgba); for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { pixels[i*stride+j*4] = gdkcolor.red>>8; pixels[i*stride+j*4+1] = gdkcolor.green>>8; pixels[i*stride+j*4+2] = gdkcolor.blue>>8; pixels[i*stride+j*4+3] = graybitmap[i*ftbitmap.pitch+j]; } } g_free(graybitmap); gdk_draw_pixbuf(renderer->pixmap, renderer->gc, rgba, 0, 0, x, y, width, height, GDK_RGB_DITHER_NONE, 0, 0); g_object_unref(G_OBJECT(rgba)); } } #else gdk_gc_set_foreground(renderer->gc, &gdkcolor); gdk_draw_layout(renderer->pixmap, renderer->gc, x, y, layout); #endif } /* !higlight_color */ g_object_unref(G_OBJECT(layout)); } /* !greeking */