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 <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 
43 // GERBER_FILE_IMAGE_LIST is a helper class to handle a list of GERBER_FILE_IMAGE files
45 {
47 
48  for( unsigned layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
49  m_GERBER_List.push_back( nullptr );
50 }
51 
52 
54 {
56 }
57 
58 
60 {
61  return s_GERBER_List;
62 }
63 
64 
66 {
67  if( (unsigned)aIdx < m_GERBER_List.size() )
68  return m_GERBER_List[aIdx];
69 
70  return NULL;
71 }
72 
73 /* creates a new, empty GERBER_FILE_IMAGE* at index aIdx
74  * or at the first free location if aIdx < 0
75  * aIdx = the index of graphic layer to use, or -1 to uses the first free graphic layer
76  * return the index actually used, or -1 if no room to add image
77  */
79 {
80  int idx = aIdx;
81 
82  if( idx < 0 )
83  {
84  for( idx = 0; idx < (int)m_GERBER_List.size(); idx++ )
85  {
86  if( m_GERBER_List[idx] == NULL )
87  break;
88  }
89  }
90 
91  if( idx >= (int)m_GERBER_List.size() )
92  return -1; // No room
93 
94  m_GERBER_List[idx] = aGbrImage;
95 
96  return idx;
97 }
98 
99 
101 {
102  for( unsigned idx = 0; idx < m_GERBER_List.size(); ++idx )
103  DeleteImage( idx );
104 }
105 
106 
108 {
109  // Ensure the index is valid:
110  if( aIdx < 0 || aIdx >= int( m_GERBER_List.size() ) )
111  return;
112 
113  // delete image aIdx
114  GERBER_FILE_IMAGE* gbr_image = GetGbrImage( aIdx );
115 
116  delete gbr_image;
117  m_GERBER_List[ aIdx ] = nullptr;
118 }
119 
120 // Build a name for image aIdx which can be used in layers manager
121 const wxString GERBER_FILE_IMAGE_LIST::GetDisplayName( int aIdx, bool aNameOnly, bool aFullName )
122 {
123  wxString name;
124 
125  GERBER_FILE_IMAGE* gerber = NULL;
126 
127  if( aIdx >= 0 && aIdx < (int)m_GERBER_List.size() )
128  gerber = m_GERBER_List[aIdx];
129 
130  // if a file is loaded, build the name:
131  // <id> <short filename> <X2 FileFunction info> if a X2 FileFunction info is found
132  // or (if no FileFunction info)
133  // <id> <short filename> *
134  if( gerber )
135  {
136  wxFileName fn( gerber->m_FileName );
137  wxString filename = fn.GetFullName();
138 
139  // If the filename is too long, display a shortened name if requested
140  const int maxlen = 30;
141 
142  if( !aFullName && filename.Length() > maxlen )
143  {
144  wxString shortenedfn = filename.Left(2) + "..." + filename.Right(maxlen-5);
145  filename = shortenedfn;
146  }
147 
148  if( gerber->m_FileFunction )
149  {
150  if( gerber->m_FileFunction->IsCopper() )
151  {
152  name.Printf( "%s (%s, %s, %s)",
153  filename.GetData(),
154  gerber->m_FileFunction->GetFileType(),
155  gerber->m_FileFunction->GetBrdLayerId(),
156  gerber->m_FileFunction->GetBrdLayerSide() );
157  }
158  if( gerber->m_FileFunction->IsDrillFile() )
159  {
160  name.Printf( "%s (%s,%s,%s,%s)",
161  filename.GetData(),
162  gerber->m_FileFunction->GetFileType(),
164  gerber->m_FileFunction->GetLPType(),
165  gerber->m_FileFunction->GetRouteType() );
166  }
167  else
168  {
169  name.Printf( "%s (%s, %s)",
170  filename.GetData(),
171  gerber->m_FileFunction->GetFileType(),
172  gerber->m_FileFunction->GetBrdLayerId() );
173  }
174  }
175  else
176  name = filename;
177 
178  if( aNameOnly )
179  return name;
180 
181  wxString fullname;
182 
183  fullname.Printf( "%d ", aIdx + 1 );
184  fullname << name;
185  return fullname;
186  }
187  else
188  name.Printf( _( "Graphic layer %d" ), aIdx + 1 );
189 
190  return name;
191 }
192 
193 
194 
195 // Helper function, for std::sort.
196 // Sort loaded images by Z order priority, if they have the X2 FileFormat info
197 // returns true if the first argument (ref) is ordered before the second (test).
198 static bool sortZorder( const GERBER_FILE_IMAGE* const& ref, const GERBER_FILE_IMAGE* const& test )
199 {
200  if( !ref && !test )
201  return false; // do not change order: no criteria to sort items
202 
203  if( !ref || !ref->m_InUse )
204  return false; // Not used: ref ordered after
205 
206  if( !test || !test->m_InUse )
207  return true; // Not used: ref ordered before
208 
209  if( !ref->m_FileFunction && !test->m_FileFunction )
210  return false; // do not change order: no criteria to sort items
211 
212  if( !ref->m_FileFunction )
213  return false;
214 
215  if( !test->m_FileFunction )
216  return true;
217 
218  if( ref->m_FileFunction->GetZOrder() != test->m_FileFunction->GetZOrder() )
219  return ref->m_FileFunction->GetZOrder() > test->m_FileFunction->GetZOrder();
220 
221  return ref->m_FileFunction->GetZSubOrder() > test->m_FileFunction->GetZSubOrder();
222 }
223 
224 
225 std::unordered_map<int, int> GERBER_FILE_IMAGE_LIST::SortImagesByZOrder()
226 {
227  std::sort( m_GERBER_List.begin(), m_GERBER_List.end(), sortZorder );
228 
229  // The image order has changed.
230  // Graphic layer numbering must be updated to match the widgets layer order
231 
232  // Store the old/new graphic layer info:
233  std::unordered_map<int, int> tab_lyr;
234 
235  for( unsigned layer = 0; layer < m_GERBER_List.size(); ++layer )
236  {
237  GERBER_FILE_IMAGE* gerber = m_GERBER_List[layer];
238 
239  if( !gerber )
240  continue;
241 
242  tab_lyr[gerber->m_GraphicLayer] = layer;
243  gerber->m_GraphicLayer = layer ;
244  }
245 
246  return tab_lyr;
247 }
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
#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
const char * name
Definition: DXF_plotter.cpp:59
#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, 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.