Ejemplo n.º 1
0
/*!
 * \brief Checks all visible lines which belong to the same group as the
 * passed arc.
 *
 * If one of the endpoints of the line lays inside the passed arc,
 * the scanned line is added to the 'rubberband' list
 */
static void
CheckArcPointForRubberbandConnection (LayerType *Layer,
				      ArcType *Arc,
				      PointType *ArcPoint,
				      bool Exact)
{
  Cardinal group;
  struct rubber_info info;
  Coord t = Arc->Thickness / 2;

  /* lookup layergroup and check all visible lines in this group */
  info.radius = Exact ? -1 : MAX(Arc->Thickness / 2, 1);
  info.box.X1 = ArcPoint->X - t;
  info.box.X2 = ArcPoint->X + t;
  info.box.Y1 = ArcPoint->Y - t;
  info.box.Y2 = ArcPoint->Y + t;
  info.line = NULL;
  info.X = ArcPoint->X;
  info.Y = ArcPoint->Y;
  group = GetLayerGroupNumberByPointer (Layer);
  GROUP_LOOP (PCB->Data, group);
  {
    /* check all visible lines of the group member */
    if (layer->On)
      {
	info.layer = layer;
	r_search (layer->line_tree, &info.box, NULL, rubber_callback, &info);
      }
  }
  END_LOOP;
}
Ejemplo n.º 2
0
/*!
 * \brief Checks all visible lines which belong to the same layergroup
 * as the passed pad.
 *
 * If one of the endpoints of the line lays inside the pad, the line is
 * added to the 'rubberband' list.
 */
static void
CheckPadForRubberbandConnection (PadType *Pad)
{
  Coord half = Pad->Thickness / 2;
  Cardinal group;
  struct rubber_info info;

  info.box.X1 = MIN (Pad->Point1.X, Pad->Point2.X) - half;
  info.box.Y1 = MIN (Pad->Point1.Y, Pad->Point2.Y) - half;
  info.box.X2 = MAX (Pad->Point1.X, Pad->Point2.X) + half;
  info.box.Y2 = MAX (Pad->Point1.Y, Pad->Point2.Y) + half;
  info.radius = 0;
  info.line = NULL;
  group = GetLayerGroupNumberBySide (
      TEST_FLAG (ONSOLDERFLAG, Pad) ? BOTTOM_SIDE : TOP_SIDE);

  /* check all visible layers in the same group */
  GROUP_LOOP (PCB->Data, group);
  {
    /* check all visible lines of the group member */
    info.layer = layer;
    if (info.layer->On)
      {
	r_search (info.layer->line_tree, &info.box, NULL, rubber_callback,
		  &info);
      }
  }
  END_LOOP;
}
Ejemplo n.º 3
0
/* ---------------------------------------------------------------------------
 * checks all visible lines which belong to the same layergroup as the
 * passed pad. If one of the endpoints of the line lays inside the pad,
 * the line is added to the 'rubberband' list
 */
static void
CheckPadForRubberbandConnection (PadTypePtr Pad)
{
  BDimension half = Pad->Thickness / 2;
  Cardinal i, group;
  struct rubber_info info;

  info.box.X1 = MIN (Pad->Point1.X, Pad->Point2.X) - half;
  info.box.Y1 = MIN (Pad->Point1.Y, Pad->Point2.Y) - half;
  info.box.X2 = MAX (Pad->Point1.X, Pad->Point2.X) + half;
  info.box.Y2 = MAX (Pad->Point1.Y, Pad->Point2.Y) + half;
  info.radius = 0;
  info.line = NULL;
  i = TEST_FLAG (ONSOLDERFLAG, Pad) ? solder_silk_layer : component_silk_layer;
  group = GetLayerGroupNumberByNumber (i);

  /* check all visible layers in the same group */
  GROUP_LOOP (PCB->Data, group);
  {
    /* check all visible lines of the group member */
    info.layer = layer;
    if (info.layer->On)
      {
	r_search (info.layer->line_tree, &info.box, NULL, rubber_callback,
		  &info);
      }
  }
  END_LOOP;
}
Ejemplo n.º 4
0
/* ---------------------------------------------------------------------------
 * checks all visible lines which belong to the same group as the passed polygon.
 * If one of the endpoints of the line lays inside the passed polygon,
 * the scanned line is added to the 'rubberband' list.
 */
