Exemple #1
0
static void
nbcb_ripup (Widget w, Std_Nbcb_Func v, XmPushButtonCallbackStruct * cbs)
{
  nbcb_std_callback (w, nbcb_find, cbs);

  VISIBLELINE_LOOP (PCB->Data);
  {
    if (TEST_FLAG (FOUNDFLAG, line) && !TEST_FLAG (LOCKFLAG, line))
      RemoveObject (LINE_TYPE, layer, line, line);
  }
  ENDALL_LOOP;

  VISIBLEARC_LOOP (PCB->Data);
  {
    if (TEST_FLAG (FOUNDFLAG, arc) && !TEST_FLAG (LOCKFLAG, arc))
      RemoveObject (ARC_TYPE, layer, arc, arc);
  }
  ENDALL_LOOP;

  if (PCB->ViaOn)
    VIA_LOOP (PCB->Data);
  {
    if (TEST_FLAG (FOUNDFLAG, via) && !TEST_FLAG (LOCKFLAG, via))
      RemoveObject (VIA_TYPE, via, via, via);
  }
  END_LOOP;
}
static void
netlist_rip_up_cb (GtkWidget * widget, gpointer data)
{

  if (!selected_net)
    return;
  netlist_find_cb(widget, data);

  VISIBLELINE_LOOP (PCB->Data);
  {
    if (TEST_FLAG (FOUNDFLAG, line) && !TEST_FLAG (LOCKFLAG, line))
      RemoveObject (LINE_TYPE, layer, line, line);
  }
  ENDALL_LOOP;

  VISIBLEARC_LOOP (PCB->Data);
  {
    if (TEST_FLAG (FOUNDFLAG, arc) && !TEST_FLAG (LOCKFLAG, arc))
      RemoveObject (ARC_TYPE, layer, arc, arc);
  }
  ENDALL_LOOP;

  if (PCB->ViaOn)
    VIA_LOOP (PCB->Data);
  {
    if (TEST_FLAG (FOUNDFLAG, via) && !TEST_FLAG (LOCKFLAG, via))
      RemoveObject (VIA_TYPE, via, via, via);
  }
  END_LOOP;

}
Exemple #3
0
void
MirrorBuffer (BufferType *Buffer)
{
  int i;

  if (Buffer->Data->ElementN)
    {
      Message (_("You can't mirror a buffer that has elements!\n"));
      return;
    }
  for (i = 0; i < max_copper_layer + 2; i++)
    {
      LayerType *layer = Buffer->Data->Layer + i;
      if (layer->TextN)
	{
	  Message (_("You can't mirror a buffer that has text!\n"));
	  return;
	}
    }
  /* set buffer offset to 'mark' position */
  Buffer->X = SWAP_X (Buffer->X);
  Buffer->Y = SWAP_Y (Buffer->Y);
  VIA_LOOP (Buffer->Data);
  {
    via->X = SWAP_X (via->X);
    via->Y = SWAP_Y (via->Y);
  }
  END_LOOP;
  ALLLINE_LOOP (Buffer->Data);
  {
    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);
  }
  ENDALL_LOOP;
  ALLARC_LOOP (Buffer->Data);
  {
    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);
  }
  ENDALL_LOOP;
  ALLPOLYGON_LOOP (Buffer->Data);
  {
    POLYGONPOINT_LOOP (polygon);
    {
      point->X = SWAP_X (point->X);
      point->Y = SWAP_Y (point->Y);
    }
    END_LOOP;
    SetPolygonBoundingBox (polygon);
  }
  ENDALL_LOOP;
  SetBufferBoundingBox (Buffer);
  SetCrosshairRangeToBuffer ();
}
Exemple #4
0
/* ---------------------------------------------------------------------------
 * rotates the contents of the pastebuffer
 */
void
RotateBuffer (BufferType *Buffer, BYTE Number)
{
  /* rotate vias */
  VIA_LOOP (Buffer->Data);
  {
    r_delete_entry (Buffer->Data->via_tree, (BoxType *)via);
    ROTATE_VIA_LOWLEVEL (via, Buffer->X, Buffer->Y, Number);
    SetPinBoundingBox (via);
    r_insert_entry (Buffer->Data->via_tree, (BoxType *)via, 0);
  }
  END_LOOP;

  /* elements */
  ELEMENT_LOOP (Buffer->Data);
  {
    RotateElementLowLevel (Buffer->Data, element, Buffer->X, Buffer->Y,
			   Number);
  }
  END_LOOP;

  /* all layer related objects */
  ALLLINE_LOOP (Buffer->Data);
  {
    r_delete_entry (layer->line_tree, (BoxType *)line);
    RotateLineLowLevel (line, Buffer->X, Buffer->Y, Number);
    r_insert_entry (layer->line_tree, (BoxType *)line, 0);
  }
  ENDALL_LOOP;
  ALLARC_LOOP (Buffer->Data);
  {
    r_delete_entry (layer->arc_tree, (BoxType *)arc);
    RotateArcLowLevel (arc, Buffer->X, Buffer->Y, Number);
    r_insert_entry (layer->arc_tree, (BoxType *)arc, 0);
  }
  ENDALL_LOOP;
  ALLTEXT_LOOP (Buffer->Data);
  {
    r_delete_entry (layer->text_tree, (BoxType *)text);
    RotateTextLowLevel (text, Buffer->X, Buffer->Y, Number);
    r_insert_entry (layer->text_tree, (BoxType *)text, 0);
  }
  ENDALL_LOOP;
  ALLPOLYGON_LOOP (Buffer->Data);
  {
    r_delete_entry (layer->polygon_tree, (BoxType *)polygon);
    RotatePolygonLowLevel (polygon, Buffer->X, Buffer->Y, Number);
    r_insert_entry (layer->polygon_tree, (BoxType *)polygon, 0);
  }
  ENDALL_LOOP;

  /* finally the origin and the bounding box */
  ROTATE (Buffer->X, Buffer->Y, Buffer->X, Buffer->Y, Number);
  RotateBoxLowLevel (&Buffer->BoundingBox, Buffer->X, Buffer->Y, Number);
  SetCrosshairRangeToBuffer ();
}
Exemple #5
0
void
ResetVisitPinsViasAndPads ()
{
  VIA_LOOP (PCB->Data);
    CLEAR_FLAG (VISITFLAG, via);
  END_LOOP; /* Via. */
  ELEMENT_LOOP (PCB->Data);
    PIN_LOOP (element);
      CLEAR_FLAG (VISITFLAG, pin);
    END_LOOP; /* Pin. */
    PAD_LOOP (element);
      CLEAR_FLAG (VISITFLAG, pad);
    END_LOOP; /* Pad. */
  END_LOOP; /* Element. */
}
Exemple #6
0
static void
move_all_thermals (int old_index, int new_index)
{
  VIA_LOOP (PCB->Data);
    {
      move_one_thermal (old_index, new_index, via);
    }
  END_LOOP;

  ALLPIN_LOOP (PCB->Data);
    {
      move_one_thermal (old_index, new_index, pin);
    }
  ENDALL_LOOP;
}
Exemple #7
0
/*!
 * \brief Move everything.
 *
 * Call our own 'MyMove*LowLevel' where they don't exist in move.c.
 * This gets very slow if there are large polygons present, since every
 * element move re-clears the poly, followed by the polys moving and
 * re-clearing everything again.
 */
static void
MoveAll(Coord dx, Coord dy)
{
  ELEMENT_LOOP (PCB->Data);
  {
    MoveElementLowLevel (PCB->Data, element, dx, dy);
    AddObjectToMoveUndoList (ELEMENT_TYPE, NULL, NULL, element, dx, dy);
  }
  END_LOOP;
  VIA_LOOP (PCB->Data);
  {
    MyMoveViaLowLevel (PCB->Data, via, dx, dy);
    AddObjectToMoveUndoList (VIA_TYPE, NULL, NULL, via, dx, dy);
  }
  END_LOOP;
  ALLLINE_LOOP (PCB->Data);
  {
    MyMoveLineLowLevel (PCB->Data, layer, line, dx, dy);
    AddObjectToMoveUndoList (LINE_TYPE, NULL, NULL, line, dx, dy);
  }
  ENDALL_LOOP;
  ALLARC_LOOP (PCB->Data);
  {
    MyMoveArcLowLevel (PCB->Data, layer, arc, dx, dy);
    AddObjectToMoveUndoList (ARC_TYPE, NULL, NULL, arc, dx, dy);
  }
  ENDALL_LOOP;
  ALLTEXT_LOOP (PCB->Data);
  {
    MyMoveTextLowLevel (layer, text, dx, dy);
    AddObjectToMoveUndoList (TEXT_TYPE, NULL, NULL, text, dx, dy);
  }
  ENDALL_LOOP;
  ALLPOLYGON_LOOP (PCB->Data);
  {
    /*
     * XXX MovePolygonLowLevel does not mean "no gui" like
     * XXX MoveElementLowLevel, it doesn't even handle layer
     * XXX tree activity.
     */
    MyMovePolygonLowLevel (PCB->Data, layer, polygon, dx, dy);
    AddObjectToMoveUndoList (POLYGON_TYPE, NULL, NULL, polygon, dx, dy);
  }
  ENDALL_LOOP;
}
Exemple #8
0
/* ---------------------------------------------------------------------------
 * get next slot for a via, allocates memory if necessary
 */
