Пример #1
0
/*!
 * \brief Convert _StdPath to one or more _BezierLine/BezierGon
 */
static ObjectChange *
_convert_to_beziers_callback (DiaObject *obj, Point *clicked, gpointer data)
{
  StdPath *stdpath = (StdPath *)obj;
  BezPoint *bezier = stdpath->points;
  GList *list = NULL;
  int i, n = 0;
  ObjectChange *change;

  for (i = 1; i < stdpath->num_points; ++i) {
    if (bezier[i].type == BEZ_MOVE_TO || i+1 == stdpath->num_points) {
      DiaObject *rep;
      int num = bezier[i].type == BEZ_MOVE_TO ? i - n : i - n + 1;
      if (stdpath->stroke_or_fill & PDO_FILL)
	rep = create_standard_beziergon (num, &bezier[n]);
      else
	rep = create_standard_bezierline (num, &bezier[n], NULL, NULL);
      if (!rep) /* no Standard objects? */
	break;
      list = g_list_append (list, rep);
      n = i;
    }
  }
  if (!list) {
    change = change_list_create ();
  } else if (g_list_length (list) == 1) {
    change = object_substitute (obj, (DiaObject *)list->data);
    g_list_free (list);
  } else {
    change = object_substitute (obj, create_standard_group (list));
  }

  return change;
}
Пример #2
0
static ObjectChange *
_textobj_convert_to_path_callback (DiaObject *obj, Point *clicked, gpointer data)
{
  Textobj *textobj = (Textobj *)obj;
  const Text *text = textobj->text;
  DiaObject *path = NULL;

  if (!text_is_empty(text)) /* still screwed with empty lines ;) */
    path = create_standard_path_from_text (text);

  if (path) {
    ObjectChange *change;
    Color bg = textobj->fill_color;

    /* FIXME: otherwise object_substitue() will tint the text with bg */
    textobj->fill_color = text->color;
    change = object_substitute (obj, path);
    /* restore */
    textobj->fill_color = bg;

    return change;
  }
  /* silently fail */
  return change_list_create ();
}
Пример #3
0
Файл: line.c Проект: mpuels/dia
/*!
 * \brief Upgrade the Line to a Zigzagline
 *
 * Convert the _Line to a _Zigzagline with the position clicked (if near enough)
 * for the new segment. The result of this function is more favorable for connected
 * lines by autorouting.
 *
 * Further object properties are preserved by the use of object_substitute()
 *
 * @param obj  self pointer
 * @param clicked  last clicked point on canvas or NULL
 * @param data  here unuesed user_data pointer
 * @return an _ObjectChange to support undo/redo
 *
 * \memberof Line
 */
