示例#1
0
static BezPoint *transform_spline(int npoints, Point *points, gboolean closed) {
    BezPoint *bezpoints = g_new(BezPoint, npoints);
    int i;
    Point vector;

    for (i = 0; i < npoints; i++) {
	bezpoints[i].p3 = points[i];
	bezpoints[i].type = BEZ_CURVE_TO;
    }
    bezpoints[0].type = BEZ_MOVE_TO;
    bezpoints[0].p1 = points[0];
    for (i = 1; i < npoints-1; i++) {
	bezpoints[i].p2 = points[i];
	bezpoints[i+1].p1 = points[i];
	vector = points[i-1];
	point_sub(&vector, &points[i+1]);
	point_scale(&vector, -TENSION);
	point_sub(&bezpoints[i].p2, &vector);
	point_add(&bezpoints[i+1].p1, &vector);
    }
    if (closed) {
	bezpoints[npoints-1].p2 = points[i];
	bezpoints[1].p1 = points[i];
	vector = points[npoints-2];
	point_sub(&vector, &points[1]);
	point_scale(&vector, -TENSION);
	point_sub(&bezpoints[npoints-1].p2, &vector);
	point_add(&bezpoints[1].p1, &vector);
    } else {
	bezpoints[1].p1 = points[0];
	bezpoints[npoints-1].p2 = bezpoints[npoints-1].p3;
    }
    return bezpoints;
}
示例#2
0
文件: arrow.c 项目: montsuqi/monpe
static void draw_dot(DiaRenderer *renderer,
		     Point *end, Point *vect, Color *col)
{
  DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
  Point vv,vp,vt,pt;
  real vlen;
  vv = *end;
  point_sub(&vv,vect);
  vlen = distance_point_point(vect,end);
  if (vlen < 1E-7) return;
  point_scale(&vv,1/vlen);

  vp.y = vv.x;
  vp.x = -vv.y;

  pt = *end;
    vt = vp;
  point_scale(&vt,ARROW_DOT_WOFFSET);
  point_add(&pt,&vt);
  vt = vv;
  point_scale(&vt,-ARROW_DOT_LOFFSET);
  point_add(&pt,&vt);
  
  renderer_ops->set_fillstyle(renderer,FILLSTYLE_SOLID);
  renderer_ops->fill_ellipse(renderer,&pt,
			 ARROW_DOT_RADIUS,ARROW_DOT_RADIUS,
			 col);
}
示例#3
0
static void
implements_update_data(Implements *implements)
{
  Connection *conn = &implements->connection;
  Object *obj = (Object *) implements;
  Point delta;
  Point point;
  real len;
  Rectangle rect;
  

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

  implements->text_handle.pos = implements->text_pos;

  /* circle handle/center pos: */
  delta = conn->endpoints[0];
  point_sub(&delta, &conn->endpoints[1]);
  len = sqrt(point_dot(&delta, &delta));
  delta.x /= len; delta.y /= len;

  point = delta;
  point_scale(&point, implements->circle_diameter);
  point_add(&point, &conn->endpoints[1]);
  implements->circle_handle.pos = point;

  point = delta;
  point_scale(&point, implements->circle_diameter/2.0);
  point_add(&point, &conn->endpoints[1]);
  implements->circle_center = point;

  connection_update_handles(conn);

  /* Boundingbox: */
  connection_update_boundingbox(conn);

  /* Add boundingbox for circle: */
  rect.left = implements->circle_center.x - implements->circle_diameter/2.0;
  rect.right = implements->circle_center.x + implements->circle_diameter/2.0;
  rect.top = implements->circle_center.y - implements->circle_diameter/2.0;
  rect.bottom = implements->circle_center.y + implements->circle_diameter/2.0;
  rectangle_union(&obj->bounding_box, &rect);

  /* Add boundingbox for text: */
  rect.left = implements->text_pos.x;
  rect.right = rect.left + implements->text_width;
  rect.top = implements->text_pos.y - font_ascent(implements_font, IMPLEMENTS_FONTHEIGHT);
  rect.bottom = rect.top + IMPLEMENTS_FONTHEIGHT;
  rectangle_union(&obj->bounding_box, &rect);

  /* fix boundingbox for implements_width: */
  obj->bounding_box.top -= IMPLEMENTS_WIDTH/2;
  obj->bounding_box.left -= IMPLEMENTS_WIDTH/2;
  obj->bounding_box.bottom += IMPLEMENTS_WIDTH/2;
  obj->bounding_box.right += IMPLEMENTS_WIDTH/2;

}
static void
rendobj_update_data(RenderObject *rend_obj)
{
  Point p;
  const RenderObjectDescriptor *desc;
  Element *elem;
  Object *obj;
  int i;

  elem = &rend_obj->element;
  obj = &elem->object;
  desc = rend_obj->desc;

  rend_obj->magnify = elem->width / rend_obj->desc->width;
  
  /* Update connections: */
  for (i=0;i<desc->num_connection_points;i++) {
    rend_obj->connections[i].pos = desc->connection_points[i];
    point_scale(&rend_obj->connections[i].pos, rend_obj->magnify);
    point_add(&rend_obj->connections[i].pos, &elem->corner);
  }

  if (desc->use_text) {
    p = desc->text_pos;
    point_scale(&p, rend_obj->magnify);
    point_add(&p, &elem->corner);
    p.y += rend_obj->text->ascent;
    text_set_position(rend_obj->text, &p);
  }
  
  element_update_boundingbox(elem);
  /* fix boundingbox for extra_border: */
  obj->bounding_box.top -= desc->extra_border;
  obj->bounding_box.left -= desc->extra_border;
  obj->bounding_box.bottom += desc->extra_border;
  obj->bounding_box.right += desc->extra_border;

  if (desc->use_text) {
    Rectangle text_box;
    
    text_calc_boundingbox(rend_obj->text, &text_box);
    rectangle_union(&obj->bounding_box, &text_box);
  }
  
  obj->position = elem->corner;

  p = desc->move_position;
  point_scale(&p, rend_obj->magnify);
  point_add(&obj->position, &p);
  
  element_update_handles(elem);
}
示例#5
0
static void
annotation_draw(Annotation *annotation, DiaRenderer *renderer)
{
  Point *endpoints;
  Point vect,rvect,v1,v2;
  Point pts[4];
  real vlen;
  DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);

  assert(annotation != NULL);
  assert(renderer != NULL);

  endpoints = &annotation->connection.endpoints[0];
  
  renderer_ops->set_linewidth(renderer, ANNOTATION_LINE_WIDTH);
  renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID);
  renderer_ops->set_linecaps(renderer, LINECAPS_BUTT);

  vect = annotation->connection.endpoints[1];
  point_sub(&vect,&annotation->connection.endpoints[0]);
  vlen = distance_point_point(&annotation->connection.endpoints[0],
			      &annotation->connection.endpoints[1]);
  if (vlen > 0.0) {
    /* draw the squiggle */
    point_scale(&vect,1/vlen);
    rvect.y = vect.x;
    rvect.x = -vect.y;
  
    pts[0] = annotation->connection.endpoints[0];
    pts[1] = annotation->connection.endpoints[0];
    v1 = vect;
    point_scale(&v1,.5*vlen);
    point_add(&pts[1],&v1);
    pts[2] = pts[1];
    /* pts[1] and pts[2] are currently both at the middle of (pts[0],pts[3]) */
    v1 = vect;
    point_scale(&v1,ANNOTATION_ZLEN);
    v2 = rvect;
    point_scale(&v2,ANNOTATION_ZLEN);
    point_sub(&v1,&v2);
    point_add(&pts[1],&v1);
    point_sub(&pts[2],&v1);
    pts[3] = annotation->connection.endpoints[1];
    renderer_ops->draw_polyline(renderer,
			     pts, sizeof(pts) / sizeof(pts[0]),
			     &color_black);
  }
  text_draw(annotation->text,renderer);
}
示例#6
0
文件: bezier.c 项目: GNOME/dia
static ObjectChange*
bezierline_move_handle(Bezierline *bezierline, Handle *handle,
		       Point *to, ConnectionPoint *cp,
		       HandleMoveReason reason, ModifierKeys modifiers)
{
  assert(bezierline!=NULL);
  assert(handle!=NULL);
  assert(to!=NULL);

  if (reason == HANDLE_MOVE_CREATE || reason == HANDLE_MOVE_CREATE_FINAL) {
    /* During creation, change the control points */
    BezierConn *bez = &bezierline->bez;
    Point dist = bez->bezier.points[0].p1;

    point_sub(&dist, to);
    dist.y = 0;
    point_scale(&dist, 0.332);

    bezierconn_move_handle(bez, handle, to, cp, reason, modifiers);

    bez->bezier.points[1].p1 = bez->bezier.points[0].p1;
    point_sub(&bez->bezier.points[1].p1, &dist);
    bez->bezier.points[1].p2 = *to;
    point_add(&bez->bezier.points[1].p2, &dist);
  } else {
    bezierconn_move_handle(&bezierline->bez, handle, to, cp, reason, modifiers);
  }

  bezierline_update_data(bezierline);

  return NULL;
}
示例#7
0
文件: arrow.c 项目: montsuqi/monpe
static void draw_tunnel(DiaRenderer *renderer,
			     Point *end, Point *vect, Color *col)
{
  DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
  Point vv,vp,vt1,vt2;
  BezPoint curve1[2];
  BezPoint curve2[2];

  real vlen;
  vv = *end;
  point_sub(&vv,vect);
  vlen = distance_point_point(vect,end);
  if (vlen < 1E-7) return;
  point_scale(&vv,1/vlen);
  vp.y = vv.x;
  vp.x = -vv.y;

  curve1[0].type = curve2[0].type = BEZ_MOVE_TO;
  curve1[0].p1   = curve2[0].p1   = *end;
  vt1 = vv;
  point_scale(&vt1,-ARROW_PARENS_LOFFSET - (.5*ARROW_PARENS_LENGTH));
  point_add(&curve1[0].p1,&vt1); point_add(&curve2[0].p1,&vt1); 
                                           /* gcc, work for me, please. */
  vt2 = vp;
  point_scale(&vt2,ARROW_PARENS_WOFFSET);
  point_add(&curve1[0].p1,&vt2);  point_sub(&curve2[0].p1,&vt2);

  vt2 = vp;
  vt1 = vv;
  point_scale(&vt1,2.0*ARROW_PARENS_LENGTH / 6.0);
  point_scale(&vt2,ARROW_PARENS_LENGTH / 6.0);
  curve1[1].type = curve2[1].type = BEZ_CURVE_TO;
  curve1[1].p1 = curve1[0].p1;  curve2[1].p1 = curve2[0].p1;
  point_add(&curve1[1].p1,&vt1);  point_add(&curve2[1].p1,&vt1); 
  point_add(&curve1[1].p1,&vt2);  point_sub(&curve2[1].p1,&vt2); 
  curve1[1].p2 = curve1[1].p1;  curve2[1].p2 = curve2[1].p1;
  point_add(&curve1[1].p2,&vt1);  point_add(&curve2[1].p2,&vt1); 
  curve1[1].p3 = curve1[1].p2;  curve2[1].p3 = curve2[1].p2;
  point_add(&curve1[1].p3,&vt1);  point_add(&curve2[1].p3,&vt1); 
  point_sub(&curve1[1].p3,&vt2);  point_add(&curve2[1].p3,&vt2); 

  renderer_ops->draw_bezier(renderer,curve1,2,col);
  renderer_ops->draw_bezier(renderer,curve2,2,col);
}
示例#8
0
void
point_convex(Point *dst, const Point *src1, const Point *src2, real alpha)
{
  /* Make convex combination of src1 and src2:
     dst = alpha * src1 + (1-alpha) * src2;
  */
  point_copy(dst,src1);
  point_scale(dst,alpha);
  point_add_scaled(dst,src2,1.0 - alpha);
}
示例#9
0
static void
scroll_motion(ScrollTool *tool, GdkEventMotion *event,
	      DDisplay *ddisp)
{
  Point to;
  Point delta;

  /* set the cursor appropriately, and change use_hand if needed */
  if (!tool->scrolling) {
    /* try to minimise the number of cursor type changes */
    if ((event->state & GDK_SHIFT_MASK) != 0) {
      if (!tool->use_hand) {
	tool->use_hand = TRUE;
	if (!open_hand_cursor)
	  open_hand_cursor = create_cursor(ddisp->canvas->window,
					   hand_open_data_bits,
					   hand_open_data_width,
					   hand_open_data_height,
					   hand_open_mask_bits,
					   hand_open_data_width/2,
					   hand_open_data_height/2);
	ddisplay_set_all_cursor(open_hand_cursor);
      }
    } else
      if (tool->use_hand) {
	tool->use_hand = FALSE;
	ddisplay_set_all_cursor(scroll_cursor);
      }
    return;
  }

  ddisplay_untransform_coords(ddisp, event->x, event->y, &to.x, &to.y);

  if (tool->use_hand) {
    delta = tool->last_pos;
    point_sub(&delta, &to);

    tool->last_pos = to;
    point_add(&tool->last_pos, &delta);

    /* we use this so you can scroll past the edge of the image */
    point_add(&delta, &ddisp->origo);
    ddisplay_set_origo(ddisp, delta.x, delta.y);
    ddisplay_update_scrollbars(ddisp);
    ddisplay_add_update_all(ddisp);
  } else {
    delta = to;
    point_sub(&delta, &tool->last_pos);
    point_scale(&delta, 0.5);

    ddisplay_scroll(ddisp, &delta);
    tool->last_pos = to;
  }
  ddisplay_flush(ddisp);
}
示例#10
0
/*!
 * \brief Limit movability of control handles
 *
 * Update a corner to have less freedom in its control handles, arranging
 * the control points at some reasonable places.
 * @param bezier A bezierconn to straighten a corner of
 * @param comp_nr The index into the corner_types array of the corner to
 *                straighten.
 * \memberof _BezierConn
 */
