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