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.

680 lines
20 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) 2004-2017 KiCad Developers, see change_log.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. * @file eda_text.cpp
  26. * @brief Implementation of base KiCad text object.
  27. */
  28. #include <algorithm> // for max
  29. #include <stddef.h> // for NULL
  30. #include <type_traits> // for swap
  31. #include <vector> // for vector
  32. #include <base_struct.h> // for EDA_ITEM
  33. #include <base_units.h>
  34. #include <basic_gal.h> // for BASIC_GAL, basic_gal
  35. #include <common.h> // for wxStringSplit
  36. #include <convert_to_biu.h> // for Mils2iu
  37. #include <core/typeinfo.h> // for KICAD_T, SCH_LABEL_T, SCH_TEXT_T, SCH_G...
  38. #include <eda_rect.h> // for EDA_RECT
  39. #include <eda_text.h> // for EDA_TEXT, TEXT_EFFECTS, GR_TEXT_VJUSTIF...
  40. #include <gal/color4d.h> // for COLOR4D, COLOR4D::BLACK
  41. #include <gal/stroke_font.h> // for STROKE_FONT
  42. #include <gr_text.h> // for GRText
  43. #include <kicad_string.h> // for UnescapeString
  44. #include <math/util.h> // for KiROUND
  45. #include <math/vector2d.h> // for VECTOR2D
  46. #include <trigo.h> // for RotatePoint
  47. #include <geometry/shape.h>
  48. #include <geometry/shape_segment.h>
  49. #include <geometry/shape_compound.h>
  50. #include <wx/debug.h> // for wxASSERT
  51. #include <wx/wx.h> // for wxPoint, wxString, wxArrayString, wxSize
  52. class OUTPUTFORMATTER;
  53. class wxFindReplaceData;
  54. EDA_TEXT_HJUSTIFY_T EDA_TEXT::MapHorizJustify( int aHorizJustify )
  55. {
  56. wxASSERT( aHorizJustify >= GR_TEXT_HJUSTIFY_LEFT && aHorizJustify <= GR_TEXT_HJUSTIFY_RIGHT );
  57. if( aHorizJustify > GR_TEXT_HJUSTIFY_RIGHT )
  58. return GR_TEXT_HJUSTIFY_RIGHT;
  59. if( aHorizJustify < GR_TEXT_HJUSTIFY_LEFT )
  60. return GR_TEXT_HJUSTIFY_LEFT;
  61. return (EDA_TEXT_HJUSTIFY_T) aHorizJustify;
  62. }
  63. EDA_TEXT_VJUSTIFY_T EDA_TEXT::MapVertJustify( int aVertJustify )
  64. {
  65. wxASSERT( aVertJustify >= GR_TEXT_VJUSTIFY_TOP && aVertJustify <= GR_TEXT_VJUSTIFY_BOTTOM );
  66. if( aVertJustify > GR_TEXT_VJUSTIFY_BOTTOM )
  67. return GR_TEXT_VJUSTIFY_BOTTOM;
  68. if( aVertJustify < GR_TEXT_VJUSTIFY_TOP )
  69. return GR_TEXT_VJUSTIFY_TOP;
  70. return (EDA_TEXT_VJUSTIFY_T) aVertJustify;
  71. }
  72. EDA_TEXT::EDA_TEXT( const wxString& text ) :
  73. m_text( text ),
  74. m_e( 1<<TE_VISIBLE )
  75. {
  76. int sz = Mils2iu( DEFAULT_SIZE_TEXT );
  77. SetTextSize( wxSize( sz, sz ) );
  78. m_shown_text_has_text_var_refs = false;
  79. if( !text.IsEmpty() )
  80. {
  81. m_shown_text = UnescapeString( text );
  82. m_shown_text_has_text_var_refs = m_shown_text.Contains( wxT( "${" ) );
  83. }
  84. }
  85. EDA_TEXT::EDA_TEXT( const EDA_TEXT& aText ) :
  86. m_text( aText.m_text ),
  87. m_e( aText.m_e )
  88. {
  89. m_shown_text = UnescapeString( m_text );
  90. m_shown_text_has_text_var_refs = m_shown_text.Contains( wxT( "${" ) );
  91. }
  92. EDA_TEXT::~EDA_TEXT()
  93. {
  94. }
  95. void EDA_TEXT::SetText( const wxString& aText )
  96. {
  97. m_text = aText;
  98. m_shown_text = UnescapeString( aText );
  99. m_shown_text_has_text_var_refs = m_shown_text.Contains( wxT( "${" ) );
  100. }
  101. void EDA_TEXT::CopyText( const EDA_TEXT& aSrc )
  102. {
  103. m_text = aSrc.m_text;
  104. m_shown_text = aSrc.m_shown_text;
  105. m_shown_text_has_text_var_refs = aSrc.m_shown_text_has_text_var_refs;
  106. }
  107. void EDA_TEXT::SetEffects( const EDA_TEXT& aSrc )
  108. {
  109. m_e = aSrc.m_e;
  110. }
  111. void EDA_TEXT::SwapText( EDA_TEXT& aTradingPartner )
  112. {
  113. std::swap( m_text, aTradingPartner.m_text );
  114. std::swap( m_shown_text, aTradingPartner.m_shown_text );
  115. std::swap( m_shown_text_has_text_var_refs, aTradingPartner.m_shown_text_has_text_var_refs );
  116. }
  117. void EDA_TEXT::SwapEffects( EDA_TEXT& aTradingPartner )
  118. {
  119. std::swap( m_e, aTradingPartner.m_e );
  120. }
  121. int EDA_TEXT::GetEffectiveTextPenWidth( int aDefaultWidth ) const
  122. {
  123. int width = GetTextThickness();
  124. if( width <= 1 )
  125. {
  126. width = aDefaultWidth;
  127. if( IsBold() )
  128. width = GetPenSizeForBold( GetTextWidth() );
  129. else if( width <= 1 )
  130. width = GetPenSizeForNormal( GetTextWidth() );
  131. }
  132. // Clip pen size for small texts:
  133. width = Clamp_Text_PenSize( width, GetTextSize(), ALLOW_BOLD_THICKNESS );
  134. return width;
  135. }
  136. bool EDA_TEXT::Replace( wxFindReplaceData& aSearchData )
  137. {
  138. bool retval = EDA_ITEM::Replace( aSearchData, m_text );
  139. m_shown_text = UnescapeString( m_text );
  140. m_shown_text_has_text_var_refs = m_shown_text.Contains( wxT( "${" ) );
  141. return retval;
  142. }
  143. int EDA_TEXT::LenSize( const wxString& aLine, int aThickness ) const
  144. {
  145. basic_gal.SetFontItalic( IsItalic() );
  146. basic_gal.SetFontBold( IsBold() );
  147. basic_gal.SetFontUnderlined( false );
  148. basic_gal.SetLineWidth( (float) aThickness );
  149. basic_gal.SetGlyphSize( VECTOR2D( GetTextSize() ) );
  150. VECTOR2D tsize = basic_gal.GetTextLineSize( aLine );
  151. return KiROUND( tsize.x );
  152. }
  153. wxString EDA_TEXT::ShortenedShownText() const
  154. {
  155. wxString tmp = GetShownText();
  156. tmp.Replace( wxT( "\n" ), wxT( " " ) );
  157. tmp.Replace( wxT( "\r" ), wxT( " " ) );
  158. tmp.Replace( wxT( "\t" ), wxT( " " ) );
  159. if( tmp.Length() > 36 )
  160. tmp = tmp.Left( 34 ) + wxT( "..." );
  161. return tmp;
  162. }
  163. int EDA_TEXT::GetInterline() const
  164. {
  165. return KiROUND( KIGFX::STROKE_FONT::GetInterline( GetTextHeight() ) );
  166. }
  167. EDA_RECT EDA_TEXT::GetTextBox( int aLine, bool aInvertY ) const
  168. {
  169. EDA_RECT rect;
  170. wxArrayString strings;
  171. wxString text = GetShownText();
  172. int thickness = GetEffectiveTextPenWidth();
  173. int linecount = 1;
  174. bool hasOverBar = false; // true if the first line of text as an overbar
  175. if( IsMultilineAllowed() )
  176. {
  177. wxStringSplit( text, strings, '\n' );
  178. if( strings.GetCount() ) // GetCount() == 0 for void strings
  179. {
  180. if( aLine >= 0 && (aLine < (int)strings.GetCount()) )
  181. text = strings.Item( aLine );
  182. else
  183. text = strings.Item( 0 );
  184. linecount = strings.GetCount();
  185. }
  186. }
  187. // Search for overbar symbol. Only text is scanned,
  188. // because only this line can change the bounding box
  189. for( unsigned ii = 1; ii < text.size(); ii++ )
  190. {
  191. if( text[ii-1] == '~' && text[ii] != '~' )
  192. {
  193. hasOverBar = true;
  194. break;
  195. }
  196. }
  197. // calculate the H and V size
  198. const auto& font = basic_gal.GetStrokeFont();
  199. VECTOR2D fontSize( GetTextSize() );
  200. double penWidth( thickness );
  201. int dx = KiROUND( font.ComputeStringBoundaryLimits( text, fontSize, penWidth ).x );
  202. int dy = GetInterline();
  203. // Creates bounding box (rectangle) for horizontal, left and top justified text. The
  204. // bounding box will be moved later according to the actual text options
  205. wxSize textsize = wxSize( dx, dy );
  206. wxPoint pos = GetTextPos();
  207. if( aInvertY )
  208. pos.y = -pos.y;
  209. rect.SetOrigin( pos );
  210. // The bbox vertical size returned by GetInterline( aThickness )
  211. // includes letters like j and y and ] + interval between lines.
  212. // The interval below the last line is not usefull, and we can use its half value
  213. // as vertical margin above the text
  214. // the full interval is roughly GetTextHeight() * 0.4 - aThickness/2
  215. rect.Move( wxPoint( 0, thickness/4 - KiROUND( GetTextHeight() * 0.22 ) ) );
  216. if( hasOverBar )
  217. { // A overbar adds an extra size to the text
  218. // Height from the base line text of chars like [ or {
  219. double curr_height = GetTextHeight() * 1.15;
  220. double overbarPosition = font.ComputeOverbarVerticalPosition( fontSize.y );
  221. int extra_height = KiROUND( overbarPosition - curr_height );
  222. extra_height += thickness / 2;
  223. textsize.y += extra_height;
  224. rect.Move( wxPoint( 0, -extra_height ) );
  225. }
  226. // for multiline texts and aLine < 0, merge all rectangles
  227. // ( if aLine < 0, we want the full text bounding box )
  228. if( IsMultilineAllowed() && aLine < 0 )
  229. {
  230. for( unsigned ii = 1; ii < strings.GetCount(); ii++ )
  231. {
  232. text = strings.Item( ii );
  233. dx = KiROUND( font.ComputeStringBoundaryLimits( text, fontSize, penWidth ).x );
  234. textsize.x = std::max( textsize.x, dx );
  235. textsize.y += dy;
  236. }
  237. }
  238. rect.SetSize( textsize );
  239. /* Now, calculate the rect origin, according to text justification
  240. * At this point the rectangle origin is the text origin (m_Pos).
  241. * This is true only for left and top text justified texts (using top to bottom Y axis
  242. * orientation). and must be recalculated for others justifications
  243. * also, note the V justification is relative to the first line
  244. */
  245. switch( GetHorizJustify() )
  246. {
  247. case GR_TEXT_HJUSTIFY_LEFT:
  248. if( IsMirrored() )
  249. rect.SetX( rect.GetX() - rect.GetWidth() );
  250. break;
  251. case GR_TEXT_HJUSTIFY_CENTER:
  252. rect.SetX( rect.GetX() - (rect.GetWidth() / 2) );
  253. break;
  254. case GR_TEXT_HJUSTIFY_RIGHT:
  255. if( !IsMirrored() )
  256. rect.SetX( rect.GetX() - rect.GetWidth() );
  257. break;
  258. }
  259. dy = GetTextHeight() + thickness;
  260. switch( GetVertJustify() )
  261. {
  262. case GR_TEXT_VJUSTIFY_TOP:
  263. break;
  264. case GR_TEXT_VJUSTIFY_CENTER:
  265. rect.SetY( rect.GetY() - ( dy / 2) );
  266. break;
  267. case GR_TEXT_VJUSTIFY_BOTTOM:
  268. rect.SetY( rect.GetY() - dy );
  269. break;
  270. }
  271. if( linecount > 1 )
  272. {
  273. int yoffset;
  274. linecount -= 1;
  275. switch( GetVertJustify() )
  276. {
  277. case GR_TEXT_VJUSTIFY_TOP:
  278. break;
  279. case GR_TEXT_VJUSTIFY_CENTER:
  280. yoffset = linecount * GetInterline() / 2;
  281. rect.SetY( rect.GetY() - yoffset );
  282. break;
  283. case GR_TEXT_VJUSTIFY_BOTTOM:
  284. yoffset = linecount * GetInterline();
  285. rect.SetY( rect.GetY() - yoffset );
  286. break;
  287. }
  288. }
  289. rect.Normalize(); // Make h and v sizes always >= 0
  290. return rect;
  291. }
  292. bool EDA_TEXT::TextHitTest( const wxPoint& aPoint, int aAccuracy ) const
  293. {
  294. EDA_RECT rect = GetTextBox();
  295. wxPoint location = aPoint;
  296. rect.Inflate( aAccuracy );
  297. RotatePoint( &location, GetTextPos(), -GetTextAngle() );
  298. return rect.Contains( location );
  299. }
  300. bool EDA_TEXT::TextHitTest( const EDA_RECT& aRect, bool aContains, int aAccuracy ) const
  301. {
  302. EDA_RECT rect = aRect;
  303. rect.Inflate( aAccuracy );
  304. if( aContains )
  305. return rect.Contains( GetTextBox() );
  306. return rect.Intersects( GetTextBox(), GetTextAngle() );
  307. }
  308. void EDA_TEXT::Print( RENDER_SETTINGS* aSettings, const wxPoint& aOffset, COLOR4D aColor,
  309. EDA_DRAW_MODE_T aFillMode )
  310. {
  311. if( IsMultilineAllowed() )
  312. {
  313. std::vector<wxPoint> positions;
  314. wxArrayString strings;
  315. wxStringSplit( GetShownText(), strings, '\n' );
  316. positions.reserve( strings.Count() );
  317. GetLinePositions( positions, strings.Count());
  318. for( unsigned ii = 0; ii < strings.Count(); ii++ )
  319. printOneLineOfText( aSettings, aOffset, aColor, aFillMode, strings[ii], positions[ii] );
  320. }
  321. else
  322. {
  323. printOneLineOfText( aSettings, aOffset, aColor, aFillMode, GetShownText(), GetTextPos() );
  324. }
  325. }
  326. void EDA_TEXT::GetLinePositions( std::vector<wxPoint>& aPositions, int aLineCount ) const
  327. {
  328. wxPoint pos = GetTextPos(); // Position of first line of the
  329. // multiline text according to
  330. // the center of the multiline text block
  331. wxPoint offset; // Offset to next line.
  332. offset.y = GetInterline();
  333. if( aLineCount > 1 )
  334. {
  335. switch( GetVertJustify() )
  336. {
  337. case GR_TEXT_VJUSTIFY_TOP:
  338. break;
  339. case GR_TEXT_VJUSTIFY_CENTER:
  340. pos.y -= ( aLineCount - 1 ) * offset.y / 2;
  341. break;
  342. case GR_TEXT_VJUSTIFY_BOTTOM:
  343. pos.y -= ( aLineCount - 1 ) * offset.y;
  344. break;
  345. }
  346. }
  347. // Rotate the position of the first line
  348. // around the center of the multiline text block
  349. RotatePoint( &pos, GetTextPos(), GetTextAngle() );
  350. // Rotate the offset lines to increase happened in the right direction
  351. RotatePoint( &offset, GetTextAngle() );
  352. for( int ii = 0; ii < aLineCount; ii++ )
  353. {
  354. aPositions.push_back( pos );
  355. pos += offset;
  356. }
  357. }
  358. void EDA_TEXT::printOneLineOfText( RENDER_SETTINGS* aSettings, const wxPoint& aOffset,
  359. COLOR4D aColor, EDA_DRAW_MODE_T aFillMode,
  360. const wxString& aText, const wxPoint &aPos )
  361. {
  362. wxDC* DC = aSettings->GetPrintDC();
  363. int penWidth = std::max( GetEffectiveTextPenWidth(), aSettings->GetDefaultPenWidth() );
  364. if( aFillMode == SKETCH )
  365. penWidth = -penWidth;
  366. wxSize size = GetTextSize();
  367. if( IsMirrored() )
  368. size.x = -size.x;
  369. GRText( DC, aOffset + aPos, aColor, aText, GetTextAngle(), size, GetHorizJustify(),
  370. GetVertJustify(), penWidth, IsItalic(), IsBold() );
  371. }
  372. wxString EDA_TEXT::GetTextStyleName()
  373. {
  374. int style = 0;
  375. if( IsItalic() )
  376. style = 1;
  377. if( IsBold() )
  378. style += 2;
  379. wxString stylemsg[4] = {
  380. _("Normal"),
  381. _("Italic"),
  382. _("Bold"),
  383. _("Bold+Italic")
  384. };
  385. return stylemsg[style];
  386. }
  387. bool EDA_TEXT::IsDefaultFormatting() const
  388. {
  389. return ( IsVisible()
  390. && !IsMirrored()
  391. && GetHorizJustify() == GR_TEXT_HJUSTIFY_CENTER
  392. && GetVertJustify() == GR_TEXT_VJUSTIFY_CENTER
  393. && GetTextThickness() == 0
  394. && !IsItalic()
  395. && !IsBold()
  396. && !IsMultilineAllowed()
  397. );
  398. }
  399. void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
  400. {
  401. #ifndef GERBVIEW // Gerbview does not use EDA_TEXT::Format
  402. // and does not define FormatInternalUnits, used here
  403. // however this function should exist
  404. aFormatter->Print( aNestLevel + 1, "(effects" );
  405. // Text size
  406. aFormatter->Print( 0, " (font" );
  407. aFormatter->Print( 0, " (size %s %s)",
  408. FormatInternalUnits( GetTextHeight() ).c_str(),
  409. FormatInternalUnits( GetTextWidth() ).c_str() );
  410. if( GetTextThickness() )
  411. aFormatter->Print( 0, " (thickness %s)", FormatInternalUnits( GetTextThickness() ).c_str() );
  412. if( IsBold() )
  413. aFormatter->Print( 0, " bold" );
  414. if( IsItalic() )
  415. aFormatter->Print( 0, " italic" );
  416. aFormatter->Print( 0, ")"); // (font
  417. if( IsMirrored() ||
  418. GetHorizJustify() != GR_TEXT_HJUSTIFY_CENTER ||
  419. GetVertJustify() != GR_TEXT_VJUSTIFY_CENTER )
  420. {
  421. aFormatter->Print( 0, " (justify");
  422. if( GetHorizJustify() != GR_TEXT_HJUSTIFY_CENTER )
  423. aFormatter->Print( 0, (GetHorizJustify() == GR_TEXT_HJUSTIFY_LEFT) ? " left" : " right" );
  424. if( GetVertJustify() != GR_TEXT_VJUSTIFY_CENTER )
  425. aFormatter->Print( 0, (GetVertJustify() == GR_TEXT_VJUSTIFY_TOP) ? " top" : " bottom" );
  426. if( IsMirrored() )
  427. aFormatter->Print( 0, " mirror" );
  428. aFormatter->Print( 0, ")" ); // (justify
  429. }
  430. if( !(aControlBits & CTL_OMIT_HIDE) && !IsVisible() )
  431. aFormatter->Print( 0, " hide" );
  432. aFormatter->Print( 0, ")\n" ); // (justify
  433. #endif
  434. }
  435. // Convert the text shape to a list of segment
  436. // each segment is stored as 2 wxPoints: its starting point and its ending point
  437. // we are using GRText to create the segments and therefore a call-back function is needed
  438. // This is a call back function, used by GRText to put each segment in buffer
  439. static void addTextSegmToBuffer( int x0, int y0, int xf, int yf, void* aData )
  440. {
  441. std::vector<wxPoint>* cornerBuffer = static_cast<std::vector<wxPoint>*>( aData );
  442. cornerBuffer->push_back( wxPoint( x0, y0 ) );
  443. cornerBuffer->push_back( wxPoint( xf, yf ) );
  444. }
  445. void EDA_TEXT::TransformTextShapeToSegmentList( std::vector<wxPoint>& aCornerBuffer ) const
  446. {
  447. wxSize size = GetTextSize();
  448. if( IsMirrored() )
  449. size.x = -size.x;
  450. bool forceBold = true;
  451. int penWidth = 0; // use max-width for bold text
  452. COLOR4D color = COLOR4D::BLACK; // not actually used, but needed by GRText
  453. if( IsMultilineAllowed() )
  454. {
  455. wxArrayString strings_list;
  456. wxStringSplit( GetShownText(), strings_list, wxChar('\n') );
  457. std::vector<wxPoint> positions;
  458. positions.reserve( strings_list.Count() );
  459. GetLinePositions( positions, strings_list.Count());
  460. for( unsigned ii = 0; ii < strings_list.Count(); ii++ )
  461. {
  462. wxString txt = strings_list.Item( ii );
  463. GRText( NULL, positions[ii], color, txt, GetDrawRotation(), size, GetHorizJustify(),
  464. GetVertJustify(), penWidth, IsItalic(), forceBold, addTextSegmToBuffer,
  465. &aCornerBuffer );
  466. }
  467. }
  468. else
  469. {
  470. GRText( NULL, GetTextPos(), color, GetText(), GetDrawRotation(), size, GetHorizJustify(),
  471. GetVertJustify(), penWidth, IsItalic(), forceBold, addTextSegmToBuffer,
  472. &aCornerBuffer );
  473. }
  474. }
  475. std::shared_ptr<SHAPE_COMPOUND> EDA_TEXT::GetEffectiveTextShape( ) const
  476. {
  477. std::shared_ptr<SHAPE_COMPOUND> shape ( new SHAPE_COMPOUND );
  478. int penWidth = GetEffectiveTextPenWidth();
  479. std::vector<wxPoint> pts;
  480. TransformTextShapeToSegmentList( pts );
  481. for( unsigned jj = 0; jj < pts.size(); jj += 2 )
  482. shape->AddShape( new SHAPE_SEGMENT( pts[jj], pts[jj+1], penWidth ) );
  483. return shape;
  484. }
  485. double EDA_TEXT::GetDrawRotation() const
  486. {
  487. return GetTextAngle();
  488. }
  489. static struct EDA_TEXT_DESC
  490. {
  491. EDA_TEXT_DESC()
  492. {
  493. ENUM_MAP<EDA_TEXT_HJUSTIFY_T>::Instance()
  494. .Map( GR_TEXT_HJUSTIFY_LEFT, _( "Left" ) )
  495. .Map( GR_TEXT_HJUSTIFY_CENTER, _( "Center" ) )
  496. .Map( GR_TEXT_HJUSTIFY_RIGHT, _( "Right" ) );
  497. ENUM_MAP<EDA_TEXT_VJUSTIFY_T>::Instance()
  498. .Map( GR_TEXT_VJUSTIFY_TOP, _( "Top" ) )
  499. .Map( GR_TEXT_VJUSTIFY_CENTER, _( "Center" ) )
  500. .Map( GR_TEXT_VJUSTIFY_BOTTOM, _( "Bottom" ) );
  501. PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
  502. REGISTER_TYPE( EDA_TEXT );
  503. propMgr.AddProperty( new PROPERTY<EDA_TEXT, wxString>( _( "Text" ),
  504. &EDA_TEXT::SetText, &EDA_TEXT::GetText ) );
  505. propMgr.AddProperty( new PROPERTY<EDA_TEXT, int>( _( "Thickness" ),
  506. &EDA_TEXT::SetTextThickness, &EDA_TEXT::GetTextThickness, PROPERTY_DISPLAY::DISTANCE ) );
  507. propMgr.AddProperty( new PROPERTY<EDA_TEXT, bool>( _( "Italic" ),
  508. &EDA_TEXT::SetItalic, &EDA_TEXT::IsItalic ) );
  509. propMgr.AddProperty( new PROPERTY<EDA_TEXT, bool>( _( "Bold" ),
  510. &EDA_TEXT::SetBold, &EDA_TEXT::IsBold ) );
  511. propMgr.AddProperty( new PROPERTY<EDA_TEXT, bool>( _( "Mirrored" ),
  512. &EDA_TEXT::SetMirrored, &EDA_TEXT::IsMirrored ) );
  513. propMgr.AddProperty( new PROPERTY<EDA_TEXT, bool>( _( "Visible" ),
  514. &EDA_TEXT::SetVisible, &EDA_TEXT::IsVisible ) );
  515. propMgr.AddProperty( new PROPERTY<EDA_TEXT, int>( _( "Width" ),
  516. &EDA_TEXT::SetTextWidth, &EDA_TEXT::GetTextWidth, PROPERTY_DISPLAY::DISTANCE ) );
  517. propMgr.AddProperty( new PROPERTY<EDA_TEXT, int>( _( "Height" ),
  518. &EDA_TEXT::SetTextHeight, &EDA_TEXT::GetTextHeight, PROPERTY_DISPLAY::DISTANCE ) );
  519. propMgr.AddProperty( new PROPERTY_ENUM<EDA_TEXT, EDA_TEXT_HJUSTIFY_T>( _( "Horizontal Justification" ),
  520. &EDA_TEXT::SetHorizJustify, &EDA_TEXT::GetHorizJustify ) );
  521. propMgr.AddProperty( new PROPERTY_ENUM<EDA_TEXT, EDA_TEXT_VJUSTIFY_T>( _( "Vertical Justification" ),
  522. &EDA_TEXT::SetVertJustify, &EDA_TEXT::GetVertJustify ) );
  523. }
  524. } _EDA_TEXT_DESC;
  525. ENUM_TO_WXANY( EDA_TEXT_HJUSTIFY_T )
  526. ENUM_TO_WXANY( EDA_TEXT_VJUSTIFY_T )