コード例 #1
0
ファイル: buffer.c プロジェクト: bgamari/geda-pcb
void
FreeRotateElementLowLevel (DataType *Data, ElementType *Element,
			   Coord X, Coord Y,
			   double cosa, double sina, Angle angle)
{
  /* solder side objects need a different orientation */

  /* the text subroutine decides by itself if the direction
   * is to be corrected
   */
#if 0
  ELEMENTTEXT_LOOP (Element);
  {
    if (Data && Data->name_tree[n])
      r_delete_entry (Data->name_tree[n], (BoxType *)text);
    RotateTextLowLevel (text, X, Y, Number);
  }
  END_LOOP;
#endif
  ELEMENTLINE_LOOP (Element);
  {
    free_rotate (&line->Point1.X, &line->Point1.Y, X, Y, cosa, sina);
    free_rotate (&line->Point2.X, &line->Point2.Y, X, Y, cosa, sina);
    SetLineBoundingBox (line);
  }
  END_LOOP;
  PIN_LOOP (Element);
  {
    /* pre-delete the pins from the pin-tree before their coordinates change */
    if (Data)
      r_delete_entry (Data->pin_tree, (BoxType *)pin);
    RestoreToPolygon (Data, PIN_TYPE, Element, pin);
    free_rotate (&pin->X, &pin->Y, X, Y, cosa, sina);
    SetPinBoundingBox (pin);
  }
  END_LOOP;
  PAD_LOOP (Element);
  {
    /* pre-delete the pads before their coordinates change */
    if (Data)
      r_delete_entry (Data->pad_tree, (BoxType *)pad);
    RestoreToPolygon (Data, PAD_TYPE, Element, pad);
    free_rotate (&pad->Point1.X, &pad->Point1.Y, X, Y, cosa, sina);
    free_rotate (&pad->Point2.X, &pad->Point2.Y, X, Y, cosa, sina);
    SetLineBoundingBox ((LineType *) pad);
  }
  END_LOOP;
  ARC_LOOP (Element);
  {
    free_rotate (&arc->X, &arc->Y, X, Y, cosa, sina);
    arc->StartAngle = NormalizeAngle (arc->StartAngle + angle);
  }
  END_LOOP;

  free_rotate (&Element->MarkX, &Element->MarkY, X, Y, cosa, sina);
  SetElementBoundingBox (Data, Element, &PCB->Font);
  ClearFromPolygon (Data, ELEMENT_TYPE, Element, Element);
}
コード例 #2
0
ファイル: mirror.c プロジェクト: fruoff/pcb-fruoff
/* ---------------------------------------------------------------------------
 * mirrors the coordinates of an element
 * an additional offset is passed
 */
