KiCad PCB EDA Suite
eagle_parser.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
5 * Copyright (C) 2012-2023 KiCad Developers, see AUTHORS.txt for contributors.
6 * Copyright (C) 2017 CERN.
7 *
8 * @author Alejandro GarcĂ­a Montoro <[email protected]>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, you may find one here:
22 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
23 * or you may search the http://www.gnu.org website for the version 2 license,
24 * or you may write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26 */
27
29
30#include <string_utils.h>
31#include <richio.h>
32#include <wx/log.h>
33
34#include <functional>
35#include <cstdio>
36
38
39
40wxString escapeName( const wxString& aNetName )
41{
42 wxString ret( aNetName );
43
44 ret.Replace( "!", "~" );
45
46 return ConvertToNewOverbarNotation( ret );
47}
48
49
50wxString interpretText( const wxString& aText )
51{
52 wxString token = aText.Upper();
53
54 if( substituteVariable( &token ) )
55 return token;
56
57 wxString text;
58 bool sectionOpen = false;
59
60 for( wxString::size_type i = 0; i < aText.size(); i++ )
61 {
62 // Interpret escaped characters
63 if( aText[ i ] == '\\' )
64 {
65 if( i + 1 != aText.size() )
66 text.Append( aText[ i + 1 ] );
67
68 i++;
69 continue;
70 }
71
72 // Escape ~ for KiCAD
73 if( aText[i] == '~' )
74 {
75 text.Append( '~' );
76 text.Append( '~' );
77 continue;
78 }
79
80 if( aText[ i ] == '!' )
81 {
82 if( sectionOpen )
83 {
84 text.Append( '~' );
85 sectionOpen = false;
86 continue;
87 }
88
89 static wxString escapeChars( wxT( " )]}'\"" ) );
90
91 if( i + 1 != aText.size() && escapeChars.Find( aText[i + 1] ) == wxNOT_FOUND )
92 {
93 sectionOpen = true;
94 text.Append( '~' );
95 }
96 else
97 {
98 text.Append( aText[ i ] );
99 }
100
101 continue;
102 }
103
104 if( aText[i] == ',' && sectionOpen )
105 {
106 text.Append( '~' );
107 sectionOpen = false;
108 }
109
110 text.Append( aText[ i ] );
111 }
112
113 return text;
114}
115
116
117bool substituteVariable( wxString* aText )
118{
119 if ( *aText == wxT( ">NAME" ) ) *aText = wxT( "${REFERENCE}" );
120 else if( *aText == wxT( ">VALUE" ) ) *aText = wxT( "${VALUE}" );
121 else if( *aText == wxT( ">PART" ) ) *aText = wxT( "${REFERENCE}" );
122 else if( *aText == wxT( ">GATE" ) ) *aText = wxT( "${UNIT}" );
123 else if( *aText == wxT( ">MODULE" ) ) *aText = wxT( "${FOOTPRINT_NAME}" );
124 else if( *aText == wxT( ">SHEETNR" ) ) *aText = wxT( "${#}" );
125 else if( *aText == wxT( ">SHEETS" ) ) *aText = wxT( "${##}" );
126 else if( *aText == wxT( ">SHEET" ) ) *aText = wxT( "${#}/${##}" );
127 else if( *aText == wxT( ">SHEETNR_TOTAL" ) ) *aText = wxT( "${#}" );
128 else if( *aText == wxT( ">SHEETS_TOTAL" ) ) *aText = wxT( "${##}" );
129 else if( *aText == wxT( ">SHEET_TOTAL" ) ) *aText = wxT( "${#}/${##}" );
130 else if( *aText == wxT( ">SHEET_HEADLINE" ) ) *aText = wxT( "${SHEETNAME}" );
131 else if( *aText == wxT( ">ASSEMBLY_VARIANT" ) ) *aText = wxT( "${ASSEMBLY_VARIANT}" );
132 else if( *aText == wxT( ">DRAWING_NAME" ) ) *aText = wxT( "${PROJECTNAME}" );
133 else if( *aText == wxT( ">LAST_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" );
134 else if( *aText == wxT( ">PLOT_DATE_TIME" ) ) *aText = wxT( "${CURRENT_DATE}" );
135 else return false;
136
137 return true;
138}
139
140
141template<> template<>
143{
144 m_isAvailable = !aData.IsEmpty();
145
146 if( m_isAvailable )
147 Set( aData );
148}
149
150
151ECOORD::ECOORD( const wxString& aValue, enum ECOORD::EAGLE_UNIT aUnit )
152{
153 // This array is used to adjust the fraction part value basing on the number of digits
154 // in the fraction.
155 constexpr int DIVIDERS[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 };
156 constexpr unsigned int DIVIDERS_MAX_IDX = sizeof( DIVIDERS ) / sizeof( DIVIDERS[0] ) - 1;
157
158 int integer, fraction, pre_fraction, post_fraction;
159
160 // The following check is needed to handle correctly negative fractions where the integer
161 // part == 0.
162 bool negative = ( aValue[0] == '-' );
163
164 // %n is used to find out how many digits contains the fraction part, e.g. 0.001 contains 3
165 // digits.
166 int ret = sscanf( aValue.c_str(), "%d.%n%d%n", &integer, &pre_fraction, &fraction,
167 &post_fraction );
168
169 if( ret == 0 )
170 throw XML_PARSER_ERROR( "Invalid coordinate" );
171
172 // process the integer part
173 value = ConvertToNm( integer, aUnit );
174
175 // process the fraction part
176 if( ret == 2 )
177 {
178 int digits = post_fraction - pre_fraction;
179
180 // adjust the number of digits if necessary as we cannot handle anything smaller than
181 // nanometers (rounding).
182 if( (unsigned) digits > DIVIDERS_MAX_IDX )
183 {
184 int diff = digits - DIVIDERS_MAX_IDX;
185 digits = DIVIDERS_MAX_IDX;
186 fraction /= DIVIDERS[diff];
187 }
188
189 int frac_value = ConvertToNm( fraction, aUnit ) / DIVIDERS[digits];
190
191 // keep the sign in mind
192 value = negative ? value - frac_value : value + frac_value;
193 }
194}
195
196
197long long int ECOORD::ConvertToNm( int aValue, enum EAGLE_UNIT aUnit )
198{
199 long long int ret;
200
201 switch( aUnit )
202 {
203 default:
204 case EU_NM: ret = aValue; break;
205 case EU_MM: ret = (long long) aValue * 1000000; break;
206 case EU_INCH: ret = (long long) aValue * 25400000; break;
207 case EU_MIL: ret = (long long) aValue * 25400; break;
208 }
209
210 if( ( ret > 0 ) != ( aValue > 0 ) )
211 wxLogError( _( "Invalid size %lld: too large" ), aValue );
212
213 return ret;
214}
215
216
217// Template specializations below parse wxString to the used types:
218// - wxString (preferred)
219// - string
220// - double
221// - int
222// - bool
223// - EROT
224// - ECOORD
225
226template <>
227wxString Convert<wxString>( const wxString& aValue )
228{
229 return aValue;
230}
231
232
233template <>
234std::string Convert<std::string>( const wxString& aValue )
235{
236 return std::string( aValue.ToUTF8() );
237}
238
239
240template <>
241double Convert<double>( const wxString& aValue )
242{
243 double value;
244
245 if( aValue.ToCDouble( &value ) )
246 return value;
247 else
248 throw XML_PARSER_ERROR( "Conversion to double failed. Original value: '" +
249 aValue.ToStdString() + "'." );
250}
251
252
253template <>
254int Convert<int>( const wxString& aValue )
255{
256 if( aValue.IsEmpty() )
257 throw XML_PARSER_ERROR( "Conversion to int failed. Original value is empty." );
258
259 return wxAtoi( aValue );
260}
261
262
263template <>
264bool Convert<bool>( const wxString& aValue )
265{
266 if( aValue != "yes" && aValue != "no" )
267 throw XML_PARSER_ERROR( "Conversion to bool failed. Original value, '" +
268 aValue.ToStdString() +
269 "', is neither 'yes' nor 'no'." );
270
271 return aValue == "yes";
272}
273
274
277template<>
278EROT Convert<EROT>( const wxString& aRot )
279{
280 EROT value;
281
282 value.spin = aRot.find( 'S' ) != aRot.npos;
283 value.mirror = aRot.find( 'M' ) != aRot.npos;
284 value.degrees = strtod( aRot.c_str()
285 + 1 // skip leading 'R'
286 + int( value.spin ) // skip optional leading 'S'
287 + int( value.mirror ), // skip optional leading 'M'
288 nullptr );
289
290 return value;
291}
292
293
294template<>
295ECOORD Convert<ECOORD>( const wxString& aCoord )
296{
297 // Eagle uses millimeters as the default unit
298 return ECOORD( aCoord, ECOORD::EAGLE_UNIT::EU_MM );
299}
300
301
310template<typename T>
311T parseRequiredAttribute( wxXmlNode* aNode, const wxString& aAttribute )
312{
313 wxString value;
314
315 if( aNode->GetAttribute( aAttribute, &value ) )
316 return Convert<T>( value );
317 else
318 throw XML_PARSER_ERROR( "The required attribute " + aAttribute + " is missing." );
319}
320
321
330template<typename T>
331OPTIONAL_XML_ATTRIBUTE<T> parseOptionalAttribute( wxXmlNode* aNode, const wxString& aAttribute )
332{
333 return OPTIONAL_XML_ATTRIBUTE<T>( aNode->GetAttribute( aAttribute ) );
334}
335
336
337NODE_MAP MapChildren( wxXmlNode* aCurrentNode )
338{
339 // Map node_name -> node_pointer
340 NODE_MAP nodesMap;
341
342 // Loop through all children mapping them in nodesMap
343 if( aCurrentNode )
344 aCurrentNode = aCurrentNode->GetChildren();
345
346 while( aCurrentNode )
347 {
348 // Create a new pair in the map
349 // key: current node name
350 // value: current node pointer
351 nodesMap[aCurrentNode->GetName()] = aCurrentNode;
352
353 // Get next child
354 aCurrentNode = aCurrentNode->GetNext();
355 }
356
357 return nodesMap;
358}
359
360
361VECTOR2I ConvertArcCenter( const VECTOR2I& aStart, const VECTOR2I& aEnd, double aAngle )
362{
363 // Eagle give us start and end.
364 // S_ARC wants start to give the center, and end to give the start.
365 double dx = aEnd.x - aStart.x, dy = aEnd.y - aStart.y;
366 VECTOR2I mid = ( aStart + aEnd ) / 2;
367
368 double dlen = sqrt( dx*dx + dy*dy );
369
370 if( !std::isnormal( dlen ) || !std::isnormal( aAngle ) )
371 {
372 THROW_IO_ERROR( wxString::Format( _( "Invalid Arc with radius %f and angle %f" ),
373 dlen,
374 aAngle ) );
375 }
376
377 double dist = dlen / ( 2 * tan( DEG2RAD( aAngle ) / 2 ) );
378
379 VECTOR2I center(
380 mid.x + dist * ( dy / dlen ),
381 mid.y - dist * ( dx / dlen )
382 );
383
384 return center;
385}
386
387
388static int parseAlignment( const wxString& aAlignment )
389{
390 // (bottom-left | bottom-center | bottom-right | center-left |
391 // center | center-right | top-left | top-center | top-right)
392 if( aAlignment == "center" )
393 return ETEXT::CENTER;
394 else if( aAlignment == "center-right" )
395 return ETEXT::CENTER_RIGHT;
396 else if( aAlignment == "top-left" )
397 return ETEXT::TOP_LEFT;
398 else if( aAlignment == "top-center" )
399 return ETEXT::TOP_CENTER;
400 else if( aAlignment == "top-right" )
401 return ETEXT::TOP_RIGHT;
402 else if( aAlignment == "bottom-left" )
403 return ETEXT::BOTTOM_LEFT;
404 else if( aAlignment == "bottom-center" )
406 else if( aAlignment == "bottom-right" )
407 return ETEXT::BOTTOM_RIGHT;
408 else if( aAlignment == "center-left" )
409 return ETEXT::CENTER_LEFT;
410
411 return DEFAULT_ALIGNMENT;
412}
413
414
415EWIRE::EWIRE( wxXmlNode* aWire )
416{
417 /*
418 <!ELEMENT wire EMPTY>
419 <!ATTLIST wire
420 x1 %Coord; #REQUIRED
421 y1 %Coord; #REQUIRED
422 x2 %Coord; #REQUIRED
423 y2 %Coord; #REQUIRED
424 width %Dimension; #REQUIRED
425 layer %Layer; #REQUIRED
426 extent %Extent; #IMPLIED -- only applicable for airwires --
427 style %WireStyle; "continuous"
428 curve %WireCurve; "0"
429 cap %WireCap; "round" -- only applicable if 'curve' is not zero --
430 >
431 */
432
433 x1 = parseRequiredAttribute<ECOORD>( aWire, "x1" );
434 y1 = parseRequiredAttribute<ECOORD>( aWire, "y1" );
435 x2 = parseRequiredAttribute<ECOORD>( aWire, "x2" );
436 y2 = parseRequiredAttribute<ECOORD>( aWire, "y2" );
437 width = parseRequiredAttribute<ECOORD>( aWire, "width" );
438 layer = parseRequiredAttribute<int>( aWire, "layer" );
439 curve = parseOptionalAttribute<double>( aWire, "curve" );
440
441 opt_wxString s = parseOptionalAttribute<wxString>( aWire, "style" );
442
443 if( s == "continuous" )
445 else if( s == "longdash" )
447 else if( s == "shortdash" )
449 else if( s == "dashdot" )
451
452 s = parseOptionalAttribute<wxString>( aWire, "cap" );
453
454 if( s == "round" )
456 else if( s == "flat" )
458}
459
460
461EJUNCTION::EJUNCTION( wxXmlNode* aJunction )
462{
463 /*
464 <!ELEMENT junction EMPTY>
465 <!ATTLIST junction
466 x %Coord; #REQUIRED
467 y %Coord; #REQUIRED
468 >
469 */
470
471 x = parseRequiredAttribute<ECOORD>( aJunction, "x" );
472 y = parseRequiredAttribute<ECOORD>( aJunction, "y" );
473}
474
475
476ELABEL::ELABEL( wxXmlNode* aLabel, const wxString& aNetName )
477{
478 /*
479 <!ELEMENT label EMPTY>
480 <!ATTLIST label
481 x %Coord; #REQUIRED
482 y %Coord; #REQUIRED
483 size %Dimension; #REQUIRED
484 layer %Layer; #REQUIRED
485 font %TextFont; "proportional"
486 ratio %Int; "8"
487 rot %Rotation; "R0"
488 xref %Bool; "no"
489 >
490 */
491
492 x = parseRequiredAttribute<ECOORD>( aLabel, "x" );
493 y = parseRequiredAttribute<ECOORD>( aLabel, "y" );
494 size = parseRequiredAttribute<ECOORD>( aLabel, "size" );
495 layer = parseRequiredAttribute<int>( aLabel, "layer" );
496 rot = parseOptionalAttribute<EROT>( aLabel, "rot" );
497 xref = parseOptionalAttribute<wxString>( aLabel, "xref" );
498 netname = aNetName;
499}
500
501
502EVIA::EVIA( wxXmlNode* aVia )
503{
504 /*
505 <!ELEMENT via EMPTY>
506 <!ATTLIST via
507 x %Coord; #REQUIRED
508 y %Coord; #REQUIRED
509 extent %Extent; #REQUIRED
510 drill %Dimension; #REQUIRED
511 diameter %Dimension; "0"
512 shape %ViaShape; "round"
513 alwaysstop %Bool; "no"
514 >
515 */
516
517 x = parseRequiredAttribute<ECOORD>( aVia, "x" );
518 y = parseRequiredAttribute<ECOORD>( aVia, "y" );
519
520 wxString ext = parseRequiredAttribute<wxString>( aVia, "extent" );
521 sscanf( ext.c_str(), "%d-%d", &layer_front_most, &layer_back_most );
522
523 drill = parseRequiredAttribute<ECOORD>( aVia, "drill" );
524 diam = parseOptionalAttribute<ECOORD>( aVia, "diameter" );
525 shape = parseOptionalAttribute<wxString>( aVia, "shape" );
526}
527
528
529ECIRCLE::ECIRCLE( wxXmlNode* aCircle )
530{
531 /*
532 <!ELEMENT circle EMPTY>
533 <!ATTLIST circle
534 x %Coord; #REQUIRED
535 y %Coord; #REQUIRED
536 radius %Coord; #REQUIRED
537 width %Dimension; #REQUIRED
538 layer %Layer; #REQUIRED
539 >
540 */
541
542 x = parseRequiredAttribute<ECOORD>( aCircle, "x" );
543 y = parseRequiredAttribute<ECOORD>( aCircle, "y" );
544 radius = parseRequiredAttribute<ECOORD>( aCircle, "radius" );
545 width = parseRequiredAttribute<ECOORD>( aCircle, "width" );
546 layer = parseRequiredAttribute<int>( aCircle, "layer" );
547}
548
549
550ERECT::ERECT( wxXmlNode* aRect )
551{
552 /*
553 <!ELEMENT rectangle EMPTY>
554 <!ATTLIST rectangle
555 x1 %Coord; #REQUIRED
556 y1 %Coord; #REQUIRED
557 x2 %Coord; #REQUIRED
558 y2 %Coord; #REQUIRED
559 layer %Layer; #REQUIRED
560 rot %Rotation; "R0"
561 >
562 */
563
564 x1 = parseRequiredAttribute<ECOORD>( aRect, "x1" );
565 y1 = parseRequiredAttribute<ECOORD>( aRect, "y1" );
566 x2 = parseRequiredAttribute<ECOORD>( aRect, "x2" );
567 y2 = parseRequiredAttribute<ECOORD>( aRect, "y2" );
568 layer = parseRequiredAttribute<int>( aRect, "layer" );
569 rot = parseOptionalAttribute<EROT>( aRect, "rot" );
570}
571
572
573EATTR::EATTR( wxXmlNode* aTree )
574{
575 /*
576 <!ELEMENT attribute EMPTY>
577 <!ATTLIST attribute
578 name %String; #REQUIRED
579 value %String; #IMPLIED
580 x %Coord; #IMPLIED
581 y %Coord; #IMPLIED
582 size %Dimension; #IMPLIED
583 layer %Layer; #IMPLIED
584 font %TextFont; #IMPLIED
585 ratio %Int; #IMPLIED
586 rot %Rotation; "R0"
587 display %AttributeDisplay; "value" -- only in <element> or <instance> context --
588 constant %Bool; "no" -- only in <device> context --
589 >
590 */
591
592 name = parseRequiredAttribute<wxString>( aTree, "name" );
593 value = parseOptionalAttribute<wxString>( aTree, "value" );
594
595 x = parseOptionalAttribute<ECOORD>( aTree, "x" );
596 y = parseOptionalAttribute<ECOORD>( aTree, "y" );
597 size = parseOptionalAttribute<ECOORD>( aTree, "size" );
598
599 layer = parseOptionalAttribute<int>( aTree, "layer" );
600 ratio = parseOptionalAttribute<double>( aTree, "ratio" );
601 rot = parseOptionalAttribute<EROT>( aTree, "rot" );
602
603 opt_wxString stemp = parseOptionalAttribute<wxString>( aTree, "display" );
604
605 // (off | value | name | both)
606 if( stemp == "off" )
608 else if( stemp == "name" )
610 else if( stemp == "both" )
612 else // "value" is the default
614
615 stemp = parseOptionalAttribute<wxString>( aTree, "align" );
616
617 align = stemp ? parseAlignment( *stemp ) : DEFAULT_ALIGNMENT;
618}
619
620
621EDIMENSION::EDIMENSION( wxXmlNode* aDimension )
622{
623 /*
624 <!ELEMENT dimension EMPTY>
625 <!ATTLIST dimension
626 x1 %Coord; #REQUIRED
627 y1 %Coord; #REQUIRED
628 x2 %Coord; #REQUIRED
629 y2 %Coord; #REQUIRED
630 x3 %Coord; #REQUIRED
631 y3 %Coord; #REQUIRED
632 textsize %Coord;
633 layer %Layer; #REQUIRED
634 dtype %DimensionType; "parallel"
635 >
636 */
637
638 x1 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x1" ) );
639 y1 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y1" ) );
640 x2 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x2" ) );
641 y2 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y2" ) );
642 x3 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "x3" ) );
643 y3 = parseRequiredAttribute<ECOORD>( aDimension, wxT( "y3" ) );
644 textsize = parseOptionalAttribute<ECOORD>( aDimension, wxT( "textsize" ) );
645 layer = parseRequiredAttribute<int>( aDimension, wxT( "layer" ) );
646 dimensionType = parseOptionalAttribute<wxString>( aDimension, wxT( "dtype" ) );
647}
648
649
650ETEXT::ETEXT( wxXmlNode* aText )
651{
652 /*
653 <!ELEMENT text (#PCDATA)>
654 <!ATTLIST text
655 x %Coord; #REQUIRED
656 y %Coord; #REQUIRED
657 size %Dimension; #REQUIRED
658 layer %Layer; #REQUIRED
659 font %TextFont; "proportional"
660 ratio %Int; "8"
661 rot %Rotation; "R0"
662 align %Align; "bottom-left"
663 >
664 */
665
666 text = aText->GetNodeContent();
667 x = parseRequiredAttribute<ECOORD>( aText, "x" );
668 y = parseRequiredAttribute<ECOORD>( aText, "y" );
669 size = parseRequiredAttribute<ECOORD>( aText, "size" );
670 layer = parseRequiredAttribute<int>( aText, "layer" );
671
672 font = parseOptionalAttribute<wxString>( aText, "font" );
673 ratio = parseOptionalAttribute<double>( aText, "ratio" );
674 rot = parseOptionalAttribute<EROT>( aText, "rot" );
675
676 opt_wxString stemp = parseOptionalAttribute<wxString>( aText, "align" );
677
678 align = stemp ? parseAlignment( *stemp ) : DEFAULT_ALIGNMENT;
679}
680
681
682wxSize ETEXT::ConvertSize() const
683{
684 wxSize textsize;
685
686 if( font )
687 {
688 const wxString& fontName = font.CGet();
689
690 if( fontName == "vector" )
691 {
692 textsize = wxSize( size.ToSchUnits(), size.ToSchUnits() );
693 }
694 else if( fontName == "fixed" )
695 {
696 textsize = wxSize( size.ToSchUnits(), size.ToSchUnits() * 0.80 );
697 }
698 else
699 {
700 textsize = wxSize( size.ToSchUnits(), size.ToSchUnits() );
701 }
702 }
703 else
704 {
705 textsize = wxSize( size.ToSchUnits() * 0.85, size.ToSchUnits() );
706 }
707
708 return textsize;
709}
710
711
712EFRAME::EFRAME( wxXmlNode* aFrameNode )
713{
714 /*
715 * <!ELEMENT frame EMPTY>
716 * <!ATTLIST frame
717 * x1 %Coord; #REQUIRED
718 * y1 %Coord; #REQUIRED
719 * x2 %Coord; #REQUIRED
720 * y2 %Coord; #REQUIRED
721 * columns %Int; #REQUIRED
722 * rows %Int; #REQUIRED
723 * layer %Layer; #REQUIRED
724 * border-left %Bool; "yes"
725 * border-top %Bool; "yes"
726 * border-right %Bool; "yes"
727 * border-bottom %Bool; "yes"
728 * >
729 */
730 border_left = true;
731 border_top = true;
732 border_right = true;
733 border_bottom = true;
734
735 x1 = parseRequiredAttribute<ECOORD>( aFrameNode, "x1" );
736 y1 = parseRequiredAttribute<ECOORD>( aFrameNode, "y1" );
737 x2 = parseRequiredAttribute<ECOORD>( aFrameNode, "x2" );
738 y2 = parseRequiredAttribute<ECOORD>( aFrameNode, "y2" );
739 columns = parseRequiredAttribute<int>( aFrameNode, "columns" );
740 rows = parseRequiredAttribute<int>( aFrameNode, "rows" );
741 layer = parseRequiredAttribute<int>( aFrameNode, "layer" );
742 border_left = parseOptionalAttribute<bool>( aFrameNode, "border-left" );
743 border_top = parseOptionalAttribute<bool>( aFrameNode, "border-top" );
744 border_right = parseOptionalAttribute<bool>( aFrameNode, "border-right" );
745 border_bottom = parseOptionalAttribute<bool>( aFrameNode, "border-bottom" );
746}
747
748
749EPAD_COMMON::EPAD_COMMON( wxXmlNode* aPad )
750{
751 // #REQUIRED says DTD, throw exception if not found
752 name = parseRequiredAttribute<wxString>( aPad, "name" );
753 x = parseRequiredAttribute<ECOORD>( aPad, "x" );
754 y = parseRequiredAttribute<ECOORD>( aPad, "y" );
755 rot = parseOptionalAttribute<EROT>( aPad, "rot" );
756 stop = parseOptionalAttribute<bool>( aPad, "stop" );
757 thermals = parseOptionalAttribute<bool>( aPad, "thermals" );
758}
759
760
761EPAD::EPAD( wxXmlNode* aPad )
762 : EPAD_COMMON( aPad )
763{
764 /*
765 <!ELEMENT pad EMPTY>
766 <!ATTLIST pad
767 name %String; #REQUIRED
768 x %Coord; #REQUIRED
769 y %Coord; #REQUIRED
770 drill %Dimension; #REQUIRED
771 diameter %Dimension; "0"
772 shape %PadShape; "round"
773 rot %Rotation; "R0"
774 stop %Bool; "yes"
775 thermals %Bool; "yes"
776 first %Bool; "no"
777 >
778 */
779
780 // #REQUIRED says DTD, throw exception if not found
781 drill = parseRequiredAttribute<ECOORD>( aPad, "drill" );
782
783 // Optional attributes
784 diameter = parseOptionalAttribute<ECOORD>( aPad, "diameter" );
785
786 opt_wxString s = parseOptionalAttribute<wxString>( aPad, "shape" );
787
788 // (square | round | octagon | long | offset)
789 if( s == "square" )
791 else if( s == "round" )
793 else if( s == "octagon" )
795 else if( s == "long" )
797 else if( s == "offset" )
799
800 first = parseOptionalAttribute<bool>( aPad, "first" );
801}
802
803
804ESMD::ESMD( wxXmlNode* aSMD )
805 : EPAD_COMMON( aSMD )
806{
807 /*
808 <!ATTLIST smd
809 name %String; #REQUIRED
810 x %Coord; #REQUIRED
811 y %Coord; #REQUIRED
812 dx %Dimension; #REQUIRED
813 dy %Dimension; #REQUIRED
814 layer %Layer; #REQUIRED
815 roundness %Int; "0"
816 rot %Rotation; "R0"
817 stop %Bool; "yes"
818 thermals %Bool; "yes"
819 cream %Bool; "yes"
820 >
821 */
822
823 // DTD #REQUIRED, throw exception if not found
824 dx = parseRequiredAttribute<ECOORD>( aSMD, "dx" );
825 dy = parseRequiredAttribute<ECOORD>( aSMD, "dy" );
826 layer = parseRequiredAttribute<int>( aSMD, "layer" );
827
828 roundness = parseOptionalAttribute<int>( aSMD, "roundness" );
829 cream = parseOptionalAttribute<bool>( aSMD, "cream" );
830}
831
832
833EPIN::EPIN( wxXmlNode* aPin )
834{
835 /*
836 <!ELEMENT pin EMPTY>
837 <!ATTLIST pin
838 name %String; #REQUIRED
839 x %Coord; #REQUIRED
840 y %Coord; #REQUIRED
841 visible %PinVisible; "both"
842 length %PinLength; "long"
843 direction %PinDirection; "io"
844 function %PinFunction; "none"
845 swaplevel %Int; "0"
846 rot %Rotation; "R0"
847 >
848 */
849
850 // DTD #REQUIRED, throw exception if not found
851 name = parseRequiredAttribute<wxString>( aPin, "name" );
852 x = parseRequiredAttribute<ECOORD>( aPin, "x" );
853 y = parseRequiredAttribute<ECOORD>( aPin, "y" );
854
855 visible = parseOptionalAttribute<wxString>( aPin, "visible" );
856 length = parseOptionalAttribute<wxString>( aPin, "length" );
857 direction = parseOptionalAttribute<wxString>( aPin, "direction" );
858 function = parseOptionalAttribute<wxString>( aPin, "function" );
859 swaplevel = parseOptionalAttribute<int>( aPin, "swaplevel" );
860 rot = parseOptionalAttribute<EROT>( aPin, "rot" );
861}
862
863
864EVERTEX::EVERTEX( wxXmlNode* aVertex )
865{
866 /*
867 <!ELEMENT vertex EMPTY>
868 <!ATTLIST vertex
869 x %Coord; #REQUIRED
870 y %Coord; #REQUIRED
871 curve %WireCurve; "0" -- the curvature from this vertex to the next one --
872 >
873 */
874
875 x = parseRequiredAttribute<ECOORD>( aVertex, "x" );
876 y = parseRequiredAttribute<ECOORD>( aVertex, "y" );
877 curve = parseOptionalAttribute<double>( aVertex, "curve" );
878}
879
880
881EPOLYGON::EPOLYGON( wxXmlNode* aPolygon )
882{
883 /*
884 <!ATTLIST polygon
885 width %Dimension; #REQUIRED
886 layer %Layer; #REQUIRED
887 spacing %Dimension; #IMPLIED
888 pour %PolygonPour; "solid"
889 isolate %Dimension; #IMPLIED -- only in <signal> or <package> context --
890 orphans %Bool; "no" -- only in <signal> context --
891 thermals %Bool; "yes" -- only in <signal> context --
892 rank %Int; "0" -- 1..6 in <signal> context, 0 or 7 in
893 <package> context --
894 >
895 */
896
897 width = parseRequiredAttribute<ECOORD>( aPolygon, "width" );
898 layer = parseRequiredAttribute<int>( aPolygon, "layer" );
899
900 spacing = parseOptionalAttribute<ECOORD>( aPolygon, "spacing" );
901 isolate = parseOptionalAttribute<ECOORD>( aPolygon, "isolate" );
902 opt_wxString s = parseOptionalAttribute<wxString>( aPolygon, "pour" );
903
904 // default pour to solid fill
906
907 // (solid | hatch | cutout)
908 if( s == "hatch" )
910 else if( s == "cutout" )
912
913 orphans = parseOptionalAttribute<bool>( aPolygon, "orphans" );
914 thermals = parseOptionalAttribute<bool>( aPolygon, "thermals" );
915 rank = parseOptionalAttribute<int>( aPolygon, "rank" );
916}
917
918
919EHOLE::EHOLE( wxXmlNode* aHole )
920{
921 /*
922 <!ELEMENT hole EMPTY>
923 <!ATTLIST hole
924 x %Coord; #REQUIRED
925 y %Coord; #REQUIRED
926 drill %Dimension; #REQUIRED
927 >
928 */
929
930 // #REQUIRED:
931 x = parseRequiredAttribute<ECOORD>( aHole, "x" );
932 y = parseRequiredAttribute<ECOORD>( aHole, "y" );
933 drill = parseRequiredAttribute<ECOORD>( aHole, "drill" );
934}
935
936
937EELEMENT::EELEMENT( wxXmlNode* aElement )
938{
939 /*
940 <!ELEMENT element (attribute*, variant*)>
941 <!ATTLIST element
942 name %String; #REQUIRED
943 library %String; #REQUIRED
944 package %String; #REQUIRED
945 value %String; #REQUIRED
946 x %Coord; #REQUIRED
947 y %Coord; #REQUIRED
948 locked %Bool; "no"
949 smashed %Bool; "no"
950 rot %Rotation; "R0"
951 >
952 */
953
954 // #REQUIRED
955 name = parseRequiredAttribute<wxString>( aElement, "name" );
956 library = parseRequiredAttribute<wxString>( aElement, "library" );
957 value = parseRequiredAttribute<wxString>( aElement, "value" );
958 std::string p = parseRequiredAttribute<std::string>( aElement, "package" );
960 package = wxString::FromUTF8( p.c_str() );
961
962 x = parseRequiredAttribute<ECOORD>( aElement, "x" );
963 y = parseRequiredAttribute<ECOORD>( aElement, "y" );
964
965 // optional
966 locked = parseOptionalAttribute<bool>( aElement, "locked" );
967 smashed = parseOptionalAttribute<bool>( aElement, "smashed" );
968 rot = parseOptionalAttribute<EROT>( aElement, "rot" );
969}
970
971
972ELAYER::ELAYER( wxXmlNode* aLayer )
973{
974 /*
975 <!ELEMENT layer EMPTY>
976 <!ATTLIST layer
977 number %Layer; #REQUIRED
978 name %String; #REQUIRED
979 color %Int; #REQUIRED
980 fill %Int; #REQUIRED
981 visible %Bool; "yes"
982 active %Bool; "yes"
983 >
984 */
985
986 number = parseRequiredAttribute<int>( aLayer, "number" );
987 name = parseRequiredAttribute<wxString>( aLayer, "name" );
988 color = parseRequiredAttribute<int>( aLayer, "color" );
989 fill = 1; // Temporary value.
990 visible = parseOptionalAttribute<bool>( aLayer, "visible" );
991 active = parseOptionalAttribute<bool>( aLayer, "active" );
992}
993
994
995EPART::EPART( wxXmlNode* aPart )
996{
997 /*
998 * <!ELEMENT part (attribute*, variant*)>
999 * <!ATTLIST part
1000 * name %String; #REQUIRED
1001 * library %String; #REQUIRED
1002 * deviceset %String; #REQUIRED
1003 * device %String; #REQUIRED
1004 * technology %String; ""
1005 * value %String; #IMPLIED
1006 * >
1007 */
1008 // #REQUIRED
1009 name = parseRequiredAttribute<wxString>( aPart, "name" );
1010 library = parseRequiredAttribute<wxString>( aPart, "library" );
1011 deviceset = parseRequiredAttribute<wxString>( aPart, "deviceset" );
1012 device = parseRequiredAttribute<wxString>( aPart, "device" );
1013 technology = parseOptionalAttribute<wxString>( aPart, "technology" );
1014 value = parseOptionalAttribute<wxString>( aPart, "value" );
1015
1016 for( wxXmlNode* child = aPart->GetChildren(); child; child = child->GetNext() )
1017 {
1018 if( child->GetName() == "attribute" )
1019 {
1020 std::string aname, avalue;
1021
1022 for( wxXmlAttribute* x = child->GetAttributes(); x; x = x->GetNext() )
1023 {
1024 if( x->GetName() == "name" )
1025 aname = x->GetValue();
1026 else if( x->GetName() == "value" )
1027 avalue = x->GetValue();
1028 }
1029
1030 if( aname.size() && avalue.size() )
1031 attribute[aname] = avalue;
1032 }
1033 else if( child->GetName() == "variant" )
1034 {
1035 std::string aname, avalue;
1036
1037 for( wxXmlAttribute* x = child->GetAttributes(); x; x = x->GetNext() )
1038 {
1039 if( x->GetName() == "name" )
1040 aname = x->GetValue();
1041 else if( x->GetName() == "value" )
1042 avalue = x->GetValue();
1043 }
1044
1045 if( aname.size() && avalue.size() )
1046 variant[aname] = avalue;
1047 }
1048 }
1049}
1050
1051
1052EINSTANCE::EINSTANCE( wxXmlNode* aInstance )
1053{
1054 /*
1055 * <!ELEMENT instance (attribute)*>
1056 * <!ATTLIST instance
1057 * part %String; #REQUIRED
1058 * gate %String; #REQUIRED
1059 * x %Coord; #REQUIRED
1060 * y %Coord; #REQUIRED
1061 * smashed %Bool; "no"
1062 * rot %Rotation; "R0"
1063 * >
1064 */
1065 part = parseRequiredAttribute<wxString>( aInstance, "part" );
1066 gate = parseRequiredAttribute<wxString>( aInstance, "gate" );
1067
1068 x = parseRequiredAttribute<ECOORD>( aInstance, "x" );
1069 y = parseRequiredAttribute<ECOORD>( aInstance, "y" );
1070
1071 // optional
1072 smashed = parseOptionalAttribute<bool>( aInstance, "smashed" );
1073 rot = parseOptionalAttribute<EROT>( aInstance, "rot" );
1074}
1075
1076
1077EGATE::EGATE( wxXmlNode* aGate )
1078{
1079 /*
1080 * <!ELEMENT gate EMPTY>
1081 * <!ATTLIST gate
1082 * name %String; #REQUIRED
1083 * symbol %String; #REQUIRED
1084 * x %Coord; #REQUIRED
1085 * y %Coord; #REQUIRED
1086 * addlevel %GateAddLevel; "next"
1087 * swaplevel %Int; "0"
1088 * >
1089 */
1090
1091 name = parseRequiredAttribute<wxString>( aGate, "name" );
1092 symbol = parseRequiredAttribute<wxString>( aGate, "symbol" );
1093
1094 x = parseRequiredAttribute<ECOORD>( aGate, "x" );
1095 y = parseRequiredAttribute<ECOORD>( aGate, "y" );
1096
1097 opt_wxString stemp = parseOptionalAttribute<wxString>( aGate, "addlevel" );
1098
1099 // (off | value | name | both)
1100 if( stemp == "must" )
1101 addlevel = EGATE::MUST;
1102 else if( stemp == "can" )
1103 addlevel = EGATE::CAN;
1104 else if( stemp == "next" )
1105 addlevel = EGATE::NEXT;
1106 else if( stemp == "request" )
1107 addlevel = EGATE::REQUEST;
1108 else if( stemp == "always" )
1109 addlevel = EGATE::ALWAYS;
1110 else
1111 addlevel = EGATE::NEXT;
1112}
1113
1114
1115ECONNECT::ECONNECT( wxXmlNode* aConnect )
1116{
1117 /*
1118 * <!ELEMENT connect EMPTY>
1119 * <!ATTLIST connect
1120 * gate %String; #REQUIRED
1121 * pin %String; #REQUIRED
1122 * pad %String; #REQUIRED
1123 * route %ContactRoute; "all"
1124 * >
1125 */
1126 gate = parseRequiredAttribute<wxString>( aConnect, "gate" );
1127 pin = parseRequiredAttribute<wxString>( aConnect, "pin" );
1128 pad = parseRequiredAttribute<wxString>( aConnect, "pad" );
1129}
1130
1131
1132EDEVICE::EDEVICE( wxXmlNode* aDevice )
1133{
1134 /*
1135 <!ELEMENT device (connects?, technologies?)>
1136 <!ATTLIST device
1137 name %String; ""
1138 package %String; #IMPLIED
1139 >
1140 */
1141 name = parseRequiredAttribute<wxString>( aDevice, "name" );
1142 opt_wxString pack = parseOptionalAttribute<wxString>( aDevice, "package" );
1143
1144 if( pack )
1145 {
1146 std::string p( pack->c_str() );
1147 ReplaceIllegalFileNameChars( &p, '_' );
1148 package.Set( wxString::FromUTF8( p.c_str() ) );
1149 }
1150
1151 NODE_MAP aDeviceChildren = MapChildren( aDevice );
1152 wxXmlNode* connectNode = getChildrenNodes( aDeviceChildren, "connects" );
1153
1154 while( connectNode )
1155 {
1156 connects.emplace_back( connectNode );
1157 connectNode = connectNode->GetNext();
1158 }
1159}
1160
1161
1162EDEVICE_SET::EDEVICE_SET( wxXmlNode* aDeviceSet )
1163{
1164 /*
1165 <!ELEMENT deviceset (description?, gates, devices)>
1166 <!ATTLIST deviceset
1167 name %String; #REQUIRED
1168 prefix %String; ""
1169 uservalue %Bool; "no"
1170 >
1171 */
1172
1173 name = parseRequiredAttribute<wxString>( aDeviceSet, "name" );
1174 prefix = parseOptionalAttribute<wxString>( aDeviceSet, "prefix" );
1175 uservalue = parseOptionalAttribute<bool>( aDeviceSet, "uservalue" );
1176}
1177
1178
1179ECLASS::ECLASS( wxXmlNode* aClass )
1180{
1181 number = parseRequiredAttribute<wxString>( aClass, "number" );
1182 name = parseRequiredAttribute<wxString>( aClass, "name" );
1183
1184 for( wxXmlNode* child = aClass->GetChildren(); child; child = child->GetNext() )
1185 {
1186 if( child->GetName() == "clearance" )
1187 {
1188 wxString to = parseRequiredAttribute<wxString>( child, "class" );
1189 ECOORD value = parseRequiredAttribute<ECOORD>( child, "value" );
1190
1191 clearanceMap[to] = value;
1192 }
1193 }
1194}
int color
Definition: DXF_plotter.cpp:57
Model an optional XML attribute.
Definition: eagle_parser.h:195
bool m_isAvailable
A boolean indicating if the data is present or not.
Definition: eagle_parser.h:198
const T & CGet() const
Return a constant reference to the value of the attribute assuming it is available.
Definition: eagle_parser.h:309
void Set(const wxString &aString)
Attempt to convert a string to the base type.
Definition: eagle_parser.h:287
OPTIONAL_XML_ATTRIBUTE()
Construct a default OPTIONAL_XML_ATTRIBUTE, whose data is not available.
Definition: eagle_parser.h:207
static int parseAlignment(const wxString &aAlignment)
NODE_MAP MapChildren(wxXmlNode *aCurrentNode)
Provide an easy access to the children of an XML node via their names.
double Convert< double >(const wxString &aValue)
wxString escapeName(const wxString &aNetName)
Interprets special characters in Eagle text and converts them to KiCAD notation.
wxString interpretText(const wxString &aText)
Translates Eagle special text reference to a KiCad variable reference.
bool substituteVariable(wxString *aText)
constexpr auto DEFAULT_ALIGNMENT
int Convert< int >(const wxString &aValue)
wxString Convert< wxString >(const wxString &aValue)
EROT Convert< EROT >(const wxString &aRot)
parse an Eagle XML "rot" field.
T parseRequiredAttribute(wxXmlNode *aNode, const wxString &aAttribute)
Parse aAttribute of the XML node aNode.
bool Convert< bool >(const wxString &aValue)
ECOORD Convert< ECOORD >(const wxString &aCoord)
OPTIONAL_XML_ATTRIBUTE< T > parseOptionalAttribute(wxXmlNode *aNode, const wxString &aAttribute)
Parse option aAttribute of the XML node aNode.
VECTOR2I ConvertArcCenter(const VECTOR2I &aStart, const VECTOR2I &aEnd, double aAngle)
static wxXmlNode * getChildrenNodes(NODE_MAP &aMap, const wxString &aName)
Definition: eagle_parser.h:63
std::unordered_map< wxString, wxXmlNode * > NODE_MAP
Definition: eagle_parser.h:49
#define _(s)
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:38
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
wxString ConvertToNewOverbarNotation(const wxString &aOldStr)
Convert the old ~...~ overbar notation to the new ~{...} one.
bool ReplaceIllegalFileNameChars(std::string *aName, int aReplaceChar)
Checks aName for illegal file name characters.
opt_double ratio
Definition: eagle_parser.h:606
opt_wxString value
Definition: eagle_parser.h:601
opt_ecoord size
Definition: eagle_parser.h:604
opt_ecoord y
Definition: eagle_parser.h:603
wxString name
Definition: eagle_parser.h:600
opt_erot rot
Definition: eagle_parser.h:607
opt_int align
Definition: eagle_parser.h:616
opt_int display
Definition: eagle_parser.h:615
opt_ecoord x
Definition: eagle_parser.h:602
opt_int layer
Definition: eagle_parser.h:605
ECOORD x
Definition: eagle_parser.h:568
ECOORD radius
Definition: eagle_parser.h:570
ECOORD y
Definition: eagle_parser.h:569
ECIRCLE(wxXmlNode *aCircle)
ECOORD width
Definition: eagle_parser.h:571
ECLASS(wxXmlNode *aClass)
ECONNECT(wxXmlNode *aConnect)
@ EU_NM
nanometers
Definition: eagle_parser.h:391
@ EU_MM
millimeters
Definition: eagle_parser.h:392
@ EU_MIL
mils/thous
Definition: eagle_parser.h:394
@ EU_INCH
inches
Definition: eagle_parser.h:393
int ToSchUnits() const
Definition: eagle_parser.h:435
long long int value
Unit used for the value field.
Definition: eagle_parser.h:398
static long long int ConvertToNm(int aValue, enum EAGLE_UNIT aUnit)
EDEVICE_SET(wxXmlNode *aDeviceSet)
EDEVICE(wxXmlNode *aDevice)
EDIMENSION(wxXmlNode *aDimension)
opt_wxString dimensionType
Definition: eagle_parser.h:634
opt_ecoord textsize
Definition: eagle_parser.h:632
opt_erot rot
Definition: eagle_parser.h:824
wxString name
Definition: eagle_parser.h:816
wxString library
Definition: eagle_parser.h:817
wxString package
Definition: eagle_parser.h:818
ECOORD y
Definition: eagle_parser.h:821
EELEMENT(wxXmlNode *aElement)
opt_bool smashed
Definition: eagle_parser.h:823
ECOORD x
Definition: eagle_parser.h:820
wxString value
Definition: eagle_parser.h:819
opt_bool locked
Definition: eagle_parser.h:822
ECOORD x1
Definition: eagle_parser.h:680
EFRAME(wxXmlNode *aFrameNode)
opt_bool border_bottom
Definition: eagle_parser.h:690
opt_bool border_left
Definition: eagle_parser.h:687
opt_bool border_right
Definition: eagle_parser.h:689
ECOORD y1
Definition: eagle_parser.h:681
int layer
Definition: eagle_parser.h:686
opt_bool border_top
Definition: eagle_parser.h:688
int columns
Definition: eagle_parser.h:684
ECOORD y2
Definition: eagle_parser.h:683
int rows
Definition: eagle_parser.h:685
ECOORD x2
Definition: eagle_parser.h:682
EGATE(wxXmlNode *aGate)
ECOORD y
Definition: eagle_parser.h:806
EHOLE(wxXmlNode *aHole)
ECOORD drill
Definition: eagle_parser.h:807
ECOORD x
Definition: eagle_parser.h:805
EINSTANCE(wxXmlNode *aInstance)
ECOORD y
Definition: eagle_parser.h:529
ECOORD x
Definition: eagle_parser.h:528
EJUNCTION(wxXmlNode *aJunction)
opt_erot rot
Definition: eagle_parser.h:542
ECOORD size
Definition: eagle_parser.h:540
wxString netname
Definition: eagle_parser.h:544
opt_wxString xref
Definition: eagle_parser.h:543
int layer
Definition: eagle_parser.h:541
ECOORD y
Definition: eagle_parser.h:539
ECOORD x
Definition: eagle_parser.h:538
ELABEL(wxXmlNode *aLabel, const wxString &aNetName)
ELAYER(wxXmlNode *aLayer)
Structure holding common properties for through-hole and SMD pads.
Definition: eagle_parser.h:698
opt_bool thermals
Definition: eagle_parser.h:703
EPAD_COMMON(wxXmlNode *aPad)
opt_bool stop
Definition: eagle_parser.h:702
wxString name
Definition: eagle_parser.h:699
opt_erot rot
Definition: eagle_parser.h:701
ECOORD drill
Definition: eagle_parser.h:712
opt_ecoord diameter
Definition: eagle_parser.h:713
opt_bool first
Definition: eagle_parser.h:725
EPAD(wxXmlNode *aPad)
@ OCTAGON
Definition: eagle_parser.h:720
@ SQUARE
Definition: eagle_parser.h:718
@ OFFSET
Definition: eagle_parser.h:722
opt_int shape
Definition: eagle_parser.h:724
EPART(wxXmlNode *aPart)
ECOORD x
Definition: eagle_parser.h:748
wxString name
Definition: eagle_parser.h:747
opt_int swaplevel
Definition: eagle_parser.h:755
opt_wxString visible
Definition: eagle_parser.h:751
opt_wxString direction
Definition: eagle_parser.h:753
opt_wxString length
Definition: eagle_parser.h:752
opt_wxString function
Definition: eagle_parser.h:754
EPIN(wxXmlNode *aPin)
opt_erot rot
Definition: eagle_parser.h:756
ECOORD y
Definition: eagle_parser.h:749
opt_bool orphans
Definition: eagle_parser.h:794
opt_int rank
Definition: eagle_parser.h:796
opt_bool thermals
Definition: eagle_parser.h:795
opt_ecoord spacing
Definition: eagle_parser.h:778
ECOORD width
Definition: eagle_parser.h:776
EPOLYGON(wxXmlNode *aPolygon)
opt_ecoord isolate
Definition: eagle_parser.h:793
ECOORD x2
Definition: eagle_parser.h:583
ERECT(wxXmlNode *aRect)
ECOORD y1
Definition: eagle_parser.h:582
opt_erot rot
Definition: eagle_parser.h:586
int layer
Definition: eagle_parser.h:585
ECOORD y2
Definition: eagle_parser.h:584
ECOORD x1
Definition: eagle_parser.h:581
Eagle rotation.
Definition: eagle_parser.h:477
double degrees
Definition: eagle_parser.h:480
bool spin
Definition: eagle_parser.h:479
bool mirror
Definition: eagle_parser.h:478
opt_int roundness
Definition: eagle_parser.h:737
ESMD(wxXmlNode *aSMD)
ECOORD dx
Definition: eagle_parser.h:734
int layer
Definition: eagle_parser.h:736
opt_bool cream
Definition: eagle_parser.h:738
ECOORD dy
Definition: eagle_parser.h:735
opt_double ratio
Definition: eagle_parser.h:649
wxString text
Definition: eagle_parser.h:643
@ BOTTOM_CENTER
Definition: eagle_parser.h:661
@ BOTTOM_RIGHT
Definition: eagle_parser.h:663
@ TOP_CENTER
Definition: eagle_parser.h:655
@ TOP_LEFT
Definition: eagle_parser.h:656
@ TOP_RIGHT
Definition: eagle_parser.h:657
@ CENTER_RIGHT
Definition: eagle_parser.h:660
@ CENTER_LEFT
Definition: eagle_parser.h:654
@ BOTTOM_LEFT
Definition: eagle_parser.h:662
ECOORD y
Definition: eagle_parser.h:645
ECOORD size
Definition: eagle_parser.h:646
opt_erot rot
Definition: eagle_parser.h:650
opt_int align
Definition: eagle_parser.h:666
ETEXT(wxXmlNode *aText)
wxSize ConvertSize() const
Calculate text size based on font type and size.
ECOORD x
Definition: eagle_parser.h:644
opt_wxString font
Definition: eagle_parser.h:648
int layer
Definition: eagle_parser.h:647
EVERTEX(wxXmlNode *aVertex)
ECOORD y
Definition: eagle_parser.h:766
ECOORD x
Definition: eagle_parser.h:765
opt_double curve
range is -359.9..359.9
Definition: eagle_parser.h:767
opt_ecoord diam
Definition: eagle_parser.h:558
ECOORD drill
< inclusive
Definition: eagle_parser.h:557
ECOORD y
Definition: eagle_parser.h:554
EVIA(wxXmlNode *aVia)
opt_wxString shape
Definition: eagle_parser.h:559
int layer_front_most
Definition: eagle_parser.h:555
int layer_back_most
< extent
Definition: eagle_parser.h:556
ECOORD x
Definition: eagle_parser.h:553
ECOORD width
Definition: eagle_parser.h:503
int layer
Definition: eagle_parser.h:504
@ LONGDASH
Definition: eagle_parser.h:508
@ CONTINUOUS
Definition: eagle_parser.h:507
@ SHORTDASH
Definition: eagle_parser.h:509
ECOORD x2
Definition: eagle_parser.h:501
opt_int cap
Definition: eagle_parser.h:519
opt_int style
Definition: eagle_parser.h:512
ECOORD y2
Definition: eagle_parser.h:502
ECOORD x1
Definition: eagle_parser.h:499
ECOORD y1
Definition: eagle_parser.h:500
EWIRE(wxXmlNode *aWire)
opt_double curve
range is -359.9..359.9
Definition: eagle_parser.h:513
Implement a simple wrapper around runtime_error to isolate the errors thrown by the Eagle XML parser.
Definition: eagle_parser.h:75
double DEG2RAD(double deg)
Definition: trigo.h:195