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