예제 #1
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);
}
예제 #2
0
파일: autoplace.c 프로젝트: bert/pcb-update
void
doPerturb (PerturbationType * pt, bool undo)
{
  LocationType bbcx, bbcy;
  /* compute center of element bounding box */
  bbcx = (pt->element->VBox.X1 + pt->element->VBox.X2) / 2;
  bbcy = (pt->element->VBox.Y1 + pt->element->VBox.Y2) / 2;
  /* do exchange, shift or flip/rotate */
  switch (pt->which)
    {
    case SHIFT:
      {
	LocationType DX = pt->DX, DY = pt->DY;
	if (undo)
	  {
	    DX = -DX;
	    DY = -DY;
	  }
	MoveElementLowLevel (PCB->Data, pt->element, DX, DY);
	return;
      }
    case ROTATE:
      {
	BYTE b = pt->rotate;
	if (undo)
	  b = (4 - b) & 3;
	/* 0 - flip; 1-3, rotate. */
	if (b)
	  RotateElementLowLevel (PCB->Data, pt->element, bbcx, bbcy, b);
	else
	  {
	    LocationType y = pt->element->VBox.Y1;
	    MirrorElementCoordinates (PCB->Data, pt->element, 0);
	    /* mirroring moves the element.  move it back. */
	    MoveElementLowLevel (PCB->Data, pt->element, 0,
				 y - pt->element->VBox.Y1);
	  }
	return;
      }
    case EXCHANGE:
      {
	/* first exchange positions */
	LocationType x1 = pt->element->VBox.X1;
	LocationType y1 = pt->element->VBox.Y1;
	LocationType x2 = pt->other->BoundingBox.X1;
	LocationType y2 = pt->other->BoundingBox.Y1;
	MoveElementLowLevel (PCB->Data, pt->element, x2 - x1, y2 - y1);
	MoveElementLowLevel (PCB->Data, pt->other, x1 - x2, y1 - y2);
	/* then flip both elements if they are on opposite sides */
	if (TEST_FLAG (ONSOLDERFLAG, pt->element) !=
	    TEST_FLAG (ONSOLDERFLAG, pt->other))
	  {
	    PerturbationType mypt;
	    mypt.element = pt->element;
	    mypt.which = ROTATE;
	    mypt.rotate = 0;	/* flip */
	    doPerturb (&mypt, undo);
	    mypt.element = pt->other;
	    doPerturb (&mypt, undo);
	  }
	/* done */
	return;
      }
    default:
      assert (0);
    }
}
예제 #3
0
파일: buffer.c 프로젝트: bgamari/geda-pcb
/* ---------------------------------------------------------------------------
 * flip components/tracks from one side to the other
 */
