static gboolean export_shape(DiagramData *data, DiaContext *ctx, const gchar *filename, const gchar *diafilename, void* user_data) { DiaSvgRenderer *renderer; int i; gchar *point; gchar *png_filename = NULL; DiaExportFilter *exportfilter; gfloat old_scaling; Rectangle *ext = &data->extents; gfloat scaling_x, scaling_y; /* create the png preview shown in the toolbox */ point = strrchr(filename, '.'); if (point == NULL || strcmp(point, ".shape") != 0) { dia_context_add_message(ctx, _("Shape files must end in .shape, or they cannot be loaded by Dia")); return FALSE; } i = (int)(point-filename); point = g_strndup(filename, i); png_filename = g_strdup_printf("%s.png",point); g_free(point); /* we are especially requesting the libart/png cause it is the only one with the size-hack */ exportfilter = filter_export_get_by_name ("png-libart"); /* ... but the code below does not use the size-hack anymore ... */ if (!exportfilter) exportfilter = filter_guess_export_filter(png_filename); if (!exportfilter) { dia_context_add_message(ctx, _("Can't export PNG icon without export plugin!")); } else { /* get the scaling right */ old_scaling = data->paper.scaling; scaling_x = 22/((ext->right - ext->left) * 20); scaling_y = 22/((ext->bottom - ext->top) * 20); data->paper.scaling = MIN(scaling_x, scaling_y); exportfilter->export_func(data, ctx, png_filename, diafilename, exportfilter->user_data); data->paper.scaling = old_scaling; } g_free(png_filename); /* create the shape */ if((renderer = new_shape_renderer(data, filename))) { data_render(data, DIA_RENDERER(renderer), NULL, NULL, NULL); g_object_unref (renderer); return TRUE; } /* Create a sheet entry if applicable (../../sheets exists) */ return FALSE; }
/*! * Return the value of a rectangle-type data node. * @param data The data node to read from. * @param rect A place to store the resulting values. If the node does * not contain a valid rectangle value, an error message is displayed to the * user, and `rect' is unchanged. * @param ctx The context in which this function is called * \ingroup DiagramXmlIn */ void data_rectangle(DataNode data, Rectangle *rect, DiaContext *ctx) { xmlChar *val; gchar *str; if (data_type(data, ctx)!=DATATYPE_RECTANGLE) { dia_context_add_message (ctx, _("Taking rectangle value of non-rectangle node.")); return; } val = xmlGetProp(data, (const xmlChar *)"val"); rect->left = g_ascii_strtod((char *)val, &str); while ((*str != ',') && (*str!=0)) str++; if (*str==0){ dia_context_add_message (ctx, _("Error parsing rectangle.")); xmlFree(val); return; } rect->top = g_ascii_strtod(str+1, &str); while ((*str != ';') && (*str!=0)) str++; if (*str==0){ dia_context_add_message (ctx, _("Error parsing rectangle.")); xmlFree(val); return; } rect->right = g_ascii_strtod(str+1, &str); while ((*str != ',') && (*str!=0)) str++; if (*str==0){ dia_context_add_message (ctx, _("Error parsing rectangle.")); xmlFree(val); return; } rect->bottom = g_ascii_strtod(str+1, NULL); xmlFree(val); }
/*! * \brief Parse a given file into XML, handling old broken files correctly. * @param filename The name of the file to read. * @returns An XML document parsed from the file. * @see xmlParseFile() in the XML2 library for details on the return value. * @param ctx The context in which this function is called * \ingroup DiagramXmlIo */ static xmlDocPtr xmlDiaParseFile(const char *filename, DiaContext *ctx) { const char *local_charset = NULL; xmlErrorPtr error_xml = NULL; xmlDocPtr ret = NULL; if ( !g_get_charset(&local_charset) && local_charset) { /* we're not in an UTF-8 environment. */ const gchar *fname = xml_file_check_encoding(filename,local_charset, ctx); if (fname != filename) { /* We've got a corrected file to parse. */ xmlDocPtr ret = xmlDoParseFile(fname, &error_xml); unlink(fname); /* printf("has read %s instead of %s\n",fname,filename); */ g_free((void *)fname); } else { /* the XML file is good. libxml is "old enough" to handle it correctly. */ ret = xmlDoParseFile(filename, &error_xml); } } else { ret = xmlDoParseFile(filename, &error_xml); } if (error_xml) dia_context_add_message (ctx, error_xml->message); return ret; }
/*! * \brief Return the value of a font-type data node. * * This handles both the current format (family and style) and the old format (name). * @param data The data node to read from. * @param ctx The context in which this function is called * @return The font value found in the node. If the node is not a * font node, an error message is registered and NULL is returned. The * resulting value should be freed after use. * \ingroup DiagramXmlIn */ DiaFont * data_font(DataNode data, DiaContext *ctx) { xmlChar *family; DiaFont *font; if (data_type(data, ctx)!=DATATYPE_FONT) { dia_context_add_message (ctx, _("Taking font value of non-font node.")); return NULL; } family = xmlGetProp(data, (const xmlChar *)"family"); /* always prefer the new format */ if (family) { DiaFontStyle style; char* style_name = (char *) xmlGetProp(data, (const xmlChar *)"style"); style = style_name ? atoi(style_name) : 0; font = dia_font_new ((char *)family, style, 1.0); if (family) free(family); if (style_name) xmlFree(style_name); } else { /* Legacy format support */ char *name = (char *)xmlGetProp(data, (const xmlChar *)"name"); font = dia_font_new_from_legacy_name(name); free(name); } return font; }
gboolean prop_list_load(GPtrArray *props, DataNode data_node, DiaContext *ctx) { guint i; gboolean ret = TRUE; for (i = 0; i < props->len; i++) { Property *prop = g_ptr_array_index(props,i); AttributeNode attr = object_find_attribute(data_node, prop->descr->name); DataNode data = attr ? attribute_first_data(attr) : NULL; if ((!attr || !data) && prop->descr->flags & PROP_FLAG_OPTIONAL) { prop->experience |= PXP_NOTSET; continue; } if ((!attr) || (!data)) { dia_context_add_message(ctx, _("No attribute '%s' (%p) or no data (%p) in this attribute"), prop->descr->name,attr,data); prop->experience |= PXP_NOTSET; ret = FALSE; continue; } prop->ops->load(prop,attr,data,ctx); } return ret; }
static Color fig_area_fill_color(int area_fill, int color_index, DiaContext *ctx) { Color col; col = fig_color(color_index, ctx); if (area_fill == -1) return col; if (area_fill >= 0 && area_fill <= 20) { if (color_index == -1 || color_index == 0) { col.red = 0xff*(20-area_fill)/20; col.green = 0xff*(20-area_fill)/20; col.blue = 0xff*(20-area_fill)/20; col.alpha = 1.0; } else { col.red = (col.red*area_fill)/20; col.green = (col.green*area_fill)/20; col.blue = (col.blue*area_fill)/20; col.alpha = 1.0; } } else if (area_fill > 20 && area_fill <= 40) { /* White and black area illegal here */ col.red += (0xff-col.red)*(area_fill-20)/20; col.green += (0xff-col.green)*(area_fill-20)/20; col.blue += (0xff-col.blue)*(area_fill-20)/20; col.alpha = 1.0; } else { dia_context_add_message(ctx, _("Patterns are not supported by Dia")); } return col; }
static char* ps_convert_string(const char *text, DiaContext *ctx) { char *buffer; gchar *localestr; const gchar *str; gint len; GError * error = NULL; localestr = g_convert(text, -1, "LATIN1", "UTF-8", NULL, NULL, &error); if (localestr == NULL) { dia_context_add_message(ctx, "Can't convert string %s: %s\n", text, error->message); localestr = g_strdup(text); } /* Escape all '(' and ')': */ buffer = g_malloc(2*strlen(localestr)+1); *buffer = 0; str = localestr; while (*str != 0) { len = strcspn(str,"()\\"); strncat(buffer, str, len); str += len; if (*str != 0) { strcat(buffer,"\\"); strncat(buffer, str, 1); str++; } } g_free(localestr); return buffer; }
static int fig_read_n_points(FILE *file, int n, Point **points, DiaContext *ctx) { int i; GArray *points_list = g_array_sized_new(FALSE, FALSE, sizeof(Point), n); for (i = 0; i < n; i++) { int x,y; Point p; if (fscanf(file, " %d %d ", &x, &y) != 2) { dia_context_add_message_with_errno (ctx, errno, _("Error while reading %dth of %d points"), i, n); g_array_free(points_list, TRUE); return FALSE; } p.x = x/FIG_UNIT; p.y = y/FIG_UNIT; g_array_append_val(points_list, p); } if (fscanf(file, "\n") == EOF) dia_context_add_message (ctx, _("Unexpected end of file.")); *points = (Point *)points_list->data; g_array_free(points_list, FALSE); return TRUE; }
/*! * \brief Return the value of a color-type data node. * @param data The XML node to read from * @param col A place to store the resulting RGBA values. If the node does * not contain a valid color value, an error message is registered in ctx * and `col' is unchanged. * @param ctx The context in which this function is called * \ingroup DiagramXmlIn */ void data_color(DataNode data, Color *col, DiaContext *ctx) { xmlChar *val; int r=0, g=0, b=0, a=0; if (data_type(data, ctx)!=DATATYPE_COLOR) { dia_context_add_message (ctx, "Taking color value of non-color node."); return; } val = xmlGetProp(data, (const xmlChar *)"val"); /* Format #RRGGBB */ /* 0123456 */ if ((val) && (xmlStrlen(val)>=7)) { r = hex_digit(val[1], ctx)*16 + hex_digit(val[2], ctx); g = hex_digit(val[3], ctx)*16 + hex_digit(val[4], ctx); b = hex_digit(val[5], ctx)*16 + hex_digit(val[6], ctx); if (xmlStrlen(val) >= 9) { a = hex_digit(val[7], ctx)*16 + hex_digit(val[8], ctx); } else { a = 0xff; } } if (val) xmlFree(val); col->red = (float)(r/255.0); col->green = (float)(g/255.0); col->blue = (float)(b/255.0); col->alpha = (float)(a/255.0); }
static gboolean import_data (const gchar *filename, DiagramData *data, DiaContext *ctx, void* user_data) { DiaObjectType *otype = object_get_type("Standard - Image"); gint width, height; if (!otype) /* this would be really broken */ return FALSE; if (!user_data) { dia_context_add_message(ctx, _("Calling error, missing user_data.")); return FALSE; } if (gdk_pixbuf_get_file_info (filename, &width, &height)) { DiaObject *obj; Handle *h1, *h2; Point point; point.x = point.y = 0.0; obj = otype->ops->create(&point, otype->default_user_data, &h1, &h2); if (obj) { GPtrArray *plist = g_ptr_array_new (); prop_list_add_filename (plist, "image_file", filename); prop_list_add_real (plist, "elem_width", width / 20.0); prop_list_add_real (plist, "elem_height", height / 20.0); obj->ops->set_props(obj, plist); prop_list_free (plist); layer_add_object(data->active_layer, obj); return TRUE; } } else { dia_context_add_message(ctx, _("Pixbuf[%s] can't load:\n%s"), (gchar*)user_data, dia_context_get_filename(ctx)); } return FALSE; }
static Arrow * fig_read_arrow(FILE *file, DiaContext *ctx) { int arrow_type, style; real thickness, width, height; Arrow *arrow; char* old_locale; old_locale = setlocale(LC_NUMERIC, "C"); if (fscanf(file, "%d %d %lf %lf %lf\n", &arrow_type, &style, &thickness, &width, &height) != 5) { dia_context_add_message(ctx, _("Error while reading arrowhead")); setlocale(LC_NUMERIC,old_locale); return NULL; } setlocale(LC_NUMERIC,old_locale); arrow = g_new(Arrow, 1); switch (arrow_type) { case 0: arrow->type = ARROW_LINES; break; case 1: arrow->type = (style?ARROW_FILLED_TRIANGLE:ARROW_HOLLOW_TRIANGLE); break; case 2: arrow->type = (style?ARROW_FILLED_CONCAVE:ARROW_BLANKED_CONCAVE); break; case 3: arrow->type = (style?ARROW_FILLED_DIAMOND:ARROW_HOLLOW_DIAMOND); break; default: dia_context_add_message(ctx, _("Unknown arrow type %d\n"), arrow_type); g_free(arrow); return NULL; } arrow->width = width/FIG_UNIT; arrow->length = height/FIG_UNIT; return arrow; }
/** Add an object at a given depth. This function checks for depth limits * and updates the compound depth if needed. * * @param newobj An object to add. If we're inside a compound, this * doesn't really add the object. * @param depth A depth as in the Fig format, max 999 */ static void add_at_depth(DiaObject *newobj, int depth, DiaContext *ctx) { if (depth < 0 || depth >= FIG_MAX_DEPTHS) { dia_context_add_message(ctx, _("Depth %d of of range, only 0-%d allowed.\n"), depth, FIG_MAX_DEPTHS-1); depth = FIG_MAX_DEPTHS - 1; } if (compound_stack == NULL) depths[depth] = g_list_append(depths[depth], newobj); else if (compound_depth > depth) compound_depth = depth; }
/*! * \brief Return the integer value of a hex digit. * @param c A hex digit, one of 0-9, a-f or A-F. * @param ctx The context in which this function is called * @return The value of the digit, i.e. 0-15. If a non-gex digit is given * an error is registered in ctx, and 0 is returned. * \ingroup DiagramXmlIn */ static int hex_digit(char c, DiaContext *ctx) { if ((c>='0') && (c<='9')) return c-'0'; if ((c>='a') && (c<='f')) return (c-'a') + 10; if ((c>='A') && (c<='F')) return (c-'A') + 10; dia_context_add_message (ctx, "wrong hex digit %c", c); return 0; }
static LineStyle fig_line_style_to_dia(int line_style, DiaContext *ctx) { switch (line_style) { case 0: return LINESTYLE_SOLID; case 1: return LINESTYLE_DASHED; case 2: return LINESTYLE_DOTTED; case 3: return LINESTYLE_DASH_DOT; case 4: return LINESTYLE_DASH_DOT_DOT; case 5: dia_context_add_message(ctx, _("Triple-dotted lines are not supported by Dia; " "using double-dotted")); return LINESTYLE_DASH_DOT_DOT; default: dia_context_add_message(ctx, _("Line style %d should not appear"), line_style); return LINESTYLE_SOLID; } }
static int fig_read_line_choice(FILE *file, char *choice1, char *choice2, DiaContext *ctx) { char buf[BUFLEN]; if (!fgets(buf, BUFLEN, file)) { return -1; } buf[strlen(buf)-1] = 0; /* Remove trailing newline */ g_strstrip(buf); /* And any other whitespace */ if (!g_ascii_strcasecmp(buf, choice1)) return 0; if (!g_ascii_strcasecmp(buf, choice2)) return 1; dia_context_add_message(ctx, _("`%s' is not one of `%s' or `%s'\n"), buf, choice1, choice2); return 0; }
/*! * \brief Return the value of a filename-type data node. * @param data The data node to read from. * @param ctx The context in which this function is called * @return The filename value found in the node. If the node is not a * filename node, an error message is added to ctx and NULL is returned. * The resulting string is in the local filesystem's encoding rather than * UTF-8, and should be freed after use. * \ingroup DiagramXmlIn */ char * data_filename(DataNode data, DiaContext *ctx) { char *utf8 = data_string(data, ctx); char *filename = NULL; if (utf8) { GError *error = NULL; if ((filename = g_filename_from_utf8(utf8, -1, NULL, NULL, &error)) == NULL) { dia_context_add_message (ctx, "%s", error->message); g_error_free (error); } g_free(utf8); } return filename; }
/*! * \brief Parse an xml file from a filename given in Dia's/GLib's filename encoding * * @param filename A file to parse. On win32 the filename encoding is utf-8 since GLib 2.6 * @param ctx If something goes wrong during parsing ctx will include according messages * @param try_harder If set an additional attempt is done with guessed encoding * @return An XML document. * * \ingroup DiagramXmlIo */ xmlDocPtr diaXmlParseFile(const char *filename, DiaContext *ctx, gboolean try_harder) { xmlDocPtr doc; xmlErrorPtr err; doc = xmlParseFile(filename); if (!doc) { err = xmlGetLastError (); dia_context_add_message (ctx, "%s", err->message); if (err->code == XML_ERR_INVALID_CHAR && try_harder) /* fallback to temporary file with encoding approach */ doc = xmlDiaParseFile (filename, ctx); } return doc; }
static Color fig_color(int color_index, DiaContext *ctx) { if (color_index <= -1) return color_black; /* Default color */ else if (color_index < FIG_MAX_DEFAULT_COLORS) return fig_default_colors[color_index]; else if (color_index < FIG_MAX_USER_COLORS) return fig_colors[color_index-FIG_MAX_DEFAULT_COLORS]; else { dia_context_add_message(ctx, _("Color index %d too high; only 512 colors allowed. Using black instead."), color_index); return color_black; } }
/*! * \brief Return the value of an integer-type data node. * @param data The data node to read from. * @param ctx The context in which this function is called * @return The integer value found in the node. If the node is not an * integer node, an error message is displayed and 0 is returned. * \ingroup DiagramXmlIn */ int data_int(DataNode data, DiaContext *ctx) { xmlChar *val; int res; if (data_type(data, ctx)!=DATATYPE_INT) { dia_context_add_message (ctx, _("Taking int value of non-int node.")); return 0; } val = xmlGetProp(data, (const xmlChar *)"val"); res = atoi((char *) val); if (val) xmlFree(val); return res; }
/*! * \brief Return the value of a real-type data node. * @param data The data node to read from. * @param ctx The context in which this function is called * @return The real value found in the node. If the node is not a * real-type node, an error message is displayed and 0.0 is returned. * \ingroup DiagramXmlIn */ real data_real(DataNode data, DiaContext *ctx) { xmlChar *val; real res; if (data_type(data, ctx)!=DATATYPE_REAL) { dia_context_add_message (ctx, "Taking real value of non-real node."); return 0; } val = xmlGetProp(data, (const xmlChar *)"val"); res = g_ascii_strtod((char *) val, NULL); if (val) xmlFree(val); return res; }
/*! * \brief Return the value of an enum-type data node. * @param data The data node to read from. * @param ctx The context in which this function is called * @return The enum value found in the node. If the node is not an * enum node, an error message is displayed and 0 is returned. * \ingroup DiagramXmlIn */ int data_enum(DataNode data, DiaContext *ctx) { xmlChar *val; int res; if (data_type(data, ctx)!=DATATYPE_ENUM) { dia_context_add_message (ctx, "Taking enum value of non-enum node."); return 0; } val = xmlGetProp(data, (const xmlChar *)"val"); res = atoi((char *) val); if (val) xmlFree(val); return res; }
/* imports the given DRS file, returns TRUE if successful */ gboolean import_drs (const gchar *filename, DiagramData *dia, DiaContext *ctx, void* user_data) { GList *item, *items; xmlDocPtr doc = xmlParseFile(filename); xmlNodePtr root = NULL, node; Layer *active_layer = NULL; for (node = doc->children; node; node = node->next) if (xmlStrcmp (node->name, (const xmlChar *)"drs") == 0) root = node; if (!root || !(root = find_child_named (root, "diagram"))) { dia_context_add_message (ctx, _("Broken file?")); return FALSE; } for (node = root->children; node != NULL; node = node->next) { if (xmlStrcmp (node->name, (const xmlChar *)"layer") == 0) { xmlChar *str; xmlChar *name = xmlGetProp (node, (const xmlChar *)"name"); Layer *layer = new_layer (g_strdup (name ? (gchar *)name : _("Layer")), dia); if (name) xmlFree (name); str = xmlGetProp (node, (const xmlChar *)"active"); if (xmlStrcmp (str, (const xmlChar *)"true")) { active_layer = layer; xmlFree (str); } items = read_items (node->children, ctx); for (item = items; item != NULL; item = g_list_next (item)) { DiaObject *obj = (DiaObject *)item->data; layer_add_object(layer, obj); } g_list_free (items); data_add_layer (dia, layer); } } if (active_layer) data_set_active_layer (dia, active_layer); xmlFreeDoc(doc); return TRUE; }
static int fig_read_paper_size(FILE *file, DiagramData *dia, DiaContext *ctx) { char buf[BUFLEN]; int paper; if (!fgets(buf, BUFLEN, file)) { dia_context_add_message_with_errno(ctx, errno, _("Error reading paper size.")); return FALSE; } buf[strlen(buf)-1] = 0; /* Remove trailing newline */ g_strstrip(buf); /* And any other whitespace */ if ((paper = find_paper(buf)) != -1) { get_paper_info(&dia->paper, paper, NULL); return TRUE; } dia_context_add_message(ctx, _("Unknown paper size `%s', using default\n"), buf); return TRUE; }
gboolean import_pdf(const gchar *filename, DiagramData *dia, DiaContext *ctx, void* user_data) { PDFDoc *doc; GooString *fileName = new GooString(filename); // no passwords yet GooString *ownerPW = NULL; GooString *userPW = NULL; gboolean ret = FALSE; // without this we will get strange crashes (at least with /O2 build) globalParams = new GlobalParams(); doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW); if (!doc->isOk()) { dia_context_add_message (ctx, _("PDF document not OK.\n%s"), dia_context_get_filename (ctx)); } else { DiaOutputDev *diaOut = new DiaOutputDev(dia, doc->getNumPages()); for (int pg = 1; pg <= doc->getNumPages(); ++pg) { Page *page = doc->getPage (pg); if (!page || !page->isOk()) continue; doc->displayPage(diaOut, pg, 72.0, 72.0, /* DPI, scaling elsewhere */ 0, /* rotate */ gTrue, /* useMediaBox */ gTrue, /* Crop */ gFalse /* printing */ ); } delete diaOut; ret = TRUE; } delete doc; delete globalParams; delete fileName; return ret; }
/*! * \brief Return the value of a boolean-type data node. * @param data The data node to read from. * @param ctx The context in which this function is called * @return The boolean value found in the node. If the node is not a * boolean node, an error message is displayed and FALSE is returned. * \ingroup DiagramXmlIn */ int data_boolean(DataNode data, DiaContext *ctx) { xmlChar *val; int res; if (data_type(data, ctx)!=DATATYPE_BOOLEAN) { dia_context_add_message (ctx, "Taking boolean value of non-boolean node."); return 0; } val = xmlGetProp(data, (const xmlChar *)"val"); if ((val) && (strcmp((char *) val, "true")==0)) res = TRUE; else res = FALSE; if (val) xmlFree(val); return res; }
/*! * \brief Return the value of a point-type data node. * @param data The XML node to read from * @param point A place to store the resulting x, y values. If the node does * not contain a valid point value, an error message is registered in ctx * and `point' is unchanged. * @param ctx The context in which this function is called * \ingroup DiagramXmlIn */ void data_point(DataNode data, Point *point, DiaContext *ctx) { xmlChar *val; gchar *str; real ax,ay; if (data_type(data, ctx)!=DATATYPE_POINT) { dia_context_add_message (ctx, _("Taking point value of non-point node.")); return; } val = xmlGetProp(data, (const xmlChar *)"val"); point->x = g_ascii_strtod((char *)val, &str); ax = fabs(point->x); if ((ax > 1e9) || ((ax < 1e-9) && (ax != 0.0)) || isnan(ax) || isinf(ax)) { /* there is no provision to keep values larger when saving, * so do this 'reduction' silent */ if (!(ax < 1e-9)) g_warning(_("Incorrect x Point value \"%s\" %f; discarding it."),val,point->x); point->x = 0.0; } while ((*str != ',') && (*str!=0)) str++; if (*str==0){ point->y = 0.0; g_warning(_("Error parsing point.")); xmlFree(val); return; } point->y = g_ascii_strtod(str+1, NULL); ay = fabs(point->y); if ((ay > 1e9) || ((ay < 1e-9) && (ay != 0.0)) || isnan(ay) || isinf(ay)) { if (!(ay < 1e-9)) /* don't bother with useless warnings (see above) */ g_warning(_("Incorrect y Point value \"%s\" %f; discarding it."),str+1,point->y); point->y = 0.0; } xmlFree(val); }
static void enumprop_load(EnumProperty *prop, AttributeNode attr, DataNode data, DiaContext *ctx) { DataType dt = data_type (data, ctx); if (DATATYPE_ENUM == dt) prop->enum_data = data_enum(data, ctx); else if (DATATYPE_INT == dt) { gboolean cast_ok = FALSE; PropEnumData *enumdata = prop->common.descr->extra_data; guint i, v = data_int(data,ctx); for (i = 0; enumdata[i].name != NULL; ++i) { if (v == enumdata[i].enumv) { prop->enum_data = v; cast_ok = TRUE; break; } } if (!cast_ok) { prop->enum_data = enumdata[0].enumv; dia_context_add_message (ctx, _("Property cast from int to enum out of range")); } } }
/*! * \brief Get the type of a data node. * @param data The data node. * @param ctx The context in which this function is called * @return The type that the data node defines, or 0 on error. * @note This function does a number of strcmp calls, which may not be the * fastest way to check if a node is of the expected type. * \ingroup DiagramXmlIn */ DataType data_type(DataNode data, DiaContext *ctx) { const char *name; name = data ? (const char *)data->name : (const char *)""; if (strcmp(name, "composite")==0) { return DATATYPE_COMPOSITE; } else if (strcmp(name, "int")==0) { return DATATYPE_INT; } else if (strcmp(name, "enum")==0) { return DATATYPE_ENUM; } else if (strcmp(name, "real")==0) { return DATATYPE_REAL; } else if (strcmp(name, "boolean")==0) { return DATATYPE_BOOLEAN; } else if (strcmp(name, "color")==0) { return DATATYPE_COLOR; } else if (strcmp(name, "point")==0) { return DATATYPE_POINT; } else if (strcmp(name, "rectangle")==0) { return DATATYPE_RECTANGLE; } else if (strcmp(name, "string")==0) { return DATATYPE_STRING; } else if (strcmp(name, "font")==0) { return DATATYPE_FONT; } else if (strcmp(name, "bezpoint")==0) { return DATATYPE_BEZPOINT; } else if (strcmp(name, "dict")==0) { return DATATYPE_DICT; } else if (strcmp(name, "pixbuf")==0) { return DATATYPE_PIXBUF; } dia_context_add_message (ctx, _("Unknown type of DataNode '%s'"), name); return 0; }
static gboolean export_data(DiagramData *data, DiaContext *ctx, const gchar *filename, const gchar *diafilename, void* user_data) { DiaCairoRenderer *renderer; GdkColor color; int width, height; GdkPixbuf* pixbuf = NULL; GError* error = NULL; Rectangle rect; real zoom = 1.0; cairo_t *cctx; const char* format = (const char*)user_data; rect.left = data->extents.left; rect.top = data->extents.top; rect.right = data->extents.right; rect.bottom = data->extents.bottom; /* quite arbitrary */ zoom = 20.0 * data->paper.scaling; /* Adding a bit of padding to account for rounding errors. Better to * pad than to clip. See bug #413275 */ width = ceil((rect.right - rect.left) * zoom) + 1; height = ceil((rect.bottom - rect.top) * zoom) + 1; renderer = g_object_new (dia_cairo_renderer_get_type(), NULL); renderer->scale = zoom; renderer->surface = cairo_surface_reference (cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height)); cctx = cairo_create (renderer->surface); /* draw background */ color_convert (&data->bg_color, &color); gdk_cairo_set_source_color (cctx, &color); cairo_rectangle (cctx, 0, 0, width, height); cairo_fill (cctx); data_render (data, DIA_RENDERER (renderer), NULL, NULL, NULL); #if GTK_CHECK_VERSION(3,0,0) pixbuf = gdk_pixbuf_get_from_surface (renderer->surface, 0, 0, width, height); #else { GdkPixmap *pixmap; cairo_t *cr; pixmap = gdk_pixmap_new (NULL, width, height, 24); cr = gdk_cairo_create (pixmap); cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); cairo_set_source_surface (cr, renderer->surface, 0, 0); cairo_paint (cr); pixbuf = gdk_pixbuf_get_from_drawable (NULL, pixmap, gdk_colormap_get_system (), 0, 0, 0, 0, width, height); } #endif if (pixbuf) { gdk_pixbuf_save (pixbuf, filename, format, &error, NULL); g_object_unref (pixbuf); } else { dia_context_add_message(ctx, _("Failed to create pixbuf from drawable.")); } if (error) { dia_context_add_message(ctx, _("Could not save file:\n%s\n%s"), dia_context_get_filename(ctx), error->message); g_error_free (error); } g_object_unref (renderer); return TRUE; }
static void set_font(DiaRenderer *self, DiaFont *font, real height) { WmfRenderer *renderer = WMF_RENDERER (self); W32::LPCTSTR sFace; W32::DWORD dwItalic = 0; W32::DWORD dwWeight = FW_DONTCARE; DiaFontStyle style = dia_font_get_style(font); real font_size = dia_font_get_size (font) * (height / dia_font_get_height (font)); DIAG_NOTE(renderer, "set_font %s %f\n", dia_font_get_family (font), height); if (renderer->hFont) { W32::DeleteObject(renderer->hFont); renderer->hFont = NULL; } if (renderer->pango_context) { g_object_unref (renderer->pango_context); renderer->pango_context = NULL; } if (renderer->use_pango) { #ifdef __PANGOWIN32_H__ /* with the pangowin32 backend there is a better way */ if (!renderer->pango_context) renderer->pango_context = pango_win32_get_context (); PangoFont* pf = pango_context_load_font (renderer->pango_context, dia_font_get_description (font)); if (pf) { W32::LOGFONT* lf = pango_win32_font_logfont (pf); /* .93 : sligthly smaller looks much better */ lf->lfHeight = -SC(height*.93); lf->lfHeight = -SC(font_size); renderer->hFont = (W32::HFONT)W32::CreateFontIndirect (lf); g_free (lf); g_object_unref (pf); } else { gchar *desc = pango_font_description_to_string (dia_font_get_description (font)); dia_context_add_message(renderer->ctx, _("Cannot render unknown font:\n%s"), desc); g_free (desc); } #else g_assert_not_reached(); #endif } else { sFace = dia_font_get_family (font); dwItalic = DIA_FONT_STYLE_GET_SLANT(style) != DIA_FONT_NORMAL; /* although there is a known algorithm avoid it for cleanness */ switch (DIA_FONT_STYLE_GET_WEIGHT(style)) { case DIA_FONT_ULTRALIGHT : dwWeight = FW_ULTRALIGHT; break; case DIA_FONT_LIGHT : dwWeight = FW_LIGHT; break; case DIA_FONT_MEDIUM : dwWeight = FW_MEDIUM; break; case DIA_FONT_DEMIBOLD : dwWeight = FW_DEMIBOLD; break; case DIA_FONT_BOLD : dwWeight = FW_BOLD; break; case DIA_FONT_ULTRABOLD : dwWeight = FW_ULTRABOLD; break; case DIA_FONT_HEAVY : dwWeight = FW_HEAVY; break; default : dwWeight = FW_NORMAL; break; } //Hack to get BYTE out of namespace W32 # ifndef BYTE # define BYTE unsigned char # endif renderer->hFont = (W32::HFONT)W32::CreateFont( - SC (font_size), // logical height of font 0, // logical average character width 0, // angle of escapement 0, // base-line orientation angle dwWeight, // font weight dwItalic, // italic attribute flag 0, // underline attribute flag 0, // strikeout attribute flag DEFAULT_CHARSET, // character set identifier OUT_TT_PRECIS, // output precision CLIP_DEFAULT_PRECIS, // clipping precision PROOF_QUALITY, // output quality DEFAULT_PITCH, // pitch and family sFace); // pointer to typeface name string } }