Example #1
0
static DiaObject *
zigzagline_create(Point *startpoint,
		  void *user_data,
		  Handle **handle1,
		  Handle **handle2)
{
  Zigzagline *zigzagline;
  OrthConn *orth;
  DiaObject *obj;
  Point dummy = {0, 0};

  /*zigzagline_init_defaults();*/
  zigzagline = g_malloc0(sizeof(Zigzagline));
  orth = &zigzagline->orth;
  obj = &orth->object;
  
  obj->type = &zigzagline_type;
  obj->ops = &zigzagline_ops;

  if (startpoint)
    orthconn_init(orth, startpoint);
  else
    orthconn_init(orth, &dummy);

  if (user_data) {
    MultipointCreateData *pcd = (MultipointCreateData *)user_data;
    orthconn_set_points (orth, pcd->num_points, pcd->points);
  }

  zigzagline->line_width =  attributes_get_default_linewidth();
  zigzagline->line_color = attributes_get_foreground();
  attributes_get_default_line_style(&zigzagline->line_style,
				    &zigzagline->dashlength);
  zigzagline->line_join = LINEJOIN_MITER;
  zigzagline->line_caps = LINECAPS_BUTT;
  zigzagline->start_arrow = attributes_get_default_start_arrow();
  zigzagline->end_arrow = attributes_get_default_end_arrow();
  zigzagline->corner_radius = 0.0;

  *handle1 = orth->handles[0];
  *handle2 = orth->handles[orth->numpoints-2];

  zigzagline_update_data(zigzagline);

  return &zigzagline->orth.object;
}
Example #2
0
/** Calculate a 'pleasing' route between two connection points.
 * If a good route is found, updates the given OrthConn with the values
 *   and returns TRUE.
 * Otherwise, the OrthConn is untouched, and the function returns FALSE.
 * Handles are not updated by this operation.
 * @param conn The orthconn object to autoroute for.
 * @param startconn The connectionpoint at the start of the orthconn,
 *                  or null if it is not connected there at the moment.
 * @param endconn The connectionpoint at the end (target) of the orthconn,
 *                or null if it is not connected there at the moment.
 * @returns TRUE if the orthconn could be laid out reasonably, FALSE otherwise.
 */
gboolean
autoroute_layout_orthconn(OrthConn *conn, 
			  ConnectionPoint *startconn, ConnectionPoint *endconn)
{
  real min_badness = MAX_BADNESS;
  Point *best_layout = NULL;
  guint best_num_points = 0;
  int startdir, enddir;

  int fromdir, todir;
  Point frompos, topos;

  frompos = conn->points[0];
  topos = conn->points[conn->numpoints-1];
  if (startconn != NULL) {
    fromdir = startconn->directions;
    frompos = startconn->pos;
  }
  else fromdir = DIR_NORTH|DIR_EAST|DIR_SOUTH|DIR_WEST;
  if (endconn != NULL) {
    todir = endconn->directions;
    topos = endconn->pos;
  }
  else todir = DIR_NORTH|DIR_EAST|DIR_SOUTH|DIR_WEST;

  for (startdir = DIR_NORTH; startdir <= DIR_WEST; startdir *= 2) {
    for (enddir = DIR_NORTH; enddir <= DIR_WEST; enddir *= 2) {
      if ((fromdir & startdir) &&
	  (todir & enddir)) {
	real this_badness;
	Point *this_layout = NULL;
	guint this_num_points;
	guint normal_enddir;
	Point startpoint, endpoint;
	Point otherpoint;
	startpoint = autolayout_adjust_for_gap(&frompos, startdir, startconn);
	autolayout_adjust_for_arrow(&startpoint, startdir, conn->extra_spacing.start_trans);
	endpoint = autolayout_adjust_for_gap(&topos, enddir, endconn);
	autolayout_adjust_for_arrow(&endpoint, enddir, conn->extra_spacing.end_trans);
	/*
	printf("Startdir %d enddir %d orgstart %.2f, %.2f orgend %.2f, %.2f start %.2f, %.2f end %.2f, %.2f\n",
	       startdir, enddir,
	       frompos.x, frompos.y,
	       topos.x, topos.y,
	       startpoint.x, startpoint.y,
	       endpoint.x, endpoint.y);
	*/
	normal_enddir = autolayout_normalize_points(startdir, enddir,
						    startpoint, endpoint,
						    &otherpoint);
	if (normal_enddir == DIR_NORTH ) {
	  this_badness = autoroute_layout_parallel(&otherpoint,
						   &this_num_points,
						   &this_layout);
	} else if (normal_enddir == DIR_SOUTH) {
	  this_badness = autoroute_layout_opposite(&otherpoint, 
						   &this_num_points,
						   &this_layout);
	} else {
	  this_badness = autoroute_layout_orthogonal(&otherpoint,
						     normal_enddir,
						     &this_num_points,
						     &this_layout);
	}
	if (this_layout != NULL) {
	  if (this_badness-min_badness < -0.00001) {
	    /*
	    printf("Dir %d to %d badness %f < %f\n", startdir, enddir,
		   this_badness, min_badness);
	    */
	    min_badness = this_badness;
	    if (best_layout != NULL) g_free(best_layout);
	    best_layout = autolayout_unnormalize_points(startdir, startpoint,
							this_layout, 
							this_num_points);
	    best_num_points = this_num_points;
            /* revert adjusting start and end point */
	    autolayout_adjust_for_arrow(&best_layout[0], startdir, 
	                                -conn->extra_spacing.start_trans);
	    autolayout_adjust_for_arrow(&best_layout[best_num_points-1], enddir, 
	                                -conn->extra_spacing.end_trans);
	  } else {
	      g_free(this_layout);
	  }
	}
      }
    }    
  }
  
  if (min_badness < MAX_BADNESS) {
    orthconn_set_points(conn, best_num_points, best_layout);
    g_free(best_layout);
    return TRUE;
  } else {
    g_free(best_layout);
    return FALSE;
  }
}