KiCad PCB EDA Suite
Loading...
Searching...
No Matches
bitmap2cmp_panel.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KICAD, a free EDA CAD application.
3 *
4 * Copyright (C) 1992-2010 jean-pierre.charras
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21#include <bitmap2cmp_frame.h>
22#include <bitmap2component.h>
23#include <reporter.h>
24#include <bitmap2cmp_panel.h>
25#include <bitmap2cmp_settings.h>
26#include <bitmap_io.h>
27#include <common.h>
28#include <math/util.h> // for KiROUND
29#include <potracelib.h>
30#include <vector>
31#include <wx/arrstr.h>
32#include <wx/clipbrd.h>
33#include <wx/dnd.h>
34#include <wx/rawbmp.h>
35#include <wx/msgdlg.h>
36#include <wx/dcclient.h>
37#include <wx/log.h>
38#include <wx/string.h>
39#include <confirm.h>
40
41#define DEFAULT_DPI 300 // the image DPI used in formats that do not define a DPI
42
43
45 BITMAP2CMP_PANEL_BASE( aParent ),
46 m_parentFrame( aParent ),
47 m_negative( false ),
48 m_aspectRatio( 1.0 )
49{
50 for( const wxString& unit : { _( "mm" ), _( "Inch" ), _( "DPI" ) } )
51 m_PixelUnit->Append( unit );
52
55 m_outputSizeX.SetOutputSize( 0, getUnitFromSelection() );
56 m_outputSizeY.SetOutputSize( 0, getUnitFromSelection() );
57
58 m_UnitSizeX->ChangeValue( formatOutputSize( m_outputSizeX.GetOutputSize() ) );
59 m_UnitSizeY->ChangeValue( formatOutputSize( m_outputSizeY.GetOutputSize() ) );
60
61 m_buttonExportFile->Enable( false );
62 m_buttonExportClipboard->Enable( false );
63
64 m_InitialPicturePanel->SetDropTarget( new DROP_FILE( this ) );
65 m_GreyscalePicturePanel->SetDropTarget( new DROP_FILE( this ) );
66 m_BNPicturePanel->SetDropTarget( new DROP_FILE( this ) );
67}
68
70{
71 return m_Notebook->GetCurrentPage();
72}
73
74
76{
77 if( cfg->m_Units >= 0 && cfg->m_Units < (int) m_PixelUnit->GetCount() )
78 m_PixelUnit->SetSelection( cfg->m_Units );
79
80 m_sliderThreshold->SetValue( cfg->m_Threshold );
81
83 m_checkNegative->SetValue( cfg->m_Negative );
84
85 m_aspectRatio = 1.0;
86 m_aspectRatioCheckbox->SetValue( true );
87
88 switch( cfg->m_LastFormat )
89 {
90 default:
91 case FOOTPRINT_FMT: m_rbFootprint->SetValue( true ); break;
92 case SYMBOL_FMT:
93 case SYMBOL_PASTE_FMT: m_rbSymbol->SetValue( true ); break;
94 case POSTSCRIPT_FMT: m_rbPostscript->SetValue( true ); break;
95 case DRAWING_SHEET_FMT: m_rbWorksheet->SetValue( true ); break;
96 }
97
98 m_layerLabel->Enable( cfg->m_LastFormat == FOOTPRINT_FMT );
99 m_layerCtrl->Enable( cfg->m_LastFormat == FOOTPRINT_FMT );
100
101 if( cfg->m_LastLayer >= 0 && cfg->m_LastLayer < (int) m_layerCtrl->GetCount() )
102 m_layerCtrl->SetSelection( cfg->m_LastLayer );
103}
104
105
107{
108 cfg->m_Threshold = m_sliderThreshold->GetValue();
109 cfg->m_Negative = m_checkNegative->IsChecked();
111 cfg->m_LastLayer = m_layerCtrl->GetSelection();
112 cfg->m_Units = m_PixelUnit->GetSelection();
113}
114
115
116void BITMAP2CMP_PANEL::OnPaintInit( wxPaintEvent& event )
117{
118#ifdef __WXMAC__
119 // Otherwise fails due: using wxPaintDC without being in a native paint event
120 wxClientDC pict_dc( m_InitialPicturePanel );
121#else
122 wxPaintDC pict_dc( m_InitialPicturePanel );
123#endif
124
125 m_InitialPicturePanel->PrepareDC( pict_dc );
126
127 // OSX crashes with empty bitmaps (on initial refreshes)
128 if( m_Pict_Bitmap.IsOk() )
129 pict_dc.DrawBitmap( m_Pict_Bitmap, 0, 0, !!m_Pict_Bitmap.GetMask() );
130
131 event.Skip();
132}
133
134
135void BITMAP2CMP_PANEL::OnPaintGreyscale( wxPaintEvent& event )
136{
137#ifdef __WXMAC__
138 // Otherwise fails due: using wxPaintDC without being in a native paint event
139 wxClientDC greyscale_dc( m_GreyscalePicturePanel );
140#else
141 wxPaintDC greyscale_dc( m_GreyscalePicturePanel );
142#endif
143
144 m_GreyscalePicturePanel->PrepareDC( greyscale_dc );
145
146 // OSX crashes with empty bitmaps (on initial refreshes)
147 if( m_Greyscale_Bitmap.IsOk() )
148 greyscale_dc.DrawBitmap( m_Greyscale_Bitmap, 0, 0, !!m_Greyscale_Bitmap.GetMask() );
149
150 event.Skip();
151}
152
153
154void BITMAP2CMP_PANEL::OnPaintBW( wxPaintEvent& event )
155{
156#ifdef __WXMAC__
157 // Otherwise fails due: using wxPaintDC without being in a native paint event
158 wxClientDC nb_dc( m_BNPicturePanel );
159#else
160 wxPaintDC nb_dc( m_BNPicturePanel );
161#endif
162
163 m_BNPicturePanel->PrepareDC( nb_dc );
164
165 if( m_BN_Bitmap.IsOk() )
166 nb_dc.DrawBitmap( m_BN_Bitmap, 0, 0, !!m_BN_Bitmap.GetMask() );
167
168 event.Skip();
169}
170
171
172void BITMAP2CMP_PANEL::OnLoadFile( wxCommandEvent& event )
173{
174 m_parentFrame->OnLoadFile();
175}
176
177
178bool BITMAP2CMP_PANEL::OpenProjectFiles( const std::vector<wxString>& aFileSet, int aCtl )
179{
180 m_Pict_Image.Destroy();
181
182 if( !m_Pict_Image.LoadFile( aFileSet[0] ) )
183 {
184 // LoadFile has its own UI, no need for further failure notification here
185 return false;
186 }
187
188 m_Pict_Bitmap = wxBitmap( m_Pict_Image );
189
190 // Determine image resolution in DPI (does not existing in all formats).
191 // the resolution can be given in bit per inches or bit per cm in file
192
193 int imageDPIx = m_Pict_Image.GetOptionInt( wxIMAGE_OPTION_RESOLUTIONX );
194 int imageDPIy = m_Pict_Image.GetOptionInt( wxIMAGE_OPTION_RESOLUTIONY );
195
196 if( imageDPIx > 1 && imageDPIy > 1 )
197 {
198 if( m_Pict_Image.GetOptionInt( wxIMAGE_OPTION_RESOLUTIONUNIT ) == wxIMAGE_RESOLUTION_CM )
199 {
200 imageDPIx = KiROUND( imageDPIx * 2.54 );
201 imageDPIy = KiROUND( imageDPIy * 2.54 );
202 }
203 }
204 else // fallback to a default value (DEFAULT_DPI)
205 {
206 imageDPIx = imageDPIy = DEFAULT_DPI;
207 }
208
209 m_InputXValueDPI->SetLabel( wxString::Format( wxT( "%d" ), imageDPIx ) );
210 m_InputYValueDPI->SetLabel( wxString::Format( wxT( "%d" ), imageDPIy ) );
211
212 int h = m_Pict_Bitmap.GetHeight();
213 int w = m_Pict_Bitmap.GetWidth();
214 m_aspectRatio = (double) w / h;
215
216 m_outputSizeX.SetOriginalDPI( imageDPIx );
217 m_outputSizeX.SetOriginalSizePixels( w );
218 m_outputSizeY.SetOriginalDPI( imageDPIy );
219 m_outputSizeY.SetOriginalSizePixels( h );
220
221 // Update display to keep aspect ratio
222 wxCommandEvent dummy;
224
226
227 m_InitialPicturePanel->SetVirtualSize( w, h );
228 m_GreyscalePicturePanel->SetVirtualSize( w, h );
229 m_BNPicturePanel->SetVirtualSize( w, h );
230
231 m_Greyscale_Image.Destroy();
232 m_Greyscale_Image = m_Pict_Image.ConvertToGreyscale( );
233
234 if( m_Pict_Bitmap.GetMask() )
235 {
236 for( int x = 0; x < m_Pict_Bitmap.GetWidth(); x++ )
237 {
238 for( int y = 0; y < m_Pict_Bitmap.GetHeight(); y++ )
239 {
240 if( m_Pict_Image.GetRed( x, y ) == m_Pict_Image.GetMaskRed()
241 && m_Pict_Image.GetGreen( x, y ) == m_Pict_Image.GetMaskGreen()
242 && m_Pict_Image.GetBlue( x, y ) == m_Pict_Image.GetMaskBlue() )
243 {
244 m_Greyscale_Image.SetRGB( x, y, 255, 255, 255 );
245 }
246 }
247 }
248 }
249
250 if( m_negative )
252
255 binarize( (double)m_sliderThreshold->GetValue() / m_sliderThreshold->GetMax() );
256
257 m_buttonExportFile->Enable( true );
258 m_buttonExportClipboard->Enable( true );
259
260 m_outputSizeX.SetOutputSizeFromInitialImageSize();
261 m_UnitSizeX->ChangeValue( formatOutputSize( m_outputSizeX.GetOutputSize() ) );
262 m_outputSizeY.SetOutputSizeFromInitialImageSize();
263 m_UnitSizeY->ChangeValue( formatOutputSize( m_outputSizeY.GetOutputSize() ) );
264
265 return true;
266}
267
268
269// return a string giving the output size, according to the selected unit
271{
272 wxString text;
273
275 text.Printf( wxS( "%.1f" ), aSize );
277 text.Printf( wxS( "%.2f" ), aSize );
278 else
279 text.Printf( wxT( "%d" ), KiROUND( aSize ) );
280
281 return text;
282}
283
285{
286 // Note: the image resolution text controls are not modified here, to avoid a race between
287 // text change when entered by user and a text change if it is modified here.
288
289 if( m_Pict_Bitmap.IsOk() )
290 {
291 m_SizeXValue->SetLabel( wxString::Format( wxT( "%d" ), m_Pict_Bitmap.GetWidth() ) );
292 m_SizeYValue->SetLabel( wxString::Format( wxT( "%d" ), m_Pict_Bitmap.GetHeight() ) );
293 m_BPPValue->SetLabel( wxString::Format( wxT( "%d" ), m_Pict_Bitmap.GetDepth() ) );
294 }
295}
296
297
299{
300 // return the EDA_UNITS from the m_PixelUnit choice
301 switch( m_PixelUnit->GetSelection() )
302 {
303 case 1: return EDA_UNITS::INCH;
304 case 2: return EDA_UNITS::UNSCALED;
305 case 0:
306 default: return EDA_UNITS::MM;
307 }
308}
309
310
311void BITMAP2CMP_PANEL::OnSizeChangeX( wxCommandEvent& event )
312{
313 double new_size;
314
315 if( m_UnitSizeX->GetValue().ToDouble( &new_size ) )
316 {
317 if( m_aspectRatioCheckbox->GetValue() )
318 {
319 double calculatedY = new_size / m_aspectRatio;
320
322 {
323 // for units in DPI, keeping aspect ratio cannot use m_AspectRatioLocked.
324 // just re-scale the other dpi
325 double ratio = new_size / m_outputSizeX.GetOutputSize();
326 calculatedY = m_outputSizeY.GetOutputSize() * ratio;
327 }
328
329 m_outputSizeY.SetOutputSize( calculatedY, getUnitFromSelection() );
330 m_UnitSizeY->ChangeValue( formatOutputSize( m_outputSizeY.GetOutputSize() ) );
331 }
332
333 m_outputSizeX.SetOutputSize( new_size, getUnitFromSelection() );
334 }
335
337}
338
339
340void BITMAP2CMP_PANEL::OnSizeChangeY( wxCommandEvent& event )
341{
342 double new_size;
343
344 if( m_UnitSizeY->GetValue().ToDouble( &new_size ) )
345 {
346 if( m_aspectRatioCheckbox->GetValue() )
347 {
348 double calculatedX = new_size * m_aspectRatio;
349
351 {
352 // for units in DPI, keeping aspect ratio cannot use m_AspectRatioLocked.
353 // just re-scale the other dpi
354 double ratio = new_size / m_outputSizeX.GetOutputSize();
355 calculatedX = m_outputSizeX.GetOutputSize() * ratio;
356 }
357
358 m_outputSizeX.SetOutputSize( calculatedX, getUnitFromSelection() );
359 m_UnitSizeX->ChangeValue( formatOutputSize( m_outputSizeX.GetOutputSize() ) );
360 }
361
362 m_outputSizeY.SetOutputSize( new_size, getUnitFromSelection() );
363 }
364
366}
367
368
369void BITMAP2CMP_PANEL::OnSizeUnitChange( wxCommandEvent& event )
370{
374
375 m_UnitSizeX->ChangeValue( formatOutputSize( m_outputSizeX.GetOutputSize() ) );
376 m_UnitSizeY->ChangeValue( formatOutputSize( m_outputSizeY.GetOutputSize() ) );
377}
378
379
380void BITMAP2CMP_PANEL::SetOutputSize( const IMAGE_SIZE& aSizeX, const IMAGE_SIZE& aSizeY )
381{
382 m_outputSizeX = aSizeX;
383 m_outputSizeY = aSizeY;
385
386 m_UnitSizeX->ChangeValue( formatOutputSize( m_outputSizeX.GetOutputSize() ) );
387 m_UnitSizeY->ChangeValue( formatOutputSize( m_outputSizeY.GetOutputSize() ) );
388}
389
390
391void BITMAP2CMP_PANEL::ToggleAspectRatioLock( wxCommandEvent& event )
392{
393 if( m_aspectRatioCheckbox->GetValue() )
394 {
395 // Force display update when aspect ratio is locked
396 wxCommandEvent dummy;
398 }
399}
400
401
402void BITMAP2CMP_PANEL::binarize( double aThreshold )
403{
404 unsigned char threshold = aThreshold * 255;
405 unsigned char alpha_thresh = 0.7 * threshold;
406
407 for( int y = 0; y < m_Greyscale_Image.GetHeight(); y++ )
408 {
409 for( int x = 0; x < m_Greyscale_Image.GetWidth(); x++ )
410 {
411 unsigned char pixel = m_Greyscale_Image.GetGreen( x, y );
412 unsigned char alpha = m_Greyscale_Image.HasAlpha() ? m_Greyscale_Image.GetAlpha( x, y )
413 : wxALPHA_OPAQUE;
414
415 if( pixel < threshold && alpha > alpha_thresh )
416 pixel = 0;
417 else
418 pixel = 255;
419
420 m_NB_Image.SetRGB( x, y, pixel, pixel, pixel );
421 }
422 }
423
424 m_BN_Bitmap = wxBitmap( m_NB_Image );
425}
426
427
429{
430 for( int y = 0; y < m_Greyscale_Image.GetHeight(); y++ )
431 {
432 for( int x = 0; x < m_Greyscale_Image.GetWidth(); x++ )
433 {
434 unsigned char pixel = m_Greyscale_Image.GetGreen( x, y );
435 pixel = ~pixel;
436 m_Greyscale_Image.SetRGB( x, y, pixel, pixel, pixel );
437 }
438 }
439}
440
441
443{
444 if( m_checkNegative->GetValue() != m_negative )
445 {
447
449 binarize( (double)m_sliderThreshold->GetValue() / m_sliderThreshold->GetMax() );
450 m_negative = m_checkNegative->GetValue();
451
452 Refresh();
453 }
454}
455
456
457void BITMAP2CMP_PANEL::OnThresholdChange( wxScrollEvent& event )
458{
459 binarize( (double)m_sliderThreshold->GetValue() / m_sliderThreshold->GetMax() );
460 Refresh();
461}
462
463
464void BITMAP2CMP_PANEL::OnExportToFile( wxCommandEvent& event )
465{
466 switch( getOutputFormat() )
467 {
468 case SYMBOL_FMT:
469 case SYMBOL_PASTE_FMT: m_parentFrame->ExportEeschemaFormat(); break;
470 case FOOTPRINT_FMT: m_parentFrame->ExportPcbnewFormat(); break;
471 case POSTSCRIPT_FMT: m_parentFrame->ExportPostScriptFormat(); break;
472 case DRAWING_SHEET_FMT: m_parentFrame->ExportDrawingSheetFormat(); break;
473 }
474}
475
476
478{
479 if( m_rbSymbol->GetValue() )
480 return SYMBOL_FMT;
481 else if( m_rbPostscript->GetValue() )
482 return POSTSCRIPT_FMT;
483 else if( m_rbWorksheet->GetValue() )
484 return DRAWING_SHEET_FMT;
485 else
486 return FOOTPRINT_FMT;
487}
488
489
490void BITMAP2CMP_PANEL::OnExportToClipboard( wxCommandEvent& event )
491{
492 std::string buffer;
494 ExportToBuffer( buffer, format );
495
496 wxLogNull doNotLog; // disable logging of failed clipboard actions
497
498 // Write buffer to the clipboard
499 if( wxTheClipboard->Open() )
500 {
501 // This data objects are held by the clipboard,
502 // so do not delete them in the app.
503 wxTheClipboard->SetData( new wxTextDataObject( buffer.c_str() ) );
504 wxTheClipboard->Flush(); // Allow data to be available after closing KiCad
505 wxTheClipboard->Close();
506 }
507 else
508 {
509 wxMessageBox( _( "Unable to export to the Clipboard") );
510 }
511}
512
513
514void BITMAP2CMP_PANEL::ExportToBuffer( std::string& aOutput, OUTPUT_FMT_ID aFormat )
515{
516 // Create a potrace bitmap
517 potrace_bitmap_t* potrace_bitmap = bm_new( m_NB_Image.GetWidth(), m_NB_Image.GetHeight() );
518
519 if( !potrace_bitmap )
520 {
521 wxMessageBox( _( "Error allocating memory for potrace bitmap" ) );
522 return;
523 }
524
525 /* fill the bitmap with data */
526 for( int y = 0; y < m_NB_Image.GetHeight(); y++ )
527 {
528 for( int x = 0; x < m_NB_Image.GetWidth(); x++ )
529 {
530 unsigned char pixel = m_NB_Image.GetGreen( x, y );
531 BM_PUT( potrace_bitmap, x, y, pixel ? 0 : 1 );
532 }
533 }
534
535 wxString layer = wxT( "F.SilkS" );
536
537 if( aFormat == FOOTPRINT_FMT )
538 {
539 switch( m_layerCtrl->GetSelection() )
540 {
541 case 0: layer = wxT( "F.Cu" ); break;
542 case 1: layer = wxT( "F.SilkS" ); break;
543 case 2: layer = wxT( "F.Mask" ); break;
544 case 3: layer = wxT( "Dwgs.User" ); break;
545 case 4: layer = wxT( "Cmts.User" ); break;
546 case 5: layer = wxT( "Eco1.User" ); break;
547 case 6: layer = wxT( "Eco2.User" ); break;
548 case 7: layer = wxT( "F.Fab" ); break;
549 }
550 }
551
552
553
555 BITMAPCONV_INFO converter( aOutput, reporter );
556
557 converter.ConvertBitmap( potrace_bitmap, aFormat, m_outputSizeX.GetOutputDPI(),
558 m_outputSizeY.GetOutputDPI(), layer );
559
560 if( reporter.HasMessage() )
561 wxMessageBox( reporter.GetMessages(), _( "Errors" ) );
562}
563
564
565void BITMAP2CMP_PANEL::OnFormatChange( wxCommandEvent& event )
566{
567 m_layerLabel->Enable( m_rbFootprint->GetValue() );
568 m_layerCtrl->Enable( m_rbFootprint->GetValue() );
569}
570
571
573 m_panel( panel )
574{
575}
576
577
578bool DROP_FILE::OnDropFiles( wxCoord x, wxCoord y, const wxArrayString& filenames )
579{
580 m_panel->SetFocus();
581
582 // If a file is already loaded
583 if( m_panel->GetOutputSizeX().GetOriginalSizePixels() != 0 )
584 {
585 wxString cap = _( "Replace Loaded File?" );
586 wxString msg = _( "There is already a file loaded. Do you want to replace it?" );
587 KICAD_MESSAGE_DIALOG acceptFileDlg( m_panel, msg, cap, wxYES_NO | wxICON_QUESTION | wxYES_DEFAULT );
588 int replace = acceptFileDlg.ShowModal();
589
590 if( replace == wxID_NO )
591 return false;
592 }
593
594 std::vector<wxString> fNameVec;
595 fNameVec.insert( fNameVec.begin(), filenames.begin(), filenames.end() );
596 m_panel->OpenProjectFiles( fNameVec );
597
598 return true;
599}
#define DEFAULT_DPI
OUTPUT_FMT_ID
@ DRAWING_SHEET_FMT
@ SYMBOL_FMT
@ SYMBOL_PASTE_FMT
@ POSTSCRIPT_FMT
@ FOOTPRINT_FMT
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:986
wxScrolledWindow * m_GreyscalePicturePanel
wxScrolledWindow * m_BNPicturePanel
BITMAP2CMP_PANEL_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
wxScrolledWindow * m_InitialPicturePanel
void OnPaintGreyscale(wxPaintEvent &event) override
void binarize(double aThreshold)
void SetOutputSize(const IMAGE_SIZE &aSizeX, const IMAGE_SIZE &aSizeY)
void OnSizeUnitChange(wxCommandEvent &event) override
void OnSizeChangeX(wxCommandEvent &event) override
void OnPaintInit(wxPaintEvent &event) override
void OnExportToClipboard(wxCommandEvent &event) override
void LoadSettings(BITMAP2CMP_SETTINGS *aCfg)
void ToggleAspectRatioLock(wxCommandEvent &event) override
bool OpenProjectFiles(const std::vector< wxString > &aFilenames, int aCtl=0)
wxWindow * GetCurrentPage()
BITMAP2CMP_PANEL(BITMAP2CMP_FRAME *aParent)
void OnExportToFile(wxCommandEvent &event) override
void SaveSettings(BITMAP2CMP_SETTINGS *aCfg)
wxString formatOutputSize(double aSize)
void OnThresholdChange(wxScrollEvent &event) override
void ExportToBuffer(std::string &aOutput, OUTPUT_FMT_ID aFormat)
generate a export data of the current bitmap.
BITMAP2CMP_FRAME * m_parentFrame
void OnFormatChange(wxCommandEvent &event) override
void OnLoadFile(wxCommandEvent &event) override
EDA_UNITS getUnitFromSelection()
void OnNegativeClicked(wxCommandEvent &event) override
void OnPaintBW(wxPaintEvent &event) override
OUTPUT_FMT_ID getOutputFormat()
void OnSizeChangeY(wxCommandEvent &event) override
int ConvertBitmap(potrace_bitmap_t *aPotrace_bitmap, OUTPUT_FMT_ID aFormat, int aDpi_X, int aDpi_Y, const wxString &aLayer)
Run the conversion of the bitmap.
BITMAP2CMP_PANEL * m_panel
DROP_FILE()=delete
bool OnDropFiles(wxCoord x, wxCoord y, const wxArrayString &filenames) override
A wrapper for reporting to a wxString object.
Definition reporter.h:189
The common library.
This file is part of the common library.
#define KICAD_MESSAGE_DIALOG
Definition confirm.h:48
#define _(s)
EDA_UNITS
Definition eda_units.h:44
std::vector< FAB_LAYER_COLOR > dummy
IbisParser parser & reporter