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 VECTOR2I begin;
278 VECTOR2I end;
279 bool includeName = aIncludeNameAndNumber && !m_pin.GetShownName().IsEmpty();
280 bool includeNumber = aIncludeNameAndNumber && !m_pin.GetShownNumber().IsEmpty();
281 bool includeType = aIncludeElectricalType;
282
283 if( !aIncludeLabelsOnInvisiblePins && !m_pin.IsVisible() )
284 {
285 includeName = false;
286 includeNumber = false;
287 includeType = false;
288 }
289
290 if( const SYMBOL* parentSymbol = m_pin.GetParentSymbol() )
291 {
292 if( !parentSymbol->GetShowPinNames() )
293 includeName = false;
294
295 if( !parentSymbol->GetShowPinNumbers() )
296 includeNumber = false;
297 }
298
300
301 const int pinLength = m_pin.GetLength();
302
303 // Creating and merging all the boxes is pretty quick, if cached we'd have
304 // to track many variables here, which is possible, but unlikely to be worth it.
305 BOX2I bbox;
306
307 // Untransformed pin box
308 {
309 BOX2I pinBox = BOX2I::ByCorners( { 0, 0 }, { pinLength, 0 } );
310 pinBox.Inflate( m_pin.GetPenWidth() / 2 );
311 bbox.Merge( pinBox );
312 }
313
315 {
316 bbox.Merge( *decoBox );
317 }
318
319 if( includeName )
320 {
321 if( OPT_BOX2I nameBox = getUntransformedPinNameBox() )
322 {
323 bbox.Merge( *nameBox );
324 }
325
326 if( OPT_BOX2I altIconBox = getUntransformedAltIconBox() )
327 {
328 bbox.Merge( *altIconBox );
329 }
330 }
331
332 if( includeNumber )
333 {
335 {
336 bbox.Merge( *numBox );
337 }
338 }
339
340 if( includeType )
341 {
342 if( OPT_BOX2I typeBox = getUntransformedPinTypeBox() )
343 {
344 bbox.Merge( *typeBox );
345 }
346 }
347
348 transformBoxForPin( bbox );
349
350 if( m_pin.IsDangling() )
351 {
352 // Not much point caching this, but we could
353 const CIRCLE c = GetDanglingIndicator();
354
355 BOX2I cBox = BOX2I::ByCenter( c.Center, { c.Radius * 2, c.Radius * 2 } );
356 // TODO: need some way to find the thickness...?
357 // cBox.Inflate( ??? );
358
359 bbox.Merge( cBox );
360 }
361
362 bbox.Normalize();
363 bbox.Inflate( ( m_pin.GetPenWidth() / 2 ) + 1 );
364
365 return bbox;
366}
367
368
370{
371 return CIRCLE{
374 };
375}
376
377
379{
380 const float offsetRatio =
382 return schIUScale.MilsToIU( KiROUND( 24 * offsetRatio ) );
383}
384
385
387{
388 int pinNameOffset = 0;
389 if( const SYMBOL* parentSymbol = m_pin.GetParentSymbol() )
390 {
391 if( parentSymbol->GetShowPinNames() )
392 pinNameOffset = parentSymbol->GetPinNameOffset();
393 }
394
395 // We're considering the PIN_RIGHT scenario
396 // TEXT
397 // X-------| TEXT
398 // TEXT
399 //
400 // We'll rotate it later.
401
402 OPT_BOX2I box;
403 const int pinLength = m_pin.GetLength();
404
405 if( pinNameOffset > 0 )
406 {
407 // This means name inside the pin
408 box = BOX2I::ByCenter( { pinLength, 0 }, m_nameExtentsCache.m_Extents );
409
410 // Bump over to be left aligned just inside the pin
411 box->Move( { m_nameExtentsCache.m_Extents.x / 2 + pinNameOffset, 0 } );
412 }
413 else
414 {
415 // The pin name is always over the pin
416 box = BOX2I::ByCenter( { pinLength / 2, 0 }, m_nameExtentsCache.m_Extents );
417
418 // Bump it up
419 box->Move( { 0, -m_nameExtentsCache.m_Extents.y / 2 - getPinTextOffset() } );
420 }
421
422 return box;
423}
424
425
427{
428 int pinNameOffset = 0;
429 if( const SYMBOL* parentSymbol = m_pin.GetParentSymbol() )
430 {
431 if( parentSymbol->GetShowPinNames() )
432 pinNameOffset = parentSymbol->GetPinNameOffset();
433 }
434
435 const int pinLength = m_pin.GetLength();
436
437 // The pin name is always over the pin
438 OPT_BOX2I box = BOX2I::ByCenter( { pinLength / 2, 0 }, m_numExtentsCache.m_Extents );
439
440 int textPos = -m_numExtentsCache.m_Extents.y / 2 - getPinTextOffset();
441
442 // The number goes below, if there is a name outside
443 if( pinNameOffset == 0 && !m_pin.GetShownName().empty()
445 textPos *= -1;
446
447 // Bump it up (or down)
448 box->Move( { 0, textPos } );
449
450 return box;
451}
452
453
455{
457 return std::nullopt;
458
459 BOX2I box{
462 };
463
464 // Jog left
465 box.Move( { -schIUScale.MilsToIU( PIN_TEXT_MARGIN ) - TARGET_PIN_RADIUS, 0 } );
466
467 return box;
468}
469
470
472{
473 const OPT_BOX2I nameBox = getUntransformedPinNameBox();
474
475 if( !nameBox || m_pin.GetAlternates().empty() || !m_showAltIcons )
476 return std::nullopt;
477
478 const int iconSize = std::min( m_pin.GetNameTextSize(), schIUScale.mmToIU( 1.5 ) );
479
480 VECTOR2I c{ 0, ( nameBox->GetTop() + nameBox->GetBottom() ) / 2 };
482 {
483 // name inside, so icon more inside
484 c.x = nameBox->GetRight() + iconSize * 0.75;
485 }
486 else
487 {
488 c.x = nameBox->GetLeft() - iconSize * 0.75;
489 }
490
491 return BOX2I::ByCenter( c, { iconSize, iconSize } );
492}
493
494
496{
497 const GRAPHIC_PINSHAPE shape = m_pin.GetShape();
498 const int decoSize = externalPinDecoSize( m_schSettings, m_pin );
499 const int intDecoSize = internalPinDecoSize( m_schSettings, m_pin );
500
501 const auto makeInvertBox = [&]()
502 {
503 return BOX2I::ByCenter( { -decoSize, 0 }, { decoSize * 2, decoSize * 2 } );
504 };
505
506 const auto makeLowBox = [&]()
507 {
508 return BOX2I::ByCorners( { -decoSize * 2, -decoSize * 2 }, { 0, 0 } );
509 };
510
511 const auto makeClockBox = [&]()
512 {
513 return BOX2I::ByCorners( { 0, -intDecoSize }, { intDecoSize, intDecoSize } );
514 };
515
516 OPT_BOX2I box;
517
518 switch( shape )
519 {
520 case GRAPHIC_PINSHAPE::INVERTED:
521 {
522 box = makeInvertBox();
523 break;
524 }
525 case GRAPHIC_PINSHAPE::CLOCK:
526 {
527 box = makeClockBox();
528 break;
529 }
530 case GRAPHIC_PINSHAPE::INVERTED_CLOCK:
531 {
532 box = makeInvertBox();
533 box->Merge( makeClockBox() );
534 break;
535 }
536 case GRAPHIC_PINSHAPE::INPUT_LOW:
537 {
538 box = makeLowBox();
539 break;
540 }
541 case GRAPHIC_PINSHAPE::FALLING_EDGE_CLOCK:
542 case GRAPHIC_PINSHAPE::CLOCK_LOW:
543 {
544 box = makeLowBox();
545 box->Merge( makeClockBox() );
546 break;
547 }
548 case GRAPHIC_PINSHAPE::NONLOGIC:
549 {
550 box = BOX2I::ByCenter( { 0, 0 }, { decoSize * 2, decoSize * 2 } );
551 break;
552 }
553 case GRAPHIC_PINSHAPE::LINE:
554 default:
555 {
556 // No decoration
557 break;
558 }
559 }
560
561 if( box )
562 {
563 // Put the box at the root of the pin
564 box->Move( { m_pin.GetLength(), 0 } );
565 box->Inflate( m_pin.GetPenWidth() / 2 );
566 }
567
568 return box;
569}
570
571
573{
576
577 if( box )
578 transformBoxForPin( *box );
579
580 return box;
581}
582
583
585{
588
589 if( box )
590 transformBoxForPin( *box );
591
592 return box;
593}
594
595
597{
599
600 if( box )
601 transformBoxForPin( *box );
602
603 return box;
604}
605
606
607std::optional<PIN_LAYOUT_CACHE::TEXT_INFO> PIN_LAYOUT_CACHE::GetPinNameInfo( int aShadowWidth )
608{
610 wxString name = m_pin.GetShownName();
611
612 // TODO - work out exactly what we need to do to cache this
613 // (or if it's worth the memory/complexity)
614 // But it's not hugely expensive to recompute, and that's what's always been
615 // done to now
616 //
617 // Becasue pins are very likely to share a lot of characteristics, a global
618 // cache might make more sense than a per-pin cache.
619
620 if( name.IsEmpty() || !m_pin.GetParentSymbol()->GetShowPinNames() )
621 return std::nullopt;
622
623 std::optional<TEXT_INFO> info = TEXT_INFO();
624 info->m_Text = std::move( name );
625 info->m_TextSize = m_pin.GetNameTextSize();
626 info->m_Thickness = m_nameThickness;
627 info->m_Angle = ANGLE_HORIZONTAL;
628
630 {
631 // This means name inside the pin
633 const int thickOffset =
634 info->m_Thickness - KiROUND( aShadowWidth * m_shadowOffsetAdjust ) / 2;
635
636 info->m_TextPosition = pos + VECTOR2I{ thickOffset, 0 };
637 info->m_HAlign = GR_TEXT_H_ALIGN_LEFT;
638 info->m_VAlign = GR_TEXT_V_ALIGN_CENTER;
639 }
640 else
641 {
642 // The pin name is always over the pin
643 VECTOR2I pos = { m_pin.GetLength() / 2, -getPinTextOffset() - info->m_Thickness / 2 };
644
645 info->m_TextPosition = pos;
646 info->m_HAlign = GR_TEXT_H_ALIGN_CENTER;
647 info->m_VAlign = GR_TEXT_V_ALIGN_BOTTOM;
648 }
649
651 return info;
652}
653
654
655std::optional<PIN_LAYOUT_CACHE::TEXT_INFO> PIN_LAYOUT_CACHE::GetPinNumberInfo( int aShadowWidth )
656{
658
659 wxString number = m_pin.GetShownNumber();
660 if( number.IsEmpty() || !m_pin.GetParentSymbol()->GetShowPinNumbers() )
661 return std::nullopt;
662
663 std::optional<TEXT_INFO> info;
664
665 info = TEXT_INFO();
666 info->m_Text = std::move( number );
667 info->m_TextSize = m_pin.GetNumberTextSize();
668 info->m_Thickness = m_numberThickness;
669 info->m_Angle = ANGLE_HORIZONTAL;
670 info->m_TextPosition = { m_pin.GetLength() / 2, 0 };
671 info->m_HAlign = GR_TEXT_H_ALIGN_CENTER;
672
673 // The pin number is above the pin if there's no name, or the name is inside
674 const bool numAbove =
676 || ( m_pin.GetShownName().empty() || !m_pin.GetParentSymbol()->GetShowPinNames() );
677 if( numAbove )
678 {
679 info->m_TextPosition.y -= getPinTextOffset() + info->m_Thickness / 2;
680 info->m_VAlign = GR_TEXT_V_ALIGN_BOTTOM;
681 }
682 else
683 {
684 info->m_TextPosition.y += getPinTextOffset() + info->m_Thickness / 2;
685 info->m_VAlign = GR_TEXT_V_ALIGN_TOP;
686 }
687
689 return info;
690}
691
692std::optional<PIN_LAYOUT_CACHE::TEXT_INFO>
694{
696
698 return std::nullopt;
699
700 std::optional<TEXT_INFO> info = TEXT_INFO();
701 info->m_Text = m_pin.GetElectricalTypeName();
702 info->m_TextSize = std::max( m_pin.GetNameTextSize() * 3 / 4, schIUScale.mmToIU( 0.7 ) );
703 info->m_Angle = ANGLE_HORIZONTAL;
704 info->m_Thickness = info->m_TextSize / 8;
705 info->m_TextPosition = { -getPinTextOffset() - info->m_Thickness / 2
706 + KiROUND( aShadowWidth * m_shadowOffsetAdjust ) / 2,
707 0 };
708 info->m_HAlign = GR_TEXT_H_ALIGN_RIGHT;
709 info->m_VAlign = GR_TEXT_V_ALIGN_CENTER;
710
711 info->m_TextPosition.x -= TARGET_PIN_RADIUS;
712
713 if( m_pin.IsDangling() )
714 {
715 info->m_TextPosition.x -= TARGET_PIN_RADIUS / 2;
716 }
717
719 return info;
720}
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:466
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