Commit Dick's Pcbnew s-expression file parser bug fixes.

* Apply Dick's patch along with a few minor changes to fix some clashes with
  changes in my branch.  Thanks Dick!
* Added missing DRAWSEGMENT line angle.
* Fix thru hole pad layer mask issue.
This commit is contained in:
Dick Hollenbeck 2012-06-10 20:47:15 -04:00 committed by Wayne Stambaugh
parent d3f9554841
commit a71857baaa
9 changed files with 3232 additions and 3127 deletions

View File

@ -70,11 +70,11 @@ else (KICAD_STABLE_VERSION )
endif(KICAD_STABLE_VERSION ) endif(KICAD_STABLE_VERSION )
# Nanometers must be enabled when USE_PCBNEW_SEXPR_FILE_FORMAT=ON. # Nanometers must be enabled when USE_PCBNEW_SEXPR_FILE_FORMAT=ON.
if( USE_PCBNEW_SEXPR_FILE_FORMAT AND NOT USE_PCBNEW_NANOMETRES ) #if( USE_PCBNEW_SEXPR_FILE_FORMAT AND NOT USE_PCBNEW_NANOMETRES )
set( TMP "The Pcbnew s-expression file format requires nano-meter internal units to be " ) # set( TMP "The Pcbnew s-expression file format requires nano-meter internal units to be " )
set( TMP "${TMP} enabled using -DUSE_PCBNEW_NANOMETRES=ON." ) # set( TMP "${TMP} enabled using -DUSE_PCBNEW_NANOMETRES=ON." )
message( FATAL_ERROR ${TMP} ) # message( FATAL_ERROR ${TMP} )
endif( USE_PCBNEW_SEXPR_FILE_FORMAT AND NOT USE_PCBNEW_NANOMETRES ) #endif( USE_PCBNEW_SEXPR_FILE_FORMAT AND NOT USE_PCBNEW_NANOMETRES )
#================================================ #================================================
# Set flags for GCC. # Set flags for GCC.

View File

@ -358,7 +358,7 @@ void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl
FMT_IU( m_Size.GetWidth() ).c_str() ); FMT_IU( m_Size.GetWidth() ).c_str() );
if( m_Thickness != 0 ) if( m_Thickness != 0 )
aFormatter->Print( 0, " (thickness %s)", FMT_IU( m_Thickness ).c_str() ); aFormatter->Print( 0, " (thickness %s)", FMT_IU( GetThickness() ).c_str() );
if( m_Bold ) if( m_Bold )
aFormatter->Print( 0, " bold" ); aFormatter->Print( 0, " bold" );

View File

@ -120,6 +120,7 @@ page
path path
pcb_text_size pcb_text_size
pcb_text_width pcb_text_width
pcbplotparams
placed placed
plus plus
polygon polygon

View File

@ -93,13 +93,23 @@ std::string BOARD_ITEM::FormatInternalUnits( int aValue )
{ {
char buf[50]; char buf[50];
#if defined( USE_PCBNEW_NANOMETRES ) double mm = aValue / IU_PER_MM;
int nm = aValue;
#else
int nm = KIROUND( ( aValue / 10000.0 ) * 25.4 * 1e6 );
#endif
int len = snprintf( buf, 49, "%g", nm / 1e6 ); int len;
if( mm != 0.0 && fabs( mm ) <= 0.0001 )
{
len = sprintf( buf, "%.10f", mm );
while( --len > 0 && buf[len] == '0' )
buf[len] = '\0';
++len;
}
else
{
len = sprintf( buf, "%.10g", mm );
}
return std::string( buf, len ); return std::string( buf, len );
} }

View File

@ -209,6 +209,7 @@ public:
const wxString& GetNetName() const { return m_Netname; }; const wxString& GetNetName() const { return m_Netname; };
void SetNetName( const wxString& aName ) { m_Netname = aName; } void SetNetName( const wxString& aName ) { m_Netname = aName; }
/// How to fill areas: 0 = use filled polygons, 1 => fill with segments.
void SetFillMode( int aFillMode ) { m_FillMode = aFillMode; } void SetFillMode( int aFillMode ) { m_FillMode = aFillMode; }
int GetFillMode() const { return m_FillMode; } int GetFillMode() const { return m_FillMode; }
@ -550,7 +551,7 @@ public:
int m_ZoneClearance; // clearance value int m_ZoneClearance; // clearance value
int m_ZoneMinThickness; // Min thickness value in filled areas int m_ZoneMinThickness; // Min thickness value in filled areas
// How to fill areas: 0 = use filled polygons, != 0 fill with segments. /// How to fill areas: 0 => use filled polygons, 1 => fill with segments.
int m_FillMode; int m_FillMode;
// number of segments to convert a circle to a polygon (uses // number of segments to convert a circle to a polygon (uses

View File

