From a47d36e399bb8adff5a28bb8647c207b9ecf44a1 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Wed, 3 Apr 2013 18:16:26 +0200 Subject: [PATCH] Pcbnew: fix Bug #1163201. Fix Bug #1162779. Fix incorrect comment in CMakeLists.txt. --- CMakeLists.txt | 2 +- common/drawtxt.cpp | 209 +++++++++++++++++-------------- pcbnew/netlist_reader_common.cpp | 4 + pcbnew/netlist_reader_kicad.cpp | 132 ++++++++++++------- 4 files changed, 210 insertions(+), 137 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e3c6ae22a0..9d7d8a9860 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ option(KICAD_STABLE_VERSION ) option(KICAD_TESTING_VERSION - "set this option to ON to build the stable version of KICAD. mainly used to set version ID (default OFF)" + "set this option to ON to build the testing version of KICAD. mainly used to set version ID (default OFF)" ) option(KICAD_SCRIPTING diff --git a/common/drawtxt.cpp b/common/drawtxt.cpp index 623b85a163..c8724bbe3a 100644 --- a/common/drawtxt.cpp +++ b/common/drawtxt.cpp @@ -40,13 +40,15 @@ #include -#define EDA_DRAWBASE #include #include -/* factor used to calculate actual size of shapes from hershey fonts (could be adjusted depending on the font name) - * Its value is choosen in order to have letters like M, P .. vertical size equal to the vertical char size parameter - * Of course some shapes can be bigger or smaller than the vertical char size parameter +/* factor used to calculate actual size of shapes from hershey fonts + * (could be adjusted depending on the font name) + * Its value is choosen in order to have letters like M, P .. vertical size + * equal to the vertical char size parameter + * Of course some shapes can be bigger or smaller than the vertical char size + * parameter */ #define HERSHEY_SCALE_FACTOR 1 / 21.0 double s_HerscheyScaleFactor = HERSHEY_SCALE_FACTOR; @@ -59,6 +61,7 @@ int OverbarPositionY( int size_v, int thickness ) return KiROUND( ( (double) size_v * 1.1 ) + ( (double) thickness * 1.5 ) ); } + /** * Function GetPensizeForBold * @return the "best" value for a pen size to draw/plot a bold text @@ -84,12 +87,13 @@ int GetPenSizeForBold( int aTextSize ) */ int Clamp_Text_PenSize( int aPenSize, int aSize, bool aBold ) { - int penSize = aPenSize; - double scale = aBold ? 4.0 : 6.0; - int maxWidth = KiROUND( std::abs( aSize ) / scale ); + int penSize = aPenSize; + double scale = aBold ? 4.0 : 6.0; + int maxWidth = KiROUND( std::abs( aSize ) / scale ); if( penSize > maxWidth ) penSize = maxWidth; + return penSize; } @@ -112,17 +116,19 @@ int Clamp_Text_PenSize( int aPenSize, wxSize aSize, bool aBold ) /** * Function NegableTextLength - * Return the text length of a negable string, excluding the ~ markers */ + * Return the text length (char count) of a negable string, + * excluding the ~ markers + */ int NegableTextLength( const wxString& aText ) { int char_count = aText.length(); - /* Fix the character count, removing the ~ found */ + // Fix the character count, removing the ~ found for( int i = char_count - 1; i >= 0; i-- ) { if( aText[i] == '~' ) { - /* '~~' draw as '~' and count as two chars */ + // '~~' draw as '~' and count as two chars if( i > 0 && aText[i - 1] == '~' ) i--; else @@ -142,13 +148,15 @@ int NegableTextLength( const wxString& aText ) */ static const char* GetHersheyShapeDescription( int AsciiCode ) { - /* calculate font length */ + // calculate font length int font_length_max = newstroke_font_bufsize; if( AsciiCode >= (32 + font_length_max) ) AsciiCode = '?'; + if( AsciiCode < 32 ) - AsciiCode = 32; /* Clamp control chars */ + AsciiCode = 32; /* Clamp control chars */ + AsciiCode -= 32; return newstroke_font[AsciiCode]; @@ -162,48 +170,50 @@ int ReturnGraphicTextWidth( const wxString& aText, int aXSize, bool aItalic, boo for( int i = 0; i < char_count; i++ ) { - int AsciiCode = aText[i]; + int asciiCode = aText[i]; /* Skip the negation marks * and first '~' char of '~~' - * ('~~' draw as '~') */ - if( AsciiCode == '~' ) + * ('~~' draw as '~') + */ + if( asciiCode == '~' ) { - if( i > 0 && aText[i - 1] != '~' ) + if( i == 0 || aText[i - 1] != '~' ) continue; } - const char* ptcar = GetHersheyShapeDescription( AsciiCode ); - /* Get metrics */ - int xsta = *ptcar++ - 'R'; - int xsto = *ptcar++ - 'R'; + const char* shape_ptr = GetHersheyShapeDescription( asciiCode ); + // Get metrics + int xsta = *shape_ptr++ - 'R'; + int xsto = *shape_ptr++ - 'R'; tally += KiROUND( aXSize * (xsto - xsta) * s_HerscheyScaleFactor ); } - /* Italic correction, 1/8em */ + // For italic correction, add 1/8 size if( aItalic ) { tally += KiROUND( aXSize * 0.125 ); } + return tally; } -/* Helper function for drawing character polygons */ -static void DrawGraphicTextPline( - EDA_RECT* aClipBox, - wxDC* aDC, - EDA_COLOR_T aColor, - int aWidth, - bool aSketchMode, - int point_count, - wxPoint* coord, - void (* aCallback)(int x0, int y0, int xf, int yf ), - PLOTTER* aPlotter ) +// Helper function for drawing character polylines +static void DrawGraphicTextPline( EDA_RECT* aClipBox, + wxDC* aDC, + EDA_COLOR_T aColor, + int aWidth, + bool aSketchMode, + int point_count, + wxPoint* coord, + void (* aCallback)( int x0, int y0, int xf, int yf ), + PLOTTER* aPlotter ) { if( aPlotter ) { aPlotter->MoveTo( coord[0] ); + for( int ik = 1; ik < point_count; ik++ ) { aPlotter->LineTo( coord[ik] ); @@ -268,26 +278,26 @@ void DrawGraphicText( EDA_DRAW_PANEL* aPanel, void (* aCallback)( int x0, int y0, int xf, int yf ), PLOTTER* aPlotter ) { - int AsciiCode; - int x0, y0; - int size_h, size_v; - unsigned ptr; - int dx, dy; // Draw coordinate for segments to draw. also used in some other calculation - wxPoint current_char_pos; // Draw coordinates for the current char - wxPoint overbar_pos; // Start point for the current overbar - int overbar_italic_comp; // Italic compensation for overbar - EDA_RECT* clipBox; // Clip box used in basic draw functions + int AsciiCode; + int x0, y0; + int size_h, size_v; + unsigned ptr; + int dx, dy; // Draw coordinate for segments to draw. also used in some other calculation + wxPoint current_char_pos; // Draw coordinates for the current char + wxPoint overbar_pos; // Start point for the current overbar + int overbar_italic_comp; // Italic compensation for overbar + EDA_RECT* clipBox; // Clip box used in basic draw functions clipBox = aPanel ? aPanel->GetClipBox() : NULL; #define BUF_SIZE 100 wxPoint coord[BUF_SIZE + 1]; // Buffer coordinate used to draw polylines (one char shape) - bool sketch_mode = false; - bool italic_reverse = false; // true for mirrored texts with m_Size.x < 0 + bool sketch_mode = false; + bool italic_reverse = false; // true for mirrored texts with m_Size.x < 0 - size_h = aSize.x; /* PLEASE NOTE: H is for HORIZONTAL not for HEIGHT */ - size_v = aSize.y; + size_h = aSize.x; /* PLEASE NOTE: H is for HORIZONTAL not for HEIGHT */ + size_v = aSize.y; - if( aWidth == 0 && aBold ) // Use default values if aWidth == 0 + if( aWidth == 0 && aBold ) // Use default values if aWidth == 0 aWidth = GetPenSizeForBold( std::min( aSize.x, aSize.y ) ); if( aWidth < 0 ) @@ -300,17 +310,18 @@ void DrawGraphicText( EDA_DRAW_PANEL* aPanel, aWidth = Clamp_Text_PenSize( aWidth, aSize, aBold ); #endif - if( size_h < 0 ) // text is mirrored using size.x < 0 (mirror / Y axis) + if( size_h < 0 ) // text is mirrored using size.x < 0 (mirror / Y axis) italic_reverse = true; unsigned char_count = NegableTextLength( aText ); + if( char_count == 0 ) return; current_char_pos = aPos; - dx = ReturnGraphicTextWidth( aText, size_h, aItalic, aWidth ); - dy = size_v; + dx = ReturnGraphicTextWidth( aText, size_h, aItalic, aWidth ); + dy = size_v; /* Do not draw the text if out of draw area! */ if( aPanel ) @@ -318,20 +329,23 @@ void DrawGraphicText( EDA_DRAW_PANEL* aPanel, int xm, ym, ll, xc, yc; ll = std::abs( dx ); - xc = current_char_pos.x; - yc = current_char_pos.y; + xc = current_char_pos.x; + yc = current_char_pos.y; - x0 = aPanel->GetClipBox()->GetX() - ll; - y0 = aPanel->GetClipBox()->GetY() - ll; - xm = aPanel->GetClipBox()->GetRight() + ll; - ym = aPanel->GetClipBox()->GetBottom() + ll; + x0 = aPanel->GetClipBox()->GetX() - ll; + y0 = aPanel->GetClipBox()->GetY() - ll; + xm = aPanel->GetClipBox()->GetRight() + ll; + ym = aPanel->GetClipBox()->GetBottom() + ll; if( xc < x0 ) return; + if( yc < y0 ) return; + if( xc > xm ) return; + if( yc > ym ) return; } @@ -404,6 +418,7 @@ void DrawGraphicText( EDA_DRAW_PANEL* aPanel, if( aItalic ) { overbar_italic_comp = OverbarPositionY( size_v, aWidth ) / 8; + if( italic_reverse ) { overbar_italic_comp = -overbar_italic_comp; @@ -412,17 +427,20 @@ void DrawGraphicText( EDA_DRAW_PANEL* aPanel, else { overbar_italic_comp = 0; - }; + } + + ; + + int overbars = 0; /* Number of '~' seen (except '~~') */ + ptr = 0; /* ptr = text index */ - int overbars = 0; /* Number of '~' seen (except '~~') */ - ptr = 0; /* ptr = text index */ while( ptr < char_count ) { if( aText[ptr + overbars] == '~' ) { - if( ptr + overbars + 1 < aText.length() && - aText[ptr + overbars + 1] == '~' ) /* '~~' draw as '~' */ - ptr++; // skip first '~' char and draw second + if( ptr + overbars + 1 < aText.length() + && aText[ptr + overbars + 1] == '~' ) /* '~~' draw as '~' */ + ptr++; // skip first '~' char and draw second else { @@ -431,41 +449,44 @@ void DrawGraphicText( EDA_DRAW_PANEL* aPanel, if( overbars & 1 ) // odd overbars count { - /* Starting the overbar */ - overbar_pos = current_char_pos; - overbar_pos.x += overbar_italic_comp; - overbar_pos.y -= OverbarPositionY( size_v, aWidth ); + // Starting the overbar + overbar_pos = current_char_pos; + overbar_pos.x += overbar_italic_comp; + overbar_pos.y -= OverbarPositionY( size_v, aWidth ); RotatePoint( &overbar_pos, aPos, aOrient ); } else { - /* Ending the overbar */ - coord[0] = overbar_pos; - overbar_pos = current_char_pos; - overbar_pos.x += overbar_italic_comp; - overbar_pos.y -= OverbarPositionY( size_v, aWidth ); + // Ending the overbar + coord[0] = overbar_pos; + overbar_pos = current_char_pos; + overbar_pos.x += overbar_italic_comp; + overbar_pos.y -= OverbarPositionY( size_v, aWidth ); RotatePoint( &overbar_pos, aPos, aOrient ); coord[1] = overbar_pos; - /* Plot the overbar segment */ + // Plot the overbar segment DrawGraphicTextPline( clipBox, aDC, aColor, aWidth, sketch_mode, 2, coord, aCallback, aPlotter ); } - continue; /* Skip ~ processing */ + + continue; /* Skip ~ processing */ } } AsciiCode = aText.GetChar( ptr + overbars ); const char* ptcar = GetHersheyShapeDescription( AsciiCode ); - /* Get metrics */ - int xsta = *ptcar++ - 'R'; - int xsto = *ptcar++ - 'R'; + // Get metrics + int xsta = *ptcar++ - 'R'; + int xsto = *ptcar++ - 'R'; int point_count = 0; bool endcar = false; + while( !endcar ) { int hc1, hc2; hc1 = *ptcar++; + if( hc1 ) { hc2 = *ptcar++; @@ -473,12 +494,15 @@ void DrawGraphicText( EDA_DRAW_PANEL* aPanel, else { // End of character, insert a synthetic pen up: - hc1 = ' '; - hc2 = 'R'; - endcar = true; + hc1 = ' '; + hc2 = 'R'; + endcar = true; } - // Do the Hershey decode thing: coordinates values are coded as + 'R' - hc1 -= 'R'; hc2 -= 'R'; + + // Do the Hershey decode thing: + // coordinates values are coded as + 'R' + hc1 -= 'R'; + hc2 -= 'R'; /* Pen up request */ if( hc1 == -50 && hc2 == 0 ) @@ -487,33 +511,36 @@ void DrawGraphicText( EDA_DRAW_PANEL* aPanel, { if( aWidth <= 1 ) aWidth = 0; + DrawGraphicTextPline( clipBox, aDC, aColor, aWidth, sketch_mode, point_count, coord, aCallback, aPlotter ); } + point_count = 0; } else { wxPoint currpoint; - hc1 -= xsta; hc2 -= 11; /* Align the midpoint */ - hc1 = KiROUND( hc1 * size_h * s_HerscheyScaleFactor ); - hc2 = KiROUND( hc2 * size_v * s_HerscheyScaleFactor ); + hc1 -= xsta; hc2 -= 11; // Align the midpoint + hc1 = KiROUND( hc1 * size_h * s_HerscheyScaleFactor ); + hc2 = KiROUND( hc2 * size_v * s_HerscheyScaleFactor ); - // To simulate an italic font, add a x offset depending on the y offset + // To simulate an italic font, + // add a x offset depending on the y offset if( aItalic ) hc1 -= KiROUND( italic_reverse ? -hc2 / 8.0 : hc2 / 8.0 ); + currpoint.x = hc1 + current_char_pos.x; currpoint.y = hc2 + current_char_pos.y; RotatePoint( &currpoint, aPos, aOrient ); coord[point_count] = currpoint; + if( point_count < BUF_SIZE - 1 ) point_count++; } - } - - /* end draw 1 char */ + } // end draw 1 char ptr++; @@ -524,9 +551,9 @@ void DrawGraphicText( EDA_DRAW_PANEL* aPanel, if( overbars % 2 ) { /* Close the last overbar */ - coord[0] = overbar_pos; - overbar_pos = current_char_pos; - overbar_pos.y -= OverbarPositionY( size_v, aWidth ); + coord[0] = overbar_pos; + overbar_pos = current_char_pos; + overbar_pos.y -= OverbarPositionY( size_v, aWidth ); RotatePoint( &overbar_pos, aPos, aOrient ); coord[1] = overbar_pos; /* Plot the overbar segment */ @@ -565,7 +592,7 @@ void PLOTTER::Text( const wxPoint& aPos, { int textPensize = aWidth; - if( textPensize == 0 && aBold ) // Use default values if aWidth == 0 + if( textPensize == 0 && aBold ) // Use default values if aWidth == 0 textPensize = GetPenSizeForBold( std::min( aSize.x, aSize.y ) ); if( textPensize >= 0 ) diff --git a/pcbnew/netlist_reader_common.cpp b/pcbnew/netlist_reader_common.cpp index c174d540ef..24462bd5e7 100644 --- a/pcbnew/netlist_reader_common.cpp +++ b/pcbnew/netlist_reader_common.cpp @@ -236,6 +236,7 @@ void NETLIST_READER::TestFootprintsMatchingAndExchange() break; } } + if( cmp_info == NULL ) // not found in netlist continue; @@ -296,9 +297,11 @@ int NETLIST_READER::SetPadsNetName( const wxString & aModule, const wxString & a int padcount = 0; MODULE* module = m_pcbframe->GetBoard()->FindModuleByReference( aModule ); + if( module ) { D_PAD * pad = module->FindPadByName( aPadname ); + if( pad ) { padcount++; @@ -316,6 +319,7 @@ int NETLIST_READER::SetPadsNetName( const wxString & aModule, const wxString & a } return padcount; } + if( m_messageWindow ) { wxString msg; diff --git a/pcbnew/netlist_reader_kicad.cpp b/pcbnew/netlist_reader_kicad.cpp index ad1dd62f8e..6b7de75230 100644 --- a/pcbnew/netlist_reader_kicad.cpp +++ b/pcbnew/netlist_reader_kicad.cpp @@ -173,62 +173,104 @@ void NETLIST_READER_KICAD_PARSER::SkipCurrent() throw( IO_ERROR, PARSE_ERROR ) void NETLIST_READER_KICAD_PARSER::Parse( BOARD * aBrd ) throw( IO_ERROR, PARSE_ERROR ) { - wxString text; + int plevel = 0; // the count of ')' to read and end of file, + // after parsing all sections + while( ( token = NextTok() ) != T_EOF ) { if( token == T_LEFT ) token = NextTok(); - if( token == T_components ) - { - // The section comp starts here. - while( ( token = NextTok() ) != T_RIGHT ) - { - if( token == T_LEFT ) - token = NextTok(); - if( token == T_comp ) - { - // A comp section if found. Read it - COMPONENT_INFO* cmp_info = ParseComp(); - netlist_reader->AddModuleInfo( cmp_info ); - } - } - if( netlist_reader->BuildModuleListOnlyOpt() ) - return; // at this point, the module list is read and built. - // Load new footprints - netlist_reader->InitializeModules(); - netlist_reader->TestFootprintsMatchingAndExchange(); - } - if( token == T_nets ) + switch( token ) { - // The section nets starts here. - while( ( token = NextTok() ) != T_RIGHT ) - { - if( token == T_LEFT ) - token = NextTok(); - if( token == T_net ) - { - // A net section if found. Read it - ParseNet( aBrd ); - } - } - } + case T_export: // The netlist starts here. + // nothing to do here, + // just increment the count of ')' to read and end of file + plevel++; + break; - if( token == T_libparts && netlist_reader->ReadLibpartSectionOpt() ) - { - // The section libparts starts here. - while( ( token = NextTok() ) != T_RIGHT ) - { - if( token == T_LEFT ) - token = NextTok(); - if( token == T_libpart ) + case T_version: // The netlist starts here. + // version id not yet used: read it but does not use it + NextTok(); + NeedRIGHT(); + break; + + case T_components: // The section comp starts here. + while( ( token = NextTok() ) != T_RIGHT ) { - // A libpart section if found. Read it - ParseKicadLibpartList(); + if( token == T_LEFT ) + token = NextTok(); + if( token == T_comp ) // A comp section if found. Read it + { + COMPONENT_INFO* cmp_info = ParseComp(); + netlist_reader->AddModuleInfo( cmp_info ); + } } - } + if( netlist_reader->BuildModuleListOnlyOpt() ) + return; // at this point, the module list is read and built. + // Load new footprints + netlist_reader->InitializeModules(); + netlist_reader->TestFootprintsMatchingAndExchange(); + break; + + case T_nets: // The section nets starts here. + while( ( token = NextTok() ) != T_RIGHT ) + { + if( token == T_LEFT ) + token = NextTok(); + if( token == T_net ) + { + // A net section if found. Read it + ParseNet( aBrd ); + } + } + break; + + case T_libparts: // The section libparts starts here. + if( netlist_reader->ReadLibpartSectionOpt() ) + { + while( ( token = NextTok() ) != T_RIGHT ) + { + if( token == T_LEFT ) + token = NextTok(); + if( token == T_libpart ) + { + // A libpart section if found. Read it + ParseKicadLibpartList(); + } + } + } + else + SkipCurrent(); + break; + + case T_libraries: // The section libraries starts here. + // List of libraries in use. + // Not used here, just skip it + SkipCurrent(); + break; + + case T_design: // The section design starts here. + // Not used (mainly thet are comments), just skip it + SkipCurrent(); + break; + + case T_RIGHT: // The closing parenthesis of the file. + // Not used (mainly thet are comments), just skip it + plevel--; + break; + + default: + SkipCurrent(); + break; } } + + if( plevel != 0 ) + { + wxLogDebug(wxT("NETLIST_READER_KICAD_PARSER::Parse(): bad parenthesis count (count = %d"), + plevel ); + } } void NETLIST_READER_KICAD_PARSER::ParseNet( BOARD * aBrd )