PinTypePtr
GetViaMemory (DataTypePtr Data)
{
  PinTypePtr via = Data->Via;

  /* realloc new memory if necessary and clear it */
  if (Data->ViaN >= Data->ViaMax)
    {
      Data->ViaMax += STEP_VIA;
      if (Data->via_tree)
	r_destroy_tree (&Data->via_tree);
      via = (PinTypePtr)realloc (via, Data->ViaMax * sizeof (PinType));
      Data->Via = via;
      memset (via + Data->ViaN, 0, STEP_VIA * sizeof (PinType));
      Data->via_tree = r_create_tree (NULL, 0, 0);
      VIA_LOOP (Data);
      {
	r_insert_entry (Data->via_tree, (BoxType *) via, 0);
      }
      END_LOOP;
    }
  return (via + Data->ViaN++);
}
Exemple #9
0
/*!
 * \brief Writes a net to the file provided.
 *
 * The net name is passed through the "net" and should be 14 characters
 * max.\n
 * The function scans through pads, pins and vias  and looks for the
 * \c FOUNDFLAG.\n
 * Once the object has been added to the net list the \c VISITFLAG is
 * set on that object.
 *
 * \todo 1) The bottom layer is always written as layer #2 (A02).\n
 *          It could output the actual layer number (example: A06 on a
 *          6 layer board).\n
 *          But I could not find an easy way to do this...
 *
 * \todo 2) Objects with mutiple connections could have the "M"
 *          (column 32) field written to indicate a Mid Net Point.
 */
void
IPCD356_WriteNet (FILE * fd, char *net)
{
  int padx, pady, tmp;

  ELEMENT_LOOP (PCB->Data);
  PAD_LOOP (element);
  if (TEST_FLAG (FOUNDFLAG, pad))
    {
      fprintf (fd, "327%-17.14s", net); /* Net Name. */
      fprintf (fd, "%-6.6s", element->Name[1].TextString); /* Refdes. */
      fprintf (fd, "-%-4.4s", pad->Number); /* pin number. */
      fprintf (fd, " "); /*! \todo Midpoint indicator (M). */
      fprintf (fd, "      "); /* Drilled hole Id (blank for pads). */
      if (TEST_FLAG (ONSOLDERFLAG, pad) == true)
        {
          fprintf (fd, "A02"); /*! \todo Put actual layer # for bottom side. */
        }
      else
        {
          fprintf (fd, "A01"); /* Top side. */
        }
      padx = (pad->Point1.X + pad->Point2.X) / 2; /* X location in PCB units. */
      pady = (PCB->MaxHeight - ((pad->Point1.Y + pad->Point2.Y) / 2)); /* Y location in PCB units. */

      if (strcmp (Settings.grid_unit->suffix, "mil") == 0)
        {
          padx = padx / 2540; /* X location in 0.0001". */
          pady = pady / 2540; /* Y location in 0.0001". */
        }
      else
        {
          padx = padx / 1000; /* X location in 0.001 mm. */
          pady = pady / 1000; /* Y location in 0.001 mm. */
        }
      fprintf (fd, "X%+6.6d", padx); /* X Pad center. */
      fprintf (fd, "Y%+6.6d", pady); /* Y pad center. */

      padx = (pad->Thickness + (pad->Point2.X - pad->Point1.X)); /* Pad dimension X in PCB units. */
      pady = (pad->Thickness + (pad->Point2.Y - pad->Point1.Y)); /* Pad dimension Y in PCB units. */

      if (strcmp(Settings.grid_unit->suffix, "mil") == 0)
        {
          padx = padx / 2540; /* X location in 0.0001". */
          pady = pady / 2540; /* Y location in 0.0001". */
        }
      else
        {
          padx = padx / 1000;	// X location in 0.001mm
          pady = pady / 1000;	// Y location in 0.001mm
        }

      fprintf (fd, "X%4.4d", padx);
      fprintf (fd, "Y%4.4d", pady);
      fprintf (fd, "R000"); /* Rotation (0 degrees). */
      fprintf (fd, " "); /* Column 72 should be left blank. */
      if (pad->Mask > 0)    
        {
          if (TEST_FLAG (ONSOLDERFLAG, pad) == true)
            {
              fprintf(fd, "S2"); /* Soldermask on bottom side. */
            }
          else
            {
              fprintf(fd, "S1"); /* SolderMask on top side. */
            }
        }
      else
        {
          fprintf(fd, "S3"); /* No soldermask. */
        }
      fprintf (fd, "      "); /* Padding. */
      fprintf (fd, "\n");
      SET_FLAG (VISITFLAG, pad);
    }

  END_LOOP; /* Pad. */
  PIN_LOOP (element);
  if (TEST_FLAG (FOUNDFLAG, pin))
    {
      if (TEST_FLAG (HOLEFLAG, pin)) /* Non plated? */
        {
          fprintf (fd, "367%-17.14s", net); /* Net Name. */
        }
      else
        {
          fprintf (fd, "317%-17.14s", net); /* Net Name. */
        }
      fprintf (fd, "%-6.6s", element->Name[1].TextString); /* Refdes. */
      fprintf (fd, "-%-4.4s", pin->Number); /* Pin number. */
      fprintf (fd, " "); /*! \todo Midpoint indicator (M). */
      tmp = pin->DrillingHole;
      if (strcmp (Settings.grid_unit->suffix, "mil") == 0)
        {
          tmp = tmp / 2540; /* 0.0001". */
        }
      else
        {
          tmp = tmp / 1000; /* 0.001 mm. */
        }

      if (TEST_FLAG (HOLEFLAG, pin))
        {
          fprintf (fd, "D%-4.4dU", tmp); /* Unplated Drilled hole Id. */
        }
      else
        {
          fprintf (fd, "D%-4.4dP", tmp); /* Plated drill hole. */
        }
      fprintf (fd, "A00"); /* Accessible from both sides. */
      padx = pin->X; /* X location in PCB units. */
      pady = (PCB->MaxHeight - pin->Y); /* Y location in PCB units.*/

      if (strcmp (Settings.grid_unit->suffix, "mil") == 0)
        {
          padx = padx / 2540; /* X location in 0.0001". */
          pady = pady / 2540; /* Y location in 0.0001". */
        }
      else
        {
          padx = padx / 1000; /* X location in 0.001 mm. */
          pady = pady / 1000; /* Y location in 0.001 mm. */
        }

      fprintf (fd, "X%+6.6d", padx); /* X Pad center. */
      fprintf (fd, "Y%+6.6d", pady); /* Y pad center. */

      padx = pin->Thickness;

      if (strcmp (Settings.grid_unit->suffix, "mil") == 0)
        {
          padx = padx / 2540; /* X location in 0.0001". */
        }
      else
        {
          padx = padx / 1000; /* X location in 0.001 mm. */
        }

      fprintf (fd, "X%4.4d", padx); /* Pad dimension X. */
      if (TEST_FLAG (SQUAREFLAG, pin))
        {
          fprintf (fd, "Y%4.4d", padx); /* Pad dimension Y. */
        }
      else
        {
          fprintf (fd, "Y0000"); /*  Y is 0 for round pins. */
        }
      fprintf (fd, "R000"); /* Rotation (0 degrees). */
      fprintf (fd, " "); /* Column 72 should be left blank.*/
      if (pin->Mask > 0)    
        {
          fprintf(fd, "S0"); /* No Soldermask. */
        }
      else
        {
          fprintf(fd, "S3"); /* Soldermask on both sides. */
        }
      fprintf (fd, "      "); /* Padding. */

      fprintf (fd, "\n");

      SET_FLAG (VISITFLAG, pin);

    }

  END_LOOP; /* Pin. */
  END_LOOP; /* Element */

  VIA_LOOP (PCB->Data);
  if (TEST_FLAG (FOUNDFLAG, via))
    {
      if (TEST_FLAG (HOLEFLAG, via)) /* Non plated ? */
        {
          fprintf (fd, "367%-17.14s", net); /* Net Name. */
        }
      else
        {
          fprintf (fd, "317%-17.14s", net); /* Net Name. */
        }
      fprintf (fd, "VIA   "); /* Refdes. */
      fprintf (fd, "-    "); /* Pin number. */
      fprintf (fd, " "); /*! \todo Midpoint indicator (M). */
      tmp = via->DrillingHole;	
      if (strcmp (Settings.grid_unit->suffix, "mil") == 0)
        {
          tmp = tmp / 2540; /* 0.0001". */
        }
      else
        {
          tmp = tmp / 1000; /* 0.001 mm. */
        }

      if (TEST_FLAG (HOLEFLAG, via))
        {
          fprintf (fd, "D%-4.4dU", tmp); /* Unplated Drilled hole Id. */
        }
      else
        {
          fprintf (fd, "D%-4.4dP", tmp); /* Plated drill hole. */
        }
      fprintf (fd, "A00"); /* Accessible from both sides. */
      padx = via->X; /* X location in PCB units. */
      pady = (PCB->MaxHeight - via->Y); /* Y location in PCB units. */

      if (strcmp (Settings.grid_unit->suffix, "mil") == 0)
        {
          padx = padx / 2540; /* X location in 0.0001". */
          pady = pady / 2540; /* Y location in 0.0001". */
        }
      else
        {
          padx = padx / 1000; /* X location in 0.001 mm. */
          pady = pady / 1000; /* Y location in 0.001 mm. */
        }

      fprintf (fd, "X%+6.6d", padx); /* X Pad center. */
      fprintf (fd, "Y%+6.6d", pady); /* Y pad center. */

      padx = via->Thickness;
      
      if (strcmp (Settings.grid_unit->suffix, "mil") == 0)
        {
          padx = padx / 2540; /* X location in 0.0001". */
        }
      else
        {
          padx = padx / 1000; /* X location in 0.001 mm. */
        }

      fprintf (fd, "X%4.4d", padx); /* Pad dimension X. */
      fprintf (fd, "Y0000"); /* Y is 0 for round pins (vias always round?). */
      fprintf (fd, "R000"); /* Rotation (0 degrees). */
      fprintf (fd, " "); /* Column 72 should be left blank. */
      if (via->Mask > 0)    
        {
          fprintf(fd, "S0"); /* No Soldermask. */
        }
      else
        {
          fprintf(fd, "S3"); /* Soldermask on both sides. */
        }
      fprintf (fd, "      "); /* Padding. */
      fprintf (fd, "\n");
      SET_FLAG (VISITFLAG, via);
    }

  END_LOOP; /* Via. */
}
Exemple #10
0
/* ---------------------------------------------------------------------------
 * creates a new via
 */
