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.

501 lines
14 KiB

10 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
Introduction of Graphics Abstraction Layer based rendering for pcbnew. New classes: - VIEW - represents view that is seen by user, takes care of layer ordering & visibility and how it is displayed (which location, how much zoomed, etc.) - VIEW_ITEM - Base class for every item that can be displayed on VIEW (the biggest change is that now it may be necessary to override ViewBBox & ViewGetLayers method for derived classes). - EDA_DRAW_PANEL_GAL - Inherits after EDA_DRAW_PANEL, displays VIEW output, right now it is not editable (in opposite to usual EDA_DRAW_PANEL). - GAL/OPENGL_GAL/CAIRO_GAL - Base Graphics Abstraction Layer class + two different flavours (Cairo is not fully supported yet), that offers methods to draw primitives using different libraries. - WX_VIEW_CONTROLS - Controller for VIEW, handles user events, allows zooming, panning, etc. - PAINTER/PCB_PAINTER - Classes that uses GAL interface to draw items (as you may have already guessed - PCB_PAINTER is a class for drawing PCB specific object, PAINTER is an abstract class). Its methods are invoked by VIEW, when an item has to be drawn. To display a new type of item - you need to implement draw(ITEM_TYPE*) method that draws it using GAL methods. - STROKE_FONT - Implements stroke font drawing using GAL methods. Most important changes to Kicad original code: * EDA_ITEM now inherits from VIEW_ITEM, which is a base class for all drawable objects. * EDA_DRAW_FRAME contains both usual EDA_DRAW_PANEL and new EDA_DRAW_PANEL_GAL, that can be switched anytime. * There are some new layers for displaying multilayer pads, vias & pads holes (these are not shown yet on the right sidebar in pcbnew) * Display order of layers is different than in previous versions (if you are curious - you may check m_galLayerOrder@pcbnew/basepcbframe.cpp). Preserving usual order would result in not very natural display, such as showing silkscreen texts on the bottom. * Introduced new hotkey (Alt+F12) and new menu option (View->Switch canvas) for switching canvas during runtime. * Some of classes (mostly derived from BOARD_ITEM) now includes ViewBBox & ViewGetLayers methods. * Removed tools/class_painter.h, as now it is extended and included in source code. Build changes: * GAL-based rendering option is turned on by a new compilation CMake option KICAD_GAL. * When compiling with CMake option KICAD_GAL=ON, GLEW and Cairo libraries are required. * GAL-related code is compiled into a static library (common/libgal). * Build with KICAD_GAL=OFF should not need any new libraries and should come out as a standard version of Kicad Currently most of items in pcbnew can be displayed using OpenGL (to be done are DIMENSIONS and MARKERS). More details about GAL can be found in: http://www.ohwr.org/attachments/1884/view-spec.pdf
13 years ago
5 years ago
5 years ago
5 years ago
  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
  5. * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
  6. * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, you may find one here:
  20. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
  21. * or you may search the http://www.gnu.org website for the version 2 license,
  22. * or you may write to the Free Software Foundation, Inc.,
  23. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
  24. */
  25. #include <pcb_edit_frame.h>
  26. #include <base_units.h>
  27. #include <bitmaps.h>
  28. #include <board.h>
  29. #include <board_design_settings.h>
  30. #include <core/mirror.h>
  31. #include <footprint.h>
  32. #include <settings/settings_manager.h>
  33. #include <trigo.h>
  34. #include <string_utils.h>
  35. #include <painter.h>
  36. #include <geometry/shape_compound.h>
  37. #include <callback_gal.h>
  38. #include <convert_basic_shapes_to_polygon.h>
  39. FP_TEXT::FP_TEXT( FOOTPRINT* aParentFootprint, TEXT_TYPE text_type ) :
  40. BOARD_ITEM( aParentFootprint, PCB_FP_TEXT_T ),
  41. EDA_TEXT()
  42. {
  43. FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( m_parent );
  44. m_Type = text_type;
  45. SetKeepUpright( true );
  46. // Set text thickness to a default value
  47. SetTextThickness( Millimeter2iu( DEFAULT_TEXT_WIDTH ) );
  48. SetLayer( F_SilkS );
  49. // Set position and give a default layer if a valid parent footprint exists
  50. if( parentFootprint && parentFootprint->Type() == PCB_FOOTPRINT_T )
  51. {
  52. SetTextPos( parentFootprint->GetPosition() );
  53. if( IsBackLayer( parentFootprint->GetLayer() ) )
  54. {
  55. SetLayer( B_SilkS );
  56. SetMirrored( true );
  57. }
  58. }
  59. SetDrawCoord();
  60. }
  61. FP_TEXT::~FP_TEXT()
  62. {
  63. }
  64. bool FP_TEXT::TextHitTest( const VECTOR2I& aPoint, int aAccuracy ) const
  65. {
  66. EDA_RECT rect = GetTextBox();
  67. VECTOR2I location = aPoint;
  68. rect.Inflate( aAccuracy );
  69. RotatePoint( location, GetTextPos(), -GetDrawRotation() );
  70. return rect.Contains( location );
  71. }
  72. bool FP_TEXT::TextHitTest( const EDA_RECT& aRect, bool aContains, int aAccuracy ) const
  73. {
  74. EDA_RECT rect = aRect;
  75. rect.Inflate( aAccuracy );
  76. if( aContains )
  77. return rect.Contains( GetBoundingBox() );
  78. else
  79. return rect.Intersects( GetTextBox(), GetDrawRotation() );
  80. }
  81. void FP_TEXT::KeepUpright( const EDA_ANGLE& aOldOrientation, const EDA_ANGLE& aNewOrientation )
  82. {
  83. if( !IsKeepUpright() )
  84. return;
  85. EDA_ANGLE newAngle = GetTextAngle() + aNewOrientation;
  86. newAngle.Normalize();
  87. bool needsFlipped = newAngle >= ANGLE_180;
  88. if( needsFlipped )
  89. {
  90. SetHorizJustify( static_cast<GR_TEXT_H_ALIGN_T>( -GetHorizJustify() ) );
  91. SetTextAngle( GetTextAngle() + ANGLE_180 );
  92. SetDrawCoord();
  93. }
  94. }
  95. void FP_TEXT::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
  96. {
  97. // Used in footprint editing
  98. // Note also in footprint editor, m_Pos0 = m_Pos
  99. VECTOR2I pt = GetTextPos();
  100. RotatePoint( pt, aRotCentre, aAngle );
  101. SetTextPos( pt );
  102. EDA_ANGLE new_angle = GetTextAngle() + aAngle;
  103. new_angle.Normalize180();
  104. SetTextAngle( new_angle );
  105. SetLocalCoord();
  106. }
  107. void FP_TEXT::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
  108. {
  109. // flipping the footprint is relative to the X axis
  110. if( aFlipLeftRight )
  111. {
  112. SetTextX( MIRRORVAL( GetTextPos().x, aCentre.x ) );
  113. SetTextAngle( -GetTextAngle() );
  114. }
  115. else
  116. {
  117. SetTextY( MIRRORVAL( GetTextPos().y, aCentre.y ) );
  118. SetTextAngle( ANGLE_180 - GetTextAngle() );
  119. }
  120. SetLayer( FlipLayer( GetLayer(), GetBoard()->GetCopperLayerCount() ) );
  121. SetMirrored( IsBackLayer( GetLayer() ) );
  122. SetLocalCoord();
  123. }
  124. bool FP_TEXT::IsParentFlipped() const
  125. {
  126. if( GetParent() && GetParent()->GetLayer() == B_Cu )
  127. return true;
  128. return false;
  129. }
  130. void FP_TEXT::Mirror( const VECTOR2I& aCentre, bool aMirrorAroundXAxis )
  131. {
  132. // the position is mirrored, but the text itself is not mirrored
  133. if( aMirrorAroundXAxis )
  134. SetTextY( ::MIRRORVAL( GetTextPos().y, aCentre.y ) );
  135. else
  136. SetTextX( ::MIRRORVAL( GetTextPos().x, aCentre.x ) );
  137. SetLocalCoord();
  138. }
  139. void FP_TEXT::Move( const VECTOR2I& aMoveVector )
  140. {
  141. Offset( aMoveVector );
  142. SetLocalCoord();
  143. }
  144. int FP_TEXT::GetLength() const
  145. {
  146. return GetText().Len();
  147. }
  148. void FP_TEXT::SetDrawCoord()
  149. {
  150. const FOOTPRINT* parentFootprint = static_cast<const FOOTPRINT*>( m_parent );
  151. SetTextPos( m_Pos0 );
  152. if( parentFootprint )
  153. {
  154. VECTOR2I pt = GetTextPos();
  155. RotatePoint( pt, parentFootprint->GetOrientation() );
  156. SetTextPos( pt );
  157. Offset( parentFootprint->GetPosition() );
  158. }
  159. }
  160. void FP_TEXT::SetLocalCoord()
  161. {
  162. const FOOTPRINT* parentFootprint = static_cast<const FOOTPRINT*>( m_parent );
  163. if( parentFootprint )
  164. {
  165. m_Pos0 = GetTextPos() - parentFootprint->GetPosition();
  166. RotatePoint( &m_Pos0.x, &m_Pos0.y, - parentFootprint->GetOrientation() );
  167. }
  168. else
  169. {
  170. m_Pos0 = GetTextPos();
  171. }
  172. }
  173. const EDA_RECT FP_TEXT::GetBoundingBox() const
  174. {
  175. EDA_ANGLE angle = GetDrawRotation();
  176. EDA_RECT text_area = GetTextBox();
  177. if( !angle.IsZero() )
  178. text_area = text_area.GetBoundingBoxRotated( GetTextPos(), angle );
  179. return text_area;
  180. }
  181. EDA_ANGLE FP_TEXT::GetDrawRotation() const
  182. {
  183. FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( m_parent );
  184. EDA_ANGLE rotation = GetTextAngle();
  185. if( parentFootprint )
  186. rotation += parentFootprint->GetOrientation();
  187. if( IsKeepUpright() )
  188. {
  189. // Keep angle between ]-90 .. 90 deg]. Otherwise the text is not easy to read
  190. while( rotation > ANGLE_90 )
  191. rotation -= ANGLE_180;
  192. while( rotation <= -ANGLE_90 )
  193. rotation += ANGLE_180;
  194. }
  195. else
  196. {
  197. rotation.Normalize();
  198. }
  199. return rotation;
  200. }
  201. void FP_TEXT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
  202. {
  203. EDA_UNITS units = aFrame->GetUserUnits();
  204. wxString msg;
  205. static const wxString text_type_msg[3] =
  206. {
  207. _( "Reference" ), _( "Value" ), _( "Text" )
  208. };
  209. if( aFrame->GetName() == PCB_EDIT_FRAME_NAME )
  210. {
  211. FOOTPRINT* fp = static_cast<FOOTPRINT*>( m_parent );
  212. if( fp )
  213. aList.emplace_back( _( "Footprint" ), fp->GetReference() );
  214. }
  215. // Don't use GetShownText() here; we want to show the user the variable references
  216. aList.emplace_back( _( "Text" ), UnescapeString( GetText() ) );
  217. wxASSERT( m_Type >= TEXT_is_REFERENCE && m_Type <= TEXT_is_DIVERS );
  218. aList.emplace_back( _( "Type" ), text_type_msg[m_Type] );
  219. if( aFrame->GetName() == PCB_EDIT_FRAME_NAME && IsLocked() )
  220. aList.emplace_back( _( "Status" ), _( "Locked" ) );
  221. aList.emplace_back( _( "Display" ), IsVisible() ? _( "Yes" ) : _( "No" ) );
  222. // Display text layer
  223. aList.emplace_back( _( "Layer" ), GetLayerName() );
  224. aList.emplace_back( _( "Mirror" ), IsMirrored() ? _( "Yes" ) : _( "No" ) );
  225. msg.Printf( wxT( "%g" ), GetTextAngle().AsDegrees() );
  226. aList.emplace_back( _( "Angle" ), msg );
  227. aList.emplace_back( _( "Font" ), GetDrawFont()->GetName() );
  228. aList.emplace_back( _( "Thickness" ), MessageTextFromValue( units, GetTextThickness() ) );
  229. aList.emplace_back( _( "Width" ), MessageTextFromValue( units, GetTextWidth() ) );
  230. aList.emplace_back( _( "Height" ), MessageTextFromValue(units, GetTextHeight() ) );
  231. }
  232. wxString FP_TEXT::GetSelectMenuText( EDA_UNITS aUnits ) const
  233. {
  234. switch( m_Type )
  235. {
  236. case TEXT_is_REFERENCE:
  237. return wxString::Format( _( "Reference '%s'" ),
  238. static_cast<FOOTPRINT*>( GetParent() )->GetReference() );
  239. case TEXT_is_VALUE:
  240. return wxString::Format( _( "Value '%s' of %s" ),
  241. GetShownText(),
  242. static_cast<FOOTPRINT*>( GetParent() )->GetReference() );
  243. default:
  244. return wxString::Format( _( "Footprint Text '%s' of %s" ),
  245. ShortenedShownText(),
  246. static_cast<FOOTPRINT*>( GetParent() )->GetReference() );
  247. }
  248. }
  249. BITMAPS FP_TEXT::GetMenuImage() const
  250. {
  251. return BITMAPS::text;
  252. }
  253. EDA_ITEM* FP_TEXT::Clone() const
  254. {
  255. return new FP_TEXT( *this );
  256. }
  257. const BOX2I FP_TEXT::ViewBBox() const
  258. {
  259. EDA_ANGLE angle = GetDrawRotation();
  260. EDA_RECT text_area = GetTextBox();
  261. if( !angle.IsZero() )
  262. text_area = text_area.GetBoundingBoxRotated( GetTextPos(), angle );
  263. return BOX2I( text_area.GetPosition(), text_area.GetSize() );
  264. }
  265. void FP_TEXT::ViewGetLayers( int aLayers[], int& aCount ) const
  266. {
  267. if( IsVisible() )
  268. aLayers[0] = GetLayer();
  269. else
  270. aLayers[0] = LAYER_MOD_TEXT_INVISIBLE;
  271. aCount = 1;
  272. }
  273. double FP_TEXT::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
  274. {
  275. constexpr double HIDE = (double)std::numeric_limits<double>::max();
  276. if( !aView )
  277. return 0.0;
  278. // Hidden text gets put on the LAYER_MOD_TEXT_INVISIBLE for rendering, but
  279. // should only render if its native layer is visible.
  280. if( !aView->IsLayerVisible( GetLayer() ) )
  281. return HIDE;
  282. // Handle Render tab switches
  283. if( m_Type == TEXT_is_VALUE || GetText() == wxT( "${VALUE}" ) )
  284. {
  285. if( !aView->IsLayerVisible( LAYER_MOD_VALUES ) )
  286. {
  287. return HIDE;
  288. }
  289. }
  290. if( m_Type == TEXT_is_REFERENCE || GetText() == wxT( "${REFERENCE}" ) )
  291. {
  292. if( !aView->IsLayerVisible( LAYER_MOD_REFERENCES ) )
  293. {
  294. return HIDE;
  295. }
  296. }
  297. if( !IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_FR ) )
  298. return HIDE;
  299. if( IsParentFlipped() && !aView->IsLayerVisible( LAYER_MOD_BK ) )
  300. return HIDE;
  301. if( !aView->IsLayerVisible( LAYER_MOD_TEXT ) )
  302. return HIDE;
  303. // Other layers are shown without any conditions
  304. return 0.0;
  305. }
  306. wxString FP_TEXT::GetShownText( int aDepth ) const
  307. {
  308. const FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( GetParent() );
  309. wxASSERT( parentFootprint );
  310. const BOARD* board = parentFootprint->GetBoard();
  311. std::function<bool( wxString* )> footprintResolver =
  312. [&]( wxString* token ) -> bool
  313. {
  314. return parentFootprint && parentFootprint->ResolveTextVar( token, aDepth );
  315. };
  316. std::function<bool( wxString* )> boardTextResolver =
  317. [&]( wxString* token ) -> bool
  318. {
  319. return board->ResolveTextVar( token, aDepth + 1 );
  320. };
  321. wxString text = EDA_TEXT::GetShownText();
  322. if( HasTextVars() )
  323. {
  324. PROJECT* project = nullptr;
  325. if( parentFootprint && parentFootprint->GetParent() )
  326. project = static_cast<BOARD*>( parentFootprint->GetParent() )->GetProject();
  327. if( aDepth < 10 )
  328. text = ExpandTextVars( text, &footprintResolver, &boardTextResolver, project );
  329. }
  330. return text;
  331. }
  332. std::shared_ptr<SHAPE> FP_TEXT::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
  333. {
  334. return GetEffectiveTextShape();
  335. }
  336. void FP_TEXT::TransformTextShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
  337. PCB_LAYER_ID aLayer, int aClearance,
  338. int aError, ERROR_LOC aErrorLoc ) const
  339. {
  340. KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
  341. KIFONT::FONT* font = GetDrawFont();
  342. int penWidth = GetEffectiveTextPenWidth();
  343. CALLBACK_GAL callback_gal( empty_opts,
  344. // Stroke callback
  345. [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
  346. {
  347. TransformOvalToPolygon( aCornerBuffer, aPt1, aPt2, penWidth+ ( 2 * aClearance ),
  348. aError, ERROR_INSIDE );
  349. },
  350. // Triangulation callback
  351. [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 )
  352. {
  353. aCornerBuffer.NewOutline();
  354. for( const VECTOR2I& point : { aPt1, aPt2, aPt3 } )
  355. aCornerBuffer.Append( point.x, point.y );
  356. } );
  357. TEXT_ATTRIBUTES attrs = GetAttributes();
  358. attrs.m_Angle = GetDrawRotation();
  359. font->Draw( &callback_gal, GetShownText(), GetTextPos(), attrs );
  360. }
  361. void FP_TEXT::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
  362. PCB_LAYER_ID aLayer, int aClearance,
  363. int aError, ERROR_LOC aErrorLoc,
  364. bool aIgnoreLineWidth ) const
  365. {
  366. SHAPE_POLY_SET buffer;
  367. EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon( &buffer, aClearance );
  368. aCornerBuffer.Append( buffer );
  369. }
  370. static struct FP_TEXT_DESC
  371. {
  372. FP_TEXT_DESC()
  373. {
  374. PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
  375. REGISTER_TYPE( FP_TEXT );
  376. propMgr.AddTypeCast( new TYPE_CAST<FP_TEXT, BOARD_ITEM> );
  377. propMgr.AddTypeCast( new TYPE_CAST<FP_TEXT, EDA_TEXT> );
  378. propMgr.InheritsAfter( TYPE_HASH( FP_TEXT ), TYPE_HASH( BOARD_ITEM ) );
  379. propMgr.InheritsAfter( TYPE_HASH( FP_TEXT ), TYPE_HASH( EDA_TEXT ) );
  380. propMgr.AddProperty( new PROPERTY<FP_TEXT, wxString>( _HKI( "Parent" ),
  381. NO_SETTER( FP_TEXT, wxString ), &FP_TEXT::GetParentAsString ) );
  382. }
  383. } _FP_TEXT_DESC;