static void
bezierconn_straighten_corner (BezierConn *bezier, int comp_nr)
{
  int next_nr = comp_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. */
  switch (bezier->bezier.corner_types[comp_nr]) {
  case BEZ_CORNER_SYMMETRIC: {
    Point pt1, pt2;

    pt1 = bezier->bezier.points[comp_nr].p3;
    point_sub(&pt1, &bezier->bezier.points[comp_nr].p2);
    pt2 = bezier->bezier.points[comp_nr].p3;
    point_sub(&pt2, &bezier->bezier.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, &bezier->bezier.points[comp_nr].p3);
    point_add(&pt2, &bezier->bezier.points[comp_nr].p3);
    bezier->bezier.points[comp_nr].p2 = pt1;
    bezier->bezier.points[next_nr].p1 = pt2;
    bezierconn_update_data(bezier);
  }
  break;
  case BEZ_CORNER_SMOOTH: {
    Point pt1, pt2;
    real len1, len2;
    pt1 = bezier->bezier.points[comp_nr].p3;
    point_sub(&pt1, &bezier->bezier.points[comp_nr].p2);
    pt2 = bezier->bezier.points[comp_nr].p3;
    point_sub(&pt2, &bezier->bezier.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, &bezier->bezier.points[comp_nr].p3);
    point_scale(&pt2, len2);
    point_add(&pt2, &bezier->bezier.points[comp_nr].p3);
    bezier->bezier.points[comp_nr].p2 = pt1;
    bezier->bezier.points[next_nr].p1 = pt2;
    bezierconn_update_data(bezier);
  }
    break;
  case BEZ_CORNER_CUSP:
    break;
  }
}
示例#11
0
文件: rib.c 项目: ibaned/tetknife
static point center_of_mass(unsigned n, point o[])
{
  point com;
  unsigned i;
  unsigned long tn;
  com = point_zero;
  for (i = 0; i < n; ++i)
    com = point_add(com, o[i]);
  mpi_add_doubles(comm_mpi(), point_arr(&com), 3);
  tn = mpi_add_ulong(comm_mpi(), n);
  return point_scale(com, 1.0 / tn);
}
示例#12
0
static void
rendobj_move(RenderObject *rend_obj, Point *to)
{
  Point p;

  p = rend_obj->desc->move_position;
  rend_obj->element.corner = *to;
  point_scale(&p, rend_obj->magnify);
  point_sub(&rend_obj->element.corner,
	    &p);
  
  rendobj_update_data(rend_obj);
}
示例#13
0
文件: arc.c 项目: jbohren-forks/dia
/* finds the point intersecting the full circle
 * on the vector defined by the center and Point *to
 * that point is returned in Point *best if 1 is returned */
