Example #1
0
/*!
 * \brief Draw an image to Dia's _Image
 * \todo use maskColors to have some alpha support
 */
void
DiaOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
			int width, int height, GfxImageColorMap *colorMap,
			GBool interpolate, int *maskColors, GBool inlineImg)
{
  DiaObject *obj;
  GdkPixbuf *pixbuf;
  Point pos;
  ObjectChange *change;
  double *ctm = state->getCTM();

  pos.x = ctm[4] * scale;
  // there is some undocumented magic done with the ctm for drawImage
  // deduced from SplashOutputDev::drawImage()
  // cmt[2] and ctm[3] being negative - use that for y postion
  // ctm[0] and ctm[3] have width and height in device coordinates
  pos.y = (ctm[5] + ctm[3]) * scale;

  pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, maskColors ? TRUE : FALSE, 8, width, height);

  {
     // 3 channels, 8 bit
    ImageStream imgStr(str, width, colorMap->getNumPixelComps(), colorMap->getBits());
    Guchar *line;
    int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
    guchar *pixels = gdk_pixbuf_get_pixels (pixbuf);
    int y;

    imgStr.reset(); // otherwise getLine() is crashing right away
    line = imgStr.getLine ();
    for (y = 0; y < height && line; ++y) {
      guchar *dest = pixels + y * rowstride;

      colorMap->getRGBLine (line, dest, width);

      // ToDo: respect maskColors

      line = imgStr.getLine ();
    }
  }
  obj = create_standard_image (pos.x, pos.y, 
			       ctm[0]  * scale,
			       ctm[3]  * scale, NULL);
  if ((change = dia_object_set_pixbuf (obj, pixbuf)) != NULL)
    change->free (change); /* reference transfered */
  else
    g_object_unref (pixbuf);

  addObject (obj);
}
Example #2
0
static DiaObject *
fig_read_polyline(FILE *file, DiaContext *ctx) 
{
    int sub_type;
    int line_style;
    int thickness;
    int pen_color;
    int fill_color;
    int depth;
    int pen_style;
    int area_fill;
    real style_val;
    int join_style;
    int cap_style;
    int radius;
    int forward_arrow, backward_arrow;
    Arrow *forward_arrow_info = NULL, *backward_arrow_info = NULL;
    int npoints;
    Point *points;
    GPtrArray *props = g_ptr_array_new();
    DiaObject *newobj = NULL;
    int flipped = 0;
    char *image_file = NULL;
    char* old_locale;

    old_locale = setlocale(LC_NUMERIC, "C");
    if (fscanf(file, "%d %d %d %d %d %d %d %d %lf %d %d %d %d %d %d\n",
	       &sub_type,
	       &line_style,
	       &thickness,
	       &pen_color,
	       &fill_color,
	       &depth,
	       &pen_style,
	       &area_fill,
	       &style_val,
	       &join_style,
	       &cap_style,
	       &radius,
	       &forward_arrow,
	       &backward_arrow,
	       &npoints) != 15) {
	dia_context_add_message_with_errno(ctx, errno, _("Couldn't read polyline info.\n"));
	goto exit;
    }

    if (forward_arrow == 1) {
	forward_arrow_info = fig_read_arrow(file, ctx);
    }

    if (backward_arrow == 1) {
	backward_arrow_info = fig_read_arrow(file, ctx);
    }

    if (sub_type == 5) { /* image has image name before npoints */
	/* Despite what the specs say */
	if (fscanf(file, " %d", &flipped) != 1) {
	    dia_context_add_message_with_errno(ctx, errno, _("Couldn't read flipped bit."));
	    goto exit;
	}

	image_file = fig_read_text_line(file);

    }

    if (!fig_read_n_points(file, npoints, &points, ctx)) {
	goto exit;
    }
     
    switch (sub_type) {
    case 4: {
	RealProperty *rprop = 
	    (RealProperty *)make_new_prop("corner_radius",
					  PROP_TYPE_REAL,PROP_FLAG_DONT_SAVE);
	if (radius < 0) {
	    dia_context_add_message(ctx, _("Negative corner radius; negating"));
	    rprop->real_data = -radius/FIG_ALT_UNIT;
	} else {
	    rprop->real_data = radius/FIG_ALT_UNIT;
	}
	g_ptr_array_add(props,rprop);
    }
	/* Notice fallthrough */
    case 2: /* box */
	if (points[0].x > points[2].x) {
	    real tmp = points[0].x;
	    points[0].x = points[2].x;
	    points[2].x = tmp;
	}
	if (points[0].y > points[2].y) {
	    real tmp = points[0].y;
	    points[0].y = points[2].y;
	    points[2].y = tmp;
	}
	newobj = create_standard_box(points[0].x, points[0].y,
				     points[2].x-points[0].x,
				     points[2].y-points[0].y);
	if (newobj == NULL) goto exit;
	newobj->ops->set_props(newobj, props);
	break;
    case 5: /* imported-picture bounding-box) */
	newobj = create_standard_image(points[0].x, points[0].y,
				       points[2].x-points[0].x,
				       points[2].y-points[0].y,
				       image_file);
	if (newobj == NULL) goto exit;
	break;
    case 1: /* polyline */
	newobj = create_standard_polyline(npoints, points, 
					  forward_arrow_info, 
					  backward_arrow_info);
	if (newobj == NULL) goto exit;
	break;
    case 3: /* polygon */
	newobj = create_standard_polygon(npoints, points);
	if (newobj == NULL) goto exit;
	break;
    default: 
	dia_context_add_message(ctx, _("Unknown polyline subtype: %d\n"), sub_type);
	goto exit;
    }

    fig_simple_properties(newobj, line_style, style_val, thickness,
			  pen_color, fill_color, area_fill, ctx);
    /* Pen style field (not used) */
    /* Style_val (size of dots and dashes) in 1/80 inch*/
    /* Join style */
    /* Cap style */
     
    /* Depth field */
    add_at_depth(newobj, depth, ctx);
 exit:
    setlocale(LC_NUMERIC, old_locale);
    prop_list_free(props);
    g_free(forward_arrow_info);
    g_free(backward_arrow_info);
    g_free(image_file);
    return newobj;
}
Example #3
0
/*!
 * \brief Draw an image to Dia's _Image
 * \todo use maskColors to have some alpha support
 */
