Beispiel #1
0
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;
}
Beispiel #2
0
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);
}
Beispiel #3
0
/*! \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);
}
Beispiel #4
0
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);
}
Beispiel #5
0
/*! \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);
}
Beispiel #6
0
/*! \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);
}
Beispiel #7
0
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);
}
Beispiel #8
0
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.);
}
Beispiel #9
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);
}