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>
33 
34 #include <html_messagebox.h>
35 #include <macros.h>
36 
37 /* Read a gerber file, RS274D, RS274X or RS274X2 format.
38  */
39 bool GERBVIEW_FRAME::Read_GERBER_File( const wxString& GERBER_FullFileName )
40 {
41  wxString msg;
42 
43  int layer = getActiveLayer();
45  GERBER_FILE_IMAGE* gerber = GetGbrImage( layer );
46 
47  if( gerber == NULL )
48  {
49  gerber = new GERBER_FILE_IMAGE( layer );
50  images->AddGbrImage( gerber, layer );
51  }
52 
53  /* Read the gerber file */
54  bool success = gerber->LoadGerberFile( GERBER_FullFileName );
55 
56  if( !success )
57  {
58  msg.Printf( _( "File <%s> not found" ), GetChars( GERBER_FullFileName ) );
59  DisplayError( this, msg, 10 );
60  return false;
61  }
62 
63  // Display errors list
64  if( gerber->GetMessages().size() > 0 )
65  {
66  HTML_MESSAGE_BOX dlg( this, _("Errors") );
67  dlg.ListSet(gerber->GetMessages());
68  dlg.ShowModal();
69  }
70 
71  /* if the gerber file is only a RS274D file
72  * (i.e. without any aperture information), wran the user:
73  */
74  if( !gerber->m_Has_DCode )
75  {
76  msg = _("Warning: this file has no D-Code definition\n"
77  "It is perhaps an old RS274D file\n"
78  "Therefore the size of items is undefined");
79  wxMessageBox( msg );
80  }
81 
82  return true;
83 }
84 
85 
86 bool GERBER_FILE_IMAGE::LoadGerberFile( const wxString& aFullFileName )
87 {
88  int G_command = 0; // command number for G commands like G04
89  int D_commande = 0; // command number for D commands like D02
90  char line[GERBER_BUFZ];
91  char* text;
92 
95 
96  // Read the gerber file */
97  m_Current_File = wxFopen( aFullFileName, wxT( "rt" ) );
98 
99  if( m_Current_File == 0 )
100  return false;
101 
102  m_FileName = aFullFileName;
103 
104  wxString path = wxPathOnly( aFullFileName );
105 
106  // This change is needed to load included files, if exists:
107  if( path != wxEmptyString )
108  wxSetWorkingDirectory( path );
109 
110  LOCALE_IO toggleIo;
111 
112  wxString msg;
113 
114  while( true )
115  {
116  if( fgets( line, sizeof(line), m_Current_File ) == NULL )
117  {
118  if( m_FilesPtr == 0 )
119  break;
120 
121  fclose( m_Current_File );
122 
123  m_FilesPtr--;
125 
126  continue;
127  }
128 
129  text = StrPurge( line );
130 
131  while( text && *text )
132  {
133  switch( *text )
134  {
135  case ' ':
136  case '\r':
137  case '\n':
138  text++;
139  break;
140 
141  case '*': // End command
143  text++;
144  break;
145 
146  case 'M': // End file
148  while( *text )
149  text++;
150  break;
151 
152  case 'G': /* Line type Gxx : command */
153  G_command = GCodeNumber( text );
154  Execute_G_Command( text, G_command );
155  break;
156 
157  case 'D': /* Line type Dxx : Tool selection (xx > 0) or
158  * command if xx = 0..9 */
159  D_commande = DCodeNumber( text );
160  Execute_DCODE_Command( text, D_commande );
161  break;
162 
163  case 'X':
164  case 'Y': /* Move or draw command */
165  m_CurrentPos = ReadXYCoord( text );
166  if( *text == '*' ) // command like X12550Y19250*
167  {
168  Execute_DCODE_Command( text,
170  }
171  break;
172 
173  case 'I':
174  case 'J': /* Auxiliary Move command */
175  m_IJPos = ReadIJCoord( text );
176 
177  if( *text == '*' ) // command like X35142Y15945J504*
178  {
179  Execute_DCODE_Command( text,
181  }
182  break;
183 
184  case '%':
186  {
188  ReadRS274XCommand( line, text );
189  }
190  else //Error
191  {
192  AddMessageToList( wxT("Expected RS274X Command") );
194  text++;
195  }
196  break;
197 
198  default:
199  text++;
200  msg.Printf( wxT("Unexpected symbol <%c>"), *text );
201  AddMessageToList( msg );
202  break;
203  }
204  }
205  }
206 
207  fclose( m_Current_File );
208 
209  m_InUse = true;
210 
211  return true;
212 }
void AddMessageToList(const wxString &aMessage)
Function AddMessageToList Add a message to the message list.
bool Execute_DCODE_Command(char *&text, int D_command)
Definition: rs274d.cpp:581
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:194
Class LOCALE_IO is a class that can be instantiated within a scope in which you are expecting excepti...
Definition: common.h:166
wxPoint ReadXYCoord(char *&Text)
Function ReadXYCoord Returns the current coordinate type pointed to by XnnYnn Text (XnnnnYmmmm) ...
This file is part of the common library.
wxPoint ReadIJCoord(char *&Text)
Function ReadIJCoord Returns the current coordinate type pointed to by InnJnn Text (InnnnJmmmm) These...
bool Read_GERBER_File(const wxString &GERBER_FullFileName)
Definition: readgerb.cpp:39
Class GERBER_FILE_IMAGE holds the Image data and parameters for one gerber file and layer parameters ...
void ClearMessageList()
Function ClearMessageList Clear the message list Call it before reading a Gerber file.
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...
This file contains miscellaneous commonly used macros and functions.
int GCodeNumber(char *&Text)
Definition: rs274d.cpp:413
int DCodeNumber(char *&Text)
Definition: rs274d.cpp:436
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:86
const wxArrayString & GetMessages() const
Subclass of DIALOG_DISPLAY_HTML_TEXT_BASE, which is generated by wxFormBuilder.
GERBER_FILE_IMAGE_LIST * GetImagesList() const
Accessors to GERBER_FILE_IMAGE_LIST and GERBER_FILE_IMAGE data.
Class HTML_MESSAGE_BOX.
bool Execute_G_Command(char *&text, int G_command)
Definition: rs274d.cpp:456
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
int getActiveLayer()
Function getActiveLayer returns the active layer.
The common library.
#define GERBER_BUFZ
size of single line of a text from a gerber file.
Definition: gerbview.h:39
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:69
FILE * m_FilesList[INCLUDE_FILES_CNT_MAX+2]
bool ReadRS274XCommand(char *aBuff, char *&text)
Function ReadRS274XCommand reads a single RS274X command terminated with a %.
Definition: rs274x.cpp:192