static gboolean goc_polyline_prepare_draw (GocItem const *item, cairo_t *cr, gboolean flag) { GocPolyline *polyline = GOC_POLYLINE (item); unsigned i; gboolean scale_line_width = goc_styled_item_get_scale_line_width (GOC_STYLED_ITEM (item)); gboolean needs_restore; cairo_save (cr); needs_restore = TRUE; _goc_item_transform (item, cr, flag); if (polyline->nb_points == 0) return FALSE; if (1 == flag) { goc_group_cairo_transform (item->parent, cr, polyline->points[0].x, polyline->points[0].y); cairo_move_to (cr, 0., 0.); } else { cairo_move_to (cr, polyline->points[0].x, polyline->points[0].y); } if (polyline->use_spline) { GOBezierSpline *spline = (GOBezierSpline *) g_object_get_data (G_OBJECT (polyline), "spline"); cairo_save (cr); if (flag == 0) cairo_translate (cr, polyline->points[0].x, polyline->points[0].y); go_bezier_spline_to_cairo (spline, cr, goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL); cairo_restore (cr); } else { double sign = (flag && goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? -1: 1; gboolean prev_valid = TRUE; for (i = 1; i < polyline->nb_points; i++) { if (go_finite (polyline->points[i].x)) { if (prev_valid) cairo_line_to (cr, (polyline->points[i].x - polyline->points[0].x * flag) * sign, polyline->points[i].y - polyline->points[0].y * flag); else { cairo_move_to (cr, (polyline->points[i].x - polyline->points[0].x * flag) * sign, polyline->points[i].y - polyline->points[0].y * flag); prev_valid = TRUE; } } else prev_valid = FALSE; } } if (!scale_line_width) { cairo_restore (cr); needs_restore = FALSE; } if (goc_styled_item_set_cairo_line (GOC_STYLED_ITEM (item), cr)) { if (needs_restore) cairo_restore (cr); return TRUE; } if (needs_restore) cairo_restore (cr); return FALSE; }
static void goc_line_draw (GocItem const *item, cairo_t *cr) { GocLine *line = GOC_LINE (item); GOStyle *style = go_styled_object_get_style (GO_STYLED_OBJECT (item)); double sign = (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? -1: 1; double endx = (line->endx - line->startx) * sign, endy = line->endy - line->starty; double hoffs, voffs = ceil (style->line.width); double startx = 0, starty = 0; double phi; if (line->startx == line->endx && line->starty == line->endy) return; if (voffs <= 0.) voffs = 1.; hoffs = ((int) voffs & 1)? .5: 0.; voffs = (line->starty == line->endy)? hoffs: 0.; if (line->startx != line->endx) hoffs = 0.; cairo_save (cr); _goc_item_transform (item, cr, TRUE); goc_group_cairo_transform (item->parent, cr, hoffs + floor (line->startx), voffs + floor (line->starty)); endx = (endx > 0.)? ceil (endx): floor (endx); endy = (endy > 0.)? ceil (endy): floor (endy); phi = atan2 (endy, endx); draw_arrow (&line->start_arrow, cr, style, &startx, &starty, phi + M_PI); draw_arrow (&line->end_arrow, cr, style, &endx, &endy, phi); if ((endx != 0. || endy!= 0.) && go_styled_object_set_cairo_line (GO_STYLED_OBJECT (item), cr)) { /* try to avoid horizontal and vertical lines between two pixels */ cairo_move_to (cr, startx, starty); cairo_line_to (cr, endx, endy); cairo_stroke (cr); } cairo_restore (cr); }
static void goc_image_draw (GocItem const *item, cairo_t *cr) { GocImage *image = GOC_IMAGE (item); double height, width; double scalex = 1., scaley = 1.; int x; if (image->image == NULL || image->width == 0. || image->height == 0.) return; if (image->width < 0.) width = go_image_get_width (image->image) * (1 - image->crop_left -image->crop_right); else { width = image->width; scalex = width / go_image_get_width (image->image) / (1 - image->crop_left -image->crop_right); } if (image->height < 0.) height = go_image_get_height (image->image) * (1 - image->crop_top -image->crop_bottom); else { height = image->height; scaley = height / go_image_get_height (image->image) / (1 - image->crop_top -image->crop_bottom); } cairo_save (cr); _goc_item_transform (item, cr, TRUE); x = (goc_canvas_get_direction (item->canvas) == GOC_DIRECTION_RTL)? image->x + image->width: image->x; goc_group_cairo_transform (item->parent, cr, x, (int) image->y); cairo_rotate (cr, image->rotation); cairo_rectangle (cr, 0, 0, image->width, image->height); cairo_clip (cr); if (scalex != 1. || scaley != 1.) cairo_scale (cr, scalex, scaley); cairo_translate (cr, -go_image_get_width (image->image) * image->crop_left, -go_image_get_height (image->image) * image->crop_top); cairo_move_to (cr, 0, 0); go_image_draw (image->image, cr); cairo_restore (cr); }