kicad/pcbnew/pcb_plot_params.cpp

426 lines
15 KiB
C++

/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2011 KiCad Developers, see change_log.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 <wx/wx.h>
#include <pcb_plot_params.h>
#include <pcb_plot_params_lexer.h>
#include <layers_id_colors_and_visibility.h>
#include <plot_common.h>
#include <macros.h>
#define PLOT_LINEWIDTH_MIN 0
#define PLOT_LINEWIDTH_MAX (200*IU_PER_DECIMILS)
#define HPGL_PEN_DIAMETER_MIN 0
#define HPGL_PEN_DIAMETER_MAX (100*IU_PER_DECIMILS)
#define HPGL_PEN_SPEED_MIN 0
#define HPGL_PEN_SPEED_MAX 1000
#define HPGL_PEN_NUMBER_MIN 1
#define HPGL_PEN_NUMBER_MAX 16
#define HPGL_PEN_OVERLAY_MIN 0
#define HPGL_PEN_OVERLAY_MAX 0x100
/**
* Default line thickness in PCnew units used to draw or plot items having a
* default thickness line value (Frame references) (i.e. = 0 ).
* 0 = single pixel line width.
*/
int g_DrawDefaultLineThickness = 60;
using namespace PCBPLOTPARAMS_T;
static const char* getTokenName( T aTok )
{
return PCB_PLOT_PARAMS_LEXER::TokenName( aTok );
}
static bool setInt( int* aInt, int aValue, int aMin, int aMax )
{
int temp = aValue;
if( aValue < aMin )
temp = aMin;
else if( aValue > aMax )
temp = aMax;
*aInt = temp;
return (temp == aValue);
}
// PCB_PLOT_PARAMS
PCB_PLOT_PARAMS::PCB_PLOT_PARAMS()
{
layerSelection = LAYER_BACK | LAYER_FRONT
| SILKSCREEN_LAYER_FRONT | SILKSCREEN_LAYER_BACK;
useGerberExtensions = true;
m_SkipNPTH_Pads = false;
m_ExcludeEdgeLayer = true;
m_PlotLineWidth = g_DrawDefaultLineThickness;
m_PlotFrameRef = false;
m_PlotViaOnMaskLayer = false;
m_PlotMode = FILLED;
useAuxOrigin = false;
m_HPGLPenNum = 1;
m_HPGLPenSpeed = 20;
m_HPGLPenDiam = 15;
m_HPGLPenOvr = 2;
m_PlotPSColorOpt = true;
m_PlotPSNegative = false;
psA4Output = false;
m_PlotReference = true;
m_PlotValue = true;
m_PlotTextOther = true;
m_PlotInvisibleTexts = false;
m_PlotPadsOnSilkLayer = false;
subtractMaskFromSilk = false;
m_PlotFormat = PLOT_FORMAT_GERBER;
m_PlotMirror = false;
m_DrillShapeOpt = SMALL_DRILL_SHAPE;
m_AutoScale = false;
m_PlotScale = 1.0;
scaleSelection = 1;
m_FineScaleAdjustX = 1.0;
m_FineScaleAdjustY = 1.0;
m_FineWidthAdjust = 0.;
outputDirectory = wxT( "" );
}
void PCB_PLOT_PARAMS::Format( OUTPUTFORMATTER* aFormatter,
int aNestLevel, int aControl ) const throw( IO_ERROR )
{
const char* falseStr = getTokenName( T_false );
const char* trueStr = getTokenName( T_true );
aFormatter->Print( aNestLevel, "(%s", getTokenName( T_pcbplotparams ) );
aFormatter->Print( aNestLevel+1, "(%s %ld)\n", getTokenName( T_layerselection ),
layerSelection );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_usegerberextensions ),
useGerberExtensions ? trueStr : falseStr );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_excludeedgelayer ),
m_ExcludeEdgeLayer ? trueStr : falseStr );
aFormatter->Print( aNestLevel+1, "(%s %d)\n", getTokenName( T_linewidth ),
m_PlotLineWidth );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_plotframeref ),
m_PlotFrameRef ? trueStr : falseStr );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_viasonmask ),
m_PlotViaOnMaskLayer ? trueStr : falseStr );
aFormatter->Print( aNestLevel+1, "(%s %d)\n", getTokenName( T_mode ),
m_PlotMode );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_useauxorigin ),
useAuxOrigin ? trueStr : falseStr );
aFormatter->Print( aNestLevel+1, "(%s %d)\n", getTokenName( T_hpglpennumber ),
m_HPGLPenNum );
aFormatter->Print( aNestLevel+1, "(%s %d)\n", getTokenName( T_hpglpenspeed ),
m_HPGLPenSpeed );
aFormatter->Print( aNestLevel+1, "(%s %d)\n", getTokenName( T_hpglpendiameter ),
m_HPGLPenDiam );
aFormatter->Print( aNestLevel+1, "(%s %d)\n", getTokenName( T_hpglpenoverlay ),
m_HPGLPenOvr );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_pscolor ),
m_PlotPSColorOpt ? trueStr : falseStr );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_psnegative ),
m_PlotPSNegative ? trueStr : falseStr );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_psa4output ),
psA4Output ? trueStr : falseStr );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_plotreference ),
m_PlotReference ? trueStr : falseStr );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_plotvalue ),
m_PlotValue ? trueStr : falseStr );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_plotothertext ),
m_PlotTextOther ? trueStr : falseStr );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_plotinvisibletext ),
m_PlotInvisibleTexts ? trueStr : falseStr );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_padsonsilk ),
m_PlotPadsOnSilkLayer ? trueStr : falseStr );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_subtractmaskfromsilk ),
subtractMaskFromSilk ? trueStr : falseStr );
aFormatter->Print( aNestLevel+1, "(%s %d)\n", getTokenName( T_outputformat ),
m_PlotFormat );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_mirror ),
m_PlotMirror ? trueStr : falseStr );
aFormatter->Print( aNestLevel+1, "(%s %d)\n", getTokenName( T_drillshape ),
m_DrillShapeOpt );
aFormatter->Print( aNestLevel+1, "(%s %d)\n", getTokenName( T_scaleselection ),
scaleSelection );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_outputdirectory ),
aFormatter->Quotew( outputDirectory ).c_str() );
aFormatter->Print( 0, ")\n" );
}
void PCB_PLOT_PARAMS::Parse( PCB_PLOT_PARAMS_PARSER* aParser ) throw( IO_ERROR, PARSE_ERROR )
{
aParser->Parse( this );
}
bool PCB_PLOT_PARAMS::operator==( const PCB_PLOT_PARAMS &aPcbPlotParams ) const
{
if( layerSelection != aPcbPlotParams.layerSelection )
return false;
if( useGerberExtensions != aPcbPlotParams.useGerberExtensions )
return false;
if( m_ExcludeEdgeLayer != aPcbPlotParams.m_ExcludeEdgeLayer )
return false;
if( m_PlotLineWidth != aPcbPlotParams.m_PlotLineWidth )
return false;
if( m_PlotFrameRef != aPcbPlotParams.m_PlotFrameRef )
return false;
if( m_PlotViaOnMaskLayer != aPcbPlotParams.m_PlotViaOnMaskLayer )
return false;
if( m_PlotMode != aPcbPlotParams.m_PlotMode )
return false;
if( useAuxOrigin != aPcbPlotParams.useAuxOrigin )
return false;
if( m_HPGLPenNum != aPcbPlotParams.m_HPGLPenNum )
return false;
if( m_HPGLPenSpeed != aPcbPlotParams.m_HPGLPenSpeed )
return false;
if( m_HPGLPenDiam != aPcbPlotParams.m_HPGLPenDiam )
return false;
if( m_HPGLPenOvr != aPcbPlotParams.m_HPGLPenOvr )
return false;
if( m_PlotPSColorOpt != aPcbPlotParams.m_PlotPSColorOpt )
return false;
if( m_PlotPSNegative != aPcbPlotParams.m_PlotPSNegative )
return false;
if( psA4Output != aPcbPlotParams.psA4Output )
return false;
if( m_PlotReference != aPcbPlotParams.m_PlotReference )
return false;
if( m_PlotValue != aPcbPlotParams.m_PlotValue )
return false;
if( m_PlotTextOther != aPcbPlotParams.m_PlotTextOther )
return false;
if( m_PlotInvisibleTexts != aPcbPlotParams.m_PlotInvisibleTexts )
return false;
if( m_PlotPadsOnSilkLayer != aPcbPlotParams.m_PlotPadsOnSilkLayer )
return false;
if( subtractMaskFromSilk != aPcbPlotParams.subtractMaskFromSilk )
return false;
if( m_PlotFormat != aPcbPlotParams.m_PlotFormat )
return false;
if( m_PlotMirror != aPcbPlotParams.m_PlotMirror )
return false;
if( m_DrillShapeOpt != aPcbPlotParams.m_DrillShapeOpt )
return false;
if( scaleSelection != aPcbPlotParams.scaleSelection )
return false;
if( !outputDirectory.IsSameAs( aPcbPlotParams.outputDirectory ) )
return false;
return true;
}
bool PCB_PLOT_PARAMS::operator!=( const PCB_PLOT_PARAMS &aPcbPlotParams ) const
{
return !( *this == aPcbPlotParams );
}
bool PCB_PLOT_PARAMS::SetHpglPenDiameter( int aValue )
{
return setInt( &m_HPGLPenDiam, aValue, HPGL_PEN_DIAMETER_MIN, HPGL_PEN_DIAMETER_MAX );
}
bool PCB_PLOT_PARAMS::SetHpglPenSpeed( int aValue )
{
return setInt( &m_HPGLPenSpeed, aValue, HPGL_PEN_SPEED_MIN, HPGL_PEN_SPEED_MAX );
}
bool PCB_PLOT_PARAMS::SetHpglPenOverlay( int aValue )
{
return setInt( &m_HPGLPenOvr, aValue, HPGL_PEN_OVERLAY_MIN, HPGL_PEN_OVERLAY_MAX );
}
bool PCB_PLOT_PARAMS::SetPlotLineWidth( int aValue )
{
return setInt( &m_PlotLineWidth, aValue, PLOT_LINEWIDTH_MIN, PLOT_LINEWIDTH_MAX );
}
// PCB_PLOT_PARAMS_PARSER
PCB_PLOT_PARAMS_PARSER::PCB_PLOT_PARAMS_PARSER( LINE_READER* aReader ) :
PCB_PLOT_PARAMS_LEXER( aReader )
{
}
PCB_PLOT_PARAMS_PARSER::PCB_PLOT_PARAMS_PARSER( char* aLine, wxString aSource ) :
PCB_PLOT_PARAMS_LEXER( aLine, aSource )
{
}
void PCB_PLOT_PARAMS_PARSER::Parse( PCB_PLOT_PARAMS* aPcbPlotParams ) throw( IO_ERROR, PARSE_ERROR )
{
T token;
while( ( token = NextTok() ) != T_RIGHT )
{
if( token == T_EOF)
Unexpected( T_EOF );
if( token == T_LEFT )
token = NextTok();
if( token == T_pcbplotparams )
continue;
switch( token )
{
case T_layerselection:
token = NextTok();
if( token != T_NUMBER )
Expecting( T_NUMBER );
aPcbPlotParams->layerSelection = atol( CurText() );
break;
case T_usegerberextensions:
aPcbPlotParams->useGerberExtensions = ParseBool();
break;
case T_psa4output:
aPcbPlotParams->psA4Output = ParseBool();
break;
case T_excludeedgelayer:
aPcbPlotParams->m_ExcludeEdgeLayer = ParseBool();
break;
case T_linewidth:
aPcbPlotParams->m_PlotLineWidth = ParseInt( PLOT_LINEWIDTH_MIN,
PLOT_LINEWIDTH_MAX );
break;
case T_plotframeref:
aPcbPlotParams->m_PlotFrameRef = ParseBool();
break;
case T_viasonmask:
aPcbPlotParams->m_PlotViaOnMaskLayer = ParseBool();
break;
case T_mode:
aPcbPlotParams->m_PlotMode = (EDA_DRAW_MODE_T)ParseInt( 0, 2 );
break;
case T_useauxorigin:
aPcbPlotParams->useAuxOrigin = ParseBool();
break;
case T_hpglpennumber:
aPcbPlotParams->m_HPGLPenNum = ParseInt( HPGL_PEN_NUMBER_MIN,
HPGL_PEN_NUMBER_MAX );
break;
case T_hpglpenspeed:
aPcbPlotParams->m_HPGLPenSpeed = ParseInt( HPGL_PEN_SPEED_MIN,
HPGL_PEN_SPEED_MAX );
break;
case T_hpglpendiameter:
aPcbPlotParams->m_HPGLPenDiam = ParseInt( HPGL_PEN_DIAMETER_MIN,
HPGL_PEN_DIAMETER_MAX );
break;
case T_hpglpenoverlay:
aPcbPlotParams->m_HPGLPenOvr = ParseInt( HPGL_PEN_OVERLAY_MIN,
HPGL_PEN_OVERLAY_MIN );
break;
case T_pscolor:
aPcbPlotParams->m_PlotPSColorOpt = ParseBool();
break;
case T_psnegative:
aPcbPlotParams->m_PlotPSNegative = ParseBool();
break;
case T_plotreference:
aPcbPlotParams->m_PlotReference = ParseBool();
break;
case T_plotvalue:
aPcbPlotParams->m_PlotValue = ParseBool();
break;
case T_plotothertext:
aPcbPlotParams->m_PlotTextOther = ParseBool();
break;
case T_plotinvisibletext:
aPcbPlotParams->m_PlotInvisibleTexts = ParseBool();
break;
case T_padsonsilk:
aPcbPlotParams->m_PlotPadsOnSilkLayer= ParseBool();
break;
case T_subtractmaskfromsilk:
aPcbPlotParams->subtractMaskFromSilk = ParseBool();
break;
case T_outputformat:
aPcbPlotParams->m_PlotFormat = ParseInt( 0, 3 );
break;
case T_mirror:
aPcbPlotParams->m_PlotMirror = ParseBool();
break;
case T_drillshape:
aPcbPlotParams->m_DrillShapeOpt = (PCB_PLOT_PARAMS::DrillShapeOptT) ParseInt( 0, 2 );
break;
case T_scaleselection:
aPcbPlotParams->scaleSelection = ParseInt( 0, 4 );
break;
case T_outputdirectory:
NeedSYMBOL();
aPcbPlotParams->outputDirectory = FROM_UTF8( CurText() );
break;
default:
Unexpected( CurText() );
break;
}
NeedRIGHT();
}
}
bool PCB_PLOT_PARAMS_PARSER::ParseBool() throw( IO_ERROR )
{
T token = NeedSYMBOL();
if( token != T_false && token != T_true )
Expecting( "true|false" );
return token == T_true;
}
int PCB_PLOT_PARAMS_PARSER::ParseInt( int aMin, int aMax ) throw( IO_ERROR )
{
T token = NextTok();
if( token != T_NUMBER )
Expecting( T_NUMBER );
int val = atoi( CurText() );
if( val < aMin )
val = aMin;
else if( val > aMax )
val = aMax;
return val;
}