Beispiel #1
0
static void
polyline_update_data(Polyline *polyline)
{
  PolyConn *poly = &polyline->poly;
  DiaObject *obj = &poly->object;
  PolyBBExtras *extra = &poly->extra_spacing;
  Point gap_endpoints[2];

  polyconn_update_data(&polyline->poly);

  extra->start_trans =  (polyline->line_width / 2.0);
  extra->end_trans =     (polyline->line_width / 2.0);
  extra->middle_trans = (polyline->line_width / 2.0);
  extra->start_long = (polyline->line_width / 2.0);
  extra->end_long   = (polyline->line_width / 2.0);

  polyline_calculate_gap_endpoints(polyline, gap_endpoints);
  polyline_exchange_gap_points(polyline, gap_endpoints);

  polyconn_update_boundingbox(poly);

  if (polyline->start_arrow.type != ARROW_NONE) {
    Rectangle bbox;
    Point move_arrow, move_line;
    Point to = gap_endpoints[0];
    Point from = poly->points[1];
    calculate_arrow_point(&polyline->start_arrow, &to, &from,
                          &move_arrow, &move_line, polyline->line_width);
    /* move them */
    point_sub(&to, &move_arrow);
    point_sub(&from, &move_line);

    arrow_bbox (&polyline->start_arrow, polyline->line_width, &to, &from, &bbox);
    rectangle_union (&obj->bounding_box, &bbox);
  }
  if (polyline->end_arrow.type != ARROW_NONE) {
    Rectangle bbox;
    int n = polyline->poly.numpoints;
    Point move_arrow, move_line;
    Point to = gap_endpoints[1];
    Point from = poly->points[n-2];
    calculate_arrow_point(&polyline->end_arrow, &to, &from,
                          &move_arrow, &move_line, polyline->line_width);
    /* move them */
    point_sub(&to, &move_arrow);
    point_sub(&from, &move_line);

    arrow_bbox (&polyline->end_arrow, polyline->line_width, &to, &from, &bbox);
    rectangle_union (&obj->bounding_box, &bbox);
  }

  polyline_exchange_gap_points(polyline, gap_endpoints);

  obj->position = poly->points[0];
}
Beispiel #2
0
static void
zigzagline_update_data(Zigzagline *zigzagline)
{
  OrthConn *orth = &zigzagline->orth;
  DiaObject *obj = &orth->object;
  PolyBBExtras *extra = &orth->extra_spacing;

  orthconn_update_data(&zigzagline->orth);
    
  extra->start_long = 
    extra->end_long = 
    extra->middle_trans = 
    extra->start_trans =
    extra->end_trans = (zigzagline->line_width / 2.0);

  orthconn_update_boundingbox(orth);

  if (zigzagline->start_arrow.type != ARROW_NONE) {
    Rectangle bbox;
    Point move_arrow, move_line;
    Point to = orth->points[0];
    Point from = orth->points[1];
    calculate_arrow_point(&zigzagline->start_arrow, &to, &from,
                          &move_arrow, &move_line, zigzagline->line_width);
    /* move them */
    point_sub(&to, &move_arrow);
    point_sub(&from, &move_line);

    arrow_bbox (&zigzagline->start_arrow, zigzagline->line_width, &to, &from, &bbox);
    rectangle_union (&obj->bounding_box, &bbox);
  }
  if (zigzagline->end_arrow.type != ARROW_NONE) {
    Rectangle bbox;
    Point move_arrow, move_line;
    int n = orth->numpoints;
    Point to = orth->points[n-1];
    Point from = orth->points[n-2];
    calculate_arrow_point(&zigzagline->end_arrow, &to, &from,
                          &move_arrow, &move_line, zigzagline->line_width);
    /* move them */
    point_sub(&to, &move_arrow);
    point_sub(&from, &move_line);

    arrow_bbox (&zigzagline->end_arrow, zigzagline->line_width, &to, &from, &bbox);
    rectangle_union (&obj->bounding_box, &bbox);
  }
}
Beispiel #3
0
Datei: line.c Projekt: mpuels/dia
static void
line_update_data(Line *line)
{
  Connection *conn = &line->connection;
  DiaObject *obj = &conn->object;
  LineBBExtras *extra = &conn->extra_spacing;
  Point start, end;

  extra->start_trans =
  extra->end_trans   =
  extra->start_long  =
  extra->end_long    = (line->line_width / 2.0);

  if (connpoint_is_autogap(line->connection.endpoint_handles[0].connected_to) ||
      connpoint_is_autogap(line->connection.endpoint_handles[1].connected_to)) {
    connection_adjust_for_autogap(conn);
  }
  if (line->absolute_start_gap || line->absolute_end_gap ) {
    Point gap_endpoints[2];

    line_adjust_for_absolute_gap(line, gap_endpoints);
    line_bbox(&gap_endpoints[0],&gap_endpoints[1],
	      &conn->extra_spacing,&conn->object.bounding_box);
    start = gap_endpoints[0];
    end = gap_endpoints[1];
  } else {
    connection_update_boundingbox(conn);
    start = conn->endpoints[0];
    end = conn->endpoints[1];
  }
  if (line->start_arrow.type != ARROW_NONE) {
    Rectangle bbox;
    Point move_arrow, move_line;
    Point to = start;
    Point from = end;
    calculate_arrow_point(&line->start_arrow, &to, &from,
                          &move_arrow, &move_line, line->line_width);
    /* move them */
    point_sub(&to, &move_arrow);
    point_sub(&from, &move_line);

    arrow_bbox (&line->start_arrow, line->line_width, &to, &from, &bbox);
    rectangle_union (&obj->bounding_box, &bbox);
  }
  if (line->end_arrow.type != ARROW_NONE) {
    Rectangle bbox;
    Point move_arrow, move_line;
    Point to = end;
    Point from = start;
    calculate_arrow_point(&line->end_arrow, &to, &from,
                          &move_arrow, &move_line, line->line_width);
    /* move them */
    point_sub(&to, &move_arrow);
    point_sub(&from, &move_line);

    arrow_bbox (&line->end_arrow, line->line_width, &to, &from, &bbox);
    rectangle_union (&obj->bounding_box, &bbox);
  }

  obj->position = conn->endpoints[0];

  connpointline_update(line->cpl);
  connpointline_putonaline(line->cpl, &start, &end, DIR_ALL);
  
  connection_update_handles(conn);
}
Beispiel #4
0
static void
bezierline_update_data(Bezierline *bezierline)
{
  BezierConn *bez = &bezierline->bez;
  DiaObject *obj = &bez->object;
  PolyBBExtras *extra = &bez->extra_spacing;

  bezierconn_update_data(bez);

  extra->start_trans = extra->start_long =
  extra->middle_trans =
  extra->end_trans = extra->end_long = (bezierline->line_width / 2.0);

  obj->position = bez->bezier.points[0].p1;

  if (connpoint_is_autogap(bez->object.handles[0]->connected_to) ||
      connpoint_is_autogap(bez->object.handles[3*(bez->bezier.num_points-1)]->connected_to) ||
      bezierline->absolute_start_gap || bezierline->absolute_end_gap ||
      bezierline->start_arrow.type != ARROW_NONE || bezierline->end_arrow.type != ARROW_NONE) {
    Point gap_points[4];
    Rectangle bbox_union = {bez->bezier.points[0].p1.x, bez->bezier.points[0].p1.y,
			    bez->bezier.points[0].p1.x, bez->bezier.points[0].p1.y};
    compute_gap_points(bezierline, gap_points);
    exchange_bez_gap_points(bez,gap_points);
    /* further modifying the points data, accounts for corrcet arrow and bezier bounding box */
    if (bezierline->start_arrow.type != ARROW_NONE) {
      Rectangle bbox;
      Point move_arrow, move_line;
      Point to = bez->bezier.points[0].p1, from = bez->bezier.points[1].p1;

      calculate_arrow_point(&bezierline->start_arrow, &to, &from, &move_arrow, &move_line, bezierline->line_width);
      point_sub(&to, &move_arrow);
      point_sub(&bez->bezier.points[0].p1, &move_line);
      arrow_bbox (&bezierline->start_arrow, bezierline->line_width, &to, &from, &bbox);
      rectangle_union (&bbox_union, &bbox);
    }
    if (bezierline->end_arrow.type != ARROW_NONE) {
      Rectangle bbox;
      Point move_arrow, move_line;
      int num_points = bez->bezier.num_points;
      Point to = bez->bezier.points[num_points-1].p3, from = bez->bezier.points[num_points-1].p2;

      calculate_arrow_point(&bezierline->end_arrow, &to, &from, &move_arrow, &move_line, bezierline->line_width);
      point_sub(&to, &move_arrow);
      point_sub(&bez->bezier.points[num_points-1].p3, &move_line);
      arrow_bbox (&bezierline->end_arrow, bezierline->line_width, &to, &from, &bbox);
      rectangle_union (&bbox_union, &bbox);
    }
    bezierconn_update_boundingbox(bez);
    rectangle_union (&obj->bounding_box, &bbox_union);
    exchange_bez_gap_points(bez,gap_points);
  } else {
    bezierconn_update_boundingbox(bez);
  }
    /* add control points to the bounding box, needed to make them visible when showing all
      * and to remove traces from them */
  {
    int i, num_points = bez->bezier.num_points;
    g_assert (obj->enclosing_box != NULL);
    *obj->enclosing_box = obj->bounding_box;
    /* starting with the second point, the first one is MOVE_TO */
    for (i = 1; 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);
    }
  }
}
Beispiel #5
0
static void
arc_update_data(Arc *arc)
{
    Connection *conn = &arc->connection;
    LineBBExtras *extra =&conn->extra_spacing;
    DiaObject *obj = &conn->object;
    Point *endpoints;
    real x1,y1,x2,y2,xc,yc;
    real lensq, alpha, radius;
    real angle1, angle2;
    gboolean righthand;

    endpoints = &arc->connection.endpoints[0];
    x1 = endpoints[0].x;
    y1 = endpoints[0].y;
    x2 = endpoints[1].x;
    y2 = endpoints[1].y;

    lensq = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
    if (fabs(arc->curve_distance) > 0.01)
        radius = lensq/(8*arc->curve_distance) + arc->curve_distance/2.0;
    else
        radius = 0.0; /* not really but used for bbox calculation below */

    if (lensq == 0.0 || arc_is_line (arc))
        alpha = 1.0; /* arbitrary, but /not/ 1/0  */
    else
        alpha = (radius - arc->curve_distance) / sqrt(lensq);

    xc = (x1 + x2) / 2.0 + (y2 - y1)*alpha;
    yc = (y1 + y2) / 2.0 + (x1 - x2)*alpha;

    angle1 = -atan2(y1-yc, x1-xc)*180.0/M_PI;
    if (angle1<0)
        angle1+=360.0;
    angle2 = -atan2(y2-yc, x2-xc)*180.0/M_PI;
    if (angle2<0)
        angle2+=360.0;

    if (radius<0.0) {
        real tmp;
        tmp = angle1;
        angle1 = angle2;
        angle2 = tmp;
        radius = -radius;
    }

    arc->radius = radius;
    arc->center.x = xc;
    arc->center.y = yc;
    arc->angle1 = angle1;
    arc->angle2 = angle2;

    /* LineBBExtras not applicable to calculate the arrows bounding box */
    extra->start_trans =
        extra->end_trans   =
            extra->start_long  =
                extra->end_long    = (arc->line_width / 2.0);

    /* updates midpoint */
    arc_update_handles(arc);
    /* startpoint, midpoint, endpoint */
    righthand = is_right_hand (&endpoints[0], &arc->middle_handle.pos, &endpoints[1]);
    connection_update_boundingbox(conn);

    /* fix boundingbox for arc's special shape XXX find a more elegant way: */
    if (in_angle(0, arc->angle1, arc->angle2)) {
        /* rigth side, y does not matter if included */
        Point pt = { arc->center.x + arc->radius + (arc->line_width / 2.0), y1 };
        rectangle_add_point (&obj->bounding_box, &pt);
    }
    if (in_angle(90, arc->angle1, arc->angle2)) {
        /* top side, x does not matter if included */
        Point pt = {x1, arc->center.y - arc->radius - (arc->line_width / 2.0) };
        rectangle_add_point (&obj->bounding_box, &pt);
    }
    if (in_angle(180, arc->angle1, arc->angle2)) {
        /* left side, y does not matter if included */
        Point pt = { arc->center.x - arc->radius - (arc->line_width / 2.0), y1 };
        rectangle_add_point (&obj->bounding_box, &pt);
    }
    if (in_angle(270, arc->angle1, arc->angle2)) {
        /* bootom side, x does not matter if included */
        Point pt = { x1, arc->center.y + arc->radius + (arc->line_width / 2.0) };
        rectangle_add_point (&obj->bounding_box, &pt);
    }
    if (arc->start_arrow.type != ARROW_NONE) {
        /* a good from-point would be the chord of arrow length, but draw_arc_with_arrows currently uses the tangent
         * For big arcs the difference is not huge and the minimum size of small arcs should be limited by the arror length.
         */
        Rectangle bbox = {0,};
        real tmp;
        Point move_arrow, move_line;
        Point to = arc->connection.endpoints[0];
        Point from = to;
        point_sub (&from, &arc->center);
        tmp = from.x;
        if (righthand)
            from.x = -from.y, from.y = tmp;
        else
            from.x = from.y, from.y = -tmp;
        point_add (&from, &to);

        calculate_arrow_point(&arc->start_arrow, &to, &from,
                              &move_arrow, &move_line, arc->line_width);
        /* move them */
        point_sub(&to, &move_arrow);
        point_sub(&from, &move_line);
        arrow_bbox(&arc->start_arrow, arc->line_width, &to, &from, &bbox);
        rectangle_union(&obj->bounding_box, &bbox);
    }
    if (arc->end_arrow.type != ARROW_NONE) {
        Rectangle bbox = {0,};
        real tmp;
        Point move_arrow, move_line;
        Point to = arc->connection.endpoints[1];
        Point from = to;
        point_sub (&from, &arc->center);
        tmp = from.x;
        if (righthand)
            from.x = from.y, from.y = -tmp;
        else
            from.x = -from.y, from.y = tmp;
        point_add (&from, &to);
        calculate_arrow_point(&arc->end_arrow, &to, &from,
                              &move_arrow, &move_line, arc->line_width);
        /* move them */
        point_sub(&to, &move_arrow);
        point_sub(&from, &move_line);
        arrow_bbox(&arc->end_arrow, arc->line_width, &to, &from, &bbox);
        rectangle_union(&obj->bounding_box, &bbox);
    }
    /* if selected put the centerpoint in the box, too. */
    obj->enclosing_box = obj->bounding_box;
    rectangle_add_point(&obj->enclosing_box, &arc->center);

    obj->position = conn->endpoints[0];
}