1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2018-2020 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
23  */
24 
25 /**
26  * Handle special data (items attributes) during plot.
27  *
28  * Used in Gerber plotter to generate auxiliary data during plot (for instance info associated
29  * to apertures and flashed pads)
30  *
31  * @file gbr_metadata.h
32  */
33 
34 #ifndef GBR_METADATA_H
35 #define GBR_METADATA_H
36 
37 #include <gbr_netlist_metadata.h>
38 
39 /**
40  * Create a gerber TF.CreationDate attribute.
41  *
42  * The attribute value must conform to the full version of the ISO 8601 date and time format,
43  * including time and time zone.
44  *
45  * Example of structured comment (compatible X1 gerber)
46  *  G04 #@! TF.CreationDate,2018-11-21T08:49:16+01:00* (example of X1 attribute)
47  *
48  * Example NC drill files
49  *  ; #@! TF.CreationDate,2018-11-21T08:49:16+01:00*    (example of NC drill comment)
50  *
51  * Example of X2 attribute:
52  *  %TF.CreationDate,2018-11-06T08:25:24+01:00*%
53  *
54  * @note This is the date the Gerber file is effectively created, not the time the project
55  *       PCB was started.
56  *
57  * @param aFormat string compatibility: X1, X2, GBRJOB or NC drill syntax.
58  */
59 enum GBR_NC_STRING_FORMAT       // Options for string format in some attribute strings
60 {
61     GBR_NC_STRING_FORMAT_X1,
62     GBR_NC_STRING_FORMAT_X2,
63     GBR_NC_STRING_FORMAT_GBRJOB,
64     GBR_NC_STRING_FORMAT_NCDRILL
65 };
66 wxString GbrMakeCreationDateAttributeString( GBR_NC_STRING_FORMAT aFormat );
67 
68 
69 /**
70  * Build a project GUID using format RFC4122 Version 1 or 4 from the project name, because
71  * a KiCad project has no specific GUID.
72  *
73  * RFC4122 is used mainly for its syntax, because fields have no meaning for Gerber files
74  * and therefore the GUID generated has no meaning because it do not use any time and time
75  * stamp specific to the project, just a random pattern (random is here a pattern specific
76  * to a project).
77  *
78  * See en.wikipedia.org/wiki/Universally_unique_identifier
79  */
80 wxString GbrMakeProjectGUIDfromString( const wxString& aText );
81 
82 
83 // this class handle info which can be added in a gerber file as attribute
84 // of an aperture, by the %TA.AperFunction command
85 // This attribute is added when creating a new aperture (command %ADDxx)
86 // Only one aperture attribute can be added to a given aperture
87 //
88 class GBR_APERTURE_METADATA
89 {
90 public:
91     enum GBR_APERTURE_ATTRIB
92     {
93         GBR_APERTURE_ATTRIB_NONE,           ///< uninitialized attribute.
94         GBR_APERTURE_ATTRIB_ETCHEDCMP,      ///< aperture used for etched components.
95 
96         ///< aperture used for connected items like tracks (not vias).
97         GBR_APERTURE_ATTRIB_CONDUCTOR,
98         GBR_APERTURE_ATTRIB_EDGECUT,        ///< aperture used for board cutout,
99 
100         ///< aperture used for not connected items (texts, outlines on copper).
101         GBR_APERTURE_ATTRIB_NONCONDUCTOR,
102         GBR_APERTURE_ATTRIB_VIAPAD,         ///< aperture used for vias.
103 
104         ///< aperture used for through hole component on outer layer.
105         GBR_APERTURE_ATTRIB_COMPONENTPAD,
106 
107         ///< aperture used for SMD pad. Excluded BGA pads which have their own type.
108         GBR_APERTURE_ATTRIB_SMDPAD_SMDEF,
109 
110         ///< aperture used for SMD pad with a solder mask defined by the solder mask.
111         GBR_APERTURE_ATTRIB_SMDPAD_CUDEF,
112 
113         ///< aperture used for BGA pads with a solder mask defined by the copper shape.
114         GBR_APERTURE_ATTRIB_BGAPAD_SMDEF,
115 
116         ///< aperture used for BGA pad with a solder mask defined by the solder mask.
117         GBR_APERTURE_ATTRIB_BGAPAD_CUDEF,
118 
119         ///< aperture used for edge connector pad (outer layers).
120         GBR_APERTURE_ATTRIB_CONNECTORPAD,
121         GBR_APERTURE_ATTRIB_WASHERPAD,      ///< aperture used for mechanical pads (NPTH).
122         GBR_APERTURE_ATTRIB_TESTPOINT,      ///< aperture used for test point pad (outer layers).
123 
124         ///< aperture used for fiducial pad (outer layers), at board level.
125         GBR_APERTURE_ATTRIB_FIDUCIAL_GLBL,
126 
127         ///< aperture used for fiducial pad (outer layers), at footprint level.
128         GBR_APERTURE_ATTRIB_FIDUCIAL_LOCAL,
129 
130         ///< aperture used for heat sink pad (typically for SMDs).
131         GBR_APERTURE_ATTRIB_HEATSINKPAD,
132 
133         ///< aperture used for castellated pads in copper layer files.
134         GBR_APERTURE_ATTRIB_CASTELLATEDPAD,
135 
136         ///< aperture used for castellated pads in drill files.
137         GBR_APERTURE_ATTRIB_CASTELLATEDDRILL,
138 
139         GBR_APERTURE_ATTRIB_VIADRILL,       ///< aperture used for via holes in drill files.
140         GBR_APERTURE_ATTRIB_CMP_DRILL,      ///< aperture used for pad holes in drill files.
141 
142         ///< aperture used for pads oblong holes in drill files.
143         GBR_APERTURE_ATTRIB_CMP_OBLONG_DRILL,
144 
145         ///< aperture used for flashed cmp position in placement files.
146         GBR_APERTURE_ATTRIB_CMP_POSITION,
147 
148         ///< aperture used for flashed pin 1 (or A1 or AA1) position in placement files.
149         GBR_APERTURE_ATTRIB_PAD1_POSITION,
150 
151         ///< aperture used for flashed pads position in placement files.
152         GBR_APERTURE_ATTRIB_PADOTHER_POSITION,
153 
154         ///< aperture used to draw component physical body outline without pins in placement files.
155         GBR_APERTURE_ATTRIB_CMP_BODY,
156 
157         ///< aperture used to draw component physical body outline with pins in placement files.
158         GBR_APERTURE_ATTRIB_CMP_LEAD2LEAD,
159 
160         ///< aperture used to draw component footprint bounding box in placement files.
161         GBR_APERTURE_ATTRIB_CMP_FOOTPRINT,
162 
163         ///< aperture used to draw component outline courtyard in placement files.
164         GBR_APERTURE_ATTRIB_CMP_COURTYARD,
165         GBR_APERTURE_ATTRIB_END             ///< sentinel: max value
166     };
167 
GBR_APERTURE_METADATA()168     GBR_APERTURE_METADATA()
169         :m_ApertAttribute( GBR_APERTURE_ATTRIB_NONE )
170     {}
171 
172     /**
173      * @return the string corresponding to the aperture attribute.
174      */
175     static std::string GetAttributeName( GBR_APERTURE_ATTRIB aAttribute );
GetAttributeName()176     std::string GetAttributeName()
177     {
178         return GetAttributeName( m_ApertAttribute );
179     }
180 
181     /**
182      * @param aUseX1StructuredComment false in X2 mode and true in X1 mode to add the net
183      *                                attribute inside a compatible X1 structured comment
184      *                                starting by "G04 #@! "
185      * @return the full command string corresponding to the aperture attribute
186      *         like "%TA.AperFunction,<function>*%"
187      */
188     static std::string FormatAttribute( GBR_APERTURE_ATTRIB aAttribute,
189                                         bool aUseX1StructuredComment );
190 
FormatAttribute(bool aUseX1StructuredComment)191     std::string FormatAttribute( bool aUseX1StructuredComment )
192     {
193         return FormatAttribute( m_ApertAttribute, aUseX1StructuredComment );
194     }
195 
196     // The id of the aperture attribute
197     GBR_APERTURE_ATTRIB m_ApertAttribute;
198 };
199 
200 
201 /**
202  * Metadata which can be added in a gerber file as attribute in X2 format.
203  */
204 class GBR_METADATA
205 {
206 public:
GBR_METADATA()207     GBR_METADATA(): m_isCopper( false)  {}
208 
SetApertureAttrib(GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB aApertAttribute)209     void SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB aApertAttribute )
210     {
211         m_ApertureMetadata.m_ApertAttribute = aApertAttribute;
212     }
213 
GetApertureAttrib()214     GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB GetApertureAttrib()
215     {
216         return m_ApertureMetadata.m_ApertAttribute;
217     }
218 
SetNetAttribType(int aNetAttribType)219     void SetNetAttribType( int aNetAttribType )
220     {
221         m_NetlistMetadata.m_NetAttribType = aNetAttribType;
222     }
223 
GetNetAttribType()224     int GetNetAttribType() const
225     {
226         return m_NetlistMetadata.m_NetAttribType;
227     }
228 
SetNetName(const wxString & aNetname)229     void SetNetName( const wxString& aNetname ) { m_NetlistMetadata.m_Netname = aNetname; }
230 
231     void SetPadName( const wxString& aPadname, bool aUseUTF8 = false, bool aEscapeString = false )
232     {
233         m_NetlistMetadata.m_Padname.SetField( aPadname, aUseUTF8, aEscapeString );
234     }
235 
SetPadPinFunction(const wxString & aPadPinFunction,bool aUseUTF8,bool aEscapeString)236     void SetPadPinFunction( const wxString& aPadPinFunction, bool aUseUTF8, bool aEscapeString )
237     {
238         m_NetlistMetadata.m_PadPinFunction.SetField( aPadPinFunction, aUseUTF8, aEscapeString );
239     }
240 
SetCmpReference(const wxString & aComponentRef)241     void SetCmpReference( const wxString& aComponentRef )
242     {
243         m_NetlistMetadata.m_Cmpref = aComponentRef;
244     }
245 
246     /**
247      * Allowed attributes are not the same on board copper layers and on other layers.
248      *
249      * A flag can be set or reset when attributes can be depending on layers
250      */
IsCopper()251     bool IsCopper() { return m_isCopper; }
SetCopper(bool aValue)252     void SetCopper( bool aValue ) { m_isCopper = aValue; }
253 
254     /**
255      * An item to handle aperture attribute.
256      */
257     GBR_APERTURE_METADATA m_ApertureMetadata;
258 
259     /**
260      * An item to handle object attribute.
261      */
262     GBR_NETLIST_METADATA m_NetlistMetadata;
263 
264 private:
265     /**
266      * If the metadata is relative to a copper layer or not, this flag which can be set/reset
267      * when an attribute for a given item depends on whether a copper layer or a non copper
268      * layer is plotted.  The initial state i false.
269      */
270     bool m_isCopper;
271 };
272 
273 
274 /**
275  * Normalize \a aString and convert it to a Gerber std::string.
276  *
277  * Normalization means convert any code > 0x7F and unauthorized code to a hexadecimal
278  * 16 bit sequence Unicode.  Illegal characters are ',' '*' '%' '\'.
279  *
280  * @param aString the string to convert.
281  * @return an ASCII7 coded compliant gerber string.
282  */
283 std::string FormatStringToGerber( const wxString& aString );
284 
285 
286 /**
287  * Normalize \a aString and convert it to a Gerber compatible wxString.
288  *
289  * Normalization means convert to a hexadecimal 16 bit sequence Unicode and on request
290  * convert any code > 0x7F.  Illegal characters are ',' '*' '%' '\'.
291  *
292  * @param aString the string to convert.
293  * @param aAllowUtf8Chars false to convert non ASCII7 values to Unicode sequence.
294  * @param aQuoteString  true to double quote the returned string.
295  * @return a without illegal chars (and converted non ASCII7 chars on request)
296  */
297 wxString ConvertNotAllowedCharsInGerber( const wxString& aString, bool aAllowUtf8Chars,
298                                          bool aQuoteString );
299 
300 /**
301  * Convert a gerber string into a 16 bit Unicode string.
302  *
303  * @param aString the gerber string to format.
304  * @return a 16 bit Unicode string.
305  */
306 wxString FormatStringFromGerber( const wxString& aString );
307 
308 /**
309  * Generate the string to set a net attribute for a graphic object to print to a gerber file.
310  *
311  * @param aPrintedText is the string to print.
312  * @param aLastNetAttributes is the current full set of attributes.
313  * @param aData is the #GBR_NETLIST_METADATA associated to the graphic object (can be NULL
314  *              if no associated metadata, and aClearPreviousAttributes will be set to false)
315  * @param aClearPreviousAttributes returns true if the full set of attributes must be deleted
316  *                                 from file before adding new attribute (happens when a previous
317  *                                 attribute no longer exists).
318  * @param aUseX1StructuredComment false in X2 mode and true in X1 mode to add the net attribute
319  *                                in compatible X1 structured comment (i.e. prefixed by "G04 #@! ")
320  * @return false if nothing can be done (GBR_NETLIST_METADATA has GBR_APERTURE_ATTRIB_NONE,
321  *         and true if OK. If the new attribute(s) is the same as current attribute(s),
322  *         \a aPrintedText will be empty.
323  */
324 bool FormatNetAttribute( std::string& aPrintedText, std::string& aLastNetAttributes,
325                          const GBR_NETLIST_METADATA* aData, bool& aClearPreviousAttributes,
326                          bool aUseX1StructuredComment );
327 
328 #endif      // GBR_METADATA_H
329