static void message_update_data(Message *message) { Connection *conn = &message->connection; Object *obj = (Object *) message; Rectangle rect; obj->position = conn->endpoints[0]; message->text_handle.pos = message->text_pos; connection_update_handles(conn); /* Boundingbox: */ connection_update_boundingbox(conn); /* Add boundingbox for text: */ rect.left = message->text_pos.x; rect.right = rect.left + message->text_width; rect.top = message->text_pos.y - font_ascent(message_font, MESSAGE_FONTHEIGHT); rect.bottom = rect.top + MESSAGE_FONTHEIGHT; rectangle_union(&obj->bounding_box, &rect); /* fix boundingbox for message_width and arrow: */ obj->bounding_box.top -= MESSAGE_WIDTH/2 + MESSAGE_ARROWLEN; obj->bounding_box.left -= MESSAGE_WIDTH/2 + MESSAGE_ARROWLEN; obj->bounding_box.bottom += MESSAGE_WIDTH/2 + MESSAGE_ARROWLEN; obj->bounding_box.right += MESSAGE_WIDTH/2 + MESSAGE_ARROWLEN; }
static void constraint_update_data(Constraint *constraint) { Connection *conn = &constraint->connection; Object *obj = (Object *) constraint; Rectangle rect; obj->position = conn->endpoints[0]; constraint->text_handle.pos = constraint->text_pos; connection_update_handles(conn); /* Boundingbox: */ connection_update_boundingbox(conn); /* Add boundingbox for text: */ rect.left = constraint->text_pos.x; rect.right = rect.left + constraint->text_width; rect.top = constraint->text_pos.y - font_ascent(constraint_font, CONSTRAINT_FONTHEIGHT); rect.bottom = rect.top + CONSTRAINT_FONTHEIGHT; rectangle_union(&obj->bounding_box, &rect); /* fix boundingbox for constraint_width and arrow: */ obj->bounding_box.top -= CONSTRAINT_WIDTH/2 + CONSTRAINT_ARROWLEN; obj->bounding_box.left -= CONSTRAINT_WIDTH/2 + CONSTRAINT_ARROWLEN; obj->bounding_box.bottom += CONSTRAINT_WIDTH/2 + CONSTRAINT_ARROWLEN; obj->bounding_box.right += CONSTRAINT_WIDTH/2 + CONSTRAINT_ARROWLEN; }
static void message_update_data(Message *message) { Connection *conn = &message->connection; DiaObject *obj = &conn->object; Rectangle rect; if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) || connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) { connection_adjust_for_autogap(conn); } obj->position = conn->endpoints[0]; message->text_handle.pos = message->text_pos; connection_update_handles(conn); connection_update_boundingbox(conn); message->text_width = dia_font_string_width(message->text, message->font, message->font_height); /* Add boundingbox for text: */ rect.left = message->text_pos.x-message->text_width/2; rect.right = rect.left + message->text_width; rect.top = message->text_pos.y - dia_font_ascent(message->text, message->font, message->font_height); rect.bottom = rect.top + message->font_height; rectangle_union(&obj->bounding_box, &rect); }
static void implements_update_data(Implements *implements) { Connection *conn = &implements->connection; Object *obj = (Object *) implements; Point delta; Point point; real len; Rectangle rect; obj->position = conn->endpoints[0]; implements->text_handle.pos = implements->text_pos; /* circle handle/center pos: */ delta = conn->endpoints[0]; point_sub(&delta, &conn->endpoints[1]); len = sqrt(point_dot(&delta, &delta)); delta.x /= len; delta.y /= len; point = delta; point_scale(&point, implements->circle_diameter); point_add(&point, &conn->endpoints[1]); implements->circle_handle.pos = point; point = delta; point_scale(&point, implements->circle_diameter/2.0); point_add(&point, &conn->endpoints[1]); implements->circle_center = point; connection_update_handles(conn); /* Boundingbox: */ connection_update_boundingbox(conn); /* Add boundingbox for circle: */ rect.left = implements->circle_center.x - implements->circle_diameter/2.0; rect.right = implements->circle_center.x + implements->circle_diameter/2.0; rect.top = implements->circle_center.y - implements->circle_diameter/2.0; rect.bottom = implements->circle_center.y + implements->circle_diameter/2.0; rectangle_union(&obj->bounding_box, &rect); /* Add boundingbox for text: */ rect.left = implements->text_pos.x; rect.right = rect.left + implements->text_width; rect.top = implements->text_pos.y - font_ascent(implements_font, IMPLEMENTS_FONTHEIGHT); rect.bottom = rect.top + IMPLEMENTS_FONTHEIGHT; rectangle_union(&obj->bounding_box, &rect); /* fix boundingbox for implements_width: */ obj->bounding_box.top -= IMPLEMENTS_WIDTH/2; obj->bounding_box.left -= IMPLEMENTS_WIDTH/2; obj->bounding_box.bottom += IMPLEMENTS_WIDTH/2; obj->bounding_box.right += IMPLEMENTS_WIDTH/2; }
static void mbr_update_data(Mbr *mbr) { Connection *conn = &mbr->connection; DiaObject *obj = &conn->object; Rectangle rect; Point p1,p2; Point p3,p4; gchar *text; /* Too complex to easily decide -- this is essentially a bezier curve */ /* if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) || connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) { connection_adjust_for_autogap(conn); } */ obj->position = conn->endpoints[0]; mbr->pm_handle.pos = mbr->pm; connection_update_handles(conn); connection_update_boundingbox(conn); /* text width */ text=compute_text(mbr); mbr->text_width = dia_font_string_width(text, mbr_font, MBR_DECFONTHEIGHT); mbr->text_ascent = dia_font_ascent(text, mbr_font, MBR_DECFONTHEIGHT); /* endpoint */ p1 = conn->endpoints[0]; p2 = conn->endpoints[1]; /* bezier */ compute_line(&p1,&p2,&mbr->pm,mbr->line); /* Add boundingbox for mid decoration (slightly overestimated) : */ p3.x=mbr->pm.x-MBR_DEC_SIZE; p3.y=mbr->pm.y-MBR_DEC_SIZE; p4.x=p3.x+MBR_DEC_SIZE*2; p4.y=p3.y+MBR_DEC_SIZE*2; rect.left=p3.x; rect.right=p4.x; rect.top=p3.y; rect.bottom=p4.y; rectangle_union(&obj->bounding_box, &rect); /* Add boundingbox for text: */ rect.left = mbr->pm.x-mbr->text_width/2; rect.right = rect.left + mbr->text_width; rect.top = mbr->pm.y - mbr->text_ascent; rect.bottom = rect.top + MBR_DECFONTHEIGHT; rectangle_union(&obj->bounding_box, &rect); g_free(text); /* free auxilliary text */ }
static void link_update_data(Link *link) { Connection *conn = &link->connection; DiaObject *obj = &conn->object; Rectangle rect; Point p1,p2,p3,p4,pa; /* Too complex to easily decide */ /* if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) || connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) { connection_adjust_for_autogap(conn); } */ obj->position = conn->endpoints[0]; link->pm_handle.pos = link->pm; connection_update_handles(conn); connection_update_boundingbox(conn); /* endpoint */ p1 = conn->endpoints[0]; p2 = conn->endpoints[1]; /* bezier */ compute_line(&p1,&p2,&link->pm,link->line); /* connection point */ link->connector.pos.x=p1.x; link->connector.pos.y=p1.y; /* Update boundingbox for mid-point (TBD is this necessary ?) */ rectangle_add_point(&obj->bounding_box, &link->pm); /* Add boundingbox for annotation text (over-estimated) : */ pa=compute_annot(&p1,&p2,&link->pm,0.75,0.75); rect.left = pa.x-0.3; rect.right = rect.left+0.6; rect.top = pa.y - LINK_FONTHEIGHT; rect.bottom = rect.top + 2*LINK_FONTHEIGHT; rectangle_union(&obj->bounding_box, &rect); /* Add boundingbox for dependency decoration (with some overestimation toi be safe) */ pa=bezier_line_eval(link->line,2,0.25); p3.x=pa.x-LINK_DEP_WIDTH*1.5; p3.y=pa.y-LINK_DEP_HEIGHT*1.5; p4.x=p3.x+LINK_DEP_WIDTH*3; p4.y=p3.y+LINK_DEP_HEIGHT*3; rect.left=p3.x; rect.right=p4.x; rect.top=p3.y; rect.bottom=p4.y; rectangle_union(&obj->bounding_box, &rect); }
static void constraint_update_data(Constraint *constraint) { Connection *conn = &constraint->connection; DiaObject *obj = &conn->object; Rectangle rect; LineBBExtras *extra; if ((constraint->text) && (constraint->text[0] == '{')) { /* we might have a string loaded from an older dia. Clean it up. */ g_free(constraint->brtext); constraint->brtext = constraint->text; constraint->text = bracketted_to_string(constraint->text,"{","}"); } else if (!constraint->brtext) { constraint->brtext = string_to_bracketted(constraint->text, "{", "}"); } if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) || connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) { connection_adjust_for_autogap(conn); } obj->position = conn->endpoints[0]; constraint->text_width = dia_font_string_width(constraint->brtext, constraint->font, constraint->font_height); constraint->text_handle.pos = constraint->text_pos; connection_update_handles(conn); /* Boundingbox: */ extra = &conn->extra_spacing; extra->start_long = extra->start_trans = extra->end_long = constraint->line_width/2.0; extra->end_trans = MAX(constraint->line_width,CONSTRAINT_ARROWLEN)/2.0; connection_update_boundingbox(conn); /* Add boundingbox for text: */ rect.left = constraint->text_pos.x; rect.right = rect.left + constraint->text_width; rect.top = constraint->text_pos.y - dia_font_ascent(constraint->brtext, constraint->font, constraint->font_height); rect.bottom = rect.top + constraint->font_height; rectangle_union(&obj->bounding_box, &rect); }
static void annotation_update_data(Annotation *annotation) { Connection *conn = &annotation->connection; DiaObject *obj = &conn->object; Rectangle textrect; if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) || connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) { connection_adjust_for_autogap(conn); } obj->position = conn->endpoints[0]; annotation->text_handle.pos = annotation->text->position; connection_update_handles(conn); connection_update_boundingbox(conn); text_calc_boundingbox(annotation->text,&textrect); rectangle_union(&obj->bounding_box, &textrect); }
static void flow_update_data(Flow *flow) { Connection *conn = &flow->connection; DiaObject *obj = &conn->object; Rectangle rect; Color* color = NULL; if (connpoint_is_autogap(flow->connection.endpoint_handles[0].connected_to) || connpoint_is_autogap(flow->connection.endpoint_handles[1].connected_to)) { connection_adjust_for_autogap(conn); } obj->position = conn->endpoints[0]; switch (flow->type) { case FLOW_ENERGY: color = &flow_color_energy ; break ; case FLOW_MATERIAL: color = &flow_color_material ; break ; case FLOW_SIGNAL: color = &flow_color_signal ; break ; } text_set_color( flow->text, color ) ; flow->text->position = flow->textpos; flow->text_handle.pos = flow->textpos; connection_update_handles(conn); /* Boundingbox: */ connection_update_boundingbox(conn); /* Add boundingbox for text: */ text_calc_boundingbox(flow->text, &rect) ; rectangle_union(&obj->bounding_box, &rect); }
static void line_update_data(Line *line) { Connection *conn = &line->connection; Object *obj = (Object *) line; line->middle_point.pos.x = conn->endpoints[0].x*0.5 + conn->endpoints[1].x*0.5; line->middle_point.pos.y = conn->endpoints[0].y*0.5 + conn->endpoints[1].y*0.5; connection_update_boundingbox(conn); /* fix boundingbox for line_width: */ obj->bounding_box.top -= line->line_width/2; obj->bounding_box.left -= line->line_width/2; obj->bounding_box.bottom += line->line_width/2; obj->bounding_box.right += line->line_width/2; /* Fix boundingbox for arrowheads */ if (line->start_arrow.type != ARROW_NONE || line->end_arrow.type != ARROW_NONE) { real arrow_width = 0.0; if (line->start_arrow.type != ARROW_NONE) arrow_width = line->start_arrow.width; if (line->end_arrow.type != ARROW_NONE) arrow_width = MAX(arrow_width, line->start_arrow.width); obj->bounding_box.top -= arrow_width; obj->bounding_box.left -= arrow_width; obj->bounding_box.bottom += arrow_width; obj->bounding_box.right += arrow_width; } obj->position = conn->endpoints[0]; connection_update_handles(conn); }
static void bus_update_data(Bus *bus) { Connection *conn = &bus->connection; DiaObject *obj = &conn->object; int i; Point u, v, vhat; Point *endpoints; real ulen; real min_par, max_par; /* * This seems to break stuff wildly. */ /* 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); min_par = 0.0; max_par = point_dot(&vhat, &v); for (i=0;i<bus->num_handles;i++) { u = bus->handles[i]->pos; point_sub(&u, &endpoints[0]); ulen = point_dot(&u, &vhat); min_par = MIN(min_par, ulen); max_par = MAX(max_par, ulen); bus->parallel_points[i] = vhat; point_scale(&bus->parallel_points[i], ulen); point_add(&bus->parallel_points[i], &endpoints[0]); } min_par -= LINE_WIDTH/2.0; max_par += LINE_WIDTH/2.0; bus->real_ends[0] = vhat; point_scale(&bus->real_ends[0], min_par); point_add(&bus->real_ends[0], &endpoints[0]); bus->real_ends[1] = vhat; point_scale(&bus->real_ends[1], max_par); point_add(&bus->real_ends[1], &endpoints[0]); connection_update_boundingbox(conn); rectangle_add_point(&obj->bounding_box, &bus->real_ends[0]); rectangle_add_point(&obj->bounding_box, &bus->real_ends[1]); for (i=0;i<bus->num_handles;i++) { rectangle_add_point(&obj->bounding_box, &bus->handles[i]->pos); } connection_update_handles(conn); }
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); }
static void lifeline_update_data(Lifeline *lifeline) { Connection *conn = &lifeline->connection; DiaObject *obj = &conn->object; LineBBExtras *extra = &conn->extra_spacing; Point p1, p2, pnw, psw, pne, pse, pmw,pme; obj->position = conn->endpoints[0]; /* Update lifeline rbot using num. of cp and cp_distance */ lifeline->rbot = lifeline->rtop + lifeline_rect_size( lifeline ) ; /* Update conn->endpoints[0].y if rbot is greater */ if( conn->endpoints[1].y < conn->endpoints[0].y + lifeline->rbot ) conn->endpoints[1].y = conn->endpoints[0].y + lifeline->rbot + lifeline->cp_distance; /* box handles: */ p1.x = conn->endpoints[0].x; p1.y = conn->endpoints[0].y + lifeline->rtop; lifeline->boxtop_handle.pos = p1; p2.x = p1.x; p2.y = conn->endpoints[0].y + lifeline->rbot; lifeline->boxbot_handle.pos = p2; /* middle handle - between the cpls */ lifeline->boxmid_handle.pos.x = p1.x; lifeline->boxmid_handle.pos.y = p1.y + (lifeline->cp_distance * (lifeline->northwest->num_connections + 1)); connection_update_handles(conn); /* Boundingbox: */ extra->start_trans = extra->start_long = extra->end_long = extra->end_trans = LIFELINE_LINEWIDTH/2.0; if (lifeline->draw_focuscontrol) { extra->start_trans = extra->end_trans = MAX(LIFELINE_LINEWIDTH/2,(LIFELINE_WIDTH/2+LIFELINE_BOXWIDTH/2)); } if (lifeline->draw_cross) { extra->end_trans += LIFELINE_CROSSLEN; extra->end_long += LIFELINE_CROSSLEN; } connection_update_boundingbox(conn); if (lifeline->draw_focuscontrol) { p1.x -= LIFELINE_WIDTH/2.0; p2.x += LIFELINE_WIDTH/2.0; } /* Update connections: */ pnw.x = p1.x; pnw.y = p1.y; psw.x = p1.x; psw.y = p2.y; pne.x = p2.x; pne.y = p1.y; pse.x = p2.x; pse.y = p2.y; pmw.x = pnw.x; pme.x = pne.x; pmw.y = pme.y = (p1.y + lifeline->cp_distance * (lifeline->northwest->num_connections+1)); lifeline->connections[6].pos.x = conn->endpoints[0].x; lifeline->connections[6].pos.y = conn->endpoints[0].y + lifeline->rbot; lifeline->connections[6].directions = DIR_SOUTH; lifeline->connections[0].pos = pnw; lifeline->connections[1].pos = pne; lifeline->connections[2].pos = pmw; lifeline->connections[3].pos = pme; lifeline->connections[4].pos = psw; lifeline->connections[5].pos = pse; lifeline->connections[0].directions = DIR_NORTH|DIR_WEST; lifeline->connections[1].directions = DIR_NORTH|DIR_EAST; lifeline->connections[2].directions = DIR_WEST; lifeline->connections[3].directions = DIR_EAST; lifeline->connections[4].directions = DIR_SOUTH|DIR_WEST; lifeline->connections[5].directions = DIR_SOUTH|DIR_EAST; connpointline_update(lifeline->northwest); connpointline_putonaline(lifeline->northwest,&pnw,&pmw, DIR_WEST); connpointline_update(lifeline->southwest); connpointline_putonaline(lifeline->southwest,&pmw,&psw, DIR_WEST); connpointline_update(lifeline->northeast); connpointline_putonaline(lifeline->northeast,&pne,&pme, DIR_EAST); connpointline_update(lifeline->southeast); connpointline_putonaline(lifeline->southeast,&pme,&pse, DIR_EAST); }
static void arc_update_data(Arc *arc) { Connection *conn = &arc->connection; Object *obj = (Object *) arc; Point *endpoints; real x1,y1,x2,y2,xc,yc; real lensq, alpha, radius; real angle1, angle2; 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); radius = lensq/(8*arc->curve_distance) + arc->curve_distance/2.0; 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; connection_update_boundingbox(conn); /* fix boundingbox for line_width: */ if (in_angle(0, arc->angle1, arc->angle2)) { obj->bounding_box.right = arc->center.x + arc->radius; } if (in_angle(90, arc->angle1, arc->angle2)) { obj->bounding_box.top = arc->center.y - arc->radius; } if (in_angle(180, arc->angle1, arc->angle2)) { obj->bounding_box.left = arc->center.x - arc->radius; } if (in_angle(270, arc->angle1, arc->angle2)) { obj->bounding_box.bottom = arc->center.y + arc->radius; } /* Fix boundingbox for arrowheads */ if (arc->start_arrow.type != ARROW_NONE || arc->end_arrow.type != ARROW_NONE) { real arrow_width = 0.0; if (arc->start_arrow.type != ARROW_NONE) arrow_width = arc->start_arrow.width; if (arc->end_arrow.type != ARROW_NONE) arrow_width = MAX(arrow_width, arc->start_arrow.width); obj->bounding_box.top -= arrow_width; obj->bounding_box.left -= arrow_width; obj->bounding_box.bottom += arrow_width; obj->bounding_box.right += arrow_width; } obj->bounding_box.top -= arc->line_width/2; obj->bounding_box.left -= arc->line_width/2; obj->bounding_box.bottom += arc->line_width/2; obj->bounding_box.right += arc->line_width/2; obj->position = conn->endpoints[0]; arc_update_handles(arc); }
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 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]; }