KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_textbox.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) 2022-2023 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <advanced_config.h>
25#include <pcb_edit_frame.h>
26#include <base_units.h>
27#include <bitmaps.h>
28#include <board.h>
30#include <footprint.h>
31#include <pcb_textbox.h>
32#include <pcb_painter.h>
33#include <trigo.h>
34#include <string_utils.h>
36#include <callback_gal.h>
38#include <macros.h>
39#include <core/ignore.h>
40
41
43 PCB_SHAPE( aParent, aType, SHAPE_T::RECTANGLE ),
45 m_borderEnabled( true )
46{
49 SetMultilineAllowed( true );
50
51 int defaultMargin = GetLegacyTextMargin();
52 m_marginLeft = defaultMargin;
53 m_marginTop = defaultMargin;
54 m_marginRight = defaultMargin;
55 m_marginBottom = defaultMargin;
56}
57
58
60{
61}
62
63
65{
67
68 SetTextSize( settings.GetTextSize( GetLayer() ) );
70 SetItalic( settings.GetTextItalic( GetLayer() ) );
71 SetKeepUpright( settings.GetTextUpright( GetLayer() ) );
73}
74
75
77{
78 return KiROUND( GetStroke().GetWidth() / 2.0 ) + KiROUND( GetTextSize().y * 0.75 );
79}
80
81
83{
84 EDA_ANGLE rotation = GetDrawRotation();
85
86 if( rotation == ANGLE_90 )
87 return VECTOR2I( GetStartX(), GetEndY() );
88 else if( rotation == ANGLE_180 )
89 return GetEnd();
90 else if( rotation == ANGLE_270 )
91 return VECTOR2I( GetEndX(), GetStartY() );
92 else
93 return GetStart();
94}
95
96
98{
99 EDA_ANGLE rotation = GetDrawRotation();
100
101 if( rotation == ANGLE_90 )
102 return VECTOR2I( GetEndX(), GetStartY() );
103 else if( rotation == ANGLE_180 )
104 return GetStart();
105 else if( rotation == ANGLE_270 )
106 return VECTOR2I( GetStartX(), GetEndY() );
107 else
108 return GetEnd();
109}
110
111
112void PCB_TEXTBOX::SetTop( int aVal )
113{
114 EDA_ANGLE rotation = GetDrawRotation();
115
116 if( rotation == ANGLE_90 || rotation == ANGLE_180 )
117 SetEndY( aVal );
118 else
119 SetStartY( aVal );
120}
121
122
124{
125 EDA_ANGLE rotation = GetDrawRotation();
126
127 if( rotation == ANGLE_90 || rotation == ANGLE_180 )
128 SetStartY( aVal );
129 else
130 SetEndY( aVal );
131}
132
133
134void PCB_TEXTBOX::SetLeft( int aVal )
135{
136 EDA_ANGLE rotation = GetDrawRotation();
137
138 if( rotation == ANGLE_180 || rotation == ANGLE_270 )
139 SetEndX( aVal );
140 else
141 SetStartX( aVal );
142}
143
144
145void PCB_TEXTBOX::SetRight( int aVal )
146{
147 EDA_ANGLE rotation = GetDrawRotation();
148
149 if( rotation == ANGLE_180 || rotation == ANGLE_270 )
150 SetStartX( aVal );
151 else
152 SetEndX( aVal );
153}
154
155
157{
158 EDA_ANGLE delta = aAngle.Normalized() - GetTextAngle();
160}
161
162
163std::vector<VECTOR2I> PCB_TEXTBOX::GetAnchorAndOppositeCorner() const
164{
165 std::vector<VECTOR2I> pts;
166 EDA_ANGLE textAngle( GetDrawRotation() );
167
168 textAngle.Normalize();
169
170 if( textAngle.IsCardinal() )
171 {
173 bbox.Normalize();
174
175 if( textAngle == ANGLE_0 )
176 {
177 pts.emplace_back( VECTOR2I( bbox.GetLeft(), bbox.GetTop() ) );
178 pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetTop() ) );
179 }
180 else if( textAngle == ANGLE_90 )
181 {
182 pts.emplace_back( VECTOR2I( bbox.GetLeft(), bbox.GetBottom() ) );
183 pts.emplace_back( VECTOR2I( bbox.GetLeft(), bbox.GetTop() ) );
184 }
185 else if( textAngle == ANGLE_180 )
186 {
187 pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetBottom() ) );
188 pts.emplace_back( VECTOR2I( bbox.GetLeft(), bbox.GetBottom() ) );
189 }
190 else if( textAngle == ANGLE_270 )
191 {
192 pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetTop() ) );
193 pts.emplace_back( VECTOR2I( bbox.GetRight(), bbox.GetBottom() ) );
194 }
195 }
196 else
197 {
198 std::vector<VECTOR2I> corners = GetCorners();
199
200 VECTOR2I minX = corners[0];
201 VECTOR2I maxX = corners[0];
202 VECTOR2I minY = corners[0];
203 VECTOR2I maxY = corners[0];
204
205 for( const VECTOR2I& corner : corners )
206 {
207 if( corner.x < minX.x )
208 minX = corner;
209
210 if( corner.x > maxX.x )
211 maxX = corner;
212
213 if( corner.y < minY.y )
214 minY = corner;
215
216 if( corner.y > maxY.y )
217 maxY = corner;
218 }
219
220 if( textAngle < ANGLE_90 )
221 {
222 pts.emplace_back( minX );
223 pts.emplace_back( minY );
224 }
225 else if( textAngle < ANGLE_180 )
226 {
227 pts.emplace_back( maxY );
228 pts.emplace_back( minX );
229 }
230 else if( textAngle < ANGLE_270 )
231 {
232 pts.emplace_back( maxX );
233 pts.emplace_back( maxY );
234 }
235 else
236 {
237 pts.emplace_back( minY );
238 pts.emplace_back( maxX );
239 }
240 }
241
242 return pts;
243}
244
245
247{
248 return GetDrawPos( false );
249}
250
251
252VECTOR2I PCB_TEXTBOX::GetDrawPos( bool aIsFlipped ) const
253{
254 std::vector<VECTOR2I> corners = GetAnchorAndOppositeCorner();
255 GR_TEXT_H_ALIGN_T effectiveAlignment = GetHorizJustify();
256 VECTOR2I textAnchor;
257 VECTOR2I offset;
258
259 if( IsMirrored() != aIsFlipped )
260 {
261 switch( GetHorizJustify() )
262 {
263 case GR_TEXT_H_ALIGN_LEFT: effectiveAlignment = GR_TEXT_H_ALIGN_RIGHT; break;
264 case GR_TEXT_H_ALIGN_CENTER: effectiveAlignment = GR_TEXT_H_ALIGN_CENTER; break;
265 case GR_TEXT_H_ALIGN_RIGHT: effectiveAlignment = GR_TEXT_H_ALIGN_LEFT; break;
266 case GR_TEXT_H_ALIGN_INDETERMINATE: wxFAIL_MSG( wxT( "Legal only in dialogs" ) ); break;
267 }
268 }
269
270 switch( effectiveAlignment )
271 {
273 textAnchor = corners[0];
274 offset = VECTOR2I( GetMarginLeft(), GetMarginTop() );
275 break;
277 textAnchor = ( corners[0] + corners[1] ) / 2;
278 offset = VECTOR2I( 0, GetMarginTop() );
279 break;
281 textAnchor = corners[1];
282 offset = VECTOR2I( -GetMarginRight(), GetMarginTop() );
283 break;
285 wxFAIL_MSG( wxT( "Indeterminate state legal only in dialogs." ) );
286 break;
287 }
288
289 RotatePoint( offset, GetDrawRotation() );
290 return textAnchor + offset;
291}
292
293
294double PCB_TEXTBOX::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
295{
296 constexpr double HIDE = std::numeric_limits<double>::max();
297
298 KIGFX::PCB_PAINTER* painter = static_cast<KIGFX::PCB_PAINTER*>( aView->GetPainter() );
299 KIGFX::PCB_RENDER_SETTINGS* renderSettings = painter->GetSettings();
300
301 if( aLayer == LAYER_LOCKED_ITEM_SHADOW )
302 {
303 // Hide shadow if the main layer is not shown
304 if( !aView->IsLayerVisible( m_layer ) )
305 return HIDE;
306
307 // Hide shadow on dimmed tracks
308 if( renderSettings->GetHighContrast() )
309 {
310 if( m_layer != renderSettings->GetPrimaryHighContrastLayer() )
311 return HIDE;
312 }
313 }
314
315 return 0.0;
316}
317
318
319void PCB_TEXTBOX::ViewGetLayers( int aLayers[], int& aCount ) const
320{
321 aLayers[0] = GetLayer();
322 aCount = 1;
323
324 if( IsLocked() )
325 aLayers[ aCount++ ] = LAYER_LOCKED_ITEM_SHADOW;
326}
327
328
329wxString PCB_TEXTBOX::GetShownText( bool aAllowExtraText, int aDepth ) const
330{
331 const FOOTPRINT* parentFootprint = GetParentFootprint();
332 const BOARD* board = GetBoard();
333
334 std::function<bool( wxString* )> resolver = [&]( wxString* token ) -> bool
335 {
336 if( parentFootprint && parentFootprint->ResolveTextVar( token, aDepth + 1 ) )
337 return true;
338
339 if( token->IsSameAs( wxT( "LAYER" ) ) )
340 {
341 *token = GetLayerName();
342 return true;
343 }
344
345 if( board->ResolveTextVar( token, aDepth + 1 ) )
346 return true;
347
348 return false;
349 };
350
351 wxString text = EDA_TEXT::GetShownText( aAllowExtraText, aDepth );
352
353 if( HasTextVars() )
354 {
355 if( aDepth < ADVANCED_CFG::GetCfg().m_ResolveTextRecursionDepth )
357 }
358
359 KIFONT::FONT* font = getDrawFont();
360 std::vector<VECTOR2I> corners = GetAnchorAndOppositeCorner();
361 int colWidth = ( corners[1] - corners[0] ).EuclideanNorm();
362
363 if( GetTextAngle().IsHorizontal() )
364 colWidth -= ( GetMarginLeft() + GetMarginRight() );
365 else
366 colWidth -= ( GetMarginTop() + GetMarginBottom() );
367
368 font->LinebreakText( text, colWidth, GetTextSize(), GetTextThickness(), IsBold(), IsItalic() );
369
370 return text;
371}
372
373
374bool PCB_TEXTBOX::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
375{
376 return BOARD_ITEM::Matches( UnescapeString( GetText() ), aSearchData );
377}
378
379
380void PCB_TEXTBOX::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
381{
382 // Don't use GetShownText() here; we want to show the user the variable references
383 aList.emplace_back( _( "Text Box" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) );
384
385 if( aFrame->GetName() == PCB_EDIT_FRAME_NAME && IsLocked() )
386 aList.emplace_back( _( "Status" ), _( "Locked" ) );
387
388 aList.emplace_back( _( "Layer" ), GetLayerName() );
389 aList.emplace_back( _( "Mirror" ), IsMirrored() ? _( "Yes" ) : _( "No" ) );
390 aList.emplace_back( _( "Angle" ), wxString::Format( "%g", GetTextAngle().AsDegrees() ) );
391
392 aList.emplace_back( _( "Font" ), GetFont() ? GetFont()->GetName() : _( "Default" ) );
393 aList.emplace_back( _( "Text Thickness" ), aFrame->MessageTextFromValue( GetTextThickness() ) );
394 aList.emplace_back( _( "Text Width" ), aFrame->MessageTextFromValue( GetTextWidth() ) );
395 aList.emplace_back( _( "Text Height" ), aFrame->MessageTextFromValue( GetTextHeight() ) );
396
397 aList.emplace_back( _( "Box Width" ),
398 aFrame->MessageTextFromValue( std::abs( GetEnd().x - GetStart().x ) ) );
399
400 aList.emplace_back( _( "Box Height" ),
401 aFrame->MessageTextFromValue( std::abs( GetEnd().y - GetStart().y ) ));
402
403 m_stroke.GetMsgPanelInfo( aFrame, aList );
404}
405
406
407void PCB_TEXTBOX::Move( const VECTOR2I& aMoveVector )
408{
409 PCB_SHAPE::Move( aMoveVector );
410 EDA_TEXT::Offset( aMoveVector );
411}
412
413
414void PCB_TEXTBOX::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
415{
416 PCB_SHAPE::Rotate( aRotCentre, aAngle );
417 EDA_TEXT::SetTextAngle( ( GetTextAngle() + aAngle ).Normalized() );
418
419 if( GetTextAngle().IsCardinal() && GetShape() != SHAPE_T::RECTANGLE )
420 {
421 std::vector<VECTOR2I> corners = GetCorners();
422 VECTOR2I diag = corners[2] - corners[0];
423 EDA_ANGLE angle = GetTextAngle();
424
425 SetShape( SHAPE_T::RECTANGLE );
426 SetStart( corners[0] );
427
428 angle.Normalize();
429
430 if( angle == ANGLE_90 )
431 SetEnd( VECTOR2I( corners[0].x + abs( diag.x ), corners[0].y - abs( diag.y ) ) );
432 else if( angle == ANGLE_180 )
433 SetEnd( VECTOR2I( corners[0].x - abs( diag.x ), corners[0].y - abs( diag.y ) ) );
434 else if( angle == ANGLE_270 )
435 SetEnd( VECTOR2I( corners[0].x - abs( diag.x ), corners[0].y + abs( diag.y ) ) );
436 else
437 SetEnd( VECTOR2I( corners[0].x + abs( diag.x ), corners[0].y + abs( diag.y ) ) );
438 }
439}
440
441
442void PCB_TEXTBOX::Mirror( const VECTOR2I& aCentre, bool aMirrorAroundXAxis )
443{
444 // the position and angle are mirrored, but not the text (or its justification)
445 PCB_SHAPE::Mirror( aCentre, aMirrorAroundXAxis );
446
447 if( aMirrorAroundXAxis )
449 else
451}
452
453
454void PCB_TEXTBOX::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
455{
456 PCB_SHAPE::Flip( aCentre, aFlipLeftRight );
457
458 if( aFlipLeftRight )
460 else
462
463 if( IsSideSpecific() )
465}
466
467
468bool PCB_TEXTBOX::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
469{
470 BOX2I rect = GetBoundingBox();
471
472 rect.Inflate( aAccuracy );
473
474 return rect.Contains( aPosition );
475}
476
477
478bool PCB_TEXTBOX::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
479{
480 BOX2I rect = aRect;
481
482 rect.Inflate( aAccuracy );
483
484 if( aContained )
485 return rect.Contains( GetBoundingBox() );
486
487 return rect.Intersects( GetBoundingBox() );
488}
489
490
491wxString PCB_TEXTBOX::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
492{
493 return wxString::Format( _( "PCB Text Box '%s' on %s" ),
494 aFull ? GetShownText( false ) : KIUI::EllipsizeMenuText( GetText() ),
495 GetLayerName() );
496}
497
498
500{
501 return BITMAPS::add_textbox;
502}
503
504
506{
507 return new PCB_TEXTBOX( *this );
508}
509
510
512{
513 wxASSERT( aImage->Type() == PCB_TEXTBOX_T );
514
515 std::swap( *((PCB_TEXTBOX*) this), *((PCB_TEXTBOX*) aImage) );
516}
517
518
519std::shared_ptr<SHAPE> PCB_TEXTBOX::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash ) const
520{
521 std::shared_ptr<SHAPE_COMPOUND> shape = GetEffectiveTextShape();
522
523 if( PCB_SHAPE::GetStroke().GetWidth() >= 0 )
524 shape->AddShape( PCB_SHAPE::GetEffectiveShape( aLayer, aFlash ) );
525
526 return shape;
527}
528
529
530void PCB_TEXTBOX::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance, int aMaxError,
531 ERROR_LOC aErrorLoc ) const
532{
534 KIFONT::FONT* font = getDrawFont();
535 int penWidth = GetEffectiveTextPenWidth();
536
537 // Note: this function is mainly used in 3D viewer.
538 // the polygonal shape of a text can have many basic shapes,
539 // so combining these shapes can be very useful to create a final shape
540 // swith a lot less vertices to speedup calculations using this final shape
541 // Simplify shapes is not usually always efficient, but in this case it is.
542 SHAPE_POLY_SET buffer;
543
544 CALLBACK_GAL callback_gal( empty_opts,
545 // Stroke callback
546 [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
547 {
548 TransformOvalToPolygon( buffer, aPt1, aPt2, penWidth, aMaxError, aErrorLoc );
549 },
550 // Triangulation callback
551 [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 )
552 {
553 buffer.NewOutline();
554
555 for( const VECTOR2I& point : { aPt1, aPt2, aPt3 } )
556 buffer.Append( point.x, point.y );
557 } );
558
559 font->Draw( &callback_gal, GetShownText( true ), GetDrawPos(), GetAttributes(), GetFontMetrics() );
560
561 if( aClearance > 0 || aErrorLoc == ERROR_OUTSIDE )
562 {
563 if( aErrorLoc == ERROR_OUTSIDE )
564 aClearance += aMaxError;
565
566 buffer.Inflate( aClearance, CORNER_STRATEGY::ROUND_ALL_CORNERS, aMaxError, true );
567 }
568 else
569 {
571 }
572
573 aBuffer.Append( buffer );
574}
575
576
578 int aClearance, int aMaxError, ERROR_LOC aErrorLoc,
579 bool aIgnoreLineWidth ) const
580{
581 // Don't use PCB_SHAPE::TransformShapeToPolygon. We want to treat the textbox as filled even
582 // if there's no background colour.
583
584 int width = GetWidth() + ( 2 * aClearance );
585
586 if( GetShape() == SHAPE_T::RECTANGLE )
587 {
588 std::vector<VECTOR2I> pts = GetRectCorners();
589
590 aBuffer.NewOutline();
591
592 for( const VECTOR2I& pt : pts )
593 aBuffer.Append( pt );
594
595 if( m_borderEnabled && width > 0 )
596 {
597 // Add in segments
598 TransformOvalToPolygon( aBuffer, pts[0], pts[1], width, aMaxError, aErrorLoc );
599 TransformOvalToPolygon( aBuffer, pts[1], pts[2], width, aMaxError, aErrorLoc );
600 TransformOvalToPolygon( aBuffer, pts[2], pts[3], width, aMaxError, aErrorLoc );
601 TransformOvalToPolygon( aBuffer, pts[3], pts[0], width, aMaxError, aErrorLoc );
602 }
603 }
604 else if( GetShape() == SHAPE_T::POLY ) // Non-cardinally-rotated rect
605 {
606 aBuffer.NewOutline();
607
608 const SHAPE_LINE_CHAIN& poly = m_poly.Outline( 0 );
609
610 for( int ii = 0; ii < poly.PointCount(); ++ii )
611 aBuffer.Append( poly.GetPoint( ii ) );
612
613 if( m_borderEnabled && width > 0 )
614 {
615 for( int ii = 0; ii < poly.SegmentCount(); ++ii )
616 {
617 const SEG& seg = poly.GetSegment( ii );
618 TransformOvalToPolygon( aBuffer, seg.A, seg.B, width, aMaxError, aErrorLoc );
619 }
620 }
621 }
622}
623
624
626{
627 return m_borderEnabled;
628}
629
630
632{
633 m_borderEnabled = enabled;
634}
635
636
637void PCB_TEXTBOX::SetBorderWidth( const int aSize )
638{
639 m_stroke.SetWidth( aSize );
640}
641
642
643bool PCB_TEXTBOX::operator==( const BOARD_ITEM& aBoardItem ) const
644{
645 if( aBoardItem.Type() != Type() )
646 return false;
647
648 const PCB_TEXTBOX& other = static_cast<const PCB_TEXTBOX&>( aBoardItem );
649
650 return *this == other;
651}
652
653
654bool PCB_TEXTBOX::operator==( const PCB_TEXTBOX& aOther ) const
655{
656 return m_borderEnabled == aOther.m_borderEnabled
657 && EDA_TEXT::operator==( aOther );
658}
659
660
661double PCB_TEXTBOX::Similarity( const BOARD_ITEM& aBoardItem ) const
662{
663 if( aBoardItem.Type() != Type() )
664 return 0.0;
665
666 const PCB_TEXTBOX& other = static_cast<const PCB_TEXTBOX&>( aBoardItem );
667
668 double similarity = 1.0;
669
670 if( m_borderEnabled != other.m_borderEnabled )
671 similarity *= 0.9;
672
673 if( GetMarginLeft() != other.GetMarginLeft() )
674 similarity *= 0.9;
675
676 if( GetMarginTop() != other.GetMarginTop() )
677 similarity *= 0.9;
678
679 if( GetMarginRight() != other.GetMarginRight() )
680 similarity *= 0.9;
681
682 if( GetMarginBottom() != other.GetMarginBottom() )
683 similarity *= 0.9;
684
685 similarity *= EDA_TEXT::Similarity( other );
686
687 return similarity;
688}
689
690
691static struct PCB_TEXTBOX_DESC
692{
694 {
696
697 if( plotDashTypeEnum.Choices().GetCount() == 0 )
698 {
699 plotDashTypeEnum.Map( LINE_STYLE::DEFAULT, _HKI( "Default" ) )
700 .Map( LINE_STYLE::SOLID, _HKI( "Solid" ) )
701 .Map( LINE_STYLE::DASH, _HKI( "Dashed" ) )
702 .Map( LINE_STYLE::DOT, _HKI( "Dotted" ) )
703 .Map( LINE_STYLE::DASHDOT, _HKI( "Dash-Dot" ) )
704 .Map( LINE_STYLE::DASHDOTDOT, _HKI( "Dash-Dot-Dot" ) );
705 }
706
713
714 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Shape" ) );
715 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Start X" ) );
716 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Start Y" ) );
717 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "End X" ) );
718 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "End Y" ) );
719 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Width" ) );
720 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Height" ) );
721 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Line Width" ) );
722 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Line Style" ) );
723 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Filled" ) );
724 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_TEXT ), _HKI( "Visible" ) );
725 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_TEXT ), _HKI( "Color" ) );
726
727 const wxString borderProps = _( "Border Properties" );
728
729 void ( PCB_TEXTBOX::*lineStyleSetter )( LINE_STYLE ) = &PCB_TEXTBOX::SetLineStyle;
730 LINE_STYLE ( PCB_TEXTBOX::*lineStyleGetter )() const = &PCB_TEXTBOX::GetLineStyle;
731
732 propMgr.AddProperty( new PROPERTY<PCB_TEXTBOX, bool>( _HKI( "Border" ),
734 borderProps );
735
736 propMgr.AddProperty( new PROPERTY_ENUM<PCB_TEXTBOX, LINE_STYLE>( _HKI( "Border Style" ),
737 lineStyleSetter, lineStyleGetter ),
738 borderProps );
739
740 propMgr.AddProperty( new PROPERTY<PCB_TEXTBOX, int>( _HKI( "Border Width" ),
742 PROPERTY_DISPLAY::PT_SIZE ),
743 borderProps );
744
745 const wxString marginProps = _( "Margins" );
746
747 propMgr.AddProperty( new PROPERTY<PCB_TEXTBOX, int>( _HKI( "Margin Left" ),
749 PROPERTY_DISPLAY::PT_SIZE ),
750 marginProps );
751 propMgr.AddProperty( new PROPERTY<PCB_TEXTBOX, int>( _HKI( "Margin Top" ),
753 PROPERTY_DISPLAY::PT_SIZE ),
754 marginProps );
755 propMgr.AddProperty( new PROPERTY<PCB_TEXTBOX, int>( _HKI( "Margin Right" ),
757 PROPERTY_DISPLAY::PT_SIZE ),
758 marginProps );
759 propMgr.AddProperty( new PROPERTY<PCB_TEXTBOX, int>( _HKI( "Margin Bottom" ),
761 PROPERTY_DISPLAY::PT_SIZE ),
762 marginProps );
763
764 }
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
Container for design settings for a BOARD object.
bool GetTextUpright(PCB_LAYER_ID aLayer) const
int GetTextThickness(PCB_LAYER_ID aLayer) const
Return the default text thickness from the layer class for the given layer.
bool GetTextItalic(PCB_LAYER_ID aLayer) const
VECTOR2I GetTextSize(PCB_LAYER_ID aLayer) const
Return the default text size from the layer class for the given layer.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:79
PCB_LAYER_ID m_layer
Definition: board_item.h:409
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
Definition: board_item.cpp:47
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:264
const KIFONT::METRICS & GetFontMetrics() const
Definition: board_item.cpp:98
virtual bool IsLocked() const
Definition: board_item.cpp:75
bool IsSideSpecific() const
Definition: board_item.cpp:114
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
Definition: board_item.cpp:104
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:289
bool ResolveTextVar(wxString *token, int aDepth) const
Definition: board.cpp:431
BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition: box2.h:136
bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:294
coord_type GetTop() const
Definition: box2.h:219
bool Contains(const Vec &aPoint) const
Definition: box2.h:158
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:541
coord_type GetRight() const
Definition: box2.h:207
coord_type GetLeft() const
Definition: box2.h:218
coord_type GetBottom() const
Definition: box2.h:212
EDA_ANGLE Normalize()
Definition: eda_angle.h:221
bool IsHorizontal() const
Definition: eda_angle.h:138
bool IsCardinal() const
Definition: eda_angle.cpp:40
EDA_ANGLE Normalized() const
Definition: eda_angle.h:232
The base class for create windows for drawing purpose.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:89
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:101
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition: eda_item.h:377
void SetStartX(int x)
Definition: eda_shape.h:146
int GetStartY() const
Definition: eda_shape.h:131
void SetEndY(int aY)
Definition: eda_shape.h:177
int GetEndX() const
Definition: eda_shape.h:169
void SetLineStyle(const LINE_STYLE aStyle)
Definition: eda_shape.cpp:1820
void SetStartY(int y)
Definition: eda_shape.h:140
SHAPE_T GetShape() const
Definition: eda_shape.h:125
int GetEndY() const
Definition: eda_shape.h:168
void SetEndX(int aX)
Definition: eda_shape.h:183
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition: eda_shape.h:167
void SetStart(const VECTOR2I &aStart)
Definition: eda_shape.h:134
LINE_STYLE GetLineStyle() const
Definition: eda_shape.cpp:1826
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition: eda_shape.h:130
void SetShape(SHAPE_T aShape)
Definition: eda_shape.h:124
std::vector< VECTOR2I > GetRectCorners() const
Definition: eda_shape.cpp:1171
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:171
int GetStartX() const
Definition: eda_shape.h:132
SHAPE_POLY_SET m_poly
Definition: eda_shape.h:435
STROKE_PARAMS m_stroke
Definition: eda_shape.h:415
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:79
int GetTextHeight() const
Definition: eda_text.h:224
bool IsItalic() const
Definition: eda_text.h:140
const EDA_ANGLE & GetTextAngle() const
Definition: eda_text.h:130
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:373
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:94
KIFONT::FONT * GetFont() const
Definition: eda_text.h:207
void SetMirrored(bool isMirrored)
Definition: eda_text.cpp:251
virtual EDA_ANGLE GetDrawRotation() const
Definition: eda_text.h:336
int GetTextWidth() const
Definition: eda_text.h:221
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:275
void Offset(const VECTOR2I &aOffset)
Definition: eda_text.cpp:436
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition: eda_text.h:160
bool HasTextVars() const
Indicates the ShownText has text var references which need to be processed.
Definition: eda_text.h:113
virtual KIFONT::FONT * getDrawFont() const
Definition: eda_text.cpp:481
double Similarity(const EDA_TEXT &aOther) const
Definition: eda_text.cpp:1142
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:196
const TEXT_ATTRIBUTES & GetAttributes() const
Definition: eda_text.h:191
bool IsMirrored() const
Definition: eda_text.h:150
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
Definition: eda_text.cpp:323
std::shared_ptr< SHAPE_COMPOUND > GetEffectiveTextShape(bool aTriangulate=true, const BOX2I &aBBox=BOX2I(), const EDA_ANGLE &aAngle=ANGLE_0) const
build a list of segments (SHAPE_SEGMENT) to describe a text shape.
Definition: eda_text.cpp:983
bool IsBold() const
Definition: eda_text.h:144
void SetKeepUpright(bool aKeepUpright)
Definition: eda_text.cpp:283
virtual wxString GetShownText(bool aAllowExtraText, int aDepth=0) const
Return the string actually shown after processing of the base text.
Definition: eda_text.h:105
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:204
int GetTextThickness() const
Definition: eda_text.h:122
void SetItalic(bool aItalic)
Definition: eda_text.cpp:212
bool operator==(const EDA_TEXT &aRhs) const
Definition: eda_text.h:353
void SetMultilineAllowed(bool aAllow)
Definition: eda_text.cpp:259
VECTOR2I GetTextSize() const
Definition: eda_text.h:218
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:267
ENUM_MAP & Map(T aValue, const wxString &aName)
Definition: property.h:669
static ENUM_MAP< T > & Instance()
Definition: property.h:663
wxPGChoices & Choices()
Definition: property.h:712
bool ResolveTextVar(wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the component.
Definition: footprint.cpp:901
FONT is an abstract base class for both outline and stroke fonts.
Definition: font.h:131
void Draw(KIGFX::GAL *aGal, const wxString &aText, const VECTOR2I &aPosition, const VECTOR2I &aCursor, const TEXT_ATTRIBUTES &aAttributes, const METRICS &aFontMetrics) const
Draw a string.
Definition: font.cpp:257
void LinebreakText(wxString &aText, int aColumnWidth, const VECTOR2I &aGlyphSize, int aThickness, bool aBold, bool aItalic) const
Insert characters into text to ensure that no lines are wider than aColumnWidth.
Definition: font.cpp:588
Contains methods for drawing PCB-specific items.
Definition: pcb_painter.h:175
virtual PCB_RENDER_SETTINGS * GetSettings() override
Return a pointer to current settings that are going to be used when drawing items.
Definition: pcb_painter.h:180
PCB specific render settings.
Definition: pcb_painter.h:78
PCB_LAYER_ID GetPrimaryHighContrastLayer() const
Return the board layer which is in high-contrast mode.
bool GetHighContrast() const
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:68
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:418
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:221
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: pcb_shape.h:115
void Flip(const VECTOR2I &aCentre, bool aFlipLeftRight) override
Flip this object, i.e.
Definition: pcb_shape.cpp:532
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
Definition: pcb_shape.cpp:526
int GetWidth() const override
Definition: pcb_shape.cpp:369
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const override
Make a set of SHAPE objects representing the PCB_SHAPE.
Definition: pcb_shape.cpp:775
virtual std::vector< VECTOR2I > GetCorners() const
Return 4 corners for a rectangle or rotated rectangle (stored as a poly).
Definition: pcb_shape.cpp:427
STROKE_PARAMS GetStroke() const override
Definition: pcb_shape.h:85
void StyleFromSettings(const BOARD_DESIGN_SETTINGS &settings) override
Definition: pcb_shape.cpp:379
void Move(const VECTOR2I &aMoveVector) override
Move this object.
Definition: pcb_shape.cpp:455
virtual void Mirror(const VECTOR2I &aCentre, bool aMirrorAroundXAxis)
Definition: pcb_shape.cpp:540
VECTOR2I GetPosition() const override
Definition: pcb_shape.h:73
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition: pcb_shape.h:70
bool HitTest(const VECTOR2I &aPosition, int aAccuracy) const override
Test if aPosition is inside or on the boundary of this item.
virtual void swapData(BOARD_ITEM *aImage) override
void SetBorderWidth(const int aSize)
double Similarity(const BOARD_ITEM &aBoardItem) const override
Return a measure of how likely the other object is to represent the same object.
bool IsBorderEnabled() const
Disables the border, this is done by changing the stroke internally.
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
int GetMarginBottom() const
Definition: pcb_textbox.h:87
PCB_TEXTBOX(BOARD_ITEM *aParent, KICAD_T aType=PCB_TEXTBOX_T)
Definition: pcb_textbox.cpp:42
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc, bool aIgnoreLineWidth=false) const override
Convert the shape to a closed polygon.
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
bool m_borderEnabled
Controls drawing the border (as defined by the stroke members)
Definition: pcb_textbox.h:168
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
int m_marginLeft
Definition: pcb_textbox.h:175
int m_marginBottom
Definition: pcb_textbox.h:178
void SetBorderEnabled(bool enabled)
void TransformTextToPolySet(SHAPE_POLY_SET &aBuffer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc) const
Function TransformTextToPolySet Convert the text to a polygonSet describing the actual character stro...
int m_marginRight
Definition: pcb_textbox.h:177
std::vector< VECTOR2I > GetAnchorAndOppositeCorner() const
EDA_ITEM * Clone() const override
Tests whether the border is disabled, as configured by the stroke.
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const override
Make a set of SHAPE objects representing the PCB_SHAPE.
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
VECTOR2I GetDrawPos() const override
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.
void SetMarginTop(int aTop)
Definition: pcb_textbox.h:80
void SetLeft(int aVal) override
int GetMarginLeft() const
Definition: pcb_textbox.h:84
void SetMarginLeft(int aLeft)
Definition: pcb_textbox.h:79
void SetMarginBottom(int aBottom)
Definition: pcb_textbox.h:82
double ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
int GetMarginRight() const
Definition: pcb_textbox.h:86
void SetRight(int aVal) override
void SetTop(int aVal) override
int GetMarginTop() const
Definition: pcb_textbox.h:85
wxString GetShownText(bool aAllowExtraText, int aDepth=0) const override
Return the string actually shown after processing of the base text.
void SetTextAngle(const EDA_ANGLE &aAngle) override
bool operator==(const PCB_TEXTBOX &aOther) const
void SetMarginRight(int aRight)
Definition: pcb_textbox.h:81
void Move(const VECTOR2I &aMoveVector) override
Move this object.
int GetLegacyTextMargin() const
Definition: pcb_textbox.cpp:76
void SetBottom(int aVal) override
void Mirror(const VECTOR2I &aCentre, bool aMirrorAroundXAxis) override
void Flip(const VECTOR2I &aCentre, bool aFlipLeftRight) override
Flip this object, i.e.
VECTOR2I GetTopLeft() const override
Definition: pcb_textbox.cpp:82
VECTOR2I GetBotRight() const override
Definition: pcb_textbox.cpp:97
int GetBorderWidth() const
Definition: pcb_textbox.h:160
void StyleFromSettings(const BOARD_DESIGN_SETTINGS &settings) override
Definition: pcb_textbox.cpp:64
void ViewGetLayers(int aLayers[], int &aCount) const override
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:85
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
void Mask(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName)
Sets a base class property as masked in a derived class.
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:87
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
Definition: seg.h:42
VECTOR2I A
Definition: seg.h:49
VECTOR2I B
Definition: seg.h:50
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
virtual const VECTOR2I GetPoint(int aIndex) const override
int PointCount() const
Return the number of points (vertices) in this line chain.
virtual const SEG GetSegment(int aIndex) const override
int SegmentCount() const
Return the number of segments in this line chain.
Represent a set of closed polygons.
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
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)
void Simplify(POLYGON_MODE aFastMode)
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFastMo...
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int NewOutline()
Creates a new empty polygon in the set and returns its index.
void SetWidth(int aWidth)
Definition: stroke_params.h:92
void GetMsgPanelInfo(UNITS_PROVIDER *aUnitsProvider, std::vector< MSG_PANEL_ITEM > &aList, bool aIncludeStyle=true, bool aIncludeWidth=true)
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject)
Definition: common.cpp:59
void TransformOvalToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a oblong shape to a polygon, using multiple segments.
#define _HKI(x)
#define _(s)
static constexpr EDA_ANGLE ANGLE_0
Definition: eda_angle.h:401
static constexpr EDA_ANGLE ANGLE_90
Definition: eda_angle.h:403
static constexpr EDA_ANGLE ANGLE_270
Definition: eda_angle.h:406
static constexpr EDA_ANGLE ANGLE_180
Definition: eda_angle.h:405
#define PCB_EDIT_FRAME_NAME
SHAPE_T
Definition: eda_shape.h:42
static FILENAME_RESOLVER * resolver
Definition: export_idf.cpp:53
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
@ ERROR_OUTSIDE
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
Definition: layer_ids.h:149
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
Definition: layer_ids.h:628
@ LAYER_LOCKED_ITEM_SHADOW
shadow layer for locked items
Definition: layer_ids.h:243
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
This file contains miscellaneous commonly used macros and functions.
KICOMMON_API wxString EllipsizeMenuText(const wxString &aString)
Ellipsize text (at the end) to be no more than 36 characters.
Definition: ui_common.cpp:213
KICOMMON_API wxString EllipsizeStatusText(wxWindow *aWindow, const wxString &aString)
Ellipsize text (at the end) to be no more than 1/3 of the window width.
Definition: ui_common.cpp:195
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:390
static struct PCB_TEXTBOX_DESC _PCB_TEXTBOX_DESC
#define TYPE_HASH(x)
Definition: property.h:71
#define REGISTER_TYPE(x)
Definition: property_mgr.h:371
wxString UnescapeString(const wxString &aSource)
LINE_STYLE
Dashed line types.
Definition: stroke_params.h:48
constexpr int delta
GR_TEXT_H_ALIGN_T
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_H_ALIGN_INDETERMINATE
@ GR_TEXT_V_ALIGN_TOP
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition: trigo.cpp:228
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition: typeinfo.h:93
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:121
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:673