Bumped versions to 1.1.2/20070818/30:2:0 for the next development snapshot
[geda-gaf/whiteaudio.git] / gschem / src / x_image.c
blob1846155fbd04e19a7144c2d357f5875a05e93eca
1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2007 Ales Hvezda
4 * Copyright (C) 1998-2007 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., 59 Temple Place, Suite 330, Boston, MA 02111 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 <libgeda/libgeda.h>
35 #include "../include/globals.h"
36 #include "../include/prototype.h"
37 #include "../include/x_dialog.h"
39 #ifdef HAVE_LIBDMALLOC
40 #include <dmalloc.h>
41 #endif
43 #define X_IMAGE_DEFAULT_SIZE "800x600"
45 #define X_IMAGE_SIZE_MENU_NAME "image_size_menu"
46 #define X_IMAGE_TYPE_MENU_NAME "image_type_menu"
48 #define X_IMAGE_DEFAULT_TYPE "PNG"
50 static char *x_image_sizes[] = {"320x240", "640x480", "800x600", "1200x768",
51 "1280x960", "1600x1200", "3200x2400", NULL};
53 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
54 /* gtk_combo_box_get_active_text was included in GTK 2.6, so we need to store
55 the different image type descriptions in a list. */
56 GSList *image_type_descriptions = NULL;
57 #endif
60 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
61 static void free_image_type_descriptions_list ()
63 GSList *ptr;
65 /* Free the data stored in each node */
66 ptr = image_type_descriptions;
67 while (ptr) {
68 g_free(ptr->data);
69 ptr->data = NULL;
70 ptr = g_slist_next(ptr);
73 /* Free the list */
74 if (!ptr)
75 g_slist_free(image_type_descriptions);
76 image_type_descriptions = NULL;
79 #endif
81 /*! \brief Create the options of the image size combobox
82 * \par This function adds the options of the image size to the given combobox.
83 * \param combo [in] the combobox to add the options to.
84 * \return nothing
85 * \note
86 * This function is only used in this file, there are other create_menus...
88 static void create_size_menu (GtkComboBox *combo)
90 char *buf;
91 char *default_size;
92 int i, default_index = 0;
94 default_size = g_strdup_printf(X_IMAGE_DEFAULT_SIZE);
95 for (i=0; x_image_sizes[i] != NULL;i++) {
96 /* Create a new string and add it as an option*/
97 buf = g_strdup_printf(x_image_sizes[i]);
98 gtk_combo_box_append_text (GTK_COMBO_BOX (combo), buf);
100 /* Compare with the default size, to get the default index */
101 if (strcasecmp(buf, default_size ) == 0) {
102 default_index = i;
104 g_free(buf);
106 g_free(default_size);
108 /* Set the default menu */
109 gtk_combo_box_set_active(GTK_COMBO_BOX (combo), default_index);
111 return;
114 /*! \brief Create the options of the image type combobox
115 * \par This function adds the options of the image type to the given combobox.
116 * \param combo [in] the combobox to add the options to.
117 * \return nothing
118 * \note
119 * This function is only used in this file, there are other create_menus...
121 static void create_type_menu(GtkComboBox *combo)
123 GSList *formats = gdk_pixbuf_get_formats ();
124 GSList *ptr;
125 char *buf;
126 int i=0, default_index=0;
128 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
129 /* If GTK < 2.6, free the descriptions list */
130 free_image_type_descriptions_list();
131 #endif
133 ptr = formats;
134 while (ptr) {
135 if (gdk_pixbuf_format_is_writable (ptr->data)) {
136 /* Get the format description and add it to the menu */
137 buf = g_strdup_printf(gdk_pixbuf_format_get_description(ptr->data));
138 gtk_combo_box_append_text (GTK_COMBO_BOX (combo), buf);
140 /* If GTK < 2.6, then add it also to the descriptions list. */
141 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
142 image_type_descriptions = g_slist_append(image_type_descriptions,
143 buf);
144 #endif
146 /* Compare the name with "png" and store the index */
147 buf = g_strdup_printf(gdk_pixbuf_format_get_name(ptr->data));
148 if (strcasecmp(buf, X_IMAGE_DEFAULT_TYPE) == 0) {
149 default_index = i;
151 i++; /* this is the count of items added to the combo box */
152 /* not the total number of pixbuf formats */
153 g_free(buf);
155 ptr = ptr->next;
157 g_slist_free (formats);
158 gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "Encapsulated Postscript");
160 /* Set the default menu */
161 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), default_index);
162 return;
165 /*! \brief Given a gdk-pixbuf image type description, it returns the type,
166 * or extension of the image.
167 * \par Return the gdk-pixbuf image type, or extension, which has the
168 * given gdk-pixbuf description.
169 * \param description The gdk-pixbuf image type description.
170 * \return The gdk-pixbuf type, or extension, of the image.
171 * \note This function is only used in this file.
173 static char *x_image_get_type_from_description(char *description) {
174 gchar *descr = g_strdup_printf(description);
175 GSList *formats = gdk_pixbuf_get_formats ();
176 GSList *ptr;
177 gchar *ptr_descr;
179 /*WK - catch EPS export case*/
180 if (strcmp(descr, _("Encapsulated Postscript")) == 0) {
181 return(g_strdup("eps"));
184 ptr = formats;
185 while (ptr) {
186 ptr_descr = gdk_pixbuf_format_get_description (ptr->data);
187 if (ptr_descr && (strcasecmp(ptr_descr, descr) == 0)) {
188 g_free(descr);
189 return(gdk_pixbuf_format_get_name(ptr->data));
192 ptr = ptr->next;
194 g_free (descr);
195 return NULL;
198 /*! \brief Update the filename of a file dialog, when the image type has changed.
199 * \par Given a combobox inside a file chooser dialog, this function updates
200 * the filename displayed by the dialog, removing the current extension, and
201 * adding the extension of the image type selected.
202 * \param combo [in] A combobox inside a file chooser dialog, with gdk-pixbuf image type descriptions.
203 * \param w_current [in] the TOPLEVEL structure.
204 * \return nothing.
207 static void x_image_update_dialog_filename(GtkComboBox *combo,
208 TOPLEVEL *w_current) {
210 char* image_type_descr = NULL;
211 char *image_type = NULL;
212 char *old_image_filename = NULL;
213 char *file_basename = NULL;
214 char *file_name = NULL ;
215 char *new_image_filename = NULL;
216 GtkWidget *file_chooser;
218 /* Get the current image type */
219 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
220 GSList *ptr;
221 /* If GTK < 2.6, get the description from the descriptions list */
222 ptr = g_slist_nth(image_type_descriptions,
223 gtk_combo_box_get_active(GTK_COMBO_BOX(combo)));
224 image_type_descr = (char *) (ptr->data);
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 = w_current->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");
265 fprintf(stderr, "x_image_update_dialog_filename: No parent file chooser found!.\n");
268 g_free(file_name);
269 g_free(file_basename);
270 g_free(new_image_filename);
273 /*! \brief Write eps image file.
274 * \par This function writes the eps file, using the postscript print code
275 * from libgeda. Orientation is portrait and type is extents without margins.
276 * \param w_current [in] the TOPLEVEL structure.
277 * \param filename [in] the image filename.
278 * \return nothing
281 void x_image_write_eps(TOPLEVEL *w_current, const char* filename)
283 int result;
284 int w, h, orientation, type;
285 w = w_current->paper_width;
286 h = w_current->paper_height;
287 orientation = w_current->print_orientation;
288 type = w_current->print_output_type;
290 w_current->paper_width = 0;
291 w_current->paper_height = 0;
292 w_current->print_orientation = PORTRAIT;
293 w_current->print_output_type = EXTENTS_NOMARGINS;
294 result = f_print_file (w_current, filename);
295 if (result) {
296 fprintf(stderr, "x_image_lowlevel: Unable to save eps file %s.\n",
297 filename);
298 s_log_message(_("x_image_lowlevel: Unable to write eps file %s.\n"),
299 filename);
302 w_current->paper_width = w;
303 w_current->paper_height = h;
304 w_current->print_orientation = orientation;
305 w_current->print_output_type = type;
308 /*! \brief Write the image file, with the desired options.
309 * \par This function writes the image file, with the options set in the
310 * dialog by the user.
311 * \param w_current [in] the TOPLEVEL structure.
312 * \param filename [in] the image filename.
313 * \param desired_width [in] the image width chosen by the user.
314 * \param desired_height [in] the image height chosen by the user.
315 * \param filetype [in] image filetype.
316 * \return nothing
319 void x_image_lowlevel(TOPLEVEL *w_current, const char* filename,
320 int desired_width, int desired_height, char *filetype)
322 int width, height;
323 int save_height, save_width;
324 int save_page_left, save_page_right, save_page_top, save_page_bottom;
325 int page_width, page_height, page_center_left, page_center_top;
326 GdkPixbuf *pixbuf;
327 GError *gerror = NULL;
328 GtkWidget *dialog;
329 float prop;
331 w_current->image_width = width = desired_width;
332 w_current->image_height = height = desired_height;
334 save_width = w_current->width;
335 save_height = w_current->height;
337 w_current->width = width;
338 w_current->height = height;
340 save_page_left = w_current->page_current->left;
341 save_page_right = w_current->page_current->right;
342 save_page_top = w_current->page_current->top;
343 save_page_bottom = w_current->page_current->bottom;
345 page_width = save_page_right - save_page_left;
346 page_height = save_page_bottom - save_page_top;
348 page_center_left = save_page_left + (page_width / 2);
349 page_center_top = save_page_top + (page_height / 2);
351 /* Preserve proportions */
352 prop = (float)width / height;
353 if(page_width > page_height) {
354 page_height = (page_width / prop);
355 }else{
356 page_width = (page_height * prop);
359 /* need to do this every time you change width / height */
360 set_window(w_current, w_current->page_current,
361 page_center_left - (page_width / 2),
362 page_center_left + (page_width / 2),
363 page_center_top - (page_height / 2),
364 page_center_top + (page_height / 2));
366 /* de select everything first */
367 o_select_run_hooks( w_current, NULL, 2 );
368 o_selection_unselect_list( w_current, w_current->page_current->selection_list );
370 if (strcmp(filetype, "eps") == 0) /*WK - catch EPS export case*/
371 x_image_write_eps(w_current, filename);
372 else {
373 pixbuf = x_image_get_pixbuf(w_current);
374 if (pixbuf != NULL) {
375 if (!gdk_pixbuf_save(pixbuf, filename, filetype, &gerror, NULL)) {
376 fprintf(stderr, "x_image_lowlevel: Unable to save %s file %s.\n",
377 filetype, filename);
378 fprintf(stderr, "%s\n", gerror->message);
379 s_log_message(_("x_image_lowlevel: Unable to write %s file %s.\n"),
380 filetype, filename);
381 s_log_message(gerror->message);
383 /* Warn the user */
384 dialog = gtk_message_dialog_new (GTK_WINDOW(w_current->main_window),
385 GTK_DIALOG_MODAL
386 | GTK_DIALOG_DESTROY_WITH_PARENT,
387 GTK_MESSAGE_ERROR,
388 GTK_BUTTONS_OK,
389 _("There was the following error when saving image with type %s to filename:\n%s\n\n%s.\n"),
390 filetype, filename, gerror->message
393 gtk_dialog_run (GTK_DIALOG (dialog));
394 gtk_widget_destroy (dialog);
396 /* Free the gerror */
397 g_error_free(gerror);
398 gerror = NULL;
400 /* Unlink the output file */
401 /* It's not safe to unlink the file if there was an error.
402 For example: if the operation was not allowed due to permissions,
403 the _previous existing_ file will be removed */
404 /* unlink(filename); */
406 else {
407 if (w_current->image_color == TRUE) {
408 s_log_message(_("Wrote color image to [%s] [%d x %d]\n"), filename, width, height);
409 } else {
410 s_log_message(_("Wrote black and white image to [%s] [%d x %d]\n"), filename, width, height);
413 if (filetype != NULL)
414 g_free(filetype);
415 if (pixbuf != NULL)
416 g_object_unref(pixbuf);
418 else {
419 fprintf(stderr, "x_image_lowlevel: Unable to get pixbuf from gschem's window.\n");
420 s_log_message(_("x_image_lowlevel: Unable to get pixbuf from gschem's window.\n"));
424 w_current->width = save_width;
425 w_current->height = save_height;
427 /* need to do this every time you change width / height */
428 set_window(w_current, w_current->page_current,
429 save_page_left,
430 save_page_right,
431 save_page_top,
432 save_page_bottom);
434 /* try to use recalc here... */
435 o_redraw_all(w_current);
439 /*! \brief Display the image file selection dialog.
440 * \par Display the image file selection dialog, allowing the user to
441 * set several options, like image size and image type.
442 * When the user hits "ok", then it writes the image file.
443 * \param w_current [in] the TOPLEVEL structure.
444 * \return nothing
446 void x_image_setup (TOPLEVEL *w_current)
448 GtkWidget *dialog;
449 GtkWidget *vbox1;
450 GtkWidget *hbox;
451 GtkWidget *label1;
452 GtkWidget *size_combo;
453 GtkWidget *vbox2;
454 GtkWidget *label2;
455 GtkWidget *type_combo;
456 char *image_type_descr;
457 char *filename;
458 char *image_size;
459 char *image_type;
460 int width, height;
462 hbox = gtk_hbox_new(FALSE, 0);
464 /* Image size selection */
465 vbox1 = gtk_vbox_new(TRUE, 0);
466 label1 = gtk_label_new (_("Width x Height"));
467 gtk_widget_show (label1);
468 gtk_misc_set_alignment( GTK_MISC (label1), 0, 0);
469 gtk_misc_set_padding (GTK_MISC (label1), 0, 0);
470 gtk_box_pack_start (GTK_BOX (vbox1),
471 label1, FALSE, FALSE, 0);
473 size_combo = gtk_combo_box_new_text ();
474 create_size_menu (GTK_COMBO_BOX(size_combo));
476 gtk_widget_show (size_combo);
477 gtk_box_pack_start (GTK_BOX (vbox1), size_combo, TRUE, TRUE, 0);
478 gtk_widget_show(vbox1);
480 /* Image type selection */
481 vbox2 = gtk_vbox_new(TRUE, 0);
482 label2 = gtk_label_new (_("Image type"));
483 gtk_widget_show (label2);
484 gtk_misc_set_alignment( GTK_MISC (label2), 0, 0);
485 gtk_misc_set_padding (GTK_MISC (label2), 0, 0);
486 gtk_box_pack_start (GTK_BOX (vbox2),
487 label2, FALSE, FALSE, 0);
489 type_combo = gtk_combo_box_new_text ();
490 gtk_box_pack_start (GTK_BOX (vbox2), type_combo, TRUE, TRUE, 0);
491 create_type_menu (GTK_COMBO_BOX(type_combo));
493 /* Connect the changed signal to the callback, so the filename
494 gets updated every time the image type is changed */
495 g_signal_connect (type_combo, "changed",
496 G_CALLBACK(x_image_update_dialog_filename),
497 w_current);
499 gtk_widget_show (type_combo);
500 gtk_widget_show(vbox2);
502 /* Create the dialog */
503 dialog = gtk_file_chooser_dialog_new (_("Write image..."),
504 GTK_WINDOW(w_current->main_window),
505 GTK_FILE_CHOOSER_ACTION_SAVE,
506 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
507 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
508 NULL);
510 #if GTK_CHECK_VERSION (2,6,0)
511 /* Set the alternative button order (ok, cancel, help) for other systems */
512 gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog),
513 GTK_RESPONSE_ACCEPT,
514 GTK_RESPONSE_CANCEL,
515 -1);
516 #endif
518 /* Add the extra widgets to the dialog*/
519 gtk_box_pack_start(GTK_BOX(hbox), vbox1, FALSE, FALSE, 10);
520 gtk_box_pack_start(GTK_BOX(hbox), vbox2, FALSE, FALSE, 10);
522 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER(dialog), hbox);
524 g_object_set (dialog,
525 /* GtkFileChooser */
526 "select-multiple", FALSE,
527 #if ((GTK_MAJOR_VERSION > 2) || ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION >=8)))
528 /* only in GTK 2.8 */
529 "do-overwrite-confirmation", TRUE,
530 #endif
531 NULL);
533 /* Update the filename */
534 x_image_update_dialog_filename(GTK_COMBO_BOX(type_combo), w_current);
536 gtk_dialog_set_default_response(GTK_DIALOG(dialog),
537 GTK_RESPONSE_ACCEPT);
539 gtk_window_position (GTK_WINDOW (dialog),
540 GTK_WIN_POS_MOUSE);
542 gtk_container_set_border_width(GTK_CONTAINER(dialog),
543 DIALOG_BORDER_SPACING);
544 gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog)->vbox),
545 DIALOG_V_SPACING);
547 gtk_widget_show (dialog);
549 if (gtk_dialog_run((GTK_DIALOG(dialog))) == GTK_RESPONSE_ACCEPT) {
550 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
551 image_size =
552 x_image_sizes[gtk_combo_box_get_active(GTK_COMBO_BOX(size_combo))];
553 #else
554 image_size = gtk_combo_box_get_active_text(GTK_COMBO_BOX(size_combo));
555 #endif
557 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
558 GSList *ptr;
559 /* If GTK < 2.6, get the description from the descriptions list */
560 ptr = g_slist_nth(image_type_descriptions,
561 gtk_combo_box_get_active(GTK_COMBO_BOX(type_combo)));
562 image_type_descr = (char *) (ptr->data);
563 #else
564 image_type_descr = gtk_combo_box_get_active_text(GTK_COMBO_BOX(type_combo));
565 #endif
567 image_type = x_image_get_type_from_description(image_type_descr);
568 sscanf(image_size, "%ix%i", &width, &height);
569 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
571 x_image_lowlevel(w_current, filename, width, height, image_type);
574 #if ((GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 6))
575 /* If GTK < 2.6, free the descriptions list */
576 free_image_type_descriptions_list();
577 #endif
579 gtk_widget_destroy (dialog);
582 /*! \todo Finish function documentation!!!
583 * \brief
584 * \par Function Description
587 static void x_image_convert_to_greyscale(GdkPixbuf *pixbuf)
589 int width, height, rowstride, n_channels;
590 guchar *pixels, *p, new_value;
591 int i, j;
593 n_channels = gdk_pixbuf_get_n_channels (pixbuf);
595 if (n_channels != 3)
597 return;
600 if (gdk_pixbuf_get_colorspace (pixbuf) != GDK_COLORSPACE_RGB)
602 return;
605 if (gdk_pixbuf_get_bits_per_sample (pixbuf) != 8)
607 return;
610 width = gdk_pixbuf_get_width (pixbuf);
611 height = gdk_pixbuf_get_height (pixbuf);
613 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
614 pixels = gdk_pixbuf_get_pixels (pixbuf);
616 for (j = 0; j < height; j++)
618 for (i = 0; i < width; i++)
620 p = pixels + j * rowstride + i * n_channels;
622 new_value = 0.3 * p[0] + 0.59 * p[1] + 0.11 * p[2];
623 p[0] = new_value;
624 p[1] = new_value;
625 p[2] = new_value;
630 /*! \todo Finish function documentation!!!
631 * \brief
632 * \par Function Description
635 GdkPixbuf *x_image_get_pixbuf (TOPLEVEL *w_current)
637 GdkPixbuf *pixbuf;
638 int origin_x, origin_y, bottom, right;
639 int size_x, size_y, s_right, s_left, s_top,s_bottom;
640 TOPLEVEL toplevel;
642 /* Do a copy of the toplevel struct and work with it */
643 memcpy(&toplevel, w_current, sizeof(TOPLEVEL));
645 WORLDtoSCREEN(&toplevel,
646 w_current->page_current->right,
647 w_current->page_current->left,
648 &s_right,
649 &s_left);
650 WORLDtoSCREEN(&toplevel,
651 w_current->page_current->bottom,
652 w_current->page_current->top,
653 &s_bottom,
654 &s_top);
656 size_x = s_left - s_right;
657 size_y = s_bottom - s_top;
659 size_x = toplevel.image_width;
660 size_y = toplevel.image_height;
662 toplevel.window = gdk_pixmap_new(w_current->window, size_x, size_y, -1);
663 toplevel.backingstore = gdk_pixmap_new(w_current->window, size_x, size_y, -1);
664 toplevel.grid = 0;
665 toplevel.text_origin_marker = FALSE;
667 toplevel.display_width = toplevel.image_width;
668 toplevel.display_height = toplevel.image_height;
670 toplevel.win_width = toplevel.image_width;
671 toplevel.win_height = toplevel.image_height;
673 if (toplevel.image_color == FALSE)
675 /* We are going to be doing black&white (grayscale) output, so change the */
676 /* color of all objects to a nice and dark color, say black */
677 toplevel.override_color = BLACK;
679 /* also reset the background to white */
680 toplevel.background_color = WHITE;
683 origin_x = origin_y = 0;
684 right = size_x;
685 bottom = size_y;
687 /* ------------------ Begin optional code ------------------------ */
688 /* If the the code in this region is commented, the PNG returned will
689 be the same as the one returned using libgd.
690 I mean: there will be some border all around the schematic.
691 This code is used to adjust the schematic to the border of the image */
692 #if 0
694 /* Do a zoom extents to get fit all the schematic in the window */
695 /* Commented so the image returned will be the same as with libgd */
696 a_zoom_extents (&toplevel,
697 toplevel.page_current->object_head,
698 A_PAN_DONT_REDRAW);
701 /* See if there are objects */
703 aux = w_current->page_current->object_head;
704 while (aux != NULL) {
705 if (aux->type != -1) {
706 object_found = 1;
707 break;
709 aux = aux->next;
713 /* If there are no objects, can't use zoom_extents */
714 if (object_found) {
715 o_redraw_all (&toplevel);
716 get_object_list_bounds(&toplevel,
717 toplevel.page_current->object_head,
718 &origin_x, &origin_y,
719 &right, &bottom);
721 #endif
722 /* ------------------ End optional code ------------------------ */
724 o_redraw_all (&toplevel);
726 /* Get the pixbuf */
727 pixbuf=gdk_pixbuf_get_from_drawable(NULL,toplevel.backingstore, NULL,
728 origin_x, origin_y, 0, 0,
729 right-origin_x,
730 bottom-origin_y);
732 if (toplevel.image_color == FALSE)
734 x_image_convert_to_greyscale(pixbuf);
737 if (toplevel.window != NULL) {
738 g_object_unref(toplevel.window);
740 if (toplevel.backingstore != NULL) {
741 g_object_unref(toplevel.backingstore);
744 return(pixbuf);