예제 #1
0
void
eda_cairo_arc (cairo_t *cr, int flags,
               double width, double x, double y,
               double radius, double start_angle, double sweep_angle)
{
  int s_width;
  double x1, y1, x2, y2;
  double s_x, s_y, s_radius;
  double offset, dummy = 0;

  if (!(flags & EDA_CAIRO_ENABLE_HINTS)) {
    do_arc (cr, x, y, radius, start_angle, sweep_angle);
    return;
  }

  WORLDtoSCREEN (cr, x - radius, y + radius, &x1, &y1);
  WORLDtoSCREEN (cr, x + radius, y - radius, &x2, &y2);
  s_width = screen_width (cr, width);
  offset = ((s_width % 2) == 0) ? 0 : 0.5;

  s_x = (double)(x1 + x2) / 2.;
  s_y = (double)(y1 + y2) / 2.;
  s_radius = (double)(y2 - y1) / 2.;

  cairo_device_to_user (cr, &s_x, &s_y);
  cairo_device_to_user_distance (cr, &offset, &dummy);
  cairo_device_to_user_distance (cr, &s_radius, &dummy);

  do_arc (cr, s_x + offset, s_y + offset,
          s_radius, start_angle, sweep_angle);
}
예제 #2
0
void
eda_cairo_box (cairo_t *cr, int flags, double line_width,
               double x1, double y1, double x2, double y2)
{
  int s_line_width;
  double s_x1, s_y1, s_x2, s_y2;
  double offset;

  if (!(flags & EDA_CAIRO_ENABLE_HINTS)) {
    cairo_rectangle (cr, x1, y1, (x2 - x1), (y2 - y1));
    return;
  }

  WORLDtoSCREEN (cr, x1, y1, &s_x1, &s_y1);
  WORLDtoSCREEN (cr, x2, y2, &s_x2, &s_y2);
  s_line_width = screen_width (cr, line_width);
  offset = (line_width == -1 || (s_line_width % 2) == 0) ? 0 : 0.5;

  /* Allow filled boxes (inferred from line_width == -1)
   * to touch an extra pixel, so the filled span is inclusive */
  if (line_width == -1) {
    if (s_x1 > s_x2) s_x1 += 1; else s_x2 += 1;
    if (s_y1 > s_y2) s_y1 += 1; else s_y2 += 1;
  }

  s_x1 += offset; s_y1 += offset;
  s_x2 += offset; s_y2 += offset;
  cairo_device_to_user (cr, &s_x1, &s_y1);
  cairo_device_to_user (cr, &s_x2, &s_y2);
  cairo_move_to (cr, s_x2, s_y2);
  cairo_line_to (cr, s_x1, s_y2);
  cairo_line_to (cr, s_x1, s_y1);
  cairo_line_to (cr, s_x2, s_y1);
  cairo_close_path (cr);
}
예제 #3
0
void gschem_cairo_arc (GSCHEM_TOPLEVEL *w_current,
                       int width, int x, int y,
                       int radius, int start_angle, int end_angle)
{
  int s_width;
  int x1, y1, x2, y2;
  double s_x, s_y, s_radius;
  double offset;

  WORLDtoSCREEN (w_current, x - radius, y + radius, &x1, &y1);
  WORLDtoSCREEN (w_current, x + radius, y - radius, &x2, &y2);
  s_width = screen_width (w_current, width);
  offset = ((s_width % 2) == 0) ? 0 : 0.5;

  s_x = (double)(x1 + x2) / 2.;
  s_y = (double)(y1 + y2) / 2.;
  s_radius = (double)(y2 - y1) / 2.;

  cairo_save (w_current->cr);
  cairo_translate (w_current->cr, s_x + offset, s_y + offset);

  /* Adjust for non-uniform X/Y scale factor. Note that the + 1
     allows for the case where x2 == x1 or y2 == y1 */
  cairo_scale (w_current->cr, (double)(x2 - x1 + 1) /
                              (double)(y2 - y1 + 1), 1.);

  do_arc (w_current->cr, 0., 0., (double) s_radius, start_angle, end_angle);

  cairo_restore (w_current->cr);
}
예제 #4
0
void gschem_cairo_box (GSCHEM_TOPLEVEL *w_current, int line_width,
                       int x1, int y1, int x2, int y2)
{
  int s_line_width;
  int s_x1, s_y1, s_x2, s_y2;
  double offset;

  WORLDtoSCREEN (w_current, x1, y1, &s_x1, &s_y1);
  WORLDtoSCREEN (w_current, x2, y2, &s_x2, &s_y2);
  s_line_width = screen_width (w_current, line_width);
  offset = (line_width == -1 || (s_line_width % 2) == 0) ? 0 : 0.5;

  /* Allow filled boxes (inferred from line_width == -1)
   * to touch an extra pixel, so the filled span is inclusive */
  if (line_width == -1) {
    if (x1 > x2) x1 += 1; else x2 += 1;
    if (y1 > y2) y1 += 1; else y2 += 1;
  }

  cairo_move_to (w_current->cr, s_x2 + offset, s_y2 + offset);
  cairo_line_to (w_current->cr, s_x1 + offset, s_y2 + offset);
  cairo_line_to (w_current->cr, s_x1 + offset, s_y1 + offset);
  cairo_line_to (w_current->cr, s_x2 + offset, s_y1 + offset);
  cairo_close_path (w_current->cr);
}
예제 #5
0
/*! \todo Finish function documentation
 *  \brief
 *  \par Function Description
 */
