Beispiel #1
0
static int
info (int argc, char **argv, Coord x, Coord y)
{
  int i, j;
  int cg, sg;
  if (!PCB || !PCB->Data || !PCB->Filename)
    {
      printf("No PCB loaded.\n");
      return 0;
    }
  printf("Filename: %s\n", PCB->Filename);
  pcb_printf("Size: %ml x %ml mils, %mm x %mm mm\n",
	 PCB->MaxWidth, PCB->MaxHeight,
	 PCB->MaxWidth, PCB->MaxHeight);
  cg = GetLayerGroupNumberByNumber (component_silk_layer);
  sg = GetLayerGroupNumberByNumber (solder_silk_layer);
  for (i=0; i<MAX_LAYER; i++)
    {
      
      int lg = GetLayerGroupNumberByNumber (i);
      for (j=0; j<MAX_LAYER; j++)
	putchar(j==lg ? '#' : '-');
      printf(" %c %s\n", lg==cg ? 'c' : lg==sg ? 's' : '-',
	     PCB->Data->Layer[i].Name);
    }
  return 0;
}
Beispiel #2
0
/* ---------------------------------------------------------------------------
 * Draws pins pads and vias - Always draws for non-gui HIDs,
 * otherwise drawing depends on PCB->PinOn and PCB->ViaOn
 */
static void
DrawPPV (int group, const BoxType *drawn_area)
{
  int component_group = GetLayerGroupNumberByNumber (component_silk_layer);
  int solder_group = GetLayerGroupNumberByNumber (solder_silk_layer);
  int side;

  if (PCB->PinOn || !gui->gui)
    {
      /* draw element pins */
      r_search (PCB->Data->pin_tree, drawn_area, NULL, pin_callback, NULL);

      /* draw element pads */
      if (group == component_group)
        {
          side = COMPONENT_LAYER;
          r_search (PCB->Data->pad_tree, drawn_area, NULL, pad_callback, &side);
        }

      if (group == solder_group)
        {
          side = SOLDER_LAYER;
          r_search (PCB->Data->pad_tree, drawn_area, NULL, pad_callback, &side);
        }
    }

  /* draw vias */
  if (PCB->ViaOn || !gui->gui)
    {
      r_search (PCB->Data->via_tree, drawn_area, NULL, via_callback, NULL);
      r_search (PCB->Data->via_tree, drawn_area, NULL, hole_callback, NULL);
    }
  if (PCB->PinOn || doing_assy)
    r_search (PCB->Data->pin_tree, drawn_area, NULL, hole_callback, NULL);
}
Beispiel #3
0
/* ---------------------------------------------------------------------------
 * Update the X, Y and group position information stored in the NetList after
 * elements have possibly been moved, rotated, flipped, etc.
 */
static void
UpdateXY (NetListTypePtr Nets)
{
  Cardinal SLayer, CLayer;
  Cardinal i, j;
  /* find layer groups of the component side and solder side */
  SLayer = GetLayerGroupNumberByNumber (solder_silk_layer);
  CLayer = GetLayerGroupNumberByNumber (component_silk_layer);
  /* update all nets */
  for (i = 0; i < Nets->NetN; i++)
    {
      for (j = 0; j < Nets->Net[i].ConnectionN; j++)
	{
	  ConnectionTypePtr c = &(Nets->Net[i].Connection[j]);
	  switch (c->type)
	    {
	    case PAD_TYPE:
	      c->group = TEST_FLAG (ONSOLDERFLAG,
				    (ElementTypePtr) c->ptr1)
		? SLayer : CLayer;
	      c->X = ((PadTypePtr) c->ptr2)->Point1.X;
	      c->Y = ((PadTypePtr) c->ptr2)->Point1.Y;
	      break;
	    case PIN_TYPE:
	      c->group = SLayer;	/* any layer will do */
	      c->X = ((PinTypePtr) c->ptr2)->X;
	      c->Y = ((PinTypePtr) c->ptr2)->Y;
	      break;
	    default:
	      Message ("Odd connection type encountered in " "UpdateXY");
	      break;
	    }
	}
    }
}
Beispiel #4
0
static int
LastLayerInComponentGroup (int layer)
{
  int cgroup = GetLayerGroupNumberByNumber(max_group + COMPONENT_LAYER);
  int lgroup = GetLayerGroupNumberByNumber(layer);
  if (cgroup == lgroup
      && PCB->LayerGroups.Number[lgroup] == 2)
    return 1;
  return 0;
}
Beispiel #5
0
static int
LastLayerInSolderGroup (int layer)
{
  int sgroup = GetLayerGroupNumberByNumber(max_group + SOLDER_LAYER);
  int lgroup = GetLayerGroupNumberByNumber(layer);
  if (sgroup == lgroup
      && PCB->LayerGroups.Number[lgroup] == 2)
    return 1;
  return 0;
}
Beispiel #6
0
/* Very similar to layer_type_to_file_name() but appends only a
   three-character suffix compatible with Eagle's defaults.  */
