Plot functions: some enhancements in mirror mode (Pcbnew specific): boards are mirrored horizontally, and the page layout is no more mirrored, and therefore is always readable.

This commit is contained in:
jean-pierre charras 2013-12-06 19:31:15 +01:00
parent 72e567f503
commit 4374e25219
9 changed files with 96 additions and 40 deletions

View File

@ -30,7 +30,9 @@ PLOTTER::PLOTTER( )
defaultPenWidth = 0; defaultPenWidth = 0;
currentPenWidth = -1; // To-be-set marker currentPenWidth = -1; // To-be-set marker
penState = 'Z'; // End-of-path idle penState = 'Z'; // End-of-path idle
plotMirror = false; // Mirror flag m_plotMirror = false; // Mirror flag
m_mirrorIsHorizontal = true;
m_yaxisReversed = false;
outputFile = 0; outputFile = 0;
colorMode = false; // Starts as a BW plot colorMode = false; // Starts as a BW plot
negativeMode = false; negativeMode = false;
@ -74,16 +76,27 @@ bool PLOTTER::OpenFile( const wxString& aFullFilename )
* scale factor, and offsets trace. Also convert from a wxPoint to DPOINT, * scale factor, and offsets trace. Also convert from a wxPoint to DPOINT,
* since some output engines needs floating point coordinates. * since some output engines needs floating point coordinates.
*/ */
DPOINT PLOTTER::userToDeviceCoordinates( const wxPoint& pos ) DPOINT PLOTTER::userToDeviceCoordinates( const wxPoint& aCoordinate )
{ {
double x = (pos.x - plotOffset.x) * plotScale * iuPerDeviceUnit; wxPoint pos = aCoordinate - plotOffset;
double y;
double x = pos.x * plotScale;
double y = ( paperSize.y - pos.y * plotScale );
if( m_plotMirror )
{
if( m_mirrorIsHorizontal )
x = ( paperSize.x - pos.x * plotScale );
else
y = pos.y * plotScale;
}
if( m_yaxisReversed )
y = paperSize.y - y;
x *= iuPerDeviceUnit;
y *= iuPerDeviceUnit;
if( plotMirror )
y = ( pos.y - plotOffset.y ) * plotScale * iuPerDeviceUnit ;
else
y = ( paperSize.y - ( pos.y - plotOffset.y )
* plotScale ) * iuPerDeviceUnit ;
return DPOINT( x, y ); return DPOINT( x, y );
} }

View File

@ -44,7 +44,7 @@ void DXF_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
iuPerDeviceUnit *= 0.00254; // ... now in mm iuPerDeviceUnit *= 0.00254; // ... now in mm
SetDefaultLineWidth( 0 ); // No line width on DXF SetDefaultLineWidth( 0 ); // No line width on DXF
plotMirror = false; // No mirroring on DXF m_plotMirror = false; // No mirroring on DXF
m_currentColor = BLACK; m_currentColor = BLACK;
} }

View File

