static void beziergon_update_data(Beziergon *beziergon) { BezierShape *bez = &beziergon->bezier; DiaObject *obj = &bez->object; ElementBBExtras *extra = &bez->extra_spacing; beziershape_update_data(bez); extra->border_trans = beziergon->line_width / 2.0; beziershape_update_boundingbox(bez); /* update the enclosing box using the control points */ { int i, num_points = bez->bezier.num_points; obj->enclosing_box = obj->bounding_box; for (i = 0; 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); } } obj->position = bez->bezier.points[0].p1; }
ObjectChange * beziershape_remove_segment(BezierShape *bezier, int pos) { Handle *old_handle1, *old_handle2, *old_handle3; ConnectionPoint *old_cp1, *old_cp2; BezPoint old_point; BezCornerType old_ctype; int next = pos+1; g_assert(pos > 0); g_assert(bezier->numpoints > 2); g_assert(pos < bezier->numpoints); if (pos == bezier->numpoints - 1) next = 1; old_handle1 = bezier->object.handles[3*pos-3]; old_handle2 = bezier->object.handles[3*pos-2]; old_handle3 = bezier->object.handles[3*pos-1]; old_point = bezier->points[pos]; /* remember the old contro point of following bezpoint */ old_point.p1 = bezier->points[next].p1; old_ctype = bezier->corner_types[pos]; old_cp1 = bezier->object.connections[2*pos-2]; old_cp2 = bezier->object.connections[2*pos-1]; object_unconnect((DiaObject *)bezier, old_handle1); object_unconnect((DiaObject *)bezier, old_handle2); object_unconnect((DiaObject *)bezier, old_handle3); remove_handles(bezier, pos); beziershape_update_data(bezier); return beziershape_create_point_change(bezier, TYPE_REMOVE_POINT, &old_point, old_ctype, pos, old_handle1, old_handle2, old_handle3, old_cp1, old_cp2); }
static void beziershape_straighten_corner(BezierShape *bez, int comp_nr) { int next_nr; if (comp_nr == 0) comp_nr = bez->numpoints - 1; next_nr = comp_nr + 1; if (comp_nr == bez->numpoints - 1) next_nr = 1; /* Neat thing would be to have the kind of straigthening depend on which handle was chosen: Mid-handle does average, other leaves that handle where it is. */ bez->points[0].p3 = bez->points[0].p1; switch (bez->corner_types[comp_nr]) { case BEZ_CORNER_SYMMETRIC: { Point pt1, pt2; pt1 = bez->points[comp_nr].p3; point_sub(&pt1, &bez->points[comp_nr].p2); pt2 = bez->points[comp_nr].p3; point_sub(&pt2, &bez->points[next_nr].p1); point_scale(&pt2, -1.0); point_add(&pt1, &pt2); point_scale(&pt1, 0.5); pt2 = pt1; point_scale(&pt1, -1.0); point_add(&pt1, &bez->points[comp_nr].p3); point_add(&pt2, &bez->points[comp_nr].p3); bez->points[comp_nr].p2 = pt1; bez->points[next_nr].p1 = pt2; beziershape_update_data(bez); } break; case BEZ_CORNER_SMOOTH: { Point pt1, pt2; real len1, len2; pt1 = bez->points[comp_nr].p3; point_sub(&pt1, &bez->points[comp_nr].p2); pt2 = bez->points[comp_nr].p3; point_sub(&pt2, &bez->points[next_nr].p1); len1 = point_len(&pt1); len2 = point_len(&pt2); point_scale(&pt2, -1.0); if (len1 > 0) point_normalize(&pt1); if (len2 > 0) point_normalize(&pt2); point_add(&pt1, &pt2); point_scale(&pt1, 0.5); pt2 = pt1; point_scale(&pt1, -len1); point_add(&pt1, &bez->points[comp_nr].p3); point_scale(&pt2, len2); point_add(&pt2, &bez->points[comp_nr].p3); bez->points[comp_nr].p2 = pt1; bez->points[next_nr].p1 = pt2; beziershape_update_data(bez); } break; case BEZ_CORNER_CUSP: break; } bez->points[0].p1 = bez->points[0].p3; }
static void beziergon_select(Beziergon *beziergon, Point *clicked_point, DiaRenderer *interactive_renderer) { beziershape_update_data(&beziergon->bezier); }