static void
assign_eagle_file_suffix (char *dest, int idx)
{
  int group;
  int nlayers;
  char *suff = "out";

  switch (idx)
    {
    case SL (SILK,      TOP):    suff = "plc"; break;
    case SL (SILK,      BOTTOM): suff = "pls"; break;
    case SL (MASK,      TOP):    suff = "stc"; break;
    case SL (MASK,      BOTTOM): suff = "sts"; break;
    case SL (PDRILL,    0):      suff = "drd"; break;
    case SL (UDRILL,    0):      suff = "dru"; break;
    case SL (PASTE,     TOP):    suff = "crc"; break;
    case SL (PASTE,     BOTTOM): suff = "crs"; break;
    case SL (INVISIBLE, 0):      suff = "inv"; break;
    case SL (FAB,       0):      suff = "fab"; break;
    case SL (ASSY,      TOP):    suff = "ast"; break;
    case SL (ASSY,      BOTTOM): suff = "asb"; break;

    default:
      group = GetLayerGroupNumberByNumber(idx);
      nlayers = PCB->LayerGroups.Number[group];
      if (group == GetLayerGroupNumberByNumber(component_silk_layer))
	{
	  suff = "cmp";
	}
      else if (group == GetLayerGroupNumberByNumber(solder_silk_layer))
	{
	  suff = "sol";
	}
      else if (nlayers == 1
	       && (strcmp (PCB->Data->Layer[idx].Name, "route") == 0 ||
		   strcmp (PCB->Data->Layer[idx].Name, "outline") == 0))
	{
	  suff = "oln";
	}
      else
	{
	  static char buf[20];
	  sprintf (buf, "ly%d", group);
	  suff = buf;
	}
      break;
    }

  strcpy (dest, suff);
}
Beispiel #7
0
const char *
layer_type_to_file_name (int idx)
{
  int group;

  switch (idx)
    {
    case SL (SILK, TOP):
      return "frontsilk";
    case SL (SILK, BOTTOM):
      return "backsilk";
    case SL (MASK, TOP):
      return "frontmask";
    case SL (MASK, BOTTOM):
      return "backmask";
    case SL (PDRILL, 0):
      return "plated-drill";
    case SL (UDRILL, 0):
      return "unplated-drill";
    case SL (PASTE, TOP):
      return "frontpaste";
    case SL (PASTE, BOTTOM):
      return "backpaste";
    case SL (INVISIBLE, 0):
      return "invisible";
    case SL (FAB, 0):
      return "fab";
    case SL (ASSY, TOP):
      return "frontassembly";
    case SL (ASSY, BOTTOM):
      return "backassembly";
    default:
      group = GetLayerGroupNumberByNumber(idx);
      if (group == GetLayerGroupNumberByNumber(component_silk_layer))
	return "front";
      else if (group == GetLayerGroupNumberByNumber(solder_silk_layer))
	return "back";
      else if (PCB->LayerGroups.Number[group] == 1
	       && (strcmp (PCB->Data->Layer[idx].Name, "route") == 0 ||
		   strcmp (PCB->Data->Layer[idx].Name, "outline") == 0))
	return "outline";
      else
	{
	  static char buf[20];
	  sprintf (buf, "group%d", group);
	  return buf;
	}
      break;
    }
}
Beispiel #8
0
/* ---------------------------------------------------------------------------
 * checks all visible lines which belong to the same layergroup as the
 * passed pad. If one of the endpoints of the line lays inside the pad,
 * the line is added to the 'rubberband' list
 */
static void
CheckPadForRubberbandConnection (PadTypePtr Pad)
{
  BDimension half = Pad->Thickness / 2;
  Cardinal i, group;
  struct rubber_info info;

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

  /* check all visible layers in the same group */
  GROUP_LOOP (PCB->Data, group);
  {
    /* check all visible lines of the group member */
    info.layer = layer;
    if (info.layer->On)
      {
	r_search (info.layer->line_tree, &info.box, NULL, rubber_callback,
		  &info);
      }
  }
  END_LOOP;
}
Beispiel #9
0
/* ---------------------------------------------------------------------------
 * moves a text object between layers; lowlevel routines
 */
static void *
MoveTextToLayerLowLevel (LayerType *Source, TextType *text,
			 LayerType *Destination)
{
  RestoreToPolygon (PCB->Data, TEXT_TYPE, Source, text);
  r_delete_entry (Source->text_tree, (BoxType *)text);

  Source->Text = g_list_remove (Source->Text, text);
  Source->TextN --;
  Destination->Text = g_list_append (Destination->Text, text);
  Destination->TextN ++;

  if (GetLayerGroupNumberByNumber (solder_silk_layer) ==
      GetLayerGroupNumberByPointer (Destination))
    SET_FLAG (ONSOLDERFLAG, text);
  else
    CLEAR_FLAG (ONSOLDERFLAG, text);

  /* re-calculate the bounding box (it could be mirrored now) */
  SetTextBoundingBox (&PCB->Font, text);
  if (!Destination->text_tree)
    Destination->text_tree = r_create_tree (NULL, 0, 0);
  r_insert_entry (Destination->text_tree, (BoxType *)text, 0);
  ClearFromPolygon (PCB->Data, TEXT_TYPE, Destination, text);

  return text;
}
Beispiel #10
0
static int
info (int argc, char **argv, Coord x, Coord y)
{
  int i, j;
  int top_group, bottom_group;
  if (!PCB || !PCB->Data || !PCB->Filename)
    {
      printf("No PCB loaded.\n");
      return 0;
    }
  printf("Filename: %s\n", PCB->Filename);
  pcb_printf("Size: %ml x %ml mils, %mm x %mm mm\n",
	 PCB->MaxWidth, PCB->MaxHeight,
	 PCB->MaxWidth, PCB->MaxHeight);
  top_group = GetLayerGroupNumberBySide (TOP_SIDE);
  bottom_group = GetLayerGroupNumberBySide (BOTTOM_SIDE);
  for (i=0; i<MAX_LAYER; i++)
    {
      
      int lg = GetLayerGroupNumberByNumber (i);
      for (j = 0; j < MAX_GROUP; j++)
	putchar(j==lg ? '#' : '-');
      printf(" %c %s\n", lg == top_group ? 'c' : lg == bottom_group ? 's' : '-',
	     PCB->Data->Layer[i].Name);
    }
  return 0;
}
Beispiel #11
0
static int
group_for_layer (int l)
{
  if (l < max_copper_layer + 2 && l >= 0)
    return GetLayerGroupNumberByNumber (l);
  /* else something unique */
  return max_group + 3 + l;
}
Beispiel #12
0
void
PrintAssembly (int side, const BoxType * drawn_area)
{
  int side_group = GetLayerGroupNumberByNumber (max_copper_layer + side);

  doing_assy = true;
  gui->graphics->set_draw_faded (Output.fgGC, 1);
  DrawLayerGroup (side_group, drawn_area);
  gui->graphics->set_draw_faded (Output.fgGC, 0);

  /* draw package */
  DrawSilk (side, drawn_area);
  doing_assy = false;
}
Beispiel #13
0
static void
CheckPadForRat (PadTypePtr Pad)
{
  struct rinfo info;
  Cardinal i;

  i = TEST_FLAG (ONSOLDERFLAG, Pad) ? solder_silk_layer : component_silk_layer;
  info.group = GetLayerGroupNumberByNumber (i);
  info.pad = Pad;
  info.type = PAD_TYPE;

  r_search (PCB->Data->rat_tree, &Pad->BoundingBox, NULL, rat_callback,
	    &info);
}
Beispiel #14
0
static void
layer_button_callback (Widget w, int layer, XmPushButtonCallbackStruct * pbcs)
{
  int l, set;
  switch (layer)
    {
    case LB_SILK:
      set = PCB->ElementOn = !PCB->ElementOn;
      PCB->Data->SILKLAYER.On = set;
      PCB->Data->BACKSILKLAYER.On = set;
      break;
    case LB_RATS:
      set = PCB->RatOn = !PCB->RatOn;
      break;
    case LB_PINS:
      set = PCB->PinOn = !PCB->PinOn;
      break;
    case LB_VIAS:
      set = PCB->ViaOn = !PCB->ViaOn;
      break;
    case LB_BACK:
      set = PCB->InvisibleObjectsOn = !PCB->InvisibleObjectsOn;
      break;
    case LB_MASK:
      TOGGLE_FLAG (SHOWMASKFLAG, PCB);
      set = TEST_FLAG (SHOWMASKFLAG, PCB);
      break;
    default:			/* layers */
      set = PCB->Data->Layer[layer].On = !PCB->Data->Layer[layer].On;
      break;
    }

  show_one_layer_button (layer, set);
  if (layer < max_copper_layer)
    {
      int i;
      int group = GetLayerGroupNumberByNumber (layer);
      for (i = 0; i < PCB->LayerGroups.Number[group]; i++)
	{
	  l = PCB->LayerGroups.Entries[group][i];
	  if (l != layer && l < max_copper_layer)
	    {
	      show_one_layer_button (l, set);
	      PCB->Data->Layer[l].On = set;
	    }
	}
    }
  lesstif_invalidate_all ();
}
Beispiel #15
0
NetListTypePtr
ProcNetlist (LibraryTypePtr net_menu)
{
  ConnectionTypePtr connection;
  ConnectionType LastPoint;
  NetTypePtr net;
  static NetListTypePtr Wantlist = NULL;

  if (!net_menu->MenuN)
    return (NULL);
  FreeNetListMemory (Wantlist);
  SaveFree (Wantlist);
  /*  MYFREE (Wantlist); *//* awkward */
  badnet = false;

  /* find layer groups of the component side and solder side */
  SLayer = GetLayerGroupNumberByNumber (solder_silk_layer);
  CLayer = GetLayerGroupNumberByNumber (component_silk_layer);

  Wantlist = MyCalloc (1, sizeof (NetListType), "ProcNetlist()");
  if (Wantlist)
    {
      ALLPIN_LOOP (PCB->Data);
      {
	pin->Spare = NULL;
	CLEAR_FLAG (DRCFLAG, pin);
      }
      ENDALL_LOOP;
      ALLPAD_LOOP (PCB->Data);
      {
	pad->Spare = NULL;
	CLEAR_FLAG (DRCFLAG, pad);
      }
      ENDALL_LOOP;
      MENU_LOOP (net_menu);
      {
	if (menu->Name[0] == '*' || menu->flag == 0)
	  {
	    badnet = true;
	    continue;
	  }
	net = GetNetMemory (Wantlist);
	if (menu->Style)
	  {
	    STYLE_LOOP (PCB);
	    {
	      if (style->Name && !NSTRCMP (style->Name, menu->Style))
		{
		  net->Style = style;
		  break;
		}
	    }
	    END_LOOP;
	  }
	else			/* default to NULL if none found */
	  net->Style = NULL;
	ENTRY_LOOP (menu);
	{
	  if (SeekPad (entry, &LastPoint, false))
	    {
	      if (TEST_FLAG (DRCFLAG, (PinTypePtr) LastPoint.ptr2))
		Message (_
			 ("Error! Element %s pin %s appears multiple times in the netlist file.\n"),
			 NAMEONPCB_NAME ((ElementTypePtr) LastPoint.ptr1),
			 (LastPoint.type ==
			  PIN_TYPE) ? ((PinTypePtr) LastPoint.ptr2)->
			 Number : ((PadTypePtr) LastPoint.ptr2)->Number);
	      else
		{
		  connection = GetConnectionMemory (net);
		  *connection = LastPoint;
		  /* indicate expect net */
		  connection->menu = menu;
		  /* mark as visited */
		  SET_FLAG (DRCFLAG, (PinTypePtr) LastPoint.ptr2);
		  if (LastPoint.type == PIN_TYPE)
		    ((PinTypePtr) LastPoint.ptr2)->Spare = (void *) menu;
		  else
		    ((PadTypePtr) LastPoint.ptr2)->Spare = (void *) menu;
		}
	    }
	  else
	    badnet = true;
	  /* check for more pins with the same number */
	  for (; SeekPad (entry, &LastPoint, true);)
	    {
	      connection = GetConnectionMemory (net);
	      *connection = LastPoint;
	      /* indicate expect net */
	      connection->menu = menu;
	      /* mark as visited */
	      SET_FLAG (DRCFLAG, (PinTypePtr) LastPoint.ptr2);
	      if (LastPoint.type == PIN_TYPE)
		((PinTypePtr) LastPoint.ptr2)->Spare = (void *) menu;
	      else
		((PadTypePtr) LastPoint.ptr2)->Spare = (void *) menu;
	    }
	}
	END_LOOP;
      }
      END_LOOP;
    }
  /* clear all visit marks */
  ALLPIN_LOOP (PCB->Data);
  {
    CLEAR_FLAG (DRCFLAG, pin);
  }
  ENDALL_LOOP;
  ALLPAD_LOOP (PCB->Data);
  {
    CLEAR_FLAG (DRCFLAG, pad);
  }
  ENDALL_LOOP;
  return (Wantlist);
}
Beispiel #16
0
/* ---------------------------------------------------------------------------
 * recalculates the passed coordinates to fit the current grid setting
 */
void
FitCrosshairIntoGrid (LocationType X, LocationType Y)
{
  LocationType x2, y2, x0, y0;
  void *ptr1, *ptr2, *ptr3;
  float nearest, sq_dist;
  int ans;

  x0 = 0;
  y0 = 0;
  x2 = PCB->MaxWidth;
  y2 = PCB->MaxHeight;
  Crosshair.X = MIN (Crosshair.MaxX, MAX (Crosshair.MinX, X));
  Crosshair.Y = MIN (Crosshair.MaxY, MAX (Crosshair.MinY, Y));

  if (PCB->RatDraw)
    {
      x0 = -600;
      y0 = -600;
    }
  else
    {
      /* check if new position is inside the output window
       * This might not be true after the window has been resized.
       * In this case we just set it to the center of the window or
       * with respect to the grid (if possible)
       */
      if (Crosshair.X < x0 || Crosshair.X > x2)
	{
	  if (x2 + 1 >= PCB->Grid)
	    /* there must be a point that matches the grid 
	     * so we just have to look for it with some integer
	     * calculations
	     */
	    x0 = GRIDFIT_X (PCB->Grid, PCB->Grid);
	  else
	    x0 = (x2) / 2;
	}
      else
	/* check if the new position matches the grid */
	x0 = GRIDFIT_X (Crosshair.X, PCB->Grid);

      /* do the same for the second coordinate */
      if (Crosshair.Y < y0 || Crosshair.Y > y2)
	{
	  if (y2 + 1 >= PCB->Grid)
	    y0 = GRIDFIT_Y (PCB->Grid, PCB->Grid);
	  else
	    y0 = (y2) / 2;
	}
      else
	y0 = GRIDFIT_Y (Crosshair.Y, PCB->Grid);

      if (Marked.status && TEST_FLAG (ORTHOMOVEFLAG, PCB))
	{
	  int dx = Crosshair.X - Marked.X;
	  int dy = Crosshair.Y - Marked.Y;
	  if (ABS (dx) > ABS (dy))
	    y0 = Marked.Y;
	  else
	    x0 = Marked.X;
	}

    }

  nearest = -1;

  if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB))
    ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                PAD_TYPE, &ptr1, &ptr2, &ptr3);
  else
    ans = NO_TYPE;

  /* Avoid self-snapping when moving */
  if (ans && Settings.Mode == MOVE_MODE &&
      Crosshair.AttachedObject.Type == ELEMENT_TYPE &&
      ptr1 == Crosshair.AttachedObject.Ptr1)
    ans = NO_TYPE;

  if (ans && (Settings.Mode == LINE_MODE ||
              (Settings.Mode == MOVE_MODE &&
               Crosshair.AttachedObject.Type == LINEPOINT_TYPE)))
    {
      PadTypePtr pad = (PadTypePtr) ptr2;
      LayerType *desired_layer;
      Cardinal desired_group;
      Cardinal SLayer, CLayer;
      int found_our_layer = false;

      desired_layer = CURRENT;
      if (Settings.Mode == MOVE_MODE &&
          Crosshair.AttachedObject.Type == LINEPOINT_TYPE)
        {
          desired_layer = (LayerType *)Crosshair.AttachedObject.Ptr1;
        }

      /* find layer groups of the component side and solder side */
      SLayer = GetLayerGroupNumberByNumber (solder_silk_layer);
      CLayer = GetLayerGroupNumberByNumber (component_silk_layer);
      desired_group = TEST_FLAG (ONSOLDERFLAG, pad) ? SLayer : CLayer;

      GROUP_LOOP (PCB->Data, desired_group);
      {
        if (layer == desired_layer)
          {
            found_our_layer = true;
            break;
          }
      }
      END_LOOP;

      if (found_our_layer == false)
        ans = NO_TYPE;
    }

  if (ans)
    {
      PadTypePtr pad = (PadTypePtr) ptr2;
      LocationType px, py;

      px = (pad->Point1.X + pad->Point2.X) / 2;
      py = (pad->Point1.Y + pad->Point2.Y) / 2;

      sq_dist = SQUARE (px - Crosshair.X) + SQUARE (py - Crosshair.Y);

      if (!gui->shift_is_pressed() ||
          SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist)
        {
          x0 = px;
          y0 = py;
          nearest = sq_dist;
        }
    }

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

  /* Avoid self-snapping when moving */
  if (ans && Settings.Mode == MOVE_MODE &&
      Crosshair.AttachedObject.Type == ELEMENT_TYPE &&
      ptr1 == Crosshair.AttachedObject.Ptr1)
    ans = NO_TYPE;

  if (ans)
    {
      PinTypePtr pin = (PinTypePtr) ptr2;
      sq_dist = SQUARE (pin->X - Crosshair.X) + SQUARE (pin->Y - Crosshair.Y);
      if ((nearest == -1 || sq_dist < nearest) &&
          (!gui->shift_is_pressed() ||
           SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist))
        {
          x0 = pin->X;
          y0 = pin->Y;
          nearest = sq_dist;
        }
    }

  if (TEST_FLAG (SNAPPINFLAG, PCB))
    ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                VIA_TYPE, &ptr1, &ptr2, &ptr3);
  else
    ans = NO_TYPE;

  /* Avoid snapping vias to any other vias */
  if (Settings.Mode == MOVE_MODE &&
      Crosshair.AttachedObject.Type == VIA_TYPE)
    {
        if (ans & PIN_TYPES)
          ans = NO_TYPE;
    }

  if (ans)
    {
      PinTypePtr pin = (PinTypePtr) ptr2;
      sq_dist = SQUARE (pin->X - Crosshair.X) + SQUARE (pin->Y - Crosshair.Y);
      if ((nearest == -1 || sq_dist < nearest) &&
          (!gui->shift_is_pressed() ||
           SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist))
        {
          x0 = pin->X;
          y0 = pin->Y;
          nearest = sq_dist;
        }
    }

  if (TEST_FLAG (SNAPPINFLAG, PCB))
    ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                LINEPOINT_TYPE, &ptr1, &ptr2, &ptr3);
  else
    ans = NO_TYPE;

  if (ans)
    {
      PointTypePtr pnt = (PointTypePtr) ptr3;
      sq_dist = SQUARE (pnt->X - Crosshair.X) + SQUARE (pnt->Y - Crosshair.Y);
      if ((nearest == -1 || sq_dist < nearest) &&
          (!gui->shift_is_pressed() ||
           SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist))
        {
          x0 = pnt->X;
          y0 = pnt->Y;
          nearest = sq_dist;
        }
    }

  if (TEST_FLAG (SNAPPINFLAG, PCB))
    ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                POLYGONPOINT_TYPE, &ptr1, &ptr2, &ptr3);
  else
    ans = NO_TYPE;

  if (ans)
    {
      PointTypePtr pnt = (PointTypePtr) ptr3;
      sq_dist = SQUARE (pnt->X - Crosshair.X) + SQUARE (pnt->Y - Crosshair.Y);
      if ((nearest == -1 || sq_dist < nearest) &&
          (!gui->shift_is_pressed() ||
           SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist))
        {
          x0 = pnt->X;
          y0 = pnt->Y;
          nearest = sq_dist;
        }
    }


  if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB))
    ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                ELEMENT_TYPE, &ptr1, &ptr2, &ptr3);
  else
    ans = NO_TYPE;

  if (ans & ELEMENT_TYPE)
    {
      ElementTypePtr el = (ElementTypePtr) ptr1;
      sq_dist = SQUARE (el->MarkX - Crosshair.X) + SQUARE (el->MarkY - Crosshair.Y);
      if ((nearest == -1 || sq_dist < nearest) &&
           SQUARE (x0 - Crosshair.X) + SQUARE (y0 - Crosshair.Y) > sq_dist)
        {
          x0 = el->MarkX;
          y0 = el->MarkY;
          nearest = sq_dist;
        }
    }

  if (x0 >= 0 && y0 >= 0)
    {
      Crosshair.X = x0;
      Crosshair.Y = y0;
    }

  if (Settings.Mode == ARROW_MODE)
    {
      ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                  LINEPOINT_TYPE, &ptr1, &ptr2, &ptr3);
      if (ans == NO_TYPE)
        hid_action("PointCursor");
      else if (!TEST_FLAG(SELECTEDFLAG, (LineType *)ptr2))
        hid_actionl("PointCursor","True", NULL);
    }

  if (Settings.Mode == LINE_MODE
      && Crosshair.AttachedLine.State != STATE_FIRST
      && TEST_FLAG (AUTODRCFLAG, PCB))
    EnforceLineDRC ();

  gui->set_crosshair (Crosshair.X, Crosshair.Y, HID_SC_DO_NOTHING);
}
Beispiel #17
0
static void
gerber_do_export (HID_Attr_Val * options)
{
  const char *fnbase;
  int i;
  static int saved_layer_stack[MAX_LAYER];
  int save_ons[MAX_LAYER + 2];
  FlagType save_thindraw;

  save_thindraw = PCB->Flags;
  CLEAR_FLAG(THINDRAWFLAG, PCB);
  CLEAR_FLAG(THINDRAWPOLYFLAG, PCB);
  CLEAR_FLAG(CHECKPLANESFLAG, PCB);

  if (!options)
    {
      gerber_get_export_options (NULL);
      for (i = 0; i < NUM_OPTIONS; i++)
	gerber_values[i] = gerber_options[i].default_val;
      options = gerber_values;
    }

  fnbase = options[HA_gerberfile].str_value;
  if (!fnbase)
    fnbase = "pcb-out";

  verbose = options[HA_verbose].int_value;
  metric = options[HA_metric].int_value;
  if (metric) {
	  x_convspec = "X%.0mu";
	  y_convspec = "Y%.0mu";
  } else {
	  x_convspec = "X%.0mc";
	  y_convspec = "Y%.0mc";
  }
  all_layers = options[HA_all_layers].int_value;

  copy_outline_mode = options[HA_copy_outline].int_value;
  name_style = options[HA_name_style].int_value;

  outline_layer = NULL;

  for (i = 0; i < max_copper_layer; i++)
    {
      LayerType *layer = PCB->Data->Layer + i;
      if (strcmp (layer->Name, "outline") == 0 ||
	  strcmp (layer->Name, "route") == 0)
	{
	  outline_layer = layer;
	}
    }

  i = strlen (fnbase);
  filename = (char *)realloc (filename, i + 40);
  strcpy (filename, fnbase);
  strcat (filename, ".");
  filesuff = filename + strlen (filename);

  if (all_layers)
    {
      memset (print_group, 1, sizeof (print_group));
      memset (print_layer, 1, sizeof (print_layer));
    }
  else
    {
      memset (print_group, 0, sizeof (print_group));
      memset (print_layer, 0, sizeof (print_layer));
    }

  hid_save_and_show_layer_ons (save_ons);
  for (i = 0; i < max_copper_layer; i++)
    {
      LayerType *layer = PCB->Data->Layer + i;
      if (layer->LineN || layer->TextN || layer->ArcN || layer->PolygonN)
	print_group[GetLayerGroupNumberByNumber (i)] = 1;
    }
  print_group[GetLayerGroupNumberByNumber (solder_silk_layer)] = 1;
  print_group[GetLayerGroupNumberByNumber (component_silk_layer)] = 1;
  for (i = 0; i < max_copper_layer; i++)
    if (print_group[GetLayerGroupNumberByNumber (i)])
      print_layer[i] = 1;

  memcpy (saved_layer_stack, LayerStack, sizeof (LayerStack));
  qsort (LayerStack, max_copper_layer, sizeof (LayerStack[0]), layer_sort);
  linewidth = -1;
  lastcap = -1;
  lastgroup = -1;

  region.X1 = 0;
  region.Y1 = 0;
  region.X2 = PCB->MaxWidth;
  region.Y2 = PCB->MaxHeight;

  pagecount = 1;
  resetApertures ();

  lastgroup = -1;
  layer_list_idx = 0;
  finding_apertures = 1;
  hid_expose_callback (&gerber_hid, &region, 0);

  layer_list_idx = 0;
  finding_apertures = 0;
  hid_expose_callback (&gerber_hid, &region, 0);

  memcpy (LayerStack, saved_layer_stack, sizeof (LayerStack));

  maybe_close_f (f);
  f = NULL;
  hid_restore_layer_ons (save_ons);
  PCB->Flags = save_thindraw;
}
Beispiel #18
0
  /* These next two functions moved from the original netlist.c as part of the
     |  gui code separation for the Gtk port.
   */
RatTypePtr
AddNet (void)
{
  static int ratDrawn = 0;
  char name1[256], *name2;
  Cardinal group1, group2;
  char ratname[20];
  int found;
  void *ptr1, *ptr2, *ptr3;
  LibraryMenuTypePtr menu;
  LibraryEntryTypePtr entry;

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

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

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

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

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

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

ratIt:
  NetlistChanged (0);
  return (CreateNewRat (PCB->Data, Crosshair.AttachedLine.Point1.X,
			Crosshair.AttachedLine.Point1.Y,
			Crosshair.AttachedLine.Point2.X,
			Crosshair.AttachedLine.Point2.Y,
			group1, group2, Settings.RatThickness, NoFlags ()));
}
Beispiel #19
0
static float
drc_lines (PointTypePtr end, bool way)
{
  float f, s, f2, s2, len, best;
  LocationType dx, dy, temp, last, length;
  LocationType temp2, last2, length2;
  LineType line1, line2;
  Cardinal group, comp;
  struct drc_info info;
  bool two_lines, x_is_long, blocker;
  PointType ans;

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

  end->X = ans.X;
  end->Y = ans.Y;
  return best;
}
Beispiel #20
0
/* ---------------------------------------------------------------------------
 * recalculates the passed coordinates to fit the current grid setting
 */
void
FitCrosshairIntoGrid (Coord X, Coord Y)
{
    Coord nearest_grid_x, nearest_grid_y;
    void *ptr1, *ptr2, *ptr3;
    struct snap_data snap_data;
    int ans;

    Crosshair.X = CLAMP (X, Crosshair.MinX, Crosshair.MaxX);
    Crosshair.Y = CLAMP (Y, Crosshair.MinY, Crosshair.MaxY);

    if (PCB->RatDraw)
    {
        nearest_grid_x = -MIL_TO_COORD (6);
        nearest_grid_y = -MIL_TO_COORD (6);
    }
    else
    {
        nearest_grid_x = GridFit (Crosshair.X, PCB->Grid, PCB->GridOffsetX);
        nearest_grid_y = GridFit (Crosshair.Y, PCB->Grid, PCB->GridOffsetY);

        if (Marked.status && TEST_FLAG (ORTHOMOVEFLAG, PCB))
        {
            Coord dx = Crosshair.X - Marked.X;
            Coord dy = Crosshair.Y - Marked.Y;
            if (ABS (dx) > ABS (dy))
                nearest_grid_y = Marked.Y;
            else
                nearest_grid_x = Marked.X;
        }

    }

    snap_data.crosshair = &Crosshair;
    snap_data.nearest_sq_dist =
        crosshair_sq_dist (&Crosshair, nearest_grid_x, nearest_grid_y);
    snap_data.nearest_is_grid = true;
    snap_data.x = nearest_grid_x;
    snap_data.y = nearest_grid_y;

    ans = NO_TYPE;
    if (!PCB->RatDraw)
        ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                    ELEMENT_TYPE, &ptr1, &ptr2, &ptr3);

    if (ans & ELEMENT_TYPE)
    {
        ElementType *el = (ElementType *) ptr1;
        check_snap_object (&snap_data, el->MarkX, el->MarkY, false);
    }

    ans = NO_TYPE;
    if (PCB->RatDraw || TEST_FLAG (SNAPPINFLAG, PCB))
        ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                    PAD_TYPE, &ptr1, &ptr2, &ptr3);

    /* Avoid self-snapping when moving */
    if (ans != NO_TYPE &&
            Settings.Mode == MOVE_MODE &&
            Crosshair.AttachedObject.Type == ELEMENT_TYPE &&
            ptr1 == Crosshair.AttachedObject.Ptr1)
        ans = NO_TYPE;

    if (ans != NO_TYPE &&
            ( Settings.Mode == LINE_MODE ||
              (Settings.Mode == MOVE_MODE &&
               Crosshair.AttachedObject.Type == LINEPOINT_TYPE)))
    {
        PadTypePtr pad = (PadTypePtr) ptr2;
        LayerType *desired_layer;
        Cardinal desired_group;
        Cardinal SLayer, CLayer;
        int found_our_layer = false;

        desired_layer = CURRENT;
        if (Settings.Mode == MOVE_MODE &&
                Crosshair.AttachedObject.Type == LINEPOINT_TYPE)
        {
            desired_layer = (LayerType *)Crosshair.AttachedObject.Ptr1;
        }

        /* find layer groups of the component side and solder side */
        SLayer = GetLayerGroupNumberByNumber (solder_silk_layer);
        CLayer = GetLayerGroupNumberByNumber (component_silk_layer);
        desired_group = TEST_FLAG (ONSOLDERFLAG, pad) ? SLayer : CLayer;

        GROUP_LOOP (PCB->Data, desired_group);
        {
            if (layer == desired_layer)
            {
                found_our_layer = true;
                break;
            }
        }
        END_LOOP;

        if (found_our_layer == false)
            ans = NO_TYPE;
    }

    if (ans != NO_TYPE)
    {
        PadType *pad = (PadType *)ptr2;
        check_snap_object (&snap_data, (pad->Point1.X + pad->Point2.X) / 2,
                           (pad->Point1.Y + pad->Point2.Y) / 2,
                           true);
    }

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

    /* Avoid self-snapping when moving */
    if (ans != NO_TYPE &&
            Settings.Mode == MOVE_MODE &&
            Crosshair.AttachedObject.Type == ELEMENT_TYPE &&
            ptr1 == Crosshair.AttachedObject.Ptr1)
        ans = NO_TYPE;

    if (ans != NO_TYPE)
    {
        PinType *pin = (PinType *)ptr2;
        check_snap_object (&snap_data, pin->X, pin->Y, true);
    }

    ans = NO_TYPE;
    if (TEST_FLAG (SNAPPINFLAG, PCB))
        ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                    VIA_TYPE, &ptr1, &ptr2, &ptr3);

    /* Avoid snapping vias to any other vias */
    if (Settings.Mode == MOVE_MODE &&
            Crosshair.AttachedObject.Type == VIA_TYPE &&
            (ans & PIN_TYPES))
        ans = NO_TYPE;

    if (ans != NO_TYPE)
    {
        PinType *pin = (PinType *)ptr2;
        check_snap_object (&snap_data, pin->X, pin->Y, true);
    }

    ans = NO_TYPE;
    if (TEST_FLAG (SNAPPINFLAG, PCB))
        ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                    LINEPOINT_TYPE, &ptr1, &ptr2, &ptr3);

    if (ans != NO_TYPE)
    {
        PointType *pnt = (PointType *)ptr3;
        check_snap_object (&snap_data, pnt->X, pnt->Y, true);
    }

    check_snap_offgrid_line (&snap_data, nearest_grid_x, nearest_grid_y);

    ans = NO_TYPE;
    if (TEST_FLAG (SNAPPINFLAG, PCB))
        ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                    POLYGONPOINT_TYPE, &ptr1, &ptr2, &ptr3);

    if (ans != NO_TYPE)
    {
        PointType *pnt = (PointType *)ptr3;
        check_snap_object (&snap_data, pnt->X, pnt->Y, true);
    }

    if (snap_data.x >= 0 && snap_data.y >= 0)
    {
        Crosshair.X = snap_data.x;
        Crosshair.Y = snap_data.y;
    }

    if (Settings.Mode == ARROW_MODE)
    {
        ans = SearchScreenGridSlop (Crosshair.X, Crosshair.Y,
                                    LINEPOINT_TYPE, &ptr1, &ptr2, &ptr3);
        if (ans == NO_TYPE)
            hid_action("PointCursor");
        else if (!TEST_FLAG(SELECTEDFLAG, (LineType *)ptr2))
            hid_actionl("PointCursor","True", NULL);
    }

    if (Settings.Mode == LINE_MODE
            && Crosshair.AttachedLine.State != STATE_FIRST
            && TEST_FLAG (AUTODRCFLAG, PCB))
        EnforceLineDRC ();

    gui->set_crosshair (Crosshair.X, Crosshair.Y, HID_SC_DO_NOTHING);
}
Beispiel #21
0
/* ---------------------------------------------------------------------------
 * initializes some identifiers for a new zoom factor and redraws whole screen
 */
static void
DrawEverything (const BoxType *drawn_area)
{
  int i, ngroups, side;
  int component, solder;
  /* This is the list of layer groups we will draw.  */
  int do_group[MAX_LAYER];
  /* This is the reverse of the order in which we draw them.  */
  int drawn_groups[MAX_LAYER];
  int plated, unplated;
  bool paste_empty;

  PCB->Data->SILKLAYER.Color = PCB->ElementColor;
  PCB->Data->BACKSILKLAYER.Color = PCB->InvisibleObjectsColor;

  memset (do_group, 0, sizeof (do_group));
  for (ngroups = 0, i = 0; i < max_copper_layer; i++)
    {
      LayerType *l = LAYER_ON_STACK (i);
      int group = GetLayerGroupNumberByNumber (LayerStack[i]);
      if (l->On && !do_group[group])
	{
	  do_group[group] = 1;
	  drawn_groups[ngroups++] = group;
	}
    }

  component = GetLayerGroupNumberByNumber (component_silk_layer);
  solder = GetLayerGroupNumberByNumber (solder_silk_layer);

  /*
   * first draw all 'invisible' stuff
   */
  if (!TEST_FLAG (CHECKPLANESFLAG, PCB)
      && gui->set_layer ("invisible", SL (INVISIBLE, 0), 0))
    {
      side = SWAP_IDENT ? COMPONENT_LAYER : SOLDER_LAYER;
      if (PCB->ElementOn)
	{
	  r_search (PCB->Data->element_tree, drawn_area, NULL, element_callback, &side);
	  r_search (PCB->Data->name_tree[NAME_INDEX (PCB)], drawn_area, NULL, name_callback, &side);
	  DrawLayer (&(PCB->Data->Layer[max_copper_layer + side]), drawn_area);
	}
      r_search (PCB->Data->pad_tree, drawn_area, NULL, pad_callback, &side);
      gui->end_layer ();
    }

  /* draw all layers in layerstack order */
  for (i = ngroups - 1; i >= 0; i--)
    {
      int group = drawn_groups[i];

      if (gui->set_layer (0, group, 0))
        {
          DrawLayerGroup (group, drawn_area);
          gui->end_layer ();
        }
    }

  if (TEST_FLAG (CHECKPLANESFLAG, PCB) && gui->gui)
    return;

  /* Draw pins, pads, vias below silk */
  if (gui->gui)
    DrawPPV (SWAP_IDENT ? solder : component, drawn_area);
  else
    {
      CountHoles (&plated, &unplated, drawn_area);

      if (plated && gui->set_layer ("plated-drill", SL (PDRILL, 0), 0))
        {
          DrawHoles (true, false, drawn_area);
          gui->end_layer ();
        }

      if (unplated && gui->set_layer ("unplated-drill", SL (UDRILL, 0), 0))
        {
          DrawHoles (false, true, drawn_area);
          gui->end_layer ();
        }
    }

  /* Draw the solder mask if turned on */
  if (gui->set_layer ("componentmask", SL (MASK, TOP), 0))
    {
      DrawMask (COMPONENT_LAYER, drawn_area);
      gui->end_layer ();
    }

  if (gui->set_layer ("soldermask", SL (MASK, BOTTOM), 0))
    {
      DrawMask (SOLDER_LAYER, drawn_area);
      gui->end_layer ();
    }

  if (gui->set_layer ("topsilk", SL (SILK, TOP), 0))
    {
      DrawSilk (COMPONENT_LAYER, drawn_area);
      gui->end_layer ();
    }

  if (gui->set_layer ("bottomsilk", SL (SILK, BOTTOM), 0))
    {
      DrawSilk (SOLDER_LAYER, drawn_area);
      gui->end_layer ();
    }

  if (gui->gui)
    {
      /* Draw element Marks */
      if (PCB->PinOn)
	r_search (PCB->Data->element_tree, drawn_area, NULL, EMark_callback,
		  NULL);
      /* Draw rat lines on top */
      if (gui->set_layer ("rats", SL (RATS, 0), 0))
        {
          DrawRats(drawn_area);
          gui->end_layer ();
        }
    }

  paste_empty = IsPasteEmpty (COMPONENT_LAYER);
  if (gui->set_layer ("toppaste", SL (PASTE, TOP), paste_empty))
    {
      DrawPaste (COMPONENT_LAYER, drawn_area);
      gui->end_layer ();
    }

  paste_empty = IsPasteEmpty (SOLDER_LAYER);
  if (gui->set_layer ("bottompaste", SL (PASTE, BOTTOM), paste_empty))
    {
      DrawPaste (SOLDER_LAYER, drawn_area);
      gui->end_layer ();
    }

  if (gui->set_layer ("topassembly", SL (ASSY, TOP), 0))
    {
      PrintAssembly (COMPONENT_LAYER, drawn_area);
      gui->end_layer ();
    }

  if (gui->set_layer ("bottomassembly", SL (ASSY, BOTTOM), 0))
    {
      PrintAssembly (SOLDER_LAYER, drawn_area);
      gui->end_layer ();
    }

  if (gui->set_layer ("fab", SL (FAB, 0), 0))
    {
      PrintFab (Output.fgGC);
      gui->end_layer ();
    }
}
Beispiel #22
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 ();
}
Beispiel #23
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);
}
Beispiel #24
0
/*---------------------------------------------------------------------------
 *
 * break buffer element into pieces
 */