static int
arc_find_radial(const Arc *arc, const Point *to, Point *best)
{
    Point tmp;
    tmp = *to;
    point_sub(&tmp, &arc->center);
    point_normalize(&tmp);
    point_scale(&tmp,arc->radius);
    point_add(&tmp, &arc->center);
    *best = tmp;
    return 1;

}
示例#14
0
文件: arc.c 项目: mpuels/dia
/** rotates p around the center by an angle given in radians 
 * a positive angle is ccw on the screen*/
static void
rotate_point_around_point(Point *p, const Point *center, real angle)
{
        real radius;
        real a;
        point_sub(p,center);
        radius = point_len(p);
        a = -atan2(p->y,p->x); /* y axis points down*/
        a += angle;
        p->x = cos(a); p->y = -sin(a);/* y axis points down*/
        point_scale(p,radius);
        point_add(p,center);
}
示例#15
0
/*
 * This function estimates the distance from a point to a line segment
 * specified by two endpoints.
 * If the point is on the line segment, 0.0 is returned. Otherwise the
 * distance in the R^2 metric from the point to the nearest point
 * on the line segment is returned. Does one sqrt per call.
 * Philosophical bug: line_width is ignored iff point is beyond
 * end of line segment.
 */
real
distance_line_point(Point *line_start, Point *line_end,
		    real line_width, Point *point)
{
  Point v1, v2;
  real v1_lensq;
  real projlen;
  real perp_dist;

  v1 = *line_end;
  point_sub(&v1,line_start);

  v2 = *point;
  point_sub(&v2, line_start);

  v1_lensq = point_dot(&v1,&v1);

  if (v1_lensq<0.000001) {
    return sqrt(point_dot(&v2,&v2));
  }

  projlen = point_dot(&v1,&v2) / v1_lensq;
  
  if (projlen<0.0) {
    return sqrt(point_dot(&v2,&v2));
  }
  
  if (projlen>1.0) {
    Point v3 = *point;
    point_sub(&v3,line_end);
    return sqrt(point_dot(&v3,&v3));
  }

  point_scale(&v1, projlen);
  point_sub(&v1, &v2);

  perp_dist = sqrt(point_dot(&v1,&v1));

  perp_dist -= line_width / 2.0;
  if (perp_dist < 0.0) {
    perp_dist = 0.0;
  }
  
  return perp_dist;
}
示例#16
0
/** Calculate the bounding box for a simple line.
 * @param p1 One end of the line.
 * @param p2 The other end of the line.
 * @param extra Extra information 
 * @param rect The box that the line and extra stuff fits inside.
 */
