KiCad PCB EDA Suite
sch_painter.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) 2014 CERN
5  * Copyright (C) 2019-2020 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, you may find one here:
21  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22  * or you may search the http://www.gnu.org website for the version 2 license,
23  * or you may write to the Free Software Foundation, Inc.,
24  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25  */
26 
27 
28 #include <sch_item.h>
29 
30 #include <bezier_curves.h>
31 #include <class_libentry.h>
32 #include <class_library.h>
33 #include <connection_graph.h>
37 #include <gr_text.h>
38 #include <lib_arc.h>
39 #include <lib_bezier.h>
40 #include <lib_circle.h>
41 #include <lib_edit_frame.h>
42 #include <lib_field.h>
43 #include <lib_item.h>
44 #include <lib_pin.h>
45 #include <lib_polyline.h>
46 #include <lib_rectangle.h>
47 #include <lib_text.h>
48 #include <math/util.h>
49 #include <plotter.h>
50 #include <sch_bitmap.h>
51 #include <sch_bus_entry.h>
52 #include <sch_component.h>
53 #include <sch_edit_frame.h>
54 #include <sch_field.h>
55 #include <sch_junction.h>
56 #include <sch_line.h>
57 #include <sch_marker.h>
58 #include <sch_no_connect.h>
59 #include <sch_sheet.h>
60 #include <sch_text.h>
62 #include <template_fieldnames.h>
63 #include <view/view.h>
64 
65 #include "sch_painter.h"
66 
67 namespace KIGFX
68 {
69 
71  m_ShowUnit( 0 ),
72  m_ShowConvert( 0 )
73 {
74  m_ShowHiddenText = true;
75  m_ShowHiddenPins = true;
77  m_ShowUmbilicals = true;
78  m_ShowDisabled = false;
79 }
80 
81 
83 {
84  for( int layer = SCH_LAYER_ID_START; layer < SCH_LAYER_ID_END; layer ++)
85  m_layerColors[ layer ] = aSettings->GetColor( layer );
86 
87  for( int layer = GAL_LAYER_ID_START; layer < GAL_LAYER_ID_END; layer ++)
88  m_layerColors[ layer ] = aSettings->GetColor( layer );
89 
91 }
92 
93 
94 const COLOR4D& SCH_RENDER_SETTINGS::GetColor( const VIEW_ITEM* aItem, int aLayer ) const
95 {
96  return m_layerColors[ aLayer ];
97 }
98 
99 
113 static LIB_PART* dummy()
114 {
115  static LIB_PART* part;
116 
117  if( !part )
118  {
119  part = new LIB_PART( wxEmptyString );
120 
121  LIB_RECTANGLE* square = new LIB_RECTANGLE( part );
122 
123  square->MoveTo( wxPoint( Mils2iu( -200 ), Mils2iu( 200 ) ) );
124  square->SetEndPosition( wxPoint( Mils2iu( 200 ), Mils2iu( -200 ) ) );
125 
126  LIB_TEXT* text = new LIB_TEXT( part );
127 
128  text->SetTextSize( wxSize( Mils2iu( 150 ), Mils2iu( 150 ) ) );
129  text->SetText( wxString( wxT( "??" ) ) );
130 
131  part->AddDrawItem( square );
132  part->AddDrawItem( text );
133  }
134 
135  return part;
136 }
137 
138 
140  KIGFX::PAINTER( aGal )
141 { }
142 
143 
144 #define HANDLE_ITEM( type_id, type_name ) \
145  case type_id: draw( (type_name *) item, aLayer ); break
146 
147 
148 bool SCH_PAINTER::Draw( const VIEW_ITEM *aItem, int aLayer )
149 {
150  auto item2 = static_cast<const EDA_ITEM*>( aItem );
151  auto item = const_cast<EDA_ITEM*>( item2 );
152 
153 #ifdef CONNECTIVITY_DEBUG
154 
155  auto sch_item = dynamic_cast<SCH_ITEM*>( item );
156  auto conn = sch_item ? sch_item->Connection( *g_CurrentSheet ) : nullptr;
157 
158  if( conn )
159  {
160  auto pos = item->GetBoundingBox().Centre();
161  auto label = conn->Name( true );
162 
166  m_gal->SetLineWidth( Mils2ui( 2 ) );
167  m_gal->SetGlyphSize( VECTOR2D( Mils2ui( 20 ), Mils2ui( 20 ) ) );
168  m_gal->StrokeText( conn->Name( true ), pos, 0.0 );
169  }
170 
171 #endif
172 
173  switch( item->Type() )
174  {
199 
200  default: return false;
201  }
202 
203  return false;
204 }
205 
206 
208 {
209  if( m_schSettings.m_ShowUnit // showing a specific unit
210  && aItem->GetUnit() // item is unit-specific
211  && aItem->GetUnit() != m_schSettings.m_ShowUnit )
212  {
213  return false;
214  }
215 
216  if( m_schSettings.m_ShowConvert // showing a specific conversion
217  && aItem->GetConvert() // item is conversion-specific
218  && aItem->GetConvert() != m_schSettings.m_ShowConvert )
219  {
220  return false;
221  }
222 
223  return true;
224 }
225 
226 
228 {
229  const MATRIX3x3D& matrix = m_gal->GetScreenWorldMatrix();
230 
231  // For best visuals the selection width must be a cross between the zoom level and the
232  // default line width.
233  return static_cast<float>( fabs( matrix.GetScale().x * 2.75 ) + GetSelectionThickness() );
234 }
235 
236 
237 COLOR4D SCH_PAINTER::getRenderColor( const EDA_ITEM* aItem, int aLayer, bool aDrawingShadows )
238 {
240 
241  if( aItem->Type() == SCH_LINE_T )
242  {
243  COLOR4D lineColor = static_cast<const SCH_LINE*>( aItem )->GetLineColor();
244 
245  if( lineColor != COLOR4D::UNSPECIFIED )
246  color = lineColor;
247  }
248  else if( aItem->Type() == SCH_SHEET_T )
249  {
250  SCH_SHEET* sheet = (SCH_SHEET*) aItem;
251  COLOR4D sheetColor = COLOR4D::UNSPECIFIED;
252 
253  if( aLayer == LAYER_SHEET )
254  sheetColor = sheet->GetBorderColor();
255  else if( aLayer == LAYER_SHEET_BACKGROUND )
256  sheetColor = sheet->GetBackgroundColor();
257 
258  if( sheetColor != COLOR4D::UNSPECIFIED )
259  color = sheetColor;
260  }
261 
262  if( aItem->IsBrightened() && !aDrawingShadows ) // Selection disambiguation, etc.
263  {
265 
266  if( aLayer == LAYER_DEVICE_BACKGROUND || aLayer == LAYER_SHEET_BACKGROUND )
267  color = color.WithAlpha( 0.2 );
268  }
269  else if( aItem->IsSelected() )
270  {
271  if( aDrawingShadows )
273  }
274 
276  color = color.Darken( 0.5f );
277 
278  return color;
279 }
280 
281 
282 float SCH_PAINTER::getLineWidth( const LIB_ITEM* aItem, bool aDrawingShadows )
283 {
284  float width = (float) aItem->GetPenSize();
285 
286  if( aItem->IsSelected() && aDrawingShadows )
287  width += getShadowWidth();
288 
289  return width;
290 }
291 
292 
293 float SCH_PAINTER::getLineWidth( const SCH_ITEM* aItem, bool aDrawingShadows )
294 {
295  float width = (float) aItem->GetPenSize();
296 
297  if( aItem->IsSelected() && aDrawingShadows )
298  width += getShadowWidth();
299 
300  return width;
301 }
302 
303 
304 float SCH_PAINTER::getTextThickness( const SCH_TEXT* aItem, bool aDrawingShadows )
305 {
306  float width = (float) aItem->GetThickness();
307 
308  if( width == 0 )
309  width = (float) GetDefaultLineThickness();
310 
311  if( aItem->IsSelected() && aDrawingShadows )
312  width += getShadowWidth();
313 
314  return width;
315 }
316 
317 
318 void SCH_PAINTER::strokeText( const wxString& aText, const VECTOR2D& aPosition, double aAngle )
319 {
320  m_gal->StrokeText( aText, aPosition, aAngle, GetTextMarkupFlags() );
321 }
322 
323 
324 void SCH_PAINTER::draw( LIB_PART *aPart, int aLayer, bool aDrawFields, int aUnit, int aConvert )
325 {
326  if( !aUnit )
327  aUnit = m_schSettings.m_ShowUnit;
328 
329  if( !aConvert )
330  aConvert = m_schSettings.m_ShowConvert;
331 
332  std::unique_ptr< LIB_PART > tmpPart;
333  LIB_PART* drawnPart = aPart;
334 
335  if( aPart->IsAlias() )
336  {
337  tmpPart = aPart->Flatten();
338  drawnPart = tmpPart.get();
339  }
340 
341  for( auto& item : drawnPart->GetDrawItems() )
342  {
343  if( !aDrawFields && item.Type() == LIB_FIELD_T )
344  continue;
345 
346  if( aUnit && item.GetUnit() && aUnit != item.GetUnit() )
347  continue;
348 
349  if( aConvert && item.GetConvert() && aConvert != item.GetConvert() )
350  continue;
351 
352  Draw( &item, aLayer );
353  }
354 }
355 
356 
357 static VECTOR2D mapCoords( const wxPoint& aCoord )
358 {
359  return VECTOR2D( aCoord.x, -aCoord.y );
360 }
361 
362 
363 void SCH_PAINTER::triLine( const VECTOR2D &a, const VECTOR2D &b, const VECTOR2D &c )
364 {
365  m_gal->DrawLine( a, b );
366  m_gal->DrawLine( b, c );
367 }
368 
369 
370 bool SCH_PAINTER::setDeviceColors( const LIB_ITEM* aItem, int aLayer )
371 {
372  switch( aLayer )
373  {
375  if( aItem->IsSelected() )
376  {
377  m_gal->SetIsFill( false );
378  m_gal->SetIsStroke( true );
379  m_gal->SetLineWidth( getLineWidth( aItem, true ) );
380  m_gal->SetStrokeColor( getRenderColor( aItem, LAYER_DEVICE, true ) );
381  m_gal->SetFillColor( getRenderColor( aItem, LAYER_DEVICE, true ) );
382  return true;
383  }
384 
385  return false;
386 
388  if( aItem->GetFillMode() == FILLED_WITH_BG_BODYCOLOR )
389  {
390  COLOR4D fillColor = getRenderColor( aItem, LAYER_DEVICE_BACKGROUND, false );
391 
392  // These actions place the item over others, so allow a modest transparency here
393  if( aItem->IsMoving() || aItem->IsDragging() || aItem->IsResized() )
394  fillColor = fillColor.WithAlpha( 0.75 );
395 
397  m_gal->SetFillColor( fillColor );
398  m_gal->SetIsStroke( false );
399  return true;
400  }
401 
402  return false;
403 
404  case LAYER_DEVICE:
405  m_gal->SetIsFill( aItem->GetFillMode() == FILLED_SHAPE );
406  m_gal->SetFillColor( getRenderColor( aItem, LAYER_DEVICE, false ) );
407  m_gal->SetIsStroke( aItem->GetPenSize() > 0 );
408  m_gal->SetLineWidth( getLineWidth( aItem, false ) );
409  m_gal->SetStrokeColor( getRenderColor( aItem, LAYER_DEVICE, false ) );
410 
411  return true;
412 
413  default:
414  return false;
415  }
416 }
417 
418 
420 {
422  m_gal->SetIsFill( true );
423 }
424 
425 
426 void SCH_PAINTER::draw( LIB_RECTANGLE *aRect, int aLayer )
427 {
428  if( !isUnitAndConversionShown( aRect ) )
429  return;
430 
431  if( setDeviceColors( aRect, aLayer ) )
432  {
433  fillIfSelection( aLayer );
434  m_gal->DrawRectangle( mapCoords( aRect->GetPosition() ), mapCoords( aRect->GetEnd() ) );
435  }
436 }
437 
438 
439 void SCH_PAINTER::draw( LIB_CIRCLE *aCircle, int aLayer )
440 {
441  if( !isUnitAndConversionShown( aCircle ) )
442  return;
443 
444  if( setDeviceColors( aCircle, aLayer ) )
445  {
446  fillIfSelection( aLayer );
447  m_gal->DrawCircle( mapCoords( aCircle->GetPosition() ), aCircle->GetRadius() );
448  }
449 }
450 
451 
452 void SCH_PAINTER::draw( LIB_ARC *aArc, int aLayer )
453 {
454  if( !isUnitAndConversionShown( aArc ) )
455  return;
456 
457  if( setDeviceColors( aArc, aLayer ) )
458  {
459  int sai = aArc->GetFirstRadiusAngle();
460  int eai = aArc->GetSecondRadiusAngle();
461 
472  if( !TRANSFORM().MapAngles( &sai, &eai ) )
473  {
474  LIB_ARC new_arc( *aArc );
475 
476  new_arc.SetStart( aArc->GetEnd() );
477  new_arc.SetEnd( aArc->GetStart() );
478  new_arc.CalcRadiusAngles();
479  sai = new_arc.GetFirstRadiusAngle();
480  eai = new_arc.GetSecondRadiusAngle();
481  TRANSFORM().MapAngles( &sai, &eai );
482  }
483 
484  double sa = (double) sai * M_PI / 1800.0;
485  double ea = (double) eai * M_PI / 1800.0 ;
486 
487  VECTOR2D pos = mapCoords( aArc->GetPosition() );
488 
489  m_gal->DrawArc( pos, aArc->GetRadius(), sa, ea );
490  }
491 }
492 
493 
494 void SCH_PAINTER::draw( LIB_POLYLINE *aLine, int aLayer )
495 {
496  if( !isUnitAndConversionShown( aLine ) )
497  return;
498 
499  if( setDeviceColors( aLine, aLayer ) )
500  {
501  const std::vector<wxPoint>& pts = aLine->GetPolyPoints();
502  std::deque<VECTOR2D> vtx;
503 
504  for( auto p : pts )
505  vtx.push_back( mapCoords( p ) );
506 
507  fillIfSelection( aLayer );
508  m_gal->DrawPolygon( vtx );
509  }
510 }
511 
512 
513 void SCH_PAINTER::draw( LIB_FIELD *aField, int aLayer )
514 {
515  bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
516 
517  if( drawingShadows && !aField->IsSelected() )
518  return;
519 
520  if( !isUnitAndConversionShown( aField ) )
521  return;
522 
523  // Must check layer as fields are sometimes drawn by their parent rather than
524  // directly from the view.
525  int layers[KIGFX::VIEW::VIEW_MAX_LAYERS];
526  int layers_count;
527  bool foundLayer = false;
528 
529  aField->ViewGetLayers( layers, layers_count );
530 
531  for( int i = 0; i < layers_count; ++i )
532  {
533  if( layers[i] == aLayer )
534  foundLayer = true;
535  }
536 
537  if( !foundLayer )
538  return;
539 
540  COLOR4D color = getRenderColor( aField, aLayer, drawingShadows );
541 
542  if( !aField->IsVisible() )
543  {
544  if( m_schSettings.m_ShowHiddenText || aField->IsBrightened() )
545  color = getRenderColor( aField, LAYER_HIDDEN, drawingShadows );
546  else
547  return;
548  }
549 
550  m_gal->SetLineWidth( getLineWidth( aField, drawingShadows ) );
551  m_gal->SetIsFill( false );
552  m_gal->SetIsStroke( true );
554 
555  auto pos = mapCoords( aField->GetPosition() );
556 
557  if( drawingShadows && GetSelectionTextAsBox() )
558  {
559  EDA_RECT boundaryBox = aField->GetBoundingBox();
560 
561  m_gal->SetIsFill( true );
563  m_gal->SetLineWidth( m_gal->GetLineWidth() * 0.5 );
564  boundaryBox.RevertYAxis();
565 
567  mapCoords( boundaryBox.GetPosition() ), mapCoords( boundaryBox.GetEnd() ) );
568  }
569  else
570  {
571  m_gal->SetGlyphSize( VECTOR2D( aField->GetTextSize() ) );
572  m_gal->SetFontItalic( aField->IsItalic() );
573 
576 
577  double orient = aField->GetTextAngleRadians();
578 
579  strokeText( aField->GetText(), pos, orient );
580  }
581 
582  // Draw the umbilical line
583  if( aField->IsMoving() && m_schSettings.m_ShowUmbilicals )
584  {
586  m_gal->SetStrokeColor( COLOR4D( 0.0, 0.0, 1.0, 1.0 ) );
587  m_gal->DrawLine( pos, wxPoint( 0, 0 ) );
588  }
589 }
590 
591 
592 void SCH_PAINTER::draw( LIB_TEXT *aText, int aLayer )
593 {
594  if( !isUnitAndConversionShown( aText ) )
595  return;
596 
597  bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
598 
599  if( drawingShadows && !aText->IsSelected() )
600  return;
601 
602  COLOR4D color = getRenderColor( aText, LAYER_DEVICE, drawingShadows );
603 
604  if( !aText->IsVisible() )
605  {
607  color = getRenderColor( aText, LAYER_HIDDEN, drawingShadows );
608  else
609  return;
610  }
611 
612  EDA_RECT bBox = aText->GetBoundingBox();
613  bBox.RevertYAxis();
614  VECTOR2D pos = mapCoords( bBox.Centre() );
615  double orient = aText->GetTextAngleRadians();
616 
619  m_gal->SetLineWidth( getLineWidth( aText, drawingShadows ) );
620  m_gal->SetIsFill( false );
621  m_gal->SetIsStroke( true );
623  m_gal->SetGlyphSize( VECTOR2D( aText->GetTextSize() ) );
624  m_gal->SetFontBold( aText->IsBold() );
625  m_gal->SetFontItalic( aText->IsItalic() );
626  strokeText( aText->GetText(), pos, orient );
627 }
628 
629 
630 static int InternalPinDecoSize( const LIB_PIN &aPin )
631 {
632  return aPin.GetNameTextSize() != 0 ? aPin.GetNameTextSize() / 2 : aPin.GetNumberTextSize() / 2;
633 }
634 
635 
636 // Utility for getting the size of the 'external' pin decorators (as a radius)
637 // i.e. the negation circle, the polarity 'slopes' and the nonlogic marker
638 static int ExternalPinDecoSize( const LIB_PIN &aPin )
639 {
640  return aPin.GetNumberTextSize() / 2;
641 }
642 
643 
644 // Draw the target (an open circle) for a pin which has no connection or is being moved.
645 void SCH_PAINTER::drawPinDanglingSymbol( const VECTOR2I& aPos, bool aDrawingShadows )
646 {
647  m_gal->SetIsFill( false );
648  m_gal->SetIsStroke( true );
649  m_gal->SetLineWidth( aDrawingShadows ? getShadowWidth() : 1.0F );
650 
652 }
653 
654 
655 void SCH_PAINTER::draw( LIB_PIN *aPin, int aLayer )
656 {
657  if( !isUnitAndConversionShown( aPin ) )
658  return;
659 
660  bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
661 
662  if( drawingShadows && !aPin->IsSelected() )
663  return;
664 
665  VECTOR2I pos = mapCoords( aPin->GetPosition() );
666  COLOR4D color = getRenderColor( aPin, LAYER_PIN, drawingShadows );
667 
668  if( !aPin->IsVisible() )
669  {
671  {
672  color = getRenderColor( aPin, LAYER_HIDDEN, drawingShadows );
673  }
674  else
675  {
676  if( aPin->HasFlag( IS_DANGLING ) && aPin->IsPowerConnection() )
677  drawPinDanglingSymbol( pos, drawingShadows );
678 
679  return;
680  }
681  }
682 
683  VECTOR2I p0;
684  VECTOR2I dir;
685  int len = aPin->GetLength();
686  int orient = aPin->GetOrientation();
687 
688  switch( orient )
689  {
690  case PIN_UP:
691  p0 = VECTOR2I( pos.x, pos.y - len );
692  dir = VECTOR2I( 0, 1 );
693  break;
694 
695  case PIN_DOWN:
696  p0 = VECTOR2I( pos.x, pos.y + len );
697  dir = VECTOR2I( 0, -1 );
698  break;
699 
700  case PIN_LEFT:
701  p0 = VECTOR2I( pos.x - len, pos.y );
702  dir = VECTOR2I( 1, 0 );
703  break;
704 
705  default:
706  case PIN_RIGHT:
707  p0 = VECTOR2I( pos.x + len, pos.y );
708  dir = VECTOR2I( -1, 0 );
709  break;
710  }
711 
712  VECTOR2D pc;
713 
714  m_gal->SetIsStroke( true );
715  m_gal->SetIsFill( false );
716  m_gal->SetLineWidth( getLineWidth( aPin, drawingShadows ) );
718  m_gal->SetFontBold( false );
719  m_gal->SetFontItalic( false );
720 
721  const int radius = ExternalPinDecoSize( *aPin );
722  const int diam = radius*2;
723  const int clock_size = InternalPinDecoSize( *aPin );
724 
725  if( aPin->GetType() == ELECTRICAL_PINTYPE::PT_NC ) // Draw a N.C. symbol
726  {
727  m_gal->DrawLine( p0, pos );
728 
729  m_gal->DrawLine( pos + VECTOR2D( -1, -1 ) * TARGET_PIN_RADIUS,
730  pos + VECTOR2D( 1, 1 ) * TARGET_PIN_RADIUS );
731  m_gal->DrawLine( pos + VECTOR2D( 1, -1 ) * TARGET_PIN_RADIUS ,
732  pos + VECTOR2D( -1, 1 ) * TARGET_PIN_RADIUS );
733 
734  aPin->ClearFlags( IS_DANGLING ); // PIN_NC pin type is always not connected and dangling.
735  }
736  else
737  {
738  switch( aPin->GetShape() )
739  {
741  m_gal->DrawLine( p0, pos );
742  break;
743 
745  m_gal->DrawCircle( p0 + dir * radius, radius );
746  m_gal->DrawLine( p0 + dir * ( diam ), pos );
747  break;
748 
750  pc = p0 - dir * clock_size ;
751 
752  triLine( p0 + VECTOR2D( dir.y, -dir.x) * clock_size,
753  pc,
754  p0 + VECTOR2D( -dir.y, dir.x) * clock_size );
755 
756  m_gal->DrawCircle( p0 + dir * radius, radius );
757  m_gal->DrawLine( p0 + dir * ( diam ), pos );
758  break;
759 
762  pc = p0 - dir * clock_size ;
763 
764  triLine( p0 + VECTOR2D( dir.y, -dir.x) * clock_size,
765  pc,
766  p0 + VECTOR2D( -dir.y, dir.x) * clock_size );
767 
768  if( !dir.y )
769  {
770  triLine( p0 + VECTOR2D(dir.x, 0) * diam,
771  p0 + VECTOR2D(dir.x, -1) * diam,
772  p0 );
773  }
774  else /* MapX1 = 0 */
775  {
776  triLine( p0 + VECTOR2D( 0, dir.y) * diam,
777  p0 + VECTOR2D(-1, dir.y) * diam,
778  p0 );
779  }
780 
781  m_gal->DrawLine( p0, pos );
782  break;
783 
785  m_gal->DrawLine( p0, pos );
786 
787  if( !dir.y )
788  {
789  triLine( p0 + VECTOR2D( 0, clock_size ),
790  p0 + VECTOR2D( -dir.x * clock_size, 0 ),
791  p0 + VECTOR2D( 0, -clock_size ) );
792  }
793  else
794  {
795  triLine( p0 + VECTOR2D( clock_size, 0 ),
796  p0 + VECTOR2D( 0, -dir.y * clock_size ),
797  p0 + VECTOR2D( -clock_size, 0 ) );
798  }
799  break;
800 
802  m_gal->DrawLine( p0, pos );
803 
804  if( !dir.y )
805  {
806  triLine( p0 + VECTOR2D(dir.x, 0) * diam,
807  p0 + VECTOR2D(dir.x, -1) * diam,
808  p0 );
809  }
810  else /* MapX1 = 0 */
811  {
812  triLine( p0 + VECTOR2D( 0, dir.y) * diam,
813  p0 + VECTOR2D(-1, dir.y) * diam,
814  p0 );
815  }
816  break;
817 
818  case GRAPHIC_PINSHAPE::OUTPUT_LOW: // IEEE symbol "Active Low Output"
819  m_gal->DrawLine( p0, pos );
820 
821  if( !dir.y ) // Horizontal pin
822  m_gal->DrawLine( p0 - VECTOR2D( 0, diam ), p0 + VECTOR2D( dir.x, 0 ) * diam );
823  else // Vertical pin
824  m_gal->DrawLine( p0 - VECTOR2D( diam, 0 ), p0 + VECTOR2D( 0, dir.y ) * diam );
825  break;
826 
827  case GRAPHIC_PINSHAPE::NONLOGIC: // NonLogic pin symbol
828  m_gal->DrawLine( p0, pos );
829 
830  m_gal->DrawLine( p0 - VECTOR2D( dir.x + dir.y, dir.y - dir.x ) * radius,
831  p0 + VECTOR2D( dir.x + dir.y, dir.y - dir.x ) * radius );
832  m_gal->DrawLine( p0 - VECTOR2D( dir.x - dir.y, dir.x + dir.y ) * radius,
833  p0 + VECTOR2D( dir.x - dir.y, dir.x + dir.y ) * radius );
834  break;
835  }
836  }
837 
838 
839  if( aPin->HasFlag( IS_DANGLING ) && ( aPin->IsVisible() || aPin->IsPowerConnection() ) )
840  drawPinDanglingSymbol( pos, drawingShadows );
841 
842  LIB_PART* libEntry = aPin->GetParent();
843 
844  // Draw the labels
845  if( drawingShadows && ( libEntry->Type() == LIB_PART_T || libEntry->IsSelected() )
847  return;
848 
849  int textOffset = libEntry->GetPinNameOffset();
850 
851  float nameLineWidth = getLineWidth( aPin, drawingShadows );
852  nameLineWidth = Clamp_Text_PenSize( nameLineWidth, aPin->GetNameTextSize(), false );
853  float numLineWidth = getLineWidth( aPin, drawingShadows );
854  numLineWidth = Clamp_Text_PenSize( numLineWidth, aPin->GetNumberTextSize(), false );
855 
856  #define PIN_TEXT_MARGIN 4.0
857 
858  // Four locations around a pin where text can be drawn
859  enum { INSIDE = 0, OUTSIDE, ABOVE, BELOW };
860  int size[4] = { 0, 0, 0, 0 };
861  float thickness[4] = { numLineWidth, numLineWidth, numLineWidth, numLineWidth };
862  COLOR4D colour[4];
863  wxString text[4];
864 
865  // TextOffset > 0 means pin NAMES on inside, pin NUMBERS above and nothing below
866  if( textOffset )
867  {
868  size [INSIDE] = libEntry->ShowPinNames() ? aPin->GetNameTextSize() : 0;
869  thickness[INSIDE] = nameLineWidth;
870  colour [INSIDE] = getRenderColor( aPin, LAYER_PINNAM, drawingShadows );
871  text [INSIDE] = aPin->GetName();
872 
873  size [ABOVE] = libEntry->ShowPinNumbers() ? aPin->GetNumberTextSize() : 0;
874  thickness[ABOVE] = numLineWidth;
875  colour [ABOVE] = getRenderColor( aPin, LAYER_PINNUM, drawingShadows );
876  text [ABOVE] = aPin->GetNumber();
877  }
878  // Otherwise pin NAMES go above and pin NUMBERS go below
879  else
880  {
881  size [ABOVE] = libEntry->ShowPinNames() ? aPin->GetNameTextSize() : 0;
882  thickness[ABOVE] = nameLineWidth;
883  colour [ABOVE] = getRenderColor( aPin, LAYER_PINNAM, drawingShadows );
884  text [ABOVE] = aPin->GetName();
885 
886  size [BELOW] = libEntry->ShowPinNumbers() ? aPin->GetNumberTextSize() : 0;
887  thickness[BELOW] = numLineWidth;
888  colour [BELOW] = getRenderColor( aPin, LAYER_PINNUM, drawingShadows );
889  text [BELOW] = aPin->GetNumber();
890  }
891 
893  {
894  size [OUTSIDE] = std::max( aPin->GetNameTextSize() * 3 / 4, Millimeter2iu( 0.7 ) );
895  thickness[OUTSIDE] = float( size[OUTSIDE] ) / 6.0F;
896  colour [OUTSIDE] = getRenderColor( aPin, LAYER_NOTES, drawingShadows );
897  text [OUTSIDE] = aPin->GetElectricalTypeName();
898  }
899 
900  if( !aPin->IsVisible() )
901  {
902  for( COLOR4D& c : colour )
903  c = getRenderColor( aPin, LAYER_HIDDEN, drawingShadows );
904  }
905 
906  int insideOffset = textOffset;
907  int outsideOffset = 10;
908  float lineThickness = (float) GetDefaultLineThickness();
909  float aboveOffset = Mils2iu( PIN_TEXT_MARGIN ) + ( thickness[ABOVE] + lineThickness ) / 2.0;
910  float belowOffset = Mils2iu( PIN_TEXT_MARGIN ) + ( thickness[BELOW] + lineThickness ) / 2.0;
911 
912  if( drawingShadows )
913  {
914  for( float& t : thickness )
915  t += getShadowWidth();
916 
917  insideOffset -= KiROUND( getShadowWidth() / 2 );
918  outsideOffset -= KiROUND( getShadowWidth() / 2 );
919  }
920 
921  #define SET_DC( i ) \
922  m_gal->SetGlyphSize( VECTOR2D( size[i], size[i] ) ); \
923  m_gal->SetLineWidth( thickness[i] ); \
924  m_gal->SetStrokeColor( colour[i] )
925 
926  switch( orient )
927  {
928  case PIN_LEFT:
929  if( size[INSIDE] )
930  {
931  SET_DC( INSIDE );
934  strokeText( text[INSIDE], pos + VECTOR2D( -insideOffset - len, 0 ), 0 );
935  }
936  if( size[OUTSIDE] )
937  {
938  SET_DC( OUTSIDE );
941  strokeText( text[OUTSIDE], pos + VECTOR2D( outsideOffset, 0 ), 0 );
942  }
943  if( size[ABOVE] )
944  {
945  SET_DC( ABOVE );
948  strokeText( text[ABOVE], pos + VECTOR2D( -len / 2.0, -aboveOffset ), 0 );
949  }
950  if( size[BELOW] )
951  {
952  SET_DC( BELOW );
955  strokeText( text[BELOW], pos + VECTOR2D( -len / 2.0, belowOffset ), 0 );
956  }
957  break;
958 
959  case PIN_RIGHT:
960  if( size[INSIDE] )
961  {
962  SET_DC( INSIDE );
966  strokeText( text[INSIDE], pos + VECTOR2D( insideOffset + len, 0 ), 0 );
967  }
968  if( size[OUTSIDE] )
969  {
970  SET_DC( OUTSIDE );
973  strokeText( text[OUTSIDE], pos + VECTOR2D( -outsideOffset, 0 ), 0 );
974  }
975  if( size[ABOVE] )
976  {
977  SET_DC( ABOVE );
980  strokeText( text[ABOVE], pos + VECTOR2D( len / 2.0, -aboveOffset ), 0 );
981  }
982  if( size[BELOW] )
983  {
984  SET_DC( BELOW );
987  strokeText( text[BELOW], pos + VECTOR2D( len / 2.0, belowOffset ), 0 );
988  }
989  break;
990 
991  case PIN_DOWN:
992  if( size[INSIDE] )
993  {
994  SET_DC( INSIDE );
997  strokeText( text[INSIDE], pos + VECTOR2D( 0, insideOffset + len ), M_PI / 2 );
998  }
999  if( size[OUTSIDE] )
1000  {
1001  SET_DC( OUTSIDE );
1004  strokeText( text[OUTSIDE], pos + VECTOR2D( 0, -outsideOffset ), M_PI / 2 );
1005  }
1006  if( size[ABOVE] )
1007  {
1008  SET_DC( ABOVE );
1011  strokeText( text[ABOVE], pos + VECTOR2D( -aboveOffset, len / 2.0 ), M_PI / 2 );
1012  }
1013  if( size[BELOW] )
1014  {
1015  SET_DC( BELOW );
1018  strokeText( text[BELOW], pos + VECTOR2D( belowOffset, len / 2.0 ), M_PI / 2 );
1019  }
1020  break;
1021 
1022  case PIN_UP:
1023  if( size[INSIDE] )
1024  {
1025  SET_DC( INSIDE );
1028  strokeText( text[INSIDE], pos + VECTOR2D( 0, -insideOffset - len ), M_PI / 2 );
1029  }
1030  if( size[OUTSIDE] )
1031  {
1032  SET_DC( OUTSIDE );
1035  strokeText( text[OUTSIDE], pos + VECTOR2D( 0, outsideOffset ), M_PI / 2 );
1036  }
1037  if( size[ABOVE] )
1038  {
1039  SET_DC( ABOVE );
1042  strokeText( text[ABOVE], pos + VECTOR2D( -aboveOffset, -len / 2.0 ), M_PI / 2 );
1043  }
1044  if( size[BELOW] )
1045  {
1046  SET_DC( BELOW );
1049  strokeText( text[BELOW], pos + VECTOR2D( belowOffset, -len / 2.0 ), M_PI / 2 );
1050  }
1051  break;
1052 
1053  default:
1054  wxFAIL_MSG( "Unknown pin orientation" );
1055  }
1056 }
1057 
1058 
1059 void SCH_PAINTER::draw( LIB_BEZIER *aCurve, int aLayer )
1060 {
1061  if( !isUnitAndConversionShown( aCurve ) )
1062  return;
1063 
1064  if( setDeviceColors( aCurve, aLayer ) )
1065  {
1066  BEZIER_POLY poly ( aCurve->GetPoints() );
1067  std::vector<wxPoint> pts;
1068  std::deque<VECTOR2D> pts_xformed;
1069  poly.GetPoly( pts );
1070 
1071  for( const auto &p : pts )
1072  pts_xformed.push_back( mapCoords( p ) );
1073 
1074  m_gal->DrawPolygon( pts_xformed );
1075  }
1076 }
1077 
1078 
1079 // Draw the target (an open square) for a wire or label which has no connection or is
1080 // being moved.
1081 void SCH_PAINTER::drawDanglingSymbol( const wxPoint& aPos, bool aDrawingShadows )
1082 {
1083  wxPoint radius( Mils2iu( DANGLING_SYMBOL_SIZE ), Mils2iu( DANGLING_SYMBOL_SIZE ) );
1084 
1085  m_gal->SetIsStroke( true );
1086  m_gal->SetIsFill( false );
1087  m_gal->SetLineWidth( aDrawingShadows ? getShadowWidth() : 1.0F );
1088 
1089  m_gal->DrawRectangle( aPos - radius, aPos + radius );
1090 }
1091 
1092 
1093 void SCH_PAINTER::draw( SCH_JUNCTION *aJct, int aLayer )
1094 {
1095  bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
1096 
1097  if( drawingShadows && !aJct->IsSelected() )
1098  return;
1099 
1100  COLOR4D color;
1101  auto conn = aJct->Connection( *g_CurrentSheet );
1102 
1103  if( conn && conn->IsBus() )
1104  color = getRenderColor( aJct, LAYER_BUS, drawingShadows );
1105  else
1106  color = getRenderColor( aJct, LAYER_JUNCTION, drawingShadows );
1107 
1108  m_gal->SetIsStroke( drawingShadows );
1109  m_gal->SetLineWidth( getLineWidth( aJct, drawingShadows ) );
1111  m_gal->SetIsFill( !drawingShadows );
1112  m_gal->SetFillColor( color );
1114 }
1115 
1116 
1117 void SCH_PAINTER::draw( SCH_LINE *aLine, int aLayer )
1118 {
1119  bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
1120 
1121  if( drawingShadows && !aLine->IsSelected() )
1122  return;
1123 
1124  COLOR4D color = getRenderColor( aLine, aLine->GetLayer(), drawingShadows );
1125  float width = getLineWidth( aLine, drawingShadows );
1126 
1127  m_gal->SetIsStroke( true );
1129  m_gal->SetLineWidth( width );
1130 
1131  if( aLine->GetLineStyle() <= PLOT_DASH_TYPE::FIRST_TYPE || drawingShadows )
1132  {
1133  m_gal->DrawLine( aLine->GetStartPoint(), aLine->GetEndPoint() );
1134  }
1135  else
1136  {
1137  VECTOR2D start = aLine->GetStartPoint();
1138  VECTOR2D end = aLine->GetEndPoint();
1139 
1140  EDA_RECT clip( (wxPoint)start, wxSize( end.x - start.x, end.y - start.y ) );
1141  clip.Normalize();
1142 
1143  double theta = atan2( end.y - start.y, end.x - start.x );
1144  double strokes[] = { 1.0, DASH_GAP_LEN( width ), 1.0, DASH_GAP_LEN( width ) };
1145 
1146  switch( aLine->GetLineStyle() )
1147  {
1148  default:
1149  case PLOT_DASH_TYPE::DASH:
1150  strokes[0] = strokes[2] = DASH_MARK_LEN( width );
1151  break;
1152  case PLOT_DASH_TYPE::DOT:
1153  strokes[0] = strokes[2] = DOT_MARK_LEN( width );
1154  break;
1156  strokes[0] = DASH_MARK_LEN( width );
1157  strokes[2] = DOT_MARK_LEN( width );
1158  break;
1159  }
1160 
1161  for( size_t i = 0; i < 10000; ++i )
1162  {
1163  // Calculations MUST be done in doubles to keep from accumulating rounding
1164  // errors as we go.
1165  VECTOR2D next( start.x + strokes[ i % 4 ] * cos( theta ),
1166  start.y + strokes[ i % 4 ] * sin( theta ) );
1167 
1168  // Drawing each segment can be done rounded to ints.
1169  wxPoint segStart( KiROUND( start.x ), KiROUND( start.y ) );
1170  wxPoint segEnd( KiROUND( next.x ), KiROUND( next.y ) );
1171 
1172  if( ClipLine( &clip, segStart.x, segStart.y, segEnd.x, segEnd.y ) )
1173  break;
1174  else if( i % 2 == 0 )
1175  m_gal->DrawLine( segStart, segEnd );
1176 
1177  start = next;
1178  }
1179  }
1180 
1181  if( aLine->IsStartDangling() )
1182  drawDanglingSymbol( aLine->GetStartPoint(), drawingShadows );
1183 
1184  if( aLine->IsEndDangling() )
1185  drawDanglingSymbol( aLine->GetEndPoint(), drawingShadows );
1186 }
1187 
1188 
1189 void SCH_PAINTER::draw( SCH_TEXT *aText, int aLayer )
1190 {
1191  bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
1192 
1193  if( drawingShadows && !aText->IsSelected() )
1194  return;
1195 
1196  switch( aText->Type() )
1197  {
1198  case SCH_SHEET_PIN_T: aLayer = LAYER_SHEETLABEL; break;
1199  case SCH_HIER_LABEL_T: aLayer = LAYER_HIERLABEL; break;
1200  case SCH_GLOBAL_LABEL_T: aLayer = LAYER_GLOBLABEL; break;
1201  case SCH_LABEL_T: aLayer = LAYER_LOCLABEL; break;
1202  default: aLayer = LAYER_NOTES; break;
1203  }
1204 
1205  COLOR4D color = getRenderColor( aText, aLayer, drawingShadows );
1206  SCH_CONNECTION* conn = aText->Connection( *g_CurrentSheet );
1207 
1208  if( conn && conn->IsBus() )
1209  color = getRenderColor( aText, LAYER_BUS, drawingShadows );
1210 
1211  if( !aText->IsVisible() )
1212  {
1213  if( m_schSettings.m_ShowHiddenText || aText->IsBrightened() )
1214  color = getRenderColor( aText, LAYER_HIDDEN, drawingShadows );
1215  else
1216  return;
1217  }
1218 
1219  m_gal->SetIsFill( false );
1220  m_gal->SetIsStroke( true );
1221  m_gal->SetLineWidth( getLineWidth( aText, drawingShadows ) );
1223  m_gal->SetTextAttributes( aText );
1224 
1225  VECTOR2D text_offset = aText->GetTextPos() + aText->GetSchematicTextOffset();
1226  wxString shownText( aText->GetShownText() );
1227 
1228  if( drawingShadows )
1229  {
1230  if( GetSelectionTextAsBox() )
1231  {
1232  EDA_RECT bBox = aText->GetBoundingBox();
1233 
1234  m_gal->SetIsFill( true );
1235  m_gal->SetFillColor( color );
1236  m_gal->SetLineWidth( m_gal->GetLineWidth() * 0.5 );
1237  bBox.RevertYAxis();
1238 
1239  m_gal->DrawRectangle( mapCoords( bBox.GetPosition() ), mapCoords( bBox.GetEnd() ) );
1240  return;
1241  }
1242 
1243  switch( aText->GetLabelSpinStyle() )
1244  {
1246  text_offset.x += getShadowWidth() / 2;
1247  break;
1248  case LABEL_SPIN_STYLE::UP:
1249  text_offset.y += getShadowWidth() / 2;
1250  break;
1252  text_offset.x -= getShadowWidth() / 2;
1253  break;
1255  text_offset.y -= getShadowWidth() / 2;
1256  break;
1257  }
1258  }
1259 
1260  if( !shownText.IsEmpty() )
1261  strokeText( shownText, text_offset, aText->GetTextAngleRadians() );
1262 
1263  if( aText->IsDangling() )
1264  drawDanglingSymbol( aText->GetTextPos(), drawingShadows );
1265 }
1266 
1267 
1268 static void orientPart( LIB_PART* part, int orientation )
1269 {
1270  struct ORIENT
1271  {
1272  int flag;
1273  int n_rots;
1274  int mirror_x;
1275  int mirror_y;
1276  }
1277  orientations[] =
1278  {
1279  { CMP_ORIENT_0, 0, 0, 0 },
1280  { CMP_ORIENT_90, 1, 0, 0 },
1281  { CMP_ORIENT_180, 2, 0, 0 },
1282  { CMP_ORIENT_270, 3, 0, 0 },
1283  { CMP_MIRROR_X + CMP_ORIENT_0, 0, 1, 0 },
1284  { CMP_MIRROR_X + CMP_ORIENT_90, 1, 1, 0 },
1285  { CMP_MIRROR_Y, 0, 0, 1 },
1286  { CMP_MIRROR_X + CMP_ORIENT_270, 3, 1, 0 },
1287  { CMP_MIRROR_Y + CMP_ORIENT_0, 0, 0, 1 },
1288  { CMP_MIRROR_Y + CMP_ORIENT_90, 1, 0, 1 },
1289  { CMP_MIRROR_Y + CMP_ORIENT_180, 2, 0, 1 },
1290  { CMP_MIRROR_Y + CMP_ORIENT_270, 3, 0, 1 }
1291  };
1292 
1293  ORIENT o = orientations[ 0 ];
1294 
1295  for( auto& i : orientations )
1296  {
1297  if( i.flag == orientation )
1298  {
1299  o = i;
1300  break;
1301  }
1302  }
1303 
1304  for( auto& item : part->GetDrawItems() )
1305  {
1306  for( int i = 0; i < o.n_rots; i++ )
1307  item.Rotate( wxPoint(0, 0 ), true );
1308 
1309  if( o.mirror_x )
1310  item.MirrorVertical( wxPoint( 0, 0 ) );
1311 
1312  if( o.mirror_y )
1313  item.MirrorHorizontal( wxPoint( 0, 0 ) );
1314  }
1315 }
1316 
1317 
1318 void SCH_PAINTER::draw( SCH_COMPONENT *aComp, int aLayer )
1319 {
1320  // Use dummy part if the actual couldn't be found (or couldn't be locked).
1321  LIB_PART* originalPart = aComp->GetPartRef() ? aComp->GetPartRef().get() : dummy();
1322 
1323  // Copy the source so we can re-orient and translate it.
1324  LIB_PART tempPart( *originalPart );
1325 
1326  tempPart.SetFlags( aComp->GetFlags() );
1327 
1328  orientPart( &tempPart, aComp->GetOrientation() );
1329 
1330  for( auto& tempItem : tempPart.GetDrawItems() )
1331  {
1332  tempItem.SetFlags( aComp->GetFlags() ); // SELECTED, HIGHLIGHTED, BRIGHTENED
1333  tempItem.MoveTo( tempItem.GetPosition() + (wxPoint) mapCoords( aComp->GetPosition() ) );
1334  }
1335 
1336  // Copy the pin info from the component to the temp pins
1337  LIB_PINS tempPins;
1338  tempPart.GetPins( tempPins, aComp->GetUnit(), aComp->GetConvert() );
1339  const SCH_PIN_PTRS compPins = aComp->GetSchPins();
1340 
1341  for( unsigned i = 0; i < tempPins.size() && i < compPins.size(); ++ i )
1342  {
1343  LIB_PIN* tempPin = tempPins[ i ];
1344  const SCH_PIN* compPin = compPins[ i ];
1345 
1346  tempPin->ClearFlags();
1347  tempPin->SetFlags( compPin->GetFlags() ); // SELECTED, HIGHLIGHTED, BRIGHTENED
1348 
1349  if( compPin->IsDangling() )
1350  tempPin->SetFlags( IS_DANGLING );
1351  }
1352 
1353  draw( &tempPart, aLayer, false, aComp->GetUnit(), aComp->GetConvert() );
1354 
1355  // The fields are SCH_COMPONENT-specific so don't need to be copied/oriented/translated
1356  for( SCH_FIELD* field : aComp->GetFields() )
1357  draw( field, aLayer );
1358 }
1359 
1360 
1361 void SCH_PAINTER::draw( SCH_FIELD *aField, int aLayer )
1362 {
1363  bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
1364 
1365  if( drawingShadows && !aField->IsSelected() )
1366  return;
1367 
1368  aLayer = aField->GetLayer();
1369 
1370  COLOR4D color = getRenderColor( aField, aLayer, drawingShadows );
1371 
1372  if( !aField->IsVisible() )
1373  {
1374  if( m_schSettings.m_ShowHiddenText || aField->IsBrightened() )
1375  color = getRenderColor( aField, LAYER_HIDDEN, drawingShadows );
1376  else
1377  return;
1378  }
1379 
1380  if( aField->IsVoid() )
1381  return;
1382 
1383  if( drawingShadows && aField->GetParent()->IsSelected() && !GetSelectionDrawChildItems() )
1384  return;
1385 
1386  // Calculate the text orientation according to the parent orientation.
1387  int orient = (int) aField->GetTextAngle();
1388 
1389  if( aField->GetParent() && aField->GetParent()->Type() == SCH_COMPONENT_T )
1390  {
1391  if( static_cast<SCH_COMPONENT*>( aField->GetParent() )->GetTransform().y1 )
1392  {
1393  // Rotate component 90 degrees.
1394  if( orient == TEXT_ANGLE_HORIZ )
1395  orient = TEXT_ANGLE_VERT;
1396  else
1397  orient = TEXT_ANGLE_HORIZ;
1398  }
1399  }
1400 
1401  /* Calculate the text justification, according to the component orientation/mirror.
1402  * This is a bit complicated due to cumulative calculations:
1403  * - numerous cases (mirrored or not, rotation)
1404  * - the DrawGraphicText function recalculate also H and H justifications according to the
1405  * text orientation.
1406  * - When a component is mirrored, the text is not mirrored and justifications are
1407  * complicated to calculate
1408  * so the easier way is to use no justifications (centered text) and use GetBoundingBox
1409  * to know the text coordinate considered as centered
1410  */
1411  EDA_RECT boundaryBox = aField->GetBoundingBox();
1412  wxPoint textpos = boundaryBox.Centre();
1413 
1415  m_gal->SetIsStroke( true );
1416  m_gal->SetLineWidth( getLineWidth( aField, drawingShadows ) );
1417 
1418  if( drawingShadows && GetSelectionTextAsBox() )
1419  {
1420  m_gal->SetIsFill( true );
1421  m_gal->SetFillColor( color );
1422  m_gal->SetLineWidth( m_gal->GetLineWidth() * 0.5 );
1423  boundaryBox.RevertYAxis();
1424 
1425  m_gal->DrawRectangle( mapCoords( boundaryBox.GetPosition() ),
1426  mapCoords( boundaryBox.GetEnd() ) );
1427  }
1428  else
1429  {
1432  m_gal->SetIsFill( false );
1433  m_gal->SetGlyphSize( VECTOR2D( aField->GetTextSize() ) );
1434  m_gal->SetFontBold( aField->IsBold() );
1435  m_gal->SetFontItalic( aField->IsItalic() );
1436  m_gal->SetTextMirrored( aField->IsMirrored() );
1437 
1438  strokeText( aField->GetFullyQualifiedText(), textpos,
1439  orient == TEXT_ANGLE_VERT ? M_PI / 2 : 0 );
1440  }
1441 
1442  // Draw the umbilical line
1443  if( aField->IsMoving() )
1444  {
1445  wxPoint parentPos = aField->GetParentPosition();
1446 
1448  m_gal->SetStrokeColor( COLOR4D( 0.0, 0.0, 1.0, 1.0 ) );
1449  m_gal->DrawLine( textpos, parentPos );
1450  }
1451 }
1452 
1453 
1454 void SCH_PAINTER::draw( SCH_GLOBALLABEL *aLabel, int aLayer )
1455 {
1456  bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
1457 
1458  if( drawingShadows && !aLabel->IsSelected() )
1459  return;
1460 
1461  COLOR4D color = getRenderColor( aLabel, LAYER_GLOBLABEL, drawingShadows );
1462 
1463  std::vector<wxPoint> pts;
1464  std::deque<VECTOR2D> pts2;
1465 
1466  aLabel->CreateGraphicShape( pts, aLabel->GetTextPos() );
1467 
1468  for( auto p : pts )
1469  pts2.emplace_back( VECTOR2D( p.x, p.y ) );
1470 
1471  // the text is drawn inside the graphic shape.
1472  // On Cairo the graphic shape is filled by the background
1473  // before drawing the text ().
1474  // However if the text is selected, it is draw twice:
1475  // first, on LAYER_SELECTION_SHADOWS
1476  // second, on the text layer.
1477  // the second must not erase the first drawing.
1478  bool fillBg = ( aLayer == LAYER_SELECTION_SHADOWS ) || !aLabel->IsSelected();
1479  m_gal->SetIsFill( fillBg );
1481  m_gal->SetIsStroke( true );
1482  m_gal->SetLineWidth( getTextThickness( aLabel, drawingShadows ) );
1484  m_gal->DrawPolyline( pts2 );
1485 
1486  draw( static_cast<SCH_TEXT*>( aLabel ), aLayer );
1487 }
1488 
1489 
1490 void SCH_PAINTER::draw( SCH_HIERLABEL *aLabel, int aLayer )
1491 {
1492  bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
1493 
1494  if( drawingShadows && !aLabel->IsSelected() )
1495  return;
1496 
1497  COLOR4D color = getRenderColor( aLabel, LAYER_SHEETLABEL, drawingShadows );
1498 
1499  SCH_CONNECTION* conn = aLabel->Connection( *g_CurrentSheet );
1500 
1501  if( conn && conn->IsBus() )
1502  color = getRenderColor( aLabel, LAYER_BUS, drawingShadows );
1503 
1504  std::vector<wxPoint> pts;
1505  std::deque<VECTOR2D> pts2;
1506 
1507  aLabel->CreateGraphicShape( pts, aLabel->GetTextPos() );
1508 
1509  for( auto p : pts )
1510  pts2.emplace_back( VECTOR2D( p.x, p.y ) );
1511 
1512  m_gal->SetIsFill( true );
1514  m_gal->SetIsStroke( true );
1515  m_gal->SetLineWidth( getTextThickness( aLabel, drawingShadows ) );
1517  m_gal->DrawPolyline( pts2 );
1518 
1519  draw( static_cast<SCH_TEXT*>( aLabel ), aLayer );
1520 }
1521 
1522 void SCH_PAINTER::draw( SCH_SHEET *aSheet, int aLayer )
1523 {
1524  bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
1525 
1526  if( aLayer == LAYER_HIERLABEL || aLayer == LAYER_SELECTION_SHADOWS )
1527  {
1528  for( SCH_SHEET_PIN* sheetPin : aSheet->GetPins() )
1529  {
1530  if( drawingShadows && !aSheet->IsSelected() && !sheetPin->IsSelected() )
1531  continue;
1532 
1533  if( drawingShadows && !GetSelectionDrawChildItems() && aSheet->IsSelected() )
1534  break;
1535 
1536  int width = aSheet->GetPenSize();
1537  wxPoint initial_pos = sheetPin->GetTextPos();
1538  wxPoint offset_pos = initial_pos;
1539 
1540  // For aesthetic reasons, the SHEET_PIN is drawn with a small offset of width / 2
1541  switch( sheetPin->GetEdge() )
1542  {
1543  case SHEET_TOP_SIDE: offset_pos.y += KiROUND( width / 2.0 ); break;
1544  case SHEET_BOTTOM_SIDE: offset_pos.y -= KiROUND( width / 2.0 ); break;
1545  case SHEET_RIGHT_SIDE: offset_pos.x -= KiROUND( width / 2.0 ); break;
1546  case SHEET_LEFT_SIDE: offset_pos.x += KiROUND( width / 2.0 ); break;
1547  default: break;
1548  }
1549 
1550  sheetPin->SetTextPos( offset_pos );
1551  draw( static_cast<SCH_HIERLABEL*>( sheetPin ), aLayer );
1552  m_gal->DrawLine( offset_pos, initial_pos );
1553  sheetPin->SetTextPos( initial_pos );
1554  }
1555  }
1556 
1557  VECTOR2D pos = aSheet->GetPosition();
1558  VECTOR2D size = aSheet->GetSize();
1559 
1560  if( aLayer == LAYER_SHEET_BACKGROUND )
1561  {
1563  m_gal->SetIsFill( true );
1564  m_gal->SetIsStroke( false );
1565 
1566  m_gal->DrawRectangle( pos, pos + size );
1567  }
1568 
1569  if( aLayer == LAYER_SHEET || aLayer == LAYER_SELECTION_SHADOWS )
1570  {
1571  m_gal->SetStrokeColor( getRenderColor( aSheet, LAYER_SHEET, drawingShadows ) );
1572  m_gal->SetIsStroke( true );
1573  m_gal->SetLineWidth( getLineWidth( aSheet, drawingShadows ) );
1574  m_gal->SetIsFill( false );
1575 
1576  m_gal->DrawRectangle( pos, pos + size );
1577 
1578  if( drawingShadows && !GetSelectionDrawChildItems() && aSheet->IsSelected() )
1579  return;
1580 
1581  for( SCH_FIELD& field : aSheet->GetFields() )
1582  draw( &field, aLayer );
1583  }
1584 }
1585 
1586 
1587 void SCH_PAINTER::draw( SCH_NO_CONNECT *aNC, int aLayer )
1588 {
1589  bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
1590 
1591  if( drawingShadows && !aNC->IsSelected() )
1592  return;
1593 
1594  m_gal->SetIsStroke( true );
1595  m_gal->SetLineWidth( getLineWidth( aNC, drawingShadows ) );
1596  m_gal->SetStrokeColor( getRenderColor( aNC, LAYER_NOCONNECT, drawingShadows ) );
1597  m_gal->SetIsFill( false );
1598 
1599  VECTOR2D p = aNC->GetPosition();
1600  int delta = aNC->GetSize() / 2;
1601 
1602  m_gal->DrawLine( p + VECTOR2D( -delta, -delta ), p + VECTOR2D( delta, delta ) );
1603  m_gal->DrawLine( p + VECTOR2D( -delta, delta ), p + VECTOR2D( delta, -delta ) );
1604 }
1605 
1606 
1607 void SCH_PAINTER::draw( SCH_BUS_ENTRY_BASE *aEntry, int aLayer )
1608 {
1609  bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
1610 
1611  if( drawingShadows && !aEntry->IsSelected() )
1612  return;
1613 
1614  COLOR4D color = getRenderColor( aEntry, LAYER_WIRE, drawingShadows );
1615 
1616  if( aEntry->Type() == SCH_BUS_BUS_ENTRY_T )
1617  color = getRenderColor( aEntry, LAYER_BUS, drawingShadows );
1618 
1619  m_gal->SetIsStroke( true );
1620  m_gal->SetLineWidth( getLineWidth( aEntry, drawingShadows ) );
1622  m_gal->SetIsFill( false );
1623 
1624  VECTOR2D pos = aEntry->GetPosition();
1625  VECTOR2D endPos = aEntry->m_End();
1626 
1627  m_gal->DrawLine( pos, endPos );
1628 
1629  // Draw dangling symbols:
1630  m_gal->SetLineWidth ( getLineWidth( aEntry, drawingShadows ) );
1631 
1632  if( aEntry->IsDanglingStart() )
1634 
1635  if( aEntry->IsDanglingEnd() )
1637 }
1638 
1639 
1640 void SCH_PAINTER::draw( SCH_BITMAP *aBitmap, int aLayer )
1641 {
1642  m_gal->Save();
1643  m_gal->Translate( aBitmap->GetPosition() );
1644 
1645  // When the image scale factor is not 1.0, we need to modify the actual as the image scale
1646  // factor is similar to a local zoom
1647  double img_scale = aBitmap->GetImageScale();
1648 
1649  if( img_scale != 1.0 )
1650  m_gal->Scale( VECTOR2D( img_scale, img_scale ) );
1651 
1652  if( aLayer == LAYER_DRAW_BITMAPS )
1653  {
1654  m_gal->DrawBitmap( *aBitmap->GetImage() );
1655  }
1656 
1657  if( aLayer == LAYER_SELECTION_SHADOWS )
1658  {
1659  if( aBitmap->IsSelected() || aBitmap->IsBrightened() || aBitmap->IsHighlighted() )
1660  {
1661  COLOR4D color = getRenderColor( aBitmap, LAYER_DRAW_BITMAPS, true );
1662  m_gal->SetIsStroke( true );
1665  m_gal->SetIsFill( false );
1666 
1667  // Draws a bounding box.
1668  VECTOR2D bm_size( aBitmap->GetSize() );
1669  // bm_size is the actual image size in UI.
1670  // but m_gal scale was previously set to img_scale
1671  // so recalculate size relative to this image size.
1672  bm_size.x /= img_scale;
1673  bm_size.y /= img_scale;
1674  VECTOR2D origin( -bm_size.x / 2.0, -bm_size.y / 2.0 );
1675  VECTOR2D end = origin + bm_size;
1676 
1677  m_gal->DrawRectangle( origin, end );
1678  }
1679  }
1680 
1681  m_gal->Restore();
1682 }
1683 
1684 
1685 void SCH_PAINTER::draw( SCH_MARKER *aMarker, int aLayer )
1686 {
1687  bool drawingShadows = aLayer == LAYER_SELECTION_SHADOWS;
1688 
1689  if( drawingShadows && !aMarker->IsSelected() )
1690  return;
1691 
1692  COLOR4D color = getRenderColor( aMarker, aMarker->GetColorLayer(), drawingShadows );
1693 
1694  m_gal->Save();
1695  m_gal->Translate( aMarker->GetPosition() );
1696  m_gal->SetIsFill( !drawingShadows );
1697  m_gal->SetFillColor( color );
1698  m_gal->SetIsStroke( drawingShadows );
1699  m_gal->SetLineWidth( getLineWidth( aMarker, drawingShadows ) );
1701 
1702  SHAPE_LINE_CHAIN polygon;
1703  aMarker->ShapeToPolygon( polygon );
1704 
1705  m_gal->DrawPolygon( polygon );
1706  m_gal->Restore();
1707 }
1708 
1709 
1710 }; // namespace KIGFX
virtual bool Draw(const VIEW_ITEM *, int) override
Function Draw Takes an instance of VIEW_ITEM and passes it to a function that know how to draw the it...
bool IsDangling() const override
Definition: sch_text.h:304
#define TEXT_ANGLE_HORIZ
SCH_PAINTER(GAL *aGal)
CITER next(CITER it)
Definition: ptree.cpp:130
virtual void SetFillColor(const COLOR4D &aColor)
Set the fill color.
void SetFontItalic(const bool aItalic)
Set italic property of current font.
virtual void DrawPolyline(const std::deque< VECTOR2D > &aPointList)
Draw a polyline.
bool IsBold() const
Definition: eda_text.h:167
SCH_FIELD instances are attached to a component and provide a place for the component's value,...
Definition: sch_field.h:52
std::vector< SCH_PIN * > SCH_PIN_PTRS
Definition: sch_component.h:73
bool GetSelectionTextAsBox()
Draw selected text items as box.
float GetLineWidth() const
Get the line width.
#define TARGET_BUSENTRY_RADIUS
Definition: sch_bus_entry.h:35
virtual void DrawRectangle(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a rectangle.
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:184
bool IsMirrored() const
Definition: eda_text.h:173
int GetPinNameOffset()
SCH_LAYER_ID GetColorLayer() const
Definition: sch_marker.cpp:87
int GetOrientation()
Get the display symbol orientation.
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:131
wxPoint GetStartPoint() const
Definition: sch_line.h:97
float m_outlineWidth
Line width used when drawing outlines.
Definition: painter.h:287
bool IsSelected() const
Definition: base_struct.h:225
wxPoint GetEnd() const
Definition: lib_rectangle.h:89
#define TEXT_ANGLE_VERT
const MATRIX3x3D & GetScreenWorldMatrix() const
Get the screen <-> world transformation matrix.
void drawPinDanglingSymbol(const VECTOR2I &aPos, bool aDrawingShadows)
wxPoint GetPosition() const override
Definition: lib_field.h:185
wxPoint GetPosition() const override
Function GetPosition.
to handle and draw images bitmaps
COLOR4D m_layerColors[LAYER_ID_COUNT]
Colors for all layers (normal)
Definition: painter.h:260
Define a symbol library graphical text item.
Definition: lib_text.h:40
int GetOrientation() const
Definition: lib_pin.h:207
void drawDanglingSymbol(const wxPoint &aPos, bool aDrawingShadows)
LIB_PART * GetParent() const
Definition: lib_item.h:185
std::vector< LIB_PIN * > LIB_PINS
Helper for defining a list of pin object pointers.
Definition: lib_item.h:54
wxPoint GetPosition() const override
Function GetPosition.
Definition: sch_marker.h:100
void GetPoly(std::vector< wxPoint > &aOutput, int aMinSegLen=0)
Converts Bezier curve to a polygon.
virtual void SetTextAttributes(const EDA_TEXT *aText)
Loads attributes of the given text (bold/italic/underline/mirrored and so on).
bool IsVisible() const
Definition: eda_text.h:170
GRAPHIC_PINSHAPE GetShape() const
Definition: lib_pin.h:219
virtual void DrawArc(const VECTOR2D &aCenterPoint, double aRadius, double aStartAngle, double aEndAngle)
Draw an arc.
virtual const COLOR4D & GetColor(const VIEW_ITEM *aItem, int aLayer) const override
Function GetColor Returns the color that should be used to draw the specific VIEW_ITEM on the specifi...
Definition: sch_painter.cpp:94
#define DANGLING_SYMBOL_SIZE
Definition: general.h:43
bool IsMoving() const
Definition: base_struct.h:222
int color
Definition: DXF_plotter.cpp:61
Field object used in symbol libraries.
Definition: lib_field.h:59
int GetDefaultLineThickness()
Default line thickness used to draw/plot items having a default thickness line value (i....
bool setDeviceColors(const LIB_ITEM *aItem, int aLayer)
double square(double x)
FILL_T GetFillMode() const
Definition: lib_item.h:315
virtual void DrawBitmap(const BITMAP_BASE &aBitmap)
Draw a bitmap image.
const COLOR4D & GetLayerColor(int aLayer) const
Function GetLayerColor Returns the color used to draw a layer.
Definition: painter.h:216
double GetTextAngle() const
Definition: eda_text.h:158
static int InternalPinDecoSize(const LIB_PIN &aPin)
wxPoint GetPosition() const override
Definition: lib_circle.h:76
COLOR4D WithAlpha(double aAlpha) const
Function WithAlpha Returns a colour with the same colour, but the given alpha.
Definition: color4d.h:248
virtual wxPoint GetSchematicTextOffset() const
Definition: sch_text.cpp:132
void CalcRadiusAngles()
Calculate the radius and angle of an arc using the start, end, and center points.
Definition: lib_arc.cpp:545
#define DASH_MARK_LEN(aLineWidth)
KIGFX::COLOR4D GetBorderColor() const
Definition: sch_sheet.h:290
bool IsBrightened() const
Definition: base_struct.h:228
int GetThickness() const
Return the pen width.
Definition: eda_text.h:148
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:222
Definition: lib_pin.h:58
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
Definition: lib_field.cpp:330
static LIB_PART * dummy()
Used when a LIB_PART is not found in library to draw a dummy shape.
Add new GAL layers here.
VIEW_ITEM - is an abstract base class for deriving all objects that can be added to a VIEW.
Definition: view_item.h:84
wxPoint GetPosition() const override
Function GetPosition.
Definition: sch_bitmap.h:140
virtual void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a line.
int GetPenSize() const override
Function GetPenSize virtual pure.
Definition: sch_sheet.cpp:445
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
void RevertYAxis()
Function RevertYAxis Mirror the rectangle from the X axis (negate Y pos and size)
Definition: eda_rect.h:209
bool IsDangling() const override
Definition: sch_pin.h:88
bool IsHighlighted() const
Definition: base_struct.h:227
VECTOR2< T > GetScale() const
Get the scale components of the matrix.
Definition: matrix3x3.h:269
bool ClipLine(const EDA_RECT *aClipBox, int &x1, int &y1, int &x2, int &y2)
Test if any part of a line falls within the bounds of a rectangle.
#define SET_DC(i)
COLOR4D getRenderColor(const EDA_ITEM *aItem, int aLayer, bool aDrawingShadows)
bool IsVoid() const
Function IsVoid returns true if the field is either empty or holds "~".
Definition: sch_field.cpp:273
void fillIfSelection(int aLayer)
bool IsDanglingEnd() const
Definition: sch_bus_entry.h:52
bool IsDragging() const
Definition: base_struct.h:223
static constexpr int VIEW_MAX_LAYERS
maximum number of layers that may be shown
Definition: view.h:701
GAL * m_gal
Instance of graphic abstraction layer that gives an interface to call commands used to draw (eg.
Definition: painter.h:360
The base class for drawable items used by schematic library components.
Definition: lib_item.h:60
bool IsPowerConnection() const
Return whether this pin forms an implicit power connection: i.e., is hidden and of type POWER_IN.
Definition: lib_pin.h:352
virtual void SetLineWidth(float aLineWidth)
Set the line width.
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition: color4d.h:308
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populates a std::vector with SCH_FIELDs.
KIGFX::COLOR4D GetBackgroundColor() const
Definition: sch_sheet.h:293
Base class for a bus or wire entry.
Definition: sch_bus_entry.h:41
void AddDrawItem(LIB_ITEM *aItem)
Add a new draw aItem to the draw object list.
bool IsItalic() const
Definition: eda_text.h:164
const std::vector< wxPoint > & GetPolyPoints() const
Definition: lib_polyline.h:60
static int ExternalPinDecoSize(const LIB_PIN &aPin)
void GetPins(LIB_PINS &aList, int aUnit=0, int aConvert=0)
Return a list of pin object pointers from the draw item list.
std::vector< SCH_FIELD > & GetFields()
Definition: sch_sheet.h:268
bool ShowPinNames()
int GetSecondRadiusAngle() const
Definition: lib_arc.h:111
const wxPoint GetEnd() const
Definition: eda_rect.h:116
void SetFontBold(const bool aBold)
Set bold property of current font.
void ViewGetLayers(int aLayers[], int &aCount) const override
Function ViewGetLayers() Returns the all the layers within the VIEW the object is painted on.
Definition: lib_field.cpp:355
int GetUnit() const
Definition: lib_item.h:309
int GetTextMarkupFlags()
Definition: gr_text.cpp:55
int GetUnit() const
PAINTER contains all the knowledge about how to draw graphical object onto any particular output devi...
Definition: painter.h:308
bool ShowPinNumbers()
for transforming drawing coordinates for a wxDC device context.
Definition: transform.h:45
virtual int GetPenSize() const
Function GetPenSize virtual pure.
Definition: sch_item.h:243
wxSize GetSize() const
Definition: sch_bitmap.cpp:125
int Clamp_Text_PenSize(int aPenSize, int aSize, bool aBold)
Function Clamp_Text_PenSize Don't allow text to become cluttered up in its own fatness.
Definition: gr_text.cpp:81
bool IsDanglingStart() const
Definition: sch_bus_entry.h:51
void SetEnd(const wxPoint &aPoint)
Definition: lib_arc.h:117
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:257
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:183
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:111
SCH_SHEET_PATH * g_CurrentSheet
With the new connectivity algorithm, many more places than before want to know what the current sheet...
VECTOR2< double > VECTOR2D
Definition: vector2d.h:593
BITMAP_BASE * GetImage()
Definition: sch_bitmap.h:59
virtual void SetIsFill(bool aIsFillEnabled)
Enable/disable fill.
wxPoint GetPosition() const override
Function GetPosition.
Definition: sch_junction.h:99
wxString const GetElectricalTypeName() const
return a translated string for messages giving the electrical type of the pin.
Definition: lib_pin.h:259
const wxString & GetName() const
Definition: lib_pin.h:152
PLOT_DASH_TYPE GetLineStyle() const
Definition: sch_line.cpp:277
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
Class LIB_PIN definition.
bool IsEndDangling() const
Definition: sch_line.h:192
const wxSize & GetTextSize() const
Definition: eda_text.h:223
const wxPoint GetPosition() const
Definition: eda_rect.h:115
bool IsResized() const
Definition: base_struct.h:226
int GetSize() const
int GetSelectionThickness()
Selection highlight thickness.
wxPoint GetStart() const
Definition: lib_arc.h:113
#define DOT_MARK_LEN(aLineWidth)
void ShapeToPolygon(SHAPE_LINE_CHAIN &aPolygon) const
Returns the shape polygon in internal units in a SHAPE_LINE_CHAIN the coordinates are relatives to th...
Define a library symbol object.
void strokeText(const wxString &aText, const VECTOR2D &aPosition, double aRotationAngle)
EDA_ITEM * GetParent() const
Definition: base_struct.h:217
const std::vector< wxPoint > & GetPoints() const
Definition: lib_bezier.h:71
void CreateGraphicShape(std::vector< wxPoint > &aPoints, const wxPoint &aPos) override
Calculate the graphic shape (a polygon) associated to the text.
Definition: sch_text.cpp:859
virtual void StrokeText(const wxString &aText, const VECTOR2D &aPosition, double aRotationAngle, int aMarkupFlags=0)
Draws a vector type text using preloaded Newstroke font.
#define OUTSIDE
void triLine(const VECTOR2D &a, const VECTOR2D &b, const VECTOR2D &c)
a few functions useful in geometry calculations.
#define F(x, y, z)
Definition: md5_hash.cpp:15
LABEL_SPIN_STYLE GetLabelSpinStyle() const
Definition: sch_text.h:237
bool IsVisible() const
Return the visibility status of the draw object.
Definition: lib_pin.h:346
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet.h:84
void SetTextMirrored(const bool aMirrored)
Set a mirrored property of text.
int GetRadius() const
Definition: lib_circle.h:92
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
Definition: sch_text.cpp:422
std::unique_ptr< LIB_PART > & GetPartRef()
wxPoint m_End() const
float getTextThickness(const SCH_TEXT *aItem, bool aDrawingShadows)
int GetNameTextSize() const
Definition: lib_pin.h:178
std::unique_ptr< LIB_PART > Flatten() const
Return a flattened symbol inheritance to the caller.
void SetVerticalJustify(const EDA_TEXT_VJUSTIFY_T aVerticalJustify)
Set the vertical justify for text drawing.
static VECTOR2D mapCoords(const wxPoint &aCoord)
wxPoint GetPosition() const override
Function GetPosition.
Definition: sch_sheet.h:565
int GetConvert() const
Definition: lib_item.h:312
Object to handle a bitmap image that can be inserted in a schematic.
Definition: sch_bitmap.h:42
SCH_CONNECTION * Connection(const SCH_SHEET_PATH &aPath) const
Retrieves the connection associated with this object in the given sheet Note: the returned value can ...
Definition: sch_item.cpp:128
virtual void Scale(const VECTOR2D &aScale)
Scale the context.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:215
int GetRadius() const
Definition: lib_arc.h:105
wxPoint GetPosition() const override
Definition: lib_pin.h:432
static void orientPart(LIB_PART *part, int orientation)
SCH_LAYER_ID GetLayer() const
Function GetLayer returns the layer this item is on.
Definition: sch_item.h:224
bool GetSelectionFillShapes()
Draw selected shapes as filled or not.
std::vector< SCH_SHEET_PIN * > & GetPins()
Definition: sch_sheet.h:357
double GetTextAngleRadians() const
Definition: eda_text.h:161
void Normalize()
Function Normalize ensures that the height ant width are positive.
const wxString & GetNumber() const
Definition: lib_pin.h:180
void CreateGraphicShape(std::vector< wxPoint > &aPoints, const wxPoint &Pos) override
Calculate the graphic shape (a polygon) associated to the text.
Definition: sch_text.cpp:1105
ELECTRICAL_PINTYPE GetType() const
Get the electrical type of the pin.
Definition: lib_pin.h:235
void LoadColors(const COLOR_SETTINGS *aSettings) override
Definition: sch_painter.cpp:82
COLOR4D GetColor(int aLayer) const
virtual void SetStrokeColor(const COLOR4D &aColor)
Set the stroke color.
Bezier curves to polygon converter.
Definition: bezier_curves.h:35
COLOR4D m_backgroundColor
The background color.
Definition: painter.h:292
virtual int GetPenSize() const =0
int GetNumberTextSize() const
Definition: lib_pin.h:205
virtual void Restore()
Restore the context.
virtual void DrawPolygon(const std::deque< VECTOR2D > &aPointList)
Draw a polygon.
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:38
#define IS_DANGLING
indicates a pin is dangling
Definition: base_struct.h:149
virtual void DrawCircle(const VECTOR2D &aCenterPoint, double aRadius)
Draw a circle using world coordinates.
const EDA_RECT GetBoundingBox() const override
Definition: lib_text.cpp:370
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes.
Definition: sch_field.cpp:204
bool isUnitAndConversionShown(const LIB_ITEM *aItem)
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
SHAPE_LINE_CHAIN.
bool GetSelectionDrawChildItems()
Draw selected child items or not.
#define HANDLE_ITEM(type_id, type_name)
bool IsStartDangling() const
Definition: sch_line.h:191
double GetImageScale() const
Definition: sch_bitmap.h:71
bool IsAlias() const
wxPoint GetEnd() const
Definition: lib_arc.h:116
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
const wxString GetFullyQualifiedText() const
Function GetFullyQualifiedText returns the fully qualified field text by allowing for the part suffix...
Definition: sch_field.cpp:76
SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:99
float getLineWidth(const LIB_ITEM *aItem, bool aDrawingShadows)
wxPoint GetPosition() const override
Function GetPosition.
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:61
#define DASH_GAP_LEN(aLineWidth)
#define TARGET_PIN_RADIUS
Definition: lib_pin.h:46
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: base_struct.h:166
wxPoint Centre() const
Definition: eda_rect.h:62
void ClearFlags(STATUS_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
Definition: base_struct.h:258
const wxPoint & GetTextPos() const
Definition: eda_text.h:232
int GetFirstRadiusAngle() const
Definition: lib_arc.h:108
void SetGlyphSize(const VECTOR2D aGlyphSize)
Set the font glyph size.
void SetStart(const wxPoint &aPoint)
Definition: lib_arc.h:114
int GetConvert() const
void draw(LIB_RECTANGLE *aRect, int aLayer)
virtual wxString GetShownText() const
Return the string actually shown after processing of the base text.
Definition: eda_text.h:129
virtual void Save()
Save the context.
void SetHorizontalJustify(const EDA_TEXT_HJUSTIFY_T aHorizontalJustify)
Set the horizontal justify for text drawing.
bool MapAngles(int *aAngle1, int *aAngle2) const
Calculate new angles according to the transform.
Definition: transform.cpp:81
Definition for part library class.
bool HasFlag(STATUS_FLAGS aFlag)
Definition: base_struct.h:260
#define INSIDE
not connected (must be left open)
bool IsBus() const
wxPoint GetParentPosition() const
Definition: sch_field.cpp:553
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:259
static int GetEffectiveSymbolSize()
virtual void Translate(const VECTOR2D &aTranslation)
Translate the context.
virtual void SetIsStroke(bool aIsStrokeEnabled)
Enable/disable stroked outlines.
#define PIN_TEXT_MARGIN
int GetLength()
Definition: lib_pin.h:285
SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:147
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:123
wxSize GetSize()
Definition: sch_sheet.h:284
wxPoint GetPosition() const override
Definition: lib_rectangle.h:76
SCH_PIN_PTRS GetSchPins(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieves a list of the SCH_PINs for the given sheet path.
SCH_RENDER_SETTINGS m_schSettings
Definition: sch_painter.h:177
KICAD_T Type() const
Function Type()
Definition: base_struct.h:212
Class GAL is the abstract interface for drawing on a 2D-surface.
Define a bezier curve graphic body item.
Definition: lib_bezier.h:34
wxPoint GetPosition() const override
Definition: lib_arc.h:92
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:40
wxPoint GetPosition() const override
Function GetPosition.
wxPoint GetEndPoint() const
Definition: sch_line.h:100