void
MirrorElementCoordinates (DataTypePtr Data, ElementTypePtr Element,
			  Coord yoff)
{
  r_delete_element (Data, Element);
  ELEMENTLINE_LOOP (Element);
  {
    line->Point1.X = SWAP_X (line->Point1.X);
    line->Point1.Y = SWAP_Y (line->Point1.Y) + yoff;
    line->Point2.X = SWAP_X (line->Point2.X);
    line->Point2.Y = SWAP_Y (line->Point2.Y) + yoff;
  }
  END_LOOP;
  PIN_LOOP (Element);
  {
    RestoreToPolygon (Data, PIN_TYPE, Element, pin);
    pin->X = SWAP_X (pin->X);
    pin->Y = SWAP_Y (pin->Y) + yoff;
  }
  END_LOOP;
  PAD_LOOP (Element);
  {
    RestoreToPolygon (Data, PAD_TYPE, Element, pad);
    pad->Point1.X = SWAP_X (pad->Point1.X);
    pad->Point1.Y = SWAP_Y (pad->Point1.Y) + yoff;
    pad->Point2.X = SWAP_X (pad->Point2.X);
    pad->Point2.Y = SWAP_Y (pad->Point2.Y) + yoff;
    TOGGLE_FLAG (ONSOLDERFLAG, pad);
  }
  END_LOOP;
  ARC_LOOP (Element);
  {
    arc->X = SWAP_X (arc->X);
    arc->Y = SWAP_Y (arc->Y) + yoff;
    arc->StartAngle = SWAP_ANGLE (arc->StartAngle);
    arc->Delta = SWAP_DELTA (arc->Delta);
  }
  END_LOOP;
  ELEMENTTEXT_LOOP (Element);
  {
    text->X = SWAP_X (text->X);
    text->Y = SWAP_Y (text->Y) + yoff;
    TOGGLE_FLAG (ONSOLDERFLAG, text);
  }
  END_LOOP;
  Element->MarkX = SWAP_X (Element->MarkX);
  Element->MarkY = SWAP_Y (Element->MarkY) + yoff;

  /* now toggle the solder-side flag */
  TOGGLE_FLAG (ONSOLDERFLAG, Element);
  /* this inserts all of the rtree data too */
  SetElementBoundingBox (Data, Element, &PCB->Font);
  ClearFromPolygon (Data, ELEMENT_TYPE, Element, Element);
}
コード例 #3
0
ファイル: footprintupdate.c プロジェクト: Mehanik/pcb-plugins
static void
replace_one_footprint_aux(ElementTypePtr old_element,
                          PadOrPinType* old1_pp, PadOrPinType* old2_pp,
                          ElementTypePtr copy_element,
                          PadOrPinType* copy1_pp, PadOrPinType* copy2_pp)
{
  Boolean two_points = (old2_pp && copy2_pp);
  Boolean reflect = IS_REFLECTED(copy_element, old_element);

  debug_log("Reflect?: %s\n", (reflect ? "yes" : "no"));
  if (reflect) {
    /* Change side of board */
    ChangeElementSide(copy_element, 0);
  }

  CheapPointType copy1_pt = pad_or_pin_center(copy1_pp);
  CheapPointType old1_pt = pad_or_pin_center(old1_pp);

  BYTE rot_steps = 0;
  if (two_points) {
    /* Calculate nearest rotation steps */
    CheapPointType copy2_pt = pad_or_pin_center(copy2_pp);
    CheapPointType old2_pt = pad_or_pin_center(old2_pp);
    rot_steps =
      calculate_rotation_steps(copy1_pt, copy2_pt, old1_pt, old2_pt);
  }
  if (rot_steps) {
    /* Rotate copy */
    RotateElementLowLevel(PCB->Data, copy_element, 0, 0, rot_steps);
    /* Recalculate since copy_element has changed. */
    copy1_pt = pad_or_pin_center(copy1_pp);
  }

  /* Calculate translation */
  LocationType dx = old1_pt.X - copy1_pt.X;
  LocationType dy = old1_pt.Y - copy1_pt.Y;
  /* Move element */
  MoveElementLowLevel(PCB->Data, copy_element, dx, dy);

  /* Transfer pad/pin text and names. */
  transfer_text(old_element, copy_element);
  transfer_names(old_element, copy_element);
  transfer_flags(old_element, copy_element);
  SetElementBoundingBox(PCB->Data, copy_element, &PCB->Font);

  AddObjectToCreateUndoList(ELEMENT_TYPE,
                            copy_element, copy_element, copy_element);
  /* Remove old element. */
  MoveObjectToRemoveUndoList(ELEMENT_TYPE,
                             old_element, old_element, old_element);
}
コード例 #4
0
ファイル: buffer.c プロジェクト: bgamari/geda-pcb
/* ---------------------------------------------------------------------------
 * loads element data from file/library into buffer
 * parse the file with disabled 'PCB mode' (see parser)
 * returns false on error
 * if successful, update some other stuff and reposition the pastebuffer
 */
bool
LoadElementToBuffer (BufferType *Buffer, char *Name, bool FromFile)
{
  ElementType *element;

  ClearBuffer (Buffer);
  if (FromFile)
    {
      if (!ParseElementFile (Buffer->Data, Name))
	{
	  if (Settings.ShowSolderSide)
	    SwapBuffer (Buffer);
	  SetBufferBoundingBox (Buffer);
	  if (Buffer->Data->ElementN)
	    {
	      element = Buffer->Data->Element->data;
	      Buffer->X = element->MarkX;
	      Buffer->Y = element->MarkY;
	    }
	  else
	    {
	      Buffer->X = 0;
	      Buffer->Y = 0;
	    }
	  return (true);
	}
    }
  else
    {
      if (!ParseLibraryEntry (Buffer->Data, Name)
	  && Buffer->Data->ElementN != 0)
	{
	  element = Buffer->Data->Element->data;

	  /* always add elements using top-side coordinates */
	  if (Settings.ShowSolderSide)
	    MirrorElementCoordinates (Buffer->Data, element, 0);
	  SetElementBoundingBox (Buffer->Data, element, &PCB->Font);

	  /* set buffer offset to 'mark' position */
	  Buffer->X = element->MarkX;
	  Buffer->Y = element->MarkY;
	  SetBufferBoundingBox (Buffer);
	  return (true);
	}
    }
  /* release memory which might have been acquired */
  ClearBuffer (Buffer);
  return (false);
}
コード例 #5
0
ファイル: buffer.c プロジェクト: bgamari/geda-pcb
/* ---------------------------------------------------------------------------
 * moves a element to buffer without allocating memory for pins/names
 */