PinTypePtr
CreateNewVia (DataTypePtr Data,
	      LocationType X, LocationType Y,
	      BDimension Thickness, BDimension Clearance, BDimension Mask,
	      BDimension DrillingHole, char *Name, FlagType Flags)
{
  PinTypePtr Via;

  if (!be_lenient)
    {
      VIA_LOOP (Data);
      {
	if (SQUARE (via->X - X) + SQUARE (via->Y - Y) <=
	    SQUARE (via->DrillingHole / 2 + DrillingHole / 2)) 
	  {
	    Message (_("Dropping via at (%d, %d) because it's hole would overlap with the via "
		       "at (%d, %d)\n"), X/100, Y/100, via->X/100, via->Y/100);
	    return (NULL);		/* don't allow via stacking */
	  }
      }
      END_LOOP;
    }

  Via = GetViaMemory (Data);

  if (!Via)
    return (Via);
  /* copy values */
  Via->X = X;
  Via->Y = Y;
  Via->Thickness = Thickness;
  Via->Clearance = Clearance;
  Via->Mask = Mask;
  Via->DrillingHole = vendorDrillMap (DrillingHole);
  if (Via->DrillingHole != DrillingHole)
    {
      Message (_
	       ("Mapped via drill hole to %.2f mils from %.2f mils per vendor table\n"),
	       0.01 * Via->DrillingHole, 0.01 * DrillingHole);
    }

  Via->Name = STRDUP (Name);
  Via->Flags = Flags;
  CLEAR_FLAG (WARNFLAG, Via);
  SET_FLAG (VIAFLAG, Via);
  Via->ID = ID++;

  /* 
   * don't complain about MIN_PINORVIACOPPER on a mounting hole (pure
   * hole)
   */
  if (!TEST_FLAG (HOLEFLAG, Via) &&
      (Via->Thickness < Via->DrillingHole + MIN_PINORVIACOPPER))
    {
      Via->Thickness = Via->DrillingHole + MIN_PINORVIACOPPER;
      Message (_("Increased via thickness to %.2f mils to allow enough copper"
		 " at (%.2f,%.2f).\n"),
	       0.01 * Via->Thickness, 0.01 * Via->X, 0.01 * Via->Y);
    }

  SetPinBoundingBox (Via);
  if (!Data->via_tree)
    Data->via_tree = r_create_tree (NULL, 0, 0);
  r_insert_entry (Data->via_tree, (BoxTypePtr) Via, 0);
  return (Via);
}
Exemple #11
0
/* ---------------------------------------------------------------------------
 * pastes the contents of the buffer to the layout. Only visible objects
 * are handled by the routine.
 */
bool
CopyPastebufferToLayout (Coord X, Coord Y)
{
  Cardinal i;
  bool changed = false;

#ifdef DEBUG
  printf("Entering CopyPastebufferToLayout.....\n");
#endif

  /* set movement vector */
  DeltaX = X - PASTEBUFFER->X, DeltaY = Y - PASTEBUFFER->Y;

  /* paste all layers */
  for (i = 0; i < max_copper_layer + 2; i++)
    {
      LayerType *sourcelayer = &PASTEBUFFER->Data->Layer[i];
      LayerType *destlayer = LAYER_PTR (i);

      if (destlayer->On)
	{
	  changed = changed ||
	    (sourcelayer->LineN != 0) ||
	    (sourcelayer->ArcN != 0) ||
	    (sourcelayer->PolygonN != 0) || (sourcelayer->TextN != 0);
	  LINE_LOOP (sourcelayer);
	  {
	    CopyLine (destlayer, line);
	  }
	  END_LOOP;
	  ARC_LOOP (sourcelayer);
	  {
	    CopyArc (destlayer, arc);
	  }
	  END_LOOP;
	  TEXT_LOOP (sourcelayer);
	  {
	    CopyText (destlayer, text);
	  }
	  END_LOOP;
	  POLYGON_LOOP (sourcelayer);
	  {
	    CopyPolygon (destlayer, polygon);
	  }
	  END_LOOP;
	}
    }

  /* paste elements */
  if (PCB->PinOn && PCB->ElementOn)
    {
      ELEMENT_LOOP (PASTEBUFFER->Data);
      {
#ifdef DEBUG
	printf("In CopyPastebufferToLayout, pasting element %s\n",
	      element->Name[1].TextString);
#endif
	if (FRONT (element) || PCB->InvisibleObjectsOn)
	  {
	    CopyElement (element);
	    changed = true;
	  }
      }
      END_LOOP;
    }

  /* finally the vias */
  if (PCB->ViaOn)
    {
      changed |= (PASTEBUFFER->Data->ViaN != 0);
      VIA_LOOP (PASTEBUFFER->Data);
      {
	CopyVia (via);
      }
      END_LOOP;
    }

  if (changed)
    {
      Draw ();
      IncrementUndoSerialNumber ();
    }

#ifdef DEBUG
  printf("  .... Leaving CopyPastebufferToLayout.\n");
#endif

  return (changed);
}
Exemple #12
0
DrillInfoTypePtr
GetDrillInfo (DataTypePtr top)
{
  DrillInfoTypePtr AllDrills;
  DrillTypePtr Drill = NULL;
  DrillType savedrill, swapdrill;
  bool DrillFound = false;
  bool NewDrill;

  AllDrills = (DrillInfoTypePtr)calloc (1, sizeof (DrillInfoType));
  ALLPIN_LOOP (top);
  {
    if (!DrillFound)
      {
	DrillFound = true;
	Drill = GetDrillInfoDrillMemory (AllDrills);
	InitializeDrill (Drill, pin, element);
      }
    else
      {
	if (Drill->DrillSize == pin->DrillingHole)
	  FillDrill (Drill, element, pin);
	else
	  {
	    NewDrill = false;
	    DRILL_LOOP (AllDrills);
	    {
	      if (drill->DrillSize == pin->DrillingHole)
		{
		  Drill = drill;
		  FillDrill (Drill, element, pin);
		  break;
		}
	      else if (drill->DrillSize > pin->DrillingHole)
		{
		  if (!NewDrill)
		    {
		      NewDrill = true;
		      InitializeDrill (&swapdrill, pin, element);
		      Drill = GetDrillInfoDrillMemory (AllDrills);
		      Drill->DrillSize = pin->DrillingHole + 1;
		      Drill = drill;
		    }
		  savedrill = *drill;
		  *drill = swapdrill;
		  swapdrill = savedrill;
		}
	    }
	    END_LOOP;
	    if (AllDrills->Drill[AllDrills->DrillN - 1].DrillSize <
		pin->DrillingHole)
	      {
		Drill = GetDrillInfoDrillMemory (AllDrills);
		InitializeDrill (Drill, pin, element);
	      }
	  }
      }
  }
  ENDALL_LOOP;
  VIA_LOOP (top);
  {
    if (!DrillFound)
      {
	DrillFound = true;
	Drill = GetDrillInfoDrillMemory (AllDrills);
	Drill->DrillSize = via->DrillingHole;
	FillDrill (Drill, NULL, via);
      }
    else
      {
	if (Drill->DrillSize != via->DrillingHole)
	  {
	    DRILL_LOOP (AllDrills);
	    {
	      if (drill->DrillSize == via->DrillingHole)
		{
		  Drill = drill;
		  FillDrill (Drill, NULL, via);
		  break;
		}
	    }
	    END_LOOP;
	    if (Drill->DrillSize != via->DrillingHole)
	      {
		Drill = GetDrillInfoDrillMemory (AllDrills);
		Drill->DrillSize = via->DrillingHole;
		FillDrill (Drill, NULL, via);
	      }
	  }
	else
	  FillDrill (Drill, NULL, via);
      }
  }
  END_LOOP;
  qsort (AllDrills->Drill, AllDrills->DrillN, sizeof (DrillType), DrillQSort);
  return (AllDrills);
}
Exemple #13
0
/* ---------------------------------------------------------------------------
 * free memory used by data struct
 */
void
FreeDataMemory (DataTypePtr Data)
{
  LayerTypePtr layer;
  int i;

  if (Data)
    {
      VIA_LOOP (Data);
      {
	MYFREE (via->Name);
      }
      END_LOOP;
      ELEMENT_LOOP (Data);
      {
	FreeElementMemory (element);
      }
      END_LOOP;

      for (layer = Data->Layer, i = 0; i < MAX_LAYER + 2; layer++, i++)
	{
	  FreeAttributeListMemory (&layer->Attributes);
	  TEXT_LOOP (layer);
	  {
	    MYFREE (text->TextString);
	  }
	  END_LOOP;
	  if (layer->Name)
	    MYFREE (layer->Name);
	  LINE_LOOP (layer);
	  {
	    if (line->Number)
	      MYFREE (line->Number);
	  }
	  END_LOOP;
	  MYFREE (layer->Line);
	  MYFREE (layer->Arc);
	  MYFREE (layer->Text);
	  POLYGON_LOOP (layer);
	  {
	    FreePolygonMemory (polygon);
	  }
	  END_LOOP;
	  MYFREE (layer->Polygon);
	  if (layer->line_tree)
	    r_destroy_tree (&layer->line_tree);
	  if (layer->arc_tree)
	    r_destroy_tree (&layer->arc_tree);
	  if (layer->text_tree)
	    r_destroy_tree (&layer->text_tree);
	  if (layer->polygon_tree)
	    r_destroy_tree (&layer->polygon_tree);
	}

      if (Data->element_tree)
	r_destroy_tree (&Data->element_tree);
      for (i = 0; i < MAX_ELEMENTNAMES; i++)
	if (Data->name_tree[i])
	  r_destroy_tree (&Data->name_tree[i]);
      if (Data->via_tree)
	r_destroy_tree (&Data->via_tree);
      if (Data->pin_tree)
	r_destroy_tree (&Data->pin_tree);
      if (Data->pad_tree)
	r_destroy_tree (&Data->pad_tree);
      if (Data->rat_tree)
	r_destroy_tree (&Data->rat_tree);
      /* clear struct */
      memset (Data, 0, sizeof (DataType));
    }
  else
    {
      fprintf (stderr, "Warning:  Tried to FreeDataMemory(null)\n");
    }
}
Exemple #14
0
/*!
 * \brief Creates a new via.
 */
