refdes_renum: warn of possible number clash with non-conforming values
[geda-gaf/whiteaudio.git] / gschem / src / x_image.c
blobe0bb83c889a1b89e128c8e0cfd1d11d817a714e6
1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #include <config.h>
22 #include <stdio.h>
23 #include <unistd.h>
24 #ifdef HAVE_STDLIB_H
25 #include <stdlib.h>
26 #endif
27 #ifdef HAVE_STRING_H
28 #include <string.h>
29 #endif
31 #include <glib.h>
33 #include "gschem.h"
35 #ifdef HAVE_LIBDMALLOC
36 #include <dmalloc.h>
37 #endif
39 #define X_IMAGE_DEFAULT_SIZE "800x600"
41 #define X_IMAGE_SIZE_MENU_NAME "image_size_menu"
42 #define X_IMAGE_TYPE_MENU_NAME "image_type_menu"
44 #define X_IMAGE_DEFAULT_TYPE "PNG"
46 static char *x_image_sizes[] = {"320x240", "640x480", "800x600", "1200x768",
47 "1280x960", "1600x1200", "3200x2400", NULL};
49 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
50 /* gtk_combo_box_get_active_text was included in GTK 2.6, so we need to store
51 the different image type descriptions in a list. */
52 GSList *image_type_descriptions = NULL;
53 #endif
56 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
57 static void free_image_type_descriptions_list ()
59 GSList *ptr;
61 /* Free the data stored in each node */
62 ptr = image_type_descriptions;
63 while (ptr) {
64 g_free(ptr->data);
65 ptr->data = NULL;
66 ptr = g_slist_next(ptr);
69 /* Free the list */
70 if (!ptr)
71 g_slist_free(image_type_descriptions);
72 image_type_descriptions = NULL;
75 #endif
77 /*! \brief Create the options of the image size combobox
78 * \par This function adds the options of the image size to the given combobox.
79 * \param combo [in] the combobox to add the options to.
80 * \return nothing
81 * \note
82 * This function is only used in this file, there are other create_menus...
84 static void create_size_menu (GtkComboBox *combo)
86 char *buf;
87 char *default_size;
88 int i, default_index = 0;
90 default_size = g_strdup (X_IMAGE_DEFAULT_SIZE);
91 for (i=0; x_image_sizes[i] != NULL;i++) {
92 /* Create a new string and add it as an option*/
93 buf = g_strdup (x_image_sizes[i]);
94 gtk_combo_box_append_text (GTK_COMBO_BOX (combo), buf);
96 /* Compare with the default size, to get the default index */
97 if (strcasecmp(buf, default_size ) == 0) {
98 default_index = i;
100 g_free(buf);
102 g_free(default_size);
104 /* Set the default menu */
105 gtk_combo_box_set_active(GTK_COMBO_BOX (combo), default_index);
107 return;
110 /*! \brief Create the options of the image type combobox
111 * \par This function adds the options of the image type to the given combobox.
112 * \param combo [in] the combobox to add the options to.
113 * \return nothing
114 * \note
115 * This function is only used in this file, there are other create_menus...
117 static void create_type_menu(GtkComboBox *combo)
119 GSList *formats = gdk_pixbuf_get_formats ();
120 GSList *ptr;
121 char *buf;
122 int i=0, default_index=0;
124 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
125 /* If GTK < 2.6, free the descriptions list */
126 free_image_type_descriptions_list();
127 #endif
129 ptr = formats;
130 while (ptr) {
131 if (gdk_pixbuf_format_is_writable (ptr->data)) {
132 /* Get the format description and add it to the menu */
133 buf = g_strdup (gdk_pixbuf_format_get_description(ptr->data));
134 gtk_combo_box_append_text (GTK_COMBO_BOX (combo), buf);
136 /* If GTK < 2.6, then add it also to the descriptions list. */
137 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
138 image_type_descriptions = g_slist_append(image_type_descriptions,
139 buf);
140 #endif
142 /* Compare the name with "png" and store the index */
143 buf = g_strdup (gdk_pixbuf_format_get_name(ptr->data));
144 if (strcasecmp(buf, X_IMAGE_DEFAULT_TYPE) == 0) {
145 default_index = i;
147 i++; /* this is the count of items added to the combo box */
148 /* not the total number of pixbuf formats */
149 g_free(buf);
151 ptr = ptr->next;
153 g_slist_free (formats);
154 gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Encapsulated Postscript");
156 /* Set the default menu */
157 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), default_index);
158 return;
161 /*! \brief Given a gdk-pixbuf image type description, it returns the type,
162 * or extension of the image.
163 * \par Return the gdk-pixbuf image type, or extension, which has the
164 * given gdk-pixbuf description.
165 * \param description The gdk-pixbuf image type description.
166 * \return The gdk-pixbuf type, or extension, of the image.
167 * \note This function is only used in this file.
169 static char *x_image_get_type_from_description(char *description) {
170 gchar *descr = g_strdup (description);
171 GSList *formats = gdk_pixbuf_get_formats ();
172 GSList *ptr;
173 gchar *ptr_descr;
175 /*WK - catch EPS export case*/
176 if (strcmp(descr, _("Encapsulated Postscript")) == 0) {
177 return(g_strdup("eps"));
180 ptr = formats;
181 while (ptr) {
182 ptr_descr = gdk_pixbuf_format_get_description (ptr->data);
183 if (ptr_descr && (strcasecmp(ptr_descr, descr) == 0)) {
184 g_free(descr);
185 return(gdk_pixbuf_format_get_name(ptr->data));
188 ptr = ptr->next;
190 g_free (descr);
191 return NULL;
194 /*! \brief Update the filename of a file dialog, when the image type has changed.
195 * \par Given a combobox inside a file chooser dialog, this function updates
196 * the filename displayed by the dialog, removing the current extension, and
197 * adding the extension of the image type selected.
198 * \param combo [in] A combobox inside a file chooser dialog, with gdk-pixbuf image type descriptions.
199 * \param w_current [in] the GSCHEM_TOPLEVEL structure.
200 * \return nothing.
203 static void x_image_update_dialog_filename(GtkComboBox *combo,
204 GSCHEM_TOPLEVEL *w_current) {
205 TOPLEVEL *toplevel = w_current->toplevel;
206 char* image_type_descr = NULL;
207 char *image_type = NULL;
208 char *old_image_filename = NULL;
209 char *file_basename = NULL;
210 char *file_name = NULL ;
211 char *new_image_filename = NULL;
212 GtkWidget *file_chooser;
214 /* Get the current image type */
215 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
216 GSList *ptr;
217 /* If GTK < 2.6, get the description from the descriptions list */
218 ptr = g_slist_nth(image_type_descriptions,
219 gtk_combo_box_get_active(GTK_COMBO_BOX(combo)));
220 if (ptr != NULL) {
221 image_type_descr = (char *) (ptr->data);
222 } else {
223 image_type_descr = NULL;
225 #else
226 image_type_descr = gtk_combo_box_get_active_text(GTK_COMBO_BOX(combo));
227 #endif
228 image_type = x_image_get_type_from_description(image_type_descr);
230 /* Get the parent dialog */
231 file_chooser = gtk_widget_get_ancestor(GTK_WIDGET(combo),
232 GTK_TYPE_FILE_CHOOSER);
234 /* Get the previous file name. If none, revert to the page filename */
235 old_image_filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_chooser));
236 if (!old_image_filename) {
237 old_image_filename = toplevel->page_current->page_filename;
240 /* Get the file name, without extension */
241 if (old_image_filename) {
242 file_basename = g_path_get_basename(old_image_filename);
244 if (g_strrstr(file_basename, ".") != NULL) {
245 file_name = g_strndup(file_basename,
246 g_strrstr(file_basename, ".") - file_basename);
250 /* Add the extension */
251 if (file_name) {
252 new_image_filename = g_strdup_printf("%s.%s", file_name,
253 image_type);
254 } else {
255 new_image_filename = g_strdup_printf("%s.%s", file_basename,
256 image_type);
259 /* Set the new filename */
260 if (file_chooser) {
261 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(file_chooser),
262 new_image_filename);
263 } else {
264 s_log_message("x_image_update_dialog_filename: No parent file chooser found!.\n");
267 g_free(file_name);
268 g_free(file_basename);
269 g_free(new_image_filename);
272 /*! \brief Write eps image file.
273 * \par This function writes the eps file, using the postscript print code
274 * from libgeda. Orientation is portrait and type is extents without margins.
275 * \param w_current [in] the GSCHEM_TOPLEVEL structure.
276 * \param filename [in] the image filename.
277 * \return nothing
280 void x_image_write_eps(GSCHEM_TOPLEVEL *w_current, const char* filename)
282 TOPLEVEL *toplevel = w_current->toplevel;
283 int result;
284 int w, h, orientation, type;
285 w = toplevel->paper_width;
286 h = toplevel->paper_height;
287 orientation = toplevel->print_orientation;
288 type = toplevel->print_output_type;
290 toplevel->paper_width = 0;
291 toplevel->paper_height = 0;
292 toplevel->print_orientation = PORTRAIT;
293 toplevel->print_output_type = EXTENTS_NOMARGINS;
294 result = f_print_file (toplevel, toplevel->page_current, filename);
295 if (result) {
296 s_log_message(_("x_image_lowlevel: Unable to write eps file %s.\n"),
297 filename);
300 toplevel->paper_width = w;
301 toplevel->paper_height = h;
302 toplevel->print_orientation = orientation;
303 toplevel->print_output_type = type;
306 /*! \brief Write the image file, with the desired options.
307 * \par This function writes the image file, with the options set in the
308 * dialog by the user.
309 * \param w_current [in] the GSCHEM_TOPLEVEL structure.
310 * \param filename [in] the image filename.
311 * \param desired_width [in] the image width chosen by the user.
312 * \param desired_height [in] the image height chosen by the user.
313 * \param filetype [in] image filetype.
314 * \return nothing
317 void x_image_lowlevel(GSCHEM_TOPLEVEL *w_current, const char* filename,
318 int desired_width, int desired_height, char *filetype)
320 TOPLEVEL *toplevel = w_current->toplevel;
321 int width, height;
322 int save_height, save_width;
323 int save_page_left, save_page_right, save_page_top, save_page_bottom;
324 int page_width, page_height, page_center_left, page_center_top;
325 GdkPixbuf *pixbuf;
326 GError *gerror = NULL;
327 GtkWidget *dialog;
328 float prop;
330 w_current->image_width = width = desired_width;
331 w_current->image_height = height = desired_height;
333 save_width = toplevel->width;
334 save_height = toplevel->height;
336 toplevel->width = width;
337 toplevel->height = height;
339 save_page_left = toplevel->page_current->left;
340 save_page_right = toplevel->page_current->right;
341 save_page_top = toplevel->page_current->top;
342 save_page_bottom = toplevel->page_current->bottom;
344 page_width = save_page_right - save_page_left;
345 page_height = save_page_bottom - save_page_top;
347 page_center_left = save_page_left + (page_width / 2);
348 page_center_top = save_page_top + (page_height / 2);
350 /* Preserve proportions */
351 prop = (float)width / height;
352 if (((float)page_width / page_height) > prop) {
353 page_height = (page_width / prop);
354 }else{
355 page_width = (page_height * prop);
358 /* need to do this every time you change width / height */
359 set_window(toplevel, toplevel->page_current,
360 page_center_left - (page_width / 2),
361 page_center_left + (page_width / 2),
362 page_center_top - (page_height / 2),
363 page_center_top + (page_height / 2));
365 /* de select everything first */
366 o_select_unselect_all( w_current );
368 if (strcmp(filetype, "eps") == 0) /*WK - catch EPS export case*/
369 x_image_write_eps(w_current, filename);
370 else {
371 pixbuf = x_image_get_pixbuf(w_current);
372 if (pixbuf != NULL) {
373 if (!gdk_pixbuf_save(pixbuf, filename, filetype, &gerror, NULL)) {
374 s_log_message(_("x_image_lowlevel: Unable to write %s file %s.\n"),
375 filetype, filename);
376 s_log_message("%s", gerror->message);
378 /* Warn the user */
379 dialog = gtk_message_dialog_new (GTK_WINDOW(w_current->main_window),
380 GTK_DIALOG_MODAL
381 | GTK_DIALOG_DESTROY_WITH_PARENT,
382 GTK_MESSAGE_ERROR,
383 GTK_BUTTONS_OK,
384 _("There was the following error when saving image with type %s to filename:\n%s\n\n%s.\n"),
385 filetype, filename, gerror->message
388 gtk_dialog_run (GTK_DIALOG (dialog));
389 gtk_widget_destroy (dialog);
391 /* Free the gerror */
392 g_error_free(gerror);
393 gerror = NULL;
395 /* Unlink the output file */
396 /* It's not safe to unlink the file if there was an error.
397 For example: if the operation was not allowed due to permissions,
398 the _previous existing_ file will be removed */
399 /* unlink(filename); */
401 else {
402 if (toplevel->image_color == TRUE) {
403 s_log_message(_("Wrote color image to [%s] [%d x %d]\n"), filename, width, height);
404 } else {
405 s_log_message(_("Wrote black and white image to [%s] [%d x %d]\n"), filename, width, height);
408 g_free(filetype);
409 if (pixbuf != NULL)
410 g_object_unref(pixbuf);
412 else {
413 s_log_message(_("x_image_lowlevel: Unable to get pixbuf from gschem's window.\n"));
417 toplevel->width = save_width;
418 toplevel->height = save_height;
420 /* need to do this every time you change width / height */
421 set_window(toplevel, toplevel->page_current,
422 save_page_left,
423 save_page_right,
424 save_page_top,
425 save_page_bottom);
427 o_invalidate_all (w_current);
431 /*! \brief Display the image file selection dialog.
432 * \par Display the image file selection dialog, allowing the user to
433 * set several options, like image size and image type.
434 * When the user hits "ok", then it writes the image file.
435 * \param w_current [in] the GSCHEM_TOPLEVEL structure.
436 * \return nothing
438 void x_image_setup (GSCHEM_TOPLEVEL *w_current)
440 GtkWidget *dialog;
441 GtkWidget *vbox1;
442 GtkWidget *hbox;
443 GtkWidget *label1;
444 GtkWidget *size_combo;
445 GtkWidget *vbox2;
446 GtkWidget *label2;
447 GtkWidget *type_combo;
448 char *image_type_descr;
449 char *filename;
450 char *image_size;
451 char *image_type;
452 int width, height;
454 hbox = gtk_hbox_new(FALSE, 0);
456 /* Image size selection */
457 vbox1 = gtk_vbox_new(TRUE, 0);
458 label1 = gtk_label_new (_("Width x Height"));
459 gtk_widget_show (label1);
460 gtk_misc_set_alignment( GTK_MISC (label1), 0, 0);
461 gtk_misc_set_padding (GTK_MISC (label1), 0, 0);
462 gtk_box_pack_start (GTK_BOX (vbox1),
463 label1, FALSE, FALSE, 0);
465 size_combo = gtk_combo_box_new_text ();
466 create_size_menu (GTK_COMBO_BOX(size_combo));
468 gtk_widget_show (size_combo);
469 gtk_box_pack_start (GTK_BOX (vbox1), size_combo, TRUE, TRUE, 0);
470 gtk_widget_show(vbox1);
472 /* Image type selection */
473 vbox2 = gtk_vbox_new(TRUE, 0);
474 label2 = gtk_label_new (_("Image type"));
475 gtk_widget_show (label2);
476 gtk_misc_set_alignment( GTK_MISC (label2), 0, 0);
477 gtk_misc_set_padding (GTK_MISC (label2), 0, 0);
478 gtk_box_pack_start (GTK_BOX (vbox2),
479 label2, FALSE, FALSE, 0);
481 type_combo = gtk_combo_box_new_text ();
482 gtk_box_pack_start (GTK_BOX (vbox2), type_combo, TRUE, TRUE, 0);
483 create_type_menu (GTK_COMBO_BOX(type_combo));
485 /* Connect the changed signal to the callback, so the filename
486 gets updated every time the image type is changed */
487 g_signal_connect (type_combo, "changed",
488 G_CALLBACK(x_image_update_dialog_filename),
489 w_current);
491 gtk_widget_show (type_combo);
492 gtk_widget_show(vbox2);
494 /* Create the dialog */
495 dialog = gtk_file_chooser_dialog_new (_("Write image..."),
496 GTK_WINDOW(w_current->main_window),
497 GTK_FILE_CHOOSER_ACTION_SAVE,
498 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
499 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
500 NULL);
502 /* Set the alternative button order (ok, cancel, help) for other systems */
503 gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog),
504 GTK_RESPONSE_ACCEPT,
505 GTK_RESPONSE_CANCEL,
506 -1);
508 /* Add the extra widgets to the dialog*/
509 gtk_box_pack_start(GTK_BOX(hbox), vbox1, FALSE, FALSE, 10);
510 gtk_box_pack_start(GTK_BOX(hbox), vbox2, FALSE, FALSE, 10);
512 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER(dialog), hbox);
514 g_object_set (dialog,
515 /* GtkFileChooser */
516 "select-multiple", FALSE,
517 #if ((GTK_MAJOR_VERSION > 2) || ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION >=8)))
518 /* only in GTK 2.8 */
519 "do-overwrite-confirmation", TRUE,
520 #endif
521 NULL);
523 /* Update the filename */
524 x_image_update_dialog_filename(GTK_COMBO_BOX(type_combo), w_current);
526 gtk_dialog_set_default_response(GTK_DIALOG(dialog),
527 GTK_RESPONSE_ACCEPT);
529 gtk_window_position (GTK_WINDOW (dialog),
530 GTK_WIN_POS_MOUSE);
532 gtk_container_set_border_width(GTK_CONTAINER(dialog),
533 DIALOG_BORDER_SPACING);
534 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox),
535 DIALOG_V_SPACING);
537 gtk_widget_show (dialog);
539 if (gtk_dialog_run((GTK_DIALOG(dialog))) == GTK_RESPONSE_ACCEPT) {
540 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
541 image_size =
542 x_image_sizes[gtk_combo_box_get_active(GTK_COMBO_BOX(size_combo))];
543 #else
544 image_size = gtk_combo_box_get_active_text(GTK_COMBO_BOX(size_combo));
545 #endif
547 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
548 GSList *ptr;
549 /* If GTK < 2.6, get the description from the descriptions list */
550 ptr = g_slist_nth(image_type_descriptions,
551 gtk_combo_box_get_active(GTK_COMBO_BOX(type_combo)));
552 image_type_descr = (char *) (ptr->data);
553 #else
554 image_type_descr = gtk_combo_box_get_active_text(GTK_COMBO_BOX(type_combo));
555 #endif
557 image_type = x_image_get_type_from_description(image_type_descr);
558 sscanf(image_size, "%ix%i", &width, &height);
559 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
561 x_image_lowlevel(w_current, filename, width, height, image_type);
564 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
565 /* If GTK < 2.6, free the descriptions list */
566 free_image_type_descriptions_list();
567 #endif
569 gtk_widget_destroy (dialog);
572 /*! \todo Finish function documentation!!!
573 * \brief
574 * \par Function Description
577 static void x_image_convert_to_greyscale(GdkPixbuf *pixbuf)
579 int width, height, rowstride, n_channels;
580 guchar *pixels, *p, new_value;
581 int i, j;
583 n_channels = gdk_pixbuf_get_n_channels (pixbuf);
585 if (n_channels != 3)
587 return;
590 if (gdk_pixbuf_get_colorspace (pixbuf) != GDK_COLORSPACE_RGB)
592 return;
595 if (gdk_pixbuf_get_bits_per_sample (pixbuf) != 8)
597 return;
600 width = gdk_pixbuf_get_width (pixbuf);
601 height = gdk_pixbuf_get_height (pixbuf);
603 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
604 pixels = gdk_pixbuf_get_pixels (pixbuf);
606 for (j = 0; j < height; j++)
608 for (i = 0; i < width; i++)
610 p = pixels + j * rowstride + i * n_channels;
612 new_value = 0.3 * p[0] + 0.59 * p[1] + 0.11 * p[2];
613 p[0] = new_value;
614 p[1] = new_value;
615 p[2] = new_value;
620 /*! \todo Finish function documentation!!!
621 * \brief
622 * \par Function Description
625 GdkPixbuf *x_image_get_pixbuf (GSCHEM_TOPLEVEL *w_current)
627 GdkPixbuf *pixbuf;
628 int origin_x, origin_y, bottom, right;
629 int size_x, size_y, s_right, s_left, s_top,s_bottom;
630 GSCHEM_TOPLEVEL new_w_current;
631 TOPLEVEL toplevel;
632 GdkRectangle rect;
634 /* Do a copy of the w_current struct and work with it */
635 memcpy(&new_w_current, w_current, sizeof(GSCHEM_TOPLEVEL));
636 /* Do a copy of the toplevel struct and work with it */
637 memcpy(&toplevel, w_current->toplevel, sizeof(TOPLEVEL));
639 new_w_current.toplevel = &toplevel;
641 WORLDtoSCREEN (&new_w_current, toplevel.page_current->right,
642 toplevel.page_current->left, &s_right, &s_left);
643 WORLDtoSCREEN (&new_w_current, toplevel.page_current->bottom,
644 toplevel.page_current->top, &s_bottom, &s_top);
646 size_x = s_left - s_right;
647 size_y = s_bottom - s_top;
649 size_x = new_w_current.image_width;
650 size_y = new_w_current.image_height;
652 new_w_current.window = gdk_pixmap_new (w_current->window, size_x, size_y, -1);
653 new_w_current.drawable = new_w_current.window;
654 new_w_current.cr = gdk_cairo_create (new_w_current.window);
655 new_w_current.pl = pango_cairo_create_layout (new_w_current.cr);
657 new_w_current.grid = 0;
658 new_w_current.text_origin_marker = FALSE;
660 new_w_current.win_width = new_w_current.image_width;
661 new_w_current.win_height = new_w_current.image_height;
663 if (toplevel.image_color == FALSE)
665 /* FIXME this assumes -- not necessarily correctly! -- that the
666 * color at index 0 in the color map is black, and the color at
667 * index 1 is white! */
669 /* We are going to be doing black&white (grayscale) output, so change the */
670 /* color of all objects to a nice and dark color, say black */
671 toplevel.override_color = 0;
673 /* also reset the background to white */
674 toplevel.background_color = 1;
677 origin_x = origin_y = 0;
678 right = size_x;
679 bottom = size_y;
681 /* ------------------ Begin optional code ------------------------ */
682 /* If the the code in this region is commented, the PNG returned will
683 be the same as the one returned using libgd.
684 I mean: there will be some border all around the schematic.
685 This code is used to adjust the schematic to the border of the image */
686 #if 0
688 /* Do a zoom extents to get fit all the schematic in the window */
689 /* Commented so the image returned will be the same as with libgd */
690 a_zoom_extents (&toplevel,
691 toplevel.page_current->object_list,
692 A_PAN_DONT_REDRAW);
695 /* See if there are objects */
697 aux = toplevel->page_current->object_list;
698 while (aux != NULL) {
699 if (aux->type != -1) {
700 object_found = 1;
701 break;
703 aux = aux->next;
707 /* If there are no objects, can't use zoom_extents */
708 if (object_found) {
709 get_object_glist_bounds (&toplevel,
710 toplevel.page_current->object_list,
711 &origin_x, &origin_y,
712 &right, &bottom);
714 #endif
715 /* ------------------ End optional code ------------------------ */
717 rect.x = origin_x;
718 rect.y = origin_y;
719 rect.width = right - origin_x;
720 rect.height = bottom - origin_y;
722 o_redraw_rects (&new_w_current, &rect, 1);
724 /* Get the pixbuf */
725 pixbuf = gdk_pixbuf_get_from_drawable (NULL,new_w_current.drawable, NULL,
726 origin_x, origin_y, 0, 0,
727 right-origin_x,
728 bottom-origin_y);
730 if (toplevel.image_color == FALSE)
732 x_image_convert_to_greyscale(pixbuf);
735 if (new_w_current.cr != NULL) cairo_destroy (new_w_current.cr);
736 if (new_w_current.pl != NULL) g_object_unref (new_w_current.pl);
737 if (new_w_current.window != NULL) {
738 g_object_unref(new_w_current.window);
741 return(pixbuf);