/* Callback function registered with libgeda to allow the libgeda * "bounds" functions to get text bounds using the renderer. If a * "rendered bounds" function isn't provided, text objects don't get * used when calculating the extents of the drawing. */ static gboolean export_text_rendered_bounds (void *user_data, const GedaObject *object, gint *left, gint *top, gint *right, gint *bottom) { int result; double t, l, r, b; EdaRenderer *renderer = EDA_RENDERER (user_data); result = eda_renderer_get_user_bounds (renderer, object, &l, &t, &r, &b); *left = lrint (fmin (l,r)); *top = lrint (fmin (t, b)); *right = lrint (fmax (l, r)); *bottom = lrint (fmax (t, b)); return result; }
/*! \brief Draw a page. * \par Function Description * Draws the \a page on the Cairo context \a cr, which should have * dimensions \a cr_width and \a cr_height. If the Pango context \a * pc is provided, it is used for rendering of text. The parameter \a * is_color controls whether to enable color printing, and \a * is_raster should be set if drawing to a raster surface such as an * image. * * \param toplevel A #TOPLEVEL structure. * \param page The #PAGE to be rendered. * \param cr The Cairo context to render to. * \param pc A Pango context for text rendering, or NULL. * \param cr_width The width of the drawing area. * \param cr_height The height of the drawing area. * \param is_color TRUE if drawing should be in color; FALSE otherwise. * \param is_raster TRUE if drawing to a raster image surface; FALSE otherwise. */ static void x_print_draw_page (TOPLEVEL *toplevel, PAGE *page, cairo_t *cr, PangoContext *pc, double cr_width, double cr_height, gboolean is_color, gboolean is_raster) { EdaRenderer *renderer; cairo_matrix_t mtx; GArray *color_map; int status, wx_min, wy_min, wx_max, wy_max; double w_width, w_height, scale; GList *iter; /* First, calculate a transformation matrix for the cairo * context. We want to center the extents of the page in the * available page area. */ status = world_get_object_glist_bounds (toplevel, s_page_objects (page), &wx_min, &wy_min, &wx_max, &wy_max); /* If there are no printable objects, draw nothing. */ if (!status) return; w_width = wx_max - wx_min; w_height = wy_max - wy_min; scale = fmin (cr_width / w_width, cr_height / w_height); cairo_matrix_init (&mtx, scale, 0, 0, -scale, - (wx_min + 0.5*w_width) * scale + 0.5*cr_width, (wy_min + 0.5*w_height) * scale + 0.5*cr_height); /* Second, build the color map. If no color printing is desired, * transform the print color map into a black-and-white color map by * making the background color transparent and replacing all other * enabled colors with solid black. */ color_map = g_array_sized_new (FALSE, FALSE, sizeof(GedaColor), MAX_COLORS); color_map = g_array_append_vals (color_map, print_colors, MAX_COLORS); if (!is_color) { int i; for (i = 0; i < MAX_COLORS; i++) { GedaColor *c = &g_array_index (color_map, GedaColor, i); if (!c->enabled) continue; /* Disable background color & fully-transparent colors */ if (c->a == 0 || i == BACKGROUND_COLOR) { c->enabled = FALSE; continue; } /* Set any remaining colors solid black */ c->r = 0; c->g = 0; c->b = 0; c->a = ~0; } } /* Thirdly, create and initialise a renderer */ renderer = EDA_RENDERER (g_object_new (EDA_TYPE_RENDERER, "cairo-context", cr, "pango-context", pc, "color-map", color_map, "render-flags", is_raster ? EDA_RENDERER_FLAG_HINTING : 0, NULL)); /* Finally, actually do drawing */ cairo_save (cr); cairo_transform (cr, &mtx); /* Draw background */ eda_cairo_set_source_color (cr, BACKGROUND_COLOR, color_map); cairo_paint (cr); /* Draw all objects and cues */ for (iter = (GList *) s_page_objects (page); iter != NULL; iter = g_list_next (iter)) { eda_renderer_draw (renderer, (OBJECT *) iter->data); } for (iter = (GList *) s_page_objects (page); iter != NULL; iter = g_list_next (iter)) { eda_renderer_draw_cues (renderer, (OBJECT *) iter->data); } cairo_restore (cr); g_object_unref (renderer); g_array_free (color_map, TRUE); }
GschemToplevel *gschem_toplevel_new () { GschemToplevel *w_current; w_current = g_new0 (GschemToplevel, 1); w_current->toplevel = NULL; w_current->dont_invalidate = FALSE; /* ------------------- */ /* main window widgets */ /* ------------------- */ w_current->main_window = NULL; w_current->drawing_area = NULL; w_current->menubar = NULL; w_current->popup_menu = NULL; w_current->find_text_widget = NULL; w_current->find_patch_widget = NULL; w_current->macro_widget = NULL; w_current->bottom_widget = NULL; w_current->translate_widget = NULL; w_current->toolbar_select = NULL; w_current->toolbar_net = NULL; w_current->toolbar_bus = NULL; w_current->left_notebook = NULL; w_current->bottom_notebook = NULL; w_current->right_notebook = NULL; w_current->keyaccel_string = NULL; w_current->keyaccel_string_source_id = FALSE; /* ------------ */ /* Dialog boxes */ /* ------------ */ w_current->sowindow = NULL; w_current->pfswindow = NULL; w_current->pswindow = NULL; w_current->tiwindow = NULL; w_current->sewindow = NULL; w_current->aawindow = NULL; w_current->aewindow = NULL; w_current->hkwindow = NULL; w_current->cowindow = NULL; w_current->coord_world = NULL; w_current->coord_screen = NULL; /* --------- */ /* Dockables */ /* --------- */ w_current->dockables = NULL; w_current->compselect_dockable = NULL; w_current->object_properties_dockable = NULL; w_current->text_properties_dockable = NULL; w_current->multiattrib_dockable = NULL; w_current->options_dockable = NULL; w_current->log_dockable = NULL; w_current->find_text_dockable = NULL; /* -------------------------------------- */ /* Models for widgets inside dialog boxes */ /* -------------------------------------- */ w_current->dash_length_list_store = NULL; w_current->dash_space_list_store = NULL; w_current->fill_angle_list_store = NULL; w_current->fill_pitch_list_store = NULL; w_current->fill_width_list_store = NULL; w_current->line_width_list_store = NULL; w_current->text_size_list_store = NULL; /* ----------------------------------------- */ /* An adapter for manipulating the selection */ /* ----------------------------------------- */ w_current->selection_adapter = NULL; /* ----------------- */ /* Picture placement */ /* ----------------- */ w_current->current_pixbuf = NULL; w_current->pixbuf_filename = NULL; w_current->pixbuf_wh_ratio = 0; /* ------------- */ /* Drawing state */ /* ------------- */ w_current->renderer = EDA_RENDERER (g_object_new (EDA_TYPE_RENDERER, NULL)); w_current->first_wx = -1; w_current->first_wy = -1; w_current->second_wx = -1; w_current->second_wy = -1; w_current->third_wx = -1; w_current->third_wy = -1; w_current->distance = 0; w_current->magnetic_wx = -1; w_current->magnetic_wy = -1; w_current->inside_action = 0; w_current->rubber_visible = 0; w_current->net_direction = 0; w_current->which_grip = -1; w_current->which_object = NULL; w_current->temp_path = NULL; w_current->pathcontrol = TRUE; /* ------------------ */ /* Rubberbanding nets */ /* ------------------ */ w_current->stretch_list = NULL; /* --------------------- */ /* Gschem internal state */ /* --------------------- */ w_current->num_untitled = 0; w_current->event_state = SELECT; w_current->image_width = 0; w_current->image_height = 0; w_current->min_zoom = 0; w_current->max_zoom = 8; w_current->drawbounding_action_mode = FREE; w_current->last_drawb_mode = LAST_DRAWB_MODE_NONE; w_current->CONTROLKEY = 0; w_current->SHIFTKEY = 0; w_current->ALTKEY = 0; w_current->buffer_number = 0; w_current->last_callback = NULL; w_current->clipboard_buffer = NULL; /* ------------------ */ /* rc/user parameters */ /* ------------------ */ w_current->options = gschem_options_new(); g_signal_connect_swapped (G_OBJECT (w_current->options), "notify", G_CALLBACK (notify_options), w_current); w_current->text_caps = 0; w_current->text_size = 0; w_current->zoom_with_pan = 0; w_current->actionfeedback_mode = OUTLINE; w_current->net_direction_mode = TRUE; w_current->net_selection_mode = 0; w_current->net_selection_state = 0; w_current->embed_complex = 0; w_current->include_complex = 0; w_current->scrollbars_flag = 0; w_current->log_window = 0; w_current->log_window_type = 0; w_current->third_button = 0; w_current->third_button_cancel = TRUE; w_current->middle_button = 0; w_current->file_preview = 0; w_current->enforce_hierarchy = 0; w_current->fast_mousepan = 0; w_current->raise_dialog_boxes = 0; w_current->continue_component_place = 0; w_current->undo_levels = 0; w_current->undo_control = 0; w_current->undo_type = 0; w_current->undo_panzoom = 0; w_current->draw_grips = 0; w_current->warp_cursor = 0; w_current->toolbars = 0; w_current->handleboxes = 0; w_current->bus_ripper_size = 0; w_current->bus_ripper_type = 0; w_current->bus_ripper_rotation = 0; w_current->grid_mode = GRID_MODE_NONE; w_current->dots_grid_fixed_threshold = 10; w_current->dots_grid_dot_size = 1; w_current->dots_grid_mode = DOTS_GRID_VARIABLE_MODE; w_current->mesh_grid_display_threshold = 3; w_current->add_attribute_offset = 50; w_current->mousepan_gain = 5; w_current->keyboardpan_gain = 10; w_current->select_slack_pixels = 4; w_current->zoom_gain = 20; w_current->scrollpan_steps = 8; w_current->smob = SCM_UNDEFINED; return w_current; }