@ -39,6 +39,7 @@
#include <class_drawsegment.h> #include <class_drawsegment.h>
#include <class_mire.h> #include <class_mire.h>
#include <class_edge_mod.h> #include <class_edge_mod.h>
#include <pcb_plot_params.h>
#include <zones.h> #include <zones.h>
#include <kicad_plugin.h> #include <kicad_plugin.h>
#include <pcb_parser.h> #include <pcb_parser.h>
@ -324,6 +325,8 @@ void PCB_IO::format( BOARD* aBoard, int aNestLevel ) const
m_out->Print( aNestLevel+1, "(visible_elements %X)\n", m_out->Print( aNestLevel+1, "(visible_elements %X)\n",
aBoard->GetDesignSettings().GetVisibleElements() ); aBoard->GetDesignSettings().GetVisibleElements() );
// aBoard->GetPlotOptions().Format( m_out, aNestLevel+1 );
m_out->Print( aNestLevel, ")\n\n" ); m_out->Print( aNestLevel, ")\n\n" );
@ -448,9 +451,10 @@ void PCB_IO::format( DRAWSEGMENT* aSegment, int aNestLevel ) const
switch( aSegment->GetShape() ) switch( aSegment->GetShape() )
{ {
case S_SEGMENT: // Line case S_SEGMENT: // Line
m_out->Print( aNestLevel, "(gr_line (pts (xy %s) (xy %s))", m_out->Print( aNestLevel, "(gr_line (pts (xy %s) (xy %s)) (angle %s)",
FMT_IU( aSegment->GetStart() ).c_str(), FMT_IU( aSegment->GetStart() ).c_str(),
FMT_IU( aSegment->GetEnd() ).c_str() ); FMT_IU( aSegment->GetEnd() ).c_str(),
FMT_ANGLE( aSegment->GetAngle() ).c_str() );
break; break;
case S_CIRCLE: // Circle case S_CIRCLE: // Circle
@ -863,11 +867,17 @@ void PCB_IO::format( TEXTE_MODULE* aText, int aNestLevel ) const
if( parent ) if( parent )
orient += parent->GetOrientation(); orient += parent->GetOrientation();
m_out->Print( aNestLevel, "(fp_text %s %s (at %s %s)%s\n", m_out->Print( aNestLevel, "(fp_text %s %s (at %s %s)",
m_out->Quotew( type ).c_str(), m_out->Quotew( type ).c_str(),
m_out->Quotew( aText->GetText() ).c_str(), m_out->Quotew( aText->GetText() ).c_str(),
FMT_IU( aText->GetPos0() ).c_str(), FMT_ANGLE( orient ).c_str(), FMT_IU( aText->GetPos0() ).c_str(), FMT_ANGLE( orient ).c_str() );
(!aText->IsVisible()) ? " hide" : "" );
formatLayer( aText );
if( !aText->IsVisible() )
m_out->Print( 0, " hide" );
m_out->Print( 0, "\n" );
aText->EDA_TEXT::Format( m_out, aNestLevel, m_ctl ); aText->EDA_TEXT::Format( m_out, aNestLevel, m_ctl );

View File

@ -26,6 +26,7 @@
* @brief Pcbnew s-expression file format parser implementation. * @brief Pcbnew s-expression file format parser implementation.
*/ */
#include <errno.h>
#include <common.h> #include <common.h>
#include <macros.h> #include <macros.h>
#include <convert_from_iu.h> #include <convert_from_iu.h>
@ -42,6 +43,7 @@
#include <class_pad.h> #include <class_pad.h>
#include <class_track.h> #include <class_track.h>
#include <class_zone.h> #include <class_zone.h>
#include <pcb_plot_params.h>
#include <zones.h> #include <zones.h>
#include <pcb_parser.h> #include <pcb_parser.h>
@ -333,7 +335,10 @@ BOARD* PCB_PARSER::parseBOARD() throw( IO_ERROR, PARSE_ERROR )
for( token = NextTok(); token != T_RIGHT; token = NextTok() ) for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{ {
if( token != T_LEFT ) if( token != T_LEFT )
{
wxLogDebug( "Expect ( in parseBoard() after %s.", PrevTok() );
Expecting( T_LEFT ); Expecting( T_LEFT );
}
token = NextTok(); token = NextTok();
@ -372,27 +377,27 @@ BOARD* PCB_PARSER::parseBOARD() throw( IO_ERROR, PARSE_ERROR )
case T_gr_curve: case T_gr_curve:
case T_gr_line: case T_gr_line:
case T_gr_poly: case T_gr_poly:
parseDRAWSEGMENT(); m_board->Add( parseDRAWSEGMENT(), ADD_APPEND );
break; break;
case T_gr_text: case T_gr_text:
parseTEXTE_PCB(); m_board->Add( parseTEXTE_PCB(), ADD_APPEND );
break; break;
case T_dimension: case T_dimension:
parseDIMENSION(); m_board->Add( parseDIMENSION(), ADD_APPEND );
break; break;
case T_module: case T_module:
parseMODULE(); m_board->Add( parseMODULE(), ADD_APPEND );
break; break;
case T_segment: case T_segment:
m_board->Add( parseTRACK(), ADD_APPEND ); m_board->m_Track.Append( parseTRACK() );
break; break;
case T_via: case T_via:
m_board->Add( parseSEGVIA(), ADD_APPEND ); m_board->m_Track.Append( parseSEGVIA() );
break; break;
case T_zone: case T_zone:
@ -552,10 +557,15 @@ void PCB_PARSER::parseTITLE_BLOCK() throw( IO_ERROR, PARSE_ERROR )
break; break;
case T_rev: case T_rev:
NeedSYMBOL(); NextTok();
titleBlock.SetRevision( FromUTF8() ); titleBlock.SetRevision( FromUTF8() );
break; break;
case T_company:
NextTok();
titleBlock.SetCompany( FromUTF8() );
break;
case T_comment: case T_comment:
{ {
int commentNumber = NeedNUMBER( "comment" ); int commentNumber = NeedNUMBER( "comment" );
@ -563,22 +573,22 @@ void PCB_PARSER::parseTITLE_BLOCK() throw( IO_ERROR, PARSE_ERROR )
switch( commentNumber ) switch( commentNumber )
{ {
case 1: case 1:
NeedSYMBOL(); NextTok();
titleBlock.SetComment1( FromUTF8() ); titleBlock.SetComment1( FromUTF8() );
break; break;
case 2: case 2:
NeedSYMBOL(); NextTok();
titleBlock.SetComment2( FromUTF8() ); titleBlock.SetComment2( FromUTF8() );
break; break;
case 3: case 3:
NeedSYMBOL(); NextTok();
titleBlock.SetComment3( FromUTF8() ); titleBlock.SetComment3( FromUTF8() );
break; break;
case 4: case 4:
NeedSYMBOL(); NextTok();
titleBlock.SetComment4( FromUTF8() ); titleBlock.SetComment4( FromUTF8() );
break; break;
@ -796,7 +806,10 @@ void PCB_PARSER::parseSetup() throw( IO_ERROR, PARSE_ERROR )
for( token = NextTok(); token != T_RIGHT; token = NextTok() ) for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{ {
if( token != T_LEFT ) if( token != T_LEFT )
{
wxLogDebug( "Expected ( in parseSetup()." );
Expecting( T_LEFT ); Expecting( T_LEFT );
}
token = NextTok(); token = NextTok();
@ -804,50 +817,62 @@ void PCB_PARSER::parseSetup() throw( IO_ERROR, PARSE_ERROR )
{ {
case T_last_trace_width: case T_last_trace_width:
lastTraceWidth = parseBoardUnits( T_last_trace_width ); lastTraceWidth = parseBoardUnits( T_last_trace_width );
NeedRIGHT();
break; break;
case T_user_trace_width: case T_user_trace_width:
m_board->m_TrackWidthList.push_back( parseBoardUnits( T_user_trace_width ) ); m_board->m_TrackWidthList.push_back( parseBoardUnits( T_user_trace_width ) );
NeedRIGHT();
break; break;
case T_trace_clearance: case T_trace_clearance:
defaultNetclass->SetClearance( parseBoardUnits( T_trace_clearance ) ); defaultNetclass->SetClearance( parseBoardUnits( T_trace_clearance ) );
NeedRIGHT();
break; break;
case T_zone_clearance: case T_zone_clearance:
zoneSettings.m_ZoneClearance = parseBoardUnits( T_zone_clearance ); zoneSettings.m_ZoneClearance = parseBoardUnits( T_zone_clearance );
NeedRIGHT();
break; break;
case T_zone_45_only: case T_zone_45_only:
zoneSettings.m_Zone_45_Only = parseBool(); zoneSettings.m_Zone_45_Only = parseBool();
NeedRIGHT();
break; break;
case T_trace_min: case T_trace_min:
designSettings.m_TrackMinWidth = parseBoardUnits( T_trace_min ); designSettings.m_TrackMinWidth = parseBoardUnits( T_trace_min );
NeedRIGHT();
break; break;
case T_segment_width: case T_segment_width:
designSettings.m_DrawSegmentWidth = parseBoardUnits( T_segment_width ); designSettings.m_DrawSegmentWidth = parseBoardUnits( T_segment_width );
NeedRIGHT();
break; break;
case T_edge_width: case T_edge_width:
designSettings.m_EdgeSegmentWidth = parseBoardUnits( T_edge_width ); designSettings.m_EdgeSegmentWidth = parseBoardUnits( T_edge_width );
NeedRIGHT();
break; break;
case T_via_size: case T_via_size:
defaultNetclass->SetViaDiameter( parseBoardUnits( T_via_size ) ); defaultNetclass->SetViaDiameter( parseBoardUnits( T_via_size ) );
NeedRIGHT();
break; break;
case T_via_drill: case T_via_drill:
defaultNetclass->SetViaDrill( parseBoardUnits( T_via_drill ) ); defaultNetclass->SetViaDrill( parseBoardUnits( T_via_drill ) );
NeedRIGHT();
break; break;
case T_via_min_size: case T_via_min_size:
designSettings.m_ViasMinSize = parseBoardUnits( T_via_min_size ); designSettings.m_ViasMinSize = parseBoardUnits( T_via_min_size );
NeedRIGHT();
break; break;
case T_via_min_drill: case T_via_min_drill:
designSettings.m_ViasMinDrill = parseBoardUnits( T_via_min_drill ); designSettings.m_ViasMinDrill = parseBoardUnits( T_via_min_drill );
NeedRIGHT();
break; break;
case T_user_via: case T_user_via:
@ -855,57 +880,69 @@ void PCB_PARSER::parseSetup() throw( IO_ERROR, PARSE_ERROR )
int viaSize = parseBoardUnits( "user via size" ); int viaSize = parseBoardUnits( "user via size" );
int viaDrill = parseBoardUnits( "user via drill" ); int viaDrill = parseBoardUnits( "user via drill" );
m_board->m_ViasDimensionsList.push_back( VIA_DIMENSION( viaSize, viaDrill ) ); m_board->m_ViasDimensionsList.push_back( VIA_DIMENSION( viaSize, viaDrill ) );
NeedRIGHT();
} }
break; break;
case T_uvia_size: case T_uvia_size:
defaultNetclass->SetuViaDiameter( parseBoardUnits( T_uvia_size ) ); defaultNetclass->SetuViaDiameter( parseBoardUnits( T_uvia_size ) );
NeedRIGHT();
break; break;
case T_uvia_drill: case T_uvia_drill:
defaultNetclass->SetuViaDrill( parseBoardUnits( T_uvia_drill ) ); defaultNetclass->SetuViaDrill( parseBoardUnits( T_uvia_drill ) );
NeedRIGHT();
break; break;
case T_uvias_allowed: case T_uvias_allowed:
designSettings.m_MicroViasAllowed = parseBool(); designSettings.m_MicroViasAllowed = parseBool();
NeedRIGHT();
break; break;
case T_uvia_min_size: case T_uvia_min_size:
designSettings.m_MicroViasMinSize = parseBoardUnits( T_uvia_min_size ); designSettings.m_MicroViasMinSize = parseBoardUnits( T_uvia_min_size );
NeedRIGHT();
break; break;
case T_uvia_min_drill: case T_uvia_min_drill:
designSettings.m_MicroViasMinDrill = parseBoardUnits( T_uvia_min_drill ); designSettings.m_MicroViasMinDrill = parseBoardUnits( T_uvia_min_drill );
NeedRIGHT();
break; break;
case T_pcb_text_width: case T_pcb_text_width:
designSettings.m_PcbTextWidth = parseBoardUnits( T_pcb_text_width ); designSettings.m_PcbTextWidth = parseBoardUnits( T_pcb_text_width );
NeedRIGHT();
break; break;
case T_pcb_text_size: case T_pcb_text_size:
designSettings.m_PcbTextSize.x = parseBoardUnits( "pcb text width" ); designSettings.m_PcbTextSize.x = parseBoardUnits( "pcb text width" );
designSettings.m_PcbTextSize.y = parseBoardUnits( "pcb text height" ); designSettings.m_PcbTextSize.y = parseBoardUnits( "pcb text height" );
NeedRIGHT();
break; break;
case T_mod_edge_width: case T_mod_edge_width:
designSettings.m_ModuleSegmentWidth = parseBoardUnits( T_mod_edge_width ); designSettings.m_ModuleSegmentWidth = parseBoardUnits( T_mod_edge_width );
NeedRIGHT();
break; break;
case T_mod_text_size: case T_mod_text_size:
designSettings.m_ModuleTextSize.x = parseBoardUnits( "module text width" ); designSettings.m_ModuleTextSize.x = parseBoardUnits( "module text width" );
designSettings.m_ModuleTextSize.y = parseBoardUnits( "module text height" ); designSettings.m_ModuleTextSize.y = parseBoardUnits( "module text height" );
NeedRIGHT();
break; break;
case T_mod_text_width: case T_mod_text_width:
designSettings.m_ModuleTextWidth = parseBoardUnits( T_mod_text_width ); designSettings.m_ModuleTextWidth = parseBoardUnits( T_mod_text_width );
NeedRIGHT();
break; break;
case T_pad_size: case T_pad_size:
{ {
wxSize sz; wxSize sz;
sz.SetHeight( parseBoardUnits( "master pad height" ) );
sz.SetWidth( parseBoardUnits( "master pad width" ) ); sz.SetWidth( parseBoardUnits( "master pad width" ) );
sz.SetHeight( parseBoardUnits( "master pad height" ) );
designSettings.m_Pad_Master.SetSize( sz ); designSettings.m_Pad_Master.SetSize( sz );
NeedRIGHT();
break; break;
} }
@ -913,35 +950,53 @@ void PCB_PARSER::parseSetup() throw( IO_ERROR, PARSE_ERROR )
{ {
int drillSize = parseBoardUnits( T_pad_drill ); int drillSize = parseBoardUnits( T_pad_drill );
designSettings.m_Pad_Master.SetDrillSize( wxSize( drillSize, drillSize ) ); designSettings.m_Pad_Master.SetDrillSize( wxSize( drillSize, drillSize ) );
NeedRIGHT();
} }
break; break;
case T_pad_to_mask_clearance: case T_pad_to_mask_clearance:
designSettings.m_SolderMaskMargin = parseBoardUnits( T_pad_to_mask_clearance ); designSettings.m_SolderMaskMargin = parseBoardUnits( T_pad_to_mask_clearance );
NeedRIGHT();
break; break;
case T_pad_to_paste_clearance: case T_pad_to_paste_clearance:
designSettings.m_SolderPasteMargin = parseBoardUnits( T_pad_to_paste_clearance ); designSettings.m_SolderPasteMargin = parseBoardUnits( T_pad_to_paste_clearance );
NeedRIGHT();
break; break;
case T_pad_to_paste_clearance_ratio: case T_pad_to_paste_clearance_ratio:
designSettings.m_SolderPasteMarginRatio = parseDouble( T_pad_to_paste_clearance_ratio ); designSettings.m_SolderPasteMarginRatio = parseDouble( T_pad_to_paste_clearance_ratio );
NeedRIGHT();
break; break;
case T_aux_axis_origin: case T_aux_axis_origin:
m_board->SetOriginAxisPosition( wxPoint( parseBoardUnits( "auxilary origin X" ), {
parseBoardUnits( "auxilary origin Y" ) ) ); int x = parseBoardUnits( "auxilary origin X" );
int y = parseBoardUnits( "auxilary origin Y" );
// x, y are not evaluated left to right, since they are push on stack right to left
m_board->SetOriginAxisPosition( wxPoint( x, y ) );
NeedRIGHT();
break; break;
}
case T_visible_elements: case T_visible_elements:
designSettings.SetVisibleElements( parseHex() ); designSettings.SetVisibleElements( parseHex() );
NeedRIGHT();
break; break;
// case T_pcbplotparams:
// {
// PCB_PLOT_PARAMS plotParams;
// PCB_PLOT_PARAMS_PARSER parser( reader );
// plotParams.Parse( &parser );
// m_board->SetPlotOptions( plotParams );
// break;
// }
default: default:
Expecting( "valid setup token" ); Expecting( "valid setup token" );
} }
NeedRIGHT();
} }
m_board->SetDesignSettings( designSettings ); m_board->SetDesignSettings( designSettings );
@ -1061,20 +1116,20 @@ void PCB_PARSER::parseNETCLASS() throw( IO_ERROR, PARSE_ERROR )
} }
void PCB_PARSER::parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR ) DRAWSEGMENT* PCB_PARSER::parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR )
{ {
wxCHECK_RET( CurTok() == T_gr_arc || CurTok() == T_gr_circle || CurTok() == T_gr_curve || wxCHECK_MSG( CurTok() == T_gr_arc || CurTok() == T_gr_circle || CurTok() == T_gr_curve ||
CurTok() == T_gr_line || CurTok() == T_gr_poly, CurTok() == T_gr_line || CurTok() == T_gr_poly, NULL,
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as DRAWSEGMENT." ) ); wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as DRAWSEGMENT." ) );
T token; T token;
auto_ptr< DRAWSEGMENT > segment( new DRAWSEGMENT( m_board ) ); auto_ptr< DRAWSEGMENT > segment( new DRAWSEGMENT( NULL ) );
switch( CurTok() ) switch( CurTok() )
{ {
case T_gr_arc: case T_gr_arc:
segment->SetType( S_ARC ); segment->SetShape( S_ARC );
NeedLEFT(); NeedLEFT();
token = NextTok(); token = NextTok();
@ -1083,6 +1138,7 @@ void PCB_PARSER::parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR )
segment->SetStart( parseXY() ); segment->SetStart( parseXY() );
NeedRIGHT(); NeedRIGHT();
NeedLEFT();
token = NextTok(); token = NextTok();
if( token != T_end ) if( token != T_end )
@ -1100,7 +1156,7 @@ void PCB_PARSER::parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR )
break; break;
case T_gr_circle: case T_gr_circle:
segment->SetType( S_CIRCLE ); segment->SetShape( S_CIRCLE );
NeedLEFT(); NeedLEFT();
token = NextTok(); token = NextTok();
@ -1109,8 +1165,9 @@ void PCB_PARSER::parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR )
segment->SetStart( parseXY() ); segment->SetStart( parseXY() );
NeedRIGHT(); NeedRIGHT();
token = NextTok(); NeedLEFT();
token = NextTok();
if( token != T_end ) if( token != T_end )
Expecting( T_end ); Expecting( T_end );
@ -1119,7 +1176,7 @@ void PCB_PARSER::parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR )
break; break;
case T_gr_curve: case T_gr_curve:
segment->SetType( S_CURVE ); segment->SetShape( S_CURVE );
NeedLEFT(); NeedLEFT();
token = NextTok(); token = NextTok();
@ -1144,11 +1201,19 @@ void PCB_PARSER::parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR )
segment->SetStart( parseXY() ); segment->SetStart( parseXY() );
segment->SetEnd( parseXY() ); segment->SetEnd( parseXY() );
NeedRIGHT(); NeedRIGHT();
NeedLEFT();
token = NextTok();
if( token != T_angle )
Expecting( T_angle );
segment->SetAngle( parseDouble( "segment angle" ) * 10.0 );
NeedRIGHT();
break; break;
case T_gr_poly: case T_gr_poly:
{ {
segment->SetType( S_POLYGON ); segment->SetShape( S_POLYGON );
NeedLEFT(); NeedLEFT();
token = NextTok(); token = NextTok();
@ -1200,13 +1265,13 @@ void PCB_PARSER::parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR )
NeedRIGHT(); NeedRIGHT();
} }
m_board->Add( segment.release() ); return segment.release();
} }
void PCB_PARSER::parseTEXTE_PCB( TEXTE_PCB* aText ) throw( IO_ERROR, PARSE_ERROR ) TEXTE_PCB* PCB_PARSER::parseTEXTE_PCB() throw( IO_ERROR, PARSE_ERROR )
{ {
wxCHECK_RET( CurTok() == T_gr_text, wxCHECK_MSG( CurTok() == T_gr_text, NULL,
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as TEXTE_PCB." ) ); wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as TEXTE_PCB." ) );
T token; T token;
@ -1257,21 +1322,18 @@ void PCB_PARSER::parseTEXTE_PCB( TEXTE_PCB* aText ) throw( IO_ERROR, PARSE_ERROR
} }
} }
if( aText == NULL ) return text.release();
m_board->Add( text.release() );
else
*aText = *text;
} }
void PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR ) DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR )
{ {
wxCHECK_RET( CurTok() == T_dimension, wxCHECK_MSG( CurTok() == T_dimension, NULL,
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as DIMENSION." ) ); wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as DIMENSION." ) );
T token; T token;
auto_ptr< DIMENSION > dimension( new DIMENSION( m_board ) ); auto_ptr< DIMENSION > dimension( new DIMENSION( NULL ) );
dimension->m_Value = parseBoardUnits( "dimension value" ); dimension->m_Value = parseBoardUnits( "dimension value" );
NeedLEFT(); NeedLEFT();
@ -1303,9 +1365,12 @@ void PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR )
break; break;
case T_gr_text: case T_gr_text:
parseTEXTE_PCB( &dimension->m_Text ); {
TEXTE_PCB* text = parseTEXTE_PCB();
dimension->m_Text = *text;
delete text;
break; break;
}
case T_feature1: case T_feature1:
NeedLEFT(); NeedLEFT();
@ -1405,13 +1470,13 @@ void PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR )
} }
} }
m_board->Add( dimension.release() ); return dimension.release();
} }
void PCB_PARSER::parseMODULE() throw( IO_ERROR, PARSE_ERROR ) MODULE* PCB_PARSER::parseMODULE() throw( IO_ERROR, PARSE_ERROR )
{ {
wxCHECK_RET( CurTok() == T_module, wxCHECK_MSG( CurTok() == T_module, NULL,
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as MODULE." ) ); wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as MODULE." ) );
wxPoint pt; wxPoint pt;
@ -1618,7 +1683,7 @@ void PCB_PARSER::parseMODULE() throw( IO_ERROR, PARSE_ERROR )
} }
} }
m_board->Add( module.release(), ADD_APPEND ); return module.release();
} }
@ -1674,6 +1739,11 @@ TEXTE_MODULE* PCB_PARSER::parseTEXTE_MODULE() throw( IO_ERROR, PARSE_ERROR )
switch( token ) switch( token )
{ {
case T_layer:
text->SetLayer( parseBoardItemLayer() );
NeedRIGHT();
break;
case T_hide: case T_hide:
text->SetVisible( false ); text->SetVisible( false );
break; break;
@ -1704,7 +1774,7 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR )
switch( CurTok() ) switch( CurTok() )
{ {
case T_fp_arc: case T_fp_arc:
segment->SetType( S_ARC ); segment->SetShape( S_ARC );
NeedLEFT(); NeedLEFT();
token = NextTok(); token = NextTok();
@ -1730,7 +1800,7 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR )
break; break;
case T_fp_circle: case T_fp_circle:
segment->SetType( S_CIRCLE ); segment->SetShape( S_CIRCLE );
NeedLEFT(); NeedLEFT();
token = NextTok(); token = NextTok();
@ -1750,7 +1820,7 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR )
break; break;
case T_fp_curve: case T_fp_curve:
segment->SetType( S_CURVE ); segment->SetShape( S_CURVE );
NeedLEFT(); NeedLEFT();
token = NextTok(); token = NextTok();
@ -1779,7 +1849,7 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR )
case T_fp_poly: case T_fp_poly:
{ {
segment->SetType( S_POLYGON ); segment->SetShape( S_POLYGON );
NeedLEFT(); NeedLEFT();
token = NextTok(); token = NextTok();
@ -1977,8 +2047,18 @@ D_PAD* PCB_PARSER::parseD_PAD() throw( IO_ERROR, PARSE_ERROR )
break; break;
case T_layers: case T_layers:
pad->SetLayerMask( parseBoardItemLayersAsMask() ); {
int layerMask = parseBoardItemLayersAsMask();
// Only the layers that are used are saved so we need to enable all the copper
// layers to prevent any problems with the current design. At some point in
// the future, the layer handling should be improved.
if( pad->GetAttribute() == PAD_STANDARD )
layerMask |= ALL_CU_LAYERS;
pad->SetLayerMask( layerMask );
break; break;
}
case T_net: case T_net:
pad->SetNet( parseInt( "net number" ) ); pad->SetNet( parseInt( "net number" ) );
@ -1987,7 +2067,6 @@ D_PAD* PCB_PARSER::parseD_PAD() throw( IO_ERROR, PARSE_ERROR )
NeedRIGHT(); NeedRIGHT();
break; break;
case T_die_length: case T_die_length:
pad->SetDieLength( parseBoardUnits( T_die_length ) ); pad->SetDieLength( parseBoardUnits( T_die_length ) );
NeedRIGHT(); NeedRIGHT();
@ -2194,6 +2273,9 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
wxPoint pt; wxPoint pt;
T token; T token;
// bigger scope since each filled_polygon is concatonated in here
std::vector< CPolyPt > pts;
auto_ptr< ZONE_CONTAINER > zone( new ZONE_CONTAINER( m_board ) ); auto_ptr< ZONE_CONTAINER > zone( new ZONE_CONTAINER( m_board ) );
zone->SetPriority( 0 ); zone->SetPriority( 0 );
@ -2299,8 +2381,8 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
if( token != T_segment && token != T_polygon ) if( token != T_segment && token != T_polygon )
Expecting( "segment or polygon" ); Expecting( "segment or polygon" );
// @todo Create an enum for fill modes. Using true/false is not clear. // @todo Create an enum for fill modes.
zone->SetFillMode( ( T_segment ) ? true : false ); zone->SetFillMode( token == T_polygon ? 0 : 1 );
break; break;
case T_arc_segments: case T_arc_segments:
@ -2352,7 +2434,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
case T_polygon: case T_polygon:
{ {
std::vector< wxPoint > pts; std::vector< wxPoint > corners;
NeedLEFT(); NeedLEFT();
token = NextTok(); token = NextTok();
@ -2362,20 +2444,18 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
for( token = NextTok(); token != T_RIGHT; token = NextTok() ) for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{ {
pts.push_back( parseXY() ); corners.push_back( parseXY() );
} }
NeedRIGHT(); NeedRIGHT();
zone->AddPolygon( pts ); zone->AddPolygon( corners );
} }
break; break;
case T_filled_polygon: case T_filled_polygon:
{ {
wxPoint pt; // "(filled_polygon (pts"
std::vector< CPolyPt > pts;
NeedLEFT(); NeedLEFT();
token = NextTok(); token = NextTok();
@ -2384,13 +2464,11 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
for( token = NextTok(); token != T_RIGHT; token = NextTok() ) for( token = NextTok(); token != T_RIGHT; token = NextTok() )
{ {
pt = parseXY(); pts.push_back( CPolyPt( parseXY() ) );
pts.push_back( CPolyPt( pt.x, pt.y ) );
} }
NeedRIGHT(); NeedRIGHT();
pts.back().end_contour = true; pts.back().end_contour = true;
zone->AddFilledPolysList( pts );
} }
break; break;
@ -2437,6 +2515,9 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
zone->m_Poly->SetHatch( hatchStyle, hatchPitch ); zone->m_Poly->SetHatch( hatchStyle, hatchPitch );
} }
if( pts.size() )
zone->AddFilledPolysList( pts );
return zone.release(); return zone.release();
} }

