KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_pin.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) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 2015 Wayne Stambaugh <[email protected]>
6 * Copyright (C) 2018 CERN
7 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
8 * @author Jon Evans <[email protected]>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
24#include "sch_pin.h"
25
26#include <api/api_enums.h>
27#include <api/api_utils.h>
28#include <base_units.h>
29#include <pgm_base.h>
30#include <pin_layout_cache.h>
31#include <plotters/plotter.h>
32#include <sch_draw_panel.h>
33#include <sch_edit_frame.h>
34#include <symbol_edit_frame.h>
37#include <trace_helpers.h>
38#include <trigo.h>
39#include <string_utils.h>
40#include <properties/property.h>
42#include <api/schematic/schematic_types.pb.h>
43
44wxString FormatStackedPinForDisplay( const wxString& aPinNumber, int aPinLength, int aTextSize, KIFONT::FONT* aFont,
45 const KIFONT::METRICS& aFontMetrics )
46{
47 // Check if this is stacked pin notation: [A,B,C]
48 if( !aPinNumber.StartsWith( "[" ) || !aPinNumber.EndsWith( "]" ) )
49 return aPinNumber;
50
51 // Escaping must never reach the user, so every display form below is built from the unescaped
52 // items. Range notation (e.g. 1-5) is preserved rather than expanded.
53 wxString inner = aPinNumber.Mid( 1, aPinNumber.Length() - 2 );
54 std::vector<wxString> parts = SplitStackedPinDisplayItems( inner );
55
56 if( parts.empty() )
57 return aPinNumber; // malformed; fallback
58
59 for( wxString& part : parts )
60 part.Trim( true ).Trim( false );
61
62 // Build the single-line (unescaped) form and check whether it fits along the pin.
63 wxString singleLine = "[";
64
65 for( size_t i = 0; i < parts.size(); ++i )
66 {
67 if( i > 0 )
68 singleLine += ",";
69
70 singleLine += parts[i];
71 }
72
73 singleLine += "]";
74
75 const int minPinTextWidth = schIUScale.MilsToIU( 50 );
76 const int maxPinTextWidth = std::max( aPinLength, minPinTextWidth );
77
78 VECTOR2D fontSize( aTextSize, aTextSize );
79 int penWidth = GetPenSizeForNormal( aTextSize );
80 VECTOR2I textExtents = aFont->StringBoundaryLimits( singleLine, fontSize, penWidth, false, false, aFontMetrics );
81
82 if( textExtents.x <= maxPinTextWidth )
83 return singleLine; // Fits already
84
85 // Build multi-line representation inside braces.
86 wxString result = "[";
87
88 for( size_t i = 0; i < parts.size(); ++i )
89 {
90 if( i > 0 )
91 result += "\n";
92
93 result += parts[i];
94 }
95
96 result += "]";
97 return result;
98}
99
100
101// small margin in internal units between the pin text and the pin line
102#define PIN_TEXT_MARGIN 4
103
107static int internalPinDecoSize( const RENDER_SETTINGS* aSettings, const SCH_PIN &aPin )
108{
109 const SCH_RENDER_SETTINGS* settings = static_cast<const SCH_RENDER_SETTINGS*>( aSettings );
110
111 if( settings && settings->m_PinSymbolSize )
112 return settings->m_PinSymbolSize;
113
114 return aPin.GetNameTextSize() != 0 ? aPin.GetNameTextSize() / 2 : aPin.GetNumberTextSize() / 2;
115}
116
117
121static int externalPinDecoSize( const RENDER_SETTINGS* aSettings, const SCH_PIN &aPin )
122{
123 const SCH_RENDER_SETTINGS* settings = static_cast<const SCH_RENDER_SETTINGS*>( aSettings );
124
125 if( settings && settings->m_PinSymbolSize )
126 return settings->m_PinSymbolSize;
127
128 return aPin.GetNumberTextSize() / 2;
129}
130
131
132SCH_PIN::SCH_PIN( LIB_SYMBOL* aParentSymbol ) :
133 SCH_ITEM( aParentSymbol, SCH_PIN_T, 0, 0 ),
134 m_libPin( nullptr ),
135 m_position( { 0, 0 } ),
136 m_length( schIUScale.MilsToIU( DEFAULT_PIN_LENGTH ) ),
137 m_orientation( PIN_ORIENTATION::PIN_RIGHT ),
138 m_shape( GRAPHIC_PINSHAPE::LINE ),
140 m_hidden( false ),
141 m_numTextSize( schIUScale.MilsToIU( DEFAULT_PINNUM_SIZE ) ),
142 m_nameTextSize( schIUScale.MilsToIU( DEFAULT_PINNAME_SIZE ) ),
143 m_isDangling( true )
144{
146 {
147 m_length = schIUScale.MilsToIU( cfg->m_Defaults.pin_length );
148 m_numTextSize = schIUScale.MilsToIU( cfg->m_Defaults.pin_num_size );
149 m_nameTextSize = schIUScale.MilsToIU( cfg->m_Defaults.pin_name_size );
150 }
151
152 m_layer = LAYER_DEVICE;
153}
154
155
156SCH_PIN::SCH_PIN( LIB_SYMBOL* aParentSymbol, const wxString& aName, const wxString& aNumber,
157 PIN_ORIENTATION aOrientation, ELECTRICAL_PINTYPE aPinType, int aLength,
158 int aNameTextSize, int aNumTextSize, int aBodyStyle, const VECTOR2I& aPos,
159 int aUnit ) :
160 SCH_ITEM( aParentSymbol, SCH_PIN_T, aUnit, aBodyStyle ),
161 m_libPin( nullptr ),
162 m_position( aPos ),
163 m_length( aLength ),
164 m_orientation( aOrientation ),
166 m_type( aPinType ),
167 m_hidden( false ),
168 m_numTextSize( aNumTextSize ),
169 m_nameTextSize( aNameTextSize ),
170 m_isDangling( true )
171{
172 SetName( aName );
173 SetNumber( aNumber );
174
176}
177
178
179SCH_PIN::SCH_PIN( SCH_SYMBOL* aParentSymbol, SCH_PIN* aLibPin ) :
180 SCH_ITEM( aParentSymbol, SCH_PIN_T, 0, 0 ),
181 m_libPin( aLibPin ),
185 m_isDangling( true )
186{
187 wxASSERT( aParentSymbol );
188
189 SetName( m_libPin->GetName() );
190 SetNumber( m_libPin->GetNumber() );
191 m_position = m_libPin->GetPosition();
192
194}
195
196
197SCH_PIN::SCH_PIN( SCH_SYMBOL* aParentSymbol, const wxString& aNumber, const wxString& aAlt,
198 const KIID& aUuid ) :
199 SCH_ITEM( aParentSymbol, SCH_PIN_T ),
200 m_libPin( nullptr ),
204 m_number( aNumber ),
205 m_alt( aAlt ),
206 m_isDangling( true )
207{
208 wxASSERT( aParentSymbol );
209
210 const_cast<KIID&>( m_Uuid ) = aUuid;
212}
213
214
215SCH_PIN::SCH_PIN( const SCH_PIN& aPin ) :
216 SCH_ITEM( aPin ),
217 m_libPin( aPin.m_libPin ),
219 m_position( aPin.m_position ),
220 m_length( aPin.m_length ),
222 m_shape( aPin.m_shape ),
223 m_type( aPin.m_type ),
224 m_hidden( aPin.m_hidden ),
227 m_alt( aPin.m_alt ),
229{
230 SetName( aPin.m_name );
231 SetNumber( aPin.m_number );
232
233 m_layer = aPin.m_layer;
234}
235
236
240
241
243{
244 SCH_ITEM::operator=( aPin );
245
246 m_libPin = aPin.m_libPin;
248 m_alt = aPin.m_alt;
249 m_name = aPin.m_name;
250 m_number = aPin.m_number;
251 m_position = aPin.m_position;
252 m_length = aPin.m_length;
254 m_shape = aPin.m_shape;
255 m_type = aPin.m_type;
256 m_hidden = aPin.m_hidden;
260 m_layoutCache.reset();
261
262 return *this;
263}
264
265
266void SCH_PIN::Serialize( google::protobuf::Any& aContainer ) const
267{
268 using namespace kiapi::common;
269 using namespace kiapi::schematic::types;
270 SchematicPin pin;
271
272 pin.mutable_id()->set_value( m_Uuid.AsStdString() );
273 pin.set_name( GetBaseName().ToUTF8() );
274 pin.set_number( GetNumber().ToUTF8() );
275
276 PackVector2( *pin.mutable_position(), GetPosition(), schIUScale );
277 PackDistance( *pin.mutable_length(), GetLength(), schIUScale );
279
282 pin.set_visible( IsVisible() );
283
284 PackDistance( *pin.mutable_name_text_size(), GetNameTextSize(), schIUScale );
285 PackDistance( *pin.mutable_number_text_size(), GetNumberTextSize(), schIUScale );
286
287 for( const ALT& alt : GetAlternates() | std::views::values )
288 {
289 SchematicPinAlternate* altProto = pin.add_alternates();
290 altProto->set_name( alt.m_Name.ToUTF8() );
291 altProto->set_shape( ToProtoEnum<GRAPHIC_PINSHAPE, SchematicPinShape>( alt.m_Shape ) );
292 altProto->set_electrical_type( ToProtoEnum<ELECTRICAL_PINTYPE, types::ElectricalPinType>( alt.m_Type ) );
293 }
294
295 if( !m_alt.IsEmpty() && m_alt != GetBaseName() )
296 pin.set_active_alternate( m_alt.ToUTF8() );
297
298 aContainer.PackFrom( pin );
299}
300
301
302bool SCH_PIN::Deserialize( const google::protobuf::Any& aContainer )
303{
304 using namespace kiapi::common;
305 using namespace kiapi::schematic::types;
306
307 SchematicPin pin;
308
309 if( !aContainer.UnpackTo( &pin ) )
310 return false;
311
312 const_cast<KIID&>( m_Uuid ) = KIID( pin.id().value() );
313 m_name = wxString::FromUTF8( pin.name() );
314 m_number = wxString::FromUTF8( pin.number() );
315
316 SetPosition( UnpackVector2( pin.position(), schIUScale ) );
317 SetLength( UnpackDistance( pin.length(), schIUScale ) );
319
320 m_type = FromProtoEnum<ELECTRICAL_PINTYPE>( pin.electrical_type() );
322 SetVisible( pin.visible() );
323
324 m_nameTextSize = UnpackDistance( pin.name_text_size(), schIUScale );
325 m_numTextSize = UnpackDistance( pin.number_text_size(), schIUScale );
326
327 std::map<wxString, ALT>& alts = GetAlternates();
328
329 for( const SchematicPinAlternate& altProto : pin.alternates() )
330 {
331 ALT alt;
332 alt.m_Name = wxString::FromUTF8( altProto.name() );
333 alt.m_Shape = FromProtoEnum<GRAPHIC_PINSHAPE>( altProto.shape() );
334 alt.m_Type = FromProtoEnum<ELECTRICAL_PINTYPE>( altProto.electrical_type() );
335 alts.emplace( alt.m_Name, alt );
336 }
337
338 if( m_layoutCache )
340
341 return true;
342}
343
344
346{
347 if( const SCH_SYMBOL* symbol = dynamic_cast<const SCH_SYMBOL*>( GetParentSymbol() ) )
348 return symbol->GetTransform().TransformCoordinate( m_position ) + symbol->GetPosition();
349 else
350 return m_position;
351}
352
354{
356 {
357 if( !m_libPin )
359
360 return m_libPin->GetOrientation();
361 }
362
363 return m_orientation;
364}
365
366
368{
369 if( !m_alt.IsEmpty() )
370 {
371 if( !m_libPin )
373
374 return m_libPin->GetAlt( m_alt ).m_Shape;
375 }
377 {
378 if( !m_libPin )
380
381 return m_libPin->GetShape();
382 }
383
384 return m_shape;
385}
386
387
389{
390 if( !m_length.has_value() )
391 {
392 if( !m_libPin )
393 return 0;
394
395 return m_libPin->GetLength();
396 }
397
398 return m_length.value();
399}
400
401
403{
404 if( !m_alt.IsEmpty() )
405 {
406 if( !m_libPin )
408
409 return m_libPin->GetAlt( m_alt ).m_Type;
410 }
412 {
413 if( !m_libPin )
415
416 return m_libPin->GetType();
417 }
418
419 return m_type;
420}
421
423{
424 if( aType == m_type )
425 return;
426
427 m_type = aType;
428
429 if( m_layoutCache )
431}
432
433
435{
436 // Use GetType() which correctly handles alternates
437 return ::GetCanonicalElectricalTypeName( GetType() );
438}
439
440
442{
443 // Use GetType() which correctly handles alternates
445}
446
447
449{
451 return false;
452
453 const SYMBOL* parent = GetParentSymbol();
454
455 if( parent->IsGlobalPower() )
456 return true;
457
458 // Local power symbols are never global, even with invisible pins
459 if( parent->IsLocalPower() )
460 return false;
461
462 // Legacy support: invisible power-in pins on non-power symbols act as global power
463 return !IsVisible();
464}
465
466
472
473
475{
476 return IsLocalPower() || IsGlobalPower();
477}
478
479
481{
482 if( !m_hidden.has_value() )
483 {
484 if( !m_libPin )
485 return true;
486
487 return m_libPin->IsVisible();
488 }
489
490 return !m_hidden.value();
491}
492
493
494const wxString& SCH_PIN::GetName() const
495{
496 if( !m_alt.IsEmpty() )
497 return m_alt;
498
499 return GetBaseName();
500}
501
502
503const wxString& SCH_PIN::GetBaseName() const
504{
505 if( m_libPin )
506 return m_libPin->GetBaseName();
507
508 return m_name;
509}
510
511
512void SCH_PIN::SetName( const wxString& aName )
513{
514 if( m_name == aName )
515 return;
516
517 m_name = aName;
518
519 // pin name string does not support spaces
520 m_name.Replace( wxT( " " ), wxT( "_" ) );
521
522 if( m_layoutCache )
524}
525
526
527void SCH_PIN::SetAlt( const wxString& aAlt )
528{
529 // Do not set the alternate pin definition to the default pin name. This breaks the library
530 // symbol comparison for the ERC and the library diff tool. It also incorrectly causes the
531 // schematic symbol pin alternate to be set.
532 if( aAlt.IsEmpty() || aAlt == GetBaseName() )
533 {
534 m_alt = wxEmptyString;
535 return;
536 }
537
538 if( !m_libPin )
539 {
540 wxFAIL_MSG( wxString::Format( wxS( "Pin '%s' has no corresponding lib_pin" ), m_number ) );
541 m_alt = wxEmptyString;
542 return;
543 }
544
545 if( !m_libPin->GetAlternates().contains( aAlt ) )
546 {
547 wxFAIL_MSG( wxString::Format( wxS( "Pin '%s' has no alterate '%s'" ), m_number, aAlt ) );
548 m_alt = wxEmptyString;
549 return;
550 }
551
552 m_alt = aAlt;
553}
554
556{
558 return false;
559
560 return m_isDangling;
561}
562
563
564void SCH_PIN::SetIsDangling( bool aIsDangling )
565{
566 m_isDangling = aIsDangling;
567}
568
569
570bool SCH_PIN::IsStacked( const SCH_PIN* aPin ) const
571{
572 const auto isPassiveOrNic = []( ELECTRICAL_PINTYPE t )
573 {
575 };
576
577 const bool sameParent = m_parent == aPin->GetParent();
578 const bool samePos = GetPosition() == aPin->GetPosition();
579 const bool sameName = GetName() == aPin->GetName();
580 const bool typeCompat = GetType() == aPin->GetType()
581 || isPassiveOrNic( GetType() )
582 || isPassiveOrNic( aPin->GetType() );
583
584 wxLogTrace( traceStackedPins,
585 wxString::Format( "IsStacked: this='%s/%s' other='%s/%s' sameParent=%d samePos=%d sameName=%d typeCompat=%d",
586 GetName(), GetNumber(), aPin->GetName(), aPin->GetNumber(), sameParent,
587 samePos, sameName, typeCompat ) );
588
589 return sameParent && samePos && sameName && typeCompat;
590}
591
592
593bool SCH_PIN::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
594{
595 const SCH_SEARCH_DATA& schSearchData =
596 dynamic_cast<const SCH_SEARCH_DATA&>( aSearchData );
597
598 if( schSearchData.searchAllPins
599 && ( EDA_ITEM::Matches( GetName(), aSearchData )
600 || EDA_ITEM::Matches( GetNumber(), aSearchData ) ) )
601 {
602 return true;
603 }
604
605 SCH_CONNECTION* connection = nullptr;
606 SCH_SHEET_PATH* sheetPath = reinterpret_cast<SCH_SHEET_PATH*>( aAuxData );
607
608 if( schSearchData.searchNetNames && sheetPath && ( connection = Connection( sheetPath ) ) )
609 {
610 wxString netName = connection->GetNetName();
611
612 if( EDA_ITEM::Matches( netName, aSearchData ) )
613 return true;
614 }
615
616 return false;
617}
618
619
620bool SCH_PIN::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
621{
622 bool isReplaced = false;
623
624 if( dynamic_cast<LIB_SYMBOL*>( GetParentSymbol() ) )
625 {
626 isReplaced |= EDA_ITEM::Replace( aSearchData, m_name );
627 isReplaced |= EDA_ITEM::Replace( aSearchData, m_number );
628 }
629 else
630 {
631 /* TODO: waiting on a way to override pins in the schematic...
632 isReplaced |= EDA_ITEM::Replace( aSearchData, m_name );
633 isReplaced |= EDA_ITEM::Replace( aSearchData, m_number );
634 */
635 }
636
637 return isReplaced;
638}
639
640
641bool SCH_PIN::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
642{
643 // When looking for an "exact" hit aAccuracy will be 0 which works poorly if the pin has
644 // no pin number or name. Give it a floor.
645 if( Schematic() )
646 aAccuracy = std::max( aAccuracy, Schematic()->Settings().m_PinSymbolSize / 4 );
647
648 BOX2I rect = GetBoundingBox( false, true, m_flags & SHOW_ELEC_TYPE );
649
650 return rect.Inflate( aAccuracy ).Contains( aPosition );
651}
652
653
654bool SCH_PIN::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
655{
657 return false;
658
659 BOX2I sel = aRect;
660
661 if ( aAccuracy )
662 sel.Inflate( aAccuracy );
663
664 if( aContained )
665 return sel.Contains( GetBoundingBox( false, false, false ) );
666
667 return sel.Intersects( GetBoundingBox( false, true, m_flags & SHOW_ELEC_TYPE ) );
668}
669
670
671const wxString& SCH_PIN::GetShownName() const
672{
673 if( !m_alt.IsEmpty() )
674 return m_alt;
675 else if( m_libPin )
676 return m_libPin->GetShownName();
677
678 return m_name;
679}
680
681
682const wxString& SCH_PIN::GetShownNumber() const
683{
684 return m_number;
685}
686
687
688std::vector<wxString> SCH_PIN::GetStackedPinNumbers( bool* aValid ) const
689{
690 const wxString& shown = GetShownNumber();
691 wxLogTrace( traceStackedPins, "GetStackedPinNumbers: shown='%s'", shown );
692
693 std::vector<wxString> numbers = ExpandStackedPinNotation( shown, aValid );
694
695 // Log the expansion for debugging
696 wxLogTrace( traceStackedPins, "Expanded '%s' to %zu pins", shown, numbers.size() );
697 for( const wxString& num : numbers )
698 {
699 wxLogTrace( traceStackedPins, wxString::Format( " -> '%s'", num ) );
700 }
701
702 return numbers;
703}
704
705
706int SCH_PIN::GetStackedPinCount( bool* aValid ) const
707{
708 const wxString& shown = GetShownNumber();
709 return CountStackedPinNotation( shown, aValid );
710}
711
712
713std::optional<wxString> SCH_PIN::GetSmallestLogicalNumber() const
714{
715 bool valid = false;
716 auto numbers = GetStackedPinNumbers( &valid );
717
718 if( valid && !numbers.empty() )
719 return numbers.front(); // Already in ascending order
720
721 return std::nullopt;
722}
723
724
726{
727 if( auto smallest = GetSmallestLogicalNumber() )
728 return *smallest;
729
730 return GetShownNumber();
731}
732
733
734void SCH_PIN::SetNumber( const wxString& aNumber )
735{
736 if( m_number == aNumber )
737 return;
738
739 m_number = aNumber;
740 // pin number string does not support spaces
741 m_number.Replace( wxT( " " ), wxT( "_" ) );
742
743 if( m_layoutCache )
745}
746
747
749{
750 if( !m_nameTextSize.has_value() )
751 {
752 if( !m_libPin )
753 return schIUScale.MilsToIU( DEFAULT_PINNAME_SIZE );
754
755 return m_libPin->GetNameTextSize();
756 }
757
758 return m_nameTextSize.value();
759}
760
761
763{
764 if( aSize == m_nameTextSize )
765 return;
766
767 m_nameTextSize = aSize;
768
769 if( m_layoutCache )
771}
772
773
775{
776 if( !m_numTextSize.has_value() )
777 {
778 if( !m_libPin )
779 return schIUScale.MilsToIU( DEFAULT_PINNUM_SIZE );
780
781 return m_libPin->GetNumberTextSize();
782 }
783
784 return m_numTextSize.value();
785}
786
787
789{
790 if( aSize == m_numTextSize )
791 return;
792
793 m_numTextSize = aSize;
794
795 if( m_layoutCache )
797}
798
799
801{
802 if( const SCH_SYMBOL* symbol = dynamic_cast<const SCH_SYMBOL*>( GetParentSymbol() ) )
803 {
804 const TRANSFORM& t = symbol->GetTransform();
805
806 if( !m_libPin )
807 return GetPosition();
808
809 return t.TransformCoordinate( m_libPin->GetPinRoot() ) + symbol->GetPosition();
810 }
811
812 switch( GetOrientation() )
813 {
814 default:
819 }
820}
821
822
823void SCH_PIN::PlotPinType( PLOTTER *aPlotter, const VECTOR2I &aPosition,
824 PIN_ORIENTATION aOrientation, bool aDimmed ) const
825{
826 int MapX1, MapY1, x1, y1;
827 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
828 COLOR4D color = renderSettings->GetLayerColor( LAYER_PIN );
829 COLOR4D bg = renderSettings->GetBackgroundColor();
830 int penWidth = GetEffectivePenWidth( renderSettings );
831 int pinLength = GetLength();
832
833 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
834 bg = COLOR4D::WHITE;
835
836 if( color.m_text && Schematic() )
837 color = COLOR4D( ResolveText( *color.m_text, &Schematic()->CurrentSheet() ) );
838
839 if( aDimmed )
840 {
841 color.Desaturate( );
842 color = color.Mix( bg, 0.5f );
843 }
844
845 aPlotter->SetColor( color );
846 aPlotter->SetCurrentLineWidth( penWidth );
847
848 MapX1 = MapY1 = 0;
849 x1 = aPosition.x; y1 = aPosition.y;
850
851 switch( aOrientation )
852 {
853 case PIN_ORIENTATION::PIN_UP: y1 = aPosition.y - pinLength; MapY1 = 1; break;
854 case PIN_ORIENTATION::PIN_DOWN: y1 = aPosition.y + pinLength; MapY1 = -1; break;
855 case PIN_ORIENTATION::PIN_LEFT: x1 = aPosition.x - pinLength; MapX1 = 1; break;
856 case PIN_ORIENTATION::PIN_RIGHT: x1 = aPosition.x + pinLength; MapX1 = -1; break;
857 case PIN_ORIENTATION::INHERIT: wxFAIL_MSG( wxS( "aOrientation must be resolved!" ) ); break;
858 }
859
861 {
862 const int radius = externalPinDecoSize( aPlotter->RenderSettings(), *this );
863 aPlotter->Circle( VECTOR2I( MapX1 * radius + x1, MapY1 * radius + y1 ), radius * 2,
864 FILL_T::NO_FILL, penWidth );
865
866 aPlotter->MoveTo( VECTOR2I( MapX1 * radius * 2 + x1, MapY1 * radius * 2 + y1 ) );
867 aPlotter->FinishTo( aPosition );
868 }
870 {
871 const int deco_size = internalPinDecoSize( aPlotter->RenderSettings(), *this );
872 if( MapY1 == 0 ) /* MapX1 = +- 1 */
873 {
874 aPlotter->MoveTo( VECTOR2I( x1, y1 + deco_size ) );
875 aPlotter->LineTo( VECTOR2I( x1 + MapX1 * deco_size * 2, y1 ) );
876 aPlotter->FinishTo( VECTOR2I( x1, y1 - deco_size ) );
877 }
878 else /* MapX1 = 0 */
879 {
880 aPlotter->MoveTo( VECTOR2I( x1 + deco_size, y1 ) );
881 aPlotter->LineTo( VECTOR2I( x1, y1 + MapY1 * deco_size * 2 ) );
882 aPlotter->FinishTo( VECTOR2I( x1 - deco_size, y1 ) );
883 }
884
885 aPlotter->MoveTo( VECTOR2I( MapX1 * deco_size * 2 + x1, MapY1 * deco_size * 2 + y1 ) );
886 aPlotter->FinishTo( aPosition );
887 }
888 else
889 {
890 aPlotter->MoveTo( VECTOR2I( x1, y1 ) );
891 aPlotter->FinishTo( aPosition );
892 }
893
897 {
898 const int deco_size = internalPinDecoSize( aPlotter->RenderSettings(), *this );
899
900 if( MapY1 == 0 ) /* MapX1 = +- 1 */
901 {
902 aPlotter->MoveTo( VECTOR2I( x1, y1 + deco_size ) );
903 aPlotter->LineTo( VECTOR2I( x1 - MapX1 * deco_size * 2, y1 ) );
904 aPlotter->FinishTo( VECTOR2I( x1, y1 - deco_size ) );
905 }
906 else /* MapX1 = 0 */
907 {
908 aPlotter->MoveTo( VECTOR2I( x1 + deco_size, y1 ) );
909 aPlotter->LineTo( VECTOR2I( x1, y1 - MapY1 * deco_size * 2 ) );
910 aPlotter->FinishTo( VECTOR2I( x1 - deco_size, y1 ) );
911 }
912 }
913
915 || m_shape == GRAPHIC_PINSHAPE::CLOCK_LOW ) /* IEEE symbol "Active Low Input" */
916 {
917 const int deco_size = externalPinDecoSize( aPlotter->RenderSettings(), *this );
918
919 if( MapY1 == 0 ) /* MapX1 = +- 1 */
920 {
921 aPlotter->MoveTo( VECTOR2I( x1 + MapX1 * deco_size * 2, y1 ) );
922 aPlotter->LineTo( VECTOR2I( x1 + MapX1 * deco_size * 2, y1 - deco_size * 2 ) );
923 aPlotter->FinishTo( VECTOR2I( x1, y1 ) );
924 }
925 else /* MapX1 = 0 */
926 {
927 aPlotter->MoveTo( VECTOR2I( x1, y1 + MapY1 * deco_size * 2 ) );
928 aPlotter->LineTo( VECTOR2I( x1 - deco_size * 2, y1 + MapY1 * deco_size * 2 ) );
929 aPlotter->FinishTo( VECTOR2I( x1, y1 ) );
930 }
931 }
932
933 if( m_shape == GRAPHIC_PINSHAPE::OUTPUT_LOW ) /* IEEE symbol "Active Low Output" */
934 {
935 const int symbol_size = externalPinDecoSize( aPlotter->RenderSettings(), *this );
936
937 if( MapY1 == 0 ) /* MapX1 = +- 1 */
938 {
939 aPlotter->MoveTo( VECTOR2I( x1, y1 - symbol_size * 2 ) );
940 aPlotter->FinishTo( VECTOR2I( x1 + MapX1 * symbol_size * 2, y1 ) );
941 }
942 else /* MapX1 = 0 */
943 {
944 aPlotter->MoveTo( VECTOR2I( x1 - symbol_size * 2, y1 ) );
945 aPlotter->FinishTo( VECTOR2I( x1, y1 + MapY1 * symbol_size * 2 ) );
946 }
947 }
948 else if( m_shape == GRAPHIC_PINSHAPE::NONLOGIC ) /* NonLogic pin symbol */
949 {
950 const int deco_size = externalPinDecoSize( aPlotter->RenderSettings(), *this );
951 aPlotter->MoveTo( VECTOR2I( x1 - ( MapX1 + MapY1 ) * deco_size,
952 y1 - ( MapY1 - MapX1 ) * deco_size ) );
953 aPlotter->FinishTo( VECTOR2I( x1 + ( MapX1 + MapY1 ) * deco_size,
954 y1 + ( MapY1 - MapX1 ) * deco_size ) );
955 aPlotter->MoveTo( VECTOR2I( x1 - ( MapX1 - MapY1 ) * deco_size,
956 y1 - ( MapY1 + MapX1 ) * deco_size ) );
957 aPlotter->FinishTo( VECTOR2I( x1 + ( MapX1 - MapY1 ) * deco_size,
958 y1 + ( MapY1 + MapX1 ) * deco_size ) );
959 }
960
961 if( GetType() == ELECTRICAL_PINTYPE::PT_NC ) // Draw a N.C. symbol
962 {
963 const int deco_size = TARGET_PIN_RADIUS;
964 const int ex1 = aPosition.x;
965 const int ey1 = aPosition.y;
966 aPlotter->MoveTo( VECTOR2I( ex1 - deco_size, ey1 - deco_size ) );
967 aPlotter->FinishTo( VECTOR2I( ex1 + deco_size, ey1 + deco_size ) );
968 aPlotter->MoveTo( VECTOR2I( ex1 + deco_size, ey1 - deco_size ) );
969 aPlotter->FinishTo( VECTOR2I( ex1 - deco_size, ey1 + deco_size ) );
970 }
971}
972
973
974void SCH_PIN::PlotPinTexts( PLOTTER *aPlotter, const VECTOR2I &aPinPos, PIN_ORIENTATION aPinOrient,
975 int aTextInside, bool aDrawPinNum, bool aDrawPinName, bool aDimmed ) const
976{
977 RENDER_SETTINGS* settings = aPlotter->RenderSettings();
978 KIFONT::FONT* font = KIFONT::FONT::GetFont( settings->GetDefaultFont(), false, false );
979 wxString name = GetShownName();
980 wxString number = GetShownNumber();
981
982 // Apply stacked pin display formatting (reuse helper from pin_layout_cache)
983 if( aDrawPinNum && !number.IsEmpty() )
984 {
985 const KIFONT::METRICS& metrics = GetFontMetrics();
986 number = FormatStackedPinForDisplay( number, GetLength(), GetNumberTextSize(), font, metrics );
987 }
988
989 if( name.IsEmpty() || m_nameTextSize == 0 )
990 aDrawPinName = false;
991
992 if( number.IsEmpty() || m_numTextSize == 0 )
993 aDrawPinNum = false;
994
995 if( !aDrawPinNum && !aDrawPinName )
996 return;
997
998 int namePenWidth = settings->GetDefaultPenWidth();
999 int numPenWidth = settings->GetDefaultPenWidth();
1000 int name_offset = schIUScale.MilsToIU( PIN_TEXT_MARGIN ) + namePenWidth;
1001 int num_offset = schIUScale.MilsToIU( PIN_TEXT_MARGIN ) + numPenWidth;
1002
1003 COLOR4D nameColor = settings->GetLayerColor( LAYER_PINNAM );
1004 COLOR4D numColor = settings->GetLayerColor( LAYER_PINNUM );
1005 COLOR4D bg = settings->GetBackgroundColor();
1006
1007 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
1008 bg = COLOR4D::WHITE;
1009
1010 if( nameColor.m_text && Schematic() )
1011 nameColor = COLOR4D( ResolveText( *nameColor.m_text, &Schematic()->CurrentSheet() ) );
1012
1013 if( numColor.m_text && Schematic() )
1014 numColor = COLOR4D( ResolveText( *numColor.m_text, &Schematic()->CurrentSheet() ) );
1015
1016 if( aDimmed )
1017 {
1018 nameColor.Desaturate();
1019 numColor.Desaturate();
1020 nameColor = nameColor.Mix( bg, 0.5f );
1021 numColor = numColor.Mix( bg, 0.5f );
1022 }
1023
1024 int x1 = aPinPos.x;
1025 int y1 = aPinPos.y;
1026
1027 switch( aPinOrient )
1028 {
1029 case PIN_ORIENTATION::PIN_UP: y1 -= GetLength(); break;
1030 case PIN_ORIENTATION::PIN_DOWN: y1 += GetLength(); break;
1031 case PIN_ORIENTATION::PIN_LEFT: x1 -= GetLength(); break;
1032 case PIN_ORIENTATION::PIN_RIGHT: x1 += GetLength(); break;
1033 default: break;
1034 }
1035
1036 auto plotSimpleText =
1037 [&]( int x, int y, const EDA_ANGLE& angle, GR_TEXT_H_ALIGN_T hJustify, GR_TEXT_V_ALIGN_T vJustify,
1038 const wxString& txt, int size, int penWidth, const COLOR4D& col )
1039 {
1040 TEXT_ATTRIBUTES attrs;
1041 attrs.m_StrokeWidth = penWidth;
1042 attrs.m_Angle = angle;
1043 attrs.m_Size = VECTOR2I( size, size );
1044 attrs.m_Halign = hJustify;
1045 attrs.m_Valign = vJustify;
1046 attrs.m_Multiline = false; // we'll manage multi-line manually
1047 aPlotter->PlotText( VECTOR2I( x, y ), col, txt, attrs, font, GetFontMetrics() );
1048 };
1049
1050 auto plotMultiLineWithBraces =
1051 [&]( int anchorX, int anchorY, EDA_ANGLE angle, GR_TEXT_V_ALIGN_T vAlign, bool /*numberBlock*/ )
1052 {
1053 // If not multi-line formatted, just plot single line centered.
1054 if( !number.StartsWith( "[" ) || !number.EndsWith( "]" ) || !number.Contains( "\n" ) )
1055 {
1056 plotSimpleText( anchorX, anchorY, angle, GR_TEXT_H_ALIGN_CENTER, vAlign, number,
1057 GetNumberTextSize(), numPenWidth, numColor );
1058 return;
1059 }
1060
1061 wxString content = number.Mid( 1, number.Length() - 2 );
1062 wxArrayString lines;
1063 wxStringSplit( content, lines, '\n' );
1064
1065 if( lines.size() <= 1 )
1066 {
1067 plotSimpleText( anchorX, anchorY, angle, GR_TEXT_H_ALIGN_CENTER, vAlign, content,
1068 GetNumberTextSize(), numPenWidth, numColor );
1069 return;
1070 }
1071
1072 int textSize = GetNumberTextSize();
1073 int lineSpacing = KiROUND( textSize * 1.3 );
1074 const KIFONT::METRICS& metrics = GetFontMetrics();
1075
1076 // Measure line widths for brace spacing
1077 int maxLineWidth = 0;
1078 for( const wxString& rawLine : lines )
1079 {
1080 wxString trimmed = rawLine; trimmed.Trim(true).Trim(false);
1081 VECTOR2I ext = font->StringBoundaryLimits( trimmed, VECTOR2D( textSize, textSize ),
1082 GetPenSizeForNormal( textSize ), false, false, metrics );
1083 if( ext.x > maxLineWidth )
1084 maxLineWidth = ext.x;
1085 }
1086
1087 // Determine starting position
1088 int startX = anchorX;
1089 int startY = anchorY;
1090
1091 if( angle == ANGLE_VERTICAL )
1092 {
1093 int totalWidth = ( (int) lines.size() - 1 ) * lineSpacing;
1094 startX -= totalWidth;
1095 }
1096 else
1097 {
1098 int totalHeight = ( (int) lines.size() - 1 ) * lineSpacing;
1099 startY -= totalHeight;
1100 }
1101
1102 for( size_t i = 0; i < lines.size(); ++i )
1103 {
1104 wxString l = lines[i]; l.Trim( true ).Trim( false );
1105 int lx = startX + ( angle == ANGLE_VERTICAL ? (int) i * lineSpacing : 0 );
1106 int ly = startY + ( angle == ANGLE_VERTICAL ? 0 : (int) i * lineSpacing );
1107 plotSimpleText( lx, ly, angle, GR_TEXT_H_ALIGN_CENTER, vAlign, l, textSize, numPenWidth, numColor );
1108 }
1109
1110 // Now draw braces emulating SCH_PAINTER brace geometry
1111 auto plotBrace =
1112 [&]( const VECTOR2I& top, const VECTOR2I& bottom, bool leftOrTop, bool isVerticalText )
1113 {
1114 // Build 4 small segments approximating curly brace
1115 VECTOR2I mid = ( top + bottom ) / 2;
1116 int braceWidth = textSize / 3; // same scale as painter
1117 VECTOR2I p1 = top;
1118 VECTOR2I p5 = bottom;
1119 VECTOR2I p2 = top;
1120 VECTOR2I p3 = mid;
1121 VECTOR2I p4 = bottom;
1122 int offset = leftOrTop ? -braceWidth : braceWidth;
1123
1124 if( isVerticalText )
1125 {
1126 // Text vertical => brace extends in Y (horizontal brace lines across X axis set)
1127 // For vertical orientation we offset Y for p2/p3/p4
1128 p2.y += offset / 2;
1129 p3.y += offset;
1130 p4.y += offset / 2;
1131 }
1132 else
1133 {
1134 // Horizontal text => brace extends in X
1135 p2.x += offset / 2;
1136 p3.x += offset;
1137 p4.x += offset / 2;
1138 }
1139
1140 aPlotter->MoveTo( p1 ); aPlotter->FinishTo( p2 );
1141 aPlotter->MoveTo( p2 ); aPlotter->FinishTo( p3 );
1142 aPlotter->MoveTo( p3 ); aPlotter->FinishTo( p4 );
1143 aPlotter->MoveTo( p4 ); aPlotter->FinishTo( p5 );
1144 };
1145
1146 aPlotter->SetCurrentLineWidth( numPenWidth );
1147 int braceWidth = textSize / 3;
1148 int extraHeight = textSize / 3; // extend beyond text block
1149
1150 if( angle == ANGLE_VERTICAL )
1151 {
1152 // Lines spaced horizontally, braces horizontal (above & below)
1153 int totalWidth = ( (int) lines.size() - 1 ) * lineSpacing;
1154 VECTOR2I braceStart( startX - 2 * extraHeight, anchorY );
1155 VECTOR2I braceEnd( startX + totalWidth + extraHeight, anchorY );
1156 int braceSpacing = maxLineWidth / 2 + braceWidth;
1157
1158 VECTOR2I topStart = braceStart; topStart.y -= braceSpacing;
1159 VECTOR2I topEnd = braceEnd; topEnd.y -= braceSpacing;
1160 VECTOR2I bottomStart = braceStart; bottomStart.y += braceSpacing;
1161 VECTOR2I bottomEnd = braceEnd; bottomEnd.y += braceSpacing;
1162
1163 plotBrace( topStart, topEnd, true, true ); // leftOrTop=true
1164 plotBrace( bottomStart, bottomEnd, false, true );
1165 }
1166 else
1167 {
1168 // Lines spaced vertically, braces vertical (left & right)
1169 int totalHeight = ( (int) lines.size() - 1 ) * lineSpacing;
1170 VECTOR2I braceStart( anchorX, startY - 2 * extraHeight );
1171 VECTOR2I braceEnd( anchorX, startY + totalHeight + extraHeight );
1172 int braceSpacing = maxLineWidth / 2 + braceWidth;
1173
1174 VECTOR2I leftTop = braceStart; leftTop.x -= braceSpacing;
1175 VECTOR2I leftBot = braceEnd; leftBot.x -= braceSpacing;
1176 VECTOR2I rightTop = braceStart; rightTop.x += braceSpacing;
1177 VECTOR2I rightBot = braceEnd; rightBot.x += braceSpacing;
1178
1179 plotBrace( leftTop, leftBot, true, false );
1180 plotBrace( rightTop, rightBot, false, false );
1181 }
1182 };
1183
1184 // Logic largely mirrors original single-line placement but calls multi-line path for numbers
1185 if( aTextInside )
1186 {
1187 if( ( aPinOrient == PIN_ORIENTATION::PIN_LEFT ) || ( aPinOrient == PIN_ORIENTATION::PIN_RIGHT ) )
1188 {
1189 if( aDrawPinName )
1190 {
1191 if( aPinOrient == PIN_ORIENTATION::PIN_RIGHT )
1192 {
1193 plotSimpleText( x1 + aTextInside, y1, ANGLE_HORIZONTAL, GR_TEXT_H_ALIGN_LEFT,
1194 GR_TEXT_V_ALIGN_CENTER, name, GetNameTextSize(), namePenWidth, nameColor );
1195 }
1196 else
1197 {
1198 plotSimpleText( x1 - aTextInside, y1, ANGLE_HORIZONTAL, GR_TEXT_H_ALIGN_RIGHT,
1199 GR_TEXT_V_ALIGN_CENTER, name, GetNameTextSize(), namePenWidth, nameColor );
1200 }
1201 }
1202
1203 if( aDrawPinNum )
1204 {
1205 plotMultiLineWithBraces( ( x1 + aPinPos.x ) / 2, y1 - num_offset, ANGLE_HORIZONTAL,
1206 GR_TEXT_V_ALIGN_BOTTOM, true );
1207 }
1208 }
1209 else
1210 {
1211 if( aPinOrient == PIN_ORIENTATION::PIN_DOWN )
1212 {
1213 if( aDrawPinName )
1214 {
1215 plotSimpleText( x1, y1 + aTextInside, ANGLE_VERTICAL, GR_TEXT_H_ALIGN_RIGHT,
1216 GR_TEXT_V_ALIGN_CENTER, name, GetNameTextSize(), namePenWidth, nameColor );
1217 }
1218
1219 if( aDrawPinNum )
1220 {
1221 plotMultiLineWithBraces( x1 - num_offset, ( y1 + aPinPos.y ) / 2, ANGLE_VERTICAL,
1222 GR_TEXT_V_ALIGN_BOTTOM, true );
1223 }
1224 }
1225 else // PIN_UP
1226 {
1227 if( aDrawPinName )
1228 {
1229 plotSimpleText( x1, y1 - aTextInside, ANGLE_VERTICAL, GR_TEXT_H_ALIGN_LEFT,
1230 GR_TEXT_V_ALIGN_CENTER, name, GetNameTextSize(), namePenWidth, nameColor );
1231 }
1232
1233 if( aDrawPinNum )
1234 {
1235 plotMultiLineWithBraces( x1 - num_offset, ( y1 + aPinPos.y ) / 2, ANGLE_VERTICAL,
1236 GR_TEXT_V_ALIGN_BOTTOM, true );
1237 }
1238 }
1239 }
1240 }
1241 else
1242 {
1243 if( ( aPinOrient == PIN_ORIENTATION::PIN_LEFT ) || ( aPinOrient == PIN_ORIENTATION::PIN_RIGHT ) )
1244 {
1245 if( aDrawPinName && aDrawPinNum )
1246 {
1247 plotSimpleText( ( x1 + aPinPos.x ) / 2, y1 - name_offset, ANGLE_HORIZONTAL,
1249 GetNameTextSize(), namePenWidth, nameColor );
1250 plotMultiLineWithBraces( ( x1 + aPinPos.x ) / 2, y1 + num_offset, ANGLE_HORIZONTAL,
1251 GR_TEXT_V_ALIGN_TOP, true );
1252 }
1253 else if( aDrawPinName )
1254 {
1255 plotSimpleText( ( x1 + aPinPos.x ) / 2, y1 - name_offset, ANGLE_HORIZONTAL,
1257 GetNameTextSize(), namePenWidth, nameColor );
1258 }
1259 else if( aDrawPinNum )
1260 {
1261 plotMultiLineWithBraces( ( x1 + aPinPos.x ) / 2, y1 - name_offset, ANGLE_HORIZONTAL,
1262 GR_TEXT_V_ALIGN_BOTTOM, true );
1263 }
1264 }
1265 else
1266 {
1267 if( aDrawPinName && aDrawPinNum )
1268 {
1269 plotSimpleText( x1 - name_offset, ( y1 + aPinPos.y ) / 2, ANGLE_VERTICAL,
1271 GetNameTextSize(), namePenWidth, nameColor );
1272 plotMultiLineWithBraces( x1 + num_offset, ( y1 + aPinPos.y ) / 2, ANGLE_VERTICAL,
1273 GR_TEXT_V_ALIGN_TOP, true );
1274 }
1275 else if( aDrawPinName )
1276 {
1277 plotSimpleText( x1 - name_offset, ( y1 + aPinPos.y ) / 2, ANGLE_VERTICAL,
1279 GetNameTextSize(), namePenWidth, nameColor );
1280 }
1281 else if( aDrawPinNum )
1282 {
1283 plotMultiLineWithBraces( x1 - num_offset, ( y1 + aPinPos.y ) / 2, ANGLE_VERTICAL,
1284 GR_TEXT_V_ALIGN_BOTTOM, true );
1285 }
1286 }
1287 }
1288}
1289
1290
1292{
1293 PIN_ORIENTATION orient;
1294 VECTOR2I end; // position of pin end starting at 0,0 according to its orientation, length = 1
1295
1296 switch( GetOrientation() )
1297 {
1298 default:
1299 case PIN_ORIENTATION::PIN_RIGHT: end.x = 1; break;
1300 case PIN_ORIENTATION::PIN_UP: end.y = -1; break;
1301 case PIN_ORIENTATION::PIN_DOWN: end.y = 1; break;
1302 case PIN_ORIENTATION::PIN_LEFT: end.x = -1; break;
1303 }
1304
1305 // = pos of end point, according to the symbol orientation.
1306 end = aTransform.TransformCoordinate( end );
1307 orient = PIN_ORIENTATION::PIN_UP;
1308
1309 if( end.x == 0 )
1310 {
1311 if( end.y > 0 )
1313 }
1314 else
1315 {
1317
1318 if( end.x < 0 )
1320 }
1321
1322 return orient;
1323}
1324
1325
1327{
1328 //return new SCH_PIN( *this );
1329 SCH_ITEM* newPin = new SCH_PIN( *this );
1330 wxASSERT( newPin->GetUnit() == m_unit && newPin->GetBodyStyle() == m_bodyStyle );
1331 return newPin;
1332}
1333
1334
1335void SCH_PIN::ChangeLength( int aLength )
1336{
1337 int lengthChange = GetLength() - aLength;
1338 int offsetX = 0;
1339 int offsetY = 0;
1340
1341 switch( GetOrientation() )
1342 {
1343 default:
1345 offsetX = lengthChange;
1346 break;
1348 offsetX = -1 * lengthChange;
1349 break;
1351 offsetY = -1 * lengthChange;
1352 break;
1354 offsetY = lengthChange;
1355 break;
1356 }
1357
1358 m_position += VECTOR2I( offsetX, offsetY );
1359 m_length = aLength;
1360}
1361
1362
1363void SCH_PIN::Move( const VECTOR2I& aOffset )
1364{
1365 m_position += aOffset;
1366}
1367
1368
1370{
1371 m_position.x -= aCenter;
1372 m_position.x *= -1;
1373 m_position.x += aCenter;
1374
1379}
1380
1381
1383{
1384 if( dynamic_cast<LIB_SYMBOL*>( GetParentSymbol() ) )
1385 MirrorHorizontallyPin( aCenter );
1386}
1387
1388
1390{
1391 m_position.y -= aCenter;
1392 m_position.y *= -1;
1393 m_position.y += aCenter;
1394
1399}
1400
1401
1402void SCH_PIN::MirrorVertically( int aCenter )
1403{
1404 if( dynamic_cast<LIB_SYMBOL*>( GetParentSymbol() ) )
1405 MirrorVerticallyPin( aCenter );
1406}
1407
1408
1409void SCH_PIN::RotatePin( const VECTOR2I& aCenter, bool aRotateCCW )
1410{
1411 if( aRotateCCW )
1412 {
1413 RotatePoint( m_position, aCenter, ANGLE_90 );
1414
1415 switch( GetOrientation() )
1416 {
1417 default:
1422 }
1423 }
1424 else
1425 {
1426 RotatePoint( m_position, aCenter, -ANGLE_90 );
1427
1428 switch( GetOrientation() )
1429 {
1430 default:
1435 }
1436 }
1437}
1438
1439
1440void SCH_PIN::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
1441{
1442 if( dynamic_cast<LIB_SYMBOL*>( GetParentSymbol() ) )
1443 RotatePin( aCenter, aRotateCCW );
1444}
1445
1446
1447void SCH_PIN::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts,
1448 int aUnit, int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed )
1449{
1450 if( aBackground )
1451 return;
1452
1453 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
1454
1455 if( !IsVisible() && !renderSettings->m_ShowHiddenPins )
1456 return;
1457
1458 const SYMBOL* part = GetParentSymbol();
1459 PIN_ORIENTATION orient = PinDrawOrient( renderSettings->m_Transform );
1460 VECTOR2I pos = renderSettings->TransformCoordinate( m_position ) + aOffset;
1461
1462 PlotPinType( aPlotter, pos, orient, aDimmed );
1463 PlotPinTexts( aPlotter, pos, orient, part->GetPinNameOffset(), part->GetShowPinNumbers(),
1464 part->GetShowPinNames(), aDimmed );
1465}
1466
1467
1468void SCH_PIN::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1469{
1470 SYMBOL* symbol = GetParentSymbol();
1471
1472 aList.emplace_back( _( "Type" ), _( "Pin" ) );
1473
1474 SCH_ITEM::GetMsgPanelInfo( aFrame, aList );
1475
1476 aList.emplace_back( _( "Name" ), UnescapeString( GetShownName() ) );
1477 aList.emplace_back( _( "Number" ), GetShownNumber() );
1478 aList.emplace_back( _( "Type" ), ElectricalPinTypeGetText( GetType() ) );
1479 aList.emplace_back( _( "Style" ), PinShapeGetText( GetShape() ) );
1480
1481 aList.emplace_back( _( "Visible" ), IsVisible() ? _( "Yes" ) : _( "No" ) );
1482
1483 // Display pin length
1484 aList.emplace_back( _( "Length" ), aFrame->MessageTextFromValue( GetLength(), true ) );
1485
1486 aList.emplace_back( _( "Orientation" ), PinOrientationName( GetOrientation() ) );
1487
1488 if( dynamic_cast<LIB_SYMBOL*>( symbol ) )
1489 {
1490 aList.emplace_back( _( "Pos X" ), aFrame->MessageTextFromValue( GetPosition().x, true ) );
1491 aList.emplace_back( _( "Pos Y" ), aFrame->MessageTextFromValue( GetPosition().y, true ) );
1492 }
1493 else if( SCH_SYMBOL* schsymbol = dynamic_cast<SCH_SYMBOL*>( symbol ) )
1494 {
1495 SCH_EDIT_FRAME* schframe = dynamic_cast<SCH_EDIT_FRAME*>( aFrame );
1496 SCH_SHEET_PATH* currentSheet = schframe ? &schframe->GetCurrentSheet() : nullptr;
1497
1498 // Don't use GetShownText(); we want to see the variable references here
1499 aList.emplace_back( symbol->GetRef( currentSheet ),
1500 UnescapeString( schsymbol->GetField( FIELD_T::VALUE )->GetText() ) );
1501 }
1502
1503#if defined(DEBUG)
1504 if( !IsConnectivityDirty() && dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) )
1505 {
1506 SCH_CONNECTION* conn = Connection();
1507
1508 if( conn )
1509 conn->AppendInfoToMsgPanel( aList );
1510 }
1511#endif
1512}
1513
1514
1516{
1517 std::lock_guard<std::recursive_mutex> lock( m_netmap_mutex );
1518
1519 if( aPath )
1520 m_net_name_map.erase( *aPath );
1521 else
1522 m_net_name_map.clear();
1523}
1524
1525
1526wxString SCH_PIN::GetDefaultNetName( const SCH_SHEET_PATH& aPath, bool aForceNoConnect )
1527{
1528 const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( GetParentSymbol() );
1529
1530 // Need to check for parent as power symbol to make sure we aren't dealing
1531 // with legacy global power pins on non-power symbols
1532 if( IsGlobalPower() || IsLocalPower() )
1533 {
1534 SYMBOL* parent = GetLibPin() ? GetLibPin()->GetParentSymbol() : nullptr;
1535
1536 if( parent && ( parent->IsGlobalPower() || parent->IsLocalPower() ) )
1537 {
1538 return EscapeString( symbol->GetValue( true, &aPath, false ), CTX_NETNAME );
1539 }
1540 else
1541 {
1542 wxString tmp = m_libPin ? m_libPin->GetName() : wxString( "??" );
1543
1544 return EscapeString( tmp, CTX_NETNAME );
1545 }
1546 }
1547
1548 std::lock_guard<std::recursive_mutex> lock( m_netmap_mutex );
1549
1550 auto it = m_net_name_map.find( aPath );
1551
1552 if( it != m_net_name_map.end() )
1553 {
1554 if( it->second.second == aForceNoConnect )
1555 return it->second.first;
1556 }
1557
1558 wxString name = "Net-(";
1559 bool unconnected = false;
1560
1561 if( aForceNoConnect || GetType() == ELECTRICAL_PINTYPE::PT_NC )
1562 {
1563 unconnected = true;
1564 name = ( "unconnected-(" );
1565 }
1566
1567 bool annotated = true;
1568
1569 std::vector<const SCH_PIN*> pins = symbol->GetPins( &aPath );
1570 bool has_multiple = false;
1571
1572 for( const SCH_PIN* pin : pins )
1573 {
1574 if( pin->GetShownName() == GetShownName()
1575 && pin->GetShownNumber() != GetShownNumber()
1576 && unconnected == ( pin->GetType() == ELECTRICAL_PINTYPE::PT_NC ) )
1577 {
1578 has_multiple = true;
1579 break;
1580 }
1581 }
1582
1583 wxString libPinShownName = m_libPin ? m_libPin->GetShownName() : wxString( "??" );
1584 wxString libPinShownNumber = m_libPin ? m_libPin->GetShownNumber() : wxString( "??" );
1585 wxString effectivePadNumber = m_libPin ? m_libPin->GetEffectivePadNumber() : libPinShownNumber;
1586
1587 if( effectivePadNumber != libPinShownNumber )
1588 {
1589 wxLogTrace( traceStackedPins,
1590 wxString::Format( "GetDefaultNetName: stacked pin shown='%s' -> using smallest logical='%s'",
1591 libPinShownNumber, effectivePadNumber ) );
1592 }
1593
1594 // Use timestamp for unannotated symbols
1595 if( symbol->GetRef( &aPath, false ).Last() == '?' )
1596 {
1598
1599 wxString libPinNumber = m_libPin ? m_libPin->GetNumber() : wxString( "??" );
1600 // Apply same smallest-logical substitution for unannotated symbols
1601 if( effectivePadNumber != libPinShownNumber && !effectivePadNumber.IsEmpty() )
1602 libPinNumber = effectivePadNumber;
1603
1604 name << "-Pad" << libPinNumber << ")";
1605 annotated = false;
1606 }
1607 else if( !libPinShownName.IsEmpty() && ( libPinShownName != libPinShownNumber ) )
1608 {
1609 // Pin names might not be unique between different units so we must have the
1610 // unit token in the reference designator
1611 name << symbol->GetRef( &aPath, true );
1612 name << "-" << EscapeString( libPinShownName, CTX_NETNAME );
1613
1614 if( unconnected || has_multiple )
1615 {
1616 // Use effective (possibly de-stacked) pad number in net name
1617 name << "-Pad" << EscapeString( effectivePadNumber, CTX_NETNAME );
1618 }
1619
1620 name << ")";
1621 }
1622 else
1623 {
1624 // Pin numbers are unique, so we skip the unit token
1625 name << symbol->GetRef( &aPath, false );
1626 name << "-Pad" << EscapeString( effectivePadNumber, CTX_NETNAME ) << ")";
1627 }
1628
1629 if( annotated )
1630 m_net_name_map[ aPath ] = std::make_pair( name, aForceNoConnect );
1631
1632 return name;
1633}
1634
1635
1637{
1638 return GetBoundingBox( false, true, m_flags & SHOW_ELEC_TYPE );
1639}
1640
1641
1647
1648
1649void SCH_PIN::validateExtentsCache( KIFONT::FONT* aFont, int aSize, const wxString& aText,
1650 EXTENTS_CACHE* aCache ) const
1651{
1652 if( aCache->m_Font == aFont
1653 && aCache->m_FontSize == aSize
1654 && aCache->m_Extents != VECTOR2I() )
1655 {
1656 return;
1657 }
1658
1659 aCache->m_Font = aFont;
1660 aCache->m_FontSize = aSize;
1661
1662 VECTOR2D fontSize( aSize, aSize );
1663 int penWidth = GetPenSizeForNormal( aSize );
1664
1665 aCache->m_Extents = aFont->StringBoundaryLimits( aText, fontSize, penWidth, false, false,
1666 GetFontMetrics() );
1667}
1668
1669
1670BOX2I SCH_PIN::GetBoundingBox( bool aIncludeLabelsOnInvisiblePins, bool aIncludeNameAndNumber,
1671 bool aIncludeElectricalType ) const
1672{
1673 // Just defer to the cache
1674 return GetLayoutCache().GetPinBoundingBox( aIncludeLabelsOnInvisiblePins,
1675 aIncludeNameAndNumber,
1676 aIncludeElectricalType );
1677}
1678
1679
1681{
1682 if( !m_layoutCache )
1683 m_layoutCache = std::make_unique<PIN_LAYOUT_CACHE>( *this );
1684
1685 return *m_layoutCache;
1686}
1687
1688
1690 const SCH_SHEET_PATH* aInstance ) const
1691{
1692 // Do not compare to ourself.
1693 if( aItem == this )
1694 return false;
1695
1696 const SCH_PIN* pin = dynamic_cast<const SCH_PIN*>( aItem );
1697
1698 // Don't compare against a different SCH_ITEM.
1699 wxCHECK( pin, false );
1700
1701 if( GetPosition() != pin->GetPosition() )
1702 return true;
1703
1704 if( GetNumber() != pin->GetNumber() )
1705 return true;
1706
1707 if( GetName() != pin->GetName() )
1708 return true;
1709
1710 // For power input pins, visibility changes affect IsGlobalPower() which changes
1711 // connectivity semantics. Hidden power pins create implicit global net connections.
1712 // Also check if a pin changed type to/from PT_POWER_IN.
1714 {
1715 if( IsVisible() != pin->IsVisible() || GetType() != pin->GetType() )
1716 return true;
1717 }
1718
1719 return false;
1720}
1721
1722
1724{
1726}
1727
1728
1730{
1731 if( const SYMBOL* parentSymbol = GetParentSymbol() )
1732 {
1733 if( parentSymbol->IsLocked() )
1734 return true;
1735 }
1736
1737 return SCH_ITEM::IsLocked();
1738}
1739
1740
1742{
1743 if( m_libPin )
1744 return m_libPin->GetMenuImage();
1745
1747}
1748
1749
1750wxString SCH_PIN::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, ALT* aAlt ) const
1751{
1752 return getItemDescription( aAlt );
1753}
1754
1755
1756wxString SCH_PIN::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
1757{
1758 if( m_libPin )
1759 {
1760 SCH_PIN::ALT localStorage;
1761 SCH_PIN::ALT* alt = nullptr;
1762
1763 if( !m_alt.IsEmpty() )
1764 {
1765 localStorage = m_libPin->GetAlt( m_alt );
1766 alt = &localStorage;
1767 }
1768
1769 wxString itemDesc = m_libPin ? m_libPin->GetItemDescription( aUnitsProvider, alt )
1770 : wxString( wxS( "Undefined library pin." ) );
1771
1772 const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( GetParentSymbol() );
1773
1774 return wxString::Format( "Symbol %s %s",
1776 itemDesc );
1777 }
1778
1779 return getItemDescription( nullptr );
1780}
1781
1782
1783wxString SCH_PIN::getItemDescription( ALT* aAlt ) const
1784{
1785 wxString name = UnescapeString( aAlt ? aAlt->m_Name : GetShownName() );
1786 wxString electricalTypeName = ElectricalPinTypeGetText( aAlt ? aAlt->m_Type : m_type );
1787 wxString pinShapeName = PinShapeGetText( aAlt ? aAlt->m_Shape : m_shape );
1788
1789 if( IsVisible() )
1790 {
1791 if ( !name.IsEmpty() )
1792 {
1793 return wxString::Format( _( "Pin %s [%s, %s, %s]" ),
1795 name,
1796 electricalTypeName,
1797 pinShapeName );
1798 }
1799 else
1800 {
1801 return wxString::Format( _( "Pin %s [%s, %s]" ),
1803 electricalTypeName,
1804 pinShapeName );
1805 }
1806 }
1807 else
1808 {
1809 if( !name.IsEmpty() )
1810 {
1811 return wxString::Format( _( "Hidden pin %s [%s, %s, %s]" ),
1813 name,
1814 electricalTypeName,
1815 pinShapeName );
1816 }
1817 else
1818 {
1819 return wxString::Format( _( "Hidden pin %s [%s, %s]" ),
1821 electricalTypeName,
1822 pinShapeName );
1823 }
1824 }
1825}
1826
1827
1828int SCH_PIN::compare( const SCH_ITEM& aOther, int aCompareFlags ) const
1829{
1830 // Ignore the UUID here
1831 // And the position, which we'll do after the number.
1832 int retv = SCH_ITEM::compare( aOther, aCompareFlags | SCH_ITEM::COMPARE_FLAGS::EQUALITY
1834
1835 if( retv )
1836 return retv;
1837
1838 const SCH_PIN* tmp = static_cast<const SCH_PIN*>( &aOther );
1839
1840 wxCHECK( tmp, -1 );
1841
1842 if( m_number != tmp->m_number )
1843 {
1844 // StrNumCmp: sort the same as the pads in the footprint file
1845 return StrNumCmp( m_number, tmp->m_number );
1846 }
1847
1848 if( m_position.x != tmp->m_position.x )
1849 return m_position.x - tmp->m_position.x;
1850
1851 if( m_position.y != tmp->m_position.y )
1852 return m_position.y - tmp->m_position.y;
1853
1854 if( dynamic_cast<const SCH_SYMBOL*>( GetParentSymbol() ) )
1855 {
1856 if( ( m_libPin == nullptr ) || ( tmp->m_libPin == nullptr ) )
1857 return -1;
1858
1859 retv = m_libPin->compare( *tmp->m_libPin );
1860
1861 if( retv )
1862 return retv;
1863
1864 retv = m_alt.Cmp( tmp->m_alt );
1865
1866 if( retv )
1867 return retv;
1868 }
1869
1870 if( dynamic_cast<const LIB_SYMBOL*>( GetParentSymbol() ) )
1871 {
1872 if( m_length != tmp->m_length )
1873 return m_length.value_or( 0 ) - tmp->m_length.value_or( 0 );
1874
1875 if( m_orientation != tmp->m_orientation )
1876 return static_cast<int>( m_orientation ) - static_cast<int>( tmp->m_orientation );
1877
1878 if( m_shape != tmp->m_shape )
1879 return static_cast<int>( m_shape ) - static_cast<int>( tmp->m_shape );
1880
1881 if( m_type != tmp->m_type )
1882 return static_cast<int>( m_type ) - static_cast<int>( tmp->m_type );
1883
1884 if( m_hidden != tmp->m_hidden )
1885 return m_hidden.value_or( false ) - tmp->m_hidden.value_or( false );
1886
1887 if( m_numTextSize != tmp->m_numTextSize )
1888 return m_numTextSize.value_or( 0 ) - tmp->m_numTextSize.value_or( 0 );
1889
1890 if( m_nameTextSize != tmp->m_nameTextSize )
1891 return m_nameTextSize.value_or( 0 ) - tmp->m_nameTextSize.value_or( 0 );
1892
1893 if( m_alternates.size() != tmp->m_alternates.size() )
1894 return static_cast<int>( m_alternates.size() - tmp->m_alternates.size() );
1895
1896 auto lhsItem = m_alternates.begin();
1897 auto rhsItem = tmp->m_alternates.begin();
1898
1899 while( lhsItem != m_alternates.end() )
1900 {
1901 const ALT& lhsAlt = lhsItem->second;
1902 const ALT& rhsAlt = rhsItem->second;
1903
1904 retv = lhsAlt.m_Name.Cmp( rhsAlt.m_Name );
1905
1906 if( retv )
1907 return retv;
1908
1909 if( lhsAlt.m_Type != rhsAlt.m_Type )
1910 return static_cast<int>( lhsAlt.m_Type ) - static_cast<int>( rhsAlt.m_Type );
1911
1912 if( lhsAlt.m_Shape != rhsAlt.m_Shape )
1913 return static_cast<int>( lhsAlt.m_Shape ) - static_cast<int>( rhsAlt.m_Shape );
1914
1915 ++lhsItem;
1916 ++rhsItem;
1917 }
1918 }
1919
1920 return 0;
1921}
1922
1923
1924double SCH_PIN::Similarity( const SCH_ITEM& aOther ) const
1925{
1926 if( aOther.m_Uuid == m_Uuid )
1927 return 1.0;
1928
1929 if( aOther.Type() != SCH_PIN_T )
1930 return 0.0;
1931
1932 const SCH_PIN* other = static_cast<const SCH_PIN*>( &aOther );
1933
1934 if( m_libPin )
1935 {
1936 if( m_number != other->m_number )
1937 return 0.0;
1938
1939 if( m_position != other->m_position )
1940 return 0.0;
1941
1942 return m_libPin->Similarity( *other->m_libPin );
1943 }
1944
1945 double similarity = SimilarityBase( aOther );
1946
1947 if( m_name != other->m_name )
1948 similarity *= 0.9;
1949
1950 if( m_number != other->m_number )
1951 similarity *= 0.9;
1952
1953 if( m_position != other->m_position )
1954 similarity *= 0.9;
1955
1956 if( m_length != other->m_length )
1957 similarity *= 0.9;
1958
1959 if( m_orientation != other->m_orientation )
1960 similarity *= 0.9;
1961
1962 if( m_shape != other->m_shape )
1963 similarity *= 0.9;
1964
1965 if( m_type != other->m_type )
1966 similarity *= 0.9;
1967
1968 if( m_hidden != other->m_hidden )
1969 similarity *= 0.9;
1970
1971 if( m_numTextSize != other->m_numTextSize )
1972 similarity *= 0.9;
1973
1974 if( m_nameTextSize != other->m_nameTextSize )
1975 similarity *= 0.9;
1976
1977 if( m_alternates.size() != other->m_alternates.size() )
1978 similarity *= 0.9;
1979
1980 return similarity;
1981}
1982
1983
1984std::ostream& SCH_PIN::operator<<( std::ostream& aStream )
1985{
1986 aStream << "SCH_PIN:" << std::endl
1987 << " Name: \"" << m_name << "\"" << std::endl
1988 << " Number: \"" << m_number << "\"" << std::endl
1989 << " Position: " << m_position << std::endl
1990 << " Length: " << GetLength() << std::endl
1991 << " Orientation: " << PinOrientationName( m_orientation ) << std::endl
1992 << " Shape: " << PinShapeGetText( m_shape ) << std::endl
1993 << " Type: " << ElectricalPinTypeGetText( m_type ) << std::endl
1994 << " Name Text Size: " << GetNameTextSize() << std::endl
1995 << " Number Text Size: " << GetNumberTextSize() << std::endl;
1996
1997 return aStream;
1998}
1999
2000
2001#if defined(DEBUG)
2002
2003void SCH_PIN::Show( int nestLevel, std::ostream& os ) const
2004{
2005 NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
2006 << " num=\"" << m_number.mb_str()
2007 << '"' << "/>\n";
2008}
2009
2010#endif
2011
2012
2013void SCH_PIN::CalcEdit( const VECTOR2I& aPosition )
2014{
2015 if( IsMoving() )
2016 SetPosition( aPosition );
2017}
2018
2019
2020static struct SCH_PIN_DESC
2021{
2023 {
2024 auto& pinTypeEnum = ENUM_MAP<ELECTRICAL_PINTYPE>::Instance();
2025
2026 if( pinTypeEnum.Choices().GetCount() == 0 )
2027 {
2028 pinTypeEnum.Map( ELECTRICAL_PINTYPE::PT_INPUT, _HKI( "Input" ) )
2029 .Map( ELECTRICAL_PINTYPE::PT_OUTPUT, _HKI( "Output" ) )
2030 .Map( ELECTRICAL_PINTYPE::PT_BIDI, _HKI( "Bidirectional" ) )
2031 .Map( ELECTRICAL_PINTYPE::PT_TRISTATE, _HKI( "Tri-state" ) )
2032 .Map( ELECTRICAL_PINTYPE::PT_PASSIVE, _HKI( "Passive" ) )
2033 .Map( ELECTRICAL_PINTYPE::PT_NIC, _HKI( "Free" ) )
2034 .Map( ELECTRICAL_PINTYPE::PT_UNSPECIFIED, _HKI( "Unspecified" ) )
2035 .Map( ELECTRICAL_PINTYPE::PT_POWER_IN, _HKI( "Power input" ) )
2036 .Map( ELECTRICAL_PINTYPE::PT_POWER_OUT, _HKI( "Power output" ) )
2037 .Map( ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR, _HKI( "Open collector" ) )
2038 .Map( ELECTRICAL_PINTYPE::PT_OPENEMITTER, _HKI( "Open emitter" ) )
2039 .Map( ELECTRICAL_PINTYPE::PT_NC, _HKI( "Unconnected" ) );
2040 }
2041
2042 auto& pinShapeEnum = ENUM_MAP<GRAPHIC_PINSHAPE>::Instance();
2043
2044 if( pinShapeEnum.Choices().GetCount() == 0 )
2045 {
2046 pinShapeEnum.Map( GRAPHIC_PINSHAPE::LINE, _HKI( "Line" ) )
2047 .Map( GRAPHIC_PINSHAPE::INVERTED, _HKI( "Inverted" ) )
2048 .Map( GRAPHIC_PINSHAPE::CLOCK, _HKI( "Clock" ) )
2049 .Map( GRAPHIC_PINSHAPE::INVERTED_CLOCK, _HKI( "Inverted clock" ) )
2050 .Map( GRAPHIC_PINSHAPE::INPUT_LOW, _HKI( "Input low" ) )
2051 .Map( GRAPHIC_PINSHAPE::CLOCK_LOW, _HKI( "Clock low" ) )
2052 .Map( GRAPHIC_PINSHAPE::OUTPUT_LOW, _HKI( "Output low" ) )
2053 .Map( GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK, _HKI( "Falling edge clock" ) )
2054 .Map( GRAPHIC_PINSHAPE::NONLOGIC, _HKI( "NonLogic" ) );
2055 }
2056
2057 auto& orientationEnum = ENUM_MAP<PIN_ORIENTATION>::Instance();
2058
2059 if( orientationEnum.Choices().GetCount() == 0 )
2060 {
2061 orientationEnum.Map( PIN_ORIENTATION::PIN_RIGHT, _HKI( "Right" ) )
2062 .Map( PIN_ORIENTATION::PIN_LEFT, _HKI( "Left" ) )
2063 .Map( PIN_ORIENTATION::PIN_UP, _HKI( "Up" ) )
2064 .Map( PIN_ORIENTATION::PIN_DOWN, _HKI( "Down" ) );
2065 }
2066
2067 auto isSymbolEditor =
2068 []( INSPECTABLE* aItem ) -> bool
2069 {
2070 if( SCH_PIN* pin = dynamic_cast<SCH_PIN*>( aItem ) )
2071 return dynamic_cast<LIB_SYMBOL*>( pin->GetParentSymbol() ) != nullptr;
2072
2073 return false;
2074 };
2075
2080
2081 // Lock state is inherited from parent symbol (no independent locking of child items)
2082 propMgr.Mask( TYPE_HASH( SCH_PIN ), TYPE_HASH( SCH_ITEM ), _HKI( "Locked" ) );
2083
2084 propMgr.AddProperty( new PROPERTY<SCH_PIN, wxString>( _HKI( "Pin Name" ),
2086 .SetWriteableFunc( isSymbolEditor );
2087
2088 propMgr.AddProperty( new PROPERTY<SCH_PIN, wxString>( _HKI( "Pin Number" ),
2090 .SetWriteableFunc( isSymbolEditor );
2091
2092 propMgr.AddProperty( new PROPERTY_ENUM<SCH_PIN, ELECTRICAL_PINTYPE>( _HKI( "Electrical Type" ),
2094 .SetWriteableFunc( isSymbolEditor );
2095
2096 propMgr.AddProperty( new PROPERTY_ENUM<SCH_PIN, GRAPHIC_PINSHAPE>( _HKI( "Graphic Style" ),
2098 .SetWriteableFunc( isSymbolEditor );
2099
2100 propMgr.AddProperty( new PROPERTY<SCH_PIN, int>( _HKI( "Position X" ),
2102 .SetAvailableFunc( isSymbolEditor );
2103
2104 propMgr.AddProperty( new PROPERTY<SCH_PIN, int>( _HKI( "Position Y" ),
2106 .SetAvailableFunc( isSymbolEditor );
2107
2108 propMgr.AddProperty( new PROPERTY_ENUM<SCH_PIN, PIN_ORIENTATION>( _HKI( "Orientation" ),
2110 .SetWriteableFunc( isSymbolEditor );
2111
2112 propMgr.AddProperty( new PROPERTY<SCH_PIN, int>( _HKI( "Length" ),
2115 .SetWriteableFunc( isSymbolEditor );
2116
2117 propMgr.AddProperty( new PROPERTY<SCH_PIN, int>( _HKI( "Name Text Size" ),
2120 .SetAvailableFunc( isSymbolEditor );
2121
2122 propMgr.AddProperty( new PROPERTY<SCH_PIN, int>( _HKI( "Number Text Size" ),
2125 .SetAvailableFunc( isSymbolEditor );
2126
2127 propMgr.AddProperty( new PROPERTY<SCH_PIN, bool>( _HKI( "Visible" ),
2129 .SetAvailableFunc( isSymbolEditor );
2130
2131 }
2133
2134
const char * name
types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
Definition api_enums.cpp:47
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:123
BITMAPS
A list of all bitmap identifiers.
BOX2< VECTOR2I > BOX2I
Definition box2.h:918
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:986
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:554
constexpr bool Contains(const Vec &aPoint) const
Definition box2.h:164
constexpr bool Intersects(const BOX2< Vec > &aRect) const
Definition box2.h:307
static const COLOR4D WHITE
Definition color4d.h:401
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:398
The base class for create windows for drawing purpose.
const KIID m_Uuid
Definition eda_item.h:531
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:108
EDA_ITEM_FLAGS m_flags
Definition eda_item.h:542
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition eda_item.h:416
EDA_ITEM * GetParent() const
Definition eda_item.h:110
EDA_ITEM * m_parent
Owner.
Definition eda_item.h:543
static bool Replace(const EDA_SEARCH_DATA &aSearchData, wxString &aText)
Perform a text replace on aText using the find and replace criteria in aSearchData on items that supp...
Definition eda_item.cpp:261
bool IsMoving() const
Definition eda_item.h:130
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:37
static ENUM_MAP< T > & Instance()
Definition property.h:721
Class that other classes need to inherit from, in order to be inspectable.
Definition inspectable.h:38
FONT is an abstract base class for both outline and stroke fonts.
Definition font.h:94
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
Definition font.cpp:143
VECTOR2I StringBoundaryLimits(const wxString &aText, const VECTOR2I &aSize, int aThickness, bool aBold, bool aItalic, const METRICS &aFontMetrics) const
Compute the boundary limits of aText (the bounding box of all shapes).
Definition font.cpp:447
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
std::shared_ptr< wxString > m_text
Definition color4d.h:395
COLOR4D & Desaturate()
Removes color (in HSL model)
Definition color4d.cpp:528
COLOR4D Mix(const COLOR4D &aColor, double aFactor) const
Return a color that is mixed with the input by a factor.
Definition color4d.h:292
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
const wxString & GetDefaultFont() const
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
virtual const COLOR4D & GetBackgroundColor() const =0
Return current background color settings.
Definition kiid.h:44
wxString AsString() const
Definition kiid.cpp:242
Define a library symbol object.
Definition lib_symbol.h:79
Definition line.h:32
A pin layout helper is a class that manages the layout of the parts of a pin on a schematic symbol:
BOX2I GetPinBoundingBox(bool aIncludeLabelsOnInvisiblePins, bool aIncludeNameAndNumber, bool aIncludeElectricalType)
Get the bounding box of the pin itself.
Base plotter engine class.
Definition plotter.h:133
virtual void Circle(const VECTOR2I &pos, int diametre, FILL_T fill, int width)=0
void MoveTo(const VECTOR2I &pos)
Definition plotter.h:305
void FinishTo(const VECTOR2I &pos)
Definition plotter.h:315
RENDER_SETTINGS * RenderSettings()
Definition plotter.h:164
bool GetColorMode() const
Definition plotter.h:161
virtual void SetCurrentLineWidth(int width, void *aData=nullptr)=0
Set the line width for the next drawing.
void LineTo(const VECTOR2I &pos)
Definition plotter.h:310
virtual void PlotText(const VECTOR2I &aPos, const COLOR4D &aColor, const wxString &aText, const TEXT_ATTRIBUTES &aAttributes, KIFONT::FONT *aFont=nullptr, const KIFONT::METRICS &aFontMetrics=KIFONT::METRICS::Default(), void *aData=nullptr)
Definition plotter.cpp:712
virtual void SetColor(const COLOR4D &color)=0
PROPERTY_BASE & SetAvailableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Set a callback function to determine whether an object provides this property.
Definition property.h:262
PROPERTY_BASE & SetWriteableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Definition property.h:287
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.
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
wxString GetNetName() const
void AppendInfoToMsgPanel(std::vector< MSG_PANEL_ITEM > &aList) const
Adds information about the connection object to aList.
Schematic editor (Eeschema) main window.
SCH_SHEET_PATH & GetCurrentSheet() const
virtual const wxString & GetText() const override
Return the string associated with the text object.
Definition sch_field.h:128
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:162
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
Definition sch_item.cpp:825
int m_unit
Definition sch_item.h:776
SCH_ITEM & operator=(const SCH_ITEM &aPin)
Definition sch_item.cpp:78
int m_bodyStyle
Definition sch_item.h:777
SCH_RENDER_SETTINGS * getRenderSettings(PLOTTER *aPlotter) const
Definition sch_item.h:724
const SYMBOL * GetParentSymbol() const
Definition sch_item.cpp:274
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition sch_item.cpp:268
int GetBodyStyle() const
Definition sch_item.h:242
bool IsLocked() const override
Definition sch_item.cpp:148
friend class LIB_SYMBOL
Definition sch_item.h:797
@ SKIP_TST_POS
Definition sch_item.h:707
int GetUnit() const
Definition sch_item.h:233
virtual int compare(const SCH_ITEM &aOther, int aCompareFlags=0) const
Provide the draw object specific comparison called by the == and < operators.
Definition sch_item.cpp:720
bool IsConnectivityDirty() const
Definition sch_item.h:585
SCH_ITEM(EDA_ITEM *aParent, KICAD_T aType, int aUnit=0, int aBodyStyle=0)
Definition sch_item.cpp:52
SCH_CONNECTION * Connection(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve the connection associated with this object in the given sheet.
Definition sch_item.cpp:487
wxString ResolveText(const wxString &aText, const SCH_SHEET_PATH *aPath, int aDepth=0) const
Definition sch_item.cpp:377
const KIFONT::METRICS & GetFontMetrics() const
Definition sch_item.cpp:781
int GetEffectivePenWidth(const SCH_RENDER_SETTINGS *aSettings) const
Definition sch_item.cpp:790
SCH_LAYER_ID m_layer
Definition sch_item.h:775
double SimilarityBase(const SCH_ITEM &aItem) const
Calculate the boilerplate similarity for all LIB_ITEMs without preventing the use above of a pure vir...
Definition sch_item.h:377
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW=true) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition sch_pin.cpp:1440
std::ostream & operator<<(std::ostream &aStream)
Definition sch_pin.cpp:1984
void SetAlt(const wxString &aAlt)
Set the name of the alternate pin.
Definition sch_pin.cpp:527
void PlotPinTexts(PLOTTER *aPlotter, const VECTOR2I &aPinPos, PIN_ORIENTATION aPinOrient, int aTextInside, bool aDrawPinNum, bool aDrawPinName, bool aDimmed) const
Plot the pin name and number.
Definition sch_pin.cpp:974
int GetNumberTextSize() const
Definition sch_pin.cpp:774
int GetLength() const
Definition sch_pin.cpp:388
std::optional< bool > m_hidden
Definition sch_pin.h:404
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
Definition sch_pin.cpp:593
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
Definition sch_pin.cpp:1468
std::unique_ptr< PIN_LAYOUT_CACHE > m_layoutCache
The layout cache for this pin.
Definition sch_pin.h:420
void MirrorVerticallyPin(int aCenter)
Definition sch_pin.cpp:1389
void validateExtentsCache(KIFONT::FONT *aFont, int aSize, const wxString &aText, EXTENTS_CACHE *aCache) const
Definition sch_pin.cpp:1649
const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
Definition sch_pin.cpp:1636
std::vector< int > ViewGetLayers() const override
Return the layers the item is drawn on (which may be more than its "home" layer)
Definition sch_pin.cpp:1642
const std::map< wxString, ALT > & GetAlternates() const
Definition sch_pin.h:163
void CalcEdit(const VECTOR2I &aPosition) override
Calculate the attributes of an item at aPosition when it is being edited.
Definition sch_pin.cpp:2013
void SetNumber(const wxString &aNumber)
Definition sch_pin.cpp:734
std::optional< int > m_nameTextSize
Definition sch_pin.h:408
PIN_ORIENTATION PinDrawOrient(const TRANSFORM &aTransform) const
Return the pin real orientation (PIN_UP, PIN_DOWN, PIN_RIGHT, PIN_LEFT), according to its orientation...
Definition sch_pin.cpp:1291
void SetVisible(bool aVisible)
Definition sch_pin.h:117
int GetX() const
Definition sch_pin.h:257
void ChangeLength(int aLength)
Change the length of a pin and adjust its position based on orientation.
Definition sch_pin.cpp:1335
void SetX(int aX)
Definition sch_pin.h:258
bool HasConnectivityChanges(const SCH_ITEM *aItem, const SCH_SHEET_PATH *aInstance=nullptr) const override
Check if aItem has connectivity changes against this object.
Definition sch_pin.cpp:1689
SCH_PIN & operator=(const SCH_PIN &aPin)
Definition sch_pin.cpp:242
SCH_PIN * m_libPin
Definition sch_pin.h:393
std::optional< wxString > GetSmallestLogicalNumber() const
Return the smallest logical pin number if this pin uses stacked notation and it is valid.
Definition sch_pin.cpp:713
void Move(const VECTOR2I &aOffset) override
Move the item by aMoveVector to a new position.
Definition sch_pin.cpp:1363
std::map< const SCH_SHEET_PATH, std::pair< wxString, bool > > m_net_name_map
Definition sch_pin.h:424
PIN_ORIENTATION m_orientation
Definition sch_pin.h:401
void SetOrientation(PIN_ORIENTATION aOrientation)
Definition sch_pin.h:96
void SetName(const wxString &aName)
Definition sch_pin.cpp:512
bool IsGlobalPower() const
Return whether this pin forms a global power connection: i.e., is part of a power symbol and of type ...
Definition sch_pin.cpp:448
wxString getItemDescription(ALT *aAlt) const
Definition sch_pin.cpp:1783
bool IsVisible() const
Definition sch_pin.cpp:480
bool ConnectionPropagatesTo(const EDA_ITEM *aItem) const override
Return true if this item should propagate connection info to aItem.
Definition sch_pin.cpp:1723
bool IsLocked() const override
Definition sch_pin.cpp:1729
std::optional< int > m_numTextSize
Definition sch_pin.h:407
VECTOR2I GetPinRoot() const
Definition sch_pin.cpp:800
bool IsLocalPower() const
Local power pin is the same except that it is sheet-local and it does not support the legacy hidden p...
Definition sch_pin.cpp:467
ELECTRICAL_PINTYPE m_type
Definition sch_pin.h:403
wxString GetEffectivePadNumber() const
Return the pin number to be used for deterministic operations such as auto‑generated net names.
Definition sch_pin.cpp:725
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition sch_pin.cpp:1402
SCH_PIN * GetLibPin() const
Definition sch_pin.h:92
void SetPosition(const VECTOR2I &aPos) override
Definition sch_pin.h:254
double Similarity(const SCH_ITEM &aOther) const override
Return a measure of how likely the other object is to represent the same object.
Definition sch_pin.cpp:1924
bool m_isDangling
Definition sch_pin.h:413
void SetIsDangling(bool aIsDangling)
Definition sch_pin.cpp:564
wxString GetElectricalTypeName() const
Definition sch_pin.cpp:441
std::vector< wxString > GetStackedPinNumbers(bool *aValid=nullptr) const
Definition sch_pin.cpp:688
std::map< wxString, ALT > m_alternates
Definition sch_pin.h:396
const wxString & GetName() const
Definition sch_pin.cpp:494
int GetStackedPinCount(bool *aValid=nullptr) const
Return the count of logical pins represented by this pin's stacked notation.
Definition sch_pin.cpp:706
void SetLength(int aLength)
Definition sch_pin.h:102
bool IsDangling() const override
Definition sch_pin.cpp:555
void Plot(PLOTTER *aPlotter, bool aBackground, const SCH_PLOT_OPTS &aPlotOpts, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aDimmed) override
Plot the item to aPlotter.
Definition sch_pin.cpp:1447
void MirrorHorizontally(int aCenter) override
These transforms have effect only if the pin has a LIB_SYMBOL as parent.
Definition sch_pin.cpp:1382
std::recursive_mutex m_netmap_mutex
The name that this pin connection will drive onto a net.
Definition sch_pin.h:423
PIN_ORIENTATION GetOrientation() const
Definition sch_pin.cpp:353
wxString GetClass() const override
Return the class name.
Definition sch_pin.h:77
void SetNumberTextSize(int aSize)
Definition sch_pin.cpp:788
void SetShape(GRAPHIC_PINSHAPE aShape)
Definition sch_pin.h:99
void RotatePin(const VECTOR2I &aCenter, bool aRotateCCW=true)
Definition sch_pin.cpp:1409
VECTOR2I GetPosition() const override
Definition sch_pin.cpp:345
wxString GetCanonicalElectricalTypeName() const
Definition sch_pin.cpp:434
bool Replace(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) override
Perform a text replace using the find and replace criteria in aSearchData on items that support text ...
Definition sch_pin.cpp:620
int GetNameTextSize() const
Definition sch_pin.cpp:748
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
Definition sch_pin.cpp:1756
VECTOR2I m_position
Definition sch_pin.h:399
GRAPHIC_PINSHAPE m_shape
Definition sch_pin.h:402
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
Definition sch_pin.cpp:302
int compare(const SCH_ITEM &aOther, int aCompareFlags=0) const override
The pin specific sort order is as follows:
Definition sch_pin.cpp:1828
const wxString & GetShownName() const
Definition sch_pin.cpp:671
void MirrorHorizontallyPin(int aCenter)
These transforms have always effects.
Definition sch_pin.cpp:1369
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
Definition sch_pin.cpp:641
PIN_LAYOUT_CACHE & GetLayoutCache() const
Get the layout cache associated with this pin.
Definition sch_pin.cpp:1680
wxString m_name
Definition sch_pin.h:405
wxString m_alt
Definition sch_pin.h:409
void SetType(ELECTRICAL_PINTYPE aType)
Definition sch_pin.cpp:422
const wxString & GetBaseName() const
Get the name without any alternates.
Definition sch_pin.cpp:503
void ClearDefaultNetName(const SCH_SHEET_PATH *aPath)
Definition sch_pin.cpp:1515
void SetY(int aY)
Definition sch_pin.h:260
SCH_PIN(LIB_SYMBOL *aParentSymbol)
Definition sch_pin.cpp:132
const wxString & GetShownNumber() const
Definition sch_pin.cpp:682
bool IsStacked(const SCH_PIN *aPin) const
Definition sch_pin.cpp:570
const wxString & GetNumber() const
Definition sch_pin.h:127
wxString m_number
Definition sch_pin.h:406
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition sch_pin.cpp:1326
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition sch_pin.h:218
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Definition sch_pin.cpp:266
wxString GetDefaultNetName(const SCH_SHEET_PATH &aPath, bool aForceNoConnect=false)
Definition sch_pin.cpp:1526
std::optional< int > m_length
Definition sch_pin.h:400
GRAPHIC_PINSHAPE GetShape() const
Definition sch_pin.cpp:367
void PlotPinType(PLOTTER *aPlotter, const VECTOR2I &aPosition, PIN_ORIENTATION aOrientation, bool aDimmed) const
Definition sch_pin.cpp:823
int GetY() const
Definition sch_pin.h:259
bool IsPower() const
Check if the pin is either a global or local power pin.
Definition sch_pin.cpp:474
ELECTRICAL_PINTYPE GetType() const
Definition sch_pin.cpp:402
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition sch_pin.cpp:1741
void SetNameTextSize(int aSize)
Definition sch_pin.cpp:762
VECTOR2I TransformCoordinate(const VECTOR2I &aPoint) const
const KIGFX::COLOR4D & GetBackgroundColor() const override
Return current background color settings.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Schematic symbol object.
Definition sch_symbol.h:69
std::vector< const SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet) const
Retrieve a list of the SCH_PINs for the given sheet path.
const wxString GetValue(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText, const wxString &aVariantName=wxEmptyString) const override
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
A base class for LIB_SYMBOL and SCH_SYMBOL.
Definition symbol.h:59
virtual bool IsGlobalPower() const =0
virtual bool IsLocalPower() const =0
virtual const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const =0
int GetPinNameOffset() const
Definition symbol.h:159
virtual bool GetShowPinNames() const
Definition symbol.h:165
virtual bool GetShowPinNumbers() const
Definition symbol.h:171
GR_TEXT_H_ALIGN_T m_Halign
GR_TEXT_V_ALIGN_T m_Valign
for transforming drawing coordinates for a wxDC device context.
Definition transform.h:42
VECTOR2I TransformCoordinate(const VECTOR2I &aPoint) const
Calculate a new coordinate according to the mirror/rotation transform.
Definition transform.cpp:40
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
#define DEFAULT_PINNUM_SIZE
The default pin name size when creating pins(can be changed in preference menu)
#define DEFAULT_PINNAME_SIZE
The default selection highlight thickness (can be changed in preference menu)
#define DEFAULT_PIN_LENGTH
The default pin number size when creating pins(can be changed in preference menu)
#define _(s)
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:413
static constexpr EDA_ANGLE ANGLE_VERTICAL
Definition eda_angle.h:408
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition eda_angle.h:407
#define STRUCT_DELETED
flag indication structures to be erased
#define SKIP_STRUCT
flag indicating that the structure should be ignored
#define SHOW_ELEC_TYPE
Show pin electrical type.
@ NO_FILL
Definition eda_shape.h:60
int GetPenSizeForNormal(int aTextSize)
Definition gr_text.cpp:57
const wxChar *const traceStackedPins
Flag to enable debug output for stacked pins handling in symbol/pin code.
@ LAYER_DANGLING
Definition layer_ids.h:475
@ LAYER_PINNUM
Definition layer_ids.h:456
@ LAYER_DEVICE
Definition layer_ids.h:464
@ LAYER_PINNAM
Definition layer_ids.h:457
@ LAYER_PIN
Definition layer_ids.h:468
@ LAYER_OP_CURRENTS
Definition layer_ids.h:500
@ LAYER_SELECTION_SHADOWS
Definition layer_ids.h:493
KICOMMON_API int UnpackDistance(const types::Distance &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API VECTOR2I UnpackVector2(const types::Vector2 &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackDistance(types::Distance &aOutput, int aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackVector2(types::Vector2 &aOutput, const VECTOR2I &aInput, const EDA_IU_SCALE &aScale)
#define _HKI(x)
Definition page_info.cpp:40
see class PGM_BASE
static int externalPinDecoSize(const SCHEMATIC_SETTINGS *aSettings, const SCH_PIN &aPin)
static int internalPinDecoSize(const SCHEMATIC_SETTINGS *aSettings, const SCH_PIN &aPin)
wxString FormatStackedPinForDisplay(const wxString &aPinNumber, int aPinLength, int aTextSize, KIFONT::FONT *aFont, const KIFONT::METRICS &aFontMetrics)
Definition sch_pin.cpp:44
wxString PinShapeGetText(GRAPHIC_PINSHAPE shape)
Definition pin_type.cpp:231
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
Definition pin_type.h:32
@ PT_INPUT
usual pin input: must be connected
Definition pin_type.h:33
@ PT_NC
not connected (must be left open)
Definition pin_type.h:46
@ PT_OUTPUT
usual output
Definition pin_type.h:34
@ PT_TRISTATE
tri state bus pin
Definition pin_type.h:36
@ PT_NIC
not internally connected (may be connected to anything)
Definition pin_type.h:40
@ PT_BIDI
input or output (like port for a microprocessor)
Definition pin_type.h:35
@ PT_OPENEMITTER
pin type open emitter
Definition pin_type.h:45
@ PT_POWER_OUT
output of a regulator: intended to be connected to power input pins
Definition pin_type.h:43
@ PT_OPENCOLLECTOR
pin type open collector
Definition pin_type.h:44
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
Definition pin_type.h:42
@ PT_UNSPECIFIED
unknown electrical properties: creates always a warning when connected
Definition pin_type.h:41
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin.
Definition pin_type.h:39
BITMAPS ElectricalPinTypeGetBitmap(ELECTRICAL_PINTYPE)
Definition pin_type.cpp:217
wxString ElectricalPinTypeGetText(ELECTRICAL_PINTYPE)
Definition pin_type.cpp:203
wxString PinOrientationName(PIN_ORIENTATION aOrientation)
Definition pin_type.cpp:259
PIN_ORIENTATION
The symbol library pin object orientations.
Definition pin_type.h:101
@ PIN_UP
The pin extends upwards from the connection point: Probably on the bottom side of the symbol.
Definition pin_type.h:123
@ PIN_RIGHT
The pin extends rightwards from the connection point.
Definition pin_type.h:107
@ PIN_LEFT
The pin extends leftwards from the connection point: Probably on the right side of the symbol.
Definition pin_type.h:114
@ PIN_DOWN
The pin extends downwards from the connection: Probably on the top side of the symbol.
Definition pin_type.h:131
GRAPHIC_PINSHAPE
Definition pin_type.h:80
#define TYPE_HASH(x)
Definition property.h:74
#define ENUM_TO_WXANY(type)
Macro to define read-only fields (no setter method available)
Definition property.h:828
@ PT_COORD
Coordinate expressed in distance units (mm/inch)
Definition property.h:65
@ PT_SIZE
Size expressed in distance units (mm/inch)
Definition property.h:63
#define REGISTER_TYPE(x)
wxString FormatStackedPinForDisplay(const wxString &aPinNumber, int aPinLength, int aTextSize, KIFONT::FONT *aFont, const KIFONT::METRICS &aFontMetrics)
Definition sch_pin.cpp:44
static int externalPinDecoSize(const RENDER_SETTINGS *aSettings, const SCH_PIN &aPin)
Utility for getting the size of the 'external' pin decorators (as a radius) i.e.
Definition sch_pin.cpp:121
#define PIN_TEXT_MARGIN
Definition sch_pin.cpp:102
static int internalPinDecoSize(const RENDER_SETTINGS *aSettings, const SCH_PIN &aPin)
Utility for getting the size of the 'internal' pin decorators (as a radius) i.e.
Definition sch_pin.cpp:107
static struct SCH_PIN_DESC _SCH_PIN_DESC
#define TARGET_PIN_RADIUS
Definition sch_pin.h:37
T * GetAppSettings(const char *aFilename)
int StrNumCmp(const wxString &aString1, const wxString &aString2, bool aIgnoreCase)
Compare two strings with alphanumerical content.
std::vector< wxString > ExpandStackedPinNotation(const wxString &aPinName, bool *aValid)
Expand stacked pin notation like [1,2,3], [1-4], [A1-A4], or [AA1-AA3,AB4,CD12-CD14] into individual ...
wxString UnescapeString(const wxString &aSource)
void wxStringSplit(const wxString &aText, wxArrayString &aStrings, wxChar aSplitter)
Split aString to a string list separated at aSplitter.
std::vector< wxString > SplitStackedPinDisplayItems(const wxString &aInner)
Split the inner part of a stacked notation string (the text between the brackets) into its individual...
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
int CountStackedPinNotation(const wxString &aPinName, bool *aValid)
Count the number of pins represented by stacked pin notation.
@ CTX_NETNAME
wxString m_Name
Definition sch_pin.h:45
GRAPHIC_PINSHAPE m_Shape
Definition sch_pin.h:46
ELECTRICAL_PINTYPE m_Type
Definition sch_pin.h:47
KIFONT::FONT * m_Font
Definition sch_pin.h:363
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
KIBIS top(path, &reporter)
KIBIS_PIN * pin
int radius
VECTOR2I end
wxString result
Test unit parsing edge cases and error handling.
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_V_ALIGN_T
This is API surface mapped to common.types.VertialAlignment.
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
wxLogTrace helper definitions.
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
@ SCH_PIN_T
Definition typeinfo.h:150
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683
VECTOR2< double > VECTOR2D
Definition vector2d.h:682