static void textobj_update_data(Textobj *textobj) { Point to2; DiaObject *obj = &textobj->object; Rectangle tx_bb; text_set_position(textobj->text, &obj->position); text_calc_boundingbox(textobj->text, &obj->bounding_box); to2 = obj->position; textobj_valign_point(textobj, &to2); /* shift text position depending on text alignment */ if (VALIGN_TOP == textobj->vert_align) to2.y += textobj->margin; /* down */ else if (VALIGN_BOTTOM == textobj->vert_align) to2.y -= textobj->margin; /* up */ if (ALIGN_LEFT == textobj->text->alignment) to2.x += textobj->margin; /* right */ else if (ALIGN_RIGHT == textobj->text->alignment) to2.x -= textobj->margin; /* left */ text_set_position(textobj->text, &to2); /* always use the unrotated box ... */ text_calc_boundingbox(textobj->text, &tx_bb); /* grow the bounding box by 2x margin */ obj->bounding_box.top -= textobj->margin; obj->bounding_box.left -= textobj->margin; obj->bounding_box.bottom += textobj->margin; obj->bounding_box.right += textobj->margin; textobj->text_handle.pos = obj->position; if (textobj->text_angle == 0) { obj->bounding_box = tx_bb; g_return_if_fail (obj->enclosing_box != NULL); *obj->enclosing_box = tx_bb; } else { /* ... and grow it when necessary */ Point poly[4]; int i; _textobj_get_poly (textobj, poly); /* we don't want the joined box for boundingbox because * selection would become too greedy than. */ obj->bounding_box.left = obj->bounding_box.right = poly[0].x; obj->bounding_box.top = obj->bounding_box.bottom = poly[0].y; for (i = 1; i < 4; ++i) rectangle_add_point (&obj->bounding_box, &poly[i]); g_return_if_fail (obj->enclosing_box != NULL); *obj->enclosing_box = obj->bounding_box; /* join for editing/selection bbox */ rectangle_union (obj->enclosing_box, &tx_bb); } }
static void basestation_update_data(Basestation *basestation) { Element *elem = &basestation->element; DiaObject *obj = &elem->object; Rectangle text_box; Point p; elem->width = BASESTATION_WIDTH; elem->height = BASESTATION_HEIGHT+basestation->text->height; p = elem->corner; p.x += elem->width/2; p.y += elem->height + basestation->text->ascent; text_set_position(basestation->text, &p); text_calc_boundingbox(basestation->text, &text_box); /* Update connections: */ element_update_connections_rectangle (elem, basestation->connections); element_update_boundingbox(elem); /* Add bounding box for text: */ rectangle_union(&obj->bounding_box, &text_box); obj->position = elem->corner; obj->position.x += elem->width/2.0; obj->position.y += elem->height/2.0; element_update_handles(elem); }
static void node_update_data(Node *node) { Element *elem = &node->element; DiaObject *obj = &node->element.object; Point p1; real h; text_calc_boundingbox(node->name, NULL); h = elem->corner.y + NODE_TEXT_MARGIN; p1.x = elem->corner.x + NODE_TEXT_MARGIN; p1.y = h + node->name->ascent; /* position of text */ text_set_position(node->name, &p1); h += node->name->height * node->name->numlines; elem->width = MAX(elem->width, node->name->max_width + 2*NODE_TEXT_MARGIN); elem->height = MAX(elem->height, node->name->height * node->name->numlines + 2*NODE_TEXT_MARGIN); /* Update connections: */ element_update_connections_rectangle(elem, node->connections); element_update_boundingbox(elem); /* fix boundingbox for depth: */ obj->bounding_box.top -= NODE_DEPTH; obj->bounding_box.right += NODE_DEPTH; obj->position = elem->corner; element_update_handles(elem); }
static void note_update_data(Note *note) { Element *elem = ¬e->element; DiaObject *obj = &elem->object; Point p; text_calc_boundingbox(note->text, NULL); elem->width = note->text->max_width + NOTE_MARGIN_X + NOTE_CORNER; elem->height = note->text->height*note->text->numlines + NOTE_MARGIN_Y + NOTE_CORNER; p = elem->corner; p.x += note->line_width/2.0 + NOTE_MARGIN_X; p.y += note->line_width/2.0 + NOTE_CORNER + note->text->ascent; text_set_position(note->text, &p); /* Update connections: */ element_update_connections_rectangle(elem, note->connections); element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static void textobj_update_data(Textobj *textobj) { Point to2; DiaObject *obj = &textobj->object; text_set_position(textobj->text, &obj->position); text_calc_boundingbox(textobj->text, &obj->bounding_box); to2 = obj->position; textobj_valign_point(textobj, &to2, 1); text_set_position(textobj->text, &to2); text_calc_boundingbox(textobj->text, &obj->bounding_box); textobj->text_handle.pos = obj->position; }
static void aadlbox_update_text_position(Aadlbox *aadlbox) { Point p; aadlbox->specific->text_position(aadlbox, &p); text_set_position(aadlbox->name, &p); }
static void compfeat_get_props(Compfeat *compfeat, GPtrArray *props) { if (compfeat->roletmp) compfeat->role = compfeat->roletmp; text_set_position(compfeat->text, &compfeat->text_pos); object_get_props_from_offsets(&compfeat->orth.object, compfeat_offsets, props); }
static void compfeat_set_props(Compfeat *compfeat, GPtrArray *props) { object_set_props_from_offsets(&compfeat->orth.object, compfeat_offsets, props); compfeat->text_handle.pos = compfeat->text_pos; text_set_position(compfeat->text, &compfeat->text_handle.pos); compfeat_update_data(compfeat); }
static void state_update_data(State *state) { real w, h; Element *elem = &state->element; ElementBBExtras *extra = &elem->extra_spacing; DiaObject *obj = &elem->object; Point p; text_calc_boundingbox(state->text, NULL); w = state->text->max_width + 2*STATE_MARGIN_X; h = state->text->height*state->text->numlines +2*STATE_MARGIN_Y; if (w < STATE_WIDTH) w = STATE_WIDTH; p.x = elem->corner.x + w/2.0; p.y = elem->corner.y + STATE_MARGIN_Y + state->text->ascent; text_set_position(state->text, &p); elem->width = w; elem->height = h; extra->border_trans = STATE_LINEWIDTH / 2.0; /* Update connections: */ state->connections[0].pos = elem->corner; state->connections[1].pos.x = elem->corner.x + elem->width / 2.0; state->connections[1].pos.y = elem->corner.y; state->connections[2].pos.x = elem->corner.x + elem->width; state->connections[2].pos.y = elem->corner.y; state->connections[3].pos.x = elem->corner.x; state->connections[3].pos.y = elem->corner.y + elem->height / 2.0; state->connections[4].pos.x = elem->corner.x + elem->width; state->connections[4].pos.y = elem->corner.y + elem->height / 2.0; state->connections[5].pos.x = elem->corner.x; state->connections[5].pos.y = elem->corner.y + elem->height; state->connections[6].pos.x = elem->corner.x + elem->width / 2.0; state->connections[6].pos.y = elem->corner.y + elem->height; state->connections[7].pos.x = elem->corner.x + elem->width; state->connections[7].pos.y = elem->corner.y + elem->height; state->connections[0].directions = DIR_NORTH|DIR_WEST; state->connections[1].directions = DIR_NORTH; state->connections[2].directions = DIR_NORTH|DIR_EAST; state->connections[3].directions = DIR_WEST; state->connections[4].directions = DIR_EAST; state->connections[5].directions = DIR_SOUTH|DIR_WEST; state->connections[6].directions = DIR_SOUTH; state->connections[7].directions = DIR_SOUTH|DIR_EAST; element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static void rendobj_update_data(RenderObject *rend_obj) { Point p; const RenderObjectDescriptor *desc; Element *elem; Object *obj; int i; elem = &rend_obj->element; obj = &elem->object; desc = rend_obj->desc; rend_obj->magnify = elem->width / rend_obj->desc->width; /* Update connections: */ for (i=0;i<desc->num_connection_points;i++) { rend_obj->connections[i].pos = desc->connection_points[i]; point_scale(&rend_obj->connections[i].pos, rend_obj->magnify); point_add(&rend_obj->connections[i].pos, &elem->corner); } if (desc->use_text) { p = desc->text_pos; point_scale(&p, rend_obj->magnify); point_add(&p, &elem->corner); p.y += rend_obj->text->ascent; text_set_position(rend_obj->text, &p); } element_update_boundingbox(elem); /* fix boundingbox for extra_border: */ obj->bounding_box.top -= desc->extra_border; obj->bounding_box.left -= desc->extra_border; obj->bounding_box.bottom += desc->extra_border; obj->bounding_box.right += desc->extra_border; if (desc->use_text) { Rectangle text_box; text_calc_boundingbox(rend_obj->text, &text_box); rectangle_union(&obj->bounding_box, &text_box); } obj->position = elem->corner; p = desc->move_position; point_scale(&p, rend_obj->magnify); point_add(&obj->position, &p); element_update_handles(elem); }
static void smallpackage_move(SmallPackage *pkg, Point *to) { Point p; pkg->element.corner = *to; p = *to; p.x += SMALLPACKAGE_MARGIN_X; p.y += pkg->text->ascent + SMALLPACKAGE_MARGIN_Y; text_set_position(pkg->text, &p); smallpackage_update_data(pkg); }
static ObjectChange* node_move(Node *node, Point *to) { Point p; node->element.corner = *to; p = *to; p.x += NODE_TEXT_MARGIN; p.y += node->name->ascent + NODE_TEXT_MARGIN; text_set_position(node->name, &p); node_update_data(node); return NULL; }
static void state_update_data(State *state) { real w, h; Element *elem = &state->element; Object *obj = (Object *) state; Point p; if (state->state_type==STATE_NORMAL) { w = state->text->max_width + 2*STATE_MARGIN_X; h = state->text->height*state->text->numlines +2*STATE_MARGIN_Y; if (w < STATE_WIDTH) w = STATE_WIDTH; p.x = elem->corner.x + w/2.0; p.y = elem->corner.y + STATE_MARGIN_Y + state->text->ascent; text_set_position(state->text, &p); } else { w = h = (state->state_type==STATE_END) ? STATE_ENDRATIO: STATE_RATIO; } elem->width = w; elem->height = h; /* Update connections: */ state->connections[0].pos = elem->corner; state->connections[1].pos.x = elem->corner.x + elem->width / 2.0; state->connections[1].pos.y = elem->corner.y; state->connections[2].pos.x = elem->corner.x + elem->width; state->connections[2].pos.y = elem->corner.y; state->connections[3].pos.x = elem->corner.x; state->connections[3].pos.y = elem->corner.y + elem->height / 2.0; state->connections[4].pos.x = elem->corner.x + elem->width; state->connections[4].pos.y = elem->corner.y + elem->height / 2.0; state->connections[5].pos.x = elem->corner.x; state->connections[5].pos.y = elem->corner.y + elem->height; state->connections[6].pos.x = elem->corner.x + elem->width / 2.0; state->connections[6].pos.y = elem->corner.y + elem->height; state->connections[7].pos.x = elem->corner.x + elem->width; state->connections[7].pos.y = elem->corner.y + elem->height; element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static ObjectChange* req_move(Requirement *req, Point *to) { real h; Point p; req->element.corner = *to; h = req->text->height*req->text->numlines; p = *to; p.x += req->element.width/2.0; p.y += (req->element.height - h)/2.0 + req->text->ascent; text_set_position(req->text, &p); req_update_data(req); return NULL; }
static ObjectChange * compfeat_move(Compfeat *compfeat, Point *to) { ObjectChange *change; Point delta = *to; delta = *to; point_sub(&delta, &compfeat->orth.points[0]); /* I don't understand this, but the text position is wrong directly after compfeat_create()! */ point_add(&delta, &compfeat->text->position); text_set_position(compfeat->text, &delta); change = orthconn_move(&compfeat->orth, to); compfeat_update_data(compfeat); return change; }
static ObjectChange* usecase_move(Usecase *usecase, Point *to) { real h; Point p; usecase->element.corner = *to; h = usecase->text->height*usecase->text->numlines; p = *to; p.x += usecase->element.width/2.0; if (usecase->text_outside) { p.y += usecase->element.height - h + usecase->text->ascent; } else { p.y += (usecase->element.height - h)/2.0 + usecase->text->ascent; } text_set_position(usecase->text, &p); usecase_update_data(usecase); return NULL; }
static ObjectChange * compfeat_move_handle(Compfeat *compfeat, Handle *handle, Point *to, ConnectionPoint *cp, HandleMoveReason reason, ModifierKeys modifiers) { ObjectChange *change; assert(compfeat!=NULL); assert(handle!=NULL); assert(to!=NULL); if (handle->id == HANDLE_MOVE_TEXT) { text_set_position(compfeat->text, to); change = NULL; } else { change = orthconn_move_handle(&compfeat->orth, handle, to, cp, reason, modifiers); } compfeat_update_data(compfeat); return change; }
static void radiocell_update_data(RadioCell *radiocell) { PolyShape *poly = &radiocell->poly; DiaObject *obj = &poly->object; ElementBBExtras *extra = &poly->extra_spacing; Rectangle text_box; Point textpos; int i; /* not exactly a regular hexagon, but this fits better in the grid */ Point points[] = { { 1., 0. }, { .5, .75 }, { -.5, .75 }, { -1., 0. }, { -.5, -.75 }, { .5, -.75 } }; radiocell->center.x = (poly->points[0].x + poly->points[3].x) / 2.; radiocell->center.y = poly->points[0].y; for (i = 0; i < 6; i++) { poly->points[i] = radiocell->center; poly->points[i].x += radiocell->radius * points[i].x; poly->points[i].y += radiocell->radius * points[i].y; } /* Add bounding box for text: */ text_calc_boundingbox(radiocell->text, NULL); textpos.x = (poly->points[0].x + poly->points[3].x) / 2.; textpos.y = poly->points[0].y - (radiocell->text->height * (radiocell->text->numlines - 1) + radiocell->text->descent) / 2.; text_set_position(radiocell->text, &textpos); text_calc_boundingbox(radiocell->text, &text_box); polyshape_update_data(poly); extra->border_trans = radiocell->line_width / 2.0; polyshape_update_boundingbox(poly); rectangle_union(&obj->bounding_box, &text_box); obj->position = poly->points[0]; }
static void usecase_update_data(Usecase *usecase) { real w, h, ratio; Point c, half, r,p; Element *elem = &usecase->element; ElementBBExtras *extra = &elem->extra_spacing; DiaObject *obj = &elem->object; text_calc_boundingbox(usecase->text, NULL); w = usecase->text->max_width; h = usecase->text->height*usecase->text->numlines; if (!usecase->text_outside) { ratio = w/h; if (ratio > USECASE_MAX_RATIO) ratio = USECASE_MAX_RATIO; if (ratio < USECASE_MIN_RATIO) { ratio = USECASE_MIN_RATIO; r.y = w / ratio + h; r.x = r.y * ratio; } else { r.x = ratio*h + w; r.y = r.x / ratio; } if (r.x < USECASE_WIDTH) r.x = USECASE_WIDTH; if (r.y < USECASE_HEIGHT) r.y = USECASE_HEIGHT; } else { r.x = USECASE_WIDTH; r.y = USECASE_HEIGHT; } elem->width = r.x; elem->height = r.y; extra->border_trans = usecase->line_width / 2.0; if (usecase->text_outside) { elem->width = MAX(elem->width, w); elem->height += h + USECASE_MARGIN_Y; } r.x /= 2.0; r.y /= 2.0; c.x = elem->corner.x + elem->width / 2.0; c.y = elem->corner.y + r.y; half.x = r.x * M_SQRT1_2; half.y = r.y * M_SQRT1_2; /* Update connections: */ usecase->connections[0].pos.x = c.x - half.x; usecase->connections[0].pos.y = c.y - half.y; usecase->connections[1].pos.x = c.x; usecase->connections[1].pos.y = elem->corner.y; usecase->connections[2].pos.x = c.x + half.x; usecase->connections[2].pos.y = c.y - half.y; usecase->connections[3].pos.x = c.x - r.x; usecase->connections[3].pos.y = c.y; usecase->connections[4].pos.x = c.x + r.x; usecase->connections[4].pos.y = c.y; if (usecase->text_outside) { usecase->connections[5].pos.x = elem->corner.x; usecase->connections[5].pos.y = elem->corner.y + elem->height; usecase->connections[6].pos.x = c.x; usecase->connections[6].pos.y = elem->corner.y + elem->height; usecase->connections[7].pos.x = elem->corner.x + elem->width; usecase->connections[7].pos.y = elem->corner.y + elem->height; } else { usecase->connections[5].pos.x = c.x - half.x; usecase->connections[5].pos.y = c.y + half.y; usecase->connections[6].pos.x = c.x; usecase->connections[6].pos.y = elem->corner.y + elem->height; usecase->connections[7].pos.x = c.x + half.x; usecase->connections[7].pos.y = c.y + half.y; } usecase->connections[8].pos.x = c.x; usecase->connections[8].pos.y = c.y; usecase->connections[0].directions = DIR_NORTH|DIR_WEST; usecase->connections[1].directions = DIR_NORTH; usecase->connections[2].directions = DIR_NORTH|DIR_EAST; usecase->connections[3].directions = DIR_WEST; usecase->connections[4].directions = DIR_EAST; usecase->connections[5].directions = DIR_SOUTH|DIR_WEST; usecase->connections[6].directions = DIR_SOUTH; usecase->connections[7].directions = DIR_SOUTH|DIR_EAST; usecase->connections[8].directions = DIR_ALL; h = usecase->text->height*usecase->text->numlines; p = usecase->element.corner; p.x += usecase->element.width/2.0; if (usecase->text_outside) { p.y += usecase->element.height - h + usecase->text->ascent; } else { p.y += (usecase->element.height - h)/2.0 + usecase->text->ascent; } text_set_position(usecase->text, &p); element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static void ellipse_update_data(Ellipse *ellipse, AnchorShape horiz, AnchorShape vert) { Element *elem = &ellipse->element; ElementBBExtras *extra = &elem->extra_spacing; DiaObject *obj = &elem->object; Point center, bottom_right; Point p, c; real dw, dh; real width, height; real radius1, radius2; int i; /* save starting points */ center = bottom_right = elem->corner; center.x += elem->width/2; bottom_right.x += elem->width; center.y += elem->height/2; bottom_right.y += elem->height; text_calc_boundingbox(ellipse->text, NULL); width = ellipse->text->max_width + 2 * ellipse->padding; height = ellipse->text->height * ellipse->text->numlines + 2 * ellipse->padding; /* stop ellipse from getting infinite width/height */ if (elem->width / elem->height > 4) elem->width = elem->height * 4; else if (elem->height / elem->width > 4) elem->height = elem->width * 4; c.x = elem->corner.x + elem->width / 2; c.y = elem->corner.y + elem->height / 2; p.x = c.x - width / 2; p.y = c.y - height / 2; radius1 = ellipse_radius(ellipse, p.x, p.y) - ellipse->border_width/2; radius2 = distance_point_point(&c, &p); if ( radius1 < radius2 && ( ellipse->text_fitting == TEXTFIT_ALWAYS || ellipse->text_fitting == TEXTFIT_WHEN_NEEDED)) { /* increase size of the ellipse while keeping its aspect ratio */ elem->width *= radius2 / radius1; elem->height *= radius2 / radius1; } /* move shape if necessary ... */ switch (horiz) { case ANCHOR_MIDDLE: elem->corner.x = center.x - elem->width/2; break; case ANCHOR_END: elem->corner.x = bottom_right.x - elem->width; break; default: break; } switch (vert) { case ANCHOR_MIDDLE: elem->corner.y = center.y - elem->height/2; break; case ANCHOR_END: elem->corner.y = bottom_right.y - elem->height; break; default: break; } p = elem->corner; p.x += elem->width / 2.0; p.y += elem->height / 2.0 - ellipse->text->height*ellipse->text->numlines/2 + ellipse->text->ascent; switch (ellipse->text->alignment) { case ALIGN_LEFT: p.x -= (elem->width - 2*(ellipse->padding + ellipse->border_width))/2; break; case ALIGN_RIGHT: p.x += (elem->width - 2*(ellipse->padding + ellipse->border_width))/2; break; case ALIGN_CENTER: break; } text_set_position(ellipse->text, &p); /* Update connections: */ c.x = elem->corner.x + elem->width / 2; c.y = elem->corner.y + elem->height / 2; dw = elem->width / 2.0; dh = elem->height / 2.0; for (i = 0; i < NUM_CONNECTIONS-1; i++) { real theta = M_PI / 8.0 * i; real costheta = cos(theta); real sintheta = sin(theta); connpoint_update(&ellipse->connections[i], c.x + dw * costheta, c.y - dh * sintheta, (costheta > .5?DIR_EAST:(costheta < -.5?DIR_WEST:0))| (sintheta > .5?DIR_NORTH:(sintheta < -.5?DIR_SOUTH:0))); } connpoint_update(&ellipse->connections[16], c.x, c.y, DIR_ALL); extra->border_trans = ellipse->border_width / 2.0; element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static void other_update_data(Other *other, AnchorShape horiz, AnchorShape vert) { Element *elem = &other->element; ElementBBExtras *extra = &elem->extra_spacing; DiaObject *obj = &elem->object; Point center, bottom_right; Point p; real width, height; Point nw,ne,se,sw; /* save starting points */ center = bottom_right = elem->corner; center.x += elem->width/2; bottom_right.x += elem->width; center.y += elem->height/2; bottom_right.y += elem->height; text_calc_boundingbox(other->text, NULL); width = other->text->max_width + other->padding*2; height = other->text->height * other->text->numlines + other->padding*2; /* autoscale here */ if (width > elem->width) elem->width = width; if (height > elem->height) elem->height = height; if (elem->width<elem->height*1.5) elem->width=elem->height*1.5; /* move shape if necessary ... */ switch (horiz) { case ANCHOR_MIDDLE: elem->corner.x = center.x - elem->width/2; break; case ANCHOR_END: elem->corner.x = bottom_right.x - elem->width; break; default: break; } switch (vert) { case ANCHOR_MIDDLE: elem->corner.y = center.y - elem->height/2; break; case ANCHOR_END: elem->corner.y = bottom_right.y - elem->height; break; default: break; } p = elem->corner; p.x += elem->width / 2.0; p.y += elem->height / 2.0 - other->text->height * other->text->numlines / 2 + other->text->ascent; text_set_position(other->text, &p); extra->border_trans = OTHER_LINE_WIDTH / 2.0; element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); /* Update connections: */ nw = elem->corner; se.x = nw.x + elem->width; se.y = nw.y + elem->height; ne.x = se.x; ne.y = nw.y; sw.y = se.y; sw.x = nw.x; connpointline_update(other->north); connpointline_putonaline(other->north,&ne,&nw,DIR_NORTH); connpointline_update(other->west); connpointline_putonaline(other->west,&nw,&sw,DIR_WEST); connpointline_update(other->south); connpointline_putonaline(other->south,&sw,&se,DIR_SOUTH); connpointline_update(other->east); connpointline_putonaline(other->east,&se,&ne,DIR_EAST); }
static void diamond_update_data(Diamond *diamond, AnchorShape horiz, AnchorShape vert) { Element *elem = &diamond->element; DiaObject *obj = &elem->object; ElementBBExtras *extra = &elem->extra_spacing; Point center, bottom_right; Point p; real dw, dh; real width, height; /* save starting points */ center = bottom_right = elem->corner; center.x += elem->width/2; bottom_right.x += elem->width; center.y += elem->height/2; bottom_right.y += elem->height; text_calc_boundingbox(diamond->text, NULL); width = diamond->text->max_width + 2*diamond->padding+diamond->border_width; height = diamond->text->height * diamond->text->numlines + 2 * diamond->padding + diamond->border_width; if (diamond->text_fitting == TEXTFIT_ALWAYS || ( diamond->text_fitting == TEXTFIT_WHEN_NEEDED && height > (elem->width - width) * elem->height / elem->width)) { /* increase size of the diamond while keeping its aspect ratio */ real grad = elem->width/elem->height; if (grad < 1.0/4) grad = 1.0/4; if (grad > 4) grad = 4; elem->width = width + height * grad; elem->height = height + width / grad; } else { /* Need this for text alignment soon */ real grad = elem->width/elem->height; if (grad < 1.0/4) grad = 1.0/4; if (grad > 4) grad = 4; width = elem->width - height*grad; } /* move shape if necessary ... */ switch (horiz) { case ANCHOR_MIDDLE: elem->corner.x = center.x - elem->width/2; break; case ANCHOR_END: elem->corner.x = bottom_right.x - elem->width; break; default: break; } switch (vert) { case ANCHOR_MIDDLE: elem->corner.y = center.y - elem->height/2; break; case ANCHOR_END: elem->corner.y = bottom_right.y - elem->height; break; default: break; } p = elem->corner; p.x += elem->width / 2.0; p.y += elem->height / 2.0 - diamond->text->height*diamond->text->numlines/2 + diamond->text->ascent; switch (diamond->text->alignment) { case ALIGN_LEFT: p.x -= width/2; break; case ALIGN_RIGHT: p.x += width/2; break; case ALIGN_CENTER: break; } text_set_position(diamond->text, &p); dw = elem->width / 8.0; dh = elem->height / 8.0; /* Update connections: */ diamond->connections[0].pos.x = elem->corner.x + 4*dw; diamond->connections[0].pos.y = elem->corner.y; diamond->connections[1].pos.x = elem->corner.x + 5*dw; diamond->connections[1].pos.y = elem->corner.y + dh; diamond->connections[2].pos.x = elem->corner.x + 6*dw; diamond->connections[2].pos.y = elem->corner.y + 2*dh; diamond->connections[3].pos.x = elem->corner.x + 7*dw; diamond->connections[3].pos.y = elem->corner.y + 3*dh; diamond->connections[4].pos.x = elem->corner.x + elem->width; diamond->connections[4].pos.y = elem->corner.y + 4*dh; diamond->connections[5].pos.x = elem->corner.x + 7*dw; diamond->connections[5].pos.y = elem->corner.y + 5*dh; diamond->connections[6].pos.x = elem->corner.x + 6*dw; diamond->connections[6].pos.y = elem->corner.y + 6*dh; diamond->connections[7].pos.x = elem->corner.x + 5*dw; diamond->connections[7].pos.y = elem->corner.y + 7*dh; diamond->connections[8].pos.x = elem->corner.x + 4*dw; diamond->connections[8].pos.y = elem->corner.y + elem->height; diamond->connections[9].pos.x = elem->corner.x + 3*dw; diamond->connections[9].pos.y = elem->corner.y + 7*dh; diamond->connections[10].pos.x = elem->corner.x + 2*dw; diamond->connections[10].pos.y = elem->corner.y + 6*dh; diamond->connections[11].pos.x = elem->corner.x + dw; diamond->connections[11].pos.y = elem->corner.y + 5*dh; diamond->connections[12].pos.x = elem->corner.x; diamond->connections[12].pos.y = elem->corner.y + 4*dh; diamond->connections[13].pos.x = elem->corner.x + dw; diamond->connections[13].pos.y = elem->corner.y + 3*dh; diamond->connections[14].pos.x = elem->corner.x + 2*dw; diamond->connections[14].pos.y = elem->corner.y + 2*dh; diamond->connections[15].pos.x = elem->corner.x + 3*dw; diamond->connections[15].pos.y = elem->corner.y + dh; diamond->connections[16].pos.x = elem->corner.x + 4*dw; diamond->connections[16].pos.y = elem->corner.y + 4*dh; /* help autorouting */ element_update_connections_directions (elem, diamond->connections); extra->border_trans = diamond->border_width / 2.0; element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static void box_update_data(Box *box, AnchorShape horiz, AnchorShape vert) { Element *elem = &box->element; ElementBBExtras *extra = &elem->extra_spacing; DiaObject *obj = &elem->object; Point center, bottom_right; Point p; real radius; real width, height; /* save starting points */ center = bottom_right = elem->corner; center.x += elem->width/2; bottom_right.x += elem->width; center.y += elem->height/2; bottom_right.y += elem->height; text_calc_boundingbox(box->text, NULL); width = box->text->max_width + box->padding*2 + box->border_width; height = box->text->height * box->text->numlines + box->padding*2 + box->border_width; /* * If elem->width (e.g. the new requested dimensions of this object * from move_handle()) is smaller than the minimum width (i.e. the * width calculated from text-width, padding and border), then * set the width to the minimum. Or else;) */ if (box->text_fitting != TEXTFIT_NEVER) { if ( box->text_fitting == TEXTFIT_ALWAYS || width > elem->width) elem->width = width; if ( box->text_fitting == TEXTFIT_ALWAYS || height > elem->height) elem->height = height; } /* move shape if necessary ... */ switch (horiz) { case ANCHOR_MIDDLE: elem->corner.x = center.x - elem->width/2; break; case ANCHOR_END: elem->corner.x = bottom_right.x - elem->width; break; default: break; } switch (vert) { case ANCHOR_MIDDLE: elem->corner.y = center.y - elem->height/2; break; case ANCHOR_END: elem->corner.y = bottom_right.y - elem->height; break; default: break; } p = elem->corner; p.x += elem->width / 2.0; p.y += elem->height / 2.0 - box->text->height * box->text->numlines / 2 + box->text->ascent; switch (box->text->alignment) { case ALIGN_LEFT: p.x -= (elem->width - box->padding*2 + box->border_width)/2; break; case ALIGN_RIGHT: p.x += (elem->width - box->padding*2 + box->border_width)/2; break; case ALIGN_CENTER: break; } text_set_position(box->text, &p); radius = box->corner_radius; radius = MIN(radius, elem->width/2); radius = MIN(radius, elem->height/2); radius *= (1-M_SQRT1_2); /* Update connections: */ connpoint_update(&box->connections[0], elem->corner.x + radius, elem->corner.y + radius, DIR_NORTHWEST); connpoint_update(&box->connections[1], elem->corner.x + elem->width / 4.0, elem->corner.y, DIR_NORTH); connpoint_update(&box->connections[2], elem->corner.x + elem->width / 2.0, elem->corner.y, DIR_NORTH); connpoint_update(&box->connections[3], elem->corner.x + elem->width * 3.0 / 4.0, elem->corner.y, DIR_NORTH); connpoint_update(&box->connections[4], elem->corner.x + elem->width - radius, elem->corner.y + radius, DIR_NORTHEAST); connpoint_update(&box->connections[5], elem->corner.x, elem->corner.y + elem->height / 4.0, DIR_WEST); connpoint_update(&box->connections[6], elem->corner.x + elem->width, elem->corner.y + elem->height / 4.0, DIR_EAST); connpoint_update(&box->connections[7], elem->corner.x, elem->corner.y + elem->height / 2.0, DIR_WEST); connpoint_update(&box->connections[8], elem->corner.x + elem->width, elem->corner.y + elem->height / 2.0, DIR_EAST); connpoint_update(&box->connections[9], elem->corner.x, elem->corner.y + elem->height * 3.0 / 4.0, DIR_WEST); connpoint_update(&box->connections[10], elem->corner.x + elem->width, elem->corner.y + elem->height * 3.0 / 4.0, DIR_EAST); connpoint_update(&box->connections[11], elem->corner.x + radius, elem->corner.y + elem->height - radius, DIR_SOUTHWEST); connpoint_update(&box->connections[12], elem->corner.x + elem->width / 4.0, elem->corner.y + elem->height, DIR_SOUTH); connpoint_update(&box->connections[13], elem->corner.x + elem->width / 2.0, elem->corner.y + elem->height, DIR_SOUTH); connpoint_update(&box->connections[14], elem->corner.x + elem->width * 3.0 / 4.0, elem->corner.y + elem->height, DIR_SOUTH); connpoint_update(&box->connections[15], elem->corner.x + elem->width - radius, elem->corner.y + elem->height - radius, DIR_SOUTHEAST); connpoint_update(&box->connections[16], elem->corner.x + elem->width / 2, elem->corner.y + elem->height / 2, DIR_ALL); extra->border_trans = box->border_width / 2.0; element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); if (radius > 0.0) { /* Fix the handles, too */ elem->resize_handles[0].pos.x += radius; elem->resize_handles[0].pos.y += radius; elem->resize_handles[2].pos.x -= radius; elem->resize_handles[2].pos.y += radius; elem->resize_handles[5].pos.x += radius; elem->resize_handles[5].pos.y -= radius; elem->resize_handles[7].pos.x -= radius; elem->resize_handles[7].pos.y -= radius; } }
static void classicon_update_data(Classicon *cicon) { Element *elem = &cicon->element; DiaObject *obj = &elem->object; Point p1; real h, wt, w = 0; int is_boundary = (cicon->stereotype==CLASSICON_BOUNDARY); text_calc_boundingbox(cicon->text, NULL); h = CLASSICON_AIR + CLASSICON_MARGIN + CLASSICON_ARROW + 2*CLASSICON_RADIOUS; w = 2*CLASSICON_RADIOUS; wt = cicon->text->max_width; if (cicon->stereotype==CLASSICON_BOUNDARY) { w += 2*CLASSICON_RADIOUS; wt += CLASSICON_RADIOUS; } w = MAX(w, wt) + CLASSICON_AIR; p1.y = h + elem->corner.y; h += cicon->text->height*cicon->text->numlines + CLASSICON_AIR; p1.y += cicon->text->ascent; p1.x = elem->corner.x + w/2.0; if (cicon->stereotype==CLASSICON_BOUNDARY) p1.x += CLASSICON_RADIOUS/2.0; text_set_position(cicon->text, &p1); elem->width = w; elem->height = h; p1.x = elem->corner.x + elem->width / 2.0; p1.y = elem->corner.y + CLASSICON_RADIOUS + CLASSICON_ARROW; w = CLASSICON_RADIOUS + CLASSICON_ARROW; h = (CLASSICON_RADIOUS + CLASSICON_ARROW) * M_SQRT1_2; if (is_boundary) p1.x += CLASSICON_RADIOUS/2.0; /* Update connections: */ cicon->connections[0].pos.x = (is_boundary) ? p1.x-2*w: p1.x - h; cicon->connections[0].pos.y = (is_boundary) ? elem->corner.y: p1.y - h; cicon->connections[0].directions = DIR_WEST|DIR_NORTH; cicon->connections[1].pos.x = p1.x; cicon->connections[1].pos.y = p1.y - w; cicon->connections[1].directions = DIR_NORTH; cicon->connections[2].pos.x = p1.x + h; cicon->connections[2].pos.y = p1.y - h; cicon->connections[2].directions = DIR_NORTH|DIR_EAST; cicon->connections[3].pos.x = (is_boundary) ? p1.x-2*w: p1.x - w; cicon->connections[3].pos.y = p1.y; cicon->connections[3].directions = DIR_WEST; cicon->connections[4].pos.x = p1.x + w; cicon->connections[4].pos.y = p1.y; cicon->connections[4].directions = DIR_EAST; cicon->connections[5].pos.x = elem->corner.x; cicon->connections[5].pos.y = elem->corner.y + elem->height; cicon->connections[5].directions = DIR_SOUTH|DIR_WEST; cicon->connections[6].pos.x = p1.x; cicon->connections[6].pos.y = elem->corner.y + elem->height; cicon->connections[6].directions = DIR_SOUTH; cicon->connections[7].pos.x = elem->corner.x + elem->width; cicon->connections[7].pos.y = elem->corner.y + elem->height; cicon->connections[7].directions = DIR_SOUTH|DIR_EAST; cicon->connections[8].pos.x = elem->corner.x + elem->width/2; cicon->connections[8].pos.y = elem->corner.y + elem->height/2; cicon->connections[8].directions = DIR_ALL; element_update_boundingbox(elem); obj->position = elem->corner; obj->position.x += (elem->width + ((is_boundary)?CLASSICON_RADIOUS:0))/2.0; obj->position.y += CLASSICON_RADIOUS + CLASSICON_ARROW; element_update_handles(elem); }
/** * Sets the absolute position for the timestamp. */ void subtitle_set_position(int x, int y) { text_set_position(text_id, x, y); }
static void actor_update_data(Actor *actor, AnchorShape horiz, AnchorShape vert) { Element *elem = &actor->element; DiaObject *obj = &elem->object; ElementBBExtras *extra = &elem->extra_spacing; Point center, bottom_right,p,c; real width, height, dw, dh; real radius, mradius; int i; center = bottom_right = elem->corner; center.x += elem->width/2; bottom_right.x += elem->width; center.y += elem->height/2; bottom_right.y += elem->height; text_calc_boundingbox(actor->text, NULL); width = actor->text->max_width+0.5; height = actor->text->height * (actor->text->numlines + 3); /* added 3 blank lines for top */ /* minimal radius */ mradius=width; if (mradius<height) mradius=height; if (mradius<ACTOR_RADIUS) mradius=ACTOR_RADIUS; /* radius */ radius=elem->width; if (radius<elem->height) radius=elem->height; /* enforce (minimal or resized) radius */ if (radius<mradius) radius=mradius; elem->width=elem->height=radius; /* move shape if necessary ... (untouched) */ switch (horiz) { case ANCHOR_MIDDLE: elem->corner.x = center.x - elem->width/2; break; case ANCHOR_END: elem->corner.x = bottom_right.x - elem->width; break; default: break; } switch (vert) { case ANCHOR_MIDDLE: elem->corner.y = center.y - elem->height/2; break; case ANCHOR_END: elem->corner.y = bottom_right.y - elem->height; break; default: break; } p = elem->corner; p.x += elem->width / 2.0; p.y += elem->height / 2.0 - actor->text->height*actor->text->numlines/2 + actor->text->ascent; text_set_position(actor->text, &p); /* compute connection positions */ c.x = elem->corner.x + elem->width / 2; c.y = elem->corner.y + elem->height / 2; dw = elem->width / 2.0; dh = elem->height / 2.0; for (i = 0; i < NUM_CONNECTIONS-1; i++) { real theta = M_PI / 8.0 * i; /* TODO: Set up directions for autorouting */ actor->connections[i].pos.x = c.x + dw * cos(theta); actor->connections[i].pos.y = c.y - dh * sin(theta); } actor->connections[16].pos.x = c.x; actor->connections[16].pos.y = c.y; extra->border_trans = ACTOR_BORDER_WIDTH / 2.0; element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static void goal_update_data(Goal *goal, AnchorShape horiz, AnchorShape vert) { Element *elem = &goal->element; ElementBBExtras *extra = &elem->extra_spacing; DiaObject *obj = &elem->object; Point center, bottom_right; Point p; real w, h; ConnectionPoint *c; /* save starting points */ center = bottom_right = elem->corner; center.x += elem->width/2; bottom_right.x += elem->width; center.y += elem->height/2; bottom_right.y += elem->height; text_calc_boundingbox(goal->text, NULL); w = goal->text->max_width + goal->padding*2; h = goal->text->height * goal->text->numlines + goal->padding*2; /* autoscale here */ if (w > elem->width) elem->width = w; if (h > elem->height) elem->height = h; if (elem->width<elem->height) elem->width=elem->height; /* move shape if necessary ... */ switch (horiz) { case ANCHOR_MIDDLE: elem->corner.x = center.x - elem->width/2; break; case ANCHOR_END: elem->corner.x = bottom_right.x - elem->width; break; default: break; } switch (vert) { case ANCHOR_MIDDLE: elem->corner.y = center.y - elem->height/2; break; case ANCHOR_END: elem->corner.y = bottom_right.y - elem->height; break; default: break; } p = elem->corner; p.x += elem->width / 2.0; p.y += elem->height / 2.0 - goal->text->height * goal->text->numlines / 2 + goal->text->ascent; text_set_position(goal->text, &p); extra->border_trans = GOAL_LINE_WIDTH; element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); /* Update connections: */ p = elem->corner; w = elem->width; h = elem->height; c = goal->connector; switch (goal->type) { case SOFTGOAL: update_softgoal_connectors(c,p,w,h); break; case GOAL: update_goal_connectors(c,p,w,h); break; } }
static void req_update_data(Requirement *req) { real w, h, ratio; Point c, half, r,p; Element *elem = &req->element; DiaObject *obj = &elem->object; text_calc_boundingbox(req->text, NULL); w = req->text->max_width; h = req->text->height*req->text->numlines; ratio = w/h; if (ratio > REQ_MAX_RATIO) ratio = REQ_MAX_RATIO; if (ratio < REQ_MIN_RATIO) { ratio = REQ_MIN_RATIO; r.y = w / ratio + h; r.x = r.y * ratio; } else { r.x = ratio*h + w; r.y = r.x / ratio; } if (r.x < REQ_WIDTH) r.x = REQ_WIDTH; if (r.y < REQ_HEIGHT) r.y = REQ_HEIGHT; elem->width = r.x; elem->height = r.y; r.x /= 2.0; r.y /= 2.0; c.x = elem->corner.x + elem->width / 2.0; c.y = elem->corner.y + r.y; half.x = r.x * M_SQRT1_2; half.y = r.y * M_SQRT1_2; /* Update connections: */ req->connections[0].pos.x = c.x - half.x; req->connections[0].pos.y = c.y - half.y; req->connections[1].pos.x = c.x; req->connections[1].pos.y = elem->corner.y; req->connections[2].pos.x = c.x + half.x; req->connections[2].pos.y = c.y - half.y; req->connections[3].pos.x = c.x - r.x; req->connections[3].pos.y = c.y; req->connections[4].pos.x = c.x + r.x; req->connections[4].pos.y = c.y; req->connections[5].pos.x = c.x - half.x; req->connections[5].pos.y = c.y + half.y; req->connections[6].pos.x = c.x; req->connections[6].pos.y = elem->corner.y + elem->height; req->connections[7].pos.x = c.x + half.x; req->connections[7].pos.y = c.y + half.y; req->connections[8].pos.x = elem->corner.x + elem->width/2; req->connections[8].pos.y = elem->corner.y + elem->height/2; h = req->text->height*req->text->numlines; p = req->element.corner; p.x += req->element.width/2.0; p.y += (req->element.height - h)/2.0 + req->text->ascent; text_set_position(req->text, &p); element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); /* Boundingbox calculation including the line width */ { Rectangle bbox; ellipse_bbox (&c, elem->width, elem->height, &elem->extra_spacing, &bbox); rectangle_union(&obj->bounding_box, &bbox); } }
static void pgram_update_data(Pgram *pgram, AnchorShape horiz, AnchorShape vert) { Element *elem = &pgram->element; ElementBBExtras *extra = &elem->extra_spacing; DiaObject *obj = &elem->object; Point center, bottom_right; Point p; real offs; real width, height; real avail_width; real top_left; /* save starting points */ center = bottom_right = elem->corner; center.x += elem->width/2; bottom_right.x += elem->width; center.y += elem->height/2; bottom_right.y += elem->height; /* this takes the shearing of the parallelogram into account, so the * text can be extend to the edges of the parallelogram */ text_calc_boundingbox(pgram->text, NULL); height = pgram->text->height * pgram->text->numlines + pgram->padding*2 + pgram->border_width; if ( pgram->text_fitting == TEXTFIT_ALWAYS || (pgram->text_fitting == TEXTFIT_WHEN_NEEDED && height > elem->height)) elem->height = height; avail_width = elem->width - (pgram->padding*2 + pgram->border_width + fabs(pgram->shear_grad) * (elem->height + pgram->text->height * pgram->text->numlines)); if ( pgram->text_fitting == TEXTFIT_ALWAYS || (pgram->text_fitting == TEXTFIT_WHEN_NEEDED && avail_width < pgram->text->max_width)) { elem->width = (elem->width-avail_width) + pgram->text->max_width; avail_width = pgram->text->max_width; } /* width = pgram->text->max_width + pgram->padding*2 + pgram->border_width + fabs(pgram->shear_grad) * (elem->height + pgram->text->height * pgram->text->numlines); if (width > elem->width) elem->width = width; */ /* move shape if necessary ... */ switch (horiz) { case ANCHOR_MIDDLE: elem->corner.x = center.x - elem->width/2; break; case ANCHOR_END: elem->corner.x = bottom_right.x - elem->width; break; default: break; } switch (vert) { case ANCHOR_MIDDLE: elem->corner.y = center.y - elem->height/2; break; case ANCHOR_END: elem->corner.y = bottom_right.y - elem->height; break; default: break; } p = elem->corner; p.x += elem->width / 2.0; p.y += elem->height / 2.0 - pgram->text->height * pgram->text->numlines / 2 + pgram->text->ascent; switch (pgram->text->alignment) { case ALIGN_LEFT: p.x -= avail_width/2; break; case ALIGN_RIGHT: p.x += avail_width/2; break; case ALIGN_CENTER: break; } text_set_position(pgram->text, &p); /* 1/4 of how much more to the left the bottom line is */ offs = -(elem->height / 4.0 * pgram->shear_grad); width = elem->width - 4.0*fabs(offs); top_left = elem->corner.x; if (offs < 0.0) { top_left -= 4*offs; } /* Update connections: */ connpoint_update(&pgram->connections[0], top_left, elem->corner.y, DIR_NORTHWEST); connpoint_update(&pgram->connections[1], top_left + width / 4.0, elem->corner.y, DIR_NORTH); connpoint_update(&pgram->connections[2], top_left + width / 2.0, elem->corner.y, DIR_NORTH); connpoint_update(&pgram->connections[3], top_left + width * 3.0 / 4.0, elem->corner.y, DIR_NORTH); connpoint_update(&pgram->connections[4], top_left + width, elem->corner.y, DIR_NORTHEAST); connpoint_update(&pgram->connections[5], top_left + offs, elem->corner.y + elem->height / 4.0, DIR_WEST); connpoint_update(&pgram->connections[6], top_left + width + offs, elem->corner.y + elem->height / 4.0, DIR_EAST); connpoint_update(&pgram->connections[7], top_left + 2.0 * offs, elem->corner.y + elem->height / 2.0, DIR_WEST); connpoint_update(&pgram->connections[8], top_left + width + 2.0 * offs, elem->corner.y + elem->height / 2.0, DIR_EAST); connpoint_update(&pgram->connections[9], top_left + 3.0 * offs, elem->corner.y + elem->height * 3.0 / 4.0, DIR_WEST); connpoint_update(&pgram->connections[10], top_left + width + 3.0 * offs, elem->corner.y + elem->height * 3.0 / 4.0, DIR_EAST); connpoint_update(&pgram->connections[11], top_left + 4.0 * offs, elem->corner.y + elem->height, DIR_SOUTHWEST); connpoint_update(&pgram->connections[12], top_left + 4.0 * offs + width / 4.0, elem->corner.y + elem->height, DIR_SOUTH); connpoint_update(&pgram->connections[13], top_left + 4.0 * offs + width / 2.0, elem->corner.y + elem->height, DIR_SOUTH); connpoint_update(&pgram->connections[14], top_left + 4.0 * offs + 3.0 * width / 4.0, elem->corner.y + elem->height, DIR_SOUTH); connpoint_update(&pgram->connections[15], top_left + 4.0 * offs + width, elem->corner.y + elem->height, DIR_SOUTHEAST); connpoint_update(&pgram->connections[16], top_left + 2.0 * offs + width / 2, elem->corner.y + elem->height / 2, DIR_ALL); extra->border_trans = pgram->border_width/2.0; element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }
static void objet_update_data(Objet *ob) { Element *elem = &ob->element; DiaObject *obj = &elem->object; DiaFont *font; Point p1, p2; real h, w = 0; text_calc_boundingbox(ob->text, NULL); ob->stereotype = remove_stereotype_from_string(ob->stereotype); if (!ob->st_stereotype) { ob->st_stereotype = string_to_stereotype(ob->stereotype); } font = ob->text->font; h = elem->corner.y + OBJET_MARGIN_Y(ob); if (ob->is_multiple) { h += OBJET_MARGIN_M(ob); } if ((ob->stereotype != NULL) && (ob->stereotype[0] != '\0')) { w = dia_font_string_width(ob->st_stereotype, font, OBJET_FONTHEIGHT(ob)); h += OBJET_FONTHEIGHT(ob); ob->st_pos.y = h; h += OBJET_MARGIN_Y(ob)/2.0; } w = MAX(w, ob->text->max_width); p1.y = h + ob->text->ascent; /* position of text */ h += ob->text->height*ob->text->numlines; if ((ob->exstate != NULL) && (ob->exstate[0] != '\0')) { w = MAX(w, dia_font_string_width(ob->exstate, font, OBJET_FONTHEIGHT(ob))); h += OBJET_FONTHEIGHT(ob); ob->ex_pos.y = h; } h += OBJET_MARGIN_Y(ob); if (ob->show_attributes) { h += OBJET_MARGIN_Y(ob) + ob->attributes->ascent; p2.x = elem->corner.x + OBJET_MARGIN_X(ob); p2.y = h; text_set_position(ob->attributes, &p2); h += ob->attributes->height*ob->attributes->numlines; text_calc_boundingbox(ob->attributes, NULL); w = MAX(w, ob->attributes->max_width); } w += 2*OBJET_MARGIN_X(ob); p1.x = elem->corner.x + w/2.0; text_set_position(ob->text, &p1); ob->ex_pos.x = ob->st_pos.x = p1.x; if (ob->is_multiple) { w += OBJET_MARGIN_M(ob); } elem->width = w; elem->height = h - elem->corner.y; /* Update connections: */ element_update_connections_rectangle(elem, ob->connections); element_update_boundingbox(elem); obj->position = elem->corner; element_update_handles(elem); }