52 std::vector<const SOURCE_SEGMENT*> out;
59 std::set<const SOURCE_SEGMENT*> seen;
61 for(
const SOURCE_SEGMENT* seg = first; seg && seen.insert( seg ).second; seg = seg->Next )
84 THROW_IO_ERROR( wxString::Format(
_(
"Easy-PC point (%lld, %lld) is outside KiCad's coordinate range" ),
85 static_cast<long long>( aX ),
static_cast<long long>( aY ) ) );
88 return VECTOR2I(
static_cast<int>( x ),
static_cast<int>( y ) );
95 double c = std::cos( aRadians );
96 double s = std::sin( aRadians );
98 return aCentre +
VECTOR2D( r.
x * c - r.
y * s, r.
x * s + r.
y * c );
105 VECTOR2D mid = ( aStart + aEnd ) / 2.0;
106 double t = std::tan( ( aAngle *
M_PI / 180000.0 ) * ( aAnticlockwise ? 1 : -1 ) / 2.0 );
111 return VECTOR2D( mid.
x - ( aEnd.
y - aStart.
y ) / ( 2 * t ), mid.
y + ( aEnd.
x - aStart.
x ) / ( 2 * t ) );
123 int32_t aAngle,
bool aAnticlockwise )
126 double radius = ( aStart - aCentre ).EuclideanNorm();
128 if(
radius * ( 1.0 - std::cos( theta / 2.0 ) ) < 1.0 )
132 double wanted = std::ceil( theta / step );
133 int count = wanted < 16384 ? std::max( 2, static_cast<int>( wanted ) ) : 16384;
135 std::vector<VECTOR2D> out;
137 for(
int k = 1; k < count; ++k )
138 out.push_back(
rotateAbout( aStart, aCentre, ( aAnticlockwise ? theta : -theta ) * k / count ) );
140 out.push_back( aEnd );
146 SCH_LAYER_ID aLayer,
int aStrokeWidth,
bool aFilled,
int aUnit )
148 std::vector<std::unique_ptr<SCH_SHAPE>> out;
149 std::vector<const SOURCE_SEGMENT*> verts =
ShapeVertices( aShape );
152 auto make = [&](
SHAPE_T aType )
154 std::unique_ptr<SCH_SHAPE> shape = std::make_unique<SCH_SHAPE>( aType, aLayer, aStrokeWidth );
155 shape->SetUnit( aUnit );
163 if( verts.size() < 2 )
167 if( closed && verts.size() == 2 && verts[0]->ArcAngle == 180000 && verts[1]->ArcAngle == 180000
168 && verts[0]->Anticlockwise == verts[1]->Anticlockwise )
174 circle->SetEnd( aFrame.
Map( verts[0]->X, verts[0]->Y ) );
175 out.push_back( std::move(
circle ) );
179 size_t spans = closed ? verts.size() : verts.size() - 1;
182 for(
size_t i = 0; i < spans; ++i )
183 hasArc |= verts[i]->ArcAngle != 0;
186 bool onePolygon = aFilled && hasArc;
187 std::unique_ptr<SCH_SHAPE> poly;
189 for(
size_t i = 0; i < spans; ++i )
199 double reach = ( s - c ).EuclideanNorm();
205 if( arcFits && !onePolygon )
208 out.push_back( std::move( poly ) );
214 aFrame.
Map( b->
X, b->
Y ) );
215 out.push_back( std::move( arc ) );
222 poly->AddPoint( aFrame.
Map( a->
X, a->
Y ) );
226 poly->AddPoint(
mapD( aFrame, pt ) );
234 poly->AddPoint( aFrame.
Map( a->
X, a->
Y ) );
237 poly->AddPoint( aFrame.
Map( b->
X, b->
Y ) );
241 out.push_back( std::move( poly ) );
277 const wxString& aMeasured )
309 text.Replace( wxS(
"\r" ), wxEmptyString );
327 bool vertical = rot >= 45000 && rot < 135000;
334 int lines =
static_cast<int>(
text.Freq(
'\n' ) ) + 1;
337 if( lines > 1 && style )
352 int aUnit,
bool aKeepUpright )
354 std::unique_ptr<SCH_TEXT>
text =
357 text->SetUnit( aUnit );
368 if( !maps || aGate < 0 || aGate >=
static_cast<int>( maps->
Items.size() ) || aTerminal < 0 )
388 if(
result.Display.IsEmpty() )
393 wxArrayString stacked;
398 result.Number = wxS(
"[" ) + wxJoin( stacked,
',', 0 ) + wxS(
"]" );
405 if( map && !map->
Pins && aTerminal <
static_cast<int>( map->
PcbSymbolPins.size() )
420 void addText(
LIB_SYMBOL& aSymbol,
const SOURCE_TEXT_POSITION& aPos,
const wxString& aText,
const SCH_FRAME& aFrame,
423 if( aText.IsEmpty() )
428 text->SetUnit( aUnit );
442 const std::vector<const SOURCE_ATTRIBUTE*>& aAttributes )
444 std::vector<const SOURCE_VALUE_POSITION*> positions;
449 positions.push_back( pos );
465 if( !valuePos && pos != refPos && ( pos->Types & wanted ) )
489 if( !attr->AttributeName || attr->AttributeName->Name.IsEmpty() )
492 SCH_FIELD* field =
new SCH_FIELD( &aSymbol,
FIELD_T::USER, attr->AttributeName->Name );
498 if( ( pos->Types &
VALUE_ATTRIBUTE ) && pos->Attribute == attr->AttributeName->Name )
500 placeField( *field, *pos, aFrame );
501 field->
SetVisible( pos->Displayed && attr->Displayed );
512 void convertGate( LIB_SYMBOL& aSymbol,
const SOURCE_SYMBOL& aGateSymbol,
int aGate,
515 const int unit = aGate + 1;
516 SCH_FRAME frame{ aGateSymbol.OriginX, aGateSymbol.OriginY };
529 const int terminal =
pad->Number - 1;
533 if( aGateDef && terminal >= 0 && terminal <
static_cast<int>( aGateDef->PinNames.size() ) )
534 name = aGateDef->PinNames[terminal];
537 SCH_PIN*
pin =
new SCH_PIN( &aSymbol );
538 pin->SetPosition( frame.Map(
pad->Position.X,
pad->Position.Y ) );
541 pin->SetNumber( aGateDef ? gate.Number : wxString::Format( wxS(
"%d" ),
pad->Number ) );
543 pin->SetUnit( unit );
558 const wxString number = aGateDef ? gate.Display :
pin->GetNumber();
563 addText( aSymbol, *pos,
name, frame, unit );
565 addText( aSymbol, *pos, number, frame, unit );
570 addText( aSymbol, *old,
name, frame, unit );
574 addText( aSymbol, *old, number, frame, unit );
580 void mergeCommonPins( LIB_SYMBOL& aSymbol )
582 std::map<wxString, std::vector<SCH_PIN*>> byNumber;
586 if( !
pin->GetNumber().IsEmpty() )
587 byNumber[
pin->GetNumber()].push_back(
pin );
590 for(
auto& [number, pins] : byNumber )
592 const SCH_PIN* first = pins.front();
593 bool alike = pins.size() > 1;
595 for(
size_t i = 1; i < pins.size(); ++i )
597 alike &= pins[i]->GetPosition() == first->
GetPosition()
599 && pins[i]->GetName() == first->
GetName() && pins[i]->GetType() == first->
GetType()
600 && pins[i]->GetUnit() != first->
GetUnit();
606 pins.front()->SetUnit( 0 );
608 for(
size_t i = 1; i < pins.size(); ++i )
614 std::unique_ptr<LIB_SYMBOL> newSymbol(
const LIB_ID& aId )
616 std::unique_ptr<LIB_SYMBOL> symbol = std::make_unique<LIB_SYMBOL>( aId.
GetLibItemName().
wx_str() );
617 symbol->SetLibId( aId );
620 symbol->SetShowPinNames(
false );
621 symbol->SetShowPinNumbers(
false );
633 std::vector<const SOURCE_GATE*> gateDefs;
637 for(
const OBJECT* obj : gates->Items )
639 gateDefs.push_back(
dynamic_cast<const SOURCE_GATE*
>( obj ) );
641 if( !gateDefs.back() )
649 if( aSrc.
Gates.size() != gateDefs.size() )
651 THROW_IO_ERROR( wxString::Format(
_(
"Easy-PC component '%s' has %zu gates but %zu gate symbols" ),
655 std::unique_ptr<LIB_SYMBOL> symbol = newSymbol( aId );
656 symbol->SetUnitCount( std::max<int>( 1,
static_cast<int>( aSrc.
Gates.size() ) ),
false );
660 symbol->GetFootprintField().SetText( aSrc.
Footprint );
663 std::vector<const SOURCE_ATTRIBUTE*> attributes;
678 for(
size_t g = 0; g < aSrc.
Gates.size(); ++g )
681 convertGate( *symbol, *aSrc.
Gates[g],
static_cast<int>( g ), aSrc.
Board, gateDefs[g], aSrc.
PinTexts );
684 mergeCommonPins( *symbol );
687 symbol->GetDrawItems().sort();
694 std::unique_ptr<LIB_SYMBOL> symbol = newSymbol( aId );
698 convertGate( *symbol, aSymbol, 0,
nullptr,
nullptr,
true );
699 symbol->GetDrawItems().sort();
constexpr EDA_IU_SCALE schIUScale
constexpr double ARC_HIGH_DEF_MM
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
bool CanMeasure() const
False for a TrueType style; the measuring calls throw IO_ERROR for one.
VECTOR2I UprightAnchor(const wxString &aText, const VECTOR2I &aAnchor, int32_t aAngle, bool aMirrored, int aHAlign, bool aKeepUpright) const
When aKeepUpright and UprightRotation turns the text, the anchor moves to the far end of the first li...
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
virtual void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
virtual const wxString & GetText() const
Return the string associated with the text object.
virtual void SetTextPos(const VECTOR2I &aPoint)
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
void SetLineSpacing(double aLineSpacing)
virtual void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
virtual void SetText(const wxString &aText)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
virtual double GetInterline(double aGlyphHeight, const METRICS &aFontMetrics) const =0
Compute the distance (interline) between 2 lines of text (for multiline texts).
static const METRICS & Default()
A logical library item identifier and consists of various portions much like a URI.
const UTF8 & GetLibItemName() const
Define a library symbol object.
SCH_FIELD & GetDescriptionField()
SCH_FIELD & GetFootprintField()
SCH_FIELD & GetValueField()
void RemoveDrawItem(SCH_ITEM *aItem)
Remove draw aItem from list.
void AddField(SCH_FIELD *aField)
Add a field.
std::vector< SCH_PIN * > GetGraphicalPins(int aUnit=0, int aBodyStyle=0) const override
Graphical pins: Return schematic pin objects as drawn (unexpanded), filtered by unit/body.
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
SCH_FIELD & GetReferenceField()
void SetText(const wxString &aText) override
const wxString & GetName() const
PIN_ORIENTATION GetOrientation() const
VECTOR2I GetPosition() const override
ELECTRICAL_PINTYPE GetType() const
Placed instances and connectivity: component, symbol and pad instances, nets, nodes,...
Shapes, vertices and the free-standing drawn items.
Free pads, apart because they derive from a connectivity class.
Symbols, components and gates, embedded in designs or the single object of a library item stream.
Design items, attributes, styles, layers, net classes and spacings.
Schematic graphics, texts and symbols shared by the sheet builder and the symbol libraries,...
Easy-PC's text measurement, so text lands where Easy-PC draws it.
Design units of 100 nm and angles of thousandths of a degree, anticlockwise from +X with Y up.
static constexpr EDA_ANGLE ANGLE_VERTICAL
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
@ FILLED_SHAPE
Fill with object color.
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
SCH_LAYER_ID
Eeschema drawing layers.
static std::vector< VECTOR2D > arcAsPolyline(const VECTOR2D &aStart, const VECTOR2D &aEnd, const VECTOR2D &aCentre, int32_t aAngle, bool aAnticlockwise)
Points after aStart of an arc span at ARC_HIGH_DEF, at most 16384 of them.
GATE_TERMINAL ResolveTerminal(const SOURCE_PCB_COMPONENT *aPcb, int aGate, int aTerminal)
Terminal aTerminal (0-based) of gate aGate; formats before 9000 map a bare pad number,...
std::vector< wxString > ExpandPinNumberList(const wxString &aList, wxString *aDisplay)
Expand a gate pin's component pin list by Easy-PC's pin list syntax: items separated by ,...
std::unique_ptr< SCH_TEXT > ConvertFreeText(const SOURCE_FREE_TEXT &aText, const SCH_FRAME &aFrame, SCH_LAYER_ID aLayer, int aUnit, bool aKeepUpright)
int32_t UprightRotation(int32_t aAngle, bool aKeepUpright)
With text kept upright, an angle above 135 and up to 305 degrees turns by 180.
constexpr double COORD_LIMIT
Half of KiCad's integer range, so shape code rotating or adding coordinates cannot overflow.
std::unique_ptr< LIB_SYMBOL > ConvertComponentSymbol(const SCH_COMPONENT_SOURCE &aSrc, const LIB_ID &aId)
One unit per gate in symbol-local coordinates, zero-length passive pins at the pads,...
static VECTOR2I mapD(const SCH_FRAME &aFrame, const VECTOR2D &aPt)
bool DrawsUpright(const SOURCE_TEXT_POSITION &aPos, bool aKeepUpright)
True when a design that keeps text upright turns aPos about the far end of its first line.
std::vector< std::unique_ptr< SCH_SHAPE > > ConvertShape(const SOURCE_SHAPE &aShape, const SCH_FRAME &aFrame, SCH_LAYER_ID aLayer, int aStrokeWidth, bool aFilled, int aUnit)
Outline of a shape: polylines, arcs and circles; a filled outline with arcs is one polygon.
std::unique_ptr< LIB_SYMBOL > ConvertSymbol(const SOURCE_SYMBOL &aSymbol, const LIB_ID &aId)
A .ssl symbol alone: one unit, pins numbered by pad number.
static VECTOR2D rotateAbout(const VECTOR2D &aPt, const VECTOR2D &aCentre, double aRadians)
std::vector< std::unique_ptr< SCH_SHAPE > > ConvertShapeItem(const SOURCE_SHAPE_ITEM &aItem, const SCH_FRAME &aFrame, SCH_LAYER_ID aLayer, int aUnit)
A shape item with its own line style and fill.
bool IsPadList(const wxString &aPcbSymbolPin)
Whether a gate pin's pad reference names several pads ("-1", the unmapped marker, does not)
std::vector< T * > TypedItems(const OBJECT *aList)
The items of ListItems that are a T, in order.
constexpr int32_t NormalizeAngle(int32_t aAngle)
Wrap an angle into [0, ANGLE_FULL_TURN)
wxString ToKiCadMarkup(const wxString &aText)
A displayed string in KiCad's markup.
static VECTOR2D arcCentre(const VECTOR2D &aStart, const VECTOR2D &aEnd, int32_t aAngle, bool aAnticlockwise)
Centre of an arc span from its ends and swept angle.
VECTOR2I TextSize(const SOURCE_TEXT_STYLE &aStyle)
KiCad text size for a source text style: its height as the width, its capital height as the height.
@ VALUE_ATTRIBUTE
the attribute the value position names
void ApplyTextPosition(EDA_TEXT &aText, const SOURCE_TEXT_POSITION &aPos, const SCH_FRAME &aFrame, bool aKeepUpright, const wxString &aMeasured)
Place any KiCad text as the source position says: anchor, angle, mirror, justification and style.
std::vector< const SOURCE_SEGMENT * > ShapeVertices(const SOURCE_SHAPE &aShape)
A shape's vertices in drawing order, following next references for formats 1 and 2.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
@ PT_NC
not connected (must be left open)
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin.
@ PIN_UP
The pin extends upwards from the connection point: Probably on the bottom side of the symbol.
@ PIN_RIGHT
The pin extends rightwards from the connection point.
@ PIN_LEFT
The pin extends leftwards from the connection point: Probably on the right side of the symbol.
@ PIN_DOWN
The pin extends downwards from the connection: Probably on the top side of the symbol.
wxString EscapeStackedPinItem(const wxString &aPinNumber)
Escape the characters that carry structural meaning inside stacked pin notation ('[',...
What a package's gate map says about one gate terminal.
Root of every deserialized object.
Everything one component LIB_SYMBOL is made from.
std::vector< const SOURCE_SYMBOL * > Gates
symbol per gate; null leaves that unit empty
const SOURCE_SCM_COMPONENT * Schematic
wxArrayString FootprintFilters
const SOURCE_PCB_COMPONENT * Board
the package whose gate map numbers the pins
bool PinTexts
a placed part draws its pin texts from its pad instances
Design to KiCad mapping: X shifted, Y negated about the origin.
VECTOR2I Map(int64_t aX, int64_t aY) const
An array: owner tag, then a counted list of objects.
std::vector< OBJECT * > Items
OBJECT * Attributes
attribute array
A pad of a symbol definition.
One gate's terminals to footprint pads.
OBJECT * Pins
gate pin array, format above 8999
std::vector< int32_t > PcbSymbolPins
older formats: pad number per terminal, -1 unmapped
A schematic symbol and its pin names.
The package half of a component.
OBJECT * GateMaps
one per schematic gate in order
Pin name and pin number definitions.
wxString DefaultReference
bool HasNextRef
the stream carried a next vertex (shape format below 3)
int32_t ArcAngle
swept angle, 0 for a straight span
OBJECT * Shape
design shape
bool IsClosed() const
The last vertex links back to the first (formats 1 and 2) or the closed byte is set (format 3)
std::vector< OBJECT * > Segments
the vertex list as read
Footprints and schematic symbols alike.
int32_t Height
the accessor is GetWidth but it is the text height
int32_t InterlineHeightPercent
@ USER
The field ID hasn't been set yet; field is invalid.
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
wxString result
Test unit parsing edge cases and error handling.
GR_TEXT_H_ALIGN_T
This is API surface mapped to common.types.HorizontalAlignment.
GR_TEXT_V_ALIGN_T
This is API surface mapped to common.types.VertialAlignment.
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D