static void *
MoveElementToBuffer (ElementType *element)
{
  /*
   * Delete the element from the source (remove it from trees,
   * restore to polygons)
   */
  r_delete_element (Source, element);

  Source->Element = g_list_remove (Source->Element, element);
  Source->ElementN --;
  Dest->Element = g_list_append (Dest->Element, element);
  Dest->ElementN ++;

  PIN_LOOP (element);
  {
    RestoreToPolygon(Source, PIN_TYPE, element, pin);
    CLEAR_FLAG (WARNFLAG | NOCOPY_FLAGS, pin);
  }
  END_LOOP;
  PAD_LOOP (element);
  {
    RestoreToPolygon(Source, PAD_TYPE, element, pad);
    CLEAR_FLAG (WARNFLAG | NOCOPY_FLAGS, pad);
  }
  END_LOOP;
  SetElementBoundingBox (Dest, element, &PCB->Font);
  /*
   * Now clear the from the polygons in the destination
   */
  PIN_LOOP (element);
  {
    ClearFromPolygon (Dest, PIN_TYPE, element, pin);
  }
  END_LOOP;
  PAD_LOOP (element);
  {
    ClearFromPolygon (Dest, PAD_TYPE, element, pad);
  }
  END_LOOP;

  return element;
}
コード例 #6
0
void *ChangePadClearSize( ElementTypePtr Element, PadTypePtr Pad )
{
  int eax;
  int ebx;
  int esi;
  BDimension value = Absolute;
  value = ( Pad->Clearance + Delta < ( PCB->Bloat + 1 ) * 2 ? Pad->Clearance + Delta : ( PCB->Bloat + 1 ) * 2 ) <= 0x989680 ? 0x989680 : Pad->Clearance + Delta < ( PCB->Bloat + 1 ) * 2 ? Pad->Clearance + Delta : ( PCB->Bloat + 1 ) * 2;
  if ( value + -100 <= 0x98961c && Pad->Clearance != value )
  {
    AddObjectToClearSizeUndoList( 512, (void*)Element, (void*)Pad, (void*)Pad );
    RestoreToPolygon( &PCB->Data, 512, (void*)Element, (void*)Pad );
    ErasePad( Pad );
    r_delete_entry( &PCB->Data->pad_tree, (int)( &Pad->BoundingBox ) );
    Pad->Clearance = value;
    SetElementBoundingBox( &PCB->Data, Element, &PCB->Font );
    ClearFromPolygon( &PCB->Data, 512, (void*)Element, (void*)Pad );
    DrawPad( Pad, 0 );
    return (void*)Pad;
  }
}
コード例 #7
0
void *ChangePinClearSize( ElementTypePtr Element, PinTypePtr Pin )
{
  int eax;
  int ebx;
  int esi;
  BDimension value = Absolute;
  value = ( Pin->Clearance + Delta < ( PCB->Bloat + 1 ) * 2 ? Pin->Clearance + Delta : ( PCB->Bloat + 1 ) * 2 ) <= 0x989680 ? 0x989680 : Pin->Clearance + Delta < ( PCB->Bloat + 1 ) * 2 ? Pin->Clearance + Delta : ( PCB->Bloat + 1 ) * 2;
  if ( Pin->Clearance != ( ( Pin->Clearance + Delta < ( PCB->Bloat + 1 ) * 2 ? Pin->Clearance + Delta : ( PCB->Bloat + 1 ) * 2 ) <= 0x989680 ? 10000000 : Pin->Clearance + Delta < ( PCB->Bloat + 1 ) * 2 ? Pin->Clearance + Delta : ( PCB->Bloat + 1 ) * 2 ) )
  {
    RestoreToPolygon( &PCB->Data, 256, (void*)Element, (void*)Pin );
    AddObjectToClearSizeUndoList( 256, (void*)Element, (void*)Pin, (void*)Pin );
    ErasePin( Pin );
    r_delete_entry( &PCB->Data->pin_tree, (int)( &Pin->BoundingBox ) );
    Pin->Clearance = value;
    SetElementBoundingBox( &PCB->Data, Element, &PCB->Font );
    ClearFromPolygon( &PCB->Data, 256, (void*)Element, (void*)Pin );
    DrawPin( Pin, 0 );
    return (void*)Pin;
  }
}
コード例 #8
0
void *ChangePadSize( ElementTypePtr Element, PadTypePtr Pad )
{
  int eax;
  int ebx;
  int esi;
  int edi;
  BDimension value = Absolute;
  if ( value + -100 <= 0x98961c && Pad->Thickness != value )
  {
    AddObjectToSizeUndoList( 512, (void*)Element, (void*)Pad, (void*)Pad );
    AddObjectToMaskSizeUndoList( 512, (void*)Element, (void*)Pad, (void*)Pad );
    RestoreToPolygon( &PCB->Data, 512, (void*)Element, (void*)Pad );
    ErasePad( Pad );
    r_delete_entry( &PCB->Data->pad_tree, (int)( &Pad->BoundingBox ) );
    Pad->Thickness = value;
    Pad->Mask = ( Pad->Mask + value ) - Pad->Thickness;
    SetElementBoundingBox( &PCB->Data, Element, &PCB->Font );
    ClearFromPolygon( &PCB->Data, 512, (void*)Element, (void*)Pad );
    DrawPad( Pad, 0 );
    return (void*)Pad;
  }
}
コード例 #9
0
void *ChangePinSize( ElementTypePtr Element, PinTypePtr Pin )
{
  int eax;
  int ebx;
  int esi;
  int edi;
  BDimension value = Absolute;
  if ( value <= 0x989680 && !( ( Pin->Flags.f & 8 ) & 255 ) && value > 1999 && Pin->DrillingHole + 399 < value && Pin->Thickness != value )
  {
    AddObjectToSizeUndoList( 256, (void*)Element, (void*)Pin, (void*)Pin );
    AddObjectToMaskSizeUndoList( 256, (void*)Element, (void*)Pin, (void*)Pin );
    ErasePin( Pin );
    r_delete_entry( &PCB->Data->pin_tree, (int)( &Pin->BoundingBox ) );
    RestoreToPolygon( &PCB->Data, 256, (void*)Element, (void*)Pin );
    Pin->Thickness = value;
    Pin->Mask = ( Pin->Mask + value ) - Pin->Thickness;
    SetElementBoundingBox( &PCB->Data, Element, &PCB->Font );
    ClearFromPolygon( &PCB->Data, 256, (void*)Element, (void*)Pin );
    DrawPin( Pin, 0 );
    return (void*)Pin;
  }
}
コード例 #10
0
ファイル: copy.c プロジェクト: bgamari/geda-pcb
/* ---------------------------------------------------------------------------
 * copies data from one element to another and creates the destination 
 * if necessary
 */
