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