Gerbview: added: image polarity, axis select, layer rotation. Code cleanup.

This commit is contained in:
jean-pierre charras 2010-10-16 16:51:22 +02:00
parent 9ec8d53604
commit a8ebad2fc4
25 changed files with 530 additions and 388 deletions

View File

@ -1,25 +1,17 @@
Here is the proposed copyright message to be added to all source files Here is the proposed copyright message to be added to all source files
at their top. There is one line that represents the main copyright holder at their top. There is one line that represents the main copyright holder.
and that would be Jean-Pierre Charras for existing modules.
But in the future, the respective author of any newly coded module would be But in the future, the respective author of any newly coded module would be
listed as the main copyright holder. Additional workers who might earn a listed as the main copyright holder. Additional workers who might earn a
partial copyright holder status of the respective module are simply left in the partial copyright holder status of the respective module are simply left in the
change_log.txt file, see the 2nd Copyright line below. change_log.txt file, see the 2nd Copyright line below.
Jean-Pierre, let me know if this is satisfactory and I will run a script I have to
pre-pend it to all the sources.
Thanks, Dick Hollenbeck dick@softplc.com.
/* /*
* 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-2009 Jean-Pierre Charras, jean-pierre.charras@inpg.fr * Copyright (C) 1992-2010 <Creator>
* Copyright (C) 1992-2009 Kicad Developers, see AUTHORS.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

@ -61,10 +61,32 @@ extern int scale( double aCoord, bool isMetric ); // defined it rs274d.cpp
*/ */
GERBER::GERBER( WinEDA_GerberFrame* aParent, int aLayer ) GERBER_LAYER::GERBER_LAYER()
{
ResetDefaultValues();
}
GERBER_LAYER::~GERBER_LAYER()
{
}
void GERBER_LAYER::ResetDefaultValues()
{
m_LayerName = wxT( "no name" ); // Layer name from the LN command
m_LayerNegative = false; // true = Negative Layer
m_StepForRepeat.x = m_StepForRepeat.y = 0; // X and Y offsets for Step and Repeat command
m_XRepeatCount = 1; // The repeat count on X axis
m_YRepeatCount = 1; // The repeat count on Y axis
m_StepForRepeatMetric = false; // false = Inches, true = metric
}
GERBER_IMAGE::GERBER_IMAGE( WinEDA_GerberFrame* aParent, int aLayer )
{ {
m_Parent = aParent; m_Parent = aParent;
m_GraphicLayer = aLayer; // Graphic layer Number m_GraphicLayer = aLayer; // Graphic layer Number
m_Selected_Tool = FIRST_DCODE; m_Selected_Tool = FIRST_DCODE;
@ -77,7 +99,7 @@ GERBER::GERBER( WinEDA_GerberFrame* aParent, int aLayer )
} }
GERBER::~GERBER() GERBER_IMAGE::~GERBER_IMAGE()
{ {
for( unsigned ii = 0; ii < DIM( m_Aperture_List ); ii++ ) for( unsigned ii = 0; ii < DIM( m_Aperture_List ); ii++ )
{ {
@ -90,7 +112,7 @@ GERBER::~GERBER()
} }
D_CODE* GERBER::GetDCODE( int aDCODE, bool create ) D_CODE* GERBER_IMAGE::GetDCODE( int aDCODE, bool create )
{ {
unsigned ndx = aDCODE - FIRST_DCODE; unsigned ndx = aDCODE - FIRST_DCODE;
@ -109,7 +131,7 @@ D_CODE* GERBER::GetDCODE( int aDCODE, bool create )
} }
APERTURE_MACRO* GERBER::FindApertureMacro( const APERTURE_MACRO& aLookup ) APERTURE_MACRO* GERBER_IMAGE::FindApertureMacro( const APERTURE_MACRO& aLookup )
{ {
APERTURE_MACRO_SET::iterator iter = m_aperture_macros.find( aLookup ); APERTURE_MACRO_SET::iterator iter = m_aperture_macros.find( aLookup );
@ -123,48 +145,41 @@ APERTURE_MACRO* GERBER::FindApertureMacro( const APERTURE_MACRO& aLookup )
} }
void GERBER::ResetDefaultValues() void GERBER_IMAGE::ResetDefaultValues()
{ {
m_GBRLayerParams.ResetDefaultValues();
m_FileName.Empty(); m_FileName.Empty();
m_ImageName = wxT( "no image name" ); // Image name from the IN command m_ImageName = wxT( "no name" ); // Image name from the IN command
m_LayerName = wxT( "no layer name" ); // Layer name from the LN command
m_LayerNegative = false; // true = Negative Layer
m_ImageNegative = false; // true = Negative image m_ImageNegative = false; // true = Negative image
m_GerbMetric = false; // false = Inches (default), true = metric m_GerbMetric = false; // false = Inches (default), true = metric
m_Relative = false; // false = absolute Coord, m_Relative = false; // false = absolute Coord,
// true = relative Coord // true = relative Coord
m_NoTrailingZeros = false; // true: trailing zeros deleted m_NoTrailingZeros = false; // true: trailing zeros deleted
m_ImageOffset.x = m_ImageOffset.y = 0; // Coord Offset, from IO command
m_ImageRotation = 0; // Allowed 0, 900, 1800, 2700 (in 0.1 degree
m_LocalRotation = 0; // Layer totation from RO command (in 0.1 degree)
m_Offset.x = 0;
m_Offset.y = 0; // Coord Offset, from OF command
m_Scale.x = m_Scale.y = 1.0; // scale (A and B) this layer
m_MirrorA = false; // true: miror / axe A (default = X) m_MirrorA = false; // true: miror / axe A (default = X)
m_MirrorB = false; // true: miror / axe B (default = Y) m_MirrorB = false; // true: miror / axe B (default = Y)
m_SwapAxis = false; // false if A = X, B = Y; true if A =Y, B = Y m_SwapAxis = false; // false if A = X, B = Y; true if A =Y, B = Y
m_ImageOffset.x = m_ImageOffset.y = 0; // Coord Offset, from IO command
m_Offset.x = m_Offset.y = 0; // Coord Offset, from OF command
m_Rotation = 0; // Allowed 0, 90, 180, 270
m_StepForRepeat.x = m_StepForRepeat.y = 0; // X and Y offsets for Step and Repeat command
m_XRepeatCount = 1; // The repeat count on X axis
m_YRepeatCount = 1; // The repeat count on Y axis
m_StepForRepeatMetric = false; // false = Inches, true = metric
m_Has_DCode = false; // true = DCodes in file m_Has_DCode = false; // true = DCodes in file
// false = no DCode-> // false = no DCode->
// search for separate DCode file // search for separate DCode file
m_FmtScale.x = m_FmtScale.y = 4; // Initialize default format to 3.4 => 4 m_FmtScale.x = m_FmtScale.y = 4; // Initialize default format to 3.4 => 4
m_FmtLen.x = m_FmtLen.y = 3 + 4; // Initialize default format len = 3+4 m_FmtLen.x = m_FmtLen.y = 3 + 4; // Initialize default format len = 3+4
m_LayerScale.x = m_LayerScale.y = 1.0; // scale (A and B) this layer
m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // Linear, 90 arc, Circ. m_Iterpolation = GERB_INTERPOL_LINEAR_1X; // Linear, 90 arc, Circ.
m_360Arc_enbl = false; // 360 deg circular m_360Arc_enbl = false; // 360 deg circular
// interpolation disable // interpolation disable
m_Current_Tool = 0; // Current Tool (Dcode) m_Current_Tool = 0; // Current Dcode selected
// number selected m_CommandState = 0; // State of the current command
m_CommandState = 0; // gives tate of the
// stacking order analysis
m_CurrentPos.x = m_CurrentPos.y = 0; // current specified coord m_CurrentPos.x = m_CurrentPos.y = 0; // current specified coord
// for plot m_PreviousPos.x = m_PreviousPos.y = 0; // last specified coord
m_PreviousPos.x = m_PreviousPos.y = 0; // old current specified
// coord for plot
m_IJPos.x = m_IJPos.y = 0; // current centre coord for m_IJPos.x = m_IJPos.y = 0; // current centre coord for
// plot arcs & circles // plot arcs & circles
m_Current_File = NULL; // File to read m_Current_File = NULL; // Gerger file to read
m_FilesPtr = 0; m_FilesPtr = 0;
m_PolygonFillMode = false; m_PolygonFillMode = false;
m_PolygonFillModeState = 0; m_PolygonFillModeState = 0;
@ -172,7 +187,7 @@ void GERBER::ResetDefaultValues()
} }
int GERBER::ReturnUsedDcodeNumber() int GERBER_IMAGE::ReturnUsedDcodeNumber()
{ {
int count = 0; int count = 0;
@ -187,7 +202,7 @@ int GERBER::ReturnUsedDcodeNumber()
} }
void GERBER::InitToolTable() void GERBER_IMAGE::InitToolTable()
{ {
for( int count = 0; count < TOOLS_MAX_COUNT; count++ ) for( int count = 0; count < TOOLS_MAX_COUNT; count++ )
{ {
@ -207,7 +222,7 @@ void GERBER::InitToolTable()
* for instance when reading a Gerber file * for instance when reading a Gerber file
* @param aMessage = the straing to add in list * @param aMessage = the straing to add in list
*/ */
void GERBER::ReportMessage( const wxString aMessage ) void GERBER_IMAGE::ReportMessage( const wxString aMessage )
{ {
m_Parent->ReportMessage( aMessage ); m_Parent->ReportMessage( aMessage );
} }
@ -217,11 +232,12 @@ void GERBER::ReportMessage( const wxString aMessage )
* Clear the message list * Clear the message list
* Call it before reading a Gerber file * Call it before reading a Gerber file
*/ */
void GERBER::ClearMessageList() void GERBER_IMAGE::ClearMessageList()
{ {
m_Parent->ClearMessageList(); m_Parent->ClearMessageList();
} }
/** Function StepAndRepeatItem /** Function StepAndRepeatItem
* Gerber format has a command Step an Repeat * Gerber format has a command Step an Repeat
* This function must be called when reading a gerber file and * This function must be called when reading a gerber file and
@ -229,25 +245,28 @@ void GERBER::ClearMessageList()
* (i.e when m_XRepeatCount or m_YRepeatCount are > 1) * (i.e when m_XRepeatCount or m_YRepeatCount are > 1)
* @param aItem = the item to repeat * @param aItem = the item to repeat
*/ */
void GERBER::StepAndRepeatItem( const GERBER_DRAW_ITEM& aItem ) void GERBER_IMAGE::StepAndRepeatItem( const GERBER_DRAW_ITEM& aItem )
{ {
if( m_XRepeatCount < 2 && m_YRepeatCount < 2 ) if( GetLayerParams().m_XRepeatCount < 2 &&
GetLayerParams().m_YRepeatCount < 2 )
return; // Nothing to repeat return; // Nothing to repeat
// Duplicate item: // Duplicate item:
wxString msg; wxString msg;
for( int ii = 0; ii < m_XRepeatCount; ii++ ) for( int ii = 0; ii < GetLayerParams().m_XRepeatCount; ii++ )
{ {
for( int jj = 0; jj < m_YRepeatCount; jj++ ) for( int jj = 0; jj < GetLayerParams().m_YRepeatCount; jj++ )
{ {
// the first gerber item already exists (this is the template) // the first gerber item already exists (this is the template)
// create duplicate only if ii or jj > 0 // create duplicate only if ii or jj > 0
if( jj == 0 && ii == 0 ) if( jj == 0 && ii == 0 )
continue; continue;
GERBER_DRAW_ITEM* dupItem = new GERBER_DRAW_ITEM( aItem ); GERBER_DRAW_ITEM* dupItem = new GERBER_DRAW_ITEM( aItem );
wxPoint move_vector; wxPoint move_vector;
move_vector.x = scale( ii * m_StepForRepeat.x, m_StepForRepeatMetric ); move_vector.x = scale( ii * GetLayerParams().m_StepForRepeat.x,
move_vector.y = scale( jj * m_StepForRepeat.y, m_StepForRepeatMetric ); GetLayerParams().m_StepForRepeatMetric );
dupItem->MoveXY(move_vector); move_vector.y = scale( jj * GetLayerParams().m_StepForRepeat.y,
GetLayerParams().m_StepForRepeatMetric );
dupItem->MoveXY( move_vector );
m_Parent->GetBoard()->m_Drawings.Append( dupItem ); m_Parent->GetBoard()->m_Drawings.Append( dupItem );
} }
} }

View File

@ -20,76 +20,126 @@ class WinEDA_GerberFrame;
class BOARD; class BOARD;
class D_CODE; class D_CODE;
/* 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_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_IMAGE per file and one graphic layer per file or GERBER_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_IMAGE must include one GERBER_LAYER to define all parameters to plot a file.
* But a GERBER_IMAGE can use more than one GERBER_LAYER.
*/
class GERBER_IMAGE;
class GERBER_LAYER
{
friend class GERBER_IMAGE;
public:
// These parameters are layer specfic:
wxString m_LayerName; // Layer name, from LN <name>* command
bool m_LayerNegative; // true = Negative Layer: command LP
wxRealPoint m_StepForRepeat; // X and Y offsets for Step and Repeat command
int m_XRepeatCount; // The repeat count on X axis
int m_YRepeatCount; // The repeat count on Y axis
bool m_StepForRepeatMetric; // false = Inches, true = metric
// needed here because repeated
// gerber items can have coordinates
// in different units than step parameters
// and the actual coordinates calculation must handle this
public:
GERBER_LAYER();
~GERBER_LAYER();
private:
void ResetDefaultValues();
};
/** /**
* Class GERBER * Class GERBER_IMAGE
* holds the data for one gerber file or layer * holds the Image data and parameters for one gerber file
* and layer parameters (TODO: move them in GERBER_LAYER class
*/ */
class GERBER class GERBER_IMAGE
{ {
WinEDA_GerberFrame* m_Parent; // the parent WinEDA_GerberFrame (used to display messages...) WinEDA_GerberFrame* m_Parent; // the parent WinEDA_GerberFrame (used to display messages...)
D_CODE* m_Aperture_List[TOOLS_MAX_COUNT]; ///< Dcode (Aperture) List for this layer D_CODE* m_Aperture_List[TOOLS_MAX_COUNT]; ///< Dcode (Aperture) List for this layer (max 999)
bool m_Exposure; ///< whether an aperture macro tool is flashed on or off bool m_Exposure; ///< whether an aperture macro tool is flashed on or off
BOARD* m_Pcb; BOARD* m_Pcb;
public: GERBER_LAYER m_GBRLayerParams; // hold params for the current gerber layer
wxString m_FileName; // Full File Name for this layer
wxString m_ImageName; // Image name, from IN <name>* command
wxString m_LayerName; // Layer name, from LN <name>* command
int m_GraphicLayer; // Graphic layer Number
bool m_LayerNegative; // true = Negative Layer
bool m_GerbMetric; // false = Inches, true = metric
bool m_Relative; // false = absolute Coord, true = relative Coord
bool m_NoTrailingZeros; // true: remove tailing zeros.
bool m_SwapAxis; // false (default) if A = X and B = Y
// true if A = Y, B = X
bool m_MirrorA; // true: miror / axe A (X)
bool m_MirrorB; // true: miror / axe B (Y)
wxPoint m_ImageOffset; // Coord Offset, from IO command
wxPoint m_Offset; // Coord Offset, from OF command
wxSize m_FmtScale; // Fmt 2.3: m_FmtScale = 3, fmt 3.4: m_FmtScale = 4
wxSize m_FmtLen; // Nb chars per coord. ex fmt 2.3, m_FmtLen = 5
wxRealPoint m_LayerScale; // scale (X and Y) of layer.
int m_Rotation; // Image rotation (0, 90, 180, 270
// Note these values are stored in 0.1 degrees
wxRealPoint m_StepForRepeat; // X and Y offsets for Step and Repeat command
int m_XRepeatCount; // The repeat count on X axis
int m_YRepeatCount; // The repeat count on Y axis
bool m_StepForRepeatMetric; // false = Inches, true = metric
// needed here because repeated
// gerber items can have coordinates
// in different units than step parameters
// and the actual coordinates calculation must handle this
int m_Iterpolation; // Linear, 90 arc, Circ.
bool m_ImageNegative; // true = Negative image
int m_Current_Tool; // Current Tool (Dcode) number selected
int m_Last_Pen_Command; // Current or last pen state (0..9, set by Dn option with n <10
int m_CommandState; // state of gerber analysis command.
wxPoint m_CurrentPos; // current specified coord for plot
wxPoint m_PreviousPos; // old current specified coord for plot
wxPoint m_IJPos; // IJ coord (for arcs & circles )
FILE* m_Current_File; // Current file to read public:
wxString m_FileName; // Full File Name for this layer
wxString m_ImageName; // Image name, from IN <name>* command
int m_GraphicLayer; // Graphic layer Number
bool m_ImageNegative; // true = Negative image
bool m_GerbMetric; // false = Inches, true = metric
bool m_Relative; // false = absolute Coord, true = relative Coord
bool m_NoTrailingZeros; // true: remove tailing zeros.
wxPoint m_ImageOffset; // Coord Offset, from IO command
wxSize m_FmtScale; // Fmt 2.3: m_FmtScale = 3, fmt 3.4: m_FmtScale = 4
wxSize m_FmtLen; // Nb chars per coord. ex fmt 2.3, m_FmtLen = 5
int m_ImageRotation; // Image rotation (0, 90, 180, 270
// Note these values are stored in 0.1 degrees
int m_LocalRotation; // Local rotation, added to m_ImageRotation
// Note this value is stored in 0.1 degrees
wxPoint m_Offset; // Coord Offset, from OF command
wxRealPoint m_Scale; // scale (X and Y) of layer.
bool m_SwapAxis; // false (default) if A = X and B = Y
// true if A = Y, B = X
bool m_MirrorA; // true: miror / axe A (X)
bool m_MirrorB; // true: miror / axe B (Y)
int m_Iterpolation; // Linear, 90 arc, Circ.
int m_Current_Tool; // Current Tool (Dcode) number selected
int m_Last_Pen_Command; // Current or last pen state (0..9, set by Dn option with n <10
int m_CommandState; // state of gerber analysis command.
wxPoint m_CurrentPos; // current specified coord for plot
wxPoint m_PreviousPos; // old current specified coord for plot
wxPoint m_IJPos; // IJ coord (for arcs & circles )
FILE* m_Current_File; // Current file to read
#define INCLUDE_FILES_CNT_MAX 10 #define INCLUDE_FILES_CNT_MAX 10
FILE* m_FilesList[INCLUDE_FILES_CNT_MAX + 2]; // Included files list FILE* m_FilesList[INCLUDE_FILES_CNT_MAX + 2]; // Included files list
int m_FilesPtr; // Stack pointer for files list int m_FilesPtr; // Stack pointer for files list
int m_Selected_Tool; // For hightlight: current selected Dcode int m_Selected_Tool; // For hightlight: current selected Dcode
bool m_Has_DCode; // true = DCodes in file bool m_Has_DCode; // true = DCodes in file
// (false = no DCode -> separate DCode file // (false = no DCode -> separate DCode file
bool m_360Arc_enbl; // Enbl 360 deg circular interpolation bool m_360Arc_enbl; // Enbl 360 deg circular interpolation
bool m_PolygonFillMode; // Enable polygon mode (read coord as a polygon descr) bool m_PolygonFillMode; // Enable polygon mode (read coord as a polygon descr)
int m_PolygonFillModeState; // In polygon mode: 0 = first segm, 1 = next segm int m_PolygonFillModeState; // In polygon mode: 0 = first segm, 1 = next segm
APERTURE_MACRO_SET m_aperture_macros; ///< a collection of APERTURE_MACROS, sorted by name APERTURE_MACRO_SET m_aperture_macros; ///< a collection of APERTURE_MACROS, sorted by name
public: public:
GERBER( WinEDA_GerberFrame* aParent, int layer ); GERBER_IMAGE( WinEDA_GerberFrame* aParent, int layer );
~GERBER(); ~GERBER_IMAGE();
void Clear_GERBER(); void Clear_GERBER_IMAGE();
int ReturnUsedDcodeNumber(); int ReturnUsedDcodeNumber();
void ResetDefaultValues(); void ResetDefaultValues();
/** function GetLayerParams
* @return the current layers params
*/
GERBER_LAYER& GetLayerParams()
{
return m_GBRLayerParams;
}
/** function ReportMessage /** function ReportMessage
* Add a message (a string) in message list * Add a message (a string) in message list
@ -174,7 +224,7 @@ public:
* looks up a previously read in aperture macro. * looks up a previously read in aperture macro.
* @param aLookup A dummy APERTURE_MACRO with [only] the name field set. * @param aLookup A dummy APERTURE_MACRO with [only] the name field set.
* @return APERTURE_MACRO* - the one with a matching name, or NULL if * @return APERTURE_MACRO* - the one with a matching name, or NULL if
* not found. * not found.
*/ */
APERTURE_MACRO* FindApertureMacro( const APERTURE_MACRO& aLookup ); APERTURE_MACRO* FindApertureMacro( const APERTURE_MACRO& aLookup );
@ -185,7 +235,7 @@ public:
* (i.e when m_XRepeatCount or m_YRepeatCount are > 1) * (i.e when m_XRepeatCount or m_YRepeatCount are > 1)
* @param aItem = the item to repeat * @param aItem = the item to repeat
*/ */
void StepAndRepeatItem( const GERBER_DRAW_ITEM& aItem ); void StepAndRepeatItem( const GERBER_DRAW_ITEM& aItem );
}; };

View File

@ -33,6 +33,7 @@
#include "macros.h" #include "macros.h"
#include "trigo.h" #include "trigo.h"
#include "gerbview.h" #include "gerbview.h"
#include "class_GERBER.h"
@ -95,7 +96,7 @@ bool AM_PRIMITIVE::mapExposure( GERBER_DRAW_ITEM* aParent )
break; break;
case 2: // reverse exposure case 2: // reverse exposure
exposure = !aParent->m_LayerNegative; exposure = !aParent->GetLayerPolarity();
} }
break; break;
@ -107,7 +108,7 @@ bool AM_PRIMITIVE::mapExposure( GERBER_DRAW_ITEM* aParent )
break; break;
} }
return exposure ^ aParent->m_ImageNegative; return exposure ^ aParent->m_imageParams->m_ImageNegative;
} }
@ -574,12 +575,12 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent,
aBuffer.push_back( pos ); aBuffer.push_back( pos );
// Copy the 4 shape, rotated by 90, 180 and 270 deg // Copy the 4 shape, rotated by 90, 180 and 270 deg
for( int jj = 900; jj <= 2700; jj += 900 ) for( int jj = 1; jj <= 3; jj ++ )
{ {
for( int ii = 0; ii < 4; ii++ ) for( int ii = 0; ii < 4; ii++ )
{ {
pos = aBuffer[ii]; pos = aBuffer[ii];
RotatePoint( &pos, jj ); RotatePoint( &pos, jj*900 );
aBuffer.push_back( pos ); aBuffer.push_back( pos );
} }
} }

View File

@ -42,7 +42,7 @@
/**********************************************************/ /**********************************************************/
GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( BOARD_ITEM* aParent, GERBER* aGerberparams ) : GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( BOARD_ITEM* aParent, GERBER_IMAGE* aGerberparams ) :
BOARD_ITEM( aParent, TYPE_GERBER_DRAW_ITEM ) BOARD_ITEM( aParent, TYPE_GERBER_DRAW_ITEM )
/**********************************************************/ /**********************************************************/
{ {
@ -52,12 +52,12 @@ GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( BOARD_ITEM* aParent, GERBER* aGerberparams )
m_Flashed = false; m_Flashed = false;
m_DCode = 0; m_DCode = 0;
m_UnitsMetric = false; m_UnitsMetric = false;
m_ImageNegative = false;
m_LayerNegative = false; m_LayerNegative = false;
m_swapAxis = false; m_swapAxis = false;
m_mirrorA = false; m_mirrorA = false;
m_mirrorB = false; m_mirrorB = false;
m_drawScale.x = m_drawScale.y = 1.0; m_drawScale.x = m_drawScale.y = 1.0;
m_layerRotation = 0;
if( m_imageParams ) if( m_imageParams )
SetLayerParameters(); SetLayerParameters();
} }
@ -83,7 +83,6 @@ GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( const GERBER_DRAW_ITEM& aSource ) :
m_DCode = aSource.m_DCode; m_DCode = aSource.m_DCode;
m_PolyCorners = aSource.m_PolyCorners; m_PolyCorners = aSource.m_PolyCorners;
m_UnitsMetric = aSource.m_UnitsMetric; m_UnitsMetric = aSource.m_UnitsMetric;
m_ImageNegative = aSource.m_ImageNegative;
m_LayerNegative = aSource.m_LayerNegative; m_LayerNegative = aSource.m_LayerNegative;
m_swapAxis = aSource.m_swapAxis; m_swapAxis = aSource.m_swapAxis;
m_mirrorA = aSource.m_mirrorA; m_mirrorA = aSource.m_mirrorA;
@ -91,6 +90,7 @@ GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( const GERBER_DRAW_ITEM& aSource ) :
m_layerOffset = aSource.m_layerOffset; m_layerOffset = aSource.m_layerOffset;
m_drawScale.x = aSource.m_drawScale.x; m_drawScale.x = aSource.m_drawScale.x;
m_drawScale.y = aSource.m_drawScale.y; m_drawScale.y = aSource.m_drawScale.y;
m_layerRotation = aSource.m_layerRotation;
} }
@ -127,16 +127,19 @@ wxPoint GERBER_DRAW_ITEM::GetABPosition( const wxPoint& aXYPosition )
abPos += m_layerOffset + m_imageParams->m_ImageOffset; abPos += m_layerOffset + m_imageParams->m_ImageOffset;
abPos.x = wxRound( abPos.x * m_drawScale.x ); abPos.x = wxRound( abPos.x * m_drawScale.x );
abPos.y = wxRound( abPos.y * m_drawScale.y ); abPos.y = wxRound( abPos.y * m_drawScale.y );
if( m_imageParams->m_Rotation ) int rotation = m_layerRotation + m_imageParams->m_ImageRotation;
RotatePoint( &abPos, -m_imageParams->m_Rotation ); if( rotation )
RotatePoint( &abPos, -rotation );
if( m_mirrorA ) if( m_mirrorA )
NEGATE( abPos.x ); NEGATE( abPos.x );
// abPos.y must be negated, because draw axis is top to bottom // abPos.y must be negated, because draw axis is top to bottom
if( !m_mirrorB ) if( !m_mirrorB )
NEGATE( abPos.y ); NEGATE( abPos.y );
return abPos; return abPos;
} }
/** /**
* Function GetXYPosition * Function GetXYPosition
* returns the image position of aPosition for this object. * returns the image position of aPosition for this object.
@ -145,17 +148,18 @@ wxPoint GERBER_DRAW_ITEM::GetABPosition( const wxPoint& aXYPosition )
* @param aABPosition = position in A,B plotter axis * @param aABPosition = position in A,B plotter axis
* @return const wxPoint - The given position in X,Y axis. * @return const wxPoint - The given position in X,Y axis.
*/ */
wxPoint GERBER_DRAW_ITEM::GetXYPosition(const wxPoint& aABPosition ) wxPoint GERBER_DRAW_ITEM::GetXYPosition( const wxPoint& aABPosition )
{ {
// do the inverse tranform made by GetABPosition // do the inverse tranform made by GetABPosition
wxPoint xyPos = aABPosition; wxPoint xyPos = aABPosition;
if( m_mirrorA ) if( m_mirrorA )
NEGATE( xyPos.x ); NEGATE( xyPos.x );
if( !m_mirrorB ) if( !m_mirrorB )
NEGATE( xyPos.y ); NEGATE( xyPos.y );
if( m_imageParams->m_Rotation ) int rotation = m_layerRotation + m_imageParams->m_ImageRotation;
RotatePoint( &xyPos, m_imageParams->m_Rotation ); if( rotation )
RotatePoint( &xyPos, rotation );
xyPos.x = wxRound( xyPos.x / m_drawScale.x ); xyPos.x = wxRound( xyPos.x / m_drawScale.x );
xyPos.y = wxRound( xyPos.y / m_drawScale.y ); xyPos.y = wxRound( xyPos.y / m_drawScale.y );
xyPos -= m_layerOffset + m_imageParams->m_ImageOffset; xyPos -= m_layerOffset + m_imageParams->m_ImageOffset;
@ -164,6 +168,7 @@ wxPoint GERBER_DRAW_ITEM::GetXYPosition(const wxPoint& aABPosition )
return xyPos; return xyPos;
} }
/** function SetLayerParameters /** function SetLayerParameters
* Initialize draw parameters from Image and Layer parameters * Initialize draw parameters from Image and Layer parameters
* found in the gerber file: * found in the gerber file:
@ -174,12 +179,14 @@ wxPoint GERBER_DRAW_ITEM::GetXYPosition(const wxPoint& aABPosition )
void GERBER_DRAW_ITEM::SetLayerParameters() void GERBER_DRAW_ITEM::SetLayerParameters()
{ {
m_UnitsMetric = m_imageParams->m_GerbMetric; m_UnitsMetric = m_imageParams->m_GerbMetric;
m_swapAxis = m_imageParams->m_SwapAxis; // false if A = X, B = Y; m_swapAxis = m_imageParams->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_imageParams->m_MirrorA; // true: mirror / axe A
m_mirrorB = m_imageParams->m_MirrorB; // true: mirror / axe B m_mirrorB = m_imageParams->m_MirrorB; // true: mirror / axe B
m_drawScale = m_imageParams->m_LayerScale; // A and B scaling factor m_drawScale = m_imageParams->m_Scale; // A and B scaling factor
m_layerOffset = m_imageParams->m_Offset; // Offset from OF command m_layerOffset = m_imageParams->m_Offset; // Offset from OF command
// Rotation from RO command:
m_layerRotation = m_imageParams->m_LocalRotation;
} }
@ -229,7 +236,7 @@ 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* gerber = g_GERBER_List[m_Layer]; GERBER_IMAGE* gerber = g_GERBER_List[m_Layer];
if( gerber == NULL ) if( gerber == NULL )
return NULL; return NULL;
@ -246,8 +253,8 @@ EDA_Rect GERBER_DRAW_ITEM::GetBoundingBox()
bbox.Inflate( m_Size.x / 2, m_Size.y / 2 ); bbox.Inflate( m_Size.x / 2, m_Size.y / 2 );
bbox.SetOrigin(GetXYPosition( bbox.GetOrigin() ) ); bbox.SetOrigin( GetABPosition( bbox.GetOrigin() ) );
bbox.SetEnd(GetXYPosition( bbox.GetEnd() ) ); bbox.SetEnd( GetABPosition( bbox.GetEnd() ) );
return bbox; return bbox;
} }
@ -260,6 +267,7 @@ EDA_Rect GERBER_DRAW_ITEM::GetBoundingBox()
void GERBER_DRAW_ITEM::MoveAB( const wxPoint& aMoveVector ) void GERBER_DRAW_ITEM::MoveAB( const wxPoint& aMoveVector )
{ {
wxPoint xymove = GetXYPosition( aMoveVector ); wxPoint xymove = GetXYPosition( aMoveVector );
m_Start += xymove; m_Start += xymove;
m_End += xymove; m_End += xymove;
m_ArcCentre += xymove; m_ArcCentre += xymove;
@ -267,6 +275,7 @@ void GERBER_DRAW_ITEM::MoveAB( const wxPoint& aMoveVector )
m_PolyCorners[ii] += xymove; m_PolyCorners[ii] += xymove;
} }
/** /**
* Function MoveXY * Function MoveXY
* move this object. * move this object.
@ -281,6 +290,7 @@ void GERBER_DRAW_ITEM::MoveXY( const wxPoint& aMoveVector )
m_PolyCorners[ii] += aMoveVector; m_PolyCorners[ii] += aMoveVector;
} }
/** function Save. /** function Save.
* currently: no nothing, but must be defined to meet requirements * currently: no nothing, but must be defined to meet requirements
* of the basic class * of the basic class
@ -325,8 +335,14 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode,
alt_color = g_DrawBgColor; alt_color = g_DrawBgColor;
if( m_Flags & DRAW_ERASED ) // draw in background color ("negative" color) /* isDark is true if flash is positive and should use a drawing
* color other than the background color, else use the background color
* when drawing so that an erasure happens.
*/
bool isDark = !(m_LayerNegative ^ m_imageParams->m_ImageNegative);
if( !isDark )
{ {
// draw in background color ("negative" color)
EXCHG( color, alt_color ); EXCHG( color, alt_color );
} }
@ -338,7 +354,7 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode,
{ {
case GBR_POLYGON: case GBR_POLYGON:
isFilled = (g_DisplayPolygonsModeSketch == false); isFilled = (g_DisplayPolygonsModeSketch == false);
if( m_Flags & DRAW_ERASED ) if( !isDark )
isFilled = true; isFilled = true;
DrawGbrPoly( &aPanel->m_ClipBox, aDC, color, aOffset, isFilled ); DrawGbrPoly( &aPanel->m_ClipBox, aDC, color, aOffset, isFilled );
break; break;
@ -367,9 +383,9 @@ void GERBER_DRAW_ITEM::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode,
case GBR_ARC: case GBR_ARC:
#if 0 // for arc debug only #if 0 // for arc debug only
GRLine( &aPanel->m_ClipBox, aDC, GetABPosition( m_Start ), GRLine( &aPanel->m_ClipBox, aDC, GetABPosition( m_Start ),
GetABPosition( m_ArcCentre ), 0, color ); GetABPosition( m_ArcCentre ), 0, color );
GRLine( &aPanel->m_ClipBox, aDC, GetABPosition( m_End ), GRLine( &aPanel->m_ClipBox, aDC, GetABPosition( m_End ),
GetABPosition( m_ArcCentre ), 0, color ); GetABPosition( m_ArcCentre ), 0, color );
#endif #endif
if( !isFilled ) if( !isFilled )
{ {
@ -453,37 +469,35 @@ void GERBER_DRAW_ITEM::DisplayInfo( WinEDA_DrawFrame* frame )
frame->AppendMsgPanel( _( "Type" ), msg, DARKCYAN ); frame->AppendMsgPanel( _( "Type" ), msg, DARKCYAN );
// Display D_Code value: // Display D_Code value:
msg.Printf( wxT("%d"), m_DCode); msg.Printf( wxT( "%d" ), m_DCode );
frame->AppendMsgPanel( _( "D Code" ), msg, RED ); frame->AppendMsgPanel( _( "D Code" ), msg, RED );
// Display Image name // Display Image name
if(m_imageParams) if( m_imageParams )
{ {
msg = m_imageParams->m_ImageName; msg = m_imageParams->m_ImageName;
frame->AppendMsgPanel( _( "Image name" ), msg, BROWN ); frame->AppendMsgPanel( _( "Image name" ), msg, BROWN );
} }
// Display graphic layer number // Display graphic layer number
msg.Printf( wxT("%d"), GetLayer()+1); msg.Printf( wxT( "%d" ), GetLayer() + 1 );
frame->AppendMsgPanel( _( "Graphic layer" ), msg, BROWN ); frame->AppendMsgPanel( _( "Graphic layer" ), msg, BROWN );
// This next info can be see as debug info, so it can be disabled // This next info can be see as debug info, so it can be disabled
#if 1 #if 1
// Display offset
wxPoint tmp = m_layerOffset + m_imageParams->m_ImageOffset;
msg.Printf( wxT("X=%f Y=%f"), (double)tmp.x/10000, (double)tmp.y/10000);
frame->AppendMsgPanel( _( "Offset" ), msg, DARKRED );
// Display rotation // Display rotation
msg.Printf( wxT("%d"), m_imageParams->m_Rotation/10); msg.Printf( wxT( "%.1f" ), (double)(m_imageParams->m_ImageRotation+m_layerRotation) / 10 );
frame->AppendMsgPanel( _( "Image rotation" ), msg, DARKRED ); frame->AppendMsgPanel( _( "Rotation" ), msg, DARKRED );
// Display mirroring // Display mirroring
msg.Printf( wxT("X%d Y%d"), m_mirrorA, m_mirrorB); msg.Printf( wxT( "A:%s B:%s" ),
m_mirrorA ? _("Yes") : _("No"),
m_mirrorB ? _("Yes") : _("No"));
frame->AppendMsgPanel( _( "Mirror" ), msg, DARKRED ); frame->AppendMsgPanel( _( "Mirror" ), msg, DARKRED );
// Display AB axis swap // Display AB axis swap
msg = m_swapAxis ? wxT("A=Y B=X") : wxT("A=X B=Y"); msg = m_swapAxis ? wxT( "A=Y B=X" ) : wxT( "A=X B=Y" );
frame->AppendMsgPanel( _( "AB axis" ), msg, DARKRED ); frame->AppendMsgPanel( _( "AB axis" ), msg, DARKRED );
#endif #endif
} }
@ -497,6 +511,7 @@ void GERBER_DRAW_ITEM::DisplayInfo( WinEDA_DrawFrame* frame )
*/ */
bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos ) bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos )
{ {
// calculate aRefPos in XY gerber axis:
wxPoint ref_pos = GetXYPosition( aRefPos ); wxPoint ref_pos = GetXYPosition( aRefPos );
// TODO: a better analyse of the shape (perhaps create a D_CODE::HitTest for flashed items) // TODO: a better analyse of the shape (perhaps create a D_CODE::HitTest for flashed items)
@ -533,6 +548,7 @@ bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos )
bool GERBER_DRAW_ITEM::HitTest( EDA_Rect& refArea ) bool GERBER_DRAW_ITEM::HitTest( EDA_Rect& refArea )
{ {
wxPoint pos = GetABPosition( m_Start ); wxPoint pos = GetABPosition( m_Start );
if( refArea.Inside( pos ) ) if( refArea.Inside( pos ) )
return true; return true;
pos = GetABPosition( m_End ); pos = GetABPosition( m_End );

View File

@ -31,7 +31,7 @@
#include "base_struct.h" #include "base_struct.h"
#include "class_board_item.h" #include "class_board_item.h"
class GERBER; class GERBER_IMAGE;
/* Shapes id for basic shapes ( .m_Shape member ) */ /* Shapes id for basic shapes ( .m_Shape member ) */
enum Gbr_Basic_Shapes { enum Gbr_Basic_Shapes {
@ -75,27 +75,27 @@ 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
// These values are used to draw this item, according to gerber layers parameters GERBER_IMAGE* m_imageParams; /* main GERBER info for this item
// Because these values can change inside a gerber image, they are stored here
// for each item
bool m_ImageNegative; // true = item in negative image
bool m_LayerNegative; // TRUE = item in negative Layer
private:
GERBER* m_imageParams; /* main GERBER info for 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 layer * to the whole gerber file (i.e) the whole graphic layer
* and some can change when reaging the file, so they * and some can change when reaging the file, so they
* are stored inside this item * are stored inside this item
* there is no redundancy for these parameters * there is no redundancy for these parameters
*/ */
private:
// These values are used to draw this item, according to gerber layers parameters
// Because they can change inside a gerber image, thery are stored here
// for each item
bool m_LayerNegative; // TRUE = item in negative Layer
bool m_swapAxis; // false if A = X, B = Y; true if A =Y, B = Y bool m_swapAxis; // false if A = X, B = Y; true if A =Y, B = Y
bool m_mirrorA; // true: mirror / axe A bool m_mirrorA; // true: mirror / axe A
bool m_mirrorB; // true: mirror / axe B bool m_mirrorB; // true: mirror / axe B
wxRealPoint m_drawScale; // A and B scaling factor wxRealPoint m_drawScale; // A and B scaling factor
wxPoint m_layerOffset; // Offset for A and B axis, from OF parameter wxPoint m_layerOffset; // Offset for A and B axis, from OF parameter
int m_layerRotation; // Fine rotation, from OR parameter
public: public:
GERBER_DRAW_ITEM( BOARD_ITEM* aParent, GERBER* aGerberparams ); GERBER_DRAW_ITEM( BOARD_ITEM* aParent, GERBER_IMAGE* aGerberparams );
GERBER_DRAW_ITEM( const GERBER_DRAW_ITEM& aSource ); GERBER_DRAW_ITEM( const GERBER_DRAW_ITEM& aSource );
~GERBER_DRAW_ITEM(); ~GERBER_DRAW_ITEM();
@ -115,6 +115,10 @@ public:
return 1 << m_Layer; return 1 << m_Layer;
} }
bool GetLayerPolarity()
{
return m_LayerNegative;
}
/** function SetLayerParameters /** function SetLayerParameters
* Initialize parameters from Image and Layer parameters * Initialize parameters from Image and Layer parameters
@ -125,6 +129,11 @@ public:
*/ */
void SetLayerParameters( ); void SetLayerParameters( );
void SetLayerPolarity( bool aNegative)
{
m_LayerNegative = aNegative;
}
/** /**
* Function MoveAB * Function MoveAB
* move this object. * move this object.

View File

@ -124,9 +124,9 @@ int WinEDA_GerberFrame::Read_D_Code_File( const wxString& D_Code_FullFileName )
int type_outil; int type_outil;
if( g_GERBER_List[layer] == NULL ) if( g_GERBER_List[layer] == NULL )
g_GERBER_List[layer] = new GERBER( this, layer ); g_GERBER_List[layer] = new GERBER_IMAGE( this, layer );
GERBER* gerber = g_GERBER_List[layer]; GERBER_IMAGE* gerber = g_GERBER_List[layer];
/* Updating gerber scale: */ /* Updating gerber scale: */

View File

@ -26,7 +26,7 @@ void WinEDA_GerberFrame::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
if( m_ID_current_state == 0 ) if( m_ID_current_state == 0 )
{ {
if( DrawStruct && (DrawStruct->m_Flags & ~DRAW_ERASED) ) if( DrawStruct && DrawStruct->m_Flags )
{ {
msg.Printf( wxT( "WinEDA_GerberFrame::ProcessCommand err: Struct %d, m_Flags = %X" ), msg.Printf( wxT( "WinEDA_GerberFrame::ProcessCommand err: Struct %d, m_Flags = %X" ),
(unsigned) DrawStruct->Type(), (unsigned) DrawStruct->Type(),
@ -73,7 +73,7 @@ void WinEDA_GerberFrame::Process_Special_Functions( wxCommandEvent& event )
{ {
int id = event.GetId(); int id = event.GetId();
int layer = GetScreen()->m_Active_Layer; int layer = GetScreen()->m_Active_Layer;
GERBER* gerber_layer = g_GERBER_List[layer]; GERBER_IMAGE* gerber_layer = g_GERBER_List[layer];
wxPoint pos; wxPoint pos;
wxGetMousePosition( &pos.x, &pos.y ); wxGetMousePosition( &pos.x, &pos.y );

View File

@ -0,0 +1,17 @@
G04 Test image polarity *
G04 Crosshairs should be cut out of a positive background*
G04 Handcoded by Julian Lamb *
%MOIN*%
%FSLAX23Y23*%
%IPNEG*%
%ADD10C,0.050*%
G04 Draw crosshairs *
X-1000Y0D02*
G54D10*
X1000Y0D01*
X0Y-1000D02*
G54D10*
X0Y1000D01*
M02*

View File

@ -0,0 +1,21 @@
G04 Test image rotation *
G04 Handcoded by Julian Lamb *
%MOIN*%
%FSLAX23Y23*%
%IR270*%
%ADD10C,0.050*%
G04 Quarter star *
X1000Y0D02*
G54D10*
X2000Y0D01*
X1000Y0D02*
G54D10*
X2000Y1000D01*
X1000Y0D02*
G54D10*
X1000Y1000D01*
M02*

View File

@ -0,0 +1,15 @@
G04 Test layer axis select *
G04 Line is drawn along A axis, then axis select switches it and renders *
G04 line along y axis *
G04 Handcoded by Julian Lamb *
%MOIN*%
%FSLAX23Y23*%
%ASAYBX*%
%ADD10C,0.050*%
G04 Draw line *
X-1000Y0D02*
G54D10*
X1000Y0D01*
M02*

View File

@ -0,0 +1,23 @@
G04 Test layer rotation 1 *
G04 Quarter star should be rotated 45 degrees counterclockwise, pointing*
G04 the center line straight up *
G04 Handcoded by Julian Lamb *
%MOIN*%
%FSLAX23Y23*%
%RO45*%
%ADD10C,0.025*%
G04 Quarter star *
X1000Y0D02*
G54D10*
X2000Y0D01*
X1000Y0D02*
G54D10*
X2000Y1000D01*
X1000Y0D02*
G54D10*
X1000Y1000D01*
M02*

View File

@ -0,0 +1,17 @@
G04 Test layer scale factor 1 *
G04 Crosshairs should be centered on 0,0 and 2 inches wide and 1 inch tall*
G04 Handcoded by Julian Lamb *
%MOIN*%
%FSLAX23Y23*%
%SFA2B1*%
%ADD10C,0.025*%
G04 Crosshairs to be on 0,0 *
X-500Y0D02*
G54D10*
X500Y0D01*
X0Y-500D02*
G54D10*
X0Y500D01*
M02*

View File

@ -430,7 +430,7 @@ void WinEDA_GerberFrame::Liste_D_Codes( )
for( int layer = 0; layer < 32; layer++ ) for( int layer = 0; layer < 32; layer++ )
{ {
GERBER* gerber = g_GERBER_List[layer]; GERBER_IMAGE* gerber = g_GERBER_List[layer];
if( gerber == NULL ) if( gerber == NULL )
continue; continue;
@ -488,7 +488,7 @@ void WinEDA_GerberFrame::Liste_D_Codes( )
*/ */
void WinEDA_GerberFrame::UpdateTitleAndInfo() void WinEDA_GerberFrame::UpdateTitleAndInfo()
{ {
GERBER* gerber = g_GERBER_List[GetScreen()->m_Active_Layer]; GERBER_IMAGE* gerber = g_GERBER_List[GetScreen()->m_Active_Layer];
wxString text; wxString text;
// Display the gerber filename // Display the gerber filename
if( gerber == NULL ) if( gerber == NULL )
@ -507,7 +507,7 @@ void WinEDA_GerberFrame::UpdateTitleAndInfo()
// Display Image Name and Layer Name (from the current gerber data): // Display Image Name and Layer Name (from the current gerber data):
text.Printf( _("Image name: \"%s\" Layer name \"%s\""), text.Printf( _("Image name: \"%s\" Layer name \"%s\""),
GetChars(gerber->m_ImageName), GetChars(gerber->m_LayerName) ); GetChars(gerber->m_ImageName), GetChars(gerber->GetLayerParams( ).m_LayerName) );
SetStatusText( text, 0 ); SetStatusText( text, 0 );
// Display data format like fmt in X3.4Y3.4 no LZ or fmt mm X2.3 Y3.5 no TZ in main toolbar // Display data format like fmt in X3.4Y3.4 no LZ or fmt mm X2.3 Y3.5 no TZ in main toolbar

View File

@ -42,7 +42,7 @@ const wxString GerbviewProjectFileWildcard( _( "GerbView project files (.cnf)|*.
const wxString GerbviewShowPageSizeOption( wxT( "ShowPageSizeOpt" ) ); const wxString GerbviewShowPageSizeOption( wxT( "ShowPageSizeOpt" ) );
extern const wxString GerbviewShowDCodes( wxT( "ShowDCodesOpt" ) ); extern const wxString GerbviewShowDCodes( wxT( "ShowDCodesOpt" ) );
GERBER* g_GERBER_List[32]; GERBER_IMAGE* g_GERBER_List[32];
// List of page sizes // List of page sizes
Ki_PageDescr* g_GerberPageSizeList[] = Ki_PageDescr* g_GerberPageSizeList[] =

View File

@ -18,7 +18,7 @@
class WinEDA_GerberFrame; class WinEDA_GerberFrame;
//class BOARD; //class BOARD;
class GERBER; class GERBER_IMAGE;
// Type of photoplotter action: // Type of photoplotter action:
#define GERB_ACTIVE_DRAW 1 // Activate light (lower pen) #define GERB_ACTIVE_DRAW 1 // Activate light (lower pen)
@ -113,7 +113,7 @@ enum Gerb_Analyse_Cmd
/* rs274x.cpp */ /* rs274x.cpp */
/**************/ /**************/
bool GetEndOfBlock( char buff[GERBER_BUFZ], char*& text, FILE* gerber_file ); bool GetEndOfBlock( char buff[GERBER_BUFZ], char*& text, FILE* gerber_file );
extern GERBER* g_GERBER_List[32]; extern GERBER_IMAGE* g_GERBER_List[32];
#include "pcbcommon.h" #include "pcbcommon.h"
#include "wxGerberFrame.h" #include "wxGerberFrame.h"

View File

@ -26,16 +26,15 @@ bool WinEDA_GerberFrame::Read_GERBER_File( const wxString& GERBER_FullFileName,
wxString msg; wxString msg;
char* text; char* text;
int layer; /* current layer used in gerbview */ int layer; /* current layer used in gerbview */
GERBER* gerber;
layer = GetScreen()->m_Active_Layer; layer = GetScreen()->m_Active_Layer;
if( g_GERBER_List[layer] == NULL ) if( g_GERBER_List[layer] == NULL )
{ {
g_GERBER_List[layer] = new GERBER( this, layer ); g_GERBER_List[layer] = new GERBER_IMAGE( this, layer );
} }
gerber = g_GERBER_List[layer]; GERBER_IMAGE* gerber = g_GERBER_List[layer];
ClearMessageList( ); ClearMessageList( );
/* Set the gerber scale: */ /* Set the gerber scale: */

View File

@ -13,7 +13,7 @@
/* These routines read the text string point from Text. /* These routines read the text string point from Text.
* After use, advanced Text the beginning of the sequence unread * After use, advanced Text the beginning of the sequence unread
*/ */
wxPoint GERBER::ReadXYCoord( char*& Text ) wxPoint GERBER_IMAGE::ReadXYCoord( char*& Text )
{ {
wxPoint pos; wxPoint pos;
int type_coord = 0, current_coord, nbdigits; int type_coord = 0, current_coord, nbdigits;
@ -115,7 +115,7 @@ wxPoint GERBER::ReadXYCoord( char*& Text )
* These coordinates are relative, so if coordinate is absent, it's value * These coordinates are relative, so if coordinate is absent, it's value
* defaults to 0 * defaults to 0
*/ */
wxPoint GERBER::ReadIJCoord( char*& Text ) wxPoint GERBER_IMAGE::ReadIJCoord( char*& Text )
{ {
wxPoint pos( 0, 0 ); wxPoint pos( 0, 0 );

View File

@ -94,16 +94,14 @@ static void fillFlashedGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
int aLayer, int aLayer,
const wxPoint& aPos, const wxPoint& aPos,
wxSize aSize, wxSize aSize,
bool aLayerNegative, bool aLayerNegative )
bool aImageNegative )
{ {
aGbrItem->SetLayer( aLayer ); aGbrItem->SetLayer( aLayer );
aGbrItem->m_Size = aSize; aGbrItem->m_Size = aSize;
aGbrItem->m_Start = aPos; aGbrItem->m_Start = aPos;
aGbrItem->m_End = aGbrItem->m_Start; aGbrItem->m_End = aGbrItem->m_Start;
aGbrItem->m_DCode = Dcode_index; aGbrItem->m_DCode = Dcode_index;
aGbrItem->m_LayerNegative = aLayerNegative; aGbrItem->SetLayerPolarity( aLayerNegative );
aGbrItem->m_ImageNegative = aImageNegative;
aGbrItem->m_Flashed = true; aGbrItem->m_Flashed = true;
switch( aAperture ) switch( aAperture )
{ {
@ -129,17 +127,6 @@ static void fillFlashedGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
aGbrItem->m_Shape = GBR_SPOT_MACRO; aGbrItem->m_Shape = GBR_SPOT_MACRO;
break; break;
} }
bool isDark = !(aGbrItem->m_LayerNegative ^ aGbrItem->m_ImageNegative);
/* isDark is true if flash is positive and should use a drawing
* color other than the background color, else use the background color
* when drawing so that an erasure happens.
*/
if( !isDark )
{
aGbrItem->m_Flags |= DRAW_ERASED;
}
} }
@ -161,8 +148,7 @@ static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
const wxPoint& aStart, const wxPoint& aStart,
const wxPoint& aEnd, const wxPoint& aEnd,
int aWidth, int aWidth,
bool aLayerNegative, bool aLayerNegative )
bool aImageNegative )
{ {
aGbrItem->SetLayer( aLayer ); aGbrItem->SetLayer( aLayer );
aGbrItem->m_Flashed = false; aGbrItem->m_Flashed = false;
@ -173,19 +159,7 @@ static void fillLineGBRITEM( GERBER_DRAW_ITEM* aGbrItem,
aGbrItem->m_End = aEnd; aGbrItem->m_End = aEnd;
aGbrItem->m_DCode = Dcode_index; aGbrItem->m_DCode = Dcode_index;
aGbrItem->m_LayerNegative = aLayerNegative; aGbrItem->SetLayerPolarity( aLayerNegative );
aGbrItem->m_ImageNegative = aImageNegative;
bool isDark = !(aGbrItem->m_LayerNegative ^ aGbrItem->m_ImageNegative);
/* isDark is true if flash is positive and should use a drawing
* color other than the background color, else use the background color
* when drawing so that an erasure happens.
*/
if( !isDark )
{
aGbrItem->m_Flags |= DRAW_ERASED;
}
} }
@ -222,8 +196,7 @@ static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aL
const wxPoint& aStart, const wxPoint& aEnd, const wxPoint& aStart, const wxPoint& aEnd,
const wxPoint& aRelCenter, int aWidth, const wxPoint& aRelCenter, int aWidth,
bool aClockwise, bool aMultiquadrant, bool aClockwise, bool aMultiquadrant,
bool aLayerNegative, bool aLayerNegative )
bool aImageNegative )
{ {
wxPoint center, delta; wxPoint center, delta;
@ -314,19 +287,7 @@ static void fillArcGBRITEM( GERBER_DRAW_ITEM* aGbrItem, int Dcode_index, int aL
aGbrItem->m_ArcCentre = center; aGbrItem->m_ArcCentre = center;
aGbrItem->m_DCode = Dcode_index; aGbrItem->m_DCode = Dcode_index;
aGbrItem->m_LayerNegative = aLayerNegative; aGbrItem->SetLayerPolarity( aLayerNegative );
aGbrItem->m_ImageNegative = aImageNegative;
bool isDark = !(aGbrItem->m_LayerNegative ^ aGbrItem->m_ImageNegative);
/* isDark is true if flash is positive and should use a drawing
* color other than the background color, else use the background color
* when drawing so that an erasure happens.
*/
if( !isDark )
{
aGbrItem->m_Flags |= DRAW_ERASED;
}
} }
@ -362,31 +323,18 @@ static void fillArcPOLY( BOARD* aPcb, GERBER_DRAW_ITEM* aGbrItem,
const wxPoint& aStart, const wxPoint& aEnd, const wxPoint& aStart, const wxPoint& aEnd,
const wxPoint& rel_center, const wxPoint& rel_center,
bool clockwise, bool multiquadrant, bool clockwise, bool multiquadrant,
bool aLayerNegative, bool aLayerNegative )
bool aImageNegative )
{ {
/* in order to calculate arc parameters, we use fillArcGBRITEM /* in order to calculate arc parameters, we use fillArcGBRITEM
* so we muse create a dummy track and use its geometric parameters * so we muse create a dummy track and use its geometric parameters
*/ */
static GERBER_DRAW_ITEM dummyGbrItem( NULL, NULL ); static GERBER_DRAW_ITEM dummyGbrItem( NULL, NULL );
aGbrItem->m_LayerNegative = aLayerNegative; aGbrItem->SetLayerPolarity( aLayerNegative );
aGbrItem->m_ImageNegative = aImageNegative;
bool isDark = !(aGbrItem->m_LayerNegative ^ aGbrItem->m_ImageNegative);
/* isDark is true if flash is positive and should use a drawing
* color other than the background color, else use the background color
* when drawing so that an erasure happens.
*/
if( !isDark )
{
aGbrItem->m_Flags |= DRAW_ERASED;
}
fillArcGBRITEM( &dummyGbrItem, 0, 0, fillArcGBRITEM( &dummyGbrItem, 0, 0,
aStart, aEnd, rel_center, 0, aStart, aEnd, rel_center, 0,
clockwise, multiquadrant, aLayerNegative, aImageNegative ); clockwise, multiquadrant, aLayerNegative );
wxPoint center; wxPoint center;
center = dummyGbrItem.m_ArcCentre; center = dummyGbrItem.m_ArcCentre;
@ -443,7 +391,7 @@ static void fillArcPOLY( BOARD* aPcb, GERBER_DRAW_ITEM* aGbrItem,
/* Read the Gnn sequence and returns the value nn. /* Read the Gnn sequence and returns the value nn.
*/ */
int GERBER::ReturnGCodeNumber( char*& Text ) int GERBER_IMAGE::ReturnGCodeNumber( char*& Text )
{ {
int ii = 0; int ii = 0;
char* text; char* text;
@ -466,7 +414,7 @@ int GERBER::ReturnGCodeNumber( char*& Text )
/* Get the sequence Dnn and returns the value nn /* Get the sequence Dnn and returns the value nn
*/ */
int GERBER::ReturnDCodeNumber( char*& Text ) int GERBER_IMAGE::ReturnDCodeNumber( char*& Text )
{ {
int ii = 0; int ii = 0;
char* text; char* text;
@ -486,7 +434,7 @@ int GERBER::ReturnDCodeNumber( char*& Text )
} }
bool GERBER::Execute_G_Command( char*& text, int G_commande ) bool GERBER_IMAGE::Execute_G_Command( char*& text, int G_commande )
{ {
// D( printf( "%22s: G_CODE<%d>\n", __func__, G_commande ); ) // D( printf( "%22s: G_CODE<%d>\n", __func__, G_commande ); )
@ -613,7 +561,7 @@ int scale( double aCoord, bool isMetric )
} }
bool GERBER::Execute_DCODE_Command( char*& text, int D_commande ) bool GERBER_IMAGE::Execute_DCODE_Command( char*& text, int D_commande )
{ {
wxSize size( 15, 15 ); wxSize size( 15, 15 );
@ -677,7 +625,7 @@ bool GERBER::Execute_DCODE_Command( char*& text, int D_commande )
fillArcPOLY( pcb, gbritem, m_PreviousPos, fillArcPOLY( pcb, gbritem, m_PreviousPos,
m_CurrentPos, m_IJPos, m_CurrentPos, m_IJPos,
( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ? false : true, ( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ? false : true,
m_360Arc_enbl, m_LayerNegative, m_ImageNegative ); m_360Arc_enbl, GetLayerParams().m_LayerNegative );
break; break;
default: default:
@ -693,13 +641,6 @@ bool GERBER::Execute_DCODE_Command( char*& text, int D_commande )
gbritem->m_End = m_CurrentPos; // m_End is used as temporary storage gbritem->m_End = m_CurrentPos; // m_End is used as temporary storage
gbritem->m_PolyCorners.push_back( gbritem->m_End ); gbritem->m_PolyCorners.push_back( gbritem->m_End );
// Set the erasure flag of gbritem if a negative polygon.
if( !m_PolygonFillModeState )
{
if( m_LayerNegative ^ m_ImageNegative )
gbritem->m_Flags |= DRAW_ERASED;
}
break; break;
} }
@ -747,7 +688,7 @@ bool GERBER::Execute_DCODE_Command( char*& text, int D_commande )
// m_PreviousPos.x, m_PreviousPos.y, // m_PreviousPos.x, m_PreviousPos.y,
// m_CurrentPos.x, m_CurrentPos.y ); ) // m_CurrentPos.x, m_CurrentPos.y ); )
fillLineGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos, fillLineGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos,
m_CurrentPos, size.x, m_LayerNegative, m_ImageNegative ); m_CurrentPos, size.x, GetLayerParams().m_LayerNegative );
StepAndRepeatItem( *gbritem ); StepAndRepeatItem( *gbritem );
break; break;
@ -769,8 +710,7 @@ bool GERBER::Execute_DCODE_Command( char*& text, int D_commande )
fillArcGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos, fillArcGBRITEM( gbritem, dcode, activeLayer, m_PreviousPos,
m_CurrentPos, m_IJPos, size.x, m_CurrentPos, m_IJPos, size.x,
( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ? ( m_Iterpolation == GERB_INTERPOL_ARC_NEG ) ?
false : true, m_360Arc_enbl, false : true, m_360Arc_enbl, GetLayerParams().m_LayerNegative );
m_LayerNegative, m_ImageNegative );
StepAndRepeatItem( *gbritem ); StepAndRepeatItem( *gbritem );
break; break;
@ -809,7 +749,7 @@ bool GERBER::Execute_DCODE_Command( char*& text, int D_commande )
// m_CurrentPos.x, m_CurrentPos.y ); ) // m_CurrentPos.x, m_CurrentPos.y ); )
fillFlashedGBRITEM( gbritem, aperture, fillFlashedGBRITEM( gbritem, aperture,
dcode, activeLayer, m_CurrentPos, dcode, activeLayer, m_CurrentPos,
size, m_LayerNegative, m_ImageNegative ); size, GetLayerParams().m_LayerNegative );
StepAndRepeatItem( *gbritem ); StepAndRepeatItem( *gbritem );
m_PreviousPos = m_CurrentPos; m_PreviousPos = m_CurrentPos;
break; break;

View File

@ -126,7 +126,7 @@ static double ReadDouble( char*& text )
} }
bool GERBER::ReadRS274XCommand( char buff[GERBER_BUFZ], char*& text ) bool GERBER_IMAGE::ReadRS274XCommand( char buff[GERBER_BUFZ], char*& text )
{ {
bool ok = true; bool ok = true;
int code_command; int code_command;
@ -179,7 +179,7 @@ exit:
} }
bool GERBER::ExecuteRS274XCommand( int command, bool GERBER_IMAGE::ExecuteRS274XCommand( int command,
char buff[GERBER_BUFZ], char buff[GERBER_BUFZ],
char*& text ) char*& text )
{ {
@ -277,9 +277,35 @@ bool GERBER::ExecuteRS274XCommand( int command,
break; break;
case AXIS_SELECT: case AXIS_SELECT: // command ASAXBY*% or %ASAYBX*%
case MIRROR_IMAGE: m_SwapAxis = false;
ok = FALSE; if( strnicmp( text, "AYBX", 4 ) == 0 )
m_SwapAxis = true;
break;
case MIRROR_IMAGE: // commanf %MIA0B0*%, %MIA0B1*%, %MIA1B0*%, %MIA1B1*%
m_MirrorA = m_MirrorB = 0;
while( *text && *text != '*' )
{
switch( *text )
{
case 'A': // Mirror A axis ?
text++;
if( *text == '1' )
m_MirrorA = true;
break;
case 'B': // Mirror B axis ?
text++;
if( *text == '1' )
m_MirrorB = true;
break;
default:
text++;
break;
}
}
break; break;
case MODE_OF_UNITS: case MODE_OF_UNITS:
@ -313,19 +339,19 @@ bool GERBER::ExecuteRS274XCommand( int command,
break; break;
case SCALE_FACTOR: case SCALE_FACTOR:
m_LayerScale.x = m_LayerScale.y = 1.0; m_Scale.x = m_Scale.y = 1.0;
while( *text != '*' ) while( *text != '*' )
{ {
switch( *text ) switch( *text )
{ {
case 'A': // A axis scale case 'A': // A axis scale
text++; text++;
m_LayerScale.x = ReadDouble( text ); m_Scale.x = ReadDouble( text );
break; break;
case 'B': // B axis scale case 'B': // B axis scale
text++; text++;
m_LayerScale.y = ReadDouble( text ); m_Scale.y = ReadDouble( text );
break; break;
} }
} }
@ -354,43 +380,45 @@ bool GERBER::ExecuteRS274XCommand( int command,
case IMAGE_ROTATION: // command IR0* or IR90* or IR180* or IR270* case IMAGE_ROTATION: // command IR0* or IR90* or IR180* or IR270*
if( strnicmp( text, "0*", 2 ) == 0 ) if( strnicmp( text, "0*", 2 ) == 0 )
m_Rotation = 0; m_ImageRotation = 0;
if( strnicmp( text, "90*", 2 ) == 0 ) if( strnicmp( text, "90*", 2 ) == 0 )
m_Rotation = 900; m_ImageRotation = 900;
if( strnicmp( text, "180*", 2 ) == 0 ) if( strnicmp( text, "180*", 2 ) == 0 )
m_Rotation = 1800; m_ImageRotation = 1800;
if( strnicmp( text, "270*", 2 ) == 0 ) if( strnicmp( text, "270*", 2 ) == 0 )
m_Rotation = 2700; m_ImageRotation = 2700;
else else
ReportMessage( _( "RS274X: Command \"IR\" rotation value not allowed" ) ); ReportMessage( _( "RS274X: Command \"IR\" rotation value not allowed" ) );
break; break;
case STEP_AND_REPEAT: // command SR, like %SRX3Y2I5.0J2*% case STEP_AND_REPEAT: // command SR, like %SRX3Y2I5.0J2*%
m_StepForRepeat.x = m_StepForRepeat.x = 0.0; // offset for Step and Repeat command GetLayerParams().m_StepForRepeat.x = 0.0;
m_XRepeatCount = m_YRepeatCount =1; // The repeat count GetLayerParams().m_StepForRepeat.x = 0.0; // offset for Step and Repeat command
m_StepForRepeatMetric = m_GerbMetric; // the step units GetLayerParams().m_XRepeatCount = 1;
GetLayerParams().m_YRepeatCount = 1; // The repeat count
GetLayerParams().m_StepForRepeatMetric = m_GerbMetric; // the step units
while( *text && *text != '*' ) while( *text && *text != '*' )
{ {
switch( *text ) switch( *text )
{ {
case 'I': // X axis offset case 'I': // X axis offset
text++; text++;
m_StepForRepeat.x = ReadDouble( text ); GetLayerParams().m_StepForRepeat.x = ReadDouble( text );
break; break;
case 'J': // Y axis offset case 'J': // Y axis offset
text++; text++;
m_StepForRepeat.y = ReadDouble( text ); GetLayerParams().m_StepForRepeat.y = ReadDouble( text );
break; break;
case 'X': // X axis repeat count case 'X': // X axis repeat count
text++; text++;
m_XRepeatCount = ReadInt( text ); GetLayerParams().m_XRepeatCount = ReadInt( text );
break; break;
case 'Y': // Y axis offset case 'Y': // Y axis offset
text++; text++;
m_YRepeatCount = ReadInt( text ); GetLayerParams().m_YRepeatCount = ReadInt( text );
break; break;
default: default:
text++; text++;
@ -402,12 +430,15 @@ bool GERBER::ExecuteRS274XCommand( int command,
case IMAGE_JUSTIFY: case IMAGE_JUSTIFY:
case PLOTTER_FILM: case PLOTTER_FILM:
case KNOCKOUT: case KNOCKOUT:
case ROTATE:
msg.Printf( _( "RS274X: Command \"%c%c\" ignored by Gerbview" ), msg.Printf( _( "RS274X: Command \"%c%c\" ignored by Gerbview" ),
(command >> 8) & 0xFF, command & 0xFF ); (command >> 8) & 0xFF, command & 0xFF );
ReportMessage( msg ); ReportMessage( msg );
break; break;
case ROTATE: // Layer rotation: command like %RO45*%
m_LocalRotation = wxRound(ReadDouble( text ) * 10 );
break;
case IMAGE_NAME: case IMAGE_NAME:
m_ImageName.Empty(); m_ImageName.Empty();
while( *text != '*' ) while( *text != '*' )
@ -418,10 +449,10 @@ bool GERBER::ExecuteRS274XCommand( int command,
break; break;
case LAYER_NAME: case LAYER_NAME:
m_LayerName.Empty(); GetLayerParams( ).m_LayerName.Empty();
while( *text != '*' ) while( *text != '*' )
{ {
m_LayerName.Append( *text++ ); GetLayerParams( ).m_LayerName.Append( *text++ );
} }
break; break;
@ -437,9 +468,9 @@ bool GERBER::ExecuteRS274XCommand( int command,
case LAYER_POLARITY: case LAYER_POLARITY:
if( *text == 'C' ) if( *text == 'C' )
m_LayerNegative = true; GetLayerParams().m_LayerNegative = true;
else else
m_LayerNegative = false; GetLayerParams().m_LayerNegative = false;
D( printf( "%22s: LAYER_POLARITY m_LayerNegative=%s\n", __func__, D( printf( "%22s: LAYER_POLARITY m_LayerNegative=%s\n", __func__,
m_LayerNegative ? "true" : "false" ); ) m_LayerNegative ? "true" : "false" ); )
break; break;
@ -719,7 +750,7 @@ static bool CheckForLineEnd( char buff[GERBER_BUFZ], char*& text, FILE* fp )
} }
bool GERBER::ReadApertureMacro( char buff[GERBER_BUFZ], bool GERBER_IMAGE::ReadApertureMacro( char buff[GERBER_BUFZ],
char*& text, char*& text,
FILE* gerber_file ) FILE* gerber_file )
{ {

View File

@ -18,7 +18,7 @@
void WinEDA_GerberFrame::ReCreateHToolbar( void ) void WinEDA_GerberFrame::ReCreateHToolbar( void )
{ {
int layer = 0; int layer = 0;
GERBER* gerber = NULL; GERBER_IMAGE* gerber = NULL;
int ii; int ii;
wxString msg; wxString msg;
@ -219,7 +219,7 @@ void WinEDA_GerberFrame::SetToolbars()
{ {
PCB_SCREEN* screen = (PCB_SCREEN*) GetScreen(); PCB_SCREEN* screen = (PCB_SCREEN*) GetScreen();
int layer = screen->m_Active_Layer; int layer = screen->m_Active_Layer;
GERBER* gerber = g_GERBER_List[layer]; GERBER_IMAGE* gerber = g_GERBER_List[layer];
if( m_HToolBar == NULL ) if( m_HToolBar == NULL )
return; return;

View File

@ -19,42 +19,43 @@
#include "class_GERBER.h" #include "class_GERBER.h"
static void Show_Items_DCode_Value( WinEDA_DrawPanel* panel, wxDC* DC, static void Show_Items_DCode_Value( WinEDA_DrawPanel* panel, wxDC* DC,
BOARD* Pcb, int drawmode ); BOARD* Pcb, int drawmode );
/** virtual Function PrintPage /** virtual Function PrintPage
* Used to print the board (on printer, or when creating SVF files). * Used to print the board (on printer, or when creating SVF files).
* Print the board, but only layers allowed by aPrintMaskLayer * Print the board, but only layers allowed by aPrintMaskLayer
* @param aDC = the print device context * @param aDC = the print device context
* @param aPrint_Sheet_Ref = true to print frame references * @param aPrint_Sheet_Ref = true to print frame references
* @param aPrint_Sheet_Ref = a 32 bits mask: bit n = 1 -> layer n is printed * @param aPrintMasklayer = a 32 bits mask: bit n = 1 -> layer n is printed
* @param aPrintMirrorMode = true to plot mirrored * @param aPrintMirrorMode = true to plot mirrored
* @param aData = a pointer to an optional data (not used here: can be NULL) * @param aData = a pointer to an optional data (not used here: can be NULL)
*/ */
void WinEDA_GerberFrame::PrintPage( wxDC* aDC, bool aPrint_Sheet_Ref, int aPrintMasklayer, void WinEDA_GerberFrame::PrintPage( wxDC* aDC, bool aPrint_Sheet_Ref, int aPrintMasklayer,
bool aPrintMirrorMode, void * aData ) bool aPrintMirrorMode, void* aData )
{ {
DISPLAY_OPTIONS save_opt; // Save current draw options, because print mode has specfic options:
int DisplayPolygonsModeImg; int DisplayPolygonsModeImg = g_DisplayPolygonsModeSketch;
int visiblemask = GetBoard()->GetVisibleLayers();
save_opt = DisplayOpt; DISPLAY_OPTIONS save_opt = DisplayOpt;
// Set draw options for printing:
GetBoard()->SetVisibleLayers( aPrintMasklayer );
DisplayOpt.DisplayPcbTrackFill = FILLED; DisplayOpt.DisplayPcbTrackFill = FILLED;
DisplayOpt.ShowTrackClearanceMode = DO_NOT_SHOW_CLEARANCE;
DisplayOpt.DisplayDrawItems = FILLED; DisplayOpt.DisplayDrawItems = FILLED;
DisplayOpt.DisplayZonesMode = 0; DisplayOpt.DisplayZonesMode = 0;
g_DisplayPolygonsModeSketch = 0;
DisplayPolygonsModeImg = g_DisplayPolygonsModeSketch;
g_DisplayPolygonsModeSketch = 0;
DrawPanel->m_PrintIsMirrored = aPrintMirrorMode; DrawPanel->m_PrintIsMirrored = aPrintMirrorMode;
Trace_Gerber( aDC, GR_COPY, aPrintMasklayer ); GetBoard()->Draw( DrawPanel, aDC, GR_COPY, wxPoint( 0, 0 ) );
if( aPrint_Sheet_Ref ) if( aPrint_Sheet_Ref )
TraceWorkSheet( aDC, GetScreen(), 0 ); TraceWorkSheet( aDC, GetScreen(), 0 );
DrawPanel->m_PrintIsMirrored = false; DrawPanel->m_PrintIsMirrored = false;
// Restore draw options:
GetBoard()->SetVisibleLayers( visiblemask );
DisplayOpt = save_opt; DisplayOpt = save_opt;
g_DisplayPolygonsModeSketch = DisplayPolygonsModeImg; g_DisplayPolygonsModeSketch = DisplayPolygonsModeImg;
} }
@ -63,25 +64,24 @@ void WinEDA_GerberFrame::PrintPage( wxDC* aDC, bool aPrint_Sheet_Ref, int aPrint
/*******************************************************************/ /*******************************************************************/
void WinEDA_GerberFrame::RedrawActiveWindow( wxDC* DC, bool EraseBg ) void WinEDA_GerberFrame::RedrawActiveWindow( wxDC* DC, bool EraseBg )
/*******************************************************************/ /*******************************************************************/
/* Redraws the full screen, including axis and grid /* Redraws the full screen, including axis and grid
*/ */
{ {
PCB_SCREEN* screen = (PCB_SCREEN*)GetScreen(); PCB_SCREEN* screen = (PCB_SCREEN*) GetScreen();
if( !GetBoard() ) if( !GetBoard() )
return; return;
ActiveScreen = screen; ActiveScreen = screen;
GRSetDrawMode( DC, GR_COPY );
GRSetDrawMode( DC, GR_COPY );
DrawPanel->DrawBackGround( DC ); DrawPanel->DrawBackGround( DC );
//buid mask layer : GetBoard()->Draw( DrawPanel, DC, GR_COPY, wxPoint( 0, 0 ) );
int masklayer = 0;
for( int layer = 0; layer < 32; layer++ ) if( IsElementVisible( DCODES_VISIBLE ) )
if( GetBoard()->IsLayerVisible( layer ) ) Show_Items_DCode_Value( DrawPanel, DC, GetBoard(), GR_COPY );
masklayer |= 1 << layer;
Trace_Gerber( DC, GR_COPY, masklayer );
TraceWorkSheet( DC, screen, 0 ); TraceWorkSheet( DC, screen, 0 );
if( DrawPanel->ManageCurseur ) if( DrawPanel->ManageCurseur )
@ -94,50 +94,56 @@ void WinEDA_GerberFrame::RedrawActiveWindow( wxDC* DC, bool EraseBg )
UpdateTitleAndInfo(); UpdateTitleAndInfo();
} }
/********************************************************************/ /********************************************************************/
void BOARD::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode, const wxPoint& aOffset ) void BOARD::Draw( WinEDA_DrawPanel* aPanel, wxDC* aDC, int aDrawMode, const wxPoint& aOffset )
/********************************************************************/ /********************************************************************/
/* Redraw the BOARD items but not cursors, axis or grid */ /* Redraw the BOARD items but not cursors, axis or grid */
// @todo: replace WinEDA_GerberFrame::Trace_Gerber() by this function
{ {
} // Because Images can be negative (i.e with background filled in color) items are drawn
// graphic layer per graphic layer, after the background is filled
for( int layer = 0; layer < 32; layer++ )
/***********************************************************************************/
void WinEDA_GerberFrame::Trace_Gerber( wxDC* aDC, int aDraw_mode, int aPrintMasklayer )
/***********************************************************************************/
/* Trace all elements of PCBs (i.e Spots, filled polygons or lines) on the active screen
* @param aDC = current device context
* @param aDraw_mode = draw mode for the device context (GR_COPY, GR_OR, GR_XOR ..)
* @param aPrintMasklayer = mask for allowed layer (=-1 to draw all layers)
*/
{
if( !GetBoard() )
return;
int layer = GetScreen()->m_Active_Layer;
GERBER* gerber = g_GERBER_List[layer];
int dcode_hightlight = 0;
if( gerber )
dcode_hightlight = gerber->m_Selected_Tool;
BOARD_ITEM* item = GetBoard()->m_Drawings;
for( ; item; item = item->Next() )
{ {
GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item; if( !GetBoard()->IsLayerVisible( layer ) )
if( !(gerb_item->ReturnMaskLayer() & aPrintMasklayer) )
continue; continue;
if( dcode_hightlight == gerb_item->m_DCode && item->GetLayer()==layer ) GERBER_IMAGE* gerber = g_GERBER_List[layer];
gerb_item->Draw( DrawPanel, aDC, aDraw_mode | GR_SURBRILL ); if( gerber == NULL ) // Graphic layer not yet used
else continue;
gerb_item->Draw( DrawPanel, aDC, aDraw_mode );
/* Draw background negative (i.e. in graphic layer color) for negative images:
* Background is drawn here in GR_OR mode because in COPY mode
* all previous graphics will be erased
* Note: items in background color ("Erased" items) are always drawn in COPY mode
* Some artifacts can happen when more than one gerber file is loaded
*/
if( gerber->m_ImageNegative )
{
int color = GetBoard()->GetLayerColor( layer );
GRSetDrawMode( aDC, GR_OR );
EDA_Rect* cbox = &aPanel->m_ClipBox;
GRSFilledRect( cbox, aDC, cbox->GetX(), cbox->GetY(),
cbox->GetRight(), cbox->GetBottom(),
0, color, color );
GRSetDrawMode( aDC, aDrawMode );
}
int dcode_hightlight = 0;
if( layer == m_PcbFrame->GetScreen()->m_Active_Layer )
dcode_hightlight = gerber->m_Selected_Tool;
BOARD_ITEM* item = GetBoard()->m_Drawings;
for( ; item; item = item->Next() )
{
GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item;
if( gerb_item->GetLayer()!= layer )
continue;
int drawMode = aDrawMode;
if( dcode_hightlight == gerb_item->m_DCode )
drawMode |= GR_SURBRILL;
gerb_item->Draw( aPanel, aDC, drawMode );
}
} }
if( IsElementVisible( DCODES_VISIBLE) ) m_PcbFrame->GetScreen()->ClrRefreshReq();
Show_Items_DCode_Value( DrawPanel, aDC, GetBoard(), GR_COPY );
GetScreen()->ClrRefreshReq();
} }
@ -145,9 +151,9 @@ void WinEDA_GerberFrame::Trace_Gerber( wxDC* aDC, int aDraw_mode, int aPrintMask
void Show_Items_DCode_Value( WinEDA_DrawPanel* aPanel, wxDC* aDC, BOARD* aPcb, int aDrawMode ) void Show_Items_DCode_Value( WinEDA_DrawPanel* aPanel, wxDC* aDC, BOARD* aPcb, int aDrawMode )
/*****************************************************************************************/ /*****************************************************************************************/
{ {
wxPoint pos; wxPoint pos;
int width, orient; int width, orient;
wxString Line; wxString Line;
GRSetDrawMode( aDC, aDrawMode ); GRSetDrawMode( aDC, aDrawMode );
BOARD_ITEM* item = aPcb->m_Drawings; BOARD_ITEM* item = aPcb->m_Drawings;
@ -187,22 +193,22 @@ void Show_Items_DCode_Value( WinEDA_DrawPanel* aPanel, wxDC* aDC, BOARD* aPcb, i
width /= 2; width /= 2;
} }
int color = g_ColorsSettings.GetItemColor(DCODES_VISIBLE); int color = g_ColorsSettings.GetItemColor( DCODES_VISIBLE );
DrawGraphicText( aPanel, aDC, DrawGraphicText( aPanel, aDC,
pos, (EDA_Colors) color, Line, pos, (EDA_Colors) color, Line,
orient, wxSize( width, width ), orient, wxSize( width, width ),
GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
0, false, false, false); 0, false, false, false );
} }
} }
/* Virtual fonction needed by the PCB_SCREEN class derived from BASE_SCREEN /* Virtual fonction needed by the PCB_SCREEN class derived from BASE_SCREEN
* this is a virtual pure function in BASE_SCREEN * this is a virtual pure function in BASE_SCREEN
* do nothing in gerbview * do nothing in gerbview
* could be removed later * could be removed later
*/ */
void PCB_SCREEN::ClearUndoORRedoList(UNDO_REDO_CONTAINER&, int ) void PCB_SCREEN::ClearUndoORRedoList( UNDO_REDO_CONTAINER&, int )
{ {
} }

View File

@ -353,8 +353,6 @@ public:
void CopyDCodesSizeToItems(); void CopyDCodesSizeToItems();
void Liste_D_Codes( ); void Liste_D_Codes( );
void Trace_Gerber( wxDC* DC, int draw_mode, int printmasklayer );
// PCB handling // PCB handling
bool Clear_Pcb( bool query ); bool Clear_Pcb( bool query );
void Erase_Current_Layer( bool query ); void Erase_Current_Layer( bool query );
@ -365,7 +363,7 @@ public:
/* SaveCopyInUndoList() virtual /* SaveCopyInUndoList() virtual
* currently: do nothing in gerbview. * currently: do nothing in gerbview.
* but but be defined because it is a pure virtual in WinEDA_BasePcbFrame * but must be defined because it is a pure virtual in WinEDA_BasePcbFrame
*/ */
virtual void SaveCopyInUndoList( virtual void SaveCopyInUndoList(
BOARD_ITEM* aItemToCopy, BOARD_ITEM* aItemToCopy,
@ -392,12 +390,12 @@ public:
* used to print a page * used to print a page
* @param aDC = wxDC given by the calling print function * @param aDC = wxDC given by the calling print function
* @param aPrint_Sheet_Ref = true to print page references * @param aPrint_Sheet_Ref = true to print page references
* @param aPrintMask = not used here * @param aPrintMasklayer = a 32 bits mask: bit n = 1 -> layer n is printed
* @param aPrintMirrorMode = not used here (Set when printing in mirror mode) * @param aPrintMirrorMode = not used here (Set when printing in mirror mode)
* @param aData = a pointer on an auxiliary data (not always used, NULL if not used) * @param aData = a pointer on an auxiliary data (not always used, NULL if not used)
*/ */
virtual void PrintPage( wxDC* aDC, bool aPrint_Sheet_Ref, virtual void PrintPage( wxDC* aDC, bool aPrint_Sheet_Ref,
int aPrintMask, bool aPrintMirrorMode, int aPrintMasklayer, bool aPrintMirrorMode,
void * aData = NULL); void * aData = NULL);
/** InstallDialogLayerPairChoice /** InstallDialogLayerPairChoice

View File

@ -282,9 +282,7 @@ class DHEAD;
// should be ignored // should be ignored
#define DO_NOT_DRAW (1 << 16) ///< Used to disable draw function #define DO_NOT_DRAW (1 << 16) ///< Used to disable draw function
#define DRAW_ERASED (1 << 17) ///< draw in background color, used by #define IS_CANCELLED (1 << 17) ///< flag set when edit dialogs are
// class TRACK in gerbview
#define IS_CANCELLED (1 << 18) ///< flag set when edit dialogs are
// canceled when editing a new object // canceled when editing a new object
class EDA_BaseStruct class EDA_BaseStruct

View File

@ -24,8 +24,7 @@
static bool ShowClearance( const TRACK* aTrack ) static bool ShowClearance( const TRACK* aTrack )
{ {
// maybe return true for tracks and vias, not for zone segments // maybe return true for tracks and vias, not for zone segments
return !(aTrack->m_Flags & DRAW_ERASED) return DisplayOpt.ShowTrackClearanceMode == SHOW_CLEARANCE_ALWAYS
&& DisplayOpt.ShowTrackClearanceMode == SHOW_CLEARANCE_ALWAYS
&& aTrack->GetLayer() <= LAST_COPPER_LAYER && aTrack->GetLayer() <= LAST_COPPER_LAYER
&& ( aTrack->Type() == TYPE_TRACK || aTrack->Type() == TYPE_VIA ); && ( aTrack->Type() == TYPE_TRACK || aTrack->Type() == TYPE_VIA );
} }
@ -567,43 +566,34 @@ void TRACK::Draw( WinEDA_DrawPanel* panel, wxDC* DC, int draw_mode, const wxPoin
return; return;
BOARD * brd = GetBoard( ); BOARD * brd = GetBoard( );
if( m_Flags & DRAW_ERASED ) // draw in background color, used by classs TRACK in gerbview color = brd->GetLayerColor(m_Layer);
if( brd->IsLayerVisible( m_Layer ) == false && ( color & HIGHT_LIGHT_FLAG ) !=
HIGHT_LIGHT_FLAG )
return;
if( DisplayOpt.ContrastModeDisplay )
{ {
color = g_DrawBgColor; if( !IsOnLayer( curr_layer ) )
D( printf( "DRAW_ERASED in Track::Draw, g_DrawBgColor=%04X\n", {
g_DrawBgColor ); ) color &= ~MASKCOLOR;
color |= DARKDARKGRAY;
}
} }
else
if( draw_mode & GR_SURBRILL )
{ {
color = brd->GetLayerColor(m_Layer); if( draw_mode & GR_AND )
color &= ~HIGHT_LIGHT_FLAG;
if( brd->IsLayerVisible( m_Layer ) == false && ( color & HIGHT_LIGHT_FLAG ) != else
HIGHT_LIGHT_FLAG ) color |= HIGHT_LIGHT_FLAG;
return;
if( DisplayOpt.ContrastModeDisplay )
{
if( !IsOnLayer( curr_layer ) )
{
color &= ~MASKCOLOR;
color |= DARKDARKGRAY;
}
}
if( draw_mode & GR_SURBRILL )
{
if( draw_mode & GR_AND )
color &= ~HIGHT_LIGHT_FLAG;
else
color |= HIGHT_LIGHT_FLAG;
}
if( color & HIGHT_LIGHT_FLAG )
color = ColorRefs[color & MASKCOLOR].m_LightColor;
SetAlpha( &color, 150 );
} }
if( color & HIGHT_LIGHT_FLAG )
color = ColorRefs[color & MASKCOLOR].m_LightColor;
SetAlpha( &color, 150 );
GRSetDrawMode( DC, draw_mode ); GRSetDrawMode( DC, draw_mode );