Ejemplo n.º 1
0
static double
gnome_canvas_item_invoke_point (GnomeCanvasItem *item, double x, double y, int cx, int cy,
				GnomeCanvasItem **actual_item)
{
#ifdef HACKISH_AFFINE
	double i2w[6], w2c[6], i2c[6], c2i[6];
	ArtPoint c, i;
#endif

#ifdef HACKISH_AFFINE
	gnome_canvas_item_i2w_affine (item, i2w);
	gnome_canvas_w2c_affine (item->canvas, w2c);
	art_affine_multiply (i2c, i2w, w2c);
	art_affine_invert (c2i, i2c);
	c.x = cx;
	c.y = cy;
	art_affine_point (&i, &c, c2i);
	x = i.x;
	y = i.y;
#endif

	return (* GNOME_CANVAS_ITEM_CLASS (GTK_OBJECT_GET_CLASS (item))->point) (
		item, x, y, cx, cy, actual_item);
}
Ejemplo n.º 2
0
static int affine( Tcl_Interp *interp, int objc, Tcl_Obj * const objv[], 
      CanvasParams *param, GPtrArray *items, int type )
{
   GnoclOption options[] = {
      { "-absolute", GNOCL_BOOL, NULL },
      { "-reverseOrder", GNOCL_BOOL, NULL },
      { NULL }
   };
   static const int absoluteIdx     = 0;
   static const int reverseOrderIdx = 1;

   guint m; 
   int   noCoords;
   int   absolute = 0; 
   int   reverse = 0;

   if( objc < 4  )
   {
      /* canvas (affine|move|scale|rotate) tag-or-id  coords ?options ? */
      Tcl_WrongNumArgs( interp, 3, objv, 
            "list-of-coordinates ?option val ...?" );
      return TCL_ERROR;
   }
   if( gnoclParseOptions( interp, objc - 3, objv + 3, options ) != TCL_OK )
      return TCL_ERROR;

   if( options[absoluteIdx].status == GNOCL_STATUS_CHANGED )
      absolute = options[absoluteIdx].val.b;
   if( options[reverseOrderIdx].status == GNOCL_STATUS_CHANGED )
      reverse = options[reverseOrderIdx].val.b;
   gnoclClearOptions( options );

   if( absolute && reverse )
   {
      Tcl_SetResult( interp, "Options \"-reverseOrder\" is only valid "
            "for relative transformations.", TCL_STATIC );
      return TCL_ERROR;
   }

   if( Tcl_ListObjLength( interp, objv[3], &noCoords ) != TCL_OK )
      return TCL_ERROR;

   for( m = 0; m < items->len; ++m )
   {
      Gnocl_CanvasItemInfo *info = GET_INFO( items, m );
      int k;
      double af[6];
      Tcl_Obj *tp;

      for( k = 0; k < 6 && k < noCoords; ++k )
      {
         if( Tcl_ListObjIndex( interp, objv[3], k, &tp ) != TCL_OK )
            return TCL_ERROR;
         if( Tcl_GetDoubleFromObj( interp, tp, &af[k] ) != TCL_OK )
            return TCL_ERROR;
      }

      /*
         x' = af[0] * x + af[2] * y + af[4];
         y' = af[1] * x + af[3] * y + af[5];
      */
      switch( type )
      {
         case Affine:
               if( noCoords != 6 )
               {
                  Tcl_SetResult( interp, 
                        "size of list-of-coordinates must be 6", TCL_STATIC );
                  return TCL_ERROR;
               }
               break;
         case Move:
               if( noCoords != 2 )
               {
                  Tcl_SetResult( interp, "size of list-of-coordinates must "
                        "be 2 (delta-x and delta-y)", TCL_STATIC );
                  return TCL_ERROR;
               }
               af[4] = af[0];
               af[5] = af[1];

               af[0] = 1.; af[2] = 0.;
               af[1] = 0.; af[3] = 1.;
               break;
         case Scale:
               if( noCoords != 3 && noCoords != 4 )
               {
                  Tcl_SetResult( interp, "size of list-of-coordinates must "
                        "be 3 or 4 (center, x-scale and y-scale)", 
                        TCL_STATIC );
                  return TCL_ERROR;
               }
               else
               {
                  double x = af[0];
                  double y = af[1];
                  double scalex = af[2];
                  double scaley = (noCoords == 4) ? af[3] : scalex;
                  af[0] = scalex; af[2] = .0;     af[4] = x * (1. - scalex);
                  af[1] = .0;     af[3] = scaley; af[5] = y * (1. - scaley);
               }
               break;
         case Rotate:
               /* there seems to be some problems with the 
                  canvas without antialiasing and rotating 
                  (bizarre drawings)
               */
               if( noCoords != 3 )
               {
                  Tcl_SetResult( interp, "size of list-of-coordinates must "
                        "be 3 (center and angle)", TCL_STATIC );
                  return TCL_ERROR;
               }
               else
               {
                  double x = af[0];
                  double y = af[1];
                  double w = af[2];
                  const double cw = cos( w );
                  const double sw = sin( w );

                  af[0] = cw; af[2] = -sw; af[4] = x - x * cw + y * sw;
                  af[1] = sw; af[3] =  cw; af[5] = y - x * sw - y * cw;
               }
               break;
      }

      /*
      printf( "\nitem: %p absolute: %d\n", info->item, absolute );
      printf( "before:\n" );
      {
         int k;
         double af[6];
         gnome_canvas_item_i2c_affine( info->item, af );
         for( k = 0; k < 6; k += 2 )
            printf( "%d: %f ", k, af[k] );
         printf( "\n" );
         for( k = 1; k < 6; k += 2 )
            printf( "%d: %f ", k, af[k] );
         printf( "\n" );
      }
      printf( "affine:\n" );
      for( k = 0; k < 6; k += 2 )
         printf( "%d: %f ", k, af[k] );
      printf( "\n" );
      for( k = 1; k < 6; k += 2 )
         printf( "%d: %f ", k, af[k] );
      printf( "\n" );
      */

      if( absolute )
         gnome_canvas_item_affine_absolute( info->item, af );
      else
      {
         /* Well, *I* think this is a bug in gnome: 
            affine_relative should not be the reverse of what one
            would expect. Or do I have wrong expectations? */
         if( reverse )
            gnome_canvas_item_affine_relative( info->item, af );
         else
         {
            double bf[6];
            gnome_canvas_item_i2w_affine( info->item, bf );
            gnome_canvas_item_affine_absolute( info->item, af );
            gnome_canvas_item_affine_relative( info->item, bf );
         }
      }
   }

   return TCL_OK;
}