Пример #1
0
/* ---------------------------------------------------------------------------
 * searches the cursor position for the type
 */
int
SearchScreenGridSlop (Coord X, Coord Y, int Type, void **Result1,
	      void **Result2, void **Result3)
{
  int ans;

  ans = SearchObjectByLocation (Type, Result1, Result2, Result3,
				X, Y, PCB->Grid / 2);
  return (ans);
}
Пример #2
0
/* ---------------------------------------------------------------------------
 * searches the cursor position for the type 
 */
int
SearchScreen (Coord X, Coord Y, int Type, void **Result1,
	      void **Result2, void **Result3)
{
  int ans;

  ans = SearchObjectByLocation (Type, Result1, Result2, Result3,
				X, Y, SLOP * pixel_slop);
  return (ans);
}
Пример #3
0
static char *
describe_location (Coord X, Coord Y)
{
  void *ptr1, *ptr2, *ptr3;
  int type;
  int Range = 0;
  char *elename = "";
  char *pinname;
  char *netname = NULL;
  char *description;

  /* check if there are any pins or pads at that position */

  type = SearchObjectByLocation (PIN_TYPE | PAD_TYPE,
                                 &ptr1, &ptr2, &ptr3, X, Y, Range);
  if (type == NO_TYPE)
    return NULL;

  /* don't mess with silk objects! */
  if (type & SILK_TYPE &&
      GetLayerNumber (PCB->Data, (LayerType *) ptr1) >= max_copper_layer)
    return NULL;

  if (type == PIN_TYPE || type == PAD_TYPE)
    elename = (char *)UNKNOWN (NAMEONPCB_NAME ((ElementType *) ptr1));

  pinname = ConnectionName (type, ptr1, ptr2);

  if (pinname == NULL)
    return NULL;

  /* Find netlist entry */
  MENU_LOOP (&PCB->NetlistLib);
  {
    if (!menu->Name)
    continue;

    ENTRY_LOOP (menu);
    {
      if (!entry->ListEntry)
        continue;

      if (strcmp (entry->ListEntry, pinname) == 0) {
        netname = g_strdup (menu->Name);
        /* For some reason, the netname has spaces in front of it, strip them */
        g_strstrip (netname);
        break;
      }
    }
    END_LOOP;

    if (netname != NULL)
      break;
  }
  END_LOOP;

  description = g_strdup_printf ("Element name: %s\n"
                                 "Pinname : %s\n"
                                 "Netname : %s",
                                 elename,
                                 (pinname != NULL) ? pinname : "--",
                                 (netname != NULL) ? netname : "--");

  g_free (netname);

  return description;
}
Пример #4
0
static void *
MoveLineToLayer (LayerType *Layer, LineType *Line)
{
  struct via_info info;
  BoxType sb;
  LineTypePtr newone;
  void *ptr1, *ptr2, *ptr3;

  if (TEST_FLAG (LOCKFLAG, Line))
    {
      Message (_("Sorry, the object is locked\n"));
      return NULL;
    }
  if (Dest == Layer && Layer->On)
    {
      DrawLine (Layer, Line);
      Draw ();
    }
  if (((long int) Dest == -1) || Dest == Layer)
    return (Line);

  AddObjectToMoveToLayerUndoList (LINE_TYPE, Layer, Line, Line);
  if (Layer->On)
    EraseLine (Line);
  RestoreToPolygon (PCB->Data, LINE_TYPE, Layer, Line);
  newone = (LineTypePtr)MoveLineToLayerLowLevel (Layer, Line, Dest);
  Line = NULL;
  ClearFromPolygon (PCB->Data, LINE_TYPE, Dest, newone);
  if (Dest->On)
    DrawLine (Dest, newone);
  Draw ();
  if (!PCB->ViaOn || MoreToCome ||
      GetLayerGroupNumberByPointer (Layer) ==
      GetLayerGroupNumberByPointer (Dest) ||
      TEST_SILK_LAYER(Layer) ||
      TEST_SILK_LAYER(Dest))
    return (newone);
  /* consider via at Point1 */
  sb.X1 = newone->Point1.X - newone->Thickness / 2;
  sb.X2 = newone->Point1.X + newone->Thickness / 2;
  sb.Y1 = newone->Point1.Y - newone->Thickness / 2;
  sb.Y2 = newone->Point1.Y + newone->Thickness / 2;
  if ((SearchObjectByLocation (PIN_TYPES, &ptr1, &ptr2, &ptr3,
			       newone->Point1.X, newone->Point1.Y,
			       Settings.ViaThickness / 2) == NO_TYPE))
    {
      info.X = newone->Point1.X;
      info.Y = newone->Point1.Y;
      if (setjmp (info.env) == 0)
	r_search (Layer->line_tree, &sb, NULL, moveline_callback, &info);
    }
  /* consider via at Point2 */
  sb.X1 = newone->Point2.X - newone->Thickness / 2;
  sb.X2 = newone->Point2.X + newone->Thickness / 2;
  sb.Y1 = newone->Point2.Y - newone->Thickness / 2;
  sb.Y2 = newone->Point2.Y + newone->Thickness / 2;
  if ((SearchObjectByLocation (PIN_TYPES, &ptr1, &ptr2, &ptr3,
			       newone->Point2.X, newone->Point2.Y,
			       Settings.ViaThickness / 2) == NO_TYPE))
    {
      info.X = newone->Point2.X;
      info.Y = newone->Point2.Y;
      if (setjmp (info.env) == 0)
	r_search (Layer->line_tree, &sb, NULL, moveline_callback, &info);
    }
  Draw ();
  return (newone);
}
Пример #5
0
Файл: rats.c Проект: rlutz/pcb
/*!
 * \brief This function is moved from the original netlist.c as
 * part of the gui code separation for the Gtk port.
 */
