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.

548 lines
18 KiB

13 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2013-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
  5. * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * as published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, you may find one here:
  19. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  20. * or you may search the http://www.gnu.org website for the version 2 license,
  21. * or you may write to the Free Software Foundation, Inc.,
  22. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  23. */
  24. #ifndef WS_DRAW_ITEM_H
  25. #define WS_DRAW_ITEM_H
  26. #include <math/vector2d.h>
  27. #include <eda_text.h>
  28. #include <eda_text.h>
  29. #include <bitmap_base.h>
  30. #include "msgpanel.h"
  31. #include <geometry/shape_poly_set.h>
  32. class WS_DATA_ITEM;
  33. class TITLE_BLOCK;
  34. class PAGE_INFO;
  35. /*
  36. * Helper classes to handle basic graphic items used to draw/plot
  37. * title blocks and frame references
  38. * segments
  39. * rect
  40. * polygons (for logos)
  41. * graphic texts
  42. * bitmaps (also for logos, but they cannot be plot by SVG, GERBER or HPGL plotters
  43. * where we just plot the bounding box)
  44. */
  45. class WS_DRAW_ITEM_BASE : public EDA_ITEM // This basic class, not directly usable.
  46. {
  47. protected:
  48. WS_DATA_ITEM* m_peer; // the parent WS_DATA_ITEM item in the WS_DATA_MODEL
  49. int m_index; // the index in the parent's repeat count
  50. WS_DRAW_ITEM_BASE( WS_DATA_ITEM* aPeer, int aIndex, KICAD_T aType ) :
  51. EDA_ITEM( aType )
  52. {
  53. m_peer = aPeer;
  54. m_index = aIndex;
  55. m_Flags = 0;
  56. }
  57. public:
  58. virtual ~WS_DRAW_ITEM_BASE() {}
  59. WS_DATA_ITEM* GetPeer() const { return m_peer; }
  60. int GetIndexInPeer() const { return m_index; }
  61. void ViewGetLayers( int aLayers[], int& aCount ) const override;
  62. virtual const wxPoint GetPosition() const = 0;
  63. virtual void SetPosition( wxPoint aPos ) = 0;
  64. virtual void SetEnd( wxPoint aPos ) { /* not all types will need this */ }
  65. // The function to print a WS_DRAW_ITEM
  66. virtual void PrintWsItem( wxDC* aDC, COLOR4D aColor )
  67. {
  68. PrintWsItem( aDC, wxPoint( 0, 0 ), aColor );
  69. }
  70. // More advanced version of DrawWsItem. This is what must be defined in the derived type.
  71. virtual void PrintWsItem( wxDC* aDC, const wxPoint& aOffset, COLOR4D aColor ) = 0;
  72. // Derived types must define GetBoundingBox() as a minimum, and can then override the
  73. // two HitTest() functions if they need something more specific.
  74. const EDA_RECT GetBoundingBox() const override = 0;
  75. bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override
  76. {
  77. // This is just here to prevent annoying compiler warnings about hidden overloaded
  78. // virtual functions
  79. return EDA_ITEM::HitTest( aPosition, aAccuracy );
  80. }
  81. bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
  82. void GetMsgPanelInfo( EDA_UNITS aUnits, MSG_PANEL_ITEMS& aList ) override;
  83. };
  84. // This class draws a thick segment
  85. class WS_DRAW_ITEM_LINE : public WS_DRAW_ITEM_BASE
  86. {
  87. wxPoint m_start; // start point of line/rect
  88. wxPoint m_end; // end point
  89. int m_penWidth;
  90. public:
  91. WS_DRAW_ITEM_LINE( WS_DATA_ITEM* aPeer, int aIndex, wxPoint aStart, wxPoint aEnd,
  92. int aPenWidth ) :
  93. WS_DRAW_ITEM_BASE( aPeer, aIndex, WSG_LINE_T )
  94. {
  95. m_start = aStart;
  96. m_end = aEnd;
  97. m_penWidth = aPenWidth;
  98. }
  99. virtual wxString GetClass() const override { return wxT( "WS_DRAW_ITEM_LINE" ); }
  100. // Accessors:
  101. int GetPenWidth() const { return m_penWidth; }
  102. const wxPoint& GetStart() const { return m_start; }
  103. void SetStart( wxPoint aPos ) { m_start = aPos; }
  104. const wxPoint& GetEnd() const { return m_end; }
  105. void SetEnd( wxPoint aPos ) override { m_end = aPos; }
  106. const wxPoint GetPosition() const override { return GetStart(); }
  107. void SetPosition( wxPoint aPos ) override { SetStart( aPos ); }
  108. const EDA_RECT GetBoundingBox() const override;
  109. bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
  110. void PrintWsItem( wxDC* aDC, const wxPoint& aOffset, COLOR4D aColor ) override;
  111. wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
  112. #if defined(DEBUG)
  113. void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
  114. #endif
  115. };
  116. // This class draws a polygon
  117. class WS_DRAW_ITEM_POLYPOLYGONS : public WS_DRAW_ITEM_BASE
  118. {
  119. wxPoint m_pos; // position of reference point, from the
  120. // WS_DATA_ITEM_POLYGONS parent
  121. // (used only in page layout editor to draw anchors)
  122. int m_penWidth;
  123. public:
  124. /** The list of polygons. Because these polygons are only for drawing purposes,
  125. * each polygon is expected having no holes, jusst a main outline
  126. */
  127. SHAPE_POLY_SET m_Polygons;
  128. public:
  129. WS_DRAW_ITEM_POLYPOLYGONS( WS_DATA_ITEM* aPeer, int aIndex, wxPoint aPos, int aPenWidth ) :
  130. WS_DRAW_ITEM_BASE( aPeer, aIndex, WSG_POLY_T )
  131. {
  132. m_penWidth = aPenWidth;
  133. m_pos = aPos;
  134. }
  135. virtual wxString GetClass() const override { return wxT( "WS_DRAW_ITEM_POLYPOLYGONS" ); }
  136. // Accessors:
  137. SHAPE_POLY_SET& GetPolygons() { return m_Polygons; }
  138. int GetPenWidth() const { return m_penWidth; }
  139. const wxPoint GetPosition() const override { return m_pos; }
  140. void SetPosition( wxPoint aPos ) override;
  141. const EDA_RECT GetBoundingBox() const override;
  142. bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
  143. bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
  144. void PrintWsItem( wxDC* aDC, const wxPoint& aOffset, COLOR4D aColor ) override;
  145. wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
  146. #if defined(DEBUG)
  147. void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
  148. #endif
  149. };
  150. // This class draws a not filled rectangle with thick segment
  151. class WS_DRAW_ITEM_RECT : public WS_DRAW_ITEM_BASE
  152. {
  153. wxPoint m_start; // start point of line/rect
  154. wxPoint m_end; // end point
  155. int m_penWidth;
  156. public:
  157. WS_DRAW_ITEM_RECT( WS_DATA_ITEM* aPeer, int aIndex, wxPoint aStart, wxPoint aEnd,
  158. int aPenWidth ) :
  159. WS_DRAW_ITEM_BASE( aPeer, aIndex, WSG_RECT_T )
  160. {
  161. m_start = aStart;
  162. m_end = aEnd;
  163. m_penWidth = aPenWidth;
  164. }
  165. virtual wxString GetClass() const override { return wxT( "WS_DRAW_ITEM_RECT" ); }
  166. // Accessors:
  167. int GetPenWidth() const { return m_penWidth; }
  168. const wxPoint& GetStart() const { return m_start; }
  169. void SetStart( wxPoint aPos ) { m_start = aPos; }
  170. const wxPoint& GetEnd() const { return m_end; }
  171. void SetEnd( wxPoint aPos ) override { m_end = aPos; }
  172. const wxPoint GetPosition() const override { return GetStart(); }
  173. void SetPosition( wxPoint aPos ) override { SetStart( aPos ); }
  174. void PrintWsItem( wxDC* aDC, const wxPoint& aOffset, COLOR4D aColor ) override;
  175. const EDA_RECT GetBoundingBox() const override;
  176. bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
  177. wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
  178. #if defined(DEBUG)
  179. void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
  180. #endif
  181. };
  182. // This class draws a rectangle with thick segment showing the page limits
  183. // and a marker showing the coord origin. This only a draw item only.
  184. // Therefore m_peer ( the parent WS_DATA_ITEM item in the WS_DATA_MODEL) is always a nullptr.
  185. class WS_DRAW_ITEM_PAGE : public WS_DRAW_ITEM_BASE
  186. {
  187. wxPoint m_markerPos; // position of the marker
  188. wxSize m_pageSize; // full size of the page
  189. int m_penWidth;
  190. double m_markerSize;
  191. public:
  192. WS_DRAW_ITEM_PAGE( int aPenWidth, double aMarkerSize ) :
  193. WS_DRAW_ITEM_BASE( nullptr, 0, WSG_PAGE_T )
  194. {
  195. m_penWidth = aPenWidth;
  196. m_markerSize = aMarkerSize;
  197. }
  198. virtual wxString GetClass() const override { return wxT( "WS_DRAW_ITEM_PAGE" ); }
  199. // Accessors:
  200. int GetPenWidth() const { return m_penWidth; }
  201. void SetPageSize( wxSize aSize ) { m_pageSize = aSize; }
  202. wxSize GetPageSize() const { return m_pageSize; }
  203. const wxPoint& GetMarkerPos() const { return m_markerPos; }
  204. void SetMarkerPos( wxPoint aPos ) { m_markerPos = aPos; }
  205. double GetMarkerSize() const { return m_markerSize; }
  206. const wxPoint GetPosition() const override { return wxPoint( 0, 0 ); }
  207. void SetPosition( wxPoint aPos ) override { /* do nothing */ }
  208. void PrintWsItem( wxDC* aDC, const wxPoint& aOffset, COLOR4D aColor ) override { /* do nothing */ }
  209. const EDA_RECT GetBoundingBox() const override;
  210. bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override { return false; }
  211. wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
  212. #if defined(DEBUG)
  213. void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
  214. #endif
  215. };
  216. // This class draws a graphic text.
  217. // it is derived from an EDA_TEXT, so it handle all caracteristics
  218. // of this graphic text (justification, rotation ... )
  219. class WS_DRAW_ITEM_TEXT : public WS_DRAW_ITEM_BASE, public EDA_TEXT
  220. {
  221. public:
  222. WS_DRAW_ITEM_TEXT( WS_DATA_ITEM* aPeer, int aIndex, wxString& aText, wxPoint aPos,
  223. wxSize aSize, int aPenWidth, bool aItalic = false, bool aBold = false ) :
  224. WS_DRAW_ITEM_BASE( aPeer, aIndex, WSG_TEXT_T),
  225. EDA_TEXT( aText )
  226. {
  227. SetTextPos( aPos );
  228. SetTextSize( aSize );
  229. SetThickness( aPenWidth );
  230. SetItalic( aItalic );
  231. SetBold( aBold );
  232. }
  233. virtual wxString GetClass() const override { return wxT( "WS_DRAW_ITEM_TEXT" ); }
  234. void PrintWsItem( wxDC* aDC, const wxPoint& aOffset, COLOR4D aColor ) override;
  235. // Accessors:
  236. int GetPenWidth() { return GetThickness(); }
  237. void SetTextAngle( double aAngle )
  238. {
  239. EDA_TEXT::SetTextAngle( NormalizeAngle360Min( aAngle ) );
  240. }
  241. const wxPoint GetPosition() const override { return GetTextPos(); }
  242. void SetPosition( wxPoint aPos ) override { SetTextPos( aPos ); }
  243. const EDA_RECT GetBoundingBox() const override;
  244. bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
  245. bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
  246. wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
  247. #if defined(DEBUG)
  248. void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
  249. #endif
  250. };
  251. // This class draws a bitmap.
  252. class WS_DRAW_ITEM_BITMAP : public WS_DRAW_ITEM_BASE
  253. {
  254. wxPoint m_pos; // position of reference point
  255. public:
  256. WS_DRAW_ITEM_BITMAP( WS_DATA_ITEM* aPeer, int aIndex, wxPoint aPos ) :
  257. WS_DRAW_ITEM_BASE( aPeer, aIndex, WSG_BITMAP_T )
  258. {
  259. m_pos = aPos;
  260. }
  261. ~WS_DRAW_ITEM_BITMAP() {}
  262. virtual wxString GetClass() const override { return wxT( "WS_DRAW_ITEM_BITMAP" ); }
  263. const wxPoint GetPosition() const override { return m_pos; }
  264. void SetPosition( wxPoint aPos ) override { m_pos = aPos; }
  265. void PrintWsItem( wxDC* aDC, const wxPoint& aOffset, COLOR4D aColor ) override;
  266. bool HitTest( const wxPoint& aPosition, int aAccuracy = 0 ) const override;
  267. bool HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy = 0 ) const override;
  268. const EDA_RECT GetBoundingBox() const override;
  269. wxString GetSelectMenuText( EDA_UNITS aUnits ) const override;
  270. #if defined(DEBUG)
  271. void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
  272. #endif
  273. };
  274. /*
  275. * this class stores the list of graphic items:
  276. * rect, lines, polygons and texts to draw/plot
  277. * the title block and frame references, and parameters to
  278. * draw/plot them
  279. */
  280. class WS_DRAW_ITEM_LIST
  281. {
  282. protected:
  283. std::vector <WS_DRAW_ITEM_BASE*> m_graphicList; // Items to draw/plot
  284. unsigned m_idx; // for GetFirst, GetNext functions
  285. double m_milsToIu; // the scalar to convert pages units ( mils)
  286. // to draw/plot units.
  287. int m_penSize; // The default line width for drawings.
  288. // used when an item has a pen size = 0
  289. int m_sheetNumber; // the value of the sheet number, for basic inscriptions
  290. int m_sheetCount; // the value of the number of sheets, in schematic
  291. // for basic inscriptions, in schematic
  292. const TITLE_BLOCK* m_titleBlock; // for basic inscriptions
  293. const wxString* m_paperFormat; // for basic inscriptions
  294. wxString m_fileName; // for basic inscriptions
  295. wxString m_sheetFullName; // for basic inscriptions
  296. const wxString* m_sheetLayer; // for basic inscriptions
  297. public:
  298. WS_DRAW_ITEM_LIST()
  299. {
  300. m_idx = 0;
  301. m_milsToIu = 1.0;
  302. m_penSize = 1;
  303. m_sheetNumber = 1;
  304. m_sheetCount = 1;
  305. m_sheetLayer = nullptr;
  306. m_titleBlock = nullptr;
  307. m_paperFormat = nullptr;
  308. }
  309. ~WS_DRAW_ITEM_LIST()
  310. {
  311. // Items in the m_graphicList are owned by their respective WORKSHEET_DATAITEMs.
  312. // for( WS_DRAW_ITEM_BASE* item : m_graphicList )
  313. // delete item;
  314. }
  315. /**
  316. * Set the title block (mainly for page layout editor)
  317. */
  318. void SetTitleBlock( const TITLE_BLOCK* aTblock ) { m_titleBlock = aTblock; }
  319. /**
  320. * Set the paper format name (mainly for page layout editor)
  321. */
  322. void SetPaperFormat( const wxString* aFormatName ) { m_paperFormat = aFormatName; }
  323. /**
  324. * Set the filename to draw/plot
  325. */
  326. void SetFileName( const wxString& aFileName )
  327. {
  328. m_fileName = aFileName;
  329. }
  330. /**
  331. * Set the sheet name to draw/plot
  332. */
  333. void SetSheetName( const wxString& aSheetName )
  334. {
  335. m_sheetFullName = aSheetName;
  336. }
  337. /**
  338. * Set the sheet layer to draw/plot
  339. */
  340. void SetSheetLayer( const wxString& aSheetLayer )
  341. {
  342. m_sheetLayer = &aSheetLayer;
  343. }
  344. void SetDefaultPenSize( int aPenSize ) { m_penSize = aPenSize; }
  345. int GetDefaultPenSize() const { return m_penSize; }
  346. /**
  347. * Function SetMilsToIUfactor
  348. * Set the scalar to convert pages units (mils) to draw/plot units
  349. */
  350. void SetMilsToIUfactor( double aScale )
  351. {
  352. m_milsToIu = aScale;
  353. }
  354. /**
  355. * Function SetSheetNumber
  356. * Set the value of the sheet number, for basic inscriptions
  357. */
  358. void SetSheetNumber( int aSheetNumber )
  359. {
  360. m_sheetNumber = aSheetNumber;
  361. }
  362. /**
  363. * Function SetSheetCount
  364. * Set the value of the count of sheets, for basic inscriptions
  365. */
  366. void SetSheetCount( int aSheetCount )
  367. {
  368. m_sheetCount = aSheetCount;
  369. }
  370. void Append( WS_DRAW_ITEM_BASE* aItem )
  371. {
  372. m_graphicList.push_back( aItem );
  373. }
  374. void Remove( WS_DRAW_ITEM_BASE* aItem )
  375. {
  376. auto newEnd = std::remove( m_graphicList.begin(), m_graphicList.end(), aItem );
  377. m_graphicList.erase( newEnd, m_graphicList.end() );
  378. }
  379. WS_DRAW_ITEM_BASE* GetFirst()
  380. {
  381. m_idx = 0;
  382. if( m_graphicList.size() )
  383. return m_graphicList[0];
  384. else
  385. return NULL;
  386. }
  387. WS_DRAW_ITEM_BASE* GetNext()
  388. {
  389. m_idx++;
  390. if( m_graphicList.size() > m_idx )
  391. return m_graphicList[m_idx];
  392. else
  393. return NULL;
  394. }
  395. void GetAllItems( std::vector<WS_DRAW_ITEM_BASE*>* aList )
  396. {
  397. *aList = m_graphicList;
  398. }
  399. /**
  400. * Draws the item list created by BuildWorkSheetGraphicList
  401. * @param aDC = the current Device Context
  402. */
  403. void Print( wxDC* aDC, COLOR4D aColor );
  404. /**
  405. * Function BuildWorkSheetGraphicList is a core function for drawing or plotting the
  406. * page layout with the frame and the basic inscriptions.
  407. *
  408. * Before calling this function, some parameters should be initialized by calling:
  409. * SetPenSize( aPenWidth );
  410. * SetMilsToIUfactor( aScalar );
  411. * SetSheetNumber( aSheetNumber );
  412. * SetSheetCount( aSheetCount );
  413. * SetFileName( aFileName );
  414. * SetSheetName( aFullSheetName );
  415. *
  416. * @param aPageInfo The PAGE_INFO, for page size, margins...
  417. * @param aTitleBlock The sheet title block, for basic inscriptions.
  418. * @param aColor The color for drawing.
  419. * @param aAltColor The color for items which need to be "highlighted".
  420. */
  421. void BuildWorkSheetGraphicList( const PAGE_INFO& aPageInfo, const TITLE_BLOCK& aTitleBlock );
  422. /**
  423. * Function BuildFullText
  424. * returns the full text corresponding to the aTextbase,
  425. * after replacing format symbols by the corresponding value
  426. *
  427. * Basic texts in Ki_WorkSheetData struct use format notation
  428. * like "Title %T" to identify at run time the full text
  429. * to display.
  430. * Currently format identifier is % followed by a letter or 2 letters
  431. *
  432. * %% = replaced by %
  433. * %K = Kicad version
  434. * %Z = paper format name (A4, USLetter)
  435. * %Y = company name
  436. * %D = date
  437. * %R = revision
  438. * %S = sheet number
  439. * %N = number of sheets
  440. * %Cx = comment (x = 0 to 9 to identify the comment)
  441. * %F = filename
  442. * %P = sheet path or sheet full name
  443. * %T = title
  444. * Other fields like Developer, Verifier, Approver could use %Cx
  445. * and are seen as comments for format
  446. *
  447. * @param aTextbase = the text with format symbols
  448. * @return the text, after replacing the format symbols by the actual value
  449. */
  450. wxString BuildFullText( const wxString& aTextbase );
  451. };
  452. #endif // WS_DRAW_ITEM_H