Exemplo n.º 1
0
static void
ghid_draw_grid (void)
{
    static GdkPoint *points = 0;
    static int npoints = 0;
    int x1, y1, x2, y2, n, i;
    double x, y;

    if (!Settings.DrawGrid)
        return;
    if (Vz (PCB->Grid) < MIN_GRID_DISTANCE)
        return;
    if (!gport->grid_gc)
    {
        if (gdk_color_parse (Settings.GridColor, &gport->grid_color))
        {
            gport->grid_color.red ^= gport->bg_color.red;
            gport->grid_color.green ^= gport->bg_color.green;
            gport->grid_color.blue ^= gport->bg_color.blue;
            gdk_color_alloc (gport->colormap, &gport->grid_color);
        }
        gport->grid_gc = gdk_gc_new (gport->drawable);
        gdk_gc_set_function (gport->grid_gc, GDK_XOR);
        gdk_gc_set_foreground (gport->grid_gc, &gport->grid_color);
    }
    x1 = GRIDFIT_X (SIDE_X (gport->view_x0), PCB->Grid);
    y1 = GRIDFIT_Y (SIDE_Y (gport->view_y0), PCB->Grid);
    x2 = GRIDFIT_X (SIDE_X (gport->view_x0 + gport->view_width - 1), PCB->Grid);
    y2 =
        GRIDFIT_Y (SIDE_Y (gport->view_y0 + gport->view_height - 1), PCB->Grid);
    if (x1 > x2)
    {
        int tmp = x1;
        x1 = x2;
        x2 = tmp;
    }
    if (y1 > y2)
    {
        int tmp = y1;
        y1 = y2;
        y2 = tmp;
    }
    if (Vx (x1) < 0)
        x1 += PCB->Grid;
    if (Vy (y1) < 0)
        y1 += PCB->Grid;
    if (Vx (x2) >= gport->width)
        x2 -= PCB->Grid;
    if (Vy (y2) >= gport->height)
        y2 -= PCB->Grid;
    n = (int) ((x2 - x1) / PCB->Grid + 0.5) + 1;
    if (n > npoints)
    {
        npoints = n + 10;
        points = (GdkPoint *)realloc (points, npoints * sizeof (GdkPoint));
    }
    n = 0;
    for (x = x1; x <= x2; x += PCB->Grid)
    {
        points[n].x = Vx (x);
        n++;
    }
    if (n == 0)
        return;
    for (y = y1; y <= y2; y += PCB->Grid)
    {
        int vy = Vy (y);
        for (i = 0; i < n; i++)
            points[i].y = vy;
        gdk_draw_points (gport->drawable, gport->grid_gc, points, n);
    }
}
Exemplo n.º 2
0
/* ---------------------------------------------------------------------------
 * recalculates the passed coordinates to fit the current grid setting
 */
