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