KiCad PCB EDA Suite
sch_sexpr_plugin_common.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) 2022 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <advanced_config.h>
21#include <base_units.h>
22#include <macros.h>
23#include <schematic_lexer.h>
25#include <string_utils.h>
26
27
28using namespace TSCHEMATIC_T;
29
30
31static const char* emptyString = "";
32
33
34void formatFill( OUTPUTFORMATTER* aFormatter, int aNestLevel, FILL_T aFillMode,
35 const COLOR4D& aFillColor )
36{
37 const char* fillType;
38
39 switch( aFillMode )
40 {
41 default:
42 case FILL_T::NO_FILL: fillType = "none"; break;
43 case FILL_T::FILLED_SHAPE: fillType = "outline"; break;
44 case FILL_T::FILLED_WITH_BG_BODYCOLOR: fillType = "background"; break;
45 case FILL_T::FILLED_WITH_COLOR: fillType = "color"; break;
46 }
47
48 if( aFillMode == FILL_T::FILLED_WITH_COLOR )
49 {
50 aFormatter->Print( aNestLevel, "(fill (type %s) (color %d %d %d %s))",
51 fillType,
52 KiROUND( aFillColor.r * 255.0 ),
53 KiROUND( aFillColor.g * 255.0 ),
54 KiROUND( aFillColor.b * 255.0 ),
55 FormatDouble2Str( aFillColor.a ).c_str() );
56 }
57 else
58 {
59 aFormatter->Print( aNestLevel, "(fill (type %s))",
60 fillType );
61 }
62}
63
64
66{
67 switch( aType )
68 {
70 return SCHEMATIC_LEXER::TokenName( T_input );
71
73 return SCHEMATIC_LEXER::TokenName( T_output );
74
76 return SCHEMATIC_LEXER::TokenName( T_bidirectional );
77
79 return SCHEMATIC_LEXER::TokenName( T_tri_state );
80
82 return SCHEMATIC_LEXER::TokenName( T_passive );
83
85 return SCHEMATIC_LEXER::TokenName( T_free );
86
88 return SCHEMATIC_LEXER::TokenName( T_unspecified );
89
91 return SCHEMATIC_LEXER::TokenName( T_power_in );
92
94 return SCHEMATIC_LEXER::TokenName( T_power_out );
95
97 return SCHEMATIC_LEXER::TokenName( T_open_collector );
98
100 return SCHEMATIC_LEXER::TokenName( T_open_emitter );
101
103 return SCHEMATIC_LEXER::TokenName( T_no_connect );
104
105 default:
106 wxFAIL_MSG( "Missing symbol library pin connection type" );
107 }
108
109 return emptyString;
110}
111
112
114{
115 switch( aShape )
116 {
118 return SCHEMATIC_LEXER::TokenName( T_line );
119
121 return SCHEMATIC_LEXER::TokenName( T_inverted );
122
124 return SCHEMATIC_LEXER::TokenName( T_clock );
125
127 return SCHEMATIC_LEXER::TokenName( T_inverted_clock );
128
130 return SCHEMATIC_LEXER::TokenName( T_input_low );
131
133 return SCHEMATIC_LEXER::TokenName( T_clock_low );
134
136 return SCHEMATIC_LEXER::TokenName( T_output_low );
137
139 return SCHEMATIC_LEXER::TokenName( T_edge_clock_high );
140
142 return SCHEMATIC_LEXER::TokenName( T_non_logic );
143
144 default:
145 wxFAIL_MSG( "Missing symbol library pin shape type" );
146 }
147
148 return emptyString;
149}
150
151
152EDA_ANGLE getPinAngle( int aOrientation )
153{
154 switch( aOrientation )
155 {
156 case PIN_RIGHT: return ANGLE_0;
157 case PIN_LEFT: return ANGLE_180;
158 case PIN_UP: return ANGLE_90;
159 case PIN_DOWN: return ANGLE_270;
160 default: wxFAIL_MSG( "Missing symbol library pin orientation type" ); return ANGLE_0;
161 }
162}
163
164
166{
167 switch( aShape )
168 {
169 case LABEL_FLAG_SHAPE::L_INPUT: return SCHEMATIC_LEXER::TokenName( T_input );
170 case LABEL_FLAG_SHAPE::L_OUTPUT: return SCHEMATIC_LEXER::TokenName( T_output );
171 case LABEL_FLAG_SHAPE::L_BIDI: return SCHEMATIC_LEXER::TokenName( T_bidirectional );
172 case LABEL_FLAG_SHAPE::L_TRISTATE: return SCHEMATIC_LEXER::TokenName( T_tri_state );
173 case LABEL_FLAG_SHAPE::L_UNSPECIFIED: return SCHEMATIC_LEXER::TokenName( T_passive );
174 case LABEL_FLAG_SHAPE::F_DOT: return SCHEMATIC_LEXER::TokenName( T_dot );
175 case LABEL_FLAG_SHAPE::F_ROUND: return SCHEMATIC_LEXER::TokenName( T_round );
176 case LABEL_FLAG_SHAPE::F_DIAMOND: return SCHEMATIC_LEXER::TokenName( T_diamond );
177 case LABEL_FLAG_SHAPE::F_RECTANGLE: return SCHEMATIC_LEXER::TokenName( T_rectangle );
178 default: wxFAIL; return SCHEMATIC_LEXER::TokenName( T_passive );
179 }
180}
181
182
184{
185 switch( aSide )
186 {
188 case SHEET_SIDE::LEFT: return ANGLE_180;
189 case SHEET_SIDE::RIGHT: return ANGLE_0;
190 case SHEET_SIDE::TOP: return ANGLE_90;
191 case SHEET_SIDE::BOTTOM: return ANGLE_270;
192 default: wxFAIL; return ANGLE_0;
193 }
194}
195
196
197const char* getTextTypeToken( KICAD_T aType )
198{
199 switch( aType )
200 {
201 case SCH_TEXT_T: return SCHEMATIC_LEXER::TokenName( T_text );
202 case SCH_LABEL_T: return SCHEMATIC_LEXER::TokenName( T_label );
203 case SCH_GLOBAL_LABEL_T: return SCHEMATIC_LEXER::TokenName( T_global_label );
204 case SCH_HIER_LABEL_T: return SCHEMATIC_LEXER::TokenName( T_hierarchical_label );
205 case SCH_DIRECTIVE_LABEL_T: return SCHEMATIC_LEXER::TokenName( T_netclass_flag );
206 default: wxFAIL; return SCHEMATIC_LEXER::TokenName( T_text );
207 }
208}
209
210
211void formatArc( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aArc,
212 bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode,
213 const COLOR4D& aFillColor, const KIID& aUuid )
214{
215 aFormatter->Print( aNestLevel, "(arc%s (start %s) (mid %s) (end %s)\n",
216 aIsPrivate ? " private" : "",
220
221 aStroke.Format( aFormatter, schIUScale, aNestLevel + 1 );
222 aFormatter->Print( 0, "\n" );
223 formatFill( aFormatter, aNestLevel + 1, aFillMode, aFillColor );
224 aFormatter->Print( 0, "\n" );
225
226 if( aUuid != niluuid )
227 aFormatter->Print( aNestLevel + 1, "(uuid %s)\n", TO_UTF8( aUuid.AsString() ) );
228
229 aFormatter->Print( aNestLevel, ")\n" );
230}
231
232
233void formatCircle( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aCircle,
234 bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode,
235 const COLOR4D& aFillColor, const KIID& aUuid )
236{
237 aFormatter->Print( aNestLevel, "(circle%s (center %s %s) (radius %s)\n",
238 aIsPrivate ? " private" : "",
242
243 aStroke.Format( aFormatter, schIUScale, aNestLevel + 1 );
244 aFormatter->Print( 0, "\n" );
245 formatFill( aFormatter, aNestLevel + 1, aFillMode, aFillColor );
246 aFormatter->Print( 0, "\n" );
247
248 if( aUuid != niluuid )
249 aFormatter->Print( aNestLevel + 1, "(uuid %s)\n", TO_UTF8( aUuid.AsString() ) );
250
251 aFormatter->Print( aNestLevel, ")\n" );
252}
253
254
255void formatRect( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aRect,
256 bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode,
257 const COLOR4D& aFillColor, const KIID& aUuid )
258{
259 aFormatter->Print( aNestLevel, "(rectangle%s (start %s %s) (end %s %s)\n",
260 aIsPrivate ? " private" : "",
265 aStroke.Format( aFormatter, schIUScale, aNestLevel + 1 );
266 aFormatter->Print( 0, "\n" );
267 formatFill( aFormatter, aNestLevel + 1, aFillMode, aFillColor );
268 aFormatter->Print( 0, "\n" );
269
270 if( aUuid != niluuid )
271 aFormatter->Print( aNestLevel + 1, "(uuid %s)\n", TO_UTF8( aUuid.AsString() ) );
272
273 aFormatter->Print( aNestLevel, ")\n" );
274}
275
276
277void formatBezier( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aBezier,
278 bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode,
279 const COLOR4D& aFillColor, const KIID& aUuid )
280{
281 aFormatter->Print( aNestLevel, "(bezier%s (pts ",
282 aIsPrivate ? " private" : "" );
283
284 for( const VECTOR2I& pt : { aBezier->GetStart(), aBezier->GetBezierC1(),
285 aBezier->GetBezierC2(), aBezier->GetEnd() } )
286 {
287 aFormatter->Print( 0, " (xy %s %s)",
290 }
291
292 aFormatter->Print( 0, ")\n" ); // Closes pts token on same line.
293
294 aStroke.Format( aFormatter, schIUScale, aNestLevel + 1 );
295 aFormatter->Print( 0, "\n" );
296 formatFill( aFormatter, aNestLevel + 1, aFillMode, aFillColor );
297 aFormatter->Print( 0, "\n" );
298
299 if( aUuid != niluuid )
300 aFormatter->Print( aNestLevel + 1, "(uuid %s)\n", TO_UTF8( aUuid.AsString() ) );
301
302 aFormatter->Print( aNestLevel, ")\n" );
303}
304
305
306void formatPoly( OUTPUTFORMATTER* aFormatter, int aNestLevel, EDA_SHAPE* aPolyLine,
307 bool aIsPrivate, const STROKE_PARAMS& aStroke, FILL_T aFillMode,
308 const COLOR4D& aFillColor, const KIID& aUuid )
309{
310 int newLine = 0;
311 int lineCount = 1;
312 aFormatter->Print( aNestLevel, "(polyline%s\n",
313 aIsPrivate ? " private" : "" );
314 aFormatter->Print( aNestLevel + 1, "(pts" );
315
316 for( const VECTOR2I& pt : aPolyLine->GetPolyShape().Outline( 0 ).CPoints() )
317 {
318 if( newLine == 4 || !ADVANCED_CFG::GetCfg().m_CompactSave )
319 {
320 aFormatter->Print( 0, "\n" );
321 aFormatter->Print( aNestLevel + 2, "(xy %s %s)",
324 newLine = 0;
325 lineCount += 1;
326 }
327 else
328 {
329 aFormatter->Print( 0, " (xy %s %s)",
332 }
333
334 newLine += 1;
335 }
336
337 if( lineCount == 1 )
338 {
339 aFormatter->Print( 0, ")\n" ); // Closes pts token on same line.
340 }
341 else
342 {
343 aFormatter->Print( 0, "\n" );
344 aFormatter->Print( aNestLevel + 1, ")\n" ); // Closes pts token with multiple lines.
345 }
346
347 aStroke.Format( aFormatter, schIUScale, aNestLevel + 1 );
348 aFormatter->Print( 0, "\n" );
349 formatFill( aFormatter, aNestLevel + 1, aFillMode, aFillColor );
350 aFormatter->Print( 0, "\n" );
351
352 if( aUuid != niluuid )
353 aFormatter->Print( aNestLevel + 1, "(uuid %s)\n", TO_UTF8( aUuid.AsString() ) );
354
355 aFormatter->Print( aNestLevel, ")\n" );
356}
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
const VECTOR2I & GetBezierC2() const
Definition: eda_shape.h:179
SHAPE_POLY_SET & GetPolyShape()
Definition: eda_shape.h:247
int GetRadius() const
Definition: eda_shape.cpp:523
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition: eda_shape.h:145
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition: eda_shape.h:120
const VECTOR2I & GetBezierC1() const
Definition: eda_shape.h:176
VECTOR2I GetArcMid() const
Definition: eda_shape.cpp:488
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
double r
Red component.
Definition: color4d.h:390
double g
Green component.
Definition: color4d.h:391
double a
Alpha component.
Definition: color4d.h:393
double b
Blue component.
Definition: color4d.h:392
Definition: kiid.h:48
wxString AsString() const
Definition: kiid.cpp:257
An interface used to output 8 bit text in a convenient way.
Definition: richio.h:310
int PRINTF_FUNC Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition: richio.cpp:433
const std::vector< VECTOR2I > & CPoints() const
SHAPE_LINE_CHAIN & Outline(int aIndex)
Simple container to manage line stroke parameters.
Definition: stroke_params.h:88
void Format(OUTPUTFORMATTER *out, const EDA_IU_SCALE &aIuScale, int nestLevel) const
static constexpr EDA_ANGLE & ANGLE_180
Definition: eda_angle.h:427
static constexpr EDA_ANGLE & ANGLE_90
Definition: eda_angle.h:425
static constexpr EDA_ANGLE & ANGLE_0
Definition: eda_angle.h:423
static constexpr EDA_ANGLE & ANGLE_270
Definition: eda_angle.h:428
FILL_T
Definition: eda_shape.h:54
@ FILLED_WITH_COLOR
@ FILLED_WITH_BG_BODYCOLOR
@ FILLED_SHAPE
KIID niluuid(0)
@ PIN_LEFT
Definition: lib_pin.h:46
@ PIN_RIGHT
Definition: lib_pin.h:45
@ PIN_UP
Definition: lib_pin.h:47
@ PIN_DOWN
Definition: lib_pin.h:48
This file contains miscellaneous commonly used macros and functions.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
std::string FormatInternalUnits(const EDA_IU_SCALE &aIuScale, int aValue)
Converts aValue from internal units to a string appropriate for writing to file.
Definition: eda_units.cpp:139
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
Definition: pin_type.h:36
@ PT_INPUT
usual pin input: must be connected
@ PT_NC
not connected (must be left open)
@ PT_OUTPUT
usual output
@ PT_TRISTATE
tris state bus pin
@ PT_NIC
not internally connected (may be connected to anything)
@ PT_BIDI
input or output (like port for a microprocessor)
@ PT_OPENEMITTER
pin type open emitter
@ PT_POWER_OUT
output of a regulator: intended to be connected to power input pins
@ PT_OPENCOLLECTOR
pin type open collector
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
@ PT_UNSPECIFIED
unknown electrical properties: creates always a warning when connected
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin
GRAPHIC_PINSHAPE
Definition: pin_type.h:56
void formatCircle(OUTPUTFORMATTER *aFormatter, int aNestLevel, EDA_SHAPE *aCircle, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, const KIID &aUuid)
EDA_ANGLE getPinAngle(int aOrientation)
void formatArc(OUTPUTFORMATTER *aFormatter, int aNestLevel, EDA_SHAPE *aArc, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, const KIID &aUuid)
const char * getSheetPinShapeToken(LABEL_FLAG_SHAPE aShape)
const char * getPinElectricalTypeToken(ELECTRICAL_PINTYPE aType)
void formatFill(OUTPUTFORMATTER *aFormatter, int aNestLevel, FILL_T aFillMode, const COLOR4D &aFillColor)
Fill token formatting helper.
const char * getTextTypeToken(KICAD_T aType)
void formatRect(OUTPUTFORMATTER *aFormatter, int aNestLevel, EDA_SHAPE *aRect, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, const KIID &aUuid)
void formatBezier(OUTPUTFORMATTER *aFormatter, int aNestLevel, EDA_SHAPE *aBezier, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, const KIID &aUuid)
void formatPoly(OUTPUTFORMATTER *aFormatter, int aNestLevel, EDA_SHAPE *aPolyLine, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, const KIID &aUuid)
EDA_ANGLE getSheetPinAngle(SHEET_SIDE aSide)
const char * getPinShapeToken(GRAPHIC_PINSHAPE aShape)
static const char * emptyString
SHEET_SIDE
Define the edge of the sheet that the sheet pin is positioned.
Definition: sch_sheet_pin.h:46
LABEL_FLAG_SHAPE
Definition: sch_text.h:96
@ L_BIDI
Definition: sch_text.h:99
@ L_TRISTATE
Definition: sch_text.h:100
@ L_UNSPECIFIED
Definition: sch_text.h:101
@ F_DOT
Definition: sch_text.h:104
@ F_ROUND
Definition: sch_text.h:105
@ L_OUTPUT
Definition: sch_text.h:98
@ F_DIAMOND
Definition: sch_text.h:106
@ L_INPUT
Definition: sch_text.h:97
@ F_RECTANGLE
Definition: sch_text.h:107
std::string FormatDouble2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 This function is intended in...
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:154
@ SCH_LABEL_T
Definition: typeinfo.h:151
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:153
@ SCH_TEXT_T
Definition: typeinfo.h:150
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:152
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:85