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 <board.h>
31 #include <core/mirror.h>
32 #include <pcb_text.h>
33 #include <pcb_painter.h>
34 #include <trigo.h>
35 #include <kicad_string.h>
36 
38 
39 
41  BOARD_ITEM( parent, PCB_TEXT_T ),
42  EDA_TEXT()
43 {
44  SetMultilineAllowed( true );
45 }
46 
47 
49 {
50 }
51 
52 
53 wxString PCB_TEXT::GetShownText( int aDepth ) const
54 {
55  BOARD* board = dynamic_cast<BOARD*>( GetParent() );
56 
57  std::function<bool( wxString* )> pcbTextResolver =
58  [&]( wxString* token ) -> bool
59  {
60  if( token->IsSameAs( wxT( "LAYER" ) ) )
61  {
62  *token = GetLayerName();
63  return true;
64  }
65 
66  if( token->Contains( ':' ) )
67  {
68  wxString remainder;
69  wxString ref = token->BeforeFirst( ':', &remainder );
70  BOARD_ITEM* refItem = board->GetItem( KIID( ref ) );
71 
72  if( refItem && refItem->Type() == PCB_FOOTPRINT_T )
73  {
74  FOOTPRINT* refFP = static_cast<FOOTPRINT*>( refItem );
75 
76  if( refFP->ResolveTextVar( &remainder, aDepth + 1 ) )
77  {
78  *token = remainder;
79  return true;
80  }
81  }
82  }
83  return false;
84  };
85 
86  std::function<bool( wxString* )> boardTextResolver =
87  [&]( wxString* token ) -> bool
88  {
89  return board->ResolveTextVar( token, aDepth + 1 );
90  };
91 
92  bool processTextVars = false;
93  wxString text = EDA_TEXT::GetShownText( &processTextVars );
94 
95  if( board && processTextVars && aDepth < 10 )
96  text = ExpandTextVars( text, &pcbTextResolver, &boardTextResolver, board->GetProject() );
97 
98  return text;
99 }
100 
101 
102 void PCB_TEXT::SetTextAngle( double aAngle )
103 {
105 }
106 
107 
108 void PCB_TEXT::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
109 {
110  EDA_UNITS units = aFrame->GetUserUnits();
111 
112  // Don't use GetShownText() here; we want to show the user the variable references
113  aList.emplace_back( _( "PCB Text" ), UnescapeString( GetText() ) );
114 
115  if( IsLocked() )
116  aList.emplace_back( _( "Status" ), _( "locked" ) );
117 
118  aList.emplace_back( _( "Layer" ), GetLayerName() );
119 
120  aList.emplace_back( _( "Mirror" ), IsMirrored() ? _( "Yes" ) : _( "No" ) );
121 
122  aList.emplace_back( _( "Angle" ), wxString::Format( "%g", GetTextAngleDegrees() ) );
123 
124  aList.emplace_back( _( "Thickness" ), MessageTextFromValue( units, GetTextThickness() ) );
125  aList.emplace_back( _( "Width" ), MessageTextFromValue( units, GetTextWidth() ) );
126  aList.emplace_back( _( "Height" ), MessageTextFromValue( units, GetTextHeight() ) );
127 }
128 
129 
131 {
132  EDA_RECT rect = GetTextBox();
133 
134  if( GetTextAngle() )
135  rect = rect.GetBoundingBoxRotated( GetTextPos(), GetTextAngle() );
136 
137  return rect;
138 }
139 
140 
141 void PCB_TEXT::Rotate( const wxPoint& aRotCentre, double aAngle )
142 {
143  wxPoint pt = GetTextPos();
144  RotatePoint( &pt, aRotCentre, aAngle );
145  SetTextPos( pt );
146 
147  SetTextAngle( GetTextAngle() + aAngle );
148 }
149 
150 
151 void PCB_TEXT::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
152 {
153  double angle = GetTextAngle();
154  bool vertical = KiROUND( angle ) % 1800 == 900;
155 
156  if( KiROUND( angle ) != 0 )
157  {
158  Rotate( aCentre, -angle );
159 
160  if( vertical )
161  aFlipLeftRight = !aFlipLeftRight;
162  }
163 
164  // Flip the bounding box
165  EDA_RECT box = GetTextBox();
166  int left = box.GetLeft();
167  int right = box.GetRight();
168  int top = box.GetTop();
169  int bottom = box.GetBottom();
170  wxPoint pos = GetTextPos();
171 
172  if( aFlipLeftRight )
173  {
174  MIRROR( left, aCentre.x );
175  MIRROR( right, aCentre.x );
176  std::swap( left, right );
177 
178  MIRROR( pos.x, aCentre.x );
179  }
180  else
181  {
182  MIRROR( top, aCentre.y );
183  MIRROR( bottom, aCentre.y );
184  std::swap( top, bottom );
185 
186  MIRROR( pos.y, aCentre.y );
187  }
188 
189  // Now put the text back in its bounding box
190  switch( GetHorizJustify() )
191  {
192  case GR_TEXT_HJUSTIFY_LEFT: SetTextX( IsMirrored() ? left : right ); break;
193  case GR_TEXT_HJUSTIFY_CENTER: SetTextX( pos.x ); break;
194  case GR_TEXT_HJUSTIFY_RIGHT: SetTextX( IsMirrored() ? right : left ); break;
195  }
196 
197  if( !aFlipLeftRight )
198  {
199  switch( GetVertJustify() )
200  {
201  case GR_TEXT_VJUSTIFY_TOP: SetTextY( bottom ); break;
202  case GR_TEXT_VJUSTIFY_CENTER: SetTextY( pos.y ); break;
203  case GR_TEXT_VJUSTIFY_BOTTOM: SetTextY( top ); break;
204  }
205  }
206 
207  // And restore orientation
208  if( KiROUND( angle ) != 0 )
209  Rotate( aCentre, angle );
210 
211  SetLayer( FlipLayer( GetLayer(), GetBoard()->GetCopperLayerCount() ) );
212  SetMirrored( !IsMirrored() );
213 }
214 
215 
216 wxString PCB_TEXT::GetSelectMenuText( EDA_UNITS aUnits ) const
217 {
218  return wxString::Format( _( "PCB Text '%s' on %s"), ShortenedShownText(), GetLayerName() );
219 }
220 
221 
223 {
224  return text_xpm;
225 }
226 
227 
229 {
230  return new PCB_TEXT( *this );
231 }
232 
233 
235 {
236  assert( aImage->Type() == PCB_TEXT_T );
237 
238  std::swap( *((PCB_TEXT*) this), *((PCB_TEXT*) aImage) );
239 }
240 
241 
242 std::shared_ptr<SHAPE> PCB_TEXT::GetEffectiveShape( PCB_LAYER_ID aLayer ) const
243 {
244  return GetEffectiveTextShape();
245 }
246 
247 
248 static struct TEXTE_PCB_DESC
249 {
251  {
258  }
void SetMirrored(bool isMirrored)
Definition: eda_text.h:195
BOARD_ITEM * GetItem(const KIID &aID) const
Definition: board.cpp:792
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aAddUnitLabel, EDA_DATA_TYPE aType)
Convert a value to a string using double notation.
Definition: base_units.cpp:125
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:66
#define TYPE_HASH(x)
Definition: property.h:57
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:206
bool IsMirrored() const
Definition: eda_text.h:196
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:234
const EDA_RECT GetBoundingBoxRotated(wxPoint aRotCenter, double aAngle) const
Useful to calculate bounding box of rotated items, when rotation if not k*90 degrees.
Definition: eda_rect.cpp:511
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject)
Definition: common.cpp:58
void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Flip this object, i.e.
Definition: pcb_text.cpp:151
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:194
Implementation of conversion functions that require both schematic and board internal units.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:82
int GetTop() const
Definition: eda_rect.h:118
void SetTextAngle(double aAngle) override
Definition: pcb_text.cpp:102
bool ResolveTextVar(wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the component.
Definition: footprint.cpp:431
int GetLeft() const
Definition: eda_rect.h:117
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Definition: lset.cpp:521
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:223
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:253
PROJECT * GetProject() const
Definition: board.h:430
const BITMAP_OPAQUE text_xpm[1]
Definition: text.cpp:17
double GetTextAngle() const
Definition: eda_text.h:181
class PCB_TEXT, text on a layer
Definition: typeinfo.h:91
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
Definition: pcb_text.cpp:108
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:228
static struct TEXTE_PCB_DESC _TEXTE_PCB_DESC
int GetTextThickness() const
Definition: eda_text.h:167
The base class for create windows for drawing purpose.
PCB_TEXT(BOARD_ITEM *parent)
Definition: pcb_text.cpp:40
#define REGISTER_TYPE(x)
Definition: property_mgr.h:249
int GetBottom() const
Definition: eda_rect.h:119
virtual std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Definition: pcb_text.cpp:242
void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
Definition: mirror.h:40
int GetTextHeight() const
Definition: eda_text.h:251
void SetTextX(int aX)
Definition: eda_text.h:256
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:119
PCB specific render settings.
Definition: pcb_painter.h:64
wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: pcb_text.cpp:53
Definition: kiid.h:44
~PCB_TEXT()
Definition: pcb_text.cpp:48
PCB_LAYER_ID
A quick note on layer IDs:
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:205
BITMAP_DEF GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: pcb_text.cpp:222
virtual BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:46
int GetRight() const
Definition: eda_rect.h:116
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
wxString ShortenedShownText() const
Returns a shortened version (max 15 characters) of the shown text.
Definition: eda_text.cpp:202
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Return the text to display to be used in the selection clarification context menu when multiple items...
Definition: pcb_text.cpp:216
void SetMultilineAllowed(bool aAllow)
Definition: eda_text.h:202
class FOOTPRINT, a footprint
Definition: typeinfo.h:88
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
EDA_UNITS
Definition: eda_units.h:38
virtual bool IsLocked() const
Definition: board_item.h:249
double GetTextAngleDegrees() const
Definition: eda_text.h:183
int GetTextWidth() const
Definition: eda_text.h:248
std::shared_ptr< SHAPE_COMPOUND > GetEffectiveTextShape() const
Definition: eda_text.cpp:624
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
#define _(s)
Definition: 3d_actions.cpp:33
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:150
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
Handle the component boundary box.
Definition: eda_rect.h:42
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
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:149
void Rotate(const wxPoint &aRotCentre, double aAngle) override
Rotate this object.
Definition: pcb_text.cpp:141
const wxPoint & GetTextPos() const
Definition: eda_text.h:254
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:63
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: pcb_text.cpp:228
virtual void SetTextAngle(double aAngle)
Definition: eda_text.h:174
const EDA_RECT GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: pcb_text.cpp:130
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:254
bool ResolveTextVar(wxString *token, int aDepth) const
Definition: board.cpp:220
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:168
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
Definition: board_item.cpp:60
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:173
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:133
virtual wxString GetShownText(int aDepth=0) const
Return the string actually shown after processing of the base text.
Definition: eda_text.h:141
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
void SetTextY(int aY)
Definition: eda_text.h:257
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:162