예제 #1
0
/*!
 * \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))];
}
예제 #2
0
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];
}
예제 #3
0
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);
}
예제 #4
0
/** 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);
}