void
FitCrosshairIntoGrid (LocationType X, LocationType Y)
{
  LocationType x2, y2, x0, y0;
  void *ptr1, *ptr2, *ptr3;
  float nearest, sq_dist;
  int ans;

  x0 = 0;
  y0 = 0;
  x2 = PCB->MaxWidth;
  y2 = PCB->MaxHeight;
  Crosshair.X = MIN (Crosshair.MaxX, MAX (Crosshair.MinX, X));
  Crosshair.Y = MIN (Crosshair.MaxY, MAX (Crosshair.MinY, Y));

  if (PCB->RatDraw)
    {
      x0 = -600;
      y0 = -600;
    }
  else
    {
      /* check if new position is inside the output window
       * This might not be true after the window has been resized.
       * In this case we just set it to the center of the window or
       * with respect to the grid (if possible)
       */
      if (Crosshair.X < x0 || Crosshair.X > x2)
	{
	  if (x2 + 1 >= PCB->Grid)
	    /* there must be a point that matches the grid 
	     * so we just have to look for it with some integer
	     * calculations
	     */
	    x0 = GRIDFIT_X (PCB->Grid, PCB->Grid);
	  else
	    x0 = (x2) / 2;
	}
      else
	/* check if the new position matches the grid */
	x0 = GRIDFIT_X (Crosshair.X, PCB->Grid);

      /* do the same for the second coordinate */
      if (Crosshair.Y < y0 || Crosshair.Y > y2)
	{
	  if (y2 + 1 >= PCB->Grid)
	    y0 = GRIDFIT_Y (PCB->Grid, PCB->Grid);
	  else
	    y0 = (y2) / 2;
	}
      else
	y0 = GRIDFIT_Y (Crosshair.Y, PCB->Grid);

      if (Marked.status && TEST_FLAG (ORTHOMOVEFLAG, PCB))
	{
	  int dx = Crosshair.X - Marked.X;
	  int dy = Crosshair.Y - Marked.Y;
	  if (ABS (dx) > ABS (dy))
	    y0 = Marked.Y;
	  else
	    x0 = Marked.X;
	}

    }

  nearest = -1;

  if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB))
    ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                PAD_TYPE, &ptr1, &ptr2, &ptr3);
  else
    ans = NO_TYPE;

  /* Avoid self-snapping when moving */
  if (ans && Settings.Mode == MOVE_MODE &&
      Crosshair.AttachedObject.Type == ELEMENT_TYPE &&
      ptr1 == Crosshair.AttachedObject.Ptr1)
    ans = NO_TYPE;

  if (ans && (Settings.Mode == LINE_MODE ||
              (Settings.Mode == MOVE_MODE &&
               Crosshair.AttachedObject.Type == LINEPOINT_TYPE)))
    {
      PadTypePtr pad = (PadTypePtr) ptr2;
      LayerType *desired_layer;
      Cardinal desired_group;
      Cardinal SLayer, CLayer;
      int found_our_layer = false;

      desired_layer = CURRENT;
      if (Settings.Mode == MOVE_MODE &&
          Crosshair.AttachedObject.Type == LINEPOINT_TYPE)
        {
          desired_layer = (LayerType *)Crosshair.AttachedObject.Ptr1;
        }

      /* find layer groups of the component side and solder side */
      SLayer = GetLayerGroupNumberByNumber (solder_silk_layer);
      CLayer = GetLayerGroupNumberByNumber (component_silk_layer);
      desired_group = TEST_FLAG (ONSOLDERFLAG, pad) ? SLayer : CLayer;

      GROUP_LOOP (PCB->Data, desired_group);
      {
        if (layer == desired_layer)
          {
            found_our_layer = true;
            break;
          }
      }
      END_LOOP;

      if (found_our_layer == false)
        ans = NO_TYPE;
    }

  if (ans)
    {
      PadTypePtr pad = (PadTypePtr) ptr2;
      LocationType px, py;

      px = (pad->Point1.X + pad->Point2.X) / 2;
      py = (pad->Point1.Y + pad->Point2.Y) / 2;

      sq_dist = SQUARE (px - Crosshair.X) + SQUARE (py - Crosshair.Y);

      if (!gui->shift_is_pressed() ||
          SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist)
        {
          x0 = px;
          y0 = py;
          nearest = sq_dist;
        }
    }

  if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB))
    ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                PIN_TYPE, &ptr1, &ptr2, &ptr3);
  else
    ans = NO_TYPE;

  /* Avoid self-snapping when moving */
  if (ans && Settings.Mode == MOVE_MODE &&
      Crosshair.AttachedObject.Type == ELEMENT_TYPE &&
      ptr1 == Crosshair.AttachedObject.Ptr1)
    ans = NO_TYPE;

  if (ans)
    {
      PinTypePtr pin = (PinTypePtr) ptr2;
      sq_dist = SQUARE (pin->X - Crosshair.X) + SQUARE (pin->Y - Crosshair.Y);
      if ((nearest == -1 || sq_dist < nearest) &&
          (!gui->shift_is_pressed() ||
           SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist))
        {
          x0 = pin->X;
          y0 = pin->Y;
          nearest = sq_dist;
        }
    }

  if (TEST_FLAG (SNAPPINFLAG, PCB))
    ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                VIA_TYPE, &ptr1, &ptr2, &ptr3);
  else
    ans = NO_TYPE;

  /* Avoid snapping vias to any other vias */
  if (Settings.Mode == MOVE_MODE &&
      Crosshair.AttachedObject.Type == VIA_TYPE)
    {
        if (ans & PIN_TYPES)
          ans = NO_TYPE;
    }

  if (ans)
    {
      PinTypePtr pin = (PinTypePtr) ptr2;
      sq_dist = SQUARE (pin->X - Crosshair.X) + SQUARE (pin->Y - Crosshair.Y);
      if ((nearest == -1 || sq_dist < nearest) &&
          (!gui->shift_is_pressed() ||
           SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist))
        {
          x0 = pin->X;
          y0 = pin->Y;
          nearest = sq_dist;
        }
    }

  if (TEST_FLAG (SNAPPINFLAG, PCB))
    ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                LINEPOINT_TYPE, &ptr1, &ptr2, &ptr3);
  else
    ans = NO_TYPE;

  if (ans)
    {
      PointTypePtr pnt = (PointTypePtr) ptr3;
      sq_dist = SQUARE (pnt->X - Crosshair.X) + SQUARE (pnt->Y - Crosshair.Y);
      if ((nearest == -1 || sq_dist < nearest) &&
          (!gui->shift_is_pressed() ||
           SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist))
        {
          x0 = pnt->X;
          y0 = pnt->Y;
          nearest = sq_dist;
        }
    }

  if (TEST_FLAG (SNAPPINFLAG, PCB))
    ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                POLYGONPOINT_TYPE, &ptr1, &ptr2, &ptr3);
  else
    ans = NO_TYPE;

  if (ans)
    {
      PointTypePtr pnt = (PointTypePtr) ptr3;
      sq_dist = SQUARE (pnt->X - Crosshair.X) + SQUARE (pnt->Y - Crosshair.Y);
      if ((nearest == -1 || sq_dist < nearest) &&
          (!gui->shift_is_pressed() ||
           SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist))
        {
          x0 = pnt->X;
          y0 = pnt->Y;
          nearest = sq_dist;
        }
    }


  if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB))
    ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                ELEMENT_TYPE, &ptr1, &ptr2, &ptr3);
  else
    ans = NO_TYPE;

  if (ans & ELEMENT_TYPE)
    {
      ElementTypePtr el = (ElementTypePtr) ptr1;
      sq_dist = SQUARE (el->MarkX - Crosshair.X) + SQUARE (el->MarkY - Crosshair.Y);
      if ((nearest == -1 || sq_dist < nearest) &&
           SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist)
        {
          x0 = el->MarkX;
          y0 = el->MarkY;
          nearest = sq_dist;
        }
    }

  if (x0 >= 0 && y0 >= 0)
    {
      Crosshair.X = x0;
      Crosshair.Y = y0;
    }

  if (Settings.Mode == ARROW_MODE)
    {
      ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                  LINEPOINT_TYPE, &ptr1, &ptr2, &ptr3);
      if (ans == NO_TYPE)
        hid_action("PointCursor");
      else if (!TEST_FLAG(SELECTEDFLAG, (LineType *)ptr2))
        hid_actionl("PointCursor","True", NULL);
    }

  if (Settings.Mode == LINE_MODE
      && Crosshair.AttachedLine.State != STATE_FIRST
      && TEST_FLAG (AUTODRCFLAG, PCB))
    EnforceLineDRC ();

  gui->set_crosshair (Crosshair.X, Crosshair.Y, HID_SC_DO_NOTHING);
}
Exemplo n.º 3
0
/* ---------------------------------------------------------------------------
 * recalculates the passed coordinates to fit the current grid setting
 */
