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