示例#1
0
文件: pydia-image.c 项目: UIKit0/dia
/*
 * GetAttr
 */
static PyObject *
PyDiaImage_GetAttr(PyDiaImage *self, gchar *attr)
{
  if (!strcmp(attr, "__members__"))
    return Py_BuildValue("[ssssss]", "width", "height", 
                                    "rgb_data", "mask_data",
                                    "filename", "uri");
  else if (!strcmp(attr, "width"))
    return PyInt_FromLong(dia_image_width(self->image));
  else if (!strcmp(attr, "height"))
    return PyInt_FromLong(dia_image_height(self->image));
  else if (!strcmp(attr, "filename")) {
    return PyString_FromString(dia_image_filename(self->image));
  }
  else if (!strcmp(attr, "uri")) {
    GError* error = NULL;
    char* s = g_filename_to_uri(dia_image_filename(self->image), NULL, &error);
    if (s) {
      PyObject* py_s = PyString_FromString(s);
      g_free(s);
      return py_s;
    }
    else {
      PyErr_SetString(PyExc_RuntimeError, error->message);
      g_error_free (error);
      return NULL;
    }
  }
  else if (!strcmp(attr, "rgb_data")) {
    unsigned char* s = dia_image_rgb_data(self->image);
    int len = dia_image_width(self->image) * dia_image_height(self->image) * 3;
    PyObject* py_s;

    if (!s)
      return PyErr_NoMemory();
    py_s = PyString_FromStringAndSize((const char *)s, len);
    g_free (s);
    return py_s;
  }
  else if (!strcmp(attr, "mask_data")) {
    unsigned char* s = dia_image_mask_data(self->image);
    int len = dia_image_width(self->image) * dia_image_height(self->image);
    PyObject* py_s;

    if (!s)
      return PyErr_NoMemory();
    py_s = PyString_FromStringAndSize((const char *)s, len);
    g_free (s);
    return py_s;
  }

  PyErr_SetString(PyExc_AttributeError, attr);
  return NULL;
}
示例#2
0
文件: eimage.c 项目: montsuqi/monpe
static void
image_draw(EImage *image, DiaRenderer *renderer)
{
  DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
  Point ul_corner, lr_corner;
  Element *elem;
  
  assert(image != NULL);
  assert(renderer != NULL);

  elem = &image->element;
  
  lr_corner.x = elem->corner.x + elem->width + image->border_width/2;
  lr_corner.y = elem->corner.y + elem->height + image->border_width/2;
  
  ul_corner.x = elem->corner.x - image->border_width/2;
  ul_corner.y = elem->corner.y - image->border_width/2;

  if (image->draw_border) {
    renderer_ops->set_linewidth(renderer, image->border_width);
    renderer_ops->set_linestyle(renderer, image->line_style);
    renderer_ops->set_dashlength(renderer, image->dashlength);
    renderer_ops->set_linejoin(renderer, LINEJOIN_MITER);
    
    renderer_ops->draw_rect(renderer, 
			     &ul_corner,
			     &lr_corner, 
			     &image->border_color);
  }
  /* Draw the image */
  if (image->image) {
    if (image->keep_orig_aspect) {
      real aspect;
      real width,height;
      Point corner;
      
      aspect = (real)dia_image_width(image->image) / 
        (real)dia_image_height(image->image);

      width = elem->height * aspect;
      if (width < elem->width) {
        height = elem->height;
      } else {
        width = elem->width;
        height = elem->width * (1.0/aspect);
      }
      corner.x = elem->corner.x + elem->width / 2.0 - width / 2.0;
      corner.y = elem->corner.y + elem->height / 2.0 - height / 2.0;
      renderer_ops->draw_image(renderer,&corner,width,height,image->image);
    } else {
      renderer_ops->draw_image(renderer, &elem->corner, elem->width,
	  		      elem->height, image->image);
    }
  } else {
    DiaImage *broken = dia_image_get_broken();
    renderer_ops->draw_image(renderer, &elem->corner, elem->width,
			      elem->height, broken);
    dia_image_unref(broken);
  }
}
示例#3
0
static Object *
image_create(Point *startpoint,
	     void *user_data,
	     Handle **handle1,
	     Handle **handle2)
{
  Image *image;
  Element *elem;
  Object *obj;
  int i;

  image = g_malloc(sizeof(Image));
  elem = (Element *) image;
  obj = (Object *) image;
  
  obj->type = &image_type;

  obj->ops = &image_ops;

  elem->corner = *startpoint;
  elem->width = DEFAULT_WIDTH;
  elem->height = DEFAULT_WIDTH;

  image_init_defaults();
    
  image->border_width =  attributes_get_default_linewidth();
  image->border_color = attributes_get_foreground();
  image->line_style = default_properties.line_style;
  
  element_init(elem, 8, 8);

  for (i=0;i<8;i++) {
    obj->connections[i] = &image->connections[i];
    image->connections[i].object = obj;
    image->connections[i].connected = NULL;
  }

  if (strcmp(default_properties.file, "")) {
    image->file = g_strdup(default_properties.file);
    image->image = dia_image_load(image->file);

    if (image->image) {
      elem->width = (elem->width*(float)dia_image_width(image->image))/
	(float)dia_image_height(image->image);
    }
  } else {
    image->file = g_strdup("");
    image->image = NULL;
  }

  image->draw_border = default_properties.draw_border;
  image->keep_aspect = default_properties.keep_aspect;

  image_update_data(image);
  
  *handle1 = NULL;
  *handle2 = obj->handles[7];  
  return (Object *)image;
}
示例#4
0
文件: image.c 项目: jbohren-forks/dia
static void
image_set_props(Image *image, GPtrArray *props)
{
  struct stat st;
  time_t mtime = 0;
  char *old_file = image->file ? g_strdup(image->file) : NULL;
  const GdkPixbuf *old_pixbuf = dia_image_pixbuf (image->image);
  gboolean was_inline = image->inline_data;

  object_set_props_from_offsets(&image->element.object, image_offsets, props);

  if (old_pixbuf != image->pixbuf) {
    if (!image->file || *image->file == '\0') {
      GdkPixbuf *pixbuf = NULL;
      image->inline_data = TRUE; /* otherwise we'll loose it */
      /* somebody deleting the filename? */
      if (!image->pixbuf && image->image)
	pixbuf = g_object_ref ((GdkPixbuf *)dia_image_pixbuf (image->image));
      if (image->image)
        g_object_unref (image->image);
      image->image = dia_image_new_from_pixbuf (image->pixbuf ? image->pixbuf : pixbuf);
      image->pixbuf = (GdkPixbuf *)dia_image_pixbuf (image->image);
      if (pixbuf)
	g_object_unref (pixbuf);
    } else {
      if (image->pixbuf)
        message_warning ("FIXME: handle pixbuf change!");
    }
  }

  /* use old value on error */
  if (!image->file || g_stat (image->file, &st) != 0)
    mtime = image->mtime;
  else
    mtime = st.st_mtime;

  /* handle changing the image. */
  if (image->file && image->pixbuf && was_inline && !image->inline_data) {
    /* export inline data */
    if (was_inline && !image->inline_data)
      /* if saving fails we keep it inline */
      image->inline_data = !dia_image_save (image->image, image->file);
  } else if (image->file && ((old_file && strcmp(image->file, old_file) != 0) || image->mtime != mtime)) {
    Element *elem = &image->element;
    DiaImage *img = NULL;

    if ((img = dia_image_load(image->file)) != NULL)
      image->image = img;
    else if (!image->pixbuf) /* dont overwrite inlined */
      image->image = dia_image_get_broken();
    elem->height = (elem->width*(float)dia_image_height(image->image))/
      (float)dia_image_width(image->image);
  }
  g_free(old_file);
  /* remember it */
  image->mtime = mtime;

  image_update_data(image);
}
示例#5
0
文件: image.c 项目: jbohren-forks/dia
static DiaObject *
image_create(Point *startpoint,
	     void *user_data,
	     Handle **handle1,
	     Handle **handle2)
{
  Image *image;
  Element *elem;
  DiaObject *obj;
  int i;

  image = g_malloc0(sizeof(Image));
  elem = &image->element;
  obj = &elem->object;
  
  obj->type = &image_type;
  obj->ops = &image_ops;

  elem->corner = *startpoint;
  elem->width = DEFAULT_WIDTH;
  elem->height = DEFAULT_HEIGHT;
    
  image->border_width =  attributes_get_default_linewidth();
  image->border_color = attributes_get_foreground();
  attributes_get_default_line_style(&image->line_style,
				    &image->dashlength);
  
  element_init(elem, 8, NUM_CONNECTIONS);

  for (i=0; i<NUM_CONNECTIONS; i++) {
    obj->connections[i] = &image->connections[i];
    image->connections[i].object = obj;
    image->connections[i].connected = NULL;
  }
  image->connections[8].flags = CP_FLAGS_MAIN;

  if (strcmp(default_properties.file, "")) {
    image->file = g_strdup(default_properties.file);
    image->image = dia_image_load(image->file);

    if (image->image) {
      elem->width = (elem->width*(float)dia_image_width(image->image))/
	(float)dia_image_height(image->image);
    }
  } else {
    image->file = g_strdup("");
    image->image = NULL;
  }

  image->draw_border = default_properties.draw_border;
  image->keep_aspect = default_properties.keep_aspect;

  image_update_data(image);
  
  *handle1 = NULL;
  *handle2 = obj->handles[7];  
  return &image->element.object;
}
示例#6
0
文件: pydia-image.c 项目: UIKit0/dia
/*
 * Repr / _Str
 */
