/*! * \brief Return the major handle for the control point with the handle closest to * a given point. * @param bezier A bezier connection * @param point A point * @return The major (middle) handle of the bezier control that has the * handle closest to point. * @bug Don't we really want the major handle that's actually closest to * the point? This is used in connection with object menus and could cause * some unexpected selection of handles if a different segment has a control * point close to the major handle. */ Handle * bezierconn_closest_major_handle (BezierConn *bezier, Point *point) { Handle *closest = bezierconn_closest_handle(bezier, point); return bezier->object.handles[3*get_major_nr(get_handle_nr(bezier, closest))]; }
Handle * beziershape_closest_major_handle(BezierShape *bezier, Point *point) { Handle *closest = beziershape_closest_handle(bezier, point); int pos = get_major_nr(get_handle_nr(bezier, closest)); if (pos == 0) pos = bezier->numpoints - 1; return bezier->object.handles[3*pos - 1]; }
ObjectChange * beziershape_set_corner_type(BezierShape *bez, Handle *handle, BezCornerType corner_type) { Handle *mid_handle = NULL; Point old_left, old_right; int old_type; int handle_nr, comp_nr; handle_nr = get_handle_nr(bez, handle); switch (handle->id) { case HANDLE_BEZMAJOR: mid_handle = handle; break; case HANDLE_LEFTCTRL: handle_nr++; if (handle_nr == bez->object.num_handles) handle_nr = 0; mid_handle = bez->object.handles[handle_nr]; break; case HANDLE_RIGHTCTRL: handle_nr--; if (handle_nr < 0) handle_nr = bez->object.num_handles - 1; mid_handle = bez->object.handles[handle_nr]; break; default: g_assert_not_reached(); break; } comp_nr = get_major_nr(handle_nr); old_type = bez->corner_types[comp_nr]; old_left = bez->points[comp_nr].p2; if (comp_nr == bez->numpoints - 1) old_right = bez->points[1].p1; else old_right = bez->points[comp_nr+1].p1; #if 0 g_message("Setting corner type on segment %d to %s", comp_nr, corner_type == BEZ_CORNER_SYMMETRIC ? "symmetric" : corner_type == BEZ_CORNER_SMOOTH ? "smooth" : "cusp"); #endif bez->corner_types[comp_nr] = corner_type; if (comp_nr == 0) bez->corner_types[bez->numpoints-1] = corner_type; else if (comp_nr == bez->numpoints - 1) bez->corner_types[0] = corner_type; beziershape_straighten_corner(bez, comp_nr); return beziershape_create_corner_change(bez, mid_handle, &old_left, &old_right, old_type, corner_type); }
/** Change the corner type of a bezier line. * @param bezier The bezierconn that has the corner * @param handle The handle whose corner should be set. * @param corner_type What type of corner the handle should have. * @returns Undo information about the corner change. */ ObjectChange * bezierconn_set_corner_type (BezierConn *bezier, Handle *handle, BezCornerType corner_type) { Handle *mid_handle; Point old_left, old_right; int old_type; int handle_nr, comp_nr; handle_nr = get_handle_nr(bezier, handle); switch (handle->id) { case HANDLE_BEZMAJOR: mid_handle = handle; break; case HANDLE_LEFTCTRL: handle_nr++; mid_handle = bezier->object.handles[handle_nr]; break; case HANDLE_RIGHTCTRL: handle_nr--; mid_handle = bezier->object.handles[handle_nr]; break; default: g_warning("Internal error: Setting corner type of endpoint of bezier"); return NULL; } comp_nr = get_major_nr(handle_nr); old_type = bezier->bezier.corner_types[comp_nr]; old_left = bezier->bezier.points[comp_nr].p2; old_right = bezier->bezier.points[comp_nr+1].p1; bezier->bezier.corner_types[comp_nr] = corner_type; bezierconn_straighten_corner(bezier, comp_nr); return bezierconn_create_corner_change(bezier, mid_handle, &old_left, &old_right, old_type, corner_type); }