static ObjectChange *
_convert_to_zigzagline_callback (DiaObject *obj, Point *clicked, gpointer data)
{
  DiaObject *zigzag;
  Line *line = (Line *)obj;
  Point points[4];

  if (clicked) {
    points[0] = line->connection.endpoints[0];
    points[3] = line->connection.endpoints[1];
    /* not sure if we really want to give it a direction at all */
    if (fabs(((points[0].x + points[3].x)/2) - clicked->x) > fabs(((points[0].y + points[3].y)/2) - clicked->y)) {
      points[1].x = points[2].x = clicked->x;
      points[1].y = points[0].y;
      points[2].y = points[3].y;
    } else {
      points[1].y = points[2].y = clicked->y;
      points[1].x = points[0].x;
      points[2].x = points[3].x;
    }
    zigzag = create_standard_zigzagline (4, points, &line->end_arrow, &line->start_arrow);
  } else {
    points[0] = line->connection.endpoints[0];
    points[3] = line->connection.endpoints[1];
    points[1].x = points[2].x = (points[0].x + points[3].x) / 2.0;
    points[1].y = points[0].y;
    points[2].y = points[3].y;
    zigzag = create_standard_zigzagline (4, points, &line->end_arrow, &line->start_arrow);
  }

  g_return_val_if_fail (zigzag != NULL, NULL);
  return object_substitute (obj, zigzag);
}
Пример #4
0
static ObjectChange *
_box_convert_to_path_callback (DiaObject *obj, Point *clicked, gpointer data)
{
  const Box *box = (Box *)obj;
  const Element *elem = &box->element;
  DiaObject *path;
  int num_points;
  BezPoint *points;

  if (box->corner_radius > 0) {
    const real w = elem->width;
    const real h = elem->height;
    const real x = elem->corner.x;
    const real y = elem->corner.y;
    real r = box->corner_radius;
    num_points = 9;
    points = g_alloca (sizeof(BezPoint) * num_points);

    /* avoid r>w/w and r>h/2 */
    r = (w > h ) ? (r > h/2 ? h/2 : r) : (r > w/2 ? w/2 : r);

    points[0].type = BEZ_MOVE_TO;  points[0].p1.x = x + r; points[0].p1.y = y; /* top-left */
    points[1].type = BEZ_LINE_TO;  points[1].p1.x = x + w - r; points[1].p1.y = y; /* top-right */
    points[2].type = BEZ_CURVE_TO; points[2].p1.x = x + w - r; points[2].p1.y = y; /* around */
    points[2].p2.x = x + w; points[2].p2.y = y; points[2].p3.x = x + w; points[2].p3.y = y + r;
    points[3].type = BEZ_LINE_TO; points[3].p1.x =  x + w; points[3].p1.y = y + h - r; /* bottom-right */
    points[4].type = BEZ_CURVE_TO; points[4].p1.x = x + w; points[4].p1.y = y + h - r; /* around */
    points[4].p2.x = x + w; points[4].p2.y = y + h; points[4].p3.x = x + w - r; points[4].p3.y = y + h;
    points[5].type = BEZ_LINE_TO;  points[5].p1.x = x + r; points[5].p1.y = y + h; /* bottom-left */
    points[6].type = BEZ_CURVE_TO; points[6].p1.x = x + r; points[6].p1.y = y + h; /* around */
    points[6].p2.x = x; points[6].p2.y = y + h; points[6].p3.x = x; points[6].p3.y = y + h - r;
    points[7].type = BEZ_LINE_TO;  points[7].p1.x = x; points[7].p1.y = y + r; /* top-left */
    points[8].type = BEZ_CURVE_TO; points[8].p1.x = x; points[8].p1.y = y + r; /* around */
    points[8].p2.x = x; points[8].p2.y = y; points[8].p3.x = x + r; points[8].p3.y = y;
  } else {
    num_points = 5;
    points = g_alloca (sizeof(BezPoint) * num_points);

    points[0].type = BEZ_MOVE_TO;
    points[0].p1 = elem->corner;
    points[1].type = points[2].type = points[3].type = points[4].type = BEZ_LINE_TO;
    points[1].p1.x = elem->corner.x + elem->width;
    points[1].p1.y = elem->corner.y;
    points[2].p1.x = elem->corner.x + elem->width;
    points[2].p1.y = elem->corner.y + elem->height;
    points[3].p1.x = elem->corner.x;
    points[3].p1.y = elem->corner.y + elem->height;
    points[4].p1 = elem->corner;
  }
  path = create_standard_path (num_points, points);
  if (path)
    return object_substitute (obj, path);

  /* Empty change */
  return change_list_create ();
}
Пример #5
0
/*!
 * \brief Upgrade the _Zigzagline to a _Bezierline
 *
 * Accessible through the object's context menu this function substitutes 
 * the _Zigzagline with a _Bezierline. The function creates a favorable
 * representation of the original _OrthConn data of the given object.
 *
 * @param obj  explicit this pointer
 * @param clicked  last clicked point on the canvas or NULL
 * @param data a pointer to extra data, unused here
 * @return  undo/redo information as _ObjectChange
 *
 * \memberof _Zigzagline
 */
static ObjectChange *
_convert_to_bezierline_callback (DiaObject *obj, Point *clicked, gpointer data)
{
  DiaObject *poly;
  Zigzagline *zigzagline = (Zigzagline *)obj;
  OrthConn *orth = &zigzagline->orth;
  BezPoint *bp;
  int i, j, num_points;
  DiaObject *bezier;

  num_points = (orth->numpoints + 1) / 2;
  bp = g_new(BezPoint, num_points);
  bp[0].type = BEZ_MOVE_TO;
  bp[0].p1 = orth->points[0];

  for (i = 1, j = 1; i < num_points && j < orth->numpoints; ++i) {
    bp[i].type = BEZ_CURVE_TO;
    bp[i].p1 = orth->points[j++];
    bp[i].p2 = orth->points[j++];
    if (j + 2 < orth->numpoints) {
      /* if we have more than two points left, use the middle of the segment */
      Point p = { (orth->points[j-1].x + orth->points[j].x) / 2.0,
		  (orth->points[j-1].y + orth->points[j].y) / 2.0 };
      bp[i].p3 = p;
    } else if (j + 2 == orth->numpoints) {
      /* if we one extra point left, use the middle of two segments */
      Point p1 = { (orth->points[j-2].x + orth->points[j-1].x) / 2.0,
		   (orth->points[j-2].y + orth->points[j-1].y) / 2.0 };
      Point p2 = { (orth->points[j-1].x + orth->points[j].x) / 2.0,
		   (orth->points[j-1].y + orth->points[j].y) / 2.0 };
      Point p =  { (p1.x + p2.x) / 2.0, (p1.y + p2.y) / 2.0 };
      bp[i].p3 = p;
      /* also adapt the previous control point */
      bp[i].p2 = p1;
      /* and do the final bezpoint */
      bp[i+1].type = BEZ_CURVE_TO;
      bp[i+1].p1 = p2;
      bp[i+1].p2 = orth->points[j];
      bp[i+1].p3 = orth->points[j+1];
      break;
    } else {
      bp[i].p3 = orth->points[j++];
    }
  }
  bezier = create_standard_bezierline(num_points, bp, &zigzagline->end_arrow, &zigzagline->start_arrow);
  g_free(bp);

  return object_substitute (obj, bezier);
}
Пример #6
0
/*!
 * \brief Convert _Beziergon to _Path
 * \memberof _Beziergon
 */
static ObjectChange *
_beziergon_convert_to_path_callback (DiaObject *obj, Point *clicked, gpointer data)
{
  Beziergon *beziergon = (Beziergon *) obj;
  BezierShape *bez = &beziergon->bezier;
  DiaObject *path = NULL;

  if (bez->bezier.num_points > 1)
    path = create_standard_path (bez->bezier.num_points, bez->bezier.points);

  if (path)
    return object_substitute (obj, path);

  /* just an empty change */
  return change_list_create ();
}
Пример #7
0
Файл: line.c Проект: mpuels/dia
/*!
 * \brief Upgrade the Line to a Polyline
 *
 * Convert the _Line to a _Polyline with the position clicked as third point.
 * Further object properties are preserved by the use of object_substitute()
 *
 * @param obj  self pointer
 * @param clicked  last clicked point on canvas or NULL
 * @param data  here unuesed user_data pointer
 * @return an _ObjectChange to support undo/redo
 *
 * \memberof Line
 */
static ObjectChange *
_convert_to_polyline_callback (DiaObject *obj, Point *clicked, gpointer data)
{
  DiaObject *poly;
  Line *line = (Line *)obj;
  Point points[3];

  points[0] = line->connection.endpoints[0];
  points[2] = line->connection.endpoints[1];
  if (clicked) {
    points[1] = *clicked;
  } else {
    points[1].x = (points[0].x + points[2].x) / 2;
    points[1].y = (points[0].y + points[2].y) / 2;
  }

  poly = create_standard_polyline (3, points, &line->end_arrow, &line->start_arrow);
  g_return_val_if_fail (poly != NULL, NULL);
  return object_substitute (obj, poly);
}