diff --git a/common/pcb_plot_params.keywords b/common/pcb_plot_params.keywords
index 066a40f799..0c8991c5d0 100644
--- a/common/pcb_plot_params.keywords
+++ b/common/pcb_plot_params.keywords
@@ -1,4 +1,5 @@
creategerberjobfile
+disableapertmacros
drillshape
excludeedgelayer
false
diff --git a/common/plotters/GERBER_plotter.cpp b/common/plotters/GERBER_plotter.cpp
index eb8d1b9fcd..0870e49ee6 100644
--- a/common/plotters/GERBER_plotter.cpp
+++ b/common/plotters/GERBER_plotter.cpp
@@ -40,6 +40,10 @@
// if GBR_USE_MACROS is defined, pads having a shape that is not a Gerber primitive
// will use a macro when possible
// Old code will be removed only after many tests
+//
+// Note also: setting m_gerberDisableApertMacros to true disable all aperture macros
+// in Gerber files
+//
#define GBR_USE_MACROS_FOR_CHAMFERED_RECT
#define GBR_USE_MACROS_FOR_ROUNDRECT
#define GBR_USE_MACROS_FOR_TRAPEZOID
@@ -64,6 +68,7 @@ GERBER_PLOTTER::GERBER_PLOTTER()
m_gerberUnitFmt = 6;
m_useX2format = true;
m_useNetAttributes = true;
+ m_gerberDisableApertMacros = false;
m_hasApertureRoundRect = false; // true is at least one round rect aperture is in use
m_hasApertureRotOval = false; // true is at least one oval rotated aperture is in use
@@ -1024,34 +1029,37 @@ void GERBER_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, doub
if( trace_mode == FILLED )
{
#ifdef GBR_USE_MACROS_FOR_ROTATED_OVAL
- m_hasApertureRotOval = true;
- // We are using a aperture macro that expect size.y < size.x
- // i.e draw a horizontal line for rotation = 0.0
- // size.x = length, size.y = width
- if( size.x < size.y )
+ if( !m_gerberDisableApertMacros )
+ #endif
{
- std::swap( size.x, size.y );
- orient += 900;
+ m_hasApertureRotOval = true;
+ // We are using a aperture macro that expect size.y < size.x
+ // i.e draw a horizontal line for rotation = 0.0
+ // size.x = length, size.y = width
+ if( size.x < size.y )
+ {
+ std::swap( size.x, size.y );
+ orient += 900;
- if( orient > 1800 )
- orient -= 1800;
+ if( orient > 1800 )
+ orient -= 1800;
+ }
+
+ DPOINT pos_dev = userToDeviceCoordinates( pos );
+ int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
+ selectAperture( size, 0, orient/10.0, APERTURE::AM_ROTATED_OVAL, aperture_attrib );
+
+ if( gbr_metadata )
+ formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
+
+ emitDcode( pos_dev, 3 );
+ return;
}
-
- DPOINT pos_dev = userToDeviceCoordinates( pos );
- int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
- selectAperture( size, 0, orient/10.0, APERTURE::AM_ROTATED_OVAL, aperture_attrib );
-
- if( gbr_metadata )
- formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
-
- emitDcode( pos_dev, 3 );
- #else
// Draw the oval as round rect pad with a radius = 50% min size)
// In gerber file, it will be drawn as a region with arcs, and can be
// detected as pads (similar to a flashed pad)
FlashPadRoundRect( pos, aSize, std::min( aSize.x, aSize.y ) /2,
orient, FILLED, aData );
- #endif
}
else // Non filled shape: plot outlines:
{
@@ -1116,7 +1124,7 @@ void GERBER_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& aSize,
default:
#ifdef GBR_USE_MACROS_FOR_ROTATED_RECT
- if( trace_mode != SKETCH )
+ if( trace_mode != SKETCH && !m_gerberDisableApertMacros )
{
m_hasApertureRotRect = true;
DPOINT pos_dev = userToDeviceCoordinates( pos );
@@ -1187,18 +1195,22 @@ void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS
else
{
#ifdef GBR_USE_MACROS_FOR_ROUNDRECT
- m_hasApertureRoundRect = true;
+ if( !m_gerberDisableApertMacros )
+ #endif
+ {
+ m_hasApertureRoundRect = true;
- DPOINT pos_dev = userToDeviceCoordinates( aPadPos );
- int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
- selectAperture( aSize, aCornerRadius, aOrient/10.0,
- APERTURE::AM_ROUND_RECT, aperture_attrib );
+ DPOINT pos_dev = userToDeviceCoordinates( aPadPos );
+ int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
+ selectAperture( aSize, aCornerRadius, aOrient/10.0,
+ APERTURE::AM_ROUND_RECT, aperture_attrib );
- if( gbr_metadata )
- formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
+ if( gbr_metadata )
+ formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
- emitDcode( pos_dev, 3 );
- #else
+ emitDcode( pos_dev, 3 );
+ return;
+ }
// A Pad RoundRect is plotted as a Gerber region.
// Initialize region metadata:
bool clearTA_AperFunction = false; // true if a TA.AperFunction is used
@@ -1226,7 +1238,6 @@ void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS
else
fputs( "G04 #@! TD.AperFunction*\n", outputFile );
}
- #endif
}
}
@@ -1420,7 +1431,8 @@ void GERBER_PLOTTER::FlashPadChamferRoundRect( const wxPoint& aShapePos, const w
bool hasRoundedCorner = aCornerRadius != 0 && aChamferPositions != 15;
#ifdef GBR_USE_MACROS_FOR_CHAMFERED_RECT
- if( aPlotMode != FILLED || hasRoundedCorner ) // Sketch mode or round rect shape
+ // Sketch mode or round rect shape or Apert Macros disabled
+ if( aPlotMode != FILLED || hasRoundedCorner || m_gerberDisableApertMacros )
#endif
{
TransformRoundChamferedRectToPolygon( outline, aShapePos, aPadSize,
@@ -1525,9 +1537,15 @@ void GERBER_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCo
metadata = *gbr_metadata;
if( aTrace_Mode == SKETCH )
+ {
PlotPoly( cornerList, NO_FILL, GetCurrentLineWidth(), &metadata );
- else
+ return;
+ }
+
+ // Plot a filled polygon:
#ifdef GBR_USE_MACROS_FOR_TRAPEZOID
+ if( !m_gerberDisableApertMacros )
+ #endif
{
m_hasApertureOutline4P = true;
DPOINT pos_dev = userToDeviceCoordinates( aPadPos );
@@ -1540,10 +1558,10 @@ void GERBER_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCo
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
emitDcode( pos_dev, 3 );
+ return;
}
- #else
- PlotGerberRegion( cornerList, &metadata );
- #endif
+
+ PlotGerberRegion( cornerList, &metadata );
}
diff --git a/common/plotters/plotter_gerber.h b/common/plotters/plotter_gerber.h
index 6ccf2f9044..bece1713d5 100644
--- a/common/plotters/plotter_gerber.h
+++ b/common/plotters/plotter_gerber.h
@@ -197,6 +197,12 @@ public:
void UseX2format( bool aEnable ) { m_useX2format = aEnable; }
void UseX2NetAttributes( bool aEnable ) { m_useNetAttributes = aEnable; }
+ /** Disable Aperture Macro (AM) command, only for broken Gerber Readers
+ * Regions will be used instead of AM shapes to draw complex shapes
+ * @param aDisable = true to disable Aperture Macro (AM) command.
+ */
+ void DisableApertMacros( bool aDisable ) { m_gerberDisableApertMacros = aDisable; }
+
/**
* calling this function allows one to define the beginning of a group
* of drawing items (used in X2 format with netlist attributes)
@@ -351,6 +357,9 @@ protected:
bool m_gerberUnitInch; // true if the gerber units are inches, false for mm
int m_gerberUnitFmt; // number of digits in mantissa.
// usually 6 in Inches and 5 or 6 in mm
+ bool m_gerberDisableApertMacros; // True to disable Aperture Macro (AM) command,
+ // for broken Gerber Readers
+ // Regions will be used instead of AM shapes
bool m_useX2format; // Add X2 file header attributes. If false, attributes
// will be added as comments.
bool m_useNetAttributes; // In recent gerber files, netlist info can be added.
diff --git a/pcbnew/dialogs/dialog_plot.cpp b/pcbnew/dialogs/dialog_plot.cpp
index 77c02e8f81..87d9f05b1a 100644
--- a/pcbnew/dialogs/dialog_plot.cpp
+++ b/pcbnew/dialogs/dialog_plot.cpp
@@ -136,6 +136,9 @@ void DIALOG_PLOT::init_Dialog()
m_layerCheckListBox->Check( checkIndex );
}
+ // Option for disabling Gerber Aperture Macro (for broken Gerber readers)
+ m_disableApertMacros->SetValue( m_plotOpts.GetDisableGerberMacros() );
+
// Option for using proper Gerber extensions. Note also Protel extensions are
// a broken feature. However, for now, we need to handle it.
m_useGerberExtensions->SetValue( m_plotOpts.GetUseGerberProtelExtensions() );
@@ -720,6 +723,7 @@ void DIALOG_PLOT::applyPlotSettings()
tempOptions.SetFormat( getPlotFormat() );
+ tempOptions.SetDisableGerberMacros( m_disableApertMacros->GetValue() );
tempOptions.SetUseGerberProtelExtensions( m_useGerberExtensions->GetValue() );
tempOptions.SetUseGerberX2format( m_useGerberX2Format->GetValue() );
tempOptions.SetIncludeGerberNetlistInfo( m_useGerberNetAttributes->GetValue() );
@@ -881,7 +885,7 @@ void DIALOG_PLOT::Plot( wxCommandEvent& event )
LOCALE_IO toggle;
- PLOTTER* plotter = StartPlotBoard( board, &m_plotOpts, layer, fn.GetFullPath(), wxEmptyString );
+ PLOTTER* plotter = StartPlotBoard( board, &m_plotOpts, layer, fn.GetFullPath(), wxEmptyString );
// Print diags in messages box:
wxString msg;
diff --git a/pcbnew/dialogs/dialog_plot_base.cpp b/pcbnew/dialogs/dialog_plot_base.cpp
index 2939eaee64..8523e4ec54 100644
--- a/pcbnew/dialogs/dialog_plot_base.cpp
+++ b/pcbnew/dialogs/dialog_plot_base.cpp
@@ -228,7 +228,7 @@ DIALOG_PLOT_BASE::DIALOG_PLOT_BASE( wxWindow* parent, wxWindowID id, const wxStr
m_coordFormatCtrl->SetSelection( 0 );
gbSizer2->Add( m_coordFormatCtrl, wxGBPosition( 0, 2 ), wxGBSpan( 1, 1 ), wxEXPAND|wxRIGHT|wxLEFT, 5 );
- m_useGerberX2Format = new wxCheckBox( m_GerberOptionsSizer->GetStaticBox(), wxID_ANY, _("Use extended X2 format"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_useGerberX2Format = new wxCheckBox( m_GerberOptionsSizer->GetStaticBox(), wxID_ANY, _("Use extended X2 format (recommended)"), wxDefaultPosition, wxDefaultSize, 0 );
m_useGerberX2Format->SetToolTip( _("Use X2 Gerber file format.\nInclude mainly X2 attributes in Gerber headers.\nIf not checked, use X1 format.\nIn X1 format, these attributes are included as comments in files.") );
gbSizer2->Add( m_useGerberX2Format, wxGBPosition( 1, 1 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 30 );
@@ -238,6 +238,11 @@ DIALOG_PLOT_BASE::DIALOG_PLOT_BASE( wxWindow* parent, wxWindowID id, const wxStr
gbSizer2->Add( m_useGerberNetAttributes, wxGBPosition( 2, 1 ), wxGBSpan( 1, 2 ), wxLEFT|wxALIGN_CENTER_VERTICAL, 30 );
+ m_disableApertMacros = new wxCheckBox( m_GerberOptionsSizer->GetStaticBox(), wxID_ANY, _("Disable aperture macros (non recommended)"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_disableApertMacros->SetToolTip( _("Disable aperture macros in Gerber files\nUse *only* for broken Gerber viewers.") );
+
+ gbSizer2->Add( m_disableApertMacros, wxGBPosition( 3, 1 ), wxGBSpan( 1, 2 ), wxLEFT|wxALIGN_CENTER_VERTICAL, 30 );
+
gbSizer2->AddGrowableCol( 2 );
diff --git a/pcbnew/dialogs/dialog_plot_base.fbp b/pcbnew/dialogs/dialog_plot_base.fbp
index 4825263a0d..288e2d06a8 100644
--- a/pcbnew/dialogs/dialog_plot_base.fbp
+++ b/pcbnew/dialogs/dialog_plot_base.fbp
@@ -2345,7 +2345,7 @@
0
0
wxID_ANY
- Use extended X2 format
+ Use extended X2 format (recommended)
0
@@ -2444,6 +2444,73 @@
+
diff --git a/pcbnew/dialogs/dialog_plot_base.h b/pcbnew/dialogs/dialog_plot_base.h
index 587cddce27..89e6e69c82 100644
--- a/pcbnew/dialogs/dialog_plot_base.h
+++ b/pcbnew/dialogs/dialog_plot_base.h
@@ -99,6 +99,7 @@ class DIALOG_PLOT_BASE : public DIALOG_SHIM
wxChoice* m_coordFormatCtrl;
wxCheckBox* m_useGerberX2Format;
wxCheckBox* m_useGerberNetAttributes;
+ wxCheckBox* m_disableApertMacros;
wxStaticBoxSizer* m_HPGLOptionsSizer;
wxStaticText* m_hpglPenLabel;
wxTextCtrl* m_hpglPenCtrl;
diff --git a/pcbnew/pcb_plot_params.cpp b/pcbnew/pcb_plot_params.cpp
index f41ca02292..8eef01eb45 100644
--- a/pcbnew/pcb_plot_params.cpp
+++ b/pcbnew/pcb_plot_params.cpp
@@ -98,6 +98,7 @@ static bool setDouble( double* aTarget, double aValue, double aMin, double aMax
PCB_PLOT_PARAMS::PCB_PLOT_PARAMS()
{
m_useGerberProtelExtensions = false;
+ m_gerberDisableApertMacros = false;
m_useGerberX2format = true;
m_includeGerberNetlistInfo = true;
m_createGerberJobFile = true;
@@ -176,6 +177,9 @@ void PCB_PLOT_PARAMS::Format( OUTPUTFORMATTER* aFormatter,
aFormatter->Print( aNestLevel+1, "(%s 0x%s)\n", getTokenName( T_layerselection ),
m_layerSelection.FmtHex().c_str() );
+ aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_disableapertmacros ),
+ m_gerberDisableApertMacros ? trueStr : falseStr );
+
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_usegerberextensions ),
m_useGerberProtelExtensions ? trueStr : falseStr );
@@ -262,6 +266,8 @@ bool PCB_PLOT_PARAMS::IsSameAs( const PCB_PLOT_PARAMS &aPcbPlotParams, bool aCom
return false;
if( m_useGerberProtelExtensions != aPcbPlotParams.m_useGerberProtelExtensions )
return false;
+ if( m_gerberDisableApertMacros != aPcbPlotParams.m_gerberDisableApertMacros )
+ return false;
if( m_useGerberX2format != aPcbPlotParams.m_useGerberX2format )
return false;
if( m_includeGerberNetlistInfo != aPcbPlotParams.m_includeGerberNetlistInfo )
@@ -419,6 +425,10 @@ void PCB_PLOT_PARAMS_PARSER::Parse( PCB_PLOT_PARAMS* aPcbPlotParams )
}
break;
+ case T_disableapertmacros:
+ aPcbPlotParams->m_gerberDisableApertMacros = parseBool();
+ break;
+
case T_usegerberextensions:
aPcbPlotParams->m_useGerberProtelExtensions = parseBool();
break;
diff --git a/pcbnew/pcb_plot_params.h b/pcbnew/pcb_plot_params.h
index 18365d073e..f9d03f2fa6 100644
--- a/pcbnew/pcb_plot_params.h
+++ b/pcbnew/pcb_plot_params.h
@@ -108,6 +108,10 @@ private:
/// Include attributes from the Gerber X2 format (chapter 5 in revision J2)
bool m_useGerberX2format;
+ /// Disable aperure macros in Gerber format (only for broken Gerber readers)
+ /// Ideally, should be never selected.
+ bool m_gerberDisableApertMacros;
+
/// Include netlist info (only in Gerber X2 format) (chapter ? in revision ?)
bool m_includeGerberNetlistInfo;
@@ -291,6 +295,9 @@ public:
void SetOutputDirectory( wxString aDir ) { m_outputDirectory = aDir; }
wxString GetOutputDirectory() const { return m_outputDirectory; }
+ void SetDisableGerberMacros( bool aDisable ) { m_gerberDisableApertMacros = aDisable; }
+ bool GetDisableGerberMacros() const { return m_gerberDisableApertMacros; }
+
void SetUseGerberX2format( bool aUse ) { m_useGerberX2format = aUse; }
bool GetUseGerberX2format() const { return m_useGerberX2format; }
diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp
index 1e141b480b..e8fca1cb16 100644
--- a/pcbnew/plot_board_layers.cpp
+++ b/pcbnew/plot_board_layers.cpp
@@ -1143,6 +1143,7 @@ PLOTTER* StartPlotBoard( BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts, int aLayer,
bool useX2mode = plotOpts.GetUseGerberX2format();
GERBER_PLOTTER* gbrplotter = static_cast ( plotter );
+ gbrplotter->DisableApertMacros( plotOpts.GetDisableGerberMacros() );
gbrplotter->UseX2format( useX2mode );
gbrplotter->UseX2NetAttributes( plotOpts.GetIncludeGerberNetlistInfo() );