ElementType *
CopyElementLowLevel (DataType *Data, ElementType *Src,
                     bool uniqueName, Coord dx, Coord dy, int mask_flags)
{
  int i;
  ElementType *Dest;

  /* both coordinates and flags are the same */
  Dest = CreateNewElement (Data, &PCB->Font,
			   MaskFlags (Src->Flags, mask_flags),
			   DESCRIPTION_NAME (Src), NAMEONPCB_NAME (Src),
			   VALUE_NAME (Src), DESCRIPTION_TEXT (Src).X + dx,
			   DESCRIPTION_TEXT (Src).Y + dy,
			   DESCRIPTION_TEXT (Src).Direction,
			   DESCRIPTION_TEXT (Src).Scale,
			   MaskFlags (DESCRIPTION_TEXT (Src).Flags,
				      mask_flags), uniqueName);

  /* abort on error */
  if (!Dest)
    return (Dest);

  ELEMENTLINE_LOOP (Src);
  {
    CreateNewLineInElement (Dest, line->Point1.X + dx,
			    line->Point1.Y + dy, line->Point2.X + dx,
			    line->Point2.Y + dy, line->Thickness);
  }
  END_LOOP;
  PIN_LOOP (Src);
  {
    CreateNewPin (Dest, pin->X + dx, pin->Y + dy, pin->Thickness,
		  pin->Clearance, pin->Mask, pin->DrillingHole,
		  pin->Name, pin->Number, MaskFlags (pin->Flags, mask_flags));
  }
  END_LOOP;
  PAD_LOOP (Src);
  {
    CreateNewPad (Dest, pad->Point1.X + dx, pad->Point1.Y + dy,
		  pad->Point2.X + dx, pad->Point2.Y + dy, pad->Thickness,
		  pad->Clearance, pad->Mask, pad->Name, pad->Number,
		  MaskFlags (pad->Flags, mask_flags));
  }
  END_LOOP;
  ARC_LOOP (Src);
  {
    CreateNewArcInElement (Dest, arc->X + dx, arc->Y + dy, arc->Width,
			   arc->Height, arc->StartAngle, arc->Delta,
			   arc->Thickness);
  }
  END_LOOP;

  for (i=0; i<Src->Attributes.Number; i++)
    CreateNewAttribute (& Dest->Attributes,
			Src->Attributes.List[i].name,
			Src->Attributes.List[i].value);

  Dest->MarkX = Src->MarkX + dx;
  Dest->MarkY = Src->MarkY + dy;

  SetElementBoundingBox (Data, Dest, &PCB->Font);
  return (Dest);
}
コード例 #11
0
ファイル: buffer.c プロジェクト: bgamari/geda-pcb
/*---------------------------------------------------------------------------
 *
 * 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);
}