KiCad PCB EDA Suite
class_dimension.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) 2012 Wayne Stambaugh <stambaughw@verizon.net>
7  * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
27 #include <fctsys.h>
28 #include <gr_basic.h>
29 #include <bitmaps.h>
30 #include <pcb_edit_frame.h>
31 #include <base_units.h>
32 #include <class_board.h>
33 #include <class_dimension.h>
34 #include <class_pcb_text.h>
35 #include <geometry/shape_circle.h>
36 #include <geometry/shape_rect.h>
37 #include <geometry/shape_segment.h>
40 
41 
43  BOARD_ITEM( aParent, aType ),
44  m_overrideTextEnabled( false ),
45  m_units( EDA_UNITS::INCHES ),
46  m_useMils( false ),
47  m_autoUnits( false ),
48  m_unitsFormat( DIM_UNITS_FORMAT::BARE_SUFFIX ),
49  m_precision( 4 ),
50  m_suppressZeroes( false ),
51  m_lineThickness( Millimeter2iu( 0.2 ) ),
52  m_arrowLength( Mils2iu( 50 ) ),
53  m_extensionOffset( 0 ),
54  m_textPosition( DIM_TEXT_POSITION::OUTSIDE ),
55  m_keepTextAligned( true ),
56  m_text( aParent ),
57  m_measuredValue( 0 )
58 {
60 }
61 
62 
64 {
65  BOARD_ITEM::SetParent( aParent );
66  m_text.SetParent( aParent );
67 }
68 
69 
70 void DIMENSION::SetPosition( const wxPoint& aPos )
71 {
72  m_text.SetTextPos( aPos );
73 }
74 
75 
77 {
78  return m_text.GetTextPos();
79 }
80 
81 
83 {
84  wxString text = m_overrideTextEnabled ? m_valueString : GetValueText();
85 
86  switch( m_unitsFormat )
87  {
88  case DIM_UNITS_FORMAT::NO_SUFFIX: // no units
89  break;
90 
91  case DIM_UNITS_FORMAT::BARE_SUFFIX: // normal
92  text += " ";
94  break;
95 
96  case DIM_UNITS_FORMAT::PAREN_SUFFIX: // parenthetical
97  text += " (";
99  text += ")";
100  break;
101  }
102 
103  text.Prepend( m_prefix );
104  text.Append( m_suffix );
105 
106  m_text.SetText( text );
107 }
108 
109 
110 template<typename ShapeType>
111 void DIMENSION::addShape( ShapeType* aShape )
112 {
113  m_shapes.emplace_back( std::make_shared<ShapeType>( *aShape ) );
114 }
115 
116 
117 wxString DIMENSION::GetValueText() const
118 {
119  int val = GetMeasuredValue();
120 
121  wxString text;
122  wxString format = wxT( "%." ) + wxString::Format( "%i", m_precision ) + wxT( "f" );
123 
124  text.Printf( format, To_User_Unit( m_units, val, m_useMils ) );
125 
126  if( m_suppressZeroes )
127  {
128  while( text.Last() == '0' )
129  {
130  text.RemoveLast();
131 
132  if( text.Last() == '.' )
133  {
134  text.RemoveLast();
135  break;
136  }
137  }
138 
139  }
140 
141  return text;
142 }
143 
144 
145 void DIMENSION::SetPrefix( const wxString& aPrefix )
146 {
147  m_prefix = aPrefix;
148 }
149 
150 
151 void DIMENSION::SetSuffix( const wxString& aSuffix )
152 {
153  m_suffix = aSuffix;
154 }
155 
156 
157 void DIMENSION::SetUnits( EDA_UNITS aUnits, bool aUseMils )
158 {
159  m_units = aUnits;
160  m_useMils = aUseMils;
161 }
162 
163 
165 {
166  if( m_autoUnits )
168  else if( m_units == EDA_UNITS::MILLIMETRES )
170  else if( m_useMils )
171  return DIM_UNITS_MODE::MILS;
172  else
173  return DIM_UNITS_MODE::INCHES;
174 }
175 
176 
178 {
179  m_autoUnits = false;
180  m_useMils = false;
181 
182  switch( aMode )
183  {
186  break;
187 
190  m_useMils = true;
191  break;
192 
195  break;
196 
198  m_autoUnits = true;
199  break;
200  }
201 }
202 
203 
204 void DIMENSION::SetText( const wxString& aNewText )
205 {
206  m_valueString = aNewText;
207  updateText();
208 }
209 
210 
211 const wxString DIMENSION::GetText() const
212 {
213  return m_text.GetText();
214 }
215 
216 
218 {
219  m_Layer = aLayer;
220  m_text.SetLayer( aLayer );
221 }
222 
223 
224 void DIMENSION::Move( const wxPoint& offset )
225 {
226  m_text.Offset( offset );
227 
228  m_start += offset;
229  m_end += offset;
230 
231  Update();
232 }
233 
234 
235 void DIMENSION::Rotate( const wxPoint& aRotCentre, double aAngle )
236 {
237  if( m_keepTextAligned )
238  m_keepTextAligned = false;
239 
240  double newAngle = m_text.GetTextAngle() + aAngle;
241 
242  if( newAngle >= 3600 )
243  newAngle -= 3600;
244 
245  m_text.SetTextAngle( newAngle );
246 
247  Update();
248 }
249 
250 
251 void DIMENSION::Flip( const wxPoint& aCentre, bool aFlipLeftRight )
252 {
253  Mirror( aCentre );
254 
255  // DIMENSION items are not usually on copper layers, so
256  // copper layers count is not taken in accoun in Flip transform
257  SetLayer( FlipLayer( GetLayer() ) );
258 }
259 
260 
261 void DIMENSION::Mirror( const wxPoint& axis_pos, bool aMirrorLeftRight )
262 {
263  int axis = aMirrorLeftRight ? axis_pos.x : axis_pos.y;
264  wxPoint newPos = m_text.GetTextPos();
265 
266 #define INVERT( pos ) ( ( pos ) = axis - ( ( pos ) - axis ) )
267 
268  if( aMirrorLeftRight )
269  INVERT( newPos.x );
270  else
271  INVERT( newPos.y );
272 
273  m_text.SetTextPos( newPos );
274 
275  // invert angle
277 
278  if( aMirrorLeftRight )
279  {
280  INVERT( m_start.x );
281  INVERT( m_end.x );
282  }
283  else
284  {
285  INVERT( m_start.y );
286  INVERT( m_end.y );
287  }
288 
289  Update();
290 }
291 
292 
293 void DIMENSION::SetStart( const wxPoint& aOrigin )
294 {
295  m_start = aOrigin;
296  Update();
297 }
298 
299 
300 void DIMENSION::SetEnd( const wxPoint& aEnd )
301 {
302  m_end = aEnd;
303  Update();
304 }
305 
306 
307 void DIMENSION::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
308 {
309  // for now, display only the text within the DIMENSION using class TEXTE_PCB.
310  m_text.GetMsgPanelInfo( aFrame, aList );
311 }
312 
313 
314 bool DIMENSION::HitTest( const wxPoint& aPosition, int aAccuracy ) const
315 {
316  if( m_text.TextHitTest( aPosition ) )
317  return true;
318 
319  int dist_max = aAccuracy + ( m_lineThickness / 2 );
320 
321  // Locate SEGMENTS
322 
323  for( const std::shared_ptr<SHAPE>& shape : GetShapes() )
324  {
325  if( shape->Collide( aPosition, dist_max ) )
326  return true;
327  }
328 
329  return false;
330 }
331 
332 
333 bool DIMENSION::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
334 {
335  EDA_RECT arect = aRect;
336  arect.Inflate( aAccuracy );
337 
338  EDA_RECT rect = GetBoundingBox();
339 
340  if( aAccuracy )
341  rect.Inflate( aAccuracy );
342 
343  if( aContained )
344  return arect.Contains( rect );
345 
346  return arect.Intersects( rect );
347 }
348 
349 
351 {
352  EDA_RECT bBox;
353  int xmin, xmax, ymin, ymax;
354 
355  bBox = m_text.GetTextBox();
356  xmin = bBox.GetX();
357  xmax = bBox.GetRight();
358  ymin = bBox.GetY();
359  ymax = bBox.GetBottom();
360 
361  for( const std::shared_ptr<SHAPE>& shape : GetShapes() )
362  {
363  BOX2I shapeBox = shape->BBox();
364  shapeBox.Inflate( m_lineThickness / 2 );
365 
366  xmin = std::min( xmin, shapeBox.GetOrigin().x );
367  xmax = std::max( xmax, shapeBox.GetEnd().x );
368  ymin = std::min( ymin, shapeBox.GetOrigin().y );
369  ymax = std::max( ymax, shapeBox.GetEnd().y );
370  }
371 
372  bBox.SetX( xmin );
373  bBox.SetY( ymin );
374  bBox.SetWidth( xmax - xmin + 1 );
375  bBox.SetHeight( ymax - ymin + 1 );
376 
377  bBox.Normalize();
378 
379  return bBox;
380 }
381 
382 
383 wxString DIMENSION::GetSelectMenuText( EDA_UNITS aUnits ) const
384 {
385  return wxString::Format( _( "Dimension \"%s\" on %s" ), GetText(), GetLayerName() );
386 }
387 
388 
389 
391 {
392  BOX2I dimBBox = BOX2I( VECTOR2I( GetBoundingBox().GetPosition() ),
393  VECTOR2I( GetBoundingBox().GetSize() ) );
394  dimBBox.Merge( m_text.ViewBBox() );
395 
396  return dimBBox;
397 }
398 
399 
401 {
402  VECTOR2I start( aStart ? aSeg.A : aSeg.B );
403  VECTOR2I endpoint( aStart ? aSeg.B : aSeg.A );
404 
405  if( aPoly.Contains( start ) )
406  return NULLOPT;
407 
408  for( SHAPE_POLY_SET::SEGMENT_ITERATOR seg = aPoly.IterateSegments(); seg; seg++ )
409  {
410  if( OPT_VECTOR2I intersection = ( *seg ).Intersect( aSeg ) )
411  {
412  if( ( *intersection - start ).SquaredEuclideanNorm() <
413  ( endpoint - start ).SquaredEuclideanNorm() )
414  endpoint = *intersection;
415  }
416  }
417  if( start == endpoint )
418  return NULLOPT;
419 
420  return OPT_VECTOR2I( endpoint );
421 }
422 
423 
424 static struct DIMENSION_DESC
425 {
427  {
431  //propMgr.AddProperty( new PROPERTY<DIMENSION, int>( "Height",
432  //&DIMENSION::SetHeight, &DIMENSION::GetHeight, PROPERTY_DISPLAY::DISTANCE ) );
433  }
435 
436 
438  DIMENSION( aParent, PCB_DIM_ALIGNED_T ),
439  m_height( 0 )
440 {
441  // To preserve look of old dimensions, initialize extension height based on default arrow length
442  m_extensionHeight = static_cast<int>( m_arrowLength * std::sin( DEG2RAD( s_arrowAngle ) ) );
443 }
444 
445 
447 {
448  return new ALIGNED_DIMENSION( *this );
449 }
450 
451 
453 {
454  assert( aImage->Type() == PCB_DIM_ALIGNED_T );
455 
456  m_shapes.clear();
457  static_cast<ALIGNED_DIMENSION*>( aImage )->m_shapes.clear();
458 
459  std::swap( *static_cast<ALIGNED_DIMENSION*>( this ),
460  *static_cast<ALIGNED_DIMENSION*>( aImage ) );
461 
462  Update();
463 }
464 
466 {
468 }
469 
470 
471 void ALIGNED_DIMENSION::SetHeight( int aHeight )
472 {
473  m_height = aHeight;
474  Update();
475 }
476 
477 
478 void ALIGNED_DIMENSION::UpdateHeight( const wxPoint& aCrossbarStart, const wxPoint& aCrossbarEnd )
479 {
480  VECTOR2D height( aCrossbarStart - GetStart() );
481  VECTOR2D crossBar( aCrossbarEnd - aCrossbarStart );
482 
483  if( height.Cross( crossBar ) > 0 )
484  m_height = -height.EuclideanNorm();
485  else
486  m_height = height.EuclideanNorm();
487 
488  Update();
489 }
490 
491 
493 {
494  m_shapes.clear();
495 
496  VECTOR2I dimension( m_end - m_start );
497 
498  m_measuredValue = KiROUND( dimension.EuclideanNorm() );
499 
500  VECTOR2I extension;
501 
502  if( m_height > 0 )
503  extension = VECTOR2I( -dimension.y, dimension.x );
504  else
505  extension = VECTOR2I( dimension.y, -dimension.x );
506 
507  // Add extension lines
508  int extensionHeight = std::abs( m_height ) - m_extensionOffset + m_extensionHeight;
509 
510  VECTOR2I extStart( m_start );
511  extStart += extension.Resize( m_extensionOffset );
512 
513  addShape( new SHAPE_SEGMENT( extStart, extStart + extension.Resize( extensionHeight ) ) );
514 
515  extStart = VECTOR2I( m_end );
516  extStart += extension.Resize( m_extensionOffset );
517 
518  addShape( new SHAPE_SEGMENT( extStart, extStart + extension.Resize( extensionHeight ) ) );
519 
520  // Add crossbar
521  VECTOR2I crossBarDistance = sign( m_height ) * extension.Resize( m_height );
522  m_crossBarStart = m_start + wxPoint( crossBarDistance );
523  m_crossBarEnd = m_end + wxPoint( crossBarDistance );
524 
525  // Update text after calculating crossbar position but before adding crossbar lines
526  updateText();
527 
528  // Now that we have the text updated, we can determine how to draw the crossbar.
529  // First we need to create an appropriate bounding polygon to collide with
532 
533  SHAPE_POLY_SET polyBox;
534  polyBox.NewOutline();
535  polyBox.Append( textBox.GetOrigin() );
536  polyBox.Append( textBox.GetOrigin().x, textBox.GetEnd().y );
537  polyBox.Append( textBox.GetEnd() );
538  polyBox.Append( textBox.GetEnd().x, textBox.GetOrigin().y );
539  polyBox.Rotate( -m_text.GetTextAngleRadians(), textBox.GetCenter() );
540 
541  // The ideal crossbar, if the text doesn't collide
542  SEG crossbar( m_crossBarStart, m_crossBarEnd );
543 
544  // Now we can draw 0, 1, or 2 crossbar lines depending on how the polygon collides
545  bool containsA = polyBox.Contains( crossbar.A );
546  bool containsB = polyBox.Contains( crossbar.B );
547 
548  OPT_VECTOR2I endpointA = segPolyIntersection( polyBox, crossbar );
549  OPT_VECTOR2I endpointB = segPolyIntersection( polyBox, crossbar, false );
550 
551  if( endpointA )
552  m_shapes.emplace_back( new SHAPE_SEGMENT( crossbar.A, *endpointA ) );
553 
554  if( endpointB )
555  m_shapes.emplace_back( new SHAPE_SEGMENT( *endpointB, crossbar.B ) );
556 
557  if( !containsA && !containsB && !endpointA && !endpointB )
558  m_shapes.emplace_back( new SHAPE_SEGMENT( crossbar ) );
559 
560  // Add arrows
561  VECTOR2I arrowEnd( m_arrowLength, 0 );
562 
563  double arrowRotPos = dimension.Angle() + DEG2RAD( s_arrowAngle );
564  double arrowRotNeg = dimension.Angle() - DEG2RAD( s_arrowAngle );
565 
566  m_shapes.emplace_back( new SHAPE_SEGMENT( m_crossBarStart,
567  m_crossBarStart + wxPoint( arrowEnd.Rotate( arrowRotPos ) ) ) );
568 
569  m_shapes.emplace_back( new SHAPE_SEGMENT( m_crossBarStart,
570  m_crossBarStart + wxPoint( arrowEnd.Rotate( arrowRotNeg ) ) ) );
571 
572  m_shapes.emplace_back( new SHAPE_SEGMENT( m_crossBarEnd,
573  m_crossBarEnd - wxPoint( arrowEnd.Rotate( arrowRotPos ) ) ) );
574 
575  m_shapes.emplace_back( new SHAPE_SEGMENT( m_crossBarEnd,
576  m_crossBarEnd - wxPoint( arrowEnd.Rotate( arrowRotNeg ) ) ) );
577 }
578 
579 
581 {
582  VECTOR2I crossbarCenter( ( m_crossBarEnd - m_crossBarStart ) / 2 );
583 
585  {
586  int textOffsetDistance = m_text.GetEffectiveTextPenWidth() + m_text.GetTextHeight();
587 
588  double rotation = std::copysign( DEG2RAD( 90 ), m_height );
589  VECTOR2I textOffset = crossbarCenter.Rotate( rotation ).Resize( textOffsetDistance );
590  textOffset += crossbarCenter;
591 
592  m_text.SetTextPos( m_crossBarStart + wxPoint( textOffset ) );
593  }
595  {
596  m_text.SetTextPos( m_crossBarStart + wxPoint( crossbarCenter ) );
597  }
598 
599  if( m_keepTextAligned )
600  {
601  double textAngle = 3600 - RAD2DECIDEG( crossbarCenter.Angle() );
602 
603  NORMALIZE_ANGLE_POS( textAngle );
604 
605  if( textAngle > 900 && textAngle < 2700 )
606  textAngle -= 1800;
607 
608  m_text.SetTextAngle( textAngle );
609  }
610 
612 }
613 
614 
616  DIMENSION( aParent, PCB_DIM_LEADER_T ),
617  m_textFrame( DIM_TEXT_FRAME::NONE )
618 {
620  m_overrideTextEnabled = true;
621  m_keepTextAligned = false;
622 }
623 
624 
626 {
627  return new LEADER( *this );
628 }
629 
630 
632 {
633  assert( aImage->Type() == PCB_DIM_LEADER_T );
634 
635  std::swap( *static_cast<LEADER*>( this ), *static_cast<LEADER*>( aImage ) );
636 }
637 
638 
640 {
641  return add_leader_xpm;
642 }
643 
644 
646 {
647  m_shapes.clear();
648 
649  VECTOR2I firstLine( m_end - m_start );
650  VECTOR2I start( m_start );
651  start += firstLine.Resize( m_extensionOffset );
652 
653  m_shapes.emplace_back( new SHAPE_SEGMENT( start, m_end ) );
654 
655  // Add arrows
656  VECTOR2I arrowEnd( m_arrowLength, 0 );
657 
658  double arrowRotPos = firstLine.Angle() + DEG2RAD( s_arrowAngle );
659  double arrowRotNeg = firstLine.Angle() - DEG2RAD( s_arrowAngle );
660 
661  m_shapes.emplace_back( new SHAPE_SEGMENT( start,
662  start + wxPoint( arrowEnd.Rotate( arrowRotPos ) ) ) );
663  m_shapes.emplace_back( new SHAPE_SEGMENT( start,
664  start + wxPoint( arrowEnd.Rotate( arrowRotNeg ) ) ) );
665 
666  updateText();
667 
668  // Now that we have the text updated, we can determine how to draw the second line
669  // First we need to create an appropriate bounding polygon to collide with
672 
673  SHAPE_POLY_SET polyBox;
674  polyBox.NewOutline();
675  polyBox.Append( textBox.GetOrigin() );
676  polyBox.Append( textBox.GetOrigin().x, textBox.GetEnd().y );
677  polyBox.Append( textBox.GetEnd() );
678  polyBox.Append( textBox.GetEnd().x, textBox.GetOrigin().y );
679  polyBox.Rotate( -m_text.GetTextAngleRadians(), textBox.GetCenter() );
680 
681  SEG textSeg( m_end, m_text.GetPosition() );
682  OPT_VECTOR2I endpoint = segPolyIntersection( polyBox, textSeg );
683 
684  if( !GetText().IsEmpty() )
685  {
686  switch( m_textFrame )
687  {
689  {
690  for( SHAPE_POLY_SET::SEGMENT_ITERATOR seg = polyBox.IterateSegments(); seg; seg++ )
691  m_shapes.emplace_back( new SHAPE_SEGMENT( *seg ) );
692 
693  break;
694  }
695 
697  {
698  double penWidth = m_text.GetEffectiveTextPenWidth() / 2.0;
699  double radius = ( textBox.GetWidth() / 2.0 ) - penWidth;
700  m_shapes.emplace_back( new SHAPE_CIRCLE( textBox.GetCenter(), radius ) );
701 
702  // Calculated bbox endpoint won't be right
703  if( endpoint )
704  {
705  VECTOR2I totalLength( textBox.GetCenter() - m_end );
706  VECTOR2I circleEndpoint( *endpoint - m_end );
707  circleEndpoint = circleEndpoint.Resize( totalLength.EuclideanNorm() - radius );
708  endpoint = OPT_VECTOR2I( VECTOR2I( m_end ) + circleEndpoint );
709  }
710 
711  break;
712  }
713 
714  default:
715  break;
716  }
717  }
718 
719  if( endpoint )
720  m_shapes.emplace_back( new SHAPE_SEGMENT( m_end, *endpoint ) );
721 }
722 
723 
725  DIMENSION( aParent, PCB_DIM_CENTER_T )
726 {
728  m_overrideTextEnabled = true;
729 }
730 
731 
733 {
734  return new CENTER_DIMENSION( *this );
735 }
736 
737 
739 {
740  assert( aImage->Type() == PCB_DIM_CENTER_T );
741 
742  std::swap( *static_cast<CENTER_DIMENSION*>( this ), *static_cast<CENTER_DIMENSION*>( aImage ) );
743 }
744 
745 
747 {
749 }
750 
751 
753 {
754  int halfWidth = VECTOR2I( m_end - m_start ).x + ( m_lineThickness / 2.0 );
755 
756  EDA_RECT bBox;
757 
758  bBox.SetX( m_start.x - halfWidth );
759  bBox.SetY( m_start.y - halfWidth );
760  bBox.SetWidth( halfWidth * 2 );
761  bBox.SetHeight( halfWidth * 2 );
762 
763  bBox.Normalize();
764 
765  return bBox;
766 }
767 
768 
770 {
771  return BOX2I( VECTOR2I( GetBoundingBox().GetPosition() ),
772  VECTOR2I( GetBoundingBox().GetSize() ) );
773 }
774 
775 
777 {
778  m_shapes.clear();
779 
780  VECTOR2I center( m_start );
781  VECTOR2I arm( m_end - m_start );
782 
783  m_shapes.emplace_back( new SHAPE_SEGMENT( center - arm, center + arm ) );
784 
785  arm = arm.Rotate( DEG2RAD( 90 ) );
786 
787  m_shapes.emplace_back( new SHAPE_SEGMENT( center - arm, center + arm ) );
788 }
double To_User_Unit(EDA_UNITS aUnit, double aValue, bool aUseMils)
Function To_User_Unit convert aValue in internal units to the appropriate user units defined by aUnit...
Definition: base_units.cpp:92
CENTER_DIMENSION(BOARD_ITEM *aParent)
EDA_UNITS
Definition: common.h:198
int m_extensionHeight
Length of extension lines past the crossbar.
extended_type Cross(const VECTOR2< T > &aVector) const
Function Cross() computes cross product of self with aVector.
Definition: vector2d.h:484
void SetTextAngle(double aAngle) override
int sign(T val)
Definition: util.h:101
void Offset(const wxPoint &aOffset)
Definition: eda_text.h:253
BOX2< VECTOR2I > BOX2I
Definition: box2.h:522
DIM_UNITS_MODE
Used for storing the units selection in the file because EDA_UNITS alone doesn't cut it.
Text appears outside the dimension line (default)
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:61
#define TYPE_HASH(x)
Macro to generate unique identifier for a type
Definition: property.h:53
class ALIGNED_DIMENSION, a linear dimension (graphic item)
Definition: typeinfo.h:101
class LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:102
void SetPosition(const wxPoint &aPos) override
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
PNG memory record (file in memory).
Definition: bitmap_def.h:29
TEXTE_PCB class definition.
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
const BITMAP_OPAQUE add_leader_xpm[1]
Definition: add_leader.cpp:51
EDA_UNITS m_units
0 = inches, 1 = mm
const Vec GetEnd() const
Definition: box2.h:195
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
void SetSuffix(const wxString &aSuffix)
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,...
void SetPrefix(const wxString &aPrefix)
int GetX() const
Definition: eda_rect.h:111
virtual void SetStart(const wxPoint &aPoint)
class CENTER_DIMENSION, a center point marking (graphic item)
Definition: typeinfo.h:103
void updateGeometry() override
Updates the cached geometry of the dimension after changing any of its properties.
static constexpr float s_arrowAngle
DIM_UNITS_FORMAT
How to display the units in a dimension's text.
void updateText() override
Updates the text field value from the current geometry (called by updateGeometry normally)
PCB_LAYER_ID FlipLayer(PCB_LAYER_ID aLayerId, int aCopperLayersCount)
Function FlippedLayerNumber.
Definition: lset.cpp:490
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 Update()
Updates the dimension's cached text and geometry.
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:247
const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers.
int GetWidth() const
Definition: eda_rect.h:119
double GetTextAngle() const
Definition: eda_text.h:174
double RAD2DECIDEG(double rad)
Definition: trigo.h:224
virtual void SwapData(BOARD_ITEM *aImage) override
Swap data between aItem and aImage.
wxString m_prefix
String prepended to the value.
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
ALIGNED_DIMENSION(BOARD_ITEM *aParent)
int m_measuredValue
value of PCB dimensions
void Rotate(double aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Function Rotate rotates all vertices by a given angle.
bool m_suppressZeroes
Suppress trailing zeroes.
bool Contains(const VECTOR2I &aP, int aSubpolyIndex=-1, int aAccuracy=0, bool aUseBBoxCaches=false) const
Returns true if a given subpolygon contains the point aP.
void NORMALIZE_ANGLE_POS(T &Angle)
Definition: trigo.h:276
DIM_UNITS_MODE GetUnitsMode() const
void Mirror(const wxPoint &axis_pos, bool aMirrorLeftRight=false)
Mirror the Dimension , relative to a given horizontal axis the text is not mirrored.
void SetUnits(EDA_UNITS aUnits, bool aUseMils)
The base class for create windows for drawing purpose.
const BITMAP_OPAQUE add_aligned_dimension_xpm[1]
LEADER(BOARD_ITEM *aParent)
wxString GetAbbreviatedUnitsLabel(EDA_UNITS aUnit, bool aUseMils, EDA_DATA_TYPE aType)
Get the units string for a given units type.
Definition: base_units.cpp:495
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
const std::vector< std::shared_ptr< SHAPE > > & GetShapes() const
bool m_autoUnits
If true, follow the currently selected UI units.
#define REGISTER_TYPE(x)
Helper macro to map type hashes to names
Definition: property_mgr.h:244
bool Contains(const wxPoint &aPoint) const
Function Contains.
void SetLayer(PCB_LAYER_ID aLayer) override
Function SetLayer sets the layer this item is on.
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
virtual void SetParent(EDA_ITEM *aParent)
Definition: base_struct.h:196
int GetEffectiveTextPenWidth(int aDefaultWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultWidth.
Definition: eda_text.cpp:157
int m_height
Perpendicular distance from features to crossbar.
int GetBottom() const
Definition: eda_rect.h:124
int GetTextHeight() const
Definition: eda_text.h:245
virtual void SwapData(BOARD_ITEM *aImage) override
Swap data between aItem and aImage.
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...
PCB_LAYER_ID m_Layer
void SetUnitsMode(DIM_UNITS_MODE aMode)
DIMENSION class definition.
const wxPoint GetEnd() const
Definition: eda_rect.h:116
void SetText(const wxString &aNewText)
Sets the override text - has no effect if m_overrideValue == false.
void Flip(const wxPoint &aCentre, bool aFlipLeftRight) override
Function Flip Flip this object, i.e.
PCB_LAYER_ID
A quick note on layer IDs:
bool m_keepTextAligned
Calculate text orientation to match dimension.
void SetHeight(int aHeight)
Sets the distance from the feature points to the crossbar line.
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
virtual void updateText()
Updates the text field value from the current geometry (called by updateGeometry normally)
const auto NULLOPT
Definition: optional.h:9
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:121
int m_extensionOffset
Distance from feature points to extension line start.
OPT< VECTOR2I > OPT_VECTOR2I
Definition: seg.h:37
void SetHeight(int val)
Definition: eda_rect.h:186
SHAPE_POLY_SET.
void updateGeometry() override
Updates the cached geometry of the dimension after changing any of its properties.
const wxPoint GetOrigin() const
Definition: eda_rect.h:114
virtual wxPoint GetPosition() const override
int GetRight() const
Definition: eda_rect.h:121
void SetParent(EDA_ITEM *aParent) override
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declares an inheritance relationship between types.
Text appears in line with the dimension line.
static struct DIMENSION_DESC _DIMENSION_DESC
BITMAP_DEF GetMenuImage() const override
Function GetMenuImage returns a pointer to an image to be used in menus.
wxPoint GetPosition() const override
#define OUTSIDE
void SetX(int val)
Definition: eda_rect.h:168
int m_precision
Number of digits to display after decimal.
std::vector< std::shared_ptr< SHAPE > > m_shapes
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Function Merge modifies the position and size of the rectangle in order to contain aRect.
Definition: box2.h:386
TEXTE_PCB m_text
The actual text object.
double Angle() const
Function Angle computes the angle of the vector.
Definition: vector2d.h:313
void SetWidth(int val)
Definition: eda_rect.h:180
int NewOutline()
Creates a new empty polygon in the set and returns its index
int m_lineThickness
Thickness used for all graphics in the dimension.
void UpdateHeight(const wxPoint &aCrossbarStart, const wxPoint &aCrossbarEnd)
Updates stored height basing on points coordinates.
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
bool HitTest(const wxPoint &aPosition, int aAccuracy) const override
Function HitTest tests if aPosition is contained within or on the bounding box of an item.
void SetY(int val)
Definition: eda_rect.h:174
DIM_TEXT_POSITION m_textPosition
How to position the text.
Definition: seg.h:39
double GetTextAngleRadians() const
Definition: eda_text.h:177
void Normalize()
Function Normalize ensures that the height ant width are positive.
DIM_TEXT_POSITION
Where to place the text on a dimension.
VECTOR2< T > Resize(T aNewLength) const
Function Resize returns a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:392
#define INVERT(pos)
bool m_useMils
If inches, use mils.
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:302
VECTOR2< T > Rotate(double aAngle) const
Function Rotate rotates the vector by a given angle.
Definition: vector2d.h:377
virtual const wxPoint & GetStart() const
The dimension's origin is the first feature point for the dimension.
int GetTextWidth() const
Definition: eda_text.h:242
DIM_TEXT_FRAME m_textFrame
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
double DEG2RAD(double deg)
Definition: trigo.h:219
#define _(s)
Definition: 3d_actions.cpp:33
void Move(const wxPoint &offset) override
Function Move move this object.
wxPoint m_end
Internal cache of drawn shapes.
const BITMAP_OPAQUE add_center_dimension_xpm[1]
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
VECTOR2I A
Definition: seg.h:47
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
virtual bool TextHitTest(const wxPoint &aPoint, int aAccuracy=0) const
Test if aPoint is within the bounds of this object.
Definition: eda_text.cpp:375
virtual void SwapData(BOARD_ITEM *aImage) override
Swap data between aItem and aImage.
DIM_UNITS_FORMAT m_unitsFormat
How to render the units suffix.
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
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
int GetY() const
Definition: eda_rect.h:112
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:159
const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers.
void addShape(ShapeType *aShape)
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
const wxPoint & GetTextPos() const
Definition: eda_text.h:248
Provides class metadata.
Definition: property_mgr.h:58
DIM_TEXT_FRAME
Frame to show around dimension text.
wxString GetValueText() const
T EuclideanNorm() const
Destructor.
Definition: vector2d.h:299
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...
bool m_overrideTextEnabled
Manually specify the displayed measurement value.
wxString m_valueString
Displayed value when m_overrideValue = true.
const wxString GetText() const
Retrieves the value text or override text, not including prefix or suffix.
EDA_ITEM * Clone() const override
Function Clone creates a duplicate of this item with linked list members set to NULL.
wxPoint m_start
static OPT_VECTOR2I segPolyIntersection(SHAPE_POLY_SET &aPoly, SEG &aSeg, bool aStart=true)
Finds the intersection between a given segment and polygon outline.
wxString m_suffix
String appended to the value.
void updateGeometry() override
Updates the cached geometry of the dimension after changing any of its properties.
const Vec & GetOrigin() const
Definition: box2.h:193
const wxPoint GetCenter() const
Definition: eda_rect.h:117
virtual const BOX2I ViewBBox() const override
Function ViewBBox() returns the bounding box of the item covering all its layers.
DIMENSION(BOARD_ITEM *aParent, KICAD_T aType=PCB_DIMENSION_T)
wxPoint m_crossBarEnd
Crossbar end control point.
wxString GetLayerName() const
Function GetLayerName returns the name of the PCB layer on which the item resides.
static constexpr int Millimeter2iu(double mm)
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
wxPoint m_crossBarStart
Crossbar start control point.
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:127
void Rotate(const wxPoint &aRotCentre, double aAngle) override
Function Rotate Rotate this object.
Abstract dimension API.
virtual void SetEnd(const wxPoint &aPoint)
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
int m_arrowLength
Length of arrow shapes.
SEGMENT_ITERATOR IterateSegments(int aFirst, int aLast, bool aIterateHoles=false)
Returns an iterator object, for iterating between aFirst and aLast outline, with or without holes (de...
KICAD_T Type() const
Function Type()
Definition: base_struct.h:193
int GetMeasuredValue() const
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
VECTOR2I B
Definition: seg.h:48