KiCad PCB EDA Suite
readgerb.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) 2007-2016 Jean-Pierre Charras jp.charras at wanadoo.fr
5  * Copyright (C) 1992-2016 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, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include <fctsys.h>
26 #include <common.h>
27 #include <confirm.h>
28 #include <kicad_string.h>
29 #include <gerbview.h>
30 #include <gerbview_frame.h>
31 #include <gerber_file_image.h>
32 #include <gerber_file_image_list.h>
33 #include <view/view.h>
34 
35 #include <html_messagebox.h>
36 #include <macros.h>
37 
38 /* Read a gerber file, RS274D, RS274X or RS274X2 format.
39  */
40 bool GERBVIEW_FRAME::Read_GERBER_File( const wxString& GERBER_FullFileName )
41 {
42  wxString msg;
43 
44  int layer = GetActiveLayer();
46  GERBER_FILE_IMAGE* gerber = GetGbrImage( layer );
47 
48  if( gerber != NULL )
49  {
50  Erase_Current_DrawLayer( false );
51  }
52 
53  gerber = new GERBER_FILE_IMAGE( layer );
54  images->AddGbrImage( gerber, layer );
55 
56  /* Read the gerber file */
57  bool success = gerber->LoadGerberFile( GERBER_FullFileName );
58 
59  if( !success )
60  {
61  msg.Printf( _( "File \"%s\" not found" ), GetChars( GERBER_FullFileName ) );
62  DisplayError( this, msg, 10 );
63  return false;
64  }
65 
66  // Display errors list
67  if( gerber->GetMessages().size() > 0 )
68  {
69  HTML_MESSAGE_BOX dlg( this, _("Errors") );
70  dlg.ListSet(gerber->GetMessages());
71  dlg.ShowModal();
72  }
73 
74  /* if the gerber file is only a RS274D file
75  * (i.e. without any aperture information, but with items), warn the user:
76  */
77  if( !gerber->m_Has_DCode && gerber->GetItemsList() )
78  {
79  msg = _("Warning: this file has no D-Code definition\n"
80  "It is perhaps an old RS274D file\n"
81  "Therefore the size of items is undefined");
82  wxMessageBox( msg );
83  }
84 
85  auto canvas = GetGalCanvas();
86 
87  if( canvas )
88  {
89  auto view = canvas->GetView();
90 
91  if( gerber->m_ImageNegative )
92  {
93  // TODO: find a way to handle negative images
94  // (maybe convert geometry into positives?)
95  }
96 
97  for( auto item = gerber->GetItemsList(); item; item = item->Next() )
98  {
99  view->Add( (KIGFX::VIEW_ITEM*) item );
100  }
101  }
102 
103  return true;
104 }
105 
106 
107 
108 // size of a single line of text from a gerber file.
109 // warning: some files can have *very long* lines, so the buffer must be large.
110 #define GERBER_BUFZ 1000000
111 // A large buffer to store one line
112 static char lineBuffer[GERBER_BUFZ+1];
113 
114 bool GERBER_FILE_IMAGE::LoadGerberFile( const wxString& aFullFileName )
115 {
116  int G_command = 0; // command number for G commands like G04
117  int D_commande = 0; // command number for D commands like D02
118  char* text;
119 
120  ClearMessageList( );
121  ResetDefaultValues();
122 
123  // Read the gerber file */
124  m_Current_File = wxFopen( aFullFileName, wxT( "rt" ) );
125 
126  if( m_Current_File == 0 )
127  return false;
128 
129  m_FileName = aFullFileName;
130 
131  LOCALE_IO toggleIo;
132 
133  wxString msg;
134 
135  while( true )
136  {
137  if( fgets( lineBuffer, GERBER_BUFZ, m_Current_File ) == NULL )
138  break;
139 
140  m_LineNum++;
141  text = StrPurge( lineBuffer );
142 
143  while( text && *text )
144  {
145  switch( *text )
146  {
147  case ' ':
148  case '\r':
149  case '\n':
150  text++;
151  break;
152 
153  case '*': // End command
154  m_CommandState = END_BLOCK;
155  text++;
156  break;
157 
158  case 'M': // End file
159  m_CommandState = CMD_IDLE;
160  while( *text )
161  text++;
162  break;
163 
164  case 'G': /* Line type Gxx : command */
165  G_command = GCodeNumber( text );
166  Execute_G_Command( text, G_command );
167  break;
168 
169  case 'D': /* Line type Dxx : Tool selection (xx > 0) or
170  * command if xx = 0..9 */
171  D_commande = DCodeNumber( text );
172  Execute_DCODE_Command( text, D_commande );
173  break;
174 
175  case 'X':
176  case 'Y': /* Move or draw command */
177  m_CurrentPos = ReadXYCoord( text );
178  if( *text == '*' ) // command like X12550Y19250*
179  {
180  Execute_DCODE_Command( text, m_Last_Pen_Command );
181  }
182  break;
183 
184  case 'I':
185  case 'J': /* Auxiliary Move command */
186  m_IJPos = ReadIJCoord( text );
187 
188  if( *text == '*' ) // command like X35142Y15945J504*
189  {
190  Execute_DCODE_Command( text, m_Last_Pen_Command );
191  }
192  break;
193 
194  case '%':
195  if( m_CommandState != ENTER_RS274X_CMD )
196  {
197  m_CommandState = ENTER_RS274X_CMD;
198  ReadRS274XCommand( lineBuffer, GERBER_BUFZ, text );
199  }
200  else //Error
201  {
202  AddMessageToList( "Expected RS274X Command" );
203  m_CommandState = CMD_IDLE;
204  text++;
205  }
206  break;
207 
208  default:
209  msg.Printf( "Unexpected char 0x%2.2X &lt;%c&lt;", *text, *text );
210  AddMessageToList( msg );
211  text++;
212  break;
213  }
214  }
215  }
216 
217  fclose( m_Current_File );
218 
219  m_InUse = true;
220 
221  return true;
222 }
char * StrPurge(char *text)
Function StrPurge removes leading and training spaces, tabs and end of line chars in text return a po...
Definition: string.cpp:271
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown...
Definition: common.h:179
This file is part of the common library.
bool Read_GERBER_File(const wxString &GERBER_FullFileName)
Definition: readgerb.cpp:40
Class GERBER_FILE_IMAGE holds 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. ...
Class VIEW_ITEM - is an abstract base class for deriving all objects that can be added to a VIEW...
Definition: view_item.h:84
void Erase_Current_DrawLayer(bool query)
GERBER_FILE_IMAGE_LIST is a helper class to handle a list of GERBER_FILE_IMAGE files which are loaded...
int GetActiveLayer()
Function SetActiveLayer returns the active layer.
This file contains miscellaneous commonly used macros and functions.
static char lineBuffer[GERBER_BUFZ+1]
Definition: readgerb.cpp:112
void ListSet(const wxString &aList)
Function ListSet Add a list of items.
bool LoadGerberFile(const wxString &aFullFileName)
Read and load a gerber file.
Definition: readgerb.cpp:114
const wxArrayString & GetMessages() const
Subclass of DIALOG_DISPLAY_HTML_TEXT_BASE, which is generated by wxFormBuilder.
GERBER_DRAW_ITEM * Next() const
GERBER_FILE_IMAGE_LIST * GetImagesList() const
Accessors to GERBER_FILE_IMAGE_LIST and GERBER_FILE_IMAGE data.
#define GERBER_BUFZ
Definition: readgerb.cpp:110
Class HTML_MESSAGE_BOX.
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:92
GERBER_DRAW_ITEM * GetItemsList()
Function GetItemsList.
The common library.
EDA_DRAW_PANEL_GAL * GetGalCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
Definition: draw_frame.h:918
GERBER_FILE_IMAGE * GetGbrImage(int aIdx) const
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:245