You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

474 lines
18 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2010-2019 Jean-Pierre Charras jp.charras at wanadoo.fr
  5. * Copyright (C) 1992-2023 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. #ifndef GERBER_FILE_IMAGE_H
  25. #define GERBER_FILE_IMAGE_H
  26. #include <vector>
  27. #include <set>
  28. #include <dcode.h>
  29. #include <gerber_draw_item.h>
  30. #include <am_primitive.h>
  31. #include <aperture_macro.h>
  32. #include <gbr_netlist_metadata.h>
  33. typedef std::vector<GERBER_DRAW_ITEM*> GERBER_DRAW_ITEMS;
  34. class GERBVIEW_FRAME;
  35. class D_CODE;
  36. /* Gerber files have different parameters to define units and how items must be plotted.
  37. * some are for the entire file, and other can change along a file.
  38. * In Gerber world:
  39. * an image is the entire gerber file and its "global" parameters
  40. * a layer (that is very different from a board layer) is just a sub set of a file that
  41. * have specific parameters
  42. * if a Image parameter is set more than once, only the last value is used
  43. * Some parameters can change along a file and are not layer specific: they are stored
  44. * in GERBER_ITEM items, when instanced.
  45. *
  46. * In GerbView, to handle these parameters, there are 2 classes:
  47. * GERBER_FILE_IMAGE : the main class containing most of parameters and data to plot a
  48. * graphic layer
  49. * Some of them can change along the file
  50. * There is one GERBER_FILE_IMAGE per file and one graphic layer per file or GERBER_FILE_IMAGE
  51. * GerbView does not read and merge 2 gerber file in one graphic layer:
  52. * I believe this is not possible due to the constraints in Image parameters.
  53. * GERBER_LAYER : containing the subset of parameters that is layer specific
  54. * A GERBER_FILE_IMAGE must include one GERBER_LAYER to define all parameters to plot a file.
  55. * But a GERBER_FILE_IMAGE can use more than one GERBER_LAYER.
  56. */
  57. class GERBER_FILE_IMAGE;
  58. class X2_ATTRIBUTE;
  59. class X2_ATTRIBUTE_FILEFUNCTION;
  60. // For arcs, coordinates need 3 info: start point, end point and center or radius
  61. // In Excellon files it can be a A## value (radius) or I#J# center coordinates (like in gerber)
  62. // We need to know the last read type when reading a list of routing coordinates
  63. enum LAST_EXTRA_ARC_DATA_TYPE
  64. {
  65. ARC_INFO_TYPE_NONE,
  66. ARC_INFO_TYPE_CENTER, // last info is a IJ command: arc center is given
  67. ARC_INFO_TYPE_RADIUS, // last info is a A command: arc radius is given
  68. };
  69. class GERBER_LAYER
  70. {
  71. public:
  72. GERBER_LAYER();
  73. ~GERBER_LAYER();
  74. private:
  75. void ResetDefaultValues();
  76. friend class GERBER_FILE_IMAGE;
  77. public:
  78. // These parameters are layer specific:
  79. wxString m_LayerName; // Layer name, from LN <name>* command
  80. bool m_LayerNegative; // true = Negative Layer: command LP
  81. wxRealPoint m_StepForRepeat; // X and Y offsets for Step and Repeat command
  82. int m_XRepeatCount; // The repeat count on X axis
  83. int m_YRepeatCount; // The repeat count on Y axis
  84. bool m_StepForRepeatMetric; // false = Inches, true = metric
  85. // needed here because repeated
  86. // gerber items can have coordinates
  87. // in different units than step parameters
  88. // and the actual coordinates calculation must handle this
  89. };
  90. /**
  91. * Hold the image data and parameters for one gerber file and layer parameters.
  92. *
  93. * @todo: Move them in #GERBER_LAYER class.
  94. */
  95. class GERBER_FILE_IMAGE : public EDA_ITEM
  96. {
  97. public:
  98. GERBER_FILE_IMAGE( int layer );
  99. virtual ~GERBER_FILE_IMAGE();
  100. wxString GetClass() const override
  101. {
  102. return wxT( "GERBER_FILE_IMAGE" );
  103. }
  104. /**
  105. * @brief Performs a heuristics-based check of whether the file is an RS274 gerber file.
  106. *
  107. * Does not invoke the full parser.
  108. *
  109. * @param aFullFileName aFullFileName is the full filename of the gerber file.
  110. * @return True if RS274 file, false otherwise
  111. */
  112. static bool TestFileIsRS274( const wxString& aFullFileName );
  113. /**
  114. * Read and load a gerber file.
  115. *
  116. * If the file cannot be loaded, warning and information messages are stored in m_messagesList.
  117. *
  118. * @param aFullFileName The full filename of the Gerber file.
  119. * @return true if file loaded successfully, false if the gerber file was not loaded.
  120. */
  121. bool LoadGerberFile( const wxString& aFullFileName );
  122. const wxArrayString& GetMessages() const { return m_messagesList; }
  123. /**
  124. * @return the count of Dcode tools in use in the image
  125. */
  126. int GetDcodesCount();
  127. /**
  128. * Set all parameters to a default value, before reading a file
  129. */
  130. virtual void ResetDefaultValues();
  131. COLOR4D GetPositiveDrawColor() const { return m_PositiveDrawColor; }
  132. /**
  133. * @return a reference to the GERBER_DRAW_ITEMS deque list
  134. */
  135. GERBER_DRAW_ITEMS& GetItems() { return m_drawings; }
  136. /**
  137. * @return the count of GERBER_DRAW_ITEMS in the image
  138. */
  139. int GetItemsCount() { return m_drawings.size(); }
  140. /**
  141. * Add a new GERBER_DRAW_ITEM item to the drawings list
  142. *
  143. * @param aItem is the GERBER_DRAW_ITEM to add to list
  144. */
  145. void AddItemToList( GERBER_DRAW_ITEM* aItem )
  146. {
  147. m_drawings.push_back( aItem );
  148. }
  149. /**
  150. * @return the last GERBER_DRAW_ITEM* item of the items list
  151. */
  152. GERBER_DRAW_ITEM* GetLastItemInList() const
  153. {
  154. return m_drawings.back();
  155. }
  156. /**
  157. * @return the current layers params.
  158. */
  159. GERBER_LAYER& GetLayerParams()
  160. {
  161. return m_GBRLayerParams;
  162. }
  163. /**
  164. * @return true if at least one item must be drawn in background color used to optimize
  165. * screen refresh (when no items are in background color refresh can be faster).
  166. */
  167. bool HasNegativeItems();
  168. /**
  169. * Clear the message list.
  170. *
  171. * Call it before reading a Gerber file
  172. */
  173. void ClearMessageList()
  174. {
  175. m_messagesList.Clear();
  176. }
  177. /**
  178. * Add a message to the message list
  179. */
  180. void AddMessageToList( const wxString& aMessage )
  181. {
  182. m_messagesList.Add( aMessage );
  183. }
  184. /**
  185. * Return the current coordinate type pointed to by XnnYnn Text (XnnnnYmmmm).
  186. *
  187. * @param aText is a pointer to the text to parse.
  188. * @param aExcellonMode = true to parse a Excellon drill file.
  189. * it forces truncation of a digit string to a maximum length because the exact coordinate
  190. * format is not always known.
  191. */
  192. VECTOR2I ReadXYCoord( char*& aText, bool aExcellonMode = false );
  193. /**
  194. * Return the current coordinate type pointed to by InnJnn Text (InnnnJmmmm)
  195. *
  196. * These coordinates are relative, so if coordinate is absent, its value
  197. * defaults to 0
  198. */
  199. VECTOR2I ReadIJCoord( char*& Text );
  200. /**
  201. * Reads the next number and returns the value
  202. * @param aText Pointer to the input string vector
  203. * @return
  204. */
  205. int CodeNumber( char*& aText );
  206. /**
  207. * Return a pointer to the D_CODE within this GERBER for the given \a aDCODE.
  208. *
  209. * @param aDCODE The numeric value of the D_CODE to look up.
  210. * @param aCreateIfNoExist If true, then create the D_CODE if it does not
  211. * exist in list.
  212. * @return The one implied by the given \a aDCODE or NULL if the requested \a aDCODE is
  213. * out of range.
  214. */
  215. D_CODE* GetDCODEOrCreate( int aDCODE, bool aCreateIfNoExist = true );
  216. /**
  217. * Return a pointer to the D_CODE within this GERBER for the given \a aDCODE.
  218. *
  219. * @param aDCODE The numeric value of the D_CODE to look up.
  220. * @return The D code implied by the given \a aDCODE or NULL if the requested \a aDCODE is
  221. * out of range.
  222. */
  223. D_CODE* GetDCODE( int aDCODE ) const;
  224. /**
  225. * Look up a previously read in aperture macro.
  226. *
  227. * @param aLookup A dummy APERTURE_MACRO with [only] the name field set.
  228. * @return the aperture macro with a matching name or NULL if not found.
  229. */
  230. APERTURE_MACRO* FindApertureMacro( const APERTURE_MACRO& aLookup );
  231. /**
  232. * Gerber format has a command Step an Repeat.
  233. *
  234. * This function must be called when reading a gerber file and
  235. * after creating a new gerber item that must be repeated
  236. * (i.e when m_XRepeatCount or m_YRepeatCount are > 1)
  237. *
  238. * @param aItem = the item to repeat
  239. */
  240. void StepAndRepeatItem( const GERBER_DRAW_ITEM& aItem );
  241. /**
  242. * Display information about image parameters in the status bar.
  243. *
  244. * @param aMainFrame The #GERBVIEW_FRAME to display messages.
  245. */
  246. void DisplayImageInfo( GERBVIEW_FRAME* aMainFrame );
  247. /**
  248. * Called when a %TD command is found the Gerber file
  249. *
  250. * Remove the attribute specified by the %TD command.
  251. * is no attribute, all current attributes specified by the %TO and the %TA
  252. * commands are cleared.
  253. * if a attribute name is specified (for instance %TD.CN*%) is specified,
  254. * only this attribute is cleared
  255. *
  256. * @param aAttribute is the X2_ATTRIBUTE which stores the full command
  257. */
  258. void RemoveAttribute( X2_ATTRIBUTE& aAttribute );
  259. ///< @copydoc EDA_ITEM::Visit()
  260. INSPECT_RESULT Visit( INSPECTOR inspector, void* testData,
  261. const std::vector<KICAD_T>& aScanTypes ) override;
  262. #if defined(DEBUG)
  263. void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
  264. #endif
  265. private:
  266. /**
  267. * Test for an end of line.
  268. *
  269. * If a end of line is found, read a new line.
  270. *
  271. * @param aBuff = buffer (size = GERBER_BUFZ) to fill with a new line
  272. * @param aText = pointer to the last useful char in aBuff
  273. * on return: points the beginning of the next line.
  274. * @param aBuffSize = the size in bytes of aBuff
  275. * @param aFile = the opened GERBER file to read
  276. * @return a pointer to the beginning of the next line or NULL if end of file
  277. */
  278. char* GetNextLine( char *aBuff, unsigned int aBuffSize, char* aText, FILE* aFile );
  279. bool GetEndOfBlock( char* aBuff, unsigned int aBuffSize, char*& aText, FILE* aGerberFile );
  280. /**
  281. * Read a single RS274X command terminated with a %
  282. */
  283. bool ReadRS274XCommand( char *aBuff, unsigned int aBuffSize, char*& aText );
  284. /**
  285. * Execute a RS274X command
  286. */
  287. bool ExecuteRS274XCommand( int aCommand, char* aBuff, unsigned int aBuffSize, char*& aText );
  288. /**
  289. * Read two bytes of data and assembles them into an int with the first
  290. * byte in the sequence put into the most significant part of a 16 bit value
  291. * to build a RS274X command identifier.
  292. *
  293. * @param text A reference to a pointer to read bytes from and to advance as
  294. * they are read.
  295. * @return a RS274X command identifier.
  296. */
  297. int ReadXCommandID( char*& text );
  298. /**
  299. * Read in an aperture macro and saves it in m_aperture_macros.
  300. *
  301. * @param aBuff a character buffer at least GERBER_BUFZ long that can be
  302. * used to read successive lines from the gerber file.
  303. * @param text A reference to a character pointer which gives the initial
  304. * text to read from.
  305. * @param aBuffSize is the size of aBuff
  306. * @param gerber_file Which file to read from for continuation.
  307. * @return true if a macro was read in successfully, else false.
  308. */
  309. bool ReadApertureMacro( char *aBuff, unsigned int aBuffSize, char*& text, FILE* gerber_file );
  310. // functions to execute G commands or D basic commands:
  311. bool Execute_G_Command( char*& text, int G_command );
  312. bool Execute_DCODE_Command( char*& text, int D_command );
  313. public:
  314. bool m_InUse; ///< true if this image is currently in use (a file
  315. ///< is loaded in it)
  316. ///< false if it must be not drawn
  317. COLOR4D m_PositiveDrawColor; ///< The color used to draw positive items
  318. wxString m_FileName; ///< Full File Name for this layer
  319. wxString m_ImageName; ///< Image name, from IN <name>* command
  320. bool m_IsX2_file; ///< True if a X2 gerber attribute was found in file
  321. X2_ATTRIBUTE_FILEFUNCTION* m_FileFunction; ///< file function parameters, found in a %TF
  322. ///< command or a G04
  323. wxString m_MD5_value; ///< MD5 value found in a %TF.MD5 command
  324. wxString m_PartString; ///< string found in a %TF.Part command
  325. int m_GraphicLayer; ///< Graphic layer Number
  326. bool m_ImageNegative; ///< true = Negative image
  327. bool m_ImageJustifyXCenter; ///< Image Justify Center on X axis (default = false)
  328. bool m_ImageJustifyYCenter; ///< Image Justify Center on Y axis (default = false)
  329. VECTOR2I m_ImageJustifyOffset; ///< Image Justify Offset on XY axis (default = 0,0)
  330. bool m_GerbMetric; ///< false = Inches, true = metric
  331. bool m_Relative; ///< false = absolute Coord, true = relative Coord.
  332. bool m_NoTrailingZeros; ///< true: remove tailing zeros.
  333. VECTOR2I m_ImageOffset; ///< Coord Offset, from IO command
  334. wxSize m_FmtScale; ///< Fmt 2.3: m_FmtScale = 3, fmt 3.4: m_FmtScale = 4
  335. wxSize m_FmtLen; ///< Nb chars per coord. ex fmt 2.3, m_FmtLen = 5
  336. int m_ImageRotation; ///< Image rotation (0, 90, 180, 270 only) in degrees
  337. double m_LocalRotation; ///< Local rotation added to m_ImageRotation
  338. ///< @note This value is stored in 0.1 degrees
  339. VECTOR2I m_Offset; ///< Coord Offset, from OF command
  340. VECTOR2I m_Scale; ///< scale (X and Y) of layer.
  341. bool m_SwapAxis; ///< false if A = X and B = Y (default); true if
  342. ///< A = Y, B = X
  343. bool m_MirrorA; ///< true: mirror / axis A (X)
  344. bool m_MirrorB; ///< true: mirror / axis B (Y)
  345. int m_Iterpolation; ///< Linear, 90 arc, Circ.
  346. int m_Current_Tool; ///< Current Tool (Dcode) number selected
  347. int m_Last_Pen_Command; ///< Current or last pen state (0..9, set by Dn
  348. ///< option with n < 10
  349. int m_CommandState; ///< state of gerber analysis command
  350. int m_LineNum; ///< Line number of the gerber file while reading.
  351. VECTOR2I m_CurrentPos; ///< current specified coord for plot
  352. VECTOR2I m_PreviousPos; ///< old current specified coord for plot
  353. VECTOR2I m_IJPos; ///< IJ coord (for arcs & circles )
  354. ///< True if a IJ coord was read (for arcs & circles ).
  355. bool m_LastCoordIsIJPos;
  356. ///< A value ( = radius in circular routing in Excellon files ).
  357. int m_ArcRadius;
  358. ///< Identifier for arc data type (IJ (center) or A## (radius)).
  359. LAST_EXTRA_ARC_DATA_TYPE m_LastArcDataType;
  360. FILE* m_Current_File; // Current file to read
  361. int m_Selected_Tool; // For highlight: current selected Dcode
  362. ///< True if has DCodes in file or false if no DCodes found. Perhaps deprecated RS274D file.
  363. bool m_Has_DCode;
  364. // true = some DCodes in file are not defined (broken file or deprecated RS274D file).
  365. bool m_Has_MissingDCode;
  366. bool m_360Arc_enbl; // Enable 360 deg circular interpolation
  367. // Set to true when a circular interpolation command type is found. Mandatory before
  368. // drawing an arc.
  369. bool m_AsArcG74G75Cmd;
  370. // Enable polygon mode (read coord as a polygon descr)
  371. bool m_PolygonFillMode;
  372. // In polygon mode: 0 = first segm, 1 = next segm
  373. int m_PolygonFillModeState;
  374. ///< a collection of APERTURE_MACROS, sorted by name
  375. APERTURE_MACRO_SET m_aperture_macros;
  376. // the net attributes set by a %TO.CN, %TO.C and/or %TO.N add object attribute command.
  377. GBR_NETLIST_METADATA m_NetAttributeDict;
  378. // the aperture function set by a %TA.AperFunction, xxx (stores the xxx value).
  379. wxString m_AperFunction;
  380. std::map<wxString, int> m_ComponentsList; // list of components
  381. std::map<wxString, int> m_NetnamesList; // list of net names
  382. ///< Dcode (Aperture) List for this layer (max TOOLS_MAX_COUNT: see dcode.h)
  383. D_CODE* m_Aperture_List[TOOLS_MAX_COUNT];
  384. ///< Whether an aperture macro tool is flashed on or off.
  385. bool m_Exposure;
  386. GERBER_LAYER m_GBRLayerParams; // hold params for the current gerber layer
  387. GERBER_DRAW_ITEMS m_drawings; // linked list of Gerber Items to draw
  388. private:
  389. wxArrayString m_messagesList; // A list of messages created when reading a file
  390. /**
  391. * True if the image is negative or has some negative items.
  392. *
  393. * Used to optimize drawing because when there are no negative items screen refresh does
  394. * not need to build an intermediate bitmap specific to this image.
  395. *
  396. * - -1 negative items are.
  397. * - 0 no negative items found.
  398. * - 1 have negative items found.
  399. */
  400. int m_hasNegativeItems;
  401. };
  402. #endif // ifndef GERBER_FILE_IMAGE_H