PinType *
CreateNewVia (DataType *Data,
	      Coord X, Coord Y,
	      Coord Thickness, Coord Clearance, Coord Mask,
	      Coord DrillingHole, char *Name, FlagType Flags)
{
  PinType *Via;

  if (!be_lenient)
    {
      VIA_LOOP (Data);
      {
	if (Distance (X, Y, via->X, via->Y) <=
	    via->DrillingHole / 2 + DrillingHole / 2)
	  {
	    Message (_("%m+Dropping via at %$mD because it's hole would overlap with the via "
		       "at %$mD\n"), Settings.grid_unit->allow, X, Y, via->X, via->Y);
	    return (NULL);		/* don't allow via stacking */
	  }
      }
      END_LOOP;
    }

  Via = GetViaMemory (Data);

  if (!Via)
    return (Via);
  /* copy values */
  Via->X = X;
  Via->Y = Y;
  Via->Thickness = Thickness;
  Via->Clearance = Clearance;
  Via->Mask = Mask;
  Via->DrillingHole = vendorDrillMap (DrillingHole);
  if (Via->DrillingHole != DrillingHole)
    {
      Message (_("%m+Mapped via drill hole to %$mS from %$mS per vendor table\n"),
	       Settings.grid_unit->allow, Via->DrillingHole, DrillingHole);
    }

  Via->Name = STRDUP (Name);
  Via->Flags = Flags;
  CLEAR_FLAG (WARNFLAG, Via);
  SET_FLAG (VIAFLAG, Via);
  Via->ID = ID++;

  /* 
   * don't complain about MIN_PINORVIACOPPER on a mounting hole (pure
   * hole)
   */
  if (!TEST_FLAG (HOLEFLAG, Via) &&
      (Via->Thickness < Via->DrillingHole + MIN_PINORVIACOPPER))
    {
      Via->Thickness = Via->DrillingHole + MIN_PINORVIACOPPER;
      Message (_("%m+Increased via thickness to %$mS to allow enough copper"
		 " at %$mD.\n"),
	       Settings.grid_unit->allow, Via->Thickness, Via->X, Via->Y);
    }

  SetPinBoundingBox (Via);
  if (!Data->via_tree)
    Data->via_tree = r_create_tree (NULL, 0, 0);
  r_insert_entry (Data->via_tree, (BoxType *) Via, 0);
  return (Via);
}
Exemple #15
0
static void
apply_vendor_map (void)
{
  int i;
  int changed, tot;
  bool state;

  state = vendorMapEnable;

  /* enable mapping */
  vendorMapEnable = true;

  /* reset our counts */
  changed = 0;
  tot = 0;

  /* If we have loaded vendor drills, then apply them to the design */
  if (n_vendor_drills > 0)
    {

      /* first all the vias */
      VIA_LOOP (PCB->Data);
      {
	tot++;
	if (via->DrillingHole != vendorDrillMap (via->DrillingHole))
	  {
	    /* only change unlocked vias */
	    if (!TEST_FLAG (LOCKFLAG, via))
	      {
		if (ChangeObject2ndSize (VIA_TYPE, via, NULL, NULL,
					 vendorDrillMap (via->DrillingHole),
					 true, false))
		  changed++;
		else
		  {
		    Message (_
			     ("Via at %.2f, %.2f not changed.  Possible reasons:\n"
			      "\t- pad size too small\n"
			      "\t- new size would be too large or too small\n"),
			     0.01 * via->X, 0.01 * via->Y);
		  }
	      }
	    else
	      {
		Message (_("Locked via at %.2f, %.2f not changed.\n"),
			 0.01 * via->X, 0.01 * via->Y);
	      }
	  }
      }
      END_LOOP;

      /* and now the pins */
      ELEMENT_LOOP (PCB->Data);
      {
	/*
	 * first figure out if this element should be skipped for some
	 * reason
	 */
	if (vendorIsElementMappable (element))
	  {
	    /* the element is ok to modify, so iterate over its pins */
	    PIN_LOOP (element);
	    {
	      tot++;
	      if (pin->DrillingHole != vendorDrillMap (pin->DrillingHole))
		{
		  if (!TEST_FLAG (LOCKFLAG, pin))
		    {
		      if (ChangeObject2ndSize (PIN_TYPE, element, pin, NULL,
					       vendorDrillMap (pin->
							       DrillingHole),
					       true, false))
			changed++;
		      else
			{
			  Message (_
				   ("Pin %s (%s) at %.2f, %.2f (element %s, %s, %s) not changed.\n"
				    "\tPossible reasons:\n"
				    "\t- pad size too small\n"
				    "\t- new size would be too large or too small\n"),
				   UNKNOWN (pin->Number), UNKNOWN (pin->Name),
				   0.01 * pin->X, 0.01 * pin->Y,
				   UNKNOWN (NAMEONPCB_NAME (element)),
				   UNKNOWN (VALUE_NAME (element)),
				   UNKNOWN (DESCRIPTION_NAME (element)));
			}
		    }
		  else
		    {
		      Message (_
			       ("Locked pin at %-6.2f, %-6.2f not changed.\n"),
			       0.01 * pin->X, 0.01 * pin->Y);
		    }
		}
	    }
	    END_LOOP;
	  }
      }
      END_LOOP;

      Message (_("Updated %d drill sizes out of %d total\n"), changed, tot);

      /* Update the current Via */
      if (Settings.ViaDrillingHole !=
	  vendorDrillMap (Settings.ViaDrillingHole))
	{
	  changed++;
	  Settings.ViaDrillingHole =
	    vendorDrillMap (Settings.ViaDrillingHole);
	  Message (_("Adjusted active via hole size to be %6.2f mils\n"),
		   0.01 * Settings.ViaDrillingHole);
	}

      /* and update the vias for the various routing styles */
      for (i = 0; i < NUM_STYLES; i++)
	{
	  if (PCB->RouteStyle[i].Hole !=
	      vendorDrillMap (PCB->RouteStyle[i].Hole))
	    {
	      changed++;
	      PCB->RouteStyle[i].Hole =
		vendorDrillMap (PCB->RouteStyle[i].Hole);
	      Message (_
		       ("Adjusted %s routing style via hole size to be %6.2f mils\n"),
		       PCB->RouteStyle[i].Name,
		       0.01 * PCB->RouteStyle[i].Hole);
	      if (PCB->RouteStyle[i].Diameter <
		  PCB->RouteStyle[i].Hole + MIN_PINORVIACOPPER)
		{
		  PCB->RouteStyle[i].Diameter =
		    PCB->RouteStyle[i].Hole + MIN_PINORVIACOPPER;
		  Message (_
			   ("Increased %s routing style via diameter to %6.2f mils\n"),
			   PCB->RouteStyle[i].Name,
			   0.01 * PCB->RouteStyle[i].Diameter);
		}
	    }
	}

      /* 
       * if we've changed anything, indicate that we need to save the
       * file, redraw things, and make sure we can undo.
       */
      if (changed)
	{
	  SetChangedFlag (true);
	  Redraw ();
	  IncrementUndoSerialNumber ();
	}
    }

  /* restore mapping on/off */
  vendorMapEnable = state;
}
Exemple #16
0
/* ---------------------------------------------------------------------------
 * searches for a object by it's unique ID. It doesn't matter if
 * the object is visible or not. The search is performed on a PCB, a
 * buffer or on the remove list.
 * The calling routine passes two pointers to allocated memory for storing
 * the results. 
 * A type value is returned too which is NO_TYPE if no objects has been found.
 */