void o_line_invalidate_rubber (GSCHEM_TOPLEVEL *w_current)
{
  int x1, y1, x2, y2;

  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);

  o_invalidate_rect (w_current, x1, y1, x2, y2);
}
예제 #6
0
void gschem_cairo_line (GSCHEM_TOPLEVEL *w_current, int line_end,
                        int w_line_width,
                        int w_x1, int w_y1, int w_x2, int w_y2)
{
  int x1, y1, x2, y2, line_width;
  double offset;
  double xoffset = 0;
  double yoffset = 0;
  int horizontal = 0;
  int vertical = 0;

  WORLDtoSCREEN (w_current, w_x1, w_y1, &x1, &y1);
  WORLDtoSCREEN (w_current, w_x2, w_y2, &x2, &y2);
  line_width = screen_width (w_current, w_line_width);
  offset = ((line_width % 2) == 0) ? 0 : 0.5;

  if (y1 == y2) horizontal = 1;
  if (x1 == x2) vertical = 1;

  /* Hint so the length of the line runs along a pixel boundary */

  if (horizontal)
    yoffset = offset;
  else if (vertical)
    xoffset = offset;
  else
    xoffset = yoffset = offset;

  /* Now hint the ends of the lines */

  switch (line_end) {
    case END_NONE:
      /* Line terminates at the passed coordinate */

      /* Add an extra pixel to give an inclusive span */
      if (horizontal) {
        if (x1 > x2) x1 += 1; else x2 += 1;
      } else if (vertical) {
        if (y1 > y2) y1 += 1; else y2 += 1;
      }
      break;

    case END_SQUARE:
    case END_ROUND:
      /* Line terminates half a width away from the passed coordinate */
      if (horizontal) {
        xoffset = offset;
      } else if (vertical) {
        yoffset = offset;
      }
      break;
  }

  cairo_move_to (w_current->cr, x1 + xoffset, y1 + yoffset);
  cairo_line_to (w_current->cr, x2 + xoffset, y2 + yoffset);
}
예제 #7
0
/*! \brief Invalidate bounding box or outline for OBJECT placement
 *
 *  \par Function Description
 *  This function invalidates the bounding box where objects would be
 *  drawn by o_place_draw_rubber()
 *
 * The function applies manhatten mode constraints to the coordinates
 * before drawing if the CONTROL key is recording as being pressed in
 * the w_current structure.
 *
 * The "drawing" parameter is used to indicate if this drawing should
 * immediately use the selected feedback mode and positioning constraints.
 *
 * With drawing=TRUE, the selected conditions are used immediately,
 * otherwise the conditions from the last drawing operation are used,
 * saving the new state for next time.
 *
 * This function should be called with drawing=TRUE when starting a
 * rubberbanding operation and when otherwise refreshing the rubberbanded
 * outline (e.g. after a screen redraw). For any undraw operation, should
 * be called with drawing=FALSE, ensuring that the undraw XOR matches the
 * mode and constraints of the corresponding "draw" operation.
 *
 * If any mode / constraint changes are made between a undraw, redraw XOR
 * pair, the latter (draw) operation must be called with drawing=TRUE. If
 * no mode / constraint changes were made between the pair, it is not
 * harmful to call the draw operation with "drawing=FALSE".
 *
 *  \param [in] w_current   GSCHEM_TOPLEVEL which we're drawing for.
 *  \param [in] drawing     Set to FALSE for undraw operations to ensure
 *                            matching conditions to a previous draw operation.
 */