void
line_bbox(const Point *p1, const Point *p2,
          const LineBBExtras *extra,
          Rectangle *rect)
{
  Point vl;
  
  rect->left = rect->right = p1->x;
  rect->top = rect->bottom = p1->y;

  rectangle_add_point(rect,p2); /* as a safety, so we don't need to care if it above or below p1 */
  
  point_copy_add_scaled(&vl,p1,p2,-1);
  point_normalize(&vl);
  add_arrow_rectangle(rect,p1,&vl,extra->start_long,extra->start_trans);
  point_scale(&vl,-1);
  add_arrow_rectangle(rect,p2,&vl,extra->end_long,extra->end_trans);
}
示例#17
0
void line_bbox(const Point *p1, const Point *p2,
        const LineBBExtras *extra,
        Rectangle *rect)
{
    Point vl;

    rect->setLeft(p1->x());
    rect->setRight(p1->x());
    rect->setTop(p1->y());
    rect->setBottom(p1->y());

    rectangle_add_point(rect,p2);

    point_copy_add_scaled(&vl,p1,p2,-1);
    point_normalize(&vl);
    add_arrow_rectangle(rect,p1,&vl,extra->startLong,extra->startTrans);
    point_scale(&vl,-1);
    add_arrow_rectangle(rect,p2,&vl,extra->endLong,extra->endTrans);
}
示例#18
0
void 
connpointline_putonaline(ConnPointLine *cpl,Point *start,Point *end, gint dirs)
{
  Point se_vector;
  real se_len,pseudopoints;
  int i;
  GSList *elem;

  point_copy(&se_vector, end);
  point_sub(&se_vector, start);
  
  se_len = point_len(&se_vector);
  
  if (se_len > 0)
    point_normalize(&se_vector);
  
  cpl->start = *start;
  cpl->end = *end;
  
  if (dirs != DIR_NONE)
    /* use the oone givne by the caller */;
  else if (fabs(se_vector.x) > fabs(se_vector.y))
    dirs = DIR_NORTH|DIR_SOUTH;
  else
    dirs = DIR_EAST|DIR_WEST;

  pseudopoints = cpl->num_connections + 1; /* here, we count the start and end 
					    points as eating real positions. */
  for (i=0, elem=cpl->connections; 
       i<cpl->num_connections; 
       i++,elem=g_slist_next(elem)) {
    ConnectionPoint *cp = (ConnectionPoint *)(elem->data);
    cp->pos = se_vector;
    cp->directions = dirs;
    point_scale(&cp->pos,se_len * (i+1.0)/pseudopoints);
    point_add(&cp->pos,start);
  }
}
示例#19
0
static void
bezierline_move_handle(Bezierline *bezierline, Handle *handle,
                       Point *to, HandleMoveReason reason, ModifierKeys modifiers)
{
    assert(bezierline!=NULL);
    assert(handle!=NULL);
    assert(to!=NULL);

    bezierconn_move_handle(&bezierline->bez, handle, to, reason);

    if (reason == HANDLE_MOVE_CREATE || reason == HANDLE_MOVE_CREATE_FINAL) {
        BezierConn *bez = &bezierline->bez;
        Point delta = bez->points[1].p3;

        point_sub(&delta, &bez->points[0].p1);
        point_scale(&delta, 1.0/3);
        bez->points[1].p1 = bez->points[0].p1;
        point_add(&bez->points[1].p1, &delta);
        bez->points[1].p2 = bez->points[1].p1;
        point_add(&bez->points[1].p2, &delta);
    }

    bezierline_update_data(bezierline);
}
示例#20
0
文件: flow.c 项目: brunetton/dia
static DiaObject *
flow_create(Point *startpoint,
	    void *user_data,
	    Handle **handle1,
	    Handle **handle2)
{
  Flow *flow;
  Connection *conn;
  DiaObject *obj;
  LineBBExtras *extra;
  Point p ;
  Point n ;
  DiaFont *font;

  flow = g_malloc0(sizeof(Flow));

  conn = &flow->connection;
  conn->endpoints[0] = *startpoint;
  conn->endpoints[1] = *startpoint;
  conn->endpoints[1].x += 1.5;
 
  obj = &conn->object;
  extra = &conn->extra_spacing;

  obj->type = &flow_type;
  obj->ops = &flow_ops;
  
  connection_init(conn, 3, 0);

  p = conn->endpoints[1] ;
  point_sub( &p, &conn->endpoints[0] ) ;
  point_scale( &p, 0.5 ) ;
  n.x = p.y ;
  n.y = -p.x ;
  if ( fabs(n.x) < 1.e-5 && fabs(n.y) < 1.e-5 ) {
    n.x = 0. ;
    n.y = -1. ;
  } else {
    point_normalize( &n ) ;
  }
  point_scale( &n, 0.5*FLOW_FONTHEIGHT ) ;

  point_add( &p, &n ) ;
  point_add( &p, &conn->endpoints[0] ) ;
  flow->textpos = p;

  font = dia_font_new_from_style(DIA_FONT_SANS, FLOW_FONTHEIGHT);

  flow->text = new_text("", font, FLOW_FONTHEIGHT, &p, &color_black, ALIGN_CENTER);
  dia_font_unref(font);  

  flow->text_handle.id = HANDLE_MOVE_TEXT;
  flow->text_handle.type = HANDLE_MINOR_CONTROL;
  flow->text_handle.connect_type = HANDLE_NONCONNECTABLE;
  flow->text_handle.connected_to = NULL;
  flow->text_handle.pos = p;
  obj->handles[2] = &flow->text_handle;

  extra->start_long = 
    extra->end_long =
    extra->start_trans = FLOW_WIDTH/2.0;
  extra->end_trans = MAX(FLOW_WIDTH, FLOW_ARROWLEN) / 2.0;
  flow_update_data(flow);
  *handle1 = obj->handles[0];
  *handle2 = obj->handles[1];
  
  return &flow->connection.object;
}
示例#21
0
文件: flow.c 项目: brunetton/dia
static ObjectChange*
flow_move_handle(Flow *flow, Handle *handle,
		 Point *to, ConnectionPoint *cp,
		 HandleMoveReason reason, ModifierKeys modifiers)
{
  Point p1, p2;
  Point *endpoints;
  
  assert(flow!=NULL);
  assert(handle!=NULL);
  assert(to!=NULL);

  if (handle->id == HANDLE_MOVE_TEXT) {
    flow->textpos = *to;
  } else  {
    real dest_length ;
    real orig_length2 ;
    real along_mag, norm_mag ;
    Point along ;

    endpoints = &flow->connection.endpoints[0]; 
    p1 = flow->textpos ;
    point_sub( &p1, &endpoints[0] ) ;

    p2 = endpoints[1] ;
    point_sub( &p2, &endpoints[0] ) ;
    orig_length2= point_dot( &p2, &p2 ) ;
    along = p2 ;
    if ( orig_length2 > 1e-5 ) {
      along_mag = point_dot( &p2, &p1 )/sqrt(orig_length2) ;
      along_mag *= along_mag ;
      norm_mag = point_dot( &p1, &p1 ) ;
      norm_mag = (real)sqrt( (double)( norm_mag - along_mag ) ) ;
      along_mag = (real)sqrt( along_mag/orig_length2 ) ;
      if ( p1.x*p2.y - p1.y*p2.x > 0.0 )
	norm_mag = -norm_mag ;
    } else {
      along_mag = 0.5 ;
      norm_mag = (real)sqrt( (double) point_dot( &p1, &p1 ) ) ;
    }

    connection_move_handle(&flow->connection, handle->id, to, cp, 
			   reason, modifiers);

    p2 = endpoints[1] ;
    point_sub( &p2, &endpoints[0] ) ;
    flow->textpos = endpoints[0] ;
    along = p2 ;
    p2.x = -along.y ;
    p2.y = along.x ;
    dest_length = point_dot( &p2, &p2 ) ;
    if ( dest_length > 1e-5 ) {
      point_normalize( &p2 ) ;
    } else {
      p2.x = 0.0 ; p2.y = -1.0 ; 
    }
    point_scale( &p2, norm_mag ) ;
    point_scale( &along, along_mag ) ;
    point_add( &flow->textpos, &p2 ) ;
    point_add( &flow->textpos, &along ) ;
  }

  flow_update_data(flow);

  return NULL;
}
示例#22
0
文件: bus.c 项目: GNOME/dia
static ObjectChange*
bus_move_handle(Bus *bus, Handle *handle,
		Point *to, ConnectionPoint *cp,
		HandleMoveReason reason, ModifierKeys modifiers)
{
  Connection *conn = &bus->connection;
  Point *endpoints;
  real *parallel=NULL;
  real *perp=NULL;
  Point vhat, vhatperp;
  Point u;
  real vlen, vlen2;
  real len_scale;
  int i;
  const int num_handles = bus->num_handles; /* const to help scan-build */

  /* code copied to Misc/tree.c */
  parallel = (real *)g_alloca (num_handles * sizeof(real));
  perp = (real *)g_alloca (num_handles * sizeof(real));

  if (handle->id == HANDLE_BUS) {
    handle->pos = *to;
  } else {
    endpoints = &conn->endpoints[0];
    vhat = endpoints[1];
    point_sub(&vhat, &endpoints[0]);
    if ((fabs(vhat.x) == 0.0) && (fabs(vhat.y)==0.0)) {
      vhat.x += 0.01;
    }
    vlen = sqrt(point_dot(&vhat, &vhat));
    point_scale(&vhat, 1.0/vlen);

    vhatperp.x = -vhat.y;
    vhatperp.y =  vhat.x;
    for (i=0;i<num_handles;i++) {
      u = bus->handles[i]->pos;
      point_sub(&u, &endpoints[0]);
      parallel[i] = point_dot(&vhat, &u);
      perp[i] = point_dot(&vhatperp, &u);
    }

    connection_move_handle(&bus->connection, handle->id, to, cp,
			   reason, modifiers);

    vhat = endpoints[1];
    point_sub(&vhat, &endpoints[0]);
    if ((fabs(vhat.x) == 0.0) && (fabs(vhat.y)==0.0)) {
      vhat.x += 0.01;
    }
    vlen2 = sqrt(point_dot(&vhat, &vhat));
    len_scale = vlen2 / vlen;
    point_normalize(&vhat);
    vhatperp.x = -vhat.y;
    vhatperp.y =  vhat.x;
    for (i=0;i<num_handles;i++) {
      if (bus->handles[i]->connected_to == NULL) {
	u = vhat;
	point_scale(&u, parallel[i]*len_scale);
	point_add(&u, &endpoints[0]);
	bus->parallel_points[i] = u;
	u = vhatperp;
	point_scale(&u, perp[i]);
	point_add(&u, &bus->parallel_points[i]);
	bus->handles[i]->pos = u;
	}
    }
  }

  bus_update_data(bus);

  return NULL;
}
示例#23
0
ObjectChange *
beziershape_move_handle(BezierShape *bezier, Handle *handle,
			Point *to, ConnectionPoint *cp,
			HandleMoveReason reason, ModifierKeys modifiers)
{
  int handle_nr, comp_nr, next_nr, prev_nr;
  Point delta, pt;
  
  delta = *to;
  point_sub(&delta, &handle->pos);

  handle_nr = get_handle_nr(bezier, handle);
  comp_nr = get_comp_nr(handle_nr);
  next_nr = comp_nr + 1;
  prev_nr = comp_nr - 1;
  if (comp_nr == bezier->numpoints - 1)
    next_nr = 1;
  if (comp_nr == 1)
    prev_nr = bezier->numpoints - 1;
  
  switch(handle->id) {
  case HANDLE_BEZMAJOR:
    if (comp_nr == bezier->numpoints - 1) {
      bezier->points[comp_nr].p3 = *to;
      bezier->points[0].p1 = bezier->points[0].p3 = *to;
      point_add(&bezier->points[comp_nr].p2, &delta);
      point_add(&bezier->points[1].p1, &delta);
    } else {
      bezier->points[comp_nr].p3 = *to;
      point_add(&bezier->points[comp_nr].p2, &delta);
      point_add(&bezier->points[comp_nr+1].p1, &delta);
    }
    break;
  case HANDLE_LEFTCTRL:
    bezier->points[comp_nr].p2 = *to;
    switch (bezier->corner_types[comp_nr]) {
    case BEZ_CORNER_SYMMETRIC:
      pt = bezier->points[comp_nr].p3;
      point_sub(&pt, &bezier->points[comp_nr].p2);
      point_add(&pt, &bezier->points[comp_nr].p3);
      bezier->points[next_nr].p1 = pt;
      break;
    case BEZ_CORNER_SMOOTH: {
      real len;

      pt = bezier->points[next_nr].p1;
      point_sub(&pt, &bezier->points[comp_nr].p3);
      len = point_len(&pt);

      pt = bezier->points[comp_nr].p3;
      point_sub(&pt, &bezier->points[comp_nr].p2);
      if (point_len(&pt) > 0)
	point_normalize(&pt);
      else {
	pt.x = 1.0; pt.y = 0.0;
      }
      point_scale(&pt, len);
      point_add(&pt, &bezier->points[comp_nr].p3);
      bezier->points[next_nr].p1 = pt;
      break;
    }
    case BEZ_CORNER_CUSP:
      /* no mirror point movement required */
      break;
    }
    break;
  case HANDLE_RIGHTCTRL:
    bezier->points[comp_nr].p1 = *to;
    switch (bezier->corner_types[prev_nr]) {
    case BEZ_CORNER_SYMMETRIC:
      pt = bezier->points[prev_nr].p3;
      point_sub(&pt, &bezier->points[comp_nr].p1);
      point_add(&pt, &bezier->points[prev_nr].p3);
      bezier->points[prev_nr].p2 = pt;
      break;
    case BEZ_CORNER_SMOOTH: {
      real len;

      pt = bezier->points[prev_nr].p2;
      point_sub(&pt, &bezier->points[prev_nr].p3);
      len = point_len(&pt);

      pt = bezier->points[prev_nr].p3;
      point_sub(&pt, &bezier->points[comp_nr].p1);
      if (point_len(&pt) > 0)
	point_normalize(&pt);
      else {
	pt.x = 1.0; pt.y = 0.0;
      }
      point_scale(&pt, len);
      point_add(&pt, &bezier->points[prev_nr].p3);
      bezier->points[prev_nr].p2 = pt;
      break;
    }
    case BEZ_CORNER_CUSP:
      /* no mirror point movement required */
      break;
    }
    break;
  default:
    message_error("Internal error in beziershape_move_handle.");
    break;
  }
  return NULL;
}
示例#24
0
文件: bus.c 项目: krattai/monoflow
static void
bus_update_data(Bus *bus)
{
  Connection *conn = &bus->connection;
  DiaObject *obj = &conn->object;
  int i;
  Point u, v, vhat;
  Point *endpoints;
  real ulen;
  real min_par, max_par;

/*
 * This seems to break stuff wildly.
 */
/*  
  if (connpoint_is_autogap(conn->endpoint_handles[0].connected_to) ||
      connpoint_is_autogap(conn->endpoint_handles[1].connected_to)) {
    connection_adjust_for_autogap(conn);
  }
*/
  endpoints = &conn->endpoints[0]; 
  obj->position = endpoints[0];

  v = endpoints[1];
  point_sub(&v, &endpoints[0]);
  if ((fabs(v.x) == 0.0) && (fabs(v.y)==0.0)) {
    v.x += 0.01;
  }
  vhat = v;
  point_normalize(&vhat);
  min_par = 0.0;
  max_par = point_dot(&vhat, &v);
  for (i=0;i<bus->num_handles;i++) {
    u = bus->handles[i]->pos;
    point_sub(&u, &endpoints[0]);
    ulen = point_dot(&u, &vhat);
    min_par = MIN(min_par, ulen);
    max_par = MAX(max_par, ulen);
    bus->parallel_points[i] = vhat;
    point_scale(&bus->parallel_points[i], ulen);
    point_add(&bus->parallel_points[i], &endpoints[0]);
  }
  
  min_par -= LINE_WIDTH/2.0;
  max_par += LINE_WIDTH/2.0;

  bus->real_ends[0] = vhat;
  point_scale(&bus->real_ends[0], min_par);
  point_add(&bus->real_ends[0], &endpoints[0]);
  bus->real_ends[1] = vhat;
  point_scale(&bus->real_ends[1], max_par);
  point_add(&bus->real_ends[1], &endpoints[0]);

  connection_update_boundingbox(conn);
  rectangle_add_point(&obj->bounding_box, &bus->real_ends[0]);
  rectangle_add_point(&obj->bounding_box, &bus->real_ends[1]);
  for (i=0;i<bus->num_handles;i++) {
    rectangle_add_point(&obj->bounding_box, &bus->handles[i]->pos);
  }

  connection_update_handles(conn);
}
示例#25
0
文件: bus.c 项目: krattai/monoflow
static ObjectChange*
bus_move_handle(Bus *bus, Handle *handle,
		Point *to, ConnectionPoint *cp,
		HandleMoveReason reason, ModifierKeys modifiers)
{
  Connection *conn = &bus->connection;
  Point *endpoints;
  static real *parallel=NULL;
  static real *perp=NULL;
  static int max_num=0;
  Point vhat, vhatperp;
  Point u;
  real vlen, vlen2;
  real len_scale;
  int i;

  if (bus->num_handles>max_num) {
    if (parallel!=NULL) {
      g_free(parallel);
      g_free(perp);
    }
    parallel = g_malloc(sizeof(real)*bus->num_handles);
    perp = g_malloc(sizeof(real)*bus->num_handles);
    max_num = bus->num_handles;
  }

  if (handle->id == HANDLE_BUS) {
    handle->pos = *to;
  } else {
    endpoints = &conn->endpoints[0];
    vhat = endpoints[1];
    point_sub(&vhat, &endpoints[0]);
    if ((fabs(vhat.x) == 0.0) && (fabs(vhat.y)==0.0)) {
      vhat.x += 0.01;
    }
    vlen = sqrt(point_dot(&vhat, &vhat));
    point_scale(&vhat, 1.0/vlen);
    
    vhatperp.x = -vhat.y;
    vhatperp.y =  vhat.x;
    for (i=0;i<bus->num_handles;i++) {
      u = bus->handles[i]->pos;
      point_sub(&u, &endpoints[0]);
      parallel[i] = point_dot(&vhat, &u);
      perp[i] = point_dot(&vhatperp, &u);
    }
    
    connection_move_handle(&bus->connection, handle->id, to, cp, 
			   reason, modifiers);

    vhat = endpoints[1];
    point_sub(&vhat, &endpoints[0]);
    if ((fabs(vhat.x) == 0.0) && (fabs(vhat.y)==0.0)) {
      vhat.x += 0.01;
    }
    vlen2 = sqrt(point_dot(&vhat, &vhat));
    len_scale = vlen2 / vlen;
    point_normalize(&vhat);
    vhatperp.x = -vhat.y;
    vhatperp.y =  vhat.x;
    for (i=0;i<bus->num_handles;i++) {
      if (bus->handles[i]->connected_to == NULL) {
	u = vhat;
	point_scale(&u, parallel[i]*len_scale);
	point_add(&u, &endpoints[0]);
	bus->parallel_points[i] = u;
	u = vhatperp;
	point_scale(&u, perp[i]);
	point_add(&u, &bus->parallel_points[i]);
	bus->handles[i]->pos = u;
	}
    }
  }

  bus_update_data(bus);

  return NULL;
}
示例#26
0
/*!
 * \brief Move one of the handles associated with the
 * @param bezier The object whose handle is being moved.
 * @param handle The handle being moved.
 * @param to The position it has been moved to (corrected for
 *   vertical/horizontal only movement).
 * @param cp If non-NULL, the connectionpoint found at this position.
 *   If @a cp is NULL, there may or may not be a connectionpoint.
 * @param reason ignored
 * @param modifiers ignored
 * @return NULL
 * \memberof BezierConn
 */