int
SearchObjectByID (DataTypePtr Base,
		  void **Result1, void **Result2, void **Result3, int ID,
		  int type)
{
  if (type == LINE_TYPE || type == LINEPOINT_TYPE)
    {
      ALLLINE_LOOP (Base);
      {
	if (line->ID == ID)
	  {
	    *Result1 = (void *) layer;
	    *Result2 = *Result3 = (void *) line;
	    return (LINE_TYPE);
	  }
	if (line->Point1.ID == ID)
	  {
	    *Result1 = (void *) layer;
	    *Result2 = (void *) line;
	    *Result3 = (void *) &line->Point1;
	    return (LINEPOINT_TYPE);
	  }
	if (line->Point2.ID == ID)
	  {
	    *Result1 = (void *) layer;
	    *Result2 = (void *) line;
	    *Result3 = (void *) &line->Point2;
	    return (LINEPOINT_TYPE);
	  }
      }
      ENDALL_LOOP;
    }
  if (type == ARC_TYPE)
    {
      ALLARC_LOOP (Base);
      {
	if (arc->ID == ID)
	  {
	    *Result1 = (void *) layer;
	    *Result2 = *Result3 = (void *) arc;
	    return (ARC_TYPE);
	  }
      }
      ENDALL_LOOP;
    }

  if (type == TEXT_TYPE)
    {
      ALLTEXT_LOOP (Base);
      {
	if (text->ID == ID)
	  {
	    *Result1 = (void *) layer;
	    *Result2 = *Result3 = (void *) text;
	    return (TEXT_TYPE);
	  }
      }
      ENDALL_LOOP;
    }

  if (type == POLYGON_TYPE || type == POLYGONPOINT_TYPE)
    {
      ALLPOLYGON_LOOP (Base);
      {
	if (polygon->ID == ID)
	  {
	    *Result1 = (void *) layer;
	    *Result2 = *Result3 = (void *) polygon;
	    return (POLYGON_TYPE);
	  }
	if (type == POLYGONPOINT_TYPE)
	  POLYGONPOINT_LOOP (polygon);
	{
	  if (point->ID == ID)
	    {
	      *Result1 = (void *) layer;
	      *Result2 = (void *) polygon;
	      *Result3 = (void *) point;
	      return (POLYGONPOINT_TYPE);
	    }
	}
	END_LOOP;
      }
      ENDALL_LOOP;
    }
  if (type == VIA_TYPE)
    {
      VIA_LOOP (Base);
      {
	if (via->ID == ID)
	  {
	    *Result1 = *Result2 = *Result3 = (void *) via;
	    return (VIA_TYPE);
	  }
      }
      END_LOOP;
    }

  if (type == RATLINE_TYPE || type == LINEPOINT_TYPE)
    {
      RAT_LOOP (Base);
      {
	if (line->ID == ID)
	  {
	    *Result1 = *Result2 = *Result3 = (void *) line;
	    return (RATLINE_TYPE);
	  }
	if (line->Point1.ID == ID)
	  {
	    *Result1 = (void *) NULL;
	    *Result2 = (void *) line;
	    *Result3 = (void *) &line->Point1;
	    return (LINEPOINT_TYPE);
	  }
	if (line->Point2.ID == ID)
	  {
	    *Result1 = (void *) NULL;
	    *Result2 = (void *) line;
	    *Result3 = (void *) &line->Point2;
	    return (LINEPOINT_TYPE);
	  }
      }
      END_LOOP;
    }

  if (type == ELEMENT_TYPE || type == PAD_TYPE || type == PIN_TYPE
      || type == ELEMENTLINE_TYPE || type == ELEMENTNAME_TYPE
      || type == ELEMENTARC_TYPE)
    /* check pins and elementnames too */
    ELEMENT_LOOP (Base);
  {
    if (element->ID == ID)
      {
	*Result1 = *Result2 = *Result3 = (void *) element;
	return (ELEMENT_TYPE);
      }
    if (type == ELEMENTLINE_TYPE)
      ELEMENTLINE_LOOP (element);
    {
      if (line->ID == ID)
	{
	  *Result1 = (void *) element;
	  *Result2 = *Result3 = (void *) line;
	  return (ELEMENTLINE_TYPE);
	}
    }
    END_LOOP;
    if (type == ELEMENTARC_TYPE)
      ARC_LOOP (element);
    {
      if (arc->ID == ID)
	{
	  *Result1 = (void *) element;
	  *Result2 = *Result3 = (void *) arc;
	  return (ELEMENTARC_TYPE);
	}
    }
    END_LOOP;
    if (type == ELEMENTNAME_TYPE)
      ELEMENTTEXT_LOOP (element);
    {
      if (text->ID == ID)
	{
	  *Result1 = (void *) element;
	  *Result2 = *Result3 = (void *) text;
	  return (ELEMENTNAME_TYPE);
	}
    }
    END_LOOP;
    if (type == PIN_TYPE)
      PIN_LOOP (element);
    {
      if (pin->ID == ID)
	{
	  *Result1 = (void *) element;
	  *Result2 = *Result3 = (void *) pin;
	  return (PIN_TYPE);
	}
    }
    END_LOOP;
    if (type == PAD_TYPE)
      PAD_LOOP (element);
    {
      if (pad->ID == ID)
	{
	  *Result1 = (void *) element;
	  *Result2 = *Result3 = (void *) pad;
	  return (PAD_TYPE);
	}
    }
    END_LOOP;
  }
  END_LOOP;

  Message ("hace: Internal error, search for ID %d failed\n", ID);
  return (NO_TYPE);
}
Exemple #17
0
/* ----------------------------------------------------------------------
 * selects/unselects all visible objects within the passed box
 * Flag determines if the block is to be selected or unselected
 * returns true if the state of any object has changed
 */
bool
SelectBlock (BoxTypePtr Box, bool Flag)
{
  bool changed = false;

  if (PCB->RatOn || !Flag)
    RAT_LOOP (PCB->Data);
  {
    if (LINE_IN_BOX ((LineTypePtr) line, Box) &&
	!TEST_FLAG (LOCKFLAG, line) && TEST_FLAG (SELECTEDFLAG, line) != Flag)
      {
	AddObjectToFlagUndoList (RATLINE_TYPE, line, line, line);
	ASSIGN_FLAG (SELECTEDFLAG, Flag, line);
	if (PCB->RatOn)
	  DrawRat (line, 0);
	changed = true;
      }
  }
  END_LOOP;

  /* check layers */
  LAYER_LOOP(PCB->Data, max_copper_layer + 2);
  {
    if (layer == & PCB->Data->SILKLAYER)
      {
	if (! (PCB->ElementOn || !Flag))
	  continue;
      }
    else if (layer == & PCB->Data->BACKSILKLAYER)
      {
	if (! (PCB->InvisibleObjectsOn || !Flag))
	  continue;
      }
    else
      if (! (layer->On || !Flag))
	continue;

    LINE_LOOP (layer);
    {
      if (LINE_IN_BOX (line, Box)
	  && !TEST_FLAG (LOCKFLAG, line)
	  && TEST_FLAG (SELECTEDFLAG, line) != Flag)
	{
	  AddObjectToFlagUndoList (LINE_TYPE, layer, line, line);
	  ASSIGN_FLAG (SELECTEDFLAG, Flag, line);
	  if (layer->On)
	    DrawLine (layer, line, 0);
	  changed = true;
	}
    }
    END_LOOP;
    ARC_LOOP (layer);
    {
      if (ARC_IN_BOX (arc, Box)
	  && !TEST_FLAG (LOCKFLAG, arc)
	  && TEST_FLAG (SELECTEDFLAG, arc) != Flag)
	{
	  AddObjectToFlagUndoList (ARC_TYPE, layer, arc, arc);
	  ASSIGN_FLAG (SELECTEDFLAG, Flag, arc);
	  if (layer->On)
	    DrawArc (layer, arc, 0);
	  changed = true;
	}
    }
    END_LOOP;
    TEXT_LOOP (layer);
    {
      if (!Flag || TEXT_IS_VISIBLE(PCB, layer, text))
	{
	  if (TEXT_IN_BOX (text, Box)
	      && !TEST_FLAG (LOCKFLAG, text)
	      && TEST_FLAG (SELECTEDFLAG, text) != Flag)
	    {
	      AddObjectToFlagUndoList (TEXT_TYPE, layer, text, text);
	      ASSIGN_FLAG (SELECTEDFLAG, Flag, text);
	      if (TEXT_IS_VISIBLE(PCB, layer, text))
		DrawText (layer, text, 0);
	      changed = true;
	    }
	}
    }
    END_LOOP;
    POLYGON_LOOP (layer);
    {
      if (POLYGON_IN_BOX (polygon, Box)
	  && !TEST_FLAG (LOCKFLAG, polygon)
	  && TEST_FLAG (SELECTEDFLAG, polygon) != Flag)
	{
	  AddObjectToFlagUndoList (POLYGON_TYPE, layer, polygon, polygon);
	  ASSIGN_FLAG (SELECTEDFLAG, Flag, polygon);
	  if (layer->On)
	    DrawPolygon (layer, polygon, 0);
	  changed = true;
	}
    }
    END_LOOP;
  }
  END_LOOP;

  /* elements */
  ELEMENT_LOOP (PCB->Data);
  {
    {
      bool gotElement = false;
      if ((PCB->ElementOn || !Flag)
	  && !TEST_FLAG (LOCKFLAG, element)
	  && ((TEST_FLAG (ONSOLDERFLAG, element) != 0) == SWAP_IDENT
	      || PCB->InvisibleObjectsOn))
	{
	  if (BOX_IN_BOX
	      (&ELEMENT_TEXT (PCB, element).BoundingBox, Box)
	      && !TEST_FLAG (LOCKFLAG, &ELEMENT_TEXT (PCB, element))
	      && TEST_FLAG (SELECTEDFLAG,
			    &ELEMENT_TEXT (PCB, element)) != Flag)
	    {
	      /* select all names of element */
	      ELEMENTTEXT_LOOP (element);
	      {
		AddObjectToFlagUndoList (ELEMENTNAME_TYPE,
					 element, text, text);
		ASSIGN_FLAG (SELECTEDFLAG, Flag, text);
	      }
	      END_LOOP;
	      if (PCB->ElementOn)
		DrawElementName (element, 0);
	      changed = true;
	    }
	  if ((PCB->PinOn || !Flag) && ELEMENT_IN_BOX (element, Box))
	    if (TEST_FLAG (SELECTEDFLAG, element) != Flag)
	      {
		AddObjectToFlagUndoList (ELEMENT_TYPE,
					 element, element, element);
		ASSIGN_FLAG (SELECTEDFLAG, Flag, element);
		PIN_LOOP (element);
		{
		  if (TEST_FLAG (SELECTEDFLAG, pin) != Flag)
		    {
		      AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
		      ASSIGN_FLAG (SELECTEDFLAG, Flag, pin);
		      if (PCB->PinOn)
			DrawPin (pin, 0);
		      changed = true;
		    }
		}
		END_LOOP;
		PAD_LOOP (element);
		{
		  if (TEST_FLAG (SELECTEDFLAG, pad) != Flag)
		    {
		      AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
		      ASSIGN_FLAG (SELECTEDFLAG, Flag, pad);
		      if (PCB->PinOn)
			DrawPad (pad, 0);
		      changed = true;
		    }
		}
		END_LOOP;
		if (PCB->PinOn)
		  DrawElement (element, 0);
		changed = true;
		gotElement = true;
	      }
	}
      if ((PCB->PinOn || !Flag) && !TEST_FLAG (LOCKFLAG, element) && !gotElement)
	{
	  PIN_LOOP (element);
	  {
	    if ((VIA_OR_PIN_IN_BOX (pin, Box)
		 && TEST_FLAG (SELECTEDFLAG, pin) != Flag))
	      {
		AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
		ASSIGN_FLAG (SELECTEDFLAG, Flag, pin);
		if (PCB->PinOn)
		  DrawPin (pin, 0);
		changed = true;
	      }
	  }
	  END_LOOP;
	  PAD_LOOP (element);
	  {
	    if (PAD_IN_BOX (pad, Box)
		&& TEST_FLAG (SELECTEDFLAG, pad) != Flag)
	      {
		AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
		ASSIGN_FLAG (SELECTEDFLAG, Flag, pad);
		if (PCB->PinOn)
		  DrawPad (pad, 0);
		changed = true;
	      }
	  }
	  END_LOOP;
	}
    }
  }
  END_LOOP;
  /* end with vias */
  if (PCB->ViaOn || !Flag)
    VIA_LOOP (PCB->Data);
  {
    if (VIA_OR_PIN_IN_BOX (via, Box)
	&& !TEST_FLAG (LOCKFLAG, via)
	&& TEST_FLAG (SELECTEDFLAG, via) != Flag)
      {
	AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
	ASSIGN_FLAG (SELECTEDFLAG, Flag, via);
	if (PCB->ViaOn)
	  DrawVia (via, 0);
	changed = true;
      }
  }
  END_LOOP;
  if (changed)
    {
      Draw ();
      IncrementUndoSerialNumber ();
    }
  return (changed);
}
Exemple #18
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);
}
Exemple #19
0
/* ----------------------------------------------------------------------
 * performs several operations on selected objects which are also visible
 * The lowlevel procedures are passed together with additional information
 * resets the selected flag if requested
 * returns true if anything has changed
 */
bool
SelectedOperation (ObjectFunctionTypePtr F, bool Reset, int type)
{
  bool changed = false;

  /* check lines */
  if (type & LINE_TYPE && F->Line)
    VISIBLELINE_LOOP (PCB->Data);
  {
    if (TEST_FLAG (SELECTEDFLAG, line))
      {
	if (Reset)
	  {
	    AddObjectToFlagUndoList (LINE_TYPE, layer, line, line);
	    CLEAR_FLAG (SELECTEDFLAG, line);
	  }
	F->Line (layer, line);
	changed = true;
      }
  }
  ENDALL_LOOP;

  /* check arcs */
  if (type & ARC_TYPE && F->Arc)
    VISIBLEARC_LOOP (PCB->Data);
  {
    if (TEST_FLAG (SELECTEDFLAG, arc))
      {
	if (Reset)
	  {
	    AddObjectToFlagUndoList (ARC_TYPE, layer, arc, arc);
	    CLEAR_FLAG (SELECTEDFLAG, arc);
	  }
	F->Arc (layer, arc);
	changed = true;
      }
  }
  ENDALL_LOOP;

  /* check text */
  if (type & TEXT_TYPE && F->Text)
    ALLTEXT_LOOP (PCB->Data);
  {
    if (TEST_FLAG (SELECTEDFLAG, text) && TEXT_IS_VISIBLE (PCB, layer, text))
      {
	if (Reset)
	  {
	    AddObjectToFlagUndoList (TEXT_TYPE, layer, text, text);
	    CLEAR_FLAG (SELECTEDFLAG, text);
	  }
	F->Text (layer, text);
	changed = true;
      }
  }
  ENDALL_LOOP;

  /* check polygons */
  if (type & POLYGON_TYPE && F->Polygon)
    VISIBLEPOLYGON_LOOP (PCB->Data);
  {
    if (TEST_FLAG (SELECTEDFLAG, polygon))
      {
	if (Reset)
	  {
	    AddObjectToFlagUndoList (POLYGON_TYPE, layer, polygon, polygon);
	    CLEAR_FLAG (SELECTEDFLAG, polygon);
	  }
	F->Polygon (layer, polygon);
	changed = true;
      }
  }
  ENDALL_LOOP;

  /* elements silkscreen */
  if (type & ELEMENT_TYPE && PCB->ElementOn && F->Element)
    ELEMENT_LOOP (PCB->Data);
  {
    if (TEST_FLAG (SELECTEDFLAG, element))
      {
	if (Reset)
	  {
	    AddObjectToFlagUndoList (ELEMENT_TYPE, element, element, element);
	    CLEAR_FLAG (SELECTEDFLAG, element);
	  }
	F->Element (element);
	changed = true;
      }
  }
  END_LOOP;
  if (type & ELEMENTNAME_TYPE && PCB->ElementOn && F->ElementName)
    ELEMENT_LOOP (PCB->Data);
  {
    if (TEST_FLAG (SELECTEDFLAG, &ELEMENT_TEXT (PCB, element)))
      {
	if (Reset)
	  {
	    AddObjectToFlagUndoList (ELEMENTNAME_TYPE,
				     element,
				     &ELEMENT_TEXT (PCB, element),
				     &ELEMENT_TEXT (PCB, element));
	    CLEAR_FLAG (SELECTEDFLAG, &ELEMENT_TEXT (PCB, element));
	  }
	F->ElementName (element);
	changed = true;
      }
  }
  END_LOOP;

  if (type & PIN_TYPE && PCB->PinOn && F->Pin)
    ELEMENT_LOOP (PCB->Data);
  {
    PIN_LOOP (element);
    {
      if (TEST_FLAG (SELECTEDFLAG, pin))
	{
	  if (Reset)
	    {
	      AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
	      CLEAR_FLAG (SELECTEDFLAG, pin);
	    }
	  F->Pin (element, pin);
	  changed = true;
	}
    }
    END_LOOP;
  }
  END_LOOP;

  if (type & PAD_TYPE && PCB->PinOn && F->Pad)
    ELEMENT_LOOP (PCB->Data);
  {
    PAD_LOOP (element);
    {
      if (TEST_FLAG (SELECTEDFLAG, pad))
	{
	  if (Reset)
	    {
	      AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
	      CLEAR_FLAG (SELECTEDFLAG, pad);
	    }
	  F->Pad (element, pad);
	  changed = true;
	}
    }
    END_LOOP;
  }
  END_LOOP;

  /* process vias */
  if (type & VIA_TYPE && PCB->ViaOn && F->Via)
    VIA_LOOP (PCB->Data);
  {
    if (TEST_FLAG (SELECTEDFLAG, via))
      {
	if (Reset)
	  {
	    AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
	    CLEAR_FLAG (SELECTEDFLAG, via);
	  }
	F->Via (via);
	changed = true;
      }
  }
  END_LOOP;
  /* and rat-lines */
  if (type & RATLINE_TYPE && PCB->RatOn && F->Rat)
    RAT_LOOP (PCB->Data);
  {
    if (TEST_FLAG (SELECTEDFLAG, line))
      {
	if (Reset)
	  {
	    AddObjectToFlagUndoList (RATLINE_TYPE, line, line, line);
	    CLEAR_FLAG (SELECTEDFLAG, line);
	  }
	F->Rat (line);
	changed = true;
      }
  }
  END_LOOP;
  if (Reset && changed)
    IncrementUndoSerialNumber ();
  return (changed);
}
Exemple #20
0
void
FreeRotateBuffer (BufferType *Buffer, Angle angle)
{
  double cosa, sina;

  cosa = cos(angle * M_PI/180.0);
  sina = sin(angle * M_PI/180.0);

  /* rotate vias */
  VIA_LOOP (Buffer->Data);
  {
    r_delete_entry (Buffer->Data->via_tree, (BoxType *)via);
    free_rotate (&via->X, &via->Y, Buffer->X, Buffer->Y, cosa, sina);
    SetPinBoundingBox (via);
    r_insert_entry (Buffer->Data->via_tree, (BoxType *)via, 0);
  }
  END_LOOP;

  /* elements */
  ELEMENT_LOOP (Buffer->Data);
  {
    FreeRotateElementLowLevel (Buffer->Data, element, Buffer->X, Buffer->Y,
			       cosa, sina, angle);
  }
  END_LOOP;

  /* all layer related objects */
  ALLLINE_LOOP (Buffer->Data);
  {
    r_delete_entry (layer->line_tree, (BoxType *)line);
    free_rotate (&line->Point1.X, &line->Point1.Y, Buffer->X, Buffer->Y, cosa, sina);
    free_rotate (&line->Point2.X, &line->Point2.Y, Buffer->X, Buffer->Y, cosa, sina);
    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);
    free_rotate (&arc->X, &arc->Y, Buffer->X, Buffer->Y, cosa, sina);
    arc->StartAngle = NormalizeAngle (arc->StartAngle + angle);
    r_insert_entry (layer->arc_tree, (BoxType *)arc, 0);
  }
  ENDALL_LOOP;
  /* FIXME: rotate text */
  ALLPOLYGON_LOOP (Buffer->Data);
  {
    r_delete_entry (layer->polygon_tree, (BoxType *)polygon);
    POLYGONPOINT_LOOP (polygon);
    {
      free_rotate (&point->X, &point->Y, Buffer->X, Buffer->Y, cosa, sina);
    }
    END_LOOP;
    SetPolygonBoundingBox (polygon);
    r_insert_entry (layer->polygon_tree, (BoxType *)polygon, 0);
  }
  ENDALL_LOOP;

  SetBufferBoundingBox (Buffer);
  SetCrosshairRangeToBuffer ();
}
Exemple #21
0
/* ----------------------------------------------------------------------
 * selects/unselects all objects which were found during a connection scan
 * Flag determines if they are to be selected or unselected
 * returns true if the state of any object has changed
 *
 * text objects and elements cannot be selected by this routine
 */
bool
SelectConnection (bool Flag)
{
  bool changed = false;

  if (PCB->RatOn)
    RAT_LOOP (PCB->Data);
  {
    if (TEST_FLAG (FOUNDFLAG, line))
      {
	AddObjectToFlagUndoList (RATLINE_TYPE, line, line, line);
	ASSIGN_FLAG (SELECTEDFLAG, Flag, line);
	DrawRat (line, 0);
	changed = true;
      }
  }
  END_LOOP;

  VISIBLELINE_LOOP (PCB->Data);
  {
    if (TEST_FLAG (FOUNDFLAG, line) && !TEST_FLAG (LOCKFLAG, line))
      {
	AddObjectToFlagUndoList (LINE_TYPE, layer, line, line);
	ASSIGN_FLAG (SELECTEDFLAG, Flag, line);
	DrawLine (layer, line, 0);
	changed = true;
      }
  }
  ENDALL_LOOP;
  VISIBLEARC_LOOP (PCB->Data);
  {
    if (TEST_FLAG (FOUNDFLAG, arc) && !TEST_FLAG (LOCKFLAG, arc))
      {
	AddObjectToFlagUndoList (ARC_TYPE, layer, arc, arc);
	ASSIGN_FLAG (SELECTEDFLAG, Flag, arc);
	DrawArc (layer, arc, 0);
	changed = true;
      }
  }
  ENDALL_LOOP;
  VISIBLEPOLYGON_LOOP (PCB->Data);
  {
    if (TEST_FLAG (FOUNDFLAG, polygon) && !TEST_FLAG (LOCKFLAG, polygon))
      {
	AddObjectToFlagUndoList (POLYGON_TYPE, layer, polygon, polygon);
	ASSIGN_FLAG (SELECTEDFLAG, Flag, polygon);
	DrawPolygon (layer, polygon, 0);
	changed = true;
      }
  }
  ENDALL_LOOP;

  if (PCB->PinOn && PCB->ElementOn)
    {
      ALLPIN_LOOP (PCB->Data);
      {
	if (!TEST_FLAG (LOCKFLAG, element) && TEST_FLAG (FOUNDFLAG, pin))
	  {
	    AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
	    ASSIGN_FLAG (SELECTEDFLAG, Flag, pin);
	    DrawPin (pin, 0);
	    changed = true;
	  }
      }
      ENDALL_LOOP;
      ALLPAD_LOOP (PCB->Data);
      {
	if (!TEST_FLAG (LOCKFLAG, element) && TEST_FLAG (FOUNDFLAG, pad))
	  {
	    AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
	    ASSIGN_FLAG (SELECTEDFLAG, Flag, pad);
	    DrawPad (pad, 0);
	    changed = true;
	  }
      }
      ENDALL_LOOP;
    }

  if (PCB->ViaOn)
    VIA_LOOP (PCB->Data);
  {
    if (TEST_FLAG (FOUNDFLAG, via) && !TEST_FLAG (LOCKFLAG, via))
      {
	AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
	ASSIGN_FLAG (SELECTEDFLAG, Flag, via);
	DrawVia (via, 0);
	changed = true;
      }
  }
  END_LOOP;
  Draw ();
  return (changed);
}
Exemple #22
0
/* ---------------------------------------------------------------------------
 * free memory used by data struct
 */
void
FreeDataMemory (DataType *data)
{
  LayerType *layer;
  int i;

  if (data == NULL)
    return;

  VIA_LOOP (data);
  {
    free (via->Name);
  }
  END_LOOP;
  g_list_free_full (data->Via, (GDestroyNotify)FreeVia);
  ELEMENT_LOOP (data);
  {
    FreeElementMemory (element);
  }
  END_LOOP;
  g_list_free_full (data->Element, (GDestroyNotify)FreeElement);
  g_list_free_full (data->Rat, (GDestroyNotify)FreeRat);

  for (layer = data->Layer, i = 0; i < MAX_LAYER + 2; layer++, i++)
    {
      FreeAttributeListMemory (&layer->Attributes);
      TEXT_LOOP (layer);
      {
        free (text->TextString);
      }
      END_LOOP;
      if (layer->Name)
        free (layer->Name);
      LINE_LOOP (layer);
      {
        if (line->Number)
          free (line->Number);
      }
      END_LOOP;
      g_list_free_full (layer->Line, (GDestroyNotify)FreeLine);
      g_list_free_full (layer->Arc, (GDestroyNotify)FreeArc);
      g_list_free_full (layer->Text, (GDestroyNotify)FreeText);
      POLYGON_LOOP (layer);
      {
        FreePolygonMemory (polygon);
      }
      END_LOOP;
      g_list_free_full (layer->Polygon, (GDestroyNotify)FreePolygon);
      if (layer->line_tree)
        r_destroy_tree (&layer->line_tree);
      if (layer->arc_tree)
        r_destroy_tree (&layer->arc_tree);
      if (layer->text_tree)
        r_destroy_tree (&layer->text_tree);
      if (layer->polygon_tree)
        r_destroy_tree (&layer->polygon_tree);
    }

  if (data->element_tree)
    r_destroy_tree (&data->element_tree);
  for (i = 0; i < MAX_ELEMENTNAMES; i++)
    if (data->name_tree[i])
      r_destroy_tree (&data->name_tree[i]);
  if (data->via_tree)
    r_destroy_tree (&data->via_tree);
  if (data->pin_tree)
    r_destroy_tree (&data->pin_tree);
  if (data->pad_tree)
    r_destroy_tree (&data->pad_tree);
  if (data->rat_tree)
    r_destroy_tree (&data->rat_tree);
  /* clear struct */
  memset (data, 0, sizeof (DataType));
}
Exemple #23
0
Fichier : rats.c Projet : rlutz/pcb
/*!
 * \brief Determine existing interconnections of the net and gather into
 * sub-nets.
 *
 * Initially the netlist has each connection in its own individual net
 * afterwards there can be many fewer nets with multiple connections
 * each.
 */
static bool
GatherSubnets (NetListType *Netl, bool NoWarn, bool AndRats)
{
  NetType *a, *b;
  ConnectionType *conn;
  Cardinal m, n;
  bool Warned = false;

  for (m = 0; Netl->NetN > 0 && m < Netl->NetN; m++)
    {
      a = &Netl->Net[m];
      ClearFlagOnAllObjects (false, DRCFLAG);
      RatFindHook (a->Connection[0].type, a->Connection[0].ptr1,
                   a->Connection[0].ptr2, a->Connection[0].ptr2,
                   false, DRCFLAG, AndRats);
      /* now anybody connected to the first point has DRCFLAG set */
      /* so move those to this subnet */
      CLEAR_FLAG (DRCFLAG, (PinType *) a->Connection[0].ptr2);
      for (n = m + 1; n < Netl->NetN; n++)
	{
	  b = &Netl->Net[n];
	  /* There can be only one connection in net b */
	  if (TEST_FLAG (DRCFLAG, (PinType *) b->Connection[0].ptr2))
	    {
	      CLEAR_FLAG (DRCFLAG, (PinType *) b->Connection[0].ptr2);
	      TransferNet (Netl, b, a);
	      /* back up since new subnet is now at old index */
	      n--;
	    }
	}
      /* now add other possible attachment points to the subnet */
      /* e.g. line end-points and vias */
      /* don't add non-manhattan lines, the auto-router can't route to them */
      ALLLINE_LOOP (PCB->Data);
      {
	if (TEST_FLAG (DRCFLAG, line))
	  {
	    conn = GetConnectionMemory (a);
	    conn->X = line->Point1.X;
	    conn->Y = line->Point1.Y;
	    conn->type = LINE_TYPE;
	    conn->ptr1 = layer;
	    conn->ptr2 = line;
	    conn->group = GetLayerGroupNumberByPointer (layer);
	    conn->menu = NULL;	/* agnostic view of where it belongs */
	    conn = GetConnectionMemory (a);
	    conn->X = line->Point2.X;
	    conn->Y = line->Point2.Y;
	    conn->type = LINE_TYPE;
	    conn->ptr1 = layer;
	    conn->ptr2 = line;
	    conn->group = GetLayerGroupNumberByPointer (layer);
	    conn->menu = NULL;
	  }
      }
      ENDALL_LOOP;
      /* add polygons so the auto-router can see them as targets */
      ALLPOLYGON_LOOP (PCB->Data);
      {
	if (TEST_FLAG (DRCFLAG, polygon))
	  {
	    conn = GetConnectionMemory (a);
	    /* make point on a vertex */
	    conn->X = polygon->Clipped->contours->head.point[0];
	    conn->Y = polygon->Clipped->contours->head.point[1];
	    conn->type = POLYGON_TYPE;
	    conn->ptr1 = layer;
	    conn->ptr2 = polygon;
	    conn->group = GetLayerGroupNumberByPointer (layer);
	    conn->menu = NULL;	/* agnostic view of where it belongs */
	  }
      }
      ENDALL_LOOP;
      VIA_LOOP (PCB->Data);
      {
	if (TEST_FLAG (DRCFLAG, via))
	  {
	    conn = GetConnectionMemory (a);
	    conn->X = via->X;
	    conn->Y = via->Y;
	    conn->type = VIA_TYPE;
	    conn->ptr1 = via;
	    conn->ptr2 = via;
	    conn->group = bottom_group;
	  }
      }
      END_LOOP;
      if (!NoWarn)
	Warned |= CheckShorts (a->Connection[0].menu);
    }
  ClearFlagOnAllObjects (false, DRCFLAG);
  return (Warned);
}
Exemple #24
0
/* ---------------------------------------------------------------------------
 * draws all visible and attached objects of the pastebuffer
 */
