void polyconn_update_boundingbox(PolyConn *poly) { assert(poly != NULL); polyline_bbox(&poly->points[0], poly->numpoints, &poly->extra_spacing, FALSE, &poly->object.bounding_box); }
/*! * \brief Object update function called after property change * * Not in the object interface but very important anyway. * Used to recalculate the object data after a change * \protected \memberof Outline */ static void outline_update_data (Outline *outline) { DiaObject *obj = &outline->object; /* calculate the ink_rect from two points and the given rotation */ cairo_t *cr; cairo_surface_t *surface; cairo_text_extents_t extents; real x, y; DiaFontStyle style; if (outline->path) cairo_path_destroy (outline->path); outline->path = NULL; /* surface will not be used to render anything, it is just to create the cairo context */ surface = cairo_svg_surface_create_for_stream (write_nul, NULL, 100, 100); cr = cairo_create (surface); cairo_surface_destroy (surface); /* in fact: unref() */ style = dia_font_get_style (outline->font); /* not exact matching but almost the best we can do with the toy api */ cairo_select_font_face (cr, dia_font_get_family (outline->font), DIA_FONT_STYLE_GET_SLANT (style) == DIA_FONT_NORMAL ? CAIRO_FONT_SLANT_NORMAL : CAIRO_FONT_SLANT_ITALIC, DIA_FONT_STYLE_GET_WEIGHT (style) < DIA_FONT_MEDIUM ? CAIRO_FONT_WEIGHT_NORMAL : CAIRO_FONT_WEIGHT_BOLD); cairo_set_font_size (cr, outline->font_height); cairo_text_extents (cr, outline->name, &extents); /* unfortunately this has no effect on the returned path? See below. */ cairo_rotate (cr, outline->rotation/(2*G_PI)); outline->mat.xx = cos(G_PI*outline->rotation/180); outline->mat.xy = sin(G_PI*outline->rotation/180); outline->mat.yx = -sin(G_PI*outline->rotation/180); outline->mat.yy = cos(G_PI*outline->rotation/180); /* fix point */ outline->ink_rect[0].x = x = obj->position.x; outline->ink_rect[0].y = y = obj->position.y; /* handle rotation */ outline->ink_rect[1].x = x + extents.width * outline->mat.xx; outline->ink_rect[1].y = y + extents.width * outline->mat.yx; outline->ink_rect[2].x = x + extents.width * outline->mat.xx + extents.height * outline->mat.xy; outline->ink_rect[2].y = y + extents.width * outline->mat.yx + extents.height * outline->mat.yy; outline->ink_rect[3].x = x + extents.height * outline->mat.xy; outline->ink_rect[3].y = y + extents.height * outline->mat.yy; /* x_advance? */ /* calculate bounding box */ { PolyBBExtras bbex = {0, 0, outline->line_width/2, 0, 0 }; polyline_bbox (&outline->ink_rect[0], 4, &bbex, TRUE, &obj->bounding_box); } outline_update_handles (outline), cairo_move_to (cr, -extents.x_bearing, -extents.y_bearing); #if 0 /* reset the matrix to not yet change the outline_draw method */ outline->mat.xx = 1.0; outline->mat.xy = 0.0; outline->mat.yx = 0.0; outline->mat.yy = 1.0; #endif cairo_text_path (cr, outline->name); /* reset the rotation to not have the path rotated back and forth: no effect */ cairo_rotate (cr, 0.0); outline->path = cairo_copy_path (cr); /* the cairo context is only used in this fuinction */ cairo_destroy (cr); }
static void wanlink_update_data(WanLink *wanlink) { Connection *conn = &wanlink->connection; DiaObject *obj = (DiaObject *) wanlink; Point v, vhat; Point *endpoints; real width, width_2; real len, angle; Point origin; int i; Matrix m; width = wanlink->width; width_2 = width / 2.0; if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) || connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) { connection_adjust_for_autogap(conn); } endpoints = &conn->endpoints[0]; obj->position = endpoints[0]; v = endpoints[1]; point_sub(&v, &endpoints[0]); if ((fabs(v.x) == 0.0) && (fabs(v.y)==0.0)) { v.x += 0.01; } vhat = v; point_normalize(&vhat); connection_update_boundingbox(conn); /** compute the polygon **/ origin = wanlink->connection.endpoints [0]; len = point_len (&v); angle = atan2 (vhat.y, vhat.x) - M_PI_2; /* The case of the wanlink */ wanlink->poly[0].x = (width * 0.50) - width_2; wanlink->poly[0].y = (len * 0.00); wanlink->poly[1].x = (width * 0.50) - width_2; wanlink->poly[1].y = (len * 0.45); wanlink->poly[2].x = (width * 0.94) - width_2; wanlink->poly[2].y = (len * 0.45); wanlink->poly[3].x = (width * 0.50) - width_2; wanlink->poly[3].y = (len * 1.00); wanlink->poly[4].x = (width * 0.50) - width_2; wanlink->poly[4].y = (len * 0.55); wanlink->poly[5].x = (width * 0.06) - width_2; wanlink->poly[5].y = (len * 0.55); /* rotate */ _identity_matrix (m); _rotate_matrix (m, angle); obj->bounding_box.top = origin.y; obj->bounding_box.left = origin.x; obj->bounding_box.bottom = conn->endpoints[1].y; obj->bounding_box.right = conn->endpoints[1].x; for (i = 0; i < WANLINK_POLY_LEN; i++) { Point new_pt; _transform_point (m, &wanlink->poly[i], &new_pt); point_add (&new_pt, &origin); wanlink->poly[i] = new_pt; } /* calculate bounding box */ { PolyBBExtras bbex = {0, 0, wanlink->width/2, 0, 0 }; polyline_bbox (&wanlink->poly[0], WANLINK_POLY_LEN, &bbex, TRUE, &obj->bounding_box); } connection_update_handles(conn); }