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-2021 KiCad Developers, see AUTHORS.txt for contributors. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, you may find one here: 19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 20 * or you may search the http://www.gnu.org website for the version 2 license, 21 * or you may write to the Free Software Foundation, Inc., 22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 23 */ 24 25 /** 26 * Plot settings, and plotting engines (PostScript, Gerber, HPGL and DXF) 27 * 28 * @file plotter.h 29 */ 30 31 #ifndef PLOT_COMMON_H_ 32 #define PLOT_COMMON_H_ 33 34 #include <eda_shape.h> 35 #include <vector> 36 #include <math/box2.h> 37 #include <gr_text.h> 38 #include <page_info.h> 39 #include <outline_mode.h> 40 #include <gal/color4d.h> 41 #include <render_settings.h> 42 43 class COLOR_SETTINGS; 44 class SHAPE_ARC; 45 class SHAPE_POLY_SET; 46 class SHAPE_LINE_CHAIN; 47 class GBR_NETLIST_METADATA; 48 class PROJECT; 49 50 using KIGFX::RENDER_SETTINGS; 51 52 53 // Must be in the same order as the drop-down list in the plot dialog inside pcbnew 54 // Units (inch/mm for DXF plotter 55 enum class DXF_UNITS 56 { 57 INCHES = 0, 58 MILLIMETERS = 1 59 }; 60 61 62 /** 63 * The set of supported output plot formats. 64 * 65 They should be kept in order of the radio buttons in the plot panel/windows. 66 */ 67 enum class PLOT_FORMAT 68 { 69 UNDEFINED = -1, 70 FIRST_FORMAT = 0, 71 HPGL = FIRST_FORMAT, 72 GERBER, 73 POST, 74 DXF, 75 PDF, 76 SVG, 77 LAST_FORMAT = SVG 78 }; 79 80 /** 81 * Which kind of text to output with the PSLIKE plotters. 82 * 83 * You can: 84 * 1) only use the internal vector font 85 * 2) only use native postscript fonts 86 * 3) use the internal vector font and add 'phantom' text to aid 87 * searching 88 * 4) keep the default for the plot driver 89 * 90 * This is recognized by the DXF driver too, where NATIVE emits 91 * TEXT entities instead of stroking the text 92 */ 93 enum class PLOT_TEXT_MODE 94 { 95 STROKE, 96 NATIVE, 97 PHANTOM, 98 DEFAULT 99 }; 100 101 /** 102 * Dashed line types. 103 */ 104 enum class PLOT_DASH_TYPE 105 { 106 DEFAULT = -1, 107 SOLID = 0, 108 FIRST_TYPE = SOLID, 109 DASH, 110 DOT, 111 DASHDOT, 112 LAST_TYPE = DASHDOT 113 }; 114 115 /** 116 * Base plotter engine class. General rule: all the interface with the caller 117 * is done in IU, the IU size is specified with SetViewport. Internal and 118 * output processing is usually done in decimils (or whatever unit the 119 * effective engine class need to use) 120 */ 121 class PLOTTER 122 { 123 public: 124 // These values are used as flag for pen or aperture selection 125 static const int DO_NOT_SET_LINE_WIDTH = -2; // Skip selection 126 static const int USE_DEFAULT_LINE_WIDTH = -1; // use the default pen 127 128 PLOTTER(); 129 130 virtual ~PLOTTER(); 131 132 /** 133 * Returns the effective plot engine in use. It's not very OO but for 134 * now is required since some things are only done with some output devices 135 * (like drill marks, emitted only for postscript 136 */ 137 virtual PLOT_FORMAT GetPlotterType() const = 0; 138 139 virtual bool StartPlot() = 0; 140 virtual bool EndPlot() = 0; 141 SetNegative(bool aNegative)142 virtual void SetNegative( bool aNegative ) 143 { 144 m_negativeMode = aNegative; 145 } 146 147 /** 148 * Plot in B/W or color. 149 * 150 * @param aColorMode use true to plot in color, false to plot in black and white. 151 */ SetColorMode(bool aColorMode)152 virtual void SetColorMode( bool aColorMode ) { m_colorMode = aColorMode; } GetColorMode()153 bool GetColorMode() const { return m_colorMode; } 154 SetRenderSettings(RENDER_SETTINGS * aSettings)155 void SetRenderSettings( RENDER_SETTINGS* aSettings ) { m_renderSettings = aSettings; } RenderSettings()156 RENDER_SETTINGS* RenderSettings() { return m_renderSettings; } 157 SetPageSettings(const PAGE_INFO & aPageSettings)158 virtual void SetPageSettings( const PAGE_INFO& aPageSettings ) { m_pageInfo = aPageSettings; } PageSettings()159 PAGE_INFO& PageSettings() { return m_pageInfo; } 160 161 /** 162 * Set the line width for the next drawing. 163 * 164 * @param width is specified in IUs. 165 * @param aData is an auxiliary parameter, mainly used in gerber plotter. 166 */ 167 virtual void SetCurrentLineWidth( int width, void* aData = nullptr ) = 0; GetCurrentLineWidth()168 virtual int GetCurrentLineWidth() const { return m_currentPenWidth; } 169 170 virtual void SetColor( const COLOR4D& color ) = 0; 171 172 virtual void SetDash( PLOT_DASH_TYPE dashed ) = 0; 173 SetCreator(const wxString & aCreator)174 virtual void SetCreator( const wxString& aCreator ) { m_creator = aCreator; } 175 SetTitle(const wxString & aTitle)176 virtual void SetTitle( const wxString& aTitle ) { m_title = aTitle; } 177 178 /** 179 * Add a line to the list of free lines to print at the beginning of the file. 180 * 181 * @param aExtraString is the string to print 182 */ AddLineToHeader(const wxString & aExtraString)183 void AddLineToHeader( const wxString& aExtraString ) 184 { 185 m_headerExtraLines.Add( aExtraString ); 186 } 187 188 /** 189 * Remove all lines from the list of free lines to print at the beginning of the file 190 */ ClearHeaderLinesList()191 void ClearHeaderLinesList() 192 { 193 m_headerExtraLines.Clear(); 194 } 195 196 /** 197 * Set the plot offset and scaling for the current plot 198 * 199 * @param aOffset is the plot offset. 200 * @param aIusPerDecimil gives the scaling factor from IUs to device units 201 * @param aScale is the user set plot scaling factor (either explicitly 202 * or using 'fit to A4'). 203 * @param aMirror flips the plot in the Y direction (useful for toner 204 * transfers or some kind of film). 205 */ 206 virtual void SetViewport( const wxPoint& aOffset, double aIusPerDecimil, 207 double aScale, bool aMirror ) = 0; 208 209 /** 210 * Open or create the plot file \a aFullFilename. 211 * 212 * @param aFullFilename is the full file name of the file to create. 213 * @return true if success, false if the file cannot be created/opened. 214 * 215 * Virtual because some plotters use ascii files, some others binary files (PDF) 216 * The base class open the file in text mode 217 */ 218 virtual bool OpenFile( const wxString& aFullFilename ); 219 220 /** 221 * The IUs per decimil are an essential scaling factor when 222 * plotting; they are set and saved when establishing the viewport. 223 * Here they can be get back again 224 */ GetIUsPerDecimil()225 double GetIUsPerDecimil() const { return m_IUsPerDecimil; } 226 GetPlotterArcLowDef()227 int GetPlotterArcLowDef() const { return m_IUsPerDecimil * 8; } GetPlotterArcHighDef()228 int GetPlotterArcHighDef() const { return m_IUsPerDecimil * 2; } 229 230 // Low level primitives 231 virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, 232 int width = USE_DEFAULT_LINE_WIDTH ) = 0; 233 virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill, 234 int width = USE_DEFAULT_LINE_WIDTH ) = 0; 235 236 /** 237 * Generic fallback: arc rendered as a polyline. 238 */ 239 virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle, int rayon, 240 FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH ); 241 virtual void Arc( const SHAPE_ARC& aArc ); 242 243 /** 244 * Generic fallback: Cubic Bezier curve rendered as a polyline 245 * In KiCad the bezier curves have 4 control points: 246 * start ctrl1 ctrl2 end 247 */ 248 virtual void BezierCurve( const wxPoint& aStart, const wxPoint& aControl1, 249 const wxPoint& aControl2, const wxPoint& aEnd, 250 int aTolerance, int aLineThickness = USE_DEFAULT_LINE_WIDTH ); 251 252 /** 253 * Moveto/lineto primitive, moves the 'pen' to the specified direction. 254 * 255 * @param pos is the target position. 256 * @param plume specifies the kind of motion: 'U' only moves the pen, 257 * 'D' draw a line from the current position and 'Z' finish 258 * the drawing and returns the 'pen' to rest (flushes the trace). 259 */ 260 virtual void PenTo( const wxPoint& pos, char plume ) = 0; 261 262 // Convenience functions for PenTo MoveTo(const wxPoint & pos)263 void MoveTo( const wxPoint& pos ) 264 { 265 PenTo( pos, 'U' ); 266 } 267 LineTo(const wxPoint & pos)268 void LineTo( const wxPoint& pos ) 269 { 270 PenTo( pos, 'D' ); 271 } 272 FinishTo(const wxPoint & pos)273 void FinishTo( const wxPoint& pos ) 274 { 275 PenTo( pos, 'D' ); 276 PenTo( pos, 'Z' ); 277 } 278 PenFinish()279 void PenFinish() 280 { 281 // The point is not important with Z motion 282 PenTo( wxPoint( 0, 0 ), 'Z' ); 283 } 284 285 /** 286 * Draw a polygon ( filled or not ). 287 * 288 * @param aCornerList is the corners list (a std::vector< wxPoint >). 289 * @param aFill is the type of fill. 290 * @param aWidth is the line width. 291 * @param aData is an auxiliary info (mainly for gerber format). 292 */ 293 virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill, 294 int aWidth = USE_DEFAULT_LINE_WIDTH, void* aData = nullptr ) = 0; 295 296 /** 297 * Draw a polygon ( filled or not ). 298 * @param aCornerList is the corners list (a SHAPE_LINE_CHAIN). 299 * must be closed (IsClosed() == true) for a polygon. Otherwise this is a polyline. 300 * @param aFill is the type of fill. 301 * @param aWidth is the line width. 302 * @param aData is an auxiliary info (mainly for gerber format). 303 */ 304 virtual void PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_T aFill, 305 int aWidth = USE_DEFAULT_LINE_WIDTH, void* aData = nullptr ); 306 307 /** 308 * Only PostScript plotters can plot bitmaps. 309 * 310 * A rectangle is plotted for plotters that cannot plot a bitmap. 311 * 312 * @param aImage is the bitmap. 313 * @param aPos is position of the center of the bitmap. 314 * @param aScaleFactor is the scale factor to apply to the bitmap size 315 * (this is not the plot scale factor). 316 */ 317 virtual void PlotImage( const wxImage& aImage, const wxPoint& aPos, double aScaleFactor ); 318 319 // Higher level primitives -- can be drawn as line, sketch or 'filled' 320 virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width, 321 OUTLINE_MODE tracemode, void* aData ); 322 virtual void ThickArc( const wxPoint& centre, double StAngle, double EndAngle, 323 int rayon, int width, OUTLINE_MODE tracemode, void* aData ); 324 virtual void ThickRect( const wxPoint& p1, const wxPoint& p2, int width, 325 OUTLINE_MODE tracemode, void* aData ); 326 virtual void ThickCircle( const wxPoint& pos, int diametre, int width, 327 OUTLINE_MODE tracemode, void* aData ); 328 virtual void FilledCircle( const wxPoint& pos, int diametre, 329 OUTLINE_MODE tracemode, void* aData ); 330 331 332 // Flash primitives 333 334 /** 335 * @param aPadPos Position of the shape (center of the rectangle. 336 * @param aDiameter is the diameter of round pad. 337 * @param aTraceMode is the drawing mode, FILLED or SKETCH. 338 * @param aData is an auxiliary info (mainly for gerber format attributes). 339 */ 340 virtual void FlashPadCircle( const wxPoint& aPadPos, int aDiameter, 341 OUTLINE_MODE aTraceMode, void* aData ) = 0; 342 343 /** 344 * @param aPadPos Position of the shape (center of the rectangle. 345 * @param aSize is the size of oblong shape. 346 * @param aPadOrient The rotation of the shape. 347 * @param aTraceMode is the drawing mode, FILLED or SKETCH. 348 * @param aData an auxiliary info (mainly for gerber format attributes). 349 */ 350 virtual void FlashPadOval( const wxPoint& aPadPos, const wxSize& aSize, double aPadOrient, 351 OUTLINE_MODE aTraceMode, void* aData ) = 0; 352 353 /** 354 * @param aPadPos Position of the shape (center of the rectangle). 355 * @param aSize is the size of rounded rect. 356 * @param aPadOrient The rotation of the shape. 357 * @param aTraceMode is the drawing mode, FILLED or SKETCH. 358 * @param aData an auxiliary info (mainly for gerber format attributes). 359 */ 360 virtual void FlashPadRect( const wxPoint& aPadPos, const wxSize& aSize, 361 double aPadOrient, OUTLINE_MODE aTraceMode, void* aData ) = 0; 362 363 /** 364 * @param aPadPos Position of the shape (center of the rectangle. 365 * @param aSize is the size of rounded rect. 366 * @param aCornerRadius Radius of the rounded corners. 367 * @param aOrient The rotation of the shape. 368 * @param aTraceMode is the drawing mode, FILLED or SKETCH. 369 * @param aData an auxiliary info (mainly for gerber format attributes). 370 */ 371 virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize, 372 int aCornerRadius, double aOrient, 373 OUTLINE_MODE aTraceMode, void* aData ) = 0; 374 375 /** 376 * @param aPadPos Position of the shape. 377 * @param aSize is the size of round reference pad. 378 * @param aPadOrient is the pad rotation, used only with aperture macros (Gerber plotter). 379 * @param aPolygons the shape as polygon set. 380 * @param aTraceMode is the drawing mode, FILLED or SKETCH. 381 * @param aData an auxiliary info (mainly for gerber format attributes). 382 */ 383 virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, 384 double aPadOrient, SHAPE_POLY_SET* aPolygons, 385 OUTLINE_MODE aTraceMode, void* aData ) = 0; 386 387 /** 388 * Flash a trapezoidal pad. 389 * 390 * @param aPadPos is the the position of the shape. 391 * @param aCorners is the list of 4 corners positions, relative to the shape position, 392 * pad orientation 0. 393 * @param aPadOrient is the rotation of the shape. 394 * @param aTraceMode is the drawing mode, FILLED or SKETCH. 395 * @param aData an auxiliary info (mainly for gerber format attributes). 396 */ 397 virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners, 398 double aPadOrient, OUTLINE_MODE aTraceMode, 399 void* aData ) = 0; 400 401 /** 402 * Flash a regular polygon. Useful only in Gerber files to flash a regular polygon. 403 * 404 * @param aShapePos is the center of the circle containing the polygon. 405 * @param aRadius is the radius of the circle containing the polygon. 406 * @param aCornerCount is the number of vertices. 407 * @param aOrient is the polygon rotation in degrees. 408 * @param aData is a auxiliary parameter used (if needed) to handle extra info 409 * specific to the plotter. 410 */ 411 virtual void FlashRegularPolygon( const wxPoint& aShapePos, int aDiameter, int aCornerCount, 412 double aOrient, OUTLINE_MODE aTraceMode, void* aData ) = 0 ; 413 414 /** 415 * Draw text with the plotter. 416 * 417 * For convenience it accept the color to use for specific plotters (GERBER) aData is used 418 * to pass extra parameters. 419 */ 420 virtual void Text( const wxPoint& aPos, 421 const COLOR4D& aColor, 422 const wxString& aText, 423 double aOrient, 424 const wxSize& aSize, 425 enum EDA_TEXT_HJUSTIFY_T aH_justify, 426 enum EDA_TEXT_VJUSTIFY_T aV_justify, 427 int aWidth, 428 bool aItalic, 429 bool aBold, 430 bool aMultilineAllowed = false, 431 void* aData = nullptr ); 432 433 /** 434 * Draw a marker (used for the drill map). 435 */ 436 static const unsigned MARKER_COUNT = 58; 437 438 /** 439 * Draw a pattern shape number aShapeId, to coord position. 440 * 441 * @param aPosition is the position of the marker. 442 * @param aDiameter is the diameter of the marker. 443 * @param aShapeId is the index (used to generate forms characters). 444 */ 445 void Marker( const wxPoint& position, int diametre, unsigned aShapeId ); 446 447 /** 448 * Set the current Gerber layer polarity to positive or negative 449 * by writing \%LPD*\% or \%LPC*\% to the Gerber file, respectively. 450 * (obviously starts a new Gerber layer, too) 451 * 452 * @param aPositive is the layer polarity and true for positive. 453 * It's not useful with most other plotter since they can't 'scratch' 454 * the film like photoplotter imagers do 455 */ SetLayerPolarity(bool aPositive)456 virtual void SetLayerPolarity( bool aPositive ) 457 { 458 // NOP for most plotters 459 } 460 461 /** 462 * Change the current text mode. See the PlotTextMode 463 * explanation at the beginning of the file. 464 */ SetTextMode(PLOT_TEXT_MODE mode)465 virtual void SetTextMode( PLOT_TEXT_MODE mode ) 466 { 467 // NOP for most plotters. 468 } 469 470 virtual void SetGerberCoordinatesFormat( int aResolution, bool aUseInches = false ) 471 { 472 // NOP for most plotters. Only for Gerber plotter 473 } 474 475 virtual void SetSvgCoordinatesFormat( unsigned aResolution, bool aUseInches = false ) 476 { 477 // NOP for most plotters. Only for SVG plotter 478 } 479 480 /** 481 * calling this function allows one to define the beginning of a group 482 * of drawing items, for instance in SVG or Gerber format. 483 * (example: group all segments of a letter or a text) 484 * @param aData can define any parameter 485 * for most of plotters: do nothing 486 */ StartBlock(void * aData)487 virtual void StartBlock( void* aData ) {} 488 489 /** 490 * calling this function allows one to define the end of a group of drawing 491 * items for instance in SVG or Gerber format. 492 * the group is started by StartBlock() 493 * @param aData can define any parameter 494 * for most of plotters: do nothing 495 */ EndBlock(void * aData)496 virtual void EndBlock( void* aData ) {} 497 498 499 protected: 500 // These are marker subcomponents 501 /** 502 * Plot a circle centered on the position. Building block for markers 503 */ 504 void markerCircle( const wxPoint& pos, int radius ); 505 506 /** 507 * Plot a - bar centered on the position. Building block for markers 508 */ 509 void markerHBar( const wxPoint& pos, int radius ); 510 511 /** 512 * Plot a / bar centered on the position. Building block for markers 513 */ 514 void markerSlash( const wxPoint& pos, int radius ); 515 516 /** 517 * Plot a \ bar centered on the position. Building block for markers 518 */ 519 void markerBackSlash( const wxPoint& pos, int radius ); 520 521 /** 522 * Plot a | bar centered on the position. Building block for markers 523 */ 524 void markerVBar( const wxPoint& pos, int radius ); 525 526 /** 527 * Plot a square centered on the position. Building block for markers 528 */ 529 void markerSquare( const wxPoint& position, int radius ); 530 531 /** 532 * Plot a lozenge centered on the position. Building block for markers 533 */ 534 void markerLozenge( const wxPoint& position, int radius ); 535 536 // Helper function for sketched filler segment 537 538 /** 539 * Convert a thick segment and plot it as an oval 540 */ 541 void segmentAsOval( const wxPoint& start, const wxPoint& end, int width, 542 OUTLINE_MODE tracemode ); 543 544 void sketchOval( const wxPoint& pos, const wxSize& size, double orient, int width ); 545 546 // Coordinate and scaling conversion functions 547 548 /** 549 * Modify coordinates according to the orientation, scale factor, and offsets trace. Also 550 * convert from a wxPoint to DPOINT, since some output engines needs floating point 551 * coordinates. 552 */ 553 virtual DPOINT userToDeviceCoordinates( const wxPoint& aCoordinate ); 554 555 /** 556 * Modify size according to the plotter scale factors (wxSize version, returns a DPOINT). 557 */ 558 virtual DPOINT userToDeviceSize( const wxSize& size ); 559 560 /** 561 * Modify size according to the plotter scale factors (simple double version). 562 */ 563 virtual double userToDeviceSize( double size ) const; 564 565 double GetDotMarkLenIU() const; 566 567 double GetDashMarkLenIU() const; 568 569 double GetDashGapLenIU() const; 570 571 protected: // variables used in most of plotters: 572 /// Plot scale - chosen by the user (even implicitly with 'fit in a4') 573 double m_plotScale; 574 575 /* Caller scale (how many IUs in a decimil - always); it's a double 576 * because in Eeschema there are 0.1 IUs in a decimil (Eeschema 577 * always works in mils internally) while PcbNew can work in decimil 578 * or nanometers, so this value would be >= 1 */ 579 double m_IUsPerDecimil; 580 581 double m_iuPerDeviceUnit; // Device scale (from IUs to plotter device units; 582 // usually decimils) 583 wxPoint m_plotOffset; // Plot offset (in IUs) 584 bool m_plotMirror; // X axis orientation (SVG) 585 // and plot mirrored (only for PS, PDF HPGL and SVG) 586 bool m_mirrorIsHorizontal; // true to mirror horizontally (else vertically) 587 bool m_yaxisReversed; // true if the Y axis is top to bottom (SVG) 588 589 /// Output file 590 FILE* m_outputFile; 591 592 // Pen handling 593 bool m_colorMode; // true to plot in color, otherwise black & white 594 bool m_negativeMode; // true to generate a negative image (PS mode mainly) 595 int m_currentPenWidth; 596 char m_penState; // current pen state: 'U', 'D' or 'Z' (see PenTo) 597 wxPoint m_penLastpos; // last pen position; -1,-1 when pen is at rest 598 599 wxString m_creator; 600 wxString m_filename; 601 wxString m_title; 602 PAGE_INFO m_pageInfo; 603 wxSize m_paperSize; // Paper size in IU - not in mils 604 605 wxArrayString m_headerExtraLines; // a set of string to print in header file 606 607 RENDER_SETTINGS* m_renderSettings; 608 }; 609 610 611 class TITLE_BLOCK; 612 613 void PlotDrawingSheet( PLOTTER* plotter, const PROJECT* aProject, const TITLE_BLOCK& aTitleBlock, 614 const PAGE_INFO& aPageInfo, const wxString& aSheetNumber, int aSheetCount, 615 const wxString& aSheetDesc, const wxString& aFilename, 616 COLOR4D aColor = COLOR4D::UNSPECIFIED, bool aIsFirstPage = true ); 617 618 /** Returns the default plot extension for a format 619 */ 620 wxString GetDefaultPlotExtension( PLOT_FORMAT aFormat ); 621 622 623 #endif // PLOT_COMMON_H_ 624