1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
22  */
23 
24 /**
25  * @file pcbnew/pcbplot.h
26  * @brief Board plot function definition file.
27  */
28 
29 #ifndef PCBPLOT_H_
30 #define PCBPLOT_H_
31 
32 #include <layer_ids.h>
33 #include <pad_shapes.h>
34 #include <pcb_plot_params.h>
35 #include <settings/color_settings.h>
36 #include <settings/settings_manager.h>
37 
38 class PLOTTER;
39 class PCB_TEXT;
40 class PAD;
41 class PCB_SHAPE;
42 class PCB_DIMENSION_BASE;
43 class FOOTPRINT;
44 class FP_SHAPE;
45 class PCB_TARGET;
46 class FP_TEXT;
47 class ZONE;
48 class BOARD;
49 class REPORTER;
50 class wxFileName;
51 
52 
53 // Define min and max reasonable values for plot/print scale
54 #define PLOT_MIN_SCALE 0.01
55 #define PLOT_MAX_SCALE 100.0
56 
57 
58 
59 // A helper class to plot board items
60 class BRDITEMS_PLOTTER : public PCB_PLOT_PARAMS
61 {
62 public:
BRDITEMS_PLOTTER(PLOTTER * aPlotter,BOARD * aBoard,const PCB_PLOT_PARAMS & aPlotOpts)63     BRDITEMS_PLOTTER( PLOTTER* aPlotter, BOARD* aBoard, const PCB_PLOT_PARAMS& aPlotOpts )
64             : PCB_PLOT_PARAMS( aPlotOpts )
65     {
66         m_plotter = aPlotter;
67         m_board = aBoard;
68     }
69 
70     /**
71      * @return a 'width adjustment' for the postscript engine
72      * (useful for controlling toner bleeding during direct transfer)
73      * added to track width and via/pads size
74      */
getFineWidthAdj()75     int getFineWidthAdj() const
76     {
77         if( GetFormat() == PLOT_FORMAT::POST )
78             return GetWidthAdjust();
79         else
80             return 0;
81     }
82 
83     // Basic functions to plot a board item
SetLayerSet(LSET aLayerMask)84     void SetLayerSet( LSET aLayerMask ) { m_layerMask = aLayerMask; }
85     void PlotFootprintGraphicItems( const FOOTPRINT* aFootprint );
86     void PlotFootprintGraphicItem( const FP_SHAPE* aShape );
87     void PlotFootprintTextItem( const FP_TEXT* aText, const COLOR4D& aColor );
88 
89     /*
90      * Reference, Value, and other fields are plotted only if the corresponding option is enabled.
91      * Invisible text fields are plotted only if PlotInvisibleText option is set.
92      */
93     void PlotFootprintTextItems( const FOOTPRINT* aFootprint );
94 
95     void PlotDimension( const PCB_DIMENSION_BASE* aDim );
96     void PlotPcbTarget( const PCB_TARGET* aMire );
97     void PlotFilledAreas( const ZONE* aZone, const SHAPE_POLY_SET& aPolysList );
98     void PlotPcbText( const PCB_TEXT* aText );
99     void PlotPcbShape( const PCB_SHAPE* aShape );
100 
101     /**
102      * Plot a pad.
103      *
104      * Unlike other items, a pad had not a specific color and be drawn as a non filled item
105      * although the plot mode is filled color and plot mode are needed by this function.
106      */
107     void PlotPad( const PAD* aPad, const COLOR4D& aColor, OUTLINE_MODE aPlotMode );
108 
109     /**
110      * Plot items like text and graphics but not tracks and footprints.
111      */
112     void PlotBoardGraphicItems();
113 
114     /**
115      * Draw a drill mark for pads and vias.
116      *
117      * Must be called after all drawings, because it redraws the drill mark on a pad or via, as
118      * a negative (i.e. white) shape in FILLED plot mode (for PS and PDF outputs).
119      */
120     void PlotDrillMarks();
121 
122     /**
123      * White color is special because it cannot be seen on a white paper in B&W mode. It is
124      * plotted as white but other colors are plotted in BLACK so the returned color is LIGHTGRAY
125      * when the layer color is WHITE.
126      *
127      * @param aLayer is the layer id.
128      * @return the layer color.
129      */
130     COLOR4D getColor( LAYER_NUM aLayer ) const;
131 
132 private:
133     /**
134      * Helper function to plot a single drill mark.
135      *
136      * It compensate and clamp the drill mark size depending on the current plot options.
137      */
138     void plotOneDrillMark( PAD_DRILL_SHAPE_T aDrillShape, const wxPoint& aDrillPos,
139                            const wxSize& aDrillSize, const wxSize& aPadSize,
140                            double aOrientation, int aSmallDrill );
141 
142     PLOTTER*    m_plotter;
143     BOARD*      m_board;
144     LSET        m_layerMask;
145 };
146 
147 PLOTTER* StartPlotBoard( BOARD* aBoard,
148                          const PCB_PLOT_PARAMS* aPlotOpts,
149                          int aLayer,
150                          const wxString& aFullFileName,
151                          const wxString& aSheetDesc );
152 
153 /**
154  * Plot one copper or technical layer.
155  *
156  * It prepares options and calls the specialized plot function according to the layer type.
157  *
158  * @param aBoard is the board to plot.
159  * @param aPlotter is the plotter to use.
160  * @param aLayer is the layer id to plot.
161  * @param aPlotOpt is the plot options (files, sketch). Has meaning for some formats only.
162  */
163 void PlotOneBoardLayer( BOARD* aBoard, PLOTTER* aPlotter, PCB_LAYER_ID aLayer,
164                         const PCB_PLOT_PARAMS& aPlotOpt );
165 
166 /**
167  * Plot copper or technical layers.
168  *
169  * This is not used for silk screen layers because these layers have specific requirements.
170  * This is  mainly for pads.
171  *
172  * @param aBoard is the board to plot.
173  * @param aPlotter is the plotter to use.
174  * @param aLayerMask is the mask to define the layers to plot.
175  * @param aPlotOpt is the plot options (files, sketch). Has meaning for some formats only.
176  *
177  * aPlotOpt has 3 important options to control this plot,
178  * which are set, depending on the layer type to plot
179  *      SetEnablePlotVia( bool aEnable )
180  *          aEnable = true to plot vias, false to skip vias (has meaning
181  *                      only for solder mask layers).
182  *      SetSkipPlotNPTH_Pads( bool aSkip )
183  *          aSkip = true to skip NPTH Pads, when the pad size and the pad hole
184  *                  have the same size. Used in GERBER format only.
185  *      SetDrillMarksType( DrillMarksType aVal ) control the actual hole:
186  *              no hole, small hole, actual hole
187  */
188 void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
189                         const PCB_PLOT_PARAMS& aPlotOpt );
190 
191 /**
192  * Plot copper outline of a copper layer.
193  *
194  * @param aBoard is the board to plot.
195  * @param aPlotter is the plotter to use.
196  * @param aLayerMask is the mask to define the layers to plot.
197  * @param aPlotOpt is the plot options. Has meaning for some formats only.
198  */
199 void PlotLayerOutlines( BOARD* aBoard, PLOTTER* aPlotter,
200                         LSET aLayerMask, const PCB_PLOT_PARAMS& aPlotOpt );
201 
202 /**
203  * Complete a plot filename.
204  *
205  * It forces the output directory, adds a suffix to the name, and sets the specified extension.
206  * The suffix is usually the layer name and replaces illegal file name character in the suffix
207  * with an underscore character.
208  *
209  * @param aFilename is the file name to initialize that contains the base filename.
210  * @param aOutputDir is the path.
211  * @param aSuffix is the suffix to add to the base filename.
212  * @param aExtension is the file extension.
213  */
214 void BuildPlotFileName( wxFileName*     aFilename,
215                         const wxString& aOutputDir,
216                         const wxString& aSuffix,
217                         const wxString& aExtension );
218 
219 
220 /**
221  * @return the appropriate Gerber file extension for \a aLayer
222  */
223 const wxString GetGerberProtelExtension( LAYER_NUM aLayer );
224 
225 /**
226  * Return the "file function" attribute for \a aLayer, as defined in the
227  * Gerber file format specification J1 (chapter 5).
228  *
229  * The returned string includes the "%TF.FileFunction" attribute prefix and the "*%" suffix.
230  *
231  * @param aBoard is the board, needed to get the total count of copper layers.
232  * @param aLayer is the layer number to create the attribute for.
233  * @return The attribute, as a text string
234  */
235 const wxString GetGerberFileFunctionAttribute( const BOARD* aBoard, LAYER_NUM aLayer );
236 
237 /**
238  * Calculate some X2 attributes as defined in the Gerber file format specification J4
239  * (chapter 5) and add them the to the gerber file header.
240  *
241  * TF.GenerationSoftware
242  * TF.CreationDate
243  * TF.ProjectId
244  * file format attribute is not added
245  *
246  * @param aPlotter is the current plotter.
247  * @param aBoard is the board, needed to extract some info.
248  * @param aUseX1CompatibilityMode set to false to generate X2 attributes, true to
249  *        use X1 compatibility (X2 attributes added as structured comments,
250  *        starting by "G04 #@! " followed by the X2 attribute
251  */
252 void AddGerberX2Header( PLOTTER* aPlotter, const BOARD* aBoard,
253                         bool aUseX1CompatibilityMode = false );
254 
255 /**
256  * Calculate some X2 attributes as defined in the Gerber file format specification and add them
257  * to the gerber file header.
258  *
259  * TF.GenerationSoftware
260  * TF.CreationDate
261  * TF.ProjectId
262  * TF.FileFunction
263  * TF.FilePolarity
264  *
265  * @param aPlotter is the current plotter.
266  * @param aBoard is the board, needed to extract some info.
267  * @param aLayer is the layer number to create the attribute for.
268  * @param aUseX1CompatibilityMode set to false to generate X2 attributes, true to use X1
269  *        compatibility (X2 attributes added as structured comments, starting by "G04 #@! "
270  *        followed by the X2 attribute.
271  */
272 void AddGerberX2Attribute( PLOTTER* aPlotter, const BOARD* aBoard,
273                            LAYER_NUM aLayer, bool aUseX1CompatibilityMode );
274 
275 #endif // PCBPLOT_H_
276