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 (C) 1992-2024 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 <trigo.h>
40#include <string_utils.h>
41
42
43// small margin in internal units between the pin text and the pin line
44#define PIN_TEXT_MARGIN 4
45
47{
48 // These strings are the canonical name of the electrictal type
49 // Not translated, no space in name, only ASCII chars.
50 // to use when the string name must be known and well defined
51 // must have same order than enum ELECTRICAL_PINTYPE (see sch_pin.h)
52 static const wxChar* msgPinElectricType[] =
53 {
54 wxT( "input" ),
55 wxT( "output" ),
56 wxT( "bidirectional" ),
57 wxT( "tri_state" ),
58 wxT( "passive" ),
59 wxT( "free" ),
60 wxT( "unspecified" ),
61 wxT( "power_in" ),
62 wxT( "power_out" ),
63 wxT( "open_collector" ),
64 wxT( "open_emitter" ),
65 wxT( "no_connect" )
66 };
67
68 return msgPinElectricType[static_cast<int>( aType )];
69}
70
71
73// i.e. the clock symbols (falling clock is actually external but is of
74// the same kind)
75
76static int internalPinDecoSize( const RENDER_SETTINGS* aSettings, const SCH_PIN &aPin )
77{
78 const SCH_RENDER_SETTINGS* settings = static_cast<const SCH_RENDER_SETTINGS*>( aSettings );
79
80 if( settings && settings->m_PinSymbolSize )
81 return settings->m_PinSymbolSize;
82
83 return aPin.GetNameTextSize() != 0 ? aPin.GetNameTextSize() / 2 : aPin.GetNumberTextSize() / 2;
84}
85
87// i.e. the negation circle, the polarity 'slopes' and the nonlogic
88// marker
89static int externalPinDecoSize( const RENDER_SETTINGS* aSettings, const SCH_PIN &aPin )
90{
91 const SCH_RENDER_SETTINGS* settings = static_cast<const SCH_RENDER_SETTINGS*>( aSettings );
92
93 if( settings && settings->m_PinSymbolSize )
94 return settings->m_PinSymbolSize;
95
96 return aPin.GetNumberTextSize() / 2;
97}
98
99
100SCH_PIN::SCH_PIN( LIB_SYMBOL* aParentSymbol ) :
101 SCH_ITEM( aParentSymbol, SCH_PIN_T, 0, 0 ),
102 m_libPin( nullptr ),
103 m_position( { 0, 0 } ),
104 m_orientation( PIN_ORIENTATION::PIN_RIGHT ),
105 m_shape( GRAPHIC_PINSHAPE::LINE ),
107 m_hidden( false ),
108 m_isDangling( true ),
109 m_layoutCache( std::make_unique<PIN_LAYOUT_CACHE>( *this ) )
110{
111 // Use the application settings for pin sizes if exists.
112 // pgm can be nullptr when running a shared lib from a script, not from a kicad appl
113 PGM_BASE* pgm = PgmOrNull();
114
115 if( pgm )
116 {
118 m_length = schIUScale.MilsToIU( settings->m_Defaults.pin_length );
119 m_numTextSize = schIUScale.MilsToIU( settings->m_Defaults.pin_num_size );
120 m_nameTextSize = schIUScale.MilsToIU( settings->m_Defaults.pin_name_size );
121 }
122 else // Use hardcoded eeschema defaults: symbol_editor settings are not existing.
123 {
125 m_numTextSize = schIUScale.MilsToIU( DEFAULT_PINNUM_SIZE );
126 m_nameTextSize = schIUScale.MilsToIU( DEFAULT_PINNAME_SIZE );
127 }
128
129 m_layer = LAYER_DEVICE;
130}
131
132
133SCH_PIN::SCH_PIN( LIB_SYMBOL* aParentSymbol, const wxString& aName, const wxString& aNumber,
134 PIN_ORIENTATION aOrientation, ELECTRICAL_PINTYPE aPinType, int aLength,
135 int aNameTextSize, int aNumTextSize, int aBodyStyle, const VECTOR2I& aPos,
136 int aUnit ) :
137 SCH_ITEM( aParentSymbol, SCH_PIN_T, aUnit, aBodyStyle ),
138 m_libPin( nullptr ),
139 m_position( aPos ),
140 m_length( aLength ),
141 m_orientation( aOrientation ),
142 m_shape( GRAPHIC_PINSHAPE::LINE ),
143 m_type( aPinType ),
144 m_hidden( false ),
145 m_numTextSize( aNumTextSize ),
146 m_nameTextSize( aNameTextSize ),
147 m_isDangling( true ),
148 m_layoutCache( std::make_unique<PIN_LAYOUT_CACHE>( *this ) )
149{
150 SetName( aName );
151 SetNumber( aNumber );
152
154}
155
156
157SCH_PIN::SCH_PIN( SCH_SYMBOL* aParentSymbol, SCH_PIN* aLibPin ) :
158 SCH_ITEM( aParentSymbol, SCH_PIN_T, 0, 0 ),
159 m_libPin( aLibPin ),
160 m_orientation( PIN_ORIENTATION::INHERIT ),
161 m_shape( GRAPHIC_PINSHAPE::INHERIT ),
163 m_isDangling( true ),
164 m_layoutCache( std::make_unique<PIN_LAYOUT_CACHE>( *this ) )
165{
166 wxASSERT( aParentSymbol );
167
171
173}
174
175
180SCH_PIN::SCH_PIN( SCH_SYMBOL* aParentSymbol, const wxString& aNumber, const wxString& aAlt,
181 const KIID& aUuid ) :
182 SCH_ITEM( aParentSymbol, SCH_PIN_T ),
183 m_libPin( nullptr ),
184 m_orientation( PIN_ORIENTATION::INHERIT ),
185 m_shape( GRAPHIC_PINSHAPE::INHERIT ),
187 m_number( aNumber ),
188 m_alt( aAlt ),
189 m_isDangling( true ),
190 m_layoutCache( std::make_unique<PIN_LAYOUT_CACHE>( *this ) )
191{
192 wxASSERT( aParentSymbol );
193
194 const_cast<KIID&>( m_Uuid ) = aUuid;
196}
197
198
199SCH_PIN::SCH_PIN( const SCH_PIN& aPin ) :
200 SCH_ITEM( aPin ),
201 m_libPin( aPin.m_libPin ),
202 m_alternates( aPin.m_alternates ),
203 m_position( aPin.m_position ),
204 m_length( aPin.m_length ),
205 m_orientation( aPin.m_orientation ),
206 m_shape( aPin.m_shape ),
207 m_type( aPin.m_type ),
208 m_hidden( aPin.m_hidden ),
209 m_numTextSize( aPin.m_numTextSize ),
210 m_nameTextSize( aPin.m_nameTextSize ),
211 m_alt( aPin.m_alt ),
212 m_isDangling( aPin.m_isDangling ),
213 m_layoutCache( std::make_unique<PIN_LAYOUT_CACHE>( *this ) )
214{
215 SetName( aPin.m_name );
216 SetNumber( aPin.m_number );
217
218 m_layer = aPin.m_layer;
219}
220
221
223{
224}
225
226
228{
229 SCH_ITEM::operator=( aPin );
230
231 m_libPin = aPin.m_libPin;
233 m_alt = aPin.m_alt;
234 m_name = aPin.m_name;
235 m_number = aPin.m_number;
236 m_position = aPin.m_position;
237 m_length = aPin.m_length;
239 m_shape = aPin.m_shape;
240 m_type = aPin.m_type;
241 m_hidden = aPin.m_hidden;
245
246 return *this;
247}
248
249
251{
252 if( const SCH_SYMBOL* symbol = dynamic_cast<const SCH_SYMBOL*>( GetParentSymbol() ) )
253 return symbol->GetTransform().TransformCoordinate( m_position ) + symbol->GetPosition();
254 else
255 return m_position;
256}
257
259{
260 if( m_orientation == PIN_ORIENTATION::INHERIT )
261 {
262 wxCHECK_MSG( m_libPin, PIN_ORIENTATION::PIN_RIGHT, wxS( "Can't inherit without a libPin!" ) );
263
264 return m_libPin->GetOrientation();
265 }
266
267 return m_orientation;
268}
269
270
272{
273 if( !m_alt.IsEmpty() )
274 {
275 wxCHECK_MSG( m_libPin, GRAPHIC_PINSHAPE::LINE, wxS( "Can't specify alternate without a "
276 "libPin!" ) );
277
278 return m_libPin->GetAlt( m_alt ).m_Shape;
279 }
280 else if( m_shape == GRAPHIC_PINSHAPE::INHERIT )
281 {
282 wxCHECK_MSG( m_libPin, GRAPHIC_PINSHAPE::LINE, wxS( "Can't inherit without a libPin!" ) );
283
284 return m_libPin->GetShape();
285 }
286
287 return m_shape;
288}
289
290
292{
293 if( !m_length.has_value() )
294 {
295 wxCHECK_MSG( m_libPin, 0, wxS( "Can't inherit without a libPin!" ) );
296
297 return m_libPin->GetLength();
298 }
299
300 return m_length.value();
301}
302
303
305{
306 if( !m_alt.IsEmpty() )
307 {
308 wxCHECK_MSG( m_libPin, ELECTRICAL_PINTYPE::PT_UNSPECIFIED, wxS( "Can't specify alternate "
309 "without a libPin!" ) );
310
311 return m_libPin->GetAlt( m_alt ).m_Type;
312 }
313 else if( m_type == ELECTRICAL_PINTYPE::PT_INHERIT )
314 {
315 wxCHECK_MSG( m_libPin, ELECTRICAL_PINTYPE::PT_UNSPECIFIED, wxS( "Can't inherit without a "
316 "libPin!" ) );
317
318 return m_libPin->GetType();
319 }
320
321 return m_type;
322}
323
325{
326 if( aType == m_type )
327 return;
328
329 m_type = aType;
331}
332
333
335{
336 if( m_type == ELECTRICAL_PINTYPE::PT_INHERIT )
337 {
338 wxCHECK_MSG( m_libPin, GetCanonicalElectricalTypeName( ELECTRICAL_PINTYPE::PT_UNSPECIFIED ),
339 wxS( "Can't inherit without a m_libPin!" ) );
340
342 }
343
345}
346
347
349{
350 if( m_type == ELECTRICAL_PINTYPE::PT_INHERIT )
351 {
352 wxCHECK_MSG( m_libPin, ElectricalPinTypeGetText( ELECTRICAL_PINTYPE::PT_UNSPECIFIED ),
353 wxS( "Can't inherit without a m_libPin!" ) );
354
356 }
357
359}
360
361
363{
364 if( !m_hidden.has_value() )
365 {
366 wxCHECK_MSG( m_libPin, true, wxS( "Can't inherit without a libPin!" ) );
367
368 return m_libPin->IsVisible();
369 }
370
371 return !m_hidden.value();
372}
373
374
375const wxString& SCH_PIN::GetName() const
376{
377 if( !m_alt.IsEmpty() )
378 return m_alt;
379
380 return GetBaseName();
381}
382
383
384const wxString& SCH_PIN::GetBaseName() const
385{
386 if( m_libPin )
387 return m_libPin->GetBaseName();
388
389 return m_name;
390}
391
392
393void SCH_PIN::SetName( const wxString& aName )
394{
395 if( m_name == aName )
396 return;
397
398 m_name = aName;
399 // pin name string does not support spaces
400 m_name.Replace( wxT( " " ), wxT( "_" ) );
401
403}
404
405
407{
408 if( GetType() == ELECTRICAL_PINTYPE::PT_NC || GetType() == ELECTRICAL_PINTYPE::PT_NIC )
409 return false;
410
411 return m_isDangling;
412}
413
414
415void SCH_PIN::SetIsDangling( bool aIsDangling )
416{
417 m_isDangling = aIsDangling;
418}
419
420
421bool SCH_PIN::IsStacked( const SCH_PIN* aPin ) const
422{
423 bool isConnectableType_a = GetType() == ELECTRICAL_PINTYPE::PT_PASSIVE
424 || GetType() == ELECTRICAL_PINTYPE::PT_NIC;
425 bool isConnectableType_b = aPin->GetType() == ELECTRICAL_PINTYPE::PT_PASSIVE
426 || aPin->GetType() == ELECTRICAL_PINTYPE::PT_NIC;
427
428 return m_parent == aPin->GetParent()
429 && GetPosition() == aPin->GetPosition()
430 && GetName() == aPin->GetName()
431 && ( GetType() == aPin->GetType() || isConnectableType_a || isConnectableType_b );
432}
433
434
435bool SCH_PIN::Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const
436{
437 const SCH_SEARCH_DATA& schSearchData =
438 dynamic_cast<const SCH_SEARCH_DATA&>( aSearchData );
439
440 if( !schSearchData.searchAllPins )
441 return false;
442
443 return EDA_ITEM::Matches( GetName(), aSearchData )
444 || EDA_ITEM::Matches( GetNumber(), aSearchData );
445}
446
447
448bool SCH_PIN::Replace( const EDA_SEARCH_DATA& aSearchData, void* aAuxData )
449{
450 bool isReplaced = false;
451
452 /* TODO: waiting on a way to override pins in the schematic...
453 isReplaced |= EDA_ITEM::Replace( aSearchData, m_name );
454 isReplaced |= EDA_ITEM::Replace( aSearchData, m_number );
455 */
456
457 return isReplaced;
458}
459
460
461bool SCH_PIN::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
462{
463 // When looking for an "exact" hit aAccuracy will be 0 which works poorly if the pin has
464 // no pin number or name. Give it a floor.
465 if( Schematic() )
466 aAccuracy = std::max( aAccuracy, Schematic()->Settings().m_PinSymbolSize / 4 );
467
468 BOX2I rect = GetBoundingBox( false, true, m_flags & SHOW_ELEC_TYPE );
469
470 return rect.Inflate( aAccuracy ).Contains( aPosition );
471}
472
473
474bool SCH_PIN::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
475{
477 return false;
478
479 BOX2I sel = aRect;
480
481 if ( aAccuracy )
482 sel.Inflate( aAccuracy );
483
484 if( aContained )
485 return sel.Contains( GetBoundingBox( false, false, false ) );
486
487 return sel.Intersects( GetBoundingBox( false, true, m_flags & SHOW_ELEC_TYPE ) );
488}
489
490
491wxString SCH_PIN::GetShownName() const
492{
493 if( !m_alt.IsEmpty() )
494 return m_alt;
495 else if( m_libPin )
496 return m_libPin->GetShownName();
497
498 if( m_name == wxS( "~" ) )
499 return wxEmptyString;
500 else
501 return m_name;
502}
503
504
506{
507 if( m_number == wxS( "~" ) )
508 return wxEmptyString;
509 else
510 return m_number;
511}
512
513
514void SCH_PIN::SetNumber( const wxString& aNumber )
515{
516 if( m_number == aNumber )
517 return;
518
519 m_number = aNumber;
520 // pin number string does not support spaces
521 m_number.Replace( wxT( " " ), wxT( "_" ) );
522
524}
525
526
528{
529 if( !m_nameTextSize.has_value() )
530 {
532 wxS( "Can't inherit without a libPin!" ) );
533
534 return m_libPin->GetNameTextSize();
535 }
536 wxASSERT( !m_libPin );
537
538 return m_nameTextSize.value();
539}
540
541
543{
544 if( aSize == m_nameTextSize )
545 return;
546
547 m_nameTextSize = aSize;
549}
550
551
553{
554 if( !m_numTextSize.has_value() )
555 {
557 wxS( "Can't inherit without a libPin!" ) );
558
559 return m_libPin->GetNumberTextSize();
560 }
561 wxASSERT( !m_libPin );
562
563 return m_numTextSize.value();
564}
565
566
568{
569 if( aSize == m_numTextSize )
570 return;
571
572 m_numTextSize = aSize;
574}
575
576
578{
579 if( const SCH_SYMBOL* symbol = dynamic_cast<const SCH_SYMBOL*>( GetParentSymbol() ) )
580 {
581 const TRANSFORM& t = symbol->GetTransform();
582 wxCHECK( m_libPin, GetPosition() );
583 return t.TransformCoordinate( m_libPin->GetPinRoot() ) + symbol->GetPosition();
584 }
585
586 switch( GetOrientation() )
587 {
588 default:
589 case PIN_ORIENTATION::PIN_RIGHT: return m_position + VECTOR2I( GetLength(), 0 );
590 case PIN_ORIENTATION::PIN_LEFT: return m_position + VECTOR2I( -GetLength(), 0 );
591 case PIN_ORIENTATION::PIN_UP: return m_position + VECTOR2I( 0, -GetLength() );
592 case PIN_ORIENTATION::PIN_DOWN: return m_position + VECTOR2I( 0, GetLength() );
593 }
594}
595
596
597void SCH_PIN::Print( const SCH_RENDER_SETTINGS* aSettings, int aUnit, int aBodyStyle,
598 const VECTOR2I& aOffset, bool aForceNoFill, bool aDimmed )
599{
600 LIB_SYMBOL* part = dynamic_cast<LIB_SYMBOL*>( GetParentSymbol() );
601
602 wxCHECK( part && aSettings, /* void */ );
603
604 /* Calculate pin orient taking in account the symbol orientation. */
605 PIN_ORIENTATION orient = PinDrawOrient( aSettings->m_Transform );
606
607 /* Calculate the pin position */
608 VECTOR2I pos1 = aSettings->TransformCoordinate( m_position ) + aOffset;
609
610 if( IsVisible() || aSettings->m_ShowHiddenFields )
611 {
612 printPinSymbol( aSettings, pos1, orient, aDimmed );
613
614 printPinTexts( aSettings, pos1, orient, part->GetPinNameOffset(),
615 aSettings->m_ShowPinNumbers || part->GetShowPinNumbers(),
616 aSettings->m_ShowPinNames || part->GetShowPinNames(),
617 aDimmed );
618
619 if( aSettings->m_ShowPinsElectricalType )
620 printPinElectricalTypeName( aSettings, pos1, orient, aDimmed );
621
622 if( aSettings->m_ShowConnectionPoints
623 && m_type != ELECTRICAL_PINTYPE::PT_NC
624 && m_type != ELECTRICAL_PINTYPE::PT_NIC )
625 {
626 wxDC* DC = aSettings->GetPrintDC();
628
629 COLOR4D bg = aSettings->GetBackgroundColor();
630
631 if( bg == COLOR4D::UNSPECIFIED || GetGRForceBlackPenState() )
632 bg = COLOR4D::WHITE;
633
634 if( aDimmed )
635 {
636 color.Desaturate( );
637 color = color.Mix( bg, 0.5f );
638 }
639
640 GRCircle( DC, pos1, TARGET_PIN_RADIUS, 0, color );
641 }
642 }
643}
644
645
646void SCH_PIN::printPinSymbol( const SCH_RENDER_SETTINGS* aSettings, const VECTOR2I& aPos,
647 PIN_ORIENTATION aOrientation, bool aDimmed )
648{
649 wxDC* DC = aSettings->GetPrintDC();
650 int MapX1, MapY1, x1, y1;
651 int width = GetEffectivePenWidth( aSettings );
652 int posX = aPos.x;
653 int posY = aPos.y;
654 int len = GetLength();
656 COLOR4D bg = aSettings->GetBackgroundColor();
657
658 if( bg == COLOR4D::UNSPECIFIED || GetGRForceBlackPenState() )
659 bg = COLOR4D::WHITE;
660
661 if( !IsVisible() )
662 bg = aSettings->GetLayerColor( LAYER_HIDDEN );
663
664 if( aDimmed )
665 {
666 color.Desaturate( );
667 color = color.Mix( bg, 0.5f );
668 }
669
670 MapX1 = MapY1 = 0;
671 x1 = posX;
672 y1 = posY;
673
674 switch( aOrientation )
675 {
676 case PIN_ORIENTATION::PIN_UP: y1 = posY - len; MapY1 = 1; break;
677 case PIN_ORIENTATION::PIN_DOWN: y1 = posY + len; MapY1 = -1; break;
678 case PIN_ORIENTATION::PIN_LEFT: x1 = posX - len; MapX1 = 1; break;
679 case PIN_ORIENTATION::PIN_RIGHT: x1 = posX + len; MapX1 = -1; break;
680 case PIN_ORIENTATION::INHERIT: wxFAIL_MSG( wxS( "aOrientation must be resolved!" ) ); break;
681 }
682
683 if( m_shape == GRAPHIC_PINSHAPE::INVERTED || m_shape == GRAPHIC_PINSHAPE::INVERTED_CLOCK )
684 {
685 const int radius = externalPinDecoSize( aSettings, *this );
686 GRCircle( DC, VECTOR2I( MapX1 * radius + x1, MapY1 * radius + y1 ), radius, width, color );
687
688 GRMoveTo( MapX1 * radius * 2 + x1, MapY1 * radius * 2 + y1 );
689 GRLineTo( DC, posX, posY, width, color );
690 }
691 else
692 {
693 GRMoveTo( x1, y1 );
694 GRLineTo( DC, posX, posY, width, color );
695 }
696
697 // Draw the clock shape (>)inside the symbol
698 if( m_shape == GRAPHIC_PINSHAPE::CLOCK
699 || m_shape == GRAPHIC_PINSHAPE::INVERTED_CLOCK
700 || m_shape == GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK
701 || m_shape == GRAPHIC_PINSHAPE::CLOCK_LOW )
702 {
703 const int clock_size = internalPinDecoSize( aSettings, *this );
704 if( MapY1 == 0 ) /* MapX1 = +- 1 */
705 {
706 GRMoveTo( x1, y1 + clock_size );
707 GRLineTo( DC, x1 - MapX1 * clock_size * 2, y1, width, color );
708 GRLineTo( DC, x1, y1 - clock_size, width, color );
709 }
710 else /* MapX1 = 0 */
711 {
712 GRMoveTo( x1 + clock_size, y1 );
713 GRLineTo( DC, x1, y1 - MapY1 * clock_size * 2, width, color );
714 GRLineTo( DC, x1 - clock_size, y1, width, color );
715 }
716 }
717
718 // Draw the active low (or H to L active transition)
719 if( m_shape == GRAPHIC_PINSHAPE::INPUT_LOW
720 || m_shape == GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK
721 || m_shape == GRAPHIC_PINSHAPE::CLOCK_LOW )
722 {
723 const int deco_size = externalPinDecoSize( aSettings, *this );
724 if( MapY1 == 0 ) /* MapX1 = +- 1 */
725 {
726 GRMoveTo( x1 + MapX1 * deco_size * 2, y1 );
727 GRLineTo( DC, x1 + MapX1 * deco_size * 2, y1 - deco_size * 2, width, color );
728 GRLineTo( DC, x1, y1, width, color );
729 }
730 else /* MapX1 = 0 */
731 {
732 GRMoveTo( x1, y1 + MapY1 * deco_size * 2 );
733 GRLineTo( DC, x1 - deco_size * 2, y1 + MapY1 * deco_size * 2, width, color );
734 GRLineTo( DC, x1, y1, width, color );
735 }
736 }
737
738 if( m_shape == GRAPHIC_PINSHAPE::OUTPUT_LOW ) /* IEEE symbol "Active Low Output" */
739 {
740 const int deco_size = externalPinDecoSize( aSettings, *this );
741 if( MapY1 == 0 ) /* MapX1 = +- 1 */
742 {
743 GRMoveTo( x1, y1 - deco_size * 2 );
744 GRLineTo( DC, x1 + MapX1 * deco_size * 2, y1, width, color );
745 }
746 else /* MapX1 = 0 */
747 {
748 GRMoveTo( x1 - deco_size * 2, y1 );
749 GRLineTo( DC, x1, y1 + MapY1 * deco_size * 2, width, color );
750 }
751 }
752 else if( m_shape == GRAPHIC_PINSHAPE::NONLOGIC ) /* NonLogic pin symbol */
753 {
754 const int deco_size = externalPinDecoSize( aSettings, *this );
755 GRMoveTo( x1 - (MapX1 + MapY1) * deco_size, y1 - (MapY1 - MapX1) * deco_size );
756 GRLineTo( DC, x1 + (MapX1 + MapY1) * deco_size, y1 + ( MapY1 - MapX1 ) * deco_size, width,
757 color );
758 GRMoveTo( x1 - (MapX1 - MapY1) * deco_size, y1 - (MapY1 + MapX1) * deco_size );
759 GRLineTo( DC, x1 + (MapX1 - MapY1) * deco_size, y1 + ( MapY1 + MapX1 ) * deco_size, width,
760 color );
761 }
762
763 if( m_type == ELECTRICAL_PINTYPE::PT_NC ) // Draw a N.C. symbol
764 {
765 const int deco_size = TARGET_PIN_RADIUS;
766 GRLine( DC, posX - deco_size, posY - deco_size, posX + deco_size, posY + deco_size, width,
767 color );
768 GRLine( DC, posX + deco_size, posY - deco_size, posX - deco_size, posY + deco_size, width,
769 color );
770 }
771}
772
773
774void SCH_PIN::printPinTexts( const RENDER_SETTINGS* aSettings, const VECTOR2I& aPinPos,
775 PIN_ORIENTATION aPinOrient, int aTextInside, bool aDrawPinNum,
776 bool aDrawPinName, bool aDimmed )
777{
778 if( !aDrawPinName && !aDrawPinNum )
779 return;
780
781 KIFONT::FONT* font = KIFONT::FONT::GetFont( aSettings->GetDefaultFont(), false, false );
782 wxString name = GetShownName();
783 wxString number = GetShownNumber();
786 int name_offset = schIUScale.MilsToIU( PIN_TEXT_MARGIN );
787 int num_offset = schIUScale.MilsToIU( PIN_TEXT_MARGIN );
788
789 /* Get the num and name colors */
790 COLOR4D nameColor = aSettings->GetLayerColor( IsVisible() ? LAYER_PINNAM : LAYER_HIDDEN );
791 COLOR4D numColor = aSettings->GetLayerColor( IsVisible() ? LAYER_PINNUM : LAYER_HIDDEN );
792 COLOR4D bg = aSettings->GetBackgroundColor();
793
794 if( bg == COLOR4D::UNSPECIFIED || GetGRForceBlackPenState() )
795 bg = COLOR4D::WHITE;
796
797 if( !IsVisible() )
798 bg = aSettings->GetLayerColor( LAYER_HIDDEN );
799
800 if( aDimmed )
801 {
802 nameColor.Desaturate();
803 numColor.Desaturate();
804 nameColor = nameColor.Mix( bg, 0.5f );
805 numColor = numColor.Mix( bg, 0.5f );
806 }
807
808 int x1 = aPinPos.x;
809 int y1 = aPinPos.y;
810
811 switch( aPinOrient )
812 {
813 case PIN_ORIENTATION::PIN_UP: y1 -= GetLength(); break;
814 case PIN_ORIENTATION::PIN_DOWN: y1 += GetLength(); break;
815 case PIN_ORIENTATION::PIN_LEFT: x1 -= GetLength(); break;
816 case PIN_ORIENTATION::PIN_RIGHT: x1 += GetLength(); break;
817 case PIN_ORIENTATION::INHERIT: wxFAIL_MSG( wxT( "aPinOrient must be resolved!" ) ); break;
818 }
819
820 if( name.IsEmpty() || m_nameTextSize == 0 )
821 aDrawPinName = false;
822
823 if( number.IsEmpty() || m_numTextSize == 0 )
824 aDrawPinNum = false;
825
826 auto printName =
827 [&]( int x, int y, const EDA_ANGLE& angle, enum GR_TEXT_H_ALIGN_T hAlign,
828 enum GR_TEXT_V_ALIGN_T vAlign )
829 {
830 GRPrintText( aSettings->GetPrintDC(), VECTOR2I( x, y ), nameColor, name, angle,
831 nameSize, hAlign, vAlign, 0, false, false, font, GetFontMetrics() );
832 };
833
834 auto printNum =
835 [&]( int x, int y, const EDA_ANGLE& angle, enum GR_TEXT_H_ALIGN_T hAlign,
836 enum GR_TEXT_V_ALIGN_T vAlign )
837 {
838 GRPrintText( aSettings->GetPrintDC(), VECTOR2I( x, y ), numColor, number, angle,
839 numSize, hAlign, vAlign, 0, false, false, font, GetFontMetrics() );
840 };
841
842 if( aTextInside ) // Draw the text inside, but the pin numbers outside.
843 {
844 if( ( aPinOrient == PIN_ORIENTATION::PIN_LEFT )
845 || ( aPinOrient == PIN_ORIENTATION::PIN_RIGHT ) )
846 {
847 // It is an horizontal line
848 if( aDrawPinName )
849 {
850 if( aPinOrient == PIN_ORIENTATION::PIN_RIGHT )
851 {
852 printName( x1 + aTextInside, y1, ANGLE_HORIZONTAL,
854 }
855 else // Orient == PIN_LEFT
856 {
857 printName( x1 - aTextInside, y1, ANGLE_HORIZONTAL,
859 }
860 }
861
862 if( aDrawPinNum )
863 {
864 printNum( ( x1 + aPinPos.x ) / 2, y1 - num_offset, ANGLE_HORIZONTAL,
866 }
867 }
868 else /* Its a vertical line. */
869 {
870 // Text is drawn from bottom to top (i.e. to negative value for Y axis)
871 if( aPinOrient == PIN_ORIENTATION::PIN_DOWN )
872 {
873 if( aDrawPinName )
874 {
875 printName( x1, y1 + aTextInside, ANGLE_VERTICAL,
877 }
878
879 if( aDrawPinNum )
880 {
881 printNum( x1 - num_offset, ( y1 + aPinPos.y ) / 2, ANGLE_VERTICAL,
883 }
884 }
885 else /* PIN_UP */
886 {
887 if( aDrawPinName )
888 {
889 printName( x1, y1 - aTextInside, ANGLE_VERTICAL,
891 }
892
893 if( aDrawPinNum )
894 {
895 printNum( x1 - num_offset, ( y1 + aPinPos.y) / 2, ANGLE_VERTICAL,
897 }
898 }
899 }
900 }
901 else /**** Draw num & text pin outside ****/
902 {
903 if( ( aPinOrient == PIN_ORIENTATION::PIN_LEFT )
904 || ( aPinOrient == PIN_ORIENTATION::PIN_RIGHT ) )
905 {
906 /* Its an horizontal line. */
907 if( aDrawPinName && aDrawPinNum )
908 {
909 printName( ( x1 + aPinPos.x ) / 2, y1 - name_offset, ANGLE_HORIZONTAL,
911
912 printNum( ( x1 + aPinPos.x ) / 2, y1 + num_offset, ANGLE_HORIZONTAL,
914 }
915 else if( aDrawPinName )
916 {
917 printName( ( x1 + aPinPos.x ) / 2, y1 - name_offset, ANGLE_HORIZONTAL,
919 }
920 else if( aDrawPinNum )
921 {
922 printNum( ( x1 + aPinPos.x ) / 2, y1 - num_offset, ANGLE_HORIZONTAL,
924 }
925 }
926 else /* Its a vertical line. */
927 {
928 if( aDrawPinName && aDrawPinNum )
929 {
930 printName( x1 - name_offset, ( y1 + aPinPos.y ) / 2, ANGLE_VERTICAL,
932
933 printNum( x1 + num_offset, ( y1 + aPinPos.y ) / 2, ANGLE_VERTICAL,
935 }
936 else if( aDrawPinName )
937 {
938 printName( x1 - name_offset, ( y1 + aPinPos.y ) / 2, ANGLE_VERTICAL,
940 }
941 else if( aDrawPinNum )
942 {
943 printNum( x1 - num_offset, ( y1 + aPinPos.y ) / 2, ANGLE_VERTICAL,
945 }
946 }
947 }
948}
949
950
952 const VECTOR2I& aPosition, PIN_ORIENTATION aOrientation,
953 bool aDimmed )
954{
955 wxDC* DC = aSettings->GetPrintDC();
956 wxString typeName = GetElectricalTypeName();
957
958 // Use a reasonable (small) size to draw the text
959 int textSize = ( GetNameTextSize() * 3 ) / 4;
960
961 #define ETXT_MAX_SIZE schIUScale.mmToIU( 0.7 )
962
963 if( textSize > ETXT_MAX_SIZE )
964 textSize = ETXT_MAX_SIZE;
965
966 // Use a reasonable pen size to draw the text
967 int pensize = textSize/6;
968
969 // Get a suitable color
971 COLOR4D bg = aSettings->GetBackgroundColor();
972
973 if( bg == COLOR4D::UNSPECIFIED || GetGRForceBlackPenState() )
974 bg = COLOR4D::WHITE;
975
976 if( !IsVisible() )
977 bg = aSettings->GetLayerColor( LAYER_HIDDEN );
978
979 if( aDimmed )
980 {
981 color.Desaturate( );
982 color = color.Mix( bg, 0.5f );
983 }
984
985 VECTOR2I txtpos = aPosition;
986 int offset = schIUScale.mmToIU( 0.4 );
989 KIFONT::FONT* font = KIFONT::FONT::GetFont( aSettings->GetDefaultFont(), false, false );
990
991 switch( aOrientation )
992 {
993 case PIN_ORIENTATION::PIN_UP:
994 txtpos.y += offset;
995 orient = ANGLE_VERTICAL;
996 hjustify = GR_TEXT_H_ALIGN_RIGHT;
997 break;
998
999 case PIN_ORIENTATION::PIN_DOWN:
1000 txtpos.y -= offset;
1001 orient = ANGLE_VERTICAL;
1002 break;
1003
1004 case PIN_ORIENTATION::PIN_LEFT:
1005 txtpos.x += offset;
1006 break;
1007
1008 case PIN_ORIENTATION::PIN_RIGHT:
1009 txtpos.x -= offset;
1010 hjustify = GR_TEXT_H_ALIGN_RIGHT;
1011 break;
1012
1013 case PIN_ORIENTATION::INHERIT:
1014 wxFAIL_MSG( wxS( "aOrientation must be resolved!" ) );
1015 break;
1016 }
1017
1018 GRPrintText( DC, txtpos, color, typeName, orient, VECTOR2I( textSize, textSize ), hjustify,
1019 GR_TEXT_V_ALIGN_CENTER, pensize, false, false, font, GetFontMetrics() );
1020}
1021
1022
1023void SCH_PIN::PlotPinType( PLOTTER *aPlotter, const VECTOR2I &aPosition,
1024 PIN_ORIENTATION aOrientation, bool aDimmed ) const
1025{
1026 int MapX1, MapY1, x1, y1;
1027 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
1028 COLOR4D color = renderSettings->GetLayerColor( LAYER_PIN );
1029 COLOR4D bg = renderSettings->GetBackgroundColor();
1030 int penWidth = GetEffectivePenWidth( renderSettings );
1031 int pinLength = GetLength();
1032
1033 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
1034 bg = COLOR4D::WHITE;
1035
1036 if( aDimmed )
1037 {
1038 color.Desaturate( );
1039 color = color.Mix( bg, 0.5f );
1040 }
1041
1042 aPlotter->SetColor( color );
1043 aPlotter->SetCurrentLineWidth( penWidth );
1044
1045 MapX1 = MapY1 = 0;
1046 x1 = aPosition.x; y1 = aPosition.y;
1047
1048 switch( aOrientation )
1049 {
1050 case PIN_ORIENTATION::PIN_UP: y1 = aPosition.y - pinLength; MapY1 = 1; break;
1051 case PIN_ORIENTATION::PIN_DOWN: y1 = aPosition.y + pinLength; MapY1 = -1; break;
1052 case PIN_ORIENTATION::PIN_LEFT: x1 = aPosition.x - pinLength; MapX1 = 1; break;
1053 case PIN_ORIENTATION::PIN_RIGHT: x1 = aPosition.x + pinLength; MapX1 = -1; break;
1054 case PIN_ORIENTATION::INHERIT: wxFAIL_MSG( wxS( "aOrientation must be resolved!" ) ); break;
1055 }
1056
1057 if( m_shape == GRAPHIC_PINSHAPE::INVERTED || m_shape == GRAPHIC_PINSHAPE::INVERTED_CLOCK )
1058 {
1059 const int radius = externalPinDecoSize( aPlotter->RenderSettings(), *this );
1060 aPlotter->Circle( VECTOR2I( MapX1 * radius + x1, MapY1 * radius + y1 ), radius * 2,
1061 FILL_T::NO_FILL, penWidth );
1062
1063 aPlotter->MoveTo( VECTOR2I( MapX1 * radius * 2 + x1, MapY1 * radius * 2 + y1 ) );
1064 aPlotter->FinishTo( aPosition );
1065 }
1066 else if( m_shape == GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK )
1067 {
1068 const int deco_size = internalPinDecoSize( aPlotter->RenderSettings(), *this );
1069 if( MapY1 == 0 ) /* MapX1 = +- 1 */
1070 {
1071 aPlotter->MoveTo( VECTOR2I( x1, y1 + deco_size ) );
1072 aPlotter->LineTo( VECTOR2I( x1 + MapX1 * deco_size * 2, y1 ) );
1073 aPlotter->FinishTo( VECTOR2I( x1, y1 - deco_size ) );
1074 }
1075 else /* MapX1 = 0 */
1076 {
1077 aPlotter->MoveTo( VECTOR2I( x1 + deco_size, y1 ) );
1078 aPlotter->LineTo( VECTOR2I( x1, y1 + MapY1 * deco_size * 2 ) );
1079 aPlotter->FinishTo( VECTOR2I( x1 - deco_size, y1 ) );
1080 }
1081
1082 aPlotter->MoveTo( VECTOR2I( MapX1 * deco_size * 2 + x1, MapY1 * deco_size * 2 + y1 ) );
1083 aPlotter->FinishTo( aPosition );
1084 }
1085 else
1086 {
1087 aPlotter->MoveTo( VECTOR2I( x1, y1 ) );
1088 aPlotter->FinishTo( aPosition );
1089 }
1090
1091 if( m_shape == GRAPHIC_PINSHAPE::CLOCK
1092 || m_shape == GRAPHIC_PINSHAPE::INVERTED_CLOCK
1093 || m_shape == GRAPHIC_PINSHAPE::CLOCK_LOW )
1094 {
1095 const int deco_size = internalPinDecoSize( aPlotter->RenderSettings(), *this );
1096 if( MapY1 == 0 ) /* MapX1 = +- 1 */
1097 {
1098 aPlotter->MoveTo( VECTOR2I( x1, y1 + deco_size ) );
1099 aPlotter->LineTo( VECTOR2I( x1 - MapX1 * deco_size * 2, y1 ) );
1100 aPlotter->FinishTo( VECTOR2I( x1, y1 - deco_size ) );
1101 }
1102 else /* MapX1 = 0 */
1103 {
1104 aPlotter->MoveTo( VECTOR2I( x1 + deco_size, y1 ) );
1105 aPlotter->LineTo( VECTOR2I( x1, y1 - MapY1 * deco_size * 2 ) );
1106 aPlotter->FinishTo( VECTOR2I( x1 - deco_size, y1 ) );
1107 }
1108 }
1109
1110 if( m_shape == GRAPHIC_PINSHAPE::INPUT_LOW
1111 || m_shape == GRAPHIC_PINSHAPE::CLOCK_LOW ) /* IEEE symbol "Active Low Input" */
1112 {
1113 const int deco_size = externalPinDecoSize( aPlotter->RenderSettings(), *this );
1114
1115 if( MapY1 == 0 ) /* MapX1 = +- 1 */
1116 {
1117 aPlotter->MoveTo( VECTOR2I( x1 + MapX1 * deco_size * 2, y1 ) );
1118 aPlotter->LineTo( VECTOR2I( x1 + MapX1 * deco_size * 2, y1 - deco_size * 2 ) );
1119 aPlotter->FinishTo( VECTOR2I( x1, y1 ) );
1120 }
1121 else /* MapX1 = 0 */
1122 {
1123 aPlotter->MoveTo( VECTOR2I( x1, y1 + MapY1 * deco_size * 2 ) );
1124 aPlotter->LineTo( VECTOR2I( x1 - deco_size * 2, y1 + MapY1 * deco_size * 2 ) );
1125 aPlotter->FinishTo( VECTOR2I( x1, y1 ) );
1126 }
1127 }
1128
1129 if( m_shape == GRAPHIC_PINSHAPE::OUTPUT_LOW ) /* IEEE symbol "Active Low Output" */
1130 {
1131 const int symbol_size = externalPinDecoSize( aPlotter->RenderSettings(), *this );
1132
1133 if( MapY1 == 0 ) /* MapX1 = +- 1 */
1134 {
1135 aPlotter->MoveTo( VECTOR2I( x1, y1 - symbol_size * 2 ) );
1136 aPlotter->FinishTo( VECTOR2I( x1 + MapX1 * symbol_size * 2, y1 ) );
1137 }
1138 else /* MapX1 = 0 */
1139 {
1140 aPlotter->MoveTo( VECTOR2I( x1 - symbol_size * 2, y1 ) );
1141 aPlotter->FinishTo( VECTOR2I( x1, y1 + MapY1 * symbol_size * 2 ) );
1142 }
1143 }
1144 else if( m_shape == GRAPHIC_PINSHAPE::NONLOGIC ) /* NonLogic pin symbol */
1145 {
1146 const int deco_size = externalPinDecoSize( aPlotter->RenderSettings(), *this );
1147 aPlotter->MoveTo( VECTOR2I( x1 - ( MapX1 + MapY1 ) * deco_size,
1148 y1 - ( MapY1 - MapX1 ) * deco_size ) );
1149 aPlotter->FinishTo( VECTOR2I( x1 + ( MapX1 + MapY1 ) * deco_size,
1150 y1 + ( MapY1 - MapX1 ) * deco_size ) );
1151 aPlotter->MoveTo( VECTOR2I( x1 - ( MapX1 - MapY1 ) * deco_size,
1152 y1 - ( MapY1 + MapX1 ) * deco_size ) );
1153 aPlotter->FinishTo( VECTOR2I( x1 + ( MapX1 - MapY1 ) * deco_size,
1154 y1 + ( MapY1 + MapX1 ) * deco_size ) );
1155 }
1156
1157 if( m_type == ELECTRICAL_PINTYPE::PT_NC ) // Draw a N.C. symbol
1158 {
1159 const int deco_size = TARGET_PIN_RADIUS;
1160 const int ex1 = aPosition.x;
1161 const int ey1 = aPosition.y;
1162 aPlotter->MoveTo( VECTOR2I( ex1 - deco_size, ey1 - deco_size ) );
1163 aPlotter->FinishTo( VECTOR2I( ex1 + deco_size, ey1 + deco_size ) );
1164 aPlotter->MoveTo( VECTOR2I( ex1 + deco_size, ey1 - deco_size ) );
1165 aPlotter->FinishTo( VECTOR2I( ex1 - deco_size, ey1 + deco_size ) );
1166 }
1167}
1168
1169
1170void SCH_PIN::PlotPinTexts( PLOTTER *aPlotter, const VECTOR2I &aPinPos, PIN_ORIENTATION aPinOrient,
1171 int aTextInside, bool aDrawPinNum, bool aDrawPinName,
1172 bool aDimmed ) const
1173{
1174 RENDER_SETTINGS* settings = aPlotter->RenderSettings();
1175 KIFONT::FONT* font = KIFONT::FONT::GetFont( settings->GetDefaultFont(), false, false );
1176 wxString name = GetShownName();
1177 wxString number = GetShownNumber();
1178
1179 if( name.IsEmpty() || m_nameTextSize == 0 )
1180 aDrawPinName = false;
1181
1182 if( number.IsEmpty() || m_numTextSize == 0 )
1183 aDrawPinNum = false;
1184
1185 if( !aDrawPinNum && !aDrawPinName )
1186 return;
1187
1188 int namePenWidth = settings->GetDefaultPenWidth();
1189 int numPenWidth = settings->GetDefaultPenWidth();
1190 int name_offset = schIUScale.MilsToIU( PIN_TEXT_MARGIN ) + namePenWidth;
1191 int num_offset = schIUScale.MilsToIU( PIN_TEXT_MARGIN ) + numPenWidth;
1192
1193 /* Get the num and name colors */
1194 COLOR4D nameColor = settings->GetLayerColor( LAYER_PINNAM );
1195 COLOR4D numColor = settings->GetLayerColor( LAYER_PINNUM );
1196 COLOR4D bg = settings->GetBackgroundColor();
1197
1198 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
1199 bg = COLOR4D::WHITE;
1200
1201 if( aDimmed )
1202 {
1203 nameColor.Desaturate( );
1204 numColor.Desaturate( );
1205 nameColor = nameColor.Mix( bg, 0.5f );
1206 numColor = numColor.Mix( bg, 0.5f );
1207 }
1208
1209 int x1 = aPinPos.x;
1210 int y1 = aPinPos.y;
1211
1212 switch( aPinOrient )
1213 {
1214 case PIN_ORIENTATION::PIN_UP: y1 -= GetLength(); break;
1215 case PIN_ORIENTATION::PIN_DOWN: y1 += GetLength(); break;
1216 case PIN_ORIENTATION::PIN_LEFT: x1 -= GetLength(); break;
1217 case PIN_ORIENTATION::PIN_RIGHT: x1 += GetLength(); break;
1218 case PIN_ORIENTATION::INHERIT: wxFAIL_MSG( wxS( "aPinOrient must be resolved!" ) ); break;
1219 }
1220
1221 auto plotName =
1222 [&]( int x, int y, const EDA_ANGLE& angle, GR_TEXT_H_ALIGN_T hJustify,
1223 GR_TEXT_V_ALIGN_T vJustify )
1224 {
1225 TEXT_ATTRIBUTES attrs;
1226 attrs.m_StrokeWidth = namePenWidth;
1227 attrs.m_Angle = angle;
1229 attrs.m_Halign = hJustify;
1230 attrs.m_Valign = vJustify;
1231 attrs.m_Multiline = false;
1232
1233 aPlotter->PlotText( VECTOR2I( x, y ), nameColor, name, attrs, font, GetFontMetrics() );
1234 };
1235
1236 auto plotNum =
1237 [&]( int x, int y, const EDA_ANGLE& angle, GR_TEXT_H_ALIGN_T hJustify,
1238 GR_TEXT_V_ALIGN_T vJustify )
1239 {
1240 TEXT_ATTRIBUTES attrs;
1241 attrs.m_StrokeWidth = numPenWidth;
1242 attrs.m_Angle = angle;
1244 attrs.m_Halign = hJustify;
1245 attrs.m_Valign = vJustify;
1246 attrs.m_Multiline = false;
1247
1248 aPlotter->PlotText( VECTOR2I( x, y ), numColor, number, attrs, font, GetFontMetrics() );
1249 };
1250
1251 /* Draw the text inside, but the pin numbers outside. */
1252 if( aTextInside )
1253 {
1254 if( ( aPinOrient == PIN_ORIENTATION::PIN_LEFT )
1255 || ( aPinOrient == PIN_ORIENTATION::PIN_RIGHT ) ) /* Its an horizontal line. */
1256 {
1257 if( aDrawPinName )
1258 {
1259 if( aPinOrient == PIN_ORIENTATION::PIN_RIGHT )
1260 {
1261 plotName( x1 + aTextInside, y1, ANGLE_HORIZONTAL,
1263 }
1264 else // orient == PIN_LEFT
1265 {
1266 plotName( x1 - aTextInside, y1, ANGLE_HORIZONTAL,
1268 }
1269 }
1270
1271 if( aDrawPinNum )
1272 {
1273 plotNum( ( x1 + aPinPos.x) / 2, y1 - num_offset, ANGLE_HORIZONTAL,
1275 }
1276 }
1277 else /* Its a vertical line. */
1278 {
1279 if( aPinOrient == PIN_ORIENTATION::PIN_DOWN )
1280 {
1281 if( aDrawPinName )
1282 {
1283 plotName( x1, y1 + aTextInside, ANGLE_VERTICAL,
1285 }
1286
1287 if( aDrawPinNum )
1288 {
1289 plotNum( x1 - num_offset, ( y1 + aPinPos.y) / 2, ANGLE_VERTICAL,
1291 }
1292 }
1293 else /* PIN_UP */
1294 {
1295 if( aDrawPinName )
1296 {
1297 plotName( x1, y1 - aTextInside, ANGLE_VERTICAL,
1299 }
1300
1301 if( aDrawPinNum )
1302 {
1303 plotNum( x1 - num_offset, ( y1 + aPinPos.y) / 2, ANGLE_VERTICAL,
1305 }
1306 }
1307 }
1308 }
1309 else /* Draw num & text pin outside */
1310 {
1311 if( ( aPinOrient == PIN_ORIENTATION::PIN_LEFT )
1312 || ( aPinOrient == PIN_ORIENTATION::PIN_RIGHT ) )
1313 {
1314 /* Its an horizontal line. */
1315 if( aDrawPinName && aDrawPinNum )
1316 {
1317 plotName( ( x1 + aPinPos.x) / 2, y1 - name_offset, ANGLE_HORIZONTAL,
1319
1320 plotNum( ( x1 + aPinPos.x) / 2, y1 + num_offset, ANGLE_HORIZONTAL,
1322 }
1323 else if( aDrawPinName )
1324 {
1325 plotName( ( x1 + aPinPos.x) / 2, y1 - name_offset, ANGLE_HORIZONTAL,
1327 }
1328 else if( aDrawPinNum )
1329 {
1330 plotNum( ( x1 + aPinPos.x) / 2, y1 - name_offset, ANGLE_HORIZONTAL,
1332 }
1333 }
1334 else
1335 {
1336 /* Its a vertical line. */
1337 if( aDrawPinName && aDrawPinNum )
1338 {
1339 plotName( x1 - name_offset, ( y1 + aPinPos.y ) / 2, ANGLE_VERTICAL,
1341
1342 plotNum( x1 + num_offset, ( y1 + aPinPos.y ) / 2, ANGLE_VERTICAL,
1344 }
1345 else if( aDrawPinName )
1346 {
1347 plotName( x1 - name_offset, ( y1 + aPinPos.y ) / 2, ANGLE_VERTICAL,
1349 }
1350 else if( aDrawPinNum )
1351 {
1352 plotNum( x1 - num_offset, ( y1 + aPinPos.y ) / 2, ANGLE_VERTICAL,
1354 }
1355 }
1356 }
1357}
1358
1359
1361{
1362 PIN_ORIENTATION orient;
1363 VECTOR2I end; // position of pin end starting at 0,0 according to its orientation, length = 1
1364
1365 switch( GetOrientation() )
1366 {
1367 default:
1368 case PIN_ORIENTATION::PIN_RIGHT: end.x = 1; break;
1369 case PIN_ORIENTATION::PIN_UP: end.y = -1; break;
1370 case PIN_ORIENTATION::PIN_DOWN: end.y = 1; break;
1371 case PIN_ORIENTATION::PIN_LEFT: end.x = -1; break;
1372 }
1373
1374 // = pos of end point, according to the symbol orientation.
1375 end = aTransform.TransformCoordinate( end );
1376 orient = PIN_ORIENTATION::PIN_UP;
1377
1378 if( end.x == 0 )
1379 {
1380 if( end.y > 0 )
1381 orient = PIN_ORIENTATION::PIN_DOWN;
1382 }
1383 else
1384 {
1385 orient = PIN_ORIENTATION::PIN_RIGHT;
1386
1387 if( end.x < 0 )
1388 orient = PIN_ORIENTATION::PIN_LEFT;
1389 }
1390
1391 return orient;
1392}
1393
1394
1396{
1397 //return new SCH_PIN( *this );
1398 SCH_ITEM* newPin = new SCH_PIN( *this );
1399 wxASSERT( newPin->GetUnit() == m_unit && newPin->GetBodyStyle() == m_bodyStyle );
1400 return newPin;
1401}
1402
1403
1404void SCH_PIN::ChangeLength( int aLength )
1405{
1406 int lengthChange = GetLength() - aLength;
1407 int offsetX = 0;
1408 int offsetY = 0;
1409
1410 switch( m_orientation )
1411 {
1412 default:
1413 case PIN_ORIENTATION::PIN_RIGHT:
1414 offsetX = lengthChange;
1415 break;
1416 case PIN_ORIENTATION::PIN_LEFT:
1417 offsetX = -1 * lengthChange;
1418 break;
1419 case PIN_ORIENTATION::PIN_UP:
1420 offsetY = lengthChange;
1421 break;
1422 case PIN_ORIENTATION::PIN_DOWN:
1423 offsetY = -1 * lengthChange;
1424 break;
1425 }
1426
1427 m_position += VECTOR2I( offsetX, offsetY );
1428 m_length = aLength;
1429}
1430
1431
1432void SCH_PIN::Move( const VECTOR2I& aOffset )
1433{
1434 m_position += aOffset;
1435}
1436
1437
1439{
1440 m_position.x -= aCenter;
1441 m_position.x *= -1;
1442 m_position.x += aCenter;
1443
1444 if( m_orientation == PIN_ORIENTATION::PIN_RIGHT )
1445 m_orientation = PIN_ORIENTATION::PIN_LEFT;
1446 else if( m_orientation == PIN_ORIENTATION::PIN_LEFT )
1447 m_orientation = PIN_ORIENTATION::PIN_RIGHT;
1448}
1449
1450
1452{
1453 if( dynamic_cast<LIB_SYMBOL*>( GetParentSymbol() ) )
1454 MirrorHorizontallyPin( aCenter );
1455}
1456
1457
1459{
1460 m_position.y -= aCenter;
1461 m_position.y *= -1;
1462 m_position.y += aCenter;
1463
1464 if( m_orientation == PIN_ORIENTATION::PIN_UP )
1465 m_orientation = PIN_ORIENTATION::PIN_DOWN;
1466 else if( m_orientation == PIN_ORIENTATION::PIN_DOWN )
1467 m_orientation = PIN_ORIENTATION::PIN_UP;
1468}
1469
1470
1471void SCH_PIN::MirrorVertically( int aCenter )
1472{
1473 if( dynamic_cast<LIB_SYMBOL*>( GetParentSymbol() ) )
1474 MirrorVerticallyPin( aCenter );
1475}
1476
1477
1478void SCH_PIN::RotatePin( const VECTOR2I& aCenter, bool aRotateCCW )
1479{
1480 if( aRotateCCW )
1481 {
1482 RotatePoint( m_position, aCenter, ANGLE_90 );
1483
1484 switch( GetOrientation() )
1485 {
1486 default:
1487 case PIN_ORIENTATION::PIN_RIGHT: m_orientation = PIN_ORIENTATION::PIN_UP; break;
1488 case PIN_ORIENTATION::PIN_UP: m_orientation = PIN_ORIENTATION::PIN_LEFT; break;
1489 case PIN_ORIENTATION::PIN_LEFT: m_orientation = PIN_ORIENTATION::PIN_DOWN; break;
1490 case PIN_ORIENTATION::PIN_DOWN: m_orientation = PIN_ORIENTATION::PIN_RIGHT; break;
1491 }
1492 }
1493 else
1494 {
1495 RotatePoint( m_position, aCenter, -ANGLE_90 );
1496
1497 switch( GetOrientation() )
1498 {
1499 default:
1500 case PIN_ORIENTATION::PIN_RIGHT: m_orientation = PIN_ORIENTATION::PIN_DOWN; break;
1501 case PIN_ORIENTATION::PIN_UP: m_orientation = PIN_ORIENTATION::PIN_RIGHT; break;
1502 case PIN_ORIENTATION::PIN_LEFT: m_orientation = PIN_ORIENTATION::PIN_UP; break;
1503 case PIN_ORIENTATION::PIN_DOWN: m_orientation = PIN_ORIENTATION::PIN_LEFT; break;
1504 }
1505 }
1506}
1507
1508
1509void SCH_PIN::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
1510{
1511 if( dynamic_cast<LIB_SYMBOL*>( GetParentSymbol() ) )
1512 RotatePin( aCenter, aRotateCCW );
1513}
1514
1515
1516void SCH_PIN::Plot( PLOTTER* aPlotter, bool aBackground, const SCH_PLOT_OPTS& aPlotOpts,
1517 int aUnit, int aBodyStyle, const VECTOR2I& aOffset, bool aDimmed )
1518{
1519 if( aBackground )
1520 return;
1521
1522 SCH_RENDER_SETTINGS* renderSettings = getRenderSettings( aPlotter );
1523
1524 if( !IsVisible() && !renderSettings->m_ShowHiddenPins )
1525 return;
1526
1527 const SYMBOL* part = GetParentSymbol();
1528 PIN_ORIENTATION orient = PinDrawOrient( renderSettings->m_Transform );
1529 VECTOR2I pos = renderSettings->TransformCoordinate( m_position ) + aOffset;
1530
1531 PlotPinType( aPlotter, pos, orient, aDimmed );
1532 PlotPinTexts( aPlotter, pos, orient, part->GetPinNameOffset(), part->GetShowPinNumbers(),
1533 part->GetShowPinNames(), aDimmed );
1534}
1535
1536
1537void SCH_PIN::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1538{
1539 wxString msg;
1540 SYMBOL* symbol = GetParentSymbol();
1541
1542 if( dynamic_cast<LIB_SYMBOL*>( symbol ) )
1543 {
1544 getSymbolEditorMsgPanelInfo( aFrame, aList );
1545 }
1546 else
1547 {
1548 aList.emplace_back( _( "Type" ), _( "Pin" ) );
1549
1550 if( symbol->GetUnitCount() )
1551 {
1553 wxString( "Undefined library pin." );
1554 aList.emplace_back( _( "Unit" ), msg );
1555 }
1556
1557 if( symbol->HasAlternateBodyStyle() )
1558 {
1560 wxString( "Undefined library pin." );
1561 aList.emplace_back( _( "Body Style" ), msg );
1562 }
1563 }
1564
1565 aList.emplace_back( _( "Name" ), UnescapeString( GetShownName() ) );
1566 aList.emplace_back( _( "Number" ), GetShownNumber() );
1567 aList.emplace_back( _( "Type" ), ElectricalPinTypeGetText( GetType() ) );
1568 aList.emplace_back( _( "Style" ), PinShapeGetText( GetShape() ) );
1569
1570 aList.emplace_back( _( "Visible" ), IsVisible() ? _( "Yes" ) : _( "No" ) );
1571
1572 // Display pin length
1573 aList.emplace_back( _( "Length" ), aFrame->MessageTextFromValue( GetLength(), true ) );
1574
1575 aList.emplace_back( _( "Orientation" ), PinOrientationName( GetOrientation() ) );
1576
1577 if( dynamic_cast<LIB_SYMBOL*>( symbol ) )
1578 {
1579 aList.emplace_back( _( "Pos X" ), aFrame->MessageTextFromValue( GetPosition().x, true ) );
1580 aList.emplace_back( _( "Pos Y" ), aFrame->MessageTextFromValue( GetPosition().y, true ) );
1581 }
1582 else
1583 {
1584 SCH_EDIT_FRAME* schframe = dynamic_cast<SCH_EDIT_FRAME*>( aFrame );
1585 SCH_SHEET_PATH* currentSheet = schframe ? &schframe->GetCurrentSheet() : nullptr;
1586 SCH_SYMBOL* schsymbol = dynamic_cast<SCH_SYMBOL*>( symbol );
1587
1588 // Don't use GetShownText(); we want to see the variable references here
1589 aList.emplace_back( symbol->GetRef( currentSheet ),
1590 UnescapeString( schsymbol->GetField( VALUE_FIELD )->GetText() ) );
1591 }
1592
1593#if defined(DEBUG)
1594 if( !IsConnectivityDirty() && dynamic_cast<SCH_EDIT_FRAME*>( aFrame ) )
1595 {
1596 SCH_CONNECTION* conn = Connection();
1597
1598 if( conn )
1599 conn->AppendInfoToMsgPanel( aList );
1600 }
1601#endif
1602}
1603
1604
1606{
1607 std::lock_guard<std::recursive_mutex> lock( m_netmap_mutex );
1608
1609 if( aPath )
1610 m_net_name_map.erase( *aPath );
1611 else
1612 m_net_name_map.clear();
1613}
1614
1615
1616wxString SCH_PIN::GetDefaultNetName( const SCH_SHEET_PATH& aPath, bool aForceNoConnect )
1617{
1618 const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( GetParentSymbol() );
1619
1620 // Need to check for parent as power symbol to make sure we aren't dealing
1621 // with legacy global power pins on non-power symbols
1622 if( IsGlobalPower() )
1623 {
1624 if( GetLibPin()->GetParentSymbol()->IsPower() )
1625 {
1626 return EscapeString( symbol->GetValue( true, &aPath, false ), CTX_NETNAME );
1627 }
1628 else
1629 {
1630 wxString tmp = m_libPin ? m_libPin->GetName() : wxString( "??" );
1631
1632 return EscapeString( tmp, CTX_NETNAME );
1633 }
1634 }
1635
1636 std::lock_guard<std::recursive_mutex> lock( m_netmap_mutex );
1637
1638 auto it = m_net_name_map.find( aPath );
1639
1640 if( it != m_net_name_map.end() )
1641 {
1642 if( it->second.second == aForceNoConnect )
1643 return it->second.first;
1644 }
1645
1646 wxString name = "Net-(";
1647 bool unconnected = false;
1648
1649 if( aForceNoConnect || GetType() == ELECTRICAL_PINTYPE::PT_NC )
1650 {
1651 unconnected = true;
1652 name = ( "unconnected-(" );
1653 }
1654
1655 bool annotated = true;
1656
1657 std::vector<SCH_PIN*> pins = symbol->GetPins( &aPath );
1658 bool has_multiple = false;
1659
1660 for( SCH_PIN* pin : pins )
1661 {
1662 if( pin->GetShownName() == GetShownName()
1663 && pin->GetShownNumber() != GetShownNumber()
1664 && unconnected == ( pin->GetType() == ELECTRICAL_PINTYPE::PT_NC ) )
1665 {
1666 has_multiple = true;
1667 break;
1668 }
1669 }
1670
1671 wxString libPinShownName = m_libPin ? m_libPin->GetShownName() : wxString( "??" );
1672 wxString libPinShownNumber = m_libPin ? m_libPin->GetShownNumber() : wxString( "??" );
1673
1674 // Use timestamp for unannotated symbols
1675 if( symbol->GetRef( &aPath, false ).Last() == '?' )
1676 {
1678
1679 wxString libPinNumber = m_libPin ? m_libPin->GetNumber() : wxString( "??" );
1680 name << "-Pad" << libPinNumber << ")";
1681 annotated = false;
1682 }
1683 else if( !libPinShownName.IsEmpty() && ( libPinShownName != libPinShownNumber ) )
1684 {
1685 // Pin names might not be unique between different units so we must have the
1686 // unit token in the reference designator
1687 name << symbol->GetRef( &aPath, true );
1688 name << "-" << EscapeString( libPinShownName, CTX_NETNAME );
1689
1690 if( unconnected || has_multiple )
1691 name << "-Pad" << EscapeString( libPinShownNumber, CTX_NETNAME );
1692
1693 name << ")";
1694 }
1695 else
1696 {
1697 // Pin numbers are unique, so we skip the unit token
1698 name << symbol->GetRef( &aPath, false );
1699 name << "-Pad" << EscapeString( libPinShownNumber, CTX_NETNAME ) << ")";
1700 }
1701
1702 if( annotated )
1703 m_net_name_map[ aPath ] = std::make_pair( name, aForceNoConnect );
1704
1705 return name;
1706}
1707
1708
1710{
1711 return GetBoundingBox( false, true, m_flags & SHOW_ELEC_TYPE );
1712}
1713
1714
1715void SCH_PIN::ViewGetLayers( int aLayers[], int& aCount ) const
1716{
1717 aCount = 6;
1718 aLayers[0] = LAYER_DANGLING;
1719 aLayers[1] = LAYER_DEVICE;
1720 aLayers[2] = LAYER_SELECTION_SHADOWS;
1721 aLayers[3] = LAYER_OP_CURRENTS;
1722 aLayers[4] = LAYER_PINNAM;
1723 aLayers[5] = LAYER_PINNUM;
1724}
1725
1726
1727void SCH_PIN::validateExtentsCache( KIFONT::FONT* aFont, int aSize, const wxString& aText,
1728 EXTENTS_CACHE* aCache ) const
1729{
1730 if( aCache->m_Font == aFont
1731 && aCache->m_FontSize == aSize
1732 && aCache->m_Extents != VECTOR2I() )
1733 {
1734 return;
1735 }
1736
1737 aCache->m_Font = aFont;
1738 aCache->m_FontSize = aSize;
1739
1740 VECTOR2D fontSize( aSize, aSize );
1741 int penWidth = GetPenSizeForNormal( aSize );
1742
1743 aCache->m_Extents = aFont->StringBoundaryLimits( aText, fontSize, penWidth, false, false,
1744 GetFontMetrics() );
1745}
1746
1747
1748BOX2I SCH_PIN::GetBoundingBox( bool aIncludeLabelsOnInvisiblePins, bool aIncludeNameAndNumber,
1749 bool aIncludeElectricalType ) const
1750{
1751 // Just defer to the cache
1752 return m_layoutCache->GetPinBoundingBox( aIncludeLabelsOnInvisiblePins, aIncludeNameAndNumber,
1753 aIncludeElectricalType );
1754}
1755
1756
1758 const SCH_SHEET_PATH* aInstance ) const
1759{
1760 // Do not compare to ourself.
1761 if( aItem == this )
1762 return false;
1763
1764 const SCH_PIN* pin = dynamic_cast<const SCH_PIN*>( aItem );
1765
1766 // Don't compare against a different SCH_ITEM.
1767 wxCHECK( pin, false );
1768
1769 if( GetPosition() != pin->GetPosition() )
1770 return true;
1771
1772 if( GetNumber() != pin->GetNumber() )
1773 return true;
1774
1775 return GetName() != pin->GetName();
1776}
1777
1778
1780{
1781 wxCHECK( m_libPin, false );
1782
1783 // Reciprocal checking is done in CONNECTION_GRAPH anyway
1784 return m_libPin->GetType() != ELECTRICAL_PINTYPE::PT_NC;
1785}
1786
1787
1789{
1791}
1792
1793
1794wxString SCH_PIN::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, ALT* aAlt ) const
1795{
1796 return getItemDescription( aAlt );
1797}
1798
1799
1800wxString SCH_PIN::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
1801{
1802 if( m_libPin )
1803 {
1804 SCH_PIN::ALT localStorage;
1805 SCH_PIN::ALT* alt = nullptr;
1806
1807 if( !m_alt.IsEmpty() )
1808 {
1809 localStorage = m_libPin->GetAlt( m_alt );
1810 alt = &localStorage;
1811 }
1812
1813 wxString itemDesc = m_libPin ? m_libPin->GetItemDescription( aUnitsProvider, alt )
1814 : wxString( wxS( "Undefined library pin." ) );
1815
1816 const SCH_SYMBOL* symbol = static_cast<const SCH_SYMBOL*>( GetParentSymbol() );
1817
1818 return wxString::Format( "Symbol %s %s",
1820 itemDesc );
1821 }
1822
1823 return getItemDescription( nullptr );
1824}
1825
1826
1827wxString SCH_PIN::getItemDescription( ALT* aAlt ) const
1828{
1829 // This code previously checked "m_name.IsEmpty()" to choose the correct
1830 // formatting path, but that check fails if the pin is called "~" which is
1831 // the default for an empty pin name. Instead we get the final display string
1832 // that will be shown and check if it's empty.
1833
1834 wxString name = UnescapeString( aAlt ? aAlt->m_Name : GetShownName() );
1835 wxString electricalTypeName = ElectricalPinTypeGetText( aAlt ? aAlt->m_Type : m_type );
1836 wxString pinShapeName = PinShapeGetText( aAlt ? aAlt->m_Shape : m_shape );
1837
1838 if( IsVisible() )
1839 {
1840 if ( !name.IsEmpty() )
1841 {
1842 return wxString::Format( _( "Pin %s [%s, %s, %s]" ),
1844 name,
1845 electricalTypeName,
1846 pinShapeName );
1847 }
1848 else
1849 {
1850 return wxString::Format( _( "Pin %s [%s, %s]" ),
1852 electricalTypeName,
1853 pinShapeName );
1854 }
1855 }
1856 else
1857 {
1858 if( !name.IsEmpty() )
1859 {
1860 return wxString::Format( _( "Hidden pin %s [%s, %s, %s]" ),
1862 name,
1863 electricalTypeName,
1864 pinShapeName );
1865 }
1866 else
1867 {
1868 return wxString::Format( _( "Hidden pin %s [%s, %s]" ),
1870 electricalTypeName,
1871 pinShapeName );
1872 }
1873 }
1874}
1875
1876
1877
1878
1879int SCH_PIN::compare( const SCH_ITEM& aOther, int aCompareFlags ) const
1880{
1881 // Ignore the UUID here.
1882 int retv = SCH_ITEM::compare( aOther, aCompareFlags | SCH_ITEM::COMPARE_FLAGS::EQUALITY );
1883
1884 if( retv )
1885 return retv;
1886
1887 const SCH_PIN* tmp = static_cast<const SCH_PIN*>( &aOther );
1888
1889 wxCHECK( tmp, -1 );
1890
1891 // When comparing units, we do not compare the part numbers. If everything else is
1892 // identical, then we can just renumber the parts for the inherited symbol.
1893 // if( !( aCompareFlags & SCH_ITEM::COMPARE_FLAGS::UNIT ) && m_number != tmp->m_number )
1894 // return m_number.Cmp( tmp->m_number );
1895
1896 // int result = m_name.Cmp( tmp->m_name );
1897
1898 // if( result )
1899 // return result;
1900
1901 // if( m_position.x != tmp->m_position.x )
1902 // return m_position.x - tmp->m_position.x;
1903
1904 // if( m_position.y != tmp->m_position.y )
1905 // return m_position.y - tmp->m_position.y;
1906
1907 // if( m_length != tmp->m_length )
1908 // return m_length.value_or( 0 ) - tmp->m_length.value_or( 0 );
1909
1910 // if( m_orientation != tmp->m_orientation )
1911 // return static_cast<int>( m_orientation ) - static_cast<int>( tmp->m_orientation );
1912
1913 // if( m_shape != tmp->m_shape )
1914 // return static_cast<int>( m_shape ) - static_cast<int>( tmp->m_shape );
1915
1916 // if( m_type != tmp->m_type )
1917 // return static_cast<int>( m_type ) - static_cast<int>( tmp->m_type );
1918
1919 // if( m_hidden != tmp->m_hidden )
1920 // return m_hidden.value_or( false ) - tmp->m_hidden.value_or( false );
1921
1922 // if( m_numTextSize != tmp->m_numTextSize )
1923 // return m_numTextSize.value_or( 0 ) - tmp->m_numTextSize.value_or( 0 );
1924
1925 // if( m_nameTextSize != tmp->m_nameTextSize )
1926 // return m_nameTextSize.value_or( 0 ) - tmp->m_nameTextSize.value_or( 0 );
1927
1928 // if( m_alternates.size() != tmp->m_alternates.size() )
1929 // return static_cast<int>( m_alternates.size() - tmp->m_alternates.size() );
1930
1931 // auto lhsItem = m_alternates.begin();
1932 // auto rhsItem = tmp->m_alternates.begin();
1933
1934 // while( lhsItem != m_alternates.end() )
1935 // {
1936 // const ALT& lhsAlt = lhsItem->second;
1937 // const ALT& rhsAlt = rhsItem->second;
1938
1939 // int retv = lhsAlt.m_Name.Cmp( rhsAlt.m_Name );
1940
1941 // if( retv )
1942 // return retv;
1943
1944 // if( lhsAlt.m_Type != rhsAlt.m_Type )
1945 // return static_cast<int>( lhsAlt.m_Type ) - static_cast<int>( rhsAlt.m_Type );
1946
1947 // if( lhsAlt.m_Shape != rhsAlt.m_Shape )
1948 // return static_cast<int>( lhsAlt.m_Shape ) - static_cast<int>( rhsAlt.m_Shape );
1949
1950 // ++lhsItem;
1951 // ++rhsItem;
1952 // }
1953
1954 if( m_number != tmp->m_number )
1955 return m_number.Cmp( tmp->m_number );
1956
1957 if( m_position.x != tmp->m_position.x )
1958 return m_position.x - tmp->m_position.x;
1959
1960 if( m_position.y != tmp->m_position.y )
1961 return m_position.y - tmp->m_position.y;
1962
1963 if( dynamic_cast<const SCH_SYMBOL*>( GetParentSymbol() ) )
1964 {
1965 wxCHECK( m_libPin && tmp->m_libPin, -1 );
1966
1967 retv = m_libPin->compare( *tmp->m_libPin );
1968
1969 if( retv )
1970 return retv;
1971
1972 retv = m_alt.Cmp( tmp->m_alt );
1973
1974 if( retv )
1975 return retv;
1976 }
1977
1978 if( dynamic_cast<const LIB_SYMBOL*>( GetParentSymbol() ) )
1979 {
1980 if( m_length != tmp->m_length )
1981 return m_length.value_or( 0 ) - tmp->m_length.value_or( 0 );
1982
1983 if( m_orientation != tmp->m_orientation )
1984 return static_cast<int>( m_orientation ) - static_cast<int>( tmp->m_orientation );
1985
1986 if( m_shape != tmp->m_shape )
1987 return static_cast<int>( m_shape ) - static_cast<int>( tmp->m_shape );
1988
1989 if( m_type != tmp->m_type )
1990 return static_cast<int>( m_type ) - static_cast<int>( tmp->m_type );
1991
1992 if( m_hidden != tmp->m_hidden )
1993 return m_hidden.value_or( false ) - tmp->m_hidden.value_or( false );
1994
1995 if( m_numTextSize != tmp->m_numTextSize )
1996 return m_numTextSize.value_or( 0 ) - tmp->m_numTextSize.value_or( 0 );
1997
1998 if( m_nameTextSize != tmp->m_nameTextSize )
1999 return m_nameTextSize.value_or( 0 ) - tmp->m_nameTextSize.value_or( 0 );
2000
2001 if( m_alternates.size() != tmp->m_alternates.size() )
2002 return static_cast<int>( m_alternates.size() - tmp->m_alternates.size() );
2003
2004 auto lhsItem = m_alternates.begin();
2005 auto rhsItem = tmp->m_alternates.begin();
2006
2007 while( lhsItem != m_alternates.end() )
2008 {
2009 const ALT& lhsAlt = lhsItem->second;
2010 const ALT& rhsAlt = rhsItem->second;
2011
2012 retv = lhsAlt.m_Name.Cmp( rhsAlt.m_Name );
2013
2014 if( retv )
2015 return retv;
2016
2017 if( lhsAlt.m_Type != rhsAlt.m_Type )
2018 return static_cast<int>( lhsAlt.m_Type ) - static_cast<int>( rhsAlt.m_Type );
2019
2020 if( lhsAlt.m_Shape != rhsAlt.m_Shape )
2021 return static_cast<int>( lhsAlt.m_Shape ) - static_cast<int>( rhsAlt.m_Shape );
2022
2023 ++lhsItem;
2024 ++rhsItem;
2025 }
2026 }
2027
2028 return 0;
2029}
2030
2031
2032double SCH_PIN::Similarity( const SCH_ITEM& aOther ) const
2033{
2034 if( aOther.m_Uuid == m_Uuid )
2035 return 1.0;
2036
2037 if( aOther.Type() != SCH_PIN_T )
2038 return 0.0;
2039
2040 const SCH_PIN* other = static_cast<const SCH_PIN*>( &aOther );
2041
2042 if( m_libPin )
2043 {
2044 if( m_number != other->m_number )
2045 return 0.0;
2046
2047 if( m_position != other->m_position )
2048 return 0.0;
2049
2050 return m_libPin->Similarity( *other->m_libPin );
2051 }
2052
2053 double similarity = SimilarityBase( aOther );
2054
2055 if( m_name != other->m_name )
2056 similarity *= 0.9;
2057
2058 if( m_number != other->m_number )
2059 similarity *= 0.9;
2060
2061 if( m_position != other->m_position )
2062 similarity *= 0.9;
2063
2064 if( m_length != other->m_length )
2065 similarity *= 0.9;
2066
2067 if( m_orientation != other->m_orientation )
2068 similarity *= 0.9;
2069
2070 if( m_shape != other->m_shape )
2071 similarity *= 0.9;
2072
2073 if( m_type != other->m_type )
2074 similarity *= 0.9;
2075
2076 if( m_hidden != other->m_hidden )
2077 similarity *= 0.9;
2078
2079 if( m_numTextSize != other->m_numTextSize )
2080 similarity *= 0.9;
2081
2082 if( m_nameTextSize != other->m_nameTextSize )
2083 similarity *= 0.9;
2084
2085 if( m_alternates.size() != other->m_alternates.size() )
2086 similarity *= 0.9;
2087
2088 return similarity;
2089}
2090
2091
2092std::ostream& SCH_PIN::operator<<( std::ostream& aStream )
2093{
2094 aStream << "SCH_PIN:" << std::endl
2095 << " Name: \"" << m_name << "\"" << std::endl
2096 << " Number: \"" << m_number << "\"" << std::endl
2097 << " Position: " << m_position << std::endl
2098 << " Length: " << GetLength() << std::endl
2099 << " Orientation: " << PinOrientationName( m_orientation ) << std::endl
2100 << " Shape: " << PinShapeGetText( m_shape ) << std::endl
2101 << " Type: " << ElectricalPinTypeGetText( m_type ) << std::endl
2102 << " Name Text Size: " << GetNameTextSize() << std::endl
2103 << " Number Text Size: " << GetNumberTextSize() << std::endl;
2104
2105 return aStream;
2106}
2107
2108
2109#if defined(DEBUG)
2110
2111void SCH_PIN::Show( int nestLevel, std::ostream& os ) const
2112{
2113 NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
2114 << " num=\"" << m_number.mb_str()
2115 << '"' << "/>\n";
2116
2117// NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
2118}
2119
2120#endif
2121
2122void SCH_PIN::CalcEdit( const VECTOR2I& aPosition )
2123{
2124 if( IsMoving() )
2125 SetPosition( aPosition );
2126}
2127
2128
2129static struct SCH_PIN_DESC
2130{
2132 {
2133 auto& pinTypeEnum = ENUM_MAP<ELECTRICAL_PINTYPE>::Instance();
2134
2135 if( pinTypeEnum.Choices().GetCount() == 0 )
2136 {
2137 pinTypeEnum.Map( ELECTRICAL_PINTYPE::PT_INPUT, _HKI( "Input" ) )
2138 .Map( ELECTRICAL_PINTYPE::PT_OUTPUT, _HKI( "Output" ) )
2139 .Map( ELECTRICAL_PINTYPE::PT_BIDI, _HKI( "Bidirectional" ) )
2140 .Map( ELECTRICAL_PINTYPE::PT_TRISTATE, _HKI( "Tri-state" ) )
2141 .Map( ELECTRICAL_PINTYPE::PT_PASSIVE, _HKI( "Passive" ) )
2142 .Map( ELECTRICAL_PINTYPE::PT_NIC, _HKI( "Free" ) )
2143 .Map( ELECTRICAL_PINTYPE::PT_UNSPECIFIED, _HKI( "Unspecified" ) )
2144 .Map( ELECTRICAL_PINTYPE::PT_POWER_IN, _HKI( "Power input" ) )
2145 .Map( ELECTRICAL_PINTYPE::PT_POWER_OUT, _HKI( "Power output" ) )
2146 .Map( ELECTRICAL_PINTYPE::PT_OPENCOLLECTOR, _HKI( "Open collector" ) )
2147 .Map( ELECTRICAL_PINTYPE::PT_OPENEMITTER, _HKI( "Open emitter" ) )
2148 .Map( ELECTRICAL_PINTYPE::PT_NC, _HKI( "Unconnected" ) );
2149 }
2150
2151 auto& pinShapeEnum = ENUM_MAP<GRAPHIC_PINSHAPE>::Instance();
2152
2153 if( pinShapeEnum.Choices().GetCount() == 0 )
2154 {
2155 pinShapeEnum.Map( GRAPHIC_PINSHAPE::LINE, _HKI( "Line" ) )
2156 .Map( GRAPHIC_PINSHAPE::INVERTED, _HKI( "Inverted" ) )
2157 .Map( GRAPHIC_PINSHAPE::CLOCK, _HKI( "Clock" ) )
2158 .Map( GRAPHIC_PINSHAPE::INVERTED_CLOCK, _HKI( "Inverted clock" ) )
2159 .Map( GRAPHIC_PINSHAPE::INPUT_LOW, _HKI( "Input low" ) )
2160 .Map( GRAPHIC_PINSHAPE::CLOCK_LOW, _HKI( "Clock low" ) )
2161 .Map( GRAPHIC_PINSHAPE::OUTPUT_LOW, _HKI( "Output low" ) )
2162 .Map( GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK, _HKI( "Falling edge clock" ) )
2163 .Map( GRAPHIC_PINSHAPE::NONLOGIC, _HKI( "NonLogic" ) );
2164 }
2165
2166 auto& orientationEnum = ENUM_MAP<PIN_ORIENTATION>::Instance();
2167
2168 if( orientationEnum.Choices().GetCount() == 0 )
2169 {
2170 orientationEnum.Map( PIN_ORIENTATION::PIN_RIGHT, _( "Right" ) )
2171 .Map( PIN_ORIENTATION::PIN_LEFT, _( "Left" ) )
2172 .Map( PIN_ORIENTATION::PIN_UP, _( "Up" ) )
2173 .Map( PIN_ORIENTATION::PIN_DOWN, _( "Down" ) );
2174 }
2175
2176 auto isSymbolEditor =
2177 []( INSPECTABLE* aItem ) -> bool
2178 {
2179 if( SCH_PIN* pin = dynamic_cast<SCH_PIN*>( aItem ) )
2180 return dynamic_cast<LIB_SYMBOL*>( pin->GetParentSymbol() ) != nullptr;
2181
2182 return false;
2183 };
2184
2189
2190 propMgr.AddProperty( new PROPERTY<SCH_PIN, wxString>( _HKI( "Pin Name" ),
2192 .SetWriteableFunc( isSymbolEditor );
2193
2194 propMgr.AddProperty( new PROPERTY<SCH_PIN, wxString>( _HKI( "Pin Number" ),
2196 .SetWriteableFunc( isSymbolEditor );
2197
2199 _HKI( "Electrical Type" ),
2201 .SetWriteableFunc( isSymbolEditor );
2202
2204 _HKI( "Graphic Style" ),
2206 .SetWriteableFunc( isSymbolEditor );
2207
2208 propMgr.AddProperty( new PROPERTY<SCH_PIN, int>( _HKI( "Position X" ),
2209 &SCH_PIN::SetX, &SCH_PIN::GetX, PROPERTY_DISPLAY::PT_COORD ) )
2210 .SetAvailableFunc( isSymbolEditor );
2211
2212 propMgr.AddProperty( new PROPERTY<SCH_PIN, int>( _HKI( "Position Y" ),
2213 &SCH_PIN::SetY, &SCH_PIN::GetY, PROPERTY_DISPLAY::PT_COORD ) )
2214 .SetAvailableFunc( isSymbolEditor );
2215
2216 propMgr.AddProperty( new PROPERTY_ENUM<SCH_PIN, PIN_ORIENTATION>( _HKI( "Orientation" ),
2218 .SetWriteableFunc( isSymbolEditor );
2219
2220 propMgr.AddProperty( new PROPERTY<SCH_PIN, int>( _HKI( "Length" ),
2222 PROPERTY_DISPLAY::PT_SIZE ) )
2223 .SetWriteableFunc( isSymbolEditor );
2224
2225 propMgr.AddProperty( new PROPERTY<SCH_PIN, int>( _HKI( "Name Text Size" ),
2227 PROPERTY_DISPLAY::PT_SIZE ) )
2228 .SetAvailableFunc( isSymbolEditor );
2229
2230 propMgr.AddProperty( new PROPERTY<SCH_PIN, int>( _HKI( "Number Text Size" ),
2232 PROPERTY_DISPLAY::PT_SIZE ) )
2233 .SetAvailableFunc( isSymbolEditor );
2234
2235 propMgr.AddProperty( new PROPERTY<SCH_PIN, bool>( _HKI( "Visible" ),
2237 .SetAvailableFunc( isSymbolEditor );
2238
2239 }
2241
2242
int color
Definition: DXF_plotter.cpp:58
const char * name
Definition: DXF_plotter.cpp:57
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
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
The base class for create windows for drawing purpose.
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:89
const KIID m_Uuid
Definition: eda_item.h:489
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:101
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:499
virtual bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const
Compare the item against the search criteria in aSearchData.
Definition: eda_item.h:377
EDA_ITEM * GetParent() const
Definition: eda_item.h:103
EDA_ITEM * m_parent
Linked list: Link (parent struct)
Definition: eda_item.h:500
bool IsMoving() const
Definition: eda_item.h:108
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:94
static ENUM_MAP< T > & Instance()
Definition: property.h:663
Class that other classes need to inherit from, in order to be inspectable.
Definition: inspectable.h:36
FONT is an abstract base class for both outline and stroke fonts.
Definition: font.h:131
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:146
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:435
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
COLOR4D & Desaturate()
Removes color (in HSL model)
Definition: color4d.cpp:511
COLOR4D Mix(const COLOR4D &aColor, double aFactor) const
Return a color that is mixed with the input by a factor.
Definition: color4d.h:295
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
int GetDefaultPenWidth() const
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.
wxDC * GetPrintDC() const
Definition: kiid.h:49
wxString AsString() const
Definition: kiid.cpp:238
Define a library symbol object.
Definition: lib_symbol.h:78
Definition: line.h:36
Container for data for KiCad programs.
Definition: pgm_base.h:102
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:142
A pin layout helper is a class that manages the layout of the parts of a pin on a schematic symbol:
Base plotter engine class.
Definition: plotter.h:105
virtual void Circle(const VECTOR2I &pos, int diametre, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH)=0
void MoveTo(const VECTOR2I &pos)
Definition: plotter.h:244
void FinishTo(const VECTOR2I &pos)
Definition: plotter.h:254
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:136
bool GetColorMode() const
Definition: plotter.h:133
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:249
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:754
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:257
PROPERTY_BASE & SetWriteableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Definition: property.h:268
Provide class metadata.Helper macro to map type hashes to names.
Definition: property_mgr.h:85
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
static PROPERTY_MANAGER & Instance()
Definition: property_mgr.h:87
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
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
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:166
int m_unit
Definition: sch_item.h:724
SCH_ITEM & operator=(const SCH_ITEM &aPin)
Definition: sch_item.cpp:101
int m_bodyStyle
Definition: sch_item.h:725
SCH_RENDER_SETTINGS * getRenderSettings(PLOTTER *aPlotter) const
Definition: sch_item.h:670
const SYMBOL * GetParentSymbol() const
Definition: sch_item.cpp:166
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:150
int GetBodyStyle() const
Definition: sch_item.h:232
static wxString GetUnitDescription(int aUnit)
Definition: sch_item.cpp:52
@ EQUALITY
Definition: sch_item.h:660
int GetUnit() const
Definition: sch_item.h:229
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:419
bool IsConnectivityDirty() const
Definition: sch_item.h:510
static wxString GetBodyStyleDescription(int aBodyStyle)
Definition: sch_item.cpp:61
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:221
const KIFONT::METRICS & GetFontMetrics() const
Definition: sch_item.cpp:466
int GetEffectivePenWidth(const SCH_RENDER_SETTINGS *aSettings) const
Definition: sch_item.cpp:475
SCH_LAYER_ID m_layer
Definition: sch_item.h:723
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:316
void getSymbolEditorMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList)
Definition: sch_item.cpp:501
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW=true) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_pin.cpp:1509
std::ostream & operator<<(std::ostream &aStream)
Definition: sch_pin.cpp:2092
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:1170
int GetNumberTextSize() const
Definition: sch_pin.cpp:552
int GetLength() const
Definition: sch_pin.cpp:291
std::optional< bool > m_hidden
Definition: sch_pin.h:374
bool Matches(const EDA_SEARCH_DATA &aSearchData, void *aAuxData) const override
Compare the item against the search criteria in aSearchData.
Definition: sch_pin.cpp:435
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:1537
std::unique_ptr< PIN_LAYOUT_CACHE > m_layoutCache
The layout cache for this pin.
Definition: sch_pin.h:389
void MirrorVerticallyPin(int aCenter)
Definition: sch_pin.cpp:1458
void validateExtentsCache(KIFONT::FONT *aFont, int aSize, const wxString &aText, EXTENTS_CACHE *aCache) const
Definition: sch_pin.cpp:1727
const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
Definition: sch_pin.cpp:1709
void CalcEdit(const VECTOR2I &aPosition) override
Calculate the attributes of an item at aPosition when it is being edited.
Definition: sch_pin.cpp:2122
void SetNumber(const wxString &aNumber)
Definition: sch_pin.cpp:514
std::optional< int > m_nameTextSize
Definition: sch_pin.h:378
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:1360
void SetVisible(bool aVisible)
Definition: sch_pin.h:107
int GetX() const
Definition: sch_pin.h:206
void ChangeLength(int aLength)
Change the length of a pin and adjust its position based on orientation.
Definition: sch_pin.cpp:1404
ALT GetAlt(const wxString &aAlt)
Definition: sch_pin.h:141
void SetX(int aX)
Definition: sch_pin.h:207
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:1757
SCH_PIN & operator=(const SCH_PIN &aPin)
Definition: sch_pin.cpp:227
wxString GetShownNumber() const
Definition: sch_pin.cpp:505
SCH_PIN * m_libPin
Definition: sch_pin.h:363
void Move(const VECTOR2I &aOffset) override
Move the item by aMoveVector to a new position.
Definition: sch_pin.cpp:1432
std::map< const SCH_SHEET_PATH, std::pair< wxString, bool > > m_net_name_map
Definition: sch_pin.h:393
PIN_ORIENTATION m_orientation
Definition: sch_pin.h:371
void SetOrientation(PIN_ORIENTATION aOrientation)
Definition: sch_pin.h:86
void SetName(const wxString &aName)
Definition: sch_pin.cpp:393
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.h:191
wxString getItemDescription(ALT *aAlt) const
Definition: sch_pin.cpp:1827
bool IsVisible() const
Definition: sch_pin.cpp:362
bool ConnectionPropagatesTo(const EDA_ITEM *aItem) const override
Return true if this item should propagate connection info to aItem.
Definition: sch_pin.cpp:1779
std::optional< int > m_numTextSize
Definition: sch_pin.h:377
VECTOR2I GetPinRoot() const
Definition: sch_pin.cpp:577
ELECTRICAL_PINTYPE m_type
Definition: sch_pin.h:373
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_pin.cpp:1471
SCH_PIN * GetLibPin() const
Definition: sch_pin.h:82
void SetPosition(const VECTOR2I &aPos) override
Definition: sch_pin.h:203
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:2032
bool m_isDangling
Definition: sch_pin.h:383
void SetIsDangling(bool aIsDangling)
Definition: sch_pin.cpp:415
wxString GetElectricalTypeName() const
Definition: sch_pin.cpp:348
std::map< wxString, ALT > m_alternates
Definition: sch_pin.h:366
void ViewGetLayers(int aLayers[], int &aCount) const override
Return the layers the item is drawn on (which may be more than its "home" layer)
Definition: sch_pin.cpp:1715
const wxString & GetName() const
Definition: sch_pin.cpp:375
void SetLength(int aLength)
Definition: sch_pin.h:92
bool IsDangling() const override
Definition: sch_pin.cpp:406
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:1516
void MirrorHorizontally(int aCenter) override
these transforms have effect only if the pin has a LIB_SYMBOL as parent
Definition: sch_pin.cpp:1451
std::recursive_mutex m_netmap_mutex
The name that this pin connection will drive onto a net.
Definition: sch_pin.h:392
PIN_ORIENTATION GetOrientation() const
Definition: sch_pin.cpp:258
wxString GetClass() const override
Return the class name.
Definition: sch_pin.h:67
void SetNumberTextSize(int aSize)
Definition: sch_pin.cpp:567
void printPinTexts(const RENDER_SETTINGS *aSettings, const VECTOR2I &aPinPos, PIN_ORIENTATION aPinOrient, int aTextInside, bool aDrawPinNum, bool aDrawPinName, bool aDimmed)
Put the pin number and pin text info, given the pin line coordinates.
Definition: sch_pin.cpp:774
void SetShape(GRAPHIC_PINSHAPE aShape)
Definition: sch_pin.h:89
void RotatePin(const VECTOR2I &aCenter, bool aRotateCCW=true)
Definition: sch_pin.cpp:1478
VECTOR2I GetPosition() const override
Definition: sch_pin.cpp:250
wxString GetCanonicalElectricalTypeName() const
Definition: sch_pin.cpp:334
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:448
int GetNameTextSize() const
Definition: sch_pin.cpp:527
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
Definition: sch_pin.cpp:1800
VECTOR2I m_position
Definition: sch_pin.h:369
void printPinSymbol(const SCH_RENDER_SETTINGS *aSettings, const VECTOR2I &aPos, PIN_ORIENTATION aOrientation, bool aDimmed)
Print the pin symbol without text.
Definition: sch_pin.cpp:646
GRAPHIC_PINSHAPE m_shape
Definition: sch_pin.h:372
int compare(const SCH_ITEM &aOther, int aCompareFlags=0) const override
The pin specific sort order is as follows:
Definition: sch_pin.cpp:1879
wxString GetShownName() const
Definition: sch_pin.cpp:491
void MirrorHorizontallyPin(int aCenter)
these transforms have always effects
Definition: sch_pin.cpp:1438
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:461
wxString m_name
Definition: sch_pin.h:375
wxString m_alt
Definition: sch_pin.h:379
void SetType(ELECTRICAL_PINTYPE aType)
Definition: sch_pin.cpp:324
const wxString & GetBaseName() const
Get the name without any alternates.
Definition: sch_pin.cpp:384
~SCH_PIN()
Definition: sch_pin.cpp:222
void ClearDefaultNetName(const SCH_SHEET_PATH *aPath)
Definition: sch_pin.cpp:1605
void SetY(int aY)
Definition: sch_pin.h:209
void printPinElectricalTypeName(const RENDER_SETTINGS *aSettings, const VECTOR2I &aPosition, PIN_ORIENTATION aOrientation, bool aDimmed)
Draw the electrical type text of the pin (only for the footprint editor)
Definition: sch_pin.cpp:951
SCH_PIN(LIB_SYMBOL *aParentSymbol)
Definition: sch_pin.cpp:100
bool IsStacked(const SCH_PIN *aPin) const
Definition: sch_pin.cpp:421
const wxString & GetNumber() const
Definition: sch_pin.h:117
wxString m_number
Definition: sch_pin.h:376
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: sch_pin.cpp:1395
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_pin.h:175
void Print(const SCH_RENDER_SETTINGS *aSettings, int aUnit, int aBodyStyle, const VECTOR2I &aOffset, bool aForceNoFill, bool aDimmed) override
Print an item.
Definition: sch_pin.cpp:597
wxString GetDefaultNetName(const SCH_SHEET_PATH &aPath, bool aForceNoConnect=false)
Definition: sch_pin.cpp:1616
std::optional< int > m_length
Definition: sch_pin.h:370
GRAPHIC_PINSHAPE GetShape() const
Definition: sch_pin.cpp:271
void PlotPinType(PLOTTER *aPlotter, const VECTOR2I &aPosition, PIN_ORIENTATION aOrientation, bool aDimmed) const
Definition: sch_pin.cpp:1023
int GetY() const
Definition: sch_pin.h:208
ELECTRICAL_PINTYPE GetType() const
Definition: sch_pin.cpp:304
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: sch_pin.cpp:1788
void SetNameTextSize(int aSize)
Definition: sch_pin.cpp:542
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:104
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:939
const wxString GetValue(bool aResolve, const SCH_SHEET_PATH *aPath, bool aAllowExtraText) const override
Definition: sch_symbol.cpp:907
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve a list of the SCH_PINs for the given sheet path.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
Definition: sch_symbol.cpp:737
T * GetAppSettings()
Returns a handle to the a given settings by type If the settings have already been loaded,...
A base class for LIB_SYMBOL and SCH_SYMBOL.
Definition: symbol.h:34
virtual int GetUnitCount() const =0
virtual const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const =0
virtual bool IsPower() const =0
int GetPinNameOffset() const
Definition: symbol.h:118
virtual bool GetShowPinNames() const
Definition: symbol.h:124
virtual bool GetShowPinNumbers() const
Definition: symbol.h:130
virtual bool HasAlternateBodyStyle() const =0
Test if symbol has more than one body conversion type (DeMorgan).
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 _HKI(x)
#define _(s)
static constexpr EDA_ANGLE ANGLE_90
Definition: eda_angle.h:403
static constexpr EDA_ANGLE ANGLE_VERTICAL
Definition: eda_angle.h:398
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition: eda_angle.h:397
#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. Shared with IS_ROLLOVER.
void GRLineTo(wxDC *DC, int x, int y, int width, const COLOR4D &Color)
Definition: gr_basic.cpp:195
void GRCircle(wxDC *aDC, const VECTOR2I &aPos, int aRadius, int aWidth, const COLOR4D &aColor)
Definition: gr_basic.cpp:357
void GRMoveTo(int x, int y)
Definition: gr_basic.cpp:188
void GRLine(wxDC *DC, int x1, int y1, int x2, int y2, int width, const COLOR4D &Color, wxPenStyle aStyle)
Definition: gr_basic.cpp:171
bool GetGRForceBlackPenState(void)
Definition: gr_basic.cpp:165
int GetPenSizeForNormal(int aTextSize)
Definition: gr_text.cpp:64
void GRPrintText(wxDC *aDC, const VECTOR2I &aPos, const COLOR4D &aColor, const wxString &aText, const EDA_ANGLE &aOrient, const VECTOR2I &aSize, enum GR_TEXT_H_ALIGN_T aH_justify, enum GR_TEXT_V_ALIGN_T aV_justify, int aWidth, bool aItalic, bool aBold, KIFONT::FONT *aFont, const KIFONT::METRICS &aFontMetrics)
Print a graphic text through wxDC.
Definition: gr_text.cpp:142
@ LAYER_DANGLING
Definition: layer_ids.h:381
@ LAYER_PINNUM
Definition: layer_ids.h:362
@ LAYER_DEVICE
Definition: layer_ids.h:370
@ LAYER_HIDDEN
Definition: layer_ids.h:395
@ LAYER_PINNAM
Definition: layer_ids.h:363
@ LAYER_PRIVATE_NOTES
Definition: layer_ids.h:372
@ LAYER_PIN
Definition: layer_ids.h:374
@ LAYER_OP_CURRENTS
Definition: layer_ids.h:404
@ LAYER_SELECTION_SHADOWS
Definition: layer_ids.h:397
STL namespace.
PGM_BASE * PgmOrNull()
similar to PGM_BASE& Pgm(), but return a reference that can be nullptr when running a shared lib from...
Definition: pgm_base.cpp:1067
see class PGM_BASE
wxString ElectricalPinTypeGetText(ELECTRICAL_PINTYPE aType)
Definition: pin_type.cpp:207
BITMAPS ElectricalPinTypeGetBitmap(ELECTRICAL_PINTYPE aType)
Definition: pin_type.cpp:220
wxString PinShapeGetText(GRAPHIC_PINSHAPE aShape)
Definition: pin_type.cpp:233
wxString PinOrientationName(PIN_ORIENTATION aOrientation)
Definition: pin_type.cpp:259
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
Definition: pin_type.h:36
@ PT_UNSPECIFIED
unknown electrical properties: creates always a warning when connected
PIN_ORIENTATION
The symbol library pin object orientations.
Definition: pin_type.h:78
@ PIN_RIGHT
The pin extends rightwards from the connection point.
GRAPHIC_PINSHAPE
Definition: pin_type.h:57
#define TYPE_HASH(x)
Definition: property.h:71
#define ENUM_TO_WXANY(type)
Macro to define read-only fields (no setter method available)
Definition: property.h:765
#define REGISTER_TYPE(x)
Definition: property_mgr.h:371
#define ETXT_MAX_SIZE
static int externalPinDecoSize(const RENDER_SETTINGS *aSettings, const SCH_PIN &aPin)
Utility for getting the size of the 'external' pin decorators (as a radius)
Definition: sch_pin.cpp:89
#define PIN_TEXT_MARGIN
Definition: sch_pin.cpp:44
static int internalPinDecoSize(const RENDER_SETTINGS *aSettings, const SCH_PIN &aPin)
Utility for getting the size of the 'internal' pin decorators (as a radius)
Definition: sch_pin.cpp:76
static struct SCH_PIN_DESC _SCH_PIN_DESC
#define TARGET_PIN_RADIUS
Definition: sch_pin.h:37
wxString UnescapeString(const wxString &aSource)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_NETNAME
Definition: string_utils.h:53
constexpr int MilsToIU(int mils) const
Definition: base_units.h:93
constexpr int mmToIU(double mm) const
Definition: base_units.h:88
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:309
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
GR_TEXT_H_ALIGN_T
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
GR_TEXT_V_ALIGN_T
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition: trigo.cpp:229
@ SCH_PIN_T
Definition: typeinfo.h:153
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:691