gschem

x_image.c

Go to the documentation of this file.
00001 /* gEDA - GPL Electronic Design Automation
00002  * gschem - gEDA Schematic Capture
00003  * Copyright (C) 1998-2010 Ales Hvezda
00004  * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00019  */
00020 #include <config.h>
00021 
00022 #include <stdio.h>
00023 #include <unistd.h>
00024 #ifdef HAVE_STDLIB_H
00025 #include <stdlib.h>
00026 #endif
00027 #ifdef HAVE_STRING_H
00028 #include <string.h>
00029 #endif
00030 
00031 #include <glib.h>
00032 
00033 #include "gschem.h"
00034 
00035 #ifdef HAVE_LIBDMALLOC
00036 #include <dmalloc.h>
00037 #endif
00038 
00039 #define X_IMAGE_DEFAULT_SIZE "800x600"
00040 
00041 #define X_IMAGE_SIZE_MENU_NAME "image_size_menu"
00042 #define X_IMAGE_TYPE_MENU_NAME "image_type_menu"
00043 
00044 #define X_IMAGE_DEFAULT_TYPE "PNG"
00045 
00046 static char *x_image_sizes[] = {"320x240", "640x480", "800x600", "1200x768",
00047   "1280x960", "1600x1200", "3200x2400", NULL};
00048 
00049 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
00050 /* gtk_combo_box_get_active_text was included in GTK 2.6, so we need to store
00051    the different image type descriptions in a list. */
00052 GSList *image_type_descriptions = NULL;
00053 #endif
00054 
00055 
00056 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
00057 static void free_image_type_descriptions_list ()
00058 {
00059   GSList *ptr;
00060 
00061   /* Free the data stored in each node */
00062   ptr = image_type_descriptions;
00063   while (ptr) {
00064     g_free(ptr->data);
00065     ptr->data = NULL;
00066     ptr = g_slist_next(ptr);
00067   }
00068 
00069   /* Free the list */
00070   if (!ptr)
00071     g_slist_free(image_type_descriptions);
00072   image_type_descriptions = NULL;
00073 }
00074 
00075 #endif
00076 
00084 static void create_size_menu (GtkComboBox *combo)
00085 {
00086   char *buf;
00087   char *default_size;
00088   int i, default_index = 0;
00089 
00090   default_size = g_strdup (X_IMAGE_DEFAULT_SIZE);
00091   for (i=0; x_image_sizes[i] != NULL;i++) {
00092     /* Create a new string and add it as an option*/
00093     buf = g_strdup (x_image_sizes[i]);
00094     gtk_combo_box_append_text (GTK_COMBO_BOX (combo), buf);
00095 
00096     /* Compare with the default size, to get the default index */
00097     if (strcasecmp(buf, default_size ) == 0) {
00098       default_index = i;
00099     }
00100     g_free(buf);
00101   }
00102   g_free(default_size);
00103 
00104   /* Set the default menu */
00105   gtk_combo_box_set_active(GTK_COMBO_BOX (combo), default_index);
00106 
00107   return;
00108 }
00109 
00117 static void create_type_menu(GtkComboBox *combo)
00118 {
00119   GSList *formats = gdk_pixbuf_get_formats ();
00120   GSList *ptr;
00121   char *buf;
00122   int i=0, default_index=0;
00123 
00124 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
00125   /* If GTK < 2.6, free the descriptions list */
00126   free_image_type_descriptions_list();
00127 #endif
00128 
00129   ptr = formats;
00130   while (ptr) {
00131     if (gdk_pixbuf_format_is_writable (ptr->data)) {
00132       /* Get the format description and add it to the menu */
00133       buf = g_strdup (gdk_pixbuf_format_get_description(ptr->data));
00134       gtk_combo_box_append_text (GTK_COMBO_BOX (combo), buf);
00135 
00136       /* If GTK < 2.6, then add it also to the descriptions list. */
00137 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
00138       image_type_descriptions = g_slist_append(image_type_descriptions,
00139           buf);
00140 #endif
00141 
00142       /* Compare the name with "png" and store the index */
00143       buf = g_strdup (gdk_pixbuf_format_get_name(ptr->data));
00144       if (strcasecmp(buf, X_IMAGE_DEFAULT_TYPE) == 0) {
00145         default_index = i;
00146       }
00147       i++;  /* this is the count of items added to the combo box */
00148       /* not the total number of pixbuf formats */
00149       g_free(buf);
00150     }
00151     ptr = ptr->next;
00152   }
00153   g_slist_free (formats);
00154   gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Encapsulated Postscript");
00155 
00156   /* Set the default menu */
00157   gtk_combo_box_set_active(GTK_COMBO_BOX(combo), default_index);
00158   return;
00159 }
00160 
00169 static char *x_image_get_type_from_description(char *description) {
00170   gchar *descr = g_strdup (description);
00171   GSList *formats = gdk_pixbuf_get_formats ();
00172   GSList *ptr;
00173   gchar *ptr_descr;
00174 
00175   /*WK - catch EPS export case*/
00176   if (strcmp(descr, _("Encapsulated Postscript")) == 0) { 
00177     return(g_strdup("eps"));
00178   }
00179 
00180   ptr = formats;
00181   while (ptr) {
00182     ptr_descr = gdk_pixbuf_format_get_description (ptr->data);
00183     if (ptr_descr && (strcasecmp(ptr_descr, descr) == 0)) {
00184       g_free(descr);
00185       return(gdk_pixbuf_format_get_name(ptr->data));
00186     }
00187 
00188     ptr = ptr->next;
00189   }
00190   g_free (descr);
00191   return NULL;  
00192 }
00193 
00203 static void x_image_update_dialog_filename(GtkComboBox *combo, 
00204     GSCHEM_TOPLEVEL *w_current) {
00205   TOPLEVEL *toplevel = w_current->toplevel;
00206   char* image_type_descr = NULL;
00207   char *image_type = NULL;
00208   char *old_image_filename = NULL;
00209   char *file_basename = NULL;
00210   char *file_name = NULL ;
00211   char *new_image_filename = NULL;
00212   GtkWidget *file_chooser;
00213 
00214   /* Get the current image type */
00215 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
00216   GSList *ptr;
00217   /* If GTK < 2.6, get the description from the descriptions list */
00218   ptr = g_slist_nth(image_type_descriptions,
00219       gtk_combo_box_get_active(GTK_COMBO_BOX(combo)));
00220   if (ptr != NULL) {
00221     image_type_descr = (char *) (ptr->data);
00222   } else {
00223     image_type_descr = NULL;
00224   }
00225 #else
00226   image_type_descr = gtk_combo_box_get_active_text(GTK_COMBO_BOX(combo));
00227 #endif
00228   image_type = x_image_get_type_from_description(image_type_descr);
00229 
00230   /* Get the parent dialog */
00231   file_chooser = gtk_widget_get_ancestor(GTK_WIDGET(combo),
00232       GTK_TYPE_FILE_CHOOSER);
00233 
00234   /* Get the previous file name. If none, revert to the page filename */
00235   old_image_filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_chooser));
00236   if (!old_image_filename) {
00237     old_image_filename = toplevel->page_current->page_filename;
00238   }
00239 
00240   /* Get the file name, without extension */
00241   if (old_image_filename) {
00242     file_basename = g_path_get_basename(old_image_filename);
00243 
00244     if (g_strrstr(file_basename, ".") != NULL) {
00245       file_name = g_strndup(file_basename, 
00246           g_strrstr(file_basename, ".") - file_basename);
00247     }
00248   }
00249 
00250   /* Add the extension */
00251   if (file_name) {
00252     new_image_filename = g_strdup_printf("%s.%s", file_name, 
00253         image_type);
00254   } else {
00255     new_image_filename = g_strdup_printf("%s.%s", file_basename, 
00256         image_type);
00257   }
00258 
00259   /* Set the new filename */
00260   if (file_chooser) {
00261     gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(file_chooser),
00262         new_image_filename);
00263   } else {
00264     s_log_message("x_image_update_dialog_filename: No parent file chooser found!.\n");
00265   }
00266 
00267   g_free(file_name);
00268   g_free(file_basename);
00269   g_free(new_image_filename);
00270 }
00271 
00280 void x_image_write_eps(GSCHEM_TOPLEVEL *w_current, const char* filename)
00281 {
00282   TOPLEVEL *toplevel = w_current->toplevel;
00283   int result;
00284   int w, h, orientation, type;
00285   w = toplevel->paper_width;
00286   h = toplevel->paper_height;
00287   orientation = toplevel->print_orientation;
00288   type = toplevel->print_output_type;
00289 
00290   toplevel->paper_width = 0;
00291   toplevel->paper_height = 0;
00292   toplevel->print_orientation = PORTRAIT;
00293   toplevel->print_output_type = EXTENTS_NOMARGINS;
00294   result = f_print_file (toplevel, toplevel->page_current, filename);
00295   if (result) {
00296     s_log_message(_("x_image_lowlevel: Unable to write eps file %s.\n"),
00297         filename);
00298   }   
00299 
00300   toplevel->paper_width = w;
00301   toplevel->paper_height = h;
00302   toplevel->print_orientation = orientation;
00303   toplevel->print_output_type = type;
00304 }
00305 
00317 void x_image_lowlevel(GSCHEM_TOPLEVEL *w_current, const char* filename,
00318     int desired_width, int desired_height, char *filetype)
00319 {
00320   TOPLEVEL *toplevel = w_current->toplevel;
00321   int width, height;
00322   int save_height, save_width;
00323   int save_page_left, save_page_right, save_page_top, save_page_bottom;
00324   int page_width, page_height, page_center_left, page_center_top;
00325   GdkPixbuf *pixbuf;
00326   GError *gerror = NULL;
00327   GtkWidget *dialog;
00328   float prop;
00329 
00330   w_current->image_width = width = desired_width;
00331   w_current->image_height = height = desired_height;
00332 
00333   save_width = toplevel->width;
00334   save_height = toplevel->height;
00335 
00336   toplevel->width = width;
00337   toplevel->height = height;
00338 
00339   save_page_left = toplevel->page_current->left;
00340   save_page_right = toplevel->page_current->right;
00341   save_page_top = toplevel->page_current->top;
00342   save_page_bottom = toplevel->page_current->bottom;
00343 
00344   page_width = save_page_right - save_page_left;
00345   page_height = save_page_bottom - save_page_top;
00346 
00347   page_center_left = save_page_left + (page_width / 2);
00348   page_center_top = save_page_top + (page_height / 2);
00349 
00350   /* Preserve proportions */
00351   prop = (float)width / height;
00352   if (((float)page_width / page_height) > prop) {
00353     page_height = (page_width / prop);
00354   }else{
00355     page_width = (page_height * prop);
00356   }
00357 
00358   /* need to do this every time you change width / height */
00359   set_window(toplevel, toplevel->page_current,
00360       page_center_left - (page_width / 2),
00361       page_center_left + (page_width / 2),
00362       page_center_top - (page_height / 2),
00363       page_center_top + (page_height / 2));
00364 
00365   /* de select everything first */
00366   o_select_unselect_all( w_current );
00367 
00368   if (strcmp(filetype, "eps") == 0) /*WK - catch EPS export case*/
00369     x_image_write_eps(w_current, filename);
00370   else {
00371     pixbuf = x_image_get_pixbuf(w_current);
00372     if (pixbuf != NULL) {
00373       if (!gdk_pixbuf_save(pixbuf, filename, filetype, &gerror, NULL)) {
00374         s_log_message(_("x_image_lowlevel: Unable to write %s file %s.\n"),
00375             filetype, filename);
00376         s_log_message("%s", gerror->message);
00377 
00378         /* Warn the user */
00379         dialog = gtk_message_dialog_new (GTK_WINDOW(w_current->main_window),
00380             GTK_DIALOG_MODAL
00381             | GTK_DIALOG_DESTROY_WITH_PARENT,
00382             GTK_MESSAGE_ERROR,
00383             GTK_BUTTONS_OK,
00384             _("There was the following error when saving image with type %s to filename:\n%s\n\n%s.\n"),
00385             filetype, filename, gerror->message
00386             );
00387 
00388         gtk_dialog_run (GTK_DIALOG (dialog));
00389         gtk_widget_destroy (dialog);
00390 
00391         /* Free the gerror */
00392         g_error_free(gerror);
00393         gerror = NULL;
00394 
00395         /* Unlink the output file */
00396         /* It's not safe to unlink the file if there was an error.
00397            For example: if the operation was not allowed due to permissions,
00398            the _previous existing_ file will be removed */
00399         /* unlink(filename); */
00400       }
00401       else {
00402         if (toplevel->image_color == TRUE) {
00403           s_log_message(_("Wrote color image to [%s] [%d x %d]\n"), filename, width, height);
00404         } else {
00405           s_log_message(_("Wrote black and white image to [%s] [%d x %d]\n"), filename, width, height);
00406         }
00407       }
00408       g_free(filetype);
00409       if (pixbuf != NULL)
00410         g_object_unref(pixbuf);
00411     }
00412     else {
00413       s_log_message(_("x_image_lowlevel: Unable to get pixbuf from gschem's window.\n"));
00414     }
00415   }
00416 
00417   toplevel->width = save_width;
00418   toplevel->height = save_height;
00419 
00420   /* need to do this every time you change width / height */
00421   set_window(toplevel, toplevel->page_current,
00422       save_page_left,
00423       save_page_right,
00424       save_page_top,
00425       save_page_bottom);
00426 
00427   o_invalidate_all (w_current);
00428 
00429 }
00430 
00438 void x_image_setup (GSCHEM_TOPLEVEL *w_current)
00439 {
00440   GtkWidget *dialog;
00441   GtkWidget *vbox1;
00442   GtkWidget *hbox;
00443   GtkWidget *label1;
00444   GtkWidget *size_combo;
00445   GtkWidget *vbox2;
00446   GtkWidget *label2;
00447   GtkWidget *type_combo;
00448   char *image_type_descr;
00449   char *filename;
00450   char *image_size;
00451   char *image_type;
00452   int width, height;
00453 
00454   hbox = gtk_hbox_new(FALSE, 0);
00455 
00456   /* Image size selection */
00457   vbox1 = gtk_vbox_new(TRUE, 0);
00458   label1 = gtk_label_new (_("Width x Height"));
00459   gtk_widget_show (label1);
00460   gtk_misc_set_alignment( GTK_MISC (label1), 0, 0);
00461   gtk_misc_set_padding (GTK_MISC (label1), 0, 0);
00462   gtk_box_pack_start (GTK_BOX (vbox1),
00463       label1, FALSE, FALSE, 0);
00464 
00465   size_combo =  gtk_combo_box_new_text ();
00466   create_size_menu (GTK_COMBO_BOX(size_combo));
00467 
00468   gtk_widget_show (size_combo);
00469   gtk_box_pack_start (GTK_BOX (vbox1), size_combo, TRUE, TRUE, 0);
00470   gtk_widget_show(vbox1);
00471 
00472   /* Image type selection */
00473   vbox2 = gtk_vbox_new(TRUE, 0);
00474   label2 = gtk_label_new (_("Image type"));
00475   gtk_widget_show (label2);
00476   gtk_misc_set_alignment( GTK_MISC (label2), 0, 0);
00477   gtk_misc_set_padding (GTK_MISC (label2), 0, 0);
00478   gtk_box_pack_start (GTK_BOX (vbox2),
00479       label2, FALSE, FALSE, 0);
00480 
00481   type_combo = gtk_combo_box_new_text ();
00482   gtk_box_pack_start (GTK_BOX (vbox2), type_combo, TRUE, TRUE, 0);
00483   create_type_menu (GTK_COMBO_BOX(type_combo));
00484 
00485   /* Connect the changed signal to the callback, so the filename
00486      gets updated every time the image type is changed */
00487   g_signal_connect (type_combo, "changed", 
00488       G_CALLBACK(x_image_update_dialog_filename),
00489       w_current);
00490 
00491   gtk_widget_show (type_combo);
00492   gtk_widget_show(vbox2);
00493 
00494   /* Create the dialog */
00495   dialog = gtk_file_chooser_dialog_new (_("Write image..."),
00496       GTK_WINDOW(w_current->main_window),
00497       GTK_FILE_CHOOSER_ACTION_SAVE,
00498       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
00499       GTK_STOCK_SAVE,   GTK_RESPONSE_ACCEPT,
00500       NULL);
00501 
00502   /* Set the alternative button order (ok, cancel, help) for other systems */
00503   gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog),
00504       GTK_RESPONSE_ACCEPT,
00505       GTK_RESPONSE_CANCEL,
00506       -1);
00507 
00508   /* Add the extra widgets to the dialog*/
00509   gtk_box_pack_start(GTK_BOX(hbox), vbox1, FALSE, FALSE, 10);
00510   gtk_box_pack_start(GTK_BOX(hbox), vbox2, FALSE, FALSE, 10);
00511 
00512   gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER(dialog), hbox);
00513 
00514   g_object_set (dialog,
00515       /* GtkFileChooser */
00516       "select-multiple", FALSE,
00517 #if ((GTK_MAJOR_VERSION > 2) || ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION >=8)))
00518       /* only in GTK 2.8 */
00519       "do-overwrite-confirmation", TRUE,
00520 #endif
00521       NULL);
00522 
00523   /* Update the filename */
00524   x_image_update_dialog_filename(GTK_COMBO_BOX(type_combo), w_current);  
00525 
00526   gtk_dialog_set_default_response(GTK_DIALOG(dialog),
00527       GTK_RESPONSE_ACCEPT);
00528 
00529   gtk_window_position (GTK_WINDOW (dialog),
00530       GTK_WIN_POS_MOUSE);
00531 
00532   gtk_container_set_border_width(GTK_CONTAINER(dialog),
00533       DIALOG_BORDER_SPACING);
00534   gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox), 
00535       DIALOG_V_SPACING);
00536 
00537   gtk_widget_show (dialog);
00538 
00539   if (gtk_dialog_run((GTK_DIALOG(dialog))) == GTK_RESPONSE_ACCEPT) {    
00540 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
00541     image_size = 
00542       x_image_sizes[gtk_combo_box_get_active(GTK_COMBO_BOX(size_combo))];
00543 #else
00544     image_size = gtk_combo_box_get_active_text(GTK_COMBO_BOX(size_combo));
00545 #endif
00546 
00547 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
00548     GSList *ptr;
00549     /* If GTK < 2.6, get the description from the descriptions list */
00550     ptr = g_slist_nth(image_type_descriptions,
00551         gtk_combo_box_get_active(GTK_COMBO_BOX(type_combo)));
00552     image_type_descr = (char *) (ptr->data);
00553 #else
00554     image_type_descr = gtk_combo_box_get_active_text(GTK_COMBO_BOX(type_combo));
00555 #endif
00556 
00557     image_type = x_image_get_type_from_description(image_type_descr);
00558     sscanf(image_size, "%ix%i", &width, &height);
00559     filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
00560 
00561     x_image_lowlevel(w_current, filename, width, height, image_type);
00562   }
00563 
00564 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
00565   /* If GTK < 2.6, free the descriptions list */
00566   free_image_type_descriptions_list();
00567 #endif
00568 
00569   gtk_widget_destroy (dialog);
00570 }
00571 
00577 static void x_image_convert_to_greyscale(GdkPixbuf *pixbuf)
00578 {
00579   int width, height, rowstride, n_channels;
00580   guchar *pixels, *p, new_value;
00581   int i, j;
00582 
00583   n_channels = gdk_pixbuf_get_n_channels (pixbuf);
00584 
00585   if (n_channels != 3)
00586   {
00587     return;
00588   }
00589 
00590   if (gdk_pixbuf_get_colorspace (pixbuf) != GDK_COLORSPACE_RGB)
00591   {
00592     return;
00593   }
00594 
00595   if (gdk_pixbuf_get_bits_per_sample (pixbuf) != 8)
00596   {
00597     return;
00598   }
00599 
00600   width = gdk_pixbuf_get_width (pixbuf);
00601   height = gdk_pixbuf_get_height (pixbuf);
00602 
00603   rowstride = gdk_pixbuf_get_rowstride (pixbuf);
00604   pixels = gdk_pixbuf_get_pixels (pixbuf);
00605 
00606   for (j = 0; j < height; j++)
00607   {
00608     for (i = 0; i < width; i++)
00609     {
00610       p = pixels + j * rowstride + i * n_channels;
00611 
00612       new_value = 0.3 * p[0] + 0.59 * p[1] + 0.11 * p[2];
00613       p[0] = new_value;
00614       p[1] = new_value;
00615       p[2] = new_value;
00616     }
00617   }
00618 }
00619 
00625 GdkPixbuf *x_image_get_pixbuf (GSCHEM_TOPLEVEL *w_current)
00626 {
00627   GdkPixbuf *pixbuf;
00628   int origin_x, origin_y, bottom, right;
00629   int size_x, size_y, s_right, s_left, s_top,s_bottom;
00630   GSCHEM_TOPLEVEL new_w_current;
00631   TOPLEVEL toplevel;
00632   GdkRectangle rect;
00633 
00634   /* Do a copy of the w_current struct and work with it */
00635   memcpy(&new_w_current, w_current, sizeof(GSCHEM_TOPLEVEL));
00636   /* Do a copy of the toplevel struct and work with it */
00637   memcpy(&toplevel, w_current->toplevel, sizeof(TOPLEVEL));
00638 
00639   new_w_current.toplevel = &toplevel;
00640 
00641   WORLDtoSCREEN (&new_w_current, toplevel.page_current->right,
00642                                  toplevel.page_current->left, &s_right, &s_left);
00643   WORLDtoSCREEN (&new_w_current, toplevel.page_current->bottom,
00644                                  toplevel.page_current->top,  &s_bottom, &s_top);
00645 
00646   size_x = s_left - s_right;
00647   size_y = s_bottom - s_top;
00648 
00649   size_x = new_w_current.image_width;
00650   size_y = new_w_current.image_height;
00651 
00652   new_w_current.window = gdk_pixmap_new (w_current->window, size_x, size_y, -1);
00653   new_w_current.drawable = new_w_current.window;
00654   new_w_current.cr = gdk_cairo_create (new_w_current.window);
00655   new_w_current.pl = pango_cairo_create_layout (new_w_current.cr);
00656 
00657   new_w_current.grid = 0;
00658   new_w_current.text_origin_marker = FALSE;
00659 
00660   new_w_current.win_width = new_w_current.image_width;
00661   new_w_current.win_height = new_w_current.image_height;
00662 
00663   if (toplevel.image_color == FALSE)
00664   {
00665     /* FIXME this assumes -- not necessarily correctly! -- that the
00666      * color at index 0 in the color map is black, and the color at
00667      * index 1 is white! */
00668 
00669     /* We are going to be doing black&white (grayscale) output, so change the */
00670     /* color of all objects to a nice and dark color, say black */
00671     toplevel.override_color = 0;
00672 
00673     /* also reset the background to white */
00674     toplevel.background_color = 1;
00675   }
00676 
00677   origin_x = origin_y = 0;
00678   right = size_x;
00679   bottom = size_y;
00680 
00681   /* ------------------  Begin optional code ------------------------ */
00682   /* If the the code in this region is commented, the PNG returned will
00683      be the same as the one returned using libgd.
00684      I mean: there will be some border all around the schematic.
00685      This code is used to adjust the schematic to the border of the image */
00686 #if 0
00687 
00688   /* Do a zoom extents to get fit all the schematic in the window */
00689   /* Commented so the image returned will be the same as with libgd */  
00690   a_zoom_extents (&toplevel,
00691           toplevel.page_current->object_list,
00692           A_PAN_DONT_REDRAW);
00693 
00694   
00695   /* See if there are objects */
00696   
00697   aux = toplevel->page_current->object_list;
00698   while (aux != NULL) {
00699     if (aux->type != -1) {
00700       object_found = 1;
00701       break;
00702     }
00703     aux = aux->next;
00704   }
00705 
00706   
00707   /* If there are no objects, can't use zoom_extents */
00708   if (object_found) {
00709     get_object_glist_bounds (&toplevel,
00710                              toplevel.page_current->object_list,
00711                              &origin_x, &origin_y,
00712                              &right, &bottom);
00713   }
00714 #endif
00715   /* ------------------  End optional code ------------------------ */
00716   
00717   rect.x = origin_x;
00718   rect.y = origin_y;
00719   rect.width = right - origin_x;
00720   rect.height = bottom - origin_y;
00721 
00722   o_redraw_rects (&new_w_current, &rect, 1);
00723 
00724   /* Get the pixbuf */
00725   pixbuf = gdk_pixbuf_get_from_drawable (NULL,new_w_current.drawable, NULL,
00726                                         origin_x, origin_y, 0, 0,
00727                                         right-origin_x,
00728                                         bottom-origin_y);
00729 
00730   if (toplevel.image_color == FALSE)
00731   {
00732     x_image_convert_to_greyscale(pixbuf); 
00733   }
00734 
00735   if (new_w_current.cr != NULL) cairo_destroy (new_w_current.cr);
00736   if (new_w_current.pl != NULL) g_object_unref (new_w_current.pl);
00737   if (new_w_current.window != NULL) {
00738     g_object_unref(new_w_current.window);
00739   }
00740 
00741   return(pixbuf);
00742 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines