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 The 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, see <https://www.gnu.org/licenses/>.
18 */
19
20#include <advanced_config.h>
21#include <common.h>
22#include <pcb_edit_frame.h>
23#include <base_units.h>
24#include <bitmaps.h>
25#include <board.h>
27#include <footprint.h>
28#include <pcb_textbox.h>
29#include <pcb_painter.h>
30#include <trigo.h>
31#include <string_utils.h>
33#include <geometry/shape_rect.h>
35#include <callback_gal.h>
37#include <macros.h>
38#include <core/ignore.h>
39#include <api/api_enums.h>
40#include <api/api_utils.h>
41#include <api/board/board_types.pb.h>
42#include <properties/property.h>
44
45
47 PCB_SHAPE( aParent, aType, SHAPE_T::RECTANGLE ),
49 m_borderEnabled( true ),
51{
54 SetMultilineAllowed( true );
55
56 int defaultMargin = GetLegacyTextMargin();
57 m_marginLeft = defaultMargin;
58 m_marginTop = defaultMargin;
59 m_marginRight = defaultMargin;
60 m_marginBottom = defaultMargin;
61}
62
63
67
68
69void PCB_TEXTBOX::CopyFrom( const BOARD_ITEM* aOther )
70{
71 wxCHECK( aOther && aOther->Type() == PCB_TEXTBOX_T, /* void */ );
72 *this = *static_cast<const PCB_TEXTBOX*>( aOther );
73}
74
75
76void PCB_TEXTBOX::Serialize( kiapi::board::types::BoardTextBox& boardText ) const
77{
78 using namespace kiapi::common::types;
79 using namespace kiapi::board;
81 boardText.mutable_id()->set_value( m_Uuid.AsStdString() );
82 boardText.set_locked( IsLocked() ? LockedState::LS_LOCKED : LockedState::LS_UNLOCKED );
83
84 TextBox& text = *boardText.mutable_textbox();
85
86 kiapi::common::PackVector2( *text.mutable_top_left(), GetPosition() );
87 kiapi::common::PackVector2( *text.mutable_bottom_right(), GetEnd() );
88 text.set_text( GetText().ToStdString() );
89
90 kiapi::common::PackTextAttributes( *text.mutable_attributes(), GetAttributes() );
91
92 text.set_border_enabled( IsBorderEnabled() );
93 text.mutable_margin_left()->set_value_nm( GetMarginLeft() );
94 text.mutable_margin_top()->set_value_nm( GetMarginTop() );
95 text.mutable_margin_right()->set_value_nm( GetMarginRight() );
96 text.mutable_margin_bottom()->set_value_nm( GetMarginBottom() );
97
98 boardText.set_knockout( IsKnockout() );
99
100 if( FOOTPRINT* parent = GetParentFootprint() )
101 boardText.mutable_parent()->set_value( parent->m_Uuid.AsStdString() );
102 else if( const BOARD* board = GetBoard() )
103 boardText.mutable_parent()->set_value( board->m_Uuid.AsStdString() );
104
105 kiapi::common::PackCustomProperties( boardText.mutable_custom_properties(), *this );
106}
107
108
109void PCB_TEXTBOX::Serialize( google::protobuf::Any& aContainer ) const
110{
111 kiapi::board::types::BoardTextBox boardText;
112 Serialize( boardText );
113 aContainer.PackFrom( boardText );
114}
115
116
117bool PCB_TEXTBOX::Deserialize( const kiapi::board::types::BoardTextBox& boardText )
118{
119 using namespace kiapi::board;
120
121
122 SetUuidDirect( KIID( boardText.id().value() ) );
124 SetLocked( boardText.locked() == kiapi::common::types::LockedState::LS_LOCKED );
125
126 const kiapi::common::types::TextBox& text = boardText.textbox();
127
129 SetEnd( kiapi::common::UnpackVector2( text.bottom_right() ) );
130 SetText( wxString( text.text().c_str(), wxConvUTF8 ) );
131
132 if( text.has_attributes() )
133 {
135 kiapi::common::UnpackTextAttributes( attrs, text.attributes() );
136 SetAttributes( attrs );
137
138 // Handles setting shape to rectangle or polygon
139 SetTextAngle( attrs.m_Angle );
140 }
141
142 if( text.has_margin_left() )
143 SetMarginLeft( text.margin_left().value_nm() );
144 if( text.has_margin_top() )
145 SetMarginTop( text.margin_top().value_nm() );
146 if( text.has_margin_right() )
147 SetMarginRight( text.margin_right().value_nm() );
148 if( text.has_margin_bottom() )
149 SetMarginBottom( text.margin_bottom().value_nm() );
150
151 SetBorderEnabled( text.border_enabled() );
152 SetIsKnockout( boardText.knockout() );
153
154 kiapi::common::UnpackCustomProperties( boardText.custom_properties(), *this );
155
156 return true;
157}
158
159
160bool PCB_TEXTBOX::Deserialize( const google::protobuf::Any& aContainer )
161{
162 kiapi::board::types::BoardTextBox boardText;
163
164 if( !aContainer.UnpackTo( &boardText ) )
165 return false;
166
167 return Deserialize( boardText );
168}
169
170
171void PCB_TEXTBOX::StyleFromSettings( const BOARD_DESIGN_SETTINGS& settings, bool aCheckSide )
172{
173 PCB_SHAPE::StyleFromSettings( settings, aCheckSide );
174
175 SetTextSize( settings.GetTextSize( GetLayer() ) );
177 SetItalic( settings.GetTextItalic( GetLayer() ) );
178
179 if( GetParentFootprint() )
180 SetKeepUpright( settings.GetTextUpright( GetLayer() ) );
181
182 if( aCheckSide )
183 {
184 if( BOARD* board = GetBoard() )
185 SetMirrored( board->IsBackLayer( GetLayer() ) );
186 else
188 }
189}
190
191
193{
194 return KiROUND( GetStroke().GetWidth() / 2.0 ) + KiROUND( GetTextSize().y * 0.75 );
195}
196
197
199{
200 if( GetText().IsEmpty() )
201 return VECTOR2I( 0, 0 );
202
203 BOX2I textBox = GetTextBox( nullptr );
204
205 int textHeight = std::abs( textBox.GetHeight() );
206
207 if( GetTextAngle().IsHorizontal() )
208 textHeight += GetMarginTop() + GetMarginBottom();
209 else
210 textHeight += GetMarginLeft() + GetMarginRight();
211
212 // Only enforce minimum height. Width returns 0 so the user can freely shrink width
213 // (text rewraps) while height is constrained to fit the wrapped text content.
214 // GetTextBox returns dimensions in text-local coordinates. For 90/270 degree rotations,
215 // the text's natural height maps to screen x-axis.
216 EDA_ANGLE rotation = GetDrawRotation();
217
218 if( rotation == ANGLE_90 || rotation == ANGLE_270 )
219 return VECTOR2I( textHeight, 0 );
220
221 return VECTOR2I( 0, textHeight );
222}
223
224
226{
227 EDA_SHAPE::SetShape( aShape );
228 m_libShape = aShape;
229}
230
231
232std::vector<VECTOR2I> PCB_TEXTBOX::GetCorners() const
233{
235}
236
237
238std::vector<VECTOR2I> PCB_TEXTBOX::GetCornersInSequence( EDA_ANGLE angle ) const
239{
241 return EDA_SHAPE::GetCornersInSequence( angle );
242
243 const int left = std::min( m_start.x, m_end.x );
244 const int right = std::max( m_start.x, m_end.x );
245 const int top = std::min( m_start.y, m_end.y );
246 const int bottom = std::max( m_start.y, m_end.y );
247
248 const VECTOR2I center( ( left + right ) / 2, ( top + bottom ) / 2 );
249
250 std::vector<VECTOR2I> pts = {
251 VECTOR2I( left, top ),
252 VECTOR2I( right, top ),
253 VECTOR2I( right, bottom ),
254 VECTOR2I( left, bottom ),
255 };
256
257 angle.Normalize();
258
259 if( !angle.IsZero() )
260 {
261 for( VECTOR2I& p : pts )
262 RotatePoint( p, center, angle );
263 }
264
265 return pts;
266}
267
268
270{
271 EDA_ANGLE rotation = GetDrawRotation();
272
273 if( rotation == ANGLE_90 )
274 return VECTOR2I( GetStartX(), GetEndY() );
275 else if( rotation == ANGLE_180 )
276 return GetEnd();
277 else if( rotation == ANGLE_270 )
278 return VECTOR2I( GetEndX(), GetStartY() );
279 else
280 return GetStart();
281}
282
283
285{
286 EDA_ANGLE rotation = GetDrawRotation();
287
288 if( rotation == ANGLE_90 )
289 return VECTOR2I( GetEndX(), GetStartY() );
290 else if( rotation == ANGLE_180 )
291 return GetStart();
292 else if( rotation == ANGLE_270 )
293 return VECTOR2I( GetStartX(), GetEndY() );
294 else
295 return GetEnd();
296}
297
298
299void PCB_TEXTBOX::SetTop( int aVal )
300{
301 EDA_ANGLE rotation = GetDrawRotation();
302
303 if( rotation == ANGLE_90 || rotation == ANGLE_180 )
304 SetEndY( aVal );
305 else
306 SetStartY( aVal );
307}
308
309
311{
312 EDA_ANGLE rotation = GetDrawRotation();
313
314 if( rotation == ANGLE_90 || rotation == ANGLE_180 )
315 SetStartY( aVal );
316 else
317 SetEndY( aVal );
318}
319
320
321void PCB_TEXTBOX::SetLeft( int aVal )
322{
323 EDA_ANGLE rotation = GetDrawRotation();
324
325 if( rotation == ANGLE_180 || rotation == ANGLE_270 )
326 SetEndX( aVal );
327 else
328 SetStartX( aVal );
329}
330
331
332void PCB_TEXTBOX::SetRight( int aVal )
333{
334 EDA_ANGLE rotation = GetDrawRotation();
335
336 if( rotation == ANGLE_180 || rotation == ANGLE_270 )
337 SetStartX( aVal );
338 else
339 SetEndX( aVal );
340}
341
342
344{
345 if( const FOOTPRINT* fp = GetParentFootprint() )
346 return m_libTextAngle + fp->GetOrientation();
347
348 return m_libTextAngle;
349}
350
351
353{
354 EDA_ANGLE delta = aAngle.Normalized() - GetTextAngle();
356}
357
358
360{
361 return GetDrawPos( false );
362}
363
364
365VECTOR2I PCB_TEXTBOX::GetDrawPos( bool aIsFlipped ) const
366{
367 EDA_ANGLE drawAngle = GetDrawRotation();
368 std::vector<VECTOR2I> corners = GetCornersInSequence( drawAngle );
369 GR_TEXT_H_ALIGN_T horizontalAlignment = GetHorizJustify();
370 GR_TEXT_V_ALIGN_T verticalAlignment = GetVertJustify();
371 VECTOR2I textAnchor;
372 VECTOR2I offset;
373
374 // Calculate midpoints
375 VECTOR2I midTop = ( corners[0] + corners[1] ) / 2;
376 VECTOR2I midBottom = ( corners[3] + corners[2] ) / 2;
377 VECTOR2I midLeft = ( corners[0] + corners[3] ) / 2;
378 VECTOR2I midRight = ( corners[1] + corners[2] ) / 2;
379 VECTOR2I center = ( corners[0] + corners[1] + corners[2] + corners[3] ) / 4;
380
381 if( IsMirrored() != aIsFlipped )
382 {
383 switch( GetHorizJustify() )
384 {
385 case GR_TEXT_H_ALIGN_LEFT: horizontalAlignment = GR_TEXT_H_ALIGN_RIGHT; break;
386 case GR_TEXT_H_ALIGN_CENTER: horizontalAlignment = GR_TEXT_H_ALIGN_CENTER; break;
387 case GR_TEXT_H_ALIGN_RIGHT: horizontalAlignment = GR_TEXT_H_ALIGN_LEFT; break;
388 case GR_TEXT_H_ALIGN_INDETERMINATE: horizontalAlignment = GR_TEXT_H_ALIGN_INDETERMINATE; break;
389 }
390 }
391
392 wxASSERT_MSG( horizontalAlignment != GR_TEXT_H_ALIGN_INDETERMINATE
393 && verticalAlignment != GR_TEXT_V_ALIGN_INDETERMINATE,
394 wxS( "Indeterminate state legal only in dialogs. Horizontal and vertical alignment "
395 "must be set before calling PCB_TEXTBOX::GetDrawPos." ) );
396
397 if( horizontalAlignment == GR_TEXT_H_ALIGN_INDETERMINATE || verticalAlignment == GR_TEXT_V_ALIGN_INDETERMINATE )
398 {
399 return center;
400 }
401
402 if( horizontalAlignment == GR_TEXT_H_ALIGN_LEFT && verticalAlignment == GR_TEXT_V_ALIGN_TOP )
403 {
404 textAnchor = corners[0];
405 }
406 else if( horizontalAlignment == GR_TEXT_H_ALIGN_CENTER && verticalAlignment == GR_TEXT_V_ALIGN_TOP )
407 {
408 textAnchor = midTop;
409 }
410 else if( horizontalAlignment == GR_TEXT_H_ALIGN_RIGHT && verticalAlignment == GR_TEXT_V_ALIGN_TOP )
411 {
412 textAnchor = corners[1];
413 }
414 else if( horizontalAlignment == GR_TEXT_H_ALIGN_LEFT && verticalAlignment == GR_TEXT_V_ALIGN_CENTER )
415 {
416 textAnchor = midLeft;
417 }
418 else if( horizontalAlignment == GR_TEXT_H_ALIGN_CENTER && verticalAlignment == GR_TEXT_V_ALIGN_CENTER )
419 {
420 textAnchor = center;
421 }
422 else if( horizontalAlignment == GR_TEXT_H_ALIGN_RIGHT && verticalAlignment == GR_TEXT_V_ALIGN_CENTER )
423 {
424 textAnchor = midRight;
425 }
426 else if( horizontalAlignment == GR_TEXT_H_ALIGN_LEFT && verticalAlignment == GR_TEXT_V_ALIGN_BOTTOM )
427 {
428 textAnchor = corners[3];
429 }
430 else if( horizontalAlignment == GR_TEXT_H_ALIGN_CENTER && verticalAlignment == GR_TEXT_V_ALIGN_BOTTOM )
431 {
432 textAnchor = midBottom;
433 }
434 else if( horizontalAlignment == GR_TEXT_H_ALIGN_RIGHT && verticalAlignment == GR_TEXT_V_ALIGN_BOTTOM )
435 {
436 textAnchor = corners[2];
437 }
438
439 int marginLeft = GetMarginLeft();
440 int marginRight = GetMarginRight();
441 int marginTop = GetMarginTop();
442 int marginBottom = GetMarginBottom();
443
444 if( horizontalAlignment == GR_TEXT_H_ALIGN_LEFT )
445 offset.x = marginLeft;
446 else if( horizontalAlignment == GR_TEXT_H_ALIGN_RIGHT )
447 offset.x = -marginRight;
448
449 if( verticalAlignment == GR_TEXT_V_ALIGN_TOP )
450 offset.y = marginTop;
451 else if( verticalAlignment == GR_TEXT_V_ALIGN_BOTTOM )
452 offset.y = -marginBottom;
453
454 RotatePoint( offset, GetDrawRotation() );
455 return textAnchor + offset;
456}
457
458
459double PCB_TEXTBOX::ViewGetLOD( int aLayer, const KIGFX::VIEW* aView ) const
460{
461 KIGFX::PCB_PAINTER& painter = static_cast<KIGFX::PCB_PAINTER&>( *aView->GetPainter() );
462 KIGFX::PCB_RENDER_SETTINGS& renderSettings = *painter.GetSettings();
463
464 if( aLayer == LAYER_LOCKED_ITEM_SHADOW )
465 {
466 // Hide shadow if the main layer is not shown
467 if( !aView->IsLayerVisibleCached( m_layer ) )
468 return LOD_HIDE;
469
470 // Hide shadow on dimmed tracks
471 if( renderSettings.GetHighContrast() )
472 {
473 if( m_layer != renderSettings.GetPrimaryHighContrastLayer() )
474 return LOD_HIDE;
475 }
476 }
477
478 return LOD_SHOW;
479}
480
481
482std::vector<int> PCB_TEXTBOX::ViewGetLayers() const
483{
486
487 return { GetLayer() };
488}
489
490
491wxString PCB_TEXTBOX::GetShownText( RESOLUTION_CONTEXT aContext, int aDepth ) const
492{
493 const FOOTPRINT* parentFootprint = GetParentFootprint();
494 const BOARD* board = GetBoard();
495
496 std::function<bool( wxString* )> resolver =
497 [&]( wxString* token ) -> bool
498 {
499 if( token->IsSameAs( wxT( "LAYER" ) ) )
500 {
501 *token = GetLayerName();
502 return true;
503 }
504
505 if( parentFootprint && parentFootprint->ResolveTextVar( token, aDepth + 1 ) )
506 return true;
507
508 if( board->ResolveTextVar( token, aDepth + 1 ) )
509 return true;
510
511 return false;
512 };
513
514 wxString text = EDA_TEXT::GetShownText( aContext, aDepth );
515
516 if( HasTextVars() && aContext != RAW_VALUE )
517 {
518 text = ResolveTextVars( text, &resolver, aDepth );
519 FinalizeTextVarExpansion( text, aContext );
520 }
521
522 KIFONT::FONT* font = GetDrawFont( nullptr );
523 EDA_ANGLE drawAngle = GetDrawRotation();
524 std::vector<VECTOR2I> corners = GetCornersInSequence( drawAngle );
525 int colWidth = ( corners[1] - corners[0] ).EuclideanNorm();
526
527 if( GetTextAngle().IsHorizontal() )
528 colWidth -= ( GetMarginLeft() + GetMarginRight() );
529 else
530 colWidth -= ( GetMarginTop() + GetMarginBottom() );
531
533
534 return text;
535}
536
537
538bool PCB_TEXTBOX::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
539{
540 return BOARD_ITEM::Matches( UnescapeString( GetText() ), aSearchData );
541}
542
543
544void PCB_TEXTBOX::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
545{
546 // Don't use GetShownText() here; we want to show the user the variable references
547 aList.emplace_back( _( "Text Box" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) );
548
549 if( aFrame->GetName() == PCB_EDIT_FRAME_NAME && IsLocked() )
550 aList.emplace_back( _( "Status" ), _( "Locked" ) );
551
552 aList.emplace_back( _( "Layer" ), GetLayerName() );
553 aList.emplace_back( _( "Mirror" ), IsMirrored() ? _( "Yes" ) : _( "No" ) );
554 aList.emplace_back( _( "Angle" ), wxString::Format( "%g", GetTextAngle().AsDegrees() ) );
555
556 aList.emplace_back( _( "Font" ), GetFont() ? GetFont()->GetName() : _( "Default" ) );
557
558 if( GetTextThickness() )
559 aList.emplace_back( _( "Text Thickness" ), aFrame->MessageTextFromValue( GetEffectiveTextPenWidth() ) );
560 else
561 aList.emplace_back( _( "Text Thickness" ), _( "Auto" ) );
562
563 aList.emplace_back( _( "Text Width" ), aFrame->MessageTextFromValue( GetTextWidth() ) );
564 aList.emplace_back( _( "Text Height" ), aFrame->MessageTextFromValue( GetTextHeight() ) );
565
566 aList.emplace_back( _( "Box Width" ), aFrame->MessageTextFromValue( std::abs( GetEnd().x - GetStart().x ) ) );
567
568 aList.emplace_back( _( "Box Height" ), aFrame->MessageTextFromValue( std::abs( GetEnd().y - GetStart().y ) ) );
569
570 m_stroke.GetMsgPanelInfo( aFrame, aList );
571}
572
573
574void PCB_TEXTBOX::Move( const VECTOR2I& aMoveVector )
575{
576 PCB_SHAPE::Move( aMoveVector );
577 EDA_TEXT::Offset( aMoveVector );
578}
579
580
582{
584
585 if( const FOOTPRINT* fp = GetParentFootprint() )
586 {
587 const TRANSFORM_TRS& xf = fp->GetTransform();
588 return { KiROUND( libSize.x * std::abs( xf.GetScaleX() ) ), KiROUND( libSize.y * std::abs( xf.GetScaleY() ) ) };
589 }
590
591 return libSize;
592}
593
594
595void PCB_TEXTBOX::SetTextSize( VECTOR2I aNewSize, bool aEnforceMinTextSize )
596{
597 if( const FOOTPRINT* fp = GetParentFootprint() )
598 {
599 const TRANSFORM_TRS& xf = fp->GetTransform();
600 aNewSize = { KiROUND( aNewSize.x / std::abs( xf.GetScaleX() ) ),
601 KiROUND( aNewSize.y / std::abs( xf.GetScaleY() ) ) };
602 }
603
604 EDA_TEXT::SetTextSize( aNewSize, aEnforceMinTextSize );
605}
606
607
609{
610 int libThickness = EDA_TEXT::GetTextThickness();
611
612 if( const FOOTPRINT* fp = GetParentFootprint() )
613 {
614 const TRANSFORM_TRS& xf = fp->GetTransform();
615 const double factor = ( std::abs( xf.GetScaleX() ) + std::abs( xf.GetScaleY() ) ) * 0.5;
616 return KiROUND( libThickness * factor );
617 }
618
619 return libThickness;
620}
621
622
624{
625 if( const FOOTPRINT* fp = GetParentFootprint() )
626 {
627 const TRANSFORM_TRS& xf = fp->GetTransform();
628 const double factor = ( std::abs( xf.GetScaleX() ) + std::abs( xf.GetScaleY() ) ) * 0.5;
629 aWidth = KiROUND( aWidth / factor );
630 }
631
633}
634
635
636void PCB_TEXTBOX::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
637{
638 // Slide the axis-aligned box, rotation lives in the text angle.
639 const VECTOR2D oldCenter( ( m_start.x + m_end.x ) * 0.5, ( m_start.y + m_end.y ) * 0.5 );
640 VECTOR2D newCenter = oldCenter;
641 RotatePoint( newCenter, VECTOR2D( aRotCentre.x, aRotCentre.y ), aAngle );
642
643 const VECTOR2I delta( KiROUND( newCenter.x - oldCenter.x ), KiROUND( newCenter.y - oldCenter.y ) );
646
648
649 EDA_ANGLE newAbs = ( GetTextAngle() + aAngle ).Normalize();
650 EDA_TEXT::SetTextAngle( newAbs );
651
652 if( const FOOTPRINT* fp = GetParentFootprint() )
653 m_libTextAngle = newAbs - fp->GetOrientation();
654 else
655 m_libTextAngle = newAbs;
656
657 m_libTextAngle.Normalize();
658}
659
660
661void PCB_TEXTBOX::Mirror( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
662{
663 // the position and angle are mirrored, but not the text (or its justification)
664 PCB_SHAPE::Mirror( aCentre, aFlipDirection );
665
666 if( aFlipDirection == FLIP_DIRECTION::LEFT_RIGHT )
668 else
670
671 m_libTextAngle.Normalize();
673}
674
675
676void PCB_TEXTBOX::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
677{
678 PCB_SHAPE::Flip( aCentre, aFlipDirection );
679
680 if( aFlipDirection == FLIP_DIRECTION::LEFT_RIGHT )
682 else
684
685 m_libTextAngle.Normalize();
687
688 if( IsSideSpecific() )
690}
691
692
694{
695 if( const FOOTPRINT* fp = GetParentFootprint(); fp && GetLibraryShape() == SHAPE_T::RECTANGLE )
696 {
697 const TRANSFORM_TRS& xform = fp->GetTransform();
699
700 const VECTOR2I libCenter( ( m_libStart.x + m_libEnd.x ) / 2, ( m_libStart.y + m_libEnd.y ) / 2 );
701 const int libHalfW = std::abs( m_libEnd.x - m_libStart.x ) / 2;
702 const int libHalfH = std::abs( m_libEnd.y - m_libStart.y ) / 2;
703
704 const VECTOR2I newCenter = xform.Apply( libCenter );
705 const int newHalfW = std::abs( KiROUND( libHalfW * xform.GetScaleX() ) );
706 const int newHalfH = std::abs( KiROUND( libHalfH * xform.GetScaleY() ) );
707
708 EDA_SHAPE::SetStart( VECTOR2I( newCenter.x - newHalfW, newCenter.y - newHalfH ) );
709 EDA_SHAPE::SetEnd( VECTOR2I( newCenter.x + newHalfW, newCenter.y + newHalfH ) );
710 }
711 else
712 {
714 }
715
719}
720
721
723{
724 const FOOTPRINT* fp = GetParentFootprint();
725
726 // Only the axis-aligned rectangle case needs the textbox-specific inverse.
727 // Poly textboxes and standalone (non-FP) boxes use the base shape mapping.
728 if( !fp || GetShape() != SHAPE_T::RECTANGLE )
729 {
731 return;
732 }
733
734 const TRANSFORM_TRS& xform = fp->GetTransform();
735
736 const VECTOR2I boardCenter( ( m_start.x + m_end.x ) / 2, ( m_start.y + m_end.y ) / 2 );
737 const int boardHalfW = std::abs( m_end.x - m_start.x ) / 2;
738 const int boardHalfH = std::abs( m_end.y - m_start.y ) / 2;
739
740 const VECTOR2I libCenter = xform.InverseApply( boardCenter );
741 const int libHalfW = std::abs( KiROUND( boardHalfW / xform.GetScaleX() ) );
742 const int libHalfH = std::abs( KiROUND( boardHalfH / xform.GetScaleY() ) );
743
744 m_libStart = VECTOR2I( libCenter.x - libHalfW, libCenter.y - libHalfH );
745 m_libEnd = VECTOR2I( libCenter.x + libHalfW, libCenter.y + libHalfH );
746}
747
748
749void PCB_TEXTBOX::OnFootprintRescaled( double aRatioX, double aRatioY, double aLinearFactor, const VECTOR2I& aAnchor,
750 const EDA_ANGLE& aParentRotate )
751{
753}
754
755
757{
758 BOX2I bbox;
759
760 for( const VECTOR2I& pt : GetCorners() )
761 bbox.Merge( pt );
762
763 bbox.Inflate( std::max( 0, GetWidth() ) / 2 );
764 bbox.Normalize();
765
766 return bbox;
767}
768
769
770bool PCB_TEXTBOX::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
771{
772 BOX2I rect = GetBoundingBox();
773
774 rect.Inflate( aAccuracy );
775
776 return rect.Contains( aPosition );
777}
778
779
780bool PCB_TEXTBOX::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
781{
782 BOX2I rect = aRect;
783
784 rect.Inflate( aAccuracy );
785
786 if( aContained )
787 return rect.Contains( GetBoundingBox() );
788
789 return rect.Intersects( GetBoundingBox() );
790}
791
792
793bool PCB_TEXTBOX::HitTest( const SHAPE_LINE_CHAIN& aPoly, bool aContained ) const
794{
795 return PCB_SHAPE::HitTest( aPoly, aContained );
796}
797
798
799wxString PCB_TEXTBOX::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
800{
801 return wxString::Format( _( "PCB text box '%s' on %s" ),
803 GetLayerName() );
804}
805
806
811
812
814{
815 return new PCB_TEXTBOX( *this );
816}
817
818
820{
821 wxASSERT( aImage->Type() == PCB_TEXTBOX_T );
822
823 std::swap( *( (PCB_TEXTBOX*) this ), *( (PCB_TEXTBOX*) aImage ) );
824}
825
826
827std::shared_ptr<SHAPE> PCB_TEXTBOX::GetEffectiveShape( PCB_LAYER_ID aLayer, FLASHING aFlash,
828 DRC_CONSTRAINT_T aUsage ) const
829{
830 std::shared_ptr<SHAPE_COMPOUND> shape = GetEffectiveTextShape();
831
832 if( PCB_SHAPE::GetStroke().GetWidth() >= 0 )
833 shape->AddShape( PCB_SHAPE::GetEffectiveShape( aLayer, aFlash, aUsage ) );
834
835 return shape;
836}
837
838
839void PCB_TEXTBOX::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance, int aMaxError,
840 ERROR_LOC aErrorLoc ) const
841{
843 KIFONT::FONT* font = GetDrawFont( nullptr );
844 int penWidth = GetEffectiveTextPenWidth();
846 wxString shownText = GetShownText( FOR_CANVAS );
847
848 // The polygonal shape of a text can have many basic shapes, so combining these shapes can
849 // be very useful to create a final shape with a lot less vertices to speedup calculations.
850 // Simplify shapes is not usually always efficient, but in this case it is.
851 SHAPE_POLY_SET textShape;
852
853 CALLBACK_GAL callback_gal(
854 empty_opts,
855 // Stroke callback
856 [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
857 {
858 TransformOvalToPolygon( textShape, aPt1, aPt2, penWidth, aMaxError, aErrorLoc );
859 },
860 // Triangulation callback
861 [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 )
862 {
863 textShape.NewOutline();
864
865 for( const VECTOR2I& point : { aPt1, aPt2, aPt3 } )
866 textShape.Append( point.x, point.y );
867 } );
868
869 if( auto* cache = GetRenderCache( font, shownText ) )
870 callback_gal.DrawGlyphs( *cache );
871 else
872 font->Draw( &callback_gal, shownText, GetDrawPos(), attrs, GetFontMetrics() );
873
874 textShape.Simplify();
875
876 if( IsKnockout() )
877 {
878 SHAPE_POLY_SET finalPoly;
879
880 TransformShapeToPolygon( finalPoly, GetLayer(), aClearance, aMaxError, aErrorLoc );
881 finalPoly.BooleanSubtract( textShape );
882
883 aBuffer.Append( finalPoly );
884 }
885 else
886 {
887 if( aClearance > 0 || aErrorLoc == ERROR_OUTSIDE )
888 {
889 if( aErrorLoc == ERROR_OUTSIDE )
890 aClearance += aMaxError;
891
892 textShape.Inflate( aClearance, CORNER_STRATEGY::ROUND_ALL_CORNERS, aMaxError, true );
893 }
894
895 aBuffer.Append( textShape );
896 }
897}
898
899
900void PCB_TEXTBOX::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aMaxError,
901 ERROR_LOC aErrorLoc, bool aIgnoreLineWidth ) const
902{
903 // Don't use PCB_SHAPE::TransformShapeToPolygon. We want to treat the textbox as filled even
904 // if there's no background colour.
905
906 int width = GetWidth() + ( 2 * aClearance );
907
909 {
910 std::vector<VECTOR2I> pts = GetRectCorners();
911
912 aBuffer.NewOutline();
913
914 for( const VECTOR2I& pt : pts )
915 aBuffer.Append( pt );
916
917 if( m_borderEnabled && width > 0 )
918 {
919 // Add in segments
920 TransformOvalToPolygon( aBuffer, pts[0], pts[1], width, aMaxError, aErrorLoc );
921 TransformOvalToPolygon( aBuffer, pts[1], pts[2], width, aMaxError, aErrorLoc );
922 TransformOvalToPolygon( aBuffer, pts[2], pts[3], width, aMaxError, aErrorLoc );
923 TransformOvalToPolygon( aBuffer, pts[3], pts[0], width, aMaxError, aErrorLoc );
924 }
925 }
926 else if( GetShape() == SHAPE_T::POLY ) // Non-cardinally-rotated rect
927 {
928 aBuffer.NewOutline();
929
930 const SHAPE_LINE_CHAIN& poly = GetPolyShape().Outline( 0 );
931
932 for( int ii = 0; ii < poly.PointCount(); ++ii )
933 aBuffer.Append( poly.GetPoint( ii ) );
934
935 if( m_borderEnabled && width > 0 )
936 {
937 for( int ii = 0; ii < poly.SegmentCount(); ++ii )
938 {
939 const SEG& seg = poly.GetSegment( ii );
940 TransformOvalToPolygon( aBuffer, seg.A, seg.B, width, aMaxError, aErrorLoc );
941 }
942 }
943 }
944}
945
946
948{
949 return m_borderEnabled;
950}
951
952
954{
955 m_borderEnabled = enabled;
956}
957
958
959void PCB_TEXTBOX::SetBorderWidth( const int aSize )
960{
961 m_stroke.SetWidth( aSize );
962}
963
964
965bool PCB_TEXTBOX::operator==( const BOARD_ITEM& aBoardItem ) const
966{
967 if( aBoardItem.Type() != Type() )
968 return false;
969
970 const PCB_TEXTBOX& other = static_cast<const PCB_TEXTBOX&>( aBoardItem );
971
972 return *this == other;
973}
974
975
976bool PCB_TEXTBOX::operator==( const PCB_TEXTBOX& aOther ) const
977{
978 return m_borderEnabled == aOther.m_borderEnabled && EDA_TEXT::operator==( aOther );
979}
980
981
982double PCB_TEXTBOX::Similarity( const BOARD_ITEM& aBoardItem ) const
983{
984 if( aBoardItem.Type() != Type() )
985 return 0.0;
986
987 const PCB_TEXTBOX& other = static_cast<const PCB_TEXTBOX&>( aBoardItem );
988
989 double similarity = 1.0;
990
991 if( m_borderEnabled != other.m_borderEnabled )
992 similarity *= 0.9;
993
994 if( GetMarginLeft() != other.GetMarginLeft() )
995 similarity *= 0.9;
996
997 if( GetMarginTop() != other.GetMarginTop() )
998 similarity *= 0.9;
999
1000 if( GetMarginRight() != other.GetMarginRight() )
1001 similarity *= 0.9;
1002
1003 if( GetMarginBottom() != other.GetMarginBottom() )
1004 similarity *= 0.9;
1005
1006 similarity *= EDA_TEXT::Similarity( other );
1007
1008 return similarity;
1009}
1010
1011
1012static struct PCB_TEXTBOX_DESC
1013{
1015 {
1017
1018 if( lineStyleEnum.Choices().GetCount() == 0 )
1019 {
1020 lineStyleEnum.Map( LINE_STYLE::SOLID, _HKI( "Solid" ) )
1021 .Map( LINE_STYLE::DASH, _HKI( "Dashed" ) )
1022 .Map( LINE_STYLE::DOT, _HKI( "Dotted" ) )
1023 .Map( LINE_STYLE::DASHDOT, _HKI( "Dash-Dot" ) )
1024 .Map( LINE_STYLE::DASHDOTDOT, _HKI( "Dash-Dot-Dot" ) );
1025 }
1026
1035
1036 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Shape" ) );
1037 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Start X" ) );
1038 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Start Y" ) );
1039 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "End X" ) );
1040 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "End Y" ) );
1041 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Width" ) );
1042 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Height" ) );
1043 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Line Width" ) );
1044 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Line Style" ) );
1045 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Filled" ) );
1046 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Line Color" ) );
1047 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_SHAPE ), _HKI( "Corner Radius" ) );
1048
1049 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_TEXT ), _HKI( "Color" ) );
1050
1051 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( PCB_SHAPE ), _HKI( "Soldermask" ) );
1052 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( PCB_SHAPE ), _HKI( "Soldermask Margin Override" ) );
1053
1054 propMgr.AddProperty( new PROPERTY<PCB_TEXTBOX, bool, BOARD_ITEM>( _HKI( "Knockout" ),
1056 _HKI( "Text Properties" ) ).SetIsCopyable();
1057
1058 const wxString borderProps = _( "Border Properties" );
1059
1060 void ( PCB_TEXTBOX::*lineStyleSetter )( LINE_STYLE ) = &PCB_TEXTBOX::SetLineStyle;
1061 LINE_STYLE ( PCB_TEXTBOX::*lineStyleGetter )() const = &PCB_TEXTBOX::GetLineStyle;
1062
1063 propMgr.AddProperty( new PROPERTY<PCB_TEXTBOX, bool>( _HKI( "Border" ),
1065 borderProps ).SetIsCopyable();
1066
1067 propMgr.AddProperty( new PROPERTY_ENUM<PCB_TEXTBOX, LINE_STYLE>( _HKI( "Border Style" ),
1068 lineStyleSetter, lineStyleGetter ),
1069 borderProps ).SetIsCopyable();
1070
1071 propMgr.AddProperty( new PROPERTY<PCB_TEXTBOX, int>( _HKI( "Border Width" ),
1073 borderProps ).SetIsCopyable();
1074
1075 const wxString marginProps = _( "Margins" );
1076
1077 propMgr.AddProperty( new PROPERTY<PCB_TEXTBOX, int>( _HKI( "Margin Left" ),
1079 marginProps ).SetIsCopyable();
1080 propMgr.AddProperty( new PROPERTY<PCB_TEXTBOX, int>( _HKI( "Margin Top" ),
1082 marginProps ).SetIsCopyable();
1083 propMgr.AddProperty( new PROPERTY<PCB_TEXTBOX, int>( _HKI( "Margin Right" ),
1085 marginProps ).SetIsCopyable();
1086 propMgr.AddProperty( new PROPERTY<PCB_TEXTBOX, int>( _HKI( "Margin Bottom" ),
1088 marginProps ).SetIsCopyable();
1089
1090 propMgr.Mask( TYPE_HASH( PCB_TEXTBOX ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
1091 }
KICOMMON_API types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICOMMON_API KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
Definition api_enums.cpp:55
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
@ ERROR_OUTSIDE
constexpr EDA_IU_SCALE pcbIUScale
Definition base_units.h:121
BITMAPS
A list of all bitmap identifiers.
BOX2< VECTOR2I > BOX2I
Definition box2.h:927
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:995
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.
BOARD_ITEM(BOARD_ITEM *aParent, KICAD_T idtype, PCB_LAYER_ID aLayer=F_Cu)
Definition board_item.h:86
friend class BOARD
Definition board_item.h:578
void SetUuidDirect(const KIID &aUuid)
Raw UUID assignment.
void SetLocked(bool aLocked) override
Definition board_item.h:417
PCB_LAYER_ID m_layer
Definition board_item.h:571
virtual bool IsKnockout() const
Definition board_item.h:413
bool IsLocked() const override
virtual void SetIsKnockout(bool aKnockout)
Definition board_item.h:414
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
FOOTPRINT * GetParentFootprint() const
const KIFONT::METRICS & GetFontMetrics() const
bool IsSideSpecific() const
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:553
constexpr BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition box2.h:143
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition box2.h:653
constexpr size_type GetHeight() const
Definition box2.h:212
constexpr bool Contains(const Vec &aPoint) const
Definition box2.h:165
constexpr bool Intersects(const BOX2< Vec > &aRect) const
Definition box2.h:308
EDA_ANGLE Normalize()
Definition eda_angle.h:229
bool IsZero() const
Definition eda_angle.h:136
EDA_ANGLE Normalized() const
Definition eda_angle.h:240
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:98
const KIID m_Uuid
Definition eda_item.h:597
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition eda_item.h:482
SHAPE_T m_shape
Definition eda_shape.h:733
virtual void SetEnd(const VECTOR2I &aEnd)
Definition eda_shape.h:329
void SetStartX(int x)
Definition eda_shape.h:293
int GetStartY() const
Definition eda_shape.h:276
void SetEndY(int aY)
Definition eda_shape.h:336
int GetEndX() const
Definition eda_shape.h:327
void SetLineStyle(const LINE_STYLE aStyle)
void SetStartY(int y)
Definition eda_shape.h:286
SHAPE_POLY_SET & GetPolyShape()
virtual std::vector< VECTOR2I > GetCornersInSequence(EDA_ANGLE angle) const
SHAPE_T GetShape() const
Definition eda_shape.h:175
int GetEndY() const
Definition eda_shape.h:326
void SetEndX(int aX)
Definition eda_shape.h:343
VECTOR2I m_start
Definition eda_shape.h:747
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition eda_shape.h:325
LINE_STYLE GetLineStyle() const
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition eda_shape.h:275
virtual void SetShape(SHAPE_T aShape)
Definition eda_shape.h:174
std::vector< VECTOR2I > GetRectCorners() const
int GetStartX() const
Definition eda_shape.h:277
VECTOR2I m_end
Definition eda_shape.h:748
STROKE_PARAMS m_stroke
Definition eda_shape.h:734
virtual void SetStart(const VECTOR2I &aStart)
Definition eda_shape.h:279
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:94
virtual VECTOR2I GetTextSize() const
Definition eda_text.h:301
bool IsItalic() const
Definition eda_text.h:200
virtual void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition eda_text.cpp:495
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:118
virtual int GetTextHeight() const
Definition eda_text.h:307
KIFONT::FONT * GetFont() const
Definition eda_text.h:286
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
Definition eda_text.cpp:389
void SetMirrored(bool isMirrored)
Definition eda_text.cpp:349
std::vector< std::unique_ptr< KIFONT::GLYPH > > * GetRenderCache(const KIFONT::FONT *aFont, const wxString &forResolvedText, const VECTOR2I &aOffset={ 0, 0 }) const
Definition eda_text.cpp:666
virtual EDA_ANGLE GetDrawRotation() const
Definition eda_text.h:419
BOX2I GetTextBox(const RENDER_SETTINGS *aSettings, int aLine=-1) const
Useful in multiline texts to calculate the full text or a line area (for zones filling,...
Definition eda_text.cpp:737
virtual wxString GetShownText(RESOLUTION_CONTEXT aContext, int aDepth=0) const
Return the string actually shown after processing of the base text.
Definition eda_text.h:128
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition eda_text.cpp:373
virtual void Offset(const VECTOR2I &aOffset)
Definition eda_text.cpp:558
virtual int GetTextWidth() const
Definition eda_text.h:304
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition eda_text.h:239
virtual KIFONT::FONT * GetDrawFont(const RENDER_SETTINGS *aSettings) const
Definition eda_text.cpp:630
bool HasTextVars() const
Indicates the ShownText has text var references which need to be processed.
Definition eda_text.h:139
EDA_TEXT(const EDA_IU_SCALE &aIuScale, const wxString &aText=wxEmptyString)
Definition eda_text.cpp:98
virtual void ClearBoundingBoxCache()
Definition eda_text.cpp:658
double Similarity(const EDA_TEXT &aOther) const
virtual void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition eda_text.cpp:245
virtual void ClearRenderCache()
Definition eda_text.cpp:652
const TEXT_ATTRIBUTES & GetAttributes() const
Definition eda_text.h:270
bool IsMirrored() const
Definition eda_text.h:229
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
Definition eda_text.cpp:422
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.
bool IsBold() const
Definition eda_text.h:215
void SetKeepUpright(bool aKeepUpright)
Definition eda_text.cpp:381
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition eda_text.h:242
virtual int GetTextThickness() const
Definition eda_text.h:159
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:231
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition eda_text.cpp:263
void SetItalic(bool aItalic)
Set the text to be italic - this will also update the font if needed.
Definition eda_text.cpp:285
bool operator==(const EDA_TEXT &aRhs) const
Definition eda_text.h:438
void SetMultilineAllowed(bool aAllow)
Definition eda_text.cpp:357
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition eda_text.cpp:365
ENUM_MAP & Map(T aValue, const wxString &aName)
Definition property.h:776
static ENUM_MAP< T > & Instance()
Definition property.h:770
wxPGChoices & Choices()
Definition property.h:821
bool ResolveTextVar(wxString *token, int aDepth=0) const
Resolve any references to system tokens supported by the component.
const TRANSFORM_TRS & GetTransform() const
Definition footprint.h:451
FONT is an abstract base class for both outline and stroke fonts.
Definition font.h:94
void Draw(KIGFX::GAL *aGal, const wxString &aText, const VECTOR2I &aPosition, const VECTOR2I &aCursor, const TEXT_ATTRIBUTES &aAttributes, const METRICS &aFontMetrics, std::optional< VECTOR2I > aMousePos=std::nullopt, wxString *aActiveUrl=nullptr) const
Draw a string.
Definition font.cpp:240
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:609
virtual void DrawGlyphs(const std::vector< std::unique_ptr< KIFONT::GLYPH > > &aGlyphs)
Draw polygons representing font glyphs.
Contains methods for drawing PCB-specific items.
virtual PCB_RENDER_SETTINGS * GetSettings() override
Return a pointer to current settings that are going to be used when drawing items.
PCB specific render settings.
Definition pcb_painter.h:84
PCB_LAYER_ID GetPrimaryHighContrastLayer() const
Return the board layer which is in high-contrast mode.
static constexpr double LOD_HIDE
Return this constant from ViewGetLOD() to hide the item unconditionally.
Definition view_item.h:176
static constexpr double LOD_SHOW
Return this constant from ViewGetLOD() to show the item unconditionally.
Definition view_item.h:181
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:63
bool IsLayerVisibleCached(int aLayer) const
Definition view.h:439
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition view.h:225
Definition kiid.h:46
virtual void Mirror(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Mirror this object relative to a given horizontal axis the layer is not changed.
void StyleFromSettings(const BOARD_DESIGN_SETTINGS &settings, bool aCheckSide) override
VECTOR2I m_libEnd
Definition pcb_shape.h:375
virtual void syncLibCoords()
PCB_SHAPE(BOARD_ITEM *aParent, KICAD_T aItemType, SHAPE_T aShapeType)
SHAPE_T m_libShape
Definition pcb_shape.h:391
int GetWidth() const override
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
Definition pcb_shape.h:160
void SetPosition(const VECTOR2I &aPos) override
Definition pcb_shape.h:75
SHAPE_T GetLibraryShape() const
Definition pcb_shape.h:229
void SetEnd(const VECTOR2I &aEnd) override
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT, DRC_CONSTRAINT_T aUsage=NULL_CONSTRAINT) const override
Make a set of SHAPE objects representing the PCB_SHAPE.
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
STROKE_PARAMS GetStroke() const override
void Move(const VECTOR2I &aMoveVector) override
Move this object.
void OnFootprintTransformed() override
Hook for items inside a footprint to refresh after the FP transform changes (translate,...
Definition pcb_shape.h:193
void Normalize() override
Perform any normalization required after a user rotate and/or flip.
VECTOR2I m_libStart
Definition pcb_shape.h:374
VECTOR2I GetPosition() const override
Definition pcb_shape.h:76
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
Definition pcb_shape.h:68
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
void StyleFromSettings(const BOARD_DESIGN_SETTINGS &settings, bool aCheckSide) override
EDA_ANGLE GetTextAngle() const override
PCB_TEXTBOX(BOARD_ITEM *aParent, KICAD_T aType=PCB_TEXTBOX_T)
int GetTextThickness() const override
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)
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
void SetBorderEnabled(bool enabled)
void Mirror(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Mirror this object relative to a given horizontal axis the layer is not changed.
void OnFootprintTransformed() override
Hook for items inside a footprint to refresh after the FP transform changes (translate,...
VECTOR2I GetMinSize() const
Return the minimum height needed to contain the textbox's wrapped text content plus margins.
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...
double ViewGetLOD(int aLayer, const KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
void OnFootprintRescaled(double aRatioX, double aRatioY, double aLinearFactor, const VECTOR2I &aAnchor, const EDA_ANGLE &aParentRotate) override
Apply a parent footprint scale to this item.
VECTOR2I GetTextSize() const override
EDA_ITEM * Clone() const override
Tests whether the border is disabled, as configured by the stroke.
void SetShape(SHAPE_T aShape) override
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
VECTOR2I GetDrawPos() const override
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
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)
void SetLeft(int aVal) override
int GetMarginLeft() const
void SetMarginLeft(int aLeft)
void Flip(const VECTOR2I &aCentre, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
void SetMarginBottom(int aBottom)
std::vector< VECTOR2I > GetCornersInSequence(EDA_ANGLE angle) const override
int GetMarginRight() const
void SetRight(int aVal) override
std::vector< int > ViewGetLayers() const override
void SetTop(int aVal) override
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
int GetMarginTop() const
void SetTextAngle(const EDA_ANGLE &aAngle) override
bool operator==(const PCB_TEXTBOX &aOther) const
void SetTextThickness(int aWidth) override
The TextThickness is that set by the user.
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
void SetMarginRight(int aRight)
void Move(const VECTOR2I &aMoveVector) override
Move this object.
int GetLegacyTextMargin() const
void syncLibCoords() override
void SetBottom(int aVal) override
EDA_ANGLE m_libTextAngle
VECTOR2I GetTopLeft() const override
VECTOR2I GetBotRight() const override
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true) override
void CopyFrom(const BOARD_ITEM *aOther) override
int GetBorderWidth() const
wxString GetShownText(RESOLUTION_CONTEXT aContext, int aDepth=0) const override
Return the string actually shown after processing of the base text.
std::vector< VECTOR2I > GetCorners() const override
Return 4 corners for a rectangle or rotated rectangle (stored as a poly).
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT, DRC_CONSTRAINT_T aUsage=NULL_CONSTRAINT) const override
Make a set of SHAPE objects representing the PCB_SHAPE.
PROPERTY_BASE & SetIsCopyable(bool aIsCopyable=true)
Definition property.h:359
Provide class metadata.Helper macro to map type hashes to names.
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()
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:38
VECTOR2I A
Definition seg.h:45
VECTOR2I B
Definition seg.h:46
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()
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections)
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 BooleanSubtract(const SHAPE_POLY_SET &b)
Perform boolean polyset difference.
VECTOR2I InverseApply(const VECTOR2I &aPoint) const
double GetScaleX() const
VECTOR2I Apply(const VECTOR2I &aPoint) const
double GetScaleY() const
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
void FinalizeTextVarExpansion(wxString &aText, RESOLUTION_CONTEXT aContext)
Definition common.cpp:88
wxString ResolveTextVars(const wxString &aSource, const std::function< bool(wxString *)> *aResolver, int &aDepth)
Multi-pass text variable expansion and math expression evaluation.
Definition common.cpp:333
RESOLUTION_CONTEXT
Definition common.h:87
@ FOR_GUI
Definition common.h:89
@ FOR_CANVAS
Definition common.h:88
@ RAW_VALUE
Definition common.h:94
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.
@ ROUND_ALL_CORNERS
All angles are rounded.
DRC_CONSTRAINT_T
Definition drc_rule.h:49
static std::string ToStdString(const wxString &aStr)
#define _(s)
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:422
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:424
static constexpr EDA_ANGLE ANGLE_270
Definition eda_angle.h:427
static constexpr EDA_ANGLE ANGLE_180
Definition eda_angle.h:426
#define PCB_EDIT_FRAME_NAME
SHAPE_T
Definition eda_shape.h:54
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
Definition eda_shape.h:57
static FILENAME_RESOLVER * resolver
a few functions useful in geometry calculations.
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
Definition layer_ids.h:180
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
Definition layer_ids.h:829
@ LAYER_LOCKED_ITEM_SHADOW
Shadow layer for locked items.
Definition layer_ids.h:303
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:56
This file contains miscellaneous commonly used macros and functions.
FLIP_DIRECTION
Definition mirror.h:23
@ LEFT_RIGHT
Flip left to right (around the Y axis)
Definition mirror.h:24
KICOMMON_API wxString EllipsizeMenuText(const wxString &aString)
Ellipsize text (at the end) to be no more than 36 characters.
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.
KICOMMON_API void PackCustomProperties(google::protobuf::RepeatedPtrField< types::CustomProperty > *aOutput, const EDA_ITEM &aItem)
KICOMMON_API VECTOR2I UnpackVector2(const types::Vector2 &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackVector2(types::Vector2 &aOutput, const VECTOR2I &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void UnpackCustomProperties(const google::protobuf::RepeatedPtrField< types::CustomProperty > &aInput, EDA_ITEM &aItem)
void PackTextAttributes(types::TextAttributes &aOutput, const TEXT_ATTRIBUTES &aInput, const EDA_IU_SCALE &aScale)
void UnpackTextAttributes(TEXT_ATTRIBUTES &aOutput, const types::TextAttributes &aInput, const EDA_IU_SCALE &aScale)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:411
#define _HKI(x)
Definition page_info.cpp:40
static struct PCB_TEXTBOX_DESC _PCB_TEXTBOX_DESC
#define TYPE_HASH(x)
Definition property.h:74
@ PT_SIZE
Size expressed in distance units (mm/inch)
Definition property.h:63
#define REGISTER_TYPE(x)
wxString UnescapeString(const wxString &aSource)
LINE_STYLE
Dashed line types.
KIBIS top(path, &reporter)
VECTOR2I center
int delta
GR_TEXT_H_ALIGN_T
This is API surface mapped to common.types.HorizontalAlignment.
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_H_ALIGN_INDETERMINATE
GR_TEXT_V_ALIGN_T
This is API surface mapped to common.types.VertialAlignment.
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_INDETERMINATE
@ GR_TEXT_V_ALIGN_CENTER
@ 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:225
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:70
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition typeinfo.h:85
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683
VECTOR2< double > VECTOR2D
Definition vector2d.h:682