KiCad PCB EDA Suite
gerber_file_image_list.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 
32 #include <gerbview.h>
33 #include <gerbview_frame.h>
34 #include <gerber_file_image.h>
35 #include <gerber_file_image_list.h>
36 #include <X2_gerber_attributes.h>
37 
38 #include <map>
39 
40 
41 // The global image list:
43 
44 
45 // GERBER_FILE_IMAGE_LIST is a helper class to handle a list of GERBER_FILE_IMAGE files
47 {
49 
50  for( unsigned layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
51  m_GERBER_List.push_back( nullptr );
52 }
53 
54 
56 {
58 }
59 
60 
62 {
63  return s_GERBER_List;
64 }
65 
66 
68 {
69  if( (unsigned)aIdx < m_GERBER_List.size() )
70  return m_GERBER_List[aIdx];
71 
72  return NULL;
73 }
74 
75 /* creates a new, empty GERBER_FILE_IMAGE* at index aIdx
76  * or at the first free location if aIdx < 0
77  * aIdx = the index of graphic layer to use, or -1 to uses the first free graphic layer
78  * return the index actually used, or -1 if no room to add image
79  */
81 {
82  int idx = aIdx;
83 
84  if( idx < 0 )
85  {
86  for( idx = 0; idx < (int)m_GERBER_List.size(); idx++ )
87  {
88  if( m_GERBER_List[idx] == NULL )
89  break;
90  }
91  }
92 
93  if( idx >= (int)m_GERBER_List.size() )
94  return -1; // No room
95 
96  m_GERBER_List[idx] = aGbrImage;
97 
98  return idx;
99 }
100 
101 
103 {
104  for( unsigned idx = 0; idx < m_GERBER_List.size(); ++idx )
105  DeleteImage( idx );
106 }
107 
108 
110 {
111  // Ensure the index is valid:
112  if( aIdx < 0 || aIdx >= int( m_GERBER_List.size() ) )
113  return;
114 
115  // delete image aIdx
116  GERBER_FILE_IMAGE* gbr_image = GetGbrImage( aIdx );
117 
118  delete gbr_image;
119  m_GERBER_List[ aIdx ] = nullptr;
120 }
121 
122 // Build a name for image aIdx which can be used in layers manager
123 const wxString GERBER_FILE_IMAGE_LIST::GetDisplayName( int aIdx, bool aNameOnly )
124 {
125  wxString name;
126 
127  GERBER_FILE_IMAGE* gerber = NULL;
128 
129  if( aIdx >= 0 && aIdx < (int)m_GERBER_List.size() )
130  gerber = m_GERBER_List[aIdx];
131 
132  // if a file is loaded, build the name:
133  // <id> <short filename> <X2 FileFunction info> if a X2 FileFunction info is found
134  // or (if no FileFunction info)
135  // <id> <short filename> *
136  if( gerber )
137  {
138  wxFileName fn( gerber->m_FileName );
139  wxString filename = fn.GetFullName();
140 
141  // if the filename is too long, display a shortened name:
142  const int maxlen = 30;
143 
144  if( filename.Length() > maxlen )
145  {
146  wxString shortenedfn = filename.Left(2) + "..." + filename.Right(maxlen-5);
147  filename = shortenedfn;
148  }
149 
150  if( gerber->m_FileFunction )
151  {
152  if( gerber->m_FileFunction->IsCopper() )
153  {
154  name.Printf( "%s (%s, %s, %s)",
155  filename.GetData(),
156  GetChars( gerber->m_FileFunction->GetFileType() ),
157  GetChars( gerber->m_FileFunction->GetBrdLayerId() ),
158  GetChars( gerber->m_FileFunction->GetBrdLayerSide() ) );
159  }
160  if( gerber->m_FileFunction->IsDrillFile() )
161  {
162  name.Printf( "%s (%s,%s,%s,%s)",
163  filename.GetData(),
164  GetChars( gerber->m_FileFunction->GetFileType() ),
166  GetChars( gerber->m_FileFunction->GetLPType() ),
167  GetChars( gerber->m_FileFunction->GetRouteType() ) );
168  }
169  else
170  {
171  name.Printf( "%s (%s, %s)",
172  filename.GetData(),
173  GetChars( gerber->m_FileFunction->GetFileType() ),
174  GetChars( gerber->m_FileFunction->GetBrdLayerId() ) );
175  }
176  }
177  else
178  name = filename;
179 
180  if( aNameOnly )
181  return name;
182 
183  wxString fullname;
184 
185  fullname.Printf( "%d ", aIdx + 1 );
186  fullname << name;
187  return fullname;
188  }
189  else
190  name.Printf( _( "Graphic layer %d" ), aIdx + 1 );
191 
192  return name;
193 }
194 
195 
196 
197 // Helper function, for std::sort.
198 // Sort loaded images by Z order priority, if they have the X2 FileFormat info
199 // returns true if the first argument (ref) is ordered before the second (test).
200 static bool sortZorder( const GERBER_FILE_IMAGE* const& ref, const GERBER_FILE_IMAGE* const& test )
201 {
202  if( !ref && !test )
203  return false; // do not change order: no criteria to sort items
204 
205  if( !ref || !ref->m_InUse )
206  return false; // Not used: ref ordered after
207 
208  if( !test || !test->m_InUse )
209  return true; // Not used: ref ordered before
210 
211  if( !ref->m_FileFunction && !test->m_FileFunction )
212  return false; // do not change order: no criteria to sort items
213 
214  if( !ref->m_FileFunction )
215  return false;
216 
217  if( !test->m_FileFunction )
218  return true;
219 
220  if( ref->m_FileFunction->GetZOrder() != test->m_FileFunction->GetZOrder() )
221  return ref->m_FileFunction->GetZOrder() > test->m_FileFunction->GetZOrder();
222 
223  return ref->m_FileFunction->GetZSubOrder() > test->m_FileFunction->GetZSubOrder();
224 }
225 
226 
227 std::unordered_map<int, int> GERBER_FILE_IMAGE_LIST::SortImagesByZOrder()
228 {
229  std::sort( m_GERBER_List.begin(), m_GERBER_List.end(), sortZorder );
230 
231  // The image order has changed.
232  // Graphic layer numbering must be updated to match the widgets layer order
233 
234  // Store the old/new graphic layer info:
235  std::unordered_map<int, int> tab_lyr;
236 
237  for( unsigned layer = 0; layer < m_GERBER_List.size(); ++layer )
238  {
239  GERBER_FILE_IMAGE* gerber = m_GERBER_List[layer];
240 
241  if( !gerber )
242  continue;
243 
244  tab_lyr[gerber->m_GraphicLayer] = layer;
245  gerber->m_GraphicLayer = layer ;
246  }
247 
248  return tab_lyr;
249 }
const wxString & GetFileType()
the type of layer (Copper, Soldermask ... )
X2_ATTRIBUTE_FILEFUNCTION * m_FileFunction
static bool sortZorder(const GERBER_FILE_IMAGE *const &ref, const GERBER_FILE_IMAGE *const &test)
void DeleteAllImages()
remove all loaded data in list, and delete all images.
GERBER_FILE_IMAGE_LIST s_GERBER_List
const wxString GetDisplayName(int aIdx, bool aNameOnly=false)
std::unordered_map< int, int > SortImagesByZOrder()
Sort loaded images by Z order priority, if they have the X2 FileFormat info (SortImagesByZOrder updat...
GERBER_FILE_IMAGE holds the Image data and parameters for one gerber file and layer parameters (TODO:...
int AddGbrImage(GERBER_FILE_IMAGE *aGbrImage, int aIdx)
Add a GERBER_FILE_IMAGE* at index aIdx or at the first free location if aIdx < 0.
GERBER_FILE_IMAGE_LIST is a helper class to handle a list of GERBER_FILE_IMAGE files which are loaded...
bool IsCopper()
return true if the filefunction type is "Copper"
int GetZSubOrder()
the Order of the bdr copper layer, from front (Top) side to back (Bot) side
#define NULL
#define GERBER_DRAWLAYERS_COUNT
GERBER_FILE_IMAGE * GetGbrImage(int aIdx)
static GERBER_FILE_IMAGE_LIST & GetImagesList()
const wxString & GetBrdLayerId()
the brd layer identifier: Ln, only for Copper type or Top, Bot for other types
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:101
const char * name
Definition: DXF_plotter.cpp:60
#define _(s)
Definition: 3d_actions.cpp:33
const wxString & GetBrdLayerSide()
the brd layer Pos: Top, Bot, Inr same as GetBrdLayerId() for non copper type
void DeleteImage(int aIdx)
delete the loaded data of image aIdx.
int GetZOrder()
the Order of the board layer, from front (Top) side to back (Bot) side
std::vector< GERBER_FILE_IMAGE * > m_GERBER_List