/* is the nearest stem cell in range */ Boolean check_distance(struct distance_result nearest, double major_radius, double minor_radius, double thres) { if (nearest.nearest_distance == -1.0) { return 1; } else { double theta = tan(nearest.nearest_z/nearest.nearest_xy); double er = ellipse_radius(major_radius, minor_radius, theta); return (thres * er < nearest.nearest_distance); } }
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); }