File: plotter_gerber.h

package info (click to toggle)
kicad 9.0.7%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 771,448 kB
  • sloc: cpp: 969,355; ansic: 121,001; xml: 66,428; python: 18,387; sh: 1,010; awk: 301; asm: 292; makefile: 228; javascript: 167; perl: 10
file content (400 lines) | stat: -rw-r--r-- 18,673 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
/*
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 * Copyright (C) 2020 Jean-Pierre Charras, jp.charras at wanadoo.fr
 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "plotter.h"
#include "gbr_plotter_apertures.h"

class SHAPE_ARC;
class GBR_METADATA;

class GERBER_PLOTTER : public PLOTTER
{
public:
    GERBER_PLOTTER();

    virtual PLOT_FORMAT GetPlotterType() const override
    {
        return PLOT_FORMAT::GERBER;
    }

    static wxString GetDefaultFileExtension()
    {
        return wxString( wxT( "gbr" ) );
    }

    /**
     * Write GERBER header to file initialize global variable g_Plot_PlotOutputFile.
     */
    virtual bool StartPlot( const wxString& pageNumber ) override;
    virtual bool EndPlot() override;
    virtual void SetCurrentLineWidth( int aLineWidth, void* aData = nullptr ) override;

    // RS274X has no dashing, nor colors
    virtual void SetDash( int aLineWidth, LINE_STYLE aLineStyle ) override
    {
    }

    virtual void SetColor( const COLOR4D& aColor ) override {}

    // Currently, aScale and aMirror are not used in gerber plotter
    virtual void SetViewport( const VECTOR2I& aOffset, double aIusPerDecimil,
                              double aScale, bool aMirror ) override;

    // Basic plot primitives
    virtual void Rect( const VECTOR2I& p1, const VECTOR2I& p2, FILL_T fill,
                       int width = USE_DEFAULT_LINE_WIDTH ) override;
    virtual void Circle( const VECTOR2I& pos, int diametre, FILL_T fill,
                         int width = USE_DEFAULT_LINE_WIDTH ) override;
    virtual void Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
                      const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill,
                      int aWidth = USE_DEFAULT_LINE_WIDTH ) override;

    // These functions plot an item and manage X2 gerber attributes
    virtual void ThickSegment( const VECTOR2I& start, const VECTOR2I& end, int width,
                               OUTLINE_MODE tracemode, void* aData ) override;

    virtual void ThickRect( const VECTOR2I& p1, const VECTOR2I& p2, int width,
                            OUTLINE_MODE tracemode, void* aData ) override;

    virtual void ThickCircle( const VECTOR2I& pos, int diametre, int width,
                              OUTLINE_MODE tracemode, void* aData ) override;

    virtual void FilledCircle( const VECTOR2I& pos, int diametre,
                              OUTLINE_MODE tracemode, void* aData ) override;

    /**
     * Gerber polygon: they can (and *should*) be filled with the
     * appropriate G36/G37 sequence
     */
    virtual void PlotPoly( const std::vector<VECTOR2I>& aCornerList, FILL_T aFill,
                           int aWidth = USE_DEFAULT_LINE_WIDTH, void* aData = nullptr ) override;

    virtual void PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_T aFill,
                           int aWidth = USE_DEFAULT_LINE_WIDTH, void* aData = nullptr ) override;

    /**
     * Similar to PlotPoly(), plot a filled polygon using Gerber region,
     * therefore adding X2 attributes to the region object, like TA.xxx
     */
    void PlotPolyAsRegion( const SHAPE_LINE_CHAIN& aPoly, FILL_T aFill,
                           int aWidth, GBR_METADATA* aGbrMetadata );

    virtual void PenTo( const VECTOR2I& pos, char plume ) override;

    virtual void Text( const VECTOR2I&        aPos,
                       const COLOR4D&         aColor,
                       const wxString&        aText,
                       const EDA_ANGLE&       aOrient,
                       const VECTOR2I&        aSize,
                       enum GR_TEXT_H_ALIGN_T aH_justify,
                       enum GR_TEXT_V_ALIGN_T aV_justify,
                       int                    aWidth,
                       bool                   aItalic,
                       bool                   aBold,
                       bool                   aMultilineAllowed,
                       KIFONT::FONT*          aFont,
                       const KIFONT::METRICS& aFontMetrics,
                       void*                  aData = nullptr ) override;


    virtual void PlotText( const VECTOR2I&        aPos,
                           const COLOR4D&         aColor,
                           const wxString&        aText,
                           const TEXT_ATTRIBUTES& aAttributes,
                           KIFONT::FONT*          aFont,
                           const KIFONT::METRICS& aFontMetrics,
                           void*                  aData = nullptr ) override;

    /**
     * Filled circular flashes are stored as apertures
     */
    virtual void FlashPadCircle( const VECTOR2I& pos, int diametre,
                                 OUTLINE_MODE trace_mode, void* aData ) override;

    virtual void FlashPadOval( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
                               const EDA_ANGLE& aOrient, OUTLINE_MODE aTraceMode,
                               void* aData ) override;

    virtual void FlashPadRect( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
                               const EDA_ANGLE& aOrient, OUTLINE_MODE aTraceMode,
                               void* aData ) override;

    virtual void FlashPadRoundRect( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
                                    int aCornerRadius, const EDA_ANGLE& aOrient,
                                    OUTLINE_MODE aTraceMode, void* aData ) override;
    virtual void FlashPadCustom( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
                                 const EDA_ANGLE& aPadOrient, SHAPE_POLY_SET* aPolygons,
                                 OUTLINE_MODE aTraceMode, void* aData ) override;

    virtual void FlashPadTrapez( const VECTOR2I& aPadPos, const VECTOR2I* aCorners,
                                 const EDA_ANGLE& aPadOrient, OUTLINE_MODE aTraceMode,
                                 void* aData ) override;

    virtual void FlashRegularPolygon( const VECTOR2I& aShapePos, int aDiameter, int aCornerCount,
                                      const EDA_ANGLE& aOrient, OUTLINE_MODE aTraceMode,
                                      void* aData ) override;

    /**
     * Flash a chamfered round rect pad.
     *
     * @param aShapePos is the position of the pad shape.
     * @param aPadSize is the size of the rectangle.
     * @param aCornerRadius is the radius of rounded corners.
     * @param aChamferRatio is the chamfer value (ratio < 0.5 between smallest size and chamfer).
     * @param aChamferPositions is the identifier of the corners to chamfer:
     *  0 = no chamfer
     *  1 = TOP_LEFT
     *  2 = TOP_RIGHT
     *  4 = BOTTOM_LEFT
     *  8 = BOTTOM_RIGHT
     * @param aPadOrient is the rotation of the shape.
     * @param aPlotMode is the drawing mode, FILLED or SKETCH.
     * @param aData is the a reference to Gerber attributes descr.
     */
    void FlashPadChamferRoundRect( const VECTOR2I& aShapePos, const VECTOR2I& aPadSize,
                                   int aCornerRadius, double aChamferRatio,
                                   int aChamferPositions, const EDA_ANGLE& aPadOrient,
                                   OUTLINE_MODE aPlotMode, void* aData );

    /**
     * Plot a Gerber region: similar to PlotPoly but plot only filled polygon,
     * and add the TA.AperFunction if aGbrMetadata contains this attribute, and clear it
     * after plotting.
     */
    void PlotGerberRegion( const std::vector<VECTOR2I>& aCornerList, GBR_METADATA* aGbrMetadata );

    void PlotGerberRegion( const SHAPE_LINE_CHAIN& aPoly, GBR_METADATA* aGbrMetadata );

    /**
     * Change the plot polarity and begin a new layer.
     *
     * Used to 'scratch off' silk screen away from solder mask.
     */
    virtual void SetLayerPolarity( bool aPositive ) override;

    /**
     * Selection of Gerber units and resolution (number of digits in mantissa).
     *
     * Should be called only after SetViewport() is called.
     *
     * @param aResolution is the number of digits in mantissa of coordinate
     *                    use 5 or 6 for mm and 6 or 7 for inches
     *                    do not use value > 6 (mm) or > 7 (in) to avoid overflow.
     * @param aUseInches use true to use inches, false to use mm (default).
     */
    virtual void SetGerberCoordinatesFormat( int aResolution, bool aUseInches = false ) override;

    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 use 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).
     *
     * @param aData can define any parameter.
     */
    virtual void StartBlock( void* aData ) override;

    /**
     * Define the end of a group of drawing items the group is started by StartBlock().
     *
     * Used in X2 format with netlist attributes.
     *
     * @param aData can define any parameter
     */
    virtual void EndBlock( void* aData ) override;

    /**
     * Remove (clear) all attributes from object attributes dictionary (TO. and TA commands)
     * similar to clearNetAttribute(), this is an unconditional reset of TO. and TA. attributes.
     */
    void ClearAllAttributes();

    /**
     * @param aSize is the size of tool.
     * @param aRadius is the radius used for some shapes tool (oval, roundrect macros).
     * @param aRotation is the rotation of tool (primitives round, oval rect accept only 0.0).
     * @param aType is the type ( shape ) of tool.
     * @param aApertureAttribute is an aperture attribute of the tool (a tool can have only one
     *                           attribute) 0 = no specific attribute.
     * @return an index to the aperture in aperture list which meets the size and type of tool
     *         if the aperture does not exist, it is created and entered in aperture list.
     */
    int GetOrCreateAperture( const VECTOR2I& aSize, int aRadius, const EDA_ANGLE& aRotation,
                             APERTURE::APERTURE_TYPE aType, int aApertureAttribute );

    /**
     * @param aCorners is the corner list.
     * @param aRotation is the rotation of tool.
     * @param aType is the type ( shape ) of tool that can manage a list of corners (polygon).
     * @param aApertureAttribute is an aperture attribute of the tool (a tool can have only one
     *        attribute) 0 = no specific attribute.
     * @return an index to the aperture in aperture list which meets the data and type of tool
     *         if the aperture does not exist, it is created and entered in aperture list.
     */
    int GetOrCreateAperture( const std::vector<VECTOR2I>& aCorners, const EDA_ANGLE& aRotation,
                             APERTURE::APERTURE_TYPE aType, int aApertureAttribute );

