summaryrefslogtreecommitdiff
path: root/gerbview/class_aperture_macro.h
blob: 959a2546aa5e104a7ad2c3bd94c0d6f24acd0bed (plain)
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
/**
 * @file class_aperture_macro.h
 */

#ifndef _APERTURE_MACRO_H_
#define _APERTURE_MACRO_H_

/*
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 * Copyright (C) 1992-2010 Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
 * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
 * Copyright (C) 1992-2010 KiCad Developers, see change_log.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 2
 * 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, you may find one here:
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * or you may search the http://www.gnu.org website for the version 2 license,
 * or you may write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 */

#include <vector>
#include <set>

#include <base_struct.h>
#include <class_am_param.h>

/*
 *  An aperture macro defines a complex shape and is a list of aperture primitives.
 *  Each aperture primitive defines a simple shape (circle, rect, regular polygon...)
 *  Inside a given aperture primitive, a fixed list of parameters defines info
 *  about the shape: size, thickness, number of vertex ...
 *
 *  Each parameter can be an immediate value or a defered value.
 *  When value is defered, it is defined when the aperture macro is instancied by
 *  an ADD macro command
 *  Note also a defered parameter can be defined in aperture macro,
 *  but outside aperture primitives. Example
 *  %AMRECTHERM*
 *  $4=$3/2*    parameter $4 is half value of parameter $3
 *  21,1,$1-$3,$2-$3,0-$1/2-$4,0-$2/2-$4,0*
 *  For the aperture primitive, parameters $1 to $3 will be defined in ADD command,
 *  and $4 is defined inside the macro
 */

/**
 * Enum AM_PRIMITIVE_ID
 * is the set of all "aperture macro primitives" (primitive numbers).  See
 * Table 3 in http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
 * aperture macro primitives are basic shapes which can be combined to create a complex shape
 * This complex shape is flashed.
 */
enum AM_PRIMITIVE_ID {
    AMP_UNKNOWN = -1,           // A value for uninitialized AM_PRIMITIVE.
    AMP_COMMENT = 0,            // A primitive description is not really a primitive, this is a comment
    AMP_CIRCLE  = 1,            // Circle. (diameter and position)
    AMP_LINE2   = 2,            // Line with rectangle ends. (Width, start and end pos + rotation)
    AMP_LINE20  = 20,           // Same as AMP_LINE2
    AMP_LINE_CENTER = 21,       // Rectangle. (height, width and center pos + rotation)
    AMP_LINE_LOWER_LEFT = 22,   // Rectangle. (height, width and left bottom corner pos + rotation)
    AMP_EOF     = 3,            // End Of File marquer: not really a shape
    AMP_OUTLINE = 4,            // Free polyline (n corners + rotation)
    AMP_POLYGON = 5,            // Closed regular polygon(diameter, number of vertices (3 to 10), rotation)
    AMP_MOIRE   = 6,            // A cross hair with n concentric circles + rotation
    AMP_THERMAL = 7             // Thermal shape (pos, outer and inner diameter, cross hair thickness + rotation)
};


/**
 * Struct AM_PRIMITIVE
 * holds an aperture macro primitive as given in Table 3 of
 * http://gerbv.sourceforge.net/docs/rs274xrevd_e.pdf
 */
class AM_PRIMITIVE
{
public:
    AM_PRIMITIVE_ID primitive_id;       ///< The primitive type
    AM_PARAMS       params;             ///< A sequence of parameters used by
                                        //   the primitive
    bool            m_GerbMetric;       // units for this primitive:
                                        // false = Inches, true = metric
public: AM_PRIMITIVE( bool aGerbMetric, AM_PRIMITIVE_ID aId = AMP_UNKNOWN )
    {
        primitive_id = aId;
        m_GerbMetric = aGerbMetric;
    }


    ~AM_PRIMITIVE() {}

    /**
     * Function GetExposure
     * returns the first parameter in integer form.  Some but not all primitives
     * use the first parameter as an exposure control.
     */
    int  GetExposure( GERBER_DRAW_ITEM* aParent ) const;

    /**
     * Function mapExposure
     * translates the first parameter from an aperture macro into a current
     * exposure setting.
     * @param aParent = a GERBER_DRAW_ITEM that handle:
     *    ** m_Exposure A dynamic setting which can change throughout the
     *          reading of the gerber file, and it indicates whether the current tool
     *          is lit or not.
     *    ** m_ImageNegative A dynamic setting which can change throughout the reading
     *          of the gerber file, and it indicates whether the current D codes are to
     *          be interpreted as erasures or not.
     * @return true to draw with current color, false to draw with alt color (erase)
     */
    bool mapExposure( GERBER_DRAW_ITEM* aParent );

    /* Draw functions: */

    /**
     * Function DrawBasicShape
     * Draw the primitive shape for flashed items.
     * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
     * @param aClipBox = DC clip box (NULL is no clip)
     * @param aDC = device context
     * @param aColor = the normal color to use
     * @param aAltColor = the color used to draw with "reverse" exposure mode (used in aperture macros only)
     * @param aShapePos = the actual shape position
     * @param aFilledShape = true to draw in filled mode, false to draw in skecth mode
     */
    void DrawBasicShape( GERBER_DRAW_ITEM* aParent, EDA_RECT* aClipBox, wxDC* aDC,
                         EDA_COLOR_T aColor, EDA_COLOR_T aAltColor, wxPoint aShapePos, bool aFilledShape );

