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.

507 lines
13 KiB

1 year ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
  5. *
  6. * This program is free software: you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation, either version 3 of the License, or (at your
  9. * option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #pragma once
  20. #include "plotter.h"
  21. /**
  22. * Legacy colors for DXF file.
  23. */
  24. enum class DXF_COLOR_T
  25. {
  26. BLACK = 0,
  27. RED,
  28. YELLOW,
  29. GREEN,
  30. CYAN,
  31. BLUE,
  32. MAGENTA,
  33. WHITE,
  34. BROWN,
  35. ORANGE,
  36. LIGHTRED,
  37. LIGHTYELLOW,
  38. LIGHTGREEN,
  39. LIGHTCYAN,
  40. LIGHTBLUE,
  41. LIGHTMAGENTA,
  42. LIGHTORANGE,
  43. LIGHTGRAY,
  44. DARKRED,
  45. DARKYELLOW,
  46. DARKGREEN,
  47. DARKCYAN,
  48. DARKBLUE,
  49. DARKMAGENTA,
  50. DARKBROWN,
  51. DARKORANGE,
  52. DARKGRAY,
  53. PURERED,
  54. PUREYELLOW,
  55. PUREGREEN,
  56. PURECYAN,
  57. PUREBLUE,
  58. PUREMAGENTA,
  59. PUREORANGE,
  60. PUREGRAY,
  61. REDONE,
  62. REDTWO,
  63. REDTHREE,
  64. REDFOUR,
  65. REDFIVE,
  66. REDSIX,
  67. ORANGEONE,
  68. ORANGETWO,
  69. ORANGETHREE,
  70. ORANGEFOUR,
  71. ORANGEFIVE,
  72. REDSEVEN,
  73. REDEIGHT,
  74. ORANGESIX,
  75. REDNINE,
  76. ORANGESEVEN,
  77. ORANGEEIGHT,
  78. ORANGENINE,
  79. ORANGETEN,
  80. ORANGEELEVEN,
  81. ORANGETWELVE,
  82. ORANGETHIRTEEN,
  83. ORANGEFOURTEEN,
  84. YELLOWONE,
  85. YELLOWTWO,
  86. YELLOWTHREE,
  87. YELLOWFOUR,
  88. YELLOWFIVE,
  89. YELLOWSIX,
  90. YELLOWSEVEN,
  91. YELLOWEIGHT,
  92. YELLOWNINE,
  93. YELLOWTEN,
  94. YELLOWELEVEN,
  95. YELLOWTWELVE,
  96. YELLOWTHIRTEEN,
  97. YELLOWFOURTEEN,
  98. GREENONE,
  99. GREENTWO,
  100. GREENTHREE,
  101. GREENFOUR,
  102. GREENFIVE,
  103. GREENSIX,
  104. GREENSEVEN,
  105. GREENEIGHT,
  106. GREENNINE,
  107. GREENTEN,
  108. GREENELEVEN,
  109. GREENTWELVE,
  110. GREENTHIRTEEN,
  111. GREENFOURTEEN,
  112. GREENFIFTEEN,
  113. GREENSIXTEEN,
  114. GREENSEVENTEEN,
  115. GREENEIGHTEEN,
  116. GREENNINETEEN,
  117. GREENTWENTY,
  118. GREENTWENTYONE,
  119. GREENTWENTYTWO,
  120. GREENTWENTYTHREE,
  121. GREENTWENTYFOUR,
  122. GREENTWENTYFIVE,
  123. GREENTWENTYSIX,
  124. GREENTWENTYSEVEN,
  125. GREENTWENTYEIGHT,
  126. GREENTWENTYNINE,
  127. GREENTHIRTY,
  128. GREENTHIRTYONE,
  129. GREENTHIRTYTWO,
  130. GREENTHIRTYTHREE,
  131. GREENTHIRTYFOUR,
  132. GREENTHIRTYFIVE,
  133. GREENTHIRTYSIX,
  134. GREENTHIRTYSEVEN,
  135. GREENTHIRTYEIGHT,
  136. GREENTHIRTYNINE,
  137. GREENFORTY,
  138. GREENFORTYONE,
  139. GREENFORTYTWO,
  140. GREENFORTYTHREE,
  141. GREENFORTYFOUR,
  142. GREENFORTYFIVE,
  143. GREENFORTYSIX,
  144. GREENFORTYSEVEN,
  145. GREENFORTYEIGHT,
  146. GREENFORTYNINE,
  147. GREENFIFTY,
  148. GREENFIFTYONE,
  149. GREENFIFTYTWO,
  150. GREENFIFTYTHREE,
  151. GREENFIFTYFOUR,
  152. GREENFIFTYFIVE,
  153. GREENFIFTYSIX,
  154. GREENFIFTYSEVEN,
  155. GREENFIFTYEIGHT,
  156. GREENFIFTYNINE,
  157. GREENSIXTY,
  158. GREENSIXTYONE,
  159. GREENSIXTYTWO,
  160. GREENSIXTYTHREE,
  161. GREENSIXTYFOUR,
  162. GREENSIXTYFIVE,
  163. CYANONE,
  164. CYANTWO,
  165. CYANTHREE,
  166. CYANFOUR,
  167. CYANFIVE,
  168. CYANSIX,
  169. CYANSEVEN,
  170. BLUEONE,
  171. BLUETWO,
  172. BLUETHREE,
  173. BLUEFOUR,
  174. BLUEFIVE,
  175. BLUESIX,
  176. BLUESEVEN,
  177. BLUEEIGHT,
  178. BLUENINE,
  179. BLUETEN,
  180. BLUEELEVEN,
  181. BLUETWELVE,
  182. BLUETHIRTEEN,
  183. BLUEFOURTEEN,
  184. BLUEFIFTEEN,
  185. BLUESIXTEEN,
  186. BLUESEVENTEEN,
  187. BLUEEIGHTEEN,
  188. BLUENINETEEN,
  189. BLUETWENTY,
  190. BLUETWENTYONE,
  191. BLUETWENTYTWO,
  192. BLUETWENTYTHREE,
  193. BLUETWENTYFOUR,
  194. BLUETWENTYFIVE,
  195. BLUETWENTYSIX,
  196. BLUETWENTYSEVEN,
  197. BLUETWENTYEIGHT,
  198. BLUETWENTYNINE,
  199. BLUETHIRTY,
  200. BLUETHIRTYONE,
  201. BLUETHIRTYTWO,
  202. BLUETHIRTYETHREE,
  203. BLUETHIRTYFOUR,
  204. VIOLETONE,
  205. VIOLETTWO,
  206. VIOLETTHREE,
  207. VIOLETFOUR,
  208. VIOLETFIVE,
  209. VIOLETSIX,
  210. VIOLETSEVEN,
  211. VIOLETEIGHT,
  212. VIOLETNINE,
  213. VIOLETTEN,
  214. VIOLETELEVEN,
  215. VIOLETTWELVE,
  216. VIOLETTHIRTEEN,
  217. VIOLETFOURTEEN,
  218. VIOLETFIFTEEN,
  219. VIOLETSIXTEEN,
  220. VIOLETSEVENTEEN,
  221. VIOLETEIGHTEEN,
  222. VIOLETNINETEEN,
  223. VIOLETTWENTY,
  224. VIOLETTWENTYONE,
  225. VIOLETTWENTYTWO,
  226. VIOLETTWENTYTHREE,
  227. VIOLETTWENTYFOUR,
  228. VIOLETTWENTYFIVE,
  229. VIOLETTWENTYSIX,
  230. VIOLETTWENTYSEVEN,
  231. VIOLETTWENTYEIGHT,
  232. VIOLETTWENTYNINE,
  233. VIOLETTHIRTY,
  234. MAGENTAONE,
  235. MAGENTATWO,
  236. MAGENTATHREE,
  237. MAGENTAFOUR,
  238. MAGENTAFIVE,
  239. MAGENTASIX,
  240. MAGENTASEVEN,
  241. MAGENTAEIGHT,
  242. MAGENTANINE,
  243. MAGENTATEN,
  244. MAGENTAELEVEN,
  245. MAGENTATWELVE,
  246. MAGENTATHIRTEEN,
  247. MAGENTAFOURTEEN,
  248. REDTEN,
  249. REDELEVEN,
  250. VIOLETTHIRTYONE,
  251. REDTWELVE,
  252. REDTHIRTEEN,
  253. REDFOURTEEN,
  254. REDFIFTEEN,
  255. REDSIXTEEN,
  256. REDSEVENTEEN,
  257. REDEIGHTEEN,
  258. REDNINETEEN,
  259. REDTWENTY,
  260. REDTWENTYONE,
  261. REDTWENTYTWO,
  262. REDTWENTYTHREE,
  263. REDTWENTYFOUR,
  264. REDTWENTYFIVE,
  265. REDTWENTYSIX,
  266. REDTWENTYSEVEN,
  267. REDTWENTYEIGHT,
  268. REDTWENTYNINE,
  269. REDTHIRTY,
  270. REDTHIRTYONE,
  271. GRAYONE,
  272. GRAYTWO,
  273. GRAYTHREE,
  274. GRAYFOUR,
  275. NBCOLORS ///< Number of colors
  276. };
  277. class DXF_PLOTTER : public PLOTTER
  278. {
  279. public:
  280. DXF_PLOTTER() :
  281. m_textAsLines( false )
  282. {
  283. m_textAsLines = true;
  284. m_currentColor = COLOR4D::BLACK;
  285. m_currentLineType = LINE_STYLE::SOLID;
  286. SetUnits( DXF_UNITS::INCH );
  287. }
  288. virtual PLOT_FORMAT GetPlotterType() const override
  289. {
  290. return PLOT_FORMAT::DXF;
  291. }
  292. static wxString GetDefaultFileExtension()
  293. {
  294. return wxString( wxT( "dxf" ) );
  295. }
  296. /**
  297. * DXF handles NATIVE text emitting TEXT entities
  298. */
  299. virtual void SetTextMode( PLOT_TEXT_MODE mode ) override
  300. {
  301. if( mode != PLOT_TEXT_MODE::DEFAULT )
  302. m_textAsLines = ( mode != PLOT_TEXT_MODE::NATIVE );
  303. }
  304. /**
  305. * Open the DXF plot with a skeleton header.
  306. */
  307. virtual bool StartPlot( const wxString& aPageNumber ) override;
  308. virtual bool EndPlot() override;
  309. // For now we don't use 'thick' primitives, so no line width
  310. virtual void SetCurrentLineWidth( int width, void* aData = nullptr ) override
  311. {
  312. m_currentPenWidth = 0;
  313. }
  314. virtual void SetDash( int aLineWidth, LINE_STYLE aLineStyle ) override;
  315. /**
  316. * The DXF exporter handles 'colors' as layers...
  317. */
  318. virtual void SetColor( const COLOR4D& color ) override;
  319. /**
  320. * Set the scale/position for the DXF plot.
  321. *
  322. * The DXF engine doesn't support line widths and mirroring. The output
  323. * coordinate system is in the first quadrant (in mm).
  324. */
  325. virtual void SetViewport( const VECTOR2I& aOffset, double aIusPerDecimil,
  326. double aScale, bool aMirror ) override;
  327. /**
  328. * DXF rectangle: fill not supported.
  329. */
  330. virtual void Rect( const VECTOR2I& p1, const VECTOR2I& p2, FILL_T fill, int width,
  331. int aCornerRadius = 0 ) override;
  332. /**
  333. * DXF circle: full functionality; it even does 'fills' drawing a
  334. * circle with a dual-arc polyline wide as the radius.
  335. *
  336. * I could use this trick to do other filled primitives.
  337. */
  338. virtual void Circle( const VECTOR2I& pos, int diametre, FILL_T fill, int width ) override;
  339. virtual void Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
  340. const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill, int aWidth ) override;
  341. /**
  342. * DXF polygon: doesn't fill it but at least it close the filled ones
  343. * DXF does not know thick outline.
  344. *
  345. * It does not know thick segments, therefore filled polygons with thick outline
  346. * are converted to inflated polygon by aWidth/2.
  347. */
  348. virtual void PlotPoly( const std::vector<VECTOR2I>& aCornerList, FILL_T aFill, int aWidth,
  349. void* aData = nullptr ) override;
  350. virtual void PlotPoly( const SHAPE_LINE_CHAIN& aLineChain, FILL_T aFill, int aWidth,
  351. void* aData = nullptr ) override;
  352. virtual void ThickSegment( const VECTOR2I& start, const VECTOR2I& end, int width,
  353. void* aData ) override;
  354. virtual void ThickArc( const VECTOR2D& aCentre, const EDA_ANGLE& aStAngle, const EDA_ANGLE& aAngle,
  355. double aRadius, int aWidth, void* aData ) override;
  356. virtual void ThickRect( const VECTOR2I& p1, const VECTOR2I& p2, int width, void* aData ) override;
  357. virtual void ThickCircle( const VECTOR2I& pos, int diametre, int width, void* aData ) override;
  358. virtual void FilledCircle( const VECTOR2I& pos, int diametre, void* aData ) override;
  359. virtual void ThickPoly( const SHAPE_POLY_SET& aPoly, int aWidth, void* aData ) override;
  360. virtual void PenTo( const VECTOR2I& pos, char plume ) override;
  361. /**
  362. * DXF round pad: always done in sketch mode; it could be filled but it isn't
  363. * pretty if other kinds of pad aren't...
  364. */
  365. virtual void FlashPadCircle( const VECTOR2I& pos, int diametre, void* aData ) override;
  366. /**
  367. * DXF oval pad: always done in sketch mode.
  368. */
  369. virtual void FlashPadOval( const VECTOR2I& aPos, const VECTOR2I& aSize,
  370. const EDA_ANGLE& aOrient, void* aData ) override;
  371. /**
  372. * DXF rectangular pad: always done in sketch mode.
  373. */
  374. virtual void FlashPadRect( const VECTOR2I& aPos, const VECTOR2I& aSize,
  375. const EDA_ANGLE& aOrient, void* aData ) override;
  376. virtual void FlashPadRoundRect( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
  377. int aCornerRadius, const EDA_ANGLE& aOrient,
  378. void* aData ) override;
  379. virtual void FlashPadCustom( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
  380. const EDA_ANGLE& aOrient, SHAPE_POLY_SET* aPolygons,
  381. void* aData ) override;
  382. /**
  383. * DXF trapezoidal pad: only sketch mode is supported.
  384. */
  385. virtual void FlashPadTrapez( const VECTOR2I& aPadPos, const VECTOR2I* aCorners,
  386. const EDA_ANGLE& aPadOrient, void* aData ) override;
  387. virtual void FlashRegularPolygon( const VECTOR2I& aShapePos, int aDiameter, int aCornerCount,
  388. const EDA_ANGLE& aOrient, void* aData ) override;
  389. virtual void Text( const VECTOR2I& aPos,
  390. const COLOR4D& aColor,
  391. const wxString& aText,
  392. const EDA_ANGLE& aOrient,
  393. const VECTOR2I& aSize,
  394. enum GR_TEXT_H_ALIGN_T aH_justify,
  395. enum GR_TEXT_V_ALIGN_T aV_justify,
  396. int aWidth,
  397. bool aItalic,
  398. bool aBold,
  399. bool aMultilineAllowed,
  400. KIFONT::FONT* aFont,
  401. const KIFONT::METRICS& aFontMetrics,
  402. void* aData = nullptr ) override;
  403. virtual void PlotText( const VECTOR2I& aPos,
  404. const COLOR4D& aColor,
  405. const wxString& aText,
  406. const TEXT_ATTRIBUTES& aAttributes,
  407. KIFONT::FONT* aFont,
  408. const KIFONT::METRICS& aFontMetrics,
  409. void* aData = nullptr ) override;
  410. /**
  411. * Set the units to use for plotting the DXF file.
  412. *
  413. * @param aUnit - The units to use
  414. */
  415. void SetUnits( DXF_UNITS aUnit );
  416. /**
  417. * The units currently enabled for plotting
  418. *
  419. * @return The currently configured units
  420. */
  421. DXF_UNITS GetUnits() const
  422. {
  423. return m_plotUnits;
  424. }
  425. /**
  426. * Get the scale factor to apply to convert the device units to be in the
  427. * currently set units.
  428. *
  429. * @return Scaling factor to apply for unit conversion
  430. */
  431. double GetUnitScaling() const
  432. {
  433. return m_unitScalingFactor;
  434. }
  435. /**
  436. * Get the correct value for the $MEASUREMENT field given the current units
  437. *
  438. * @return the $MEASUREMENT directive field value
  439. */
  440. unsigned int GetMeasurementDirective() const
  441. {
  442. return m_measurementDirective;
  443. }
  444. /**
  445. * Get the correct value for the $INSUNITS header variable given the current units.
  446. *
  447. * @return the $INSUNITS value (1 = inches, 4 = millimeters)
  448. */
  449. unsigned int GetInsUnits() const
  450. {
  451. return m_insUnits;
  452. }
  453. // Finds the nearest legacy color to the given RGB values (aR, aG, aB).
  454. int FindNearestLegacyColor( int aR, int aG, int aB );
  455. // Retrieves the current layer name based on the output mode and optional layer ID.
  456. wxString GetCurrentLayerName( DXF_LAYER_OUTPUT_MODE aMode, std::optional<PCB_LAYER_ID> aLayerId = std::nullopt );
  457. protected:
  458. void plotOneLineOfText( const VECTOR2I& aPos, const COLOR4D& aColor, const wxString& aText,
  459. const TEXT_ATTRIBUTES& aAttrs );
  460. bool m_textAsLines;
  461. COLOR4D m_currentColor;
  462. LINE_STYLE m_currentLineType;
  463. DXF_UNITS m_plotUnits;
  464. double m_unitScalingFactor;
  465. unsigned int m_measurementDirective;
  466. unsigned int m_insUnits;
  467. };