static inline int screen_width (GSCHEM_TOPLEVEL *w_current, int w_width) { int width = SCREENabs (w_current, w_width); if (width < 1) width = 1; return width; }
void eda_cairo_center_arc (cairo_t *cr, int flags, double center_width, double line_width, double x, double y, double radius, double start_angle, double sweep_angle) { int s_center_width, s_line_width; double s_x, s_y, dummy = 0; int s_diameter; double even_center_width; double even_line_width; double even_diameter; double center_offset; double s_radius; int do_radius_hint = TRUE; if (!(flags & EDA_CAIRO_ENABLE_HINTS)) { do_arc (cr, x, y, radius, start_angle, sweep_angle); return; } WORLDtoSCREEN (cr, x, y, &s_x, &s_y); s_diameter = SCREENabs (cr, 2 * radius); even_diameter = ((s_diameter % 2) == 0); s_radius = (double) s_diameter / 2.; /* Switch off radius hinting for small radii. If we don't, then we get * a very abrupt transition once the arc reaches a single pixel size. */ if (s_radius <= 1.) do_radius_hint = FALSE; /* Hint the center of the arc based on where a line * of thickness center_width (world) would drawn */ s_center_width = screen_width (cr, center_width); even_center_width = (center_width == -1 || (s_center_width % 2) == 0); center_offset = even_center_width ? 0. : 0.5; /* Hint the radius to land its extermity on the pixel grid */ s_line_width = screen_width (cr, line_width); even_line_width = (line_width == -1 || (s_line_width % 2) == 0); if (do_radius_hint) s_radius += ((even_center_width == even_line_width) == even_diameter) ? 0. : 0.5; s_x += center_offset; s_y += center_offset; cairo_device_to_user (cr, &s_x, &s_y); cairo_device_to_user_distance (cr, &s_radius, &dummy); do_arc (cr, s_x, s_y, s_radius, start_angle, sweep_angle); }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void o_net_invalidate_rubber (GSCHEM_TOPLEVEL *w_current) { TOPLEVEL *toplevel = w_current->toplevel; int size = 0, magnetic_halfsize; int bloat; int magnetic_x, magnetic_y; int first_x, first_y, third_x, third_y, second_x, second_y; int x1, y1, x2, y2; WORLDtoSCREEN (w_current, w_current->magnetic_wx, w_current->magnetic_wy, &magnetic_x, &magnetic_y); WORLDtoSCREEN (w_current, w_current->first_wx, w_current->first_wy, &first_x, &first_y); WORLDtoSCREEN (w_current, w_current->third_wx, w_current->third_wy, &third_x, &third_y); WORLDtoSCREEN (w_current, w_current->second_wx, w_current->second_wy, &second_x, &second_y); if (toplevel->net_style == THICK) { size = SCREENabs (w_current, NET_WIDTH); } size = max (size, 0); bloat = size / 2; if (w_current->magneticnet_mode) { if (w_current->magnetic_wx != -1 && w_current->magnetic_wy != -1) { magnetic_halfsize = max (4 * size, MAGNETIC_HALFSIZE); o_invalidate_rect (w_current, magnetic_x - magnetic_halfsize, magnetic_y - magnetic_halfsize, magnetic_x + magnetic_halfsize, magnetic_y + magnetic_halfsize); } } x1 = min (first_x, second_x) - bloat; x2 = max (first_x, second_x) + bloat; y1 = min (first_y, second_y) - bloat; y2 = max (first_y, second_y) + bloat; o_invalidate_rect (w_current, x1, y1, x2, y2); x1 = min (second_x, third_x) - bloat; x2 = max (second_x, third_x) + bloat; y1 = min (second_y, third_y) - bloat; y2 = max (second_y, third_y) + bloat; o_invalidate_rect (w_current, x1, y1, x2, y2); }
void gschem_cairo_center_arc (GSCHEM_TOPLEVEL *w_current, int center_width, int line_width, int x, int y, int radius, int start_angle, int end_angle) { int s_center_width, s_line_width; int s_x, s_y, s_diameter; int even_center_width; int even_line_width; int even_diameter; double center_offset; double s_radius; int do_radius_hint = TRUE; WORLDtoSCREEN (w_current, x, y, &s_x, &s_y); s_diameter = SCREENabs (w_current, 2 * radius); even_diameter = ((s_diameter % 2) == 0); s_radius = (double) s_diameter / 2.; /* Switch off radius hinting for small radii. If we don't, then we get * a very abrupt transition once the arc reaches a single pixel size. */ if (s_radius <= 1.) do_radius_hint = FALSE; /* Hint the center of the arc based on where a line * of thickness center_width (world) would drawn */ s_center_width = screen_width (w_current, center_width); even_center_width = (center_width == -1 || (s_center_width % 2) == 0); center_offset = even_center_width ? 0. : 0.5; /* Hint the radius to land its extermity on the pixel grid */ s_line_width = screen_width (w_current, line_width); even_line_width = (line_width == -1 || (s_line_width % 2) == 0); if (do_radius_hint) s_radius += ((even_center_width == even_line_width) == even_diameter) ? 0. : 0.5; do_arc (w_current->cr, (double) s_x + center_offset, (double) s_y + center_offset, (double) s_radius, start_angle, end_angle); }
/*! \todo Finish function documentation!!! * \brief * \par Function Description */ void o_pin_invalidate_rubber (GSCHEM_TOPLEVEL *w_current) { TOPLEVEL *toplevel = w_current->toplevel; int x1, y1, x2, y2; int min_x, min_y, max_x, max_y; int bloat = 0; WORLDtoSCREEN (w_current, w_current->first_wx, w_current->first_wy, &x1, &y1); WORLDtoSCREEN (w_current, w_current->second_wx, w_current->second_wy, &x2, &y2); /* Pins are always first created as net pins, use net pin width */ if (toplevel->net_style == THICK ) { bloat = SCREENabs (w_current, PIN_WIDTH_NET) / 2; } min_x = min (x1, x2) - bloat; max_x = max (x1, x2) + bloat; min_y = min (y1, y2) - bloat; max_y = max (y1, y2) + bloat; o_invalidate_rect (w_current, min_x, min_y, max_x, max_y); }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * * \todo Only descends into the first source schematic * */ int o_edit_find_text (GSCHEM_TOPLEVEL *w_current, const GList *o_list, char *stext, int descend, int skip) { TOPLEVEL *toplevel = w_current->toplevel; char *attrib = NULL; int count = 0; PAGE *parent = NULL; char *current_filename = NULL; int page_control = 0; int pcount = 0; int rv; int x1, y1, x2, y2; int text_screen_height; const GList *iter; OBJECT *o_current; skiplast = skip; iter = o_list; while (iter != NULL) { o_current = (OBJECT *)iter->data; if (descend) { if (o_current->type == OBJ_COMPLEX) { parent = toplevel->page_current; attrib = o_attrib_search_attached_attribs_by_name (o_current, "source", count); /* if above is null, then look inside symbol */ if (attrib == NULL) { attrib = o_attrib_search_inherited_attribs_by_name (o_current, "source", count); /* looking_inside = TRUE; */ } if (attrib) { pcount = 0; current_filename = u_basic_breakup_string(attrib, ',', pcount); if (current_filename != NULL) { PAGE *child_page = s_hierarchy_down_schematic_single(toplevel, current_filename, parent, page_control, HIERARCHY_NORMAL_LOAD); if (child_page != NULL) { page_control = child_page->page_control; rv = o_edit_find_text (w_current, s_page_objects (child_page), stext, descend, skiplast); if (!rv) { s_page_goto( toplevel, child_page ); return 0; } } } } } } if (o_current->type == OBJ_TEXT) { const gchar *str = o_text_get_string (toplevel, o_current); /* replaced strcmp with strstr to simplify the search */ if (strstr (str,stext)) { if (!skiplast) { a_zoom(w_current, ZOOM_FULL, DONTCARE, A_PAN_DONT_REDRAW); world_get_single_object_bounds (toplevel, o_current, &x1, &y1, &x2, &y2); text_screen_height = SCREENabs (w_current, y2 - y1); /* this code will zoom/pan till the text screen height is about */ /* 50 pixels high, perhaps a future enhancement will be to make */ /* this number configurable */ while (text_screen_height < 50) { a_zoom(w_current, ZOOM_IN, DONTCARE, A_PAN_DONT_REDRAW); text_screen_height = SCREENabs (w_current, y2 - y1); } a_pan_general(w_current, o_current->text->x, o_current->text->y, 1, 0); /* Make sure the titlebar and scrollbars are up-to-date */ x_window_set_current_page(w_current, w_current->toplevel->page_current ); last_o = o_current; break; } if (last_o == o_current) { skiplast = 0; } } /* if (strstr(o_current->text->string,stext)) */ } /* if (o_current->type == OBJ_TEXT) */ iter = g_list_next (iter); if (iter == NULL) { return 1; } } return (iter == NULL); }
void eda_cairo_center_box (cairo_t *cr, int flags, double center_width, double line_width, double x, double y, double half_width, double half_height) { int s_center_width, s_line_width; int s_width, s_height; double s_half_width, s_half_height; double s_x, s_y; double even_center_width; double even_line_width; double even_width, even_height; double x1, y1, x2, y2; double center_offset; int do_width_hint = TRUE; int do_height_hint = TRUE; if (!(flags & EDA_CAIRO_ENABLE_HINTS)) { cairo_rectangle (cr, (x - half_width), (y - half_height), 2*half_width, 2*half_height); return; } WORLDtoSCREEN (cr, x, y, &s_x, &s_y); s_width = SCREENabs (cr, 2 * half_width); s_height = SCREENabs (cr, 2 * half_height); even_width = (s_width % 2 == 0); even_height = (s_width % 2 == 0); s_half_width = (double) s_width / 2.; s_half_height = (double) s_height / 2.; #if 0 /* Not as nice an effect as with arcs */ /* Switch off radius hinting for small radii. If we don't, then we get * a very abrupt transition once the box reaches a single pixel size. */ if (s_half_width <= 1.) do_width_hint = FALSE; if (s_half_height <= 1.) do_height_hint = FALSE; #endif /* Hint the center of the box based on where a line * of thickness center_width (world) would drawn */ s_center_width = screen_width (cr, center_width); even_center_width = (center_width == -1 || (s_center_width % 2) == 0); center_offset = even_center_width ? 0. : 0.5; /* Hint the half-widths to land the stroke on the pixel grid */ s_line_width = screen_width (cr, line_width); even_line_width = (line_width == -1 || (s_line_width % 2) == 0); if (do_width_hint) s_half_width += ((even_center_width == even_line_width) == even_width ) ? 0. : 0.5; if (do_height_hint) s_half_height += ((even_center_width == even_line_width) == even_height) ? 0. : 0.5; x1 = (double) s_x + center_offset - s_half_width; y1 = (double) s_y + center_offset - s_half_height; x2 = (double) s_x + center_offset + s_half_width; y2 = (double) s_y + center_offset + s_half_height; /* Allow filled boxes (inferred from line_width == -1) * to touch an extra pixel, so the filled span is inclusive */ if (line_width == -1) { x2 += 1; y2 += 1; } cairo_device_to_user (cr, &x1, &y1); cairo_device_to_user (cr, &x2, &y2); cairo_move_to (cr, x2, y2); cairo_line_to (cr, x1, y2); cairo_line_to (cr, x1, y1); cairo_line_to (cr, x2, y1); cairo_close_path (cr); }
void gschem_cairo_stroke (GSCHEM_TOPLEVEL *w_current, int line_type, int line_end, int wwidth, int wlength, int wspace) { double offset; double dashes[4]; cairo_line_cap_t cap; cairo_line_cap_t round_cap_if_legible; int num_dashes; int width, length, space; width = screen_width (w_current, wwidth); length = SCREENabs (w_current, wlength); space = SCREENabs (w_current, wspace); offset = ((width % 2) == 0) ? 0 : 0.5; cairo_set_line_width (w_current->cr, width); cairo_set_line_join (w_current->cr, CAIRO_LINE_JOIN_MITER); round_cap_if_legible = (width <= 1) ? CAIRO_LINE_CAP_SQUARE : CAIRO_LINE_CAP_ROUND; switch (line_end) { case END_NONE: cap = CAIRO_LINE_CAP_BUTT; break; case END_SQUARE: cap = CAIRO_LINE_CAP_SQUARE; break; case END_ROUND: cap = round_cap_if_legible; break; default: fprintf(stderr, _("Unknown end for line (%d)\n"), line_end); cap = CAIRO_LINE_CAP_BUTT; break; } switch (line_type) { default: fprintf(stderr, _("Unknown type for stroke (%d) !\n"), line_type); /* Fall through */ case TYPE_SOLID: num_dashes = 0; cairo_set_dash (w_current->cr, dashes, num_dashes, 0.); cairo_set_line_cap (w_current->cr, cap); cairo_stroke (w_current->cr); break; case TYPE_DOTTED: dashes[0] = 0; /* DOT */ dashes[1] = space; num_dashes = 2; cairo_set_dash (w_current->cr, dashes, num_dashes, offset); cairo_set_line_cap (w_current->cr, round_cap_if_legible); cairo_stroke (w_current->cr); break; case TYPE_DASHED: dashes[0] = length; /* DASH */ dashes[1] = space; num_dashes = 2; cairo_set_dash (w_current->cr, dashes, num_dashes, 0.); cairo_set_line_cap (w_current->cr, CAIRO_LINE_CAP_BUTT); cairo_stroke (w_current->cr); break; case TYPE_CENTER: dashes[0] = length; /* DASH */ dashes[1] = 2 * space; num_dashes = 2; cairo_set_dash (w_current->cr, dashes, num_dashes, 0.); cairo_set_line_cap (w_current->cr, CAIRO_LINE_CAP_BUTT); cairo_stroke_preserve (w_current->cr); dashes[0] = 0; /* DOT */ dashes[1] = 2 * space + length; num_dashes = 2; cairo_set_dash (w_current->cr, dashes, num_dashes, -length - space + offset); cairo_set_line_cap (w_current->cr, round_cap_if_legible); cairo_stroke (w_current->cr); break; case TYPE_PHANTOM: dashes[0] = length; /* DASH */ dashes[1] = 3 * space; num_dashes = 2; cairo_set_dash (w_current->cr, dashes, num_dashes, 0.); cairo_set_line_cap (w_current->cr, CAIRO_LINE_CAP_BUTT); cairo_stroke_preserve (w_current->cr); dashes[0] = 0; /* DOT */ dashes[1] = space; dashes[2] = 0; /* DOT */ dashes[3] = 2 * space + length; num_dashes = 4; cairo_set_dash (w_current->cr, dashes, num_dashes, -length - space + offset); cairo_set_line_cap (w_current->cr, round_cap_if_legible); cairo_stroke (w_current->cr); break; } cairo_set_dash (w_current->cr, NULL, 0, 0.); }
void gschem_cairo_center_box (GSCHEM_TOPLEVEL *w_current, int center_width, int line_width, int x, int y, int half_width, int half_height) { int s_center_width, s_line_width; int s_width, s_height; double s_half_width, s_half_height; int s_x, s_y; int even_center_width; int even_line_width; int even_width, even_height; double x1, y1, x2, y2; double center_offset; int do_width_hint = TRUE; int do_height_hint = TRUE; WORLDtoSCREEN (w_current, x, y, &s_x, &s_y); s_width = SCREENabs (w_current, 2 * half_width); s_height = SCREENabs (w_current, 2 * half_height); even_width = (s_width % 2 == 0); even_height = (s_width % 2 == 0); s_half_width = (double) s_width / 2.; s_half_height = (double) s_height / 2.; #if 0 /* Not as nice an effect as with arcs */ /* Switch off radius hinting for small radii. If we don't, then we get * a very abrupt transition once the box reaches a single pixel size. */ if (s_half_width <= 1.) do_width_hint = FALSE; if (s_half_height <= 1.) do_height_hint = FALSE; #endif /* Hint the center of the box based on where a line * of thickness center_width (world) would drawn */ s_center_width = screen_width (w_current, center_width); even_center_width = (center_width == -1 || (s_center_width % 2) == 0); center_offset = even_center_width ? 0. : 0.5; /* Hint the half-widths to land the stroke on the pixel grid */ s_line_width = screen_width (w_current, line_width); even_line_width = (line_width == -1 || (s_line_width % 2) == 0); if (do_width_hint) s_half_width += ((even_center_width == even_line_width) == even_width ) ? 0. : 0.5; if (do_height_hint) s_half_height += ((even_center_width == even_line_width) == even_height) ? 0. : 0.5; x1 = (double) s_x + center_offset - s_half_width; y1 = (double) s_y + center_offset - s_half_height; x2 = (double) s_x + center_offset + s_half_width; y2 = (double) s_y + center_offset + s_half_height; /* Allow filled boxes (inferred from line_width == -1) * to touch an extra pixel, so the filled span is inclusive */ if (line_width == -1) { x2 += 1; y2 += 1; } cairo_move_to (w_current->cr, x2, y2); cairo_line_to (w_current->cr, x1, y2); cairo_line_to (w_current->cr, x1, y1); cairo_line_to (w_current->cr, x2, y1); cairo_close_path (w_current->cr); }