Commit 64f12ffe authored by dickelbeck's avatar dickelbeck

gerberview & pcbnew fixes

parent 5e448ec4
......@@ -4,6 +4,21 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with
email address.
2007-Sep-25 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
+ pcbnew
* got rid of reference to global display options DisplayOpt.DisplayZones from
collectors.cpp so collectors.cpp can continue to be used in multiple future
(non-display related) general contexts.
* Moved TYPEZONE to end of AllBoardItems, added GENERAL_COLLECTOR::AllButZones to
provide support of DisplayOpt.DisplayZones.
* Added aHotKeyCode to PcbGeneralLocateAndDisplay()
+ gerbview
* viewer was getting stuck in a loop when loading a bad gerber file. Fixed
the bug, but line 223 through 225 of readgerb.cpp need review.
* beautified a few files with uncrustify, (any I had to look at).
2007-sept-25 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+ pcbnew:
......
/******************************************************/
/* Files.cp: Lecture / Sauvegarde des fichiers gerber */
/******************************************************/
/******************************************************/
/* Files.cp: Lecture / Sauvegarde des fichiers gerber */
/******************************************************/
#include "fctsys.h"
......@@ -12,215 +12,223 @@
/* Routines locales */
static void LoadDCodeFile(WinEDA_GerberFrame * frame, const wxString & FullFileName, wxDC * DC);
static void LoadDCodeFile( WinEDA_GerberFrame* frame, const wxString& FullFileName, wxDC* DC );
/********************************************************/
void WinEDA_GerberFrame::Files_io(wxCommandEvent& event)
void WinEDA_GerberFrame::Files_io( wxCommandEvent& event )
/********************************************************/
/* Gestion generale des commandes de lecture de fichiers
*/
*/
{
int id = event.GetId();
wxClientDC dc(DrawPanel);
DrawPanel->CursorOff(&dc);
switch (id)
{
case ID_MENU_LOAD_FILE:
case ID_LOAD_FILE:
if ( Clear_Pcb(&dc, TRUE) )
{
LoadOneGerberFile(wxEmptyString, &dc, 0);
}
break;
case ID_MENU_INC_LAYER_AND_APPEND_FILE:
case ID_INC_LAYER_AND_APPEND_FILE:
{
int layer = GetScreen()->m_Active_Layer;
GetScreen()->m_Active_Layer++;
if( ! LoadOneGerberFile(wxEmptyString, &dc, 0) )
GetScreen()->m_Active_Layer = layer;
SetToolbars();
}
break;
case ID_MENU_APPEND_FILE:
case ID_APPEND_FILE:
LoadOneGerberFile(wxEmptyString, &dc, 0);
break;
case ID_MENU_NEW_BOARD:
case ID_NEW_BOARD:
Clear_Pcb(&dc, TRUE);
Zoom_Automatique(FALSE);
GetScreen()->SetRefreshReq();
break;
case ID_LOAD_FILE_1:
case ID_LOAD_FILE_2:
case ID_LOAD_FILE_3:
case ID_LOAD_FILE_4:
case ID_LOAD_FILE_5:
case ID_LOAD_FILE_6:
case ID_LOAD_FILE_7:
case ID_LOAD_FILE_8:
case ID_LOAD_FILE_9:
case ID_LOAD_FILE_10:
if ( Clear_Pcb(&dc, TRUE) )
{
LoadOneGerberFile(
GetLastProject(id - ID_LOAD_FILE_1).GetData(),
&dc, FALSE);
}
break;
case ID_GERBVIEW_LOAD_DRILL_FILE:
DisplayError(this, _("Not yet available..."));
break;
case ID_GERBVIEW_LOAD_DCODE_FILE:
LoadDCodeFile(this, wxEmptyString, &dc);
break;
case ID_SAVE_BOARD:
case ID_MENU_SAVE_BOARD:
SaveGerberFile(GetScreen()->m_FileName, &dc);
break;
case ID_MENU_SAVE_BOARD_AS:
SaveGerberFile(wxEmptyString, &dc);
break;
default:
DisplayError(this, wxT("File_io Internal Error") );
break;
}
DrawPanel->MouseToCursorSchema();
DrawPanel->CursorOn(&dc);
int id = event.GetId();
wxClientDC dc( DrawPanel );
DrawPanel->CursorOff( &dc );
switch( id )
{
case ID_MENU_LOAD_FILE:
case ID_LOAD_FILE:
if( Clear_Pcb( &dc, TRUE ) )
{
LoadOneGerberFile( wxEmptyString, &dc, 0 );
}
break;
case ID_MENU_INC_LAYER_AND_APPEND_FILE:
case ID_INC_LAYER_AND_APPEND_FILE:
{
int layer = GetScreen()->m_Active_Layer;
GetScreen()->m_Active_Layer++;
if( !LoadOneGerberFile( wxEmptyString, &dc, 0 ) )
GetScreen()->m_Active_Layer = layer;
SetToolbars();
}
break;
case ID_MENU_APPEND_FILE:
case ID_APPEND_FILE:
LoadOneGerberFile( wxEmptyString, &dc, 0 );
break;
case ID_MENU_NEW_BOARD:
case ID_NEW_BOARD:
Clear_Pcb( &dc, TRUE );
Zoom_Automatique( FALSE );
GetScreen()->SetRefreshReq();
break;
case ID_LOAD_FILE_1:
case ID_LOAD_FILE_2:
case ID_LOAD_FILE_3:
case ID_LOAD_FILE_4:
case ID_LOAD_FILE_5:
case ID_LOAD_FILE_6:
case ID_LOAD_FILE_7:
case ID_LOAD_FILE_8:
case ID_LOAD_FILE_9:
case ID_LOAD_FILE_10:
if( Clear_Pcb( &dc, TRUE ) )
{
LoadOneGerberFile(
GetLastProject( id - ID_LOAD_FILE_1 ).GetData(),
&dc, FALSE );
}
break;
case ID_GERBVIEW_LOAD_DRILL_FILE:
DisplayError( this, _( "Not yet available..." ) );
break;
case ID_GERBVIEW_LOAD_DCODE_FILE:
LoadDCodeFile( this, wxEmptyString, &dc );
break;
case ID_SAVE_BOARD:
case ID_MENU_SAVE_BOARD:
SaveGerberFile( GetScreen()->m_FileName, &dc );
break;
case ID_MENU_SAVE_BOARD_AS:
SaveGerberFile( wxEmptyString, &dc );
break;
default:
DisplayError( this, wxT( "File_io Internal Error" ) );
break;
}
DrawPanel->MouseToCursorSchema();
DrawPanel->CursorOn( &dc );
}
/*******************************************************************************************/
int WinEDA_GerberFrame::LoadOneGerberFile(const wxString & FullFileName,
wxDC * DC, int mode)
int WinEDA_GerberFrame::LoadOneGerberFile( const wxString& FullFileName,
wxDC* DC, int mode )
/*******************************************************************************************/
/*
Lecture d'un fichier PCB, le nom etant dans PcbNameBuffer.s
retourne:
0 si fichier non lu ( annulation de commande ... )
1 si OK
*/
* Lecture d'un fichier PCB, le nom etant dans PcbNameBuffer.s
* retourne:
* 0 si fichier non lu ( annulation de commande ... )
* 1 si OK
*/
{
wxString filename = FullFileName;
wxString path = wxPathOnly(FullFileName);
ActiveScreen = GetScreen();
if( filename == wxEmptyString)
{
wxString mask = wxT("*") + g_PhotoFilenameExt;
mask += wxT(";*.gbr;*.gbx;*.lgr;*.ger");
filename = EDA_FileSelector(_("Gerber files:"),
path, /* Chemin par defaut */
wxEmptyString, /* nom fichier par defaut */
g_PhotoFilenameExt, /* extension par defaut */
mask, /* Masque d'affichage */
this,
0,
FALSE
);
if ( filename == wxEmptyString ) return FALSE;
}
GetScreen()->m_FileName = filename;
wxSetWorkingDirectory(path);
ChangeFileNameExt(filename,g_PenFilenameExt);
if ( Read_GERBER_File(DC, GetScreen()->m_FileName, filename) )
SetLastProject(GetScreen()->m_FileName);
Zoom_Automatique(FALSE);
GetScreen()->SetRefreshReq();
g_SaveTime = time(NULL);
return(1);
wxString filename = FullFileName;
wxString path = wxPathOnly( FullFileName );
ActiveScreen = GetScreen();
if( filename == wxEmptyString )
{
wxString mask = wxT( "*" ) + g_PhotoFilenameExt;
mask += wxT( ";*.gbr;*.gbx;*.lgr;*.ger" );
filename = EDA_FileSelector( _( "Gerber files:" ),
path, /* Chemin par defaut */
wxEmptyString, /* nom fichier par defaut */
g_PhotoFilenameExt, /* extension par defaut */
mask, /* Masque d'affichage */
this,
0,
FALSE
);
if( filename == wxEmptyString )
return FALSE;
}
GetScreen()->m_FileName = filename;
wxSetWorkingDirectory( path );
ChangeFileNameExt( filename, g_PenFilenameExt );
if( Read_GERBER_File( DC, GetScreen()->m_FileName, filename ) )
SetLastProject( GetScreen()->m_FileName );
Zoom_Automatique( FALSE );
GetScreen()->SetRefreshReq();
g_SaveTime = time( NULL );
return 1;
}
/**********************************************************************************************/
static void LoadDCodeFile(WinEDA_GerberFrame * frame, const wxString & FullFileName, wxDC * DC)
static void LoadDCodeFile( WinEDA_GerberFrame* frame, const wxString& FullFileName, wxDC* DC )
/**********************************************************************************************/
/*
Lecture d'un fichier PCB, le nom etant dans PcbNameBuffer.s
retourne:
0 si fichier non lu ( annulation de commande ... )
1 si OK
*/
* Lecture d'un fichier PCB, le nom etant dans PcbNameBuffer.s
* retourne:
* 0 si fichier non lu ( annulation de commande ... )
* 1 si OK
*/
{
wxString filename = FullFileName;
ActiveScreen = frame->GetScreen();
if( filename == wxEmptyString)
{
wxString penfilesmask( wxT("*") );
penfilesmask += g_PenFilenameExt;
filename = frame->GetScreen()->m_FileName;
ChangeFileNameExt(filename,g_PenFilenameExt);
filename = EDA_FileSelector(_("D codes files:"),
wxEmptyString, /* Chemin par defaut */
filename, /* nom fichier par defaut */
g_PenFilenameExt, /* extension par defaut */
penfilesmask, /* Masque d'affichage */
frame,
0,
TRUE
);
if ( filename == wxEmptyString ) return;
}
frame->Read_D_Code_File(filename);
frame->CopyDCodesSizeToItems();
frame->GetScreen()->SetRefreshReq();
wxString filename = FullFileName;
ActiveScreen = frame->GetScreen();
if( filename == wxEmptyString )
{
wxString penfilesmask( wxT( "*" ) );
penfilesmask += g_PenFilenameExt;
filename = frame->GetScreen()->m_FileName;
ChangeFileNameExt( filename, g_PenFilenameExt );
filename = EDA_FileSelector( _( "D codes files:" ),
wxEmptyString, /* Chemin par defaut */
filename, /* nom fichier par defaut */
g_PenFilenameExt, /* extension par defaut */
penfilesmask, /* Masque d'affichage */
frame,
0,
TRUE
);
if( filename == wxEmptyString )
return;
}
frame->Read_D_Code_File( filename );
frame->CopyDCodesSizeToItems();
frame->GetScreen()->SetRefreshReq();
}
/*******************************************************************************/
bool WinEDA_GerberFrame::SaveGerberFile(const wxString & FullFileName, wxDC * DC)
bool WinEDA_GerberFrame::SaveGerberFile( const wxString& FullFileName, wxDC* DC )
/*******************************************************************************/
/* Sauvegarde du fichier PCB en format ASCII
*/
*/
{
wxString filename = FullFileName;
if( filename == wxEmptyString )
{
wxString mask( wxT("*"));
mask += g_PhotoFilenameExt;
filename = EDA_FileSelector(_("Gerber files:"),
wxEmptyString, /* Chemin par defaut */
GetScreen()->m_FileName, /* nom fichier par defaut */
g_PhotoFilenameExt, /* extension par defaut */
mask, /* Masque d'affichage */
this,
wxFD_SAVE,
FALSE
);
if ( filename.IsEmpty() ) return FALSE;
}
GetScreen()->m_FileName = filename;
wxString filename = FullFileName;
if( filename == wxEmptyString )
{
wxString mask( wxT( "*" ) );
mask += g_PhotoFilenameExt;
filename = EDA_FileSelector( _( "Gerber files:" ),
wxEmptyString, /* Chemin par defaut */
GetScreen()->m_FileName, /* nom fichier par defaut */
g_PhotoFilenameExt, /* extension par defaut */
mask, /* Masque d'affichage */
this,
wxFD_SAVE,
FALSE
);
if( filename.IsEmpty() )
return FALSE;
}
GetScreen()->m_FileName = filename;
// TODO
return TRUE;
return TRUE;
}
/********************************************************/
/**** Routine de lecture et visu d'un fichier GERBER ****/
/********************************************************/
/********************************************************/
/**** Routine de lecture et visu d'un fichier GERBER ****/
/********************************************************/
#include "fctsys.h"
......@@ -11,57 +11,57 @@
#include "protos.h"
/* Format Gerber : NOTES :
Fonctions preparatoires:
Gn =
G01 interpolation lineaire ( trace de droites )
G02,G20,G21 Interpolation circulaire , sens trigo < 0
G03,G30,G31 Interpolation circulaire , sens trigo > 0
G04 commentaire
G06 Interpolation parabolique
G07 Interpolation cubique
G10 interpolation lineaire ( echelle 10x )
G11 interpolation lineaire ( echelle 0.1x )
G12 interpolation lineaire ( echelle 0.01x )
G52 plot symbole reference par Dnn code
G53 plot symbole reference par Dnn ; symbole tourne de -90 degres
G54 Selection d'outil
G55 Mode exposition photo
G56 plot symbole reference par Dnn A code
G57 affiche le symbole reference sur la console
G58 plot et affiche le symbole reference sur la console
G60 interpolation lineaire ( echelle 100x )
G70 Unites = Inches
G71 Unites = Millimetres
G74 supprime interpolation circulaire sur 360 degre, revient a G01
G75 Active interpolation circulaire sur 360 degre
G90 Mode Coordonnees absolues
G91 Mode Coordonnees Relatives
Coordonnees X,Y
X,Y sont suivies de + ou - et de m+n chiffres (non separes)
m = partie entiere
n = partie apres la virgule
formats classiques : m = 2, n = 3 (format 2.3)
m = 3, n = 4 (format 3.4)
ex:
G__ X00345Y-06123 D__*
Outils et D_CODES
numero d'outil ( identification des formes )
1 a 99 (classique)
1 a 999
D_CODES:
D01 ... D9 = codes d'action:
D01 = activation de lumiere (baisser de plume) lors du déplacement
D02 = extinction de lumiere (lever de plume) lors du déplacement
D03 = Flash
D09 = VAPE Flash
D51 = precede par G54 -> Select VAPE
D10 ... D255 = Indentification d'outils ( d'ouvertures )
Ne sont pas tj dans l'ordre ( voir tableau dans PCBPLOT.H)
*/
* Fonctions preparatoires:
* Gn =
* G01 interpolation lineaire ( trace de droites )
* G02,G20,G21 Interpolation circulaire , sens trigo < 0
* G03,G30,G31 Interpolation circulaire , sens trigo > 0
* G04 commentaire
* G06 Interpolation parabolique
* G07 Interpolation cubique
* G10 interpolation lineaire ( echelle 10x )
* G11 interpolation lineaire ( echelle 0.1x )
* G12 interpolation lineaire ( echelle 0.01x )
* G52 plot symbole reference par Dnn code
* G53 plot symbole reference par Dnn ; symbole tourne de -90 degres
* G54 Selection d'outil
* G55 Mode exposition photo
* G56 plot symbole reference par Dnn A code
* G57 affiche le symbole reference sur la console
* G58 plot et affiche le symbole reference sur la console
* G60 interpolation lineaire ( echelle 100x )
* G70 Unites = Inches
* G71 Unites = Millimetres
* G74 supprime interpolation circulaire sur 360 degre, revient a G01
* G75 Active interpolation circulaire sur 360 degre
* G90 Mode Coordonnees absolues
* G91 Mode Coordonnees Relatives
*
* Coordonnees X,Y
* X,Y sont suivies de + ou - et de m+n chiffres (non separes)
* m = partie entiere
* n = partie apres la virgule
* formats classiques : m = 2, n = 3 (format 2.3)
* m = 3, n = 4 (format 3.4)
* ex:
* G__ X00345Y-06123 D__*
*
* Outils et D_CODES
* numero d'outil ( identification des formes )
* 1 a 99 (classique)
* 1 a 999
* D_CODES:
*
* D01 ... D9 = codes d'action:
* D01 = activation de lumiere (baisser de plume) lors du déplacement
* D02 = extinction de lumiere (lever de plume) lors du déplacement
* D03 = Flash
* D09 = VAPE Flash
* D51 = precede par G54 -> Select VAPE
*
* D10 ... D255 = Indentification d'outils ( d'ouvertures )
* Ne sont pas tj dans l'ordre ( voir tableau dans PCBPLOT.H)
*/
/* Variables locales : */
......@@ -69,208 +69,218 @@ Outils et D_CODES
/* Routines Locales */
/* Routine de Lecture d'un fichier de D Codes.
Accepte format standard ou ALSPCB
un ';' demarre un commentaire.
Format Standard:
tool, Horiz, Vert, drill, vitesse, acc. ,Type ; [DCODE (commentaire)]
ex: 1, 12, 12, 0, 0, 0, 3 ; D10
Format ALSPCB:
Ver , Hor , Type , Tool [,Drill]
ex: 0.012, 0.012, L , D10
Classe les caract en buf_tmp sous forme de tableau de structures D_CODE.
Retourne:
< 0 si erreur:
-1 = Fichier non trouve
-2 = Erreur lecture fichier
Rang de D_code maxi lu ( nbr de dcodes )
Representation interne:
Les lignes sont représentées par des TRACKS standards
Les Flash sont représentées par des DRAWSEGMENTS
- ronds ou ovales: DRAWSEGMENTS
- rectangles: DRAWSEGMENTS
la reference aux D-CODES est placée dans le membre m_NetCode
*/
* Accepte format standard ou ALSPCB
* un ';' demarre un commentaire.
*
* Format Standard:
* tool, Horiz, Vert, drill, vitesse, acc. ,Type ; [DCODE (commentaire)]
* ex: 1, 12, 12, 0, 0, 0, 3 ; D10
*
* Format ALSPCB:
* Ver , Hor , Type , Tool [,Drill]
* ex: 0.012, 0.012, L , D10
*
* Classe les caract en buf_tmp sous forme de tableau de structures D_CODE.
* Retourne:
* < 0 si erreur:
* -1 = Fichier non trouve
* -2 = Erreur lecture fichier
* Rang de D_code maxi lu ( nbr de dcodes )
*
*
* Representation interne:
*
* Les lignes sont représentées par des TRACKS standards
* Les Flash sont représentées par des DRAWSEGMENTS
* - ronds ou ovales: DRAWSEGMENTS
* - rectangles: DRAWSEGMENTS
* la reference aux D-CODES est placée dans le membre m_NetCode
*/
/********************************************************/
bool WinEDA_GerberFrame::Read_GERBER_File(wxDC * DC,
const wxString & GERBER_FullFileName,
const wxString & D_Code_FullFileName)
bool WinEDA_GerberFrame::Read_GERBER_File( wxDC* DC,
const wxString& GERBER_FullFileName,
const wxString& D_Code_FullFileName )
/********************************************************/
/* Lecture de 1 fichier gerber.
Format
Imperial
Absolu
fin de bloc = *
CrLf apres chaque commande
G codes repetes
* Format
* Imperial
* Absolu
* fin de bloc = *
* CrLf apres chaque commande
* G codes repetes
*/
{
int G_commande = 0, D_commande = 0 ; /* Numero de commande G et D codes */
char Line[1024]; // Buffer des lignes du fichier gerber en cours
wxString msg;
char * text;
int layer = GetScreen()->m_Active_Layer;
GERBER_Descr * gerber_layer;
wxPoint pos;
int error = 0;
if ( g_GERBER_Descr_List[layer] == NULL )
{
g_GERBER_Descr_List[layer] = new GERBER_Descr(layer);
}
gerber_layer = g_GERBER_Descr_List[layer];
/* Mise a jour de l'echelle gerber : */
gerber_layer->ResetDefaultValues();
/* Lecture du fichier de Trace */
gerber_layer->m_Current_File = wxFopen(GERBER_FullFileName, wxT("rt") );
if (gerber_layer->m_Current_File == 0)
{
msg = _("File ") + GERBER_FullFileName + _(" not found");
DisplayError(this, msg, 10); return FALSE;
}
gerber_layer->m_FileName = GERBER_FullFileName;
wxSetWorkingDirectory(wxPathOnly(GERBER_FullFileName));
wxBusyCursor show_wait;
setlocale(LC_NUMERIC, "C");
while( TRUE )
{
if ( fgets(Line,255,gerber_layer->m_Current_File) == NULL ) // E.O.F
{
if ( gerber_layer->m_FilesPtr == 0 ) break;
fclose(gerber_layer->m_Current_File);
gerber_layer->m_FilesPtr --;
gerber_layer->m_Current_File =
gerber_layer->m_FilesList[gerber_layer->m_FilesPtr];
continue;
}
text = StrPurge(Line);
while ( text && *text )
{
switch( *text )
{
case ' ':
case '\r':
case '\n':
text ++;
break;
case '*': // End commande
gerber_layer->m_CommandState = END_BLOCK;
text ++;
break;
case 'M': // End file
gerber_layer->m_CommandState = CMD_IDLE;
while ( *text ) text ++;
break;
case 'G': /* Ligne type Gxx : commande */
G_commande = gerber_layer->ReturnGCodeNumber(text);
gerber_layer->Execute_G_Command(text, G_commande);
break ;
case 'D': /* Ligne type Dxx : Selection d'un outil ou commande si xx = 0..9*/
D_commande = gerber_layer->ReturnDCodeNumber(text);
gerber_layer->Execute_DCODE_Command(this, DC,
text, D_commande);
break ;
case 'X':
case 'Y': /* Commande de deplacement ou de Trace */
pos = gerber_layer->ReadXYCoord(text);
if ( *text == '*' ) // command like X12550Y19250*
{
gerber_layer->Execute_DCODE_Command(this, DC, text,
gerber_layer->m_Last_Pen_Command);
}
break;
case 'I':
case 'J': /* Commande de deplacement ou de Trace */
pos = gerber_layer->ReadIJCoord(text);
break;
case '%':
if (gerber_layer->m_CommandState != ENTER_RS274X_CMD )
{
gerber_layer->m_CommandState = ENTER_RS274X_CMD;
gerber_layer->ReadRS274XCommand(this, DC, Line, text);
}
else //Error
{
wxBell(); error++;
gerber_layer->m_CommandState = CMD_IDLE;
text++;
}
break;
default:
text ++; error++;
break;
} // end switch (*text)
} // end while (text
} // end while (TRUE)
if ( error )
{
msg.Printf( _("%d errors while reading Gerber file [%s]"),
error, GERBER_FullFileName.GetData());
DisplayError(this, msg);
}
fclose(gerber_layer->m_Current_File) ;
setlocale(LC_NUMERIC, "");
/* Init tableau des DCodes et Lecture fichier DCODES */
if ( !gerber_layer->m_As_DCode )
{
wxString DCodeFileName;
if( D_Code_FullFileName.IsEmpty())
{
wxString mask;
DCodeFileName = GERBER_FullFileName;
ChangeFileNameExt(DCodeFileName, g_PenFilenameExt);
mask = wxT("*") + g_PenFilenameExt;
DCodeFileName = EDA_FileSelector( _("D codes files:"),
wxEmptyString, /* Chemin par defaut */
DCodeFileName, /* nom fichier par defaut */
g_PenFilenameExt, /* extension par defaut */
mask, /* Masque d'affichage */
this,
0,
TRUE
);
}
else DCodeFileName = D_Code_FullFileName;
if ( ! DCodeFileName.IsEmpty() )
{
Read_D_Code_File(DCodeFileName);
CopyDCodesSizeToItems();
}
}
return TRUE;
int G_commande = 0, D_commande = 0; /* Numero de commande G et D codes */
char Line[1024]; // Buffer des lignes du fichier gerber en cours
wxString msg;
char* text;
int layer = GetScreen()->m_Active_Layer;
GERBER_Descr* gerber_layer;
wxPoint pos;
int error = 0;
if( g_GERBER_Descr_List[layer] == NULL )
{
g_GERBER_Descr_List[layer] = new GERBER_Descr( layer );
}
gerber_layer = g_GERBER_Descr_List[layer];
/* Mise a jour de l'echelle gerber : */
gerber_layer->ResetDefaultValues();
/* Lecture du fichier de Trace */
gerber_layer->m_Current_File = wxFopen( GERBER_FullFileName, wxT( "rt" ) );
if( gerber_layer->m_Current_File == 0 )
{
msg = _( "File " ) + GERBER_FullFileName + _( " not found" );
DisplayError( this, msg, 10 );
return FALSE;
}
gerber_layer->m_FileName = GERBER_FullFileName;
wxSetWorkingDirectory( wxPathOnly( GERBER_FullFileName ) );
wxBusyCursor show_wait;
setlocale( LC_NUMERIC, "C" );
while( TRUE )
{
if( fgets( Line, 255, gerber_layer->m_Current_File ) == NULL ) // E.O.F
{
if( gerber_layer->m_FilesPtr == 0 )
break;
fclose( gerber_layer->m_Current_File );
gerber_layer->m_FilesPtr--;
gerber_layer->m_Current_File =
gerber_layer->m_FilesList[gerber_layer->m_FilesPtr];
continue;
}
text = StrPurge( Line );
while( text && *text )
{
switch( *text )
{
case ' ':
case '\r':
case '\n':
text++;
break;
case '*': // End commande
gerber_layer->m_CommandState = END_BLOCK;
text++;
break;
case 'M': // End file
gerber_layer->m_CommandState = CMD_IDLE;
while( *text )
text++;
break;
case 'G': /* Ligne type Gxx : commande */
G_commande = gerber_layer->ReturnGCodeNumber( text );
gerber_layer->Execute_G_Command( text, G_commande );
break;
case 'D': /* Ligne type Dxx : Selection d'un outil ou commande si xx = 0..9*/
D_commande = gerber_layer->ReturnDCodeNumber( text );
gerber_layer->Execute_DCODE_Command( this, DC,
text, D_commande );
break;
case 'X':
case 'Y': /* Commande de deplacement ou de Trace */
pos = gerber_layer->ReadXYCoord( text );
if( *text == '*' ) // command like X12550Y19250*
{
gerber_layer->Execute_DCODE_Command( this, DC, text,
gerber_layer->m_Last_Pen_Command );
}
break;
case 'I':
case 'J': /* Commande de deplacement ou de Trace */
pos = gerber_layer->ReadIJCoord( text );
break;
case '%':
if( gerber_layer->m_CommandState != ENTER_RS274X_CMD )
{
gerber_layer->m_CommandState = ENTER_RS274X_CMD;
if( !gerber_layer->ReadRS274XCommand( this, DC, Line, text ) )
{
error++;
}
}
else //Error
{
wxBell();
error++;
gerber_layer->m_CommandState = CMD_IDLE;
text++;
}
break;
default:
text++;
error++;
break;
}
}
}
if( error )
{
msg.Printf( _( "%d errors while reading Gerber file [%s]" ),
error, GERBER_FullFileName.GetData() );
DisplayError( this, msg );
}
fclose( gerber_layer->m_Current_File );
setlocale( LC_NUMERIC, "" );
/* Init tableau des DCodes et Lecture fichier DCODES */
if( !gerber_layer->m_As_DCode )
{
wxString DCodeFileName;
if( D_Code_FullFileName.IsEmpty() )
{
wxString mask;
DCodeFileName = GERBER_FullFileName;
ChangeFileNameExt( DCodeFileName, g_PenFilenameExt );
mask = wxT( "*" ) + g_PenFilenameExt;
DCodeFileName = EDA_FileSelector( _( "D codes files:" ),
wxEmptyString, /* Chemin par defaut */
DCodeFileName, /* nom fichier par defaut */
g_PenFilenameExt, /* extension par defaut */
mask, /* Masque d'affichage */
this,
0,
TRUE
);
}
else
DCodeFileName = D_Code_FullFileName;
if( !DCodeFileName.IsEmpty() )
{
Read_D_Code_File( DCodeFileName );
CopyDCodesSizeToItems();
}
}
return TRUE;
}
/********************************************************/
/* Routine de lecture d'un fichier GERBER format RS274X */
/********************************************************/
/********************************************************/
/* Routine de lecture d'un fichier GERBER format RS274X */
/********************************************************/
#include "fctsys.h"
......@@ -10,462 +10,521 @@
#include "protos.h"
#define IsNumber(x) ( ( ((x) >= '0') && ((x) <='9') ) ||\
((x) == '-') || ((x) == '+') || ((x) == '.') || ((x) == ','))
#define CODE(x,y) ((x<<8) + (y))
enum rs274x_parameters
{
FORMAT_STATEMENT_COMMAND = CODE('F','S'),
AXIS_SELECT = CODE('A','S'),
MIRROR_IMAGE = CODE('M','I'),
MODE_OF_UNITS = CODE('M','O'),
INCH = CODE('I','N'),
MILLIMETER = CODE('M','M'),
OFFSET = CODE('O','F'),
SCALE_FACTOR = CODE('S','F'),
IMAGE_NAME = CODE('I','N'),
IMAGE_JUSTIFY = CODE('I','J'),
IMAGE_OFFSET = CODE('I','O'),
IMAGE_POLARITY = CODE('I','P'),
IMAGE_ROTATION = CODE('I','R'),
PLOTTER_FILM = CODE('P','M'),
INCLUDE_FILE = CODE('I','F'),
APERTURE_DESCR = CODE('A','D'),
APERTURE_MACRO = CODE('A','M'),
LAYER_NAME = CODE('L','N'),
LAYER_POLARITY = CODE('L','P'),
KNOCKOUT = CODE('K','O'),
STEP_AND_REPEAT = CODE('S','P'),
ROTATE = CODE('R','O')
#define IsNumber( x ) ( ( ( (x) >= '0' ) && ( (x) <='9' ) ) \
|| ( (x) == '-' ) || ( (x) == '+' ) || ( (x) == '.' ) || ( (x) == ',' ) )
#define CODE( x, y ) ( (x << 8) + (y) )
enum rs274x_parameters {
FORMAT_STATEMENT_COMMAND = CODE( 'F', 'S' ),
AXIS_SELECT = CODE( 'A', 'S' ),
MIRROR_IMAGE = CODE( 'M', 'I' ),
MODE_OF_UNITS = CODE( 'M', 'O' ),
INCH = CODE( 'I', 'N' ),
MILLIMETER = CODE( 'M', 'M' ),
OFFSET = CODE( 'O', 'F' ),
SCALE_FACTOR = CODE( 'S', 'F' ),
IMAGE_NAME = CODE( 'I', 'N' ),
IMAGE_JUSTIFY = CODE( 'I', 'J' ),
IMAGE_OFFSET = CODE( 'I', 'O' ),
IMAGE_POLARITY = CODE( 'I', 'P' ),
IMAGE_ROTATION = CODE( 'I', 'R' ),
PLOTTER_FILM = CODE( 'P', 'M' ),
INCLUDE_FILE = CODE( 'I', 'F' ),
APERTURE_DESCR = CODE( 'A', 'D' ),
APERTURE_MACRO = CODE( 'A', 'M' ),
LAYER_NAME = CODE( 'L', 'N' ),
LAYER_POLARITY = CODE( 'L', 'P' ),
KNOCKOUT = CODE( 'K', 'O' ),
STEP_AND_REPEAT = CODE( 'S', 'P' ),
ROTATE = CODE( 'R', 'O' )
};
/* Variables locales : */
/* Routines Locales */
static bool ReadApertureMacro( char * buff, char * &text, FILE *gerber_file);
static bool ReadApertureMacro( char* buff, char*& text, FILE* gerber_file );
/* Lit 2 codes ascii du texte point par text
retourne le code correspondant ou -1 si erreur
*/
static int ReadXCommand(char * &text)
* retourne le code correspondant ou -1 si erreur
*/
static int ReadXCommand( char*& text )
{
int result;
if ( text && *text )
{
result = (*text) << 8; text ++;
}
else return -1;
if ( text && *text )
{
result += (*text) & 255; text ++;
}
else return -1;
return result;
int result;
if( text && *text )
{
result = (*text) << 8; text++;
}
else
return -1;
if( text && *text )
{
result += (*text) & 255; text++;
}
else
return -1;
return result;
}
/********************************/
static int ReadInt(char * &text)
static int ReadInt( char*& text )
/********************************/
{
int nb = 0;
while ( text && *text == ' ' ) text++; // Skip blanks before number
while ( text && *text)
{
if ( (*text >= '0') && (*text <='9') )
{
nb *= 10; nb += *text & 0x0F;
text++;
}
else break;
}
return nb;
int nb = 0;
while( text && *text == ' ' )
text++;
// Skip blanks before number
while( text && *text )
{
if( (*text >= '0') && (*text <='9') )
{
nb *= 10; nb += *text & 0x0F;
text++;
}
else
break;
}
return nb;
}
/************************************/
static double ReadDouble(char * &text)
static double ReadDouble( char*& text )
/************************************/
{
double nb = 0.0;
char buf[256], * ptchar;
ptchar = buf;
while ( text && *text == ' ' ) text++; // Skip blanks before number
while ( text && *text)
{
if ( IsNumber(*text) )
{
* ptchar = * text;
text++; ptchar ++;
}
else break;
}
*ptchar = 0;
nb = atof(buf);
return nb;
double nb = 0.0;
char buf[256], * ptchar;
ptchar = buf;
while( text && *text == ' ' )
text++;
// Skip blanks before number
while( text && *text )
{
if( IsNumber( *text ) )
{
*ptchar = *text;
text++; ptchar++;
}
else
break;
}
*ptchar = 0;
nb = atof( buf );
return nb;
}
/****************************************************************************/
bool GERBER_Descr::ReadRS274XCommand(WinEDA_GerberFrame * frame, wxDC * DC,
char * buff, char * &text)
bool GERBER_Descr::ReadRS274XCommand( WinEDA_GerberFrame* frame, wxDC* DC,
char* buff, char*& text )
/****************************************************************************/
/* Lit toutes les commandes RS274X jusqu'a trouver de code de fin %
appelle ExecuteRS274XCommand() pour chaque commande trouve
*/
* appelle ExecuteRS274XCommand() pour chaque commande trouve
*/
{
int code_command;
bool eof = FALSE;
text++;
do
{
while ( *text )
{
switch( *text )
{
case '%': // End commande
text ++;
m_CommandState = CMD_IDLE;
return TRUE;
case ' ':
case '\r':
case '\n':
text++;
break;
case '*':
text++;
break;
default:
code_command = ReadXCommand ( text );
ExecuteRS274XCommand(code_command,
buff, text);
break;
}
}
// End of current line
if ( fgets(buff,255,m_Current_File) == NULL ) eof = TRUE;
text = buff;
} while( !eof );
return FALSE;
bool ok = true;
int code_command;
text++;
for(;;)
{
while( *text )
{
switch( *text )
{
case '%': // End commande
text++;
m_CommandState = CMD_IDLE;
goto exit; // success completion
case ' ':
case '\r':
case '\n':
text++;
break;
case '*':
text++;
break;
default:
code_command = ReadXCommand( text );
ok = ExecuteRS274XCommand( code_command, buff, text );
if( !ok )
goto exit;
break;
}
}
// End of current line
if( fgets( buff, 255, m_Current_File ) == NULL )
{
ok = false;
break;
}
text = buff;
}
exit:
return ok;
}
/*******************************************************************************/
bool GERBER_Descr::ExecuteRS274XCommand(int command, char * buff, char * &text)
bool GERBER_Descr::ExecuteRS274XCommand( int command, char* buff, char*& text )
/*******************************************************************************/
/* Execute 1 commande RS274X
*/
*/
{
int code;
int xy_seq_len, xy_seq_char;
char ctmp;
bool ok = TRUE;
D_CODE * dcode;
char Line[1024];
wxString msg;
double fcoord;
double conv_scale = m_GerbMetric ? PCB_INTERNAL_UNIT/25.4 : PCB_INTERNAL_UNIT;
switch( command )
{
case FORMAT_STATEMENT_COMMAND:
xy_seq_len = 2;
while ( *text != '*' )
{
switch ( *text )
{
case ' ':
text++;
break;
case'L': // No Leading 0
m_NoTrailingZeros = FALSE;
text ++;
break;
case'T': // No trailing 0
m_NoTrailingZeros = TRUE;
text ++;
break;
case 'A': // Absolute coord
m_Relative = FALSE; text++;
break;
case 'I': // Absolute coord
m_Relative = TRUE; text++;
break;
case 'N': // Sequence code (followed by the number of digits for the X,Y command
text++;
xy_seq_char = * text; text++;
if ( (xy_seq_char >= '0') && (xy_seq_char <= '9') )
xy_seq_len = - '0';
break;
case 'X':
case 'Y': // Valeurs transmises :2 (really xy_seq_len : FIX ME) digits
code = *(text ++); ctmp = *(text++) - '0';
if ( code == 'X' )
{
m_FmtScale.x = * text - '0'; // = nb chiffres apres la virgule
m_FmtLen.x = ctmp + m_FmtScale.x; // = nb total de chiffres
}
else {
m_FmtScale.y = * text - '0';
m_FmtLen.y = ctmp + m_FmtScale.y;
}
text++;
break;
case'*':
break;
default:
GetEndOfBlock( buff, text, m_Current_File );
ok = FALSE;
break;
}
}
break;
case AXIS_SELECT:
case MIRROR_IMAGE:
ok = FALSE;
break;
case MODE_OF_UNITS:
code = ReadXCommand ( text );
if ( code == INCH ) m_GerbMetric = FALSE;
else if ( code == MILLIMETER ) m_GerbMetric = TRUE;
conv_scale = m_GerbMetric ? PCB_INTERNAL_UNIT/25.4 : PCB_INTERNAL_UNIT;
break;
case OFFSET: // command: OFAnnBnn (nn = float number)
m_Offset.x = m_Offset.y = 0;
while ( *text != '*' )
{
switch ( *text )
{
case'A': // A axis offset in current unit (inch ou mm)
text ++;
fcoord = ReadDouble(text);
m_Offset.x = (int) round(fcoord * conv_scale);
break;
case'B': // B axis offset in current unit (inch ou mm)
text ++;
fcoord = ReadDouble(text);
m_Offset.y = (int) round(fcoord * conv_scale);
break;
}
}
break;
case SCALE_FACTOR:
case IMAGE_JUSTIFY:
case IMAGE_ROTATION :
case IMAGE_OFFSET:
case PLOTTER_FILM:
case LAYER_NAME:
case KNOCKOUT:
case STEP_AND_REPEAT:
case ROTATE:
msg.Printf(_("Command <%c%c> ignored by Gerbview"),
(command>>8) & 0xFF, command & 0xFF);
if ( g_DebugLevel > 0 )wxMessageBox(msg);
break;
case IMAGE_NAME:
m_Name.Empty();
while ( *text != '*' )
{
m_Name.Append(*text); text++;
}
break;
case IMAGE_POLARITY:
if ( strnicmp(text, "NEG", 3 ) == 0 ) m_ImageNegative = TRUE;
else m_ImageNegative = FALSE;
break;
case LAYER_POLARITY:
if ( * text == 'C' ) m_LayerNegative = TRUE;
else m_LayerNegative = FALSE;
break;
case APERTURE_MACRO:
ReadApertureMacro( buff, text, m_Current_File );
break;
case INCLUDE_FILE:
if ( m_FilesPtr >= 10 )
{
ok = FALSE;
DisplayError(NULL, _("Too many include files!!") );
break;
}
strcpy(Line, text);
strtok(Line,"*%%\n\r");
m_FilesList[m_FilesPtr] = m_Current_File;
m_Current_File = fopen(Line,"rt");
if (m_Current_File == 0)
{
wxString msg;
msg.Printf( wxT("fichier <%s> non trouve"),Line);
DisplayError(NULL, msg, 10);
ok = FALSE;
m_Current_File = m_FilesList[m_FilesPtr];
break;
}
m_FilesPtr ++;
break;
case APERTURE_DESCR:
if ( *text != 'D' )
{
ok = FALSE; break;
}
m_As_DCode = TRUE;
text++;
code = ReadInt(text);
ctmp = *text;
dcode = ReturnToolDescr(m_Layer, code);
if ( dcode == NULL ) break;
if ( text[1] == ',' ) // Tool usuel (C,R,O,P)
{
text += 2; // text pointe size ( 1er modifier)
dcode->m_Size.x = dcode->m_Size.y =
(int) round(ReadDouble(text) * conv_scale);
switch (ctmp )
{
case 'C': // Circle
dcode->m_Shape = GERB_CIRCLE;
while ( * text == ' ' ) text++;
if ( * text == 'X' )
{
text++;
dcode->m_Drill.x = dcode->m_Drill.y =
(int) round(ReadDouble(text) * conv_scale);
dcode->m_DrillShape = 1;
}
while ( * text == ' ' ) text++;
if ( * text == 'X' )
{
text++;
dcode->m_Drill.y =
(int) round(ReadDouble(text) * conv_scale);
dcode->m_DrillShape = 2;
}
dcode->m_Defined = TRUE;
break;
case 'O': // ovale
case 'R': // rect
dcode->m_Shape = (ctmp == 'O') ? GERB_OVALE : GERB_RECT;
while ( * text == ' ' ) text++;
if ( * text == 'X' )
{
text++;
dcode->m_Size.y =
(int) round(ReadDouble(text) * conv_scale);
}
while ( * text == ' ' ) text++;
if ( * text == 'X' )
{
text++;
dcode->m_Drill.x = dcode->m_Drill.y =
(int) round(ReadDouble(text) * conv_scale);
dcode->m_DrillShape = 1;
}
while ( * text == ' ' ) text++;
if ( * text == 'Y' )
{
text++;
dcode->m_Drill.y =
(int) round(ReadDouble(text) * conv_scale);
dcode->m_DrillShape = 2;
}
dcode->m_Defined = TRUE;
break;
case 'P': // Polygone
int code;
int xy_seq_len, xy_seq_char;
char ctmp;
bool ok = TRUE;
D_CODE* dcode;
char Line[1024];
wxString msg;
double fcoord;
double conv_scale = m_GerbMetric ? PCB_INTERNAL_UNIT / 25.4 : PCB_INTERNAL_UNIT;
switch( command )
{
case FORMAT_STATEMENT_COMMAND:
xy_seq_len = 2;
while( *text != '*' )
{
switch( *text )
{
case ' ':
text++;
break;
case 'L': // No Leading 0
m_NoTrailingZeros = FALSE;
text++;
break;
case 'T': // No trailing 0
m_NoTrailingZeros = TRUE;
text++;
break;
case 'A': // Absolute coord
m_Relative = FALSE; text++;
break;
case 'I': // Absolute coord
m_Relative = TRUE; text++;
break;
case 'N': // Sequence code (followed by the number of digits for the X,Y command
text++;
xy_seq_char = *text; text++;
if( (xy_seq_char >= '0') && (xy_seq_char <= '9') )
xy_seq_len = -'0';
break;
case 'X':
case 'Y': // Valeurs transmises :2 (really xy_seq_len : FIX ME) digits
code = *(text++); ctmp = *(text++) - '0';
if( code == 'X' )
{
m_FmtScale.x = *text - '0'; // = nb chiffres apres la virgule
m_FmtLen.x = ctmp + m_FmtScale.x; // = nb total de chiffres
}
else
{
m_FmtScale.y = *text - '0';
m_FmtLen.y = ctmp + m_FmtScale.y;
}
text++;
break;
case '*':
break;
default:
GetEndOfBlock( buff, text, m_Current_File );
ok = FALSE;
break;
}
}
break;
case AXIS_SELECT:
case MIRROR_IMAGE:
ok = FALSE;
break;
case MODE_OF_UNITS:
code = ReadXCommand( text );
if( code == INCH )
m_GerbMetric = FALSE;
else if( code == MILLIMETER )
m_GerbMetric = TRUE;
conv_scale = m_GerbMetric ? PCB_INTERNAL_UNIT / 25.4 : PCB_INTERNAL_UNIT;
break;
case OFFSET: // command: OFAnnBnn (nn = float number)
m_Offset.x = m_Offset.y = 0;
while( *text != '*' )
{
switch( *text )
{
case 'A': // A axis offset in current unit (inch ou mm)
text++;
fcoord = ReadDouble( text );
m_Offset.x = (int) round( fcoord * conv_scale );
break;
case 'B': // B axis offset in current unit (inch ou mm)
text++;
fcoord = ReadDouble( text );
m_Offset.y = (int) round( fcoord * conv_scale );
break;
}
}
break;
case SCALE_FACTOR:
case IMAGE_JUSTIFY:
case IMAGE_ROTATION:
case IMAGE_OFFSET:
case PLOTTER_FILM:
case LAYER_NAME:
case KNOCKOUT:
case STEP_AND_REPEAT:
case ROTATE:
msg.Printf( _( "Command <%c%c> ignored by Gerbview" ),
(command >> 8) & 0xFF, command & 0xFF );
if( g_DebugLevel > 0 )
wxMessageBox( msg );
break;
case IMAGE_NAME:
m_Name.Empty();
while( *text != '*' )
{
m_Name.Append( *text ); text++;
}
break;
case IMAGE_POLARITY:
if( strnicmp( text, "NEG", 3 ) == 0 )
m_ImageNegative = TRUE;
else
m_ImageNegative = FALSE;
break;
case LAYER_POLARITY:
if( *text == 'C' )
m_LayerNegative = TRUE;
else
m_LayerNegative = FALSE;
break;
case APERTURE_MACRO:
ReadApertureMacro( buff, text, m_Current_File );
break;
case INCLUDE_FILE:
if( m_FilesPtr >= 10 )
{
ok = FALSE;
DisplayError( NULL, _( "Too many include files!!" ) );
break;
}
strcpy( Line, text );
strtok( Line, "*%%\n\r" );
m_FilesList[m_FilesPtr] = m_Current_File;
m_Current_File = fopen( Line, "rt" );
if( m_Current_File == 0 )
{
wxString msg;
msg.Printf( wxT( "fichier <%s> non trouve" ), Line );
DisplayError( NULL, msg, 10 );
ok = FALSE;
m_Current_File = m_FilesList[m_FilesPtr];
break;
}
m_FilesPtr++;
break;
case APERTURE_DESCR:
if( *text != 'D' )
{
ok = FALSE; break;
}
m_As_DCode = TRUE;
text++;
code = ReadInt( text );
ctmp = *text;
dcode = ReturnToolDescr( m_Layer, code );
if( dcode == NULL )
break;
if( text[1] == ',' ) // Tool usuel (C,R,O,P)
{
text += 2; // text pointe size ( 1er modifier)
dcode->m_Size.x = dcode->m_Size.y =
(int) round( ReadDouble( text ) * conv_scale );
switch( ctmp )
{
case 'C': // Circle
dcode->m_Shape = GERB_CIRCLE;
while( *text == ' ' )
text++;
if( *text == 'X' )
{
text++;
dcode->m_Drill.x = dcode->m_Drill.y =
(int) round( ReadDouble( text ) * conv_scale );
dcode->m_DrillShape = 1;
}
while( *text == ' ' )
text++;
if( *text == 'X' )
{
text++;
dcode->m_Drill.y =
(int) round( ReadDouble( text ) * conv_scale );
dcode->m_DrillShape = 2;
}
dcode->m_Defined = TRUE;
break;
case 'O': // ovale
case 'R': // rect
dcode->m_Shape = (ctmp == 'O') ? GERB_OVALE : GERB_RECT;
while( *text == ' ' )
text++;
if( *text == 'X' )
{
text++;
dcode->m_Size.y =
(int) round( ReadDouble( text ) * conv_scale );
}
while( *text == ' ' )
text++;
if( *text == 'X' )
{
text++;
dcode->m_Drill.x = dcode->m_Drill.y =
(int) round( ReadDouble( text ) * conv_scale );
dcode->m_DrillShape = 1;
}
while( *text == ' ' )
text++;
if( *text == 'Y' )
{
text++;
dcode->m_Drill.y =
(int) round( ReadDouble( text ) * conv_scale );
dcode->m_DrillShape = 2;
}
dcode->m_Defined = TRUE;
break;
case 'P': // Polygone
// A modifier: temporairement la forme ronde est utilise
dcode->m_Shape = GERB_CIRCLE;
dcode->m_Defined = TRUE;
break;
}
}
break;
default:
ok = FALSE;
break;
}
GetEndOfBlock( buff, text, m_Current_File );
return ok;
dcode->m_Shape = GERB_CIRCLE;
dcode->m_Defined = TRUE;
break;
}
}
break;
default:
ok = FALSE;
break;
}
ok = GetEndOfBlock( buff, text, m_Current_File );
return ok;
}
/*****************************************************************/
bool GetEndOfBlock( char * buff, char * &text, FILE *gerber_file)
bool GetEndOfBlock( char* buff, char*& text, FILE* gerber_file )
/*****************************************************************/
{
bool eof = FALSE;
do {
while ( (text < buff+255) && *text )
{
if ( *text == '*' ) return TRUE;
if ( *text == '%' ) return TRUE;
text ++;
}
if ( fgets(buff,255,gerber_file) == NULL ) eof = TRUE;
text = buff;
} while( ! eof);
return FALSE;
for(;;)
{
while( (text < buff + 255) && *text )
{
if( *text == '*' )
return TRUE;
if( *text == '%' )
return TRUE;
text++;
}
if( fgets( buff, 255, gerber_file ) == NULL )
break;
text = buff;
}
return FALSE;
}
/*******************************************************************/
bool ReadApertureMacro( char * buff, char * &text, FILE *gerber_file)
bool ReadApertureMacro( char* buff, char*& text, FILE* gerber_file )
/*******************************************************************/
{
wxString macro_name;
int macro_type = 0;
// Read macro name
while ( (text < buff+255) && *text )
{
if ( *text == '*' ) break;
macro_name.Append(*text);
text ++;
}
if ( g_DebugLevel > 0 ) wxMessageBox(macro_name, wxT("macro name"));
text = buff;
fgets(buff,255,gerber_file);
// Read parameters
macro_type = ReadInt(text);
while ( (text < buff+255) && *text )
{
if ( *text == '*' ) return TRUE;
text ++;
}
return FALSE;
wxString macro_name;
int macro_type = 0;
// Read macro name
while( (text < buff + 255) && *text )
{
if( *text == '*' )
break;
macro_name.Append( *text );
text++;
}
if( g_DebugLevel > 0 )
wxMessageBox( macro_name, wxT( "macro name" ) );
text = buff;
fgets( buff, 255, gerber_file );
// Read parameters
macro_type = ReadInt( text );
while( (text < buff + 255) && *text )
{
if( *text == '*' )
return TRUE;
text++;
}
return FALSE;
}
......@@ -112,11 +112,11 @@ public:
/**
* Function Remove
* removes the item at item_position (first position is 0);
* @param item_position index.
* @param ndx The index into the list.
*/
void Remove( unsigned int item_position )
void Remove( int ndx )
{
m_List.erase( m_List.begin() + item_position );
m_List.erase( m_List.begin() + (unsigned) ndx );
}
/**
......
......@@ -400,8 +400,12 @@ public:
* a popup menu is shown which allows the user to pick which item he/she is
* interested in. Once an item is chosen, then it is make the "current item"
* and the status window is updated to reflect this.
*
* @param aHotKeyCode The hotkey which relates to the caller and determines the
* type of search to be performed. If zero, then the mouse tools will be
* tested instead.
*/
BOARD_ITEM* PcbGeneralLocateAndDisplay();
BOARD_ITEM* PcbGeneralLocateAndDisplay( int aHotKeyCode = 0 );
BOARD_ITEM* Locate( int typeloc, int LayerSearch );
void ProcessItemSelection( wxCommandEvent& event );
......
......@@ -38,10 +38,10 @@ const KICAD_T GENERAL_COLLECTOR::AllBoardItems[] = {
TYPECOTATION,
TYPEVIA,
TYPETRACK,
TYPEZONE,
TYPEPAD,
TYPETEXTEMODULE,
TYPEMODULE,
TYPEZONE,
EOT
};
......@@ -52,13 +52,24 @@ const KICAD_T GENERAL_COLLECTOR::PrimaryItems[] = {
TYPECOTATION,
TYPEVIA,
TYPETRACK,
// TYPEPAD, TYPEPAD and TYPETEXTEMODULE are handled in a subsearch
// TYPETEXTEMODULE,
TYPEMODULE,
EOT
};
const KICAD_T GENERAL_COLLECTOR::AllButZones[] = {
TYPETEXTE,
TYPEDRAWSEGMENT,
TYPECOTATION,
TYPEVIA,
TYPETRACK,
TYPEPAD,
TYPETEXTEMODULE,
TYPEMODULE,
EOT
};
const KICAD_T GENERAL_COLLECTOR::ModuleItems[] = {
TYPEMODULE,
EOT
......@@ -95,7 +106,6 @@ SEARCH_RESULT GENERAL_COLLECTOR::Inspect( EDA_BaseStruct* testItem, const void*
{
BOARD_ITEM* item = (BOARD_ITEM*) testItem;
MODULE* module = NULL;
bool skip_item = false;
#if 0 // debugging
static int breakhere = 0;
......@@ -173,7 +183,6 @@ SEARCH_RESULT GENERAL_COLLECTOR::Inspect( EDA_BaseStruct* testItem, const void*
case TYPETRACK:
break;
case TYPEZONE:
if( ! DisplayOpt.DisplayZones ) skip_item = true;
break;
case TYPETEXTE:
break;
......@@ -183,20 +192,18 @@ SEARCH_RESULT GENERAL_COLLECTOR::Inspect( EDA_BaseStruct* testItem, const void*
break;
case TYPETEXTEMODULE:
module = (MODULE*) item->GetParent();
if( m_Guide->IgnoreMTextsMarkedNoShow() && ((TEXTE_MODULE*)item)->m_NoShow )
goto exit;
if( module )
{
module = (MODULE*) item->GetParent();
if( m_Guide->IgnoreMTextsMarkedNoShow() && ((TEXTE_MODULE*)item)->m_NoShow )
if( m_Guide->IgnoreMTextsOnCopper() && module->GetLayer()==LAYER_CUIVRE_N )
goto exit;
if( module )
{
if( m_Guide->IgnoreMTextsOnCopper() && module->GetLayer()==LAYER_CUIVRE_N )
goto exit;
if( m_Guide->IgnoreMTextsOnCmp() && module->GetLayer()==LAYER_CMP_N )
goto exit;
}
if( m_Guide->IgnoreMTextsOnCmp() && module->GetLayer()==LAYER_CMP_N )
goto exit;
}
break;
......@@ -234,7 +241,7 @@ SEARCH_RESULT GENERAL_COLLECTOR::Inspect( EDA_BaseStruct* testItem, const void*
{
if( item->HitTest( m_RefPos ) )
{
if ( ! skip_item ) Append( item );
Append( item );
goto exit;
}
}
......@@ -261,7 +268,7 @@ SEARCH_RESULT GENERAL_COLLECTOR::Inspect( EDA_BaseStruct* testItem, const void*
{
if( item->HitTest( m_RefPos ) )
{
if ( ! skip_item ) Append2nd( item );
Append2nd( item );
goto exit;
}
}
......
......@@ -146,6 +146,7 @@ public:
* @return bool - ture if should ignore MODULEs on component layer.
*/
virtual bool IgnoreModulesOnCmp() const = 0;
/**
* Function UseHitTesting
......@@ -201,6 +202,12 @@ public:
static const KICAD_T AllBoardItems[];
/**
* A scan list for all editable board items, except zones
*/
static const KICAD_T AllButZones[];
/**
* A scan list for all primary board items, omitting items which are subordinate to
* a MODULE, such as D_PAD and TEXTEMODULE.
......
......@@ -153,9 +153,9 @@ static BOARD_ITEM* AllAreModulesAndReturnSmallestIfSo( GENERAL_COLLECTOR* aColle
}
/*************************************************************/
BOARD_ITEM* WinEDA_BasePcbFrame::PcbGeneralLocateAndDisplay()
/*************************************************************/
/****************************************************************************/
BOARD_ITEM* WinEDA_BasePcbFrame::PcbGeneralLocateAndDisplay( int aHotKeyCode )
/****************************************************************************/
{
BOARD_ITEM* item;
......@@ -166,7 +166,11 @@ BOARD_ITEM* WinEDA_BasePcbFrame::PcbGeneralLocateAndDisplay()
const KICAD_T* scanList;
if( m_ID_current_state == 0 )
if( aHotKeyCode )
{
// switch here
}
else if( m_ID_current_state == 0 )
{
switch( m_HTOOL_current_state )
{
......@@ -175,7 +179,9 @@ BOARD_ITEM* WinEDA_BasePcbFrame::PcbGeneralLocateAndDisplay()
break;
default:
scanList = GENERAL_COLLECTOR::AllBoardItems;
scanList = DisplayOpt.DisplayZones ?
GENERAL_COLLECTOR::AllBoardItems :
GENERAL_COLLECTOR::AllButZones;
break;
}
}
......@@ -196,26 +202,32 @@ BOARD_ITEM* WinEDA_BasePcbFrame::PcbGeneralLocateAndDisplay()
break;
default:
scanList = GENERAL_COLLECTOR::AllBoardItems;
scanList = DisplayOpt.DisplayZones ?
GENERAL_COLLECTOR::AllBoardItems :
GENERAL_COLLECTOR::AllButZones;
}
}
m_Collector->Collect( m_Pcb, scanList, GetScreen()->RefPos( true ), guide );
/* debugging: print out the collected items, showing their priority order too.
* for( unsigned i=0; i<m_Collector->GetCount(); ++i )
* (*m_Collector)[i]->Show( 0, std::cout );
*/
#if 0
// debugging: print out the collected items, showing their priority order too.
for( unsigned i=0; i<m_Collector->GetCount(); ++i )
(*m_Collector)[i]->Show( 0, std::cout );
#endif
/* Remove redundancies: most of time, zones are found twice,
* because zones are filled twice ( once by by horizontal and once by vertical segments )
*/
unsigned long timestampzone = 0;
for( unsigned int ii = 0; ii < m_Collector->GetCount(); ii++ )
int limit = m_Collector->GetCount();
for( int ii = 0; ii < limit; ii++ )
{
item = (*m_Collector)[ii];
if( item->Type() != TYPEZONE )
continue;
/* Found a TYPE ZONE */
if( item->m_TimeStamp == timestampzone ) // Remove it, redundant, zone already found
{
......@@ -282,14 +294,6 @@ BOARD_ITEM* WinEDA_BasePcbFrame::PcbGeneralLocateAndDisplay()
}
return item;
/* old way:
*
* item = Locate( CURSEUR_OFF_GRILLE, GetScreen()->m_Active_Layer );
* if( item == NULL )
* item = Locate( CURSEUR_OFF_GRILLE, -1 );
* return item;
*/
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment