⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtkcurve.c

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 C
📖 第 1 页 / 共 2 页
字号:
      if (c->curve_type != GTK_CURVE_TYPE_FREE)	{	  for (src = dst = 0; src < c->num_ctlpoints; ++src)	    {	      if (c->ctlpoint[src][0] >= min_x)		{		  memcpy (c->ctlpoint + dst, c->ctlpoint + src,			  sizeof (*c->ctlpoint));		  ++dst;		}	    }	  if (dst < src)	    {	      c->num_ctlpoints -= (src - dst);	      if (c->num_ctlpoints <= 0)		{		  c->num_ctlpoints = 1;		  c->ctlpoint[0][0] = min_x;		  c->ctlpoint[0][1] = c->min_y;		  gtk_curve_interpolate (c, width, height);		  gtk_curve_draw (c, width, height);		}	      c->ctlpoint =		g_realloc (c->ctlpoint,			   c->num_ctlpoints * sizeof (*c->ctlpoint));	    }	}      new_type = GDK_FLEUR;      c->grab_point = -1;      break;    case GDK_MOTION_NOTIFY:      mevent = (GdkEventMotion *) event;      switch (c->curve_type)	{	case GTK_CURVE_TYPE_LINEAR:	case GTK_CURVE_TYPE_SPLINE:	  if (c->grab_point == -1)	    {	      /* if no point is grabbed...  */	      if (distance <= MIN_DISTANCE)		new_type = GDK_FLEUR;	      else		new_type = GDK_TCROSS;	    }	  else	    {	      /* drag the grabbed point  */	      new_type = GDK_TCROSS;	      leftbound = -MIN_DISTANCE;	      if (c->grab_point > 0)		leftbound = project (c->ctlpoint[c->grab_point - 1][0],				     min_x, c->max_x, width);	      rightbound = width + RADIUS * 2 + MIN_DISTANCE;	      if (c->grab_point + 1 < c->num_ctlpoints)		rightbound = project (c->ctlpoint[c->grab_point + 1][0],				      min_x, c->max_x, width);	      if (tx <= leftbound || tx >= rightbound		  || ty > height + RADIUS * 2 + MIN_DISTANCE		  || ty < -MIN_DISTANCE)		c->ctlpoint[c->grab_point][0] = min_x - 1.0;	      else		{		  rx = unproject (x, min_x, c->max_x, width);		  ry = unproject (height - y, c->min_y, c->max_y, height);		  c->ctlpoint[c->grab_point][0] = rx;		  c->ctlpoint[c->grab_point][1] = ry;		}	      gtk_curve_interpolate (c, width, height);	      gtk_curve_draw (c, width, height);	    }	  break;	case GTK_CURVE_TYPE_FREE:	  if (c->grab_point != -1)	    {	      if (c->grab_point > x)		{		  x1 = x;		  x2 = c->grab_point;		  y1 = y;		  y2 = c->last;		}	      else		{		  x1 = c->grab_point;		  x2 = x;		  y1 = c->last;		  y2 = y;		}	      if (x2 != x1)		for (i = x1; i <= x2; i++)		  {		    c->point[i].x = RADIUS + i;		    c->point[i].y = RADIUS +		      (y1 + ((y2 - y1) * (i - x1)) / (x2 - x1));		  }	      else		{		  c->point[x].x = RADIUS + x;		  c->point[x].y = RADIUS + y;		}	      c->grab_point = x;	      c->last = y;	      gtk_curve_draw (c, width, height);	    }	  if (mevent->state & GDK_BUTTON1_MASK)	    new_type = GDK_TCROSS;	  else	    new_type = GDK_PENCIL;	  break;	}      if (new_type != (GdkCursorType) c->cursor_type)	{	  GdkCursor *cursor;	  c->cursor_type = new_type;	  cursor = gdk_cursor_new (c->cursor_type);	  gdk_window_set_cursor (w->window, cursor);	  gdk_cursor_destroy (cursor);	}      break;    default:      break;    }  return FALSE;}voidgtk_curve_set_curve_type (GtkCurve *c, GtkCurveType new_type){  gfloat rx, dx;  gint x, i;  if (new_type != c->curve_type)    {      gint width, height;      width  = GTK_WIDGET(c)->allocation.width - RADIUS * 2;      height = GTK_WIDGET(c)->allocation.height - RADIUS * 2;      if (new_type == GTK_CURVE_TYPE_FREE)	{	  gtk_curve_interpolate (c, width, height);	  c->curve_type = new_type;	}      else if (c->curve_type == GTK_CURVE_TYPE_FREE)	{	  if (c->ctlpoint)	    g_free (c->ctlpoint);	  c->num_ctlpoints = 9;	  c->ctlpoint = g_malloc (c->num_ctlpoints * sizeof (*c->ctlpoint));	  rx = 0.0;	  dx = (width - 1) / (gfloat) (c->num_ctlpoints - 1);	  for (i = 0; i < c->num_ctlpoints; ++i, rx += dx)	    {	      x = (int) (rx + 0.5);	      c->ctlpoint[i][0] =		unproject (x, c->min_x, c->max_x, width);	      c->ctlpoint[i][1] =		unproject (RADIUS + height - c->point[x].y,			   c->min_y, c->max_y, height);	    }	  c->curve_type = new_type;	  gtk_curve_interpolate (c, width, height);	}      else	{	  c->curve_type = new_type;	  gtk_curve_interpolate (c, width, height);	}      gtk_signal_emit (GTK_OBJECT (c), curve_type_changed_signal);      gtk_curve_draw (c, width, height);    }}static voidgtk_curve_size_graph (GtkCurve *curve){  gint width, height;  gfloat aspect;  width  = (curve->max_x - curve->min_x) + 1;  height = (curve->max_y - curve->min_y) + 1;  aspect = width / (gfloat) height;  if (width > gdk_screen_width () / 4)    width  = gdk_screen_width () / 4;  if (height > gdk_screen_height () / 4)    height = gdk_screen_height () / 4;  if (aspect < 1.0)    width  = height * aspect;  else    height = width / aspect;  gtk_drawing_area_size (GTK_DRAWING_AREA (curve),			 width + RADIUS * 2, height + RADIUS * 2);}static voidgtk_curve_reset_vector (GtkCurve *curve){  if (curve->ctlpoint)    g_free (curve->ctlpoint);  curve->num_ctlpoints = 2;  curve->ctlpoint = g_malloc (2 * sizeof (curve->ctlpoint[0]));  curve->ctlpoint[0][0] = curve->min_x;  curve->ctlpoint[0][1] = curve->min_y;  curve->ctlpoint[1][0] = curve->max_x;  curve->ctlpoint[1][1] = curve->max_y;  if (curve->pixmap)    {      gint width, height;      width = GTK_WIDGET (curve)->allocation.width - RADIUS * 2;      height = GTK_WIDGET (curve)->allocation.height - RADIUS * 2;      if (curve->curve_type == GTK_CURVE_TYPE_FREE)	{	  curve->curve_type = GTK_CURVE_TYPE_LINEAR;	  gtk_curve_interpolate (curve, width, height);	  curve->curve_type = GTK_CURVE_TYPE_FREE;	}      else	gtk_curve_interpolate (curve, width, height);      gtk_curve_draw (curve, width, height);    }}voidgtk_curve_reset (GtkCurve *c){  GtkCurveType old_type;  old_type = c->curve_type;  c->curve_type = GTK_CURVE_TYPE_SPLINE;  gtk_curve_reset_vector (c);  if (old_type != GTK_CURVE_TYPE_SPLINE)    gtk_signal_emit (GTK_OBJECT (c), curve_type_changed_signal);}voidgtk_curve_set_gamma (GtkCurve *c, gfloat gamma){  gfloat x, one_over_gamma, height, one_over_width;  GtkCurveType old_type;  gint i;  if (c->num_points < 2)    return;  old_type = c->curve_type;  c->curve_type = GTK_CURVE_TYPE_FREE;  if (gamma <= 0)    one_over_gamma = 1.0;  else    one_over_gamma = 1.0 / gamma;  one_over_width = 1.0 / (c->num_points - 1);  height = c->height;  for (i = 0; i < c->num_points; ++i)    {      x = (gfloat) i / (c->num_points - 1);      c->point[i].x = RADIUS + i;      c->point[i].y =	RADIUS + (height * (1.0 - pow (x, one_over_gamma)) + 0.5);    }  if (old_type != GTK_CURVE_TYPE_FREE)    gtk_signal_emit (GTK_OBJECT (c), curve_type_changed_signal);  gtk_curve_draw (c, c->num_points, c->height);}voidgtk_curve_set_range (GtkCurve *curve,		     gfloat min_x, gfloat max_x, gfloat min_y, gfloat max_y){  curve->min_x = min_x;  curve->max_x = max_x;  curve->min_y = min_y;  curve->max_y = max_y;  gtk_curve_size_graph (curve);  gtk_curve_reset_vector (curve);}voidgtk_curve_set_vector (GtkCurve *c, int veclen, gfloat vector[]){  GtkCurveType old_type;  gfloat rx, dx, ry;  gint i, height;  old_type = c->curve_type;  c->curve_type = GTK_CURVE_TYPE_FREE;  if (c->point)    height = GTK_WIDGET (c)->allocation.height - RADIUS * 2;  else    {      height = (c->max_y - c->min_y);      if (height > gdk_screen_height () / 4)	height = gdk_screen_height () / 4;      c->height = height;      c->num_points = veclen;      c->point = g_malloc (c->num_points * sizeof (c->point[0]));    }  rx = 0;  dx = (veclen - 1.0) / (c->num_points - 1.0);  for (i = 0; i < c->num_points; ++i, rx += dx)    {      ry = vector[(int) (rx + 0.5)];      if (ry > c->max_y) ry = c->max_y;      if (ry < c->min_y) ry = c->min_y;      c->point[i].x = RADIUS + i;      c->point[i].y =	RADIUS + height - project (ry, c->min_y, c->max_y, height);    }  if (old_type != GTK_CURVE_TYPE_FREE)    gtk_signal_emit (GTK_OBJECT (c), curve_type_changed_signal);  gtk_curve_draw (c, c->num_points, height);}voidgtk_curve_get_vector (GtkCurve *c, int veclen, gfloat vector[]){  gfloat rx, ry, dx, dy, min_x, delta_x, *mem, *xv, *yv, *y2v, prev;  gint dst, i, x, next, num_active_ctlpoints = 0, first_active = -1;  min_x = c->min_x;  if (c->curve_type != GTK_CURVE_TYPE_FREE)    {      /* count active points: */      prev = min_x - 1.0;      for (i = num_active_ctlpoints = 0; i < c->num_ctlpoints; ++i)	if (c->ctlpoint[i][0] > prev)	  {	    if (first_active < 0)	      first_active = i;	    prev = c->ctlpoint[i][0];	    ++num_active_ctlpoints;	  }      /* handle degenerate case: */      if (num_active_ctlpoints < 2)	{	  if (num_active_ctlpoints > 0)	    ry = c->ctlpoint[first_active][1];	  else	    ry = c->min_y;	  if (ry < c->min_y) ry = c->min_y;	  if (ry > c->max_y) ry = c->max_y;	  for (x = 0; x < veclen; ++x)	    vector[x] = ry;	  return;	}    }  switch (c->curve_type)    {    case GTK_CURVE_TYPE_SPLINE:      mem = g_malloc (3 * num_active_ctlpoints * sizeof (gfloat));      xv  = mem;      yv  = mem + num_active_ctlpoints;      y2v = mem + 2*num_active_ctlpoints;      prev = min_x - 1.0;      for (i = dst = 0; i < c->num_ctlpoints; ++i)	if (c->ctlpoint[i][0] > prev)	  {	    prev    = c->ctlpoint[i][0];	    xv[dst] = c->ctlpoint[i][0];	    yv[dst] = c->ctlpoint[i][1];	    ++dst;	  }      spline_solve (num_active_ctlpoints, xv, yv, y2v);      rx = min_x;      dx = (c->max_x - min_x) / (veclen - 1);      for (x = 0; x < veclen; ++x, rx += dx)	{	  ry = spline_eval (num_active_ctlpoints, xv, yv, y2v, rx);	  if (ry < c->min_y) ry = c->min_y;	  if (ry > c->max_y) ry = c->max_y;	  vector[x] = ry;	}      g_free (mem);      break;    case GTK_CURVE_TYPE_LINEAR:      dx = (c->max_x - min_x) / (veclen - 1);      rx = min_x;      ry = c->min_y;      dy = 0.0;      i  = first_active;      for (x = 0; x < veclen; ++x, rx += dx)	{	  if (rx >= c->ctlpoint[i][0])	    {	      if (rx > c->ctlpoint[i][0])		ry = c->min_y;	      dy = 0.0;	      next = i + 1;	      while (next < c->num_ctlpoints		     && c->ctlpoint[next][0] <= c->ctlpoint[i][0])		++next;	      if (next < c->num_ctlpoints)		{		  delta_x = c->ctlpoint[next][0] - c->ctlpoint[i][0];		  dy = ((c->ctlpoint[next][1] - c->ctlpoint[i][1])			/ delta_x);		  dy *= dx;		  ry = c->ctlpoint[i][1];		  i = next;		}	    }	  vector[x] = ry;	  ry += dy;	}      break;    case GTK_CURVE_TYPE_FREE:      if (c->point)	{	  rx = 0.0;	  dx = c->num_points / (double) veclen;	  for (x = 0; x < veclen; ++x, rx += dx)	    vector[x] = unproject (RADIUS + c->height - c->point[(int) rx].y,				   c->min_y, c->max_y,				   c->height);	}      else	memset (vector, 0, veclen * sizeof (vector[0]));      break;    }}GtkWidget*gtk_curve_new (void){  return gtk_type_new (gtk_curve_get_type ());}static voidgtk_curve_finalize (GtkObject *object){  GtkCurve *curve;  g_return_if_fail (object != NULL);  g_return_if_fail (GTK_IS_CURVE (object));  curve = GTK_CURVE (object);  if (curve->pixmap)    gdk_pixmap_unref (curve->pixmap);  if (curve->point)    g_free (curve->point);  if (curve->ctlpoint)    g_free (curve->ctlpoint);  (*GTK_OBJECT_CLASS (parent_class)->finalize) (object);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -