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