← Back to team overview

kicad-developers team mailing list archive

[PATCH] Support for the "file function" attribute of the new Gerber specification

 

Hello everyone,

The attached patch optionally includes the attribute that describes the
"function" or (position in the stack) of the Gerber file. This feature is
introduced in the latest Gerber specification (revision J1).

Whether or not to include the attribute, is an option in the plot dialog.
There are a few Gerber viewers that reject files with the attribute set
(most viewers simply ignore the field).

I have not looked yet at adding the "MD5 checksum" attribute (for file
integrity); I don't know whether it really is useful. In practice, a set of
Gerber files is zipped, and the zip file has its own checksums.

Regards,
Thiadmer Riemersma
=== modified file 'common/common_plotGERBER_functions.cpp'
--- common/common_plotGERBER_functions.cpp	2014-05-16 19:03:45 +0000
+++ common/common_plotGERBER_functions.cpp	2014-06-18 12:03:46 +0000
@@ -67,6 +67,12 @@
     if( outputFile == NULL )
         return false;
 
+    if( !attribFunction.IsEmpty() )
+    {
+        fputs( "%TF.GerberVersion,J1*%\n", outputFile );
+        fprintf( outputFile, "%%TF.FileFunction,%s*%%\n", TO_UTF8( attribFunction ) );
+    }
+
     /* Set coordinate format to 3.4 absolute, leading zero omitted */
     fputs( "%FSLAX34Y34*%\n", outputFile );
     fputs( "G04 Gerber Fmt 3.4, Leading zero omitted, Abs format*\n", outputFile );

=== modified file 'common/pcb_plot_params.keywords'
--- common/pcb_plot_params.keywords	2011-12-08 18:23:44 +0000
+++ common/pcb_plot_params.keywords	2014-06-18 12:04:46 +0000
@@ -27,3 +27,4 @@
 useauxorigin
 usegerberextensions
 viasonmask
+usegerberattributes

=== modified file 'include/plot_common.h'
--- include/plot_common.h	2014-05-18 15:16:59 +0000
+++ include/plot_common.h	2014-06-18 12:06:02 +0000
@@ -282,7 +282,12 @@
      */
     virtual void SetTextMode( PlotTextMode mode )
     {
-    // NOP for most plotters
+        // NOP for most plotters
+    }
+
+    virtual void SetLayerAttribFunction( const wxString& function )
+    {
+        // NOP for most plotters
     }
 
 protected:
@@ -769,6 +774,7 @@
         workFile  = 0;
         finalFile = 0;
         currentAperture = apertures.end();
+        attribFunction = wxEmptyString;
     }
 
     virtual PlotFormat GetPlotterType() const
@@ -813,6 +819,11 @@
 
     virtual void SetLayerPolarity( bool aPositive );
 
+    virtual void SetLayerAttribFunction( const wxString& function )
+    {
+        attribFunction = function;
+    }
+
 protected:
     void selectAperture( const wxSize& size, APERTURE::APERTURE_TYPE type );
     void emitDcode( const DPOINT& pt, int dcode );
@@ -828,6 +839,8 @@
 
     std::vector<APERTURE>           apertures;
     std::vector<APERTURE>::iterator currentAperture;
+
+    wxString attribFunction; /* the layer "function", it is linked with the layer id */
 };
 
 

=== modified file 'pcbnew/dialogs/dialog_SVG_print.cpp'
--- pcbnew/dialogs/dialog_SVG_print.cpp	2014-04-02 13:38:59 +0000
+++ pcbnew/dialogs/dialog_SVG_print.cpp	2014-06-18 12:07:31 +0000
@@ -334,7 +334,9 @@
 
     LOCALE_IO    toggle;
     SVG_PLOTTER* plotter = (SVG_PLOTTER*) StartPlotBoard( m_board,
-                                                          &m_plotOpts, aFullFileName,
+                                                          &m_plotOpts,
+                                                          UNDEFINED_LAYER,
+                                                          aFullFileName,
                                                           wxEmptyString );
 
     if( plotter )

=== modified file 'pcbnew/dialogs/dialog_plot.cpp'
--- pcbnew/dialogs/dialog_plot.cpp	2014-05-26 06:54:04 +0000
+++ pcbnew/dialogs/dialog_plot.cpp	2014-06-18 12:08:50 +0000
@@ -171,6 +171,9 @@
     // Option for using proper Gerber extensions
     m_useGerberExtensions->SetValue( m_plotOpts.GetUseGerberExtensions() );
 
+    // Option for including Gerber attributes (from Gerber X2 format) in the output
+    m_useGerberAttributes->SetValue( m_plotOpts.GetUseGerberAttributes() );
+
     // Option for excluding contents of "Edges Pcb" layer
     m_excludeEdgeLayerOpt->SetValue( m_plotOpts.GetExcludeEdgeLayer() );
 
@@ -379,6 +382,8 @@
         m_subtractMaskFromSilk->SetValue( false );
         m_useGerberExtensions->Enable( false );
         m_useGerberExtensions->SetValue( false );
+        m_useGerberAttributes->Enable( false );
+        m_useGerberAttributes->SetValue( false );
         m_scaleOpt->Enable( false );
         m_scaleOpt->SetSelection( 1 );
         m_fineAdjustXscaleOpt->Enable( false );
@@ -407,6 +412,8 @@
         m_subtractMaskFromSilk->SetValue( false );
         m_useGerberExtensions->Enable( false );
         m_useGerberExtensions->SetValue( false );
+        m_useGerberAttributes->Enable( false );
+        m_useGerberAttributes->SetValue( false );
         m_scaleOpt->Enable( true );
         m_fineAdjustXscaleOpt->Enable( true );
         m_fineAdjustYscaleOpt->Enable( true );
@@ -433,6 +440,7 @@
         m_excludeEdgeLayerOpt->Enable( true );
         m_subtractMaskFromSilk->Enable( true );
         m_useGerberExtensions->Enable( true );
+        m_useGerberAttributes->Enable( true );
         m_scaleOpt->Enable( false );
         m_scaleOpt->SetSelection( 1 );
         m_fineAdjustXscaleOpt->Enable( false );
@@ -462,6 +470,8 @@
         m_subtractMaskFromSilk->SetValue( false );
         m_useGerberExtensions->Enable( false );
         m_useGerberExtensions->SetValue( false );
+        m_useGerberAttributes->Enable( false );
+        m_useGerberAttributes->SetValue( false );
         m_scaleOpt->Enable( true );
         m_fineAdjustXscaleOpt->Enable( false );
         m_fineAdjustYscaleOpt->Enable( false );
@@ -489,6 +499,8 @@
         m_subtractMaskFromSilk->SetValue( false );
         m_useGerberExtensions->Enable( false );
         m_useGerberExtensions->SetValue( false );
+        m_useGerberAttributes->Enable( false );
+        m_useGerberAttributes->SetValue( false );
         m_scaleOpt->Enable( false );
         m_scaleOpt->SetSelection( 1 );
         m_fineAdjustXscaleOpt->Enable( false );
@@ -667,6 +679,8 @@
 
     tempOptions.SetUseGerberExtensions( m_useGerberExtensions->GetValue() );
 
+    tempOptions.SetUseGerberAttributes( m_useGerberAttributes->GetValue() );
+
     tempOptions.SetFormat( GetPlotFormat() );
 
     long            selectedLayers = 0;
@@ -794,7 +808,7 @@
             LOCALE_IO toggle;
             BOARD *board = m_parent->GetBoard();
             PLOTTER *plotter = StartPlotBoard( board, &m_plotOpts,
-                                               fn.GetFullPath(),
+                                               layer, fn.GetFullPath(),
                                                wxEmptyString );
 
             // Print diags in messages box:

=== modified file 'pcbnew/dialogs/dialog_plot_base.cpp'
--- pcbnew/dialogs/dialog_plot_base.cpp	2014-06-02 16:16:06 +0000
+++ pcbnew/dialogs/dialog_plot_base.cpp	2014-06-18 12:00:15 +0000
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Nov  6 2013)
+// C++ code generated with wxFormBuilder (version Feb 26 2014)
 // http://www.wxformbuilder.org/
 //
 // PLEASE DO "NOT" EDIT THIS FILE!
@@ -226,6 +226,11 @@
 	
 	m_GerberOptionsSizer->Add( m_useGerberExtensions, 0, wxLEFT|wxRIGHT|wxTOP, 2 );
 	