ObjectChange*
bezierconn_move_handle (BezierConn *bezier,
			Handle *handle,
			Point *to,
			ConnectionPoint *cp,
			HandleMoveReason reason,
			ModifierKeys modifiers)
{
  int handle_nr, comp_nr;
  Point delta, pt;
  
  delta = *to;
  point_sub(&delta, &handle->pos);

  handle_nr = get_handle_nr(bezier, handle);
  comp_nr = get_comp_nr(handle_nr);
  switch(handle->id) {
  case HANDLE_MOVE_STARTPOINT:
    bezier->bezier.points[0].p1 = *to;
    /* shift adjacent point */
    point_add(&bezier->bezier.points[1].p1, &delta);
    break;
  case HANDLE_MOVE_ENDPOINT:
    bezier->bezier.points[bezier->bezier.num_points-1].p3 = *to;
    /* shift adjacent point */
    point_add(&bezier->bezier.points[bezier->bezier.num_points-1].p2, &delta);
    break;
  case HANDLE_BEZMAJOR:
    bezier->bezier.points[comp_nr].p3 = *to;
    /* shift adjacent point */
    point_add(&bezier->bezier.points[comp_nr].p2, &delta);
    point_add(&bezier->bezier.points[comp_nr+1].p1, &delta);
    break;
  case HANDLE_LEFTCTRL:
    bezier->bezier.points[comp_nr].p2 = *to;
    if (comp_nr < bezier->bezier.num_points - 1) {
      switch (bezier->bezier.corner_types[comp_nr]) {
      case BEZ_CORNER_SYMMETRIC:
	pt = bezier->bezier.points[comp_nr].p3;
	point_sub(&pt, &bezier->bezier.points[comp_nr].p2);
	point_add(&pt, &bezier->bezier.points[comp_nr].p3);
	bezier->bezier.points[comp_nr+1].p1 = pt;
	break;
      case BEZ_CORNER_SMOOTH: {
	real len;
	pt = bezier->bezier.points[comp_nr+1].p1;
	point_sub(&pt, &bezier->bezier.points[comp_nr].p3);
	len = point_len(&pt);
	pt = bezier->bezier.points[comp_nr].p2;
	point_sub(&pt, &bezier->bezier.points[comp_nr].p3);
	if (point_len(&pt) > 0)
	  point_normalize(&pt);
	else { pt.x = 1.0; pt.y = 0.0; }
	point_scale(&pt, -len);
	point_add(&pt, &bezier->bezier.points[comp_nr].p3);
	bezier->bezier.points[comp_nr+1].p1 = pt;
	break;
      }	
      case BEZ_CORNER_CUSP:
	/* Do nothing to the other guy */
	break;
      }
    }
    break;
  case HANDLE_RIGHTCTRL:
    bezier->bezier.points[comp_nr].p1 = *to;
    if (comp_nr > 1) {
      switch (bezier->bezier.corner_types[comp_nr-1]) {
      case BEZ_CORNER_SYMMETRIC:
	pt = bezier->bezier.points[comp_nr - 1].p3;
	point_sub(&pt, &bezier->bezier.points[comp_nr].p1);
	point_add(&pt, &bezier->bezier.points[comp_nr - 1].p3);
	bezier->bezier.points[comp_nr-1].p2 = pt;
	break;
      case BEZ_CORNER_SMOOTH: {
	real len;
	pt = bezier->bezier.points[comp_nr-1].p2;
	point_sub(&pt, &bezier->bezier.points[comp_nr-1].p3);
	len = point_len(&pt);
	pt = bezier->bezier.points[comp_nr].p1;
	point_sub(&pt, &bezier->bezier.points[comp_nr-1].p3);
	if (point_len(&pt) > 0)
	  point_normalize(&pt);
	else { pt.x = 1.0; pt.y = 0.0; }
	point_scale(&pt, -len);
	point_add(&pt, &bezier->bezier.points[comp_nr-1].p3);
	bezier->bezier.points[comp_nr-1].p2 = pt;
	break;
      }	
      case BEZ_CORNER_CUSP:
	/* Do nothing to the other guy */
	break;
      }
    }
    break;
  default:
    g_warning("Internal error in bezierconn_move_handle.\n");
    break;
  }
  return NULL;
}
示例#27
0
static void
arc_draw(Arc *arc, Renderer *renderer)
{
  Point *endpoints;
  real width;
    
  assert(arc != NULL);
  assert(renderer != NULL);

  endpoints = &arc->connection.endpoints[0];

  renderer->ops->set_linewidth(renderer, arc->line_width);
  renderer->ops->set_linestyle(renderer, arc->line_style);
  renderer->ops->set_dashlength(renderer, arc->dashlength);
  renderer->ops->set_linecaps(renderer, LINECAPS_BUTT);
  
  /* Special case when almost line: */
  if (fabs(arc->curve_distance) <= 0.0001) {
    renderer->ops->draw_line(renderer,
			     &endpoints[0], &endpoints[1],
			     &arc->arc_color);
    return;
  }
  
  width = 2*arc->radius;
  
  renderer->ops->draw_arc(renderer,
			  &arc->center,
			  width, width,
			  arc->angle1, arc->angle2,
			  &arc->arc_color);

  if (arc->start_arrow.type != ARROW_NONE ||
      arc->end_arrow.type != ARROW_NONE) {
    Point reversepoint, centervec;
    Point controlpoint0, controlpoint1;
    real len, len2;

    centervec = endpoints[0];
    point_sub(&centervec, &endpoints[1]);
    point_scale(&centervec, 0.5);
    len = centervec.x*centervec.x+centervec.y*centervec.y;
    point_add(&centervec, &endpoints[1]);
    /* Centervec should now be the midpoint between [0] and [1] */
    reversepoint = centervec;
    point_sub(&centervec, &arc->center);
    len2 = centervec.x*centervec.x+centervec.y*centervec.y;
    if (len2 != 0) {
      point_scale(&centervec, 1/len2);
    }
    point_scale(&centervec, len);
    point_add(&reversepoint, &centervec);
    controlpoint0 = controlpoint1 = reversepoint;
    len = arc->angle2-arc->angle1;
    if (len > 180 || (len < 0.0 && len > -180)) {
      centervec = endpoints[0];
      point_sub(&centervec, &reversepoint);
      point_add(&controlpoint0, &centervec);
      point_add(&controlpoint0, &centervec);
      centervec = endpoints[1];
      point_sub(&centervec, &reversepoint);
      point_add(&controlpoint1, &centervec);
      point_add(&controlpoint1, &centervec);
    }
    if (arc->start_arrow.type != ARROW_NONE) {
      arrow_draw(renderer, arc->start_arrow.type,
		 &endpoints[0],&controlpoint0,
		 arc->start_arrow.length, arc->start_arrow.width,
		 arc->line_width,
		 &arc->arc_color, &color_white);
    }
    if (arc->end_arrow.type != ARROW_NONE) {
      arrow_draw(renderer, arc->end_arrow.type,
		 &endpoints[1], &controlpoint1,
		 arc->end_arrow.length, arc->end_arrow.width,
		 arc->line_width,
		 &arc->arc_color, &color_white);
    }
  }
}