RatType *
AddNet (void)
{
  static int ratDrawn = 0;
  char name1[256], *name2;
  Cardinal group1, group2;
  char ratname[20];
  int found;
  void *ptr1, *ptr2, *ptr3;
  LibraryMenuType *menu;
  LibraryEntryType *entry;

  if (Crosshair.AttachedLine.Point1.X == Crosshair.AttachedLine.Point2.X
      && Crosshair.AttachedLine.Point1.Y == Crosshair.AttachedLine.Point2.Y)
    return (NULL);

  found = SearchObjectByLocation (PAD_TYPE | PIN_TYPE, &ptr1, &ptr2, &ptr3,
				  Crosshair.AttachedLine.Point1.X,
				  Crosshair.AttachedLine.Point1.Y, 5);
  if (found == NO_TYPE)
    {
      Message (_("No pad/pin under rat line\n"));
      return (NULL);
    }
  if (NAMEONPCB_NAME ((ElementType *) ptr1) == NULL
      || *NAMEONPCB_NAME ((ElementType *) ptr1) == 0)
    {
      Message (_("You must name the starting element first\n"));
      return (NULL);
    }

  /* will work for pins to since the FLAG is common */
  group1 = GetLayerGroupNumberBySide (
            TEST_FLAG (ONSOLDERFLAG, (PadType *) ptr2) ? BOTTOM_SIDE : TOP_SIDE);
  strcpy (name1, ConnectionName (found, ptr1, ptr2));
  found = SearchObjectByLocation (PAD_TYPE | PIN_TYPE, &ptr1, &ptr2, &ptr3,
				  Crosshair.AttachedLine.Point2.X,
				  Crosshair.AttachedLine.Point2.Y, 5);
  if (found == NO_TYPE)
    {
      Message (_("No pad/pin under rat line\n"));
      return (NULL);
    }
  if (NAMEONPCB_NAME ((ElementType *) ptr1) == NULL
      || *NAMEONPCB_NAME ((ElementType *) ptr1) == 0)
    {
      Message (_("You must name the ending element first\n"));
      return (NULL);
    }
  group2 = GetLayerGroupNumberBySide (
            TEST_FLAG (ONSOLDERFLAG, (PadType *) ptr2) ? BOTTOM_SIDE : TOP_SIDE);
  name2 = ConnectionName (found, ptr1, ptr2);

  menu = netnode_to_netname (name1);
  if (menu)
    {
      if (netnode_to_netname (name2))
	{
	  Message (_
		   ("Both connections already in netlist - cannot merge nets\n"));
	  return (NULL);
	}
      entry = GetLibraryEntryMemory (menu);
      entry->ListEntry = strdup (name2);
      netnode_to_netname (name2);
      goto ratIt;
    }
  /* ok, the first name did not belong to a net */
  menu = netnode_to_netname (name2);
  if (menu)
    {
      entry = GetLibraryEntryMemory (menu);
      entry->ListEntry = strdup (name1);
      netnode_to_netname (name1);
      goto ratIt;
    }

  /*
   * neither belong to a net, so create a new one.
   *
   * before creating a new rats here, we need to search
   * for a unique name.
   */
  sprintf (ratname, "  ratDrawn%i", ++ratDrawn);
  while (rat_used (ratname))
    {
      sprintf (ratname, "  ratDrawn%i", ++ratDrawn);
    }

  menu = GetLibraryMenuMemory (&PCB->NetlistLib);
  menu->Name = strdup (ratname);
  entry = GetLibraryEntryMemory (menu);
  entry->ListEntry = strdup (name1);
  entry = GetLibraryEntryMemory (menu);
  entry->ListEntry = strdup (name2);
  menu->flag = 1;

ratIt:
  NetlistChanged (0);
  return (CreateNewRat (PCB->Data, Crosshair.AttachedLine.Point1.X,
			Crosshair.AttachedLine.Point1.Y,
			Crosshair.AttachedLine.Point2.X,
			Crosshair.AttachedLine.Point2.Y,
			group1, group2, Settings.RatThickness, NoFlags ()));
}
Пример #6
0
/*!
 * \brief 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 = SearchObjectByLocation (ELEMENT_TYPE, &ptr1, &ptr2, &ptr3,
                                  Crosshair.X, Crosshair.Y, PCB->Grid / 2);

  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 = SearchObjectByLocation (PAD_TYPE, &ptr1, &ptr2, &ptr3,
                                  Crosshair.X, Crosshair.Y, PCB->Grid / 2);

  /* 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)))
    {
      PadType *pad = (PadType *) ptr2;
      LayerType *desired_layer;
      Cardinal desired_group;
      Cardinal bottom_group, top_group;
      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 top and bottom sides */
      top_group = GetLayerGroupNumberBySide (TOP_SIDE);
      bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE);
      desired_group = TEST_FLAG (ONSOLDERFLAG, pad) ? bottom_group : top_group;

      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 - pad->Point1.X) / 2,
                                     pad->Point1.Y + (pad->Point2.Y - pad->Point1.Y) / 2,
                         true);
    }

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

  /* 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 = SearchObjectByLocation (VIA_TYPE, &ptr1, &ptr2, &ptr3,
                                  Crosshair.X, Crosshair.Y, PCB->Grid / 2);

  /* 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 = SearchObjectByLocation (LINEPOINT_TYPE | ARCPOINT_TYPE,
                                  &ptr1, &ptr2, &ptr3,
                                  Crosshair.X, Crosshair.Y, PCB->Grid / 2);

  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 = SearchObjectByLocation (POLYGONPOINT_TYPE, &ptr1, &ptr2, &ptr3,
                                  Crosshair.X, Crosshair.Y, PCB->Grid / 2);

  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 = SearchObjectByLocation (LINEPOINT_TYPE | ARCPOINT_TYPE,
                                    &ptr1, &ptr2, &ptr3,
                                    Crosshair.X, Crosshair.Y, PCB->Grid / 2);
      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);
}
Пример #7
0
static void
check_snap_offgrid_line (struct snap_data *snap_data,
                         Coord nearest_grid_x,
                         Coord nearest_grid_y)
{
  void *ptr1, *ptr2, *ptr3;
  int ans;
  LineType *line;
  Coord try_x, try_y;
  double dx, dy;
  double dist;

  if (!TEST_FLAG (SNAPPINFLAG, PCB))
    return;

  /* Code to snap at some sensible point along a line */
  /* Pick the nearest grid-point in the x or y direction
   * to align with, then adjust until we hit the line
   */
  ans = SearchObjectByLocation (LINE_TYPE, &ptr1, &ptr2, &ptr3,
                                Crosshair.X, Crosshair.Y, PCB->Grid / 2);


  if (ans == NO_TYPE)
    return;

  line = (LineType *)ptr2;

  /* Allow snapping to off-grid lines when drawing new lines (on
   * the same layer), and when moving a line end-point
   * (but don't snap to the same line)
   */
  if ((Settings.Mode != LINE_MODE || CURRENT != ptr1) &&
      (Settings.Mode != MOVE_MODE ||
       Crosshair.AttachedObject.Ptr1 != ptr1 ||
       Crosshair.AttachedObject.Type != LINEPOINT_TYPE ||
       Crosshair.AttachedObject.Ptr2 == line))
    return;

  dx = line->Point2.X - line->Point1.X;
  dy = line->Point2.Y - line->Point1.Y;

  /* Try snapping along the X axis */
  if (dy != 0.)
    {
      /* Move in the X direction until we hit the line */
      try_x = (nearest_grid_y - line->Point1.Y) / dy * dx + line->Point1.X;
      try_y = nearest_grid_y;
      check_snap_object (snap_data, try_x, try_y, true);
    }

  /* Try snapping along the Y axis */
  if (dx != 0.)
    {
      try_x = nearest_grid_x;
      try_y = (nearest_grid_x - line->Point1.X) / dx * dy + line->Point1.Y;
      check_snap_object (snap_data, try_x, try_y, true);
    }

  if (dx != dy) /* If line not parallel with dX = dY direction.. */
    {
      /* Try snapping diagonally towards the line in the dX = dY direction */

      if (dy == 0)
        dist = line->Point1.Y - nearest_grid_y;
      else
        dist = ((line->Point1.X - nearest_grid_x) -
                (line->Point1.Y - nearest_grid_y) * dx / dy) / (1 - dx / dy);

      try_x = nearest_grid_x + dist;
      try_y = nearest_grid_y + dist;

      check_snap_object (snap_data, try_x, try_y, true);
    }

  if (dx != -dy) /* If line not parallel with dX = -dY direction.. */
    {
      /* Try snapping diagonally towards the line in the dX = -dY direction */

      if (dy == 0)
        dist = nearest_grid_y - line->Point1.Y;
      else
        dist = ((line->Point1.X - nearest_grid_x) -
                (line->Point1.Y - nearest_grid_y) * dx / dy) / (1 + dx / dy);

      try_x = nearest_grid_x + dist;
      try_y = nearest_grid_y - dist;

      check_snap_object (snap_data, try_x, try_y, true);
    }
}