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