From 984146c37d63e3903966c32c95998168406b1c03 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Mon, 1 Aug 2016 19:47:35 +0200 Subject: [PATCH] Gerbview: better support of advanced X2 attributes. --- gerbview/attributes.h | 112 +++++++++++++++++++++++++++ gerbview/class_gerber_draw_item.cpp | 47 +++++++---- gerbview/class_gerber_draw_item.h | 5 +- gerbview/class_gerber_file_image.cpp | 16 ++++ gerbview/class_gerber_file_image.h | 19 +++++ gerbview/dcode.h | 25 +----- gerbview/rs274d.cpp | 18 ++--- gerbview/rs274x.cpp | 49 ++++++++---- 8 files changed, 221 insertions(+), 70 deletions(-) create mode 100644 gerbview/attributes.h diff --git a/gerbview/attributes.h b/gerbview/attributes.h new file mode 100644 index 0000000000..f5d9301fea --- /dev/null +++ b/gerbview/attributes.h @@ -0,0 +1,112 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2010-2016 Jean-Pierre Charras jp.charras at wanadoo.fr + * 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 + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef ATTRIBUTES_H +#define ATTRIBUTES_H + + +// this class handle info which can be added in a gerber file as attribute +// of an obtect +// the GBR_INFO_TYPE types can be OR'ed to add 2 (or more) attributes +// There are only 3 net attributes attached to an object by the %TO command +// %TO.CN +// %TO.N +// %TO.C +// the .CN attribute can be used only for flashed pads (using the D03 command) +// and only for external copper layers, if the component is on a external copper layer +// for other copper layer items (pads on internal layers, tracks ... ), only .N and .C +// can be used +class GBR_NETLIST_METADATA +{ +public: + enum GBR_NETINFO_TYPE + { + GBR_NETINFO_UNSPECIFIED, ///< idle command (no command) + GBR_NETINFO_FLASHED_PAD, ///< print info associated to a flashed pad (TO.CN attribute) + GBR_NETINFO_NET, ///< print info associated to a net (TO.N attribute) + GBR_NETINFO_COMPONENT, ///< print info associated to a footprint (TO.C attribute) + GBR_NETINFO_NET_AND_CMP ///< combine GBR_INFO_NET and GBR_INFO_NET_AND_COMPONENT + ///< to add both TO.N and TO.C attributes + }; + + // these members are used in the %TO object attributes command. + GBR_NETINFO_TYPE m_NetAttribType; ///< the type of net info + ///< (used to define the gerber string to create) + wxString m_Padname; ///< for a flashed pad: the pad name ((TO.CN attribute) + wxString m_ComponentRef; ///< the footprint reference parent of the data + wxString m_Netname; ///< for items associated to a net: the netname + + GBR_NETLIST_METADATA(): m_NetAttribType( GBR_NETINFO_UNSPECIFIED ) + { + } + + /* + * remove the net attribute specified by aName + * If aName == NULL or empty, remove all attributes + */ + void ClearAttribute( const wxString* aName ) + { + if( m_NetAttribType == GBR_NETLIST_METADATA::GBR_NETINFO_UNSPECIFIED ) + return; + + if( !aName || aName->IsEmpty() ) + { + m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_UNSPECIFIED; + m_Padname.clear(); + m_ComponentRef.clear(); + m_Netname.clear(); + } + + if( aName && *aName == ".CN" ) + { + m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_UNSPECIFIED; + m_Padname.clear(); + m_ComponentRef.clear(); + m_Netname.clear(); + } + + if( aName && *aName == ".C" ) + { + if( m_NetAttribType == GBR_NETINFO_COMPONENT ) + m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_UNSPECIFIED; + else + m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_NET; + + m_ComponentRef.clear(); + } + + if( aName && *aName == ".N" ) + { + if( m_NetAttribType == GBR_NETINFO_NET ) + m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_UNSPECIFIED; + else + m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_COMPONENT; + + m_Netname.clear(); + } + } +}; + + +#endif // #define ATTRIBUTES_H diff --git a/gerbview/class_gerber_draw_item.cpp b/gerbview/class_gerber_draw_item.cpp index b93935c907..806b2e81f4 100644 --- a/gerbview/class_gerber_draw_item.cpp +++ b/gerbview/class_gerber_draw_item.cpp @@ -484,13 +484,21 @@ void GERBER_DRAW_ITEM::DrawGbrPoly( EDA_RECT* aClipBox, void GERBER_DRAW_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) { wxString msg; + wxString text; msg = ShowGBRShape(); aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, DARKCYAN ) ); // Display D_Code value: - msg.Printf( wxT( "%d" ), m_DCode ); - aList.push_back( MSG_PANEL_ITEM( _( "D Code" ), msg, RED ) ); + msg.Printf( _( "D Code %d" ), m_DCode ); + D_CODE* apertDescr = GetDcodeDescr(); + + if( apertDescr->m_AperFunction.IsEmpty() ) + text = _( "No attribute" ); + else + text = apertDescr->m_AperFunction; + + aList.push_back( MSG_PANEL_ITEM( msg, text, RED ) ); // Display graphic layer number msg.Printf( wxT( "%d" ), GetLayer() + 1 ); @@ -518,31 +526,36 @@ void GERBER_DRAW_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList ) aList.push_back( MSG_PANEL_ITEM( _( "AB axis" ), msg, DARKRED ) ); // Display net info, if exists - switch( m_NetAttribute.m_TypeNetAttribute ) + switch( m_NetAttribute.m_NetAttribType ) { default: - case 0: + case GBR_NETLIST_METADATA::GBR_NETINFO_UNSPECIFIED: break; - case 1: // .CN attribute - { + case GBR_NETLIST_METADATA::GBR_NETINFO_FLASHED_PAD: // .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 ) ); + msg << " " << m_NetAttribute.m_Netname; + text.Printf( _( "Pad: '%s' (Cmp: '%s')" ), GetChars( m_NetAttribute.m_Padname ), + GetChars( m_NetAttribute.m_ComponentRef ) ); 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 ) ); + case GBR_NETLIST_METADATA::GBR_NETINFO_NET: // .N attribute + aList.push_back( MSG_PANEL_ITEM( _( "Net:" ), + m_NetAttribute.m_Netname, CYAN ) ); break; - case 3: // .C attribute - aList.push_back( MSG_PANEL_ITEM( _( "Cmp reference:" ), - m_NetAttribute.m_NetAttrCmpReference, CYAN ) ); + case GBR_NETLIST_METADATA::GBR_NETINFO_COMPONENT: // .C attribute + aList.push_back( MSG_PANEL_ITEM( _( "Ref:" ), + m_NetAttribute.m_ComponentRef, CYAN ) ); + break; + + case GBR_NETLIST_METADATA::GBR_NETINFO_NET_AND_CMP: // .C and .N attribute + msg = _( "Net:" ); + msg << " " << m_NetAttribute.m_Netname; + text =_( "Ref:" ); + text << m_NetAttribute.m_ComponentRef; + aList.push_back( MSG_PANEL_ITEM( msg, text, CYAN ) ); break; } } diff --git a/gerbview/class_gerber_draw_item.h b/gerbview/class_gerber_draw_item.h index acad975724..1c321ec4f1 100644 --- a/gerbview/class_gerber_draw_item.h +++ b/gerbview/class_gerber_draw_item.h @@ -33,6 +33,7 @@ #include #include #include +#include #include class GERBER_FILE_IMAGE; @@ -91,9 +92,9 @@ 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 + GBR_NETLIST_METADATA m_NetAttribute; ///< the string given by a %TO attribute set in aperture ///< (dcode). Stored in each item, because %TO is - ///< a dynamic attribute + ///< a dynamic object attribute private: // These values are used to draw this item, according to gerber layers parameters diff --git a/gerbview/class_gerber_file_image.cpp b/gerbview/class_gerber_file_image.cpp index 6d21aa1e69..00b63b5365 100644 --- a/gerbview/class_gerber_file_image.cpp +++ b/gerbview/class_gerber_file_image.cpp @@ -358,3 +358,19 @@ void GERBER_FILE_IMAGE::DisplayImageInfo( GERBVIEW_FRAME* aMainFrame ) aMainFrame->AppendMsgPanel( _( "Image Justify Offset" ), msg, DARKRED ); } + + +void GERBER_FILE_IMAGE::RemoveAttribute( X2_ATTRIBUTE& aAttribute ) +{ + /* Called when a %TD command is found + * Remove the attribute specified by the %TD command. + * is no attribute, all current attributes specified by the %TO and the %TA + * commands are cleared. + * if a attribute name is specified (for instance %TD.CN*%) is specified, + * only this attribute is cleared + */ + m_NetAttributeDict.ClearAttribute( &aAttribute.GetPrm( 1 ) ); + + if( aAttribute.GetPrm( 1 ).IsEmpty() || aAttribute.GetPrm( 1 ) == ".AperFunction" ) + m_AperFunction.Clear(); +} diff --git a/gerbview/class_gerber_file_image.h b/gerbview/class_gerber_file_image.h index f7be3575ed..15cd6df7e9 100644 --- a/gerbview/class_gerber_file_image.h +++ b/gerbview/class_gerber_file_image.h @@ -31,6 +31,7 @@ #include #include #include +#include // An useful macro used when reading gerber files; #define IsNumber( x ) ( ( ( (x) >= '0' ) && ( (x) <='9' ) ) \ @@ -61,8 +62,10 @@ class D_CODE; */ class GERBER_FILE_IMAGE; +class X2_ATTRIBUTE; class X2_ATTRIBUTE_FILEFUNCTION; + class GERBER_LAYER { friend class GERBER_FILE_IMAGE; @@ -158,6 +161,10 @@ public: APERTURE_MACRO_SET m_aperture_macros; ///< a collection of APERTURE_MACROS, sorted by name + GBR_NETLIST_METADATA m_NetAttributeDict; // the net attributes set by a %TO.CN, %TO.C and/or %TO.N + // add object attribute command. + wxString m_AperFunction; // the aperture function set by a %TA.AperFunction, xxx + // (stores thre xxx value). private: wxArrayString m_messagesList; // A list of messages created when reading a file int m_hasNegativeItems; // true if the image is negative or has some negative items @@ -330,6 +337,18 @@ public: * @param aMainFrame = the GERBVIEW_FRAME to display messages */ void DisplayImageInfo( GERBVIEW_FRAME* aMainFrame ); + + /** + * Function RemoveAttribute. + * Called when a %TD command is found the Gerber file + * @param aAttribute is the X2_ATTRIBUTE which stores the full command + * Remove the attribute specified by the %TD command. + * is no attribute, all current attributes specified by the %TO and the %TA + * commands are cleared. + * if a attribute name is specified (for instance %TD.CN*%) is specified, + * only this attribute is cleared + */ + void RemoveAttribute( X2_ATTRIBUTE& aAttribute ); }; #endif // ifndef CLASS_GERBER_FILE_IMAGE_H diff --git a/gerbview/dcode.h b/gerbview/dcode.h index 0a643e0647..d809848dc0 100644 --- a/gerbview/dcode.h +++ b/gerbview/dcode.h @@ -70,28 +70,6 @@ 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 @@ -125,7 +103,8 @@ public: 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 + wxString m_AperFunction; ///< the aperture attribute (created by a %TA.AperFunction command) + ///< attached to the D_CODE public: diff --git a/gerbview/rs274d.cpp b/gerbview/rs274d.cpp index 035a665025..b54a204ca4 100644 --- a/gerbview/rs274d.cpp +++ b/gerbview/rs274d.cpp @@ -118,11 +118,7 @@ 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; + aGbrItem->m_NetAttribute = aGbrItem->m_GerberImageFile->m_NetAttributeDict; switch( aAperture ) { @@ -179,10 +175,7 @@ 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; + aGbrItem->m_NetAttribute = aGbrItem->m_GerberImageFile->m_NetAttributeDict; } @@ -228,10 +221,7 @@ 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; + aGbrItem->m_NetAttribute = aGbrItem->m_GerberImageFile->m_NetAttributeDict; if( aMultiquadrant ) center = aStart + aRelCenter; @@ -362,6 +352,8 @@ static void fillArcPOLY( GERBER_DRAW_ITEM* aGbrItem, aStart, aEnd, rel_center, wxSize(0, 0), aClockwise, aMultiquadrant, aLayerNegative ); + aGbrItem->m_NetAttribute = aGbrItem->m_GerberImageFile->m_NetAttributeDict; + wxPoint center; center = dummyGbrItem.m_ArcCentre; diff --git a/gerbview/rs274x.cpp b/gerbview/rs274x.cpp index 822034739d..21f859b394 100644 --- a/gerbview/rs274x.cpp +++ b/gerbview/rs274x.cpp @@ -126,14 +126,21 @@ enum RS274X_PARAMETERS { static int ReadXCommand( char*& text ) { int result; + int currbyte; if( text && *text ) - result = *text++ << 8; + { + currbyte = *text++; + result = ( currbyte & 0xFF ) << 8; + } else return -1; if( text && *text ) - result += *text++; + { + currbyte = *text++; + result += currbyte & 0xFF; + } else return -1; @@ -426,32 +433,42 @@ 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.GetAttribute() == ".AperFunction" ) + m_AperFunction = dummy.GetPrm( 1 ); } break; - case NET_ATTRIBUTE: // Command %TO ... + case NET_ATTRIBUTE: // Command %TO currently %TO.CN %TO.N and %TO.C { 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 ) ); + m_NetAttributeDict.m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_FLASHED_PAD; + m_NetAttributeDict.m_ComponentRef = fromGerberString( dummy.GetPrm( 1 ) ); + m_NetAttributeDict.m_Padname = fromGerberString( dummy.GetPrm( 2 ) ); + m_NetAttributeDict.m_Netname = fromGerberString( dummy.GetPrm( 3 ) ); } else if( dummy.GetAttribute() == ".N" ) { - tool->m_NetAttribute.m_TypeNetAttribute = 2; - tool->m_NetAttribute.m_NetAttrNetname = fromGerberString( dummy.GetPrm( 1 ) ); + if( m_NetAttributeDict.m_NetAttribType == GBR_NETLIST_METADATA::GBR_NETINFO_COMPONENT ) + m_NetAttributeDict.m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_NET_AND_CMP; + else + m_NetAttributeDict.m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_NET; + + m_NetAttributeDict.m_Netname = fromGerberString( dummy.GetPrm( 1 ) ); } else if( dummy.GetAttribute() == ".C" ) { - tool->m_NetAttribute.m_TypeNetAttribute = 3; - tool->m_NetAttribute.m_NetAttrCmpReference = fromGerberString( dummy.GetPrm( 1 ) ); + if( m_NetAttributeDict.m_NetAttribType == GBR_NETLIST_METADATA::GBR_NETINFO_NET ) + m_NetAttributeDict.m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_NET_AND_CMP; + else + m_NetAttributeDict.m_NetAttribType = GBR_NETLIST_METADATA::GBR_NETINFO_COMPONENT; + + m_NetAttributeDict.m_ComponentRef = fromGerberString( dummy.GetPrm( 1 ) ); } } break; @@ -460,8 +477,7 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int command, char* buff, char*& te { X2_ATTRIBUTE dummy; dummy.ParseAttribCmd( m_Current_File, buff, GERBER_BUFZ, text ); - D_CODE* tool = GetDCODE( m_Current_Tool, false ); - tool->m_NetAttribute.RemoveAttribute(); + RemoveAttribute( dummy ); } break; @@ -739,9 +755,12 @@ bool GERBER_FILE_IMAGE::ExecuteRS274XCommand( int command, char* buff, char*& te D_CODE* dcode; dcode = GetDCODE( code ); + if( dcode == NULL ) break; + dcode->m_AperFunction = m_AperFunction; + // at this point, text points to character after the ADD, // i.e. R in example above. If text[0] is one of the usual // apertures: (C,R,O,P), there is a comma after it.