/*! * \brief Creates a new line on a layer and checks for overlap and * extension. */ LineType * CreateDrawnLineOnLayer (LayerType *Layer, Coord X1, Coord Y1, Coord X2, Coord Y2, Coord Thickness, Coord Clearance, FlagType Flags) { struct line_info info; BoxType search; search.X1 = MIN (X1, X2); search.X2 = MAX (X1, X2); search.Y1 = MIN (Y1, Y2); search.Y2 = MAX (Y1, Y2); if (search.Y2 == search.Y1) search.Y2++; if (search.X2 == search.X1) search.X2++; info.X1 = X1; info.X2 = X2; info.Y1 = Y1; info.Y2 = Y2; info.Thickness = Thickness; info.Clearance = Clearance; info.Flags = Flags; info.test.Thickness = 0; info.test.Flags = NoFlags (); info.ans = NULL; /* prevent stacking of duplicate lines * and remove needless intermediate points * verify that the layer is on the board first! */ if (setjmp (info.env) == 0) { r_search (Layer->line_tree, &search, NULL, line_callback, &info); return CreateNewLineOnLayer (Layer, X1, Y1, X2, Y2, Thickness, Clearance, Flags); } if ((void *) info.ans == (void *) (-1)) return NULL; /* stacked line */ /* remove unnecessary points */ if (info.ans) { /* must do this BEFORE getting new line memory */ MoveObjectToRemoveUndoList (LINE_TYPE, Layer, info.ans, info.ans); X1 = info.test.Point1.X; X2 = info.test.Point2.X; Y1 = info.test.Point1.Y; Y2 = info.test.Point2.Y; } return CreateNewLineOnLayer (Layer, X1, Y1, X2, Y2, Thickness, Clearance, Flags); }
/* --------------------------------------------------------------------------- * moves a line between layers */ static void * MoveRatToLayer (RatType *Rat) { LineTypePtr newone; //Coord X1 = Rat->Point1.X, Y1 = Rat->Point1.Y; //Coord X1 = Rat->Point1.X, Y1 = Rat->Point1.Y; // if VIAFLAG // if we're on a pin, add a thermal // else make a via and a wire, but 0-length wire not good // else as before newone = CreateNewLineOnLayer (Dest, Rat->Point1.X, Rat->Point1.Y, Rat->Point2.X, Rat->Point2.Y, Settings.LineThickness, 2 * Settings.Keepaway, Rat->Flags); if (TEST_FLAG (CLEARNEWFLAG, PCB)) SET_FLAG (CLEARLINEFLAG, newone); if (!newone) return (NULL); AddObjectToCreateUndoList (LINE_TYPE, Dest, newone, newone); if (PCB->RatOn) EraseRat (Rat); MoveObjectToRemoveUndoList (RATLINE_TYPE, Rat, Rat, Rat); DrawLine (Dest, newone); Draw (); return (newone); }
/* makes a line on the solder layer surrounding all boxes in blist */ static void showboxes (BoxListTypePtr blist) { Cardinal i; LayerTypePtr SLayer = &(PCB->Data->Layer[solder_silk_layer]); for (i = 0; i < blist->BoxN; i++) { CreateNewLineOnLayer (SLayer, blist->Box[i].X1, blist->Box[i].Y1, blist->Box[i].X2, blist->Box[i].Y1, 1, 1, 0); CreateNewLineOnLayer (SLayer, blist->Box[i].X1, blist->Box[i].Y2, blist->Box[i].X2, blist->Box[i].Y2, 1, 1, 0); CreateNewLineOnLayer (SLayer, blist->Box[i].X1, blist->Box[i].Y1, blist->Box[i].X1, blist->Box[i].Y2, 1, 1, 0); CreateNewLineOnLayer (SLayer, blist->Box[i].X2, blist->Box[i].Y1, blist->Box[i].X2, blist->Box[i].Y2, 1, 1, 0); } }
/* * Wrapper for CreateNewLineOnLayer that takes vectors and deals with Undo */ static LineType * CreateVectorLineOnLayer(LayerType *layer, Vector a, Vector b, int thickness, int clearance, FlagType flags) { LineType *line; line = CreateNewLineOnLayer(layer, a[0], a[1], b[0], b[1], thickness, clearance, flags); if (line) { AddObjectToCreateUndoList (LINE_TYPE, layer, line, line); } return line; }
/* --------------------------------------------------------------------------- * copies a line to buffer */ static void * AddLineToBuffer (LayerType *Layer, LineType *Line) { LineType *line; LayerType *layer = &Dest->Layer[GetLayerNumber (Source, Layer)]; line = CreateNewLineOnLayer (layer, Line->Point1.X, Line->Point1.Y, Line->Point2.X, Line->Point2.Y, Line->Thickness, Line->Clearance, MaskFlags (Line->Flags, NOCOPY_FLAGS | ExtraFlag)); if (line && Line->Number) line->Number = strdup (Line->Number); return (line); }
/*--------------------------------------------------------------------------- * * 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); }