diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index be61d5d6e1..1e2292c91c 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -141,6 +141,9 @@ const wxPoint D_PAD::ReturnShapePos() const wxString D_PAD::GetPadName() const { +#if 0 // m_Padname is not ASCII and not UTF8, it is LATIN1 basically, whatever + // 8 bit font is supported in KiCad plotting and drawing. + // Return pad name as wxString, assume it starts as a non-terminated // utf8 character sequence @@ -151,11 +154,21 @@ const wxString D_PAD::GetPadName() const temp[sizeof(m_Padname)] = 0; return FROM_UTF8( temp ); +#else + + wxString name; + + ReturnStringPadName( name ); + return name; +#endif } void D_PAD::ReturnStringPadName( wxString& text ) const { +#if 0 // m_Padname is not ASCII and not UTF8, it is LATIN1 basically, whatever + // 8 bit font is supported in KiCad plotting and drawing. + // Return pad name as wxString, assume it starts as a non-terminated // utf8 character sequence @@ -166,6 +179,20 @@ void D_PAD::ReturnStringPadName( wxString& text ) const temp[sizeof(m_Padname)] = 0; text = FROM_UTF8( temp ); + +#else + + text.Empty(); + + for( int ii = 0; ii < PADNAMEZ; ii++ ) + { + if( !m_Padname[ii] ) + break; + + // add an unsigned 8 bit byte, which is LATIN1 or CRYLIC + text.Append( (unsigned char) m_Padname[ii] ); + } +#endif } @@ -176,25 +203,17 @@ void D_PAD::SetPadName( const wxString& name ) len = name.Length(); - if( len > 4 ) - len = 4; + if( len > PADNAMEZ ) + len = PADNAMEZ; + + // m_Padname[] is not UTF8, it is an 8 bit character that matches the KiCad font, + // so only copy the lower 8 bits of each character. for( ii = 0; ii < len; ii++ ) - m_Padname[ii] = name.GetChar( ii ); + m_Padname[ii] = (char) name.GetChar( ii ); - for( ii = len; ii < 4; ii++ ) - m_Padname[ii] = 0; -} - -void D_PAD::SetPadName( const char* aName ) -{ - unsigned i; - - for( i=0; im_NumPadName; // hide tricks behind sensible API + } + /** * Function SetNetname * @param aNetname: the new netname @@ -347,10 +354,6 @@ public: */ int BuildSegmentFromOvalShape( wxPoint& aSegStart, wxPoint& aSegEnd, int aRotation ) const; - void SetPadName( const wxString& name ); // Change pad name - void SetPadName( const char* aName ); - const wxString GetPadName() const; - void ReturnStringPadName( wxString& text ) const; // Return pad name as string in a buffer void ComputeShapeMaxRadius(); // compute radius diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index c6d0dad691..2f99cdfc3c 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -664,7 +664,7 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_li // one can argue that this 2nd test is not necessary, that any // two pads from a single module are acceptable. This 2nd test // should eventually be a configuration option. - if( pad->m_NumPadName == aRefPad->m_NumPadName ) + if( pad->PadNameEqual( aRefPad ) ) continue; } diff --git a/pcbnew/gen_modules_placefile.cpp b/pcbnew/gen_modules_placefile.cpp index 0c95897ddc..524b0e25fb 100644 --- a/pcbnew/gen_modules_placefile.cpp +++ b/pcbnew/gen_modules_placefile.cpp @@ -435,7 +435,7 @@ void PCB_EDIT_FRAME::GenModuleReport( wxCommandEvent& event ) for( pad = Module->m_Pads; pad != NULL; pad = pad->Next() ) { - fprintf( rptfile, "$PAD \"%.4s\"\n", pad->m_Padname ); + fprintf( rptfile, "$PAD \"%s\"\n", TO_UTF8( pad->GetPadName() ) ); sprintf( line, "position %9.6f %9.6f\n", pad->m_Pos0.x * conv_unit, pad->m_Pos0.y * conv_unit ); diff --git a/pcbnew/kicad_plugin.cpp b/pcbnew/kicad_plugin.cpp index 2b9056a12d..5bd9f92dc8 100644 --- a/pcbnew/kicad_plugin.cpp +++ b/pcbnew/kicad_plugin.cpp @@ -60,13 +60,7 @@ #include #include #include -#include - -//#include -//#include -//#include -//#include - +//#include #include #ifdef CVPCB @@ -90,17 +84,15 @@ #include + +//#define KICAD_NANOMETRE + + #define VERSION_ERROR_FORMAT _( "File '%s' is format version: %d.\nI only support format version <= %d.\nPlease upgrade PCBNew to load this file." ) #define UNKNOWN_GRAPHIC_FORMAT _( "unknown graphic type: %d") #define UNKNOWN_PAD_FORMAT _( "unknown pad type: %d") #define UNKNOWN_PAD_ATTRIBUTE _( "unknown pad attribute: %d" ) -/* -#include -#include -#include -*/ - /// C string compare test for a specific length of characters. @@ -330,6 +322,8 @@ void KICAD_PLUGIN::checkVersion() m_error.Printf( VERSION_ERROR_FORMAT, ver ); THROW_IO_ERROR( m_error ); } + + m_loading_format_version = ver; } @@ -1039,11 +1033,15 @@ void KICAD_PLUGIN::loadPAD( MODULE* aModule ) // e.g. "Sh "A2" C 520 520 0 0 900" // or "Sh "1" R 157 1378 0 0 900" - char padname[sizeof(pad->m_Padname)+1]; + // mypadname is LATIN1/CRYLIC for BOARD_FORMAT_VERSION 1, + // but for BOARD_FORMAT_VERSION 2, it is UTF8 from disk. + // So we have to go through two code paths. Moving forward + // padnames will be in UTF8 on disk, as are all KiCad strings on disk. + char mypadname[50]; data = line + SZ( "Sh" ) + 1; // +1 skips trailing whitespace - data = data + ReadDelimitedText( padname, data, sizeof(padname) ) + 1; // +1 trailing whitespace + data = data + ReadDelimitedText( mypadname, data, sizeof(mypadname) ) + 1; // +1 trailing whitespace // sscanf( PtLine, " %s %d %d %d %d %d", BufCar, &m_Size.x, &m_Size.y, &m_DeltaSize.x, &m_DeltaSize.y, &m_Orient ); @@ -1066,6 +1064,26 @@ void KICAD_PLUGIN::loadPAD( MODULE* aModule ) THROW_IO_ERROR( m_error ); } + // go through a wxString to establish a universal character set properly + wxString padname; + + if( m_loading_format_version == 1 ) + { + // add 8 bit bytes, file format 1 was KiCad font type byte, + // simply promote those 8 bit bytes up into UNICODE. (subset of LATIN1) + const unsigned char* cp = (unsigned char*) mypadname; + while( *cp ) + { + padname += *cp++; // unsigned, ls 8 bits only + } + } + else + { + // version 2, which is UTF8. + padname = FROM_UTF8( mypadname ); + } + // chances are both were ASCII, but why take chances? + pad->SetPadName( padname ); pad->SetShape( padshape ); pad->SetSize( wxSize( size_x, size_y ) ); @@ -3059,8 +3077,28 @@ void KICAD_PLUGIN::savePAD( const D_PAD* me ) const THROW_IO_ERROR( wxString::Format( UNKNOWN_PAD_FORMAT, me->GetShape() ) ); } + // universal character set padname + wxString padname = me->GetPadName(); + +#if BOARD_FORMAT_VERSION == 1 + + char mypadname[PADNAMEZ+1]; + + int i; + for( i = 0; iGetPadName() ).c_str(), +#endif cshape, fmtBIUSize( me->GetSize() ).c_str(), fmtBIUSize( me->GetDelta() ).c_str(), diff --git a/pcbnew/kicad_plugin.h b/pcbnew/kicad_plugin.h index 087c0c7bc5..5155dbd810 100644 --- a/pcbnew/kicad_plugin.h +++ b/pcbnew/kicad_plugin.h @@ -80,6 +80,7 @@ protected: wxString m_filename; ///< for saves only, name is in m_reader for loads wxString m_field; ///< reused to stuff MODULE fields. + int m_loading_format_version; ///< which BOARD_FORMAT_VERSION am I Load()ing? /// initialize PLUGIN like a constructor would, and futz with fresh BOARD if needed. void init( PROPERTIES* aProperties ); diff --git a/pcbnew/netlist.cpp b/pcbnew/netlist.cpp index 57abc6fa16..856a989ca8 100644 --- a/pcbnew/netlist.cpp +++ b/pcbnew/netlist.cpp @@ -97,7 +97,8 @@ public: bool m_ChangeFootprints; // Set to true to change existing footprints to new ones // when netlist gives a different footprint name -public: NETLIST_READER( PCB_EDIT_FRAME* aFrame, wxTextCtrl* aMessageWindow = NULL ) +public: + NETLIST_READER( PCB_EDIT_FRAME* aFrame, wxTextCtrl* aMessageWindow = NULL ) { m_pcbframe = aFrame; m_messageWindow = aMessageWindow; @@ -199,7 +200,7 @@ private: static FILE* OpenNetlistFile( const wxString& aFullFileName ) { if( aFullFileName.IsEmpty() ) - return false; /* No filename: exit */ + return false; // No filename: exit FILE* file = wxFopen( aFullFileName, wxT( "rt" ) ); @@ -341,7 +342,7 @@ void NETLIST_READER::RemoveExtraFootprints( const wxString& aNetlistFileName ) for( ii = 0; ii < modulesCount; ii++ ) { if( module->m_Reference->m_Text.CmpNoCase( componentsInNetlist[ii] ) == 0 ) - break; /* Module is found in net list. */ + break; // Module is found in net list. } if( ii == modulesCount ) // Module not found in netlist. @@ -404,7 +405,7 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, { char* line = StrPurge( netlineReader.Line() ); - if( is_comment ) /* Comments in progress */ + if( is_comment ) // Comments in progress { // Test for end of the current comment if( ( line = strchr( line, '}' ) ) == NULL ) @@ -412,7 +413,7 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, is_comment = false; } - if( *line == '{' ) /* Start Comment */ + if( *line == '{' ) // Start Comment { is_comment = true; @@ -438,7 +439,7 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, } } - /* Load new footprints */ + // Load new footprints bool success = loadNewModules(); if( ! success ) @@ -487,11 +488,9 @@ bool NETLIST_READER::ReadNetList( FILE* aFile, // footprint not found in library) continue; } - else /* clear pads netnames */ + else // clear pads netnames { - D_PAD* pad = m_currModule->m_Pads; - - for( ; pad != NULL; pad = pad->Next() ) + for( D_PAD* pad = m_currModule->m_Pads; pad; pad = pad->Next() ) { pad->SetNetname( wxEmptyString ); } @@ -576,7 +575,7 @@ MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) if( error ) return NULL; - /* Test if module is already loaded. */ + // Test if module is already loaded. wxString * identMod = &textCmpReference; if( m_UseTimeStamp ) @@ -590,12 +589,12 @@ MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) { nextModule = module->Next(); - if( m_UseTimeStamp ) /* identification by time stamp */ + if( m_UseTimeStamp ) // identification by time stamp { if( timeStampPath.CmpNoCase( module->m_Path ) == 0 ) found = true; } - else /* identification by Reference */ + else // identification by Reference { if( textCmpReference.CmpNoCase( module->m_Reference->m_Text ) == 0 ) found = true; @@ -696,36 +695,34 @@ MODULE* NETLIST_READER::ReadNetlistModuleDescr( char* aText, bool aTstOnly ) */ bool NETLIST_READER::SetPadNetName( char* aText ) { - D_PAD* pad; - char* TextPinName, * TextNetName; - bool found; - bool error = false; - char Line[256]; + char* p; + char line[256]; if( m_currModule == NULL ) return false; - strcpy( Line, aText ); + strncpy( line, aText, sizeof(line) ); - if( ( TextPinName = strtok( Line, " ()\t\n" ) ) == NULL ) - error = true; + if( ( p = strtok( line, " ()\t\n" ) ) == NULL ) + return false; - if( ( TextNetName = strtok( NULL, " ()\t\n" ) ) == NULL ) - error = true; + wxString pinName = FROM_UTF8( p ); - if( error ) - return 0; + if( ( p = strtok( NULL, " ()\t\n" ) ) == NULL ) + return false; - pad = m_currModule->m_Pads; - found = false; + wxString netName = FROM_UTF8( p ); - for( ; pad != NULL; pad = pad->Next() ) + bool found = false; + for( D_PAD* pad = m_currModule->m_Pads; pad; pad = pad->Next() ) { - if( strnicmp( TextPinName, pad->m_Padname, 4 ) == 0 ) + wxString padName = pad->GetPadName(); + + if( padName == pinName ) { found = true; - if( *TextNetName != '?' ) - pad->SetNetname( FROM_UTF8( TextNetName ) ); + if( (char) netName[0] != '?' ) + pad->SetNetname( netName ); else pad->SetNetname( wxEmptyString ); } @@ -736,10 +733,9 @@ bool NETLIST_READER::SetPadNetName( char* aText ) if( m_messageWindow ) { wxString msg; - wxString pin_name = FROM_UTF8( TextPinName ); msg.Printf( _( "Module [%s]: Pad [%s] not found" ), GetChars( m_currModule->m_Reference->m_Text ), - GetChars( pin_name ) ); + GetChars( pinName ) ); m_messageWindow->AppendText( msg + wxT( "\n" ) ); } } @@ -812,12 +808,12 @@ void PCB_EDIT_FRAME::Test_Duplicate_Missing_And_Extra_Footprints( return; } - /* Build the list of references of the net list modules. */ + // Build the list of references of the net list modules. NETLIST_READER netList_Reader( this ); NbModulesNetListe = netList_Reader.BuildComponentsListFromNetlist( aNetlistFullFilename, tmp ); if( NbModulesNetListe < 0 ) - return; /* File not found */ + return; // File not found if( NbModulesNetListe == 0 ) { @@ -825,7 +821,7 @@ void PCB_EDIT_FRAME::Test_Duplicate_Missing_And_Extra_Footprints( return; } - /* Search for duplicate footprints. */ + // Search for duplicate footprints. list.Add( _( "Duplicates" ) ); MODULE* module = GetBoard()->m_Modules; @@ -849,7 +845,7 @@ void PCB_EDIT_FRAME::Test_Duplicate_Missing_And_Extra_Footprints( } } - /* Search for the missing module by the net list. */ + // Search for the missing module by the net list. list.Add( _( "Missing:" ) ); for( ii = 0; ii < NbModulesNetListe; ii++ ) @@ -871,7 +867,7 @@ void PCB_EDIT_FRAME::Test_Duplicate_Missing_And_Extra_Footprints( } } - /* Search for modules not in net list. */ + // Search for modules not in net list. list.Add( _( "Not in Netlist:" ) ); module = GetBoard()->m_Modules; @@ -881,11 +877,11 @@ void PCB_EDIT_FRAME::Test_Duplicate_Missing_And_Extra_Footprints( { if( module->m_Reference->m_Text.CmpNoCase( tmp[ii] ) == 0 ) { - break; /* Module is in net list. */ + break; // Module is in net list. } } - if( ii == NbModulesNetListe ) /* Module not found in netlist */ + if( ii == NbModulesNetListe ) // Module not found in netlist { list.Add( module->m_Reference->m_Text ); nberr++; @@ -938,7 +934,7 @@ int NETLIST_READER::BuildComponentsListFromNetlist( const wxString& aNetlistFile is_comment = false; } - if( *text == '{' ) /* Comments. */ + if( *text == '{' ) // Comments. { is_comment = true; @@ -1035,7 +1031,7 @@ bool NETLIST_READER::readModuleComponentLinkfile( const wxString* aCmpIdent, if( ! buffer.StartsWith( wxT("BeginCmp") ) ) continue; - /* Begin component description. */ + // Begin component description. refcurrcmp.Empty(); idmod.Empty(); timestamp.Empty(); @@ -1130,7 +1126,7 @@ bool NETLIST_READER::loadNewModules() if( (ii == 0) || ( ref->m_LibName != cmp->m_LibName) ) { - /* New footprint : must be loaded from a library */ + // New footprint : must be loaded from a library Module = m_pcbframe->GetModuleLibrary( wxEmptyString, cmp->m_LibName, false ); ref = cmp; @@ -1167,7 +1163,7 @@ bool NETLIST_READER::loadNewModules() { // Footprint already loaded from a library, duplicate it (faster) if( Module == NULL ) - continue; /* Module does not exist in library. */ + continue; // Module does not exist in library. MODULE* newmodule = new MODULE( pcb ); newmodule->Copy( Module ); diff --git a/pcbnew/xchgmod.cpp b/pcbnew/xchgmod.cpp index f7f547dc0c..4d76866d9e 100644 --- a/pcbnew/xchgmod.cpp +++ b/pcbnew/xchgmod.cpp @@ -530,7 +530,7 @@ void PCB_EDIT_FRAME::Exchange_Module( MODULE* aOldModule, for( ; old_pad != NULL; old_pad = old_pad->Next() ) { - if( strnicmp( pad->m_Padname, old_pad->m_Padname, sizeof(pad->m_Padname) ) == 0 ) + if( pad->PadNameEqual( old_pad ) ) { pad->SetNetname( old_pad->GetNetname() ); pad->SetNet( old_pad->GetNet() );