static void
CheckPolygonForRubberbandConnection (LayerType *Layer,
				     PolygonType *Polygon)
{
  Cardinal group;

  /* lookup layergroup and check all visible lines in this group */
  group = GetLayerGroupNumberByPointer (Layer);
  GROUP_LOOP (PCB->Data, group);
  {
    if (layer->On)
      {
	Coord thick;

	/* the following code just stupidly compares the endpoints
	 * of the lines
	 */
	LINE_LOOP (layer);
	{
	  if (TEST_FLAG (LOCKFLAG, line))
	    continue;
	  if (TEST_FLAG (CLEARLINEFLAG, line))
	    continue;
	  thick = (line->Thickness + 1) / 2;
	  if (IsPointInPolygon (line->Point1.X, line->Point1.Y,
				thick, Polygon))
	    CreateNewRubberbandEntry (layer, line, &line->Point1);
	  if (IsPointInPolygon (line->Point2.X, line->Point2.Y,
				thick, Polygon))
	    CreateNewRubberbandEntry (layer, line, &line->Point2);
	}
	END_LOOP;
      }
  }
  END_LOOP;
}
Ejemplo n.º 5
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);
}
Ejemplo n.º 6
0
static float
drc_lines (PointTypePtr end, bool way)
{
  float f, s, f2, s2, len, best;
  LocationType dx, dy, temp, last, length;
  LocationType temp2, last2, length2;
  LineType line1, line2;
  Cardinal group, comp;
  struct drc_info info;
  bool two_lines, x_is_long, blocker;
  PointType ans;

  f = 1.0;
  s = 0.5;
  last = -1;
  line1.Flags = line2.Flags = NoFlags ();
  line1.Thickness = Settings.LineThickness + 2 * (PCB->Bloat + 1);
  line2.Thickness = line1.Thickness;
  line1.Clearance = line2.Clearance = 0;
  line1.Point1.X = Crosshair.AttachedLine.Point1.X;
  line1.Point1.Y = Crosshair.AttachedLine.Point1.Y;
  dy = end->Y - line1.Point1.Y;
  dx = end->X - line1.Point1.X;
  if (abs (dx) > abs (dy))
    {
      x_is_long = true;
      length = abs (dx);
    }
  else
    {
      x_is_long = false;
      length = abs (dy);
    }
  group = GetGroupOfLayer (INDEXOFCURRENT);
  comp = max_group + 10;	/* this out-of-range group might save a call */
  if (GetLayerGroupNumberByNumber (solder_silk_layer) == group)
    info.solder = true;
  else
    {
      info.solder = false;
      comp = GetLayerGroupNumberByNumber (component_silk_layer);
    }
  temp = length;
  /* assume the worst */
  best = 0.0;
  ans.X = line1.Point1.X;
  ans.Y = line1.Point1.Y;
  while (length != last)
    {
      last = length;
      if (x_is_long)
	{
	  dx = SGN (dx) * length;
	  dy = end->Y - line1.Point1.Y;
	  length2 = abs (dy);
	}
      else
	{
	  dy = SGN (dy) * length;
	  dx = end->X - line1.Point1.X;
	  length2 = abs (dx);
	}
      temp2 = length2;
      f2 = 1.0;
      s2 = 0.5;
      last2 = -1;
      blocker = true;
      while (length2 != last2)
	{
	  if (x_is_long)
	    dy = SGN (dy) * length2;
	  else
	    dx = SGN (dx) * length2;
	  two_lines = true;
	  if (abs (dx) > abs (dy) && x_is_long)
	    {
	      line1.Point2.X = line1.Point1.X +
		(way ? SGN (dx) * abs (dy) : dx - SGN (dx) * abs (dy));
	      line1.Point2.Y = line1.Point1.Y + (way ? dy : 0);
	    }
	  else if (abs (dy) >= abs (dx) && !x_is_long)
	    {
	      line1.Point2.X = line1.Point1.X + (way ? dx : 0);
	      line1.Point2.Y = line1.Point1.Y +
		(way ? SGN (dy) * abs (dx) : dy - SGN (dy) * abs (dx));
	    }
	  else if (x_is_long)
	    {
	      /* we've changed which axis is long, so only do one line */
	      line1.Point2.X = line1.Point1.X + dx;
	      line1.Point2.Y =
		line1.Point1.Y + (way ? SGN (dy) * abs (dx) : 0);
	      two_lines = false;
	    }
	  else
	    {
	      /* we've changed which axis is long, so only do one line */
	      line1.Point2.Y = line1.Point1.Y + dy;
	      line1.Point2.X =
		line1.Point1.X + (way ? SGN (dx) * abs (dy) : 0);
	      two_lines = false;
	    }
	  line2.Point1.X = line1.Point2.X;
	  line2.Point1.Y = line1.Point2.Y;
	  if (!two_lines)
	    {
	      line2.Point2.Y = line1.Point2.Y;
	      line2.Point2.X = line1.Point2.X;
	    }
	  else
	    {
	      line2.Point2.X = line1.Point1.X + dx;
	      line2.Point2.Y = line1.Point1.Y + dy;
	    }
	  SetLineBoundingBox (&line1);
	  SetLineBoundingBox (&line2);
	  last2 = length2;
	  if (setjmp (info.env) == 0)
	    {
	      info.line = &line1;
	      r_search (PCB->Data->via_tree, &line1.BoundingBox, NULL,
			drcVia_callback, &info);
	      r_search (PCB->Data->pin_tree, &line1.BoundingBox, NULL,
			drcVia_callback, &info);
	      if (info.solder || comp == group)
		r_search (PCB->Data->pad_tree, &line1.BoundingBox, NULL,
			  drcPad_callback, &info);
	      if (two_lines)
		{
		  info.line = &line2;
		  r_search (PCB->Data->via_tree, &line2.BoundingBox, NULL,
			    drcVia_callback, &info);
		  r_search (PCB->Data->pin_tree, &line2.BoundingBox, NULL,
			    drcVia_callback, &info);
		  if (info.solder || comp == group)
		    r_search (PCB->Data->pad_tree, &line2.BoundingBox, NULL,
			      drcPad_callback, &info);
		}
	      GROUP_LOOP (PCB->Data, group);
	      {
		info.line = &line1;
		r_search (layer->line_tree, &line1.BoundingBox, NULL,
			  drcLine_callback, &info);
		r_search (layer->arc_tree, &line1.BoundingBox, NULL,
			  drcArc_callback, &info);
		if (two_lines)
		  {
		    info.line = &line2;
		    r_search (layer->line_tree, &line2.BoundingBox,
			      NULL, drcLine_callback, &info);
		    r_search (layer->arc_tree, &line2.BoundingBox,
			      NULL, drcArc_callback, &info);
		  }
	      }
	      END_LOOP;
	      /* no intersector! */
	      blocker = false;
	      f2 += s2;
	      len = (line2.Point2.X - line1.Point1.X);
	      len *= len;
	      len += (float) (line2.Point2.Y - line1.Point1.Y) *
		(line2.Point2.Y - line1.Point1.Y);
	      if (len > best)
		{
		  best = len;
		  ans.X = line2.Point2.X;
		  ans.Y = line2.Point2.Y;
		}
#if 0
	      if (f2 > 1.0)
		f2 = 0.5;
#endif
	    }
	  else
	    {
	      /* bumped into something, back off */
	      f2 -= s2;
	    }
	  s2 *= 0.5;
	  length2 = MIN (f2 * temp2, temp2);
	}
      if (!blocker && ((x_is_long && line2.Point2.X - line1.Point1.X == dx)
		       || (!x_is_long
			   && line2.Point2.Y - line1.Point1.Y == dy)))
	f += s;
      else
	f -= s;
      s *= 0.5;
      length = MIN (f * temp, temp);
    }

  end->X = ans.X;
  end->Y = ans.Y;
  return best;
}
Ejemplo n.º 7
0
/*---------------------------------------------------------------------------
 *
 * convert buffer contents into an element
 */