+	m_useGerberAttributes = new wxCheckBox( this, wxID_ANY, _("Include extended attributes"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_useGerberAttributes->SetToolTip( _("Include extended attributes for non-image data in the Gerber file") );
+	
+	m_GerberOptionsSizer->Add( m_useGerberAttributes, 0, wxTOP|wxRIGHT|wxLEFT, 2 );
+	
 	m_subtractMaskFromSilk = new wxCheckBox( this, wxID_ANY, _("Subtract soldermask from silkscreen"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_subtractMaskFromSilk->SetToolTip( _("Remove silkscreen from areas without soldermask") );
 	

=== modified file 'pcbnew/dialogs/dialog_plot_base.fbp'
--- pcbnew/dialogs/dialog_plot_base.fbp	2014-06-02 16:16:06 +0000
+++ pcbnew/dialogs/dialog_plot_base.fbp	2014-06-18 11:57:35 +0000
@@ -2778,6 +2778,90 @@
                                                         <event name="OnUpdateUI"></event>
                                                     </object>
                                                 </object>
+                                                <object class="sizeritem" expanded="1">
+                                                    <property name="border">2</property>
+                                                    <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>
+                                                    <property name="proportion">0</property>
+                                                    <object class="wxCheckBox" expanded="1">
+                                                        <property name="BottomDockable">1</property>
+                                                        <property name="LeftDockable">1</property>
+                                                        <property name="RightDockable">1</property>
+                                                        <property name="TopDockable">1</property>
+                                                        <property name="aui_layer"></property>
+                                                        <property name="aui_name"></property>
+                                                        <property name="aui_position"></property>
+                                                        <property name="aui_row"></property>
+                                                        <property name="best_size"></property>
+                                                        <property name="bg"></property>
+                                                        <property name="caption"></property>
+                                                        <property name="caption_visible">1</property>
+                                                        <property name="center_pane">0</property>
+                                                        <property name="checked">0</property>
+                                                        <property name="close_button">1</property>
+                                                        <property name="context_help"></property>
+                                                        <property name="context_menu">1</property>
+                                                        <property name="default_pane">0</property>
+                                                        <property name="dock">Dock</property>
+                                                        <property name="dock_fixed">0</property>
+                                                        <property name="docking">Left</property>
+                                                        <property name="enabled">1</property>
+                                                        <property name="fg"></property>
+                                                        <property name="floatable">1</property>
+                                                        <property name="font"></property>
+                                                        <property name="gripper">0</property>
+                                                        <property name="hidden">0</property>
+                                                        <property name="id">wxID_ANY</property>
+                                                        <property name="label">Include extended attributes</property>
+                                                        <property name="max_size"></property>
+                                                        <property name="maximize_button">0</property>
+                                                        <property name="maximum_size"></property>
+                                                        <property name="min_size"></property>
+                                                        <property name="minimize_button">0</property>
+                                                        <property name="minimum_size"></property>
+                                                        <property name="moveable">1</property>
+                                                        <property name="name">m_useGerberAttributes</property>
+                                                        <property name="pane_border">1</property>
+                                                        <property name="pane_position"></property>
+                                                        <property name="pane_size"></property>
+                                                        <property name="permission">protected</property>
+                                                        <property name="pin_button">1</property>
+                                                        <property name="pos"></property>
+                                                        <property name="resize">Resizable</property>
+                                                        <property name="show">1</property>
+                                                        <property name="size"></property>
+                                                        <property name="style"></property>
+                                                        <property name="subclass"></property>
+                                                        <property name="toolbar_pane">0</property>
+                                                        <property name="tooltip">Include extended attributes for non-image data in the Gerber file</property>
+                                                        <property name="window_extra_style"></property>
+                                                        <property name="window_name"></property>
+                                                        <property name="window_style"></property>
+                                                        <event name="OnChar"></event>
+                                                        <event name="OnCheckBox"></event>
+                                                        <event name="OnEnterWindow"></event>
+                                                        <event name="OnEraseBackground"></event>
+                                                        <event name="OnKeyDown"></event>
+                                                        <event name="OnKeyUp"></event>
+                                                        <event name="OnKillFocus"></event>
+                                                        <event name="OnLeaveWindow"></event>
+                                                        <event name="OnLeftDClick"></event>
+                                                        <event name="OnLeftDown"></event>
+                                                        <event name="OnLeftUp"></event>
+                                                        <event name="OnMiddleDClick"></event>
+                                                        <event name="OnMiddleDown"></event>
+                                                        <event name="OnMiddleUp"></event>
+                                                        <event name="OnMotion"></event>
+                                                        <event name="OnMouseEvents"></event>
+                                                        <event name="OnMouseWheel"></event>
+                                                        <event name="OnPaint"></event>
+                                                        <event name="OnRightDClick"></event>
+                                                        <event name="OnRightDown"></event>
+                                                        <event name="OnRightUp"></event>
+                                                        <event name="OnSetFocus"></event>
+                                                        <event name="OnSize"></event>
+                                                        <event name="OnUpdateUI"></event>
+                                                    </object>
+                                                </object>
                                                 <object class="sizeritem" expanded="0">
                                                     <property name="border">2</property>
                                                     <property name="flag">wxTOP|wxRIGHT|wxLEFT</property>

=== modified file 'pcbnew/dialogs/dialog_plot_base.h'
--- pcbnew/dialogs/dialog_plot_base.h	2014-05-19 18:24:07 +0000
+++ pcbnew/dialogs/dialog_plot_base.h	2014-06-18 12:00:15 +0000
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Nov  6 2013)
+// C++ code generated with wxFormBuilder (version Feb 26 2014)
 // http://www.wxformbuilder.org/
 //
 // PLEASE DO "NOT" EDIT THIS FILE!
@@ -89,6 +89,7 @@
 		wxStaticText* m_SolderMaskMinWidthCurrValue;
 		wxStaticBoxSizer* m_GerberOptionsSizer;
 		wxCheckBox* m_useGerberExtensions;
+		wxCheckBox* m_useGerberAttributes;
 		wxCheckBox* m_subtractMaskFromSilk;
 		wxStaticBoxSizer* m_HPGLOptionsSizer;
 		wxStaticText* m_textPenSize;

=== modified file 'pcbnew/pcb_plot_params.cpp'
--- pcbnew/pcb_plot_params.cpp	2014-05-19 18:24:07 +0000
+++ pcbnew/pcb_plot_params.cpp	2014-06-18 12:09:57 +0000
@@ -79,6 +79,7 @@
     m_layerSelection       = LAYER_BACK | LAYER_FRONT
         | SILKSCREEN_LAYER_FRONT | SILKSCREEN_LAYER_BACK;
     m_useGerberExtensions  = true;
+    m_useGerberAttributes  = false;
     m_excludeEdgeLayer     = true;
     m_lineWidth            = g_DrawDefaultLineThickness;
     m_plotFrameRef         = false;
@@ -129,6 +130,8 @@
                        long(m_layerSelection) );
     aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_usegerberextensions ),
                        m_useGerberExtensions ? trueStr : falseStr );
