static void compfeat_update_data(Compfeat *compfeat) { OrthConn *orth = &compfeat->orth; PolyBBExtras *extra = &orth->extra_spacing; int n; DiaObject *obj = &orth->object; Rectangle rect; Point *points; points = &orth->points[0]; n = orth->numpoints; obj->position = points[0]; if (compfeat->role == COMPPROP_FACET || compfeat->role == COMPPROP_EVENTSOURCE) compfeat->cp.pos = points[n - 1]; compfeat->text_pos = compfeat->text_handle.pos = compfeat->text->position; orthconn_update_data(orth); /* Boundingbox: */ extra->start_long = extra->start_trans = extra->end_long = compfeat->line_width + COMPPROP_DIAMETER; extra->end_trans = compfeat->line_width + COMPPROP_DIAMETER; orthconn_update_boundingbox(orth); text_calc_boundingbox(compfeat->text, &rect); rectangle_union(&obj->bounding_box, &rect); }
static void generalization_update_data(Generalization *genlz) { OrthConn *orth = &genlz->orth; Object *obj = (Object *) genlz; int num_segm, i; Point *points; Rectangle rect; orthconn_update_data(orth); orthconn_update_boundingbox(orth); /* fix boundinggeneralization for linewidth and triangle: */ obj->bounding_box.top -= GENERALIZATION_WIDTH/2.0 + GENERALIZATION_TRIANGLESIZE; obj->bounding_box.left -= GENERALIZATION_WIDTH/2.0 + GENERALIZATION_TRIANGLESIZE; obj->bounding_box.bottom += GENERALIZATION_WIDTH/2.0 + GENERALIZATION_TRIANGLESIZE; obj->bounding_box.right += GENERALIZATION_WIDTH/2.0 + GENERALIZATION_TRIANGLESIZE; /* Calc text pos: */ num_segm = genlz->orth.numpoints - 1; points = genlz->orth.points; i = num_segm / 2; if ((num_segm % 2) == 0) { /* If no middle segment, use horizontal */ if (genlz->orth.orientation[i]==VERTICAL) i--; } switch (genlz->orth.orientation[i]) { case HORIZONTAL: genlz->text_align = ALIGN_CENTER; genlz->text_pos.x = 0.5*(points[i].x+points[i+1].x); genlz->text_pos.y = points[i].y - font_descent(genlz_font, GENERALIZATION_FONTHEIGHT); break; case VERTICAL: genlz->text_align = ALIGN_LEFT; genlz->text_pos.x = points[i].x + 0.1; genlz->text_pos.y = 0.5*(points[i].y+points[i+1].y) - font_descent(genlz_font, GENERALIZATION_FONTHEIGHT); break; } /* Add the text recangle to the bounding box: */ rect.left = genlz->text_pos.x; if (genlz->text_align == ALIGN_CENTER) rect.left -= genlz->text_width/2.0; rect.right = rect.left + genlz->text_width; rect.top = genlz->text_pos.y - font_ascent(genlz_font, GENERALIZATION_FONTHEIGHT); rect.bottom = rect.top + 2*GENERALIZATION_FONTHEIGHT; rectangle_union(&obj->bounding_box, &rect); }
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); } }
static void arc_update_data(Arc *arc) { OrthConn *orth = &arc->orth; PolyBBExtras *extra = &orth->extra_spacing; orthconn_update_data(&arc->orth); extra->start_trans = extra->start_long = extra->end_long = extra->end_trans = ARC_LINE_WIDTH/2.0; if (arc->uparrow) { extra->middle_trans = (ARC_LINE_WIDTH + ARC_ARROW_WIDTH)/2.0; } else { extra->middle_trans = ARC_LINE_WIDTH/2.0; } orthconn_update_boundingbox(orth); }
static void participation_update_data(Participation *participation) { OrthConn *orth = &participation->orth; PolyBBExtras *extra = &orth->extra_spacing; real extra_width; orthconn_update_data(orth); if (participation->total) { extra_width = TOTAL_SEPARATION/2.0; } else { extra_width = 0.0; } extra->middle_trans = extra->start_trans = extra->end_trans = extra->start_long = extra->end_long = PARTICIPATION_WIDTH/2.0 + extra_width; orthconn_update_boundingbox(orth); }
static void uml_transition_update_data(Transition *transition) { gchar *temp_text; Point *points; /* Setup helpful pointers as shortcuts */ OrthConn *orth = &transition->orth; DiaObject *obj = &orth->object; PolyBBExtras *extra = &orth->extra_spacing; points = &orth->points[0]; /* Set the transitions position */ obj->position = points[0]; transition->trigger_text_handle.pos = transition->trigger_text_pos; transition->guard_text_handle.pos = transition->guard_text_pos; /* Update the orthogonal connection to match the new data */ orthconn_update_data(orth); extra->start_long = extra->end_long = extra->middle_trans = TRANSITION_WIDTH/2.0; extra->start_trans = extra->end_trans = MAX(TRANSITION_ARROWLEN, TRANSITION_WIDTH/2.0); /* Update the bounding box to match the new connection data */ orthconn_update_boundingbox(orth); /* Update the bounding box to match the new trigger text size and position */ temp_text = create_event_action_text(transition); expand_bbox_for_text(&obj->bounding_box, &transition->trigger_text_pos, temp_text); g_free(temp_text); /* Update the bounding box to match the new guard text size and position */ temp_text = g_strdup_printf("[%s]", transition->guard_text ? transition->guard_text : ""); expand_bbox_for_text(&obj->bounding_box, &transition->guard_text_pos, temp_text); g_free(temp_text); }
static void participation_update_data(Participation *participation) { OrthConn *orth = &participation->orth; Object *obj = (Object *) participation; real extra_width; orthconn_update_data(orth); orthconn_update_boundingbox(orth); if (participation->total) { extra_width = TOTAL_SEPARATION/2.0; } else { extra_width = 0.0; } /* fix boundingparticipation for linewidth */ obj->bounding_box.top -= PARTICIPATION_WIDTH/2.0 + extra_width; obj->bounding_box.left -= PARTICIPATION_WIDTH/2.0 + extra_width; obj->bounding_box.bottom += PARTICIPATION_WIDTH/2.0 + extra_width; obj->bounding_box.right += PARTICIPATION_WIDTH/2.0 + extra_width; }
static void dependency_update_data(Dependency *dep) { OrthConn *orth = &dep->orth; DiaObject *obj = &orth->object; PolyBBExtras *extra = &orth->extra_spacing; int num_segm, i; Point *points; Rectangle rect; orthconn_update_data(orth); dep->stereotype = remove_stereotype_from_string(dep->stereotype); if (!dep->st_stereotype) { dep->st_stereotype = string_to_stereotype(dep->stereotype); } dep->text_width = 0.0; if (dep->name) dep->text_width = dia_font_string_width(dep->name, dep_font, DEPENDENCY_FONTHEIGHT); if (dep->stereotype) dep->text_width = MAX(dep->text_width, dia_font_string_width(dep->stereotype, dep_font, DEPENDENCY_FONTHEIGHT)); extra->start_trans = extra->start_long = extra->middle_trans = DEPENDENCY_WIDTH/2.0; extra->end_trans = extra->end_long = (dep->draw_arrow? (DEPENDENCY_WIDTH + DEPENDENCY_ARROWLEN)/2.0: DEPENDENCY_WIDTH/2.0); orthconn_update_boundingbox(orth); /* Calc text pos: */ num_segm = dep->orth.numpoints - 1; points = dep->orth.points; i = num_segm / 2; if ((num_segm % 2) == 0) { /* If no middle segment, use horizontal */ if (dep->orth.orientation[i]==VERTICAL) i--; } switch (dep->orth.orientation[i]) { case HORIZONTAL: dep->text_align = ALIGN_CENTER; dep->text_pos.x = 0.5*(points[i].x+points[i+1].x); dep->text_pos.y = points[i].y; if (dep->name) dep->text_pos.y -= dia_font_descent(dep->name, dep_font, DEPENDENCY_FONTHEIGHT); break; case VERTICAL: dep->text_align = ALIGN_LEFT; dep->text_pos.x = points[i].x + 0.1; dep->text_pos.y = 0.5*(points[i].y+points[i+1].y); if (dep->name) dep->text_pos.y -= dia_font_descent(dep->name, dep_font, DEPENDENCY_FONTHEIGHT); break; } /* Add the text recangle to the bounding box: */ rect.left = dep->text_pos.x; if (dep->text_align == ALIGN_CENTER) rect.left -= dep->text_width/2.0; rect.right = rect.left + dep->text_width; rect.top = dep->text_pos.y; if (dep->name) rect.top -= dia_font_ascent(dep->name, dep_font, DEPENDENCY_FONTHEIGHT); rect.bottom = rect.top + 2*DEPENDENCY_FONTHEIGHT; rectangle_union(&obj->bounding_box, &rect); }
static void realizes_update_data(Realizes *realize) { OrthConn *orth = &realize->orth; DiaObject *obj = &orth->object; int num_segm, i; Point *points; Rectangle rect; PolyBBExtras *extra; orthconn_update_data(orth); realize->text_width = 0.0; realize->stereotype = remove_stereotype_from_string(realize->stereotype); if (!realize->st_stereotype) { realize->st_stereotype = string_to_stereotype(realize->stereotype); } if (realize->name) realize->text_width = dia_font_string_width(realize->name, realize_font, REALIZES_FONTHEIGHT); if (realize->stereotype) realize->text_width = MAX(realize->text_width, dia_font_string_width(realize->stereotype, realize_font, REALIZES_FONTHEIGHT)); extra = &orth->extra_spacing; extra->start_trans = REALIZES_WIDTH/2.0 + REALIZES_TRIANGLESIZE; extra->start_long = extra->middle_trans = extra->end_trans = extra->end_long = REALIZES_WIDTH/2.0; orthconn_update_boundingbox(orth); /* Calc text pos: */ num_segm = realize->orth.numpoints - 1; points = realize->orth.points; i = num_segm / 2; if ((num_segm % 2) == 0) { /* If no middle segment, use horizontal */ if (realize->orth.orientation[i]==VERTICAL) i--; } switch (realize->orth.orientation[i]) { case HORIZONTAL: realize->text_align = ALIGN_CENTER; realize->text_pos.x = 0.5*(points[i].x+points[i+1].x); realize->text_pos.y = points[i].y; if (realize->name) realize->text_pos.y -= dia_font_descent(realize->name,realize_font, REALIZES_FONTHEIGHT); break; case VERTICAL: realize->text_align = ALIGN_LEFT; realize->text_pos.x = points[i].x + 0.1; realize->text_pos.y = 0.5*(points[i].y+points[i+1].y); if (realize->name) realize->text_pos.y -= dia_font_descent(realize->name, realize_font, REALIZES_FONTHEIGHT); break; } /* Add the text recangle to the bounding box: */ rect.left = realize->text_pos.x; if (realize->text_align == ALIGN_CENTER) rect.left -= realize->text_width/2.0; rect.right = rect.left + realize->text_width; rect.top = realize->text_pos.y; if (realize->name) rect.top -= dia_font_ascent(realize->name,realize_font, REALIZES_FONTHEIGHT); rect.bottom = rect.top + 2*REALIZES_FONTHEIGHT; rectangle_union(&obj->bounding_box, &rect); }
static void association_update_data(Association *assoc) { /* FIXME: The ascent and descent computation logic here is fundamentally slow. */ OrthConn *orth = &assoc->orth; DiaObject *obj = &orth->object; PolyBBExtras *extra = &orth->extra_spacing; int num_segm, i; Point *points; Rectangle rect; Orientation dir; orthconn_update_data(orth); /* translate new assoc state to old assoc ends */ if (assoc->direction == ASSOC_NODIR) { assoc->end[0].aggregate = AGGREGATE_NONE; assoc->end[1].aggregate = AGGREGATE_NONE; } else if (assoc->direction == ASSOC_RIGHT) { /* the diamond is at the start of the line */ assoc->end[0].aggregate = assoc->assoc_type; assoc->end[1].aggregate = AGGREGATE_NONE; } else { assoc->end[1].aggregate = assoc->assoc_type; assoc->end[0].aggregate = AGGREGATE_NONE; } extra->start_trans = extra->start_long = (assoc->end[0].aggregate == AGGREGATE_NONE? ASSOCIATION_WIDTH/2.0: (ASSOCIATION_WIDTH + ASSOCIATION_DIAMONDLEN)/2.0); extra->middle_trans = ASSOCIATION_WIDTH/2.0; extra->end_trans = extra->end_long = (assoc->end[1].aggregate == AGGREGATE_NONE? ASSOCIATION_WIDTH/2.0: (ASSOCIATION_WIDTH + ASSOCIATION_DIAMONDLEN)/2.0); if (assoc->end[0].arrow) extra->start_trans = MAX(extra->start_trans, ASSOCIATION_TRIANGLESIZE); if (assoc->end[1].arrow) extra->end_trans = MAX(extra->end_trans, ASSOCIATION_TRIANGLESIZE); orthconn_update_boundingbox(orth); /* Calc text pos: */ num_segm = assoc->orth.numpoints - 1; points = assoc->orth.points; i = num_segm / 2; if ((num_segm % 2) == 0) { /* If no middle segment, use horizontal */ if (assoc->orth.orientation[i]==VERTICAL) i--; } dir = assoc->orth.orientation[i]; /* also adapt for degenerated segment */ if (VERTICAL == dir && fabs(points[i].y - points[i+1].y) < 1e-6) dir = HORIZONTAL; else if (HORIZONTAL == dir && fabs(points[i].x - points[i+1].x) < 1e-6) dir = VERTICAL; switch (dir) { case HORIZONTAL: assoc->text_align = ALIGN_CENTER; assoc->text_pos.x = 0.5*(points[i].x+points[i+1].x); assoc->text_pos.y = points[i].y - assoc->descent; break; case VERTICAL: assoc->text_align = ALIGN_LEFT; assoc->text_pos.x = points[i].x + 0.1; assoc->text_pos.y = 0.5*(points[i].y+points[i+1].y) - assoc->descent; break; } /* Add the text recangle to the bounding box: */ rect.left = assoc->text_pos.x; if (assoc->text_align == ALIGN_CENTER) rect.left -= assoc->text_width/2.0; rect.right = rect.left + assoc->text_width; rect.top = assoc->text_pos.y - assoc->ascent; rect.bottom = rect.top + ASSOCIATION_FONTHEIGHT; rectangle_union(&obj->bounding_box, &rect); association_update_data_end(assoc, 0); association_update_data_end(assoc, 1); }