KiCad PCB EDA Suite
pcb_text.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
5  * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 1992-2020 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 
26 #include <eda_item.h>
27 #include <pcb_edit_frame.h>
28 #include <base_units.h>
29 #include <bitmaps.h>
30 #include <class_board.h>
31 #include <pcb_text.h>
32 #include <pcb_painter.h>
33 #include <trigo.h>
34 
36 
37 
39  BOARD_ITEM( parent, PCB_TEXT_T ),
40  EDA_TEXT()
41 {
42  SetMultilineAllowed( true );
43 }
44 
45 
47 {
48 }
49 
50 
51 wxString PCB_TEXT::GetShownText( int aDepth ) const
52 {
53  BOARD* board = dynamic_cast<BOARD*>( GetParent() );
54 
55  std::function<bool( wxString* )> pcbTextResolver =
56  [&]( wxString* token ) -> bool
57  {
58  if( token->IsSameAs( wxT( "LAYER" ) ) )
59  {
60  *token = GetLayerName();
61  return true;
62  }
63 
64  if( token->Contains( ':' ) )
65  {
66  wxString remainder;
67  wxString ref = token->BeforeFirst( ':', &remainder );
68  BOARD_ITEM* refItem = board->GetItem( KIID( ref ) );
69 
70  if( refItem && refItem->Type() == PCB_MODULE_T )
71  {
72  MODULE* refModule = static_cast<MODULE*>( refItem );
73 
74  if( refModule->ResolveTextVar( &remainder, aDepth + 1 ) )
75  {
76  *token = remainder;
77  return true;
78  }
79  }
80  }
81  return false;
82  };
83 
84  std::function<bool( wxString* )> boardTextResolver =
85  [&]( wxString* token ) -> bool
86  {
87  return board->ResolveTextVar( token, aDepth + 1 );
88  };
89 
90  bool processTextVars = false;
91  wxString text = EDA_TEXT::GetShownText( &processTextVars );
92 
93  if( board && processTextVars && aDepth < 10 )
94  text = ExpandTextVars( text, &pcbTextResolver, board->GetProject(), &boardTextResolver );
95 
96  return text;
97 }
98 
99 
100 void PCB_TEXT::SetTextAngle( double aAngle )
101 {
103 }
104 
105 
106 void PCB_TEXT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
107 {
108  wxString msg;
109 
110  wxCHECK_RET( m_Parent != NULL, wxT( "PCB_TEXT::GetMsgPanelInfo() m_Parent is NULL." ) );
111 
112  aList.emplace_back( _( "PCB Text" ), GetShownText(), DARKGREEN );
113 
114  aList.emplace_back( _( "Layer" ), GetLayerName(), BLUE );
115 
116  if( !IsMirrored() )
117  aList.emplace_back( _( "Mirror" ), _( "No" ), DARKGREEN );
118  else
119  aList.emplace_back( _( "Mirror" ), _( "Yes" ), DARKGREEN );
120 
121  msg.Printf( wxT( "%.1f" ), GetTextAngle() / 10.0 );
122  aList.emplace_back( _( "Angle" ), msg, DARKGREEN );
123 
124  msg = MessageTextFromValue( aFrame->GetUserUnits(), GetTextThickness() );
125  aList.emplace_back( _( "Thickness" ), msg, MAGENTA );
126 
127  msg = MessageTextFromValue( aFrame->GetUserUnits(), GetTextWidth() );
128  aList.emplace_back( _( "Width" ), msg, RED );
129 
130  msg = MessageTextFromValue( aFrame->GetUserUnits(), GetTextHeight() );
131  aList.emplace_back( _( "Height" ), msg, RED );
132 }
133 
134 
136 {
137  EDA_RECT rect = GetTextBox();
138 
139  if( GetTextAngle() )
140  rect = rect.GetBoundingBoxRotated( GetTextPos(), GetTextAngle() );
141 
142  return rect;
143 }
144 
145 
146 void PCB_TEXT::Rotate( const wxPoint& aRotCentre, double aAngle )
147 {
148  wxPoint pt = GetTextPos();
149  RotatePoint( &pt, aRotCentre, aAngle );
150  SetTextPos( pt );
151 
152  SetTextAngle( GetTextAngle() + aAngle );
153 }
154 
155 
156 void PCB_TEXT::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
157 {
158  double angle = GetTextAngle();
159  bool vertical = KiROUND( angle ) % 1800 == 900;
160 
161  if( KiROUND( angle ) != 0 )
162  {
163  Rotate( aCentre, -angle );
164 
165  if( vertical )
166  aFlipLeftRight = !aFlipLeftRight;
167  }
168 
169  // Flip the bounding box
170  EDA_RECT box = GetTextBox();
171  int left = box.GetLeft();
172  int right = box.GetRight();
173  int top = box.GetTop();
174  int bottom = box.GetBottom();
175 
176  if( aFlipLeftRight )
177  {
178  MIRROR( left, aCentre.x );
179  MIRROR( right, aCentre.x );
180  std::swap( left, right );
181  }
182  else
183  {
184  MIRROR( top, aCentre.y );
185  MIRROR( bottom, aCentre.y );
186  std::swap( top, bottom );
187  }
188 
189  // Now put the text back in it (these look backwards but remember that out text will
190  // be mirrored when all is said and done)
191  switch( GetHorizJustify() )
192  {
193  case GR_TEXT_HJUSTIFY_LEFT: SetTextX( right ); break;
194  case GR_TEXT_HJUSTIFY_CENTER: SetTextX( ( left + right ) / 2 ); break;
195  case GR_TEXT_HJUSTIFY_RIGHT: SetTextX( left ); break;
196  }
197 
198  switch( GetVertJustify() )
199  {
200  case GR_TEXT_VJUSTIFY_TOP: SetTextY( bottom ); break;
201  case GR_TEXT_VJUSTIFY_CENTER: SetTextY( ( top + bottom ) / 2 ); break;
202  case GR_TEXT_VJUSTIFY_BOTTOM: SetTextY( top ); break;
203  }
204 
205  // And restore orientation
206  if( KiROUND( angle ) != 0 )
207  Rotate( aCentre, angle );
208 
209  SetLayer( FlipLayer( GetLayer(), GetBoard()->GetCopperLayerCount() ) );
210  SetMirrored( !IsMirrored() );
211 }
212 
213 
214 wxString PCB_TEXT::GetSelectMenuText( EDA_UNITS aUnits ) const
215 {
216  return wxString::Format( _( "PCB Text '%s' on %s"), ShortenedShownText(), GetLayerName() );
217 }
218 
219 
221 {
222  return text_xpm;
223 }
224 
225 
227 {
228  return new PCB_TEXT( *this );
229 }
230 
231 
233 {
234  assert( aImage->Type() == PCB_TEXT_T );
235 
236  std::swap( *((PCB_TEXT*) this), *((PCB_TEXT*) aImage) );
237 }
238 
239 
240 std::shared_ptr<SHAPE> PCB_TEXT::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
241 {
242  return GetEffectiveTextShape();
243 }
244 
245 
246 static struct TEXTE_PCB_DESC
247 {
249  {
256  }
void SetMirrored(bool isMirrored)
Definition: eda_text.h:189
BOARD_ITEM * GetItem(const KIID &aID) const
EDA_UNITS
Definition: common.h:200
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aAddUnitLabel, EDA_DATA_TYPE aType)
Definition: base_units.cpp:122
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:61
EDA_ITEM * m_Parent
Linked list: Link (parent struct)
Definition: eda_item.h:162
#define TYPE_HASH(x)
Macro to generate unique identifier for a type
Definition: property.h:53
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:201
bool IsMirrored() const
Definition: eda_text.h:190
PNG memory record (file in memory).
Definition: bitmap_def.h:29
virtual void SwapData(BOARD_ITEM *aImage) override
Swap data between aItem and aImage.
Definition: pcb_text.cpp:232
bool ResolveTextVar(wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the component.
const EDA_RECT GetBoundingBoxRotated(wxPoint aRotCenter, double aAngle) const
Function GetBoundingBoxRotated.
Definition: eda_rect.cpp:511
void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Function Flip Flip this object, i.e.
Definition: pcb_text.cpp:156
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
Implementation of conversion functions that require both schematic and board internal units.
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
int GetTop() const
Definition: eda_rect.h:123
void SetTextAngle(double aAngle) override
Definition: pcb_text.cpp:100
int GetLeft() const
Definition: eda_rect.h:122
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition: lset.cpp:520
EDA_RECT GetTextBox(int aLine=-1, bool aInvertY=false) const
Useful in multiline texts to calculate the full text or a line area (for zones filling,...
Definition: eda_text.cpp:222
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:248
PROJECT * GetProject() const
Definition: class_board.h:396
const BITMAP_OPAQUE text_xpm[1]
Definition: text.cpp:24
double GetTextAngle() const
Definition: eda_text.h:175
class PCB_TEXT, text on a layer
Definition: typeinfo.h:92
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
Definition: pcb_text.cpp:106
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:208
static struct TEXTE_PCB_DESC _TEXTE_PCB_DESC
int GetTextThickness() const
Definition: eda_text.h:160
The base class for create windows for drawing purpose.
PCB_TEXT(BOARD_ITEM *parent)
Definition: pcb_text.cpp:38
#define REGISTER_TYPE(x)
Helper macro to map type hashes to names
Definition: property_mgr.h:244
int GetBottom() const
Definition: eda_rect.h:124
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER) const override
Function GetEffectiveShape Some pad shapes can be complex (rounded/chamfered rectangle),...
Definition: pcb_text.cpp:240
int GetTextHeight() const
Definition: eda_text.h:246
void SetTextX(int aX)
Definition: eda_text.h:251
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:114
PCB_RENDER_SETTINGS Stores PCB specific render settings.
Definition: pcb_painter.h:64
void MIRROR(T &aPoint, const T &aMirrorRef)
Definition: macros.h:142
wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: pcb_text.cpp:51
Definition: common.h:70
class MODULE, a footprint
Definition: typeinfo.h:89
~PCB_TEXT()
Definition: pcb_text.cpp:46
PCB_LAYER_ID
A quick note on layer IDs:
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:200
#define NULL
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
Definition: pcb_text.cpp:220
virtual BOARD * GetBoard() const
Function GetBoard returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
int GetRight() const
Definition: eda_rect.h:121
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declares an inheritance relationship between types.
wxString ShortenedShownText() const
Returns a shortened version (max 15 characters) of the shown text.
Definition: eda_text.cpp:201
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
Definition: pcb_text.cpp:214
Definition: color4d.h:60
void SetMultilineAllowed(bool aAllow)
Definition: eda_text.h:197
wxString ExpandTextVars(const wxString &aSource, const std::function< bool(wxString *)> *aLocalResolver, const PROJECT *aProject, const std::function< bool(wxString *)> *aFallbackResolver)
Expand '${var-name}' templates in text.
Definition: common.cpp:413
Definition: color4d.h:57
int GetTextWidth() const
Definition: eda_text.h:243
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:201
std::shared_ptr< SHAPE_COMPOUND > GetEffectiveTextShape() const
Definition: eda_text.cpp:620
Information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:186
#define _(s)
Definition: 3d_actions.cpp:33
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
void AddTypeCast(TYPE_CAST_BASE *aCast)
Registers a type converter.
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:68
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: eda_item.h:147
void Rotate(const wxPoint &aRotCentre, double aAngle) override
Function Rotate Rotate this object.
Definition: pcb_text.cpp:146
const wxPoint & GetTextPos() const
Definition: eda_text.h:249
Provides class metadata.
Definition: property_mgr.h:58
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
Definition: pcb_text.cpp:226
virtual void SetTextAngle(double aAngle)
Definition: eda_text.h:168
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
Definition: pcb_text.cpp:135
T NormalizeAngle360Min(T Angle)
Normalize angle to be > -360.0 and < 360.0 Angle equal to -360 or +360 are set to 0.
Definition: trigo.h:243
bool ResolveTextVar(wxString *token, int aDepth) const
BOARD_ITEM_CONTAINER * GetParent() const
wxString GetLayerName() const
Function GetLayerName returns the name of the PCB layer on which the item resides.
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
virtual wxString GetShownText(int aDepth=0) const
Return the string actually shown after processing of the base text.
Definition: eda_text.h:135
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
void SetTextY(int aY)
Definition: eda_text.h:252
KICAD_T Type() const
Function Type()
Definition: eda_item.h:181