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 == "~" )
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 )
221  {
222  wxDC* DC = aSettings->GetPrintDC();
224  GRCircle( nullptr, DC, pos1.x, pos1.y, TARGET_PIN_RADIUS, 0, color );
225  }
226  }
227 }
228 
229 
230 void LIB_PIN::printPinSymbol( const RENDER_SETTINGS* aSettings, const wxPoint& aPos, int aOrient )
231 {
232  wxDC* DC = aSettings->GetPrintDC();
233  int MapX1, MapY1, x1, y1;
234  int width = GetEffectivePenWidth( aSettings );
235  int posX = aPos.x, posY = aPos.y, len = m_length;
237 
238  MapX1 = MapY1 = 0;
239  x1 = posX;
240  y1 = posY;
241 
242  switch( aOrient )
243  {
244  case PIN_UP: y1 = posY - len; MapY1 = 1; break;
245  case PIN_DOWN: y1 = posY + len; MapY1 = -1; break;
246  case PIN_LEFT: x1 = posX - len; MapX1 = 1; break;
247  case PIN_RIGHT: x1 = posX + len; MapX1 = -1; break;
248  }
249 
251  {
252  const int radius = externalPinDecoSize( aSettings, *this );
253  GRCircle( nullptr, DC, MapX1 * radius + x1, MapY1 * radius + y1, radius, width, color );
254 
255  GRMoveTo( MapX1 * radius * 2 + x1, MapY1 * radius * 2 + y1 );
256  GRLineTo( nullptr, DC, posX, posY, width, color );
257  }
258  else
259  {
260  GRMoveTo( x1, y1 );
261  GRLineTo( nullptr, DC, posX, posY, width, color );
262  }
263 
264  // Draw the clock shape (>)inside the symbol
269  {
270  const int clock_size = internalPinDecoSize( aSettings, *this );
271  if( MapY1 == 0 ) /* MapX1 = +- 1 */
272  {
273  GRMoveTo( x1, y1 + clock_size );
274  GRLineTo( nullptr, DC, x1 - MapX1 * clock_size * 2, y1, width, color );
275  GRLineTo( nullptr, DC, x1, y1 - clock_size, width, color );
276  }
277  else /* MapX1 = 0 */
278  {
279  GRMoveTo( x1 + clock_size, y1 );
280  GRLineTo( nullptr, DC, x1, y1 - MapY1 * clock_size * 2, width, color );
281  GRLineTo( nullptr, DC, x1 - clock_size, y1, width, color );
282  }
283  }
284 
285  // Draw the active low (or H to L active transition)
289  {
290  const int deco_size = externalPinDecoSize( aSettings, *this );
291  if( MapY1 == 0 ) /* MapX1 = +- 1 */
292  {
293  GRMoveTo( x1 + MapX1 * deco_size * 2, y1 );
294  GRLineTo( nullptr, DC, x1 + MapX1 * deco_size * 2, y1 - deco_size * 2, width, color );
295  GRLineTo( nullptr, DC, x1, y1, width, color );
296  }
297  else /* MapX1 = 0 */
298  {
299  GRMoveTo( x1, y1 + MapY1 * deco_size * 2 );
300  GRLineTo( nullptr, DC, x1 - deco_size * 2, y1 + MapY1 * deco_size * 2, width, color );
301  GRLineTo( nullptr, DC, x1, y1, width, color );
302  }
303  }
304 
305  if( m_shape == GRAPHIC_PINSHAPE::OUTPUT_LOW ) /* IEEE symbol "Active Low Output" */
306  {
307  const int deco_size = externalPinDecoSize( aSettings, *this );
308  if( MapY1 == 0 ) /* MapX1 = +- 1 */
309  {
310  GRMoveTo( x1, y1 - deco_size * 2 );
311  GRLineTo( nullptr, DC, x1 + MapX1 * deco_size * 2, y1, width, color );
312  }
313  else /* MapX1 = 0 */
314  {
315  GRMoveTo( x1 - deco_size * 2, y1 );
316  GRLineTo( nullptr, DC, x1, y1 + MapY1 * deco_size * 2, width, color );
317  }
318  }
319  else if( m_shape == GRAPHIC_PINSHAPE::NONLOGIC ) /* NonLogic pin symbol */
320  {
321  const int deco_size = externalPinDecoSize( aSettings, *this );
322  GRMoveTo( x1 - (MapX1 + MapY1) * deco_size, y1 - (MapY1 - MapX1) * deco_size );
323  GRLineTo( nullptr, DC, x1 + (MapX1 + MapY1) * deco_size,
324  y1 + ( MapY1 - MapX1 ) * deco_size, width, color );
325  GRMoveTo( x1 - (MapX1 - MapY1) * deco_size, y1 - (MapY1 + MapX1) * deco_size );
326  GRLineTo( nullptr, DC, x1 + (MapX1 - MapY1) * deco_size,
327  y1 + ( MapY1 + MapX1 ) * deco_size, width, color );
328  }
329 
330  if( m_type == ELECTRICAL_PINTYPE::PT_NC ) // Draw a N.C. symbol
331  {
332  const int deco_size = TARGET_PIN_RADIUS;
333  GRLine( nullptr, DC, posX - deco_size, posY - deco_size, posX + deco_size,
334  posY + deco_size, width, color );
335  GRLine( nullptr, DC, posX + deco_size, posY - deco_size, posX - deco_size,
336  posY + deco_size, width, color );
337  }
338 }
339 
340 
341 void LIB_PIN::printPinTexts( const RENDER_SETTINGS* aSettings, wxPoint& aPinPos, int aPinOrient,
342  int aTextInside, bool aDrawPinNum, bool aDrawPinName )
343 {
344  if( !aDrawPinName && !aDrawPinNum )
345  return;
346 
347  int x, y;
348  wxDC* DC = aSettings->GetPrintDC();
349  wxSize PinNameSize( m_nameTextSize, m_nameTextSize );
350  wxSize PinNumSize( m_numTextSize, m_numTextSize );
351 
352  int namePenWidth = std::max( Clamp_Text_PenSize( GetPenWidth(), m_nameTextSize, false ),
353  aSettings->GetDefaultPenWidth() );
354  int numPenWidth = std::max( Clamp_Text_PenSize( GetPenWidth(), m_numTextSize, false ),
355  aSettings->GetDefaultPenWidth() );
356 
357  int name_offset = Mils2iu( PIN_TEXT_MARGIN ) + namePenWidth;
358  int num_offset = Mils2iu( PIN_TEXT_MARGIN ) + numPenWidth;
359 
360  /* Get the num and name colors */
361  COLOR4D NameColor = aSettings->GetLayerColor( IsVisible() ? LAYER_PINNAM : LAYER_HIDDEN );
362  COLOR4D NumColor = aSettings->GetLayerColor( IsVisible() ? LAYER_PINNUM : LAYER_HIDDEN );
363 
364  int x1 = aPinPos.x;
365  int y1 = aPinPos.y;
366 
367  switch( aPinOrient )
368  {
369  case PIN_UP: y1 -= m_length; break;
370  case PIN_DOWN: y1 += m_length; break;
371  case PIN_LEFT: x1 -= m_length; break;
372  case PIN_RIGHT: x1 += m_length; break;
373  }
374 
375  wxString name = GetShownName();
376  wxString number = GetShownNumber();
377 
378  if( name.IsEmpty() )
379  aDrawPinName = false;
380 
381  if( number.IsEmpty() )
382  aDrawPinNum = false;
383 
384  if( aTextInside ) // Draw the text inside, but the pin numbers outside.
385  {
386  if(( aPinOrient == PIN_LEFT) || ( aPinOrient == PIN_RIGHT) )
387  {
388  // It is an horizontal line
389  if( aDrawPinName )
390  {
391  if( aPinOrient == PIN_RIGHT )
392  {
393  x = x1 + aTextInside;
394  GRText( DC, wxPoint( x, y1 ), NameColor, name, TEXT_ANGLE_HORIZ, PinNameSize,
395  GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, namePenWidth, false,
396  false );
397  }
398  else // Orient == PIN_LEFT
399  {
400  x = x1 - aTextInside;
401  GRText( DC, wxPoint( x, y1 ), NameColor, name, TEXT_ANGLE_HORIZ, PinNameSize,
402  GR_TEXT_HJUSTIFY_RIGHT, GR_TEXT_VJUSTIFY_CENTER, namePenWidth, false,
403  false );
404  }
405  }
406 
407  if( aDrawPinNum )
408  {
409  GRText( DC, wxPoint(( x1 + aPinPos.x) / 2, y1 - num_offset ), NumColor, number,
411  GR_TEXT_VJUSTIFY_BOTTOM, numPenWidth, false, false );
412  }
413  }
414  else /* Its a vertical line. */
415  {
416  // Text is drawn from bottom to top (i.e. to negative value for Y axis)
417  if( aPinOrient == PIN_DOWN )
418  {
419  y = y1 + aTextInside;
420 
421  if( aDrawPinName )
422  {
423  GRText( DC, wxPoint( x1, y ), NameColor, name, TEXT_ANGLE_VERT, PinNameSize,
424  GR_TEXT_HJUSTIFY_RIGHT, GR_TEXT_VJUSTIFY_CENTER, namePenWidth, false,
425  false );
426  }
427 
428  if( aDrawPinNum )
429  {
430  GRText( DC, wxPoint( x1 - num_offset, ( y1 + aPinPos.y) / 2 ), NumColor,
431  number, TEXT_ANGLE_VERT, PinNumSize, GR_TEXT_HJUSTIFY_CENTER,
432  GR_TEXT_VJUSTIFY_BOTTOM, numPenWidth, false, false );
433  }
434  }
435  else /* PIN_UP */
436  {
437  y = y1 - aTextInside;
438 
439  if( aDrawPinName )
440  {
441  GRText( DC, wxPoint( x1, y ), NameColor, name, TEXT_ANGLE_VERT, PinNameSize,
442  GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_CENTER, namePenWidth, false,
443  false );
444  }
445 
446  if( aDrawPinNum )
447  {
448  GRText( DC, wxPoint( x1 - num_offset, ( y1 + aPinPos.y) / 2 ), NumColor,
449  number, TEXT_ANGLE_VERT, PinNumSize, GR_TEXT_HJUSTIFY_CENTER,
450  GR_TEXT_VJUSTIFY_BOTTOM, numPenWidth, false, false );
451  }
452  }
453  }
454  }
455  else /**** Draw num & text pin outside ****/
456  {
457  if(( aPinOrient == PIN_LEFT) || ( aPinOrient == PIN_RIGHT) )
458  {
459  /* Its an horizontal line. */
460  if( aDrawPinName )
461  {
462  x = ( x1 + aPinPos.x) / 2;
463  GRText( DC, wxPoint( x, y1 - name_offset ), NameColor, name, TEXT_ANGLE_HORIZ,
465  namePenWidth, false, false );
466  }
467  if( aDrawPinNum )
468  {
469  x = ( x1 + aPinPos.x) / 2;
470  GRText( DC, wxPoint( x, y1 + num_offset ), NumColor, number, TEXT_ANGLE_HORIZ,
471  PinNumSize, GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_TOP, numPenWidth,
472  false, false );
473  }
474  }
475  else /* Its a vertical line. */
476  {
477  if( aDrawPinName )
478  {
479  y = ( y1 + aPinPos.y) / 2;
480  GRText( DC, wxPoint( x1 - name_offset, y ), NameColor, name, TEXT_ANGLE_VERT,
482  namePenWidth, false, false );
483  }
484 
485  if( aDrawPinNum )
486  {
487  GRText( DC, wxPoint( x1 + num_offset, ( y1 + aPinPos.y) / 2 ), NumColor, number,
489  numPenWidth, false, false );
490  }
491  }
492  }
493 }
494 
495 
496 
497 void LIB_PIN::printPinElectricalTypeName( const RENDER_SETTINGS* aSettings, wxPoint& aPosition,
498  int aOrientation )
499 {
500  wxDC* DC = aSettings->GetPrintDC();
501  wxString typeName = GetElectricalTypeName();
502 
503  // Use a reasonable (small) size to draw the text
504  int textSize = ( m_nameTextSize * 3 ) / 4;
505 
506  #define ETXT_MAX_SIZE Millimeter2iu( 0.7 )
507 
508  if( textSize > ETXT_MAX_SIZE )
509  textSize = ETXT_MAX_SIZE;
510 
511  // Use a reasonable pen size to draw the text
512  int pensize = textSize/6;
513 
514  // Get a suitable color
516 
517  wxPoint txtpos = aPosition;
518  int offset = Millimeter2iu( 0.4 );
520  int orient = TEXT_ANGLE_HORIZ;
521 
522  switch( aOrientation )
523  {
524  case PIN_UP:
525  txtpos.y += offset;
526  orient = TEXT_ANGLE_VERT;
527  hjustify = GR_TEXT_HJUSTIFY_RIGHT;
528  break;
529 
530  case PIN_DOWN:
531  txtpos.y -= offset;
532  orient = TEXT_ANGLE_VERT;
533  break;
534 
535  case PIN_LEFT:
536  txtpos.x += offset;
537  break;
538 
539  case PIN_RIGHT:
540  txtpos.x -= offset;
541  hjustify = GR_TEXT_HJUSTIFY_RIGHT;
542  break;
543  }
544 
545  GRText( DC, txtpos, color, typeName, orient, wxSize( textSize, textSize ), hjustify,
546  GR_TEXT_VJUSTIFY_CENTER, pensize, false, false, nullptr );
547 }
548 
549 
550 void LIB_PIN::PlotSymbol( PLOTTER* aPlotter, const wxPoint& aPosition, int aOrientation ) const
551 {
552  int MapX1, MapY1, x1, y1;
554  int penWidth = GetEffectivePenWidth( aPlotter->RenderSettings() );
555 
556  aPlotter->SetColor( color );
557  aPlotter->SetCurrentLineWidth( penWidth );
558 
559  MapX1 = MapY1 = 0;
560  x1 = aPosition.x; y1 = aPosition.y;
561 
562  switch( aOrientation )
563  {
564  case PIN_UP: y1 = aPosition.y - m_length; MapY1 = 1; break;
565  case PIN_DOWN: y1 = aPosition.y + m_length; MapY1 = -1; break;
566  case PIN_LEFT: x1 = aPosition.x - m_length; MapX1 = 1; break;
567  case PIN_RIGHT: x1 = aPosition.x + m_length; MapX1 = -1; break;
568  }
569 
571  {
572  const int radius = externalPinDecoSize( aPlotter->RenderSettings(), *this );
573  aPlotter->Circle( wxPoint( MapX1 * radius + x1, MapY1 * radius + y1 ), radius * 2,
574  FILL_T::NO_FILL, penWidth );
575 
576  aPlotter->MoveTo( wxPoint( MapX1 * radius * 2 + x1, MapY1 * radius * 2 + y1 ) );
577  aPlotter->FinishTo( aPosition );
578  }
580  {
581  const int deco_size = internalPinDecoSize( aPlotter->RenderSettings(), *this );
582  if( MapY1 == 0 ) /* MapX1 = +- 1 */
583  {
584  aPlotter->MoveTo( wxPoint( x1, y1 + deco_size ) );
585  aPlotter->LineTo( wxPoint( x1 + MapX1 * deco_size * 2, y1 ) );
586  aPlotter->FinishTo( wxPoint( x1, y1 - deco_size ) );
587  }
588  else /* MapX1 = 0 */
589  {
590  aPlotter->MoveTo( wxPoint( x1 + deco_size, y1 ) );
591  aPlotter->LineTo( wxPoint( x1, y1 + MapY1 * deco_size * 2 ) );
592  aPlotter->FinishTo( wxPoint( x1 - deco_size, y1 ) );
593  }
594 
595  aPlotter->MoveTo( wxPoint( MapX1 * deco_size * 2 + x1, MapY1 * deco_size * 2 + y1 ) );
596  aPlotter->FinishTo( aPosition );
597  }
598  else
599  {
600  aPlotter->MoveTo( wxPoint( x1, y1 ) );
601  aPlotter->FinishTo( aPosition );
602  }
603 
607  {
608  const int deco_size = internalPinDecoSize( aPlotter->RenderSettings(), *this );
609  if( MapY1 == 0 ) /* MapX1 = +- 1 */
610  {
611  aPlotter->MoveTo( wxPoint( x1, y1 + deco_size ) );
612  aPlotter->LineTo( wxPoint( x1 - MapX1 * deco_size * 2, y1 ) );
613  aPlotter->FinishTo( wxPoint( x1, y1 - deco_size ) );
614  }
615  else /* MapX1 = 0 */
616  {
617  aPlotter->MoveTo( wxPoint( x1 + deco_size, y1 ) );
618  aPlotter->LineTo( wxPoint( x1, y1 - MapY1 * deco_size * 2 ) );
619  aPlotter->FinishTo( wxPoint( x1 - deco_size, y1 ) );
620  }
621  }
622 
624  || m_shape == GRAPHIC_PINSHAPE::CLOCK_LOW ) /* IEEE symbol "Active Low Input" */
625  {
626  const int deco_size = externalPinDecoSize( aPlotter->RenderSettings(), *this );
627 
628  if( MapY1 == 0 ) /* MapX1 = +- 1 */
629  {
630  aPlotter->MoveTo( wxPoint( x1 + MapX1 * deco_size * 2, y1 ) );
631  aPlotter->LineTo( wxPoint( x1 + MapX1 * deco_size * 2, y1 - deco_size * 2 ) );
632  aPlotter->FinishTo( wxPoint( x1, y1 ) );
633  }
634  else /* MapX1 = 0 */
635  {
636  aPlotter->MoveTo( wxPoint( x1, y1 + MapY1 * deco_size * 2 ) );
637  aPlotter->LineTo( wxPoint( x1 - deco_size * 2, y1 + MapY1 * deco_size * 2 ) );
638  aPlotter->FinishTo( wxPoint( x1, y1 ) );
639  }
640  }
641 
642  if( m_shape == GRAPHIC_PINSHAPE::OUTPUT_LOW ) /* IEEE symbol "Active Low Output" */
643  {
644  const int symbol_size = externalPinDecoSize( aPlotter->RenderSettings(), *this );
645 
646  if( MapY1 == 0 ) /* MapX1 = +- 1 */
647  {
648  aPlotter->MoveTo( wxPoint( x1, y1 - symbol_size * 2 ) );
649  aPlotter->FinishTo( wxPoint( x1 + MapX1 * symbol_size * 2, y1 ) );
650  }
651  else /* MapX1 = 0 */
652  {
653  aPlotter->MoveTo( wxPoint( x1 - symbol_size * 2, y1 ) );
654  aPlotter->FinishTo( wxPoint( x1, y1 + MapY1 * symbol_size * 2 ) );
655  }
656  }
657  else if( m_shape == GRAPHIC_PINSHAPE::NONLOGIC ) /* NonLogic pin symbol */
658  {
659  const int deco_size = externalPinDecoSize( aPlotter->RenderSettings(), *this );
660  aPlotter->MoveTo( wxPoint( x1 - (MapX1 + MapY1) * deco_size, y1 - (MapY1 - MapX1) * deco_size ) );
661  aPlotter->FinishTo( wxPoint( x1 + (MapX1 + MapY1) * deco_size, y1 + (MapY1 - MapX1) * deco_size ) );
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  }
665 
666  if( m_type == ELECTRICAL_PINTYPE::PT_NC ) // Draw a N.C. symbol
667  {
668  const int deco_size = TARGET_PIN_RADIUS;
669  const int ex1 = aPosition.x;
670  const int ey1 = aPosition.y;
671  aPlotter->MoveTo( wxPoint( ex1 - deco_size, ey1 - deco_size ) );
672  aPlotter->FinishTo( wxPoint( ex1 + deco_size, ey1 + deco_size ) );
673  aPlotter->MoveTo( wxPoint( ex1 + deco_size, ey1 - deco_size ) );
674  aPlotter->FinishTo( wxPoint( ex1 - deco_size, ey1 + deco_size ) );
675  }
676 }
677 
678 
679 void LIB_PIN::PlotPinTexts( PLOTTER* aPlotter, const wxPoint& aPinPos, int aPinOrient, int aTextInside,
680  bool aDrawPinNum, bool aDrawPinName ) const
681 {
682  wxString name = GetShownName();
683  wxString number = GetShownNumber();
684 
685  if( name.IsEmpty() )
686  aDrawPinName = false;
687 
688  if( number.IsEmpty() )
689  aDrawPinNum = false;
690 
691  if( !aDrawPinNum && !aDrawPinName )
692  return;
693 
694  int x, y;
695  wxSize pinNameSize = wxSize( m_nameTextSize, m_nameTextSize );
696  wxSize pinNumSize = wxSize( m_numTextSize, m_numTextSize );
697 
698  int namePenWidth = std::max( Clamp_Text_PenSize( GetPenWidth(), m_nameTextSize, false ),
699  aPlotter->RenderSettings()->GetDefaultPenWidth() );
700  int numPenWidth = std::max( Clamp_Text_PenSize( GetPenWidth(), m_numTextSize, false ),
701  aPlotter->RenderSettings()->GetDefaultPenWidth() );
702 
703  int name_offset = Mils2iu( PIN_TEXT_MARGIN ) + namePenWidth;
704  int num_offset = Mils2iu( PIN_TEXT_MARGIN ) + numPenWidth;
705 
706  /* Get the num and name colors */
707  COLOR4D nameColor = aPlotter->RenderSettings()->GetLayerColor( LAYER_PINNAM );
708  COLOR4D numColor = aPlotter->RenderSettings()->GetLayerColor( LAYER_PINNUM );
709 
710  int x1 = aPinPos.x;
711  int y1 = aPinPos.y;
712 
713  switch( aPinOrient )
714  {
715  case PIN_UP: y1 -= m_length; break;
716  case PIN_DOWN: y1 += m_length; break;
717  case PIN_LEFT: x1 -= m_length; break;
718  case PIN_RIGHT: x1 += m_length; break;
719  }
720 
721  /* Draw the text inside, but the pin numbers outside. */
722  if( aTextInside )
723  {
724  if( ( aPinOrient == PIN_LEFT) || ( aPinOrient == PIN_RIGHT) ) /* Its an horizontal line. */
725  {
726  if( aDrawPinName )
727  {
728  EDA_TEXT_HJUSTIFY_T hjustify;
729  if( aPinOrient == PIN_RIGHT )
730  {
731  x = x1 + aTextInside;
732  hjustify = GR_TEXT_HJUSTIFY_LEFT;
733  }
734  else // orient == PIN_LEFT
735  {
736  x = x1 - aTextInside;
737  hjustify = GR_TEXT_HJUSTIFY_RIGHT;
738  }
739 
740  aPlotter->Text( wxPoint( x, y1 ), nameColor, name, TEXT_ANGLE_HORIZ, pinNameSize,
741  hjustify, GR_TEXT_VJUSTIFY_CENTER, namePenWidth,
742  false, false );
743  }
744  if( aDrawPinNum )
745  {
746  aPlotter->Text( wxPoint( ( x1 + aPinPos.x) / 2, y1 - num_offset ), numColor,
747  number, TEXT_ANGLE_HORIZ, pinNumSize, GR_TEXT_HJUSTIFY_CENTER,
748  GR_TEXT_VJUSTIFY_BOTTOM, numPenWidth, false, false );
749  }
750  }
751  else /* Its a vertical line. */
752  {
753  if( aPinOrient == PIN_DOWN )
754  {
755  y = y1 + aTextInside;
756 
757  if( aDrawPinName )
758  aPlotter->Text( wxPoint( x1, y ), nameColor, name, TEXT_ANGLE_VERT,
760  namePenWidth, false, false );
761 
762  if( aDrawPinNum )
763  {
764  aPlotter->Text( wxPoint( x1 - num_offset, ( y1 + aPinPos.y) / 2 ), numColor,
765  number, TEXT_ANGLE_VERT, pinNumSize, GR_TEXT_HJUSTIFY_CENTER,
766  GR_TEXT_VJUSTIFY_BOTTOM, numPenWidth, false, false );
767  }
768  }
769  else /* PIN_UP */
770  {
771  y = y1 - aTextInside;
772 
773  if( aDrawPinName )
774  {
775  aPlotter->Text( wxPoint( x1, y ), nameColor, name, TEXT_ANGLE_VERT,
777  namePenWidth, false, false );
778  }
779 
780  if( aDrawPinNum )
781  {
782  aPlotter->Text( wxPoint( x1 - num_offset, ( y1 + aPinPos.y) / 2 ), numColor,
783  number, TEXT_ANGLE_VERT, pinNumSize, GR_TEXT_HJUSTIFY_CENTER,
784  GR_TEXT_VJUSTIFY_BOTTOM, numPenWidth, false, false );
785  }
786  }
787  }
788  }
789  else /* Draw num & text pin outside */
790  {
791  if(( aPinOrient == PIN_LEFT) || ( aPinOrient == PIN_RIGHT) )
792  {
793  /* Its an horizontal line. */
794  if( aDrawPinName )
795  {
796  x = ( x1 + aPinPos.x) / 2;
797  aPlotter->Text( wxPoint( x, y1 - name_offset ), nameColor, name,
799  GR_TEXT_VJUSTIFY_BOTTOM, namePenWidth, false, false );
800  }
801 
802  if( aDrawPinNum )
803  {
804  x = ( x1 + aPinPos.x ) / 2;
805  aPlotter->Text( wxPoint( x, y1 + num_offset ), numColor, number,
807  GR_TEXT_VJUSTIFY_TOP, numPenWidth, false, false );
808  }
809  }
810  else /* Its a vertical line. */
811  {
812  if( aDrawPinName )
813  {
814  y = ( y1 + aPinPos.y ) / 2;
815  aPlotter->Text( wxPoint( x1 - name_offset, y ), nameColor, name,
817  GR_TEXT_VJUSTIFY_BOTTOM, namePenWidth, false, false );
818  }
819 
820  if( aDrawPinNum )
821  {
822  aPlotter->Text( wxPoint( x1 + num_offset, ( y1 + aPinPos.y ) / 2 ), numColor,
823  number, TEXT_ANGLE_VERT, pinNumSize, GR_TEXT_HJUSTIFY_CENTER,
824  GR_TEXT_VJUSTIFY_TOP, numPenWidth, false, false );
825  }
826  }
827  }
828 }
829 
830 
831 int LIB_PIN::PinDrawOrient( const TRANSFORM& aTransform ) const
832 {
833  int orient;
834  wxPoint end; // position of pin end starting at 0,0 according to its orientation, length = 1
835 
836  switch( m_orientation )
837  {
838  case PIN_UP: end.y = 1; break;
839  case PIN_DOWN: end.y = -1; break;
840  case PIN_LEFT: end.x = -1; break;
841  case PIN_RIGHT: end.x = 1; break;
842  }
843 
844  // = pos of end point, according to the symbol orientation.
845  end = aTransform.TransformCoordinate( end );
846  orient = PIN_UP;
847 
848  if( end.x == 0 )
849  {
850  if( end.y > 0 )
851  orient = PIN_DOWN;
852  }
853  else
854  {
855  orient = PIN_RIGHT;
856 
857  if( end.x < 0 )
858  orient = PIN_LEFT;
859  }
860 
861  return orient;
862 }
863 
864 
866 {
867  return new LIB_PIN( *this );
868 }
869 
870 
871 int LIB_PIN::compare( const LIB_ITEM& aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags ) const
872 {
873  wxASSERT( aOther.Type() == LIB_PIN_T );
874 
875  int retv = LIB_ITEM::compare( aOther, aCompareFlags );
876 
877  if( retv )
878  return retv;
879 
880  const LIB_PIN* tmp = (LIB_PIN*) &aOther;
881 
882  // When comparing units, we do not compare the part numbers. If everything else is
883  // identical, then we can just renumber the parts for the inherited symbol.
884  if( !( aCompareFlags & COMPARE_FLAGS::UNIT ) && m_number != tmp->m_number )
885  return m_number.Cmp( tmp->m_number );
886 
887  int result = m_name.CmpNoCase( tmp->m_name );
888 
889  if( result )
890  return result;
891 
892  if( m_position.x != tmp->m_position.x )
893  return m_position.x - tmp->m_position.x;
894 
895  if( m_position.y != tmp->m_position.y )
896  return m_position.y - tmp->m_position.y;
897 
898  if( m_length != tmp->m_length )
899  return m_length - tmp->m_length;
900 
901  if( m_orientation != tmp->m_orientation )
902  return m_orientation - tmp->m_orientation;
903 
904  if( m_shape != tmp->m_shape )
905  return static_cast<int>( m_shape ) - static_cast<int>( tmp->m_shape );
906 
907  if( m_type != tmp->m_type )
908  return static_cast<int>( m_type ) - static_cast<int>( tmp->m_type );
909 
910  if( m_attributes != tmp->m_attributes )
911  return m_attributes - tmp->m_attributes;
912 
913  if( m_numTextSize != tmp->m_numTextSize )
914  return m_numTextSize - tmp->m_numTextSize;
915 
916  if( m_nameTextSize != tmp->m_nameTextSize )
917  return m_nameTextSize - tmp->m_nameTextSize;
918 
919  if( m_alternates.size() != tmp->m_alternates.size() )
920  return m_alternates.size() - tmp->m_alternates.size();
921 
922  auto lhsItem = m_alternates.begin();
923  auto rhsItem = tmp->m_alternates.begin();
924 
925  while( lhsItem != m_alternates.end() )
926  {
927  const ALT& lhsAlt = lhsItem->second;
928  const ALT& rhsAlt = rhsItem->second;
929 
930  retv = lhsAlt.m_Name.Cmp( rhsAlt.m_Name );
931 
932  if( retv )
933  return retv;
934 
935  if( lhsAlt.m_Type != rhsAlt.m_Type )
936  return static_cast<int>( lhsAlt.m_Type ) - static_cast<int>( rhsAlt.m_Type );
937 
938  if( lhsAlt.m_Shape != rhsAlt.m_Shape )
939  return static_cast<int>( lhsAlt.m_Shape ) - static_cast<int>( rhsAlt.m_Shape );
940 
941  ++lhsItem;
942  ++rhsItem;
943  }
944 
945  return 0;
946 }
947 
948 
949 void LIB_PIN::Offset( const wxPoint& aOffset )
950 {
951  m_position += aOffset;
952 }
953 
954 
955 void LIB_PIN::MoveTo( const wxPoint& aNewPosition )
956 {
957  if( m_position != aNewPosition )
958  {
959  m_position = aNewPosition;
960  SetModified();
961  }
962 }
963 
964 
965 void LIB_PIN::MirrorHorizontal( const wxPoint& aCenter )
966 {
967  m_position.x -= aCenter.x;
968  m_position.x *= -1;
969  m_position.x += aCenter.x;
970 
971  if( m_orientation == PIN_RIGHT )
973  else if( m_orientation == PIN_LEFT )
975 }
976 
977 
978 void LIB_PIN::MirrorVertical( const wxPoint& aCenter )
979 {
980  m_position.y -= aCenter.y;
981  m_position.y *= -1;
982  m_position.y += aCenter.y;
983 
984  if( m_orientation == PIN_UP )
986  else if( m_orientation == PIN_DOWN )
988 }
989 
990 
991 void LIB_PIN::Rotate( const wxPoint& aCenter, bool aRotateCCW )
992 {
993  int rot_angle = aRotateCCW ? -900 : 900;
994 
995  RotatePoint( &m_position, aCenter, rot_angle );
996 
997  if( aRotateCCW )
998  {
999  switch( m_orientation )
1000  {
1001  case PIN_RIGHT: m_orientation = PIN_UP; break;
1002  case PIN_UP: m_orientation = PIN_LEFT; break;
1003  case PIN_LEFT: m_orientation = PIN_DOWN; break;
1004  case PIN_DOWN: m_orientation = PIN_RIGHT; break;
1005  }
1006  }
1007  else
1008  {
1009  switch( m_orientation )
1010  {
1011  case PIN_RIGHT: m_orientation = PIN_DOWN; break;
1012  case PIN_UP: m_orientation = PIN_RIGHT; break;
1013  case PIN_LEFT: m_orientation = PIN_UP; break;
1014  case PIN_DOWN: m_orientation = PIN_LEFT; break;
1015  }
1016  }
1017 }
1018 
1019 
1020 void LIB_PIN::Plot( PLOTTER* aPlotter, const wxPoint& aPffset, bool aFill,
1021  const TRANSFORM& aTransform ) const
1022 {
1023  if( !IsVisible() )
1024  return;
1025 
1026  int orient = PinDrawOrient( aTransform );
1027  wxPoint pos = aTransform.TransformCoordinate( m_position ) + aPffset;
1028 
1029  PlotSymbol( aPlotter, pos, orient );
1030  PlotPinTexts( aPlotter, pos, orient, GetParent()->GetPinNameOffset(),
1031  GetParent()->ShowPinNumbers(), GetParent()->ShowPinNames() );
1032 }
1033 
1034 
1035 void LIB_PIN::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
1036 {
1037  LIB_ITEM::GetMsgPanelInfo( aFrame, aList );
1038 
1039  aList.emplace_back( _( "Name" ), UnescapeString( GetShownName() ) );
1040  aList.emplace_back( _( "Number" ), GetShownNumber() );
1041  aList.emplace_back( _( "Type" ), ElectricalPinTypeGetText( m_type ) );
1042  aList.emplace_back( _( "Style" ), PinShapeGetText( m_shape ) );
1043 
1044  aList.emplace_back( _( "Style" ), IsVisible() ? _( "Yes" ) : _( "No" ) );
1045 
1046  // Display pin length
1047  aList.emplace_back( _( "Length" ), StringFromValue( aFrame->GetUserUnits(), m_length ) );
1048 
1050  aList.emplace_back( _( "Orientation" ), PinOrientationName( (unsigned) i ) );
1051 
1052  wxPoint pinpos = GetPosition();
1053  pinpos.y = -pinpos.y; // Display coords are top to bottom; lib item coords are bottom to top
1054 
1055  aList.emplace_back( _( "Pos X" ), MessageTextFromValue( aFrame->GetUserUnits(), pinpos.x ) );
1056  aList.emplace_back( _( "Pos Y" ), MessageTextFromValue( aFrame->GetUserUnits(), pinpos.y ) );
1057 }
1058 
1059 
1060 const EDA_RECT LIB_PIN::GetBoundingBox( bool aIncludeInvisibles, bool aPinOnly ) const
1061 {
1062  EDA_RECT bbox;
1063  wxPoint begin;
1064  wxPoint end;
1065  int nameTextOffset = 0;
1066  wxString name = GetShownName();
1067  wxString number = GetShownNumber();
1068  bool showName = !name.IsEmpty();
1069  bool showNum = !number.IsEmpty();
1070  int minsizeV = TARGET_PIN_RADIUS;
1071 
1072  if( !aIncludeInvisibles && !IsVisible() )
1073  showName = false;
1074 
1075  if( GetParent() )
1076  {
1077  if( GetParent()->ShowPinNames() )
1078  nameTextOffset = GetParent()->GetPinNameOffset();
1079  else
1080  showName = false;
1081 
1082  if( !GetParent()->ShowPinNumbers() )
1083  showNum = false;
1084  }
1085 
1086  if( aPinOnly )
1087  {
1088  showName = false;
1089  showNum = false;
1090  }
1091 
1092  // First, calculate boundary box corners position
1093  int numberTextLength = showNum ? m_numTextSize * number.Len() : 0;
1094 
1095  // Actual text height is bigger than text size
1096  int numberTextHeight = showNum ? KiROUND( m_numTextSize * 1.1 ) : 0;
1097 
1099  minsizeV = std::max( TARGET_PIN_RADIUS, externalPinDecoSize( nullptr, *this ) );
1100 
1101  // calculate top left corner position
1102  // for the default pin orientation (PIN_RIGHT)
1103  begin.y = std::max( minsizeV, numberTextHeight + Mils2iu( PIN_TEXT_MARGIN ) );
1104  begin.x = std::min( 0, m_length - (numberTextLength / 2) );
1105 
1106  // calculate bottom right corner position and adjust top left corner position
1107  int nameTextLength = 0;
1108  int nameTextHeight = 0;
1109 
1110  if( showName )
1111  {
1112  int length = name.Len();
1113 
1114  // TODO: exclude markup characters!
1115  nameTextLength = ( m_nameTextSize * length ) + nameTextOffset;
1116 
1117  // Actual text height are bigger than text size
1118  nameTextHeight = KiROUND( m_nameTextSize * 1.1 ) + Mils2iu( PIN_TEXT_MARGIN );
1119  }
1120 
1121  if( nameTextOffset ) // for values > 0, pin name is inside the body
1122  {
1123  end.x = m_length + nameTextLength;
1124  end.y = std::min( -minsizeV, -nameTextHeight / 2 );
1125  }
1126  else // if value == 0:
1127  // pin name is outside the body, and above the pin line
1128  // pin num is below the pin line
1129  {
1130  end.x = std::max( m_length, nameTextLength );
1131  end.y = -begin.y;
1132  begin.y = std::max( minsizeV, nameTextHeight );
1133  }
1134 
1135  // Now, calculate boundary box corners position for the actual pin orientation
1136  int orient = PinDrawOrient( DefaultTransform );
1137 
1138  /* Calculate the pin position */
1139  switch( orient )
1140  {
1141  case PIN_UP:
1142  // Pin is rotated and texts positions are mirrored
1143  RotatePoint( &begin, wxPoint( 0, 0 ), -900 );
1144  RotatePoint( &end, wxPoint( 0, 0 ), -900 );
1145  break;
1146 
1147  case PIN_DOWN:
1148  RotatePoint( &begin, wxPoint( 0, 0 ), 900 );
1149  RotatePoint( &end, wxPoint( 0, 0 ), 900 );
1150  begin.x = -begin.x;
1151  end.x = -end.x;
1152  break;
1153 
1154  case PIN_LEFT:
1155  begin.x = -begin.x;
1156  end.x = -end.x;
1157  break;
1158 
1159  case PIN_RIGHT:
1160  break;
1161  }
1162 
1163  begin += m_position;
1164  end += m_position;
1165 
1166  bbox.SetOrigin( begin );
1167  bbox.SetEnd( end );
1168  bbox.Normalize();
1169  bbox.Inflate( ( GetPenWidth() / 2 ) + 1 );
1170 
1171  // Draw Y axis is reversed in schematic:
1172  bbox.RevertYAxis();
1173 
1174  return bbox;
1175 }
1176 
1177 
1179 {
1181 }
1182 
1183 
1184 wxString LIB_PIN::GetSelectMenuText( EDA_UNITS aUnits ) const
1185 {
1186  if( !m_name.IsEmpty() )
1187  {
1188  return wxString::Format( _( "Pin %s [%s, %s, %s]" ),
1189  GetShownNumber(),
1192  PinShapeGetText( m_shape ) );
1193  }
1194  else
1195  {
1196  return wxString::Format( _( "Pin %s [%s, %s]" ),
1197  GetShownNumber(),
1199  PinShapeGetText( m_shape ) );
1200  }
1201 }
1202 
1203 
1204 #if defined(DEBUG)
1205 
1206 void LIB_PIN::Show( int nestLevel, std::ostream& os ) const
1207 {
1208  NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str()
1209  << " num=\"" << m_number.mb_str()
1210  << '"' << "/>\n";
1211 
1212 // NestedSpace( nestLevel, os ) << "</" << GetClass().Lower().mb_str() << ">\n";
1213 }
1214 
1215 #endif
1216 
1217 void LIB_PIN::CalcEdit( const wxPoint& aPosition )
1218 {
1219  if( IsMoving() )
1220  MoveTo( aPosition );
1221 }
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:1184
void SetModified()
Definition: eda_item.cpp:65
int GetPinNameOffset() const
Definition: lib_symbol.h:561
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:287
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:865
void Rotate(const wxPoint &aCenter, bool aRotateCCW=true) override
Rotate the object about aCenter point.
Definition: lib_pin.cpp:991
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:1020
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:679
GRAPHIC_PINSHAPE m_shape
Definition: lib_pin.h:281
#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:955
int m_numTextSize
Definition: lib_pin.h:286
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:341
wxString ElectricalPinTypeGetText(ELECTRICAL_PINTYPE aType)
Definition: pin_type.cpp:237
LIB_PIN(LIB_SYMBOL *aParent)
Definition: lib_pin.cpp:94
bool IsMoving() const
Definition: eda_item.h:120
int color
Definition: DXF_plotter.cpp:57
void PlotSymbol(PLOTTER *aPlotter, const wxPoint &aPosition, int aOrientation) const
Definition: lib_pin.cpp:550
BITMAPS ElectricalPinTypeGetBitmap(ELECTRICAL_PINTYPE aType)
Definition: pin_type.cpp:247
bool ShowPinNumbers() const
Definition: lib_symbol.h:577
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:121
int PinOrientationIndex(int code)
Definition: pin_type.cpp:147
wxString m_name
Definition: lib_pin.h:284
virtual int GetEffectivePenWidth(const RENDER_SETTINGS *aSettings) const
Definition: lib_item.h:145
bool HitTest(const wxPoint &aPosition, int aAccuracy=0) const override
Test if aPosition is contained within or on the bounding box of an 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:258
Definition: lib_pin.h:48
EDA_ITEM_FLAGS m_flags
Definition: eda_item.h:481
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:229
const EDA_RECT GetBoundingBox() const override
Definition: lib_pin.h:174
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:831
int m_length
Definition: lib_pin.h:279
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:198
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:978
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:116
void LineTo(const wxPoint &pos)
Definition: plotter.h:268
int m_orientation
Definition: lib_pin.h:280
void printPinSymbol(const RENDER_SETTINGS *aSettings, const wxPoint &aPos, int aOrientation)
Print the pin symbol without text.
Definition: lib_pin.cpp:230
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:285
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
COMPARE_FLAGS
The list of flags used by the compare function.
Definition: lib_item.h:80
void SetEnd(int x, int y)
Definition: eda_rect.h:182
void GRCircle(EDA_RECT *ClipBox, wxDC *DC, int xc, int yc, int r, int width, const COLOR4D &Color)
Definition: gr_basic.cpp:551
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:569
#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:212
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 compare(const LIB_ITEM &aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags=LIB_ITEM::COMPARE_FLAGS::NORMAL) const override
Provide the draw object specific comparison called by the == and < operators.
Definition: lib_pin.cpp:871
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:1178
#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:1035
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:1217
void GRLineTo(EDA_RECT *ClipBox, wxDC *DC, int x, int y, int width, const COLOR4D &Color)
Definition: gr_basic.cpp:236
virtual void SetColor(const COLOR4D &color)=0
void SetConvert(int aConvert)
Definition: lib_item.h:260
wxPoint GetPosition() const override
Definition: lib_pin.h:210
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:283
EDA_UNITS
Definition: eda_units.h:38
void GRMoveTo(int x, int y)
Definition: gr_basic.cpp:229
void Normalize()
Ensures that the height ant width are positive.
Definition: eda_rect.cpp:35
LIB_SYMBOL * GetParent() const
Definition: lib_item.h:156
void SetUnit(int aUnit)
Definition: lib_item.h:257
Base plotter engine class.
Definition: plotter.h:121
std::map< wxString, ALT > m_alternates
Definition: lib_pin.h:289
wxPoint m_position
Definition: lib_pin.h:278
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:497
#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:100
ELECTRICAL_PINTYPE m_type
Definition: lib_pin.h:282
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
wxString StringFromValue(EDA_UNITS aUnits, double aValue, bool aAddUnitSymbol, EDA_DATA_TYPE aType)
Convert a value to a string using double notation.
Definition: base_units.cpp:204
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:949
static constexpr int Millimeter2iu(double mm)
virtual int compare(const LIB_ITEM &aOther, LIB_ITEM::COMPARE_FLAGS aCompareFlags=LIB_ITEM::COMPARE_FLAGS::NORMAL) const
Provide the draw object specific comparison called by the == and < operators.
Definition: lib_item.cpp:67
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:113
void MirrorHorizontal(const wxPoint &aCenter) override
Mirror the draw object along the horizontal (X) axis about aCenter point.
Definition: lib_pin.cpp:965
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:103