← Back to team overview

kicad-developers team mailing list archive

Re: Plotting/fabricating in nanometers

 

On Sat, Apr 28, 2012 at 05:16:15PM +0200, jean-pierre charras wrote:
> Two kind of point using doubles:
> the first is wxRealPoint, the floating version of wxPoint.
> the second is a new class: DPOINT defined in vector2d.h, very recently created by Dick.
> DPOINT is a powerful class.

OK, I changed the plotting engines to work with DPOINT device coordinates. It still accept wxPoint coordinates so nothing else has to be changed (which is good). Also it accepts them as const references so there is no copying during call (which is good, too).

I also removed the m_PlotType member since it was very non-OO... now there is simply a virtual function returning the right value. I actually don't like this RTTI very much but in pcbnew there are some things that are plotted only on some kind of plotter (like the ps drill marks...)

I just don't get why the specialized conversion for portrait was added in the postscript engine... it just works out of the box without it (mirrored, too); I removed it but if there's really a good reason for it to stay just keep it... but I'd like to hear why, I simply can't figure out its purpose!

As a bonus I added the module name in the pick-and-place output file (just because it's useful and a fabricator asked me to...).

The question of thick lines in DXF: historically there was no pen width
recorded, it was the pen table assigned which determined it (like, color 3 had
a 0.25 mm pen assigned) i.e. a plot only issue.

Newer release (IIRC about from 2004) added the pen size as entity attribute
(group code 370) but it is limited to about 2.1 mm (that's right, you can't use
a 2.5mm pen in autocad :P). This is clearly not acceptable, because I often
have track of 6mm or more... also newer releases *can* round the line ends, but
only for available lineweight (so it's not useful)...

An interesting approach is shown here: http://www.artwork.com/acad/pcb_app/pcb.htm

For (filled) tracks we could just use lwpolys with the right width. The only
problem is that these would have butt ends. Then we could a) just don't care
about them (since a DXF couldn't be used for fabrication anyway) or b) add a
donut at each end. This should give a pretty good approximation for tracks.

The real issue is that the DXF format isn't really suited for representing
filled/thick entities... IIRC the only available entities are the polyline, the
donut, the solid and the trace. Of these only the polyline would be probably
imported by some other cad system (the other three are really rare in the
wild...). OK, actually there *is* a better entity (the region) but it's a
binary blob so isn't portable...

Any comments on how to handle these?

-- 
Lorenzo Marcantonio
Logos Srl
=== modified file 'common/class_plotter.cpp'
--- common/class_plotter.cpp	2012-04-27 10:52:50 +0000
+++ common/class_plotter.cpp	2012-04-29 08:06:32 +0000
@@ -21,9 +21,8 @@
 #include <class_base_screen.h>
 #include <drawtxt.h>
 
-PLOTTER::PLOTTER( PlotFormat aPlotType )
+PLOTTER::PLOTTER( )
 {
-    m_PlotType = aPlotType;
     plot_scale = 1;
     default_pen_width = 0;
     current_pen_width = -1;     /* To-be-set marker */
@@ -36,25 +35,23 @@
 
 
 /* Modifies coordinates pos.x and pos.y trace according to the orientation,
- * scale factor, and offsets trace
- * IMPORTANT: there is a special case for portrait handling in the
- * Postscript specialization (more or less the same with the coordinates
- * swapped), keep it in sync with this!
+ * scale factor, and offsets trace. Also convert from a wxPoint to DPOINT,
+ * since some output engines needs floating point coordinates.
  */
-void PLOTTER::user_to_device_coordinates( wxPoint& pos )
+void PLOTTER::user_to_device_coordinates( const wxPoint& pos, DPOINT& out )
 {
-    pos.x = (int) ( (pos.x - plot_offset.x) * plot_scale * device_scale );
+    out.x = (pos.x - plot_offset.x) * plot_scale * device_scale;
 
     if( plotMirror )
-        pos.y = (int) ( ( pos.y - plot_offset.y ) * plot_scale * device_scale );
+        out.y = ( pos.y - plot_offset.y ) * plot_scale * device_scale ;
     else
-        pos.y = (int) ( ( paper_size.y - ( pos.y - plot_offset.y )
-                          * plot_scale ) * device_scale );
+        out.y = ( paper_size.y - ( pos.y - plot_offset.y )
+                          * plot_scale ) * device_scale ;
 }
 
 
 /* Generic arc rendered as a polyline */
-void PLOTTER::arc( wxPoint centre, int StAngle, int EndAngle, int radius,
+void PLOTTER::arc( const wxPoint& centre, int StAngle, int EndAngle, int radius,
                    FILL_T fill, int width )
 {
     wxPoint   start, end;
@@ -86,10 +83,10 @@
 
 
 /* Modifies size size.x and size.y trace according to the scale factor. */
-void PLOTTER::user_to_device_size( wxSize& size )
+void PLOTTER::user_to_device_size( const wxSize& size, DPOINT& out )
 {
-    size.x = (int) ( size.x * plot_scale * device_scale );
-    size.y = (int) ( size.y * plot_scale * device_scale );
+    out.x = size.x * plot_scale * device_scale;
+    out.y = size.y * plot_scale * device_scale;
 }
 
 
@@ -254,7 +251,7 @@
 
 
 /* Convert a thick segment and plot it as an oval */
-void PLOTTER::segment_as_oval( wxPoint start, wxPoint end, int width,
+void PLOTTER::segment_as_oval( const wxPoint& start, const wxPoint& end, int width,
                                EDA_DRAW_MODE_T tracemode )
 {
     wxPoint center( (start.x + end.x) / 2, (start.y + end.y) / 2 );
@@ -276,12 +273,13 @@
 }
 
 
-void PLOTTER::sketch_oval( wxPoint pos, wxSize size, int orient,
+void PLOTTER::sketch_oval( const wxPoint& pos, const wxSize& aSize, int orient,
                            int width )
 {
     set_current_line_width( width );
     width = current_pen_width;
     int radius, deltaxy, cx, cy;
+    wxSize size( aSize );
 
     if( size.x > size.y )
     {
@@ -328,7 +326,7 @@
 
 /* Plot 1 segment like a track segment
  */
-void PLOTTER::thick_segment( wxPoint start, wxPoint end, int width,
+void PLOTTER::thick_segment( const wxPoint& start, const wxPoint& end, int width,
                              EDA_DRAW_MODE_T tracemode )
 {
     switch( tracemode )
@@ -348,7 +346,7 @@
 }
 
 
-void PLOTTER::thick_arc( wxPoint centre, int StAngle, int EndAngle, int radius,
+void PLOTTER::thick_arc( const wxPoint& centre, int StAngle, int EndAngle, int radius,
                          int width, EDA_DRAW_MODE_T tracemode )
 {
     switch( tracemode )
@@ -373,7 +371,7 @@
 }
 
 
-void PLOTTER::thick_rect( wxPoint p1, wxPoint p2, int width,
+void PLOTTER::thick_rect( const wxPoint& p1, const wxPoint& p2, int width,
                           EDA_DRAW_MODE_T tracemode )
 {
     switch( tracemode )
@@ -388,22 +386,22 @@
 
     case SKETCH:
         set_current_line_width( -1 );
-        p1.x -= (width - current_pen_width) / 2;
-        p1.y -= (width - current_pen_width) / 2;
-        p2.x += (width - current_pen_width) / 2;
-        p2.y += (width - current_pen_width) / 2;
-        rect( p1, p2, NO_FILL, -1 );
-        p1.x += (width - current_pen_width);
-        p1.y += (width - current_pen_width);
-        p2.x -= (width - current_pen_width);
-        p2.y -= (width - current_pen_width);
-        rect( p1, p2, NO_FILL, -1 );
+        wxPoint offsetp1( p1.x - (width - current_pen_width) / 2,
+                          p1.y - (width - current_pen_width) / 2 );
+        wxPoint offsetp2( p2.x + (width - current_pen_width) / 2,
+			  p2.y + (width - current_pen_width) / 2 );
+        rect( offsetp1, offsetp2, NO_FILL, -1 );
+        offsetp1.x += (width - current_pen_width);
+        offsetp1.y += (width - current_pen_width);
+        offsetp2.x -= (width - current_pen_width);
+        offsetp2.y -= (width - current_pen_width);
+        rect( offsetp1, offsetp2, NO_FILL, -1 );
         break;
     }
 }
 
 
-void PLOTTER::thick_circle( wxPoint pos, int diametre, int width,
+void PLOTTER::thick_circle( const wxPoint& pos, int diametre, int width,
                             EDA_DRAW_MODE_T tracemode )
 {
     switch( tracemode )

=== modified file 'common/common_plotDXF_functions.cpp'
--- common/common_plotDXF_functions.cpp	2012-04-27 10:52:50 +0000
+++ common/common_plotDXF_functions.cpp	2012-04-28 19:57:44 +0000
@@ -21,7 +21,7 @@
  * @param aScale = coordinate scale (scale coefficient for coordinates)
  * @param aMirror = Mirror plot if true.
  */
-void DXF_PLOTTER::set_viewport( wxPoint aOffset, double aIusPerDecimil,
+void DXF_PLOTTER::set_viewport( const wxPoint& aOffset, double aIusPerDecimil,
 	double aScale, bool aMirror )
 {
     wxASSERT( !output_file );
@@ -90,7 +90,7 @@
 }
 
 
-void DXF_PLOTTER::rect( wxPoint p1, wxPoint p2, FILL_T fill, int width )
+void DXF_PLOTTER::rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width )
 {
     wxASSERT( output_file );
     move_to( p1 );
@@ -101,30 +101,33 @@
 }
 
 
-void DXF_PLOTTER::circle( wxPoint centre, int diameter, FILL_T fill, int width )
+void DXF_PLOTTER::circle( const wxPoint& centre, int diameter, FILL_T fill, int width )
 {
     wxASSERT( output_file );
     double radius = user_to_device_size( diameter / 2 );
-    user_to_device_coordinates( centre );
+    DPOINT centre_dev;
+    user_to_device_coordinates( centre, centre_dev );
     if( radius > 0 )
     {
         wxString cname = ColorRefs[current_color].m_Name;
         if (!fill) {
-          fprintf( output_file, "0\nCIRCLE\n8\n%s\n10\n%d.0\n20\n%d.0\n40\n%g\n",
+          fprintf( output_file, "0\nCIRCLE\n8\n%s\n10\n%g\n20\n%g\n40\n%g\n",
                   TO_UTF8( cname ),
-                  centre.x, centre.y, radius );
+                  centre_dev.x, centre_dev.y, radius );
         }
         if (fill == FILLED_SHAPE) {
-            int r = (int)(radius*0.5);
+            double r = radius*0.5;
             fprintf( output_file, "0\nPOLYLINE\n");
             fprintf( output_file, "8\n%s\n66\n1\n70\n1\n", TO_UTF8( cname ));
-            fprintf( output_file, "40\n%g\n41\n%g\n", radius,radius);
-            fprintf( output_file, "0\nVERTEX\n8\n%s\n", TO_UTF8( cname ));
-            fprintf( output_file, "10\n%d.0\n 20\n%d.0\n42\n1.0\n", centre.x-r,centre.y);
-            fprintf( output_file, "0\nVERTEX\n8\n%s\n", TO_UTF8( cname ));
-            fprintf( output_file, "10\n%d.0\n 20\n%d.0\n42\n1.0\n", centre.x+r,centre.y);
+            fprintf( output_file, "40\n%g\n41\n%g\n", radius, radius);
+            fprintf( output_file, "0\nVERTEX\n8\n%s\n", TO_UTF8( cname ));
+            fprintf( output_file, "10\n%g\n 20\n%g\n42\n1.0\n", 
+		     centre_dev.x-r, centre_dev.y );
+            fprintf( output_file, "0\nVERTEX\n8\n%s\n", TO_UTF8( cname ));
+            fprintf( output_file, "10\n%g\n 20\n%g\n42\n1.0\n", 
+	             centre_dev.x+r, centre_dev.y );
             fprintf( output_file, "0\nSEQEND\n");
-    }
+	}
      }
 }
 
@@ -133,7 +136,8 @@
  * nb = number of coord (coord 1 = 2 elements: X and Y table)
  * aFill: if != 0 filled polygon
  */
-void DXF_PLOTTER::PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth)
+void DXF_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList, 
+                            FILL_T aFill, int aWidth)
 {
     if( aCornerList.size() <= 1 )
         return;
@@ -162,14 +166,14 @@
  * param aScaleFactor = the scale factor to apply to the bitmap size
  *                      (this is not the plot scale factor)
  */
-void DXF_PLOTTER::PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor )
+void DXF_PLOTTER::PlotImage( wxImage & aImage, const wxPoint& aPos, double aScaleFactor )
 {
     wxSize size;
     size.x = aImage.GetWidth();
     size.y = aImage.GetHeight();
 
-    size.x = KiROUND( size.x * aScaleFactor );
-    size.y = KiROUND( size.y * aScaleFactor );
+    size.x = size.x * aScaleFactor;
+    size.y = size.y * aScaleFactor;
 
     wxPoint start = aPos;
     start.x -= size.x / 2;
@@ -190,22 +194,24 @@
  * Unit to unit DRAWING
  * If pen = 'Z' without lifting pen displacement
  */
-void DXF_PLOTTER::pen_to( wxPoint pos, char plume )
+void DXF_PLOTTER::pen_to( const wxPoint& pos, char plume )
 {
     wxASSERT( output_file );
     if( plume == 'Z' )
     {
         return;
     }
-    user_to_device_coordinates( pos );
+    DPOINT pos_dev, pen_lastpos_dev;
+    user_to_device_coordinates( pos, pos_dev );
+    user_to_device_coordinates( pen_lastpos, pen_lastpos_dev );
 
     if( pen_lastpos != pos && plume == 'D' )
     {
         /* DXF LINE */
         wxString cname = ColorRefs[current_color].m_Name;
-        fprintf( output_file, "0\nLINE\n8\n%s\n10\n%d.0\n20\n%d.0\n11\n%d.0\n21\n%d.0\n",
+        fprintf( output_file, "0\nLINE\n8\n%s\n10\n%g\n20\n%g\n11\n%g\n21\n%g\n",
                  TO_UTF8( cname ),
-                 pen_lastpos.x, pen_lastpos.y, pos.x, pos.y );
+                 pen_lastpos_dev.x, pen_lastpos_dev.y, pos_dev.x, pos_dev.y );
     }
     pen_lastpos = pos;
 }
@@ -225,7 +231,7 @@
  * @param aWidth = segment width (thickness)
  * @param aPlotMode = FILLED, SKETCH ..
  */
-void DXF_PLOTTER::thick_segment( wxPoint aStart, wxPoint aEnd, int aWidth,
+void DXF_PLOTTER::thick_segment( const wxPoint& aStart, const wxPoint& aEnd, int aWidth,
                                  EDA_DRAW_MODE_T aPlotMode )
 {
     if( aPlotMode == LINE )  /* just a line is Ok */
@@ -245,7 +251,7 @@
  * StAngle, EndAngle = angle of beginning and end
  * Radius = radius of the arc
  */
-void DXF_PLOTTER::arc( wxPoint centre, int StAngle, int EndAngle, int radius,
+void DXF_PLOTTER::arc( const wxPoint& centre, int StAngle, int EndAngle, int radius,
                        FILL_T fill, int width )
 {
     wxASSERT( output_file );
@@ -253,24 +259,26 @@
     if( radius <= 0 )
         return;
 
-    user_to_device_coordinates( centre );
-    radius = KiROUND( user_to_device_size( radius ) );
+    DPOINT centre_dev;
+    user_to_device_coordinates( centre, centre_dev );
+    double radius_dev = user_to_device_size( radius );
 
     /* DXF ARC */
     wxString cname = ColorRefs[current_color].m_Name;
     fprintf( output_file,
-             "0\nARC\n8\n%s\n10\n%d.0\n20\n%d.0\n40\n%d.0\n50\n%d.0\n51\n%d.0\n",
+             "0\nARC\n8\n%s\n10\n%g\n20\n%g\n40\n%g\n50\n%g\n51\n%g\n",
              TO_UTF8( cname ),
-             centre.x, centre.y, radius,
-             StAngle / 10, EndAngle / 10 );
+             centre_dev.x, centre_dev.y, radius_dev,
+             StAngle / 10.0, EndAngle / 10.0 );
 }
 
 
 /* Plot oval pad at position. */
-void DXF_PLOTTER::flash_pad_oval( wxPoint pos, wxSize size, int orient,
+void DXF_PLOTTER::flash_pad_oval( const wxPoint& pos, const wxSize& aSize, int orient,
                                   EDA_DRAW_MODE_T trace_mode )
 {
     wxASSERT( output_file );
+    wxSize size( aSize );
 
     /* The chip is reduced to an oval tablet with size.y > size.x
      * (Oval vertical orientation 0) */
@@ -286,7 +294,7 @@
 
 
 /* Plot round pad or via. */
-void DXF_PLOTTER::flash_pad_circle( wxPoint pos, int diametre,
+void DXF_PLOTTER::flash_pad_circle( const wxPoint& pos, int diametre,
                                     EDA_DRAW_MODE_T trace_mode )
 {
     wxASSERT( output_file );
@@ -297,7 +305,7 @@
 /*
  * Plot rectangular pad vertical or horizontal (rectangular Pad)
  */
-void DXF_PLOTTER::flash_pad_rect( wxPoint pos, wxSize padsize,
+void DXF_PLOTTER::flash_pad_rect( const wxPoint& pos, const wxSize& padsize,
                                   int orient, EDA_DRAW_MODE_T trace_mode )
 {
     wxASSERT( output_file );
@@ -367,7 +375,7 @@
  * Orientation aPadOrient in 0.1 degrees
  * Plot mode = FILLED, SKETCH (unused)
  */
-void DXF_PLOTTER::flash_pad_trapez( wxPoint aPadPos, wxPoint aCorners[4],
+void DXF_PLOTTER::flash_pad_trapez( const wxPoint& aPadPos, const wxPoint *aCorners,
                                     int aPadOrient, EDA_DRAW_MODE_T aTrace_Mode )
 {
     wxASSERT( output_file );

=== modified file 'common/common_plotGERBER_functions.cpp'
--- common/common_plotGERBER_functions.cpp	2012-04-27 10:52:50 +0000
+++ common/common_plotGERBER_functions.cpp	2012-04-29 06:48:31 +0000
@@ -24,7 +24,7 @@
  * @param aScale = coordinate scale (scale coefficient for coordinates)
  * @param aMirror = Mirror plot if true.
  */
-void GERBER_PLOTTER::set_viewport( wxPoint aOffset, double aIusPerDecimil,
+void GERBER_PLOTTER::set_viewport( const wxPoint& aOffset, double aIusPerDecimil,
 	double aScale, bool aMirror )
 {
     wxASSERT( !output_file );
@@ -41,6 +41,17 @@
     set_default_line_width( 100 * aIusPerDecimil ); // Arbitrary default
 }
 
+/**
+ * Emit a D-Code record, using proper conversions
+ * to format a leading zero omitted gerber coordinate 
+ * (for 4 decimal positions, see header generation in start_plot
+ */
+void GERBER_PLOTTER::emit_dcode( const DPOINT& pt, int dcode )
+{
+
+    fprintf( output_file, "X%dY%dD%02d*\n", 
+	    int( pt.x ), int( pt.y ), dcode );
+}
 
 /**
  * Function start_plot
@@ -67,14 +78,15 @@
     fprintf( output_file, "G04 (created by %s) date %s*\n",
              TO_UTF8( Title ), TO_UTF8( DateAndTime() ) );
 
-    // Specify linear interpol (G01), unit = INCH (G70), abs format (G90):
-    fputs( "G01*\nG70*\nG90*\n", output_file );
-    fputs( "%MOIN*%\n", output_file );     // set unites = INCHES
+    /* Mass parameter: unit = INCHES */
+    fputs( "%MOIN*%\n", output_file );
 
-    /* Set gerber format to 3.4 */
+    /* Set coordinate format to 3.4 absolute, leading zero omitted */
     fputs( "G04 Gerber Fmt 3.4, Leading zero omitted, Abs format*\n%FSLAX34Y34*%\n",
            output_file );
 
+    /* Specify linear interpol (G01), unit = INCH (G70), abs format (G90) */
+    fputs( "G01*\nG70*\nG90*\n", output_file );
     fputs( "G04 APERTURE LIST*\n", output_file );
     /* Select the default aperture */
     set_current_line_width( -1 );
@@ -90,11 +102,10 @@
 
     wxASSERT( output_file );
 
-    /* Outfile is actually a temporary file! */
+    /* Outfile is actually a temporary file i.e. work_file */
     fputs( "M02*\n", output_file );
     fflush( output_file );
 
-//    rewind( work_file ); // work_file == output_file !!!
     fclose( work_file );
     work_file   = wxFopen( m_workFilename, wxT( "rt" ));
     wxASSERT( work_file );
@@ -211,20 +222,22 @@
         switch( tool->type )
         {
         case APERTURE::Circle:
-            sprintf( text, "C,%f*%%\n", tool->size.x * fscale );
+            sprintf( text, "C,%g*%%\n", tool->size.x * fscale );
             break;
 
         case APERTURE::Rect:
-            sprintf( text, "R,%fX%f*%%\n", tool->size.x * fscale,
+            sprintf( text, "R,%gX%g*%%\n", 
+	             tool->size.x * fscale,
                      tool->size.y * fscale );
             break;
 
         case APERTURE::Plotting:
-            sprintf( text, "C,%f*%%\n", tool->size.x * fscale );
+            sprintf( text, "C,%g*%%\n", tool->size.x * fscale );
             break;
 
         case APERTURE::Oval:
-            sprintf( text, "O,%fX%f*%%\n", tool->size.x * fscale, 
+            sprintf( text, "O,%gX%g*%%\n", 
+	            tool->size.x * fscale, 
 		    tool->size.y * fscale );
             break;
         }
@@ -234,10 +247,11 @@
 }
 
 
-void GERBER_PLOTTER::pen_to( wxPoint aPos, char plume )
+void GERBER_PLOTTER::pen_to( const wxPoint& aPos, char plume )
 {
     wxASSERT( output_file );
-    user_to_device_coordinates( aPos );
+    DPOINT pos_dev;
+    user_to_device_coordinates( aPos, pos_dev );
 
     switch( plume )
     {
@@ -245,18 +259,18 @@
         break;
 
     case 'U':
-        fprintf( output_file, "X%5.5dY%5.5dD02*\n", aPos.x, aPos.y );
+	emit_dcode( pos_dev, 2 );
         break;
 
     case 'D':
-        fprintf( output_file, "X%5.5dY%5.5dD01*\n", aPos.x, aPos.y );
+	emit_dcode( pos_dev, 1 );
     }
 
     pen_state = plume;
 }
 
 
-void GERBER_PLOTTER::rect( wxPoint p1, wxPoint p2, FILL_T fill, int width )
+void GERBER_PLOTTER::rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width )
 {
     static std::vector< wxPoint > cornerList;
     cornerList.clear();
@@ -285,7 +299,7 @@
  * not used here: circles are always not filled the gerber. Filled circles are flashed
  * @param aWidth = line width
  */
-void GERBER_PLOTTER::circle( wxPoint aCentre, int aDiameter, FILL_T aFill, int aWidth )
+void GERBER_PLOTTER::circle( const wxPoint& aCentre, int aDiameter, FILL_T aFill, int aWidth )
 {
     wxASSERT( output_file );
     wxPoint   start, end;
@@ -315,7 +329,8 @@
  * @param aFill = plot option (NO_FILL, FILLED_SHAPE, FILLED_WITH_BG_BODYCOLOR)
  * @param aWidth = Width of the line to plot.
  */
-void GERBER_PLOTTER::PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth )
+void GERBER_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList, 
+                               FILL_T aFill, int aWidth )
 {
     if( aCornerList.size() <= 1 )
         return;
@@ -353,7 +368,7 @@
  * param aScaleFactor = the scale factor to apply to the bitmap size
  *                      (this is not the plot scale factor)
  */
-void GERBER_PLOTTER::PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor )
+void GERBER_PLOTTER::PlotImage( wxImage & aImage, const wxPoint& aPos, double aScaleFactor )
 {
     wxSize size;
     size.x = aImage.GetWidth();
@@ -377,7 +392,7 @@
 /* Function flash_pad_circle
  * Plot a circular pad or via at the user position pos
  */
-void GERBER_PLOTTER::flash_pad_circle( wxPoint pos, int diametre, EDA_DRAW_MODE_T trace_mode )
+void GERBER_PLOTTER::flash_pad_circle( const wxPoint& pos, int diametre, EDA_DRAW_MODE_T trace_mode )
 {
     wxASSERT( output_file );
     wxSize size( diametre, diametre );
@@ -391,9 +406,10 @@
         break;
 
     case FILLED:
-        user_to_device_coordinates( pos );
+	DPOINT pos_dev;
+        user_to_device_coordinates( pos, pos_dev );
         select_aperture( size, APERTURE::Circle );
-        fprintf( output_file, "X%5.5dY%5.5dD03*\n", pos.x, pos.y );
+	emit_dcode( pos_dev, 3 );
         break;
     }
 }
@@ -405,11 +421,12 @@
  * For a vertical or horizontal orientation, the shape is flashed
  * For any orientation the shape is drawn as a segment
  */
-void GERBER_PLOTTER::flash_pad_oval( wxPoint pos, wxSize size, int orient,
+void GERBER_PLOTTER::flash_pad_oval( const wxPoint& pos, const wxSize& aSize, int orient,
                                      EDA_DRAW_MODE_T trace_mode )
 {
     wxASSERT( output_file );
     int x0, y0, x1, y1, delta;
+    wxSize size( aSize );
 
     /* Plot a flashed shape. */
     if( ( orient == 0 || orient == 900 || orient == 1800 || orient == 2700 )
@@ -417,10 +434,11 @@
     {
         if( orient == 900 || orient == 2700 ) /* orientation turned 90 deg. */
             EXCHG( size.x, size.y );
-
-        user_to_device_coordinates( pos );
+	
+	DPOINT pos_dev;
+        user_to_device_coordinates( pos, pos_dev );
         select_aperture( size, APERTURE::Oval );
-        fprintf( output_file, "X%5.5dY%5.5dD03*\n", pos.x, pos.y );
+	emit_dcode( pos_dev, 3 );
     }
     else /* Plot pad as a segment. */
     {
@@ -436,6 +454,7 @@
 
         if( trace_mode == FILLED )
         {
+	    /* XXX to do: use an aperture macro to declare the rotated pad */
             /* The pad  is reduced to an oval with dy > dx */
             delta = size.y - size.x;
             x0    = 0;
@@ -462,17 +481,18 @@
  * it is flashed.
  * For others shape the direction is plotted as a polygon.
  */
-void GERBER_PLOTTER::flash_pad_rect( wxPoint pos, wxSize size,
+void GERBER_PLOTTER::flash_pad_rect( const wxPoint& pos, const wxSize& aSize,
                                      int orient, EDA_DRAW_MODE_T trace_mode )
 
 {
     wxASSERT( output_file );
+    wxSize size( aSize );
 
     /* Plot as flashed. */
     switch( orient )
     {
     case 900:
-    case 2700:        /* rotation of 90 degrees or 270 returns dimensions */
+    case 2700:        /* rotation of 90 degrees or 270 swaps dimensions */
         EXCHG( size.x, size.y );
 
     // Pass through
@@ -491,9 +511,10 @@
             break;
 
         case FILLED:
-            user_to_device_coordinates( pos );
+	    DPOINT pos_dev;
+            user_to_device_coordinates( pos, pos_dev );
             select_aperture( size, APERTURE::Rect );
-            fprintf( output_file, "X%5.5dY%5.5dD03*\n", pos.x, pos.y );
+	    emit_dcode( pos_dev, 3 );
             break;
         }
 
@@ -501,6 +522,7 @@
 
     default: /* plot pad shape as polygon */
     {
+	/* XXX to do: use an aperture macro to declare the rotated pad */
         wxPoint coord[4];
         // coord[0] is assumed the lower left
         // coord[1] is assumed the upper left
@@ -529,10 +551,11 @@
  * Orientation aPadOrient in 0.1 degrees
  * Plot mode  = FILLED or SKETCH
  */
- void GERBER_PLOTTER::flash_pad_trapez( wxPoint aPadPos,  wxPoint aCorners[4],
+ void GERBER_PLOTTER::flash_pad_trapez( const wxPoint& aPadPos,  const wxPoint* aCorners,
                                         int aPadOrient, EDA_DRAW_MODE_T aTrace_Mode )
 
 {
+    /* XXX to do: use an aperture macro to declare the pad */
     // polygon corners list
     static std::vector< wxPoint > cornerList;
     cornerList.clear();
@@ -555,7 +578,10 @@
     PlotPoly( cornerList, aTrace_Mode==FILLED ? FILLED_SHAPE : NO_FILL );
 }
 
-
+/** 
+ * Change the plot polarity and begin a new layer
+ * Used to 'scratch off' silk screen away from solder mask
+ */
 void GERBER_PLOTTER::SetLayerPolarity( bool aPositive )
 {
     if( aPositive )

=== modified file 'common/common_plotHPGL_functions.cpp'
--- common/common_plotHPGL_functions.cpp	2012-04-27 10:52:50 +0000
+++ common/common_plotHPGL_functions.cpp	2012-04-28 19:56:48 +0000
@@ -24,7 +24,7 @@
  * @param aScale = coordinate scale (scale coefficient for coordinates)
  * @param aMirror = Mirror plot if true.
  */
-void HPGL_PLOTTER::set_viewport( wxPoint aOffset, double aIusPerDecimil,
+void HPGL_PLOTTER::set_viewport( const wxPoint& aOffset, double aIusPerDecimil,
 	double aScale, bool aMirror )
 {
     wxASSERT( !output_file );
@@ -59,17 +59,18 @@
 }
 
 
-void HPGL_PLOTTER::rect( wxPoint p1, wxPoint p2, FILL_T fill, int width )
+void HPGL_PLOTTER::rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width )
 {
     wxASSERT( output_file );
-    user_to_device_coordinates( p2 );
+    DPOINT p2dev;
+    user_to_device_coordinates( p2, p2dev );
     move_to( p1 );
-    fprintf( output_file, "EA %d,%d;\n", p2.x, p2.y );
+    fprintf( output_file, "EA %.0f,%.0f;\n", p2dev.x, p2dev.y );
     pen_finish();
 }
 
 
-void HPGL_PLOTTER::circle( wxPoint centre,
+void HPGL_PLOTTER::circle( const wxPoint& centre,
                            int     diameter,
                            FILL_T  fill,
                            int     width )
@@ -90,7 +91,8 @@
  * aCornerList = a wxPoint list of corner
  * aFill: if != 0 filled polygon
  */
-void HPGL_PLOTTER::PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth)
+void HPGL_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList, 
+                             FILL_T aFill, int aWidth)
 {
     if( aCornerList.size() <= 1 )
         return;
@@ -119,7 +121,7 @@
  * param aScaleFactor = the scale factor to apply to the bitmap size
  *                      (this is not the plot scale factor)
  */
-void HPGL_PLOTTER::PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor )
+void HPGL_PLOTTER::PlotImage( wxImage & aImage, const wxPoint& aPos, double aScaleFactor )
 {
     wxSize size;
     size.x = aImage.GetWidth();
@@ -180,7 +182,7 @@
  * Unit to unit DRAWING
  * If pen = 'Z' without changing pen during move.
  */
-void HPGL_PLOTTER::pen_to( wxPoint pos, char plume )
+void HPGL_PLOTTER::pen_to( const wxPoint& pos, char plume )
 {
     wxASSERT( output_file );
 
@@ -191,10 +193,11 @@
     }
 
     pen_control( plume );
-    user_to_device_coordinates( pos );
+    DPOINT pos_dev;
+    user_to_device_coordinates( pos, pos_dev );
 
     if( pen_lastpos != pos )
-        fprintf( output_file, "PA %d,%d;\n", pos.x, pos.y );
+        fprintf( output_file, "PA %.0f,%.0fd;\n", pos_dev.x, pos_dev.y );
 
     pen_lastpos = pos;
 }
@@ -217,7 +220,7 @@
  * @param width = segment width (thickness)
  * @param tracemode = FILLED, SKETCH ..
  */
-void HPGL_PLOTTER::thick_segment( wxPoint start, wxPoint end, int width, EDA_DRAW_MODE_T tracemode )
+void HPGL_PLOTTER::thick_segment( const wxPoint& start, const wxPoint& end, int width, EDA_DRAW_MODE_T tracemode )
 {
     wxASSERT( output_file );
     wxPoint center;
@@ -242,19 +245,18 @@
  * PU PY x, y; PD start_arc_X AA, start_arc_Y, angle, NbSegm; PU;
  * Or PU PY x, y; PD start_arc_X AA, start_arc_Y, angle, PU;
  */
-void HPGL_PLOTTER::arc( wxPoint centre, int StAngle, int EndAngle, int rayon,
+void HPGL_PLOTTER::arc( const wxPoint& centre, int StAngle, int EndAngle, int rayon,
                         FILL_T fill, int width )
 {
     wxASSERT( output_file );
     wxPoint cmap;
-    wxPoint cpos;
+    DPOINT centre_dev, cmap_dev;
     float   angle;
 
     if( rayon <= 0 )
         return;
 
-    cpos = centre;
-    user_to_device_coordinates( cpos );
+    user_to_device_coordinates( centre, centre_dev );
 
     if( plotMirror )
         angle = (StAngle - EndAngle) / 10.0;
@@ -263,15 +265,15 @@
     // Calculate start point,
     cmap.x = (int) ( centre.x + ( rayon * cos( StAngle * M_PI / 1800 ) ) );
     cmap.y = (int) ( centre.y - ( rayon * sin( StAngle * M_PI / 1800 ) ) );
-    user_to_device_coordinates( cmap );
+    user_to_device_coordinates( cmap, cmap_dev );
 
     fprintf( output_file,
-             "PU;PA %d,%d;PD;AA %d,%d, ",
-             cmap.x,
-             cmap.y,
-             cpos.x,
-             cpos.y );
-    fprintf( output_file, "%f", angle );
+             "PU;PA %.0f,%.0f;PD;AA %.0f,%.0f,",
+             cmap_dev.x,
+             cmap_dev.y,
+             centre_dev.x,
+             centre_dev.y );
+    fprintf( output_file, "%.0f", angle );
     fprintf( output_file, ";PU;\n" );
     pen_finish();
 }
@@ -279,11 +281,12 @@
 
 /* Plot oval pad.
  */
-void HPGL_PLOTTER::flash_pad_oval( wxPoint pos, wxSize size, int orient,
+void HPGL_PLOTTER::flash_pad_oval( const wxPoint& pos, const wxSize& aSize, int orient,
                                    EDA_DRAW_MODE_T trace_mode )
 {
     wxASSERT( output_file );
     int deltaxy, cx, cy;
+    wxSize size( aSize );
 
     /* The pad is reduced to an oval with size.y > size.x
      * (Oval vertical orientation 0)
@@ -318,13 +321,14 @@
 
 /* Plot round pad or via.
  */
-void HPGL_PLOTTER::flash_pad_circle( wxPoint pos, int diametre,
+void HPGL_PLOTTER::flash_pad_circle( const wxPoint& pos, int diametre,
                                      EDA_DRAW_MODE_T trace_mode )
 {
     wxASSERT( output_file );
     int rayon, delta;
 
-    user_to_device_coordinates( pos );
+    DPOINT pos_dev;
+    user_to_device_coordinates( pos, pos_dev );
 
     delta = KiROUND( pen_diameter - pen_overlap );
     rayon = diametre / 2;
@@ -338,11 +342,11 @@
     {
         rayon = 0;
     }
-    wxSize rsize( rayon, rayon );
-
-    user_to_device_size( rsize );
-
-    fprintf( output_file, "PA %d,%d;CI %d;\n", pos.x, pos.y, rsize.x );
+
+    double rsize = user_to_device_size( rayon );
+
+    fprintf( output_file, "PA %.0f,%.0fd;CI %.0f;\n", 
+             pos_dev.x, pos_dev.y, rsize );
 
     if( trace_mode == FILLED )        // Plot in filled mode.
     {
@@ -350,13 +354,12 @@
         {
             while( (rayon -= delta ) >= 0 )
             {
-                rsize.x = rsize.y = rayon;
-                user_to_device_size( rsize );
+                rsize = user_to_device_size( rayon );
                 fprintf( output_file,
-                         "PA %d,%d; CI %d;\n",
-                         pos.x,
-                         pos.y,
-                         rsize.x );
+                         "PA %.0f,%.0f;CI %.0f;\n",
+                         pos_dev.x,
+                         pos_dev.y,
+                         rsize );
             }
         }
     }
@@ -370,7 +373,7 @@
  * Gives its center and its dimensions X and Y
  * Units are user units
  */
-void HPGL_PLOTTER::flash_pad_rect( wxPoint pos, wxSize padsize,
+void HPGL_PLOTTER::flash_pad_rect( const wxPoint& pos, const wxSize& padsize,
                                    int orient, EDA_DRAW_MODE_T trace_mode )
 {
     wxASSERT( output_file );
@@ -488,7 +491,7 @@
  * Orientation aPadOrient in 0.1 degrees
  * Plot mode FILLED or SKETCH
  */
-void HPGL_PLOTTER::flash_pad_trapez( wxPoint aPadPos, wxPoint aCorners[4],
+void HPGL_PLOTTER::flash_pad_trapez( const wxPoint& aPadPos, const wxPoint *aCorners,
                                      int aPadOrient, EDA_DRAW_MODE_T aTrace_Mode )
 {
     wxASSERT( output_file );

=== modified file 'common/common_plotPS_functions.cpp'
--- common/common_plotPS_functions.cpp	2012-04-27 10:52:50 +0000
+++ common/common_plotPS_functions.cpp	2012-04-29 08:08:14 +0000
@@ -22,7 +22,7 @@
  * @param aScale = coordinate scale (scale coefficient for coordinates)
  * @param aMirror = Mirror plot if true.
  */
-void PS_PLOTTER::set_viewport( wxPoint aOffset, double aIusPerDecimil,
+void PS_PLOTTER::set_viewport( const wxPoint& aOffset, double aIusPerDecimil,
 	double aScale, bool aMirror )
 {
     wxASSERT( !output_file );
@@ -131,35 +131,34 @@
 }
 
 
-void PS_PLOTTER::rect( wxPoint p1, wxPoint p2, FILL_T fill, int width )
+void PS_PLOTTER::rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width )
 {
-    user_to_device_coordinates( p1 );
-    user_to_device_coordinates( p2 );
+    DPOINT p1_dev, p2_dev;
+    user_to_device_coordinates( p1, p1_dev );
+    user_to_device_coordinates( p2, p2_dev );
 
     set_current_line_width( width );
-    fprintf( output_file, "%d %d %d %d rect%d\n", p1.x, p1.y,
-             p2.x - p1.x, p2.y - p1.y, fill );
+    fprintf( output_file, "%g %g %g %g rect%d\n", p1_dev.x, p1_dev.y,
+             p2_dev.x - p1_dev.x, p2_dev.y - p1_dev.y, fill );
 }
 
 
-void PS_PLOTTER::circle( wxPoint pos, int diametre, FILL_T fill, int width )
+void PS_PLOTTER::circle( const wxPoint& pos, int diametre, FILL_T fill, int width )
 {
     wxASSERT( output_file );
-    user_to_device_coordinates( pos );
+    DPOINT pos_dev;
+    user_to_device_coordinates( pos, pos_dev );
     double radius = user_to_device_size( diametre / 2.0 );
 
-    if( radius < 1 )
-        radius = 1;
-
     set_current_line_width( width );
-    fprintf( output_file, "%d %d %g cir%d\n", pos.x, pos.y, radius, fill );
+    fprintf( output_file, "%g %g %g cir%d\n", pos_dev.x, pos_dev.y, radius, fill );
 }
 
 
 /* Plot an arc:
  * StAngle, EndAngle = start and end arc in 0.1 degree
  */
-void PS_PLOTTER::arc( wxPoint centre, int StAngle, int EndAngle, int radius,
+void PS_PLOTTER::arc( const wxPoint& centre, int StAngle, int EndAngle, int radius,
                       FILL_T fill, int width )
 {
     wxASSERT( output_file );
@@ -172,15 +171,16 @@
     set_current_line_width( width );
 
     // Calculate start point.
-    user_to_device_coordinates( centre );
-    radius = KiROUND( user_to_device_size( radius ) );
+    DPOINT centre_dev;
+    user_to_device_coordinates( centre, centre_dev );
+    double radius_dev = user_to_device_size( radius );
     if( plotMirror )
-        fprintf( output_file, "%d %d %d %g %g arc%d\n", centre.x, centre.y,
-                 radius, (double) -EndAngle / 10, (double) -StAngle / 10,
+        fprintf( output_file, "%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( output_file, "%d %d %d %g %g arc%d\n", centre.x, centre.y,
-                 radius, (double) StAngle / 10, (double) EndAngle / 10,
+        fprintf( output_file, "%g %g %g %g %g arc%d\n", centre_dev.x, centre_dev.y,
+                 radius_dev, StAngle / 10.0, EndAngle / 10.0,
                  fill );
 }
 
@@ -192,22 +192,22 @@
  * param aFill :if true : filled polygon
  * param aWidth = line width
  */
-void PS_PLOTTER::PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth )
+void PS_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList, 
+                           FILL_T aFill, int aWidth )
 {
     if( aCornerList.size() <= 1 )
         return;
 
     set_current_line_width( aWidth );
 
-    wxPoint pos = aCornerList[0];
-    user_to_device_coordinates( pos );
-    fprintf( output_file, "newpath\n%d %d moveto\n", pos.x, pos.y );
+    DPOINT pos;
+    user_to_device_coordinates( aCornerList[0], pos );
+    fprintf( output_file, "newpath\n%g %g moveto\n", pos.x, pos.y );
 
     for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
     {
-        pos = aCornerList[ii];
-        user_to_device_coordinates( pos );
-        fprintf( output_file, "%d %d lineto\n", pos.x, pos.y );
+        user_to_device_coordinates( aCornerList[ii], pos );
+        fprintf( output_file, "%g %g lineto\n", pos.x, pos.y );
     }
 
     // Close path
@@ -223,14 +223,13 @@
  * param aScaleFactor = the scale factor to apply to the bitmap size
  *                      (this is not the plot scale factor)
  */
-void PS_PLOTTER::PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor )
+void PS_PLOTTER::PlotImage( wxImage & aImage, const wxPoint& aPos, double aScaleFactor )
 {
     wxSize pix_size;                // size of the bitmap in pixels
     pix_size.x = aImage.GetWidth();
     pix_size.y = aImage.GetHeight();
-    wxSize drawsize;                // requested size of image
-    drawsize.x = KiROUND( aScaleFactor * pix_size.x );
-    drawsize.y = KiROUND( aScaleFactor * pix_size.y );
+    DPOINT drawsize( aScaleFactor * pix_size.x,
+                     aScaleFactor * pix_size.y ); // requested size of image
 
     // calculate the bottom left corner position of bitmap
     wxPoint start = aPos;
@@ -247,12 +246,13 @@
     fprintf( output_file, "/greys %d string def\n", pix_size.x );
 
     // Locate lower-left corner of image
-    user_to_device_coordinates( start );
-    fprintf( output_file, "%d %d translate\n", start.x, start.y );
+    DPOINT start_dev, end_dev;
+    user_to_device_coordinates( start, start_dev );
+    fprintf( output_file, "%g %g translate\n", start_dev.x, start_dev.y );
     // Map image size to device
-    user_to_device_coordinates( end );
-    fprintf( output_file, "%d %d scale\n",
-            ABS(end.x - start.x), ABS(end.y - start.y));
+    user_to_device_coordinates( end, end_dev );
+    fprintf( output_file, "%g %g scale\n",
+            ABS(end_dev.x - start_dev.x), ABS(end_dev.y - start_dev.y));
 
     // Dimensions of source image (in pixels
     fprintf( output_file, "%d %d 8", pix_size.x, pix_size.y );
@@ -287,7 +287,7 @@
 
 /* Routine to draw to a new position
  */
-void PS_PLOTTER::pen_to( wxPoint pos, char plume )
+void PS_PLOTTER::pen_to( const wxPoint& pos, char plume )
 {
     wxASSERT( output_file );
     if( plume == 'Z' )
@@ -302,17 +302,20 @@
         return;
     }
 
-    user_to_device_coordinates( pos );
     if( pen_state == 'Z' )
     {
         fputs( "newpath\n", output_file );
     }
     if( pen_state != plume || pos != pen_lastpos )
+    {
+	DPOINT pos_dev;
+	user_to_device_coordinates( pos, pos_dev );
         fprintf( output_file,
-                 "%d %d %sto\n",
-                 pos.x,
-                 pos.y,
+                 "%g %g %sto\n",
+                 pos_dev.x,
+                 pos_dev.y,
                  ( plume=='D' ) ? "line" : "move" );
+    }
     pen_state   = plume;
     pen_lastpos = pos;
 }
@@ -442,12 +445,7 @@
         fputs( PSMacro[ii], output_file );
     }
 
-    // (If support for creating postscript files with a portrait orientation
-    // is ever provided, determine whether it would be necessary to provide
-    // an "else" command and then an appropriate "sprintf" command here.)
-    // XXX indeed it would remove the ugly virtual override for 
-    // user_to_device_coordinates
-
+    /* Rototranslate the coordinate to achieve the landscape layout */
     if( !pageInfo.IsPortrait() )
         fprintf( output_file, "%d 0 translate 90 rotate\n", 10 * psPaperSize.x );
 
@@ -481,11 +479,12 @@
  * Orient Orient
  * The shape is drawn as a segment
  */
-void PS_PLOTTER::flash_pad_oval( wxPoint pos, wxSize size, int orient,
+void PS_PLOTTER::flash_pad_oval( const wxPoint& pos, const wxSize& aSize, int orient,
                                  EDA_DRAW_MODE_T modetrace )
 {
     wxASSERT( output_file );
     int x0, y0, x1, y1, delta;
+    wxSize size( aSize );
 
     // The pad is reduced to an oval by dy > dx
     if( size.x > size.y )
@@ -514,7 +513,7 @@
 
 /* Plot round pad or via.
  */
-void PS_PLOTTER::flash_pad_circle( wxPoint pos, int diametre,
+void PS_PLOTTER::flash_pad_circle( const wxPoint& pos, int diametre,
                                    EDA_DRAW_MODE_T modetrace )
 {
     int current_line_width;
@@ -536,10 +535,11 @@
 
 /* Plot rectangular pad in any orientation.
  */
-void PS_PLOTTER::flash_pad_rect( wxPoint pos, wxSize size,
+void PS_PLOTTER::flash_pad_rect( const wxPoint& pos, const wxSize& aSize,
                                  int orient, EDA_DRAW_MODE_T trace_mode )
 {
     static std::vector< wxPoint > cornerList;
+    wxSize size( aSize );
     cornerList.clear();
 
     set_current_line_width( -1 );
@@ -584,7 +584,7 @@
  * Orientation aPadOrient in 0.1 degrees
  * Plot mode FILLED or SKETCH
  */
-void PS_PLOTTER::flash_pad_trapez( wxPoint aPadPos, wxPoint aCorners[4],
+void PS_PLOTTER::flash_pad_trapez( const wxPoint& aPadPos, const wxPoint *aCorners,
                                    int aPadOrient, EDA_DRAW_MODE_T aTrace_Mode )
 {
     static std::vector< wxPoint > cornerList;
@@ -628,21 +628,3 @@
     PlotPoly( cornerList, ( aTrace_Mode == FILLED ) ? FILLED_SHAPE : NO_FILL );
 }
 
-
-void PS_PLOTTER::user_to_device_coordinates( wxPoint& pos )
-{
-    if( pageInfo.IsPortrait() )
-    {
-        pos.y = (int) ( ( paper_size.y - ( pos.y - plot_offset.y )
-                        * plot_scale ) * device_scale );
-
-        if( plotMirror )
-            pos.x = (int) ( ( paper_size.x - ( pos.x - plot_offset.x )
-                          * plot_scale ) * device_scale );
-        else
-            pos.x = (int) ( (pos.x - plot_offset.x) * plot_scale * device_scale );
-    }
-    else
-        PLOTTER::user_to_device_coordinates( pos );
-}
-

=== modified file 'include/plot_common.h'
--- include/plot_common.h	2012-04-27 10:52:50 +0000
+++ include/plot_common.h	2012-04-29 08:06:06 +0000
@@ -1,6 +1,6 @@
 /**
  * Common plot library \n
- * Plot settings, postscript plotting, gerber plotting.
+ * Plot settings, and plotting engines (Postscript, Gerber, HPGL and DXF)
  *
  * @file plot_common.h
  */
@@ -9,6 +9,7 @@
 #define PLOT_COMMON_H_
 
 #include <vector>
+#include <vector2d.h>
 #include <drawtxt.h>
 #include <common.h>         // PAGE_INFO
 #include <eda_text.h>       // FILL_T
@@ -26,10 +27,16 @@
 };
 
 
+/**
+ * Base plotter engine class. General rule: all the interface with the caller
+ * is done in IU, the IU size is specified with set_viewport. Internal and
+ * output processing is done in decimils (or whatever unit the effective engine
+ * need to use)
+ */
 class PLOTTER
 {
 public:
-    PLOTTER( PlotFormat aPlotType );
+    PLOTTER( );
 
     virtual ~PLOTTER()
     {
@@ -40,12 +47,7 @@
         }
     }
 
-
-    /**
-     * Function GetPlotterType
-     * @return the format of the plot file
-     */
-    PlotFormat GetPlotterType()    { return m_PlotType; }
+    virtual PlotFormat GetPlotterType() const = 0;
 
     virtual bool start_plot( FILE* fout ) = 0;
     virtual bool end_plot() = 0;
@@ -77,6 +79,12 @@
         return current_pen_width;
     }
 
+    /* PLEASE NOTE: the plot width adjustment is actually done by the
+     * pcbnew routines, the plotter class only carry it along! 
+     * XXX In fact it's only used during postscript plot, I'd move this
+     * variable as a static in pcbnew/plot_rtn.cpp. Also: why it's double?
+     * it's added to pad/track size and it's specified in IU, so it should
+     * be an int */
     virtual void set_plot_width_adj( double width )
     {
     }
@@ -97,25 +105,26 @@
     }
 
     /// Set the plot offset for the current plotting
-    virtual void set_viewport( wxPoint aOffset, double aIusPerDecimil,
+    virtual void set_viewport( const wxPoint& aOffset, double aIusPerDecimil,
 	    double aScale, bool aMirror ) = 0;
 
     // Standard primitives
-    virtual void rect( wxPoint p1, wxPoint p2, FILL_T fill,
+    virtual void rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill,
                        int width = -1 ) = 0;
-    virtual void circle( wxPoint pos, int diametre, FILL_T fill,
+    virtual void circle( const wxPoint& pos, int diametre, FILL_T fill,
                          int width = -1 ) = 0;
-    virtual void arc( wxPoint centre, int StAngle, int EndAngle, int rayon,
+    virtual void arc( const wxPoint& centre, int StAngle, int EndAngle, int rayon,
                       FILL_T fill, int width = -1 );
 
     /**
      * Function PlotPoly
      * @brief Draw a polygon ( filled or not )
      * @param aCornerList = corners list
-     * @param aFill :if true : filled polygon
+     * @param aFill = type of fill
      * @param aWidth = line width
      */
-    virtual void PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = -1 ) = 0;
+    virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, 
+			   int aWidth = -1 ) = 0;
 
     /**
      * Function PlotImage
@@ -127,24 +136,25 @@
      * @param aScaleFactor = the scale factor to apply to the bitmap size
      *                      (this is not the plot scale factor)
      */
-    virtual void PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor ) = 0;
+    virtual void PlotImage( wxImage & aImage, const wxPoint& aPos, 
+                            double aScaleFactor ) = 0;
 
-    virtual void thick_segment( wxPoint start, wxPoint end, int width,
+    virtual void thick_segment( const wxPoint& start, const wxPoint& end, int width,
                                 EDA_DRAW_MODE_T tracemode );
-    virtual void thick_arc( wxPoint centre, int StAngle, int EndAngle, int rayon,
+    virtual void thick_arc( const wxPoint& centre, int StAngle, int EndAngle, int rayon,
                             int width, EDA_DRAW_MODE_T tracemode );
-    virtual void thick_rect( wxPoint p1, wxPoint p2, int width,
+    virtual void thick_rect( const wxPoint& p1, const wxPoint& p2, int width,
                              EDA_DRAW_MODE_T tracemode );
-    virtual void thick_circle( wxPoint pos, int diametre, int width,
+    virtual void thick_circle( const wxPoint& pos, int diametre, int width,
                                EDA_DRAW_MODE_T tracemode );
-    virtual void pen_to( wxPoint pos, char plume ) = 0;
+    virtual void pen_to( const wxPoint& pos, char plume ) = 0;
 
     // Flash primitives
-    virtual void flash_pad_circle( wxPoint pos, int diametre,
+    virtual void flash_pad_circle( const wxPoint& pos, int diametre,
                                    EDA_DRAW_MODE_T trace_mode ) = 0;
-    virtual void flash_pad_oval( wxPoint pos, wxSize size, int orient,
+    virtual void flash_pad_oval( const wxPoint& pos, const wxSize& size, int orient,
                                  EDA_DRAW_MODE_T trace_mode ) = 0;
-    virtual void flash_pad_rect( wxPoint pos, wxSize size,
+    virtual void flash_pad_rect( const wxPoint& pos, const wxSize& size,
                                  int orient, EDA_DRAW_MODE_T trace_mode ) = 0;
 
     /** virtual function flash_pad_trapez
@@ -154,21 +164,21 @@
      * @param aPadOrient = the rotation of the shape
      * @param aTrace_Mode = FILLED or SKETCH
      */
-    virtual void flash_pad_trapez( wxPoint aPadPos, wxPoint aCorners[4],
+    virtual void flash_pad_trapez( const wxPoint& aPadPos, const wxPoint *aCorners,
                                    int aPadOrient, EDA_DRAW_MODE_T aTrace_Mode ) = 0;
 
     // Convenience functions
-    void move_to( wxPoint pos )
+    void move_to( const wxPoint& pos )
     {
         pen_to( pos, 'U' );
     }
 
-    void line_to( wxPoint pos )
+    void line_to( const wxPoint& pos )
     {
         pen_to( pos, 'D' );
     }
 
-    void finish_to( wxPoint pos )
+    void finish_to( const wxPoint& pos )
     {
         pen_to( pos, 'D' );
         pen_to( pos, 'Z' );
@@ -207,20 +217,19 @@
     void           center_lozenge( const wxPoint& position, int diametre, FILL_T fill );
 
     // Helper function for sketched filler segment
-    void           segment_as_oval( wxPoint start, wxPoint end, int width,
+    void           segment_as_oval( const wxPoint& start, const wxPoint& end, int width,
                                     EDA_DRAW_MODE_T tracemode );
-    void           sketch_oval( wxPoint pos, wxSize size, int orient, int width );
+    void           sketch_oval( const wxPoint& pos, const wxSize& size, int orient, 
+                                int width );
 
-    virtual void   user_to_device_coordinates( wxPoint& pos );
-    virtual void   user_to_device_size( wxSize& size );
+    virtual void user_to_device_coordinates( const wxPoint& pos, DPOINT& out );
+    virtual void user_to_device_size( const wxSize& size, DPOINT& out );
     virtual double user_to_device_size( double size );
 
-    PlotFormat    m_PlotType;
-
     /// Plot scale
     double        plot_scale;
 
-    /// Device scale (from IUs to device units)
+    /// Device scale (from IUs to device units - usually decimils)
     double        device_scale;
 
     /// Plot offset (in IUs)
@@ -239,6 +248,7 @@
     wxString      creator;
     wxString      filename;
     PAGE_INFO     pageInfo;
+    // Paper size in IU - not in mils
     wxSize        paper_size;
 };
 
@@ -246,9 +256,13 @@
 class HPGL_PLOTTER : public PLOTTER
 {
 public:
-    HPGL_PLOTTER() :
-        PLOTTER( PLOT_FORMAT_HPGL )
-    {
+    HPGL_PLOTTER() 
+    {
+    }
+
+    virtual PlotFormat GetPlotterType() const
+    {
+	return PLOT_FORMAT_HPGL;
     }
 
     virtual bool start_plot( FILE* fout );
@@ -290,10 +304,10 @@
         pen_overlap = overlap;
     }
 
-    virtual void set_viewport( wxPoint aOffset, double aIusPerDecimil,
+    virtual void set_viewport( const wxPoint& aOffset, double aIusPerDecimil,
 	    double aScale, bool aMirror );
-    virtual void rect( wxPoint p1, wxPoint p2, FILL_T fill, int width = -1 );
-    virtual void circle( wxPoint pos, int diametre, FILL_T fill, int width = -1 );
+    virtual void rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width = -1 );
+    virtual void circle( const wxPoint& pos, int diametre, FILL_T fill, int width = -1 );
 
     /*
      * Function PlotPoly
@@ -302,7 +316,7 @@
      * param aFill :if true : filled polygon
      * param aWidth = line width
      */
-    virtual void PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = -1);
+    virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = -1);
 
     /*
      * Function PlotImage
@@ -314,21 +328,21 @@
      * param aScaleFactor = the scale factor to apply to the bitmap size
      *                      (this is not the plot scale factor)
      */
-    virtual void PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor );
+    virtual void PlotImage( wxImage & aImage, const wxPoint& aPos, double aScaleFactor );
 
-    virtual void thick_segment( wxPoint start, wxPoint end, int width,
+    virtual void thick_segment( const wxPoint& start, const wxPoint& end, int width,
                                 EDA_DRAW_MODE_T tracemode );
-    virtual void arc( wxPoint centre, int StAngle, int EndAngle, int rayon,
+    virtual void arc( const wxPoint& centre, int StAngle, int EndAngle, int rayon,
                       FILL_T fill, int width = -1 );
-    virtual void pen_to( wxPoint pos, char plume );
-    virtual void flash_pad_circle( wxPoint pos, int diametre,
+    virtual void pen_to( const wxPoint& pos, char plume );
+    virtual void flash_pad_circle( const wxPoint& pos, int diametre,
                                    EDA_DRAW_MODE_T trace_mode );
-    virtual void flash_pad_oval( wxPoint pos, wxSize size, int orient,
+    virtual void flash_pad_oval( const wxPoint& pos, const wxSize& size, int orient,
                                  EDA_DRAW_MODE_T trace_mode );
-    virtual void flash_pad_rect( wxPoint pos, wxSize size,
+    virtual void flash_pad_rect( const wxPoint& pos, const wxSize& size,
                                  int orient, EDA_DRAW_MODE_T trace_mode );
 
-    virtual void flash_pad_trapez( wxPoint aPadPos, wxPoint aCorners[4],
+    virtual void flash_pad_trapez( const wxPoint& aPadPos, const wxPoint *aCorners,
                                    int aPadOrient, EDA_DRAW_MODE_T aTrace_Mode );
 
     virtual void SetLayerPolarity( bool aPositive ) {}
@@ -346,13 +360,17 @@
 class PS_PLOTTER : public PLOTTER
 {
 public:
-    PS_PLOTTER() :
-        PLOTTER( PLOT_FORMAT_POST )
+    PS_PLOTTER()
     {
         plot_scale_adjX = 1;
         plot_scale_adjY = 1;
     }
 
+    virtual PlotFormat GetPlotterType() const
+    {
+	return PLOT_FORMAT_POST;
+    }
+
     virtual bool start_plot( FILE* fout );
     virtual bool end_plot();
     virtual void set_current_line_width( int width );
@@ -376,11 +394,11 @@
         return plot_width_adj;
     }
 
-    virtual void set_viewport( wxPoint aOffset, double aIusPerDecimil,
+    virtual void set_viewport( const wxPoint& aOffset, double aIusPerDecimil,
 	    double aScale, bool aMirror );
-    virtual void rect( wxPoint p1, wxPoint p2, FILL_T fill, int width = -1 );
-    virtual void circle( wxPoint pos, int diametre, FILL_T fill, int width = -1 );
-    virtual void arc( wxPoint centre, int StAngle, int EndAngle, int rayon,
+    virtual void rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width = -1 );
+    virtual void circle( const wxPoint& pos, int diametre, FILL_T fill, int width = -1 );
+    virtual void arc( const wxPoint& centre, int StAngle, int EndAngle, int rayon,
                       FILL_T fill, int width = -1 );
     /*
      * Function PlotPoly
@@ -389,7 +407,7 @@
      * param aFill :if true : filled polygon
      * param aWidth = line width
      */
-    virtual void PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = -1);
+    virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = -1);
 
     /*
      * Function PlotImage
@@ -401,23 +419,21 @@
      * param aScaleFactor = the scale factor to apply to the bitmap size
      *                      (this is not the plot scale factor)
      */
-    virtual void PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor );
+    virtual void PlotImage( wxImage & aImage, const wxPoint& aPos, double aScaleFactor );
 
-    virtual void pen_to( wxPoint pos, char plume );
-    virtual void flash_pad_circle( wxPoint pos, int diametre,
+    virtual void pen_to( const wxPoint& pos, char plume );
+    virtual void flash_pad_circle( const wxPoint& pos, int diametre,
                                    EDA_DRAW_MODE_T trace_mode );
-    virtual void flash_pad_oval( wxPoint pos, wxSize size, int orient,
+    virtual void flash_pad_oval( const wxPoint& pos, const wxSize& size, int orient,
                                  EDA_DRAW_MODE_T trace_mode );
-    virtual void flash_pad_rect( wxPoint pos, wxSize size,
+    virtual void flash_pad_rect( const wxPoint& pos, const wxSize& size,
                                  int orient, EDA_DRAW_MODE_T trace_mode );
 
-    virtual void flash_pad_trapez( wxPoint aPadPos, wxPoint aCorners[4],
+    virtual void flash_pad_trapez( const wxPoint& aPadPos, const wxPoint *aCorners,
                                    int aPadOrient, EDA_DRAW_MODE_T aTrace_Mode );
 
     virtual void SetLayerPolarity( bool aPositive ) {}
 
-    void   user_to_device_coordinates( wxPoint& pos );      // overload
-
 protected:
     double plot_scale_adjX, plot_scale_adjY;
     double plot_width_adj;
@@ -447,14 +463,18 @@
 class GERBER_PLOTTER : public PLOTTER
 {
 public:
-    GERBER_PLOTTER() :
-        PLOTTER( PLOT_FORMAT_GERBER )
+    GERBER_PLOTTER()
     {
         work_file  = 0;
         final_file = 0;
         current_aperture = apertures.end();
     }
 
+    virtual PlotFormat GetPlotterType() const
+    {
+	return PLOT_FORMAT_GERBER;
+    }
+
     virtual bool start_plot( FILE* fout );
     virtual bool end_plot();
     virtual void set_current_line_width( int width );
@@ -463,10 +483,10 @@
     // RS274X has no dashing, nor colours
     virtual void set_dash( bool dashed ) {};
     virtual void set_color( int color ) {};
-    virtual void set_viewport( wxPoint aOffset, double aIusPerDecimil,
+    virtual void set_viewport( const wxPoint& aOffset, double aIusPerDecimil,
 	    double aScale, bool aMirror );
-    virtual void rect( wxPoint p1, wxPoint p2, FILL_T fill, int width = -1 );
-    virtual void circle( wxPoint pos, int diametre, FILL_T fill, int width = -1 );
+    virtual void rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width = -1 );
+    virtual void circle( const wxPoint& pos, int diametre, FILL_T fill, int width = -1 );
     /*
      * Function PlotPoly
      * Draw a polygon (filled or not) in GERBER format
@@ -474,7 +494,7 @@
      * param aFill :if true : filled polygon
      * param aWidth = line width
      */
-    virtual void PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = -1);
+    virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = -1);
 
     /*
      * Function PlotImage
@@ -486,23 +506,24 @@
      * param aScaleFactor = the scale factor to apply to the bitmap size
      *                      (this is not the plot scale factor)
      */
-    virtual void PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor );
+    virtual void PlotImage( wxImage & aImage, const wxPoint& aPos, double aScaleFactor );
 
-    virtual void pen_to( wxPoint pos, char plume );
-    virtual void flash_pad_circle( wxPoint pos, int diametre,
+    virtual void pen_to( const wxPoint& pos, char plume );
+    virtual void flash_pad_circle( const wxPoint& pos, int diametre,
                                    EDA_DRAW_MODE_T trace_mode );
-    virtual void flash_pad_oval( wxPoint pos, wxSize size, int orient,
+    virtual void flash_pad_oval( const wxPoint& pos, const wxSize& size, int orient,
                                  EDA_DRAW_MODE_T trace_mode );
-    virtual void flash_pad_rect( wxPoint pos, wxSize size,
+    virtual void flash_pad_rect( const wxPoint& pos, const wxSize& size,
                                  int orient, EDA_DRAW_MODE_T trace_mode );
 
-    virtual void flash_pad_trapez( wxPoint aPadPos, wxPoint aCorners[4],
+    virtual void flash_pad_trapez( const wxPoint& aPadPos, const wxPoint *aCorners,
                                    int aPadOrient, EDA_DRAW_MODE_T aTrace_Mode );
 
     virtual void                    SetLayerPolarity( bool aPositive );
 
 protected:
-    void  select_aperture( const wxSize& size, APERTURE::Aperture_Type type );
+    void select_aperture( const wxSize& size, APERTURE::Aperture_Type type );
+    void emit_dcode( const DPOINT& pt, int dcode );
 
     std::vector<APERTURE>::iterator
                         get_aperture( const wxSize& size, APERTURE::Aperture_Type type );
@@ -520,9 +541,13 @@
 class DXF_PLOTTER : public PLOTTER
 {
 public:
-    DXF_PLOTTER() :
-        PLOTTER( PLOT_FORMAT_DXF )
-    {
+    DXF_PLOTTER()
+    {
+    }
+
+    virtual PlotFormat GetPlotterType() const
+    {
+	return PLOT_FORMAT_DXF;
     }
 
 
@@ -546,10 +571,10 @@
 
     virtual void set_color( int color );
 
-    virtual void set_viewport( wxPoint aOffset, double aIusPerDecimil,
+    virtual void set_viewport( const wxPoint& aOffset, double aIusPerDecimil,
 	    double aScale, bool aMirror );
-    virtual void rect( wxPoint p1, wxPoint p2, FILL_T fill, int width = -1 );
-    virtual void circle( wxPoint pos, int diametre, FILL_T fill, int width = -1 );
+    virtual void rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, int width = -1 );
+    virtual void circle( const wxPoint& pos, int diametre, FILL_T fill, int width = -1 );
     /*
      * Function PlotPoly
      * Draw a polygon (filled or not) in DXF format
@@ -557,7 +582,7 @@
      * param aFill :if true : filled polygon
      * param aWidth = line width
      */
-    virtual void PlotPoly( std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = -1 );
+    virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, int aWidth = -1 );
 
     /*
      * Function PlotImage
@@ -569,21 +594,21 @@
      * param aScaleFactor = the scale factor to apply to the bitmap size
      *                      (this is not the plot scale factor)
      */
-    virtual void PlotImage( wxImage & aImage, wxPoint aPos, double aScaleFactor );
+    virtual void PlotImage( wxImage & aImage, const wxPoint& aPos, double aScaleFactor );
 
-    virtual void thick_segment( wxPoint start, wxPoint end, int width,
+    virtual void thick_segment( const wxPoint& start, const wxPoint& end, int width,
                                 EDA_DRAW_MODE_T tracemode );
-    virtual void arc( wxPoint centre, int StAngle, int EndAngle, int rayon,
+    virtual void arc( const wxPoint& centre, int StAngle, int EndAngle, int rayon,
                       FILL_T fill, int width = -1 );
-    virtual void pen_to( wxPoint pos, char plume );
-    virtual void flash_pad_circle( wxPoint pos, int diametre,
+    virtual void pen_to( const wxPoint& pos, char plume );
+    virtual void flash_pad_circle( const wxPoint& pos, int diametre,
                                    EDA_DRAW_MODE_T trace_mode );
-    virtual void flash_pad_oval( wxPoint pos, wxSize size, int orient,
+    virtual void flash_pad_oval( const wxPoint& pos, const wxSize& size, int orient,
                                  EDA_DRAW_MODE_T trace_mode );
-    virtual void flash_pad_rect( wxPoint pos, wxSize size,
+    virtual void flash_pad_rect( const wxPoint& pos, const wxSize& size,
                                  int orient, EDA_DRAW_MODE_T trace_mode );
 
-    virtual void flash_pad_trapez( wxPoint aPadPos, wxPoint aCorners[4],
+    virtual void flash_pad_trapez( const wxPoint& aPadPos, const wxPoint *aCorners,
                                    int aPadOrient, EDA_DRAW_MODE_T aTrace_Mode );
 
     virtual void SetLayerPolarity( bool aPositive ) {}

=== modified file 'pcbnew/gen_modules_placefile.cpp'
--- pcbnew/gen_modules_placefile.cpp	2012-04-27 10:52:50 +0000
+++ pcbnew/gen_modules_placefile.cpp	2012-04-29 07:26:27 +0000
@@ -451,15 +451,17 @@
     fputs( line, file );
 
     sprintf( line,
-             "# Ref    Val                  PosX       PosY        Rot     Side\n" );
+             "# Ref    Val                  Package         PosX       PosY        Rot     Side\n" );
     fputs( line, file );
 
     for( int ii = 0; ii < moduleCount; ii++ )
     {
         wxPoint  module_pos;
-        wxString ref = list[ii].m_Reference;
-        wxString val = list[ii].m_Value;
-        sprintf( line, "%-8.8s %-16.16s ", TO_UTF8( ref ), TO_UTF8( val ) );
+        const wxString& ref = list[ii].m_Reference;
+        const wxString& val = list[ii].m_Value;
+        const wxString& pkg = list[ii].m_Module->m_LibRef;
+        sprintf( line, "%-8.8s %-16.16s %-16.16s", 
+	         TO_UTF8( ref ), TO_UTF8( val ), TO_UTF8( pkg ) );
 
         module_pos    = list[ii].m_Module->m_Pos;
         module_pos -= File_Place_Offset;


Follow ups

References