void o_place_invalidate_rubber (GSCHEM_TOPLEVEL *w_current, int drawing)
{
  TOPLEVEL *toplevel = w_current->toplevel;
  int diff_x, diff_y;
  int left, top, bottom, right;
  int s_left, s_top, s_bottom, s_right;

  g_return_if_fail (toplevel->page_current->place_list != NULL);

  /* If drawing is true, then don't worry about the previous drawing
   * method and movement constraints, use with the current settings */
  if (drawing) {
    /* Ensure we set this to flag there is "something" supposed to be
     * drawn when the invaliate call below causes an expose event. */
    w_current->last_drawb_mode = w_current->actionfeedback_mode;
    w_current->drawbounding_action_mode = (w_current->CONTROLKEY)
                                            ? CONSTRAINED : FREE;
  }

  /* Calculate delta of X-Y positions from buffer's origin */
  diff_x = w_current->second_wx - w_current->first_wx;
  diff_y = w_current->second_wy - w_current->first_wy;

  /* Adjust the coordinates according to the movement constraints */

  /* Need to update the w_current->{first,second}_w{x,y} coords even
   * though we're only invalidating because the move rubberband code
   * (which may execute right after this function) expects these
   * coordinates to be correct.
   */
  if (w_current->drawbounding_action_mode == CONSTRAINED) {
    if (abs (diff_x) >= abs (diff_y)) {
      w_current->second_wy = w_current->first_wy;
      diff_y = 0;
    } else {
      w_current->second_wx = w_current->first_wx;
      diff_x = 0;
    }
  }

  /* Find the bounds of the drawing to be done */
  world_get_object_glist_bounds (toplevel, toplevel->page_current->place_list,
                                 &left, &top, &right, &bottom);
  WORLDtoSCREEN (w_current, left + diff_x, top + diff_y, &s_left, &s_top);
  WORLDtoSCREEN (w_current, right + diff_x, bottom + diff_y, &s_right, &s_bottom);

  o_invalidate_rect (w_current, s_left, s_top, s_right, s_bottom);
}
예제 #8
0
파일: o_net.c 프로젝트: jgriessen/geda-gaf
/*! \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);
}
예제 #9
0
파일: o_pin.c 프로젝트: fvila/geda-gaf
/*! \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);
}
예제 #10
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);
}
예제 #11
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);
}
예제 #12
0
void
eda_cairo_line (cairo_t *cr, int flags, int line_end,
                double w_line_width,
                double w_x1, double w_y1, double w_x2, double w_y2)
{
  double x1, y1, x2, y2;
  int line_width;
  double offset;
  double xoffset = 0;
  double yoffset = 0;
  double horizontal = 0;
  double vertical = 0;

  if (!(flags & EDA_CAIRO_ENABLE_HINTS)) {
    cairo_move_to (cr, w_x1, w_y1);
    cairo_line_to (cr, w_x2, w_y2);
    return;
  }

  WORLDtoSCREEN (cr, w_x1, w_y1, &x1, &y1);
  WORLDtoSCREEN (cr, w_x2, w_y2, &x2, &y2);
  line_width = screen_width (cr, w_line_width);
  offset = ((line_width % 2) == 0) ? 0 : 0.5;

  if (y1 == y2) horizontal = 1;
  if (x1 == x2) vertical = 1;

  /* Hint so the length of the line runs along a pixel boundary */

  if (horizontal)
    yoffset = offset;
  else if (vertical)
    xoffset = offset;
  else
    xoffset = yoffset = offset;

  /* Now hint the ends of the lines */

  switch (line_end) {
    case END_NONE:
      /* Line terminates at the passed coordinate */

      /* Add an extra pixel to give an inclusive span */
      if (horizontal) {
        if (x1 > x2) x1 += 1; else x2 += 1;
      } else if (vertical) {
        if (y1 > y2) y1 += 1; else y2 += 1;
      }
      break;

    case END_SQUARE:
    case END_ROUND:
      /* Line terminates half a width away from the passed coordinate */
      if (horizontal) {
        xoffset = offset;
      } else if (vertical) {
        yoffset = offset;
      }
      break;
  }

  x1 += xoffset; y1 += yoffset;
  x2 += xoffset; y2 += yoffset;
  cairo_device_to_user (cr, &x1, &y1);
  cairo_device_to_user (cr, &x2, &y2);
  cairo_move_to (cr, x1, y1);
  cairo_line_to (cr, x2, y2);
}
예제 #13
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);
}
예제 #14
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);
}