    /** GetShapeDim
     * Calculate a value that can be used to evaluate the size of text
     * when displaying the D-Code of an item
     * due to the complexity of the shape of some primitives
     * one cannot calculate the "size" of a shape (only a bounding box)
     * but here, the "dimension" of the shape is the diameter of the primitive
     * or for lines the width of the line
     * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
     * @return a dimension, or -1 if no dim to calculate
     */
    int  GetShapeDim( GERBER_DRAW_ITEM* aParent );

private:

    /**
     * Function ConvertShapeToPolygon
     * convert a shape to an equivalent polygon.
     * Arcs and circles are approximated by segments
     * Useful when a shape is not a graphic primitive (shape with hole,
     * rotated shape ... ) and cannot be easily drawn.
     */
    void ConvertShapeToPolygon( GERBER_DRAW_ITEM* aParent, std::vector<wxPoint>& aBuffer );
};


typedef std::vector<AM_PRIMITIVE> AM_PRIMITIVES;

/**
 * Struct APERTURE_MACRO
 * helps support the "aperture macro" defined within standard RS274X.
 */
struct APERTURE_MACRO
{
    wxString      name;             ///< The name of the aperture macro
    AM_PRIMITIVES primitives;       ///< A sequence of AM_PRIMITIVEs

    /*  A defered parameter can be defined in aperture macro,
     *  but outside aperture primitives. Example
     *  %AMRECTHERM*
     *  $4=$3/2*    parameter $4 is half value of parameter $3
     * m_localparamStack handle a list of local defered parameters
     */
    AM_PARAMS m_localparamStack;

    /**
     * function GetLocalParam
     * Usually, parameters are defined inside the aperture primitive
     * using immediate mode or defered mode.
     * in defered mode the value is defined in a DCODE that want to use the aperture macro.
     * But some parameters are defined outside the aperture primitive
     * and are local to the aperture macro
     * @return the value of a defered parameter defined inside the aperture macro
     * @param aDcode = the D_CODE that uses this apertur macro and define defered parameters
     * @param aParamId = the param id (defined by $3 or $5 ..) to evaluate
     */
    double GetLocalParam( const D_CODE* aDcode, unsigned aParamId ) const;

   /**
     * Function DrawApertureMacroShape
     * Draw the primitive shape for flashed items.
     * When an item is flashed, this is the shape of the item
     * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
     * @param aClipBox = DC clip box (NULL is no clip)
     * @param aDC = device context
     * @param aColor = the normal color to use
     * @param aAltColor = the color used to draw with "reverse" exposure mode (used in aperture macros only)
     * @param aShapePos = the actual shape position
     * @param aFilledShape = true to draw in filled mode, false to draw in skecth mode
     */
    void DrawApertureMacroShape( GERBER_DRAW_ITEM* aParent, EDA_RECT* aClipBox, wxDC* aDC,
                                 EDA_COLOR_T aColor, EDA_COLOR_T aAltColor, wxPoint aShapePos, bool aFilledShape );

    /**
     * Function GetShapeDim
     * Calculate a value that can be used to evaluate the size of text
     * when displaying the D-Code of an item
     * due to the complexity of a shape using many primitives
     * one cannot calculate the "size" of a shape (only abounding box)
     * but most of aperture macro are using one or few primitives
     * and the "dimension" of the shape is the diameter of the primitive
     * (or the max diameter of primitives)
     * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
     * @return a dimension, or -1 if no dim to calculate
     */
    int  GetShapeDim( GERBER_DRAW_ITEM* aParent );

    /**
     * Function HasNegativeItems
     * @param aParent = the parent GERBER_DRAW_ITEM which is actually drawn
     * @return true if this macro has at least one shape (using aperture primitives)
     *    must be drawn in background color
     * used to optimize screen refresh (when no items are in background color
     * refresh can be faster)
     */
    bool HasNegativeItems( GERBER_DRAW_ITEM* aParent );
};


/**
 * Struct APERTURE_MACRO_less_than
 * is used by std:set<APERTURE_MACRO> instantiation which uses
 * APERTURE_MACRO.name as its key.
 */
struct APERTURE_MACRO_less_than
{
    // a "less than" test on two APERTURE_MACROs (.name wxStrings)
    bool operator()( const APERTURE_MACRO& am1, const APERTURE_MACRO& am2 ) const
    {
        return am1.name.Cmp( am2.name ) < 0;  // case specific wxString compare
    }
};


/**
 * Type APERTURE_MACRO_SET
 * is a sorted collection of APERTURE_MACROS whose key is the name field in
 * the APERTURE_MACRO.
 */
typedef std::set<APERTURE_MACRO, APERTURE_MACRO_less_than> APERTURE_MACRO_SET;
typedef std::pair<APERTURE_MACRO_SET::iterator, bool>      APERTURE_MACRO_SET_PAIR;


#endif  // ifndef _APERTURE_MACRO_H_