KiCad PCB EDA Suite
lib_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) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <base_units.h>
27#include <pgm_base.h>
28#include <sch_draw_panel.h>
29#include <sch_edit_frame.h>
30#include <symbol_edit_frame.h>
31#include <lib_pin.h>
34#include <trigo.h>
35#include <string_utils.h>
36#include "sch_painter.h"
37#include "plotters/plotter.h"
38
39
40// small margin in internal units between the pin text and the pin line
41#define PIN_TEXT_MARGIN 4
42
44{
45 // These strings are the canonical name of the electrictal type
46 // Not translated, no space in name, only ASCII chars.
47 // to use when the string name must be known and well defined
48 // must have same order than enum ELECTRICAL_PINTYPE (see lib_pin.h)
49 static const wxChar* msgPinElectricType[] =
50 {
51 wxT( "input" ),
52 wxT( "output" ),
53 wxT( "bidirectional" ),
54 wxT( "tri_state" ),
55 wxT( "passive" ),
56 wxT( "free" ),
57 wxT( "unspecified" ),
58 wxT( "power_in" ),
59 wxT( "power_out" ),
60 wxT( "open_collector" ),
61 wxT( "open_emitter" ),
62 wxT( "no_connect" )
63 };
64
65 return msgPinElectricType[static_cast<int>( aType )];
66}
67
68
70// i.e. the clock symbols (falling clock is actually external but is of
71// the same kind)
72
73static int internalPinDecoSize( const RENDER_SETTINGS* aSettings, const LIB_PIN &aPin )
74{
75 const KIGFX::SCH_RENDER_SETTINGS* settings = static_cast<const KIGFX::SCH_RENDER_SETTINGS*>( aSettings );
76
77 if( settings && settings->m_PinSymbolSize )
78 return settings->m_PinSymbolSize;
79
80 return aPin.GetNameTextSize() != 0 ? aPin.GetNameTextSize() / 2 : aPin.GetNumberTextSize() / 2;
81}
82
84// i.e. the negation circle, the polarity 'slopes' and the nonlogic
85// marker
86static int externalPinDecoSize( const RENDER_SETTINGS* aSettings, const LIB_PIN &aPin )
87{
88 const KIGFX::SCH_RENDER_SETTINGS* settings = static_cast<const KIGFX::SCH_RENDER_SETTINGS*>( aSettings );
89
90 if( settings && settings->m_PinSymbolSize )
91 return settings->m_PinSymbolSize;
92
93 return aPin.GetNumberTextSize() / 2;
94}
95
96
98 LIB_ITEM( LIB_PIN_T, aParent ),
99 m_orientation( PIN_RIGHT ),
100 m_shape( GRAPHIC_PINSHAPE::LINE ),
102 m_attributes( 0 )
103{
104 // Use the application settings for pin sizes if exists.
105 // pgm can be nullptr when running a shared lib from a script, not from a kicad appl
106 PGM_BASE* pgm = PgmOrNull();
107
108 if( pgm )
109 {
111 m_length = schIUScale.MilsToIU( settings->m_Defaults.pin_length );
112 m_numTextSize = schIUScale.MilsToIU( settings->m_Defaults.pin_num_size );
113 m_nameTextSize = schIUScale.MilsToIU( settings->m_Defaults.pin_name_size );
114 }
115 else // Use hardcoded eeschema defaults: symbol_editor settings are not existing.
116 {
120 }
121}
122
123
124LIB_PIN::LIB_PIN( LIB_SYMBOL* aParent, const wxString& aName, const wxString& aNumber,
125 int aOrientation, ELECTRICAL_PINTYPE aPinType, int aLength, int aNameTextSize,
126 int aNumTextSize, int aConvert, const VECTOR2I& aPos, int aUnit ) :
127 LIB_ITEM( LIB_PIN_T, aParent ),
128 m_position( aPos ),
129 m_length( aLength ),
130 m_orientation( aOrientation ),
131 m_shape( GRAPHIC_PINSHAPE::LINE ),
132 m_type( aPinType ),
133 m_attributes( 0 ),
134 m_numTextSize( aNumTextSize ),
135 m_nameTextSize( aNameTextSize )
136{
137 SetName( aName );
138 SetNumber( aNumber );
139 SetUnit( aUnit );
140 SetConvert( aConvert );
141}
142
143
144bool LIB_PIN::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
145{
146 BOX2I rect = GetBoundingBox( false, true, m_flags & SHOW_ELEC_TYPE );
147
148 return rect.Inflate( aAccuracy ).Contains( aPosition );
149}
150
151
152bool LIB_PIN::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
153{
155 return false;
156
157 BOX2I sel = aRect;
158
159 if ( aAccuracy )
160 sel.Inflate( aAccuracy );
161
162 if( aContained )
163 return sel.Contains( GetBoundingBox( false, false, false ) );
164
165 return sel.Intersects( GetBoundingBox( false, true, m_flags & SHOW_ELEC_TYPE ) );
166}
167
168
170{
171 return 0;
172}
173
174
175wxString LIB_PIN::GetShownName() const
176{
177 if( m_name == wxS( "~" ) )
178 return wxEmptyString;
179 else
180 return m_name;
181}
182
183
185{
186 switch( m_orientation )
187 {
188 default:
189 case PIN_RIGHT: return VECTOR2I( m_position.x + m_length, -( m_position.y ) );
190 case PIN_LEFT: return VECTOR2I( m_position.x - m_length, -( m_position.y ) );
191 case PIN_UP: return VECTOR2I( m_position.x, -( m_position.y + m_length ) );
192 case PIN_DOWN: return VECTOR2I( m_position.x, -( m_position.y - m_length ) );
193 }
194}
195
196
197void LIB_PIN::print( const RENDER_SETTINGS* aSettings, const VECTOR2I& aOffset, void* aData,
198 const TRANSFORM& aTransform, bool aDimmed )
199{
200 LIB_SYMBOL_OPTIONS* opts = (LIB_SYMBOL_OPTIONS*) aData;
201 bool drawHiddenFields = opts ? opts->draw_hidden_fields : false;
202 bool showPinType = opts ? opts->show_elec_type : false;
203 bool show_connect_point = opts ? opts->show_connect_point : false;
204
205 LIB_SYMBOL* part = GetParent();
206
207 wxCHECK( part && opts, /* void */ );
208
209 /* Calculate pin orient taking in account the symbol orientation. */
210 int orient = PinDrawOrient( aTransform );
211
212 /* Calculate the pin position */
213 VECTOR2I pos1 = aTransform.TransformCoordinate( m_position ) + aOffset;
214
215 if( IsVisible() || drawHiddenFields )
216 {
217 printPinSymbol( aSettings, pos1, orient, aDimmed );
218
219 printPinTexts( aSettings, pos1, orient, part->GetPinNameOffset(),
220 opts->force_draw_pin_text || part->ShowPinNumbers(),
221 opts->force_draw_pin_text || part->ShowPinNames(),
222 aDimmed );
223
224 if( showPinType )
225 printPinElectricalTypeName( aSettings, pos1, orient, aDimmed );
226
227 if( show_connect_point
230 {
231 wxDC* DC = aSettings->GetPrintDC();
233
234 COLOR4D bg = aSettings->GetBackgroundColor();
235
236 if( bg == COLOR4D::UNSPECIFIED || GetGRForceBlackPenState() )
237 bg = COLOR4D::WHITE;
238
239 if( aDimmed )
240 color = color.Mix( bg, 0.5f );
241
242 GRCircle( DC, pos1, TARGET_PIN_RADIUS, 0, color );
243 }
244 }
245}
246
247
248void LIB_PIN::printPinSymbol( const RENDER_SETTINGS* aSettings, const VECTOR2I& aPos, int aOrient, bool aDimmed )
249{
250 wxDC* DC = aSettings->GetPrintDC();
251 int MapX1, MapY1, x1, y1;
252 int width = GetEffectivePenWidth( aSettings );
253 int posX = aPos.x, posY = aPos.y, len = m_length;
255 COLOR4D bg = aSettings->GetBackgroundColor();
256
257 if( bg == COLOR4D::UNSPECIFIED || GetGRForceBlackPenState() )
258 bg = COLOR4D::WHITE;
259
260 if( !IsVisible() )
261 bg = aSettings->GetLayerColor( LAYER_HIDDEN );
262
263 if( aDimmed )
264 color = color.Mix( bg, 0.5f );
265
266 MapX1 = MapY1 = 0;
267 x1 = posX;
268 y1 = posY;
269
270 switch( aOrient )
271 {
272 case PIN_UP: y1 = posY - len; MapY1 = 1; break;
273 case PIN_DOWN: y1 = posY + len; MapY1 = -1; break;
274 case PIN_LEFT: x1 = posX - len; MapX1 = 1; break;
275 case PIN_RIGHT: x1 = posX + len; MapX1 = -1; break;
276 }
277
279 {
280 const int radius = externalPinDecoSize( aSettings, *this );
281 GRCircle( DC, VECTOR2I( MapX1 * radius + x1, MapY1 * radius + y1 ), radius, width, color );
282
283 GRMoveTo( MapX1 * radius * 2 + x1, MapY1 * radius * 2 + y1 );
284 GRLineTo( DC, posX, posY, width, color );
285 }
286 else
287 {
288 GRMoveTo( x1, y1 );
289 GRLineTo( DC, posX, posY, width, color );
290 }
291
292 // Draw the clock shape (>)inside the symbol
297 {
298 const int clock_size = internalPinDecoSize( aSettings, *this );
299 if( MapY1 == 0 ) /* MapX1 = +- 1 */
300 {
301 GRMoveTo( x1, y1 + clock_size );
302 GRLineTo( DC, x1 - MapX1 * clock_size * 2, y1, width, color );
303 GRLineTo( DC, x1, y1 - clock_size, width, color );
304 }
305 else /* MapX1 = 0 */
306 {
307 GRMoveTo( x1 + clock_size, y1 );
308 GRLineTo( DC, x1, y1 - MapY1 * clock_size * 2, width, color );
309 GRLineTo( DC, x1 - clock_size, y1, width, color );
310 }
311 }
312
313 // Draw the active low (or H to L active transition)
317 {
318 const int deco_size = externalPinDecoSize( aSettings, *this );
319 if( MapY1 == 0 ) /* MapX1 = +- 1 */
320 {
321 GRMoveTo( x1 + MapX1 * deco_size * 2, y1 );
322 GRLineTo( DC, x1 + MapX1 * deco_size * 2, y1 - deco_size * 2, width, color );
323 GRLineTo( DC, x1, y1, width, color );
324 }
325 else /* MapX1 = 0 */
326 {
327 GRMoveTo( x1, y1 + MapY1 * deco_size * 2 );
328 GRLineTo( DC, x1 - deco_size * 2, y1 + MapY1 * deco_size * 2, width, color );
329 GRLineTo( DC, x1, y1, width, color );
330 }
331 }
332
333 if( m_shape == GRAPHIC_PINSHAPE::OUTPUT_LOW ) /* IEEE symbol "Active Low Output" */
334 {
335 const int deco_size = externalPinDecoSize( aSettings, *this );
336 if( MapY1 == 0 ) /* MapX1 = +- 1 */
337 {
338 GRMoveTo( x1, y1 - deco_size * 2 );
339 GRLineTo( DC, x1 + MapX1 * deco_size * 2, y1, width, color );
340 }
341 else /* MapX1 = 0 */
342 {
343 GRMoveTo( x1 - deco_size * 2, y1 );
344 GRLineTo( DC, x1, y1 + MapY1 * deco_size * 2, width, color );
345 }
346 }
347 else if( m_shape == GRAPHIC_PINSHAPE::NONLOGIC ) /* NonLogic pin symbol */
348 {
349 const int deco_size = externalPinDecoSize( aSettings, *this );
350 GRMoveTo( x1 - (MapX1 + MapY1) * deco_size, y1 - (MapY1 - MapX1) * deco_size );
351 GRLineTo( DC, x1 + (MapX1 + MapY1) * deco_size, y1 + ( MapY1 - MapX1 ) * deco_size, width,
352 color );
353 GRMoveTo( x1 - (MapX1 - MapY1) * deco_size, y1 - (MapY1 + MapX1) * deco_size );
354 GRLineTo( DC, x1 + (MapX1 - MapY1) * deco_size, y1 + ( MapY1 + MapX1 ) * deco_size, width,
355 color );
356 }
357
358 if( m_type == ELECTRICAL_PINTYPE::PT_NC ) // Draw a N.C. symbol
359 {
360 const int deco_size = TARGET_PIN_RADIUS;
361 GRLine( DC, posX - deco_size, posY - deco_size, posX + deco_size, posY + deco_size, width,
362 color );
363 GRLine( DC, posX + deco_size, posY - deco_size, posX - deco_size, posY + deco_size, width,
364 color );
365 }
366}
367
368
369void LIB_PIN::printPinTexts( const RENDER_SETTINGS* aSettings, VECTOR2I& aPinPos, int aPinOrient,
370 int aTextInside, bool aDrawPinNum, bool aDrawPinName, bool aDimmed )
371{
372 if( !aDrawPinName && !aDrawPinNum )
373 return;
374
375 int x, y;
376 wxDC* DC = aSettings->GetPrintDC();
377 KIFONT::FONT* font = KIFONT::FONT::GetFont( aSettings->GetDefaultFont(), false, false );
378
379 wxSize pinNameSize( m_nameTextSize, m_nameTextSize );
380 wxSize pinNumSize( m_numTextSize, m_numTextSize );
381
382 int namePenWidth = std::max( Clamp_Text_PenSize( GetPenWidth(), m_nameTextSize, true ),
383 aSettings->GetDefaultPenWidth() );
384 int numPenWidth = std::max( Clamp_Text_PenSize( GetPenWidth(), m_numTextSize, true ),
385 aSettings->GetDefaultPenWidth() );
386
387 int name_offset = schIUScale.MilsToIU( PIN_TEXT_MARGIN ) + namePenWidth;
388 int num_offset = schIUScale.MilsToIU( PIN_TEXT_MARGIN ) + numPenWidth;
389
390 /* Get the num and name colors */
391 COLOR4D nameColor = aSettings->GetLayerColor( IsVisible() ? LAYER_PINNAM : LAYER_HIDDEN );
392 COLOR4D numColor = aSettings->GetLayerColor( IsVisible() ? LAYER_PINNUM : LAYER_HIDDEN );
393 COLOR4D bg = aSettings->GetBackgroundColor();
394
395 if( bg == COLOR4D::UNSPECIFIED || GetGRForceBlackPenState() )
396 bg = COLOR4D::WHITE;
397
398 if( !IsVisible() )
399 bg = aSettings->GetLayerColor( LAYER_HIDDEN );
400
401 if( aDimmed )
402 {
403 nameColor = nameColor.Mix( bg, 0.5f );
404 numColor = numColor.Mix( bg, 0.5f );
405 }
406
407 int x1 = aPinPos.x;
408 int y1 = aPinPos.y;
409
410 switch( aPinOrient )
411 {
412 case PIN_UP: y1 -= m_length; break;
413 case PIN_DOWN: y1 += m_length; break;
414 case PIN_LEFT: x1 -= m_length; break;
415 case PIN_RIGHT: x1 += m_length; break;
416 }
417
418 wxString name = GetShownName();
419 wxString number = GetShownNumber();
420
421 if( name.IsEmpty() || m_nameTextSize == 0 )
422 aDrawPinName = false;
423
424 if( number.IsEmpty() || m_numTextSize == 0 )
425 aDrawPinNum = false;
426
427 if( aTextInside ) // Draw the text inside, but the pin numbers outside.
428 {
429 if(( aPinOrient == PIN_LEFT) || ( aPinOrient == PIN_RIGHT) )
430 {
431 // It is an horizontal line
432 if( aDrawPinName )
433 {
434 if( aPinOrient == PIN_RIGHT )
435 {
436 x = x1 + aTextInside;
437 GRPrintText( DC, VECTOR2I( x, y1 ), nameColor, name, ANGLE_HORIZONTAL,
439 namePenWidth, false, false, font );
440 }
441 else // Orient == PIN_LEFT
442 {
443 x = x1 - aTextInside;
444 GRPrintText( DC, VECTOR2I( x, y1 ), nameColor, name, ANGLE_HORIZONTAL,
446 namePenWidth, false, false, font );
447 }
448 }
449
450 if( aDrawPinNum )
451 {
452 GRPrintText( DC, VECTOR2I(( x1 + aPinPos.x) / 2, y1 - num_offset ), numColor,
453 number, ANGLE_HORIZONTAL, pinNumSize, GR_TEXT_H_ALIGN_CENTER,
454 GR_TEXT_V_ALIGN_BOTTOM, numPenWidth, false, false, font );
455 }
456 }
457 else /* Its a vertical line. */
458 {
459 // Text is drawn from bottom to top (i.e. to negative value for Y axis)
460 if( aPinOrient == PIN_DOWN )
461 {
462 y = y1 + aTextInside;
463
464 if( aDrawPinName )
465 {
466 GRPrintText( DC, VECTOR2I( x1, y ), nameColor, name, ANGLE_VERTICAL,
468 namePenWidth, false, false, font );
469 }
470
471 if( aDrawPinNum )
472 {
473 GRPrintText( DC, VECTOR2I( x1 - num_offset, ( y1 + aPinPos.y) / 2 ), numColor,
474 number, ANGLE_VERTICAL, pinNumSize, GR_TEXT_H_ALIGN_CENTER,
475 GR_TEXT_V_ALIGN_BOTTOM, numPenWidth, false, false, font );
476 }
477 }
478 else /* PIN_UP */
479 {
480 y = y1 - aTextInside;
481
482 if( aDrawPinName )
483 {
484 GRPrintText( DC, VECTOR2I( x1, y ), nameColor, name, ANGLE_VERTICAL,
486 namePenWidth, false, false, font );
487 }
488
489 if( aDrawPinNum )
490 {
491 GRPrintText( DC, VECTOR2I( x1 - num_offset, ( y1 + aPinPos.y) / 2 ), numColor,
492 number, ANGLE_VERTICAL, pinNumSize, GR_TEXT_H_ALIGN_CENTER,
493 GR_TEXT_V_ALIGN_BOTTOM, numPenWidth, false, false, font );
494 }
495 }
496 }
497 }
498 else /**** Draw num & text pin outside ****/
499 {
500 if( ( aPinOrient == PIN_LEFT) || ( aPinOrient == PIN_RIGHT) )
501 {
502 /* Its an horizontal line. */
503 if( aDrawPinName )
504 {
505 x = ( x1 + aPinPos.x) / 2;
506 GRPrintText( DC, VECTOR2I( x, y1 - name_offset ), nameColor, name, ANGLE_HORIZONTAL,
508 namePenWidth, false, false, font );
509 }
510 if( aDrawPinNum )
511 {
512 x = ( x1 + aPinPos.x) / 2;
513 GRPrintText( DC, VECTOR2I( x, y1 + num_offset ), numColor, number, ANGLE_HORIZONTAL,
515 numPenWidth, false, false, font );
516 }
517 }
518 else /* Its a vertical line. */
519 {
520 if( aDrawPinName )
521 {
522 y = ( y1 + aPinPos.y) / 2;
523 GRPrintText( DC, VECTOR2I( x1 - name_offset, y ), nameColor, name, ANGLE_VERTICAL,
525 namePenWidth, false, false, font );
526 }
527
528 if( aDrawPinNum )
529 {
530 GRPrintText( DC, VECTOR2I( x1 + num_offset, ( y1 + aPinPos.y) / 2 ), numColor,
531 number, ANGLE_VERTICAL, pinNumSize, GR_TEXT_H_ALIGN_CENTER,
532 GR_TEXT_V_ALIGN_TOP, numPenWidth, false, false, font );
533 }
534 }
535 }
536}
537
538
539
541 int aOrientation, bool aDimmed )
542{
543 wxDC* DC = aSettings->GetPrintDC();
544 wxString typeName = GetElectricalTypeName();
545
546 // Use a reasonable (small) size to draw the text
547 int textSize = ( m_nameTextSize * 3 ) / 4;
548
549 #define ETXT_MAX_SIZE schIUScale.mmToIU( 0.7 )
550
551 if( textSize > ETXT_MAX_SIZE )
552 textSize = ETXT_MAX_SIZE;
553
554 // Use a reasonable pen size to draw the text
555 int pensize = textSize/6;
556
557 // Get a suitable color
559 COLOR4D bg = aSettings->GetBackgroundColor();
560
561 if( bg == COLOR4D::UNSPECIFIED || GetGRForceBlackPenState() )
562 bg = COLOR4D::WHITE;
563
564 if( !IsVisible() )
565 bg = aSettings->GetLayerColor( LAYER_HIDDEN );
566
567 if( aDimmed )
568 color = color.Mix( bg, 0.5f );
569
570 VECTOR2I txtpos = aPosition;
571 int offset = schIUScale.mmToIU( 0.4 );
574 KIFONT::FONT* font = KIFONT::FONT::GetFont( aSettings->GetDefaultFont(), false, false );
575
576 switch( aOrientation )
577 {
578 case PIN_UP:
579 txtpos.y += offset;
580 orient = ANGLE_VERTICAL;
581 hjustify = GR_TEXT_H_ALIGN_RIGHT;
582 break;
583
584 case PIN_DOWN:
585 txtpos.y -= offset;
586 orient = ANGLE_VERTICAL;
587 break;
588
589 case PIN_LEFT:
590 txtpos.x += offset;
591 break;
592
593 case PIN_RIGHT:
594 txtpos.x -= offset;
595 hjustify = GR_TEXT_H_ALIGN_RIGHT;
596 break;
597 }
598
599 GRPrintText( DC, txtpos, color, typeName, orient, wxSize( textSize, textSize ), hjustify,
600 GR_TEXT_V_ALIGN_CENTER, pensize, false, false, font );
601}
602
603
604void LIB_PIN::PlotSymbol( PLOTTER *aPlotter, const VECTOR2I &aPosition, int aOrientation,
605 bool aDimmed ) const
606{
607 int MapX1, MapY1, x1, y1;
609 COLOR4D bg = aPlotter->RenderSettings()->GetBackgroundColor();
610 int penWidth = GetEffectivePenWidth( aPlotter->RenderSettings() );
611
612 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
613 bg = COLOR4D::WHITE;
614
615 if( aDimmed )
616 color = color.Mix( bg, 0.5f );
617
618 aPlotter->SetColor( color );
619 aPlotter->SetCurrentLineWidth( penWidth );
620
621 MapX1 = MapY1 = 0;
622 x1 = aPosition.x; y1 = aPosition.y;
623
624 switch( aOrientation )
625 {
626 case PIN_UP: y1 = aPosition.y - m_length; MapY1 = 1; break;
627 case PIN_DOWN: y1 = aPosition.y + m_length; MapY1 = -1; break;
628 case PIN_LEFT: x1 = aPosition.x - m_length; MapX1 = 1; break;
629 case PIN_RIGHT: x1 = aPosition.x + m_length; MapX1 = -1; break;
630 }
631
633 {
634 const int radius = externalPinDecoSize( aPlotter->RenderSettings(), *this );
635 aPlotter->Circle( VECTOR2I( MapX1 * radius + x1, MapY1 * radius + y1 ), radius * 2,
636 FILL_T::NO_FILL, penWidth );
637
638 aPlotter->MoveTo( VECTOR2I( MapX1 * radius * 2 + x1, MapY1 * radius * 2 + y1 ) );
639 aPlotter->FinishTo( aPosition );
640 }
642 {
643 const int deco_size = internalPinDecoSize( aPlotter->RenderSettings(), *this );
644 if( MapY1 == 0 ) /* MapX1 = +- 1 */
645 {
646 aPlotter->MoveTo( VECTOR2I( x1, y1 + deco_size ) );
647 aPlotter->LineTo( VECTOR2I( x1 + MapX1 * deco_size * 2, y1 ) );
648 aPlotter->FinishTo( VECTOR2I( x1, y1 - deco_size ) );
649 }
650 else /* MapX1 = 0 */
651 {
652 aPlotter->MoveTo( VECTOR2I( x1 + deco_size, y1 ) );
653 aPlotter->LineTo( VECTOR2I( x1, y1 + MapY1 * deco_size * 2 ) );
654 aPlotter->FinishTo( VECTOR2I( x1 - deco_size, y1 ) );
655 }
656
657 aPlotter->MoveTo( VECTOR2I( MapX1 * deco_size * 2 + x1, MapY1 * deco_size * 2 + y1 ) );
658 aPlotter->FinishTo( aPosition );
659 }
660 else
661 {
662 aPlotter->MoveTo( VECTOR2I( x1, y1 ) );
663 aPlotter->FinishTo( aPosition );
664 }
665
669 {
670 const int deco_size = internalPinDecoSize( aPlotter->RenderSettings(), *this );
671 if( MapY1 == 0 ) /* MapX1 = +- 1 */
672 {
673 aPlotter->MoveTo( VECTOR2I( x1, y1 + deco_size ) );
674 aPlotter->LineTo( VECTOR2I( x1 - MapX1 * deco_size * 2, y1 ) );
675 aPlotter->FinishTo( VECTOR2I( x1, y1 - deco_size ) );
676 }
677 else /* MapX1 = 0 */
678 {
679 aPlotter->MoveTo( VECTOR2I( x1 + deco_size, y1 ) );
680 aPlotter->LineTo( VECTOR2I( x1, y1 - MapY1 * deco_size * 2 ) );
681 aPlotter->FinishTo( VECTOR2I( x1 - deco_size, y1 ) );
682 }
683 }
684
686 || m_shape == GRAPHIC_PINSHAPE::CLOCK_LOW ) /* IEEE symbol "Active Low Input" */
687 {
688 const int deco_size = externalPinDecoSize( aPlotter->RenderSettings(), *this );
689
690 if( MapY1 == 0 ) /* MapX1 = +- 1 */
691 {
692 aPlotter->MoveTo( VECTOR2I( x1 + MapX1 * deco_size * 2, y1 ) );
693 aPlotter->LineTo( VECTOR2I( x1 + MapX1 * deco_size * 2, y1 - deco_size * 2 ) );
694 aPlotter->FinishTo( VECTOR2I( x1, y1 ) );
695 }
696 else /* MapX1 = 0 */
697 {
698 aPlotter->MoveTo( VECTOR2I( x1, y1 + MapY1 * deco_size * 2 ) );
699 aPlotter->LineTo( VECTOR2I( x1 - deco_size * 2, y1 + MapY1 * deco_size * 2 ) );
700 aPlotter->FinishTo( VECTOR2I( x1, y1 ) );
701 }
702 }
703
704 if( m_shape == GRAPHIC_PINSHAPE::OUTPUT_LOW ) /* IEEE symbol "Active Low Output" */
705 {
706 const int symbol_size = externalPinDecoSize( aPlotter->RenderSettings(), *this );
707
708 if( MapY1 == 0 ) /* MapX1 = +- 1 */
709 {
710 aPlotter->MoveTo( VECTOR2I( x1, y1 - symbol_size * 2 ) );
711 aPlotter->FinishTo( VECTOR2I( x1 + MapX1 * symbol_size * 2, y1 ) );
712 }
713 else /* MapX1 = 0 */
714 {
715 aPlotter->MoveTo( VECTOR2I( x1 - symbol_size * 2, y1 ) );
716 aPlotter->FinishTo( VECTOR2I( x1, y1 + MapY1 * symbol_size * 2 ) );
717 }
718 }
719 else if( m_shape == GRAPHIC_PINSHAPE::NONLOGIC ) /* NonLogic pin symbol */
720 {
721 const int deco_size = externalPinDecoSize( aPlotter->RenderSettings(), *this );
722 aPlotter->MoveTo( VECTOR2I( x1 - ( MapX1 + MapY1 ) * deco_size,
723 y1 - ( MapY1 - MapX1 ) * deco_size ) );
724 aPlotter->FinishTo( VECTOR2I( x1 + ( MapX1 + MapY1 ) * deco_size,
725 y1 + ( MapY1 - MapX1 ) * deco_size ) );
726 aPlotter->MoveTo( VECTOR2I( x1 - ( MapX1 - MapY1 ) * deco_size,
727 y1 - ( MapY1 + MapX1 ) * deco_size ) );
728 aPlotter->FinishTo( VECTOR2I( x1 + ( MapX1 - MapY1 ) * deco_size,
729 y1 + ( MapY1 + MapX1 ) * deco_size ) );
730 }
731
732 if( m_type == ELECTRICAL_PINTYPE::PT_NC ) // Draw a N.C. symbol
733 {
734 const int deco_size = TARGET_PIN_RADIUS;
735 const int ex1 = aPosition.x;
736 const int ey1 = aPosition.y;
737 aPlotter->MoveTo( VECTOR2I( ex1 - deco_size, ey1 - deco_size ) );
738 aPlotter->FinishTo( VECTOR2I( ex1 + deco_size, ey1 + deco_size ) );
739 aPlotter->MoveTo( VECTOR2I( ex1 + deco_size, ey1 - deco_size ) );
740 aPlotter->FinishTo( VECTOR2I( ex1 - deco_size, ey1 + deco_size ) );
741 }
742}
743
744void LIB_PIN::PlotPinTexts( PLOTTER *aPlotter, const VECTOR2I &aPinPos, int aPinOrient,
745 int aTextInside, bool aDrawPinNum, bool aDrawPinName, bool aDimmed ) const
746{
747 RENDER_SETTINGS* settings = aPlotter->RenderSettings();
748 KIFONT::FONT* font = KIFONT::FONT::GetFont( settings->GetDefaultFont(), false, false );
749 wxString name = GetShownName();
750 wxString number = GetShownNumber();
751
752 if( name.IsEmpty() || m_nameTextSize == 0 )
753 aDrawPinName = false;
754
755 if( number.IsEmpty() || m_numTextSize == 0 )
756 aDrawPinNum = false;
757
758 if( !aDrawPinNum && !aDrawPinName )
759 return;
760
761 int x, y;
762 int namePenWidth = std::max( Clamp_Text_PenSize( GetPenWidth(), m_nameTextSize, true ),
763 settings->GetDefaultPenWidth() );
764 int numPenWidth = std::max( Clamp_Text_PenSize( GetPenWidth(), m_numTextSize, true ),
765 settings->GetDefaultPenWidth() );
766 int name_offset = schIUScale.MilsToIU( PIN_TEXT_MARGIN ) + namePenWidth;
767 int num_offset = schIUScale.MilsToIU( PIN_TEXT_MARGIN ) + numPenWidth;
768
769 /* Get the num and name colors */
770 COLOR4D nameColor = settings->GetLayerColor( LAYER_PINNAM );
771 COLOR4D numColor = settings->GetLayerColor( LAYER_PINNUM );
772 COLOR4D bg = settings->GetBackgroundColor();
773
774 if( bg == COLOR4D::UNSPECIFIED || !aPlotter->GetColorMode() )
775 bg = COLOR4D::WHITE;
776
777 if( aDimmed )
778 {
779 nameColor = nameColor.Mix( bg, 0.5f );
780 numColor = numColor.Mix( bg, 0.5f );
781 }
782
783 int x1 = aPinPos.x;
784 int y1 = aPinPos.y;
785
786 switch( aPinOrient )
787 {
788 case PIN_UP: y1 -= m_length; break;
789 case PIN_DOWN: y1 += m_length; break;
790 case PIN_LEFT: x1 -= m_length; break;
791 case PIN_RIGHT: x1 += m_length; break;
792 }
793
794 auto plotText =
795 [&]( int px, int py, const COLOR4D& color, const wxString& text, const EDA_ANGLE& angle,
796 int size, GR_TEXT_H_ALIGN_T hJustify, GR_TEXT_V_ALIGN_T vJustify, int penWidth )
797
798 {
799 aPlotter->Text( VECTOR2I( px, py ), color, text, angle, VECTOR2I( size, size ),
800 hJustify, vJustify, penWidth, false, false, false, font );
801 };
802
803 /* Draw the text inside, but the pin numbers outside. */
804 if( aTextInside )
805 {
806 if( ( aPinOrient == PIN_LEFT) || ( aPinOrient == PIN_RIGHT) ) /* Its an horizontal line. */
807 {
808 if( aDrawPinName )
809 {
810 GR_TEXT_H_ALIGN_T hjustify;
811 if( aPinOrient == PIN_RIGHT )
812 {
813 x = x1 + aTextInside;
814 hjustify = GR_TEXT_H_ALIGN_LEFT;
815 }
816 else // orient == PIN_LEFT
817 {
818 x = x1 - aTextInside;
819 hjustify = GR_TEXT_H_ALIGN_RIGHT;
820 }
821
822 plotText( x, y1, nameColor, name, ANGLE_HORIZONTAL, m_nameTextSize, hjustify,
823 GR_TEXT_V_ALIGN_CENTER, namePenWidth );
824 }
825
826 if( aDrawPinNum )
827 {
828 plotText( ( x1 + aPinPos.x) / 2, y1 - num_offset, numColor, number,
830 GR_TEXT_V_ALIGN_BOTTOM, numPenWidth );
831 }
832 }
833 else /* Its a vertical line. */
834 {
835 if( aPinOrient == PIN_DOWN )
836 {
837 y = y1 + aTextInside;
838
839 if( aDrawPinName )
840 {
841 plotText( x1, y, nameColor, name, ANGLE_VERTICAL, m_nameTextSize,
843 }
844
845 if( aDrawPinNum )
846 {
847 plotText( x1 - num_offset, ( y1 + aPinPos.y) / 2, numColor, number,
849 GR_TEXT_V_ALIGN_BOTTOM, numPenWidth );
850 }
851 }
852 else /* PIN_UP */
853 {
854 y = y1 - aTextInside;
855
856 if( aDrawPinName )
857 {
858 plotText( x1, y, nameColor, name, ANGLE_VERTICAL, m_nameTextSize,
860 }
861
862 if( aDrawPinNum )
863 {
864 plotText( x1 - num_offset, ( y1 + aPinPos.y) / 2, numColor, number,
866 GR_TEXT_V_ALIGN_BOTTOM, numPenWidth );
867 }
868 }
869 }
870 }
871 else /* Draw num & text pin outside */
872 {
873 if(( aPinOrient == PIN_LEFT) || ( aPinOrient == PIN_RIGHT) )
874 {
875 /* Its an horizontal line. */
876 if( aDrawPinName )
877 {
878 x = ( x1 + aPinPos.x) / 2;
879 plotText( x, y1 - name_offset, nameColor, name, ANGLE_HORIZONTAL, m_nameTextSize,
881 }
882
883 if( aDrawPinNum )
884 {
885 x = ( x1 + aPinPos.x ) / 2;
886 plotText( x, y1 + num_offset, numColor, number, ANGLE_HORIZONTAL, m_numTextSize,
888 }
889 }
890 else /* Its a vertical line. */
891 {
892 if( aDrawPinName )
893 {
894 y = ( y1 + aPinPos.y ) / 2;
895 plotText( x1 - name_offset, y, nameColor, name, ANGLE_VERTICAL, m_nameTextSize,
897 }
898
899 if( aDrawPinNum )
900 {
901 plotText( x1 + num_offset, ( y1 + aPinPos.y ) / 2, numColor, number, ANGLE_VERTICAL,
903 }
904 }
905 }
906}
907
908
909int LIB_PIN::PinDrawOrient( const TRANSFORM& aTransform ) const
910{
911 int orient;
912 VECTOR2I end; // position of pin end starting at 0,0 according to its orientation, length = 1
913
914 switch( m_orientation )
915 {
916 case PIN_UP: end.y = 1; break;
917 case PIN_DOWN: end.y = -1; break;
918 case PIN_LEFT: end.x = -1; break;
919 case PIN_RIGHT: end.x = 1; break;
920 }
921
922 // = pos of end point, according to the symbol orientation.
923 end = aTransform.TransformCoordinate( end );
924 orient = PIN_UP;
925
926 if( end.x == 0 )
927 {
928 if( end.y > 0 )
929 orient = PIN_DOWN;
930 }
931 else
932 {
933 orient = PIN_RIGHT;
934
935 if( end.x < 0 )
936 orient = PIN_LEFT;
937 }
938
939 return orient;
940}
941
942
944{
945 return new LIB_PIN( *this );
946}
947
948
949int LIB_PIN::compare( const LIB_ITEM& aOther, int aCompareFlags ) const
950{
951 wxASSERT( aOther.Type() == LIB_PIN_T );
952
953 int retv = LIB_ITEM::compare( aOther, aCompareFlags );
954
955 if( retv )
956 return retv;
957
958 const LIB_PIN* tmp = (LIB_PIN*) &aOther;
959
960 // When comparing units, we do not compare the part numbers. If everything else is
961 // identical, then we can just renumber the parts for the inherited symbol.
962 if( !( aCompareFlags & COMPARE_FLAGS::UNIT ) && m_number != tmp->m_number )
963 return m_number.Cmp( tmp->m_number );
964
965 int result = m_name.Cmp( tmp->m_name );
966
967 if( result )
968 return result;
969
970 if( m_position.x != tmp->m_position.x )
971 return m_position.x - tmp->m_position.x;
972
973 if( m_position.y != tmp->m_position.y )
974 return m_position.y - tmp->m_position.y;
975
976 if( m_length != tmp->m_length )
977 return m_length - tmp->m_length;
978
979 if( m_orientation != tmp->m_orientation )
980 return m_orientation - tmp->m_orientation;
981
982 if( m_shape != tmp->m_shape )
983 return static_cast<int>( m_shape ) - static_cast<int>( tmp->m_shape );
984
985 if( m_type != tmp->m_type )
986 return static_cast<int>( m_type ) - static_cast<int>( tmp->m_type );
987
988 if( m_attributes != tmp->m_attributes )
989 return m_attributes - tmp->m_attributes;
990
991 if( m_numTextSize != tmp->m_numTextSize )
992 return m_numTextSize - tmp->m_numTextSize;
993
994 if( m_nameTextSize != tmp->m_nameTextSize )
995 return m_nameTextSize - tmp->m_nameTextSize;
996
997 if( m_alternates.size() != tmp->m_alternates.size() )
998 return m_alternates.size() - tmp->m_alternates.size();
999
1000 auto lhsItem = m_alternates.begin();
1001 auto rhsItem = tmp->m_alternates.begin();
1002
1003 while( lhsItem != m_alternates.end() )
1004 {
1005 const ALT& lhsAlt = lhsItem->second;
1006 const ALT& rhsAlt = rhsItem->second;
1007
1008 retv = lhsAlt.m_Name.Cmp( rhsAlt.m_Name );
1009
1010 if( retv )
1011 return retv;
1012
1013 if( lhsAlt.m_Type != rhsAlt.m_Type )
1014 return static_cast<int>( lhsAlt.m_Type ) - static_cast<int>( rhsAlt.m_Type );
1015
1016 if( lhsAlt.m_Shape != rhsAlt.m_Shape )
1017 return static_cast<int>( lhsAlt.m_Shape ) - static_cast<int>( rhsAlt.m_Shape );
1018
1019 ++lhsItem;
1020 ++rhsItem;
1021 }
1022
1023 return 0;
1024}
1025
1026void LIB_PIN::ChangeLength( int aLength )
1027{
1028 int lengthChange = m_length - aLength;
1029 int offsetX = 0;
1030 int offsetY = 0;
1031
1032 switch( m_orientation )
1033 {
1034 case PIN_RIGHT:
1035 offsetX = lengthChange;
1036 break;
1037 case PIN_LEFT:
1038 offsetX = -1 * lengthChange;
1039 break;
1040 case PIN_UP:
1041 offsetY = lengthChange;
1042 break;
1043 case PIN_DOWN:
1044 offsetY = -1 * lengthChange;
1045 break;
1046 }
1047
1048 wxPoint offset = wxPoint( offsetX, offsetY );
1049 Offset( offset );
1050
1051 m_length = aLength;
1052}
1053
1054void LIB_PIN::Offset( const VECTOR2I& aOffset )
1055{
1056 m_position += aOffset;
1057}
1058
1059
1060void LIB_PIN::MoveTo( const VECTOR2I& aNewPosition )
1061{
1062 if( m_position != aNewPosition )
1063 {
1064 m_position = aNewPosition;
1065 SetModified();
1066 }
1067}
1068
1069
1071{
1072 m_position.x -= aCenter.x;
1073 m_position.x *= -1;
1074 m_position.x += aCenter.x;
1075
1076 if( m_orientation == PIN_RIGHT )
1078 else if( m_orientation == PIN_LEFT )
1080}
1081
1082
1083void LIB_PIN::MirrorVertical( const VECTOR2I& aCenter )
1084{
1085 m_position.y -= aCenter.y;
1086 m_position.y *= -1;
1087 m_position.y += aCenter.y;
1088
1089 if( m_orientation == PIN_UP )
1091 else if( m_orientation == PIN_DOWN )
1093}
1094
1095
1096void LIB_PIN::Rotate( const VECTOR2I& aCenter, bool aRotateCCW )
1097{
1098 EDA_ANGLE rot_angle = aRotateCCW ? -ANGLE_90 : ANGLE_90;
1099
1100 RotatePoint( m_position, aCenter, rot_angle );
1101
1102 if( aRotateCCW )
1103 {
1104 switch( m_orientation )
1105 {
1106 case PIN_RIGHT: m_orientation = PIN_UP; break;
1107 case PIN_UP: m_orientation = PIN_LEFT; break;
1108 case PIN_LEFT: m_orientation = PIN_DOWN; break;
1109 case PIN_DOWN: m_orientation = PIN_RIGHT; break;
1110 }
1111 }
1112 else
1113 {
1114 switch( m_orientation )
1115 {
1116 case PIN_RIGHT: m_orientation = PIN_DOWN; break;
1117 case PIN_UP: m_orientation = PIN_RIGHT; break;
1118 case PIN_LEFT: m_orientation = PIN_UP; break;
1119 case PIN_DOWN: m_orientation = PIN_LEFT; break;
1120 }
1121 }
1122}
1123
1124
1125void LIB_PIN::Plot( PLOTTER* aPlotter, bool aBackground, const VECTOR2I& aOffset,
1126 const TRANSFORM& aTransform, bool aDimmed ) const
1127{
1128 if( !IsVisible() || aBackground )
1129 return;
1130
1131 int orient = PinDrawOrient( aTransform );
1132 VECTOR2I pos = aTransform.TransformCoordinate( m_position ) + aOffset;
1133
1134 PlotSymbol( aPlotter, pos, orient, aDimmed );
1135 PlotPinTexts( aPlotter, pos, orient, GetParent()->GetPinNameOffset(),
1136 GetParent()->ShowPinNumbers(), GetParent()->ShowPinNames(),
1137 aDimmed );
1138}
1139
1140
1141void LIB_PIN::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1142{
1143 LIB_ITEM::GetMsgPanelInfo( aFrame, aList );
1144
1145 aList.emplace_back( _( "Name" ), UnescapeString( GetShownName() ) );
1146 aList.emplace_back( _( "Number" ), GetShownNumber() );
1147 aList.emplace_back( _( "Type" ), ElectricalPinTypeGetText( m_type ) );
1148 aList.emplace_back( _( "Style" ), PinShapeGetText( m_shape ) );
1149
1150 aList.emplace_back( _( "Style" ), IsVisible() ? _( "Yes" ) : _( "No" ) );
1151
1152 // Display pin length
1153 aList.emplace_back( _( "Length" ), aFrame->MessageTextFromValue( m_length, true ) );
1154
1156 aList.emplace_back( _( "Orientation" ), PinOrientationName( (unsigned) i ) );
1157
1158 VECTOR2I pinpos = GetPosition();
1159 pinpos.y = -pinpos.y; // Display coords are top to bottom; lib item coords are bottom to top
1160
1161 aList.emplace_back( _( "Pos X" ), aFrame->MessageTextFromValue( pinpos.x, true ) );
1162 aList.emplace_back( _( "Pos Y" ), aFrame->MessageTextFromValue( pinpos.y, true ) );
1163}
1164
1165
1167{
1168 return GetBoundingBox( false, true, true );
1169}
1170
1171
1172void LIB_PIN::ViewGetLayers( int aLayers[], int& aCount ) const
1173{
1174 aCount = 3;
1175 aLayers[0] = LAYER_DANGLING; // We don't really show dangling vs non-dangling (since there
1176 // are no connections in the symbol editor), but it's still
1177 // a good visual indication of which end of the pin is which.
1178 aLayers[1] = LAYER_DEVICE;
1179 aLayers[2] = LAYER_SELECTION_SHADOWS;
1180}
1181
1182
1183const BOX2I LIB_PIN::GetBoundingBox( bool aIncludeInvisiblePins, bool aIncludeNameAndNumber,
1184 bool aIncludeElectricalType ) const
1185{
1186 EESCHEMA_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
1188
1189 BOX2I bbox;
1190 VECTOR2I begin;
1191 VECTOR2I end;
1192 int nameTextOffset = 0;
1193 int nameTextLength = 0;
1194 int nameTextHeight = 0;
1195 int numberTextLength = 0;
1196 int numberTextHeight = 0;
1197 int typeTextLength = 0;
1198 wxString name = GetShownName();
1199 wxString number = GetShownNumber();
1200 bool includeName = aIncludeNameAndNumber && !name.IsEmpty();
1201 bool includeNumber = aIncludeNameAndNumber && !number.IsEmpty();
1202 bool includeType = aIncludeElectricalType;
1203 int minsizeV = TARGET_PIN_RADIUS;
1204 int penWidth = GetPenWidth();
1205
1206 if( !aIncludeInvisiblePins && !IsVisible() )
1207 {
1208 includeName = false;
1209 includeType = false;
1210 }
1211
1212 if( GetParent() )
1213 {
1214 if( GetParent()->ShowPinNames() )
1215 nameTextOffset = GetParent()->GetPinNameOffset();
1216 else
1217 includeName = false;
1218
1219 if( !GetParent()->ShowPinNumbers() )
1220 includeNumber = false;
1221 }
1222
1223 if( includeNumber )
1224 {
1226 VECTOR2I numSize = font->StringBoundaryLimits( number, fontSize, penWidth, false, false );
1227
1228 numberTextLength = numSize.x;
1229 numberTextHeight = numSize.y;
1230 }
1231
1232 if( includeName )
1233 {
1235 VECTOR2I nameSize = font->StringBoundaryLimits( name, fontSize, penWidth, false, false );
1236
1237 nameTextLength = nameSize.x + nameTextOffset;
1238 nameTextHeight = nameSize.y + schIUScale.MilsToIU( PIN_TEXT_MARGIN );
1239 }
1240
1241 if( includeType )
1242 {
1243 double fontSize = std::max( m_nameTextSize * 3 / 4, schIUScale.mmToIU( 0.7 ) );
1244 VECTOR2I typeTextSize = font->StringBoundaryLimits( GetElectricalTypeName(),
1245 VECTOR2D( fontSize, fontSize ),
1246 fontSize / 8.0, false, false );
1247
1248 typeTextLength = typeTextSize.x + schIUScale.MilsToIU( PIN_TEXT_MARGIN ) + TARGET_PIN_RADIUS;
1249 minsizeV = std::max( minsizeV, typeTextSize.y / 2 );
1250 }
1251
1252 // First, calculate boundary box corners position
1254 minsizeV = std::max( TARGET_PIN_RADIUS, externalPinDecoSize( nullptr, *this ) );
1255
1256 // calculate top left corner position
1257 // for the default pin orientation (PIN_RIGHT)
1258 begin.y = std::max( minsizeV, numberTextHeight + schIUScale.MilsToIU( PIN_TEXT_MARGIN ) );
1259 begin.x = std::min( -typeTextLength, m_length - ( numberTextLength / 2) );
1260
1261 // calculate bottom right corner position and adjust top left corner position
1262 if( nameTextOffset ) // for values > 0, pin name is inside the body
1263 {
1264 end.x = m_length + nameTextLength;
1265 end.y = std::min( -minsizeV, -nameTextHeight / 2 );
1266 }
1267 else // if value == 0:
1268 // pin name is outside the body, and above the pin line
1269 // pin num is below the pin line
1270 {
1271 end.x = std::max( m_length, nameTextLength );
1272 end.y = -begin.y;
1273 begin.y = std::max( minsizeV, nameTextHeight );
1274 }
1275
1276 // Now, calculate boundary box corners position for the actual pin orientation
1277 int orient = PinDrawOrient( DefaultTransform );
1278
1279 /* Calculate the pin position */
1280 switch( orient )
1281 {
1282 case PIN_UP:
1283 // Pin is rotated and texts positions are mirrored
1284 RotatePoint( begin, VECTOR2I( 0, 0 ), -ANGLE_90 );
1285 RotatePoint( end, VECTOR2I( 0, 0 ), -ANGLE_90 );
1286 break;
1287
1288 case PIN_DOWN:
1289 RotatePoint( begin, VECTOR2I( 0, 0 ), ANGLE_90 );
1290 RotatePoint( end, VECTOR2I( 0, 0 ), ANGLE_90 );
1291 begin.x = -begin.x;
1292 end.x = -end.x;
1293 break;
1294
1295 case PIN_LEFT:
1296 begin.x = -begin.x;
1297 end.x = -end.x;
1298 break;
1299
1300 case PIN_RIGHT:
1301 break;
1302 }
1303
1304 begin += m_position;
1305 end += m_position;
1306
1307 bbox.SetOrigin( begin );
1308 bbox.SetEnd( end );
1309 bbox.Normalize();
1310 bbox.Inflate( ( GetPenWidth() / 2 ) + 1 );
1311
1312 // Draw Y axis is reversed in schematic:
1313 bbox.RevertYAxis();
1314
1315 return bbox;
1316}
1317
1318
1320{
1322}
1323
1324
1325wxString LIB_PIN::GetSelectMenuText( UNITS_PROVIDER* aUnitsProvider ) const
1326{
1327 if( IsVisible() )
1328 {
1329 if( !m_name.IsEmpty() )
1330 {
1331 return wxString::Format( _( "Pin %s [%s, %s, %s]" ),
1336 }
1337 else
1338 {
1339 return wxString::Format( _( "Pin %s [%s, %s]" ),
1343 }
1344 }
1345 else
1346 {
1347 if( !m_name.IsEmpty() )
1348 {
1349 return wxString::Format( _( "Hidden pin %s [%s, %s, %s]" ),
1354 }
1355 else
1356 {
1357 return wxString::Format( _( "Hidden pin %s [%s, %s]" ),
1361 }
1362 }
1363}
1364
1365
1366#if defined(DEBUG)
1367
1368void LIB_PIN::Show( int nestLevel, std::ostream& os ) const
1369{
1370 NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
1371 << " num=\"" << m_number.mb_str()
1372 << '"' << "/>\n";
1373
1374// NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
1375}
1376
1377#endif
1378
1379void LIB_PIN::CalcEdit( const VECTOR2I& aPosition )
1380{
1381 if( IsMoving() )
1382 MoveTo( aPosition );
1383}
int color
Definition: DXF_plotter.cpp:57
const char * name
Definition: DXF_plotter.cpp:56
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:33
void SetOrigin(const Vec &pos)
Definition: box2.h:202
BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition: box2.h:119
void RevertYAxis()
Mirror the rectangle from the X axis (negate Y pos and size).
Definition: box2.h:689
bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:269
bool Contains(const Vec &aPoint) const
Definition: box2.h:141
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:506
void SetEnd(coord_type x, coord_type y)
Definition: box2.h:255
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:85
void SetModified()
Definition: eda_item.cpp:64
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:500
bool IsMoving() const
Definition: eda_item.h:104
FONT is an abstract base class for both outline and stroke fonts.
Definition: font.h:105
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false)
Definition: font.cpp:65
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
COLOR4D Mix(const COLOR4D &aColor, double aFactor) const
Return a color that is mixed with the input by a factor.
Definition: color4d.h:305
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
Store schematic specific render settings.
Definition: sch_painter.h:71
The base class for drawable items used by schematic library symbols.
Definition: lib_item.h:61
virtual int compare(const LIB_ITEM &aOther, int aCompareFlags=0) const
Provide the draw object specific comparison called by the == and < operators.
Definition: lib_item.cpp:74
virtual int GetEffectivePenWidth(const RENDER_SETTINGS *aSettings) const
Definition: lib_item.h:155
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Display basic info (type, part and convert) about the current item in message panel.
Definition: lib_item.cpp:47
LIB_SYMBOL * GetParent() const
Definition: lib_item.h:168
void SetConvert(int aConvert)
Definition: lib_item.h:275
void SetUnit(int aUnit)
Definition: lib_item.h:272
int m_attributes
Definition: lib_pin.h:295
void ViewGetLayers(int aLayers[], int &aCount) const override
Return the all the layers within the VIEW the object is painted on.
Definition: lib_pin.cpp:1172
void MirrorHorizontal(const VECTOR2I &aCenter) override
Mirror the draw object along the horizontal (X) axis about aCenter point.
Definition: lib_pin.cpp:1070
void Offset(const VECTOR2I &aOffset) override
Set the drawing object by aOffset from the current position.
Definition: lib_pin.cpp:1054
void PlotPinTexts(PLOTTER *aPlotter, const VECTOR2I &aPinPos, int aPinOrient, int aTextInside, bool aDrawPinNum, bool aDrawPinName, bool aDimmed) const
Plot the pin number and pin text info, given the pin line coordinates.
Definition: lib_pin.cpp:744
const BOX2I GetBoundingBox() const override
Definition: lib_pin.h:184
void SetName(const wxString &aName)
Definition: lib_pin.h:114
void MirrorVertical(const VECTOR2I &aCenter) override
Mirror the draw object along the MirrorVertical (Y) axis about aCenter point.
Definition: lib_pin.cpp:1083
int compare(const LIB_ITEM &aOther, int aCompareFlags=0) const override
Provide the draw object specific comparison called by the == and < operators.
Definition: lib_pin.cpp:949
wxString m_name
Definition: lib_pin.h:296
const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
Definition: lib_pin.cpp:1166
int m_nameTextSize
Definition: lib_pin.h:299
wxString GetShownNumber() const
Definition: lib_pin.h:123
LIB_PIN(LIB_SYMBOL *aParent)
Definition: lib_pin.cpp:97
int GetNumberTextSize() const
Definition: lib_pin.h:135
void printPinSymbol(const RENDER_SETTINGS *aSettings, const VECTOR2I &aPos, int aOrientation, bool aDimmed)
Print the pin symbol without text.
Definition: lib_pin.cpp:248
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Display basic info (type, part and convert) about the current item in message panel.
Definition: lib_pin.cpp:1141
wxString GetShownName() const
Definition: lib_pin.cpp:175
int m_length
Definition: lib_pin.h:291
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW=true) override
Rotate the object about aCenter point.
Definition: lib_pin.cpp:1096
void ChangeLength(int aLength)
Change the length of a pin and adjust its position based on orientation.
Definition: lib_pin.cpp:1026
wxString const GetCanonicalElectricalTypeName() const
Definition: lib_pin.h:93
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: lib_pin.cpp:1319
void MoveTo(const VECTOR2I &aNewPosition) override
Move a draw object to aPosition.
Definition: lib_pin.cpp:1060
wxString GetClass() const override
Return the class name.
Definition: lib_pin.h:64
VECTOR2I m_position
Definition: lib_pin.h:290
int m_orientation
Definition: lib_pin.h:292
int m_numTextSize
Definition: lib_pin.h:298
GRAPHIC_PINSHAPE m_shape
Definition: lib_pin.h:293
VECTOR2I GetPosition() const override
Definition: lib_pin.h:222
wxString GetSelectMenuText(UNITS_PROVIDER *aUnitsProvider) const override
Return the text to display to be used in the selection clarification context menu when multiple items...
Definition: lib_pin.cpp:1325
void CalcEdit(const VECTOR2I &aPosition) override
Calculate the attributes of an item at aPosition when it is being edited.
Definition: lib_pin.cpp:1379
wxString const GetElectricalTypeName() const
Definition: lib_pin.h:98
std::map< wxString, ALT > m_alternates
Definition: lib_pin.h:301
bool IsVisible() const
Definition: lib_pin.h:103
void SetNumber(const wxString &aNumber)
Definition: lib_pin.h:124
void print(const RENDER_SETTINGS *aSettings, const VECTOR2I &aOffset, void *aData, const TRANSFORM &aTransform, bool aDimmed) override
Print a pin, with or without the pin texts.
Definition: lib_pin.cpp:197
ELECTRICAL_PINTYPE m_type
Definition: lib_pin.h:294
void Plot(PLOTTER *aPlotter, bool aBackground, const VECTOR2I &aOffset, const TRANSFORM &aTransform, bool aDimmed) const override
Plot the draw item using the plot object.
Definition: lib_pin.cpp:1125
int PinDrawOrient(const TRANSFORM &aTransform) const
Return the pin real orientation (PIN_UP, PIN_DOWN, PIN_RIGHT, PIN_LEFT), according to its orientation...
Definition: lib_pin.cpp:909
wxString m_number
Definition: lib_pin.h:297
int GetNameTextSize() const
Definition: lib_pin.h:132
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: lib_pin.cpp:943
VECTOR2I GetPinRoot() const
Definition: lib_pin.cpp:184
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
Definition: lib_pin.cpp:144
int GetPenWidth() const override
Definition: lib_pin.cpp:169
void printPinElectricalTypeName(const RENDER_SETTINGS *aSettings, VECTOR2I &aPosition, int aOrientation, bool aDimmed)
Draw the electrical type text of the pin (only for the footprint editor)
Definition: lib_pin.cpp:540
void PlotSymbol(PLOTTER *aPlotter, const VECTOR2I &aPosition, int aOrientation, bool aDimmed) const
Definition: lib_pin.cpp:604
void printPinTexts(const RENDER_SETTINGS *aSettings, VECTOR2I &aPinPos, int aPinOrient, int aTextInside, bool aDrawPinNum, bool aDrawPinName, bool aDimmed)
Put the pin number and pin text info, given the pin line coordinates.
Definition: lib_pin.cpp:369
Define a library symbol object.
Definition: lib_symbol.h:98
int GetPinNameOffset() const
Definition: lib_symbol.h:628
bool ShowPinNames() const
Definition: lib_symbol.h:636
bool ShowPinNumbers() const
Definition: lib_symbol.h:644
Container for data for KiCad programs.
Definition: pgm_base.h:94
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:134
Base plotter engine class.
Definition: plotter.h:110
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:247
void FinishTo(const VECTOR2I &pos)
Definition: plotter.h:257
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:141
virtual void Text(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 aPenWidth, bool aItalic, bool aBold, bool aMultilineAllowed, KIFONT::FONT *aFont, void *aData=nullptr)
Draw text with the plotter.
Definition: plotter.cpp:714
bool GetColorMode() const
Definition: plotter.h:138
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:252
virtual void SetColor(const COLOR4D &color)=0
T * GetAppSettings(bool aLoadNow=true)
Returns a handle to the a given settings by type If the settings have already been loaded,...
for transforming drawing coordinates for a wxDC device context.
Definition: transform.h:47
VECTOR2I TransformCoordinate(const VECTOR2I &aPoint) const
Calculate a new coordinate according to the mirror/rotation transform.
Definition: transform.cpp:41
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
A lower-precision version of StringFromValue().
@ WHITE
Definition: color4d.h:48
PGM_BASE * PgmOrNull()
similar to PGM_BASE& Pgm(), but return a reference that can be nullptr when running a shared lib from...
Definition: cvpcb.cpp:125
#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 _(s)
static constexpr EDA_ANGLE & ANGLE_HORIZONTAL
Definition: eda_angle.h:408
static constexpr EDA_ANGLE & ANGLE_VERTICAL
Definition: eda_angle.h:409
static constexpr EDA_ANGLE & ANGLE_90
Definition: eda_angle.h:414
#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: eeschema.cpp:68
void GRLineTo(wxDC *DC, int x, int y, int width, const COLOR4D &Color)
Definition: gr_basic.cpp:186
void GRCircle(wxDC *aDC, const VECTOR2I &aPos, int aRadius, int aWidth, const COLOR4D &aColor)
Definition: gr_basic.cpp:348
void GRMoveTo(int x, int y)
Definition: gr_basic.cpp:179
void GRLine(wxDC *DC, int x1, int y1, int x2, int y2, int width, const COLOR4D &Color, wxPenStyle aStyle)
Definition: gr_basic.cpp:162
bool GetGRForceBlackPenState(void)
Definition: gr_basic.cpp:156
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)
Print a graphic text through wxDC.
Definition: gr_text.cpp:129
int Clamp_Text_PenSize(int aPenSize, int aSize, bool aStrict)
Pen width should not allow characters to become cluttered up in their own fatness.
Definition: gr_text.cpp:75
@ LAYER_DANGLING
Definition: layer_ids.h:368
@ LAYER_PINNUM
Definition: layer_ids.h:350
@ LAYER_DEVICE
Definition: layer_ids.h:357
@ LAYER_HIDDEN
Definition: layer_ids.h:380
@ LAYER_PINNAM
Definition: layer_ids.h:351
@ LAYER_PRIVATE_NOTES
Definition: layer_ids.h:359
@ LAYER_PIN
Definition: layer_ids.h:361
@ LAYER_SELECTION_SHADOWS
Definition: layer_ids.h:381
#define ETXT_MAX_SIZE
#define PIN_TEXT_MARGIN
Definition: lib_pin.cpp:41
static int externalPinDecoSize(const RENDER_SETTINGS *aSettings, const LIB_PIN &aPin)
Utility for getting the size of the 'external' pin decorators (as a radius)
Definition: lib_pin.cpp:86
static int internalPinDecoSize(const RENDER_SETTINGS *aSettings, const LIB_PIN &aPin)
Utility for getting the size of the 'internal' pin decorators (as a radius)
Definition: lib_pin.cpp:73
@ PIN_LEFT
Definition: lib_pin.h:46
@ PIN_RIGHT
Definition: lib_pin.h:45
@ PIN_UP
Definition: lib_pin.h:47
@ PIN_DOWN
Definition: lib_pin.h:48
#define TARGET_PIN_RADIUS
Definition: lib_pin.h:35
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
see class PGM_BASE
wxString PinOrientationName(unsigned aPinOrientationCode)
Definition: pin_type.cpp:119
int PinOrientationIndex(int code)
Definition: pin_type.cpp:150
wxString ElectricalPinTypeGetText(ELECTRICAL_PINTYPE aType)
Definition: pin_type.cpp:240
BITMAPS ElectricalPinTypeGetBitmap(ELECTRICAL_PINTYPE aType)
Definition: pin_type.cpp:268
wxString PinShapeGetText(GRAPHIC_PINSHAPE aShape)
Definition: pin_type.cpp:278
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
Definition: pin_type.h:36
@ PT_NC
not connected (must be left open)
@ PT_NIC
not internally connected (may be connected to anything)
@ PT_UNSPECIFIED
unknown electrical properties: creates always a warning when connected
GRAPHIC_PINSHAPE
Definition: pin_type.h:56
Plot settings, and plotting engines (PostScript, Gerber, HPGL and DXF)
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:111
wxString UnescapeString(const wxString &aSource)
constexpr int MilsToIU(int mils) const
Definition: base_units.h:94
constexpr int mmToIU(double mm) const
Definition: base_units.h:89
GRAPHIC_PINSHAPE m_Shape
Definition: lib_pin.h:58
ELECTRICAL_PINTYPE m_Type
Definition: lib_pin.h:59
wxString m_Name
Definition: lib_pin.h:57
bool force_draw_pin_text
Definition: lib_symbol.h:64
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)
Definition: trigo.cpp:183
@ LIB_PIN_T
Definition: typeinfo.h:202
VECTOR2< double > VECTOR2D
Definition: vector2d.h:617
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618