@ -21,7 +21,7 @@ void GERBER_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
{ {
wxASSERT( !outputFile ); wxASSERT( !outputFile );
wxASSERT( aMirror == false ); wxASSERT( aMirror == false );
plotMirror = false; m_plotMirror = false;
plotOffset = aOffset; plotOffset = aOffset;
wxASSERT( aScale == 1 ); wxASSERT( aScale == 1 );
plotScale = 1; plotScale = 1;

View File

@ -196,7 +196,7 @@ void HPGL_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
paperSize.x *= 10.0 * aIusPerDecimil; paperSize.x *= 10.0 * aIusPerDecimil;
paperSize.y *= 10.0 * aIusPerDecimil; paperSize.y *= 10.0 * aIusPerDecimil;
SetDefaultLineWidth( 0 ); // HPGL has pen sizes instead SetDefaultLineWidth( 0 ); // HPGL has pen sizes instead
plotMirror = aMirror; m_plotMirror = aMirror;
} }
@ -392,14 +392,15 @@ void HPGL_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle,
DPOINT centre_dev = userToDeviceCoordinates( centre ); DPOINT centre_dev = userToDeviceCoordinates( centre );
if( plotMirror ) if( m_plotMirror )
angle = StAngle - EndAngle; angle = StAngle - EndAngle;
else else
angle = EndAngle - StAngle; angle = EndAngle - StAngle;
NORMALIZE_ANGLE_180( angle ); NORMALIZE_ANGLE_180( angle );
angle /= 10; angle /= 10;
// Calculate start point, // Calculate arc start point:
wxPoint cmap; wxPoint cmap;
cmap.x = centre.x + KiROUND( cosdecideg( radius, StAngle ) ); cmap.x = centre.x + KiROUND( cosdecideg( radius, StAngle ) );
cmap.y = centre.y - KiROUND( sindecideg( radius, StAngle ) ); cmap.y = centre.y - KiROUND( sindecideg( radius, StAngle ) );
@ -407,10 +408,8 @@ void HPGL_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle,
fprintf( outputFile, fprintf( outputFile,
"PU;PA %.0f,%.0f;PD;AA %.0f,%.0f,", "PU;PA %.0f,%.0f;PD;AA %.0f,%.0f,",
cmap_dev.x, cmap_dev.x, cmap_dev.y,
cmap_dev.y, centre_dev.x, centre_dev.y );
centre_dev.x,
centre_dev.y );
fprintf( outputFile, "%.0f", angle ); fprintf( outputFile, "%.0f", angle );
fprintf( outputFile, ";PU;\n" ); fprintf( outputFile, ";PU;\n" );
PenFinish(); PenFinish();
@ -431,7 +430,7 @@ void HPGL_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, double
*/ */
if( size.x > size.y ) if( size.x > size.y )
{ {
EXCHG( size.x, size.y ); EXCHG( size.x, size.y );
orient = AddAngles( orient, 900 ); orient = AddAngles( orient, 900 );
} }

View File

@ -71,7 +71,7 @@ void PDF_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
double aScale, bool aMirror ) double aScale, bool aMirror )
{ {
wxASSERT( !workFile ); wxASSERT( !workFile );
plotMirror = aMirror; m_plotMirror = aMirror;
plotOffset = aOffset; plotOffset = aOffset;
plotScale = aScale; plotScale = aScale;
m_IUsPerDecimil = aIusPerDecimil; m_IUsPerDecimil = aIusPerDecimil;

View File

@ -306,7 +306,7 @@ void PS_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
double aScale, bool aMirror ) double aScale, bool aMirror )
{ {
wxASSERT( !outputFile ); wxASSERT( !outputFile );
plotMirror = aMirror; m_plotMirror = aMirror;
plotOffset = aOffset; plotOffset = aOffset;
plotScale = aScale; plotScale = aScale;
m_IUsPerDecimil = aIusPerDecimil; m_IUsPerDecimil = aIusPerDecimil;
@ -471,7 +471,7 @@ void PS_PLOTTER::Circle( const wxPoint& pos, int diametre, FILL_T fill, int widt
} }
void PS_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, void PS_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle,
int radius, FILL_T fill, int width ) int radius, FILL_T fill, int width )
{ {
wxASSERT( outputFile ); wxASSERT( outputFile );
@ -486,14 +486,24 @@ void PS_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle,
// Calculate start point. // Calculate start point.
DPOINT centre_dev = userToDeviceCoordinates( centre ); DPOINT centre_dev = userToDeviceCoordinates( centre );
double radius_dev = userToDeviceSize( radius ); double radius_dev = userToDeviceSize( radius );
if( plotMirror )
fprintf( outputFile, "%g %g %g %g %g arc%d\n", centre_dev.x, centre_dev.y, if( m_plotMirror )
radius_dev, -EndAngle / 10.0, -StAngle / 10.0, {
fill ); if( m_mirrorIsHorizontal )
else {
fprintf( outputFile, "%g %g %g %g %g arc%d\n", centre_dev.x, centre_dev.y, StAngle = 1800.0 -StAngle;
radius_dev, StAngle / 10.0, EndAngle / 10.0, EndAngle = 1800.0 -EndAngle;
fill ); EXCHG( StAngle, EndAngle );
}
else
{
StAngle = -StAngle;
EndAngle = -EndAngle;
}
}
fprintf( outputFile, "%g %g %g %g %g arc%d\n", centre_dev.x, centre_dev.y,
radius_dev, StAngle / 10.0, EndAngle / 10.0, fill );
} }

View File

