From 4374e252191b3f15747b777af4faf45b24832eb9 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Fri, 6 Dec 2013 19:31:15 +0100 Subject: [PATCH] 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. --- common/class_plotter.cpp | 31 ++++++++++++++++++-------- common/common_plotDXF_functions.cpp | 2 +- common/common_plotGERBER_functions.cpp | 2 +- common/common_plotHPGL_functions.cpp | 15 ++++++------- common/common_plotPDF_functions.cpp | 2 +- common/common_plotPS_functions.cpp | 30 ++++++++++++++++--------- common/common_plotSVG_functions.cpp | 20 +++++++++++++++-- include/plot_common.h | 19 ++++++++++------ pcbnew/plot_board_layers.cpp | 15 ++++++++++++- 9 files changed, 96 insertions(+), 40 deletions(-) diff --git a/common/class_plotter.cpp b/common/class_plotter.cpp index a6be0a315a..e726e93c3e 100644 --- a/common/class_plotter.cpp +++ b/common/class_plotter.cpp @@ -30,7 +30,9 @@ PLOTTER::PLOTTER( ) defaultPenWidth = 0; currentPenWidth = -1; // To-be-set marker penState = 'Z'; // End-of-path idle - plotMirror = false; // Mirror flag + m_plotMirror = false; // Mirror flag + m_mirrorIsHorizontal = true; + m_yaxisReversed = false; outputFile = 0; colorMode = false; // Starts as a BW plot negativeMode = false; @@ -74,16 +76,27 @@ bool PLOTTER::OpenFile( const wxString& aFullFilename ) * scale factor, and offsets trace. Also convert from a wxPoint to DPOINT, * 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; - double y; + wxPoint pos = aCoordinate - plotOffset; + + 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 ); } diff --git a/common/common_plotDXF_functions.cpp b/common/common_plotDXF_functions.cpp index e76d6805c1..cf216e03d4 100644 --- a/common/common_plotDXF_functions.cpp +++ b/common/common_plotDXF_functions.cpp @@ -44,7 +44,7 @@ void DXF_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil, iuPerDeviceUnit *= 0.00254; // ... now in mm SetDefaultLineWidth( 0 ); // No line width on DXF - plotMirror = false; // No mirroring on DXF + m_plotMirror = false; // No mirroring on DXF m_currentColor = BLACK; } diff --git a/common/common_plotGERBER_functions.cpp b/common/common_plotGERBER_functions.cpp index 5ed5ec0f55..e8b5273ded 100644 --- a/common/common_plotGERBER_functions.cpp +++ b/common/common_plotGERBER_functions.cpp @@ -21,7 +21,7 @@ void GERBER_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil, { wxASSERT( !outputFile ); wxASSERT( aMirror == false ); - plotMirror = false; + m_plotMirror = false; plotOffset = aOffset; wxASSERT( aScale == 1 ); plotScale = 1; diff --git a/common/common_plotHPGL_functions.cpp b/common/common_plotHPGL_functions.cpp index 15893dfeeb..d3ff46b6f4 100644 --- a/common/common_plotHPGL_functions.cpp +++ b/common/common_plotHPGL_functions.cpp @@ -196,7 +196,7 @@ void HPGL_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil, paperSize.x *= 10.0 * aIusPerDecimil; paperSize.y *= 10.0 * aIusPerDecimil; 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 ); - if( plotMirror ) + if( m_plotMirror ) angle = StAngle - EndAngle; else angle = EndAngle - StAngle; + NORMALIZE_ANGLE_180( angle ); angle /= 10; - // Calculate start point, + // Calculate arc start point: wxPoint cmap; cmap.x = centre.x + KiROUND( cosdecideg( 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, "PU;PA %.0f,%.0f;PD;AA %.0f,%.0f,", - cmap_dev.x, - cmap_dev.y, - centre_dev.x, - centre_dev.y ); + cmap_dev.x, cmap_dev.y, + centre_dev.x, centre_dev.y ); fprintf( outputFile, "%.0f", angle ); fprintf( outputFile, ";PU;\n" ); PenFinish(); @@ -431,7 +430,7 @@ void HPGL_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, double */ if( size.x > size.y ) { - EXCHG( size.x, size.y ); + EXCHG( size.x, size.y ); orient = AddAngles( orient, 900 ); } diff --git a/common/common_plotPDF_functions.cpp b/common/common_plotPDF_functions.cpp index b053121c48..8349c5ff45 100644 --- a/common/common_plotPDF_functions.cpp +++ b/common/common_plotPDF_functions.cpp @@ -71,7 +71,7 @@ void PDF_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil, double aScale, bool aMirror ) { wxASSERT( !workFile ); - plotMirror = aMirror; + m_plotMirror = aMirror; plotOffset = aOffset; plotScale = aScale; m_IUsPerDecimil = aIusPerDecimil; diff --git a/common/common_plotPS_functions.cpp b/common/common_plotPS_functions.cpp index 2a0057e081..cad37ae694 100644 --- a/common/common_plotPS_functions.cpp +++ b/common/common_plotPS_functions.cpp @@ -306,7 +306,7 @@ void PS_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil, double aScale, bool aMirror ) { wxASSERT( !outputFile ); - plotMirror = aMirror; + m_plotMirror = aMirror; plotOffset = aOffset; plotScale = aScale; 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 ) { wxASSERT( outputFile ); @@ -486,14 +486,24 @@ void PS_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, // Calculate start point. DPOINT centre_dev = userToDeviceCoordinates( centre ); double radius_dev = userToDeviceSize( radius ); - if( plotMirror ) - fprintf( outputFile, "%g %g %g %g %g arc%d\n", centre_dev.x, centre_dev.y, - radius_dev, -EndAngle / 10.0, -StAngle / 10.0, - fill ); - else - 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 ); + + if( m_plotMirror ) + { + if( m_mirrorIsHorizontal ) + { + StAngle = 1800.0 -StAngle; + EndAngle = 1800.0 -EndAngle; + 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 ); } diff --git a/common/common_plotSVG_functions.cpp b/common/common_plotSVG_functions.cpp index 03d53698b0..b883107c84 100644 --- a/common/common_plotSVG_functions.cpp +++ b/common/common_plotSVG_functions.cpp @@ -172,7 +172,8 @@ void SVG_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil, double aScale, bool aMirror ) { 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; plotScale = aScale; m_IUsPerDecimil = aIusPerDecimil; @@ -345,13 +346,28 @@ void SVG_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, i DPOINT centre_dev = userToDeviceCoordinates( centre ); double radius_dev = userToDeviceSize( radius ); - if( !plotMirror ) + if( m_yaxisReversed ) // Should be always the case { double tmp = StAngle; StAngle = -EndAngle; 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; start.x = radius_dev; RotatePoint( &start.x, &start.y, StAngle ); diff --git a/include/plot_common.h b/include/plot_common.h index cdb6ff049b..1dff640eb4 100644 --- a/include/plot_common.h +++ b/include/plot_common.h @@ -153,7 +153,7 @@ public: int width = DEFAULT_LINE_WIDTH ) = 0; virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill, 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 ); /** @@ -214,7 +214,7 @@ public: // Higher level primitives -- can be drawn as line, sketch or 'filled' virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width, 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 ); virtual void ThickRect( const wxPoint& p1, const wxPoint& p2, int width, EDA_DRAW_MODE_T tracemode ); @@ -301,7 +301,7 @@ protected: int width ); // Coordinate and scaling conversion functions - virtual DPOINT userToDeviceCoordinates( const wxPoint& pos ); + virtual DPOINT userToDeviceCoordinates( const wxPoint& aCoordinate ); virtual DPOINT userToDeviceSize( const wxSize& size ); virtual double userToDeviceSize( double size ); @@ -320,6 +320,12 @@ protected: /// Plot offset (in IUs) 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 FILE* outputFile; @@ -332,7 +338,6 @@ protected: char penState; /// Last pen positions; set to -1,-1 when the pen is at rest wxPoint penLastpos; - bool plotMirror; wxString creator; wxString filename; PAGE_INFO pageInfo; @@ -402,7 +407,7 @@ public: virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width, 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 ); virtual void PenTo( const wxPoint& pos, char plume ); virtual void FlashPadCircle( const wxPoint& pos, int diametre, @@ -786,7 +791,7 @@ public: int width = DEFAULT_LINE_WIDTH ); virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill, 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 ); virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = DEFAULT_LINE_WIDTH ); @@ -877,7 +882,7 @@ public: FILL_T aFill, int aWidth = DEFAULT_LINE_WIDTH ); virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width, 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 ); virtual void PenTo( const wxPoint& pos, char plume ); virtual void FlashPadCircle( const wxPoint& pos, int diametre, diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp index 8ba01ab009..34d708195b 100644 --- a/pcbnew/plot_board_layers.cpp +++ b/pcbnew/plot_board_layers.cpp @@ -797,7 +797,15 @@ PLOTTER* StartPlotBoard( BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts, } // 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 ) ) { @@ -805,11 +813,16 @@ PLOTTER* StartPlotBoard( BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts, // Plot the frame reference if requested if( aPlotOpts->GetPlotFrameRef() ) + { PlotWorkSheet( plotter, aBoard->GetTitleBlock(), aBoard->GetPageSettings(), 1, 1, // Only one page aSheetDesc, aBoard->GetFileName() ); + if( aPlotOpts->GetMirror() ) + initializePlotter( plotter, aBoard, aPlotOpts ); + } + /* When plotting a negative board: draw a black rectangle * (background for plot board in white) and switch the current * color to WHITE; note the color inversion is actually done