static void matenu_menu_bar_reset_bg_pixmap (MatenuMenuBar* self) {
	GdkPixmap* pixmap;
	cairo_t* cairo;
	cairo_pattern_t* pattern;
	GtkStyle* style;
	GdkPixmap* _tmp0_;
	g_return_if_fail (self != NULL);
	if (matenu_menu_bar_get_background (self)->type != MATENU_BACKGROUND_TYPE_PIXMAP) {
		return;
	}
	if (!GTK_WIDGET_REALIZED ((GtkWidget*) self)) {
		return;
	}
	g_assert (GDK_IS_DRAWABLE (((GtkWidget*) self)->window));
	g_assert (GDK_IS_DRAWABLE (self->priv->_background->pixmap));
	pixmap = gdk_pixmap_new ((GdkDrawable*) ((GtkWidget*) self)->window, ((GtkWidget*) self)->allocation.width, ((GtkWidget*) self)->allocation.height, -1);
	g_assert (GDK_IS_DRAWABLE (pixmap));
	cairo = gdk_cairo_create ((GdkDrawable*) pixmap);
	g_assert (cairo != NULL);
	gdk_cairo_set_source_pixmap (cairo, self->priv->_background->pixmap, (double) (-self->priv->_background->offset_x), (double) (-self->priv->_background->offset_y));
	pattern = cairo_get_source (cairo);
	cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
	cairo_rectangle (cairo, (double) 0, (double) 0, (double) ((GtkWidget*) self)->allocation.width, (double) ((GtkWidget*) self)->allocation.height);
	cairo_fill (cairo);
	style = _g_object_ref0 (gtk_widget_get_style ((GtkWidget*) self));
	style->bg_pixmap[(gint) GTK_STATE_NORMAL] = (_tmp0_ = _g_object_ref0 (pixmap), _g_object_unref0 (style->bg_pixmap[(gint) GTK_STATE_NORMAL]), _tmp0_);
	gtk_style_set_background (style, ((GtkWidget*) self)->window, GTK_STATE_NORMAL);
	gtk_widget_queue_draw ((GtkWidget*) self);
	_g_object_unref0 (style);
	_cairo_destroy0 (cairo);
	_g_object_unref0 (pixmap);
}
static gboolean 
_on_expose (GtkWidget *widget, GdkEventExpose *expose)
{
	static gint oWidth = 0;
	static gint oHeight = 0;
	gint width;
	gint height;
	cairo_t *cr = NULL;
	if (!GDK_IS_DRAWABLE (widget->window))
		return FALSE;
	cr = gdk_cairo_create (widget->window);
	if (!cr)
		return FALSE;

	gtk_window_get_size (GTK_WINDOW (widget), &width, &height);
	render (cr, width, height);
	//render3 (cr, width, height);
	cairo_destroy (cr);
	
	if ( oWidth != width || oHeight != height)
		_position_window(GTK_WIDGET(widget));
	oWidth = width;
	oHeight = height;
	
	gdk_window_raise (widget->window);
	return FALSE;
}
Example #3
0
void CCaret::DrawInverse()
{
	if( !m_pParent )
		return;
	if( !GDK_IS_DRAWABLE(m_pParent->window))
	{
//		g_warning("Warring! Draw on DELETED widget!\n");
		return;
	}
	gdk_gc_set_function(m_GC, GDK_INVERT);
	gdk_draw_drawable(m_pParent->window, m_GC, m_pParent->window,
					m_Pos.x, m_Pos.y, m_Pos.x, m_Pos.y, m_Width, m_Height);
	gdk_gc_set_function(m_GC, GDK_COPY);
}
Example #4
0
File: gdkcairo.c Project: krh/gtk
/**
 * gdk_cairo_create:
 * @drawable: a #GdkDrawable
 *
 * Creates a Cairo context for drawing to @drawable.
 *
 * <note><para>
 * Note that due to double-buffering, Cairo contexts created
 * in a GTK+ expose event handler cannot be cached and reused
 * between different expose events.
 * </para></note>
 *
 * Return value: A newly created Cairo context. Free with
 *  cairo_destroy() when you are done drawing.
 *
 * Since: 2.8
 **/
cairo_t *
gdk_cairo_create (GdkDrawable *drawable)
{
    cairo_surface_t *surface;
    cairo_t *cr;

    g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL);

    surface = _gdk_drawable_ref_cairo_surface (drawable);
    cr = cairo_create (surface);
    cairo_surface_destroy (surface);

    return cr;
}
Example #5
0
gchar *
_gdk_win32_drawable_description (GdkDrawable *d)
{
  gint width, height, depth;

  g_return_val_if_fail (GDK_IS_DRAWABLE (d), NULL);

  gdk_drawable_get_size (d, &width, &height);
  depth = gdk_drawable_get_depth (d);

  return static_printf ("%s:%p:%dx%dx%d",
			G_OBJECT_TYPE_NAME (d),
			GDK_DRAWABLE_HANDLE (d),
			width, height, depth);
}
Example #6
0
void CCaret::DrawInverse()
{
	if( !m_pParent )
		return;
	if( !GDK_IS_DRAWABLE(m_pParent->window))
	{
//		g_warning("Warring! Draw on DELETED widget!\n");
		return;
	}

	if (m_Cairo == NULL) {
		m_Cairo = gdk_cairo_create(m_pParent->window);
	}
	cairo_set_source_rgb(m_Cairo, 1, 1, 1);
	cairo_set_operator(m_Cairo, CAIRO_OPERATOR_DIFFERENCE);
	cairo_rectangle(m_Cairo, m_Pos.x, m_Pos.y, m_Width, m_Height);
	cairo_fill(m_Cairo);
}
Example #7
0
static void
pn_redraw_cb (GtkWidget * wid, GdkEventExpose * pose, struct pan_node *xq)
{
  gint usew, useh, isw, sub, i, j, midy;
  GdkGC *gc;
  GdkColor color[1];

  if (!GDK_IS_DRAWABLE (wid->window))
    {
      return;
    }

//  acc_debug ("drawarea allocation '%d:%d'\n", wid->allocation.width, wid->allocation.height);
  if (wid->allocation.width < wid->allocation.height)
    {
      isw = 1;
      usew = wid->allocation.width;
      useh = wid->allocation.width;
      sub = wid->allocation.height - wid->allocation.width;
    }
  else
    {
      isw = 0;
      usew = wid->allocation.height;
      useh = wid->allocation.height;
      sub = wid->allocation.width - wid->allocation.height;
    }

  xq->perx = usew / 9;
  xq->pery = useh / 11;
  if (isw)
    {
      xq->fromx = xq->perx >> 1;
      xq->fromy = (sub >> 1) + xq->pery;
    }
  else
    {
Example #8
0
void regenerer_test(TxDonneesFenetre *onglet_leto)
{
  type_groupe *groupe1, *groupe2, *groupe;
  type_liaison * liaison;
  TxPoint point;
  int i, j, largeur = 0, hauteur = 0;

  if (!GDK_IS_DRAWABLE(onglet_leto->pixmap))
  {
    return;
  }

  init_cairo(onglet_leto);

  groupe = sc->deb_groupe;
  liaison = sc->deb_liaison;

  point.x = sc->xmin;
  point.y = sc->ymin;
  TxDessinerRectangle(onglet_leto, sc->couleur_fond, TxPlein, point, sc->xmax - sc->xmin, sc->ymax - sc->ymin, 0);/* background */
  for (i = 0; i < limite_nbre_max_ech; i++)
  {
    sc->boite_x_min[i] = 999999;
    sc->boite_y_min[i] = 999999;
    sc->boite_x_max[i] = 0;
    sc->boite_y_max[i] = 0;
  }

  sc->nbre_max_ech = -1;
  while (groupe != NULL)
  {
    point.x = groupe->posx;
    point.y = groupe->posy;

    if (groupe->posx > sc->xmin && groupe->posy > sc->ymin && groupe->posx < sc->xmax && groupe->posy < sc->ymax) if (sc->display_plane[abs(groupe->reverse)] == 1 && (groupe->deja_active == 0 || sc->show_sub_networks == 1))
    {
      if (groupe->type != No_Sub_Network) affiche_groupe(point, groupe, onglet_leto);
      else affiche_macro(point, groupe, onglet_leto);
    }

    if (groupe->ech_temps > sc->nbre_max_ech) sc->nbre_max_ech = groupe->ech_temps;
    if (sc->boite_x_min[groupe->ech_temps] > point.x) sc->boite_x_min[groupe->ech_temps] = point.x;
    if (sc->boite_y_min[groupe->ech_temps] > point.y) sc->boite_y_min[groupe->ech_temps] = point.y;
    if (sc->boite_x_max[groupe->ech_temps] < point.x) sc->boite_x_max[groupe->ech_temps] = point.x;
    if (sc->boite_y_max[groupe->ech_temps] < point.y) sc->boite_y_max[groupe->ech_temps] = point.y;
    groupe = groupe->s;
  }

  liaison = sc->deb_liaison;
  while (liaison != NULL)
  {
    if (liaison->depart >= 0) /* ne pas s'occuper de la premiere liaison qui lie micro-neurone et macro-neurone */
    /* typage general, pas vraie connexion */
    {
      groupe1 = trouver_groupe(liaison->depart);
      if (groupe1 == NULL)
      {
        printf("\nListe des groupes existants = \n\n");
        affiche_liste_groupes();
        EXIT_ON_ERROR("Le gpe1 %d %s de la liaison n'a pas ete trouve liaison->depart \n", liaison->depart, liaison->depart_name);
      }

      groupe2 = trouver_groupe(liaison->arrivee);
      if (groupe2 == NULL)
      {
        printf("\nListe des groupes existants = \n\n");
        affiche_liste_groupes();
        EXIT_ON_ERROR("Le gpe2 %d %s de la liaison n'a pas ete trouve liaison->depart \n", liaison->arrivee, liaison->arrivee_name);
      }

      if ((groupe1->posx < sc->xmin && groupe2->posx < sc->xmin) || (groupe1->posx > sc->xmax && groupe2->posx > sc->xmax) || (groupe1->posy < sc->ymin && groupe2->posy < sc->ymin) || (groupe1->posy > sc->ymax && groupe2->posy > sc->ymax))
      {
        liaison = liaison->s;
        continue;
      }
      if (sc->display_plane[abs(groupe1->reverse)] == 1 && sc->display_plane[abs(groupe2->reverse)] == 1 && (sc->show_sub_networks == 1 || liaison->deja_active == 0))

      affiche_liaison(liaison, groupe1, groupe2, onglet_leto);
    }
    liaison = liaison->s;
  }

  for (i = 0; i <= sc->nbre_max_ech; i++)
    for (j = i + 1; j <= sc->nbre_max_ech; j++)
    {

      if (sc->boite_x_min[j] > sc->boite_x_min[i]) sc->boite_x_min[j] = sc->boite_x_min[i];
      if (sc->boite_y_min[j] > sc->boite_y_min[i]) sc->boite_y_min[j] = sc->boite_y_min[i];
      if (sc->boite_x_max[j] < sc->boite_x_max[i]) sc->boite_x_max[j] = sc->boite_x_max[i];
      if (sc->boite_y_max[j] < sc->boite_y_max[i]) sc->boite_y_max[j] = sc->boite_y_max[i];
    }

  for (i = 0; i <= sc->nbre_max_ech; i++)
  {
    if (sc->boite_x_min[i] <= sc->boite_x_max[i] && sc->boite_y_min[i] <= sc->boite_y_max[i])
    {

      point.x = sc->boite_x_min[i] - distc - 2 * deltax;
      point.y = sc->boite_y_min[i] - (2 * deltay + i * 5);
      largeur = sc->boite_x_max[i] - point.x + distc + 2 * deltax + 5 * i;
      hauteur = sc->boite_y_max[i] - point.y + 4 * deltay + 5 * i;
      TxDessinerRectangle(onglet_leto, lut_g[i], TxVide, point, largeur, hauteur, 2);
    }
  }

  TxFlushDessin(onglet_leto, sc->xmin, sc->ymin, sc->xmax - sc->xmin, sc->ymax - sc->ymin);
}
Example #9
0
File: mapa.c Project: Lamieur/Lac
void maluj_mape( GtkWidget *widget )
{
    EXIT_DATA *e;
    char buf[ 16 ];
    int d;

    if ( !GDK_IS_DRAWABLE( dmapa.pixmap ) )
	return;

    gdk_draw_rectangle( dmapa.pixmap, widget->style->dark_gc[ 0 ], TRUE,
		0, 0, widget->allocation.width, widget->allocation.height );

    gdk_draw_rectangle( dmapa.pixmap, widget->style->mid_gc[ 0 ], TRUE,
		prostokaty[ 10 ].x, prostokaty[ 10 ].y, 80, 80 );
    gdk_draw_rectangle( dmapa.pixmap, widget->style->black_gc, FALSE,
		prostokaty[ 10 ].x, prostokaty[ 10 ].y, 80, 80 );

    sprintf( buf, "#%d", dmapa.room->vnum );
    pango_layout_set_text( dmapa.layout, buf, -1 );
    gdk_draw_layout( dmapa.pixmap, widget->style->black_gc,
		prostokaty[ 10 ].x + 3, prostokaty[ 10 ].y + 1, dmapa.layout );
    pango_layout_set_text( dmapa.layout, pols_z_lac_len( dmapa.room->name, 10 ), -1 );
    gdk_draw_layout( dmapa.pixmap, widget->style->black_gc,
		prostokaty[ 10 ].x + 3, prostokaty[ 10 ].y + 14, dmapa.layout );

    for ( d = 0; d < 10; d++ )
    {
	gdk_draw_rectangle( dmapa.pixmap, widget->style->white_gc, TRUE,
		prostokaty[ d ].x, prostokaty[ d ].y, 80, 80 );
	pango_layout_set_text( dmapa.layout, kierunki[ d ].skrot, -1 );
	gdk_draw_layout( dmapa.pixmap, widget->style->black_gc,
		prostokaty[ d ].x, prostokaty[ d ].y - 14, dmapa.layout );
	if ( ( e = dmapa.room->exit[ d ] ) )
	{
	    gdk_draw_rectangle( dmapa.pixmap, widget->style->white_gc, TRUE,
		prostokaty[ d ].x, prostokaty[ d ].y, 80, 80 );
	    if ( e->to_room )
	    {
		sprintf( buf, "#%d", e->to_room->vnum );
		pango_layout_set_text( dmapa.layout, buf, -1 );
		gdk_draw_layout( dmapa.pixmap, widget->style->black_gc,
			prostokaty[ d ].x + 3, prostokaty[ d ].y + 1, dmapa.layout );
		pango_layout_set_text( dmapa.layout, pols_z_lac_len( e->to_room->name, 10 ), -1 );
		gdk_draw_layout( dmapa.pixmap, widget->style->black_gc,
			prostokaty[ d ].x + 3, prostokaty[ d ].y + 14, dmapa.layout );
	    }
	    else
	    {
		pango_layout_set_text( dmapa.layout, "(brak)", -1 );
		gdk_draw_layout( dmapa.pixmap, widget->style->black_gc,
			prostokaty[ d ].x + 3, prostokaty[ d ].y + 1, dmapa.layout );
	    }
	}
	else
	    gdk_draw_rectangle( dmapa.pixmap, widget->style->dark_gc[ 0 ], TRUE,
		prostokaty[ d ].x, prostokaty[ d ].y, 80, 80 );
	gdk_draw_rectangle( dmapa.pixmap, widget->style->black_gc, FALSE,
		prostokaty[ d ].x, prostokaty[ d ].y, 80, 80 );
    }

    /* wymuszenie odswiezenia calego GtkDrawable */
    gtk_widget_queue_draw_area( widget, 0, 0, widget->allocation.width,
		widget->allocation.height );

    return;
}
Example #10
0
GdkPixmap*
gdk_pixmap_create_from_data (GdkDrawable   *drawable,
                             const gchar *data,
                             gint         width,
                             gint         height,
                             gint         depth,
                             const GdkColor    *fg,
                             const GdkColor    *bg)
{
  GdkPixmap *pixmap;
  gi_gc_ptr_t gc;

  g_return_val_if_fail (drawable == NULL || GDK_IS_DRAWABLE (drawable), NULL);
  g_return_val_if_fail (data != NULL, NULL);
  g_return_val_if_fail (drawable != NULL || depth > 0, NULL);
  g_return_val_if_fail (width > 0 && height > 0, NULL);

  GDK_NOTE (MISC, g_print ("gdk_pixmap_create_from_data: %dx%dx%d\n",
                           width, height, depth));

  pixmap = gdk_pixmap_new (drawable, width, height, depth);

  if (pixmap)
    {
	  gi_window_id_t wid;
      gi_image_t* surface;
      gchar            *dst;
      gint              pitch;
      gint              src_pitch;
	  unsigned format ;	  

      depth = gdk_drawable_get_depth (pixmap);
      src_pitch = width * ((depth + 7) / 8);
	  format = gi_get_choose_format(depth); //FIMXE

      wid = GDK_DRAWABLE_IMPL_GIX (GDK_PIXMAP_OBJECT (pixmap)->impl)->window_id;

	   surface=gi_create_image_depth(width,height,format);
	   dst = (gchar*)surface->rgba;
	   pitch = surface->pitch;

        {
          gint i;

          for (i = 0; i < height; i++)
            {
              memcpy (dst, data, src_pitch);
              dst += pitch;
              data += src_pitch;
            }

		gc = gi_create_gc(wid,NULL);
			gi_draw_image(gc,surface,0,0);
		gi_destroy_gc(gc);
		gi_destroy_image(surface);

        }
    }

  return pixmap;
}
Example #11
0
GdkPixmap *
gdk_bitmap_create_from_data (GdkDrawable   *drawable,
                             const gchar *data,
                             gint         width,
                             gint         height)
{
  GdkPixmap *pixmap;
  gi_gc_ptr_t gc;

  g_return_val_if_fail (drawable == NULL || GDK_IS_DRAWABLE (drawable), NULL);
  g_return_val_if_fail (data != NULL, NULL);
  g_return_val_if_fail (width > 0 && height > 0, NULL);

  GDK_NOTE (MISC, g_print ("gdk_bitmap_create_from_data: %dx%d\n",
                           width, height));

  pixmap = gdk_pixmap_new (drawable, width, height, 1);

#define GET_PIXEL(data,pixel) \
  ((data[(pixel / 8)] & (0x1 << ((pixel) % 8))) >> ((pixel) % 8))

  if (pixmap)
    {
      guchar *dst;
      gint    pitch;

	  gc = gi_create_gc(GDK_DRAWABLE_IMPL_GIX (GDK_PIXMAP_OBJECT (pixmap)->impl)->window_id,NULL);

#if 1
	  dst = bitmap_create_from_data((const uint8_t *)data, width,height,TRUE, &pitch);
	  if(dst){
		gi_image_t img;
		img.rgba = (gi_color_t*)dst;
		img.format = GI_RENDER_a8;
		img.w = width;
		img.h = height;
		img.pitch = pitch;
		gi_draw_image(gc,&img,0,0);
		free(dst);
	  }
#else
	  gint i, j;
      surface = gi_create_image_depth(width,height,GI_RENDER_a8);
	  dst = surface->rgba;
	  pitch = surface->pitch;

	  for (i = 0; i < height; i++)
		{
	    for (j = 0; j < width; j++){
		  dst[j] = GET_PIXEL (data, j) * 255;
		}
		data += (width + 7) / 8;
		dst += pitch;
		}

		gi_draw_image(gc,surface,0,0);
		gi_destroy_image(surface);
#endif
		gi_destroy_gc(gc);

    }

#undef GET_PIXEL

  return pixmap;
}
Example #12
0
GdkPixmap*
gdk_pixmap_new (GdkDrawable *drawable,
                gint       width,
                gint       height,
                gint       depth)
{
  GIXSurfacePixelFormat    format;
  GdkPixmap               *pixmap;
  GdkDrawableImplGix *draw_impl;

  g_return_val_if_fail (drawable == NULL || GDK_IS_DRAWABLE (drawable), NULL);
  g_return_val_if_fail (drawable != NULL || depth != -1, NULL);
  g_return_val_if_fail (width > 0 && height > 0, NULL);

  if (!drawable)
    drawable = _gdk_parent_root;

  if (GDK_IS_WINDOW (drawable) && GDK_WINDOW_DESTROYED (drawable))
    return NULL;

  GDK_NOTE (MISC, g_print ("gdk_pixmap_new: %dx%dx%d\n",
                           width, height, depth));

  if (depth == -1)
    {
      draw_impl =
        GDK_DRAWABLE_IMPL_GIX (GDK_WINDOW_OBJECT (drawable)->impl);

      g_return_val_if_fail (draw_impl != NULL, NULL);

	  format = gi_screen_format();
	  depth = GI_RENDER_FORMAT_BPP (format);      
    }
  else
    {
      switch (depth)
        {
        case  1:
          format = GI_RENDER_a8;
          break;
        case  8:
          format = GI_RENDER_r3g3b2;
          break;
        case 15:
          format = GI_RENDER_x1r5g5b5;
          break;
        case 16:
          format = GI_RENDER_r5g6b5;
          break;
        case 24:
          format = GI_RENDER_r8g8b8;
          break;
        case 32:
          format = GI_RENDER_x8r8g8b8;
          break;
        default:
          g_message ("unimplemented %s for depth %d", __FUNCTION__, depth);
          return NULL;
        }
    }

 
  pixmap = g_object_new (gdk_pixmap_get_type (), NULL);
  draw_impl = GDK_DRAWABLE_IMPL_GIX (GDK_PIXMAP_OBJECT (pixmap)->impl);
  draw_impl->window_id = gi_create_pixmap_window(
	  GDK_DRAWABLE_IMPL_GIX (drawable)->window_id,width,height,format);

  //surface->Clear (surface, 0x0, 0x0, 0x0, 0x0);
  //surface->GetSize (surface, &draw_impl->width, &draw_impl->height);
  //surface->GetPixelFormat (surface, &draw_impl->format);

  draw_impl->width = width;
  draw_impl->height = height;
  draw_impl->format = format;
  draw_impl->abs_x = draw_impl->abs_y = 0;
  GDK_PIXMAP_OBJECT (pixmap)->depth = depth;
  return pixmap;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkImagePainter_drawPixels
  (JNIEnv *env, jobject obj __attribute__((unused)), jobject gc_obj,
   jint bg_red, jint bg_green, jint bg_blue, jint x, jint y, jint width,
   jint height, jintArray jpixels, jint offset, jint scansize,
   jdoubleArray jaffine)
{
  struct graphics *g;
  jint *pixels, *elems;
  guchar *packed;
  int i;
  jsize num_pixels;
  guchar *j_rgba, *c_rgb;

  g = (struct graphics *) NSA_GET_PTR (env, gc_obj);

  if (!jpixels)
    return;

  elems = (*env)->GetIntArrayElements (env, jpixels, NULL);
  num_pixels = (*env)->GetArrayLength (env, jpixels);
 
  /* get a copy of the pixel data so we can modify it */
  pixels = malloc (sizeof (jint) * num_pixels);
  memcpy (pixels, elems, sizeof (jint) * num_pixels);
 
  (*env)->ReleaseIntArrayElements (env, jpixels, elems, 0);

#ifndef WORDS_BIGENDIAN
  /* convert pixels from 0xBBGGRRAA to 0xAARRGGBB */
  for (i = 0; i < num_pixels; i++)
    pixels[i] = SWAPU32 ((unsigned)pixels[i]);
#endif

  packed = (guchar *) malloc (sizeof (guchar) * 3 * num_pixels);
  j_rgba = (guchar *) pixels;
  c_rgb = packed;

  /* copy over pixels in DirectColorModel format to 24 bit RGB image data,
     and process the alpha channel */
  for (i = 0; i < num_pixels; i++)
    {
      jint ialpha = *j_rgba++;

      switch (ialpha)
	{
	case 0:			/* full transparency */
	  *c_rgb++ = bg_red;
	  *c_rgb++ = bg_green;
	  *c_rgb++ = bg_blue;
	  j_rgba += 3;
	  break;
	case 255:		/* opaque */
	  *c_rgb++ = *j_rgba++;
	  *c_rgb++ = *j_rgba++;
	  *c_rgb++ = *j_rgba++;
	  break;
	default:		/* compositing required */
	  {
	    jfloat alpha = ialpha / 255.0;
	    jfloat comp_alpha = 1.0 - alpha;
	    
	    *c_rgb++ = *j_rgba++ * alpha + bg_red * comp_alpha;
	    *c_rgb++ = *j_rgba++ * alpha + bg_green * comp_alpha;
	    *c_rgb++ = *j_rgba++ * alpha + bg_blue * comp_alpha;
	  }
	  break;
	}
    }

  if (jaffine)
    {
      jdouble *affine;
      ArtAlphaGamma *alphagamma = NULL;
      art_u8 *dst;
      int new_width, new_height;

      affine = (*env)->GetDoubleArrayElements (env, jaffine, NULL);

      new_width = abs (width * affine[0]);
      new_height = abs (height * affine[3]);

      dst = (art_u8 *) malloc (sizeof (art_u8) * 3 * (new_width * new_height));
      
      art_rgb_affine (dst, 
		      0, 0,
		      new_width, new_height,
		      new_width * 3,
		      (art_u8 *) packed + offset * 3,
		      width, height,
		      scansize * 3,
		      affine,
		      ART_FILTER_NEAREST,
		      alphagamma);

      (*env)->ReleaseDoubleArrayElements (env, jaffine, affine, JNI_ABORT);
      
      free (packed);
      packed = (guchar *) dst;

      width = scansize = new_width;
      height = new_height;
      offset = 0;
    }

  gdk_threads_enter ();

  if (!g || !GDK_IS_DRAWABLE (g->drawable))
    {
      gdk_threads_leave ();
      return;
    }

  gdk_draw_rgb_image (g->drawable,
		      g->gc,
		      x + g->x_offset, 
		      y + g->y_offset, 
		      width, height, GDK_RGB_DITHER_NORMAL,
		      packed + offset * 3, scansize * 3);

  gdk_threads_leave ();

  free (pixels); 
  free (packed);
}