KiCad PCB EDA Suite
class_gerber_file_image.cpp
Go to the documentation of this file.
1 
6 /*
7  * This program source code file is part of KiCad, a free EDA CAD application.
8  *
9  * Copyright (C) 1992-2016 Jean-Pierre Charras jp.charras at wanadoo.fr
10  * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, you may find one here:
24  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
25  * or you may search the http://www.gnu.org website for the version 2 license,
26  * or you may write to the Free Software Foundation, Inc.,
27  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
28  */
29 
30 #include <fctsys.h>
31 #include <common.h>
32 #include <class_drawpanel.h>
33 #include <macros.h>
34 #include <convert_to_biu.h>
35 
36 #include <gerbview.h>
37 #include <gerbview_frame.h>
40 
41 #include <algorithm>
42 #include <map>
43 
44 
49 extern int scaletoIU( double aCoord, bool isMetric ); // defined it rs274d_read_XY_and_IJ_coordiantes.cpp
50 
51 /* Format Gerber: NOTES:
52  * Tools and D_CODES
53  * tool number (identification of shapes)
54  * 1 to 999
55  *
56  * D_CODES:
57  * D01 ... D9 = action codes:
58  * D01 = activating light (lower pen) when di placement
59  * D02 = light extinction (lift pen) when di placement
60  * D03 Flash
61  * D09 = VAPE Flash
62  * D10 ... = Indentification Tool (Opening)
63  *
64  * For tools:
65  * DCode min = D10
66  * DCode max = 999
67  */
68 
69 
71 {
73 }
74 
75 
77 {
78 }
79 
80 
82 {
83  m_LayerName = wxT( "no name" ); // Layer name from the LN command
84  m_LayerNegative = false; // true = Negative Layer
85  m_StepForRepeat.x = m_StepForRepeat.y = 0; // X and Y offsets for Step and Repeat command
86  m_XRepeatCount = 1; // The repeat count on X axis
87  m_YRepeatCount = 1; // The repeat count on Y axis
88  m_StepForRepeatMetric = false; // false = Inches, true = metric
89 }
90 
91 
93 {
94  m_GraphicLayer = aLayer; // Graphic layer Number
95  m_IsVisible = true; // must be drawn
96  m_PositiveDrawColor = WHITE; // The color used to draw positive items for this image
97 
98  m_Selected_Tool = 0;
99  m_FileFunction = NULL; // file function parameters
100 
102 
103  for( unsigned ii = 0; ii < DIM( m_Aperture_List ); ii++ )
104  m_Aperture_List[ii] = 0;
105 }
106 
107 
109 {
111 
112  for( unsigned ii = 0; ii < DIM( m_Aperture_List ); ii++ )
113  {
114  delete m_Aperture_List[ii];
115  }
116 
117  delete m_FileFunction;
118 }
119 
120 /*
121  * Function GetItemsList
122  * returns the first GERBER_DRAW_ITEM * item of the items list
123  */
125 {
126  return m_Drawings;
127 }
128 
129 D_CODE* GERBER_FILE_IMAGE::GetDCODE( int aDCODE, bool aCreateIfNoExist )
130 {
131  unsigned ndx = aDCODE - FIRST_DCODE;
132 
133  if( ndx < (unsigned) DIM( m_Aperture_List ) )
134  {
135  // lazily create the D_CODE if it does not exist.
136  if( aCreateIfNoExist )
137  {
138  if( m_Aperture_List[ndx] == NULL )
139  m_Aperture_List[ndx] = new D_CODE( ndx + FIRST_DCODE );
140  }
141 
142  return m_Aperture_List[ndx];
143  }
144 
145  return NULL;
146 }
147 
148 
150 {
151  APERTURE_MACRO_SET::iterator iter = m_aperture_macros.find( aLookup );
152 
153  if( iter != m_aperture_macros.end() )
154  {
155  APERTURE_MACRO* pam = (APERTURE_MACRO*) &(*iter);
156  return pam;
157  }
158 
159  return NULL; // not found
160 }
161 
162 
164 {
165  m_InUse = false;
167  m_FileName.Empty();
168  m_ImageName = wxT( "no name" ); // Image name from the IN command
169  m_ImageNegative = false; // true = Negative image
170  m_IsX2_file = false; // true only if a %TF, %TA or %TD command
171  delete m_FileFunction; // file function parameters
172  m_FileFunction = NULL;
173  m_MD5_value.Empty(); // MD5 value found in a %TF.MD5 command
174  m_PartString.Empty(); // string found in a %TF.Part command
175  m_hasNegativeItems = -1; // set to uninitialized
176  m_ImageJustifyOffset = wxPoint(0,0); // Image justify Offset
177  m_ImageJustifyXCenter = false; // Image Justify Center on X axis (default = false)
178  m_ImageJustifyYCenter = false; // Image Justify Center on Y axis (default = false)
179  m_GerbMetric = false; // false = Inches (default), true = metric
180  m_Relative = false; // false = absolute Coord,
181  // true = relative Coord
182  m_NoTrailingZeros = false; // true: trailing zeros deleted
183  m_DecimalFormat = false; // true: use floating point notations for coordinates
184  m_ImageOffset.x = m_ImageOffset.y = 0; // Coord Offset, from IO command
185  m_ImageRotation = 0; // Allowed 0, 90, 180, 270 (in degree)
186  m_LocalRotation = 0.0; // Layer totation from RO command (in 0.1 degree)
187  m_Offset.x = 0;
188  m_Offset.y = 0; // Coord Offset, from OF command
189  m_Scale.x = m_Scale.y = 1.0; // scale (A and B) this layer
190  m_MirrorA = false; // true: miror / axe A (default = X)
191  m_MirrorB = false; // true: miror / axe B (default = Y)
192  m_SwapAxis = false; // false if A = X, B = Y; true if A =Y, B = Y
193  m_Has_DCode = false; // true = DCodes in file
194  // false = no DCode->
195  // search for separate DCode file
196  m_FmtScale.x = m_FmtScale.y = 4; // Initialize default format to 3.4 => 4
197  m_FmtLen.x = m_FmtLen.y = 3 + 4; // Initialize default format len = 3+4
198 
199  m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // Linear, 90 arc, Circ.
200  m_360Arc_enbl = false; // 360 deg circular
201  // interpolation disable
202  m_Current_Tool = 0; // Current Dcode selected
203  m_CommandState = 0; // State of the current command
204  m_CurrentPos.x = m_CurrentPos.y = 0; // current specified coord
205  m_PreviousPos.x = m_PreviousPos.y = 0; // last specified coord
206  m_IJPos.x = m_IJPos.y = 0; // current centre coord for
207  // plot arcs & circles
208  m_Current_File = NULL; // Gerber file to read
209  m_FilesPtr = 0;
210  m_PolygonFillMode = false;
212  m_Selected_Tool = 0;
213  m_Last_Pen_Command = 0;
214  m_Exposure = false;
215 
216  for( unsigned ii = 0; ii < DIM( m_FilesList ); ii++ )
217  m_FilesList[ii] = NULL;
218 }
219 
220 
221 /* Function HasNegativeItems
222  * return true if at least one item must be drawn in background color
223  * used to optimize screen refresh
224  */
226 {
227  if( m_hasNegativeItems < 0 ) // negative items are not yet searched: find them if any
228  {
229  if( m_ImageNegative ) // A negative layer is expected having always negative objects.
230  m_hasNegativeItems = 1;
231  else
232  {
233  m_hasNegativeItems = 0;
234  for( GERBER_DRAW_ITEM* item = GetItemsList(); item; item = item->Next() )
235  {
236  if( item->GetLayer() != m_GraphicLayer )
237  continue;
238  if( item->HasNegativeItems() )
239  {
240  m_hasNegativeItems = 1;
241  break;
242  }
243  }
244  }
245  }
246  return m_hasNegativeItems == 1;
247 }
248 
250 {
251  int count = 0;
252 
253  for( unsigned ii = 0; ii < DIM( m_Aperture_List ); ii++ )
254  {
255  if( m_Aperture_List[ii] )
256  if( m_Aperture_List[ii]->m_InUse || m_Aperture_List[ii]->m_Defined )
257  ++count;
258  }
259 
260  return count;
261 }
262 
263 
265 {
266  for( int count = 0; count < TOOLS_MAX_COUNT; count++ )
267  {
268  if( m_Aperture_List[count] == NULL )
269  continue;
270 
271  m_Aperture_List[count]->m_Num_Dcode = count + FIRST_DCODE;
273  }
274 
275  m_aperture_macros.clear();
276 }
277 
278 
288 {
289  if( GetLayerParams().m_XRepeatCount < 2 &&
290  GetLayerParams().m_YRepeatCount < 2 )
291  return; // Nothing to repeat
292 
293  // Duplicate item:
294  for( int ii = 0; ii < GetLayerParams().m_XRepeatCount; ii++ )
295  {
296  for( int jj = 0; jj < GetLayerParams().m_YRepeatCount; jj++ )
297  {
298  // the first gerber item already exists (this is the template)
299  // create duplicate only if ii or jj > 0
300  if( jj == 0 && ii == 0 )
301  continue;
302  GERBER_DRAW_ITEM* dupItem = new GERBER_DRAW_ITEM( aItem );
303  wxPoint move_vector;
304  move_vector.x = scaletoIU( ii * GetLayerParams().m_StepForRepeat.x,
305  GetLayerParams().m_StepForRepeatMetric );
306  move_vector.y = scaletoIU( jj * GetLayerParams().m_StepForRepeat.y,
307  GetLayerParams().m_StepForRepeatMetric );
308  dupItem->MoveXY( move_vector );
309  m_Drawings.Append( dupItem );
310  }
311  }
312 }
313 
314 
324 {
325  wxString msg;
326 
327  aMainFrame->ClearMsgPanel();
328 
329  // Display Image name (Image specific)
330  aMainFrame->AppendMsgPanel( _( "Image name" ), m_ImageName, CYAN );
331 
332  // Display graphic layer number used to draw this Image
333  // (not a Gerber parameter but is also image specific)
334  msg.Printf( wxT( "%d" ), m_GraphicLayer + 1 );
335  aMainFrame->AppendMsgPanel( _( "Graphic layer" ), msg, BROWN );
336 
337  // Display Image rotation (Image specific)
338  msg.Printf( wxT( "%d" ), m_ImageRotation );
339  aMainFrame->AppendMsgPanel( _( "Img Rot." ), msg, CYAN );
340 
341  // Display Image polarity (Image specific)
342  msg = m_ImageNegative ? _("Negative") : _("Normal");
343  aMainFrame->AppendMsgPanel( _( "Polarity" ), msg, BROWN );
344 
345  // Display Image justification and offset for justification (Image specific)
346  msg = m_ImageJustifyXCenter ? _("Center") : _("Normal");
347  aMainFrame->AppendMsgPanel( _( "X Justify" ), msg, DARKRED );
348 
349  msg = m_ImageJustifyYCenter ? _("Center") : _("Normal");
350  aMainFrame->AppendMsgPanel( _( "Y Justify" ), msg, DARKRED );
351 
352  if( g_UserUnit == INCHES )
353  msg.Printf( wxT( "X=%f Y=%f" ), Iu2Mils( m_ImageJustifyOffset.x ) / 1000.0,
354  Iu2Mils( m_ImageJustifyOffset.y ) / 1000.0 );
355  else
356  msg.Printf( wxT( "X=%f Y=%f" ), Iu2Millimeter( m_ImageJustifyOffset.x ),
357  Iu2Millimeter( m_ImageJustifyOffset.y ) );
358 
359  aMainFrame->AppendMsgPanel( _( "Image Justify Offset" ), msg, DARKRED );
360 }
361 
362 
364 {
365  /* Called when a %TD command is found
366  * Remove the attribute specified by the %TD command.
367  * is no attribute, all current attributes specified by the %TO and the %TA
368  * commands are cleared.
369  * if a attribute name is specified (for instance %TD.CN*%) is specified,
370  * only this attribute is cleared
371  */
372  m_NetAttributeDict.ClearAttribute( &aAttribute.GetPrm( 1 ) );
373 
374  if( aAttribute.GetPrm( 1 ).IsEmpty() || aAttribute.GetPrm( 1 ) == ".AperFunction" )
375  m_AperFunction.Clear();
376 }
APERTURE_MACRO_SET m_aperture_macros
a collection of APERTURE_MACROS, sorted by name
#define DIM(x)
of elements in an array
Definition: macros.h:98
X2_ATTRIBUTE_FILEFUNCTION * m_FileFunction
bool HasNegativeItems()
Function HasNegativeItems.
class X2_ATTRIBUTE The attribute value consists of a number of substrings separated by a comma ...
void Append(T *aNewElement)
Function Append adds aNewElement to the end of the list.
Definition: dlist.h:177
wxRealPoint m_StepForRepeat
D_CODE * GetDCODE(int aDCODE, bool aCreateIfNoExist=true)
Function GetDCODE returns a pointer to the D_CODE within this GERBER for the given aDCODE...
const wxString & GetPrm(int aIdx)
void DeleteAll()
Function DeleteAll deletes all items on the list and leaves the list empty.
Definition: dlist.cpp:41
int scaletoIU(double aCoord, bool isMetric)
Function scaletoIU converts a distance given in floating point to our internal units.
Definition: colors.h:54
This file contains miscellaneous commonly used macros and functions.
D_CODE * m_Aperture_List[TOOLS_MAX_COUNT]
Dcode (Aperture) List for this layer (max 999)
void DisplayImageInfo(GERBVIEW_FRAME *aMainFrame)
Function DisplayImageInfo has knowledge about the frame and how and where to put status information a...
#define FIRST_DCODE
Definition: dcode.h:70
Definition: common.h:145
int m_Num_Dcode
D code value ( >= 10 )
Definition: dcode.h:100
Definition: colors.h:59
GERBER_DRAW_ITEM * Next() const
APERTURE_MACRO * FindApertureMacro(const APERTURE_MACRO &aLookup)
Function FindApertureMacro looks up a previously read in aperture macro.
void RemoveAttribute(X2_ATTRIBUTE &aAttribute)
Function RemoveAttribute.
EDA_UNITS_T g_UserUnit
Global variables definitions.
Definition: common.cpp:56
void AppendMsgPanel(const wxString &textUpper, const wxString &textLower, COLOR4D color, int pad=6)
Append a message to the message panel.
Definition: draw_frame.cpp:734
bool m_Exposure
whether an aperture macro tool is flashed on or off
Class D_CODE holds a gerber DCODE (also called Aperture) definition.
Definition: dcode.h:81
DLIST< GERBER_DRAW_ITEM > m_Drawings
GERBER_DRAW_ITEM * GetItemsList()
Function GetItemsList.
GBR_NETLIST_METADATA m_NetAttributeDict
#define TOOLS_MAX_COUNT
Definition: dcode.h:72
The common library.
Definition: colors.h:49
void ClearAttribute(const wxString *aName)
remove the net attribute specified by aName If aName == NULL or empty, remove all attributes ...
Struct APERTURE_MACRO helps support the "aperture macro" defined within standard RS274X.
void InitToolTable()
Function InitToolTable.
void MoveXY(const wxPoint &aMoveVector)
Function MoveXY move this object.
void StepAndRepeatItem(const GERBER_DRAW_ITEM &aItem)
Function StepAndRepeatItem Gerber format has a command Step an Repeat This function must be called wh...
void Clear_D_CODE_Data()
Definition: dcode.cpp:78
void ClearMsgPanel(void)
Clear all messages from the message panel.
Definition: draw_frame.cpp:745
GERBER_LAYER & GetLayerParams()
Function GetLayerParams.
FILE * m_FilesList[INCLUDE_FILES_CNT_MAX+2]
Definition: colors.h:62