void
FitCrosshairIntoGrid (LocationType X, LocationType Y)
{
  LocationType x2, y2, x0, y0;
  void *ptr1, *ptr2, *ptr3;
  int ans;

  x0 = 0;
  y0 = 0;
  x2 = PCB->MaxWidth;
  y2 = PCB->MaxHeight;
  Crosshair.X = MIN (Crosshair.MaxX, MAX (Crosshair.MinX, X));
  Crosshair.Y = MIN (Crosshair.MaxY, MAX (Crosshair.MinY, Y));

  if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB))
    {
      ans =
	SearchScreen (Crosshair.X, Crosshair.Y,
		      PAD_TYPE | PIN_TYPE, &ptr1, &ptr2, &ptr3);
      if (ans == NO_TYPE && !PCB->RatDraw)
	ans =
	  SearchScreen (Crosshair.X, Crosshair.Y, VIA_TYPE | LINEPOINT_TYPE,
			&ptr1, &ptr2, &ptr3);
      if (ans == NO_TYPE && !PCB->RatDraw)
	ans =
	  SearchScreen (Crosshair.X, Crosshair.Y, ELEMENT_TYPE, &ptr1, &ptr2,
			&ptr3);
    }
  else
    ans = NO_TYPE;

  /* avoid self-snapping */
  if (Settings.Mode == MOVE_MODE)
    {
      switch (Crosshair.AttachedObject.Type)
	{
	case ELEMENT_TYPE:
	  if ((ans & (PAD_TYPE | PIN_TYPE)) &&
	      ptr1 == Crosshair.AttachedObject.Ptr1)
	    ans = NO_TYPE;
	  break;
	case VIA_TYPE:
	  /* just avoid snapping to any other vias */
	  if (ans & PIN_TYPES)
	    ans = NO_TYPE;
	  break;
	}
    }

  if (PCB->RatDraw)
    {
      x0 = -600;
      y0 = -600;
    }
  else
    {
      /* check if new position is inside the output window
       * This might not be true after the window has been resized.
       * In this case we just set it to the center of the window or
       * with respect to the grid (if possible)
       */
      if (Crosshair.X < x0 || Crosshair.X > x2)
	{
	  if (x2 + 1 >= PCB->Grid)
	    /* there must be a point that matches the grid 
	     * so we just have to look for it with some integer
	     * calculations
	     */
	    x0 = GRIDFIT_X (PCB->Grid, PCB->Grid);
	  else
	    x0 = (x2) / 2;
	}
      else
	/* check if the new position matches the grid */
	x0 = GRIDFIT_X (Crosshair.X, PCB->Grid);

      /* do the same for the second coordinate */
      if (Crosshair.Y < y0 || Crosshair.Y > y2)
	{
	  if (y2 + 1 >= PCB->Grid)
	    y0 = GRIDFIT_Y (PCB->Grid, PCB->Grid);
	  else
	    y0 = (y2) / 2;
	}
      else
	y0 = GRIDFIT_Y (Crosshair.Y, PCB->Grid);

      if (Marked.status && TEST_FLAG (ORTHOMOVEFLAG, PCB))
	{
	  int dx = Crosshair.X - Marked.X;
	  int dy = Crosshair.Y - Marked.Y;
	  if (ABS (dx) > ABS (dy))
	    y0 = Marked.Y;
	  else
	    x0 = Marked.X;
	}

    }
  if (ans & PAD_TYPE)
    {
      PadTypePtr pad = (PadTypePtr) ptr2;
      LocationType px, py;

      px = (pad->Point1.X + pad->Point2.X) / 2;
      py = (pad->Point1.Y + pad->Point2.Y) / 2;

      if (!gui->shift_is_pressed()
	  || (SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) >
	      SQUARE (px - Crosshair.X) + SQUARE (py - Crosshair.Y)))
	{
	  x0 = px;
	  y0 = py;
	}
    }

  else if (ans & (PIN_TYPE | VIA_TYPE))
    {
      PinTypePtr pin = (PinTypePtr) ptr2;
      if (!gui->shift_is_pressed()
	  || (SQUARE (x0 - Crosshair.X) +
	      SQUARE (y0 - Crosshair.Y) >
	      SQUARE (pin->X - Crosshair.X) + SQUARE (pin->Y - Crosshair.Y)))
	{
	  x0 = pin->X;
	  y0 = pin->Y;
	}
    }
  else if (ans & LINEPOINT_TYPE)
    {
      PointTypePtr pnt = (PointTypePtr) ptr3;
      if (((x0 - Crosshair.X) * (x0 - Crosshair.X) +
	   (y0 - Crosshair.Y) * (y0 - Crosshair.Y)) >
	  ((pnt->X - Crosshair.X) * (pnt->X - Crosshair.X) +
	   (pnt->Y - Crosshair.Y) * (pnt->Y - Crosshair.Y)))
	{
	  x0 = pnt->X;
	  y0 = pnt->Y;
	}
    }
  else if (ans & ELEMENT_TYPE)
    {
      ElementTypePtr el = (ElementTypePtr) ptr1;
      if (SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) >
	  SQUARE (el->MarkX - Crosshair.X) + SQUARE (el->MarkY - Crosshair.Y))
	{
	  x0 = el->MarkX;
	  y0 = el->MarkY;
	}
    }
  if (x0 >= 0 && y0 >= 0)
    {
      Crosshair.X = x0;
      Crosshair.Y = y0;
    }
  if (Settings.Mode == ARROW_MODE)
    {
	ans =
	  SearchScreen (Crosshair.X, Crosshair.Y, LINEPOINT_TYPE,
			&ptr1, &ptr2, &ptr3);
	if (ans == NO_TYPE)
	  hid_action("PointCursor");
	else if (!TEST_FLAG(SELECTEDFLAG, (LineType *)ptr2))
	  hid_actionl("PointCursor","True", NULL);
    }
  if (Settings.Mode == LINE_MODE
      && Crosshair.AttachedLine.State != STATE_FIRST
      && TEST_FLAG (AUTODRCFLAG, PCB))
    EnforceLineDRC ();

  gui->set_crosshair (Crosshair.X, Crosshair.Y, HID_SC_DO_NOTHING);
}