static void
XORDrawBuffer (BufferTypePtr Buffer)
{
  Cardinal i;
  LocationType x, y;

  /* set offset */
  x = Crosshair.X - Buffer->X;
  y = Crosshair.Y - Buffer->Y;

  /* draw all visible layers */
  for (i = 0; i < max_copper_layer + 2; i++)
    if (PCB->Data->Layer[i].On)
      {
	LayerTypePtr layer = &Buffer->Data->Layer[i];

	LINE_LOOP (layer);
	{
/*
				XORDrawAttachedLine(x +line->Point1.X,
					y +line->Point1.Y, x +line->Point2.X,
					y +line->Point2.Y, line->Thickness);
*/
	  gui->draw_line (Crosshair.GC,
			  x + line->Point1.X, y + line->Point1.Y,
			  x + line->Point2.X, y + line->Point2.Y);
	}
	END_LOOP;
	ARC_LOOP (layer);
	{
	  gui->draw_arc (Crosshair.GC,
			 x + arc->X,
			 y + arc->Y,
			 arc->Width,
			 arc->Height, arc->StartAngle, arc->Delta);
	}
	END_LOOP;
	TEXT_LOOP (layer);
	{
	  BoxTypePtr box = &text->BoundingBox;
	  gui->draw_rect (Crosshair.GC,
			  x + box->X1, y + box->Y1, x + box->X2, y + box->Y2);
	}
	END_LOOP;
	/* the tmp polygon has n+1 points because the first
	 * and the last one are set to the same coordinates
	 */
	POLYGON_LOOP (layer);
	{
	  XORPolygon (polygon, x, y);
	}
	END_LOOP;
      }

  /* draw elements if visible */
  if (PCB->PinOn && PCB->ElementOn)
    ELEMENT_LOOP (Buffer->Data);
  {
    if (FRONT (element) || PCB->InvisibleObjectsOn)
      XORDrawElement (element, x, y);
  }
  END_LOOP;

  /* and the vias, move offset by thickness/2 */
  if (PCB->ViaOn)
    VIA_LOOP (Buffer->Data);
  {
    gui->draw_arc (Crosshair.GC,
		   x + via->X, y + via->Y,
		   via->Thickness / 2, via->Thickness / 2, 0, 360);
  }
  END_LOOP;
}
Exemple #25
0
/*!
 * \brief The main IPC-D-356 function.
 *
 * Gets the filename for the netlist from the dialog.
 */
int
IPCD356_Netlist (void)
{
  FILE *fp;
  char nodename[256];
  char net[256];
  LibraryMenuType *netname;
  IPCD356_AliasList * aliaslist;

  if (IPCD356_SanityCheck()) /* Check for invalid names + numbers. */
    {
      Message ("Aborting.\n");
      return(1);
    }

  sprintf (net, "%s.ipc", PCB->Name);
  if (IPCD356_filename == NULL)
    return 1;

  fp = fopen (IPCD356_filename, "w+");
  if (fp == NULL)
    {
      Message ("error opening %s\n", IPCD356_filename);
      return 1;
    }
/*   free (IPCD356_filename); */


  IPCD356_WriteHeader (fp);

  aliaslist = CreateAliasList ();
  if (aliaslist == NULL)
    {
      Message ("Error Aloccating memory for IPC-D-356 AliasList\n");
      return 1;
    }

  if (IPCD356_WriteAliases (fp, aliaslist))
    {
      Message ("Error Writing IPC-D-356 AliasList\n");
      return 1;
    }


  ELEMENT_LOOP (PCB->Data);
  PIN_LOOP (element);
  if (!TEST_FLAG (VISITFLAG, pin))
    {
      ClearFlagOnLinesAndPolygons (true, FOUNDFLAG);
      ClearFlagOnPinsViasAndPads (true, FOUNDFLAG);
      LookupConnectionByPin (PIN_TYPE, pin);
      sprintf (nodename, "%s-%s", element->Name[1].TextString, pin->Number);
      netname = netnode_to_netname (nodename);
/*      Message("Netname: %s\n", netname->Name +2); */
      if (netname)
        {
          strcpy (net, &netname->Name[2]);
          CheckNetLength (net, aliaslist);
        }
      else
        {
          strcpy (net, "N/C");
        }
      IPCD356_WriteNet (fp, net);
    }
  END_LOOP; /* Pin. */
  PAD_LOOP (element);
  if (!TEST_FLAG (VISITFLAG, pad))
    {
      ClearFlagOnLinesAndPolygons (true, FOUNDFLAG);
      ClearFlagOnPinsViasAndPads (true, FOUNDFLAG);
      LookupConnectionByPin (PAD_TYPE, pad);
      sprintf (nodename, "%s-%s", element->Name[1].TextString, pad->Number);
      netname = netnode_to_netname (nodename);
/*      Message("Netname: %s\n", netname->Name +2); */
      if (netname)
        {
          strcpy (net, &netname->Name[2]);
          CheckNetLength (net, aliaslist);
        }
      else
        {
          strcpy (net, "N/C");
        }
      IPCD356_WriteNet (fp, net);
    }
  END_LOOP; /* Pad. */

  END_LOOP; /* Element. */

  VIA_LOOP (PCB->Data);
  if (!TEST_FLAG (VISITFLAG, via))
    {
      ClearFlagOnLinesAndPolygons (true, FOUNDFLAG);
      ClearFlagOnPinsViasAndPads (true, FOUNDFLAG);
      LookupConnectionByPin (PIN_TYPE, via);
      strcpy (net, "N/C");
      IPCD356_WriteNet (fp, net);
    }
  END_LOOP; /* Via. */

  IPCD356_End (fp);
  fclose (fp);
  free (aliaslist);
  ResetVisitPinsViasAndPads ();
  ClearFlagOnLinesAndPolygons (true, FOUNDFLAG);
  ClearFlagOnPinsViasAndPads (true, FOUNDFLAG);
  return 0;
}
Exemple #26
0
/* ---------------------------------------------------------------------------
 * 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 ();
}
Exemple #27
0
bool
SelectObjectByName (int Type, char *Pattern, bool Flag)
{
  bool changed = false;

#if defined(HAVE_REGCOMP)
#define	REGEXEC(arg)	(regexec_match_all(&compiled, (arg)))

  int result;
  regex_t compiled;

  /* compile the regular expression */
  result = regcomp (&compiled, Pattern, REG_EXTENDED | REG_ICASE);
  if (result)
    {
      char errorstring[128];

      regerror (result, &compiled, errorstring, 128);
      Message (_("regexp error: %s\n"), errorstring);
      regfree (&compiled);
      return (false);
    }
#else
#define	REGEXEC(arg)	(re_exec((arg)) == 1)

  char *compiled;

  /* compile the regular expression */
  if ((compiled = re_comp (Pattern)) != NULL)
    {
      Message (_("re_comp error: %s\n"), compiled);
      return (false);
    }
#endif

  /* loop over all visible objects with names */
  if (Type & TEXT_TYPE)
    ALLTEXT_LOOP (PCB->Data);
  {
    if (!TEST_FLAG (LOCKFLAG, text)
	&& TEXT_IS_VISIBLE (PCB, layer, text)
	&& text->TextString
	&& REGEXEC (text->TextString)
	&& TEST_FLAG (SELECTEDFLAG, text) != Flag)
      {
	AddObjectToFlagUndoList (TEXT_TYPE, layer, text, text);
	ASSIGN_FLAG (SELECTEDFLAG, Flag, text);
	DrawText (layer, text, 0);
	changed = true;
      }
  }
  ENDALL_LOOP;

  if (PCB->ElementOn && (Type & ELEMENT_TYPE))
    ELEMENT_LOOP (PCB->Data);
  {
    if (!TEST_FLAG (LOCKFLAG, element)
	&& ((TEST_FLAG (ONSOLDERFLAG, element) != 0) == SWAP_IDENT
	    || PCB->InvisibleObjectsOn)
	&& TEST_FLAG (SELECTEDFLAG, element) != Flag)
      {
	String name = ELEMENT_NAME (PCB, element);
	if (name && REGEXEC (name))
	  {
	    AddObjectToFlagUndoList (ELEMENT_TYPE, element, element, element);
	    ASSIGN_FLAG (SELECTEDFLAG, Flag, element);
	    PIN_LOOP (element);
	    {
	      AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
	      ASSIGN_FLAG (SELECTEDFLAG, Flag, pin);
	    }
	    END_LOOP;
	    PAD_LOOP (element);
	    {
	      AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
	      ASSIGN_FLAG (SELECTEDFLAG, Flag, pad);
	    }
	    END_LOOP;
	    ELEMENTTEXT_LOOP (element);
	    {
	      AddObjectToFlagUndoList (ELEMENTNAME_TYPE, element, text, text);
	      ASSIGN_FLAG (SELECTEDFLAG, Flag, text);
	    }
	    END_LOOP;
	    DrawElementName (element, 0);
	    DrawElement (element, 0);
	    changed = true;
	  }
      }
  }
  END_LOOP;
  if (PCB->PinOn && (Type & PIN_TYPE))
    ALLPIN_LOOP (PCB->Data);
  {
    if (!TEST_FLAG (LOCKFLAG, element)
	&& pin->Name && REGEXEC (pin->Name)
	&& TEST_FLAG (SELECTEDFLAG, pin) != Flag)
      {
	AddObjectToFlagUndoList (PIN_TYPE, element, pin, pin);
	ASSIGN_FLAG (SELECTEDFLAG, Flag, pin);
	DrawPin (pin, 0);
	changed = true;
      }
  }
  ENDALL_LOOP;
  if (PCB->PinOn && (Type & PAD_TYPE))
    ALLPAD_LOOP (PCB->Data);
  {
    if (!TEST_FLAG (LOCKFLAG, element)
	&& ((TEST_FLAG (ONSOLDERFLAG, pad) != 0) == SWAP_IDENT
	    || PCB->InvisibleObjectsOn)
	&& TEST_FLAG (SELECTEDFLAG, pad) != Flag)
      if (pad->Name && REGEXEC (pad->Name))
	{
	  AddObjectToFlagUndoList (PAD_TYPE, element, pad, pad);
	  ASSIGN_FLAG (SELECTEDFLAG, Flag, pad);
	  DrawPad (pad, 0);
	  changed = true;
	}
  }
  ENDALL_LOOP;
  if (PCB->ViaOn && (Type & VIA_TYPE))
    VIA_LOOP (PCB->Data);
  {
    if (!TEST_FLAG (LOCKFLAG, via)
	&& via->Name
	&& REGEXEC (via->Name) && TEST_FLAG (SELECTEDFLAG, via) != Flag)
      {
	AddObjectToFlagUndoList (VIA_TYPE, via, via, via);
	ASSIGN_FLAG (SELECTEDFLAG, Flag, via);
	DrawVia (via, 0);
	changed = true;
      }
  }
  END_LOOP;

#if defined(HAVE_REGCOMP)
#if !defined(sgi)
  regfree (&compiled);
#endif
#endif

  if (changed)
    {
      IncrementUndoSerialNumber ();
      Draw ();
    }
  return (changed);
}