Gerbview: move gerber_file_image_list to a separate file

This commit is contained in:
jean-pierre charras 2016-05-26 09:50:49 +02:00
parent 8c8a1238f1
commit 3b379787bc
22 changed files with 408 additions and 307 deletions

View File

@ -29,6 +29,7 @@ set( GERBVIEW_SRCS
class_gbr_screen.cpp class_gbr_screen.cpp
class_gbr_layout.cpp class_gbr_layout.cpp
class_gerber_file_image.cpp class_gerber_file_image.cpp
class_gerber_file_image_list.cpp
class_gerber_draw_item.cpp class_gerber_draw_item.cpp
class_gerbview_layer_widget.cpp class_gerbview_layer_widget.cpp
class_gbr_layer_box_selector.cpp class_gbr_layer_box_selector.cpp

View File

@ -5,9 +5,9 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 1992-2010 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr> * Copyright (C) 1992-2016 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors. * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -108,7 +108,7 @@ bool AM_PRIMITIVE::mapExposure( GERBER_DRAW_ITEM* aParent )
break; break;
} }
return exposure ^ aParent->m_imageParams->m_ImageNegative; return exposure ^ aParent->m_GerberImageFile->m_ImageNegative;
} }

View File

@ -10,7 +10,7 @@
* *
* Copyright (C) 1992-2010 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr> * Copyright (C) 1992-2010 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
* Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2010 KiCad Developers, see change_log.txt for contributors. * Copyright (C) 1992-2010 KiCad Developers, see AUTHORS.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License

View File

@ -32,7 +32,7 @@
#include <common.h> #include <common.h>
#include <colors_selection.h> #include <colors_selection.h>
#include <gerbview_frame.h> #include <gerbview_frame.h>
#include <class_gerber_file_image.h> #include <class_gerber_file_image_list.h>
#include <class_gbr_layer_box_selector.h> #include <class_gbr_layer_box_selector.h>

View File

@ -34,6 +34,7 @@
#include <class_drawpanel.h> #include <class_drawpanel.h>
#include <class_gbr_layout.h> #include <class_gbr_layout.h>
#include <class_gerber_file_image.h> #include <class_gerber_file_image.h>
#include <class_gerber_file_image_list.h>
GBR_LAYOUT::GBR_LAYOUT() GBR_LAYOUT::GBR_LAYOUT()
{ {

View File

@ -38,10 +38,10 @@
#include <class_gerber_file_image.h> #include <class_gerber_file_image.h>
GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( GBR_LAYOUT* aParent, GERBER_FILE_IMAGE* aGerberparams ) : GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( GBR_LAYOUT* aParent, GERBER_FILE_IMAGE* aGerberImageFile ) :
EDA_ITEM( (EDA_ITEM*)aParent, TYPE_GERBER_DRAW_ITEM ) EDA_ITEM( (EDA_ITEM*)aParent, TYPE_GERBER_DRAW_ITEM )
{ {
m_imageParams = aGerberparams; m_GerberImageFile = aGerberImageFile;
m_Layer = 0; m_Layer = 0;
m_Shape = GBR_SEGMENT; m_Shape = GBR_SEGMENT;
m_Flashed = false; m_Flashed = false;
@ -53,7 +53,7 @@ GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( GBR_LAYOUT* aParent, GERBER_FILE_IMAGE* aGer
m_mirrorB = false; m_mirrorB = false;
m_drawScale.x = m_drawScale.y = 1.0; m_drawScale.x = m_drawScale.y = 1.0;
m_lyrRotation = 0; m_lyrRotation = 0;
if( m_imageParams ) if( m_GerberImageFile )
SetLayerParameters(); SetLayerParameters();
} }
@ -62,7 +62,7 @@ GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( GBR_LAYOUT* aParent, GERBER_FILE_IMAGE* aGer
GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( const GERBER_DRAW_ITEM& aSource ) : GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( const GERBER_DRAW_ITEM& aSource ) :
EDA_ITEM( aSource ) EDA_ITEM( aSource )
{ {
m_imageParams = aSource.m_imageParams; m_GerberImageFile = aSource.m_GerberImageFile;
m_Shape = aSource.m_Shape; m_Shape = aSource.m_Shape;
m_Flags = aSource.m_Flags; m_Flags = aSource.m_Flags;
@ -105,15 +105,15 @@ wxPoint GERBER_DRAW_ITEM::GetABPosition( const wxPoint& aXYPosition ) const
* For instance: Rotation must be made after or before mirroring ? * For instance: Rotation must be made after or before mirroring ?
* Note: if something is changed here, GetYXPosition must reflect changes * Note: if something is changed here, GetYXPosition must reflect changes
*/ */
wxPoint abPos = aXYPosition + m_imageParams->m_ImageJustifyOffset; wxPoint abPos = aXYPosition + m_GerberImageFile->m_ImageJustifyOffset;
if( m_swapAxis ) if( m_swapAxis )
std::swap( abPos.x, abPos.y ); std::swap( abPos.x, abPos.y );
abPos += m_layerOffset + m_imageParams->m_ImageOffset; abPos += m_layerOffset + m_GerberImageFile->m_ImageOffset;
abPos.x = KiROUND( abPos.x * m_drawScale.x ); abPos.x = KiROUND( abPos.x * m_drawScale.x );
abPos.y = KiROUND( abPos.y * m_drawScale.y ); abPos.y = KiROUND( abPos.y * m_drawScale.y );
double rotation = m_lyrRotation * 10 + m_imageParams->m_ImageRotation * 10; double rotation = m_lyrRotation * 10 + m_GerberImageFile->m_ImageRotation * 10;
if( rotation ) if( rotation )
RotatePoint( &abPos, -rotation ); RotatePoint( &abPos, -rotation );
@ -140,36 +140,36 @@ wxPoint GERBER_DRAW_ITEM::GetXYPosition( const wxPoint& aABPosition ) const
if( !m_mirrorB ) if( !m_mirrorB )
xyPos.y = -xyPos.y; xyPos.y = -xyPos.y;
double rotation = m_lyrRotation * 10 + m_imageParams->m_ImageRotation * 10; double rotation = m_lyrRotation * 10 + m_GerberImageFile->m_ImageRotation * 10;
if( rotation ) if( rotation )
RotatePoint( &xyPos, rotation ); RotatePoint( &xyPos, rotation );
xyPos.x = KiROUND( xyPos.x / m_drawScale.x ); xyPos.x = KiROUND( xyPos.x / m_drawScale.x );
xyPos.y = KiROUND( xyPos.y / m_drawScale.y ); xyPos.y = KiROUND( xyPos.y / m_drawScale.y );
xyPos -= m_layerOffset + m_imageParams->m_ImageOffset; xyPos -= m_layerOffset + m_GerberImageFile->m_ImageOffset;
if( m_swapAxis ) if( m_swapAxis )
std::swap( xyPos.x, xyPos.y ); std::swap( xyPos.x, xyPos.y );
return xyPos - m_imageParams->m_ImageJustifyOffset; return xyPos - m_GerberImageFile->m_ImageJustifyOffset;
} }
void GERBER_DRAW_ITEM::SetLayerParameters() void GERBER_DRAW_ITEM::SetLayerParameters()
{ {
m_UnitsMetric = m_imageParams->m_GerbMetric; m_UnitsMetric = m_GerberImageFile->m_GerbMetric;
m_swapAxis = m_imageParams->m_SwapAxis; // false if A = X, B = Y; m_swapAxis = m_GerberImageFile->m_SwapAxis; // false if A = X, B = Y;
// true if A =Y, B = Y // true if A =Y, B = Y
m_mirrorA = m_imageParams->m_MirrorA; // true: mirror / axe A m_mirrorA = m_GerberImageFile->m_MirrorA; // true: mirror / axe A
m_mirrorB = m_imageParams->m_MirrorB; // true: mirror / axe B m_mirrorB = m_GerberImageFile->m_MirrorB; // true: mirror / axe B
m_drawScale = m_imageParams->m_Scale; // A and B scaling factor m_drawScale = m_GerberImageFile->m_Scale; // A and B scaling factor
m_layerOffset = m_imageParams->m_Offset; // Offset from OF command m_layerOffset = m_GerberImageFile->m_Offset; // Offset from OF command
// Rotation from RO command: // Rotation from RO command:
m_lyrRotation = m_imageParams->m_LocalRotation; m_lyrRotation = m_GerberImageFile->m_LocalRotation;
m_LayerNegative = m_imageParams->GetLayerParams().m_LayerNegative; m_LayerNegative = m_GerberImageFile->GetLayerParams().m_LayerNegative;
} }
@ -223,14 +223,10 @@ D_CODE* GERBER_DRAW_ITEM::GetDcodeDescr()
if( (m_DCode < FIRST_DCODE) || (m_DCode > LAST_DCODE) ) if( (m_DCode < FIRST_DCODE) || (m_DCode > LAST_DCODE) )
return NULL; return NULL;
GERBER_FILE_IMAGE* gerber = g_GERBER_List.GetGbrImage( m_Layer ); if( m_GerberImageFile == NULL )
if( gerber == NULL )
return NULL; return NULL;
D_CODE* d_code = gerber->GetDCODE( m_DCode, false ); return m_GerberImageFile->GetDCODE( m_DCode, false );
return d_code;
} }
@ -278,7 +274,7 @@ bool GERBER_DRAW_ITEM::Save( FILE* aFile ) const
bool GERBER_DRAW_ITEM::HasNegativeItems() bool GERBER_DRAW_ITEM::HasNegativeItems()
{ {
bool isClear = m_LayerNegative ^ m_imageParams->m_ImageNegative; bool isClear = m_LayerNegative ^ m_GerberImageFile->m_ImageNegative;
// if isClear is true, this item has negative shape // if isClear is true, this item has negative shape
// but if isClear is true, and if this item use an aperture macro definition, // but if isClear is true, and if this item use an aperture macro definition,
@ -336,7 +332,7 @@ void GERBER_DRAW_ITEM::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDra
* color other than the background color, else use the background color * color other than the background color, else use the background color
* when drawing so that an erasure happens. * when drawing so that an erasure happens.
*/ */
bool isDark = !(m_LayerNegative ^ m_imageParams->m_ImageNegative); bool isDark = !(m_LayerNegative ^ m_GerberImageFile->m_ImageNegative);
if( !isDark ) if( !isDark )
{ {

View File

@ -82,11 +82,11 @@ public:
// 0 for items that do not use DCodes (polygons) // 0 for items that do not use DCodes (polygons)
// or when unknown and normal values are 10 to 999 // or when unknown and normal values are 10 to 999
// values 0 to 9 can be used for special purposes // values 0 to 9 can be used for special purposes
GERBER_FILE_IMAGE* m_imageParams; /* main GERBER info for this item GERBER_FILE_IMAGE* m_GerberImageFile; /* Gerber file image source of this item
* Note: some params stored in this class are common * Note: some params stored in this class are common
* to the whole gerber file (i.e) the whole graphic * to the whole gerber file (i.e) the whole graphic
* layer and some can change when reaging the file, * layer and some can change when reading the file,
* so they are stored inside this item there is no * so they are stored inside this item if there is no
* redundancy for these parameters * redundancy for these parameters
*/ */
private: private:

View File

@ -374,202 +374,3 @@ void GERBER_FILE_IMAGE::DisplayImageInfo( void )
(double) m_ImageJustifyOffset.y*2.54/1000 ); (double) m_ImageJustifyOffset.y*2.54/1000 );
m_parent->AppendMsgPanel( _( "Image Justify Offset" ), msg, DARKRED ); m_parent->AppendMsgPanel( _( "Image Justify Offset" ), msg, DARKRED );
} }
// GERBER_FILE_IMAGE_LIST is a helper class to handle a list of GERBER_FILE_IMAGE files
GERBER_FILE_IMAGE_LIST::GERBER_FILE_IMAGE_LIST()
{
m_GERBER_List.reserve( GERBER_DRAWLAYERS_COUNT );
for( unsigned layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
m_GERBER_List.push_back( NULL );
}
GERBER_FILE_IMAGE_LIST::~GERBER_FILE_IMAGE_LIST()
{
ClearList();
for( unsigned layer = 0; layer < m_GERBER_List.size(); ++layer )
{
delete m_GERBER_List[layer];
m_GERBER_List[layer] = NULL;
}
}
GERBER_FILE_IMAGE* GERBER_FILE_IMAGE_LIST::GetGbrImage( int aIdx )
{
if( (unsigned)aIdx < m_GERBER_List.size() )
return m_GERBER_List[aIdx];
return NULL;
}
/**
* creates a new, empty GERBER_FILE_IMAGE* at index aIdx
* or at the first free location if aIdx < 0
* @param aIdx = the location to use ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
* @return true if the index used, or -1 if no room to add image
*/
int GERBER_FILE_IMAGE_LIST::AddGbrImage( GERBER_FILE_IMAGE* aGbrImage, int aIdx )
{
int idx = aIdx;
if( idx < 0 )
{
for( idx = 0; idx < (int)m_GERBER_List.size(); idx++ )
{
if( !IsUsed( idx ) )
break;
}
}
if( idx >= (int)m_GERBER_List.size() )
return -1; // No room
m_GERBER_List[idx] = aGbrImage;
return idx;
}
// remove all loaded data in list, but do not delete empty images
// (can be reused)
void GERBER_FILE_IMAGE_LIST::ClearList()
{
for( unsigned layer = 0; layer < m_GERBER_List.size(); ++layer )
ClearImage( layer );
}
// remove the loaded data of image aIdx, but do not delete it
void GERBER_FILE_IMAGE_LIST::ClearImage( int aIdx )
{
if( aIdx >= 0 && aIdx < (int)m_GERBER_List.size() && m_GERBER_List[aIdx] )
{
m_GERBER_List[aIdx]->InitToolTable();
m_GERBER_List[aIdx]->ResetDefaultValues();
m_GERBER_List[aIdx]->m_InUse = false;
}
}
// Build a name for image aIdx which can be used in layers manager
const wxString GERBER_FILE_IMAGE_LIST::GetDisplayName( int aIdx )
{
wxString name;
GERBER_FILE_IMAGE* gerber = NULL;
if( aIdx >= 0 && aIdx < (int)m_GERBER_List.size() )
gerber = m_GERBER_List[aIdx];
// if a file is loaded, build the name:
// <id> <short filename> <X2 FileFunction info> if a X2 FileFunction info is found
// or (if no FileFunction info)
// <id> <short filename> *
if( gerber && IsUsed(aIdx ) )
{
wxFileName fn( gerber->m_FileName );
wxString filename = fn.GetFullName();
// if the filename is too long, display a shortened name:
const int maxlen = 30;
if( filename.Length() > maxlen )
{
wxString shortenedfn = filename.Left(2) + "..." + filename.Right(maxlen-5);
filename = shortenedfn;
}
if( gerber->m_FileFunction )
{
if( gerber->m_FileFunction->IsCopper() )
{
name.Printf( "%d %s (%s, %s, %s)", aIdx + 1,
filename.GetData(),
GetChars( gerber->m_FileFunction->GetFileType() ),
GetChars( gerber->m_FileFunction->GetBrdLayerId() ),
GetChars( gerber->m_FileFunction->GetBrdLayerSide() ) );
}
else
{
name.Printf( "%d %s (%s, %s)", aIdx + 1,
filename.GetData(),
GetChars( gerber->m_FileFunction->GetFileType() ),
GetChars( gerber->m_FileFunction->GetBrdLayerId() ) );
}
}
else
name.Printf( _( "%d %s" ), aIdx + 1, filename.GetData() );
}
else
name.Printf( _( "Graphic layer %d" ), aIdx + 1 );
return name;
}
// return true if image is used (loaded and not cleared)
bool GERBER_FILE_IMAGE_LIST::IsUsed( int aIdx )
{
if( aIdx >= 0 && aIdx < (int)m_GERBER_List.size() )
return m_GERBER_List[aIdx] != NULL && m_GERBER_List[aIdx]->m_InUse;
return false;
}
// Helper function, for std::sort.
// Sort loaded images by Z order priority, if they have the X2 FileFormat info
// returns true if the first argument (ref) is ordered before the second (test).
static bool sortZorder( const GERBER_FILE_IMAGE* const& ref, const GERBER_FILE_IMAGE* const& test )
{
if( !ref && !test )
return false; // do not change order: no criteria to sort items
if( !ref || !ref->m_InUse )
return false; // Not used: ref ordered after
if( !test || !test->m_InUse )
return true; // Not used: ref ordered before
if( !ref->m_FileFunction && !test->m_FileFunction )
return false; // do not change order: no criteria to sort items
if( !ref->m_FileFunction )
return false;
if( !test->m_FileFunction )
return true;
if( ref->m_FileFunction->GetZOrder() != test->m_FileFunction->GetZOrder() )
return ref->m_FileFunction->GetZOrder() > test->m_FileFunction->GetZOrder();
return ref->m_FileFunction->GetZSubOrder() > test->m_FileFunction->GetZSubOrder();
}
void GERBER_FILE_IMAGE_LIST::SortImagesByZOrder( GERBER_DRAW_ITEM* aDrawList )
{
std::sort( m_GERBER_List.begin(), m_GERBER_List.end(), sortZorder );
// The image order has changed.
// Graphic layer numbering must be updated to match the widgets layer order
// Store the old/new graphic layer info:
std::map <int, int> tab_lyr;
for( unsigned layer = 0; layer < m_GERBER_List.size(); ++layer )
{
if( m_GERBER_List[layer] )
{
tab_lyr[m_GERBER_List[layer]->m_GraphicLayer] = layer;
m_GERBER_List[layer]->m_GraphicLayer = layer ;
}
}
// update the graphic layer in items to draw
for( GERBER_DRAW_ITEM* item = aDrawList; item; item = item->Next() )
{
int layer = item->GetLayer();
item->SetLayer( tab_lyr[layer] );
}
}
// The global image list:
GERBER_FILE_IMAGE_LIST g_GERBER_List;

View File

@ -22,8 +22,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#ifndef _CLASS_GERBER_H_ #ifndef CLASS_GERBER_FILE_IMAGE_H
#define _CLASS_GERBER_H_ #define CLASS_GERBER_FILE_IMAGE_H
#include <vector> #include <vector>
#include <set> #include <set>
@ -312,72 +312,4 @@ public:
void DisplayImageInfo( void ); void DisplayImageInfo( void );
}; };
/** #endif // ifndef CLASS_GERBER_FILE_IMAGE_H
* @brief GERBER_FILE_IMAGE_LIST is a helper class to handle a list of GERBER_FILE_IMAGE files
* which are loaded and can be displayed
* there are 32 images max which can be loaded
*/
class GERBER_FILE_IMAGE_LIST
{
// the list of loaded images (1 image = 1 gerber file)
std::vector<GERBER_FILE_IMAGE*> m_GERBER_List;
public:
GERBER_FILE_IMAGE_LIST();
~GERBER_FILE_IMAGE_LIST();
//Accessor
GERBER_FILE_IMAGE* GetGbrImage( int aIdx );
/**
* Add a GERBER_FILE_IMAGE* at index aIdx
* or at the first free location if aIdx < 0
* @param aGbrImage = the image to add
* @param aIdx = the location to use ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
* @return true if the index used, or -1 if no room to add image
*/
int AddGbrImage( GERBER_FILE_IMAGE* aGbrImage, int aIdx );
/**
* remove all loaded data in list
*/
void ClearList();
/**
* remove the loaded data of image aIdx
* @param aIdx = the index ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
*/
void ClearImage( int aIdx );
/**
* @return a name for image aIdx which can be used in layers manager
* and layer selector
* if a file is loaded, the name is:
* "<aIdx+1> <short filename> <X2 FileFunction info> if a X2 FileFunction info is found"
* or (if no FileFunction info)
* "<aIdx+1> <short filename> *"
* if no file loaded, the name is:
* "Layer n" with n = aIdx+1
* @param aIdx = the index ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
*/
const wxString GetDisplayName( int aIdx );
/**
* @return true if image is used (loaded and with items)
* @param aIdx = the index ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
*/
bool IsUsed( int aIdx );
/**
* Sort loaded images by Z order priority, if they have the X2 FileFormat info
* @param aDrawList: the draw list associated to the gerber images
* (SortImagesByZOrder updates the graphic layer of these items)
*/
void SortImagesByZOrder( GERBER_DRAW_ITEM* aDrawList );
};
extern GERBER_FILE_IMAGE_LIST g_GERBER_List;
#endif // ifndef _CLASS_GERBER_H_

View File

@ -0,0 +1,236 @@
/**
* @file class_gerber_file_image.cpp
* a GERBER class handle for a given layer info about used D_CODES and how the layer is drawn
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2016 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <fctsys.h>
#include <gerbview.h>
#include <gerbview_frame.h>
#include <class_gerber_file_image.h>
#include <class_gerber_file_image_list.h>
#include <class_X2_gerber_attributes.h>
// GERBER_FILE_IMAGE_LIST is a helper class to handle a list of GERBER_FILE_IMAGE files
GERBER_FILE_IMAGE_LIST::GERBER_FILE_IMAGE_LIST()
{
m_GERBER_List.reserve( GERBER_DRAWLAYERS_COUNT );
for( unsigned layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
m_GERBER_List.push_back( NULL );
}
GERBER_FILE_IMAGE_LIST::~GERBER_FILE_IMAGE_LIST()
{
ClearList();
for( unsigned layer = 0; layer < m_GERBER_List.size(); ++layer )
{
delete m_GERBER_List[layer];
m_GERBER_List[layer] = NULL;
}
}
GERBER_FILE_IMAGE* GERBER_FILE_IMAGE_LIST::GetGbrImage( int aIdx )
{
if( (unsigned)aIdx < m_GERBER_List.size() )
return m_GERBER_List[aIdx];
return NULL;
}
/**
* creates a new, empty GERBER_FILE_IMAGE* at index aIdx
* or at the first free location if aIdx < 0
* @param aIdx = the location to use ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
* @return true if the index used, or -1 if no room to add image
*/
int GERBER_FILE_IMAGE_LIST::AddGbrImage( GERBER_FILE_IMAGE* aGbrImage, int aIdx )
{
int idx = aIdx;
if( idx < 0 )
{
for( idx = 0; idx < (int)m_GERBER_List.size(); idx++ )
{
if( !IsUsed( idx ) )
break;
}
}
if( idx >= (int)m_GERBER_List.size() )
return -1; // No room
m_GERBER_List[idx] = aGbrImage;
return idx;
}
// remove all loaded data in list, but do not delete empty images
// (can be reused)
void GERBER_FILE_IMAGE_LIST::ClearList()
{
for( unsigned layer = 0; layer < m_GERBER_List.size(); ++layer )
ClearImage( layer );
}
// remove the loaded data of image aIdx, but do not delete it
void GERBER_FILE_IMAGE_LIST::ClearImage( int aIdx )
{
if( aIdx >= 0 && aIdx < (int)m_GERBER_List.size() && m_GERBER_List[aIdx] )
{
m_GERBER_List[aIdx]->InitToolTable();
m_GERBER_List[aIdx]->ResetDefaultValues();
m_GERBER_List[aIdx]->m_InUse = false;
}
}
// Build a name for image aIdx which can be used in layers manager
const wxString GERBER_FILE_IMAGE_LIST::GetDisplayName( int aIdx )
{
wxString name;
GERBER_FILE_IMAGE* gerber = NULL;
if( aIdx >= 0 && aIdx < (int)m_GERBER_List.size() )
gerber = m_GERBER_List[aIdx];
// if a file is loaded, build the name:
// <id> <short filename> <X2 FileFunction info> if a X2 FileFunction info is found
// or (if no FileFunction info)
// <id> <short filename> *
if( gerber && IsUsed(aIdx ) )
{
wxFileName fn( gerber->m_FileName );
wxString filename = fn.GetFullName();
// if the filename is too long, display a shortened name:
const int maxlen = 30;
if( filename.Length() > maxlen )
{
wxString shortenedfn = filename.Left(2) + "..." + filename.Right(maxlen-5);
filename = shortenedfn;
}
if( gerber->m_FileFunction )
{
if( gerber->m_FileFunction->IsCopper() )
{
name.Printf( "%d %s (%s, %s, %s)", aIdx + 1,
filename.GetData(),
GetChars( gerber->m_FileFunction->GetFileType() ),
GetChars( gerber->m_FileFunction->GetBrdLayerId() ),
GetChars( gerber->m_FileFunction->GetBrdLayerSide() ) );
}
else
{
name.Printf( "%d %s (%s, %s)", aIdx + 1,
filename.GetData(),
GetChars( gerber->m_FileFunction->GetFileType() ),
GetChars( gerber->m_FileFunction->GetBrdLayerId() ) );
}
}
else
name.Printf( _( "%d %s" ), aIdx + 1, filename.GetData() );
}
else
name.Printf( _( "Graphic layer %d" ), aIdx + 1 );
return name;
}
// return true if image is used (loaded and not cleared)
bool GERBER_FILE_IMAGE_LIST::IsUsed( int aIdx )
{
if( aIdx >= 0 && aIdx < (int)m_GERBER_List.size() )
return m_GERBER_List[aIdx] != NULL && m_GERBER_List[aIdx]->m_InUse;
return false;
}
// Helper function, for std::sort.
// Sort loaded images by Z order priority, if they have the X2 FileFormat info
// returns true if the first argument (ref) is ordered before the second (test).
static bool sortZorder( const GERBER_FILE_IMAGE* const& ref, const GERBER_FILE_IMAGE* const& test )
{
if( !ref && !test )
return false; // do not change order: no criteria to sort items
if( !ref || !ref->m_InUse )
return false; // Not used: ref ordered after
if( !test || !test->m_InUse )
return true; // Not used: ref ordered before
if( !ref->m_FileFunction && !test->m_FileFunction )
return false; // do not change order: no criteria to sort items
if( !ref->m_FileFunction )
return false;
if( !test->m_FileFunction )
return true;
if( ref->m_FileFunction->GetZOrder() != test->m_FileFunction->GetZOrder() )
return ref->m_FileFunction->GetZOrder() > test->m_FileFunction->GetZOrder();
return ref->m_FileFunction->GetZSubOrder() > test->m_FileFunction->GetZSubOrder();
}
void GERBER_FILE_IMAGE_LIST::SortImagesByZOrder( GERBER_DRAW_ITEM* aDrawList )
{
std::sort( m_GERBER_List.begin(), m_GERBER_List.end(), sortZorder );
// The image order has changed.
// Graphic layer numbering must be updated to match the widgets layer order
// Store the old/new graphic layer info:
std::map <int, int> tab_lyr;
for( unsigned layer = 0; layer < m_GERBER_List.size(); ++layer )
{
if( m_GERBER_List[layer] )
{
tab_lyr[m_GERBER_List[layer]->m_GraphicLayer] = layer;
m_GERBER_List[layer]->m_GraphicLayer = layer ;
}
}
// update the graphic layer in items to draw
for( GERBER_DRAW_ITEM* item = aDrawList; item; item = item->Next() )
{
int layer = item->GetLayer();
item->SetLayer( tab_lyr[layer] );
}
}
// The global image list:
GERBER_FILE_IMAGE_LIST g_GERBER_List;

View File

@ -0,0 +1,126 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2010-2016 Jean-Pierre Charras jp.charras at wanadoo.fr
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef CLASS_GERBER_FILE_IMAGE_LIST_H
#define CLASS_GERBER_FILE_IMAGE_LIST_H
#include <vector>
#include <set>
//#include <dcode.h>
#include <class_gerber_draw_item.h>
#include <class_aperture_macro.h>
/* gerber files have different parameters to define units and how items must be plotted.
* some are for the entire file, and other can change along a file.
* In Gerber world:
* an image is the entire gerber file and its "global" parameters
* a layer (that is very different from a board layer) is just a sub set of a file that
* have specific parameters
* if a Image parameter is set more than once, only the last value is used
* Some parameters can change along a file and are not layer specific: they are stored
* in GERBER_ITEM items, when instancied.
*
* In GerbView, to handle these parameters, there are 2 classes:
* GERBER_FILE_IMAGE : the main class containing most of parameters and data to plot a graphic layer
* Some of them can change along the file
* There is one GERBER_FILE_IMAGE per file and one graphic layer per file or GERBER_FILE_IMAGE
* GerbView does not read and merge 2 gerber file in one graphic layer:
* I believe this is not possible due to the constraints in Image parameters.
* GERBER_LAYER : containing the subset of parameters that is layer speficic
* A GERBER_FILE_IMAGE must include one GERBER_LAYER to define all parameters to plot a file.
* But a GERBER_FILE_IMAGE can use more than one GERBER_LAYER.
*/
class GERBER_FILE_IMAGE;
/**
* @brief GERBER_FILE_IMAGE_LIST is a helper class to handle a list of GERBER_FILE_IMAGE files
* which are loaded and can be displayed
* there are 32 images max which can be loaded
*/
class GERBER_FILE_IMAGE_LIST
{
// the list of loaded images (1 image = 1 gerber file)
std::vector<GERBER_FILE_IMAGE*> m_GERBER_List;
public:
GERBER_FILE_IMAGE_LIST();
~GERBER_FILE_IMAGE_LIST();
//Accessor
GERBER_FILE_IMAGE* GetGbrImage( int aIdx );
/**
* Add a GERBER_FILE_IMAGE* at index aIdx
* or at the first free location if aIdx < 0
* @param aGbrImage = the image to add
* @param aIdx = the location to use ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
* @return true if the index used, or -1 if no room to add image
*/
int AddGbrImage( GERBER_FILE_IMAGE* aGbrImage, int aIdx );
/**
* remove all loaded data in list
*/
void ClearList();
/**
* remove the loaded data of image aIdx
* @param aIdx = the index ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
*/
void ClearImage( int aIdx );
/**
* @return a name for image aIdx which can be used in layers manager
* and layer selector
* if a file is loaded, the name is:
* "<aIdx+1> <short filename> <X2 FileFunction info> if a X2 FileFunction info is found"
* or (if no FileFunction info)
* "<aIdx+1> <short filename> *"
* if no file loaded, the name is:
* "Layer n" with n = aIdx+1
* @param aIdx = the index ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
*/
const wxString GetDisplayName( int aIdx );
/**
* @return true if image is used (loaded and with items)
* @param aIdx = the index ( 0 ... GERBER_DRAWLAYERS_COUNT-1 )
*/
bool IsUsed( int aIdx );
/**
* Sort loaded images by Z order priority, if they have the X2 FileFormat info
* @param aDrawList: the draw list associated to the gerber images
* (SortImagesByZOrder updates the graphic layer of these items)
*/
void SortImagesByZOrder( GERBER_DRAW_ITEM* aDrawList );
};
extern GERBER_FILE_IMAGE_LIST g_GERBER_List;
#endif // ifndef CLASS_GERBER_FILE_IMAGE_LIST_H

View File

@ -37,7 +37,7 @@
#include <gerbview.h> #include <gerbview.h>
#include <gerbview_frame.h> #include <gerbview_frame.h>
#include <class_gerber_file_image.h> #include <class_gerber_file_image_list.h>
#include <layer_widget.h> #include <layer_widget.h>
#include <class_gerbview_layer_widget.h> #include <class_gerbview_layer_widget.h>

View File

@ -34,7 +34,7 @@
#include <gerbview.h> #include <gerbview.h>
#include <gerbview_frame.h> #include <gerbview_frame.h>
#include <class_gerber_file_image.h> #include <class_gerber_file_image_list.h>
#include <pcbplot.h> #include <pcbplot.h>
static double s_ScaleList[] = static double s_ScaleList[] =

View File

@ -37,6 +37,7 @@
#include <kicad_device_context.h> #include <kicad_device_context.h>
#include <gerbview_id.h> #include <gerbview_id.h>
#include <class_gerber_file_image.h> #include <class_gerber_file_image.h>
#include <class_gerber_file_image_list.h>
#include <dialog_helpers.h> #include <dialog_helpers.h>
#include <class_DCodeSelectionbox.h> #include <class_DCodeSelectionbox.h>
#include <class_gerbview_layer_widget.h> #include <class_gerbview_layer_widget.h>

View File

@ -69,6 +69,7 @@
#include <gerbview.h> #include <gerbview.h>
#include <gerbview_frame.h> #include <gerbview_frame.h>
#include <class_gerber_file_image.h> #include <class_gerber_file_image.h>
#include <class_gerber_file_image_list.h>
#include <class_excellon.h> #include <class_excellon.h>
#include <kicad_string.h> #include <kicad_string.h>
#include <class_X2_gerber_attributes.h> #include <class_X2_gerber_attributes.h>

View File

@ -37,6 +37,7 @@
#include <gerbview.h> #include <gerbview.h>
#include <gerbview_frame.h> #include <gerbview_frame.h>
#include <class_gerber_file_image.h> #include <class_gerber_file_image.h>
#include <class_gerber_file_image_list.h>
#include <select_layers_to_pcb.h> #include <select_layers_to_pcb.h>
#include <build_version.h> #include <build_version.h>
#include <wildcards_and_files_ext.h> #include <wildcards_and_files_ext.h>

View File

@ -43,6 +43,7 @@
#include <gerbview_id.h> #include <gerbview_id.h>
#include <hotkeys.h> #include <hotkeys.h>
#include <class_gerber_file_image.h> #include <class_gerber_file_image.h>
#include <class_gerber_file_image_list.h>
#include <dialog_helpers.h> #include <dialog_helpers.h>
#include <class_DCodeSelectionbox.h> #include <class_DCodeSelectionbox.h>
#include <class_gerbview_layer_widget.h> #include <class_gerbview_layer_widget.h>

View File

@ -31,7 +31,7 @@
#include <confirm.h> #include <confirm.h>
#include <gerbview_frame.h> #include <gerbview_frame.h>
#include <class_gerber_file_image.h> #include <class_gerber_file_image_list.h>
#include <class_gerbview_layer_widget.h> #include <class_gerbview_layer_widget.h>
bool GERBVIEW_FRAME::Clear_DrawLayers( bool query ) bool GERBVIEW_FRAME::Clear_DrawLayers( bool query )

View File

@ -28,6 +28,7 @@
#include <gerbview.h> #include <gerbview.h>
#include <gerbview_frame.h> #include <gerbview_frame.h>
#include <class_gerber_file_image.h> #include <class_gerber_file_image.h>
#include <class_gerber_file_image_list.h>
#include <dialog_helpers.h> #include <dialog_helpers.h>
/* Process the command triggered by the left button of the mouse /* Process the command triggered by the left button of the mouse

View File

@ -29,6 +29,7 @@
#include <gerbview.h> #include <gerbview.h>
#include <gerbview_frame.h> #include <gerbview_frame.h>
#include <class_gerber_file_image.h> #include <class_gerber_file_image.h>
#include <class_gerber_file_image_list.h>
#include <html_messagebox.h> #include <html_messagebox.h>
#include <macros.h> #include <macros.h>

View File

@ -32,6 +32,7 @@
#include <gerbview_frame.h> #include <gerbview_frame.h>
#include <gerbview_id.h> #include <gerbview_id.h>
#include <class_gerber_file_image.h> #include <class_gerber_file_image.h>
#include <class_gerber_file_image_list.h>
#include <select_layers_to_pcb.h> #include <select_layers_to_pcb.h>

View File

@ -37,6 +37,7 @@
#include <gerbview_id.h> #include <gerbview_id.h>
#include <hotkeys.h> #include <hotkeys.h>
#include <class_gerber_file_image.h> #include <class_gerber_file_image.h>
#include <class_gerber_file_image_list.h>
#include <class_gbr_layer_box_selector.h> #include <class_gbr_layer_box_selector.h>
#include <class_DCodeSelectionbox.h> #include <class_DCodeSelectionbox.h>
#include <dialog_helpers.h> #include <dialog_helpers.h>