+    aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_usegerberattributes ),
+                       m_useGerberAttributes ? trueStr : falseStr );
     aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_excludeedgelayer ),
                        m_excludeEdgeLayer ? trueStr : falseStr );
     aFormatter->Print( aNestLevel+1, "(%s %f)\n", getTokenName( T_linewidth ),
@@ -194,6 +197,8 @@
         return false;
     if( m_useGerberExtensions != aPcbPlotParams.m_useGerberExtensions )
         return false;
+    if( m_useGerberAttributes != aPcbPlotParams.m_useGerberAttributes )
+        return false;
     if( m_excludeEdgeLayer != aPcbPlotParams.m_excludeEdgeLayer )
         return false;
     if( m_lineWidth != aPcbPlotParams.m_lineWidth )
@@ -329,6 +334,9 @@
         case T_usegerberextensions:
             aPcbPlotParams->m_useGerberExtensions = parseBool();
             break;
+        case T_usegerberattributes:
+            aPcbPlotParams->m_useGerberAttributes = parseBool();
+            break;
         case T_psa4output:
             aPcbPlotParams->m_A4Output = parseBool();
             break;

=== modified file 'pcbnew/pcb_plot_params.h'
--- pcbnew/pcb_plot_params.h	2014-05-19 18:24:07 +0000
+++ pcbnew/pcb_plot_params.h	2014-06-18 12:10:32 +0000
@@ -131,6 +131,9 @@
      * appending a suffix to the board name */
     bool        m_useGerberExtensions;
 
+    /// Include attributes from the Gerber X2 format (chapter 5 in revision J1)
+    bool        m_useGerberAttributes;
+
     /// Plot gerbers using auxiliary (drill) origin instead of page coordinates
     bool        m_useAuxOrigin;
 
@@ -257,6 +260,9 @@
     void        SetOutputDirectory( wxString aDir ) { m_outputDirectory = aDir; };
     wxString    GetOutputDirectory() const { return m_outputDirectory; };
 
+    void        SetUseGerberAttributes( bool aUse ) { m_useGerberAttributes = aUse; };
+    bool        GetUseGerberAttributes() const { return m_useGerberAttributes; };
+
     void        SetUseGerberExtensions( bool aUse ) { m_useGerberExtensions = aUse; };
     bool        GetUseGerberExtensions() const { return m_useGerberExtensions; };
 

=== modified file 'pcbnew/pcbplot.cpp'
--- pcbnew/pcbplot.cpp	2014-01-28 09:43:55 +0000
+++ pcbnew/pcbplot.cpp	2014-06-18 12:14:09 +0000
@@ -109,6 +109,112 @@
 }
 
 
+wxString GetGerberFileFunction( const BOARD *aBoard, LAYER_NUM aLayer )
+{
+    wxString attrib = wxEmptyString;
+
+    switch( aLayer )
+    {
+    case LAYER_N_BACK:
+        attrib = wxString::Format( wxT( "Copper,L%d" ), aBoard->GetCopperLayerCount() );
+        break;
+
+    case LAYER_N_2:
+    case LAYER_N_3:
+    case LAYER_N_4:
+    case LAYER_N_5:
+    case LAYER_N_6:
+    case LAYER_N_7:
+    case LAYER_N_8:
+    case LAYER_N_9:
+    case LAYER_N_10:
+    case LAYER_N_11:
+    case LAYER_N_12:
+    case LAYER_N_13:
+    case LAYER_N_14:
+    case LAYER_N_15:
+        // LAYER_N_2 is the first inner layer counting from the bottom; this
+        // must be converted to a 1-based number starting from the top
+        attrib = wxString::Format( wxT( "Copper,L%d" ),
+                                   aBoard->GetCopperLayerCount() - ( aLayer - LAYER_N_2 + 1 ) );
+        break;
+
+    case LAYER_N_FRONT:
+        attrib = wxString( wxT( "Copper,L1" ) );
+        break;
+
+    case ADHESIVE_N_FRONT:
+        attrib = wxString( wxT( "Glue,Top" ) );
+        break;
+
+    case ADHESIVE_N_BACK:
+        attrib = wxString( wxT( "Glue,Bot" ) );
+        break;
+
+    case SILKSCREEN_N_FRONT:
+        attrib = wxString( wxT( "Legend,Top" ) );
+        break;
+
+    case SILKSCREEN_N_BACK:
+        attrib = wxString( wxT( "Legend,Bot" ) );
+        break;
+
+    case SOLDERMASK_N_FRONT:
+        attrib = wxString( wxT( "Soldermask,Top" ) );
+        break;
+
+    case SOLDERMASK_N_BACK:
+        attrib = wxString( wxT( "Soldermask,Bot" ) );
+        break;
+
+    case SOLDERPASTE_N_FRONT:
+        attrib = wxString( wxT( "Paste,Top" ) );
+        break;
+
+    case SOLDERPASTE_N_BACK:
+        attrib = wxString( wxT( "Paste,Bot" ) );
+        break;
+
+    case EDGE_N:
+        attrib = wxString( wxT( "Profile" ) );
+        break;
+
+    case DRAW_N:
+        attrib = wxString( wxT( "Drawing" ) );
+        break;
+
+    case COMMENT_N:
+        attrib = wxString( wxT( "Other,Comment" ) );
+        break;
+
+    case ECO1_N:
+    case ECO2_N:
+        attrib = wxString::Format( wxT( "Other,ECO%d" ), aLayer - ECO1_N + 1 );
+        break;
+    }
+
+    // Add the signal type of the layer, if relevant
+    if( FIRST_COPPER_LAYER <= aLayer && aLayer <= LAST_COPPER_LAYER ) {
+        LAYER_T type = aBoard->GetLayerType( aLayer );
+        switch( type )
+        {
+        case LT_SIGNAL:
+            attrib += wxString( wxT( ",Signal" ) );
+            break;
+        case LT_POWER:
+            attrib += wxString( wxT( ",Plane" ) );
+            break;
+        case LT_MIXED:
+            attrib += wxString( wxT( ",Mixed" ) );
+            break;
+        default:
+            ;   // do nothing (but avoid a warning for unhandled LAYER_T values from GCC)
+        }
+    }
+
+    return attrib;
+}
+
 void BuildPlotFileName( wxFileName*     aFilename,
                         const wxString& aOutputDir,
                         const wxString& aSuffix,
@@ -241,7 +347,7 @@
         wxFileName fn( boardFilename );
         BuildPlotFileName( &fn, outputDirName, aSuffix, GetDefaultPlotExtension( aFormat ) );
 
-        m_plotter = StartPlotBoard( m_board, &m_plotOpts, fn.GetFullPath(), aSheetDesc );
+        m_plotter = StartPlotBoard( m_board, &m_plotOpts, UNDEFINED_LAYER, fn.GetFullPath(), aSheetDesc );
     }
 
     return( m_plotter != NULL );

