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