static PyObject *
PyDiaImage_Str(PyDiaImage *self)
{
  PyObject* py_s;
  const gchar* name = dia_image_filename(self->image);
  gchar* s = g_strdup_printf("%ix%i,%s",
                             dia_image_width(self->image),
                             dia_image_height(self->image),
                             name ? name : "(null)");
  py_s = PyString_FromString(s);
  g_free (s);
  return py_s;
}
示例#7
0
static void
draw_image(DiaRenderer *self,
	   Point *point,
	   real width, real height,
	   DiaImage *image)
{
    WmfRenderer *renderer = WMF_RENDERER (self);
#ifdef DIRECT_WMF
    /* not yet supported in compatibility mode */
#else	
    W32::HBITMAP hBmp;
    int iWidth, iHeight;
    unsigned char* pData = NULL;
    unsigned char* pImg  = NULL;

    DIAG_NOTE(renderer, "draw_image %fx%f @%f,%f\n", 
              width, height, point->x, point->y);

    iWidth  = dia_image_width(image);
    iHeight = dia_image_height(image);
    pImg = dia_image_rgb_data(image);

#if 0 /* only working with 24 bit screen resolution */
    if ((dia_image_width(image)*3) % 4)
    {
        /* transform data to be DWORD aligned */
        int x, y;
        const unsigned char* pIn = NULL;
        unsigned char* pOut = NULL;

        pOut = pData = g_new(unsigned char, ((((iWidth*3-1)/4)+1)*4)*iHeight);

        pIn = pImg;
        for (y = 0; y < iHeight; y++)
        {
            for (x = 0; x < iWidth; x++)
            {
                *pOut++ = *pIn++;
                *pOut++ = *pIn++;
                *pOut++ = *pIn++;
            }
            pOut += (4 - (iWidth*3)%4);
        }

        hBmp = W32::CreateBitmap ( iWidth, iHeight, 1, 24, pData);
    }
示例#8
0
文件: image.c 项目: jbohren-forks/dia
static void
image_update_data(Image *image)
{
  Element *elem = &image->element;
  ElementBBExtras *extra = &elem->extra_spacing;
  DiaObject *obj = &elem->object;

  if (image->keep_aspect && image->image) {
    /* maybe the image got changes since */
    real aspect_org = (float)dia_image_width(image->image)
                    / (float)dia_image_height(image->image);
    real aspect_now = elem->width / elem->height;

    if (fabs (aspect_now - aspect_org) > 1e-4) {
      elem->height = elem->width /aspect_org;
    }
  }

  /* Update connections: */
  image->connections[0].pos = elem->corner;
  image->connections[1].pos.x = elem->corner.x + elem->width / 2.0;
  image->connections[1].pos.y = elem->corner.y;
  image->connections[2].pos.x = elem->corner.x + elem->width;
  image->connections[2].pos.y = elem->corner.y;
  image->connections[3].pos.x = elem->corner.x;
  image->connections[3].pos.y = elem->corner.y + elem->height / 2.0;
  image->connections[4].pos.x = elem->corner.x + elem->width;
  image->connections[4].pos.y = elem->corner.y + elem->height / 2.0;
  image->connections[5].pos.x = elem->corner.x;
  image->connections[5].pos.y = elem->corner.y + elem->height;
  image->connections[6].pos.x = elem->corner.x + elem->width / 2.0;
  image->connections[6].pos.y = elem->corner.y + elem->height;
  image->connections[7].pos.x = elem->corner.x + elem->width;
  image->connections[7].pos.y = elem->corner.y + elem->height;
  image->connections[8].pos.x = elem->corner.x + elem->width / 2.0;
  image->connections[8].pos.y = elem->corner.y + elem->height / 2.0;
  
  /* the image border is drawn vompletely outside of the image, so no /2.0 on border width */
  extra->border_trans = (image->draw_border ? image->border_width : 0.0);
  element_update_boundingbox(elem);
  
  obj->position = elem->corner;
  image->connections[8].directions = DIR_ALL;
  element_update_handles(elem);
}
示例#9
0
static ObjectChange *
image_apply_properties(Image *image)
{
  gchar *new_file;
  ObjectState *old_state;

  if (image != image_properties_dialog->image) {
    message_warning("Image dialog problem:  %p != %p\n", 
		    image, image_properties_dialog->image);
    image = image_properties_dialog->image;
  }

  old_state = (ObjectState *)image_get_state(image);

  image->border_width = gtk_spin_button_get_value_as_float(image_properties_dialog->border_width);
  dia_color_selector_get_color(image_properties_dialog->fg_color, &image->border_color);
  dia_line_style_selector_get_linestyle(image_properties_dialog->line_style, &image->line_style, NULL);

  image->draw_border = gtk_toggle_button_get_active(image_properties_dialog->draw_border);
  image->keep_aspect = gtk_toggle_button_get_active(image_properties_dialog->keep_aspect);
  
  new_file = dia_file_selector_get_file(image_properties_dialog->file);
  if (image->file) g_free(image->file);
  if (image->image) {
    dia_image_release(image->image);
  }
  image->image = dia_image_load(new_file);
  if ((image->image != NULL) && (image->keep_aspect)) {
    /* Must... keep... aspect... ratio... */
    float ratio = (float)dia_image_height(image->image)/
      (float)dia_image_width(image->image);
    image->element.height = image->element.width * ratio;
  }
  image->file = g_strdup(new_file);

  image_update_data(image);
  return new_object_state_change((Object *)image, old_state, 
				 (GetStateFunc)image_get_state,
				 (SetStateFunc)image_set_state);
}
示例#10
0
文件: eimage.c 项目: montsuqi/monpe
static void
image_set_props(EImage *image, GPtrArray *props)
{
  struct stat st;
  time_t mtime = 0;
  char *old_file = image->file ? g_strdup(image->file) : "";

  object_set_props_from_offsets(&image->element.object, image_offsets, props);

  /* use old value on error */
  if (g_stat (image->file, &st) != 0)
    mtime = image->mtime;
  else
    mtime = st.st_mtime;

  /* handle changing the image. */
  if (strcmp(image->file, old_file) != 0 || image->mtime != mtime) {
    Element *elem = &image->element;
    DiaImage *img = NULL;

    img = dia_image_load(image->file);
    if (img)
      image->image = img;
    else
      image->image = dia_image_get_broken();
    elem->height = (elem->width*(float)dia_image_height(image->image))/
      (float)dia_image_width(image->image);
  }
  g_free(old_file);
  /* remember it */
  image->mtime = mtime;

  register_embed_id(image->embed_id);

  image_update_data(image);
}
示例#11
0
static void
draw_image(DiaRenderer *self,
	   Point *point,
	   real width, real height,
	   DiaImage *image)
{
  DiaPsRenderer *renderer = DIA_PS_RENDERER(self);
  int img_width, img_height, img_rowstride;
  int x, y;
  guint8 *rgb_data;
  guint8 *mask_data;
  gchar d1_buf[DTOSTR_BUF_SIZE];
  gchar d2_buf[DTOSTR_BUF_SIZE];

  img_width = dia_image_width(image);
  img_rowstride = dia_image_rowstride(image);
  img_height = dia_image_height(image);

  rgb_data = dia_image_rgb_data(image);
  if (!rgb_data) {
    dia_context_add_message(renderer->ctx, _("Not enough memory for image drawing."));
    return;
  }
  mask_data = dia_image_mask_data(image);

  fprintf(renderer->file, "gs\n");

  /* color output only */
  fprintf(renderer->file, "/pix %i string def\n", img_width * 3);
  fprintf(renderer->file, "%i %i 8\n", img_width, img_height);
  fprintf(renderer->file, "%s %s tr\n",
			   psrenderer_dtostr(d1_buf, point->x),
			   psrenderer_dtostr(d2_buf, point->y) );
  fprintf(renderer->file, "%s %s sc\n",
			   psrenderer_dtostr(d1_buf, width),
			   psrenderer_dtostr(d2_buf, height) );
  fprintf(renderer->file, "[%i 0 0 %i 0 0]\n", img_width, img_height);

  fprintf(renderer->file, "{currentfile pix readhexstring pop}\n");
  fprintf(renderer->file, "false 3 colorimage\n");
  fprintf(renderer->file, "\n");

  if (mask_data) {
    for (y = 0; y < img_height; y++) {
      for (x = 0; x < img_width; x++) {
	int i = y*img_rowstride+x*3;
	int m = y*img_width+x;
        fprintf(renderer->file, "%02x", 255-(mask_data[m]*(255-rgb_data[i])/255));
        fprintf(renderer->file, "%02x", 255-(mask_data[m]*(255-rgb_data[i+1])/255));
        fprintf(renderer->file, "%02x", 255-(mask_data[m]*(255-rgb_data[i+2])/255));
      }
      fprintf(renderer->file, "\n");
    }
  } else {
    for (y = 0; y < img_height; y++) {
      for (x = 0; x < img_width; x++) {
	int i = y*img_rowstride+x*3;
        fprintf(renderer->file, "%02x", (int)(rgb_data[i]));
        fprintf(renderer->file, "%02x", (int)(rgb_data[i+1]));
        fprintf(renderer->file, "%02x", (int)(rgb_data[i+2]));
      }
      fprintf(renderer->file, "\n");
    }
  }
  fprintf(renderer->file, "gr\n");
  fprintf(renderer->file, "\n");
   
  g_free(rgb_data);
  g_free(mask_data);
}
示例#12
0
文件: wpg.c 项目: mpuels/dia
static void
draw_image(DiaRenderer *self,
           Point *point,
           real width, real height,
           DiaImage *image)
{
  WpgRenderer *renderer = WPG_RENDERER (self);
  WPGBitmap2 bmp;
  guint8 * pDiaImg = NULL, * pOut = NULL, * pIn = NULL, * p = NULL;
  guint8 b_1 = 0, b = 0, cnt;
  int x, y, stride;

  bmp.Angle  = 0;
  bmp.Left   = SCX(point->x);
  bmp.Top    = SCY(-point->y);
  bmp.Right  = SCX(point->x + width);
  bmp.Bottom = SCY(-point->y - height);

  bmp.Width  = dia_image_width(image);
  bmp.Height = dia_image_height(image);
  bmp.Depth  = 8; /* maximum allowed */

  bmp.Xdpi = 72; /* ??? */
  bmp.Ydpi = 72;

  DIAG_NOTE(g_message("draw_image %fx%f [%d,%d] @%f,%f", 
            width, height, bmp.Width, bmp.Height, point->x, point->y));

  pDiaImg = dia_image_rgb_data(image);
  if (!pDiaImg) {
    dia_context_add_message(renderer->ctx, _("Not enough memory for image drawing."));
    return;
  }
  stride = dia_image_rowstride(image);
  pOut = g_new(guint8, bmp.Width * bmp.Height * 2); /* space for worst case RLE */
  p = pOut;

  for (y = 0; y < bmp.Height; y++)
  {
    /* from top to bottom line */
    pIn = pDiaImg + stride * y;
    cnt = 0; /* reset with every line */
    for (x = 0; x < bmp.Width; x ++)
    {
      /* simple color reduction to default palette */
      b = (((CC_LEN - 1) * pIn[0]) / 255) /* red */
        + (((CC_LEN - 1) * pIn[1]) / 255) * CC_LEN /* green */
        + (((CC_LEN - 1) * pIn[2]) / 255) * CC_LEN * CC_LEN /* blue */
        + WPG_NUM_DEF_COLORS;

      pIn += 3; /* increase read pointer */

      if (cnt > 0)
      {
        if ((b == b_1) && (cnt < 127)) 
          cnt++; /* increase counter*/
        else
        {
          *p++ = (cnt | 0x80); /* write run length and value */
          *p++ = b_1;
          cnt = 1; /* reset */
          b_1 = b;
        }
      }
      else
      {
        b_1 = b;
        cnt = 1;
      }
    }
    *p++ = (cnt | 0x80); /* write last value(s) */
    *p++ = b;
  }
  DIAG_NOTE(g_message( "Width x Height: %d RLE: %d", 
	      bmp.Width * bmp.Height, p - pOut));

  if ((p - pOut) > 32767) {
    dia_context_add_message(renderer->ctx, "Bitmap size exceeds blocksize. Ignored.");
  }
  else {
    WriteRecHead(renderer, WPG_BITMAP2, sizeof(WPGBitmap2) + (p - pOut));
#if 0
    fwrite(&bmp, sizeof(WPGBitmap2), 1, renderer->file);
#else
    g_assert(20 == sizeof(WPGBitmap2));
    fwrite(&bmp, sizeof(guint16), sizeof(WPGBitmap2) / sizeof(guint16), renderer->file);
#endif
    fwrite(pOut, sizeof(guint8), p - pOut, renderer->file);
  }
#if 0
  /* RLE diagnose */
  {
    FILE* f;
    int i, j;
    f = g_fopen("c:\\temp\\wpg_bmp.raw", "wb");
    j = p - pOut;
    for (i = 0; i < j; i+=2)
    {
      for (x = 0; x < (pOut[i] & 0x7F); x++) 
        fwrite(&pOut[i+1], 1, 1, f);
    }
    fclose(f);
  }
#endif
  g_free(pDiaImg);
  g_free(pOut);
}
示例#13
0
static void
draw_image(DiaRenderer *self,
           Point *point,
           real width, real height,
           DiaImage *image)
{
  DiaCairoRenderer *renderer = DIA_CAIRO_RENDERER (self);
  cairo_surface_t *surface;
  guint8 *data;
  int w = dia_image_width(image);
  int h = dia_image_height(image);
  int rs = dia_image_rowstride(image);

  DIAG_NOTE(g_message("draw_image %fx%f [%d(%d),%d] @%f,%f", 
            width, height, w, rs, h, point->x, point->y));

  if (dia_image_rgba_data (image))
    {
      const guint8 *p1 = dia_image_rgba_data (image);
      /* we need to make a copy to rearrange channels 
       * (also need to use malloc, cause Cairo insists to free() it)
       */
      guint8 *p2 = data = g_malloc (h * rs);
      int i;

      for (i = 0; i < (h * rs) / 4; i++)
        {
#  if G_BYTE_ORDER == G_LITTLE_ENDIAN
          p2[0] = p1[2]; /* b */
          p2[1] = p1[1]; /* g */
          p2[2] = p1[0]; /* r */
          p2[3] = p1[3]; /* a */
#  else
          p2[3] = p1[2]; /* b */
          p2[2] = p1[1]; /* g */
          p2[1] = p1[0]; /* r */
          p2[0] = p1[3]; /* a */
#  endif
          p1+=4;
          p2+=4;
        }

      surface = cairo_image_surface_create_for_data (data, CAIRO_FORMAT_ARGB32, w, h, rs);
    }
  else
    {
      guint8 *p, *p2;
      guint8 *p1 = data = dia_image_rgb_data (image);
      /* need to copy to be owned by cairo/pixman, urgh.
       * Also cairo wants RGB24 32 bit aligned
       */
      int x, y;

      p = p2 = g_malloc(h*w*4);
      for (y = 0; y < h; y++)
        {
          for (x = 0; x < w; x++)
            {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
              /* apparently BGR is required */
              p2[x*4  ] = p1[x*3+2];
              p2[x*4+1] = p1[x*3+1];
              p2[x*4+2] = p1[x*3  ];
              p2[x*4+3] = 0x80; /* should not matter */
#else
              p2[x*4+3] = p1[x*3+2];
              p2[x*4+2] = p1[x*3+1];
              p2[x*4+1] = p1[x*3  ];
              p2[x*4+0] = 0x80; /* should not matter */
#endif
            }
          p2 += (w*4);
          p1 += rs;
        }
      surface = cairo_image_surface_create_for_data (p, CAIRO_FORMAT_RGB24, w, h, w*4);
      g_free (data);
      data = p;
    }
  cairo_save (renderer->cr);
  cairo_translate (renderer->cr, point->x, point->y);
  cairo_scale (renderer->cr, width/w, height/h);
  cairo_move_to (renderer->cr, 0.0, 0.0);
  /* maybe just the second set_filter is required */
#if 0
  cairo_surface_set_filter (renderer->surface, CAIRO_FILTER_BEST);
  cairo_surface_set_filter (surface, CAIRO_FILTER_BEST);
#endif
  cairo_set_source_surface (renderer->cr, surface, 0.0, 0.0);
  cairo_paint (renderer->cr);
  cairo_restore (renderer->cr);
  cairo_surface_destroy (surface);

  g_free (data);

  DIAG_STATE(renderer->cr);
}