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-2021 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 <pgm_base.h>
27 #include <sch_draw_panel.h>
28 #include <sch_edit_frame.h>
29 #include <symbol_edit_frame.h>
30 #include <lib_pin.h>
33 #include <trigo.h>
34 #include <string_utils.h>
35 #include "sch_painter.h"
36 
37 // small margin in internal units between the pin text and the pin line
38 #define PIN_TEXT_MARGIN 4
39 
41 {
42  // These strings are the canonical name of the electrictal type
43  // Not translated, no space in name, only ASCII chars.
44  // to use when the string name must be known and well defined
45  // must have same order than enum ELECTRICAL_PINTYPE (see lib_pin.h)
46  static const wxChar* msgPinElectricType[] =
47  {
48  wxT( "input" ),
49  wxT( "output" ),
50  wxT( "bidirectional" ),
51  wxT( "tri_state" ),
52  wxT( "passive" ),
53  wxT( "free" ),
54  wxT( "unspecified" ),
55  wxT( "power_in" ),
56  wxT( "power_out" ),
57  wxT( "open_collector" ),
58  wxT( "open_emitter" ),
59  wxT( "no_connect" )
60  };
61 
62  return msgPinElectricType[static_cast<int>( aType )];
63 }
64 
65 
67 // i.e. the clock symbols (falling clock is actually external but is of
68 // the same kind)
69 
70 static int internalPinDecoSize( const RENDER_SETTINGS* aSettings, const LIB_PIN &aPin )
71 {
72  const KIGFX::SCH_RENDER_SETTINGS* settings = static_cast<const KIGFX::SCH_RENDER_SETTINGS*>( aSettings );
73 
74  if( settings && settings->m_PinSymbolSize )
75  return settings->m_PinSymbolSize;
76 
77  return aPin.GetNameTextSize() != 0 ? aPin.GetNameTextSize() / 2 : aPin.GetNumberTextSize() / 2;
78 }
79 
81 // i.e. the negation circle, the polarity 'slopes' and the nonlogic
82 // marker
83 static int externalPinDecoSize( const RENDER_SETTINGS* aSettings, const LIB_PIN &aPin )
84 {
85  const KIGFX::SCH_RENDER_SETTINGS* settings = static_cast<const KIGFX::SCH_RENDER_SETTINGS*>( aSettings );
86 
87  if( settings && settings->m_PinSymbolSize )
88  return settings->m_PinSymbolSize;
89 
90  return aPin.GetNumberTextSize() / 2;
91 }
92 
93 
95  LIB_ITEM( LIB_PIN_T, aParent ),
96  m_orientation( PIN_RIGHT ),
97  m_shape( GRAPHIC_PINSHAPE::LINE ),
99  m_attributes( 0 )
100 {
101  // Use the application settings for pin sizes if exists.
102  // pgm can be nullptr when running a shared lib from a script, not from a kicad appl
103  PGM_BASE* pgm = PgmOrNull();
104 
105  if( pgm )
106  {
107  auto* settings = pgm->GetSettingsManager().GetAppSettings<SYMBOL_EDITOR_SETTINGS>();
108  m_length = Mils2iu( settings->m_Defaults.pin_length );
109  m_numTextSize = Mils2iu( settings->m_Defaults.pin_num_size );
110  m_nameTextSize = Mils2iu( settings->m_Defaults.pin_name_size );
111  }
112  else // Use hardcoded eeschema defaults: symbol_editor settings are not existing.
113  {
114  m_length = Mils2iu( DEFAULT_PIN_LENGTH );
115  m_numTextSize = Mils2iu( DEFAULT_PINNUM_SIZE );
117  }
118 }
119 
120 
121 LIB_PIN::LIB_PIN( LIB_SYMBOL* aParent, const wxString& aName, const wxString& aNumber,
122  int aOrientation, ELECTRICAL_PINTYPE aPinType, int aLength, int aNameTextSize,
123  int aNumTextSize, int aConvert, const wxPoint& aPos, int aUnit ) :
124  LIB_ITEM( LIB_PIN_T, aParent ),
125  m_position( aPos ),
126  m_length( aLength ),
127  m_orientation( aOrientation ),
128  m_shape( GRAPHIC_PINSHAPE::LINE ),
129  m_type( aPinType ),
130  m_attributes( 0 ),
131  m_numTextSize( aNumTextSize ),
132  m_nameTextSize( aNameTextSize )
133 {
134  SetName( aName );
135  SetNumber( aNumber );
136  SetUnit( aUnit );
137  SetConvert( aConvert );
138 }
139 
140 
141 bool LIB_PIN::HitTest( const wxPoint& aPosition, int aAccuracy ) const
142 {
143  EDA_RECT rect = GetBoundingBox();
144 
145  return rect.Inflate( aAccuracy ).Contains( aPosition );
146 }
147 
148 
149 bool LIB_PIN::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
150 {
151  if( m_flags & (STRUCT_DELETED | SKIP_STRUCT ) )
152  return false;
153 
154  EDA_RECT sel = aRect;
155 
156  if ( aAccuracy )
157  sel.Inflate( aAccuracy );
158 
159  if( aContained )
160  return sel.Contains( GetBoundingBox( false, true ) );
161 
162  return sel.Intersects( GetBoundingBox( false, true ) );
163 }
164 
165 
167 {
168  return 0;
169 }
170 
171 
172 wxString LIB_PIN::GetShownName() const
173 {
174  if( m_name == wxT( "~" ) )
175  return wxEmptyString;
176  else
177  return m_name;
178 }
179 
180 
181 wxPoint LIB_PIN::GetPinRoot() const
182 {
183  switch( m_orientation )
184  {
185  default:
186  case PIN_RIGHT: return wxPoint( m_position.x + m_length, -( m_position.y ) );
187  case PIN_LEFT: return wxPoint( m_position.x - m_length, -( m_position.y ) );
188  case PIN_UP: return wxPoint( m_position.x, -( m_position.y + m_length ) );
189  case PIN_DOWN: return wxPoint( m_position.x, -( m_position.y - m_length ) );
190  }
191 }
192 
193 
194 void LIB_PIN::print( const RENDER_SETTINGS* aSettings, const wxPoint& aOffset, void* aData,
195  const TRANSFORM& aTransform )
196 {
197  LIB_SYMBOL_OPTIONS* opts = (LIB_SYMBOL_OPTIONS*) aData;
198  bool drawHiddenFields = opts ? opts->draw_hidden_fields : false;
199  bool showPinType = opts ? opts->show_elec_type : false;
200  bool show_connect_point = opts ? opts->show_connect_point : false;
201 
202  LIB_SYMBOL* part = GetParent();
203 
204  /* Calculate pin orient taking in account the symbol orientation. */
205  int orient = PinDrawOrient( aTransform );
206 
207  /* Calculate the pin position */
208  wxPoint pos1 = aTransform.TransformCoordinate( m_position ) + aOffset;
209 
210  if( IsVisible() || drawHiddenFields )
211  {
212  printPinSymbol( aSettings, pos1, orient );
213 
214  printPinTexts( aSettings, pos1, orient, part->GetPinNameOffset(), part->ShowPinNumbers(),
215  part->ShowPinNames() );
216 
217  if( showPinType )
218  printPinElectricalTypeName( aSettings, pos1, orient );
219 
220  if( show_connect_point
223  {
224  wxDC* DC = aSettings->GetPrintDC();
226  GRCircle( nullptr, DC, pos1.x, pos1.y, TARGET_PIN_RADIUS, 0, color );
227  }
228  }
229 }
230 
231 
232 void LIB_PIN::printPinSymbol( const RENDER_SETTINGS* aSettings, const wxPoint& aPos, int aOrient )
233 {
234  wxDC* DC = aSettings->GetPrintDC();
235  int MapX1, MapY1, x1, y1;
236  int width = GetEffectivePenWidth( aSettings );
237  int posX = aPos.x, posY = aPos.y, len = m_length;
239 
240  MapX1 = MapY1 = 0;
241  x1 = posX;
242  y1 = posY;
243 
244  switch( aOrient )
245  {
246  case PIN_UP: y1 = posY - len; MapY1 = 1; break;
247  case PIN_DOWN: y1 = posY + len; MapY1 = -1; break;
248  case PIN_LEFT: x1 = posX - len; MapX1 = 1; break;
249  case PIN_RIGHT: x1 = posX + len; MapX1 = -1; break;
250  }
251 
253  {
254  const int radius = externalPinDecoSize( aSettings, *this );
255  GRCircle( nullptr, DC, MapX1 * radius + x1, MapY1 * radius + y1, radius, width, color );
256 
257  GRMoveTo( MapX1 * radius * 2 + x1, MapY1 * radius * 2 + y1 );
258  GRLineTo( nullptr, DC, posX, posY, width, color );
259  }
260  else
261  {
262  GRMoveTo( x1, y1 );
263  GRLineTo( nullptr, DC, posX, posY, width, color );
264  }
265 
266  // Draw the clock shape (>)inside the symbol
271  {
272  const int clock_size = internalPinDecoSize( aSettings, *this );
273  if( MapY1 == 0 ) /* MapX1 = +- 1 */
274  {
275  GRMoveTo( x1, y1 + clock_size );
276  GRLineTo( nullptr, DC, x1 - MapX1 * clock_size * 2, y1, width, color );
277  GRLineTo( nullptr, DC, x1, y1 - clock_size, width, color );
278  }
279  else /* MapX1 = 0 */
280  {
281  GRMoveTo( x1 + clock_size, y1 );
282  GRLineTo( nullptr, DC, x1, y1 - MapY1 * clock_size * 2, width, color );
283  GRLineTo( nullptr, DC, x1 - clock_size, y1, width, color );
284  }
285  }
286 
287  // Draw the active low (or H to L active transition)
291  {
292  const int deco_size = externalPinDecoSize( aSettings, *this );
293  if( MapY1 == 0 ) /* MapX1 = +- 1 */
294  {
295  GRMoveTo( x1 + MapX1 * deco_size * 2, y1 );
296  GRLineTo( nullptr, DC, x1 + MapX1 * deco_size * 2, y1 - deco_size * 2, width, color );
297  GRLineTo( nullptr, DC, x1, y1, width, color );
298  }
299  else /* MapX1 = 0 */
300  {
301  GRMoveTo( x1, y1 + MapY1 * deco_size * 2 );
302  GRLineTo( nullptr, DC, x1 - deco_size * 2, y1 + MapY1 * deco_size * 2, width, color );
303  GRLineTo( nullptr, DC, x1, y1, width, color );
304  }
305  }
306 
307  if( m_shape == GRAPHIC_PINSHAPE::OUTPUT_LOW ) /* IEEE symbol "Active Low Output" */
308  {
309  const int deco_size = externalPinDecoSize( aSettings, *this );
310  if( MapY1 == 0 ) /* MapX1 = +- 1 */
311  {
312  GRMoveTo( x1, y1 - deco_size * 2 );
313  GRLineTo( nullptr, DC, x1 + MapX1 * deco_size * 2, y1, width, color );
314  }
315  else /* MapX1 = 0 */
316  {
317  GRMoveTo( x1 - deco_size * 2, y1 );
318  GRLineTo( nullptr, DC, x1, y1 + MapY1 * deco_size * 2, width, color );
319  }
320  }
321  else if( m_shape == GRAPHIC_PINSHAPE::NONLOGIC ) /* NonLogic pin symbol */
322  {
323  const int deco_size = externalPinDecoSize( aSettings, *this );
324  GRMoveTo( x1 - (MapX1 + MapY1) * deco_size, y1 - (MapY1 - MapX1) * deco_size );
325  GRLineTo( nullptr, DC, x1 + (MapX1 + MapY1) * deco_size,
326  y1 + ( MapY1 - MapX1 ) * deco_size, width, color );
327  GRMoveTo( x1 - (MapX1 - MapY1) * deco_size, y1 - (MapY1 + MapX1) * deco_size );
328  GRLineTo( nullptr, DC, x1 + (MapX1 - MapY1) * deco_size,
329  y1 + ( MapY1 + MapX1 ) * deco_size, width, color );
330  }
331 
332  if( m_type == ELECTRICAL_PINTYPE::PT_NC ) // Draw a N.C. symbol
333  {
334  const int deco_size = TARGET_PIN_RADIUS;
335  GRLine( nullptr, DC, posX - deco_size, posY - deco_size, posX + deco_size,
336  posY + deco_size, width, color );
337  GRLine( nullptr, DC, posX + deco_size, posY - deco_size, posX - deco_size,
338  posY + deco_size, width, color );
339  }
340 }
341 
342 
343 void LIB_PIN::printPinTexts( const RENDER_SETTINGS* aSettings, wxPoint& aPinPos, int aPinOrient,
344  int aTextInside, bool aDrawPinNum, bool aDrawPinName )
345 {
346  if( !aDrawPinName && !aDrawPinNum )
347  return;
348 
349  int x, y;
350  wxDC* DC = aSettings->GetPrintDC();
351  wxSize PinNameSize( m_nameTextSize, m_nameTextSize );
352  wxSize PinNumSize( m_numTextSize, m_numTextSize );
353 
354  int namePenWidth = std::max( Clamp_Text_PenSize( GetPenWidth(), m_nameTextSize, false ),
355  aSettings->GetDefaultPenWidth() );
356  int numPenWidth = std::max( Clamp_Text_PenSize( GetPenWidth(), m_numTextSize, false ),
357  aSettings->GetDefaultPenWidth() );
358 
359  int name_offset = Mils2iu( PIN_TEXT_MARGIN ) + namePenWidth;
360  int num_offset = Mils2iu( PIN_TEXT_MARGIN ) + numPenWidth;
361 
362  /* Get the num and name colors */
363  COLOR4D NameColor = aSettings->GetLayerColor( IsVisible() ? LAYER_PINNAM : LAYER_HIDDEN );
364  COLOR4D NumColor = aSettings->GetLayerColor( IsVisible() ? LAYER_PINNUM : LAYER_HIDDEN );
365 
366  int x1 = aPinPos.x;
367  int y1 = aPinPos.y;
368 
369  switch( aPinOrient )
370  {
371  case PIN_UP: y1 -= m_length; break;
372  case PIN_DOWN: y1 += m_length; break;
373  case PIN_LEFT: x1 -= m_length; break;
374  case PIN_RIGHT: x1 += m_length; break;
375  }
376 
377  wxString name = GetShownName();
378  wxString number = GetShownNumber();
379 
380  if( name.IsEmpty() )
381  aDrawPinName = false;
382 
383  if( number.IsEmpty() )
384  aDrawPinNum = false;
385 
386  if( aTextInside ) // Draw the text inside, but the pin numbers outside.
387  {
388  if(( aPinOrient == PIN_LEFT) || ( aPinOrient == PIN_RIGHT) )
389  {
390  // It is an horizontal line
391  if( aDrawPinName )
392  {
393  if( aPinOrient == PIN_RIGHT )
394  {
395  x = x1 + aTextInside;
396  GRText( DC, wxPoint( x, y1 ), NameColor, name, TEXT_ANGLE_HORIZ, PinNameSize,
397  GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, namePenWidth, false,
398  false );
399  }
400  else // Orient == PIN_LEFT
401  {
402  x = x1 - aTextInside;
403  GRText( DC, wxPoint( x, y1 ), NameColor, name, TEXT_ANGLE_HORIZ, PinNameSize,
404  GR_TEXT_HJUSTIFY_RIGHT, GR_TEXT_VJUSTIFY_CENTER, namePenWidth, false,
405  false );
406  }
407  }
408 
409  if( aDrawPinNum )
410  {
411  GRText( DC, wxPoint(( x1 + aPinPos.x) / 2, y1 - num_offset ), NumColor, number,
413  GR_TEXT_VJUSTIFY_BOTTOM, numPenWidth, false, false );
414  }
415  }
416  else /* Its a vertical line. */
417  {
418  // Text is drawn from bottom to top (i.e. to negative value for Y axis)
419  if( aPinOrient == PIN_DOWN )
420  {
421  y = y1 + aTextInside;
422 
423  if( aDrawPinName )
424  {
425  GRText( DC, wxPoint( x1, y ), NameColor, name, TEXT_ANGLE_VERT, PinNameSize,
426  GR_TEXT_HJUSTIFY_RIGHT, GR_TEXT_VJUSTIFY_CENTER, namePenWidth, false,
427  false );
428  }
429 
430  if( aDrawPinNum )
431  {
432  GRText( DC, wxPoint( x1 - num_offset, ( y1 + aPinPos.y) / 2 ), NumColor,
433  number, TEXT_ANGLE_VERT, PinNumSize, GR_TEXT_HJUSTIFY_CENTER,
434  GR_TEXT_VJUSTIFY_BOTTOM, numPenWidth, false, false );
435  }
436  }
437  else /* PIN_UP */
438  {
439  y = y1 - aTextInside;
440 
441  if( aDrawPinName )
442  {
443  GRText( DC, wxPoint( x1, y ), NameColor, name, TEXT_ANGLE_VERT, PinNameSize,
444  GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, namePenWidth, false,
445  false );
446  }
447 
448  if( aDrawPinNum )
449  {
450  GRText( DC, wxPoint( x1 - num_offset, ( y1 + aPinPos.y) / 2 ), NumColor,
451  number, TEXT_ANGLE_VERT, PinNumSize, GR_TEXT_HJUSTIFY_CENTER,
452  GR_TEXT_VJUSTIFY_BOTTOM, numPenWidth, false, false );
453  }
454  }
455  }
456  }
457  else /**** Draw num & text pin outside ****/
458  {
459  if(( aPinOrient == PIN_LEFT) || ( aPinOrient == PIN_RIGHT) )
460  {
461  /* Its an horizontal line. */
462  if( aDrawPinName )
463  {
464  x = ( x1 + aPinPos.x) / 2;
465  GRText( DC, wxPoint( x, y1 - name_offset ), NameColor, name, TEXT_ANGLE_HORIZ,
467  namePenWidth, false, false );
468  }
469  if( aDrawPinNum )
470  {
471  x = ( x1 + aPinPos.x) / 2;
472  GRText( DC, wxPoint( x, y1 + num_offset ), NumColor, number, TEXT_ANGLE_HORIZ,
473  PinNumSize, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_TOP, numPenWidth,
474  false, false );
475  }
476  }
477  else /* Its a vertical line. */
478  {
479  if( aDrawPinName )
480  {
481  y = ( y1 + aPinPos.y) / 2;
482  GRText( DC, wxPoint( x1 - name_offset, y ), NameColor, name, TEXT_ANGLE_VERT,
484  namePenWidth, false, false );
485  }
486 
487  if( aDrawPinNum )
488  {
489  GRText( DC, wxPoint( x1 + num_offset, ( y1 + aPinPos.y) / 2 ), NumColor, number,
491  numPenWidth, false, false );
492  }
493  }
494  }
495 }
496 
497 
498 
499 void LIB_PIN::printPinElectricalTypeName( const RENDER_SETTINGS* aSettings, wxPoint& aPosition,
500  int aOrientation )
501 {
502  wxDC* DC = aSettings->GetPrintDC();
503  wxString typeName = GetElectricalTypeName();
504 
505  // Use a reasonable (small) size to draw the text
506  int textSize = ( m_nameTextSize * 3 ) / 4;
507 
508  #define ETXT_MAX_SIZE Millimeter2iu( 0.7 )
509 
510  if( textSize > ETXT_MAX_SIZE )
511  textSize = ETXT_MAX_SIZE;
512 
513  // Use a reasonable pen size to draw the text
514  int pensize = textSize/6;
515 
516  // Get a suitable color
518 
519  wxPoint txtpos = aPosition;
520  int offset = Millimeter2iu( 0.4 );
522  int orient = TEXT_ANGLE_HORIZ;
523 
524  switch( aOrientation )
525  {
526  case PIN_UP:
527  txtpos.y += offset;
528  orient = TEXT_ANGLE_VERT;
529  hjustify = GR_TEXT_HJUSTIFY_RIGHT;
530  break;
531 
532  case PIN_DOWN:
533  txtpos.y -= offset;
534  orient = TEXT_ANGLE_VERT;
535  break;
536 
537  case PIN_LEFT:
538  txtpos.x += offset;
539  break;
540 
541  case PIN_RIGHT:
542  txtpos.x -= offset;
543  hjustify = GR_TEXT_HJUSTIFY_RIGHT;
544  break;
545  }
546 
547  GRText( DC, txtpos, color, typeName, orient, wxSize( textSize, textSize ), hjustify,
548  GR_TEXT_VJUSTIFY_CENTER, pensize, false, false, nullptr );
549 }
550 
551 
552 void LIB_PIN::PlotSymbol( PLOTTER* aPlotter, const wxPoint& aPosition, int aOrientation ) const
553 {
554  int MapX1, MapY1, x1, y1;
556  int penWidth = GetEffectivePenWidth( aPlotter->RenderSettings() );
557 
558  aPlotter->SetColor( color );
559  aPlotter->SetCurrentLineWidth( penWidth );
560 
561  MapX1 = MapY1 = 0;
562  x1 = aPosition.x; y1 = aPosition.y;
563 
564  switch( aOrientation )
565  {
566  case PIN_UP: y1 = aPosition.y - m_length; MapY1 = 1; break;
567  case PIN_DOWN: y1 = aPosition.y + m_length; MapY1 = -1; break;
568  case PIN_LEFT: x1 = aPosition.x - m_length; MapX1 = 1; break;
569  case PIN_RIGHT: x1 = aPosition.x + m_length; MapX1 = -1; break;
570  }
571 
573  {
574  const int radius = externalPinDecoSize( aPlotter->RenderSettings(), *this );
575  aPlotter->Circle( wxPoint( MapX1 * radius + x1, MapY1 * radius + y1 ), radius * 2,
576  FILL_T::NO_FILL, penWidth );
577 
578  aPlotter->MoveTo( wxPoint( MapX1 * radius * 2 + x1, MapY1 * radius * 2 + y1 ) );
579  aPlotter->FinishTo( aPosition );
580  }
582  {
583  const int deco_size = internalPinDecoSize( aPlotter->RenderSettings(), *this );
584  if( MapY1 == 0 ) /* MapX1 = +- 1 */
585  {
586  aPlotter->MoveTo( wxPoint( x1, y1 + deco_size ) );
587  aPlotter->LineTo( wxPoint( x1 + MapX1 * deco_size * 2, y1 ) );
588  aPlotter->FinishTo( wxPoint( x1, y1 - deco_size ) );
589  }
590  else /* MapX1 = 0 */
591  {
592  aPlotter->MoveTo( wxPoint( x1 + deco_size, y1 ) );
593  aPlotter->LineTo( wxPoint( x1, y1 + MapY1 * deco_size * 2 ) );
594  aPlotter->FinishTo( wxPoint( x1 - deco_size, y1 ) );
595  }
596 
597  aPlotter->MoveTo( wxPoint( MapX1 * deco_size * 2 + x1, MapY1 * deco_size * 2 + y1 ) );
598  aPlotter->FinishTo( aPosition );
599  }
600  else
601  {
602  aPlotter->MoveTo( wxPoint( x1, y1 ) );
603  aPlotter->FinishTo( aPosition );
604  }
605 
609  {
610  const int deco_size = internalPinDecoSize( aPlotter->RenderSettings(), *this );
611  if( MapY1 == 0 ) /* MapX1 = +- 1 */
612  {
613  aPlotter->MoveTo( wxPoint( x1, y1 + deco_size ) );
614  aPlotter->LineTo( wxPoint( x1 - MapX1 * deco_size * 2, y1 ) );
615  aPlotter->FinishTo( wxPoint( x1, y1 - deco_size ) );
616  }
617  else /* MapX1 = 0 */
618  {
619  aPlotter->MoveTo( wxPoint( x1 + deco_size, y1 ) );
620  aPlotter->LineTo( wxPoint( x1, y1 - MapY1 * deco_size * 2 ) );
621  aPlotter->FinishTo( wxPoint( x1 - deco_size, y1 ) );
622  }
623  }
624 
626  || m_shape == GRAPHIC_PINSHAPE::CLOCK_LOW ) /* IEEE symbol "Active Low Input" */
627  {
628  const int deco_size = externalPinDecoSize( aPlotter->RenderSettings(), *this );
629 
630  if( MapY1 == 0 ) /* MapX1 = +- 1 */
631  {
632  aPlotter->MoveTo( wxPoint( x1 + MapX1 * deco_size * 2, y1 ) );
633  aPlotter->LineTo( wxPoint( x1 + MapX1 * deco_size * 2, y1 - deco_size * 2 ) );
634  aPlotter->FinishTo( wxPoint( x1, y1 ) );
635  }
636  else /* MapX1 = 0 */
637  {
638  aPlotter->MoveTo( wxPoint( x1, y1 + MapY1 * deco_size * 2 ) );
639  aPlotter->LineTo( wxPoint( x1 - deco_size * 2, y1 + MapY1 * deco_size * 2 ) );
640  aPlotter->FinishTo( wxPoint( x1, y1 ) );
641  }
642  }
643 
644  if( m_shape == GRAPHIC_PINSHAPE::OUTPUT_LOW ) /* IEEE symbol "Active Low Output" */
645  {
646  const int symbol_size = externalPinDecoSize( aPlotter->RenderSettings(), *this );
647 
648  if( MapY1 == 0 ) /* MapX1 = +- 1 */
649  {
650  aPlotter->MoveTo( wxPoint( x1, y1 - symbol_size * 2 ) );
651  aPlotter->FinishTo( wxPoint( x1 + MapX1 * symbol_size * 2, y1 ) );
652  }
653  else /* MapX1 = 0 */
654  {
655  aPlotter->MoveTo( wxPoint( x1 - symbol_size * 2, y1 ) );
656  aPlotter->FinishTo( wxPoint( x1, y1 + MapY1 * symbol_size * 2 ) );
657  }
658  }
659  else if( m_shape == GRAPHIC_PINSHAPE::NONLOGIC ) /* NonLogic pin symbol */
660  {
661  const int deco_size = externalPinDecoSize( aPlotter->RenderSettings(), *this );
662  aPlotter->MoveTo( wxPoint( x1 - (MapX1 + MapY1) * deco_size, y1 - (MapY1 - MapX1) * deco_size ) );
663  aPlotter->FinishTo( wxPoint( x1 + (MapX1 + MapY1) * deco_size, y1 + (MapY1 - MapX1) * deco_size ) );
664  aPlotter->MoveTo( wxPoint( x1 - (MapX1 - MapY1) * deco_size, y1 - (MapY1 + MapX1) * deco_size ) );
665  aPlotter->FinishTo( wxPoint( x1 + (MapX1 - MapY1) * deco_size, y1 + (MapY1 + MapX1) * deco_size ) );
666  }
667 
668  if( m_type == ELECTRICAL_PINTYPE::PT_NC ) // Draw a N.C. symbol
669  {
670  const int deco_size = TARGET_PIN_RADIUS;
671  const int ex1 = aPosition.x;
672  const int ey1 = aPosition.y;
673  aPlotter->MoveTo( wxPoint( ex1 - deco_size, ey1 - deco_size ) );
674  aPlotter->FinishTo( wxPoint( ex1 + deco_size, ey1 + deco_size ) );
675  aPlotter->MoveTo( wxPoint( ex1 + deco_size, ey1 - deco_size ) );
676  aPlotter->FinishTo( wxPoint( ex1 - deco_size, ey1 + deco_size ) );
677  }
678 }
679 
680 
681 void LIB_PIN::PlotPinTexts( PLOTTER* aPlotter, const wxPoint& aPinPos, int aPinOrient, int aTextInside,
682  bool aDrawPinNum, bool aDrawPinName ) const
683 {
684  wxString name = GetShownName();
685  wxString number = GetShownNumber();
686 
687  if( name.IsEmpty() )
688  aDrawPinName = false;
689 
690  if( number.IsEmpty() )
691  aDrawPinNum = false;
692 
693  if( !aDrawPinNum && !aDrawPinName )
694  return;
695 
696  int x, y;
697  wxSize pinNameSize = wxSize( m_nameTextSize, m_nameTextSize );
698  wxSize pinNumSize = wxSize( m_numTextSize, m_numTextSize );
699 
700  int namePenWidth = std::max( Clamp_Text_PenSize( GetPenWidth(), m_nameTextSize, false ),
701  aPlotter->RenderSettings()->GetDefaultPenWidth() );
702  int numPenWidth = std::max( Clamp_Text_PenSize( GetPenWidth(), m_numTextSize, false ),
703  aPlotter->RenderSettings()->GetDefaultPenWidth() );
704 
705  int name_offset = Mils2iu( PIN_TEXT_MARGIN ) + namePenWidth;
706  int num_offset = Mils2iu( PIN_TEXT_MARGIN ) + numPenWidth;
707 
708  /* Get the num and name colors */
709  COLOR4D nameColor = aPlotter->RenderSettings()->GetLayerColor( LAYER_PINNAM );
710  COLOR4D numColor = aPlotter->RenderSettings()->GetLayerColor( LAYER_PINNUM );
711 
712  int x1 = aPinPos.x;
713  int y1 = aPinPos.y;
714 
715  switch( aPinOrient )
716  {
717  case PIN_UP: y1 -= m_length; break;
718  case PIN_DOWN: y1 += m_length; break;
719  case PIN_LEFT: x1 -= m_length; break;
720  case PIN_RIGHT: x1 += m_length; break;
721  }
722 
723  /* Draw the text inside, but the pin numbers outside. */
724  if( aTextInside )
725  {
726  if( ( aPinOrient == PIN_LEFT) || ( aPinOrient == PIN_RIGHT) ) /* Its an horizontal line. */
727  {
728  if( aDrawPinName )
729  {
730  EDA_TEXT_HJUSTIFY_T hjustify;
731  if( aPinOrient == PIN_RIGHT )
732  {
733  x = x1 + aTextInside;
734  hjustify = GR_TEXT_HJUSTIFY_LEFT;
735  }
736  else // orient == PIN_LEFT
737  {
738  x = x1 - aTextInside;
739  hjustify = GR_TEXT_HJUSTIFY_RIGHT;
740  }
741 
742  aPlotter->Text( wxPoint( x, y1 ), nameColor, name, TEXT_ANGLE_HORIZ, pinNameSize,
743  hjustify, GR_TEXT_VJUSTIFY_CENTER, namePenWidth,
744  false, false );
745  }
746  if( aDrawPinNum )
747  {
748  aPlotter->Text( wxPoint( ( x1 + aPinPos.x) / 2, y1 - num_offset ), numColor,
749  number, TEXT_ANGLE_HORIZ, pinNumSize, GR_TEXT_HJUSTIFY_CENTER,
750  GR_TEXT_VJUSTIFY_BOTTOM, numPenWidth, false, false );
751  }
752  }
753  else /* Its a vertical line. */
754  {
755  if( aPinOrient == PIN_DOWN )
756  {
757  y = y1 + aTextInside;
758 
759  if( aDrawPinName )
760  aPlotter->Text( wxPoint( x1, y ), nameColor, name, TEXT_ANGLE_VERT,
762  namePenWidth, false, false );
763 
764  if( aDrawPinNum )
765  {
766  aPlotter->Text( wxPoint( x1 - num_offset, ( y1 + aPinPos.y) / 2 ), numColor,
767  number, TEXT_ANGLE_VERT, pinNumSize, GR_TEXT_HJUSTIFY_CENTER,
768  GR_TEXT_VJUSTIFY_BOTTOM, numPenWidth, false, false );
769  }
770  }
771  else /* PIN_UP */
772  {
773  y = y1 - aTextInside;
774 
775  if( aDrawPinName )
776  {
777  aPlotter->Text( wxPoint( x1, y ), nameColor, name, TEXT_ANGLE_VERT,
779  namePenWidth, false, false );
780  }
781 
782  if( aDrawPinNum )
783  {
784  aPlotter->Text( wxPoint( x1 - num_offset, ( y1 + aPinPos.y) / 2 ), numColor,
785  number, TEXT_ANGLE_VERT, pinNumSize, GR_TEXT_HJUSTIFY_CENTER,
786  GR_TEXT_VJUSTIFY_BOTTOM, numPenWidth, false, false );
787  }
788  }
789  }
790  }
791  else /* Draw num & text pin outside */
792  {
793  if(( aPinOrient == PIN_LEFT) || ( aPinOrient == PIN_RIGHT) )
794  {
795  /* Its an horizontal line. */
796  if( aDrawPinName )
797  {
798  x = ( x1 + aPinPos.x) / 2;
799  aPlotter->Text( wxPoint( x, y1 - name_offset ), nameColor, name,
801  GR_TEXT_VJUSTIFY_BOTTOM, namePenWidth, false, false );
802  }
803 
804  if( aDrawPinNum )
805  {
806  x = ( x1 + aPinPos.x ) / 2;
807  aPlotter->Text( wxPoint( x, y1 + num_offset ), numColor, number,
809  GR_TEXT_VJUSTIFY_TOP, numPenWidth, false, false );
810  }
811  }
812  else /* Its a vertical line. */
813  {
814  if( aDrawPinName )
815  {
816  y = ( y1 + aPinPos.y ) / 2;
817  aPlotter->Text( wxPoint( x1 - name_offset, y ), nameColor, name,
819  GR_TEXT_VJUSTIFY_BOTTOM, namePenWidth, false, false );
820  }
821 
822  if( aDrawPinNum )
823  {
824  aPlotter->Text( wxPoint( x1 + num_offset, ( y1 + aPinPos.y ) / 2 ), numColor,
825  number, TEXT_ANGLE_VERT, pinNumSize, GR_TEXT_HJUSTIFY_CENTER,
826  GR_TEXT_VJUSTIFY_TOP, numPenWidth, false, false );
827  }
828  }
829  }
830 }
831 
832 
833 int LIB_PIN::PinDrawOrient( const TRANSFORM& aTransform ) const
834 {
835  int orient;
836  wxPoint end; // position of pin end starting at 0,0 according to its orientation, length = 1
837 
838  switch( m_orientation )
839  {
840  case PIN_UP: end.y = 1; break;
841  case PIN_DOWN: end.y = -1; break;
842  case PIN_LEFT: end.x = -1; break;
843  case PIN_RIGHT: end.x = 1; break;
844  }
845 
846  // = pos of end point, according to the symbol orientation.
847  end = aTransform.TransformCoordinate( end );
848  orient = PIN_UP;
849 
850  if( end.x == 0 )
851  {
852  if( end.y > 0 )
853  orient = PIN_DOWN;
854  }
855  else
856  {
857  orient = PIN_RIGHT;
858 
859  if( end.x < 0 )
860  orient = PIN_LEFT;
861  }
862 
863  return orient;
864 }
865 
866 
868 {
869  return new LIB_PIN( *this );
870 }
871 
872 
873 int LIB_PIN::compare( const LIB_ITEM& aOther, int aCompareFlags ) const
874 {
875  wxASSERT( aOther.Type() == LIB_PIN_T );
876 
877  int retv = LIB_ITEM::compare( aOther, aCompareFlags );
878 
879  if( retv )
880  return retv;
881 
882  const LIB_PIN* tmp = (LIB_PIN*) &aOther;
883 
884  // When comparing units, we do not compare the part numbers. If everything else is
885  // identical, then we can just renumber the parts for the inherited symbol.
886  if( !( aCompareFlags & COMPARE_FLAGS::UNIT ) && m_number != tmp->m_number )
887  return m_number.Cmp( tmp->m_number );
888 
889  int result = m_name.CmpNoCase( tmp->m_name );
890 
891  if( result )
892  return result;
893 
894  if( m_position.x != tmp->m_position.x )
895  return m_position.x - tmp->m_position.x;
896 
897  if( m_position.y != tmp->m_position.y )
898  return m_position.y - tmp->m_position.y;
899 
900  if( m_length != tmp->m_length )
901  return m_length - tmp->m_length;
902 
903  if( m_orientation != tmp->m_orientation )
904  return m_orientation - tmp->m_orientation;
905 
906  if( m_shape != tmp->m_shape )
907  return static_cast<int>( m_shape ) - static_cast<int>( tmp->m_shape );
908 
909  if( m_type != tmp->m_type )
910  return static_cast<int>( m_type ) - static_cast<int>( tmp->m_type );
911 
912  if( m_attributes != tmp->m_attributes )
913  return m_attributes - tmp->m_attributes;
914 
915  if( m_numTextSize != tmp->m_numTextSize )
916  return m_numTextSize - tmp->m_numTextSize;
917 
918  if( m_nameTextSize != tmp->m_nameTextSize )
919  return m_nameTextSize - tmp->m_nameTextSize;
920 
921  if( m_alternates.size() != tmp->m_alternates.size() )
922  return m_alternates.size() - tmp->m_alternates.size();
923 
924  auto lhsItem = m_alternates.begin();
925  auto rhsItem = tmp->m_alternates.begin();
926 
927  while( lhsItem != m_alternates.end() )
928  {
929  const ALT& lhsAlt = lhsItem->second;
930  const ALT& rhsAlt = rhsItem->second;
931 
932  retv = lhsAlt.m_Name.Cmp( rhsAlt.m_Name );
933 
934  if( retv )
935  return retv;
936 
937  if( lhsAlt.m_Type != rhsAlt.m_Type )
938  return static_cast<int>( lhsAlt.m_Type ) - static_cast<int>( rhsAlt.m_Type );
939 
940  if( lhsAlt.m_Shape != rhsAlt.m_Shape )
941  return static_cast<int>( lhsAlt.m_Shape ) - static_cast<int>( rhsAlt.m_Shape );
942 
943  ++lhsItem;
944  ++rhsItem;
945  }
946 
947  return 0;
948 }
949 
950 
951 void LIB_PIN::Offset( const wxPoint& aOffset )
952 {
953  m_position += aOffset;
954 }
955 
956 
957 void LIB_PIN::MoveTo( const wxPoint& aNewPosition )
958 {
959  if( m_position != aNewPosition )
960  {
961  m_position = aNewPosition;
962  SetModified();
963  }
964 }
965 
966 
967 void LIB_PIN::MirrorHorizontal( const wxPoint& aCenter )
968 {
969  m_position.x -= aCenter.x;
970  m_position.x *= -1;
971  m_position.x += aCenter.x;
972 
973  if( m_orientation == PIN_RIGHT )
975  else if( m_orientation == PIN_LEFT )
977 }
978 
979 
980 void LIB_PIN::MirrorVertical( const wxPoint& aCenter )
981 {
982  m_position.y -= aCenter.y;
983  m_position.y *= -1;
984  m_position.y += aCenter.y;
985 
986  if( m_orientation == PIN_UP )
988  else if( m_orientation == PIN_DOWN )
990 }
991 
992 
993 void LIB_PIN::Rotate( const wxPoint& aCenter, bool aRotateCCW )
994 {
995  int rot_angle = aRotateCCW ? -900 : 900;
996 
997  RotatePoint( &m_position, aCenter, rot_angle );
998 
999  if( aRotateCCW )
1000  {
1001  switch( m_orientation )
1002  {
1003  case PIN_RIGHT: m_orientation = PIN_UP; break;
1004  case PIN_UP: m_orientation = PIN_LEFT; break;
1005  case PIN_LEFT: m_orientation = PIN_DOWN; break;
1006  case PIN_DOWN: m_orientation = PIN_RIGHT; break;
1007  }
1008  }
1009  else
1010  {
1011  switch( m_orientation )
1012  {
1013  case PIN_RIGHT: m_orientation = PIN_DOWN; break;
1014  case PIN_UP: m_orientation = PIN_RIGHT; break;
1015  case PIN_LEFT: m_orientation = PIN_UP; break;
1016  case PIN_DOWN: m_orientation = PIN_LEFT; break;
1017  }
1018  }
1019 }
1020 
1021 
1022 void LIB_PIN::Plot( PLOTTER* aPlotter, const wxPoint& aPffset, bool aFill,
1023  const TRANSFORM& aTransform ) const
1024 {
1025  if( !IsVisible() )
1026  return;
1027 
1028  int orient = PinDrawOrient( aTransform );
1029  wxPoint pos = aTransform.TransformCoordinate( m_position ) + aPffset;
1030 
1031  PlotSymbol( aPlotter, pos, orient );
1032  PlotPinTexts( aPlotter, pos, orient, GetParent()->GetPinNameOffset(),
1033  GetParent()->ShowPinNumbers(), GetParent()->ShowPinNames() );
1034 }
1035 
1036 
1037 void LIB_PIN::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1038 {
1039  EDA_UNITS units = aFrame->GetUserUnits();
1040 
1041  LIB_ITEM::GetMsgPanelInfo( aFrame, aList );
1042 
1043  aList.emplace_back( _( "Name" ), UnescapeString( GetShownName() ) );
1044  aList.emplace_back( _( "Number" ), GetShownNumber() );
1045  aList.emplace_back( _( "Type" ), ElectricalPinTypeGetText( m_type ) );
1046  aList.emplace_back( _( "Style" ), PinShapeGetText( m_shape ) );
1047 
1048  aList.emplace_back( _( "Style" ), IsVisible() ? _( "Yes" ) : _( "No" ) );
1049 
1050  // Display pin length
1051  aList.emplace_back( _( "Length" ), MessageTextFromValue( units, m_length, true ) );
1052 
1054  aList.emplace_back( _( "Orientation" ), PinOrientationName( (unsigned) i ) );
1055 
1056  wxPoint pinpos = GetPosition();
1057  pinpos.y = -pinpos.y; // Display coords are top to bottom; lib item coords are bottom to top
1058 
1059  aList.emplace_back( _( "Pos X" ), MessageTextFromValue( units, pinpos.x, true ) );
1060  aList.emplace_back( _( "Pos Y" ), MessageTextFromValue( units, pinpos.y, true ) );
1061 }
1062 
1063 
1064 void LIB_PIN::ViewGetLayers( int aLayers[], int& aCount ) const
1065 {
1066  aCount = 3;
1067  aLayers[0] = LAYER_DANGLING; // We don't really show dangling vs non-dangling (since there
1068  // are no connections in the symbol editor), but it's still
1069  // a good visual indication of which end of the pin is which.
1070  aLayers[1] = LAYER_DEVICE;
1071  aLayers[2] = LAYER_SELECTION_SHADOWS;
1072 }
1073 
1074 
1075 const EDA_RECT LIB_PIN::GetBoundingBox( bool aIncludeInvisibles, bool aPinOnly ) const
1076 {
1077  EDA_RECT bbox;
1078  wxPoint begin;
1079  wxPoint end;
1080  int nameTextOffset = 0;
1081  wxString name = GetShownName();
1082  wxString number = GetShownNumber();
1083  bool showName = !name.IsEmpty();
1084  bool showNum = !number.IsEmpty();
1085  int minsizeV = TARGET_PIN_RADIUS;
1086 
1087  if( !aIncludeInvisibles && !IsVisible() )
1088  showName = false;
1089 
1090  if( GetParent() )
1091  {
1092  if( GetParent()->ShowPinNames() )
1093  nameTextOffset = GetParent()->GetPinNameOffset();
1094  else
1095  showName = false;
1096 
1097  if( !GetParent()->ShowPinNumbers() )
1098  showNum = false;
1099  }
1100 
1101  if( aPinOnly )
1102  {
1103  showName = false;
1104  showNum = false;
1105  }
1106 
1107  // First, calculate boundary box corners position
1108  int numberTextLength = showNum ? m_numTextSize * number.Len() : 0;
1109 
1110  // Actual text height is bigger than text size
1111  int numberTextHeight = showNum ? KiROUND( m_numTextSize * 1.1 ) : 0;
1112 
1114  minsizeV = std::max( TARGET_PIN_RADIUS, externalPinDecoSize( nullptr, *this ) );
1115 
1116  // calculate top left corner position
1117  // for the default pin orientation (PIN_RIGHT)
1118  begin.y = std::max( minsizeV, numberTextHeight + Mils2iu( PIN_TEXT_MARGIN ) );
1119  begin.x = std::min( 0, m_length - (numberTextLength / 2) );
1120 
1121  // calculate bottom right corner position and adjust top left corner position
1122  int nameTextLength = 0;
1123  int nameTextHeight = 0;
1124 
1125  if( showName )
1126  {
1127  int length = name.Len();
1128 
1129  // TODO: exclude markup characters!
1130  nameTextLength = ( m_nameTextSize * length ) + nameTextOffset;
1131 
1132  // Actual text height are bigger than text size
1133  nameTextHeight = KiROUND( m_nameTextSize * 1.1 ) + Mils2iu( PIN_TEXT_MARGIN );
1134  }
1135 
1136  if( nameTextOffset ) // for values > 0, pin name is inside the body
1137  {
1138  end.x = m_length + nameTextLength;
1139  end.y = std::min( -minsizeV, -nameTextHeight / 2 );
1140  }
1141  else // if value == 0:
1142  // pin name is outside the body, and above the pin line
1143  // pin num is below the pin line
1144  {
1145  end.x = std::max( m_length, nameTextLength );
1146  end.y = -begin.y;
1147  begin.y = std::max( minsizeV, nameTextHeight );
1148  }
1149 
1150  // Now, calculate boundary box corners position for the actual pin orientation
1151  int orient = PinDrawOrient( DefaultTransform );
1152 
1153  /* Calculate the pin position */
1154  switch( orient )
1155  {
1156  case PIN_UP:
1157  // Pin is rotated and texts positions are mirrored
1158  RotatePoint( &begin, wxPoint( 0, 0 ), -900 );
1159  RotatePoint( &end, wxPoint( 0, 0 ), -900 );
1160  break;
1161 
1162  case PIN_DOWN:
1163  RotatePoint( &begin, wxPoint( 0, 0 ), 900 );
1164  RotatePoint( &end, wxPoint( 0, 0 ), 900 );
1165  begin.x = -begin.x;
1166  end.x = -end.x;
1167  break;
1168 
1169  case PIN_LEFT:
1170  begin.x = -begin.x;
1171  end.x = -end.x;
1172  break;
1173 
1174  case PIN_RIGHT:
1175  break;
1176  }
1177 
1178  begin += m_position;
1179  end += m_position;
1180 
1181  bbox.SetOrigin( begin );
1182  bbox.SetEnd( end );
1183  bbox.Normalize();
1184  bbox.Inflate( ( GetPenWidth() / 2 ) + 1 );
1185 
1186  // Draw Y axis is reversed in schematic:
1187  bbox.RevertYAxis();
1188 
1189  return bbox;
1190 }
1191 
1192 
1194 {
1196 }
1197 
1198 
1199 wxString LIB_PIN::GetSelectMenuText( EDA_UNITS aUnits ) const
1200 {
1201  if( !m_name.IsEmpty() )
1202  {
1203  return wxString::Format( _( "Pin %s [%s, %s, %s]" ),
1204  GetShownNumber(),
1207  PinShapeGetText( m_shape ) );
1208  }
1209  else
1210  {
1211  return wxString::Format( _( "Pin %s [%s, %s]" ),
1212  GetShownNumber(),
1214  PinShapeGetText( m_shape ) );
1215  }
1216 }
1217 
1218 
1219 #if defined(DEBUG)
1220 
1221 void LIB_PIN::Show( int nestLevel, std::ostream& os ) const
1222 {
1223  NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
1224  << " num=\"" << m_number.mb_str()
1225  << '"' << "/>\n";
1226 
1227 // NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
1228 }
1229 
1230 #endif
1231 
1232 void LIB_PIN::CalcEdit( const wxPoint& aPosition )
1233 {
1234  if( IsMoving() )
1235  MoveTo( aPosition );
1236 }
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:873
void FinishTo(const wxPoint &pos)
Definition: plotter.h:273
wxString GetClass() const override
Return the class name.
Definition: lib_pin.h:65
virtual SETTINGS_MANAGER & GetSettingsManager() const
Definition: pgm_base.h:129
#define TEXT_ANGLE_HORIZ
Frequent text rotations, used with {Set,Get}TextAngle(), in 0.1 degrees for now, hoping to migrate to...
Definition: eda_text.h:71
wxString GetSelectMenuText(EDA_UNITS aUnits) const override
Return the text to display to be used in the selection clarification context menu when multiple items...
Definition: lib_pin.cpp:1199
void SetModified()
Definition: eda_item.cpp:65
int GetPinNameOffset() const
Definition: lib_symbol.h:572
wxString MessageTextFromValue(EDA_UNITS aUnits, int aValue, bool aAddUnitLabel, EDA_DATA_TYPE aType)
Convert a value to a string using double notation.
Definition: base_units.cpp:104
int m_nameTextSize
Definition: lib_pin.h:288
wxString GetShownNumber() const
Definition: lib_pin.h:117
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
Definition: lib_pin.cpp:867
void Rotate(const wxPoint &aCenter, bool aRotateCCW=true) override
Rotate the object about aCenter point.
Definition: lib_pin.cpp:993
EDA_TEXT_HJUSTIFY_T
Definition: eda_text.h:82
void Plot(PLOTTER *aPlotter, const wxPoint &aPffset, bool aFill, const TRANSFORM &aTransform) const override
Plot the draw item using the plot object.
Definition: lib_pin.cpp:1022
void PlotPinTexts(PLOTTER *aPlotter, const wxPoint &aPinPos, int aPinOrient, int aTextInside, bool aDrawPinNum, bool aDrawPinName) const
Plot the pin number and pin text info, given the pin line coordinates.
Definition: lib_pin.cpp:681
GRAPHIC_PINSHAPE m_shape
Definition: lib_pin.h:282
#define ETXT_MAX_SIZE
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
void MoveTo(const wxPoint &aNewPosition) override
Move a draw object to aPosition.
Definition: lib_pin.cpp:957
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:1064
int m_numTextSize
Definition: lib_pin.h:287
Container for data for KiCad programs.
Definition: pgm_base.h:93
void printPinTexts(const RENDER_SETTINGS *aSettings, wxPoint &aPinPos, int aPinOrient, int aTextInside, bool aDrawPinNum, bool aDrawPinName)
Put the pin number and pin text info, given the pin line coordinates.
Definition: lib_pin.cpp:343
wxString ElectricalPinTypeGetText(ELECTRICAL_PINTYPE aType)
Definition: pin_type.cpp:240
LIB_PIN(LIB_SYMBOL *aParent)
Definition: lib_pin.cpp:94
bool IsMoving() const
Definition: eda_item.h:119
int color
Definition: DXF_plotter.cpp:57
void PlotSymbol(PLOTTER *aPlotter, const wxPoint &aPosition, int aOrientation) const
Definition: lib_pin.cpp:552
BITMAPS ElectricalPinTypeGetBitmap(ELECTRICAL_PINTYPE aType)
Definition: pin_type.cpp:268
bool ShowPinNumbers() const
Definition: lib_symbol.h:588
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
unknown electrical properties: creates always a warning when connected
void SetOrigin(const wxPoint &pos)
Definition: eda_rect.h:130
int PinOrientationIndex(int code)
Definition: pin_type.cpp:150
wxString m_name
Definition: lib_pin.h:285
virtual int GetEffectivePenWidth(const RENDER_SETTINGS *aSettings) const
Definition: lib_item.h:153
bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
Definition: lib_pin.cpp:141
void GRText(wxDC *aDC, const wxPoint &aPos, const COLOR4D &aColor, const wxString &aText, double aOrient, const wxSize &aSize, enum EDA_TEXT_HJUSTIFY_T aH_justify, enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, bool aBold, void(*aCallback)(int x0, int y0, int xf, int yf, void *aData), void *aCallbackData, PLOTTER *aPlotter)
Draw a graphic text (like footprint texts).
Definition: gr_text.cpp:129
#define DEFAULT_PIN_LENGTH
The default pin number size when creating pins(can be changed in preference menu)
wxString PinShapeGetText(GRAPHIC_PINSHAPE aShape)
Definition: pin_type.cpp:279
Definition: lib_pin.h:48
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:480
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
const EDA_RECT GetBoundingBox() const override
Definition: lib_pin.h:176
GRAPHIC_PINSHAPE
Definition: pin_type.h:55
The base class for create windows for drawing purpose.
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:833
int m_length
Definition: lib_pin.h:280
Define a library symbol object.
Definition: lib_symbol.h:96
void RevertYAxis()
Mirror the rectangle from the X axis (negate Y pos and size).
Definition: eda_rect.h:207
ELECTRICAL_PINTYPE m_Type
Definition: lib_pin.h:60
bool Contains(const wxPoint &aPoint) const
Definition: eda_rect.cpp:57
wxPoint TransformCoordinate(const wxPoint &aPoint) const
Calculate a new coordinate according to the mirror/rotation transform.
Definition: transform.cpp:42
The base class for drawable items used by schematic library symbols.
Definition: lib_item.h:61
void MirrorVertical(const wxPoint &aCenter) override
Mirror the draw object along the MirrorVertical (Y) axis about aCenter point.
Definition: lib_pin.cpp:980
void SetNumber(const wxString &aNumber)
Definition: lib_pin.h:118
wxPoint GetPinRoot() const
Definition: lib_pin.cpp:181
wxString PinOrientationName(unsigned aPinOrientationCode)
Definition: pin_type.cpp:119
not internally connected (may be connected to anything)
void LineTo(const wxPoint &pos)
Definition: plotter.h:268
int m_orientation
Definition: lib_pin.h:281
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:67
void printPinSymbol(const RENDER_SETTINGS *aSettings, const wxPoint &aPos, int aOrientation)
Print the pin symbol without text.
Definition: lib_pin.cpp:232
for transforming drawing coordinates for a wxDC device context.
Definition: transform.h:45
int Clamp_Text_PenSize(int aPenSize, int aSize, bool aBold)
Don't allow text to become cluttered up in its own fatness.
Definition: gr_text.cpp:67
wxString m_number
Definition: lib_pin.h:286
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
wxString const GetElectricalTypeName() const
Definition: lib_pin.h:92
void SetEnd(int x, int y)
Definition: eda_rect.h:191
void GRCircle(EDA_RECT *ClipBox, wxDC *DC, int xc, int yc, int r, int width, const COLOR4D &Color)
Draw a circle onto the drawing context aDC centered at the user coordinates (x,y).
Definition: gr_basic.cpp:507
T * GetAppSettings(bool aLoadNow=true)
Returns a handle to the a given settings by type If the settings have already been loaded,...
wxString m_Name
Definition: lib_pin.h:58
bool ShowPinNames() const
Definition: lib_symbol.h:580
#define STRUCT_DELETED
flag indication structures to be erased
#define _(s)
int GetPenWidth() const override
Definition: lib_pin.cpp:166
void GRLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, const COLOR4D &Color, wxPenStyle aStyle)
Definition: gr_basic.cpp:197
wxDC * GetPrintDC() const
bool IsVisible() const
Definition: lib_pin.h:97
#define DEFAULT_PINNUM_SIZE
The default pin name size when creating pins(can be changed in preference menu)
int GetNameTextSize() const
Definition: lib_pin.h:126
wxString GetShownName() const
Definition: lib_pin.cpp:172
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
Definition: lib_pin.cpp:1193
#define DEFAULT_PINNAME_SIZE
The default selection highlight thickness (can be changed in preference menu)
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:1037
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:43
wxString UnescapeString(const wxString &aSource)
void CalcEdit(const wxPoint &aPosition) override
Calculate the attributes of an item at aPosition when it is being edited.
Definition: lib_pin.cpp:1232
void GRLineTo(EDA_RECT *ClipBox, wxDC *DC, int x, int y, int width, const COLOR4D &Color)
Definition: gr_basic.cpp:221
virtual void SetColor(const COLOR4D &color)=0
void SetConvert(int aConvert)
Definition: lib_item.h:268
wxPoint GetPosition() const override
Definition: lib_pin.h:212
void MoveTo(const wxPoint &pos)
Definition: plotter.h:263
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
int m_attributes
Definition: lib_pin.h:284
EDA_UNITS
Definition: eda_units.h:38
void GRMoveTo(int x, int y)
Definition: gr_basic.cpp:214
void Normalize()
Ensures that the height ant width are positive.
Definition: eda_rect.cpp:35
LIB_SYMBOL * GetParent() const
Definition: lib_item.h:164
void SetUnit(int aUnit)
Definition: lib_item.h:265
Base plotter engine class.
Definition: plotter.h:121
std::map< wxString, ALT > m_alternates
Definition: lib_pin.h:290
wxPoint m_position
Definition: lib_pin.h:279
RENDER_SETTINGS * RenderSettings()
Definition: plotter.h:156
int GetNumberTextSize() const
Definition: lib_pin.h:129
see class PGM_BASE
TRANSFORM DefaultTransform
Definition: eeschema.cpp:56
void SetName(const wxString &aName)
Definition: lib_pin.h:108
#define SKIP_STRUCT
flag indicating that the structure should be ignored
const char * name
Definition: DXF_plotter.cpp:56
BITMAPS
A list of all bitmap identifiers.
Definition: bitmaps_list.h:32
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
Definition: pin_type.h:35
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:70
void printPinElectricalTypeName(const RENDER_SETTINGS *aSettings, wxPoint &aPosition, int aOrientation)
Draw the electrical type text of the pin (only for the footprint editor)
Definition: lib_pin.cpp:499
#define PIN_TEXT_MARGIN
Definition: lib_pin.cpp:38
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:83
Handle the component boundary box.
Definition: eda_rect.h:42
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
#define TARGET_PIN_RADIUS
Definition: lib_pin.h:36
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:99
ELECTRICAL_PINTYPE m_type
Definition: lib_pin.h:283
bool Intersects(const EDA_RECT &aRect) const
Test for a common area between rectangles.
Definition: eda_rect.cpp:150
Store schematic specific render settings.
Definition: sch_painter.h:66
int GetDefaultPenWidth() const
virtual void Text(const wxPoint &aPos, const COLOR4D &aColor, const wxString &aText, double aOrient, const wxSize &aSize, enum EDA_TEXT_HJUSTIFY_T aH_justify, enum EDA_TEXT_VJUSTIFY_T aV_justify, int aWidth, bool aItalic, bool aBold, bool aMultilineAllowed=false, void *aData=nullptr)
Draw text with the plotter.
Definition: gr_text.cpp:219
#define TEXT_ANGLE_VERT
Definition: eda_text.h:72
wxString const GetCanonicalElectricalTypeName() const
Definition: lib_pin.h:87
not connected (must be left open)
void Offset(const wxPoint &aOffset) override
Set the drawing object by aOffset from the current position.
Definition: lib_pin.cpp:951
static constexpr int Millimeter2iu(double mm)
virtual void SetCurrentLineWidth(int width, void *aData=nullptr)=0
Set the line width for the next drawing.
GRAPHIC_PINSHAPE m_Shape
Definition: lib_pin.h:59
virtual void Circle(const wxPoint &pos, int diametre, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH)=0
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Inflate the rectangle horizontally by dx and vertically by dy.
Definition: eda_rect.cpp:364
void print(const RENDER_SETTINGS *aSettings, const wxPoint &aOffset, void *aData, const TRANSFORM &aTransform) override
Print a pin, with or without the pin texts.
Definition: lib_pin.cpp:194
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:112
void MirrorHorizontal(const wxPoint &aCenter) override
Mirror the draw object along the horizontal (X) axis about aCenter point.
Definition: lib_pin.cpp:967
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:103