bool
ConvertBufferToElement (BufferType *Buffer)
{
  ElementType *Element;
  Cardinal group;
  Cardinal pin_n = 1;
  bool hasParts = false, crooked = false;
  int onsolder;
  bool warned = false;

  if (Buffer->Data->pcb == 0)
    Buffer->Data->pcb = PCB;

  Element = CreateNewElement (PCB->Data, &PCB->Font, NoFlags (),
			      NULL, NULL, NULL, PASTEBUFFER->X,
			      PASTEBUFFER->Y, 0, 100,
			      MakeFlags (SWAP_IDENT ? ONSOLDERFLAG : NOFLAG),
			      false);
  if (!Element)
    return (false);
  VIA_LOOP (Buffer->Data);
  {
    char num[8];
    if (via->Mask < via->Thickness)
      via->Mask = via->Thickness + 2 * MASKFRAME;
    if (via->Name)
      CreateNewPin (Element, via->X, via->Y, via->Thickness,
		    via->Clearance, via->Mask, via->DrillingHole,
		    NULL, via->Name, MaskFlags (via->Flags,
						VIAFLAG | NOCOPY_FLAGS |
						SELECTEDFLAG | WARNFLAG));
    else
      {
	sprintf (num, "%d", pin_n++);
	CreateNewPin (Element, via->X, via->Y, via->Thickness,
		      via->Clearance, via->Mask, via->DrillingHole,
		      NULL, num, MaskFlags (via->Flags,
					    VIAFLAG | NOCOPY_FLAGS | SELECTEDFLAG
					    | WARNFLAG));
      }
    hasParts = true;
  }
  END_LOOP;

  for (onsolder = 0; onsolder < 2; onsolder ++)
    {
      int silk_layer;
      int onsolderflag;

      if ((!onsolder) == (!SWAP_IDENT))
	{
	  silk_layer = component_silk_layer;
	  onsolderflag = NOFLAG;
	}
      else
	{
	  silk_layer = solder_silk_layer;
	  onsolderflag = ONSOLDERFLAG;
	}

#define MAYBE_WARN() \
	  if (onsolder && !hasParts && !warned) \
	    { \
	      warned = true; \
	      Message \
		(_("Warning: All of the pads are on the opposite\n" \
		   "side from the component - that's probably not what\n" \
		   "you wanted\n")); \
	    } \

      /* get the component-side SM pads */
      group = GetLayerGroupNumberByNumber (silk_layer);
      GROUP_LOOP (Buffer->Data, group);
      {
	char num[8];
	LINE_LOOP (layer);
	{
	  sprintf (num, "%d", pin_n++);
	  CreateNewPad (Element, line->Point1.X,
			line->Point1.Y, line->Point2.X,
			line->Point2.Y, line->Thickness,
			line->Clearance,
			line->Thickness + line->Clearance, NULL,
			line->Number ? line->Number : num,
			MakeFlags (onsolderflag));
	  MAYBE_WARN();
	  hasParts = true;
	}
	END_LOOP;
	POLYGON_LOOP (layer);
	{
	  Coord x1, y1, x2, y2, w, h, t;

	  if (! polygon_is_rectangle (polygon))
	    {
	      crooked = true;
	      continue;
	    }

	  w = polygon->Points[2].X - polygon->Points[0].X;
	  h = polygon->Points[1].Y - polygon->Points[0].Y;
	  t = (w < h) ? w : h;
	  x1 = polygon->Points[0].X + t/2;
	  y1 = polygon->Points[0].Y + t/2;
	  x2 = x1 + (w-t);
	  y2 = y1 + (h-t);

	  sprintf (num, "%d", pin_n++);
	  CreateNewPad (Element,
			x1, y1, x2, y2, t,
			2 * Settings.Keepaway,
			t + Settings.Keepaway,
			NULL, num,
			MakeFlags (SQUAREFLAG | onsolderflag));
	  MAYBE_WARN();
	  hasParts = true;
	}
	END_LOOP;
      }
      END_LOOP;
    }

  /* now add the silkscreen. NOTE: elements must have pads or pins too */
  LINE_LOOP (&Buffer->Data->SILKLAYER);
  {
    if (line->Number && !NAMEONPCB_NAME (Element))
      NAMEONPCB_NAME (Element) = strdup (line->Number);
    CreateNewLineInElement (Element, line->Point1.X,
			    line->Point1.Y, line->Point2.X,
			    line->Point2.Y, line->Thickness);
    hasParts = true;
  }
  END_LOOP;
  ARC_LOOP (&Buffer->Data->SILKLAYER);
  {
    CreateNewArcInElement (Element, arc->X, arc->Y, arc->Width,
			   arc->Height, arc->StartAngle, arc->Delta,
			   arc->Thickness);
    hasParts = true;
  }
  END_LOOP;
  if (!hasParts)
    {
      DestroyObject (PCB->Data, ELEMENT_TYPE, Element, Element, Element);
      Message (_("There was nothing to convert!\n"
		 "Elements must have some silk, pads or pins.\n"));
      return (false);
    }
  if (crooked)
     Message (_("There were polygons that can't be made into pins!\n"
                "So they were not included in the element\n"));
  Element->MarkX = Buffer->X;
  Element->MarkY = Buffer->Y;
  if (SWAP_IDENT)
    SET_FLAG (ONSOLDERFLAG, Element);
  SetElementBoundingBox (PCB->Data, Element, &PCB->Font);
  ClearBuffer (Buffer);
  MoveObjectToBuffer (Buffer->Data, PCB->Data, ELEMENT_TYPE, Element, Element,
		      Element);
  SetBufferBoundingBox (Buffer);
  return (true);
}
Ejemplo n.º 8
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);
}