protected:
    virtual void ThickArc( const VECTOR2D& aCentre, const EDA_ANGLE& aStartAngle,
                           const EDA_ANGLE& aAngle, double aRadius, int aWidth,
                           OUTLINE_MODE aTraceMode, void* aData ) override;

    /**
     * Plot a round rect (a round rect shape in fact) as a Gerber region using lines and arcs
     * for corners.
     *
     * @note Only the G36 ... G37 region is created.
     *
     * @param aRectCenter is the center of the rectangle.
     * @param aSize is the size of the rectangle.
     * @param aCornerRadius is the radius of the corners.
     * @param aOrient is the rotation of the rectangle.
     */
    void plotRoundRectAsRegion( const VECTOR2I& aRectCenter, const VECTOR2I& aSize,
                                int aCornerRadius, const EDA_ANGLE& aOrient );
    /**
     * Plot a Gerber arc.
     *
     * If aPlotInRegion = true, the current pen position will not be initialized to the arc
     * start position, and therefore the arc can be used to define a region outline item
     * a line will be created from current position to arc start point.  If aPlotInRegion
     * = false, the current pen position will be initialized to the arc start position, to
     * plot an usual arc item.  The line thickness is not initialized in plotArc, and must
     * be initialized before calling it if needed.
     */
    void plotArc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aEndAngle,
                  double aRadius, bool aPlotInRegion );
    void plotArc( const SHAPE_ARC& aArc, bool aPlotInRegion );

    /**
     * Pick an existing aperture or create a new one, matching the size, type and attributes.
     *
     * Write the DCode selection on gerber file.
     */
    void selectAperture( const VECTOR2I& aSize, int aRadius, const EDA_ANGLE& aRotation,
                         APERTURE::APERTURE_TYPE aType, int aApertureAttribute );
    /**
     * Pick an existing aperture or create a new one, matching the aDiameter, aPolygonRotation,
     * type and attributes.
     *
     * It apply only to apertures with type = AT_REGULAR_POLY3 to AT_REGULAR_POLY12
     * write the DCode selection on gerber file
     */
    void selectAperture( const std::vector<VECTOR2I>& aCorners, const EDA_ANGLE& aPolygonRotation,
                         APERTURE::APERTURE_TYPE aType, int aApertureAttribute );

    /**
     * Pick an existing aperture or create a new one, matching the corner list, aRotDegree,
     * type and attributes.
     *
     * It only applies to apertures managing a polygon that differs from AT_REGULAR_POLY3
     * to AT_REGULAR_POLY12 (for instance APER_MACRO_TRAPEZOID ) write the DCode selection
     * on gerber file.
     */
    void selectAperture( int aDiameter, const EDA_ANGLE& aRotation,
                         APERTURE::APERTURE_TYPE aType, int aApertureAttribute );

    /**
     * Emit a D-Code record, using proper conversions to format a leading zero omitted gerber
     * coordinate.
     *
     * For n decimal positions, see header generation in start_plot.
     */
    void emitDcode( const VECTOR2D& pt, int dcode );

    /**
     * Print a Gerber net attribute object record.
     *
     * In a gerber file, a net attribute is owned by a graphic object formatNetAttribute must
     * be called before creating the object.  The generated string depends on the type of
     * netlist info.
     *
     * @param aData contains the data to format.
     */
    void formatNetAttribute( GBR_NETLIST_METADATA* aData );

    /**
     * Clear a Gerber net attribute record (clear object attribute dictionary)
     * and output the clear object attribute dictionary command to gerber file
     * has effect only if a net attribute is stored in m_objectAttributesDictionary.
     */
    void clearNetAttribute();

    // the attributes dictionary created/modified by %TO, attached to objects, when they are created
    // by D01, D03, G36/G37 commands
    // standard attributes are .P, .C and .N
    // this is used by gerber readers when creating a new object. Cleared by %TD command
    // Note: m_objectAttributesDictionary can store more than one attribute
    // the string stores the line(s) actually written to the gerber file
    // it can store a .P, .C or .N attribute, or 2 or 3 attributes, separated by a \n char (EOL)
    std::string   m_objectAttributesDictionary;

    // The last aperture attribute generated (only one aperture attribute can be set)
    int           m_apertureAttribute;

    FILE* workFile;
    FILE* finalFile;
    wxString m_workFilename;

    /**
     * Generate the table of D codes
     */
    void writeApertureList();

    std::vector<APERTURE> m_apertures;  // The list of available apertures
    int     m_currentApertureIdx;       // The index of the current aperture in m_apertures
    bool    m_hasApertureRoundRect;     // true is at least one round rect aperture is in use
    bool    m_hasApertureRotOval;       // true is at least one oval rotated aperture is in use
    bool    m_hasApertureRotRect;       // true is at least one rect. rotated aperture is in use
    bool    m_hasApertureOutline4P;     // true is at least one 4 corners outline (free polygon
                                        // with 4 corners) aperture is in use
    bool    m_hasApertureChamferedRect; // true is at least one chamfered rect is in use
                                        // (with no rounded corner)

    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.
                                       // It will be added if this param is true, using X2 or
                                       // X1 format

    // A list of aperture macros defined "on the fly" because the number of parameters is not
    // defined: this is the case of the macro using the primitive 4 to create a polygon.
    // The number of vertices is not known for free polygonal shapes, and an aperture macro
    // must be created for each specific polygon
    APER_MACRO_FREEPOLY_LIST m_am_freepoly_list;
};