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
897 if( orientation == SYM_ORIENT_90 )
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 m_out->Print( "(path %s (reference %s) (unit %d))", m_out->Quotew( path ).c_str(),
1099 m_out->Quotew( instance.m_Reference ).c_str(), instance.m_Unit );
1100 }
1101
1102 m_out->Print( ")" ); // Closes `project`.
1103 }
1104
1105 m_out->Print( ")" ); // Closes `instances`.
1106 }
1107
1108 m_out->Print( ")" ); // Closes `symbol`.
1109}
1110
1111
1113{
1114 wxCHECK_RET( aField != nullptr && m_out != nullptr, "" );
1115
1116 wxString fieldName;
1117
1118 if( aField->IsMandatory() )
1119 fieldName = aField->GetUntranslatedName();
1120 else
1121 fieldName = aField->GetName();
1122
1123 m_out->Print( "(property %s %s %s (at %s %s %s)", aField->IsPrivate() ? "private" : "",
1124 m_out->Quotew( fieldName ).c_str(), m_out->Quotew( aField->GetText() ).c_str(),
1127 EDA_UNIT_UTILS::FormatAngle( aField->GetTextAngle() ).c_str() );
1128
1129 if( aField->IsNameShown() )
1130 KICAD_FORMAT::LEGACY::FormatBool( m_out, "show_name", true );
1131
1132 if( !aField->CanAutoplace() )
1133 KICAD_FORMAT::LEGACY::FormatBool( m_out, "do_not_autoplace", true );
1134
1135 if( !isDefaultFormattingV9( *aField ) || ( aField->GetTextHeight() != schIUScale.MilsToIU( DEFAULT_SIZE_TEXT ) ) )
1136 {
1137 formatEdaTextV9( m_out, *aField, 0 );
1138 }
1139
1140 m_out->Print( ")" ); // Closes `property` token
1141}
1142
1143
1145{
1146 wxCHECK_RET( m_out != nullptr, "" );
1147
1148 const REFERENCE_IMAGE& refImage = aBitmap.GetReferenceImage();
1149 const BITMAP_BASE& bitmapBase = refImage.GetImage();
1150
1151 const wxImage* image = bitmapBase.GetImageData();
1152
1153 wxCHECK_RET( image != nullptr, "wxImage* is NULL" );
1154
1155 m_out->Print( "(image (at %s %s)",
1158
1159 double scale = refImage.GetImageScale();
1160
1161 // 20230121 or older file format versions assumed 300 image PPI at load/save.
1162 // Let's keep compatibility by changing image scale.
1163 if( SCH_WRITER_V9::FORMAT_VERSION <= 20230121 )
1164 scale = scale * 300.0 / bitmapBase.GetPPI();
1165
1166 if( scale != 1.0 )
1167 m_out->Print( "(scale %g)", scale ); //format:allow
1168
1170
1171 wxMemoryOutputStream stream;
1172 bitmapBase.SaveImageData( stream );
1173
1174 KICAD_FORMAT::LEGACY::FormatStreamData( *m_out, *stream.GetOutputStreamBuffer() );
1175
1176 m_out->Print( ")" ); // Closes image token.
1177}
1178
1179
1180void SCH_WRITER_V9::saveSheet( SCH_SHEET* aSheet, const SCH_SHEET_LIST& aSheetList )
1181{
1182 wxCHECK_RET( aSheet != nullptr && m_out != nullptr, "" );
1183
1184 m_out->Print( "(sheet (at %s %s) (size %s %s)",
1189
1190 KICAD_FORMAT::LEGACY::FormatBool( m_out, "exclude_from_sim", aSheet->GetExcludedFromSim() );
1193 KICAD_FORMAT::LEGACY::FormatBool( m_out, "dnp", aSheet->GetDNP() );
1194
1195 AUTOPLACE_ALGO fieldsAutoplaced = aSheet->GetFieldsAutoplaced();
1196
1197 if( fieldsAutoplaced == AUTOPLACE_AUTO || fieldsAutoplaced == AUTOPLACE_MANUAL )
1198 KICAD_FORMAT::LEGACY::FormatBool( m_out, "fields_autoplaced", true );
1199
1200 STROKE_PARAMS stroke( aSheet->GetBorderWidth(), LINE_STYLE::SOLID, aSheet->GetBorderColor() );
1201
1202 stroke.SetWidth( aSheet->GetBorderWidth() );
1204
1205 m_out->Print( "(fill (color %d %d %d %0.4f))", KiROUND( aSheet->GetBackgroundColor().r * 255.0 ), //format:allow
1206 KiROUND( aSheet->GetBackgroundColor().g * 255.0 ), KiROUND( aSheet->GetBackgroundColor().b * 255.0 ),
1207 aSheet->GetBackgroundColor().a );
1208
1210
1211
1212 for( SCH_FIELD& field : aSheet->GetFields() )
1213 saveField( &field );
1214
1215 for( const SCH_SHEET_PIN* pin : aSheet->GetPins() )
1216 {
1217 m_out->Print( "(pin %s %s (at %s %s %s)", EscapedUTF8( pin->GetText() ).c_str(),
1218 getSheetPinShapeToken( pin->GetShape() ),
1219 EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pin->GetPosition().x ).c_str(),
1220 EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, pin->GetPosition().y ).c_str(),
1221 EDA_UNIT_UTILS::FormatAngle( getSheetPinAngle( pin->GetSide() ) ).c_str() );
1222
1224
1225 formatEdaTextV9( m_out, *pin, 0 );
1226
1227 m_out->Print( ")" ); // Closes pin token.
1228 }
1229
1230 // Save all sheet instances here except the root sheet instance.
1231 std::vector<SCH_SHEET_INSTANCE> sheetInstances = aSheet->GetInstances();
1232
1233 auto it = sheetInstances.begin();
1234
1235 while( it != sheetInstances.end() )
1236 {
1237 if( it->m_Path.size() == 0 )
1238 it = sheetInstances.erase( it );
1239 else
1240 it++;
1241 }
1242
1243 if( !sheetInstances.empty() )
1244 {
1245 m_out->Print( "(instances" );
1246
1247 KIID lastProjectUuid;
1248 KIID rootSheetUuid = effectiveRootUuid( *m_schematic );
1249 bool inProjectClause = false;
1250
1251 for( size_t i = 0; i < sheetInstances.size(); i++ )
1252 {
1253 // If the instance data is part of this design but no longer has an associated sheet
1254 // path, don't save it. This prevents large amounts of orphaned instance data for the
1255 // current project from accumulating in the schematic files.
1256 //
1257 // Keep all instance data when copying to the clipboard. It may be needed on paste.
1258 if( ( sheetInstances[i].m_Path[0] == rootSheetUuid )
1259 && !aSheetList.GetSheetPathByKIIDPath( sheetInstances[i].m_Path, false ) )
1260 {
1261 if( inProjectClause
1262 && ( ( i + 1 == sheetInstances.size() ) || lastProjectUuid != sheetInstances[i + 1].m_Path[0] ) )
1263 {
1264 m_out->Print( ")" ); // Closes `project` token.
1265 inProjectClause = false;
1266 }
1267
1268 continue;
1269 }
1270
1271 if( lastProjectUuid != sheetInstances[i].m_Path[0] )
1272 {
1273 wxString projectName;
1274
1275 if( sheetInstances[i].m_Path[0] == rootSheetUuid )
1276 projectName = m_schematic->Project().GetProjectName();
1277 else
1278 projectName = sheetInstances[i].m_ProjectName;
1279
1280 lastProjectUuid = sheetInstances[i].m_Path[0];
1281 m_out->Print( "(project %s", m_out->Quotew( projectName ).c_str() );
1282 inProjectClause = true;
1283 }
1284
1285 wxString path = sheetInstances[i].m_Path.AsString();
1286
1287 m_out->Print( "(path %s (page %s))", m_out->Quotew( path ).c_str(),
1288 m_out->Quotew( sheetInstances[i].m_PageNumber ).c_str() );
1289
1290 if( inProjectClause
1291 && ( ( i + 1 == sheetInstances.size() ) || lastProjectUuid != sheetInstances[i + 1].m_Path[0] ) )
1292 {
1293 m_out->Print( ")" ); // Closes `project` token.
1294 inProjectClause = false;
1295 }
1296 }
1297
1298 m_out->Print( ")" ); // Closes `instances` token.
1299 }
1300
1301 m_out->Print( ")" ); // Closes sheet token.
1302}
1303
1304
1306{
1307 wxCHECK_RET( aJunction != nullptr && m_out != nullptr, "" );
1308
1309 m_out->Print( "(junction (at %s %s) (diameter %s) (color %d %d %d %s)",
1313 KiROUND( aJunction->GetColor().r * 255.0 ), KiROUND( aJunction->GetColor().g * 255.0 ),
1314 KiROUND( aJunction->GetColor().b * 255.0 ), FormatDouble2Str( aJunction->GetColor().a ).c_str() );
1315
1317 m_out->Print( ")" );
1318}
1319
1320
1322{
1323 wxCHECK_RET( aNoConnect != nullptr && m_out != nullptr, "" );
1324
1325 m_out->Print( "(no_connect (at %s %s)",
1327 EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aNoConnect->GetPosition().y ).c_str() );
1328
1330 m_out->Print( ")" );
1331}
1332
1333
1335{
1336 wxCHECK_RET( aBusEntry != nullptr && m_out != nullptr, "" );
1337
1338 // Bus to bus entries are converted to bus line segments.
1339 if( aBusEntry->GetClass() == "SCH_BUS_BUS_ENTRY" )
1340 {
1341 SCH_LINE busEntryLine( aBusEntry->GetPosition(), LAYER_BUS );
1342
1343 busEntryLine.SetEndPoint( aBusEntry->GetEnd() );
1344 saveLine( &busEntryLine );
1345 return;
1346 }
1347
1348 m_out->Print( "(bus_entry (at %s %s) (size %s %s)",
1352 EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aBusEntry->GetSize().y ).c_str() );
1353
1356 m_out->Print( ")" );
1357}
1358
1359
1361{
1362 wxCHECK_RET( aShape != nullptr && m_out != nullptr, "" );
1363
1364 switch( aShape->GetShape() )
1365 {
1366 case SHAPE_T::ARC:
1367 formatArc( m_out, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), aShape->GetFillColor(), false,
1368 aShape->m_Uuid );
1369 break;
1370
1371 case SHAPE_T::CIRCLE:
1372 formatCircle( m_out, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), aShape->GetFillColor(), false,
1373 aShape->m_Uuid );
1374 break;
1375
1376 case SHAPE_T::RECTANGLE:
1377 formatRect( m_out, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), aShape->GetFillColor(), false,
1378 aShape->m_Uuid );
1379 break;
1380
1381 case SHAPE_T::BEZIER:
1382 formatBezier( m_out, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), aShape->GetFillColor(), false,
1383 aShape->m_Uuid );
1384 break;
1385
1386 case SHAPE_T::POLY:
1387 formatPoly( m_out, aShape, false, aShape->GetStroke(), aShape->GetFillMode(), aShape->GetFillColor(), false,
1388 aShape->m_Uuid );
1389 break;
1390
1391 default: UNIMPLEMENTED_FOR( aShape->SHAPE_T_asString() );
1392 }
1393}
1394
1395
1397{
1398 wxCHECK_RET( aRuleArea != nullptr && m_out != nullptr, "" );
1399
1400 m_out->Print( "(rule_area " );
1401 saveShape( aRuleArea );
1402 m_out->Print( ")" );
1403}
1404
1405
1407{
1408 wxCHECK_RET( aLine != nullptr && m_out != nullptr, "" );
1409
1410 wxString lineType;
1411
1412 STROKE_PARAMS line_stroke = aLine->GetStroke();
1413
1414 switch( aLine->GetLayer() )
1415 {
1416 case LAYER_BUS: lineType = "bus"; break;
1417 case LAYER_WIRE: lineType = "wire"; break;
1418 case LAYER_NOTES: lineType = "polyline"; break;
1419 default: UNIMPLEMENTED_FOR( LayerName( aLine->GetLayer() ) );
1420 }
1421
1422 m_out->Print( "(%s (pts (xy %s %s) (xy %s %s))", TO_UTF8( lineType ),
1427
1430 m_out->Print( ")" );
1431}
1432
1433
1435{
1436 wxCHECK_RET( aText != nullptr && m_out != nullptr, "" );
1437
1438 // Note: label is nullptr SCH_TEXT, but not for SCH_LABEL_XXX,
1439 SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( aText );
1440
1441 m_out->Print( "(%s %s", getTextTypeToken( aText->Type() ), m_out->Quotew( aText->GetText() ).c_str() );
1442
1443 if( aText->Type() == SCH_TEXT_T )
1444 KICAD_FORMAT::LEGACY::FormatBool( m_out, "exclude_from_sim", aText->GetExcludedFromSim() );
1445
1446 if( aText->Type() == SCH_DIRECTIVE_LABEL_T )
1447 {
1448 SCH_DIRECTIVE_LABEL* flag = static_cast<SCH_DIRECTIVE_LABEL*>( aText );
1449
1450 m_out->Print( "(length %s)", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, flag->GetPinLength() ).c_str() );
1451 }
1452
1453 EDA_ANGLE angle = aText->GetTextAngle();
1454
1455 if( label )
1456 {
1457 if( label->Type() == SCH_GLOBAL_LABEL_T || label->Type() == SCH_HIER_LABEL_T
1458 || label->Type() == SCH_DIRECTIVE_LABEL_T )
1459 {
1460 m_out->Print( "(shape %s)", getSheetPinShapeToken( label->GetShape() ) );
1461 }
1462
1463 // The angle of the text is always 0 or 90 degrees for readibility reasons,
1464 // but the item itself can have more rotation (-90 and 180 deg)
1465 switch( label->GetSpinStyle() )
1466 {
1467 default:
1468 case SPIN_STYLE::LEFT: angle += ANGLE_180; break;
1469 case SPIN_STYLE::UP: break;
1470 case SPIN_STYLE::RIGHT: break;
1471 case SPIN_STYLE::BOTTOM: angle += ANGLE_180; break;
1472 }
1473 }
1474
1475 m_out->Print( "(at %s %s %s)", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aText->GetPosition().x ).c_str(),
1477 EDA_UNIT_UTILS::FormatAngle( angle ).c_str() );
1478
1479 if( label && !label->GetFields().empty() )
1480 {
1481 AUTOPLACE_ALGO fieldsAutoplaced = label->GetFieldsAutoplaced();
1482
1483 if( fieldsAutoplaced == AUTOPLACE_AUTO || fieldsAutoplaced == AUTOPLACE_MANUAL )
1484 KICAD_FORMAT::LEGACY::FormatBool( m_out, "fields_autoplaced", true );
1485 }
1486
1487 formatEdaTextV9( m_out, *aText, 0 );
1489
1490 if( label )
1491 {
1492 for( SCH_FIELD& field : label->GetFields() )
1493 saveField( &field );
1494 }
1495
1496 m_out->Print( ")" ); // Closes text token.
1497}
1498
1499
1501{
1502 wxCHECK_RET( aTextBox != nullptr && m_out != nullptr, "" );
1503
1504 m_out->Print( "(%s %s", aTextBox->Type() == SCH_TABLECELL_T ? "table_cell" : "text_box",
1505 m_out->Quotew( aTextBox->GetText() ).c_str() );
1506
1507 KICAD_FORMAT::LEGACY::FormatBool( m_out, "exclude_from_sim", aTextBox->GetExcludedFromSim() );
1508
1509 VECTOR2I pos = aTextBox->GetStart();
1510 VECTOR2I size = aTextBox->GetEnd() - pos;
1511
1512 m_out->Print( "(at %s %s %s) (size %s %s) (margins %s %s %s %s)",
1515 EDA_UNIT_UTILS::FormatAngle( aTextBox->GetTextAngle() ).c_str(),
1522
1523 if( SCH_TABLECELL* cell = dynamic_cast<SCH_TABLECELL*>( aTextBox ) )
1524 m_out->Print( "(span %d %d)", cell->GetColSpan(), cell->GetRowSpan() );
1525
1526 if( aTextBox->Type() != SCH_TABLECELL_T )
1528
1529 formatFill( m_out, aTextBox->GetFillMode(), aTextBox->GetFillColor() );
1530 formatEdaTextV9( m_out, *aTextBox, 0 );
1532 m_out->Print( ")" );
1533}
1534
1535
1537{
1538 if( aTable->GetFlags() & SKIP_STRUCT )
1539 {
1540 aTable = static_cast<SCH_TABLE*>( aTable->Clone() );
1541
1542 int minCol = aTable->GetColCount();
1543 int maxCol = -1;
1544 int minRow = aTable->GetRowCount();
1545 int maxRow = -1;
1546
1547 for( int row = 0; row < aTable->GetRowCount(); ++row )
1548 {
1549 for( int col = 0; col < aTable->GetColCount(); ++col )
1550 {
1551 SCH_TABLECELL* cell = aTable->GetCell( row, col );
1552
1553 if( cell->IsSelected() )
1554 {
1555 minRow = std::min( minRow, row );
1556 maxRow = std::max( maxRow, row );
1557 minCol = std::min( minCol, col );
1558 maxCol = std::max( maxCol, col );
1559 }
1560 else
1561 {
1562 cell->SetFlags( STRUCT_DELETED );
1563 }
1564 }
1565 }
1566
1567 wxCHECK_MSG( maxCol >= minCol && maxRow >= minRow, /*void*/, wxT( "No selected cells!" ) );
1568
1569 int destRow = 0;
1570
1571 for( int row = minRow; row <= maxRow; row++ )
1572 aTable->SetRowHeight( destRow++, aTable->GetRowHeight( row ) );
1573
1574 int destCol = 0;
1575
1576 for( int col = minCol; col <= maxCol; col++ )
1577 aTable->SetColWidth( destCol++, aTable->GetColWidth( col ) );
1578
1579 aTable->DeleteMarkedCells();
1580 aTable->SetColCount( ( maxCol - minCol ) + 1 );
1581 }
1582
1583 wxCHECK_RET( aTable != nullptr && m_out != nullptr, "" );
1584
1585 m_out->Print( "(table (column_count %d)", aTable->GetColCount() );
1586
1587 m_out->Print( "(border" );
1588 KICAD_FORMAT::LEGACY::FormatBool( m_out, "external", aTable->StrokeExternal() );
1590
1591 if( aTable->StrokeExternal() || aTable->StrokeHeaderSeparator() )
1593
1594 m_out->Print( ")" ); // Close `border` token.
1595
1596 m_out->Print( "(separators" );
1599
1600 if( aTable->StrokeRows() || aTable->StrokeColumns() )
1602
1603 m_out->Print( ")" ); // Close `separators` token.
1604
1605 m_out->Print( "(column_widths" );
1606
1607 for( int col = 0; col < aTable->GetColCount(); ++col )
1608 {
1609 m_out->Print( " %s", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aTable->GetColWidth( col ) ).c_str() );
1610 }
1611
1612 m_out->Print( ")" );
1613
1614 m_out->Print( "(row_heights" );
1615
1616 for( int row = 0; row < aTable->GetRowCount(); ++row )
1617 {
1618 m_out->Print( " %s", EDA_UNIT_UTILS::FormatInternalUnits( schIUScale, aTable->GetRowHeight( row ) ).c_str() );
1619 }
1620
1621 m_out->Print( ")" );
1622
1623 m_out->Print( "(cells" );
1624
1625 for( SCH_TABLECELL* cell : aTable->GetCells() )
1626 saveTextBox( cell );
1627
1628 m_out->Print( ")" ); // Close `cells` token.
1629 m_out->Print( ")" ); // Close `table` token.
1630
1631 if( aTable->GetFlags() & SKIP_STRUCT )
1632 delete aTable;
1633}
1634
1635
1636void SCH_WRITER_V9::saveBusAlias( std::shared_ptr<BUS_ALIAS> aAlias )
1637{
1638 wxCHECK_RET( aAlias != nullptr, "BUS_ALIAS* is NULL" );
1639
1640 wxString members;
1641
1642 for( const wxString& member : aAlias->Members() )
1643 {
1644 if( !members.IsEmpty() )
1645 members += wxS( " " );
1646
1647 members += m_out->Quotew( member );
1648 }
1649
1650 m_out->Print( "(bus_alias %s (members %s))", m_out->Quotew( aAlias->GetName() ).c_str(), TO_UTF8( members ) );
1651}
1652
1653
1654void SCH_WRITER_V9::saveInstances( const std::vector<SCH_SHEET_INSTANCE>& aInstances )
1655{
1656 if( aInstances.size() )
1657 {
1658 m_out->Print( "(sheet_instances" );
1659
1660 for( const SCH_SHEET_INSTANCE& instance : aInstances )
1661 {
1662 wxString path = instance.m_Path.AsString();
1663
1664 if( path.IsEmpty() )
1665 path = wxT( "/" ); // Root path
1666
1667 m_out->Print( "(path %s (page %s))", m_out->Quotew( path ).c_str(),
1668 m_out->Quotew( instance.m_PageNumber ).c_str() );
1669 }
1670
1671 m_out->Print( ")" ); // Close sheet instances token.
1672 }
1673}
const char * name
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:130
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:982
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:45
bool SaveImageData(wxOutputStream &aOutStream) const
Write the bitmap data to aOutStream.
int GetPPI() const
wxImage * GetImageData()
Definition bitmap_base.h:64
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:368
FILL_T GetFillMode() const
Definition eda_shape.h:148
SHAPE_POLY_SET & GetPolyShape()
int GetRadius() const
SHAPE_T GetShape() const
Definition eda_shape.h:175
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition eda_shape.h:325
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition eda_shape.h:275
COLOR4D GetFillColor() const
Definition eda_shape.h:159
wxString SHAPE_T_asString() const
const VECTOR2I & GetBezierC1() const
Definition eda_shape.h:365
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:149
SCH_SHEET & Root() const
Definition schematic.h:200
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:229
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:240
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:673
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:557
EE_RTREE & Items()
Get the full RTree, usually for iterating.
Definition sch_screen.h:122
const KIID & GetUuid() const
Definition sch_screen.h:594
TITLE_BLOCK & GetTitleBlock()
Definition sch_screen.h:168
STROKE_PARAMS GetStroke() const override
Definition sch_shape.h:57
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:48
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:91
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:147
SCH_SCREEN * GetScreen() const
Definition sch_sheet.h:145
VECTOR2I GetPosition() const override
Definition sch_sheet.h:506
const SCH_SHEET_INSTANCE & GetRootInstance() const
Return the root sheet instance data.
KIGFX::COLOR4D GetBorderColor() const
Definition sch_sheet.h:153
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:477
int GetBorderWidth() const
Definition sch_sheet.h:150
std::vector< SCH_SHEET_PIN * > & GetPins()
Definition sch_sheet.h:243
const std::vector< SCH_SHEET_INSTANCE > & GetInstances() const
Definition sch_sheet.h:521
KIGFX::COLOR4D GetBackgroundColor() const
Definition sch_sheet.h:156
Schematic symbol object.
Definition sch_symbol.h:73
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:678
const std::vector< SCH_SYMBOL_INSTANCE > & GetInstances() const
Definition sch_symbol.h:133
bool UseLibIdLookup() const
Definition sch_symbol.h:180
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:900
const LIB_ID & GetLibId() const override
Definition sch_symbol.h:163
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:238
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:448
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:450
static constexpr EDA_ANGLE ANGLE_270
Definition eda_angle.h:453
static constexpr EDA_ANGLE ANGLE_180
Definition eda_angle.h:452
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:474
@ LAYER_NOTES
Definition layer_ids.h:489
@ LAYER_BUS
Definition layer_ids.h:475
#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".
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