static void polyline_update_data(Polyline *polyline) { PolyConn *poly = &polyline->poly; DiaObject *obj = &poly->object; PolyBBExtras *extra = &poly->extra_spacing; Point gap_endpoints[2]; polyconn_update_data(&polyline->poly); extra->start_trans = (polyline->line_width / 2.0); extra->end_trans = (polyline->line_width / 2.0); extra->middle_trans = (polyline->line_width / 2.0); extra->start_long = (polyline->line_width / 2.0); extra->end_long = (polyline->line_width / 2.0); polyline_calculate_gap_endpoints(polyline, gap_endpoints); polyline_exchange_gap_points(polyline, gap_endpoints); polyconn_update_boundingbox(poly); if (polyline->start_arrow.type != ARROW_NONE) { Rectangle bbox; Point move_arrow, move_line; Point to = gap_endpoints[0]; Point from = poly->points[1]; calculate_arrow_point(&polyline->start_arrow, &to, &from, &move_arrow, &move_line, polyline->line_width); /* move them */ point_sub(&to, &move_arrow); point_sub(&from, &move_line); arrow_bbox (&polyline->start_arrow, polyline->line_width, &to, &from, &bbox); rectangle_union (&obj->bounding_box, &bbox); } if (polyline->end_arrow.type != ARROW_NONE) { Rectangle bbox; int n = polyline->poly.numpoints; Point move_arrow, move_line; Point to = gap_endpoints[1]; Point from = poly->points[n-2]; calculate_arrow_point(&polyline->end_arrow, &to, &from, &move_arrow, &move_line, polyline->line_width); /* move them */ point_sub(&to, &move_arrow); point_sub(&from, &move_line); arrow_bbox (&polyline->end_arrow, polyline->line_width, &to, &from, &bbox); rectangle_union (&obj->bounding_box, &bbox); } polyline_exchange_gap_points(polyline, gap_endpoints); obj->position = poly->points[0]; }
static void zigzagline_update_data(Zigzagline *zigzagline) { OrthConn *orth = &zigzagline->orth; DiaObject *obj = &orth->object; PolyBBExtras *extra = &orth->extra_spacing; orthconn_update_data(&zigzagline->orth); extra->start_long = extra->end_long = extra->middle_trans = extra->start_trans = extra->end_trans = (zigzagline->line_width / 2.0); orthconn_update_boundingbox(orth); if (zigzagline->start_arrow.type != ARROW_NONE) { Rectangle bbox; Point move_arrow, move_line; Point to = orth->points[0]; Point from = orth->points[1]; calculate_arrow_point(&zigzagline->start_arrow, &to, &from, &move_arrow, &move_line, zigzagline->line_width); /* move them */ point_sub(&to, &move_arrow); point_sub(&from, &move_line); arrow_bbox (&zigzagline->start_arrow, zigzagline->line_width, &to, &from, &bbox); rectangle_union (&obj->bounding_box, &bbox); } if (zigzagline->end_arrow.type != ARROW_NONE) { Rectangle bbox; Point move_arrow, move_line; int n = orth->numpoints; Point to = orth->points[n-1]; Point from = orth->points[n-2]; calculate_arrow_point(&zigzagline->end_arrow, &to, &from, &move_arrow, &move_line, zigzagline->line_width); /* move them */ point_sub(&to, &move_arrow); point_sub(&from, &move_line); arrow_bbox (&zigzagline->end_arrow, zigzagline->line_width, &to, &from, &bbox); rectangle_union (&obj->bounding_box, &bbox); } }
/*! Not in the object interface but very important anyway. Used to recalculate the object data after a change */ static void measure_update_data (Measure *measure) { Connection *conn = &measure->connection; DiaObject *obj = &measure->connection.object; real value; Point *ends = measure->connection.endpoints; LineBBExtras *extra = &conn->extra_spacing; Rectangle bbox; Arrow arrow = MEASURE_ARROW(measure); real ascent, width; g_return_if_fail (obj->handles != NULL); connection_update_handles(conn); extra->start_trans = extra->end_trans = extra->start_long = extra->end_long = (measure->line_width / 2.0); g_free (measure->name); value = distance_point_point (&ends[0], &ends[1]); value *= measure->scale; value *= (28.346457 / units[measure->unit].factor); measure->name = g_strdup_printf ("%.*g %s", measure->precision, value, units[measure->unit].unit); ascent = dia_font_ascent (measure->name, measure->font, measure->font_height); width = dia_font_string_width (measure->name, measure->font, measure->font_height); measure->text_pos.x = (ends[0].x + ends[1].x) / 2; measure->text_pos.y = (ends[0].y + ends[1].y) / 2; /* for horizontal we could try to center over the line */ line_bbox (&ends[0], &ends[0], &conn->extra_spacing,&conn->object.bounding_box); arrow_bbox (&arrow, measure->line_width, &ends[0], &ends[1], &bbox); rectangle_union(&obj->bounding_box, &bbox); arrow_bbox (&arrow, measure->line_width, &ends[1], &ends[0], &bbox); rectangle_union(&obj->bounding_box, &bbox); bbox.left = measure->text_pos.x; bbox.top = measure->text_pos.y - ascent; bbox.bottom = bbox.top + measure->font_height; bbox.right = bbox.left + width; rectangle_union(&obj->bounding_box, &bbox); obj->position = conn->endpoints[0]; }
static void line_update_data(Line *line) { Connection *conn = &line->connection; DiaObject *obj = &conn->object; LineBBExtras *extra = &conn->extra_spacing; Point start, end; extra->start_trans = extra->end_trans = extra->start_long = extra->end_long = (line->line_width / 2.0); if (connpoint_is_autogap(line->connection.endpoint_handles[0].connected_to) || connpoint_is_autogap(line->connection.endpoint_handles[1].connected_to)) { connection_adjust_for_autogap(conn); } if (line->absolute_start_gap || line->absolute_end_gap ) { Point gap_endpoints[2]; line_adjust_for_absolute_gap(line, gap_endpoints); line_bbox(&gap_endpoints[0],&gap_endpoints[1], &conn->extra_spacing,&conn->object.bounding_box); start = gap_endpoints[0]; end = gap_endpoints[1]; } else { connection_update_boundingbox(conn); start = conn->endpoints[0]; end = conn->endpoints[1]; } if (line->start_arrow.type != ARROW_NONE) { Rectangle bbox; Point move_arrow, move_line; Point to = start; Point from = end; calculate_arrow_point(&line->start_arrow, &to, &from, &move_arrow, &move_line, line->line_width); /* move them */ point_sub(&to, &move_arrow); point_sub(&from, &move_line); arrow_bbox (&line->start_arrow, line->line_width, &to, &from, &bbox); rectangle_union (&obj->bounding_box, &bbox); } if (line->end_arrow.type != ARROW_NONE) { Rectangle bbox; Point move_arrow, move_line; Point to = end; Point from = start; calculate_arrow_point(&line->end_arrow, &to, &from, &move_arrow, &move_line, line->line_width); /* move them */ point_sub(&to, &move_arrow); point_sub(&from, &move_line); arrow_bbox (&line->end_arrow, line->line_width, &to, &from, &bbox); rectangle_union (&obj->bounding_box, &bbox); } obj->position = conn->endpoints[0]; connpointline_update(line->cpl); connpointline_putonaline(line->cpl, &start, &end, DIR_ALL); connection_update_handles(conn); }
static void bezierline_update_data(Bezierline *bezierline) { BezierConn *bez = &bezierline->bez; DiaObject *obj = &bez->object; PolyBBExtras *extra = &bez->extra_spacing; bezierconn_update_data(bez); extra->start_trans = extra->start_long = extra->middle_trans = extra->end_trans = extra->end_long = (bezierline->line_width / 2.0); obj->position = bez->bezier.points[0].p1; if (connpoint_is_autogap(bez->object.handles[0]->connected_to) || connpoint_is_autogap(bez->object.handles[3*(bez->bezier.num_points-1)]->connected_to) || bezierline->absolute_start_gap || bezierline->absolute_end_gap || bezierline->start_arrow.type != ARROW_NONE || bezierline->end_arrow.type != ARROW_NONE) { Point gap_points[4]; Rectangle bbox_union = {bez->bezier.points[0].p1.x, bez->bezier.points[0].p1.y, bez->bezier.points[0].p1.x, bez->bezier.points[0].p1.y}; compute_gap_points(bezierline, gap_points); exchange_bez_gap_points(bez,gap_points); /* further modifying the points data, accounts for corrcet arrow and bezier bounding box */ if (bezierline->start_arrow.type != ARROW_NONE) { Rectangle bbox; Point move_arrow, move_line; Point to = bez->bezier.points[0].p1, from = bez->bezier.points[1].p1; calculate_arrow_point(&bezierline->start_arrow, &to, &from, &move_arrow, &move_line, bezierline->line_width); point_sub(&to, &move_arrow); point_sub(&bez->bezier.points[0].p1, &move_line); arrow_bbox (&bezierline->start_arrow, bezierline->line_width, &to, &from, &bbox); rectangle_union (&bbox_union, &bbox); } if (bezierline->end_arrow.type != ARROW_NONE) { Rectangle bbox; Point move_arrow, move_line; int num_points = bez->bezier.num_points; Point to = bez->bezier.points[num_points-1].p3, from = bez->bezier.points[num_points-1].p2; calculate_arrow_point(&bezierline->end_arrow, &to, &from, &move_arrow, &move_line, bezierline->line_width); point_sub(&to, &move_arrow); point_sub(&bez->bezier.points[num_points-1].p3, &move_line); arrow_bbox (&bezierline->end_arrow, bezierline->line_width, &to, &from, &bbox); rectangle_union (&bbox_union, &bbox); } bezierconn_update_boundingbox(bez); rectangle_union (&obj->bounding_box, &bbox_union); exchange_bez_gap_points(bez,gap_points); } else { bezierconn_update_boundingbox(bez); } /* add control points to the bounding box, needed to make them visible when showing all * and to remove traces from them */ { int i, num_points = bez->bezier.num_points; g_assert (obj->enclosing_box != NULL); *obj->enclosing_box = obj->bounding_box; /* starting with the second point, the first one is MOVE_TO */ for (i = 1; i < num_points; ++i) { if (bez->bezier.points[i].type != BEZ_CURVE_TO) continue; rectangle_add_point(obj->enclosing_box, &bez->bezier.points[i].p1); rectangle_add_point(obj->enclosing_box, &bez->bezier.points[i].p2); } } }
static void arc_update_data(Arc *arc) { Connection *conn = &arc->connection; LineBBExtras *extra =&conn->extra_spacing; DiaObject *obj = &conn->object; Point *endpoints; real x1,y1,x2,y2,xc,yc; real lensq, alpha, radius; real angle1, angle2; gboolean righthand; endpoints = &arc->connection.endpoints[0]; x1 = endpoints[0].x; y1 = endpoints[0].y; x2 = endpoints[1].x; y2 = endpoints[1].y; lensq = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1); if (fabs(arc->curve_distance) > 0.01) radius = lensq/(8*arc->curve_distance) + arc->curve_distance/2.0; else radius = 0.0; /* not really but used for bbox calculation below */ if (lensq == 0.0 || arc_is_line (arc)) alpha = 1.0; /* arbitrary, but /not/ 1/0 */ else alpha = (radius - arc->curve_distance) / sqrt(lensq); xc = (x1 + x2) / 2.0 + (y2 - y1)*alpha; yc = (y1 + y2) / 2.0 + (x1 - x2)*alpha; angle1 = -atan2(y1-yc, x1-xc)*180.0/M_PI; if (angle1<0) angle1+=360.0; angle2 = -atan2(y2-yc, x2-xc)*180.0/M_PI; if (angle2<0) angle2+=360.0; if (radius<0.0) { real tmp; tmp = angle1; angle1 = angle2; angle2 = tmp; radius = -radius; } arc->radius = radius; arc->center.x = xc; arc->center.y = yc; arc->angle1 = angle1; arc->angle2 = angle2; /* LineBBExtras not applicable to calculate the arrows bounding box */ extra->start_trans = extra->end_trans = extra->start_long = extra->end_long = (arc->line_width / 2.0); /* updates midpoint */ arc_update_handles(arc); /* startpoint, midpoint, endpoint */ righthand = is_right_hand (&endpoints[0], &arc->middle_handle.pos, &endpoints[1]); connection_update_boundingbox(conn); /* fix boundingbox for arc's special shape XXX find a more elegant way: */ if (in_angle(0, arc->angle1, arc->angle2)) { /* rigth side, y does not matter if included */ Point pt = { arc->center.x + arc->radius + (arc->line_width / 2.0), y1 }; rectangle_add_point (&obj->bounding_box, &pt); } if (in_angle(90, arc->angle1, arc->angle2)) { /* top side, x does not matter if included */ Point pt = {x1, arc->center.y - arc->radius - (arc->line_width / 2.0) }; rectangle_add_point (&obj->bounding_box, &pt); } if (in_angle(180, arc->angle1, arc->angle2)) { /* left side, y does not matter if included */ Point pt = { arc->center.x - arc->radius - (arc->line_width / 2.0), y1 }; rectangle_add_point (&obj->bounding_box, &pt); } if (in_angle(270, arc->angle1, arc->angle2)) { /* bootom side, x does not matter if included */ Point pt = { x1, arc->center.y + arc->radius + (arc->line_width / 2.0) }; rectangle_add_point (&obj->bounding_box, &pt); } if (arc->start_arrow.type != ARROW_NONE) { /* a good from-point would be the chord of arrow length, but draw_arc_with_arrows currently uses the tangent * For big arcs the difference is not huge and the minimum size of small arcs should be limited by the arror length. */ Rectangle bbox = {0,}; real tmp; Point move_arrow, move_line; Point to = arc->connection.endpoints[0]; Point from = to; point_sub (&from, &arc->center); tmp = from.x; if (righthand) from.x = -from.y, from.y = tmp; else from.x = from.y, from.y = -tmp; point_add (&from, &to); calculate_arrow_point(&arc->start_arrow, &to, &from, &move_arrow, &move_line, arc->line_width); /* move them */ point_sub(&to, &move_arrow); point_sub(&from, &move_line); arrow_bbox(&arc->start_arrow, arc->line_width, &to, &from, &bbox); rectangle_union(&obj->bounding_box, &bbox); } if (arc->end_arrow.type != ARROW_NONE) { Rectangle bbox = {0,}; real tmp; Point move_arrow, move_line; Point to = arc->connection.endpoints[1]; Point from = to; point_sub (&from, &arc->center); tmp = from.x; if (righthand) from.x = from.y, from.y = -tmp; else from.x = -from.y, from.y = tmp; point_add (&from, &to); calculate_arrow_point(&arc->end_arrow, &to, &from, &move_arrow, &move_line, arc->line_width); /* move them */ point_sub(&to, &move_arrow); point_sub(&from, &move_line); arrow_bbox(&arc->end_arrow, arc->line_width, &to, &from, &bbox); rectangle_union(&obj->bounding_box, &bbox); } /* if selected put the centerpoint in the box, too. */ obj->enclosing_box = obj->bounding_box; rectangle_add_point(&obj->enclosing_box, &arc->center); obj->position = conn->endpoints[0]; }