KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_writer_v9.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 The 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
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20// Schematic writer for the KiCad 9.0 file format, extracted from the 9.0.0 release. It can
21// only emit what that release knew, so its output always opens there.
22
24
25#include <algorithm>
26#include <wx/mstream.h>
27#include <base_units.h>
28#include <bitmap_base.h>
29#include <build_version.h>
30#include <schematic_lexer.h>
31
32using namespace TSCHEMATIC_T;
33#include <ctl_flags.h>
34#include <font/font.h>
37#include <locale_io.h>
38#include <schematic.h>
39#include <sch_bitmap.h>
40#include <sch_bus_entry.h>
41#include <sch_edit_frame.h> // SYMBOL_ORIENTATION_T
42#include <sch_junction.h>
43#include <sch_line.h>
44#include <sch_no_connect.h>
45#include <sch_pin.h>
46#include <sch_rule_area.h>
47#include <sch_screen.h>
48#include <sch_shape.h>
49#include <sch_sheet.h>
50#include <sch_sheet_pin.h>
51#include <sch_symbol.h>
52#include <sch_table.h>
53#include <sch_tablecell.h>
54#include <sch_text.h>
55#include <sch_textbox.h>
56#include <string_utils.h>
57#include <richio.h>
58
59
60// Era copies of the shared fill and shape helpers. The current ones emit newer tokens.
61static const char* emptyString = "";
62
63static void formatArc( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aArc, bool aIsPrivate, const STROKE_PARAMS& aStroke,
64 FILL_T aFillMode, const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid = niluuid );
65static void formatCircle( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aCircle, bool aIsPrivate,
66 const STROKE_PARAMS& aStroke, FILL_T aFillMode, const COLOR4D& aFillColor, bool aInvertY,
67 const KIID& aUuid = niluuid );
68static void formatRect( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aRect, bool aIsPrivate, const STROKE_PARAMS& aStroke,
69 FILL_T aFillMode, const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid = niluuid );
70static void formatBezier( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aBezier, bool aIsPrivate,
71 const STROKE_PARAMS& aStroke, FILL_T aFillMode, const COLOR4D& aFillColor, bool aInvertY,
72 const KIID& aUuid = niluuid );
73static void formatPoly( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aPolyLine, bool aIsPrivate,
74 const STROKE_PARAMS& aStroke, FILL_T aFillMode, const COLOR4D& aFillColor, bool aInvertY,
75 const KIID& aUuid = niluuid );
76
77static void formatFill( OUTPUTFORMATTER* aFormatter, FILL_T aFillMode, const COLOR4D& aFillColor )
78{
79 const char* fillType;
80
81 switch( aFillMode )
82 {
83 default:
84 case FILL_T::NO_FILL: fillType = "none"; break;
85 case FILL_T::FILLED_SHAPE: fillType = "outline"; break;
86 case FILL_T::FILLED_WITH_BG_BODYCOLOR: fillType = "background"; break;
87 case FILL_T::FILLED_WITH_COLOR: fillType = "color"; break;
88 }
89
90 if( aFillMode == FILL_T::FILLED_WITH_COLOR )
91 {
92 aFormatter->Print( "(fill (type %s) (color %d %d %d %s))", fillType, KiROUND( aFillColor.r * 255.0 ),
93 KiROUND( aFillColor.g * 255.0 ), KiROUND( aFillColor.b * 255.0 ),
94 FormatDouble2Str( aFillColor.a ).c_str() );
95 }
96 else
97 {
98 aFormatter->Print( "(fill (type %s))", fillType );
99 }
100}
101
102
103// Era copies of EDA_TEXT::IsDefaultFormatting and EDA_TEXT::Format. The current ones no
104// longer treat visibility as formatting, so invisible fields would lose their hide flag.
105static bool isDefaultFormattingV9( const EDA_TEXT& aText )
106{
107 return ( aText.IsVisible() && !aText.IsMirrored() && aText.GetHorizJustify() == GR_TEXT_H_ALIGN_CENTER
108 && aText.GetVertJustify() == GR_TEXT_V_ALIGN_CENTER && aText.GetTextThickness() == 0 && !aText.IsItalic()
109 && !aText.IsBold() && !aText.IsMultilineAllowed() && aText.GetFontName().IsEmpty() );
110}
111
112
113static void formatEdaTextV9( OUTPUTFORMATTER* aFormatter, const EDA_TEXT& aText, int aControlBits )
114{
115 KICAD_FORMAT::LEGACY::FormatTextV9( aFormatter, aText, schIUScale, aControlBits );
116}
117
118
120{
121 switch( aType )
122 {
123 case ELECTRICAL_PINTYPE::PT_INPUT: return SCHEMATIC_LEXER::TokenName( T_input );
124
125 case ELECTRICAL_PINTYPE::PT_OUTPUT: return SCHEMATIC_LEXER::TokenName( T_output );
126
127 case ELECTRICAL_PINTYPE::PT_BIDI: return SCHEMATIC_LEXER::TokenName( T_bidirectional );
128
129 case ELECTRICAL_PINTYPE::PT_TRISTATE: return SCHEMATIC_LEXER::TokenName( T_tri_state );
130
131 case ELECTRICAL_PINTYPE::PT_PASSIVE: return SCHEMATIC_LEXER::TokenName( T_passive );
132
133 case ELECTRICAL_PINTYPE::PT_NIC: return SCHEMATIC_LEXER::TokenName( T_free );
134
135 case ELECTRICAL_PINTYPE::PT_UNSPECIFIED: return SCHEMATIC_LEXER::TokenName( T_unspecified );
136
137 case ELECTRICAL_PINTYPE::PT_POWER_IN: return SCHEMATIC_LEXER::TokenName( T_power_in );
138
139 case ELECTRICAL_PINTYPE::PT_POWER_OUT: return SCHEMATIC_LEXER::TokenName( T_power_out );
140
141 case ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR: return SCHEMATIC_LEXER::TokenName( T_open_collector );
142
143 case ELECTRICAL_PINTYPE::PT_OPENEMITTER: return SCHEMATIC_LEXER::TokenName( T_open_emitter );
144
145 case ELECTRICAL_PINTYPE::PT_NC: return SCHEMATIC_LEXER::TokenName( T_no_connect );
146
147 default: wxFAIL_MSG( "Missing symbol library pin connection type" );
148 }
149
150 return emptyString;
151}
152
153
154static const char* getPinShapeToken( GRAPHIC_PINSHAPE aShape )
155{
156 switch( aShape )
157 {
158 case GRAPHIC_PINSHAPE::LINE: return SCHEMATIC_LEXER::TokenName( T_line );
159
160 case GRAPHIC_PINSHAPE::INVERTED: return SCHEMATIC_LEXER::TokenName( T_inverted );
161
162 case GRAPHIC_PINSHAPE::CLOCK: return SCHEMATIC_LEXER::TokenName( T_clock );
163
164 case GRAPHIC_PINSHAPE::INVERTED_CLOCK: return SCHEMATIC_LEXER::TokenName( T_inverted_clock );
165
166 case GRAPHIC_PINSHAPE::INPUT_LOW: return SCHEMATIC_LEXER::TokenName( T_input_low );
167
168 case GRAPHIC_PINSHAPE::CLOCK_LOW: return SCHEMATIC_LEXER::TokenName( T_clock_low );
169
170 case GRAPHIC_PINSHAPE::OUTPUT_LOW: return SCHEMATIC_LEXER::TokenName( T_output_low );
171
172 case GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK: return SCHEMATIC_LEXER::TokenName( T_edge_clock_high );
173
174 case GRAPHIC_PINSHAPE::NONLOGIC: return SCHEMATIC_LEXER::TokenName( T_non_logic );
175
176 default: wxFAIL_MSG( "Missing symbol library pin shape type" );
177 }
178
179 return emptyString;
180}
181
182
184{
185 switch( aOrientation )
186 {
191 default: wxFAIL_MSG( "Missing symbol library pin orientation type" ); return ANGLE_0;
192 }
193}
194
195
196static const char* getSheetPinShapeToken( LABEL_FLAG_SHAPE aShape )
197{
198 switch( aShape )
199 {
200 case LABEL_FLAG_SHAPE::L_INPUT: return SCHEMATIC_LEXER::TokenName( T_input );
201 case LABEL_FLAG_SHAPE::L_OUTPUT: return SCHEMATIC_LEXER::TokenName( T_output );
202 case LABEL_FLAG_SHAPE::L_BIDI: return SCHEMATIC_LEXER::TokenName( T_bidirectional );
203 case LABEL_FLAG_SHAPE::L_TRISTATE: return SCHEMATIC_LEXER::TokenName( T_tri_state );
204 case LABEL_FLAG_SHAPE::L_UNSPECIFIED: return SCHEMATIC_LEXER::TokenName( T_passive );
205 case LABEL_FLAG_SHAPE::F_DOT: return SCHEMATIC_LEXER::TokenName( T_dot );
206 case LABEL_FLAG_SHAPE::F_ROUND: return SCHEMATIC_LEXER::TokenName( T_round );
207 case LABEL_FLAG_SHAPE::F_DIAMOND: return SCHEMATIC_LEXER::TokenName( T_diamond );
208 case LABEL_FLAG_SHAPE::F_RECTANGLE: return SCHEMATIC_LEXER::TokenName( T_rectangle );
209 default: wxFAIL; return SCHEMATIC_LEXER::TokenName( T_passive );
210 }
211}
212
213
215{
216 switch( aSide )
217 {
219 case SHEET_SIDE::LEFT: return ANGLE_180;
220 case SHEET_SIDE::RIGHT: return ANGLE_0;
221 case SHEET_SIDE::TOP: return ANGLE_90;
222 case SHEET_SIDE::BOTTOM: return ANGLE_270;
223 default: wxFAIL; return ANGLE_0;
224 }
225}
226
227
228static const char* getTextTypeToken( KICAD_T aType )
229{
230 switch( aType )
231 {
232 case SCH_TEXT_T: return SCHEMATIC_LEXER::TokenName( T_text );
233 case SCH_LABEL_T: return SCHEMATIC_LEXER::TokenName( T_label );
234 case SCH_GLOBAL_LABEL_T: return SCHEMATIC_LEXER::TokenName( T_global_label );
235 case SCH_HIER_LABEL_T: return SCHEMATIC_LEXER::TokenName( T_hierarchical_label );
236 case SCH_DIRECTIVE_LABEL_T: return SCHEMATIC_LEXER::TokenName( T_netclass_flag );
237 default: wxFAIL; return SCHEMATIC_LEXER::TokenName( T_text );
238 }
239}
240
241
242static std::string formatIU( const int& aValue )
243{
245}
246
247
248static std::string formatIU( const VECTOR2I& aPt, bool aInvertY )
249{
250 VECTOR2I pt( aPt.x, aInvertY ? -aPt.y : aPt.y );
252}
253
254
255static void formatArc( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aArc, bool aIsPrivate, const STROKE_PARAMS& aStroke,
256 FILL_T aFillMode, const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid )
257{
258 aFormatter->Print( "(arc %s (start %s) (mid %s) (end %s)", aIsPrivate ? "private" : "",
259 formatIU( aArc->GetStart(), aInvertY ).c_str(), formatIU( aArc->GetArcMid(), aInvertY ).c_str(),
260 formatIU( aArc->GetEnd(), aInvertY ).c_str() );
261
262 KICAD_FORMAT::LEGACY::FormatStroke( aFormatter, aStroke, schIUScale );
263 formatFill( aFormatter, aFillMode, aFillColor );
264
265 if( aUuid != niluuid )
266 aFormatter->Print( "(uuid %s)", TO_UTF8( aUuid.AsString() ) );
267
268 aFormatter->Print( ")" );
269}
270
271
272static void formatCircle( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aCircle, bool aIsPrivate,
273 const STROKE_PARAMS& aStroke, FILL_T aFillMode, const COLOR4D& aFillColor, bool aInvertY,
274 const KIID& aUuid )
275{
276 aFormatter->Print( "(circle %s (center %s) (radius %s)", aIsPrivate ? "private" : "",
277 formatIU( aCircle->GetStart(), aInvertY ).c_str(), formatIU( aCircle->GetRadius() ).c_str() );
278
279 KICAD_FORMAT::LEGACY::FormatStroke( aFormatter, aStroke, schIUScale );
280 formatFill( aFormatter, aFillMode, aFillColor );
281
282 if( aUuid != niluuid )
283 aFormatter->Print( "(uuid %s)", TO_UTF8( aUuid.AsString() ) );
284
285 aFormatter->Print( ")" );
286}
287
288
289static void formatRect( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aRect, bool aIsPrivate, const STROKE_PARAMS& aStroke,
290 FILL_T aFillMode, const COLOR4D& aFillColor, bool aInvertY, const KIID& aUuid )
291{
292 aFormatter->Print( "(rectangle %s (start %s) (end %s)", aIsPrivate ? "private" : "",
293 formatIU( aRect->GetStart(), aInvertY ).c_str(), formatIU( aRect->GetEnd(), aInvertY ).c_str() );
294 KICAD_FORMAT::LEGACY::FormatStroke( aFormatter, aStroke, schIUScale );
295 formatFill( aFormatter, aFillMode, aFillColor );
296
297 if( aUuid != niluuid )
298 aFormatter->Print( "(uuid %s)", TO_UTF8( aUuid.AsString() ) );
299
300 aFormatter->Print( ")" );
301}
302
303
304static void formatBezier( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aBezier, bool aIsPrivate,
305 const STROKE_PARAMS& aStroke, FILL_T aFillMode, const COLOR4D& aFillColor, bool aInvertY,
306 const KIID& aUuid )
307{
308 aFormatter->Print( "(bezier %s (pts ", aIsPrivate ? "private" : "" );
309
310 for( const VECTOR2I& pt :
311 { aBezier->GetStart(), aBezier->GetBezierC1(), aBezier->GetBezierC2(), aBezier->GetEnd() } )
312 {
313 aFormatter->Print( "(xy %s)", formatIU( pt, aInvertY ).c_str() );
314 }
315
316 aFormatter->Print( ")" ); // Closes pts token
317
318 KICAD_FORMAT::LEGACY::FormatStroke( aFormatter, aStroke, schIUScale );
319 formatFill( aFormatter, aFillMode, aFillColor );
320
321 if( aUuid != niluuid )
322 aFormatter->Print( "(uuid %s)", TO_UTF8( aUuid.AsString() ) );
323
324 aFormatter->Print( ")" );
325}
326
327
328static void formatPoly( OUTPUTFORMATTER* aFormatter, EDA_SHAPE* aPolyLine, bool aIsPrivate,
329 const STROKE_PARAMS& aStroke, FILL_T aFillMode, const COLOR4D& aFillColor, bool aInvertY,
330 const KIID& aUuid )
331{
332 aFormatter->Print( "(polyline %s (pts ", aIsPrivate ? "private" : "" );
333
334 const SHAPE_POLY_SET& aPolySet = aPolyLine->GetPolyShape();
335
336 if( aPolySet.OutlineCount() == 0 )
337 {
338 // If we've managed to get a polyline with no points, that's probably a bad thing,
339 // but at least don't dereference it and crash.
340 wxFAIL_MSG( "Polyline has no outlines" );
341 }
342 else
343 {
344 const SHAPE_LINE_CHAIN& outline = aPolySet.Outline( 0 );
345
346 for( const VECTOR2I& pt : outline.CPoints() )
347 aFormatter->Print( "(xy %s)", formatIU( pt, aInvertY ).c_str() );
348
349 if( outline.IsClosed() && outline.PointCount() > 1 && outline.CPoint( -1 ) != outline.CPoint( 0 ) )
350 aFormatter->Print( "(xy %s)", formatIU( outline.CPoint( 0 ), aInvertY ).c_str() );
351 }
352
353 aFormatter->Print( ")" ); // Closes pts token
354
355 KICAD_FORMAT::LEGACY::FormatStroke( aFormatter, aStroke, schIUScale );
356 formatFill( aFormatter, aFillMode, aFillColor );
357
358 if( aUuid != niluuid )
359 aFormatter->Print( "(uuid %s)", TO_UTF8( aUuid.AsString() ) );
360
361 aFormatter->Print( ")" );
362}
363
364
365static void libSaveSymbol( LIB_SYMBOL* aSymbol, OUTPUTFORMATTER& aFormatter, const wxString& aLibName = wxEmptyString,
366 bool aIncludeData = true );
367static void libSaveSymbolDrawItem( SCH_ITEM* aItem, OUTPUTFORMATTER& aFormatter );
368static void libSaveField( SCH_FIELD* aField, OUTPUTFORMATTER& aFormatter );
369static void libSavePin( SCH_PIN* aPin, OUTPUTFORMATTER& aFormatter );
370static void libSaveText( SCH_TEXT* aText, OUTPUTFORMATTER& aFormatter );
371static void libSaveTextBox( SCH_TEXTBOX* aTextBox, OUTPUTFORMATTER& aFormatter );
372static void libSaveDcmInfoAsFields( LIB_SYMBOL* aSymbol, OUTPUTFORMATTER& aFormatter );
373
374
375static void libSaveSymbol( LIB_SYMBOL* aSymbol, OUTPUTFORMATTER& aFormatter, const wxString& aLibName,
376 bool aIncludeData )
377{
378 wxCHECK_RET( aSymbol, "Invalid LIB_SYMBOL pointer." );
379
380
381 // If we've requested to embed the fonts in the symbol, do so.
382 // Otherwise, clear the embedded fonts from the symbol. Embedded
383 // fonts will be used if available
384 if( aSymbol->GetAreFontsEmbedded() )
385 aSymbol->EmbedFonts();
386 else
388
389 std::vector<SCH_FIELD*> fields;
390 std::string name = aFormatter.Quotew( aSymbol->GetLibId().GetLibItemName().wx_str() );
391 std::string unitName = aSymbol->GetLibId().GetLibItemName();
392
393 if( !aLibName.IsEmpty() )
394 {
395 name = aFormatter.Quotew( aLibName );
396
397 LIB_ID unitId;
398
399 wxCHECK2( unitId.Parse( aLibName ) < 0, /* do nothing */ );
400
401 unitName = unitId.GetLibItemName();
402 }
403
404 if( aSymbol->IsRoot() )
405 {
406 aFormatter.Print( "(symbol %s", name.c_str() );
407
408 if( aSymbol->IsPower() )
409 aFormatter.Print( "(power)" );
410
411 if( !aSymbol->GetShowPinNumbers() )
412 aFormatter.Print( "(pin_numbers (hide yes))" );
413
414 if( aSymbol->GetPinNameOffset() != schIUScale.MilsToIU( DEFAULT_PIN_NAME_OFFSET )
415 || !aSymbol->GetShowPinNames() )
416 {
417 aFormatter.Print( "(pin_names" );
418
419 if( aSymbol->GetPinNameOffset() != schIUScale.MilsToIU( DEFAULT_PIN_NAME_OFFSET ) )
420 {
421 aFormatter.Print(
422 "(offset %s)",
424 }
425
426 if( !aSymbol->GetShowPinNames() )
427 KICAD_FORMAT::LEGACY::FormatBool( &aFormatter, "hide", true );
428
429 aFormatter.Print( ")" );
430 }
431
432 KICAD_FORMAT::LEGACY::FormatBool( &aFormatter, "exclude_from_sim", aSymbol->GetExcludedFromSim() );
433 KICAD_FORMAT::LEGACY::FormatBool( &aFormatter, "in_bom", !aSymbol->GetExcludedFromBOM() );
434 KICAD_FORMAT::LEGACY::FormatBool( &aFormatter, "on_board", !aSymbol->GetExcludedFromBoard() );
435
436 aSymbol->GetFields( fields );
437
438 for( SCH_FIELD* field : fields )
439 libSaveField( field, aFormatter );
440
441 // @todo At some point in the future the lock status (all units interchangeable) should
442 // be set deterministically. For now a custom lock property is used to preserve the
443 // locked flag state.
444 if( aSymbol->UnitsLocked() )
445 {
446 SCH_FIELD locked( nullptr, FIELD_T::USER, "ki_locked" );
447 libSaveField( &locked, aFormatter );
448 }
449
450 libSaveDcmInfoAsFields( aSymbol, aFormatter );
451
452 // Save the draw items grouped by units.
453 std::vector<LIB_SYMBOL_UNIT> units = aSymbol->GetUnitDrawItems();
454 std::sort( units.begin(), units.end(),
455 []( const LIB_SYMBOL_UNIT& a, const LIB_SYMBOL_UNIT& b )
456 {
457 if( a.m_unit == b.m_unit )
458 return a.m_bodyStyle < b.m_bodyStyle;
459
460 return a.m_unit < b.m_unit;
461 } );
462
463 for( const LIB_SYMBOL_UNIT& unit : units )
464 {
465 // Add quotes and escape chars like ") to the UTF8 unitName string
466 name = aFormatter.Quotes( unitName );
467 name.pop_back(); // Remove last char: the quote ending the string.
468
469 aFormatter.Print( "(symbol %s_%d_%d\"", name.c_str(), unit.m_unit, unit.m_bodyStyle );
470
471 // if the unit has a display name, write that
472 if( aSymbol->GetUnitDisplayNames().contains( unit.m_unit ) )
473 {
474 name = aSymbol->GetUnitDisplayNames()[unit.m_unit];
475 aFormatter.Print( "(unit_name %s)", aFormatter.Quotes( name ).c_str() );
476 }
477
478 // Enforce item ordering
479 auto cmp = []( const SCH_ITEM* a, const SCH_ITEM* b )
480 {
481 return *a < *b;
482 };
483
484 std::multiset<SCH_ITEM*, decltype( cmp )> save_map( cmp );
485
486 for( SCH_ITEM* item : unit.m_items )
487 save_map.insert( item );
488
489 for( SCH_ITEM* item : save_map )
490 libSaveSymbolDrawItem( item, aFormatter );
491
492 aFormatter.Print( ")" );
493 }
494
495 KICAD_FORMAT::LEGACY::FormatBool( &aFormatter, "embedded_fonts", aSymbol->GetAreFontsEmbedded() );
496
497 if( !aSymbol->EmbeddedFileMap().empty() )
498 KICAD_FORMAT::LEGACY::FormatEmbeddedFilesV9( aFormatter, *aSymbol, aIncludeData );
499 }
500 else
501 {
502 std::shared_ptr<LIB_SYMBOL> parent = aSymbol->GetParent().lock();
503
504 wxASSERT( parent );
505
506 aFormatter.Print( "(symbol %s (extends %s)", name.c_str(), aFormatter.Quotew( parent->GetName() ).c_str() );
507
508 aSymbol->GetFields( fields );
509
510 for( SCH_FIELD* field : fields )
511 libSaveField( field, aFormatter );
512
513 libSaveDcmInfoAsFields( aSymbol, aFormatter );
514
515 KICAD_FORMAT::LEGACY::FormatBool( &aFormatter, "embedded_fonts", aSymbol->GetAreFontsEmbedded() );
516
517 if( !aSymbol->EmbeddedFileMap().empty() )
518 KICAD_FORMAT::LEGACY::FormatEmbeddedFilesV9( aFormatter, *aSymbol, aIncludeData );
519 }
520
521 aFormatter.Print( ")" );
522}
523
524
525static void libSaveDcmInfoAsFields( LIB_SYMBOL* aSymbol, OUTPUTFORMATTER& aFormatter )
526{
527 wxCHECK_RET( aSymbol, "Invalid LIB_SYMBOL pointer." );
528
529 if( !aSymbol->GetRawKeyWords().IsEmpty() )
530 {
531 SCH_FIELD keywords( nullptr, FIELD_T::USER, wxString( "ki_keywords" ) );
532 keywords.SetVisible( false );
533 keywords.SetText( aSymbol->GetRawKeyWords() );
534 libSaveField( &keywords, aFormatter );
535 }
536
537 wxArrayString fpFilters = aSymbol->GetFPFilters();
538
539 if( !fpFilters.IsEmpty() )
540 {
541 wxString tmp;
542
543 for( const wxString& filter : fpFilters )
544 {
545 // Spaces are not handled in fp filter names so escape spaces if any
546 wxString curr_filter = EscapeString( filter, ESCAPE_CONTEXT::CTX_NO_SPACE );
547
548 if( tmp.IsEmpty() )
549 tmp = curr_filter;
550 else
551 tmp += " " + curr_filter;
552 }
553
554 SCH_FIELD description( nullptr, FIELD_T::USER, wxString( "ki_fp_filters" ) );
555 description.SetVisible( false );
556 description.SetText( tmp );
557 libSaveField( &description, aFormatter );
558 }
559}
560
561
562static void libSaveSymbolDrawItem( SCH_ITEM* aItem, OUTPUTFORMATTER& aFormatter )
563{
564 wxCHECK_RET( aItem, "Invalid SCH_ITEM pointer." );
565
566 switch( aItem->Type() )
567 {
568 case SCH_SHAPE_T:
569 {
570 SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( aItem );
571 STROKE_PARAMS stroke = shape->GetStroke();
572 FILL_T fillMode = shape->GetFillMode();
573 COLOR4D fillColor = shape->GetFillColor();
574 bool isPrivate = shape->IsPrivate();
575
576 switch( shape->GetShape() )
577 {
578 case SHAPE_T::ARC: formatArc( &aFormatter, shape, isPrivate, stroke, fillMode, fillColor, true ); break;
579
580 case SHAPE_T::CIRCLE: formatCircle( &aFormatter, shape, isPrivate, stroke, fillMode, fillColor, true ); break;
581
582 case SHAPE_T::RECTANGLE: formatRect( &aFormatter, shape, isPrivate, stroke, fillMode, fillColor, true ); break;
583
584 case SHAPE_T::BEZIER: formatBezier( &aFormatter, shape, isPrivate, stroke, fillMode, fillColor, true ); break;
585
586 case SHAPE_T::POLY: formatPoly( &aFormatter, shape, isPrivate, stroke, fillMode, fillColor, true ); break;
587
588 default: UNIMPLEMENTED_FOR( shape->SHAPE_T_asString() );
589 }
590
591 break;
592 }
593
594 case SCH_PIN_T: libSavePin( static_cast<SCH_PIN*>( aItem ), aFormatter ); break;
595
596 case SCH_TEXT_T: libSaveText( static_cast<SCH_TEXT*>( aItem ), aFormatter ); break;
597
598 case SCH_TEXTBOX_T: libSaveTextBox( static_cast<SCH_TEXTBOX*>( aItem ), aFormatter ); break;
599
600 default: UNIMPLEMENTED_FOR( aItem->GetClass() );
601 }
602}
603
604
605static void libSaveField( SCH_FIELD* aField, OUTPUTFORMATTER& aFormatter )
606{
607 wxCHECK_RET( aField && aField->Type() == SCH_FIELD_T, "Invalid SCH_FIELD object." );
608
609 wxString fieldName = aField->GetName();
610
611 if( aField->IsMandatory() )
612 fieldName = aField->GetUntranslatedName();
613
614 aFormatter.Print( "(property %s %s %s (at %s %s %g)", aField->IsPrivate() ? "private" : "", //format:allow
615 aFormatter.Quotew( fieldName ).c_str(), aFormatter.Quotew( aField->GetText() ).c_str(),
618 aField->GetTextAngle().AsDegrees() );
619
620 if( aField->IsNameShown() )
621 aFormatter.Print( "(show_name)" );
622
623 if( !aField->CanAutoplace() )
624 aFormatter.Print( "(do_not_autoplace)" );
625
626 formatEdaTextV9( &aFormatter, *aField, 0 );
627 aFormatter.Print( ")" );
628}
629
630
631static void libSavePin( SCH_PIN* aPin, OUTPUTFORMATTER& aFormatter )
632{
633 wxCHECK_RET( aPin && aPin->Type() == SCH_PIN_T, "Invalid SCH_PIN object." );
634
635 aPin->ClearFlags( IS_CHANGED );
636
637 aFormatter.Print( "(pin %s %s (at %s %s %s) (length %s)", getPinElectricalTypeToken( aPin->GetType() ),
638 getPinShapeToken( aPin->GetShape() ),
643
644 if( !aPin->IsVisible() )
645 KICAD_FORMAT::LEGACY::FormatBool( &aFormatter, "hide", true );
646
647 // This follows the EDA_TEXT effects formatting for future expansion.
648 aFormatter.Print( "(name %s (effects (font (size %s %s))))", aFormatter.Quotew( aPin->GetName() ).c_str(),
651
652 aFormatter.Print( "(number %s (effects (font (size %s %s))))", aFormatter.Quotew( aPin->GetNumber() ).c_str(),
655
656
657 for( const std::pair<const wxString, SCH_PIN::ALT>& alt : aPin->GetAlternates() )
658 {
659 aFormatter.Print( "(alternate %s %s %s)", aFormatter.Quotew( alt.second.m_Name ).c_str(),
660 getPinElectricalTypeToken( alt.second.m_Type ), getPinShapeToken( alt.second.m_Shape ) );
661 }
662
663 aFormatter.Print( ")" );
664}
665
666
667static void libSaveText( SCH_TEXT* aText, OUTPUTFORMATTER& aFormatter )
668{
669 wxCHECK_RET( aText && aText->Type() == SCH_TEXT_T, "Invalid SCH_TEXT object." );
670
671 aFormatter.Print( "(text %s %s (at %s %s %g)", aText->IsPrivate() ? "private" : "", //format:allow
672 aFormatter.Quotew( aText->GetText() ).c_str(),
675 (double) aText->GetTextAngle().AsTenthsOfADegree() );
676
677 formatEdaTextV9( &aFormatter, *aText, 0 );
678 aFormatter.Print( ")" );
679}
680
681
682static void libSaveTextBox( SCH_TEXTBOX* aTextBox, OUTPUTFORMATTER& aFormatter )
683{
684 wxCHECK_RET( aTextBox && aTextBox->Type() == SCH_TEXTBOX_T, "Invalid SCH_TEXTBOX object." );
685
686 aFormatter.Print( "(text_box %s %s", aTextBox->IsPrivate() ? "private" : "",
687 aFormatter.Quotew( aTextBox->GetText() ).c_str() );
688
689 VECTOR2I pos = aTextBox->GetStart();
690 VECTOR2I size = aTextBox->GetEnd() - pos;
691
692 aFormatter.Print( "(at %s %s %s) (size %s %s) (margins %s %s %s %s)",
695 EDA_UNIT_UTILS::FormatAngle( aTextBox->GetTextAngle() ).c_str(),
702
703 KICAD_FORMAT::LEGACY::FormatStroke( &aFormatter, aTextBox->GetStroke(), schIUScale );
704 formatFill( &aFormatter, aTextBox->GetFillMode(), aTextBox->GetFillColor() );
705 formatEdaTextV9( &aFormatter, *aTextBox, 0 );
706 aFormatter.Print( ")" );
707}
708
709
710void SCH_WRITER_V9::SaveSchematicFile( const wxString& aFileName, SCH_SHEET* aSheet, SCHEMATIC* aSchematic )
711{
712 LOCALE_IO toggle;
713
714 m_schematic = aSchematic;
715
716 PRETTIFIED_FILE_OUTPUTFORMATTER formatter( aFileName );
717
718 m_out = &formatter;
719 Format( aSheet );
720 formatter.Finish();
721 m_out = nullptr;
722}
723
724
725void SCH_WRITER_V9::SaveSymbolLibrary( const wxString& aFileName, const std::vector<LIB_SYMBOL*>& aSymbols )
726{
727 LOCALE_IO toggle;
728
729 PRETTIFIED_FILE_OUTPUTFORMATTER formatter( aFileName );
730
731 formatter.Print( "(kicad_symbol_lib (version %d) (generator \"kicad_symbol_editor\") "
732 "(generator_version \"%s\")",
734
735 for( LIB_SYMBOL* symbol : aSymbols )
736 libSaveSymbol( symbol, formatter, wxEmptyString );
737
738 formatter.Print( ")" );
739 formatter.Finish();
740}
741
742
744{
745 wxCHECK_RET( aSheet != nullptr, "NULL SCH_SHEET* object." );
746 wxCHECK_RET( m_schematic != nullptr, "NULL SCHEMATIC* object." );
747
748 SCH_SHEET_LIST sheets = m_schematic->Hierarchy();
749 SCH_SCREEN* screen = aSheet->GetScreen();
750
751 wxCHECK( screen, /* void */ );
752
753 // If we've requested to embed the fonts in the schematic, do so.
754 // Otherwise, clear the embedded fonts from the schematic. Embedded
755 // fonts will be used if available
756 if( m_schematic->GetAreFontsEmbedded() )
757 m_schematic->EmbedFonts();
758 else
759 m_schematic->GetEmbeddedFiles()->ClearEmbeddedFonts();
760
761 m_out->Print( "(kicad_sch (version %d) (generator \"eeschema\") (generator_version %s)",
763
765
768
769 // Save cache library.
770 m_out->Print( "(lib_symbols" );
771
772 for( const auto& [libItemName, libSymbol] : screen->GetLibSymbols() )
773 libSaveSymbol( libSymbol, *m_out, libItemName );
774
775 m_out->Print( ")" );
776
777 // Bus aliases moved from the screen to the schematic after 9.0. Write them all here, which
778 // is where the 9.0 format expects them.
779 for( const std::shared_ptr<BUS_ALIAS>& alias : m_schematic->GetAllBusAliases() )
780 saveBusAlias( alias );
781
782 // Enforce item ordering
783 auto cmp = []( const SCH_ITEM* a, const SCH_ITEM* b )
784 {
785 if( a->Type() != b->Type() )
786 return a->Type() < b->Type();
787
788 return a->m_Uuid < b->m_Uuid;
789 };
790
791 std::multiset<SCH_ITEM*, decltype( cmp )> save_map( cmp );
792
793 for( SCH_ITEM* item : screen->Items() )
794 {
795 // Markers are not saved, so keep them from being considered below
796 if( item->Type() != SCH_MARKER_T )
797 save_map.insert( item );
798 }
799
800 for( SCH_ITEM* item : save_map )
801 {
802 switch( item->Type() )
803 {
804 case SCH_SYMBOL_T: saveSymbol( static_cast<SCH_SYMBOL*>( item ), *m_schematic, sheets, false ); break;
805
806 case SCH_BITMAP_T: saveBitmap( static_cast<SCH_BITMAP&>( *item ) ); break;
807
808 case SCH_SHEET_T: saveSheet( static_cast<SCH_SHEET*>( item ), sheets ); break;
809
810 case SCH_JUNCTION_T: saveJunction( static_cast<SCH_JUNCTION*>( item ) ); break;
811
812 case SCH_NO_CONNECT_T: saveNoConnect( static_cast<SCH_NO_CONNECT*>( item ) ); break;
813
815 case SCH_BUS_BUS_ENTRY_T: saveBusEntry( static_cast<SCH_BUS_ENTRY_BASE*>( item ) ); break;
816
817 case SCH_LINE_T: saveLine( static_cast<SCH_LINE*>( item ) ); break;
818
819 case SCH_SHAPE_T: saveShape( static_cast<SCH_SHAPE*>( item ) ); break;
820
821 case SCH_RULE_AREA_T: saveRuleArea( static_cast<SCH_RULE_AREA*>( item ) ); break;
822
823 case SCH_TEXT_T:
824 case SCH_LABEL_T:
826 case SCH_HIER_LABEL_T:
827 case SCH_DIRECTIVE_LABEL_T: saveText( static_cast<SCH_TEXT*>( item ) ); break;
828
829 case SCH_TEXTBOX_T: saveTextBox( static_cast<SCH_TEXTBOX*>( item ) ); break;
830
831 case SCH_TABLE_T: saveTable( static_cast<SCH_TABLE*>( item ) ); break;
832
833 default: wxASSERT( "Unexpected schematic object type in SCH_WRITER_V9::Format()" );
834 }
835 }
836
837 if( aSheet->HasRootInstance() )
838 {
839 std::vector<SCH_SHEET_INSTANCE> instances;
840
841 instances.emplace_back( aSheet->GetRootInstance() );
842 saveInstances( instances );
843 }
844
845 if( m_schematic->GetTopLevelSheet( 0 ) == aSheet )
846 {
847 KICAD_FORMAT::LEGACY::FormatBool( m_out, "embedded_fonts", m_schematic->GetAreFontsEmbedded() );
848
849 // Save any embedded files
850 if( !m_schematic->GetEmbeddedFiles()->IsEmpty() )
852 }
853
854 m_out->Print( ")" );
855}
856
857
858// The current model roots every schematic in a virtual sheet with a nil uuid. Instance paths
859// skip it, so the era root comparisons need the real top-level sheet instead.
860static KIID effectiveRootUuid( const SCHEMATIC& aSchematic )
861{
862 KIID rootUuid = aSchematic.Root().m_Uuid;
863
864 if( rootUuid == niluuid )
865 {
866 const std::vector<SCH_SHEET*>& topLevelSheets = aSchematic.GetTopLevelSheets();
867
868 if( topLevelSheets.size() == 1 )
869 return topLevelSheets[0]->m_Uuid;
870 }
871
872 return rootUuid;
873}
874
875
876void SCH_WRITER_V9::saveSymbol( SCH_SYMBOL* aSymbol, const SCHEMATIC& aSchematic, const SCH_SHEET_LIST& aSheetList,
877 bool aForClipboard, const SCH_SHEET_PATH* aRelativePath )
878{
879 wxCHECK_RET( aSymbol != nullptr && m_out != nullptr, "" );
880
881 std::string libName;
882
883 wxString symbol_name = KICAD_FORMAT::LEGACY::FormatLibId( aSymbol->GetLibId() );
884
885 if( symbol_name.size() )
886 {
887 libName = toUTFTildaText( symbol_name );
888 }
889 else
890 {
891 libName = "_NONAME_";
892 }
893
894 EDA_ANGLE angle;
895 int orientation = aSymbol->GetOrientation() & ~( SYM_MIRROR_X | SYM_MIRROR_Y );
896
898 angle = ANGLE_90;
899 else if( orientation == SYM_ORIENT_180 )
900 angle = ANGLE_180;
901 else if( orientation == SYM_ORIENT_270 )
902 angle = ANGLE_270;
903 else
904 angle = ANGLE_0;
905
906 m_out->Print( "(symbol" );
907
908 if( !aSymbol->UseLibIdLookup() )
909 {
910 m_out->Print( "(lib_name %s)", m_out->Quotew( aSymbol->GetSchSymbolLibraryName() ).c_str() );
911 }
912
913 m_out->Print( "(lib_id %s) (at %s %s %s)",
914 m_out->Quotew( KICAD_FORMAT::LEGACY::FormatLibId( aSymbol->GetLibId() ).wx_str() ).c_str(),
917 EDA_UNIT_UTILS::FormatAngle( angle ).c_str() );
918
919 bool mirrorX = aSymbol->GetOrientation() & SYM_MIRROR_X;
920 bool mirrorY = aSymbol->GetOrientation() & SYM_MIRROR_Y;
921
922 if( mirrorX || mirrorY )
923 {
924 m_out->Print( "(mirror %s %s)", mirrorX ? "x" : "", mirrorY ? "y" : "" );
925 }
926
927 // The symbol unit is always set to the ordianal instance regardless of the current sheet
928 // instance to prevent file churn.
929 SCH_SYMBOL_INSTANCE ordinalInstance;
930
931 ordinalInstance.m_Reference = aSymbol->GetPrefix();
932
933 const SCH_SCREEN* parentScreen = static_cast<const SCH_SCREEN*>( aSymbol->GetParent() );
934
935 wxASSERT( parentScreen );
936
937 if( parentScreen && m_schematic )
938 {
939 std::optional<SCH_SHEET_PATH> ordinalPath = m_schematic->Hierarchy().GetOrdinalPath( parentScreen );
940
941 // Design blocks are saved from a temporary sheet & screen which will not be found in
942 // the schematic, and will therefore have no ordinal path.
943 // wxASSERT( ordinalPath );
944
945 if( ordinalPath )
946 aSymbol->GetInstance( ordinalInstance, ordinalPath->Path() );
947 else if( aSymbol->GetInstances().size() )
948 ordinalInstance = aSymbol->GetInstances()[0];
949 }
950
951 int unit = ordinalInstance.m_Unit;
952
953 if( aForClipboard && aRelativePath )
954 {
955 SCH_SYMBOL_INSTANCE unitInstance;
956
957 if( aSymbol->GetInstance( unitInstance, aRelativePath->Path() ) )
958 unit = unitInstance.m_Unit;
959 }
960
961 m_out->Print( "(unit %d)", unit );
962
963 if( aSymbol->GetBodyStyle() == BODY_STYLE::DEMORGAN )
964 m_out->Print( "(convert %d)", aSymbol->GetBodyStyle() );
965
966 KICAD_FORMAT::LEGACY::FormatBool( m_out, "exclude_from_sim", aSymbol->GetExcludedFromSim() );
969 KICAD_FORMAT::LEGACY::FormatBool( m_out, "dnp", aSymbol->GetDNP() );
970
971 AUTOPLACE_ALGO fieldsAutoplaced = aSymbol->GetFieldsAutoplaced();
972
973 if( fieldsAutoplaced == AUTOPLACE_AUTO || fieldsAutoplaced == AUTOPLACE_MANUAL )
974 KICAD_FORMAT::LEGACY::FormatBool( m_out, "fields_autoplaced", true );
975
977
978
979 for( SCH_FIELD& field : aSymbol->GetFields() )
980 {
981 FIELD_T id = field.GetId();
982 wxString value = field.GetText();
983
984 if( !aForClipboard && aSymbol->GetInstances().size() )
985 {
986 // The instance fields are always set to the default instance regardless of the
987 // sheet instance to prevent file churn.
988 if( id == FIELD_T::REFERENCE )
989 {
990 field.SetText( ordinalInstance.m_Reference );
991 }
992 else if( id == FIELD_T::VALUE )
993 {
994 field.SetText( aSymbol->GetField( FIELD_T::VALUE )->GetText() );
995 }
996 else if( id == FIELD_T::FOOTPRINT )
997 {
998 field.SetText( aSymbol->GetField( FIELD_T::FOOTPRINT )->GetText() );
999 }
1000 }
1001 else if( aForClipboard && aSymbol->GetInstances().size() && aRelativePath && ( id == FIELD_T::REFERENCE ) )
1002 {
1003 SCH_SYMBOL_INSTANCE instance;
1004
1005 if( aSymbol->GetInstance( instance, aRelativePath->Path() ) )
1006 field.SetText( instance.m_Reference );
1007 }
1008
1009 try
1010 {
1011 saveField( &field );
1012 }
1013 catch( ... )
1014 {
1015 // Restore the changed field text on write error.
1016 if( id == FIELD_T::REFERENCE || id == FIELD_T::VALUE || id == FIELD_T::FOOTPRINT )
1017 field.SetText( value );
1018
1019 throw;
1020 }
1021
1022 if( id == FIELD_T::REFERENCE || id == FIELD_T::VALUE || id == FIELD_T::FOOTPRINT )
1023 field.SetText( value );
1024 }
1025
1026 for( const std::unique_ptr<SCH_PIN>& pin : aSymbol->GetRawPins() )
1027 {
1028 if( pin->GetAlt().IsEmpty() )
1029 {
1030 m_out->Print( "(pin %s", m_out->Quotew( pin->GetNumber() ).c_str() );
1032 m_out->Print( ")" );
1033 }
1034 else
1035 {
1036 m_out->Print( "(pin %s", m_out->Quotew( pin->GetNumber() ).c_str() );
1038 m_out->Print( "(alternate %s))", m_out->Quotew( pin->GetAlt() ).c_str() );
1039 }
1040 }
1041
1042 if( !aSymbol->GetInstances().empty() )
1043 {
1044 std::map<KIID, std::vector<SCH_SYMBOL_INSTANCE>> projectInstances;
1045
1046 m_out->Print( "(instances" );
1047
1048 wxString projectName;
1049 KIID rootSheetUuid = effectiveRootUuid( aSchematic );
1050
1051 for( const SCH_SYMBOL_INSTANCE& inst : aSymbol->GetInstances() )
1052 {
1053 // Zero length KIID_PATH objects are not valid and will cause a crash below.
1054 wxCHECK2( inst.m_Path.size(), continue );
1055
1056 // If the instance data is part of this design but no longer has an associated sheet
1057 // path, don't save it. This prevents large amounts of orphaned instance data for the
1058 // current project from accumulating in the schematic files.
1059 bool isOrphaned = ( inst.m_Path[0] == rootSheetUuid ) && !aSheetList.GetSheetPathByKIIDPath( inst.m_Path );
1060
1061 // Keep all instance data when copying to the clipboard. They may be needed on paste.
1062 if( !aForClipboard && isOrphaned )
1063 continue;
1064
1065 auto it = projectInstances.find( inst.m_Path[0] );
1066
1067 if( it == projectInstances.end() )
1068 projectInstances[inst.m_Path[0]] = { inst };
1069 else
1070 it->second.emplace_back( inst );
1071 }
1072
1073 for( auto& [uuid, instances] : projectInstances )
1074 {
1075 wxCHECK2( instances.size(), continue );
1076
1077 // Sort project instances by KIID_PATH.
1078 std::sort( instances.begin(), instances.end(),
1079 []( SCH_SYMBOL_INSTANCE& aLhs, SCH_SYMBOL_INSTANCE& aRhs )
1080 {
1081 return aLhs.m_Path < aRhs.m_Path;
1082 } );
1083
1084 projectName = instances[0].m_ProjectName;
1085
1086 m_out->Print( "(project %s", m_out->Quotew( projectName ).c_str() );
1087
1088 for( const SCH_SYMBOL_INSTANCE& instance : instances )
1089 {
1090 wxString path;
1091 KIID_PATH tmp = instance.m_Path;
1092
1093 if( aForClipboard && aRelativePath )
1094 tmp.MakeRelativeTo( aRelativePath->Path() );
1095
1096 path = tmp.AsString();
1097
1098 wxString reference = instance.m_Reference;
1099
1100 // This version cannot compose references, so it reads them with the package's suffix baked in
1101 if( m_schematic && !aForClipboard && !reference.EndsWith( wxS( "?" ) ) )
1102 reference += m_schematic->GetPackageRefSuffix( aSymbol, instance.m_Path );
1103
1104 m_out->Print( "(path %s (reference %s) (unit %d))", m_out->Quotew( path ).c_str(),
1105 m_out->Quotew( reference ).c_str(), instance.m_Unit );
1106 }
1107
1108 m_out->Print( ")" ); // Closes `project`.
1109 }
1110
1111 m_out->Print( ")" ); // Closes `instances`.
1112 }
1113
1114 m_out->Print( ")" ); // Closes `symbol`.
1115}
1116
1117
1119{
1120 wxCHECK_RET( aField != nullptr && m_out != nullptr, "" );
1121
1122 wxString fieldName;
1123
1124 if( aField->IsMandatory() )
1125 fieldName = aField->GetUntranslatedName();
1126 else
1127 fieldName = aField->GetName();
1128
1129 m_out->Print( "(property %s %s %s (at %s %s %s)", aField->IsPrivate() ? "private" : "",
1130 m_out->Quotew( fieldName ).c_str(), m_out->Quotew( aField->GetText() ).c_str(),
1133 EDA_UNIT_UTILS::FormatAngle( aField->GetTextAngle() ).c_str() );
1134
1135 if( aField->IsNameShown() )
1136 KICAD_FORMAT::LEGACY::FormatBool( m_out, "show_name", true );
1137
1138 if( !aField->CanAutoplace() )
1139 KICAD_FORMAT::LEGACY::FormatBool( m_out, "do_not_autoplace", true );
1140
1141 if( !isDefaultFormattingV9( *aField ) || ( aField->GetTextHeight() != schIUScale.MilsToIU( DEFAULT_SIZE_TEXT ) ) )
1142 {
1143 formatEdaTextV9( m_out, *aField, 0 );
1144 }
1145
1146 m_out->Print( ")" ); // Closes `property` token
1147}
1148
1149
1151{
1152 wxCHECK_RET( m_out != nullptr, "" );
1153
1154 const REFERENCE_IMAGE& refImage = aBitmap.GetReferenceImage();
1155 const BITMAP_BASE& bitmapBase = refImage.GetImage();
1156
1157 const wxImage* image = bitmapBase.GetImageData();
1158
1159 wxCHECK_RET( image != nullptr, "wxImage* is NULL" );
1160
1161 m_out->Print( "(image (at %s %s)",
1164
1165 double scale = refImage.GetImageScale();
1166
1167 // 20230121 or older file format versions assumed 300 image PPI at load/save.
1168 // Let's keep compatibility by changing image scale.
1169 if( SCH_WRITER_V9::FORMAT_VERSION <= 20230121 )
1170 scale = scale * 300.0 / bitmapBase.GetPPI();
1171
1172 if( scale != 1.0 )
1173 m_out->Print( "(scale %g)", scale ); //format:allow
1174
1176
1177 wxMemoryOutputStream stream;
1178 bitmapBase.SaveImageData( stream );
1179
1180 KICAD_FORMAT::LEGACY::FormatStreamData( *m_out, *stream.GetOutputStreamBuffer() );
1181
1182 m_out->Print( ")" ); // Closes image token.
1183}
1184
1185
1186void SCH_WRITER_V9::saveSheet( SCH_SHEET* aSheet, const SCH_SHEET_LIST& aSheetList )
1187{
1188 wxCHECK_RET( aSheet != nullptr && m_out != nullptr, "" );
1189
1190 m_out->Print( "(sheet (at %s %s) (size %s %s)",
1195
1196 KICAD_FORMAT::LEGACY::FormatBool( m_out, "exclude_from_sim", aSheet->GetExcludedFromSim() );
1199 KICAD_FORMAT::LEGACY::FormatBool( m_out, "dnp", aSheet->GetDNP() );
1200
1201 AUTOPLACE_ALGO fieldsAutoplaced = aSheet->GetFieldsAutoplaced();
1202
1203 if( fieldsAutoplaced == AUTOPLACE_AUTO || fieldsAutoplaced == AUTOPLACE_MANUAL )
1204 KICAD_FORMAT::LEGACY::FormatBool( m_out, "fields_autoplaced", true );
1205
1206 STROKE_PARAMS stroke( aSheet->GetBorderWidth(), LINE_STYLE::SOLID, aSheet->GetBorderColor() );
1207
1208 stroke.SetWidth( aSheet->GetBorderWidth() );
1210
1211 m_out->Print( "(fill (color %d %d %d %0.4f))", KiROUND( aSheet->GetBackgroundColor().r * 255.0 ), //format:allow
1212 KiROUND( aSheet->GetBackgroundColor().g * 255.0 ), KiROUND( aSheet->GetBackgroundColor().b * 255.0 ),
1213 aSheet->GetBackgroundColor().a );
1214
1216
1217
1218 for( SCH_FIELD& field : aSheet->GetFields() )
1219 saveField( &field );
1220
1221 for( const SCH_SHEET_PIN* pin : aSheet->GetPins() )
1222 {
1223 m_out->Print( "(pin %s %s (at %s %s %s)", EscapedUTF8( pin->GetText() ).c_str(),
1224 getSheetPinShapeToken( pin->GetShape() ),
1225 EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pin->GetPosition().x ).c_str(),
1226 EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pin->GetPosition().y ).c_str(),
1227 EDA_UNIT_UTILS::FormatAngle( getSheetPinAngle( pin->GetSide() ) ).c_str() );
1228
1230
1231 formatEdaTextV9( m_out, *pin, 0 );
1232
1233 m_out->Print( ")" ); // Closes pin token.
1234 }
1235
1236 // Save all sheet instances here except the root sheet instance.
1237 std::vector<SCH_SHEET_INSTANCE> sheetInstances = aSheet->GetInstances();
1238
1239 auto it = sheetInstances.begin();
1240
1241 while( it != sheetInstances.end() )
1242 {
1243 if( it->m_Path.size() == 0 )
1244 it = sheetInstances.erase( it );
1245 else
1246 it++;
1247 }
1248
1249 if( !sheetInstances.empty() )
1250 {
1251 m_out->Print( "(instances" );
1252
1253 KIID lastProjectUuid;
1254 KIID rootSheetUuid = effectiveRootUuid( *m_schematic );
1255 bool inProjectClause = false;
1256
1257 for( size_t i = 0; i < sheetInstances.size(); i++ )
1258 {
1259 // If the instance data is part of this design but no longer has an associated sheet
1260 // path, don't save it. This prevents large amounts of orphaned instance data for the
1261 // current project from accumulating in the schematic files.
1262 //
1263 // Keep all instance data when copying to the clipboard. It may be needed on paste.
1264 if( ( sheetInstances[i].m_Path[0] == rootSheetUuid )
1265 && !aSheetList.GetSheetPathByKIIDPath( sheetInstances[i].m_Path, false ) )
1266 {
1267 if( inProjectClause
1268 && ( ( i + 1 == sheetInstances.size() ) || lastProjectUuid != sheetInstances[i + 1].m_Path[0] ) )
1269 {
1270 m_out->Print( ")" ); // Closes `project` token.
1271 inProjectClause = false;
1272 }
1273
1274 continue;
1275 }
1276
1277 if( lastProjectUuid != sheetInstances[i].m_Path[0] )
1278 {
1279 wxString projectName;
1280
1281 if( sheetInstances[i].m_Path[0] == rootSheetUuid )
1282 projectName = m_schematic->Project().GetProjectName();
1283 else
1284 projectName = sheetInstances[i].m_ProjectName;
1285
1286 lastProjectUuid = sheetInstances[i].m_Path[0];
1287 m_out->Print( "(project %s", m_out->Quotew( projectName ).c_str() );
1288 inProjectClause = true;
1289 }
1290
1291 wxString path = sheetInstances[i].m_Path.AsString();
1292
1293 m_out->Print( "(path %s (page %s))", m_out->Quotew( path ).c_str(),
1294 m_out->Quotew( sheetInstances[i].m_PageNumber ).c_str() );
1295
1296 if( inProjectClause
1297 && ( ( i + 1 == sheetInstances.size() ) || lastProjectUuid != sheetInstances[i + 1].m_Path[0] ) )
1298 {
1299 m_out->Print( ")" ); // Closes `project` token.
1300 inProjectClause = false;
1301 }
1302 }
1303
1304 m_out->Print( ")" ); // Closes `instances` token.
1305 }
1306
1307 m_out->Print( ")" ); // Closes sheet token.
1308}
1309
1310
1312{
1313 wxCHECK_RET( aJunction != nullptr && m_out != nullptr, "" );
1314
1315 m_out->Print( "(junction (at %s %s) (diameter %s) (color %d %d %d %s)",
1319 KiROUND( aJunction->GetColor().r * 255.0 ), KiROUND( aJunction->GetColor().g * 255.0 ),
1320 KiROUND( aJunction->GetColor().b * 255.0 ), FormatDouble2Str( aJunction->GetColor().a ).c_str() );
1321
1323 m_out->Print( ")" );
1324}
1325
1326
1328{
1329 wxCHECK_RET( aNoConnect != nullptr && m_out != nullptr, "" );
1330
1331 m_out->Print( "(no_connect (at %s %s)",
1333 EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aNoConnect->GetPosition().y ).c_str() );
1334
1336 m_out->Print( ")" );
1337}
1338
1339
1341{
1342 wxCHECK_RET( aBusEntry != nullptr && m_out != nullptr, "" );
1343
1344 // Bus to bus entries are converted to bus line segments.
1345 if( aBusEntry->GetClass() == "SCH_BUS_BUS_ENTRY" )
1346 {
1347 SCH_LINE busEntryLine( aBusEntry->GetPosition(), LAYER_BUS );
1348
1349 busEntryLine.SetEndPoint( aBusEntry->GetEnd() );
1350 saveLine( &busEntryLine );
1351 return;
1352 }
1353
1354 m_out->Print( "(bus_entry (at %s %s) (size %s %s)",
1358 EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aBusEntry->GetSize().y ).c_str() );
1359
1362 m_out->Print( ")" );
1363}
1364
1365
1367{
1368 wxCHECK_RET( aShape != nullptr && m_out != nullptr, "" );
1369
1370 switch( aShape->GetShape() )
1371 {
1372 case SHAPE_T::ARC:
1373 formatArc( m_out, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), aShape->GetFillColor(), false,
1374 aShape->m_Uuid );
1375 break;
1376
1377 case SHAPE_T::CIRCLE:
1378 formatCircle( m_out, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), aShape->GetFillColor(), false,
1379 aShape->m_Uuid );
1380 break;
1381
1382 case SHAPE_T::RECTANGLE:
1383 formatRect( m_out, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), aShape->GetFillColor(), false,
1384 aShape->m_Uuid );
1385 break;
1386
1387 case SHAPE_T::BEZIER:
1388 formatBezier( m_out, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), aShape->GetFillColor(), false,
1389 aShape->m_Uuid );
1390 break;
1391
1392 case SHAPE_T::POLY:
1393 formatPoly( m_out, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), aShape->GetFillColor(), false,
1394 aShape->m_Uuid );
1395 break;
1396
1397 default: UNIMPLEMENTED_FOR( aShape->SHAPE_T_asString() );
1398 }
1399}
1400
1401
1403{
1404 wxCHECK_RET( aRuleArea != nullptr && m_out != nullptr, "" );
1405
1406 m_out->Print( "(rule_area " );
1407 saveShape( aRuleArea );
1408 m_out->Print( ")" );
1409}
1410
1411
1413{
1414 wxCHECK_RET( aLine != nullptr && m_out != nullptr, "" );
1415
1416 wxString lineType;
1417
1418 STROKE_PARAMS line_stroke = aLine->GetStroke();
1419
1420 switch( aLine->GetLayer() )
1421 {
1422 case LAYER_BUS: lineType = "bus"; break;
1423 case LAYER_WIRE: lineType = "wire"; break;
1424 case LAYER_NOTES: lineType = "polyline"; break;
1425 default: UNIMPLEMENTED_FOR( LayerName( aLine->GetLayer() ) );
1426 }
1427
1428 m_out->Print( "(%s (pts (xy %s %s) (xy %s %s))", TO_UTF8( lineType ),
1433
1436 m_out->Print( ")" );
1437}
1438
1439
1441{
1442 wxCHECK_RET( aText != nullptr && m_out != nullptr, "" );
1443
1444 // Note: label is nullptr SCH_TEXT, but not for SCH_LABEL_XXX,
1445 SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( aText );
1446
1447 m_out->Print( "(%s %s", getTextTypeToken( aText->Type() ), m_out->Quotew( aText->GetText() ).c_str() );
1448
1449 if( aText->Type() == SCH_TEXT_T )
1450 KICAD_FORMAT::LEGACY::FormatBool( m_out, "exclude_from_sim", aText->GetExcludedFromSim() );
1451
1452 if( aText->Type() == SCH_DIRECTIVE_LABEL_T )
1453 {
1454 SCH_DIRECTIVE_LABEL* flag = static_cast<SCH_DIRECTIVE_LABEL*>( aText );
1455
1456 m_out->Print( "(length %s)", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, flag->GetPinLength() ).c_str() );
1457 }
1458
1459 EDA_ANGLE angle = aText->GetTextAngle();
1460
1461 if( label )
1462 {
1463 if( label->Type() == SCH_GLOBAL_LABEL_T || label->Type() == SCH_HIER_LABEL_T
1464 || label->Type() == SCH_DIRECTIVE_LABEL_T )
1465 {
1466 m_out->Print( "(shape %s)", getSheetPinShapeToken( label->GetShape() ) );
1467 }
1468
1469 // The angle of the text is always 0 or 90 degrees for readibility reasons,
1470 // but the item itself can have more rotation (-90 and 180 deg)
1471 switch( label->GetSpinStyle() )
1472 {
1473 default:
1474 case SPIN_STYLE::LEFT: angle += ANGLE_180; break;
1475 case SPIN_STYLE::UP: break;
1476 case SPIN_STYLE::RIGHT: break;
1477 case SPIN_STYLE::BOTTOM: angle += ANGLE_180; break;
1478 }
1479 }
1480
1481 m_out->Print( "(at %s %s %s)", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aText->GetPosition().x ).c_str(),
1483 EDA_UNIT_UTILS::FormatAngle( angle ).c_str() );
1484
1485 if( label && !label->GetFields().empty() )
1486 {
1487 AUTOPLACE_ALGO fieldsAutoplaced = label->GetFieldsAutoplaced();
1488
1489 if( fieldsAutoplaced == AUTOPLACE_AUTO || fieldsAutoplaced == AUTOPLACE_MANUAL )
1490 KICAD_FORMAT::LEGACY::FormatBool( m_out, "fields_autoplaced", true );
1491 }
1492
1493 formatEdaTextV9( m_out, *aText, 0 );
1495
1496 if( label )
1497 {
1498 for( SCH_FIELD& field : label->GetFields() )
1499 saveField( &field );
1500 }
1501
1502 m_out->Print( ")" ); // Closes text token.
1503}
1504
1505
1507{
1508 wxCHECK_RET( aTextBox != nullptr && m_out != nullptr, "" );
1509
1510 m_out->Print( "(%s %s", aTextBox->Type() == SCH_TABLECELL_T ? "table_cell" : "text_box",
1511 m_out->Quotew( aTextBox->GetText() ).c_str() );
1512
1513 KICAD_FORMAT::LEGACY::FormatBool( m_out, "exclude_from_sim", aTextBox->GetExcludedFromSim() );
1514
1515 VECTOR2I pos = aTextBox->GetStart();
1516 VECTOR2I size = aTextBox->GetEnd() - pos;
1517
1518 m_out->Print( "(at %s %s %s) (size %s %s) (margins %s %s %s %s)",
1521 EDA_UNIT_UTILS::FormatAngle( aTextBox->GetTextAngle() ).c_str(),
1528
1529 if( SCH_TABLECELL* cell = dynamic_cast<SCH_TABLECELL*>( aTextBox ) )
1530 m_out->Print( "(span %d %d)", cell->GetColSpan(), cell->GetRowSpan() );
1531
1532 if( aTextBox->Type() != SCH_TABLECELL_T )
1534
1535 formatFill( m_out, aTextBox->GetFillMode(), aTextBox->GetFillColor() );
1536 formatEdaTextV9( m_out, *aTextBox, 0 );
1538 m_out->Print( ")" );
1539}
1540
1541
1543{
1544 if( aTable->GetFlags() & SKIP_STRUCT )
1545 {
1546 aTable = static_cast<SCH_TABLE*>( aTable->Clone() );
1547
1548 int minCol = aTable->GetColCount();
1549 int maxCol = -1;
1550 int minRow = aTable->GetRowCount();
1551 int maxRow = -1;
1552
1553 for( int row = 0; row < aTable->GetRowCount(); ++row )
1554 {
1555 for( int col = 0; col < aTable->GetColCount(); ++col )
1556 {
1557 SCH_TABLECELL* cell = aTable->GetCell( row, col );
1558
1559 if( cell->IsSelected() )
1560 {
1561 minRow = std::min( minRow, row );
1562 maxRow = std::max( maxRow, row );
1563 minCol = std::min( minCol, col );
1564 maxCol = std::max( maxCol, col );
1565 }
1566 else
1567 {
1568 cell->SetFlags( STRUCT_DELETED );
1569 }
1570 }
1571 }
1572
1573 wxCHECK_MSG( maxCol >= minCol && maxRow >= minRow, /*void*/, wxT( "No selected cells!" ) );
1574
1575 int destRow = 0;
1576
1577 for( int row = minRow; row <= maxRow; row++ )
1578 aTable->SetRowHeight( destRow++, aTable->GetRowHeight( row ) );
1579
1580 int destCol = 0;
1581
1582 for( int col = minCol; col <= maxCol; col++ )
1583 aTable->SetColWidth( destCol++, aTable->GetColWidth( col ) );
1584
1585 aTable->DeleteMarkedCells();
1586 aTable->SetColCount( ( maxCol - minCol ) + 1 );
1587 }
1588
1589 wxCHECK_RET( aTable != nullptr && m_out != nullptr, "" );
1590
1591 m_out->Print( "(table (column_count %d)", aTable->GetColCount() );
1592
1593 m_out->Print( "(border" );
1594 KICAD_FORMAT::LEGACY::FormatBool( m_out, "external", aTable->StrokeExternal() );
1596
1597 if( aTable->StrokeExternal() || aTable->StrokeHeaderSeparator() )
1599
1600 m_out->Print( ")" ); // Close `border` token.
1601
1602 m_out->Print( "(separators" );
1605
1606 if( aTable->StrokeRows() || aTable->StrokeColumns() )
1608
1609 m_out->Print( ")" ); // Close `separators` token.
1610
1611 m_out->Print( "(column_widths" );
1612
1613 for( int col = 0; col < aTable->GetColCount(); ++col )
1614 {
1615 m_out->Print( " %s", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aTable->GetColWidth( col ) ).c_str() );
1616 }
1617
1618 m_out->Print( ")" );
1619
1620 m_out->Print( "(row_heights" );
1621
1622 for( int row = 0; row < aTable->GetRowCount(); ++row )
1623 {
1624 m_out->Print( " %s", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aTable->GetRowHeight( row ) ).c_str() );
1625 }
1626
1627 m_out->Print( ")" );
1628
1629 m_out->Print( "(cells" );
1630
1631 for( SCH_TABLECELL* cell : aTable->GetCells() )
1632 saveTextBox( cell );
1633
1634 m_out->Print( ")" ); // Close `cells` token.
1635 m_out->Print( ")" ); // Close `table` token.
1636
1637 if( aTable->GetFlags() & SKIP_STRUCT )
1638 delete aTable;
1639}
1640
1641
1642void SCH_WRITER_V9::saveBusAlias( std::shared_ptr<BUS_ALIAS> aAlias )
1643{
1644 wxCHECK_RET( aAlias != nullptr, "BUS_ALIAS* is NULL" );
1645
1646 wxString members;
1647
1648 for( const wxString& member : aAlias->Members() )
1649 {
1650 if( !members.IsEmpty() )
1651 members += wxS( " " );
1652
1653 members += m_out->Quotew( member );
1654 }
1655
1656 m_out->Print( "(bus_alias %s (members %s))", m_out->Quotew( aAlias->GetName() ).c_str(), TO_UTF8( members ) );
1657}
1658
1659
1660void SCH_WRITER_V9::saveInstances( const std::vector<SCH_SHEET_INSTANCE>& aInstances )
1661{
1662 if( aInstances.size() )
1663 {
1664 m_out->Print( "(sheet_instances" );
1665
1666 for( const SCH_SHEET_INSTANCE& instance : aInstances )
1667 {
1668 wxString path = instance.m_Path.AsString();
1669
1670 if( path.IsEmpty() )
1671 path = wxT( "/" ); // Root path
1672
1673 m_out->Print( "(path %s (page %s))", m_out->Quotew( path ).c_str(),
1674 m_out->Quotew( instance.m_PageNumber ).c_str() );
1675 }
1676
1677 m_out->Print( ")" ); // Close sheet instances token.
1678 }
1679}
const char * name
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:130
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:985
wxString GetMajorMinorVersion()
Get only the major and minor version in a string major.minor.
This class handle bitmap images in KiCad.
Definition bitmap_base.h:47
bool SaveImageData(wxOutputStream &aOutStream) const
Write the bitmap data to aOutStream.
int GetPPI() const
wxImage * GetImageData()
Definition bitmap_base.h:66
int AsTenthsOfADegree() const
Definition eda_angle.h:117
double AsDegrees() const
Definition eda_angle.h:115
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition eda_item.h:158
const KIID m_Uuid
Definition eda_item.h:599
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition eda_item.h:160
bool IsSelected() const
Definition eda_item.h:134
EDA_ITEM * GetParent() const
Definition eda_item.h:112
EDA_ITEM_FLAGS GetFlags() const
Definition eda_item.h:167
const VECTOR2I & GetBezierC2() const
Definition eda_shape.h:376
FILL_T GetFillMode() const
Definition eda_shape.h:150
SHAPE_POLY_SET & GetPolyShape()
int GetRadius() const
SHAPE_T GetShape() const
Definition eda_shape.h:177
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition eda_shape.h:333
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition eda_shape.h:283
COLOR4D GetFillColor() const
Definition eda_shape.h:161
wxString SHAPE_T_asString() const
const VECTOR2I & GetBezierC1() const
Definition eda_shape.h:373
VECTOR2I GetArcMid() const
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:94
wxString GetFontName() const
bool IsItalic() const
Definition eda_text.h:200
bool IsMultilineAllowed() const
Definition eda_text.h:236
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:118
virtual bool IsVisible() const
Definition eda_text.h:226
virtual int GetTextHeight() const
Definition eda_text.h:307
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition eda_text.h:239
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:347
virtual EDA_ANGLE GetTextAngle() const
Definition eda_text.h:178
bool IsMirrored() const
Definition eda_text.h:229
bool IsBold() const
Definition eda_text.h:215
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition eda_text.h:242
virtual int GetTextThickness() const
Definition eda_text.h:159
void ClearEmbeddedFonts()
Remove all embedded fonts from the collection.
const std::map< wxString, std::shared_ptr< EMBEDDED_FILE > > & EmbeddedFileMap() const
Provide an iterable view of the file collection.
bool GetAreFontsEmbedded() const
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
double r
Red component.
Definition color4d.h:391
double g
Green component.
Definition color4d.h:392
double a
Alpha component.
Definition color4d.h:394
double b
Blue component.
Definition color4d.h:393
bool MakeRelativeTo(const KIID_PATH &aPath)
Definition kiid.cpp:378
wxString AsString() const
Definition kiid.cpp:423
Definition kiid.h:46
wxString AsString() const
Definition kiid.cpp:264
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition lib_id.cpp:65
const UTF8 & GetLibItemName() const
Definition lib_id.h:98
Define a library symbol object.
Definition lib_symbol.h:114
const wxString & GetRawKeyWords() const
Return only this symbol's keywords, without inheriting from its parent.
Definition lib_symbol.h:218
const LIB_ID & GetLibId() const override
Definition lib_symbol.h:190
std::weak_ptr< LIB_SYMBOL > & GetParent()
Definition lib_symbol.h:152
void GetFields(std::vector< SCH_FIELD * > &aList, bool aVisibleOnly=false) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
bool IsPower() const override
bool UnitsLocked() const
Check whether symbol units are interchangeable.
bool IsRoot() const override
For symbols derived from other symbols, IsRoot() indicates no derivation.
Definition lib_symbol.h:240
std::vector< struct LIB_SYMBOL_UNIT > GetUnitDrawItems()
Return a list of SCH_ITEM objects separated by unit and convert number.
std::map< int, wxString > & GetUnitDisplayNames()
Definition lib_symbol.h:881
wxArrayString GetFPFilters() const
Definition lib_symbol.h:252
EMBEDDED_FILES * GetEmbeddedFiles() override
void EmbedFonts() override
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:37
An interface used to output 8 bit text in a convenient way.
Definition richio.h:294
std::string Quotew(const wxString &aWrapee) const
Definition richio.cpp:505
int PRINTF_FUNC_N Print(int nestLevel, const char *fmt,...)
Format and write text to the output stream.
Definition richio.cpp:432
virtual std::string Quotes(const std::string &aWrapee) const
Check aWrapee input string for a need to be quoted (e.g.
Definition richio.cpp:466
bool Finish() override
Runs prettification over the buffered bytes, writes them to the sibling temp file,...
Definition richio.cpp:710
A REFERENCE_IMAGE is a wrapper around a BITMAP_IMAGE that is displayed in an editor as a reference fo...
VECTOR2I GetPosition() const
const BITMAP_BASE & GetImage() const
Get the underlying image.
double GetImageScale() const
Holds all the data relating to one schematic.
Definition schematic.h:153
SCH_SHEET & Root() const
Definition schematic.h:280
std::vector< SCH_SHEET * > GetTopLevelSheets() const
Get the list of top-level sheets.
Object to handle a bitmap image that can be inserted in a schematic.
Definition sch_bitmap.h:36
REFERENCE_IMAGE & GetReferenceImage()
Definition sch_bitmap.h:50
Base class for a bus or wire entry.
VECTOR2I GetSize() const
VECTOR2I GetPosition() const override
virtual STROKE_PARAMS GetStroke() const override
VECTOR2I GetEnd() const
bool IsMandatory() const
VECTOR2I GetPosition() const override
bool IsNameShown() const
Definition sch_field.h:225
virtual const wxString & GetText() const override
Return the string associated with the text object.
Definition sch_field.h:139
wxString GetUntranslatedName() const
Get the untranslated field name for storage, variable look-up, etc.
wxString GetName(bool aUseDefaultName=true) const
Return the field name (not translated).
bool CanAutoplace() const
Definition sch_field.h:236
void SetText(const wxString &aText) override
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:170
int GetBodyStyle() const
Definition sch_item.h:253
bool IsPrivate() const
Definition sch_item.h:259
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition sch_item.h:353
AUTOPLACE_ALGO GetFieldsAutoplaced() const
Return whether the fields have been automatically placed.
Definition sch_item.h:678
wxString GetClass() const override
Return the class name.
Definition sch_item.h:180
int GetDiameter() const
VECTOR2I GetPosition() const override
KIGFX::COLOR4D GetColor() const
SPIN_STYLE GetSpinStyle() const
LABEL_FLAG_SHAPE GetShape() const
Definition sch_label.h:178
std::vector< SCH_FIELD > & GetFields()
Definition sch_label.h:210
Segment description base class to describe items which have 2 end points (track, wire,...
Definition sch_line.h:39
virtual STROKE_PARAMS GetStroke() const override
Definition sch_line.h:198
VECTOR2I GetEndPoint() const
Definition sch_line.h:145
VECTOR2I GetStartPoint() const
Definition sch_line.h:136
void SetEndPoint(const VECTOR2I &aPosition)
Definition sch_line.h:146
VECTOR2I GetPosition() const override
int GetNumberTextSize() const
Definition sch_pin.cpp:882
int GetLength() const
Definition sch_pin.cpp:421
const std::map< wxString, ALT > & GetAlternates() const
Definition sch_pin.h:219
bool IsVisible() const
Definition sch_pin.cpp:513
const wxString & GetName() const
Definition sch_pin.cpp:527
PIN_ORIENTATION GetOrientation() const
Definition sch_pin.cpp:386
VECTOR2I GetPosition() const override
Definition sch_pin.cpp:378
int GetNameTextSize() const
Definition sch_pin.cpp:856
const wxString & GetNumber() const
Definition sch_pin.h:144
GRAPHIC_PINSHAPE GetShape() const
Definition sch_pin.cpp:400
ELECTRICAL_PINTYPE GetType() const
Definition sch_pin.cpp:435
const PAGE_INFO & GetPageSettings() const
Definition sch_screen.h:144
const std::map< wxString, LIB_SYMBOL * > & GetLibSymbols() const
Fetch a list of unique LIB_SYMBOL object pointers required to properly render each SCH_SYMBOL in this...
Definition sch_screen.h:565
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition sch_screen.h:122
const KIID & GetUuid() const
Definition sch_screen.h:602
TITLE_BLOCK & GetTitleBlock()
Definition sch_screen.h:168
STROKE_PARAMS GetStroke() const override
Definition sch_shape.h:59
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
std::optional< SCH_SHEET_PATH > GetSheetPathByKIIDPath(const KIID_PATH &aPath, bool aIncludeLastSheet=true) const
Finds a SCH_SHEET_PATH that matches the provided KIID_PATH.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition sch_sheet.h:50
bool HasRootInstance() const
Check to see if this sheet has a root sheet instance.
std::vector< SCH_FIELD > & GetFields()
Return a reference to the vector holding the sheet's fields.
Definition sch_sheet.h:93
bool GetExcludedFromBOM(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
bool GetExcludedFromSim(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
VECTOR2I GetSize() const
Definition sch_sheet.h:189
SCH_SCREEN * GetScreen() const
Definition sch_sheet.h:187
VECTOR2I GetPosition() const override
Definition sch_sheet.h:548
const SCH_SHEET_INSTANCE & GetRootInstance() const
Return the root sheet instance data.
KIGFX::COLOR4D GetBorderColor() const
Definition sch_sheet.h:195
bool GetDNP(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
Set or clear the 'Do Not Populate' flags.
bool GetExcludedFromBoard(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
Definition sch_sheet.h:519
int GetBorderWidth() const
Definition sch_sheet.h:192
std::vector< SCH_SHEET_PIN * > & GetPins()
Definition sch_sheet.h:285
const std::vector< SCH_SHEET_INSTANCE > & GetInstances() const
Definition sch_sheet.h:563
KIGFX::COLOR4D GetBackgroundColor() const
Definition sch_sheet.h:198
Schematic symbol object.
Definition sch_symbol.h:76
bool GetExcludedFromSim(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
std::vector< std::unique_ptr< SCH_PIN > > & GetRawPins()
Definition sch_symbol.h:715
const std::vector< SCH_SYMBOL_INSTANCE > & GetInstances() const
Definition sch_symbol.h:136
bool UseLibIdLookup() const
Definition sch_symbol.h:183
wxString GetSchSymbolLibraryName() const
bool GetExcludedFromBOM(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
VECTOR2I GetPosition() const override
Definition sch_symbol.h:958
const LIB_ID & GetLibId() const override
Definition sch_symbol.h:166
bool GetInstance(SCH_SYMBOL_INSTANCE &aInstance, const KIID_PATH &aSheetPath, bool aTestFromEnd=false) const
bool GetExcludedFromBoard(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
int GetOrientation() const override
Get the display symbol orientation.
virtual bool GetDNP(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
Set or clear the 'Do Not Populate' flag.
wxString GetPrefix() const
Definition sch_symbol.h:241
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
void SetRowHeight(int aRow, int aHeight)
Definition sch_table.h:138
const STROKE_PARAMS & GetSeparatorsStroke() const
Definition sch_table.h:76
void SetColCount(int aCount)
Definition sch_table.h:118
bool StrokeExternal() const
Definition sch_table.h:52
int GetRowHeight(int aRow) const
Definition sch_table.h:140
void SetColWidth(int aCol, int aWidth)
Definition sch_table.h:128
std::vector< SCH_TABLECELL * > GetCells() const
Definition sch_table.h:158
int GetColWidth(int aCol) const
Definition sch_table.h:130
const STROKE_PARAMS & GetBorderStroke() const
Definition sch_table.h:58
int GetColCount() const
Definition sch_table.h:119
bool StrokeHeaderSeparator() const
Definition sch_table.h:55
void DeleteMarkedCells()
Definition sch_table.h:183
SCH_TABLECELL * GetCell(int aRow, int aCol) const
Definition sch_table.h:148
bool StrokeColumns() const
Definition sch_table.h:98
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition sch_table.h:232
bool StrokeRows() const
Definition sch_table.h:101
int GetRowCount() const
Definition sch_table.h:121
int GetMarginBottom() const
Definition sch_textbox.h:82
int GetMarginLeft() const
Definition sch_textbox.h:79
bool GetExcludedFromSim(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
int GetMarginRight() const
Definition sch_textbox.h:81
int GetMarginTop() const
Definition sch_textbox.h:80
bool GetExcludedFromSim(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
Definition sch_text.h:86
VECTOR2I GetPosition() const override
Definition sch_text.h:143
void Format(SCH_SHEET *aSheet)
void SaveSymbolLibrary(const wxString &aFileName, const std::vector< LIB_SYMBOL * > &aSymbols)
void saveRuleArea(SCH_RULE_AREA *aRuleArea)
void saveTable(SCH_TABLE *aTable)
void saveInstances(const std::vector< SCH_SHEET_INSTANCE > &aInstances)
void saveJunction(SCH_JUNCTION *aJunction)
void saveLine(SCH_LINE *aLine)
static constexpr int FORMAT_VERSION
void saveSheet(SCH_SHEET *aSheet, const SCH_SHEET_LIST &aSheetList)
void saveBitmap(const SCH_BITMAP &aBitmap)
void saveShape(SCH_SHAPE *aShape)
OUTPUTFORMATTER * m_out
void SaveSchematicFile(const wxString &aFileName, SCH_SHEET *aSheet, SCHEMATIC *aSchematic)
void saveField(SCH_FIELD *aField)
void saveBusEntry(SCH_BUS_ENTRY_BASE *aBusEntry)
void saveSymbol(SCH_SYMBOL *aSymbol, const SCHEMATIC &aSchematic, const SCH_SHEET_LIST &aSheetList, bool aForClipboard, const SCH_SHEET_PATH *aRelativePath=nullptr)
void saveBusAlias(std::shared_ptr< BUS_ALIAS > aAlias)
void saveTextBox(SCH_TEXTBOX *aTextBox)
static constexpr int SYMBOL_LIB_VERSION
SCHEMATIC * m_schematic
void saveText(SCH_TEXT *aText)
void saveNoConnect(SCH_NO_CONNECT *aNoConnect)
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
bool IsClosed() const override
int PointCount() const
Return the number of points (vertices) in this line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
const std::vector< VECTOR2I > & CPoints() const
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int OutlineCount() const
Return the number of outlines in the set.
Simple container to manage line stroke parameters.
void SetWidth(int aWidth)
int GetPinNameOffset() const
Definition symbol.h:163
virtual bool GetExcludedFromBOM(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
Definition symbol.h:201
virtual bool GetShowPinNames() const
Definition symbol.h:169
bool GetExcludedFromBoard(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
Definition symbol.h:216
virtual bool GetExcludedFromSim(const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) const override
Definition symbol.h:186
virtual bool GetShowPinNumbers() const
Definition symbol.h:175
wxString wx_str() const
Definition utf8.cpp:41
#define DEFAULT_PIN_NAME_OFFSET
The offset of the pin name string from the end of the pin in mils.
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:472
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:474
static constexpr EDA_ANGLE ANGLE_270
Definition eda_angle.h:477
static constexpr EDA_ANGLE ANGLE_180
Definition eda_angle.h:476
FILL_T
Definition eda_fill.h:29
@ FILLED_WITH_COLOR
Definition eda_fill.h:33
@ NO_FILL
Definition eda_fill.h:30
@ FILLED_WITH_BG_BODYCOLOR
Definition eda_fill.h:32
@ FILLED_SHAPE
Fill with object color.
Definition eda_fill.h:31
#define IS_CHANGED
Item was edited, and modified.
#define STRUCT_DELETED
flag indication structures to be erased
#define SKIP_STRUCT
flag indicating that the structure should be ignored
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
Definition eda_shape.h:57
#define DEFAULT_SIZE_TEXT
This is the "default-of-the-default" hardcoded text size; individual application define their own def...
Definition eda_text.h:84
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition idf_helpers.h:37
KIID niluuid(0)
wxString LayerName(int aLayer)
Returns the default display name for a given layer.
Definition layer_id.cpp:31
@ LAYER_WIRE
Definition layer_ids.h:483
@ LAYER_NOTES
Definition layer_ids.h:498
@ LAYER_BUS
Definition layer_ids.h:484
#define UNIMPLEMENTED_FOR(type)
Definition macros.h:92
KICOMMON_API std::string FormatAngle(const EDA_ANGLE &aAngle)
Convert aAngle from board units to a string appropriate for writing to file.
KICOMMON_API std::string FormatInternalUnits(const EDA_IU_SCALE &aIuScale, int aValue, EDA_DATA_TYPE aDataType=EDA_DATA_TYPE::DISTANCE)
Converts aValue from internal units to a string appropriate for writing to file.
void FormatBool(OUTPUTFORMATTER *aOut, const wxString &aKey, bool aValue)
void FormatTitle(OUTPUTFORMATTER *aOut, const TITLE_BLOCK &aTitle)
void FormatStreamData(OUTPUTFORMATTER &aOut, const wxStreamBuffer &aStream)
void FormatEmbeddedFilesV9(OUTPUTFORMATTER &aOut, const EMBEDDED_FILES &aFiles, bool aWriteData)
void FormatUuid(OUTPUTFORMATTER *aOut, const KIID &aUuid)
void FormatTextV9(OUTPUTFORMATTER *aOut, const EDA_TEXT &aText, const EDA_IU_SCALE &aScale, int aControlBits)
void FormatStroke(OUTPUTFORMATTER *aOut, const STROKE_PARAMS &aStroke, const EDA_IU_SCALE &aScale)
UTF8 FormatLibId(const LIB_ID &aId)
void FormatPageV9(OUTPUTFORMATTER *aOut, const PAGE_INFO &aPage)
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
Definition pin_type.h:32
@ PT_INPUT
usual pin input: must be connected
Definition pin_type.h:33
@ PT_NC
not connected (must be left open)
Definition pin_type.h:46
@ PT_OUTPUT
usual output
Definition pin_type.h:34
@ PT_TRISTATE
tri state bus pin
Definition pin_type.h:36
@ PT_NIC
not internally connected (may be connected to anything)
Definition pin_type.h:40
@ PT_BIDI
input or output (like port for a microprocessor)
Definition pin_type.h:35
@ PT_OPENEMITTER
pin type open emitter
Definition pin_type.h:45
@ PT_POWER_OUT
output of a regulator: intended to be connected to power input pins
Definition pin_type.h:43
@ PT_OPENCOLLECTOR
pin type open collector
Definition pin_type.h:44
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
Definition pin_type.h:42
@ PT_UNSPECIFIED
unknown electrical properties: creates always a warning when connected
Definition pin_type.h:41
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin.
Definition pin_type.h:39
PIN_ORIENTATION
The symbol library pin object orientations.
Definition pin_type.h:101
@ PIN_UP
The pin extends upwards from the connection point: Probably on the bottom side of the symbol.
Definition pin_type.h:123
@ PIN_RIGHT
The pin extends rightwards from the connection point.
Definition pin_type.h:107
@ PIN_LEFT
The pin extends leftwards from the connection point: Probably on the right side of the symbol.
Definition pin_type.h:114
@ PIN_DOWN
The pin extends downwards from the connection: Probably on the top side of the symbol.
Definition pin_type.h:131
GRAPHIC_PINSHAPE
Definition pin_type.h:80
EDA_ANGLE getPinAngle(PIN_ORIENTATION aOrientation)
void formatArc(OUTPUTFORMATTER *aFormatter, EDA_SHAPE *aArc, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, bool aInvertY, const KIID &aUuid, bool aLocked)
void formatCircle(OUTPUTFORMATTER *aFormatter, EDA_SHAPE *aCircle, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, bool aInvertY, const KIID &aUuid, bool aLocked)
const char * getSheetPinShapeToken(LABEL_FLAG_SHAPE aShape)
void formatRect(OUTPUTFORMATTER *aFormatter, EDA_SHAPE *aRect, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, bool aInvertY, const KIID &aUuid, bool aLocked)
const char * getPinElectricalTypeToken(ELECTRICAL_PINTYPE aType)
const char * getTextTypeToken(KICAD_T aType)
void formatBezier(OUTPUTFORMATTER *aFormatter, EDA_SHAPE *aBezier, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, bool aInvertY, const KIID &aUuid, bool aLocked)
std::string formatIU(const int &aValue)
void formatPoly(OUTPUTFORMATTER *aFormatter, EDA_SHAPE *aPolyLine, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, bool aInvertY, const KIID &aUuid, bool aLocked)
EDA_ANGLE getSheetPinAngle(SHEET_SIDE aSide)
void formatFill(OUTPUTFORMATTER *aFormatter, FILL_T aFillMode, const COLOR4D &aFillColor)
Fill token formatting helper.
const char * getPinShapeToken(GRAPHIC_PINSHAPE aShape)
static const char * emptyString
AUTOPLACE_ALGO
Definition sch_item.h:73
@ AUTOPLACE_MANUAL
Definition sch_item.h:76
@ AUTOPLACE_AUTO
Definition sch_item.h:75
@ DEMORGAN
Definition sch_item.h:65
LABEL_FLAG_SHAPE
Label and flag shapes used with text objects.
Definition sch_label.h:97
@ L_BIDI
Definition sch_label.h:100
@ L_TRISTATE
Definition sch_label.h:101
@ L_UNSPECIFIED
Definition sch_label.h:102
@ F_DOT
Definition sch_label.h:105
@ F_ROUND
Definition sch_label.h:106
@ L_OUTPUT
Definition sch_label.h:99
@ F_DIAMOND
Definition sch_label.h:107
@ L_INPUT
Definition sch_label.h:98
@ F_RECTANGLE
Definition sch_label.h:108
SHEET_SIDE
Define the edge of the sheet that the sheet pin is positioned.
std::string toUTFTildaText(const wxString &txt)
Convert a wxString to UTF8 and replace any control characters with a ~, where a control character is ...
static void libSaveSymbol(LIB_SYMBOL *aSymbol, OUTPUTFORMATTER &aFormatter, const wxString &aLibName=wxEmptyString, bool aIncludeData=true)
static const char * getTextTypeToken(KICAD_T aType)
static void formatEdaTextV9(OUTPUTFORMATTER *aFormatter, const EDA_TEXT &aText, int aControlBits)
static EDA_ANGLE getSheetPinAngle(SHEET_SIDE aSide)
static void formatFill(OUTPUTFORMATTER *aFormatter, FILL_T aFillMode, const COLOR4D &aFillColor)
static void formatArc(OUTPUTFORMATTER *aFormatter, EDA_SHAPE *aArc, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, bool aInvertY, const KIID &aUuid=niluuid)
static bool isDefaultFormattingV9(const EDA_TEXT &aText)
static void formatPoly(OUTPUTFORMATTER *aFormatter, EDA_SHAPE *aPolyLine, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, bool aInvertY, const KIID &aUuid=niluuid)
static EDA_ANGLE getPinAngle(PIN_ORIENTATION aOrientation)
static void formatCircle(OUTPUTFORMATTER *aFormatter, EDA_SHAPE *aCircle, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, bool aInvertY, const KIID &aUuid=niluuid)
static void libSaveField(SCH_FIELD *aField, OUTPUTFORMATTER &aFormatter)
static void libSaveSymbol(LIB_SYMBOL *aSymbol, OUTPUTFORMATTER &aFormatter, const wxString &aLibName=wxEmptyString, bool aIncludeData=true)
static const char * getPinShapeToken(GRAPHIC_PINSHAPE aShape)
static void formatBezier(OUTPUTFORMATTER *aFormatter, EDA_SHAPE *aBezier, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, bool aInvertY, const KIID &aUuid=niluuid)
static std::string formatIU(const int &aValue)
static void libSaveText(SCH_TEXT *aText, OUTPUTFORMATTER &aFormatter)
static void formatRect(OUTPUTFORMATTER *aFormatter, EDA_SHAPE *aRect, bool aIsPrivate, const STROKE_PARAMS &aStroke, FILL_T aFillMode, const COLOR4D &aFillColor, bool aInvertY, const KIID &aUuid=niluuid)
static void libSaveTextBox(SCH_TEXTBOX *aTextBox, OUTPUTFORMATTER &aFormatter)
static void libSaveDcmInfoAsFields(LIB_SYMBOL *aSymbol, OUTPUTFORMATTER &aFormatter)
static const char * getPinElectricalTypeToken(ELECTRICAL_PINTYPE aType)
static KIID effectiveRootUuid(const SCHEMATIC &aSchematic)
static void libSavePin(SCH_PIN *aPin, OUTPUTFORMATTER &aFormatter)
static void libSaveSymbolDrawItem(SCH_ITEM *aItem, OUTPUTFORMATTER &aFormatter)
static const char * getSheetPinShapeToken(LABEL_FLAG_SHAPE aShape)
const int scale
std::string FormatDouble2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 This function is intended in...
std::string EscapedUTF8(const wxString &aString)
Return an 8 bit UTF8 string given aString in Unicode form.
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_NO_SPACE
A simple container for sheet instance information.
A simple container for schematic symbol instance information.
@ SYM_ORIENT_270
Definition symbol.h:39
@ SYM_MIRROR_Y
Definition symbol.h:41
@ SYM_ORIENT_180
Definition symbol.h:38
@ SYM_MIRROR_X
Definition symbol.h:40
@ SYM_ORIENT_90
Definition symbol.h:37
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ USER
The field ID hasn't been set yet; field is invalid.
@ FOOTPRINT
Field Name Module PCB, i.e. "16DIP300".
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
static EDA_ORIENTATION orientation(double d)
std::string path
KIBIS_PIN * pin
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_CENTER
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:70
@ SCH_TABLE_T
Definition typeinfo.h:161
@ SCH_LINE_T
Definition typeinfo.h:159
@ SCH_NO_CONNECT_T
Definition typeinfo.h:156
@ SCH_SYMBOL_T
Definition typeinfo.h:168
@ SCH_TABLECELL_T
Definition typeinfo.h:162
@ SCH_FIELD_T
Definition typeinfo.h:146
@ SCH_DIRECTIVE_LABEL_T
Definition typeinfo.h:167
@ SCH_LABEL_T
Definition typeinfo.h:163
@ SCH_SHEET_T
Definition typeinfo.h:171
@ SCH_MARKER_T
Definition typeinfo.h:154
@ SCH_SHAPE_T
Definition typeinfo.h:145
@ SCH_RULE_AREA_T
Definition typeinfo.h:166
@ SCH_HIER_LABEL_T
Definition typeinfo.h:165
@ SCH_BUS_BUS_ENTRY_T
Definition typeinfo.h:158
@ SCH_TEXT_T
Definition typeinfo.h:147
@ SCH_BUS_WIRE_ENTRY_T
Definition typeinfo.h:157
@ SCH_BITMAP_T
Definition typeinfo.h:160
@ SCH_TEXTBOX_T
Definition typeinfo.h:148
@ SCH_GLOBAL_LABEL_T
Definition typeinfo.h:164
@ SCH_JUNCTION_T
Definition typeinfo.h:155
@ SCH_PIN_T
Definition typeinfo.h:149
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708