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.

229 lines
8.4 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2016-2022 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. /**
  20. * Plotting engine (HPGL)
  21. *
  22. * @file plotter_hpgl.h
  23. */
  24. #pragma once
  25. #include <list>
  26. #include "plotter.h"
  27. class HPGL_PLOTTER : public PLOTTER
  28. {
  29. public:
  30. HPGL_PLOTTER();
  31. virtual PLOT_FORMAT GetPlotterType() const override
  32. {
  33. return PLOT_FORMAT::HPGL;
  34. }
  35. static wxString GetDefaultFileExtension()
  36. {
  37. return wxString( wxT( "plt" ) );
  38. }
  39. /**
  40. * Set the target length of chords used to draw approximated circles and arcs.
  41. *
  42. * @param chord_len the chord length in IUs.
  43. */
  44. void SetTargetChordLength( double chord_len );
  45. /// Switch to the user coordinate system
  46. void SetUserCoords( bool user_coords ) { m_useUserCoords = user_coords; }
  47. /// Set whether the user coordinate system is fit to content
  48. void SetUserCoordsFit( bool user_coords_fit ) { m_fitUserCoords = user_coords_fit; }
  49. /**
  50. * At the start of the HPGL plot pen speed and number are requested.
  51. */
  52. virtual bool StartPlot( const wxString& aPageNumber ) override;
  53. /**
  54. * HPGL end of plot: sort and emit graphics, pen return and release.
  55. */
  56. virtual bool EndPlot() override;
  57. /// HPGL doesn't handle line thickness or color
  58. virtual void SetCurrentLineWidth( int width, void* aData = nullptr ) override
  59. {
  60. // This is the truth
  61. m_currentPenWidth = userToDeviceSize( m_penDiameter );
  62. }
  63. /**
  64. * HPGL supports dashed lines.
  65. */
  66. virtual void SetDash( int aLineWidth, PLOT_DASH_TYPE aLineStyle ) override;
  67. virtual void SetColor( const COLOR4D& color ) override {}
  68. virtual void SetPenSpeed( int speed )
  69. {
  70. m_penSpeed = speed;
  71. }
  72. virtual void SetPenNumber( int number )
  73. {
  74. m_penNumber = number;
  75. }
  76. virtual void SetPenDiameter( double diameter );
  77. virtual void SetViewport( const VECTOR2I& aOffset, double aIusPerDecimil,
  78. double aScale, bool aMirror ) override;
  79. virtual void Rect( const VECTOR2I& p1, const VECTOR2I& p2, FILL_T aFill,
  80. int aWidth = USE_DEFAULT_LINE_WIDTH ) override;
  81. virtual void Circle( const VECTOR2I& aCenter, int aDiameter, FILL_T aFill,
  82. int aWidth = USE_DEFAULT_LINE_WIDTH ) override;
  83. virtual void PlotPoly( const std::vector<VECTOR2I>& aCornerList, FILL_T aFill,
  84. int aWidth = USE_DEFAULT_LINE_WIDTH, void* aData = nullptr ) override;
  85. virtual void ThickSegment( const VECTOR2I& start, const VECTOR2I& end, int width,
  86. OUTLINE_MODE tracemode, void* aData ) override;
  87. virtual void Arc( const VECTOR2I& aCenter, const VECTOR2I& aStart, const VECTOR2I& aEnd,
  88. FILL_T aFill, int aWidth, int aMaxError ) override;
  89. virtual void PenTo( const VECTOR2I& pos, char plume ) override;
  90. virtual void FlashPadCircle( const VECTOR2I& aPadPos, int aDiameter,
  91. OUTLINE_MODE aTraceMode, void* aData ) override;
  92. virtual void FlashPadOval( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
  93. const EDA_ANGLE& aPadOrient, OUTLINE_MODE aTraceMode,
  94. void* aData ) override;
  95. virtual void FlashPadRect( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
  96. const EDA_ANGLE& aOrient, OUTLINE_MODE aTraceMode,
  97. void* aData ) override;
  98. virtual void FlashPadRoundRect( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
  99. int aCornerRadius, const EDA_ANGLE& aOrient,
  100. OUTLINE_MODE aTraceMode, void* aData ) override;
  101. virtual void FlashPadCustom( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
  102. const EDA_ANGLE& aOrient, SHAPE_POLY_SET* aPolygons,
  103. OUTLINE_MODE aTraceMode, void* aData ) override;
  104. virtual void FlashPadTrapez( const VECTOR2I& aPadPos, const VECTOR2I* aCorners,
  105. const EDA_ANGLE& aPadOrient, OUTLINE_MODE aTraceMode,
  106. void* aData ) override;
  107. virtual void FlashRegularPolygon( const VECTOR2I& aShapePos, int aDiameter, int aCornerCount,
  108. const EDA_ANGLE& aOrient, OUTLINE_MODE aTraceMode,
  109. void* aData ) override;
  110. protected:
  111. /**
  112. * Plot an arc.
  113. *
  114. * Command
  115. * PU PY x, y; PD start_arc_X AA, start_arc_Y, angle, NbSegm; PU;
  116. * Or PU PY x, y; PD start_arc_X AA, start_arc_Y, angle, PU;
  117. *
  118. * center is the center of the arc.
  119. * StAngled is the start angle of the arc.
  120. * aEndAngle is end angle the arc.
  121. * Radius is the radius of the arc.
  122. */
  123. virtual void Arc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAngle,
  124. const EDA_ANGLE& aEndAngle, int aRadius, FILL_T aFill,
  125. int aWidth = USE_DEFAULT_LINE_WIDTH ) override;
  126. /**
  127. * Start a new HPGL_ITEM if necessary, keeping the current one if it exists.
  128. *
  129. * @param location is the location of the item.
  130. * @return whether a new item was made.
  131. */
  132. bool startItem( const VECTOR2D& location );
  133. /// Flush the current HPGL_ITEM and clear out the current item pointer.
  134. void flushItem();
  135. /**
  136. * Start a new HPGL_ITEM with the given string if necessary, or append the
  137. * string to the current item.
  138. *
  139. * @param location is the location of the item, if a new one is made.
  140. * @param content is the content substring.
  141. * @return whether a new item was made.
  142. */
  143. bool startOrAppendItem( const VECTOR2D& location, const wxString& content );
  144. struct HPGL_ITEM
  145. {
  146. HPGL_ITEM() :
  147. lift_before( false ),
  148. lift_after( false ),
  149. pen_returns( false ),
  150. pen( 0 ),
  151. dashType( PLOT_DASH_TYPE::SOLID ) {}
  152. /// Location the pen should start at
  153. VECTOR2D loc_start;
  154. /// Location the pen will be at when it finishes. If this is not known,
  155. /// leave it equal to loc_start and set lift_after.
  156. VECTOR2D loc_end;
  157. /// Bounding box of this item
  158. BOX2D bbox;
  159. /// Whether the command should be executed with the pen lifted
  160. bool lift_before;
  161. /// Whether the pen must be lifted after the command. If the location of the pen
  162. /// is not known, this must be set (so that another command starting at loc_end
  163. /// is not immediately executed with no lift).
  164. bool lift_after;
  165. /// Whether the pen returns to its original state after the command. Otherwise,
  166. /// the pen is assumed to be down following the command.
  167. bool pen_returns;
  168. int pen; /// Pen number for this command
  169. PLOT_DASH_TYPE dashType; /// Line style for this command
  170. wxString content; /// Text of the command
  171. };
  172. /// Sort a list of HPGL items to improve plotting speed on mechanical plotters.
  173. ///
  174. /// @param items - items to sort
  175. static void sortItems( std::list<HPGL_ITEM>& items );
  176. /// Return the plot command corresponding to a line type
  177. static const char* lineStyleCommand( PLOT_DASH_TYPE aLineStyle );
  178. protected:
  179. int m_penSpeed;
  180. int m_penNumber;
  181. double m_penDiameter;
  182. double m_arcTargetChordLength;
  183. EDA_ANGLE m_arcMinChordDegrees;
  184. PLOT_DASH_TYPE m_lineStyle;
  185. bool m_useUserCoords;
  186. bool m_fitUserCoords;
  187. std::list<HPGL_ITEM> m_items;
  188. HPGL_ITEM* m_current_item;
  189. };