|
|
/*
* This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2010-2014 Jean-Pierre Charras jp.charras at wanadoo.fr * Copyright (C) 1992-2014 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 */
/**
* @file X2_gerber_attributes.cpp */
/*
* Manage the gerber extensions (attributes) in the new X2 version * only few extensions are handled * See http://www.ucamco.com/files/downloads/file/81/the_gerber_file_format_specification.pdf
* * gerber attributes in the new X2 version look like: * %TF.FileFunction,Copper,L1,Top*% * * Currently: * .FileFunction .FileFunction Identifies the file's function in the PCB. * Other Standard Attributes, not yet used in Gerbview: * .Part Identifies the part the file represents, e.g. a single PCB * .MD5 Sets the MD5 file signature or checksum. */
#include <wx/log.h>
#include <X2_gerber_attributes.h>
#include <macros.h>
/*
* X2_ATTRIBUTE * The attribute value consists of a number of substrings separated by a comma */
X2_ATTRIBUTE::X2_ATTRIBUTE(){}
X2_ATTRIBUTE::~X2_ATTRIBUTE(){}
/* return the attribute name (for instance .FileFunction)
* which is given by TF command. */const wxString& X2_ATTRIBUTE::GetAttribute(){ return m_Prms.Item( 0 );}
/* return a parameter
* aIdx = the index of the parameter * aIdx = 0 is the parameter read after the TF function * (the same as GetAttribute()) */const wxString& X2_ATTRIBUTE::GetPrm( int aIdx){ static const wxString dummy;
if( GetPrmCount() > aIdx && aIdx >= 0 ) return m_Prms.Item( aIdx );
return dummy;}
// Debug function: pring using wxLogMessage the list of parameters
void X2_ATTRIBUTE::DbgListPrms(){ wxLogMessage( wxT("prms count %d"), GetPrmCount() );
for( int ii = 0; ii < GetPrmCount(); ii++ ) wxLogMessage( m_Prms.Item( ii ) );}
bool X2_ATTRIBUTE::ParseAttribCmd( FILE* aFile, char *aBuffer, int aBuffSize, char* &aText, int& aLineNum ){ // parse a TF, TA, TO ... command and fill m_Prms by the parameters found.
// the "%TF" (start of command) is already read by the caller
bool ok = true; std::string data;
for( ; ; ) { while( *aText ) { switch( *aText ) { case '%': // end of command
return ok; // success completion
case ' ': case '\r': case '\n': aText++; break;
case '*': // End of block
m_Prms.Add( FROM_UTF8( data.c_str() ) ); data.clear(); aText++; break;
case ',': // End of parameter (separator)
aText++; m_Prms.Add( FROM_UTF8( data.c_str() ) ); data.clear(); break;
default: data += *aText; aText++; break; } }
// end of current line, read another one.
if( aBuffer && aFile ) { if( fgets( aBuffer, aBuffSize, aFile ) == NULL ) { // end of file
ok = false; break; }
aLineNum++; aText = aBuffer; } else return ok; }
return ok;}
/*
* X2_ATTRIBUTE_FILEFUNCTION ( from %TF.FileFunction in Gerber file) * Example file function: * %TF.FileFunction,Copper,L1,Top*% * - Type. Such as copper, solder mask etc. * - Position. Specifies where the file appears in the PCB layer structure. * Corresponding position substring: * Copper layer: L1, L2, L3...to indicate the layer position followed by Top, Inr or * Bot. L1 is always the top copper layer. E.g. L2,Inr. * Extra layer, e.g. solder mask: Top or Bot - defines the attachment of the layer. * Drill/rout layer: E.g. 1,4 - where 1 is the start and 4 is the end copper layer. The * pair 1,4 defines the span of the drill/rout file * Optional index. This can be used in instances where for example there are two solder * masks on the same side. The index counts from the PCB surface outwards. */X2_ATTRIBUTE_FILEFUNCTION::X2_ATTRIBUTE_FILEFUNCTION( X2_ATTRIBUTE& aAttributeBase ) : X2_ATTRIBUTE(){ m_Prms = aAttributeBase.GetPrms(); m_z_order = 0;
// ensure at least 7 parameters exist.
while( GetPrmCount() < 7 ) m_Prms.Add( wxEmptyString );
set_Z_Order();}
const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetFileType(){ // the type of layer (Copper, Soldermask ... )
return m_Prms.Item( 1 );}
const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetBrdLayerId(){ // the brd layer identifier: Ln (for Copper type) or Top, Bot
return m_Prms.Item( 2 );}
const wxString X2_ATTRIBUTE_FILEFUNCTION::GetDrillLayerPair(){ // the layer pair identifiers, for drill files, i.e.
// with m_Prms.Item( 1 ) = "Plated" or "NonPlated"
wxString lpair = m_Prms.Item( 2 ) + ',' + m_Prms.Item( 3 ); return lpair;}
const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetBrdLayerSide(){ if( IsCopper() ) // the brd layer identifier: Top, Bot, Inr
return m_Prms.Item( 3 ); else // the brd layer identifier: Top, Bot ( same as GetBrdLayerId() )
return m_Prms.Item( 2 );}
const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetLabel(){ if( IsCopper() ) return m_Prms.Item( 4 ); else return m_Prms.Item( 3 );}
const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetLPType(){ // Only for drill files: the Layer Pair type (PTH, NPTH, Blind or Buried)
return m_Prms.Item( 4 );}
const wxString& X2_ATTRIBUTE_FILEFUNCTION::GetRouteType(){ // Only for drill files: the drill/routing type(Drill, Route, Mixed)
return m_Prms.Item( 5 );}
bool X2_ATTRIBUTE_FILEFUNCTION::IsCopper(){ // the filefunction label, if any
return GetFileType().IsSameAs( wxT( "Copper" ), false );}
bool X2_ATTRIBUTE_FILEFUNCTION::IsDrillFile(){ // the filefunction label, if any
return GetFileType().IsSameAs( wxT( "Plated" ), false ) || GetFileType().IsSameAs( wxT( "NonPlated" ), false );}
// Initialize the z order priority of the current file, from its attributes
// this priority is the order of layers from top to bottom to draw/display gerber images
// Stack up is( from external copper layer to external)
// copper, then solder paste, then solder mask, then silk screen.
// and global stackup is Front (top) layers then internal copper layers then Back (bottom) layers
void X2_ATTRIBUTE_FILEFUNCTION::set_Z_Order(){ m_z_order = -100; // low level
m_z_sub_order = 0;
if( IsCopper() ) { // Copper layer: the priority is the layer Id
m_z_order = 0; wxString num = GetBrdLayerId().Mid( 1 ); long lnum; if( num.ToLong( &lnum ) ) m_z_sub_order = -lnum; }
if( GetFileType().IsSameAs( wxT( "Paste" ), false ) ) { // solder paste layer: the priority is top then bottom
m_z_order = 1; // for top
if( GetBrdLayerId().IsSameAs( wxT( "Bot" ), false ) ) m_z_order = -m_z_order; }
if( GetFileType().IsSameAs( wxT( "Soldermask" ), false ) ) { // solder mask layer: the priority is top then bottom
m_z_order = 2; // for top
if( GetBrdLayerId().IsSameAs( wxT( "Bot" ), false ) ) m_z_order = -m_z_order; }
if( GetFileType().IsSameAs( wxT( "Legend" ), false ) ) { // Silk screen layer: the priority is top then bottom
m_z_order = 3; // for top
if( GetBrdLayerId().IsSameAs( wxT( "Bot" ), false ) ) m_z_order = -m_z_order; }
if( GetFileType().IsSameAs( wxT( "Glue" ), false ) ) { // Glue spots used to fix components to the board prior to soldering:
// the priority is top then bottom
m_z_order = 4; // for top
if( GetBrdLayerId().IsSameAs( wxT( "Bot" ), false ) ) m_z_order = -m_z_order; }}
|