static void
SwapBuffer (BufferType *Buffer)
{
  int j, k;
  Cardinal sgroup, cgroup;
  LayerType swap;

  ELEMENT_LOOP (Buffer->Data);
  {
    r_delete_element (Buffer->Data, element);
    MirrorElementCoordinates (Buffer->Data, element, 0);
  }
  END_LOOP;
  /* set buffer offset to 'mark' position */
  Buffer->X = SWAP_X (Buffer->X);
  Buffer->Y = SWAP_Y (Buffer->Y);
  VIA_LOOP (Buffer->Data);
  {
    r_delete_entry (Buffer->Data->via_tree, (BoxType *)via);
    via->X = SWAP_X (via->X);
    via->Y = SWAP_Y (via->Y);
    SetPinBoundingBox (via);
    r_insert_entry (Buffer->Data->via_tree, (BoxType *)via, 0);
  }
  END_LOOP;
  ALLLINE_LOOP (Buffer->Data);
  {
    r_delete_entry (layer->line_tree, (BoxType *)line);
    line->Point1.X = SWAP_X (line->Point1.X);
    line->Point1.Y = SWAP_Y (line->Point1.Y);
    line->Point2.X = SWAP_X (line->Point2.X);
    line->Point2.Y = SWAP_Y (line->Point2.Y);
    SetLineBoundingBox (line);
    r_insert_entry (layer->line_tree, (BoxType *)line, 0);
  }
  ENDALL_LOOP;
  ALLARC_LOOP (Buffer->Data);
  {
    r_delete_entry (layer->arc_tree, (BoxType *)arc);
    arc->X = SWAP_X (arc->X);
    arc->Y = SWAP_Y (arc->Y);
    arc->StartAngle = SWAP_ANGLE (arc->StartAngle);
    arc->Delta = SWAP_DELTA (arc->Delta);
    SetArcBoundingBox (arc);
    r_insert_entry (layer->arc_tree, (BoxType *)arc, 0);
  }
  ENDALL_LOOP;
  ALLPOLYGON_LOOP (Buffer->Data);
  {
    r_delete_entry (layer->polygon_tree, (BoxType *)polygon);
    POLYGONPOINT_LOOP (polygon);
    {
      point->X = SWAP_X (point->X);
      point->Y = SWAP_Y (point->Y);
    }
    END_LOOP;
    SetPolygonBoundingBox (polygon);
    r_insert_entry (layer->polygon_tree, (BoxType *)polygon, 0);
    /* hmmm, how to handle clip */
  }
  ENDALL_LOOP;
  ALLTEXT_LOOP (Buffer->Data);
  {
    r_delete_entry (layer->text_tree, (BoxType *)text);
    text->X = SWAP_X (text->X);
    text->Y = SWAP_Y (text->Y);
    TOGGLE_FLAG (ONSOLDERFLAG, text);
    SetTextBoundingBox (&PCB->Font, text);
    r_insert_entry (layer->text_tree, (BoxType *)text, 0);
  }
  ENDALL_LOOP;
  /* swap silkscreen layers */
  swap = Buffer->Data->Layer[solder_silk_layer];
  Buffer->Data->Layer[solder_silk_layer] =
    Buffer->Data->Layer[component_silk_layer];
  Buffer->Data->Layer[component_silk_layer] = swap;

  /* swap layer groups when balanced */
  sgroup = GetLayerGroupNumberByNumber (solder_silk_layer);
  cgroup = GetLayerGroupNumberByNumber (component_silk_layer);
  if (PCB->LayerGroups.Number[cgroup] == PCB->LayerGroups.Number[sgroup])
    {
      for (j = k = 0; j < PCB->LayerGroups.Number[sgroup]; j++)
	{
	  int t1, t2;
	  Cardinal cnumber = PCB->LayerGroups.Entries[cgroup][k];
	  Cardinal snumber = PCB->LayerGroups.Entries[sgroup][j];

	  if (snumber >= max_copper_layer)
	    continue;
	  swap = Buffer->Data->Layer[snumber];

	  while (cnumber >= max_copper_layer)
	    {
	      k++;
	      cnumber = PCB->LayerGroups.Entries[cgroup][k];
	    }
	  Buffer->Data->Layer[snumber] = Buffer->Data->Layer[cnumber];
	  Buffer->Data->Layer[cnumber] = swap;
	  k++;
	  /* move the thermal flags with the layers */
	  ALLPIN_LOOP (Buffer->Data);
	  {
	    t1 = TEST_THERM (snumber, pin);
	    t2 = TEST_THERM (cnumber, pin);
	    ASSIGN_THERM (snumber, t2, pin);
	    ASSIGN_THERM (cnumber, t1, pin);
	  }
	  ENDALL_LOOP;
	  VIA_LOOP (Buffer->Data);
	  {
	    t1 = TEST_THERM (snumber, via);
	    t2 = TEST_THERM (cnumber, via);
	    ASSIGN_THERM (snumber, t2, via);
	    ASSIGN_THERM (cnumber, t1, via);
	  }
	  END_LOOP;
	}
    }
  SetBufferBoundingBox (Buffer);
  SetCrosshairRangeToBuffer ();
}