/*! * \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); }
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; }
/*! * \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); }