View File

@ -40,6 +40,8 @@ using namespace PCB;
class BOARD; class BOARD;
class BOARD_ITEM; class BOARD_ITEM;
class D_PAD; class D_PAD;
class DIMENSION;
class DRAWSEGMENT;
class EDGE_MODULE; class EDGE_MODULE;
class TEXTE_MODULE; class TEXTE_MODULE;
class TEXTE_PCB; class TEXTE_PCB;
@ -73,10 +75,10 @@ class PCB_PARSER : public PCB_LEXER
void parseSetup() throw( IO_ERROR, PARSE_ERROR ); void parseSetup() throw( IO_ERROR, PARSE_ERROR );
void parseNETINFO_ITEM() throw( IO_ERROR, PARSE_ERROR ); void parseNETINFO_ITEM() throw( IO_ERROR, PARSE_ERROR );
void parseNETCLASS() throw( IO_ERROR, PARSE_ERROR ); void parseNETCLASS() throw( IO_ERROR, PARSE_ERROR );
void parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR ); DRAWSEGMENT* parseDRAWSEGMENT() throw( IO_ERROR, PARSE_ERROR );
void parseTEXTE_PCB( TEXTE_PCB* aText = NULL ) throw( IO_ERROR, PARSE_ERROR ); TEXTE_PCB* parseTEXTE_PCB() throw( IO_ERROR, PARSE_ERROR );
void parseDIMENSION() throw( IO_ERROR, PARSE_ERROR ); DIMENSION* parseDIMENSION() throw( IO_ERROR, PARSE_ERROR );
void parseMODULE() throw( IO_ERROR, PARSE_ERROR ); MODULE* parseMODULE() throw( IO_ERROR, PARSE_ERROR );
TEXTE_MODULE* parseTEXTE_MODULE() throw( IO_ERROR, PARSE_ERROR ); TEXTE_MODULE* parseTEXTE_MODULE() throw( IO_ERROR, PARSE_ERROR );
EDGE_MODULE* parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR ); EDGE_MODULE* parseEDGE_MODULE() throw( IO_ERROR, PARSE_ERROR );
D_PAD* parseD_PAD() throw( IO_ERROR, PARSE_ERROR ); D_PAD* parseD_PAD() throw( IO_ERROR, PARSE_ERROR );
@ -168,12 +170,12 @@ class PCB_PARSER : public PCB_LEXER
{ {
// There should be no rounding issues here, since the values in the file are in mm // There should be no rounding issues here, since the values in the file are in mm
// and get converted to nano-meters. This product should be an integer, exactly. // and get converted to nano-meters. This product should be an integer, exactly.
return int( parseDouble() * 1e6 ); return int( parseDouble() * IU_PER_MM );
} }
inline int parseBoardUnits( const char* aExpected ) throw( PARSE_ERROR ) inline int parseBoardUnits( const char* aExpected ) throw( PARSE_ERROR )
{ {
return KIROUND( parseDouble( aExpected ) * 1e6 ); return KIROUND( parseDouble( aExpected ) * IU_PER_MM );
} }
inline int parseBoardUnits( T aToken ) throw( PARSE_ERROR ) inline int parseBoardUnits( T aToken ) throw( PARSE_ERROR )