@ -172,7 +172,8 @@ void SVG_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
double aScale, bool aMirror ) double aScale, bool aMirror )
{ {
wxASSERT( !outputFile ); wxASSERT( !outputFile );
plotMirror = not aMirror; // unlike other plotters, SVG has Y axis reversed m_plotMirror = aMirror;
m_yaxisReversed = true; // unlike other plotters, SVG has Y axis reversed
plotOffset = aOffset; plotOffset = aOffset;
plotScale = aScale; plotScale = aScale;
m_IUsPerDecimil = aIusPerDecimil; m_IUsPerDecimil = aIusPerDecimil;
@ -345,13 +346,28 @@ void SVG_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, i
DPOINT centre_dev = userToDeviceCoordinates( centre ); DPOINT centre_dev = userToDeviceCoordinates( centre );
double radius_dev = userToDeviceSize( radius ); double radius_dev = userToDeviceSize( radius );
if( !plotMirror ) if( m_yaxisReversed ) // Should be always the case
{ {
double tmp = StAngle; double tmp = StAngle;
StAngle = -EndAngle; StAngle = -EndAngle;
EndAngle = -tmp; EndAngle = -tmp;
} }
if( m_plotMirror )
{
if( m_mirrorIsHorizontal )
{
StAngle = 1800.0 -StAngle;
EndAngle = 1800.0 -EndAngle;
EXCHG( StAngle, EndAngle );
}
else
{
StAngle = -StAngle;
EndAngle = -EndAngle;
}
}
DPOINT start; DPOINT start;
start.x = radius_dev; start.x = radius_dev;
RotatePoint( &start.x, &start.y, StAngle ); RotatePoint( &start.x, &start.y, StAngle );

View File

@ -153,7 +153,7 @@ public:
int width = DEFAULT_LINE_WIDTH ) = 0; int width = DEFAULT_LINE_WIDTH ) = 0;
virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill, virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill,
int width = DEFAULT_LINE_WIDTH ) = 0; int width = DEFAULT_LINE_WIDTH ) = 0;
virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle, virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle,
int rayon, FILL_T fill, int width = DEFAULT_LINE_WIDTH ); int rayon, FILL_T fill, int width = DEFAULT_LINE_WIDTH );
/** /**
@ -214,7 +214,7 @@ public:
// Higher level primitives -- can be drawn as line, sketch or 'filled' // Higher level primitives -- can be drawn as line, sketch or 'filled'
virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width, virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width,
EDA_DRAW_MODE_T tracemode ); EDA_DRAW_MODE_T tracemode );
virtual void ThickArc( const wxPoint& centre, double StAngle, double EndAngle, virtual void ThickArc( const wxPoint& centre, double StAngle, double EndAngle,
int rayon, int width, EDA_DRAW_MODE_T tracemode ); int rayon, int width, EDA_DRAW_MODE_T tracemode );
virtual void ThickRect( const wxPoint& p1, const wxPoint& p2, int width, virtual void ThickRect( const wxPoint& p1, const wxPoint& p2, int width,
EDA_DRAW_MODE_T tracemode ); EDA_DRAW_MODE_T tracemode );
@ -301,7 +301,7 @@ protected:
int width ); int width );
// Coordinate and scaling conversion functions // Coordinate and scaling conversion functions
virtual DPOINT userToDeviceCoordinates( const wxPoint& pos ); virtual DPOINT userToDeviceCoordinates( const wxPoint& aCoordinate );
virtual DPOINT userToDeviceSize( const wxSize& size ); virtual DPOINT userToDeviceSize( const wxSize& size );
virtual double userToDeviceSize( double size ); virtual double userToDeviceSize( double size );
@ -320,6 +320,12 @@ protected:
/// Plot offset (in IUs) /// Plot offset (in IUs)
wxPoint plotOffset; wxPoint plotOffset;
/// X axis orientation (SVG)
/// and plot mirrored (only for PS, PDF HPGL and SVG)
bool m_plotMirror;
bool m_mirrorIsHorizontal; /// true to mirror horizontally (else vertically)
bool m_yaxisReversed; /// true if the Y axis is top to bottom (SVG)
/// Output file /// Output file
FILE* outputFile; FILE* outputFile;
@ -332,7 +338,6 @@ protected:
char penState; char penState;
/// Last pen positions; set to -1,-1 when the pen is at rest /// Last pen positions; set to -1,-1 when the pen is at rest
wxPoint penLastpos; wxPoint penLastpos;
bool plotMirror;
wxString creator; wxString creator;
wxString filename; wxString filename;
PAGE_INFO pageInfo; PAGE_INFO pageInfo;
@ -402,7 +407,7 @@ public:
virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width, virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width,
EDA_DRAW_MODE_T tracemode ); EDA_DRAW_MODE_T tracemode );
virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle, virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle,
int rayon, FILL_T fill, int width = DEFAULT_LINE_WIDTH ); int rayon, FILL_T fill, int width = DEFAULT_LINE_WIDTH );
virtual void PenTo( const wxPoint& pos, char plume ); virtual void PenTo( const wxPoint& pos, char plume );
virtual void FlashPadCircle( const wxPoint& pos, int diametre, virtual void FlashPadCircle( const wxPoint& pos, int diametre,
@ -786,7 +791,7 @@ public:
int width = DEFAULT_LINE_WIDTH ); int width = DEFAULT_LINE_WIDTH );
virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill, virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill,
int width = DEFAULT_LINE_WIDTH ); int width = DEFAULT_LINE_WIDTH );
virtual void Arc( const wxPoint& aCenter, double aStAngle, double aEndAngle, virtual void Arc( const wxPoint& aCenter, double aStAngle, double aEndAngle,
int aRadius, FILL_T aFill, int aWidth = DEFAULT_LINE_WIDTH ); int aRadius, FILL_T aFill, int aWidth = DEFAULT_LINE_WIDTH );
virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, virtual void PlotPoly( const std::vector< wxPoint >& aCornerList,
FILL_T aFill, int aWidth = DEFAULT_LINE_WIDTH ); FILL_T aFill, int aWidth = DEFAULT_LINE_WIDTH );
@ -877,7 +882,7 @@ public:
FILL_T aFill, int aWidth = DEFAULT_LINE_WIDTH ); FILL_T aFill, int aWidth = DEFAULT_LINE_WIDTH );
virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width, virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width,
EDA_DRAW_MODE_T tracemode ); EDA_DRAW_MODE_T tracemode );
virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle, virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle,
int rayon, FILL_T fill, int width = DEFAULT_LINE_WIDTH ); int rayon, FILL_T fill, int width = DEFAULT_LINE_WIDTH );
virtual void PenTo( const wxPoint& pos, char plume ); virtual void PenTo( const wxPoint& pos, char plume );
virtual void FlashPadCircle( const wxPoint& pos, int diametre, virtual void FlashPadCircle( const wxPoint& pos, int diametre,

View File

@ -797,7 +797,15 @@ PLOTTER* StartPlotBoard( BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts,
} }
// Compute the viewport and set the other options // Compute the viewport and set the other options
initializePlotter( plotter, aBoard, aPlotOpts );
// page layout is not mirrored, so temporary change mirror option
// just to plot the page layout
PCB_PLOT_PARAMS plotOpts = *aPlotOpts;
if( plotOpts.GetPlotFrameRef() && plotOpts.GetMirror() )
plotOpts.SetMirror( false );
initializePlotter( plotter, aBoard, &plotOpts );
if( plotter->OpenFile( aFullFileName ) ) if( plotter->OpenFile( aFullFileName ) )
{ {
@ -805,11 +813,16 @@ PLOTTER* StartPlotBoard( BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts,
// Plot the frame reference if requested // Plot the frame reference if requested
if( aPlotOpts->GetPlotFrameRef() ) if( aPlotOpts->GetPlotFrameRef() )
{
PlotWorkSheet( plotter, aBoard->GetTitleBlock(), PlotWorkSheet( plotter, aBoard->GetTitleBlock(),
aBoard->GetPageSettings(), aBoard->GetPageSettings(),
1, 1, // Only one page 1, 1, // Only one page
aSheetDesc, aBoard->GetFileName() ); aSheetDesc, aBoard->GetFileName() );
if( aPlotOpts->GetMirror() )
initializePlotter( plotter, aBoard, aPlotOpts );
}
/* When plotting a negative board: draw a black rectangle /* When plotting a negative board: draw a black rectangle
* (background for plot board in white) and switch the current * (background for plot board in white) and switch the current
* color to WHITE; note the color inversion is actually done * color to WHITE; note the color inversion is actually done