From c291505830338e23bd7cf7a1a227f484ab15078d Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Tue, 17 Jul 2018 14:28:51 +0200 Subject: [PATCH] Gerbview, read Excellon files: fix a few issues. The main issue is the fact Excellon files have no coordinate fine format definition. Only the units are defined. Units are floating point numbers or integer numbers. Integer numbers can be defined as 3.3 or 2.4 numbers (mm/inches) However some files (altium drill files for instance) use an other notation. This fix is a workaround to accept 2.x (inch) or 3.x (mm) notations. Fixes: lp:1754121 https://bugs.launchpad.net/kicad/+bug/1754121 Fixes: lp:1782053 https://bugs.launchpad.net/kicad/+bug/1782053 --- gerbview/excellon_read_drill_file.cpp | 12 +++++++---- gerbview/gerber_file_image.h | 6 +++++- gerbview/rs274_read_XY_and_IJ_coordinates.cpp | 21 +++++++++++++++---- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/gerbview/excellon_read_drill_file.cpp b/gerbview/excellon_read_drill_file.cpp index 4eb2585216..8c7e439e16 100644 --- a/gerbview/excellon_read_drill_file.cpp +++ b/gerbview/excellon_read_drill_file.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 1992-2016 Jean-Pierre Charras - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -526,6 +526,7 @@ bool EXCELLON_IMAGE::readToolInformation( char*& aText ) return true; } + bool EXCELLON_IMAGE::Execute_Drill_Command( char*& text ) { D_CODE* tool; @@ -536,15 +537,18 @@ bool EXCELLON_IMAGE::Execute_Drill_Command( char*& text ) switch( *text ) { case 'X': - ReadXYCoord( text ); + ReadXYCoord( text, true ); break; + case 'Y': - ReadXYCoord( text ); + ReadXYCoord( text, true ); break; + case 'G': // G85 is found here for oval holes m_PreviousPos = m_CurrentPos; Execute_EXCELLON_G_Command( text ); break; + case 0: // E.O.L: execute command tool = GetDCODE( m_Current_Tool ); @@ -656,7 +660,7 @@ bool EXCELLON_IMAGE::Execute_EXCELLON_G_Command( char*& text ) switch( id ) { case DRILL_G_ZERO_SET: - ReadXYCoord( text ); + ReadXYCoord( text, true ); m_Offset = m_CurrentPos; break; diff --git a/gerbview/gerber_file_image.h b/gerbview/gerber_file_image.h index f071231d00..98f90dddc2 100644 --- a/gerbview/gerber_file_image.h +++ b/gerbview/gerber_file_image.h @@ -308,8 +308,12 @@ public: /** * Function ReadXYCoord * Returns the current coordinate type pointed to by XnnYnn Text (XnnnnYmmmm) + * @param aText is a pointer to the text to parse. + * @param aExcellonMode = true to parse a Excellon drill file. + * it force truncation of a digit string to a max len because the exact coordinate + * format is not always known */ - wxPoint ReadXYCoord( char*& Text ); + wxPoint ReadXYCoord( char*& aText, bool aExcellonMode = false ); /** * Returns the current coordinate type pointed to by InnJnn Text (InnnnJmmmm) diff --git a/gerbview/rs274_read_XY_and_IJ_coordinates.cpp b/gerbview/rs274_read_XY_and_IJ_coordinates.cpp index 2c39687524..429f7e4de7 100644 --- a/gerbview/rs274_read_XY_and_IJ_coordinates.cpp +++ b/gerbview/rs274_read_XY_and_IJ_coordinates.cpp @@ -69,7 +69,7 @@ int scaletoIU( double aCoord, bool isMetric ) } -wxPoint GERBER_FILE_IMAGE::ReadXYCoord( char*& Text ) +wxPoint GERBER_FILE_IMAGE::ReadXYCoord( char*& Text, bool aExcellonMode ) { wxPoint pos; int type_coord = 0, current_coord, nbdigits; @@ -123,14 +123,27 @@ wxPoint GERBER_FILE_IMAGE::ReadXYCoord( char*& Text ) if( m_NoTrailingZeros ) { - int min_digit = - (type_coord == 'X') ? m_FmtLen.x : m_FmtLen.y; - while( nbdigits < min_digit ) + // no trailing zero format, we need to add missing zeros. + int digit_count = (type_coord == 'X') ? m_FmtLen.x : m_FmtLen.y; + + while( nbdigits < digit_count ) { *(text++) = '0'; nbdigits++; } + if( aExcellonMode ) + { + // Truncate the extra digits if the len is more than expected + // because the conversion to internal units expect exactly + // digit_count digits + while( nbdigits > digit_count ) + { + *(text--) = 0; + nbdigits--; + } + } + *text = 0; }