Exemplo n.º 1
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);
}
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 (Coord X, Coord Y)
{
    Coord nearest_grid_x, nearest_grid_y;
    void *ptr1, *ptr2, *ptr3;
    struct snap_data snap_data;
    int ans;

    Crosshair.X = CLAMP (X, Crosshair.MinX, Crosshair.MaxX);
    Crosshair.Y = CLAMP (Y, Crosshair.MinY, Crosshair.MaxY);

    if (PCB->RatDraw)
    {
        nearest_grid_x = -MIL_TO_COORD (6);
        nearest_grid_y = -MIL_TO_COORD (6);
    }
    else
    {
        nearest_grid_x = GridFit (Crosshair.X, PCB->Grid, PCB->GridOffsetX);
        nearest_grid_y = GridFit (Crosshair.Y, PCB->Grid, PCB->GridOffsetY);

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

    }

    snap_data.crosshair = &Crosshair;
    snap_data.nearest_sq_dist =
        crosshair_sq_dist (&Crosshair, nearest_grid_x, nearest_grid_y);
    snap_data.nearest_is_grid = true;
    snap_data.x = nearest_grid_x;
    snap_data.y = nearest_grid_y;

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

    if (ans & ELEMENT_TYPE)
    {
        ElementType *el = (ElementType *) ptr1;
        check_snap_object (&snap_data, el->MarkX, el->MarkY, false);
    }

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

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

    if (ans != NO_TYPE &&
            ( 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 != NO_TYPE)
    {
        PadType *pad = (PadType *)ptr2;
        check_snap_object (&snap_data, (pad->Point1.X + pad->Point2.X) / 2,
                           (pad->Point1.Y + pad->Point2.Y) / 2,
                           true);
    }

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

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

    if (ans != NO_TYPE)
    {
        PinType *pin = (PinType *)ptr2;
        check_snap_object (&snap_data, pin->X, pin->Y, true);
    }

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

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

    if (ans != NO_TYPE)
    {
        PinType *pin = (PinType *)ptr2;
        check_snap_object (&snap_data, pin->X, pin->Y, true);
    }

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

    if (ans != NO_TYPE)
    {
        PointType *pnt = (PointType *)ptr3;
        check_snap_object (&snap_data, pnt->X, pnt->Y, true);
    }

    check_snap_offgrid_line (&snap_data, nearest_grid_x, nearest_grid_y);

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

    if (ans != NO_TYPE)
    {
        PointType *pnt = (PointType *)ptr3;
        check_snap_object (&snap_data, pnt->X, pnt->Y, true);
    }

    if (snap_data.x >= 0 && snap_data.y >= 0)
    {
        Crosshair.X = snap_data.x;
        Crosshair.Y = snap_data.y;
    }

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