bool
SmashBufferElement (BufferType *Buffer)
{
  ElementType *element;
  Cardinal group;
  LayerType *clayer, *slayer;

  if (Buffer->Data->ElementN != 1)
    {
      Message (_("Error!  Buffer doesn't contain a single element\n"));
      return (false);
    }
  /*
   * At this point the buffer should contain just a single element.
   * Now we detach the single element from the buffer and then clear the
   * buffer, ready to receive the smashed elements.  As a result of detaching
   * it the single element is orphaned from the buffer and thus will not be
   * free()'d by FreeDataMemory (called via ClearBuffer).  This leaves it
   * around for us to smash bits off it.  It then becomes our responsibility,
   * however, to free the single element when we're finished with it.
   */
  element = Buffer->Data->Element->data;
  Buffer->Data->Element = NULL;
  Buffer->Data->ElementN = 0;
  ClearBuffer (Buffer);
  ELEMENTLINE_LOOP (element);
  {
    CreateNewLineOnLayer (&Buffer->Data->SILKLAYER,
			  line->Point1.X, line->Point1.Y,
			  line->Point2.X, line->Point2.Y,
			  line->Thickness, 0, NoFlags ());
    if (line)
      line->Number = STRDUP (NAMEONPCB_NAME (element));
  }
  END_LOOP;
  ARC_LOOP (element);
  {
    CreateNewArcOnLayer (&Buffer->Data->SILKLAYER,
			 arc->X, arc->Y, arc->Width, arc->Height, arc->StartAngle,
			 arc->Delta, arc->Thickness, 0, NoFlags ());
  }
  END_LOOP;
  PIN_LOOP (element);
  {
    FlagType f = NoFlags ();
    AddFlags (f, VIAFLAG);
    if (TEST_FLAG (HOLEFLAG, pin))
      AddFlags (f, HOLEFLAG);

    CreateNewVia (Buffer->Data, pin->X, pin->Y,
		  pin->Thickness, pin->Clearance, pin->Mask,
		  pin->DrillingHole, pin->Number, f);
  }
  END_LOOP;
  group =
    GetLayerGroupNumberByNumber (SWAP_IDENT ? solder_silk_layer :
					      component_silk_layer);
  clayer = &Buffer->Data->Layer[PCB->LayerGroups.Entries[group][0]];
  group =
    GetLayerGroupNumberByNumber (SWAP_IDENT ? component_silk_layer :
					      solder_silk_layer);
  slayer = &Buffer->Data->Layer[PCB->LayerGroups.Entries[group][0]];
  PAD_LOOP (element);
  {
    LineType *line;
    line = CreateNewLineOnLayer (TEST_FLAG (ONSOLDERFLAG, pad) ? slayer : clayer,
				 pad->Point1.X, pad->Point1.Y,
				 pad->Point2.X, pad->Point2.Y,
				 pad->Thickness, pad->Clearance, NoFlags ());
    if (line)
      line->Number = STRDUP (pad->Number);
  }
  END_LOOP;
  FreeElementMemory (element);
  g_slice_free (ElementType, element);
  return (true);
}