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