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.

1596 lines
62 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
  5. * Copyright (C) 2016-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. * Common plot library \n
  26. * Plot settings, and plotting engines (Postscript, Gerber, HPGL and DXF)
  27. *
  28. * @file plot_common.h
  29. */
  30. #ifndef PLOT_COMMON_H_
  31. #define PLOT_COMMON_H_
  32. #include <vector>
  33. #include <math/box2.h>
  34. #include <gr_text.h>
  35. #include <page_info.h>
  36. #include <base_struct.h> // FILL_T
  37. class COLOR_SETTINGS;
  38. class SHAPE_POLY_SET;
  39. class SHAPE_LINE_CHAIN;
  40. class GBR_NETLIST_METADATA;
  41. /**
  42. * Enum PlotFormat
  43. * is the set of supported output plot formats. They should be kept in order
  44. * of the radio buttons in the plot panel/windows.
  45. */
  46. enum class PLOT_FORMAT
  47. {
  48. UNDEFINED = -1,
  49. FIRST_FORMAT = 0,
  50. HPGL = FIRST_FORMAT,
  51. GERBER,
  52. POST,
  53. DXF,
  54. PDF,
  55. SVG,
  56. LAST_FORMAT = SVG
  57. };
  58. /**
  59. * Enum for choosing which kind of text to output with the PSLIKE
  60. * plotters. You can:
  61. * 1) only use the internal vector font
  62. * 2) only use native postscript fonts
  63. * 3) use the internal vector font and add 'phantom' text to aid
  64. * searching
  65. * 4) keep the default for the plot driver
  66. *
  67. * This is recognized by the DXF driver too, where NATIVE emits
  68. * TEXT entities instead of stroking the text
  69. */
  70. enum class PLOT_TEXT_MODE
  71. {
  72. STROKE,
  73. NATIVE,
  74. PHANTOM,
  75. DEFAULT
  76. };
  77. /**
  78. * Enum for choosing dashed line type
  79. */
  80. enum class PLOT_DASH_TYPE
  81. {
  82. DEFAULT = -1,
  83. SOLID = 0,
  84. FIRST_TYPE = SOLID,
  85. DASH,
  86. DOT,
  87. DASHDOT,
  88. LAST_TYPE = DASHDOT
  89. };
  90. /**
  91. * Convert KiCad line plot styles to wxWidgets device context styles.
  92. *
  93. * @param aType The KiCad line plot style to convert.
  94. *
  95. * @return The equivalent wxPenStyle of \a aType.
  96. */
  97. wxPenStyle GetwxPenStyle( PLOT_DASH_TYPE aType );
  98. /**
  99. * Base plotter engine class. General rule: all the interface with the caller
  100. * is done in IU, the IU size is specified with SetViewport. Internal and
  101. * output processing is usually done in decimils (or whatever unit the
  102. * effective engine class need to use)
  103. */
  104. class PLOTTER
  105. {
  106. public:
  107. // These values are used as flag for pen or aperture selection
  108. static const int DO_NOT_SET_LINE_WIDTH = -2; // Skip selection
  109. static const int USE_DEFAULT_LINE_WIDTH = -1; // use the default pen
  110. PLOTTER();
  111. virtual ~PLOTTER();
  112. /**
  113. * Returns the effective plot engine in use. It's not very OO but for
  114. * now is required since some things are only done with some output devices
  115. * (like drill marks, emitted only for postscript
  116. */
  117. virtual PLOT_FORMAT GetPlotterType() const = 0;
  118. virtual bool StartPlot() = 0;
  119. virtual bool EndPlot() = 0;
  120. virtual void SetNegative( bool aNegative )
  121. {
  122. negativeMode = aNegative;
  123. }
  124. /** Plot in B/W or color.
  125. * @param aColorMode = true to plot in color, false to plot in black and white
  126. */
  127. virtual void SetColorMode( bool aColorMode ) { colorMode = aColorMode; }
  128. bool GetColorMode() const { return colorMode; }
  129. void SetRenderSettings( RENDER_SETTINGS* aSettings ) { m_renderSettings = aSettings; }
  130. RENDER_SETTINGS* RenderSettings() { return m_renderSettings; }
  131. virtual void SetPageSettings( const PAGE_INFO& aPageSettings ) { pageInfo = aPageSettings; }
  132. PAGE_INFO& PageSettings() { return pageInfo; }
  133. /**
  134. * Set the line width for the next drawing.
  135. * @param width is specified in IUs
  136. * @param aData is an auxiliary parameter, mainly used in gerber plotter
  137. */
  138. virtual void SetCurrentLineWidth( int width, void* aData = NULL ) = 0;
  139. virtual int GetCurrentLineWidth() const { return currentPenWidth; }
  140. virtual void SetColor( COLOR4D color ) = 0;
  141. virtual void SetDash( PLOT_DASH_TYPE dashed ) = 0;
  142. virtual void SetCreator( const wxString& aCreator )
  143. {
  144. creator = aCreator;
  145. }
  146. virtual void SetTitle( const wxString& aTitle )
  147. {
  148. title = aTitle;
  149. }
  150. /**
  151. * Function AddLineToHeader
  152. * Add a line to the list of free lines to print at the beginning of the file
  153. * @param aExtraString is the string to print
  154. */
  155. void AddLineToHeader( const wxString& aExtraString )
  156. {
  157. m_headerExtraLines.Add( aExtraString );
  158. }
  159. /**
  160. * Function ClearHeaderLinesList
  161. * remove all lines from the list of free lines to print at the beginning of the file
  162. */
  163. void ClearHeaderLinesList()
  164. {
  165. m_headerExtraLines.Clear();
  166. }
  167. /**
  168. * Set the plot offset and scaling for the current plot
  169. * @param aOffset is the plot offset
  170. * @param aIusPerDecimil gives the scaling factor from IUs to device units
  171. * @param aScale is the user set plot scaling factor (either explicitly
  172. * or using 'fit to A4')
  173. * @param aMirror flips the plot in the Y direction (useful for toner
  174. * transfers or some kind of film)
  175. */
  176. virtual void SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
  177. double aScale, bool aMirror ) = 0;
  178. /**
  179. * Open or create the plot file aFullFilename
  180. * @param aFullFilename = the full file name of the file to create
  181. * @return true if success, false if the file cannot be created/opened
  182. *
  183. * Virtual because some plotters use ascii files, some others binary files (PDF)
  184. * The base class open the file in text mode
  185. */
  186. virtual bool OpenFile( const wxString& aFullFilename );
  187. /**
  188. * The IUs per decimil are an essential scaling factor when
  189. * plotting; they are set and saved when establishing the viewport.
  190. * Here they can be get back again
  191. */
  192. double GetIUsPerDecimil() const { return m_IUsPerDecimil; }
  193. int GetPlotterArcLowDef() const { return m_IUsPerDecimil * 8; }
  194. int GetPlotterArcHighDef() const { return m_IUsPerDecimil * 2; }
  195. // Low level primitives
  196. virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill,
  197. int width = USE_DEFAULT_LINE_WIDTH ) = 0;
  198. virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill,
  199. int width = USE_DEFAULT_LINE_WIDTH ) = 0;
  200. /**
  201. * Generic fallback: arc rendered as a polyline
  202. */
  203. virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle,
  204. int rayon, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH );
  205. /**
  206. * Generic fallback: Cubic Bezier curve rendered as a polyline
  207. * In Kicad the bezier curves have 4 control points:
  208. * start ctrl1 ctrl2 end
  209. */
  210. virtual void BezierCurve( const wxPoint& aStart, const wxPoint& aControl1,
  211. const wxPoint& aControl2, const wxPoint& aEnd,
  212. int aTolerance,
  213. int aLineThickness = USE_DEFAULT_LINE_WIDTH );
  214. /**
  215. * moveto/lineto primitive, moves the 'pen' to the specified direction
  216. * @param pos is the target position
  217. * @param plume specifies the kind of motion: 'U' only moves the pen,
  218. * 'D' draw a line from the current position and 'Z' finish
  219. * the drawing and returns the 'pen' to rest (flushes the trace)
  220. */
  221. virtual void PenTo( const wxPoint& pos, char plume ) = 0;
  222. // Convenience functions for PenTo
  223. void MoveTo( const wxPoint& pos )
  224. {
  225. PenTo( pos, 'U' );
  226. }
  227. void LineTo( const wxPoint& pos )
  228. {
  229. PenTo( pos, 'D' );
  230. }
  231. void FinishTo( const wxPoint& pos )
  232. {
  233. PenTo( pos, 'D' );
  234. PenTo( pos, 'Z' );
  235. }
  236. void PenFinish()
  237. {
  238. // The point is not important with Z motion
  239. PenTo( wxPoint( 0, 0 ), 'Z' );
  240. }
  241. /**
  242. * Function PlotPoly
  243. * @brief Draw a polygon ( filled or not )
  244. * @param aCornerList = corners list (a std::vector< wxPoint >)
  245. * @param aFill = type of fill
  246. * @param aWidth = line width
  247. * @param aData an auxiliary info (mainly for gerber format)
  248. */
  249. virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill,
  250. int aWidth = USE_DEFAULT_LINE_WIDTH, void * aData = NULL ) = 0;
  251. /**
  252. * Function PlotPoly
  253. * @brief Draw a polygon ( filled or not )
  254. * @param aCornerList = corners list (a SHAPE_LINE_CHAIN).
  255. * must be closed (IsClosed() == true) for a polygon. Otherwise this is a polyline
  256. * @param aFill = type of fill
  257. * @param aWidth = line width
  258. * @param aData an auxiliary info (mainly for gerber format)
  259. */
  260. virtual void PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_T aFill,
  261. int aWidth = USE_DEFAULT_LINE_WIDTH, void * aData = NULL );
  262. /**
  263. * Function PlotImage
  264. * Only Postscript plotters can plot bitmaps
  265. * for plotters that cannot plot a bitmap, a rectangle is plotted
  266. * @brief Draw an image bitmap
  267. * @param aImage = the bitmap
  268. * @param aPos = position of the center of the bitmap
  269. * @param aScaleFactor = the scale factor to apply to the bitmap size
  270. * (this is not the plot scale factor)
  271. */
  272. virtual void PlotImage( const wxImage & aImage, const wxPoint& aPos,
  273. double aScaleFactor );
  274. // Higher level primitives -- can be drawn as line, sketch or 'filled'
  275. virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width,
  276. EDA_DRAW_MODE_T tracemode, void* aData );
  277. virtual void ThickArc( const wxPoint& centre, double StAngle, double EndAngle,
  278. int rayon, int width, EDA_DRAW_MODE_T tracemode, void* aData );
  279. virtual void ThickRect( const wxPoint& p1, const wxPoint& p2, int width,
  280. EDA_DRAW_MODE_T tracemode, void* aData );
  281. virtual void ThickCircle( const wxPoint& pos, int diametre, int width,
  282. EDA_DRAW_MODE_T tracemode, void* aData );
  283. // Flash primitives
  284. /**
  285. * virtual function FlashPadCircle
  286. * @param aPadPos Position of the shape (center of the rectangle
  287. * @param aDiameter diameter of round pad
  288. * @param aTraceMode FILLED or SKETCH
  289. * @param aData an auxiliary info (mainly for gerber format attributes)
  290. */
  291. virtual void FlashPadCircle( const wxPoint& aPadPos, int aDiameter,
  292. EDA_DRAW_MODE_T aTraceMode, void* aData ) = 0;
  293. /**
  294. * virtual function FlashPadOval
  295. * @param aPadPos Position of the shape (center of the rectangle
  296. * @param aSize = size of oblong shape
  297. * @param aPadOrient The rotation of the shape
  298. * @param aTraceMode FILLED or SKETCH
  299. * @param aData an auxiliary info (mainly for gerber format attributes)
  300. */
  301. virtual void FlashPadOval( const wxPoint& aPadPos, const wxSize& aSize, double aPadOrient,
  302. EDA_DRAW_MODE_T aTraceMode, void* aData ) = 0;
  303. /**
  304. * virtual function FlashPadRect
  305. * @param aPadPos Position of the shape (center of the rectangle
  306. * @param aSize = size of rounded rect
  307. * @param aPadOrient The rotation of the shape
  308. * @param aTraceMode FILLED or SKETCH
  309. * @param aData an auxuliary info (mainly for gerber format attributes)
  310. */
  311. virtual void FlashPadRect( const wxPoint& aPadPos, const wxSize& aSize,
  312. double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) = 0;
  313. /**
  314. * virtual function FlashPadRoundRect
  315. * @param aPadPos Position of the shape (center of the rectangle
  316. * @param aSize = size of rounded rect
  317. * @param aCornerRadius Radius of the rounded corners
  318. * @param aOrient The rotation of the shape
  319. * @param aTraceMode FILLED or SKETCH
  320. * @param aData an auxiliary info (mainly for gerber format attributes)
  321. */
  322. virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
  323. int aCornerRadius, double aOrient,
  324. EDA_DRAW_MODE_T aTraceMode, void* aData ) = 0;
  325. /**
  326. * virtual function FlashPadCustom
  327. * @param aPadPos Position of the shape (center of the rectangle
  328. * @param aSize = size of round reference pad
  329. * @param aPolygons the shape as polygon set
  330. * @param aTraceMode FILLED or SKETCH
  331. * @param aData an auxiliary info (mainly for gerber format attributes)
  332. */
  333. virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
  334. SHAPE_POLY_SET* aPolygons,
  335. EDA_DRAW_MODE_T aTraceMode, void* aData ) = 0;
  336. /** virtual function FlashPadTrapez
  337. * flash a trapezoidal pad
  338. * @param aPadPos = the position of the shape
  339. * @param aCorners = the list of 4 corners positions,
  340. * relative to the shape position, pad orientation 0
  341. * @param aPadOrient = the rotation of the shape
  342. * @param aTraceMode = FILLED or SKETCH
  343. * @param aData an auxiliary info (mainly for gerber format attributes)
  344. */
  345. virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
  346. double aPadOrient, EDA_DRAW_MODE_T aTraceMode,
  347. void* aData ) = 0;
  348. /** Flash a regular polygon. Usefull only in Gerber files to flash a regular polygon
  349. * @param aShapePos is the center of the circle containing the polygon
  350. * @param aRadius is the radius of the circle containing the polygon
  351. * @param aCornerCount is the number of vertices
  352. * @param aOrient is the polygon rotation in degrees
  353. * @param aData is a auxiliary parameter used (if needed) to handle extra info
  354. * specific to the plotter
  355. */
  356. virtual void FlashRegularPolygon( const wxPoint& aShapePos, int aDiameter, int aCornerCount,
  357. double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) = 0 ;
  358. /**
  359. * Draws text with the plotter. For convenience it accept the color to use
  360. * for specific plotters (GERBER) aData is used to pass extra parameters
  361. */
  362. virtual void Text( const wxPoint& aPos,
  363. const COLOR4D aColor,
  364. const wxString& aText,
  365. double aOrient,
  366. const wxSize& aSize,
  367. enum EDA_TEXT_HJUSTIFY_T aH_justify,
  368. enum EDA_TEXT_VJUSTIFY_T aV_justify,
  369. int aWidth,
  370. bool aItalic,
  371. bool aBold,
  372. bool aMultilineAllowed = false,
  373. void* aData = NULL );
  374. /**
  375. * Draw a marker (used for the drill map)
  376. */
  377. static const unsigned MARKER_COUNT = 58;
  378. /**
  379. * Draw a pattern shape number aShapeId, to coord position.
  380. * Diameter diameter = (coord table) hole
  381. * AShapeId = index (used to generate forms characters)
  382. */
  383. void Marker( const wxPoint& position, int diametre, unsigned aShapeId );
  384. /**
  385. * Function SetLayerPolarity
  386. * sets current Gerber layer polarity to positive or negative
  387. * by writing \%LPD*\% or \%LPC*\% to the Gerber file, respectively.
  388. * (obviously starts a new Gerber layer, too)
  389. * @param aPositive is the layer polarity and true for positive.
  390. * It's not useful with most other plotter since they can't 'scratch'
  391. * the film like photoplotter imagers do
  392. */
  393. virtual void SetLayerPolarity( bool aPositive )
  394. {
  395. // NOP for most plotters
  396. }
  397. /**
  398. * Change the current text mode. See the PlotTextMode
  399. * explanation at the beginning of the file
  400. */
  401. virtual void SetTextMode( PLOT_TEXT_MODE mode )
  402. {
  403. // NOP for most plotters.
  404. }
  405. virtual void SetGerberCoordinatesFormat( int aResolution, bool aUseInches = false )
  406. {
  407. // NOP for most plotters. Only for Gerber plotter
  408. }
  409. virtual void SetSvgCoordinatesFormat( unsigned aResolution, bool aUseInches = false )
  410. {
  411. // NOP for most plotters. Only for SVG plotter
  412. }
  413. /**
  414. * calling this function allows one to define the beginning of a group
  415. * of drawing items, for instance in SVG or Gerber format.
  416. * (example: group all segments of a letter or a text)
  417. * @param aData can define any parameter
  418. * for most of plotters: do nothing
  419. */
  420. virtual void StartBlock( void* aData ) {}
  421. /**
  422. * calling this function allows one to define the end of a group of drawing
  423. * items for instance in SVG or Gerber format.
  424. * the group is started by StartBlock()
  425. * @param aData can define any parameter
  426. * for most of plotters: do nothing
  427. */
  428. virtual void EndBlock( void* aData ) {}
  429. protected:
  430. // These are marker subcomponents
  431. /**
  432. * Plot a circle centered on the position. Building block for markers
  433. */
  434. void markerCircle( const wxPoint& pos, int radius );
  435. /**
  436. * Plot a - bar centered on the position. Building block for markers
  437. */
  438. void markerHBar( const wxPoint& pos, int radius );
  439. /**
  440. * Plot a / bar centered on the position. Building block for markers
  441. */
  442. void markerSlash( const wxPoint& pos, int radius );
  443. /**
  444. * Plot a \ bar centered on the position. Building block for markers
  445. */
  446. void markerBackSlash( const wxPoint& pos, int radius );
  447. /**
  448. * Plot a | bar centered on the position. Building block for markers
  449. */
  450. void markerVBar( const wxPoint& pos, int radius );
  451. /**
  452. * Plot a square centered on the position. Building block for markers
  453. */
  454. void markerSquare( const wxPoint& position, int radius );
  455. /**
  456. * Plot a lozenge centered on the position. Building block for markers
  457. */
  458. void markerLozenge( const wxPoint& position, int radius );
  459. // Helper function for sketched filler segment
  460. /**
  461. * Cdonvert a thick segment and plot it as an oval
  462. */
  463. void segmentAsOval( const wxPoint& start, const wxPoint& end, int width,
  464. EDA_DRAW_MODE_T tracemode );
  465. void sketchOval( const wxPoint& pos, const wxSize& size, double orient, int width );
  466. // Coordinate and scaling conversion functions
  467. /**
  468. * Modifies coordinates according to the orientation,
  469. * scale factor, and offsets trace. Also convert from a wxPoint to DPOINT,
  470. * since some output engines needs floating point coordinates.
  471. */
  472. virtual DPOINT userToDeviceCoordinates( const wxPoint& aCoordinate );
  473. /**
  474. * Modifies size according to the plotter scale factors
  475. * (wxSize version, returns a DPOINT)
  476. */
  477. virtual DPOINT userToDeviceSize( const wxSize& size );
  478. /**
  479. * Modifies size according to the plotter scale factors
  480. * (simple double version)
  481. */
  482. virtual double userToDeviceSize( double size ) const;
  483. double GetDotMarkLenIU() const;
  484. double GetDashMarkLenIU() const;
  485. double GetDashGapLenIU() const;
  486. protected: // variables used in most of plotters:
  487. /// Plot scale - chosen by the user (even implicitly with 'fit in a4')
  488. double plotScale;
  489. /* Caller scale (how many IUs in a decimil - always); it's a double
  490. * because in eeschema there are 0.1 IUs in a decimil (eeschema
  491. * always works in mils internally) while pcbnew can work in decimil
  492. * or nanometers, so this value would be >= 1 */
  493. double m_IUsPerDecimil;
  494. /// Device scale (from IUs to plotter device units - usually decimils)
  495. double iuPerDeviceUnit;
  496. /// Plot offset (in IUs)
  497. wxPoint plotOffset;
  498. /// X axis orientation (SVG)
  499. /// and plot mirrored (only for PS, PDF HPGL and SVG)
  500. bool m_plotMirror;
  501. bool m_mirrorIsHorizontal; /// true to mirror horizontally (else vertically)
  502. bool m_yaxisReversed; /// true if the Y axis is top to bottom (SVG)
  503. /// Output file
  504. FILE* outputFile;
  505. // Pen handling
  506. bool colorMode; // true to plot in color, false to plot in black & white
  507. bool negativeMode; // true to generate a negative image (PS mode mainly)
  508. int currentPenWidth;
  509. char penState; // Current pen state: 'U', 'D' or 'Z' (see PenTo)
  510. wxPoint penLastpos; // Last pen positions; set to -1,-1 when the pen is
  511. // at rest
  512. wxString creator;
  513. wxString filename;
  514. wxString title;
  515. PAGE_INFO pageInfo;
  516. wxSize paperSize; // Paper size in IU - not in mils
  517. wxArrayString m_headerExtraLines; // a set of string to print in header file
  518. RENDER_SETTINGS* m_renderSettings;
  519. };
  520. class HPGL_PLOTTER : public PLOTTER
  521. {
  522. public:
  523. HPGL_PLOTTER();
  524. virtual PLOT_FORMAT GetPlotterType() const override
  525. {
  526. return PLOT_FORMAT::HPGL;
  527. }
  528. static wxString GetDefaultFileExtension()
  529. {
  530. return wxString( wxT( "plt" ) );
  531. }
  532. virtual bool StartPlot() override;
  533. virtual bool EndPlot() override;
  534. /// HPGL doesn't handle line thickness or color
  535. virtual void SetCurrentLineWidth( int width, void* aData = NULL ) override
  536. {
  537. // This is the truth
  538. currentPenWidth = userToDeviceSize( penDiameter );
  539. }
  540. virtual void SetDash( PLOT_DASH_TYPE dashed ) override;
  541. virtual void SetColor( COLOR4D color ) override {}
  542. virtual void SetPenSpeed( int speed )
  543. {
  544. penSpeed = speed;
  545. }
  546. virtual void SetPenNumber( int number )
  547. {
  548. penNumber = number;
  549. }
  550. virtual void SetPenDiameter( double diameter );
  551. virtual void SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
  552. double aScale, bool aMirror ) override;
  553. virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill,
  554. int width = USE_DEFAULT_LINE_WIDTH ) override;
  555. virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill,
  556. int width = USE_DEFAULT_LINE_WIDTH ) override;
  557. virtual void PlotPoly( const std::vector< wxPoint >& aCornerList,
  558. FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH,
  559. void * aData = NULL) override;
  560. virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width,
  561. EDA_DRAW_MODE_T tracemode, void* aData ) override;
  562. virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle,
  563. int rayon, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override;
  564. virtual void PenTo( const wxPoint& pos, char plume ) override;
  565. virtual void FlashPadCircle( const wxPoint& aPadPos, int aDiameter,
  566. EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  567. virtual void FlashPadOval( const wxPoint& aPadPos, const wxSize& aSize, double aPadOrient,
  568. EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  569. virtual void FlashPadRect( const wxPoint& aPadPos, const wxSize& aSize,
  570. double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  571. virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
  572. int aCornerRadius, double aOrient,
  573. EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  574. virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
  575. SHAPE_POLY_SET* aPolygons,
  576. EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  577. virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
  578. double aPadOrient, EDA_DRAW_MODE_T aTraceMode,
  579. void* aData ) override;
  580. virtual void FlashRegularPolygon( const wxPoint& aShapePos, int aDiameter, int aCornerCount,
  581. double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  582. protected:
  583. void penControl( char plume );
  584. int penSpeed;
  585. int penNumber;
  586. double penDiameter;
  587. };
  588. /**
  589. * The PSLIKE_PLOTTER class is an intermediate class to handle common
  590. * routines for engines working more or less with the postscript imaging
  591. * model
  592. */
  593. class PSLIKE_PLOTTER : public PLOTTER
  594. {
  595. public:
  596. PSLIKE_PLOTTER() :
  597. plotScaleAdjX( 1 ),
  598. plotScaleAdjY( 1 ),
  599. m_textMode( PLOT_TEXT_MODE::PHANTOM )
  600. {
  601. }
  602. /**
  603. * PS and PDF fully implement native text (for the Latin-1 subset)
  604. */
  605. virtual void SetTextMode( PLOT_TEXT_MODE mode ) override
  606. {
  607. if( mode != PLOT_TEXT_MODE::DEFAULT )
  608. m_textMode = mode;
  609. }
  610. /**
  611. * Set the 'fine' scaling for the postscript engine
  612. */
  613. void SetScaleAdjust( double scaleX, double scaleY )
  614. {
  615. plotScaleAdjX = scaleX;
  616. plotScaleAdjY = scaleY;
  617. }
  618. // Pad routines are handled with lower level primitives
  619. virtual void FlashPadCircle( const wxPoint& aPadPos, int aDiameter,
  620. EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  621. virtual void FlashPadOval( const wxPoint& aPadPos, const wxSize& aSize, double aPadOrient,
  622. EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  623. virtual void FlashPadRect( const wxPoint& aPadPos, const wxSize& aSize,
  624. double aPadOrient, EDA_DRAW_MODE_T aTraceMode,
  625. void* aData ) override;
  626. virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
  627. int aCornerRadius, double aOrient,
  628. EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  629. virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
  630. SHAPE_POLY_SET* aPolygons,
  631. EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  632. virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
  633. double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  634. virtual void FlashRegularPolygon( const wxPoint& aShapePos, int aDiameter, int aCornerCount,
  635. double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  636. /** The SetColor implementation is split with the subclasses:
  637. * The PSLIKE computes the rgb values, the subclass emits the
  638. * operator to actually do it
  639. */
  640. virtual void SetColor( COLOR4D color ) override;
  641. protected:
  642. void computeTextParameters( const wxPoint& aPos,
  643. const wxString& aText,
  644. int aOrient,
  645. const wxSize& aSize,
  646. bool aMirror,
  647. enum EDA_TEXT_HJUSTIFY_T aH_justify,
  648. enum EDA_TEXT_VJUSTIFY_T aV_justify,
  649. int aWidth,
  650. bool aItalic,
  651. bool aBold,
  652. double *wideningFactor,
  653. double *ctm_a,
  654. double *ctm_b,
  655. double *ctm_c,
  656. double *ctm_d,
  657. double *ctm_e,
  658. double *ctm_f,
  659. double *heightFactor );
  660. void postscriptOverlinePositions( const wxString& aText, int aXSize,
  661. bool aItalic, bool aBold,
  662. std::vector<int> *pos_pairs );
  663. /// convert a wxString unicode string to a char string compatible with the accepted
  664. /// string plotter format (convert special chars and non ascii7 chars)
  665. virtual std::string encodeStringForPlotter( const wxString& aUnicode );
  666. /// Virtual primitive for emitting the setrgbcolor operator
  667. virtual void emitSetRGBColor( double r, double g, double b ) = 0;
  668. /// Height of the postscript font (from the AFM)
  669. static const double postscriptTextAscent; // = 0.718;
  670. int returnPostscriptTextWidth( const wxString& aText, int aXSize,
  671. bool aItalic, bool aBold );
  672. /// Fine user scale adjust ( = 1.0 if no correction)
  673. double plotScaleAdjX, plotScaleAdjY;
  674. /// How to draw text
  675. PLOT_TEXT_MODE m_textMode;
  676. };
  677. class PS_PLOTTER : public PSLIKE_PLOTTER
  678. {
  679. public:
  680. PS_PLOTTER()
  681. {
  682. // The phantom plot in postscript is an hack and reportedly
  683. // crashes Adobe's own postscript interpreter!
  684. m_textMode = PLOT_TEXT_MODE::STROKE;
  685. }
  686. static wxString GetDefaultFileExtension()
  687. {
  688. return wxString( wxT( "ps" ) );
  689. }
  690. virtual PLOT_FORMAT GetPlotterType() const override
  691. {
  692. return PLOT_FORMAT::POST;
  693. }
  694. virtual bool StartPlot() override;
  695. virtual bool EndPlot() override;
  696. virtual void SetCurrentLineWidth( int width, void* aData = NULL ) override;
  697. virtual void SetDash( PLOT_DASH_TYPE dashed ) override;
  698. virtual void SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
  699. double aScale, bool aMirror ) override;
  700. virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill,
  701. int width = USE_DEFAULT_LINE_WIDTH ) override;
  702. virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill,
  703. int width = USE_DEFAULT_LINE_WIDTH ) override;
  704. virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle,
  705. int rayon, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override;
  706. virtual void PlotPoly( const std::vector< wxPoint >& aCornerList,
  707. FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH,
  708. void * aData = NULL ) override;
  709. virtual void PlotImage( const wxImage& aImage, const wxPoint& aPos,
  710. double aScaleFactor ) override;
  711. virtual void PenTo( const wxPoint& pos, char plume ) override;
  712. virtual void Text( const wxPoint& aPos,
  713. const COLOR4D aColor,
  714. const wxString& aText,
  715. double aOrient,
  716. const wxSize& aSize,
  717. enum EDA_TEXT_HJUSTIFY_T aH_justify,
  718. enum EDA_TEXT_VJUSTIFY_T aV_justify,
  719. int aWidth,
  720. bool aItalic,
  721. bool aBold,
  722. bool aMultilineAllowed = false,
  723. void* aData = NULL ) override;
  724. protected:
  725. virtual void emitSetRGBColor( double r, double g, double b ) override;
  726. };
  727. class PDF_PLOTTER : public PSLIKE_PLOTTER
  728. {
  729. public:
  730. PDF_PLOTTER() :
  731. pageTreeHandle( 0 ),
  732. fontResDictHandle( 0 ),
  733. pageStreamHandle( 0 ),
  734. streamLengthHandle( 0 ),
  735. workFile( nullptr )
  736. {
  737. }
  738. virtual PLOT_FORMAT GetPlotterType() const override
  739. {
  740. return PLOT_FORMAT::PDF;
  741. }
  742. static wxString GetDefaultFileExtension()
  743. {
  744. return wxString( wxT( "pdf" ) );
  745. }
  746. /**
  747. * Open or create the plot file aFullFilename
  748. * @param aFullFilename = the full file name of the file to create
  749. * @return true if success, false if the file cannot be created/opened
  750. *
  751. * The base class open the file in text mode, so we should have this
  752. * function overlaid for PDF files, which are binary files
  753. */
  754. virtual bool OpenFile( const wxString& aFullFilename ) override;
  755. virtual bool StartPlot() override;
  756. virtual bool EndPlot() override;
  757. virtual void StartPage();
  758. virtual void ClosePage();
  759. virtual void SetCurrentLineWidth( int width, void* aData = NULL ) override;
  760. virtual void SetDash( PLOT_DASH_TYPE dashed ) override;
  761. /** PDF can have multiple pages, so SetPageSettings can be called
  762. * with the outputFile open (but not inside a page stream!) */
  763. virtual void SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
  764. double aScale, bool aMirror ) override;
  765. virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill,
  766. int width = USE_DEFAULT_LINE_WIDTH ) override;
  767. virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill,
  768. int width = USE_DEFAULT_LINE_WIDTH ) override;
  769. virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle,
  770. int rayon, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override;
  771. virtual void PlotPoly( const std::vector< wxPoint >& aCornerList,
  772. FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH,
  773. void * aData = NULL ) override;
  774. virtual void PenTo( const wxPoint& pos, char plume ) override;
  775. virtual void Text( const wxPoint& aPos,
  776. const COLOR4D aColor,
  777. const wxString& aText,
  778. double aOrient,
  779. const wxSize& aSize,
  780. enum EDA_TEXT_HJUSTIFY_T aH_justify,
  781. enum EDA_TEXT_VJUSTIFY_T aV_justify,
  782. int aWidth,
  783. bool aItalic,
  784. bool aBold,
  785. bool aMultilineAllowed = false,
  786. void* aData = NULL ) override;
  787. virtual void PlotImage( const wxImage& aImage, const wxPoint& aPos,
  788. double aScaleFactor ) override;
  789. protected:
  790. /// convert a wxString unicode string to a char string compatible with the accepted
  791. /// string PDF format (convert special chars and non ascii7 chars)
  792. std::string encodeStringForPlotter( const wxString& aUnicode ) override;
  793. virtual void emitSetRGBColor( double r, double g, double b ) override;
  794. int allocPdfObject();
  795. int startPdfObject(int handle = -1);
  796. void closePdfObject();
  797. int startPdfStream(int handle = -1);
  798. void closePdfStream();
  799. int pageTreeHandle; /// Handle to the root of the page tree object
  800. int fontResDictHandle; /// Font resource dictionary
  801. std::vector<int> pageHandles;/// Handles to the page objects
  802. int pageStreamHandle; /// Handle of the page content object
  803. int streamLengthHandle; /// Handle to the deferred stream length
  804. wxString workFilename;
  805. FILE* workFile; /// Temporary file to costruct the stream before zipping
  806. std::vector<long> xrefTable; /// The PDF xref offset table
  807. };
  808. class SVG_PLOTTER : public PSLIKE_PLOTTER
  809. {
  810. public:
  811. SVG_PLOTTER();
  812. static wxString GetDefaultFileExtension()
  813. {
  814. return wxString( wxT( "svg" ) );
  815. }
  816. virtual PLOT_FORMAT GetPlotterType() const override
  817. {
  818. return PLOT_FORMAT::SVG;
  819. }
  820. virtual void SetColor( COLOR4D color ) override;
  821. virtual bool StartPlot() override;
  822. virtual bool EndPlot() override;
  823. virtual void SetCurrentLineWidth( int width, void* aData = NULL ) override;
  824. virtual void SetDash( PLOT_DASH_TYPE dashed ) override;
  825. virtual void SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
  826. double aScale, bool aMirror ) override;
  827. virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill,
  828. int width = USE_DEFAULT_LINE_WIDTH ) override;
  829. virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill,
  830. int width = USE_DEFAULT_LINE_WIDTH ) override;
  831. virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle,
  832. int rayon, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override;
  833. virtual void BezierCurve( const wxPoint& aStart, const wxPoint& aControl1,
  834. const wxPoint& aControl2, const wxPoint& aEnd,
  835. int aTolerance,
  836. int aLineThickness = USE_DEFAULT_LINE_WIDTH ) override;
  837. virtual void PlotPoly( const std::vector< wxPoint >& aCornerList,
  838. FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH,
  839. void * aData = NULL ) override;
  840. virtual void PlotImage( const wxImage& aImage, const wxPoint& aPos,
  841. double aScaleFactor ) override;
  842. virtual void PenTo( const wxPoint& pos, char plume ) override;
  843. /**
  844. * Function SetSvgCoordinatesFormat
  845. * selection of SVG step size (number of digits needed for 1 mm or 1 inch )
  846. * @param aResolution = number of digits in mantissa of coordinate
  847. * use a value from 3-6
  848. * do not use value > 6 to avoid overflow in PCBNEW
  849. * do not use value > 4 to avoid overflow for other parts
  850. * @param aUseInches = true to use inches, false to use mm (default)
  851. *
  852. * Should be called only after SetViewport() is called
  853. */
  854. virtual void SetSvgCoordinatesFormat( unsigned aResolution, bool aUseInches = false ) override;
  855. /**
  856. * calling this function allows one to define the beginning of a group
  857. * of drawing items (used in SVG format to separate components)
  858. * @param aData should be a string for the SVG ID tage
  859. */
  860. virtual void StartBlock( void* aData ) override;
  861. /**
  862. * calling this function allows one to define the end of a group of drawing
  863. * items the group is started by StartBlock()
  864. * @param aData should be null
  865. */
  866. virtual void EndBlock( void* aData ) override;
  867. virtual void Text( const wxPoint& aPos,
  868. const COLOR4D aColor,
  869. const wxString& aText,
  870. double aOrient,
  871. const wxSize& aSize,
  872. enum EDA_TEXT_HJUSTIFY_T aH_justify,
  873. enum EDA_TEXT_VJUSTIFY_T aV_justify,
  874. int aWidth,
  875. bool aItalic,
  876. bool aBold,
  877. bool aMultilineAllowed = false,
  878. void* aData = NULL ) override;
  879. protected:
  880. FILL_T m_fillMode; // true if the current contour
  881. // rect, arc, circle, polygon must be filled
  882. long m_pen_rgb_color; // current rgb color value: each color has
  883. // a value 0 ... 255, and the 3 colors are
  884. // grouped in a 3x8 bits value
  885. // (written in hex to svg files)
  886. long m_brush_rgb_color; // same as m_pen_rgb_color, used to fill
  887. // some contours.
  888. bool m_graphics_changed; // true if a pen/brush parameter is modified
  889. // color, pen size, fil mode ...
  890. // the new SVG stype must be output on file
  891. PLOT_DASH_TYPE m_dashed; // plot line style
  892. bool m_useInch; // is 0 if the step size is 10**-n*mm
  893. // is 1 if the step size is 10**-n*inch
  894. // Where n is given from m_precision
  895. unsigned m_precision; // How fine the step size is
  896. // Use 3-6 (3 means um precision, 6 nm precision) in pcbnew
  897. // 3-4 in other moduls (avoid values >4 to avoid overflow)
  898. // see also comment for m_useInch.
  899. /**
  900. * function emitSetRGBColor()
  901. * initialize m_pen_rgb_color from reduced values r, g ,b
  902. * ( reduced values are 0.0 to 1.0 )
  903. */
  904. virtual void emitSetRGBColor( double r, double g, double b ) override;
  905. /**
  906. * function setSVGPlotStyle()
  907. * output the string which define pen and brush color, shape, transparency
  908. *
  909. * @param aIsGroup If false, do not form a new group for the style.
  910. * @param aExtraStyle If given, the string will be added into the style string before closing
  911. */
  912. void setSVGPlotStyle( bool aIsGroup = true, const std::string& aExtraStyle = {} );
  913. /**
  914. * function setFillMode()
  915. * prepare parameters for setSVGPlotStyle()
  916. */
  917. void setFillMode( FILL_T fill );
  918. };
  919. /* Class to handle a D_CODE when plotting a board using Standard Aperture Templates
  920. * (complex apertures need aperture macros
  921. * 5 types:
  922. * Circle (round)
  923. * Rectangle
  924. * Obround (oval)
  925. * regular polygon
  926. *
  927. * We need round apertures to plot lines, so we also defined a aperture type for plotting
  928. */
  929. #define FIRST_DCODE_VALUE 10 // D_CODE < 10 is a command, D_CODE >= 10 is a tool
  930. class APERTURE
  931. {
  932. public:
  933. enum APERTURE_TYPE {
  934. AT_CIRCLE = 1, // round aperture, to flash pads
  935. AT_RECT = 2, // rect aperture, to flash pads
  936. AT_PLOTTING = 3, // round aperture, to plot lines
  937. AT_OVAL = 4, // oval aperture, to flash pads
  938. AT_REGULAR_POLY = 5,// Regular polygon (n vertices, n = 3 .. 12, with rotation)
  939. AT_REGULAR_POLY3, // Regular polygon 3 vertices, with rotation
  940. AT_REGULAR_POLY4, // Regular polygon 4 vertices, with rotation
  941. AT_REGULAR_POLY5, // Regular polygon 5 vertices, with rotation
  942. AT_REGULAR_POLY6, // Regular polygon 6 vertices, with rotation
  943. AT_REGULAR_POLY7, // Regular polygon 7 vertices, with rotation
  944. AT_REGULAR_POLY8, // Regular polygon 8 vertices, with rotation
  945. AT_REGULAR_POLY9, // Regular polygon 9 vertices, with rotation
  946. AT_REGULAR_POLY10, // Regular polygon 10 vertices, with rotation
  947. AT_REGULAR_POLY11, // Regular polygon 11 vertices, with rotation
  948. AT_REGULAR_POLY12, // Regular polygon 12 vertices, with rotation
  949. };
  950. void SetSize( const wxSize& aSize )
  951. {
  952. m_Size = aSize;
  953. }
  954. const wxSize GetSize()
  955. {
  956. return m_Size;
  957. }
  958. void SetDiameter( int aDiameter )
  959. {
  960. m_Size.x = aDiameter;
  961. }
  962. int GetDiameter()
  963. {
  964. return m_Size.x;
  965. }
  966. void SetVerticeCount( int aCount )
  967. {
  968. if( aCount < 3 )
  969. aCount = 3;
  970. else if( aCount > 12 )
  971. aCount = 12;
  972. m_Type = (APERTURE_TYPE)(AT_REGULAR_POLY3 - 3 + aCount);
  973. }
  974. int GetVerticeCount()
  975. {
  976. return m_Type - AT_REGULAR_POLY3 + 3;
  977. }
  978. void SetRotation( double aRotDegree )
  979. {
  980. // The rotation is stored in 1/1000 degree
  981. m_Size.y = int( aRotDegree * 1000.0 );
  982. }
  983. double GetRotation()
  984. {
  985. // The rotation is stored in 1/1000 degree
  986. return m_Size.y / 1000.0;
  987. }
  988. // Type ( Line, rect , circulaire , ovale poly 3 to 12 vertices )
  989. APERTURE_TYPE m_Type;
  990. // horiz and Vert size, or diameter and rotation for regular polygon
  991. // The diameter (for circle and polygons) is stored in m_Size.x
  992. // the rotation is stored in m_Size.y in 1/1000 degree
  993. wxSize m_Size;
  994. // code number ( >= 10 )
  995. int m_DCode;
  996. // the attribute attached to this aperture
  997. // Only one attribute is allowed by aperture
  998. // 0 = no specific aperture attribute
  999. int m_ApertureAttribute;
  1000. };
  1001. class GERBER_PLOTTER : public PLOTTER
  1002. {
  1003. public:
  1004. GERBER_PLOTTER();
  1005. virtual PLOT_FORMAT GetPlotterType() const override
  1006. {
  1007. return PLOT_FORMAT::GERBER;
  1008. }
  1009. static wxString GetDefaultFileExtension()
  1010. {
  1011. return wxString( wxT( "gbr" ) );
  1012. }
  1013. /**
  1014. * Function StartPlot
  1015. * Write GERBER header to file
  1016. * initialize global variable g_Plot_PlotOutputFile
  1017. */
  1018. virtual bool StartPlot() override;
  1019. virtual bool EndPlot() override;
  1020. virtual void SetCurrentLineWidth( int width, void* aData = NULL ) override;
  1021. // RS274X has no dashing, nor colours
  1022. virtual void SetDash( PLOT_DASH_TYPE dashed ) override
  1023. {
  1024. }
  1025. virtual void SetColor( COLOR4D color ) override {}
  1026. // Currently, aScale and aMirror are not used in gerber plotter
  1027. virtual void SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
  1028. double aScale, bool aMirror ) override;
  1029. virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill,
  1030. int width = USE_DEFAULT_LINE_WIDTH ) override;
  1031. virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill,
  1032. int width = USE_DEFAULT_LINE_WIDTH ) override;
  1033. virtual void Arc( const wxPoint& aCenter, double aStAngle, double aEndAngle,
  1034. int aRadius, FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH ) override;
  1035. virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width,
  1036. EDA_DRAW_MODE_T tracemode, void* aData ) override;
  1037. virtual void ThickArc( const wxPoint& centre, double StAngle, double EndAngle,
  1038. int rayon, int width, EDA_DRAW_MODE_T tracemode, void* aData ) override;
  1039. virtual void ThickRect( const wxPoint& p1, const wxPoint& p2, int width,
  1040. EDA_DRAW_MODE_T tracemode, void* aData ) override;
  1041. virtual void ThickCircle( const wxPoint& pos, int diametre, int width,
  1042. EDA_DRAW_MODE_T tracemode, void* aData ) override;
  1043. /**
  1044. * Gerber polygon: they can (and *should*) be filled with the
  1045. * appropriate G36/G37 sequence
  1046. */
  1047. virtual void PlotPoly( const std::vector< wxPoint >& aCornerList,
  1048. FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH,
  1049. void* aData = nullptr ) override;
  1050. virtual void PenTo( const wxPoint& pos, char plume ) override;
  1051. virtual void Text( const wxPoint& aPos,
  1052. const COLOR4D aColor,
  1053. const wxString& aText,
  1054. double aOrient,
  1055. const wxSize& aSize,
  1056. enum EDA_TEXT_HJUSTIFY_T aH_justify,
  1057. enum EDA_TEXT_VJUSTIFY_T aV_justify,
  1058. int aWidth,
  1059. bool aItalic,
  1060. bool aBold,
  1061. bool aMultilineAllowed = false,
  1062. void* aData = NULL ) override;
  1063. /**
  1064. * Filled circular flashes are stored as apertures
  1065. */
  1066. virtual void FlashPadCircle( const wxPoint& pos, int diametre,
  1067. EDA_DRAW_MODE_T trace_mode, void* aData ) override;
  1068. /**
  1069. * Filled oval flashes are handled as aperture in the 90 degree positions only
  1070. */
  1071. virtual void FlashPadOval( const wxPoint& pos, const wxSize& size, double orient,
  1072. EDA_DRAW_MODE_T trace_mode, void* aData ) override;
  1073. /**
  1074. * Filled rect flashes are handled as aperture in the 0 90 180 or 270 degree orientation only
  1075. * and as polygon for other orientations
  1076. * TODO: always use flashed shapes (aperture macros)
  1077. */
  1078. virtual void FlashPadRect( const wxPoint& pos, const wxSize& size,
  1079. double orient, EDA_DRAW_MODE_T trace_mode, void* aData ) override;
  1080. /**
  1081. * Roundrect pad at the moment are not handled as aperture, since
  1082. * they require aperture macros
  1083. * TODO: always use flashed shapes (aperture macros)
  1084. */
  1085. virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
  1086. int aCornerRadius, double aOrient,
  1087. EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  1088. virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
  1089. SHAPE_POLY_SET* aPolygons,
  1090. EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  1091. /**
  1092. * Trapezoidal pad at the moment are *never* handled as aperture, since
  1093. * they require aperture macros
  1094. * TODO: always use flashed shapes (aperture macros)
  1095. */
  1096. virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
  1097. double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  1098. virtual void FlashRegularPolygon( const wxPoint& aShapePos, int aDiameter, int aCornerCount,
  1099. double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  1100. /**
  1101. * Plot a Gerber region: similar to PlotPoly but plot only filled polygon,
  1102. * and add the TA.AperFunction if aData contains this attribute, and clear it
  1103. * after plotting
  1104. */
  1105. void PlotGerberRegion( const std::vector< wxPoint >& aCornerList,
  1106. void * aData = NULL );
  1107. /**
  1108. * Change the plot polarity and begin a new layer
  1109. * Used to 'scratch off' silk screen away from solder mask
  1110. */
  1111. virtual void SetLayerPolarity( bool aPositive ) override;
  1112. /**
  1113. * Function SetGerberCoordinatesFormat
  1114. * selection of Gerber units and resolution (number of digits in mantissa)
  1115. * @param aResolution = number of digits in mantissa of coordinate
  1116. * use 5 or 6 for mm and 6 or 7 for inches
  1117. * do not use value > 6 (mm) or > 7 (in) to avoid overflow
  1118. * @param aUseInches = true to use inches, false to use mm (default)
  1119. *
  1120. * Should be called only after SetViewport() is called
  1121. */
  1122. virtual void SetGerberCoordinatesFormat( int aResolution, bool aUseInches = false ) override;
  1123. void UseX2format( bool aEnable ) { m_useX2format = aEnable; }
  1124. void UseX2NetAttributes( bool aEnable ) { m_useNetAttributes = aEnable; }
  1125. /**
  1126. * calling this function allows one to define the beginning of a group
  1127. * of drawing items (used in X2 format with netlist attributes)
  1128. * @param aData can define any parameter
  1129. */
  1130. virtual void StartBlock( void* aData ) override;
  1131. /**
  1132. * calling this function allows one to define the end of a group of drawing
  1133. * items the group is started by StartBlock()
  1134. * (used in X2 format with netlist attributes)
  1135. * @param aData can define any parameter
  1136. */
  1137. virtual void EndBlock( void* aData ) override;
  1138. /** Remove (clear) all attributes from object attributes dictionary (TO. and TA commands)
  1139. * similar to clearNetAttribute(), this is an unconditional reset of TO. and TA. attributes
  1140. */
  1141. void ClearAllAttributes();
  1142. /**
  1143. * @return a index to the aperture in aperture list which meets the size and type of tool
  1144. * if the aperture does not exist, it is created and entered in aperture list
  1145. * @param aSize = the size of tool
  1146. * @param aType = the type ( shape ) of tool
  1147. * @param aApertureAttribute = an aperture attribute of the tool (a tool can have onlu one attribute)
  1148. * 0 = no specific attribute
  1149. */
  1150. int GetOrCreateAperture( const wxSize& aSize,
  1151. APERTURE::APERTURE_TYPE aType, int aApertureAttribute );
  1152. protected:
  1153. /** Plot a round rect (a round rect shape in fact) as a Gerber region
  1154. * using lines and arcs for corners
  1155. * @param aRectCenter is the center of the rectangle
  1156. * @param aSize is the size of the rectangle
  1157. * @param aCornerRadius is the radius of the corners
  1158. * @param aOrient is the rotation of the rectangle
  1159. * Note: only the G36 ... G37 region is created.
  1160. */
  1161. void plotRoundRectAsRegion( const wxPoint& aRectCenter, const wxSize& aSize,
  1162. int aCornerRadius, double aOrient );
  1163. /**
  1164. * Plot a Gerber arc.
  1165. * if aPlotInRegion = true, the current pen position will not be
  1166. * initialized to the arc start position, and therefore the arc can be used
  1167. * to define a region outline item
  1168. * a line will be created from current ^position to arc start point
  1169. * if aPlotInRegion = false, the current pen position will be initialized
  1170. * to the arc start position, to plot an usual arc item
  1171. * The line thickness is not initialized in plotArc, and must be initialized
  1172. * before calling it if needed.
  1173. */
  1174. void plotArc( const wxPoint& aCenter, double aStAngle, double aEndAngle,
  1175. int aRadius, bool aPlotInRegion );
  1176. /**
  1177. * Pick an existing aperture or create a new one, matching the
  1178. * size, type and attributes.
  1179. * write the DCode selection on gerber file
  1180. */
  1181. void selectAperture( const wxSize& aSize, APERTURE::APERTURE_TYPE aType,
  1182. int aApertureAttribute );
  1183. /**
  1184. * Pick an existing aperture or create a new one, matching the
  1185. * aDiameter, aPolygonRotation, type and attributes.
  1186. * It apply only to apertures with type = AT_REGULAR_POLY3 to AT_REGULAR_POLY12
  1187. * write the DCode selection on gerber file
  1188. */
  1189. void selectAperture( int aDiameter, double aPolygonRotation,
  1190. APERTURE::APERTURE_TYPE aType, int aApertureAttribute );
  1191. /**
  1192. * Emit a D-Code record, using proper conversions
  1193. * to format a leading zero omitted gerber coordinate
  1194. * (for n decimal positions, see header generation in start_plot
  1195. */
  1196. void emitDcode( const DPOINT& pt, int dcode );
  1197. /**
  1198. * print a Gerber net attribute object record.
  1199. * In a gerber file, a net attribute is owned by a graphic object
  1200. * formatNetAttribute must be called before creating the object
  1201. * @param aData contains the dato to format.
  1202. * the generated string depends on the type of netlist info
  1203. */
  1204. void formatNetAttribute( GBR_NETLIST_METADATA* aData );
  1205. /**
  1206. * clear a Gerber net attribute record (clear object attribute dictionary)
  1207. * and output the clear object attribute dictionary command to gerber file
  1208. * has effect only if a net attribute is stored in m_objectAttributesDictionnary
  1209. */
  1210. void clearNetAttribute();
  1211. // the attributes dictionary created/modifed by %TO, attached to objects, when they are created
  1212. // by D01, D03, G36/G37 commands
  1213. // standard attributes are .P, .C and .N
  1214. // this is used by gerber readers when creating a new object. Cleared by %TD command
  1215. // Note: m_objectAttributesDictionnary can store more than one attribute
  1216. // the string stores the line(s) actually written to the gerber file
  1217. // it can store a .P, .C or .N attribute, or 2 or 3 attributes, separated by a \n char (EOL)
  1218. std::string m_objectAttributesDictionnary;
  1219. // The last aperture attribute generated (only one aperture attribute can be set)
  1220. int m_apertureAttribute;
  1221. FILE* workFile;
  1222. FILE* finalFile;
  1223. wxString m_workFilename;
  1224. /**
  1225. * Generate the table of D codes
  1226. */
  1227. void writeApertureList();
  1228. std::vector<APERTURE> m_apertures; // The list of available apertures
  1229. int m_currentApertureIdx; // The index of the current aperture in m_apertures
  1230. bool m_gerberUnitInch; // true if the gerber units are inches, false for mm
  1231. int m_gerberUnitFmt; // number of digits in mantissa.
  1232. // usually 6 in Inches and 5 or 6 in mm
  1233. bool m_useX2format; // Add X2 file header attributes. If false, attributes
  1234. // will be added as comments.
  1235. bool m_useNetAttributes; // In recent gerber files, netlist info can be added.
  1236. // It will be added if this param is true, using X2 or
  1237. // X1 format
  1238. };
  1239. class DXF_PLOTTER : public PLOTTER
  1240. {
  1241. public:
  1242. DXF_PLOTTER() : m_textAsLines( false )
  1243. {
  1244. m_textAsLines = true;
  1245. m_currentColor = COLOR4D::BLACK;
  1246. m_currentLineType = PLOT_DASH_TYPE::SOLID;
  1247. SetUnits( DXF_UNITS::INCHES );
  1248. }
  1249. virtual PLOT_FORMAT GetPlotterType() const override
  1250. {
  1251. return PLOT_FORMAT::DXF;
  1252. }
  1253. static wxString GetDefaultFileExtension()
  1254. {
  1255. return wxString( wxT( "dxf" ) );
  1256. }
  1257. /**
  1258. * DXF handles NATIVE text emitting TEXT entities
  1259. */
  1260. virtual void SetTextMode( PLOT_TEXT_MODE mode ) override
  1261. {
  1262. if( mode != PLOT_TEXT_MODE::DEFAULT )
  1263. m_textAsLines = ( mode != PLOT_TEXT_MODE::NATIVE );
  1264. }
  1265. virtual bool StartPlot() override;
  1266. virtual bool EndPlot() override;
  1267. // For now we don't use 'thick' primitives, so no line width
  1268. virtual void SetCurrentLineWidth( int width, void* aData = NULL ) override
  1269. {
  1270. currentPenWidth = 0;
  1271. }
  1272. virtual void SetDash( PLOT_DASH_TYPE dashed ) override;
  1273. virtual void SetColor( COLOR4D color ) override;
  1274. virtual void SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
  1275. double aScale, bool aMirror ) override;
  1276. virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill,
  1277. int width = USE_DEFAULT_LINE_WIDTH ) override;
  1278. virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill,
  1279. int width = USE_DEFAULT_LINE_WIDTH ) override;
  1280. virtual void PlotPoly( const std::vector< wxPoint >& aCornerList,
  1281. FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH, void * aData = NULL ) override;
  1282. virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width,
  1283. EDA_DRAW_MODE_T tracemode, void* aData ) override;
  1284. virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle,
  1285. int rayon, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ) override;
  1286. virtual void PenTo( const wxPoint& pos, char plume ) override;
  1287. virtual void FlashPadCircle( const wxPoint& pos, int diametre,
  1288. EDA_DRAW_MODE_T trace_mode, void* aData ) override;
  1289. virtual void FlashPadOval( const wxPoint& pos, const wxSize& size, double orient,
  1290. EDA_DRAW_MODE_T trace_mode, void* aData ) override;
  1291. virtual void FlashPadRect( const wxPoint& pos, const wxSize& size,
  1292. double orient, EDA_DRAW_MODE_T trace_mode, void* aData ) override;
  1293. virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
  1294. int aCornerRadius, double aOrient,
  1295. EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  1296. virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
  1297. SHAPE_POLY_SET* aPolygons,
  1298. EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  1299. virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
  1300. double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  1301. virtual void FlashRegularPolygon( const wxPoint& aShapePos, int aDiameter, int aCornerCount,
  1302. double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
  1303. virtual void Text( const wxPoint& aPos,
  1304. const COLOR4D aColor,
  1305. const wxString& aText,
  1306. double aOrient,
  1307. const wxSize& aSize,
  1308. enum EDA_TEXT_HJUSTIFY_T aH_justify,
  1309. enum EDA_TEXT_VJUSTIFY_T aV_justify,
  1310. int aWidth,
  1311. bool aItalic,
  1312. bool aBold,
  1313. bool aMultilineAllowed = false,
  1314. void* aData = NULL ) override;
  1315. // Must be in the same order as the drop-down list in the plot dialog inside pcbnew
  1316. enum class DXF_UNITS
  1317. {
  1318. INCHES = 0,
  1319. MILLIMETERS = 1
  1320. };
  1321. /**
  1322. * Set the units to use for plotting the DXF file.
  1323. *
  1324. * @param aUnit - The units to use
  1325. */
  1326. void SetUnits( DXF_UNITS aUnit );
  1327. /**
  1328. * The units currently enabled for plotting
  1329. *
  1330. * @return The currently configured units
  1331. */
  1332. DXF_UNITS GetUnits() const
  1333. {
  1334. return m_plotUnits;
  1335. }
  1336. /**
  1337. * Get the scale factor to apply to convert the device units to be in the
  1338. * currently set units.
  1339. *
  1340. * @return Scaling factor to apply for unit conversion
  1341. */
  1342. double GetUnitScaling() const
  1343. {
  1344. return m_unitScalingFactor;
  1345. }
  1346. /**
  1347. * Get the correct value for the $MEASUREMENT field given the current units
  1348. *
  1349. * @return the $MEASUREMENT directive field value
  1350. */
  1351. unsigned int GetMeasurementDirective() const
  1352. {
  1353. return m_measurementDirective;
  1354. }
  1355. protected:
  1356. bool m_textAsLines;
  1357. COLOR4D m_currentColor;
  1358. PLOT_DASH_TYPE m_currentLineType;
  1359. DXF_UNITS m_plotUnits;
  1360. double m_unitScalingFactor;
  1361. unsigned int m_measurementDirective;
  1362. };
  1363. class TITLE_BLOCK;
  1364. void PlotWorkSheet( PLOTTER* plotter, const PROJECT* aProject, const TITLE_BLOCK& aTitleBlock,
  1365. const PAGE_INFO& aPageInfo, int aSheetNumber, int aNumberOfSheets,
  1366. const wxString &aSheetDesc, const wxString &aFilename,
  1367. COLOR4D aColor = COLOR4D::UNSPECIFIED );
  1368. /** Returns the default plot extension for a format
  1369. */
  1370. wxString GetDefaultPlotExtension( PLOT_FORMAT aFormat );
  1371. #endif // PLOT_COMMON_H_