KiCad PCB EDA Suite
Loading...
Searching...
No Matches
graphics_importer_lib_symbol.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KICAD, a free EDA CAD application.
3 *
4 * Copyright (C) 2016 CERN
5 * @author Maciej Suminski <[email protected]>
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
23
24#include <lib_symbol.h>
25#include <sch_shape.h>
26#include <sch_text.h>
27#include <memory>
28
29
31 m_symbol( aSymbol ), m_unit( aUnit )
32{
33 m_millimeterToIu = schIUScale.mmToIU( 1.0 );
34}
35
36
38{
39 VECTOR2D coord = aCoordinate;
40 coord *= GetScale();
41 coord += GetImportOffsetMM();
42 coord *= GetMillimeterToIuFactor();
43
44 return KiROUND( coord );
45}
46
47
49{
51 double scale = ( std::abs( factor.x ) + std::abs( factor.y ) ) * 0.5;
52
53 if( aLineWidth <= 0.0 )
54 return int( GetLineWidthMM() * scale );
55
56 // aLineWidth is in mm:
57 return int( aLineWidth * scale );
58}
59
60
62{
63 // Historicaly -1 meant no-stroke in Eeschema.
64 int width = ( aStroke.GetWidth() == -1 ) ? -1 : MapLineWidth( aStroke.GetWidth() );
65
66 return STROKE_PARAMS( width, aStroke.GetPlotStyle(), aStroke.GetColor() );
67}
68
69
71 const IMPORTED_STROKE& aStroke )
72{
73 VECTOR2I pt0 = MapCoordinate( aStart );
74 VECTOR2I pt1 = MapCoordinate( aEnd );
75
76 // Skip 0 len lines:
77 if( pt0 == pt1 )
78 return;
79
80 std::unique_ptr<SCH_SHAPE> line = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY, LAYER_DEVICE );
81 line->SetParent( m_symbol );
82 line->SetUnit( m_unit );
83 line->SetStroke( MapStrokeParams( aStroke ) );
84
85 line->AddPoint( pt0 );
86 line->AddPoint( pt1 );
87
88 addItem( std::move( line ) );
89}
90
91
92void GRAPHICS_IMPORTER_LIB_SYMBOL::AddCircle( const VECTOR2D& aCenter, double aRadius,
93 const IMPORTED_STROKE& aStroke, bool aFilled,
94 const COLOR4D& aFillColor )
95{
96 std::unique_ptr<SCH_SHAPE> circle = std::make_unique<SCH_SHAPE>( SHAPE_T::CIRCLE, LAYER_DEVICE );
97 circle->SetParent( m_symbol );
98 circle->SetUnit( m_unit );
99 circle->SetFillColor( aFillColor );
100 circle->SetFilled( aFilled );
101 circle->SetStroke( MapStrokeParams( aStroke ) );
102 circle->SetStart( MapCoordinate( aCenter ) );
103 circle->SetEnd( MapCoordinate( VECTOR2D( aCenter.x + aRadius, aCenter.y ) ) );
104
105 addItem( std::move( circle ) );
106}
107
108
109void GRAPHICS_IMPORTER_LIB_SYMBOL::AddArc( const VECTOR2D& aCenter, const VECTOR2D& aStart,
110 const EDA_ANGLE& aAngle, const IMPORTED_STROKE& aStroke )
111{
112 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>( SHAPE_T::ARC, LAYER_DEVICE );
113 arc->SetParent( m_symbol );
114 arc->SetUnit( m_unit );
115
120 VECTOR2D end = aStart;
121 VECTOR2D mid = aStart;
122
123 RotatePoint( end, aCenter, -aAngle );
124 RotatePoint( mid, aCenter, -aAngle / 2.0 );
125
126 arc->SetArcGeometry( MapCoordinate( aStart ), MapCoordinate( mid ), MapCoordinate( end ) );
127
128 // Ensure the arc can be handled by KiCad. Arcs with a too big radius cannot.
129 // The criteria used here is radius < MAX_INT / 2.
130 // this is not perfect, but we do not know the exact final position of the arc, so
131 // we cannot test the coordinate values, because the arc can be moved before being placed.
132 VECTOR2D center = CalcArcCenter( arc->GetStart(), arc->GetEnd(), aAngle );
133 double radius = ( center - arc->GetStart() ).EuclideanNorm();
134 constexpr double rd_max_value = std::numeric_limits<VECTOR2I::coord_type>::max() / 2.0;
135
136 if( radius >= rd_max_value )
137 {
138 // Arc cannot be handled: convert it to a segment
139 AddLine( aStart, end, aStroke );
140 return;
141 }
142
143 arc->SetStroke( MapStrokeParams( aStroke ) );
144
145 addItem( std::move( arc ) );
146}
147
148
149void GRAPHICS_IMPORTER_LIB_SYMBOL::AddPolygon( const std::vector<VECTOR2D>& aVertices,
150 const IMPORTED_STROKE& aStroke, bool aFilled,
151 const COLOR4D& aFillColor )
152{
153 std::vector<VECTOR2I> convertedPoints;
154 convertedPoints.reserve( aVertices.size() );
155
156 for( const VECTOR2D& precisePoint : aVertices )
157 convertedPoints.emplace_back( MapCoordinate( precisePoint ) );
158
159 if( convertedPoints.empty() )
160 return;
161
162 std::unique_ptr<SCH_SHAPE> polygon = std::make_unique<SCH_SHAPE>( SHAPE_T::POLY, LAYER_DEVICE );
163 polygon->SetParent( m_symbol );
164 polygon->SetUnit( m_unit );
165
166 if( aFilled )
167 {
168 polygon->SetFillMode( aFillColor != COLOR4D::UNSPECIFIED ? FILL_T::FILLED_WITH_COLOR
170 }
171
172 polygon->SetFillColor( aFillColor );
173 polygon->SetPolyPoints( convertedPoints );
174 polygon->AddPoint( convertedPoints[0] ); // Need to close last point for libedit
175
176 polygon->SetStroke( MapStrokeParams( aStroke ) );
177
178 if( polygon->IsPolyShapeValid() )
179 addItem( std::move( polygon ) );
180}
181
182
183void GRAPHICS_IMPORTER_LIB_SYMBOL::AddText( const VECTOR2D& aOrigin, const wxString& aText,
184 double aHeight, double aWidth, double aThickness,
185 double aOrientation, GR_TEXT_H_ALIGN_T aHJustify,
186 GR_TEXT_V_ALIGN_T aVJustify, const COLOR4D& aColor )
187{
188 auto textItem = std::make_unique<SCH_TEXT>( MapCoordinate( aOrigin ), aText, LAYER_DEVICE );
189 textItem->SetParent( m_symbol );
190 textItem->SetUnit( m_unit );
191 textItem->SetTextColor( aColor );
192 textItem->SetTextThickness( MapLineWidth( aThickness ) );
193 textItem->SetTextAngle( EDA_ANGLE( aOrientation, DEGREES_T ) );
194 textItem->SetTextWidth( aWidth * ImportScalingFactor().x );
195 textItem->SetTextHeight( aHeight * ImportScalingFactor().y );
196 textItem->SetVertJustify( aVJustify );
197 textItem->SetHorizJustify( aHJustify );
198
199 addItem( std::move( textItem ) );
200}
201
202
204 const VECTOR2D& aBezierControl1,
205 const VECTOR2D& aBezierControl2, const VECTOR2D& aEnd,
206 const IMPORTED_STROKE& aStroke )
207{
208 std::unique_ptr<SCH_SHAPE> spline = std::make_unique<SCH_SHAPE>( SHAPE_T::BEZIER, LAYER_DEVICE );
209 spline->SetParent( m_symbol );
210 spline->SetUnit( m_unit );
211 spline->SetStroke( MapStrokeParams( aStroke ) );
212 spline->SetStart( MapCoordinate( aStart ) );
213 spline->SetBezierC1( MapCoordinate( aBezierControl1 ) );
214 spline->SetBezierC2( MapCoordinate( aBezierControl2 ) );
215 spline->SetEnd( MapCoordinate( aEnd ) );
216 spline->RebuildBezierToSegmentsPointsList( schIUScale.mmToIU( ARC_LOW_DEF_MM ) );
217
218 // If the spline is degenerated (i.e. a segment) add it as segment or discard it if
219 // null (i.e. very small) length)
220 if( spline->GetBezierPoints().size() <= 2 )
221 {
222 // segment smaller than 1 IU len are skipped by AddLine()
223 AddLine( aStart, aEnd, aStroke );
224 return;
225 }
226
227 addItem( std::move( spline ) );
228}
229
230
231void GRAPHICS_IMPORTER_LIB_SYMBOL::AddEllipse( const VECTOR2D& aCenter, double aMajorRadius, double aMinorRadius,
232 const EDA_ANGLE& aRotation, const IMPORTED_STROKE& aStroke, bool aFilled,
233 const COLOR4D& aFillColor )
234{
235 std::unique_ptr<SCH_SHAPE> ellipse = std::make_unique<SCH_SHAPE>( SHAPE_T::ELLIPSE, LAYER_DEVICE );
236 ellipse->SetParent( m_symbol );
237 ellipse->SetUnit( m_unit );
238 ellipse->SetStroke( MapStrokeParams( aStroke ) );
239 ellipse->SetFilled( aFilled );
240 ellipse->SetFillColor( aFillColor );
241
242 ellipse->SetEllipseCenter( MapCoordinate( aCenter ) );
243 ellipse->SetEllipseMajorRadius( KiROUND( aMajorRadius * ImportScalingFactor().x ) );
244 ellipse->SetEllipseMinorRadius( KiROUND( aMinorRadius * ImportScalingFactor().y ) );
245 ellipse->SetEllipseRotation( aRotation );
246
247 addItem( std::move( ellipse ) );
248}
249
250
251void GRAPHICS_IMPORTER_LIB_SYMBOL::AddEllipseArc( const VECTOR2D& aCenter, double aMajorRadius, double aMinorRadius,
252 const EDA_ANGLE& aRotation, const EDA_ANGLE& aStartAngle,
253 const EDA_ANGLE& aEndAngle, const IMPORTED_STROKE& aStroke )
254{
255 std::unique_ptr<SCH_SHAPE> arc = std::make_unique<SCH_SHAPE>( SHAPE_T::ELLIPSE_ARC, LAYER_DEVICE );
256 arc->SetParent( m_symbol );
257 arc->SetUnit( m_unit );
258 arc->SetStroke( MapStrokeParams( aStroke ) );
259
260 arc->SetEllipseCenter( MapCoordinate( aCenter ) );
261 arc->SetEllipseMajorRadius( KiROUND( aMajorRadius * ImportScalingFactor().x ) );
262 arc->SetEllipseMinorRadius( KiROUND( aMinorRadius * ImportScalingFactor().y ) );
263 arc->SetEllipseRotation( aRotation );
264 arc->SetEllipseStartAngle( aStartAngle );
265 arc->SetEllipseEndAngle( aEndAngle );
266
267 addItem( std::move( arc ) );
268}
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:123
constexpr double ARC_LOW_DEF_MM
Definition base_units.h:127
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:986
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:398
VECTOR2I MapCoordinate(const VECTOR2D &aCoordinate)
Convert an imported coordinate to a board coordinate, according to the internal units,...
void AddEllipseArc(const VECTOR2D &aCenter, double aMajorRadius, double aMinorRadius, const EDA_ANGLE &aRotation, const EDA_ANGLE &aStartAngle, const EDA_ANGLE &aEndAngle, const IMPORTED_STROKE &aStroke) override
Create an object representing an elliptical arc.
void AddText(const VECTOR2D &aOrigin, const wxString &aText, double aHeight, double aWidth, double aThickness, double aOrientation, GR_TEXT_H_ALIGN_T aHJustify, GR_TEXT_V_ALIGN_T aVJustify, const COLOR4D &aColor=COLOR4D::UNSPECIFIED) override
Create an object representing a text.
void AddSpline(const VECTOR2D &aStart, const VECTOR2D &aBezierControl1, const VECTOR2D &aBezierControl2, const VECTOR2D &aEnd, const IMPORTED_STROKE &aStroke) override
Create an object representing an arc.
STROKE_PARAMS MapStrokeParams(const IMPORTED_STROKE &aStroke)
void AddPolygon(const std::vector< VECTOR2D > &aVertices, const IMPORTED_STROKE &aStroke, bool aFilled, const COLOR4D &aFillColor=COLOR4D::UNSPECIFIED) override
Create an object representing a polygon.
void AddEllipse(const VECTOR2D &aCenter, double aMajorRadius, double aMinorRadius, const EDA_ANGLE &aRotation, const IMPORTED_STROKE &aStroke, bool aFilled, const COLOR4D &aFillColor=COLOR4D::UNSPECIFIED) override
Create an object representing a closed ellipse.
void AddLine(const VECTOR2D &aStart, const VECTOR2D &aEnd, const IMPORTED_STROKE &aStroke) override
Create an object representing a line segment.
void AddArc(const VECTOR2D &aCenter, const VECTOR2D &aStart, const EDA_ANGLE &aAngle, const IMPORTED_STROKE &aStroke) override
Create an object representing an arc.
int MapLineWidth(double aLineWidth)
If aLineWidth < 0, the default line thickness value is returned.
void AddCircle(const VECTOR2D &aCenter, double aRadius, const IMPORTED_STROKE &aStroke, bool aFilled, const COLOR4D &aFillColor=COLOR4D::UNSPECIFIED) override
Create an object representing a circle.
GRAPHICS_IMPORTER_LIB_SYMBOL(LIB_SYMBOL *aSymbol, int aUnit)
VECTOR2D GetScale() const
double GetLineWidthMM() const
Return the line width used for importing the outlines (in mm).
void addItem(std::unique_ptr< EDA_ITEM > aItem)
Add an item to the imported shapes list.
double m_millimeterToIu
Factor to convert millimeters to Internal Units.
const VECTOR2D & GetImportOffsetMM() const
VECTOR2D ImportScalingFactor() const
A clone of IMPORTED_STROKE, but with floating-point width.
LINE_STYLE GetPlotStyle() const
double GetWidth() const
KIGFX::COLOR4D GetColor() const
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
Define a library symbol object.
Definition lib_symbol.h:79
Simple container to manage line stroke parameters.
@ DEGREES_T
Definition eda_angle.h:31
@ ELLIPSE
Definition eda_shape.h:52
@ ELLIPSE_ARC
Definition eda_shape.h:53
@ FILLED_WITH_COLOR
Definition eda_shape.h:63
@ FILLED_SHAPE
Fill with object color.
Definition eda_shape.h:61
@ LAYER_DEVICE
Definition layer_ids.h:464
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:400
const int scale
VECTOR2I center
int radius
VECTOR2I end
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
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.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition trigo.cpp:225
const VECTOR2I CalcArcCenter(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Determine the center of an arc or circle given three points on its circumference.
Definition trigo.cpp:530
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683
VECTOR2< double > VECTOR2D
Definition vector2d.h:682