=== modified file 'pcbnew/pcbplot.h'
--- pcbnew/pcbplot.h	2014-05-17 19:29:15 +0000
+++ pcbnew/pcbplot.h	2014-06-18 12:13:22 +0000
@@ -164,6 +164,7 @@
 
 PLOTTER* StartPlotBoard( BOARD* aBoard,
                          PCB_PLOT_PARAMS* aPlotOpts,
+                         int aLayer,
                          const wxString& aFullFileName,
                          const wxString& aSheetDesc );
 
@@ -265,6 +266,16 @@
  */
 extern wxString GetGerberExtension( LAYER_NUM aLayer );
 
+/**
+ * Function GetGerberFileFunction
+ * Returns the "file function" attribute for \a aLayer, as defined in the
+ * Gerber file format specification J1 (chapter 5). The returned string excludes
+ * the "%TF.FileFunction" attribute prefix and the "*%" suffix.
+ * @param aBoard = the board, needed to get the total count of copper layers
+ * @param aLayer = the layer number to create the attribute for
+ * @return The attribute, as a text string
+ */
+extern wxString GetGerberFileFunction( const BOARD *aBoard, LAYER_NUM aLayer );
 
 // PLOTGERB.CPP
 void SelectD_CODE_For_LineDraw( PLOTTER* plotter, int aSize );

=== modified file 'pcbnew/plot_board_layers.cpp'
--- pcbnew/plot_board_layers.cpp	2014-06-06 09:44:21 +0000
+++ pcbnew/plot_board_layers.cpp	2014-06-18 12:12:37 +0000
@@ -877,6 +877,7 @@
  * (or has a problem)
  */
 PLOTTER* StartPlotBoard( BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts,
+                         int aLayer,
                          const wxString& aFullFileName,
                          const wxString& aSheetDesc )
 {
@@ -938,6 +939,10 @@
 
     if( plotter->OpenFile( aFullFileName ) )
     {
+        // For the Gerber "file function" attribute, set the layer number
+        if( plotter->GetPlotterType() == PLOT_FORMAT_GERBER && plotOpts.GetUseGerberAttributes() )
+            plotter->SetLayerAttribFunction( GetGerberFileFunction( aBoard, aLayer ) );
+
         plotter->StartPlot();
 
         // Plot the frame reference if requested
@@ -949,7 +954,7 @@
                            aSheetDesc, aBoard->GetFileName() );
 
             if( aPlotOpts->GetMirror() )
-            initializePlotter( plotter, aBoard, aPlotOpts );
+                initializePlotter( plotter, aBoard, aPlotOpts );
         }
 
         /* When plotting a negative board: draw a black rectangle


Follow ups