You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							310 lines
						
					
					
						
							8.9 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							310 lines
						
					
					
						
							8.9 KiB
						
					
					
				| /* | |
|  * 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; | |
|     } | |
| } | |
| 
 |