/* SciGraphica - Scientific graphics and data manipulation * Copyright (C) 2001 Adrian E. Feiguin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include "sg_plot_file_xml.h" #include "sg.h" #ifdef WITH_WARNINGS #warining TODO: dataset function #endif static void save_plot (SGplotfile *file); static void save_layer (SGplotfile *file, SGlayer *layer); static void save_dataset (SGplotfile *file, SGdataset *dataset, gboolean save_points); static void save_axis (SGplotfile *file, GtkPlotAxis *axis); static void set_line_style (SGplotfile *file, GtkPlotLine line); static void put_text (SGplotfile *file, GtkPlotText *text); static void put_child (SGplotfile *file, GtkPlotCanvasChild *child); static void put_pixmap (SGplotfile *file, GdkPixmap *pixmap); static void color_to_hex (gint pixel, gchar string[5]); SGplotfile * sg_plot_file_new_xml(SGplot *plot, gchar *filename, FILE* opened) { SGplotfile *file; file = sg_plot_file_new(plot, filename); if(!opened){ file->file = sg_fopen(filename, "w"); if (!file->file){ g_warning("ERROR: Cannot write to file: %s", filename); sg_plot_file_destroy(file); return FALSE; } fprintf(file->file,"\n"); } else { file->file = opened; } file->save_plot = save_plot; file->save_layer = save_layer; file->save_dataset = save_dataset; file->save_axis = save_axis; file->set_line_style = set_line_style; file->put_text = put_text; file->put_child = put_child; return file; } gboolean sg_plot_file_export_xml(SGplot *plot, gchar *filename, FILE* opened, gboolean in_project) { SGplotfile *file; file = sg_plot_file_new(plot, filename); if(!opened){ file->file = sg_fopen(filename, "w"); if (!file->file){ g_warning("ERROR: Cannot write to file: %s", filename); sg_plot_file_destroy(file); return FALSE; } fprintf(file->file,"\n"); } else { file->file = opened; } file->save_plot = save_plot; file->save_layer = save_layer; file->save_dataset = save_dataset; file->save_axis = save_axis; file->set_line_style = set_line_style; file->put_text = put_text; file->put_child = put_child; sg_plot_file_export(file, in_project); if(!opened){ sg_fclose(file->file); } sg_plot_file_destroy(file); return TRUE; } gboolean sg_plot_file_export_data_xml (SGdataset *dataset, gchar *filename, FILE* opened, gboolean save_points) { SGplotfile *file; file = sg_plot_file_new(NULL, filename); if(!opened){ file->file = sg_fopen(filename, "w"); if (!file->file){ g_warning("ERROR: Cannot write to file: %s", filename); g_free(file); return FALSE; } fprintf(file->file,"\n"); } else { file->file = opened; } file->save_plot = save_plot; file->save_layer = save_layer; file->save_dataset = save_dataset; file->save_axis = save_axis; file->set_line_style = set_line_style; file->put_text = put_text; file->put_child = put_child; file->save_dataset(file, dataset, save_points); if(!opened){ sg_fclose(file->file); } sg_plot_file_destroy(file); return TRUE; } static void save_plot(SGplotfile *file) { SGplot *plot = file->plot; GtkPlotCanvas *canvas; GList *list; canvas = GTK_PLOT_CANVAS(plot->real_canvas); fprintf(file->file,"\n"); fprintf(file->file, " \n"); fprintf(file->file, " \n"); fprintf(file->file, " application\n"); fprintf(file->file, " scigraphica\n"); fprintf(file->file, " \n"); fprintf(file->file, " \n"); fprintf(file->file, " author\n"); fprintf(file->file, " %s\n", g_get_real_name()); fprintf(file->file, " \n"); fprintf(file->file, " \n"); fprintf(file->file, " \n", plot->width, plot->height); fprintf(file->file, " %s\n", plot->name); fprintf(file->file, " \n", plot->orientation, plot->page_size, plot->page_width, plot->page_height, plot->scale); fprintf(file->file, " \n", canvas->background.red, canvas->background.green, canvas->background.blue); fprintf(file->file, " \n"); list = canvas->childs; while(list) { GtkPlotCanvasChild *child; child = (GtkPlotCanvasChild *)list->data; file->put_child(file, child); list = list->next; } list = plot->layers; while(list) { file->save_layer(file, (SGlayer *)list->data); list = list->next; } fprintf(file->file,"\n"); } static void save_layer(SGplotfile *file, SGlayer *layer) { GtkPlot *plot = GTK_PLOT(layer->real_plot); GList *list; /********************************************************************* * LAYER PLOT *********************************************************************/ fprintf(file->file, " \n", layer->type); fprintf(file->file, " \n", plot->x, plot->y, plot->width, plot->height, plot->magnification, plot->xscale, plot->yscale); fprintf(file->file, " \n", layer->symbol, layer->symbol_style, layer->line_style, layer->connector); if(GTK_IS_PLOT3D(plot)) fprintf(file->file, " \n", plot->xmin, plot->xmax, plot->ymin, plot->ymax, GTK_PLOT3D(plot)->zmin, GTK_PLOT3D(plot)->zmax); else if(GTK_IS_PLOT_POLAR(plot)) fprintf(file->file, " \n", plot->xmin, plot->xmax, plot->ymin, plot->ymax, GTK_PLOT_POLAR(plot)->rotation); else fprintf(file->file, " \n", plot->xmin, plot->xmax, plot->ymin, plot->ymax); fprintf(file->file, " \n", plot->background.red, plot->background.green, plot->background.blue, gtk_plot_is_transparent(plot)); if(plot->bg_pixmap){ fprintf(file->file, " \n"); put_pixmap(file, plot->bg_pixmap); fprintf(file->file, " \n"); } fprintf(file->file, " \n", plot->show_x0); file->set_line_style(file, plot->x0_line); fprintf(file->file, " \n"); fprintf(file->file, " \n", plot->show_y0); file->set_line_style(file, plot->y0_line); fprintf(file->file, " \n"); /********************************************************************* * AXES *********************************************************************/ fprintf(file->file, " \n", plot->bottom_align, plot->bottom->is_visible, plot->bottom->orientation, plot->bottom->scale); file->save_axis(file, plot->bottom); if(plot->bottom->custom_labels){ fprintf(file->file, " \n", layer->bottom_labels_worksheet->name, layer->bottom_values_column, layer->bottom_labels_column); } fprintf(file->file, " \n"); fprintf(file->file, " \n", plot->top_align, plot->top->is_visible, plot->top->orientation, plot->top->scale); file->save_axis(file, plot->top); if(plot->top->custom_labels){ fprintf(file->file, " \n", layer->top_labels_worksheet->name, layer->top_values_column, layer->top_labels_column); } fprintf(file->file, " \n"); fprintf(file->file, " \n", plot->left_align, plot->left->is_visible, plot->left->orientation, plot->left->scale); file->save_axis(file, plot->left); if(plot->left->custom_labels){ fprintf(file->file, " \n", layer->left_labels_worksheet->name, layer->left_values_column, layer->left_labels_column); } fprintf(file->file, " \n"); fprintf(file->file, " \n", plot->right_align, plot->right->is_visible, plot->right->orientation, plot->right->scale); file->save_axis(file, plot->right); if(plot->right->custom_labels){ fprintf(file->file, " \n", layer->right_labels_worksheet->name, layer->right_values_column, layer->right_labels_column); } fprintf(file->file, " \n"); /********************************************************************* * PLANES *********************************************************************/ if(GTK_IS_PLOT3D(plot)){ GtkPlot3D *plot3d = GTK_PLOT3D(plot); fprintf(file->file, " \n", plot3d->titles_offset, plot3d->xfactor, plot3d->yfactor, plot3d->zfactor); file->set_line_style(file, plot3d->frame); fprintf(file->file, " \n"); fprintf(file->file, " \n", plot3d->corner_visible); file->set_line_style(file, plot3d->corner); fprintf(file->file, " \n"); fprintf(file->file, " \n", GTK_PLOT_PLANE_XY, plot3d->xy_visible, plot3d->color_xy.red, plot3d->color_xy.green, plot3d->color_xy.blue); fprintf(file->file, " \n", GTK_PLOT_PLANE_YZ, plot3d->yz_visible, plot3d->color_yz.red, plot3d->color_yz.green, plot3d->color_yz.blue); fprintf(file->file, " \n", GTK_PLOT_PLANE_ZX, plot3d->zx_visible, plot3d->color_zx.red, plot3d->color_zx.green, plot3d->color_zx.blue); fprintf(file->file, " \n", GTK_PLOT_SIDE_XY, plot3d->xy.major_mask, plot3d->xy.minor_mask, plot3d->xy.label_mask, plot3d->xy.title_visible); fprintf(file->file, " \n", GTK_PLOT_SIDE_XZ, plot3d->xz.major_mask, plot3d->xz.minor_mask, plot3d->xz.label_mask, plot3d->xz.title_visible); fprintf(file->file, " \n", GTK_PLOT_SIDE_YX, plot3d->yx.major_mask, plot3d->yx.minor_mask, plot3d->yx.label_mask, plot3d->yx.title_visible); fprintf(file->file, " \n", GTK_PLOT_SIDE_YZ, plot3d->yz.major_mask, plot3d->yz.minor_mask, plot3d->yz.label_mask, plot3d->yz.title_visible); fprintf(file->file, " \n", GTK_PLOT_SIDE_ZX, plot3d->zx.major_mask, plot3d->zx.minor_mask, plot3d->zx.label_mask, plot3d->zx.title_visible); fprintf(file->file, " \n", GTK_PLOT_SIDE_ZY, plot3d->zy.major_mask, plot3d->zy.minor_mask, plot3d->zy.label_mask, plot3d->zy.title_visible); } /********************************************************************* * LEGENDS *********************************************************************/ fprintf(file->file, " \n", plot->legends_x, plot->legends_y, plot->legends_width, plot->legends_height, plot->show_legends); fprintf(file->file, " \n", plot->legends_border, plot->legends_border_width, plot->legends_shadow_width); file->put_text(file, &plot->legends_attr); fprintf(file->file, " \n"); /********************************************************************* * DATASETS *********************************************************************/ list = layer->datasets; while(list) { file->save_dataset(file, (SGdataset *)list->data, !file->in_project); list = list->next; } fprintf(file->file, " \n"); } static void save_dataset(SGplotfile *file, SGdataset *dataset, gboolean save_points) { GtkPlotData *data = dataset->real_data; gint n = 0; gdouble x = 0.; gdouble y = 0.; gdouble z = 0.; gdouble a = 0.; gdouble dx = 0.; gdouble dy = 0.; gdouble dz = 0.; gdouble da = 0.; /********************************************************************* * DATASET *********************************************************************/ if(data->is_function) fprintf(file->file, " \n", dataset->id, dataset->style, GTK_WIDGET_VISIBLE(GTK_WIDGET(data)), data->show_labels, data->line_connector, data->fill_area, data->show_gradient, xml_get_string(data->name), xml_get_string(dataset->exp)); else{ SGdataset *real_data; real_data = SG_DATASET(gtk_plot_data_get_link(data)); fprintf(file->file, " \n", dataset->id, dataset->style, GTK_WIDGET_VISIBLE(GTK_WIDGET(data)), data->show_labels, data->line_connector, data->fill_area, data->show_gradient, xml_get_string(real_data->real_data->name)); } if(GTK_IS_PLOT_SURFACE(data)){ GtkPlotSurface *s = GTK_PLOT_SURFACE(data); fprintf(file->file, " \n", s->color.red, s->color.green, s->color.blue, s->shadow.red, s->shadow.green, s->shadow.blue, s->height_gradient, s->transparent); fprintf(file->file, " \n", s->show_grid, s->grid_foreground.red, s->grid_foreground.green, s->grid_foreground.blue, s->grid_background.red, s->grid_background.green, s->grid_background.blue); fprintf(file->file, " \n", GTK_PLOT_SURFACE(data)->show_mesh); } if(GTK_IS_PLOT_CSURFACE(data)) fprintf(file->file, " \n", GTK_PLOT_CSURFACE(data)->lines_visible, GTK_PLOT_CSURFACE(data)->project_xy); if(data->legend){ gchar *xml_text = NULL; xml_text = xml_get_string(data->legend); fprintf(file->file, " %s\n", data->show_legend, data->legends_precision, xml_text); g_free(xml_text); }else{ fprintf(file->file, " \n", data->show_legend, data->legends_precision); } if(dataset->worksheet) fprintf(file->file, " \n", dataset->worksheet->name, dataset->x, dataset->y, dataset->z, dataset->a, dataset->dx, dataset->dy, dataset->dz, dataset->da, dataset->l); else if (dataset->type == SG_DATA_PYTHON) fprintf(file->file, " \n", xml_get_string(dataset->real_data->name), xml_get_string(dataset->p_exp[0]), xml_get_string(dataset->p_exp[1]), xml_get_string(dataset->p_exp[2]), xml_get_string(dataset->p_exp[3]), xml_get_string(dataset->p_exp[4]), xml_get_string(dataset->p_exp[5]), xml_get_string(dataset->p_exp[6]), xml_get_string(dataset->p_exp[7]), xml_get_string(dataset->p_exp[8])); /********************************************************************* * SYMBOL STYLE *********************************************************************/ if(dataset->style == SG_STYLE_FLUX) fprintf(file->file, " \n", data->symbol.symbol_type, data->symbol.symbol_style, data->symbol.size, data->symbol.border.line_width, GTK_PLOT_FLUX(data)->arrow_style, GTK_PLOT_FLUX(data)->arrow_length, GTK_PLOT_FLUX(data)->arrow_width, GTK_PLOT_FLUX(data)->centered, data->a_scale, data->symbol.color.red, data->symbol.color.green, data->symbol.color.blue, data->symbol.border.color.red, data->symbol.border.color.green, data->symbol.border.color.blue); else if(dataset->style == SG_STYLE_HBARS || dataset->style == SG_STYLE_VBARS) fprintf(file->file, " \n", data->symbol.symbol_type, data->symbol.symbol_style, data->symbol.size, data->symbol.border.line_width, GTK_PLOT_BAR(data)->width, data->symbol.color.red, data->symbol.color.green, data->symbol.color.blue, data->symbol.border.color.red, data->symbol.border.color.green, data->symbol.border.color.blue); else fprintf(file->file, " \n", data->symbol.symbol_type, data->symbol.symbol_style, data->symbol.size, data->symbol.border.line_width, data->a_scale, data->symbol.color.red, data->symbol.color.green, data->symbol.color.blue,data->symbol.border.color.red, data->symbol.border.color.green, data->symbol.border.color.blue); file->set_line_style(file, data->line); fprintf(file->file, " \n"); file->set_line_style(file, data->x_line); fprintf(file->file, " \n"); fprintf(file->file, " \n"); file->set_line_style(file, data->y_line); fprintf(file->file, " \n"); fprintf(file->file, " \n"); file->set_line_style(file, data->y_line); fprintf(file->file, " \n"); /********************************************************************* * GRADIENT *********************************************************************/ fprintf(file->file, " \n", data->gradient_mask, data->gradient.begin, data->gradient.end, data->gradient.nmajorticks, data->gradient.nminorticks, data->color_min.red, data->color_min.green, data->color_min.blue, data->color_max.red, data->color_max.green, data->color_max.blue); /********************************************************************* * POINTS *********************************************************************/ if(GTK_IS_PLOT_SURFACE(data)) fprintf(file->file, " \n", data->num_points, GTK_PLOT_SURFACE(data)->nx, GTK_PLOT_SURFACE(data)->ny); else fprintf(file->file, " \n", data->num_points); if(save_points){ if(data->x && data->y){ for(n = 0; n < dataset->real_data->num_points; n++){ if(data->z) z = data->z[n]; if(data->a) a = data->a[n]; if(data->dx) dx = data->dx[n]; if(data->dy) dy = data->dy[n]; if(data->dz) dz = data->dz[n]; if(data->da) da = data->da[n]; fprintf(file->file, " \n", data->x[n], data->y[n], z, a, dx, dy, dz, da); } }else if(data->iterator){ for(n = 0; n < dataset->real_data->num_points; n++){ gchar *label; gboolean error; data->iterator(data->plot, data, n, &x, &y, &z, &a, &dx, &dy, &dz, &da, &label, &error); if(!error){ fprintf(file->file, " \n", x, y, z, a, dx, dy, dz, da); } } } } fprintf(file->file, " \n"); /********************************************************************* * X ERRBARS *********************************************************************/ fprintf(file->file, " \n", data->show_xerrbars, data->xerrbar_width, data->xerrbar_caps); /********************************************************************* * Y ERRBARS *********************************************************************/ fprintf(file->file, " \n", data->show_yerrbars, data->yerrbar_width, data->yerrbar_caps); /********************************************************************* * Z ERRBARS *********************************************************************/ fprintf(file->file, " \n", data->show_zerrbars, data->zerrbar_width, data->zerrbar_caps); /********************************************************************* /********************************************************************* * LABELS *********************************************************************/ fprintf(file->file, " \n", data->show_labels, data->labels_offset); file->put_text(file, &data->labels_attr); if(data->labels){ for(n = 0; n < dataset->real_data->num_points; n++){ if(data->labels[n]) fprintf(file->file, " \n", n, data->labels[n]); } }else if(data->iterator){ for(n = 0; n < dataset->real_data->num_points; n++){ gchar *label = NULL; gboolean error; data->iterator(data->plot, data, n, &x, &y, &z, &a, &dx, &dy, &dz, &da, &label, &error); if(!error && label && strlen(label) > 0) fprintf(file->file, " \n", n, label); } } fprintf(file->file, " \n"); /*********************************************************************/ fprintf(file->file, " \n"); } static void save_axis(SGplotfile *file, GtkPlotAxis *axis) { gint n = 0; gchar prefix[100] = ""; gchar suffix[100] = ""; if(axis->labels_prefix) g_snprintf(prefix, 100, "%s", axis->labels_prefix); if(axis->labels_suffix) g_snprintf(suffix, 100, "%s", axis->labels_suffix); /********************************************************************* * AXIS *********************************************************************/ fprintf(file->file, " \n", axis->major_mask,axis->minor_mask, axis->ticks_length, axis->ticks_width, axis->ticks.step, axis->ticks.nminor, axis->ticks.set_limits, axis->ticks.begin, axis->ticks.end); file->set_line_style(file, axis->line); fprintf(file->file, " \n", axis->title_visible); file->put_text(file, &axis->title); fprintf(file->file, " \n"); fprintf(file->file, " \n", axis->label_precision, axis->label_style, axis->label_mask, axis->labels_offset, prefix, suffix); file->put_text(file, &axis->labels_attr); fprintf(file->file, " \n"); fprintf(file->file, " \n"); fprintf(file->file, " \n", axis->show_major_grid); file->set_line_style(file, axis->major_grid); fprintf(file->file, " \n"); fprintf(file->file, " \n", axis->show_minor_grid); file->set_line_style(file, axis->minor_grid); fprintf(file->file, " \n"); } /********************************************************************* * LINE STYLE *********************************************************************/ static void set_line_style(SGplotfile *file, GtkPlotLine line) { fprintf(file->file, " \n", line.line_style, line.line_width, line.color.red, line.color.green, line.color.blue); } /********************************************************************* * TEXT *********************************************************************/ static void put_text(SGplotfile *file, GtkPlotText *text) { fprintf(file->file, " \n", text->x, text->y, text->angle, text->justification, text->transparent); fprintf(file->file, " \n", text->border, text->border_space, text->border_width, text->shadow_width); fprintf(file->file, " \n", text->fg.red, text->fg.green, text->fg.blue); fprintf(file->file, " \n", text->bg.red, text->bg.green, text->bg.blue); fprintf(file->file, " \n", text->font, text->height); if(text->text && strlen(text->text) > 0){ gchar *xml_text = NULL; xml_text = xml_get_string(text->text); fprintf(file->file, " %s\n", xml_text); g_free(xml_text); } fprintf(file->file, " \n"); } static void put_child(SGplotfile *file, GtkPlotCanvasChild *child) { GtkPlotCanvasLine *line = NULL; GtkPlotCanvasRectangle *rectangle = NULL; GtkPlotCanvasEllipse *ellipse = NULL; GdkPixmap *pixmap = NULL; fprintf(file->file, " \n", child->rx1, child->ry1, child->rx2, child->ry2, child->type, child->flags); switch(child->type){ case GTK_PLOT_CANVAS_TEXT: file->put_text(file, (GtkPlotText *)child->data); break; case GTK_PLOT_CANVAS_LINE: line = (GtkPlotCanvasLine *)child->data; fprintf(file->file, " \n", line->arrow_mask, line->arrow_style, line->arrow_length, line->arrow_width); file->set_line_style(file, line->line); fprintf(file->file, " \n"); break; case GTK_PLOT_CANVAS_RECTANGLE: rectangle = (GtkPlotCanvasRectangle *)child->data; fprintf(file->file, " \n", rectangle->filled, rectangle->border, rectangle->shadow_width, rectangle->bg.red, rectangle->bg.green, rectangle->bg.blue); file->set_line_style(file, rectangle->line); fprintf(file->file, " \n"); break; case GTK_PLOT_CANVAS_ELLIPSE: ellipse = (GtkPlotCanvasEllipse *)child->data; fprintf(file->file, " \n", ellipse->filled, ellipse->bg.red, ellipse->bg.green, ellipse->bg.blue); file->set_line_style(file, ellipse->line); fprintf(file->file, " \n"); break; case GTK_PLOT_CANVAS_PIXMAP: pixmap = (GdkPixmap *)child->data; put_pixmap(file, pixmap); break; } fprintf(file->file, " \n"); } static void put_pixmap(SGplotfile *file, GdkPixmap *pixmap) { GdkImage *image; GdkVisual *visual; GdkColormap *colormap; GdkColorContext *cc; gint width, height; gint x, y; gint i; gint ncolors = 0; GdkColor *colors; if(!pixmap) return; visual = gdk_visual_get_system(); colormap = gdk_colormap_get_system(); cc = gdk_color_context_new(visual, colormap); colors = g_new0(GdkColor, 1); gdk_window_get_size(pixmap, &width, &height); image = gdk_image_get(pixmap, 0, 0, width, height); for(y = 0; y < height; y++){ for(x = 0; x < width; x++){ GdkColor color; gchar string[5]; gboolean stored; color.pixel = gdk_image_get_pixel(image, x, y); stored = FALSE; for(i = 0; i < ncolors; i++) if(colors[i].pixel == color.pixel) stored = TRUE; if(!stored){ gdk_color_context_query_color(cc, &color); colors = (GdkColor *)g_realloc(colors, (ncolors+1)*sizeof(GdkColor)); colors[ncolors] = color; ncolors++; } } } fprintf(file->file, "\n", width, height, ncolors); for(i = 0; i < ncolors; i++){ gchar r[5], g[5], b[5]; color_to_hex(colors[i].red, r); color_to_hex(colors[i].green, g); color_to_hex(colors[i].blue, b); /* printf("%s %s %s %d %d %d\n",r,g,b,colors[i].red,colors[i].green,colors[i].blue); */ fprintf(file->file," %s%s%s\n", r, g, b); } fprintf(file->file, "\n"); for(y = 0; y < height; y++){ for(x = 0; x < width; x++){ GdkColor color, real_color; gchar string[5]; color.pixel = gdk_image_get_pixel(image, x, y); for(i = 0; i < ncolors; i++) if(colors[i].pixel == color.pixel) break; color_to_hex(i, string); fprintf(file->file,"%s",string); if(fmod(x+1, 13) == 0) fprintf(file->file,"\n"); } fprintf(file->file,"\n"); } fprintf(file->file, "\n"); fprintf(file->file, "\n"); gdk_image_destroy(image); gdk_color_context_free(cc); g_free(colors); } static void color_to_hex(gint pixel, gchar string[5]) { gint i, n; gint powers[4] = {1, 16, 256, 4096}; for(i=3; i>=0; i--){ n = pixel / powers[i]; pixel -= n * powers[i]; if(n < 10) string[3-i] = '0' + n; else string[3-i] = 'A' + n - 10; } string[4] = '\0'; }