View File

@ -120,7 +120,7 @@ void PCB_PLOT_PARAMS::Format( OUTPUTFORMATTER* aFormatter,
const char* falseStr = getTokenName( T_false ); const char* falseStr = getTokenName( T_false );
const char* trueStr = getTokenName( T_true ); const char* trueStr = getTokenName( T_true );
aFormatter->Print( aNestLevel, "(%s", getTokenName( T_pcbplotparams ) ); aFormatter->Print( aNestLevel, "(%s\n", getTokenName( T_pcbplotparams ) );
aFormatter->Print( aNestLevel+1, "(%s %ld)\n", getTokenName( T_layerselection ), aFormatter->Print( aNestLevel+1, "(%s %ld)\n", getTokenName( T_layerselection ),
layerSelection ); layerSelection );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_usegerberextensions ), aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_usegerberextensions ),
@ -173,7 +173,7 @@ void PCB_PLOT_PARAMS::Format( OUTPUTFORMATTER* aFormatter,
scaleSelection ); scaleSelection );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_outputdirectory ), aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_outputdirectory ),
aFormatter->Quotew( outputDirectory ).c_str() ); aFormatter->Quotew( outputDirectory ).c_str() );
aFormatter->Print( 0, ")\n" ); aFormatter->Print( aNestLevel, ")\n" );
} }