void
DiaOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
			int width, int height, GfxImageColorMap *colorMap,
			GBool interpolate, int *maskColors, GBool inlineImg)
{
  DiaObject *obj;
  GdkPixbuf *pixbuf;
  Point pos;
  ObjectChange *change;
  double *ctm = state->getCTM();

  pos.x = ctm[4] * scale;
  // there is some undocumented magic done with the ctm for drawImage
  // deduced from SplashOutputDev::drawImage()
  // cmt[2] and ctm[3] being negative - use that for y postion
  // ctm[0] and ctm[3] have width and height in device coordinates
  pos.y = (ctm[5] + ctm[3]) * scale;
#ifdef USE_IMAGE_CACHE /* bogus: neither 'ref' nor  'str' work as unique key */
  // rather than creating the image over and over again we try to cache them
  // via the given 'stream' object
  if ((pixbuf = static_cast<GdkPixbuf*>(g_hash_table_lookup (this->image_cache, str))) != NULL) {
    g_object_ref (pixbuf);
  } else {
#endif
    pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, maskColors ? TRUE : FALSE, 8, width, height);

    {
       // 3 channels, 8 bit
      ImageStream imgStr(str, width, colorMap->getNumPixelComps(), colorMap->getBits());
      Guchar *line;
      int rowstride = gdk_pixbuf_get_rowstride (pixbuf);
      guchar *pixels = gdk_pixbuf_get_pixels (pixbuf);
      int y;

      imgStr.reset(); // otherwise getLine() is crashing right away
      line = imgStr.getLine ();
      for (y = 0; y < height && line; ++y) {
	guchar *dest = pixels + y * rowstride;

	colorMap->getRGBLine (line, dest, width);

	if (maskColors) {
	  for (int x = 0; x < width; x++) {
	    bool is_opaque = false;
	    for (int i = 0; i < colorMap->getNumPixelComps(); ++i) {
	      if (line[i] < maskColors[2*i] ||
		  line[i] > maskColors[2*i+1]) {
		is_opaque = true;
		break;
	      }
	    }
	    if (is_opaque)
	      *dest |= 0xff000000;
	    else
	      *dest = 0;
	    dest++;
	    line += colorMap->getNumPixelComps();
	  }
	}

	line = imgStr.getLine ();
      }
    }
#ifdef USE_IMAGE_CACHE
    // insert the new image into our cache
    g_hash_table_insert (this->image_cache, str, g_object_ref (pixbuf));
  }
#endif
  obj = create_standard_image (pos.x, pos.y, 
			       ctm[0]  * scale,
			       ctm[3]  * scale, NULL);
  if ((change = dia_object_set_pixbuf (obj, pixbuf)) != NULL) {
    change->free (change);
    g_free (change);
  }

  g_object_unref (pixbuf);

  addObject (obj);
}