gschem
|
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 }