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 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 void image_draw(Image *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) { 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 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); }
/*! * \brief Parse the SVG node from a shape file * * Fill the ShapeInfo display list with GraphicElement each got from * a single node within the shape's SVG part. * * \extends _ShapeInfo */ static void parse_svg_node(ShapeInfo *info, xmlNodePtr node, xmlNsPtr svg_ns, DiaSvgStyle *style, const gchar *filename) { xmlChar *str; /* walk SVG node ... */ for (node = node->xmlChildrenNode; node != NULL; node = node->next) { GraphicElement *el = NULL; DiaSvgStyle s; if (xmlIsBlankNode(node)) continue; if (node->type != XML_ELEMENT_NODE || node->ns != svg_ns) continue; dia_svg_style_init (&s, style); dia_svg_parse_style(node, &s, -1); if (!xmlStrcmp(node->name, (const xmlChar *)"line")) { GraphicElementLine *line = g_new0(GraphicElementLine, 1); el = (GraphicElement *)line; line->type = GE_LINE; str = xmlGetProp(node, (const xmlChar *)"x1"); if (str) { line->p1.x = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"y1"); if (str) { line->p1.y = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"x2"); if (str) { line->p2.x = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"y2"); if (str) { line->p2.y = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } } else if (!xmlStrcmp(node->name, (const xmlChar *)"polyline")) { GraphicElementPoly *poly; GArray *arr = g_array_new(FALSE, FALSE, sizeof(real)); real val, *rarr; gchar *tmp; int i; str = xmlGetProp(node, (const xmlChar *)"points"); tmp = (gchar *) str; while (tmp[0] != '\0') { /* skip junk */ while (tmp[0] != '\0' && !g_ascii_isdigit(tmp[0]) && tmp[0]!='.'&&tmp[0]!='-') tmp++; if (tmp[0] == '\0') break; val = g_ascii_strtod(tmp, &tmp); g_array_append_val(arr, val); } xmlFree(str); val = 0; if (arr->len % 2 == 1) g_array_append_val(arr, val); poly = g_malloc0(sizeof(GraphicElementPoly) + arr->len/2*sizeof(Point)); el = (GraphicElement *)poly; poly->type = GE_POLYLINE; poly->npoints = arr->len / 2; rarr = (real *)arr->data; for (i = 0; i < poly->npoints; i++) { poly->points[i].x = rarr[2*i]; poly->points[i].y = rarr[2*i+1]; } g_array_free(arr, TRUE); } else if (!xmlStrcmp(node->name, (const xmlChar *)"polygon")) { GraphicElementPoly *poly; GArray *arr = g_array_new(FALSE, FALSE, sizeof(real)); real val, *rarr; char *tmp; int i; str = xmlGetProp(node, (const xmlChar *)"points"); tmp = (char *) str; while (tmp[0] != '\0') { /* skip junk */ while (tmp[0] != '\0' && !g_ascii_isdigit(tmp[0]) && tmp[0]!='.'&&tmp[0]!='-') tmp++; if (tmp[0] == '\0') break; val = g_ascii_strtod(tmp, &tmp); g_array_append_val(arr, val); } xmlFree(str); val = 0; if (arr->len % 2 == 1) g_array_append_val(arr, val); poly = g_malloc0(sizeof(GraphicElementPoly) + arr->len/2*sizeof(Point)); el = (GraphicElement *)poly; poly->type = GE_POLYGON; poly->npoints = arr->len / 2; rarr = (real *)arr->data; for (i = 0; i < poly->npoints; i++) { poly->points[i].x = rarr[2*i]; poly->points[i].y = rarr[2*i+1]; } g_array_free(arr, TRUE); } else if (!xmlStrcmp(node->name, (const xmlChar *)"rect")) { GraphicElementRect *rect = g_new0(GraphicElementRect, 1); real corner_radius = 0.0; el = (GraphicElement *)rect; rect->type = GE_RECT; str = xmlGetProp(node, (const xmlChar *)"x"); if (str) { rect->corner1.x = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } else rect->corner1.x = 0; str = xmlGetProp(node, (const xmlChar *)"y"); if (str) { rect->corner1.y = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } else rect->corner1.y = 0; str = xmlGetProp(node, (const xmlChar *)"width"); if (str) { rect->corner2.x = rect->corner1.x + g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"height"); if (str) { rect->corner2.y = rect->corner1.y + g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"rx"); if (str) { corner_radius = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"ry"); if (str) { if(corner_radius != 0.0) { /* calculate the mean value of rx and ry */ corner_radius = (corner_radius+g_ascii_strtod((gchar *) str, NULL))/2; } else { corner_radius = g_ascii_strtod((gchar *) str, NULL); } xmlFree(str); } rect->corner_radius = corner_radius; } else if (!xmlStrcmp(node->name, (const xmlChar *)"text")) { GraphicElementText *text = g_new(GraphicElementText, 1); el = (GraphicElement *)text; text->type = GE_TEXT; text->object = NULL; str = xmlGetProp(node, (const xmlChar *)"x"); if (str) { text->anchor.x = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } else text->anchor.x = 0; str = xmlGetProp(node, (const xmlChar *)"y"); if (str) { text->anchor.y = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } else text->anchor.y = 0; str = xmlGetProp(node, (const xmlChar *)"font-size"); if (str) { text->s.font_height = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } else text->s.font_height = 0.8; str = xmlNodeGetContent(node); if (str) { text->string = g_strdup((gchar *) str); xmlFree(str); } else text->string = g_strdup(""); } else if (!xmlStrcmp(node->name, (const xmlChar *)"circle")) { GraphicElementEllipse *ellipse = g_new0(GraphicElementEllipse, 1); el = (GraphicElement *)ellipse; ellipse->type = GE_ELLIPSE; str = xmlGetProp(node, (const xmlChar *)"cx"); if (str) { ellipse->center.x = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"cy"); if (str) { ellipse->center.y = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"r"); if (str) { ellipse->width = ellipse->height = 2 * g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } } else if (!xmlStrcmp(node->name, (const xmlChar *)"ellipse")) { GraphicElementEllipse *ellipse = g_new0(GraphicElementEllipse, 1); el = (GraphicElement *)ellipse; ellipse->type = GE_ELLIPSE; str = xmlGetProp(node, (const xmlChar *)"cx"); if (str) { ellipse->center.x = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"cy"); if (str) { ellipse->center.y = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"rx"); if (str) { ellipse->width = 2 * g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"ry"); if (str) { ellipse->height = 2 * g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } } else if (!xmlStrcmp(node->name, (const xmlChar *)"path")) { str = xmlGetProp(node, (const xmlChar *)"d"); if (str) { parse_path(info, (char *) str, &s, filename); xmlFree(str); } } else if (!xmlStrcmp(node->name, (const xmlChar *)"image")) { GraphicElementImage *image = g_new0(GraphicElementImage, 1); el = (GraphicElement *)image; image->type = GE_IMAGE; str = xmlGetProp(node, (const xmlChar *)"x"); if (str) { image->topleft.x = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"y"); if (str) { image->topleft.y = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"width"); if (str) { image->width = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"height"); if (str) { image->height = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"xlink:href"); if (!str) /* this doesn't look right but it appears to work w/o namespace --hb */ str = xmlGetProp(node, (const xmlChar *)"href"); if (str) { gchar *imgfn = NULL; const char* data = strchr((char *)str, ','); /* first check for inlined data */ if (data) { GdkPixbuf *pixbuf = pixbuf_decode_base64 (data+1); if (pixbuf) { image->image = dia_image_new_from_pixbuf (pixbuf); g_object_unref (pixbuf); } } else { imgfn = g_filename_from_uri((gchar *) str, NULL, NULL); if (!imgfn) /* despite it's name it ensures an absolute filename */ imgfn = custom_get_relative_filename(filename, (gchar *) str); image->image = dia_image_load(imgfn); } if (!image->image) g_debug("failed to load image file %s", imgfn ? imgfn : "(data:)"); g_free(imgfn); xmlFree(str); } /* w/o the image we would crash later */ if (!image->image) image->image = dia_image_get_broken(); } else if (!xmlStrcmp(node->name, (const xmlChar *)"g")) { if (!is_subshape(node)) { /* add elements from the group element */ parse_svg_node(info, node, svg_ns, &s, filename); } else { /* add elements from the group element, but make it a subshape */ GraphicElementSubShape *subshape = g_new0(GraphicElementSubShape, 1); ShapeInfo* tmpinfo = g_new0(ShapeInfo, 1); xmlChar *v_anchor_attr = xmlGetProp(node, (const xmlChar*)"v_anchor"); xmlChar *h_anchor_attr = xmlGetProp(node, (const xmlChar*)"h_anchor"); parse_svg_node(tmpinfo, node, svg_ns, &s, filename); tmpinfo->shape_bounds.top = DBL_MAX; tmpinfo->shape_bounds.left = DBL_MAX; tmpinfo->shape_bounds.bottom = -DBL_MAX; tmpinfo->shape_bounds.right = -DBL_MAX; update_bounds( tmpinfo ); update_bounds( info ); subshape->half_width = (tmpinfo->shape_bounds.right-tmpinfo->shape_bounds.left) / 2.0; subshape->half_height = (tmpinfo->shape_bounds.bottom-tmpinfo->shape_bounds.top) / 2.0; subshape->center.x = tmpinfo->shape_bounds.left + subshape->half_width; subshape->center.y = tmpinfo->shape_bounds.top + subshape->half_height; subshape->type = GE_SUBSHAPE; subshape->display_list = tmpinfo->display_list; subshape->v_anchor_method = OFFSET_METHOD_FIXED; subshape->h_anchor_method = OFFSET_METHOD_FIXED; subshape->default_scale = 0.0; if (!v_anchor_attr || !strcmp((const char*)v_anchor_attr,"fixed.top")) subshape->v_anchor_method = OFFSET_METHOD_FIXED; else if (v_anchor_attr && !strcmp((const char*)v_anchor_attr,"fixed.bottom")) subshape->v_anchor_method = -OFFSET_METHOD_FIXED; else if (v_anchor_attr && !strcmp((const char*)v_anchor_attr,"proportional")) subshape->v_anchor_method = OFFSET_METHOD_PROPORTIONAL; else fprintf( stderr, "illegal v_anchor `%s', defaulting to fixed.top\n", v_anchor_attr ); if (!h_anchor_attr || !strcmp((const char*)h_anchor_attr,"fixed.left")) subshape->h_anchor_method = OFFSET_METHOD_FIXED; else if (h_anchor_attr && !strcmp((const char*)h_anchor_attr,"fixed.right")) subshape->h_anchor_method = -OFFSET_METHOD_FIXED; else if (h_anchor_attr && !strcmp((const char*)h_anchor_attr,"proportional")) subshape->h_anchor_method = OFFSET_METHOD_PROPORTIONAL; else fprintf( stderr, "illegal h_anchor `%s', defaulting to fixed.left\n", h_anchor_attr ); info->subshapes = g_list_append(info->subshapes, subshape); /* gfree( tmpinfo );*/ xmlFree(v_anchor_attr); xmlFree(h_anchor_attr); el = (GraphicElement *)subshape; } } if (el) { el->any.s = s; if (el->any.s.font) el->any.s.font = g_object_ref(s.font); info->display_list = g_list_append(info->display_list, el); } if (s.font) dia_font_unref (s.font); } }