diff --git a/gerbview/class_X2_gerber_attributes.cpp b/gerbview/class_X2_gerber_attributes.cpp index 52a00f88a3..8184c91565 100644 --- a/gerbview/class_X2_gerber_attributes.cpp +++ b/gerbview/class_X2_gerber_attributes.cpp @@ -74,13 +74,13 @@ const wxString& X2_ATTRIBUTE::GetPrm( int aIdx) { static const wxString dummy; - if( GetPrmCount() < aIdx && aIdx >= 0 ) + if( GetPrmCount() > aIdx && aIdx >= 0 ) return m_Prms.Item( aIdx ); return dummy; } -// Debug function: pring using wxLogMessage le list of parameters +// Debug function: pring using wxLogMessage the list of parameters void X2_ATTRIBUTE::DbgListPrms() { wxLogMessage( wxT("prms count %d"), GetPrmCount() ); diff --git a/gerbview/class_gerber_draw_item.cpp b/gerbview/class_gerber_draw_item.cpp index e5593eaf68..b93935c907 100644 --- a/gerbview/class_gerber_draw_item.cpp +++ b/gerbview/class_gerber_draw_item.cpp @@ -516,6 +516,35 @@ void GERBER_DRAW_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) // Display AB axis swap (item specific) msg = m_swapAxis ? wxT( "A=Y B=X" ) : wxT( "A=X B=Y" ); aList.push_back( MSG_PANEL_ITEM( _( "AB axis" ), msg, DARKRED ) ); + + // Display net info, if exists + switch( m_NetAttribute.m_TypeNetAttribute ) + { + default: + case 0: + break; + + case 1: // .CN attribute + { + msg = _( "Net:" ); + msg << " " << m_NetAttribute.m_NetAttrNetname; + wxString text; + text.Printf( _( "Pad: '%s' (Cmp: '%s')" ), GetChars( m_NetAttribute.m_NetAttrPadname ), + GetChars( m_NetAttribute.m_NetAttrCmpReference ) ); + aList.push_back( MSG_PANEL_ITEM( msg, text, CYAN ) ); + } + break; + + case 2: // .N attribute + aList.push_back( MSG_PANEL_ITEM( _( "Net name:" ), + m_NetAttribute.m_NetAttrNetname, CYAN ) ); + break; + + case 3: // .C attribute + aList.push_back( MSG_PANEL_ITEM( _( "Cmp reference:" ), + m_NetAttribute.m_NetAttrCmpReference, CYAN ) ); + break; + } } diff --git a/gerbview/class_gerber_draw_item.h b/gerbview/class_gerber_draw_item.h index 6e468583ce..acad975724 100644 --- a/gerbview/class_gerber_draw_item.h +++ b/gerbview/class_gerber_draw_item.h @@ -33,6 +33,7 @@ #include #include #include +#include class GERBER_FILE_IMAGE; class GBR_LAYOUT; @@ -90,6 +91,10 @@ public: * so they are stored inside this item if there is no * redundancy for these parameters */ + NET_ATTRIBUTES m_NetAttribute; ///< the string given by a %TO attribute set in aperture + ///< (dcode). Stored in each item, because %TO is + ///< a dynamic attribute + private: // These values are used to draw this item, according to gerber layers parameters // Because they can change inside a gerber image, they are stored here diff --git a/gerbview/dcode.cpp b/gerbview/dcode.cpp index e6c8954d18..992cf9cf53 100644 --- a/gerbview/dcode.cpp +++ b/gerbview/dcode.cpp @@ -1,9 +1,9 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2009 Jean-Pierre Charras, jean-pierre.charras@gipsa-lab.inpg.fr + * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2011 Wayne Stambaugh - * Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2016 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 diff --git a/gerbview/dcode.h b/gerbview/dcode.h index f92cadd06e..0a643e0647 100644 --- a/gerbview/dcode.h +++ b/gerbview/dcode.h @@ -70,10 +70,32 @@ enum APERTURE_DEF_HOLETYPE { struct APERTURE_MACRO; +// helper class to handle a net attribute for a given D_CODE +// net attributesare given by the %TO command following a Dn command (n >= 10) +// This net attribute is dynamic, so it need to be also stored in each gerber item +struct NET_ATTRIBUTES +{ + int m_TypeNetAttribute; ///< identify %TO.N %TO.C or TO.CN net attribute + ///< 0 = no attribute, 1 = .CN, 2 =.N 3=.C + wxString m_NetAttrNetname; + wxString m_NetAttrPadname; + wxString m_NetAttrCmpReference; + + NET_ATTRIBUTES(): m_TypeNetAttribute( 0 ) {} + + void RemoveAttribute() ///< Clear all strings + { + m_TypeNetAttribute = 0; // no attribute + m_NetAttrNetname.Empty(); + m_NetAttrPadname.Empty(); + m_NetAttrCmpReference.Empty(); + } +}; + /** * Class D_CODE - * holds a gerber DCODE definition. + * holds a gerber DCODE (also called Aperture) definition. */ class D_CODE { @@ -92,16 +114,19 @@ private: */ public: - wxSize m_Size; /* Horizontal and vertical dimensions. */ - APERTURE_T m_Shape; /* shape ( Line, rectangle, circle , oval .. ) */ - int m_Num_Dcode; /* D code ( >= 10 ) */ - wxSize m_Drill; /* dimension of the hole (if any) */ - APERTURE_DEF_HOLETYPE m_DrillShape; /* shape of the hole (0 = no hole, round = 1, rect = 2) */ - double m_Rotation; /* shape rotation in degrees */ - int m_EdgesCount; /* in aperture definition Polygon only: number of edges for the polygon */ - bool m_InUse; /* false if not used */ - bool m_Defined; /* false if not defined */ - wxString m_SpecialDescr; + wxSize m_Size; ///< Horizontal and vertical dimensions. + APERTURE_T m_Shape; ///< shape ( Line, rectangle, circle , oval .. ) + int m_Num_Dcode; ///< D code value ( >= 10 ) + wxSize m_Drill; ///< dimension of the hole (if any) (draill file) + APERTURE_DEF_HOLETYPE m_DrillShape; ///< shape of the hole (0 = no hole, round = 1, rect = 2) */ + double m_Rotation; ///< shape rotation in degrees + int m_EdgesCount; ///< in aperture definition Polygon only: + ///< number of edges for the polygon + bool m_InUse; ///< false if the aperure (previously defined) + ///< is not used to draw something + bool m_Defined; ///< false if the aperture is not defined in the header + NET_ATTRIBUTES m_NetAttribute; ///< the dynamic net info currently attached to the D_CODE + public: D_CODE( int num_dcode ); diff --git a/gerbview/rs274d.cpp b/gerbview/rs274d.cpp index 158bf82a63..035a665025 100644 --- a/gerbview/rs274d.cpp +++ b/gerbview/rs274d.cpp @@ -118,6 +118,12 @@ void fillFlashedGBRITEM( GERBER_DRAW_ITEM* aGbrItem, aGbrItem->m_DCode = Dcode_index; aGbrItem->SetLayerPolarity( aLayerNegative ); aGbrItem->m_Flashed = true; + + D_CODE* aperture = aGbrItem->GetDcodeDescr(); + + if( aperture ) + aGbrItem->m_NetAttribute = aperture->m_NetAttribute; + switch( aAperture ) { case APT_POLYGON: // flashed regular polygon @@ -172,6 +178,11 @@ void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem, aGbrItem->m_DCode = Dcode_index; aGbrItem->SetLayerPolarity( aLayerNegative ); + + D_CODE* aperture = aGbrItem->GetDcodeDescr(); + + if( aperture ) + aGbrItem->m_NetAttribute = aperture->m_NetAttribute; } @@ -217,6 +228,11 @@ static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, aGbrItem->m_Size = aPenSize; aGbrItem->m_Flashed = false; + D_CODE* aperture = aGbrItem->GetDcodeDescr(); + + if( aperture ) + aGbrItem->m_NetAttribute = aperture->m_NetAttribute; + if( aMultiquadrant ) center = aStart + aRelCenter; else diff --git a/gerbview/rs274x.cpp b/gerbview/rs274x.cpp index e0d90fb71d..822034739d 100644 --- a/gerbview/rs274x.cpp +++ b/gerbview/rs274x.cpp @@ -82,10 +82,23 @@ enum RS274X_PARAMETERS { // X2 extention attribute commands // Mainly are found standard attributes and user attributes // standard attributes commands are: - // TF (file attribute) + // TF (file attribute) TO (net attribute) // TA (aperture attribute) and TD (delete aperture attribute) FILE_ATTRIBUTE = CODE( 'T', 'F' ), + // X2 extention Net attribute info + // Net attribute options are: + // TO (net attribute data): TO.CN ot TO.N or TO.C + NET_ATTRIBUTE = CODE( 'T', 'O' ), + + // X2 extention Aperture attribute TA + APERTURE_ATTRIBUTE = CODE( 'T', 'A' ), + + // TD (delete aperture attribute): TD (delete all) or TD.CN or TD.N or TD.C ... + // due to not yet fully defined, + // TD TD.CNr TD.N TD.C are delete all + REMOVE_APERTURE_ATTRIBUTE = CODE( 'T', 'D' ), + // Layer specific parameters // May be used singly or may be layer specfic // theses parameters are at the beginning of the file or layer @@ -127,6 +140,46 @@ static int ReadXCommand( char*& text ) return result; } +/** + * convert a string read from a gerber file to an unicode string + * usual chars are just copied. \hhhh values are converted to + * the unicoade char value + */ +static const wxString fromGerberString( const wxString& aGbrString ) +{ + wxString text; + + for( unsigned ii = 0; ii < aGbrString.size(); ++ii ) + { + if( aGbrString[ii] == '\\' ) + { + unsigned value = 0; + + for( int jj = 0; jj < 4; jj++ ) + { + ii++; + value <<= 4; + int digit = aGbrString[ii]; + + if( digit >= '0' && digit <= '9' ) + digit -= '0'; + else if( digit >= 'A' && digit <= 'F' ) + digit -= 'A'; + else if( digit >= 'a' && digit <= 'f' ) + digit -= 'a'; + else digit = 0; + + value += digit && 0xFF; + } + + text.Append( wxUniChar( value ) ); + } + else + text.Append( aGbrString[ii] ); + } + + return text; +} bool GERBER_FILE_IMAGE::ReadRS274XCommand( char* buff, char*& text ) { @@ -352,6 +405,7 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int command, char* buff, char*& te { X2_ATTRIBUTE dummy; dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text ); + if( dummy.IsFileFunction() ) { delete m_FileFunction; @@ -368,6 +422,49 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int command, char* buff, char*& te } break; + case APERTURE_ATTRIBUTE: // Command %TA ... Not yet supported + { + X2_ATTRIBUTE dummy; + dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text ); + } + break; + + case NET_ATTRIBUTE: // Command %TO ... + { + X2_ATTRIBUTE dummy; + dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text ); + D_CODE* tool = GetDCODE( m_Current_Tool, false ); + tool->m_NetAttribute.RemoveAttribute(); + + if( dummy.GetAttribute() == ".CN" ) + { + tool->m_NetAttribute.m_TypeNetAttribute = 1; + tool->m_NetAttribute.m_NetAttrCmpReference = fromGerberString( dummy.GetPrm( 1 ) ); + tool->m_NetAttribute.m_NetAttrPadname = fromGerberString( dummy.GetPrm( 2 ) ); + tool->m_NetAttribute.m_NetAttrNetname = fromGerberString( dummy.GetPrm( 3 ) ); + } + else if( dummy.GetAttribute() == ".N" ) + { + tool->m_NetAttribute.m_TypeNetAttribute = 2; + tool->m_NetAttribute.m_NetAttrNetname = fromGerberString( dummy.GetPrm( 1 ) ); + } + else if( dummy.GetAttribute() == ".C" ) + { + tool->m_NetAttribute.m_TypeNetAttribute = 3; + tool->m_NetAttribute.m_NetAttrCmpReference = fromGerberString( dummy.GetPrm( 1 ) ); + } + } + break; + + case REMOVE_APERTURE_ATTRIBUTE: // Command %TD ... + { + X2_ATTRIBUTE dummy; + dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text ); + D_CODE* tool = GetDCODE( m_Current_Tool, false ); + tool->m_NetAttribute.RemoveAttribute(); + } + break; + case OFFSET: // command: OFAnnBnn (nn = float number) = layer Offset m_Offset.x = m_Offset.y = 0; while( *text != '*' )