KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pin_layout_cache.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) 2024 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include "pin_layout_cache.h"
25
27#include <pgm_base.h>
29#include <sch_symbol.h>
30#include <eeschema_settings.h>
31#include <schematic_settings.h>
32
34
35
36namespace
37{
38
39// small margin in internal units between the pin text and the pin line
40const int PIN_TEXT_MARGIN = 4;
41
42struct EXTENTS_CACHE
43{
44 KIFONT::FONT* m_Font = nullptr;
45 int m_FontSize = 0;
46 VECTOR2I m_Extents;
47};
48
50// i.e. the negation circle, the polarity 'slopes' and the nonlogic
51// marker
52int externalPinDecoSize( const SCHEMATIC_SETTINGS* aSettings, const SCH_PIN& aPin )
53{
54 if( aSettings && aSettings->m_PinSymbolSize )
55 return aSettings->m_PinSymbolSize;
56
57 return aPin.GetNumberTextSize() / 2;
58}
59
60
61int internalPinDecoSize( const SCHEMATIC_SETTINGS* aSettings, const SCH_PIN& aPin )
62{
63 if( aSettings && aSettings->m_PinSymbolSize > 0 )
64 return aSettings->m_PinSymbolSize;
65
66 return aPin.GetNameTextSize() != 0 ? aPin.GetNameTextSize() / 2 : aPin.GetNumberTextSize() / 2;
67}
68
69} // namespace
70
71
73 m_pin( aPin ), m_schSettings( nullptr ), m_dirtyFlags( DIRTY_FLAGS::ALL )
74{
75 // Resolve the schematic (can be null, e.g. in previews)
76 const SCHEMATIC* schematic = aPin.Schematic();
77
78 if( schematic )
79 {
80 m_schSettings = &schematic->Settings();
81 }
82}
83
84
85void PIN_LAYOUT_CACHE::MarkDirty( int aDirtyFlags )
86{
87 m_dirtyFlags |= aDirtyFlags;
88}
89
90
91void PIN_LAYOUT_CACHE::SetRenderParameters( int aNameThickness, int aNumberThickness,
92 bool aShowElectricalType, bool aShowAltIcons )
93{
94 if( aNameThickness != m_nameThickness )
95 {
97 m_nameThickness = aNameThickness;
98 }
99
100 if( aNumberThickness != m_numberThickness )
101 {
103 m_numberThickness = aNumberThickness;
104 }
105
106 if( aShowElectricalType != m_showElectricalType )
107 {
109 m_showElectricalType = aShowElectricalType;
110 }
111
112 // Not (yet?) cached
113 m_showAltIcons = aShowAltIcons;
114}
115
116
117void PIN_LAYOUT_CACHE::recomputeExtentsCache( bool aDefinitelyDirty, KIFONT::FONT* aFont, int aSize,
118 const wxString& aText,
119 const KIFONT::METRICS& aFontMetrics,
120 TEXT_EXTENTS_CACHE& aCache )
121{
122 // Even if not definitely dirty, verify no font changes
123 if( !aDefinitelyDirty && aCache.m_Font == aFont && aCache.m_FontSize == aSize )
124 {
125 return;
126 }
127
128 aCache.m_Font = aFont;
129 aCache.m_FontSize = aSize;
130
131 VECTOR2D fontSize( aSize, aSize );
132 int penWidth = GetPenSizeForNormal( aSize );
133
134 aCache.m_Extents =
135 aFont->StringBoundaryLimits( aText, fontSize, penWidth, false, false, aFontMetrics );
136}
137
138
140{
143 const KIFONT::METRICS& metrics = m_pin.GetFontMetrics();
144
145 // Due to the fact a shadow text in position INSIDE or OUTSIDE is drawn left or right aligned,
146 // it needs an offset = shadowWidth/2 to be drawn at the same place as normal text
147 // texts drawn as GR_TEXT_H_ALIGN_CENTER do not need a specific offset.
148 // this offset is shadowWidth/2 but for some reason we need to slightly modify this offset
149 // for a better look (better alignment of shadow shape), for KiCad font only
150 if( !font->IsOutline() )
151 m_shadowOffsetAdjust = 1.2f; // Value chosen after tests
152 else
154
155 {
156 const bool dirty = isDirty( DIRTY_FLAGS::NUMBER );
157 const wxString number = m_pin.GetShownNumber();
158 recomputeExtentsCache( dirty, font, m_pin.GetNumberTextSize(), number, metrics,
160 }
161
162 {
163 const bool dirty = isDirty( DIRTY_FLAGS::NAME );
164 const wxString name = m_pin.GetShownName();
165 recomputeExtentsCache( dirty, font, m_pin.GetNameTextSize(), name, metrics,
167 }
168
169 {
170 double fontSize = std::max( m_pin.GetNameTextSize() * 3 / 4, schIUScale.mmToIU( 0.7 ) );
173 }
174
176}
177
178
180{
181 // Now, calculate boundary box corners position for the actual pin orientation
183 {
184 case PIN_ORIENTATION::PIN_UP:
185 {
186 // Pin is rotated and texts positions are mirrored
187 VECTOR2I c1{ aBox.GetLeft(), aBox.GetTop() };
188 VECTOR2I c2{ aBox.GetRight(), aBox.GetBottom() };
189
190 RotatePoint( c1, VECTOR2I( 0, 0 ), ANGLE_90 );
191 RotatePoint( c2, VECTOR2I( 0, 0 ), ANGLE_90 );
192
193 aBox = BOX2I::ByCorners( c1, c2 );
194 break;
195 }
196 case PIN_ORIENTATION::PIN_DOWN:
197 {
198 VECTOR2I c1{ aBox.GetLeft(), aBox.GetTop() };
199 VECTOR2I c2{ aBox.GetRight(), aBox.GetBottom() };
200
201 RotatePoint( c1, VECTOR2I( 0, 0 ), -ANGLE_90 );
202 RotatePoint( c2, VECTOR2I( 0, 0 ), -ANGLE_90 );
203
204 c1.x = -c1.x;
205 c2.x = -c2.x;
206
207 aBox = BOX2I::ByCorners( c1, c2 );
208 break;
209 }
210 case PIN_ORIENTATION::PIN_LEFT:
211 // Flip it around
212 aBox.Move( { -aBox.GetCenter().x * 2, 0 } );
213 break;
214
215 default:
216 case PIN_ORIENTATION::PIN_RIGHT:
217 // Already in this form
218 break;
219 }
220
221 aBox.Move( m_pin.GetPosition() );
222}
223
224
226{
227 // Now, calculate boundary box corners position for the actual pin orientation
229 {
230 case PIN_ORIENTATION::PIN_LEFT:
231 {
232 aInfo.m_HAlign = GetFlippedAlignment( aInfo.m_HAlign );
233 aInfo.m_TextPosition.x = -aInfo.m_TextPosition.x;
234 break;
235 }
236 case PIN_ORIENTATION::PIN_UP:
237 {
238 aInfo.m_Angle = ANGLE_VERTICAL;
239 aInfo.m_TextPosition = { aInfo.m_TextPosition.y, -aInfo.m_TextPosition.x };
240 break;
241 }
242 case PIN_ORIENTATION::PIN_DOWN:
243 {
244 aInfo.m_Angle = ANGLE_VERTICAL;
245 aInfo.m_TextPosition = { aInfo.m_TextPosition.y, aInfo.m_TextPosition.x };
246 aInfo.m_HAlign = GetFlippedAlignment( aInfo.m_HAlign );
247 break;
248 }
249 default:
250 case PIN_ORIENTATION::PIN_RIGHT:
251 // Already in this form
252 break;
253 }
254
256}
257
258
259BOX2I PIN_LAYOUT_CACHE::GetPinBoundingBox( bool aIncludeLabelsOnInvisiblePins,
260 bool aIncludeNameAndNumber, bool aIncludeElectricalType )
261{
262 if( const SCH_SYMBOL* symbol = dynamic_cast<const SCH_SYMBOL*>( m_pin.GetParentSymbol() ) )
263 {
264 SCH_PIN* const libPin = m_pin.GetLibPin();
265 wxCHECK( libPin, BOX2I() );
266
267 BOX2I r = libPin->GetBoundingBox( aIncludeLabelsOnInvisiblePins, aIncludeNameAndNumber,
268 aIncludeElectricalType );
269
270 r = symbol->GetTransform().TransformCoordinate( r );
271 r.Offset( symbol->GetPosition() );
272 r.Normalize();
273
274 return r;
275 }
276
277 bool includeName = aIncludeNameAndNumber && !m_pin.GetShownName().IsEmpty();
278 bool includeNumber = aIncludeNameAndNumber && !m_pin.GetShownNumber().IsEmpty();
279 bool includeType = aIncludeElectricalType;
280
281 if( !aIncludeLabelsOnInvisiblePins && !m_pin.IsVisible() )
282 {
283 includeName = false;
284 includeNumber = false;
285 includeType = false;
286 }
287
288 if( const SYMBOL* parentSymbol = m_pin.GetParentSymbol() )
289 {
290 if( !parentSymbol->GetShowPinNames() )
291 includeName = false;
292
293 if( !parentSymbol->GetShowPinNumbers() )
294 includeNumber = false;
295 }
296
298
299 const int pinLength = m_pin.GetLength();
300
301 // Creating and merging all the boxes is pretty quick, if cached we'd have
302 // to track many variables here, which is possible, but unlikely to be worth it.
303 BOX2I bbox;
304
305 // Untransformed pin box
306 {
307 BOX2I pinBox = BOX2I::ByCorners( { 0, 0 }, { pinLength, 0 } );
308 pinBox.Inflate( m_pin.GetPenWidth() / 2 );
309 bbox.Merge( pinBox );
310 }
311
313 {
314 bbox.Merge( *decoBox );
315 }
316
317 if( includeName )
318 {
319 if( OPT_BOX2I nameBox = getUntransformedPinNameBox() )
320 {
321 bbox.Merge( *nameBox );
322 }
323
324 if( OPT_BOX2I altIconBox = getUntransformedAltIconBox() )
325 {
326 bbox.Merge( *altIconBox );
327 }
328 }
329
330 if( includeNumber )
331 {
333 {
334 bbox.Merge( *numBox );
335 }
336 }
337
338 if( includeType )
339 {
340 if( OPT_BOX2I typeBox = getUntransformedPinTypeBox() )
341 {
342 bbox.Merge( *typeBox );
343 }
344 }
345
346 transformBoxForPin( bbox );
347
348 if( m_pin.IsDangling() )
349 {
350 // Not much point caching this, but we could
351 const CIRCLE c = GetDanglingIndicator();
352
353 BOX2I cBox = BOX2I::ByCenter( c.Center, { c.Radius * 2, c.Radius * 2 } );
354 // TODO: need some way to find the thickness...?
355 // cBox.Inflate( ??? );
356
357 bbox.Merge( cBox );
358 }
359
360 bbox.Normalize();
361 bbox.Inflate( ( m_pin.GetPenWidth() / 2 ) + 1 );
362
363 return bbox;
364}
365
366
368{
369 return CIRCLE{
372 };
373}
374
375
377{
378 const float offsetRatio =
380 return schIUScale.MilsToIU( KiROUND( 24 * offsetRatio ) );
381}
382
383
385{
386 int pinNameOffset = 0;
387 if( const SYMBOL* parentSymbol = m_pin.GetParentSymbol() )
388 {
389 if( parentSymbol->GetShowPinNames() )
390 pinNameOffset = parentSymbol->GetPinNameOffset();
391 }
392
393 // We're considering the PIN_RIGHT scenario
394 // TEXT
395 // X-------| TEXT
396 // TEXT
397 //
398 // We'll rotate it later.
399
400 OPT_BOX2I box;
401 const int pinLength = m_pin.GetLength();
402
403 if( pinNameOffset > 0 )
404 {
405 // This means name inside the pin
406 box = BOX2I::ByCenter( { pinLength, 0 }, m_nameExtentsCache.m_Extents );
407
408 // Bump over to be left aligned just inside the pin
409 box->Move( { m_nameExtentsCache.m_Extents.x / 2 + pinNameOffset, 0 } );
410 }
411 else
412 {
413 // The pin name is always over the pin
414 box = BOX2I::ByCenter( { pinLength / 2, 0 }, m_nameExtentsCache.m_Extents );
415
416 // Bump it up
417 box->Move( { 0, -m_nameExtentsCache.m_Extents.y / 2 - getPinTextOffset() } );
418 }
419
420 return box;
421}
422
423
425{
426 int pinNameOffset = 0;
427 if( const SYMBOL* parentSymbol = m_pin.GetParentSymbol() )
428 {
429 if( parentSymbol->GetShowPinNames() )
430 pinNameOffset = parentSymbol->GetPinNameOffset();
431 }
432
433 const int pinLength = m_pin.GetLength();
434
435 // The pin name is always over the pin
436 OPT_BOX2I box = BOX2I::ByCenter( { pinLength / 2, 0 }, m_numExtentsCache.m_Extents );
437
438 int textPos = -m_numExtentsCache.m_Extents.y / 2 - getPinTextOffset();
439
440 // The number goes below, if there is a name outside
441 if( pinNameOffset == 0 && !m_pin.GetShownName().empty()
443 textPos *= -1;
444
445 // Bump it up (or down)
446 box->Move( { 0, textPos } );
447
448 return box;
449}
450
451
453{
455 return std::nullopt;
456
457 BOX2I box{
460 };
461
462 // Jog left
463 box.Move( { -schIUScale.MilsToIU( PIN_TEXT_MARGIN ) - TARGET_PIN_RADIUS, 0 } );
464
465 return box;
466}
467
468
470{
471 const OPT_BOX2I nameBox = getUntransformedPinNameBox();
472
473 if( !nameBox || m_pin.GetAlternates().empty() || !m_showAltIcons )
474 return std::nullopt;
475
476 const int iconSize = std::min( m_pin.GetNameTextSize(), schIUScale.mmToIU( 1.5 ) );
477
478 VECTOR2I c{ 0, ( nameBox->GetTop() + nameBox->GetBottom() ) / 2 };
480 {
481 // name inside, so icon more inside
482 c.x = nameBox->GetRight() + iconSize * 0.75;
483 }
484 else
485 {
486 c.x = nameBox->GetLeft() - iconSize * 0.75;
487 }
488
489 return BOX2I::ByCenter( c, { iconSize, iconSize } );
490}
491
492
494{
495 const GRAPHIC_PINSHAPE shape = m_pin.GetShape();
496 const int decoSize = externalPinDecoSize( m_schSettings, m_pin );
497 const int intDecoSize = internalPinDecoSize( m_schSettings, m_pin );
498
499 const auto makeInvertBox = [&]()
500 {
501 return BOX2I::ByCenter( { -decoSize, 0 }, { decoSize * 2, decoSize * 2 } );
502 };
503
504 const auto makeLowBox = [&]()
505 {
506 return BOX2I::ByCorners( { -decoSize * 2, -decoSize * 2 }, { 0, 0 } );
507 };
508
509 const auto makeClockBox = [&]()
510 {
511 return BOX2I::ByCorners( { 0, -intDecoSize }, { intDecoSize, intDecoSize } );
512 };
513
514 OPT_BOX2I box;
515
516 switch( shape )
517 {
518 case GRAPHIC_PINSHAPE::INVERTED:
519 {
520 box = makeInvertBox();
521 break;
522 }
523 case GRAPHIC_PINSHAPE::CLOCK:
524 {
525 box = makeClockBox();
526 break;
527 }
528 case GRAPHIC_PINSHAPE::INVERTED_CLOCK:
529 {
530 box = makeInvertBox();
531 box->Merge( makeClockBox() );
532 break;
533 }
534 case GRAPHIC_PINSHAPE::INPUT_LOW:
535 {
536 box = makeLowBox();
537 break;
538 }
539 case GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK:
540 case GRAPHIC_PINSHAPE::CLOCK_LOW:
541 {
542 box = makeLowBox();
543 box->Merge( makeClockBox() );
544 break;
545 }
546 case GRAPHIC_PINSHAPE::NONLOGIC:
547 {
548 box = BOX2I::ByCenter( { 0, 0 }, { decoSize * 2, decoSize * 2 } );
549 break;
550 }
551 case GRAPHIC_PINSHAPE::LINE:
552 default:
553 {
554 // No decoration
555 break;
556 }
557 }
558
559 if( box )
560 {
561 // Put the box at the root of the pin
562 box->Move( { m_pin.GetLength(), 0 } );
563 box->Inflate( m_pin.GetPenWidth() / 2 );
564 }
565
566 return box;
567}
568
569
571{
574
575 if( box )
576 transformBoxForPin( *box );
577
578 return box;
579}
580
581
583{
586
587 if( box )
588 transformBoxForPin( *box );
589
590 return box;
591}
592
593
595{
597
598 if( box )
599 transformBoxForPin( *box );
600
601 return box;
602}
603
604
605std::optional<PIN_LAYOUT_CACHE::TEXT_INFO> PIN_LAYOUT_CACHE::GetPinNameInfo( int aShadowWidth )
606{
608 wxString name = m_pin.GetShownName();
609
610 // TODO - work out exactly what we need to do to cache this
611 // (or if it's worth the memory/complexity)
612 // But it's not hugely expensive to recompute, and that's what's always been
613 // done to now
614 //
615 // Becasue pins are very likely to share a lot of characteristics, a global
616 // cache might make more sense than a per-pin cache.
617
618 if( name.IsEmpty() || !m_pin.GetParentSymbol()->GetShowPinNames() )
619 return std::nullopt;
620
621 std::optional<TEXT_INFO> info = TEXT_INFO();
622 info->m_Text = std::move( name );
623 info->m_TextSize = m_pin.GetNameTextSize();
624 info->m_Thickness = m_nameThickness;
625 info->m_Angle = ANGLE_HORIZONTAL;
626
628 {
629 // This means name inside the pin
631 const int thickOffset =
632 info->m_Thickness - KiROUND( aShadowWidth * m_shadowOffsetAdjust ) / 2;
633
634 info->m_TextPosition = pos + VECTOR2I{ thickOffset, 0 };
635 info->m_HAlign = GR_TEXT_H_ALIGN_LEFT;
636 info->m_VAlign = GR_TEXT_V_ALIGN_CENTER;
637 }
638 else
639 {
640 // The pin name is always over the pin
641 VECTOR2I pos = { m_pin.GetLength() / 2, -getPinTextOffset() - info->m_Thickness / 2 };
642
643 info->m_TextPosition = pos;
644 info->m_HAlign = GR_TEXT_H_ALIGN_CENTER;
645 info->m_VAlign = GR_TEXT_V_ALIGN_BOTTOM;
646 }
647
649 return info;
650}
651
652
653std::optional<PIN_LAYOUT_CACHE::TEXT_INFO> PIN_LAYOUT_CACHE::GetPinNumberInfo( int aShadowWidth )
654{
656
657 wxString number = m_pin.GetShownNumber();
658 if( number.IsEmpty() || !m_pin.GetParentSymbol()->GetShowPinNumbers() )
659 return std::nullopt;
660
661 std::optional<TEXT_INFO> info;
662
663 info = TEXT_INFO();
664 info->m_Text = std::move( number );
665 info->m_TextSize = m_pin.GetNumberTextSize();
666 info->m_Thickness = m_numberThickness;
667 info->m_Angle = ANGLE_HORIZONTAL;
668 info->m_TextPosition = { m_pin.GetLength() / 2, 0 };
669 info->m_HAlign = GR_TEXT_H_ALIGN_CENTER;
670
671 // The pin number is above the pin if there's no name, or the name is inside
672 const bool numAbove =
674 || ( m_pin.GetShownName().empty() || !m_pin.GetParentSymbol()->GetShowPinNames() );
675 if( numAbove )
676 {
677 info->m_TextPosition.y -= getPinTextOffset() + info->m_Thickness / 2;
678 info->m_VAlign = GR_TEXT_V_ALIGN_BOTTOM;
679 }
680 else
681 {
682 info->m_TextPosition.y += getPinTextOffset() + info->m_Thickness / 2;
683 info->m_VAlign = GR_TEXT_V_ALIGN_TOP;
684 }
685
687 return info;
688}
689
690std::optional<PIN_LAYOUT_CACHE::TEXT_INFO>
692{
694
696 return std::nullopt;
697
698 std::optional<TEXT_INFO> info = TEXT_INFO();
699 info->m_Text = m_pin.GetElectricalTypeName();
700 info->m_TextSize = std::max( m_pin.GetNameTextSize() * 3 / 4, schIUScale.mmToIU( 0.7 ) );
701 info->m_Angle = ANGLE_HORIZONTAL;
702 info->m_Thickness = info->m_TextSize / 8;
703 info->m_TextPosition = { -getPinTextOffset() - info->m_Thickness / 2
704 + KiROUND( aShadowWidth * m_shadowOffsetAdjust ) / 2,
705 0 };
706 info->m_HAlign = GR_TEXT_H_ALIGN_RIGHT;
707 info->m_VAlign = GR_TEXT_V_ALIGN_CENTER;
708
709 info->m_TextPosition.x -= TARGET_PIN_RADIUS;
710
711 if( m_pin.IsDangling() )
712 {
713 info->m_TextPosition.x -= TARGET_PIN_RADIUS / 2;
714 }
715
717 return info;
718}
const char * name
Definition: DXF_plotter.cpp:57
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
BOX2< VECTOR2I > BOX2I
Definition: box2.h:922
std::optional< BOX2I > OPT_BOX2I
Definition: box2.h:926
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition: box2.h:990
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:558
static constexpr BOX2< VECTOR2I > ByCorners(const VECTOR2I &aCorner1, const VECTOR2I &aCorner2)
Definition: box2.h:70
constexpr BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition: box2.h:146
static constexpr BOX2< VECTOR2I > ByCenter(const VECTOR2I &aCenter, const SizeVec &aSize)
Definition: box2.h:75
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:658
constexpr const Vec GetCenter() const
Definition: box2.h:230
constexpr coord_type GetLeft() const
Definition: box2.h:228
constexpr void Move(const Vec &aMoveVector)
Move the rectangle by the aMoveVector.
Definition: box2.h:138
constexpr coord_type GetRight() const
Definition: box2.h:217
constexpr coord_type GetTop() const
Definition: box2.h:229
constexpr void Offset(coord_type dx, coord_type dy)
Definition: box2.h:259
constexpr coord_type GetBottom() const
Definition: box2.h:222
Represent basic circle geometry with utility geometry functions.
Definition: circle.h:33
VECTOR2I Center
Public to make access simpler.
Definition: circle.h:130
FONT is an abstract base class for both outline and stroke fonts.
Definition: font.h:131
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
Definition: font.cpp:146
VECTOR2I StringBoundaryLimits(const wxString &aText, const VECTOR2I &aSize, int aThickness, bool aBold, bool aItalic, const METRICS &aFontMetrics) const
Compute the boundary limits of aText (the bounding box of all shapes).
Definition: font.cpp:435
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:142
OPT_BOX2I getUntransformedPinNameBox() const
Get the untransformd text box in the default orientation.
TEXT_EXTENTS_CACHE m_nameExtentsCache
void transformTextForPin(TEXT_INFO &aTextInfo) const
Transform text info to suit a pin's.
OPT_BOX2I GetAltIconBBox()
Get the box of the alt mode icon, if there is one.
void transformBoxForPin(BOX2I &aBox) const
Transform a box (in-place) to the pin's orientation.
void recomputeCaches()
Recompute all the caches that have become dirty.
const SCHEMATIC_SETTINGS * m_schSettings
OPT_BOX2I GetPinNumberBBox()
Get the bounding box of the pin number, if there is one.
PIN_LAYOUT_CACHE(const SCH_PIN &aPin)
TEXT_EXTENTS_CACHE m_typeExtentsCache
BOX2I GetPinBoundingBox(bool aIncludeLabelsOnInvisiblePins, bool aIncludeNameAndNumber, bool aIncludeElectricalType)
Get the bounding box of the pin itself.
TEXT_EXTENTS_CACHE m_numExtentsCache
void setClean(int aMask)
OPT_BOX2I getUntransformedPinTypeBox() const
std::optional< TEXT_INFO > GetPinNameInfo(int aShadowWidth)
Get the text info for the pin name.
static void recomputeExtentsCache(bool aDefinitelyDirty, KIFONT::FONT *aFont, int aSize, const wxString &aText, const KIFONT::METRICS &aFontMetrics, TEXT_EXTENTS_CACHE &aCache)
std::optional< TEXT_INFO > GetPinElectricalTypeInfo(int aShadowWidth)
bool isDirty(int aMask) const
CIRCLE GetDanglingIndicator() const
Gets the dangling indicator geometry for this pin, if the pin were to be dangling.
std::optional< TEXT_INFO > GetPinNumberInfo(int aShadowWidth)
OPT_BOX2I GetPinNameBBox()
Get the bounding box of the pin name, if there is one.
void MarkDirty(int aFlags)
Recompute all the layout information.
void SetRenderParameters(int aNameThickness, int aNumberThickness, bool aShowElectricalType, bool aShowAltIcons)
OPT_BOX2I getUntransformedAltIconBox() const
Pin type decoration if any.
int getPinTextOffset() const
Get the current pin text offset.
OPT_BOX2I getUntransformedDecorationBox() const
const SCH_PIN & m_pin
The pin in question.
OPT_BOX2I getUntransformedPinNumberBox() const
These are loaded from Eeschema settings but then overwritten by the project settings.
Holds all the data relating to one schematic.
Definition: schematic.h:77
SCHEMATIC_SETTINGS & Settings() const
Definition: schematic.cpp:314
const SYMBOL * GetParentSymbol() const
Definition: sch_item.cpp:166
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:150
const KIFONT::METRICS & GetFontMetrics() const
Definition: sch_item.cpp:463
int GetNumberTextSize() const
Definition: sch_pin.cpp:552
int GetLength() const
Definition: sch_pin.cpp:291
const std::map< wxString, ALT > & GetAlternates() const
Definition: sch_pin.h:127
PIN_ORIENTATION PinDrawOrient(const TRANSFORM &aTransform) const
Return the pin real orientation (PIN_UP, PIN_DOWN, PIN_RIGHT, PIN_LEFT), according to its orientation...
Definition: sch_pin.cpp:1360
wxString GetShownNumber() const
Definition: sch_pin.cpp:505
bool IsVisible() const
Definition: sch_pin.cpp:362
SCH_PIN * GetLibPin() const
Definition: sch_pin.h:82
wxString GetElectricalTypeName() const
Definition: sch_pin.cpp:348
int GetPenWidth() const override
Definition: sch_pin.h:197
bool IsDangling() const override
Definition: sch_pin.cpp:406
VECTOR2I GetPosition() const override
Definition: sch_pin.cpp:250
int GetNameTextSize() const
Definition: sch_pin.cpp:527
wxString GetShownName() const
Definition: sch_pin.cpp:491
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_pin.h:175
GRAPHIC_PINSHAPE GetShape() const
Definition: sch_pin.cpp:271
Schematic symbol object.
Definition: sch_symbol.h:104
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
int GetPinNameOffset() const
Definition: symbol.h:118
virtual bool GetShowPinNames() const
Definition: symbol.h:124
virtual bool GetShowPinNumbers() const
Definition: symbol.h:130
#define DEFAULT_TEXT_OFFSET_RATIO
Ratio of the font height to space around global labels.
static constexpr EDA_ANGLE ANGLE_90
Definition: eda_angle.h:403
static constexpr EDA_ANGLE ANGLE_VERTICAL
Definition: eda_angle.h:398
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition: eda_angle.h:397
TRANSFORM DefaultTransform
Definition: transform.cpp:32
int GetPenSizeForNormal(int aTextSize)
Definition: gr_text.cpp:64
PGM_BASE & Pgm()
The global Program "get" accessor.
Definition: pgm_base.cpp:1060
see class PGM_BASE
GRAPHIC_PINSHAPE
Definition: pin_type.h:57
static int externalPinDecoSize(const RENDER_SETTINGS *aSettings, const SCH_PIN &aPin)
Utility for getting the size of the 'external' pin decorators (as a radius)
Definition: sch_pin.cpp:89
#define PIN_TEXT_MARGIN
Definition: sch_pin.cpp:44
static int internalPinDecoSize(const RENDER_SETTINGS *aSettings, const SCH_PIN &aPin)
Utility for getting the size of the 'internal' pin decorators (as a radius)
Definition: sch_pin.cpp:76
#define TARGET_PIN_RADIUS
Definition: sch_pin.h:37
Utility functions for working with shapes.
constexpr int MilsToIU(int mils) const
Definition: base_units.h:93
constexpr int mmToIU(double mm) const
Definition: base_units.h:88
Cached extent of a text item.
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
constexpr GR_TEXT_H_ALIGN_T GetFlippedAlignment(GR_TEXT_H_ALIGN_T aAlign)
Get the reverse alignment: left-right are swapped, others are unchanged.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition: trigo.cpp:229
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:691