KiCad PCB EDA Suite
class_gerber_draw_item.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) 1992-2017 <Jean-Pierre Charras>
5  * Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
29 #include <fctsys.h>
30 #include <gr_basic.h>
31 #include <common.h>
32 #include <trigo.h>
33 #include <class_drawpanel.h>
34 #include <msgpanel.h>
35 #include <gerbview_frame.h>
37 
38 #include <class_gerber_draw_item.h>
41 
42 
45 {
46  m_GerberImageFile = aGerberImageFile;
48  m_Flashed = false;
49  m_DCode = 0;
50  m_UnitsMetric = false;
51  m_LayerNegative = false;
52  m_swapAxis = false;
53  m_mirrorA = false;
54  m_mirrorB = false;
55  m_drawScale.x = m_drawScale.y = 1.0;
56  m_lyrRotation = 0;
57 
58  if( m_GerberImageFile )
60 }
61 
62 
64 {
65 }
66 
67 
69 {
70  m_netAttributes = aNetAttributes;
71 
74  m_GerberImageFile->m_ComponentsList.insert( std::make_pair( m_netAttributes.m_Cmpref, 0 ) );
75 
77  m_GerberImageFile->m_NetnamesList.insert( std::make_pair( m_netAttributes.m_Netname, 0 ) );
78 }
79 
80 
82 {
83  // returns the layer this item is on, or 0 if the m_GerberImageFile is NULL.
85 }
86 
87 
88 wxPoint GERBER_DRAW_ITEM::GetABPosition( const wxPoint& aXYPosition ) const
89 {
90  /* Note: RS274Xrevd_e is obscure about the order of transforms:
91  * For instance: Rotation must be made after or before mirroring ?
92  * Note: if something is changed here, GetYXPosition must reflect changes
93  */
94  wxPoint abPos = aXYPosition + m_GerberImageFile->m_ImageJustifyOffset;
95 
96  if( m_swapAxis )
97  std::swap( abPos.x, abPos.y );
98 
100  abPos.x = KiROUND( abPos.x * m_drawScale.x );
101  abPos.y = KiROUND( abPos.y * m_drawScale.y );
102  double rotation = m_lyrRotation * 10 + m_GerberImageFile->m_ImageRotation * 10;
103 
104  if( rotation )
105  RotatePoint( &abPos, -rotation );
106 
107  // Negate A axis if mirrored
108  if( m_mirrorA )
109  abPos.x = -abPos.x;
110 
111  // abPos.y must be negated when no mirror, because draw axis is top to bottom
112  if( !m_mirrorB )
113  abPos.y = -abPos.y;
114  return abPos;
115 }
116 
117 
119 {
120  // do the inverse transform made by GetABPosition
121  wxPoint xyPos = aABPosition;
122 
123  if( m_mirrorA )
124  xyPos.x = -xyPos.x;
125 
126  if( !m_mirrorB )
127  xyPos.y = -xyPos.y;
128 
129  double rotation = m_lyrRotation * 10 + m_GerberImageFile->m_ImageRotation * 10;
130 
131  if( rotation )
132  RotatePoint( &xyPos, rotation );
133 
134  xyPos.x = KiROUND( xyPos.x / m_drawScale.x );
135  xyPos.y = KiROUND( xyPos.y / m_drawScale.y );
137 
138  if( m_swapAxis )
139  std::swap( xyPos.x, xyPos.y );
140 
141  return xyPos - m_GerberImageFile->m_ImageJustifyOffset;
142 }
143 
144 
146 {
148  m_swapAxis = m_GerberImageFile->m_SwapAxis; // false if A = X, B = Y;
149 
150  // true if A =Y, B = Y
151  m_mirrorA = m_GerberImageFile->m_MirrorA; // true: mirror / axe A
152  m_mirrorB = m_GerberImageFile->m_MirrorB; // true: mirror / axe B
153  m_drawScale = m_GerberImageFile->m_Scale; // A and B scaling factor
154  m_layerOffset = m_GerberImageFile->m_Offset; // Offset from OF command
155 
156  // Rotation from RO command:
159 }
160 
161 
163 {
164  switch( m_Shape )
165  {
166  case GBR_SEGMENT:
167  return _( "Line" );
168 
169  case GBR_ARC:
170  return _( "Arc" );
171 
172  case GBR_CIRCLE:
173  return _( "Circle" );
174 
175  case GBR_SPOT_OVAL:
176  return wxT( "spot_oval" );
177 
178  case GBR_SPOT_CIRCLE:
179  return wxT( "spot_circle" );
180 
181  case GBR_SPOT_RECT:
182  return wxT( "spot_rect" );
183 
184  case GBR_SPOT_POLY:
185  return wxT( "spot_poly" );
186 
187  case GBR_POLYGON:
188  return wxT( "polygon" );
189 
190  case GBR_SPOT_MACRO:
191  {
192  wxString name = wxT( "apt_macro" );
193  D_CODE* dcode = GetDcodeDescr();
194 
195  if( dcode && dcode->GetMacro() )
196  name << wxT(" ") << dcode->GetMacro()->name;
197 
198  return name;
199  }
200 
201  default:
202  return wxT( "??" );
203  }
204 }
205 
206 
208 {
209  if( (m_DCode < FIRST_DCODE) || (m_DCode > LAST_DCODE) )
210  return NULL;
211 
212  if( m_GerberImageFile == NULL )
213  return NULL;
214 
216 }
217 
218 
220 {
221  // return a rectangle which is (pos,dim) in nature. therefore the +1
222  EDA_RECT bbox( m_Start, wxSize( 1, 1 ) );
223  D_CODE* code = GetDcodeDescr();
224 
225  // TODO(JE) GERBER_DRAW_ITEM maybe should actually be a number of subclasses.
226  // Until/unless that is changed, we need to do different things depending on
227  // what is actually being represented by this GERBER_DRAW_ITEM.
228 
229  switch( m_Shape )
230  {
231  case GBR_POLYGON:
232  {
233  auto bb = m_Polygon.BBox();
234  bbox.Inflate( bb.GetWidth() / 2, bb.GetHeight() / 2 );
235  bbox.SetOrigin( bb.GetOrigin().x, bb.GetOrigin().y );
236  break;
237  }
238 
239  case GBR_CIRCLE:
240  {
241  double radius = GetLineLength( m_Start, m_End );
242  bbox.Inflate( radius, radius );
243  break;
244  }
245 
246  case GBR_ARC:
247  {
248  // Note: using a larger-than-necessary BB to simplify computation
249  double radius = GetLineLength( m_Start, m_ArcCentre );
250  bbox.Inflate( radius, radius );
251  break;
252  }
253 
254  case GBR_SPOT_CIRCLE:
255  {
256  int radius = code->m_Size.x >> 1;
257  bbox.Inflate( radius, radius );
258  break;
259  }
260 
261  case GBR_SPOT_RECT:
262  {
263  bbox.Inflate( code->m_Size.x / 2, code->m_Size.y / 2 );
264  break;
265  }
266 
267  case GBR_SPOT_OVAL:
268  {
269  bbox.Inflate( code->m_Size.x, code->m_Size.y );
270  break;
271  }
272 
273  case GBR_SPOT_POLY:
274  {
275  if( code->m_Polygon.OutlineCount() == 0 )
276  code->ConvertShapeToPolygon();
277 
278  bbox.Inflate( code->m_Polygon.BBox().GetWidth() / 2, code->m_Polygon.BBox().GetHeight() / 2 );
279  break;
280  }
281  case GBR_SPOT_MACRO:
282  {
283  bbox = code->GetMacro()->GetBoundingBox();
284  break;
285  }
286 
287  case GBR_SEGMENT:
288  {
289  if( code && code->m_Shape == APT_RECT )
290  {
291  if( m_Polygon.OutlineCount() > 0 )
292  {
293  auto bb = m_Polygon.BBox();
294  bbox.Inflate( bb.GetWidth() / 2, bb.GetHeight() / 2 );
295  bbox.SetOrigin( bb.GetOrigin().x, bb.GetOrigin().y );
296  }
297  }
298  else
299  {
300  int radius = ( m_Size.x + 1 ) / 2;
301 
302  int ymax = std::max( m_Start.y, m_End.y ) + radius;
303  int xmax = std::max( m_Start.x, m_End.x ) + radius;
304 
305  int ymin = std::min( m_Start.y, m_End.y ) - radius;
306  int xmin = std::min( m_Start.x, m_End.x ) - radius;
307 
308  bbox = EDA_RECT( wxPoint( xmin, ymin ), wxSize( xmax - xmin + 1, ymax - ymin + 1 ) );
309  }
310 
311  break;
312  }
313  default:
314  wxASSERT_MSG( false, wxT( "GERBER_DRAW_ITEM shape is unknown!" ) );
315  break;
316  }
317 
318  // calculate the corners coordinates in current gerber axis orientations
319  wxPoint org = GetABPosition( bbox.GetOrigin() );
320  wxPoint end = GetABPosition( bbox.GetEnd() );
321 
322  // Set the corners position:
323  bbox.SetOrigin( org );
324  bbox.SetEnd( end );
325  bbox.Normalize();
326 
327  return bbox;
328 }
329 
330 
331 void GERBER_DRAW_ITEM::MoveAB( const wxPoint& aMoveVector )
332 {
333  wxPoint xymove = GetXYPosition( aMoveVector );
334 
335  m_Start += xymove;
336  m_End += xymove;
337  m_ArcCentre += xymove;
338 
339  if( m_Polygon.OutlineCount() > 0 )
340  {
341  for( auto it = m_Polygon.Iterate( 0 ); it; ++it )
342  *it += xymove;
343  }
344 }
345 
346 
347 void GERBER_DRAW_ITEM::MoveXY( const wxPoint& aMoveVector )
348 {
349  m_Start += aMoveVector;
350  m_End += aMoveVector;
351  m_ArcCentre += aMoveVector;
352 
353  if( m_Polygon.OutlineCount() > 0 )
354  {
355  for( auto it = m_Polygon.Iterate( 0 ); it; ++it )
356  *it += aMoveVector;
357  }
358 }
359 
360 
362 {
364 
365  // if isClear is true, this item has negative shape
366  return isClear;
367 }
368 
369 
370 void GERBER_DRAW_ITEM::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode,
371  const wxPoint& aOffset, GBR_DISPLAY_OPTIONS* aDrawOptions )
372 {
373  // used when a D_CODE is not found. default D_CODE to draw a flashed item
374  static D_CODE dummyD_CODE( 0 );
375  bool isFilled;
376  int radius;
377  int halfPenWidth;
378  static bool show_err;
379  D_CODE* d_codeDescr = GetDcodeDescr();
380 
381  if( d_codeDescr == NULL )
382  d_codeDescr = &dummyD_CODE;
383 
385 
386  if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) )
387  color.SetToLegacyHighlightColor();
388 
389  /* isDark is true if flash is positive and should use a drawing
390  * color other than the background color, else use the background color
391  * when drawing so that an erasure happens.
392  */
394 
395  if( !isDark )
396  {
397  // draw in background color ("negative" color)
398  color = aDrawOptions->m_NegativeDrawColor;
399  }
400 
401  GRSetDrawMode( aDC, aDrawMode );
402 
403  isFilled = aDrawOptions->m_DisplayLinesFill;
404 
405  switch( m_Shape )
406  {
407  case GBR_POLYGON:
408  isFilled = aDrawOptions->m_DisplayPolygonsFill;
409 
410  if( !isDark )
411  isFilled = true;
412 
413  DrawGbrPoly( aPanel->GetClipBox(), aDC, color, aOffset, isFilled );
414  break;
415 
416  case GBR_CIRCLE:
417  radius = KiROUND( GetLineLength( m_Start, m_End ) );
418 
419  halfPenWidth = m_Size.x >> 1;
420 
421  if( !isFilled )
422  {
423  // draw the border of the pen's path using two circles, each as narrow as possible
424  GRCircle( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
425  radius - halfPenWidth, 0, color );
426  GRCircle( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
427  radius + halfPenWidth, 0, color );
428  }
429  else // Filled mode
430  {
431  GRCircle( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
432  radius, m_Size.x, color );
433  }
434  break;
435 
436  case GBR_ARC:
437  // Currently, arcs plotted with a rectangular aperture are not supported.
438  // a round pen only is expected.
439 
440 #if 0 // for arc debug only
441  GRLine( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
443  GRLine( aPanel->GetClipBox(), aDC, GetABPosition( m_End ),
445 #endif
446 
447  if( !isFilled )
448  {
449  GRArc1( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
451  0, color );
452  }
453  else
454  {
455  GRArc1( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
457  m_Size.x, color );
458  }
459 
460  break;
461 
462  case GBR_SPOT_CIRCLE:
463  case GBR_SPOT_RECT:
464  case GBR_SPOT_OVAL:
465  case GBR_SPOT_POLY:
466  case GBR_SPOT_MACRO:
467  isFilled = aDrawOptions->m_DisplayFlashedItemsFill;
468  d_codeDescr->DrawFlashedShape( this, aPanel->GetClipBox(), aDC, color,
469  m_Start, isFilled );
470  break;
471 
472  case GBR_SEGMENT:
473  /* Plot a line from m_Start to m_End.
474  * Usually, a round pen is used, but some gerber files use a rectangular pen
475  * In fact, any aperture can be used to plot a line.
476  * currently: only a square pen is handled (I believe using a polygon gives a strange plot).
477  */
478  if( d_codeDescr->m_Shape == APT_RECT )
479  {
480  if( m_Polygon.OutlineCount() == 0 )
482 
483  DrawGbrPoly( aPanel->GetClipBox(), aDC, color, aOffset, isFilled );
484  }
485  else
486  {
487  if( !isFilled )
488  {
489  GRCSegm( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
490  GetABPosition( m_End ), m_Size.x, color );
491  }
492  else
493  {
494  GRFilledSegment( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
495  GetABPosition( m_End ), m_Size.x, color );
496  }
497  }
498 
499  break;
500 
501  default:
502  if( !show_err )
503  {
504  wxMessageBox( wxT( "Trace_Segment() type error" ) );
505  show_err = true;
506  }
507 
508  break;
509  }
510 }
511 
512 
514 {
517 
518  wxPoint start = m_Start;
519  wxPoint end = m_End;
520 
521  // make calculations more easy if ensure start.x < end.x
522  // (only 2 quadrants to consider)
523  if( start.x > end.x )
524  std::swap( start, end );
525 
526  // calculate values relative to start point:
527  wxPoint delta = end - start;
528 
529  // calculate corners for the first quadrant only (delta.x and delta.y > 0 )
530  // currently, delta.x already is > 0.
531  // make delta.y > 0
532  bool change = delta.y < 0;
533 
534  if( change )
535  delta.y = -delta.y;
536 
537  // Now create the full polygon.
538  // Due to previous changes, the shape is always something like
539  // 3 4
540  // 2 5
541  // 1 6
542  wxPoint corner;
543  corner.x -= m_Size.x/2;
544  corner.y -= m_Size.y/2;
545  wxPoint close = corner;
546  m_Polygon.Append( VECTOR2I( corner ) ); // Lower left corner, start point (1)
547  corner.y += m_Size.y;
548  m_Polygon.Append( VECTOR2I( corner ) ); // upper left corner, start point (2)
549 
550  if( delta.x || delta.y)
551  {
552  corner += delta;
553  m_Polygon.Append( VECTOR2I( corner ) ); // upper left corner, end point (3)
554  }
555 
556  corner.x += m_Size.x;
557  m_Polygon.Append( VECTOR2I( corner ) ); // upper right corner, end point (4)
558  corner.y -= m_Size.y;
559  m_Polygon.Append( VECTOR2I( corner ) ); // lower right corner, end point (5)
560 
561  if( delta.x || delta.y )
562  {
563  corner -= delta;
564  m_Polygon.Append( VECTOR2I( corner ) ); // lower left corner, start point (6)
565  }
566 
567  m_Polygon.Append( VECTOR2I( close ) ); // close the shape
568 
569  // Create final polygon:
570  for( auto it = m_Polygon.Iterate( 0 ); it; ++it )
571  {
572  if( change )
573  ( *it ).y = -( *it ).y;
574 
575  *it += start;
576  }
577 }
578 
579 
581  wxDC* aDC,
582  COLOR4D aColor,
583  const wxPoint& aOffset,
584  bool aFilledShape )
585 {
586  std::vector<wxPoint> points;
587  SHAPE_LINE_CHAIN& poly = m_Polygon.Outline( 0 );
588  int pointCount = poly.PointCount() - 1;
589 
590  points.reserve( pointCount );
591 
592  for( int ii = 0; ii < pointCount; ii++ )
593  {
594  wxPoint p( poly.Point( ii ).x, poly.Point( ii ).y );
595  points[ii] = p + aOffset;
596  points[ii] = GetABPosition( points[ii] );
597  }
598 
599  GRClosedPoly( aClipBox, aDC, pointCount, &points[0], aFilledShape, aColor, aColor );
600 }
601 
602 
603 void GERBER_DRAW_ITEM::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
604 {
605  wxString msg;
606  wxString text;
607 
608  msg = ShowGBRShape();
609  aList.push_back( MSG_PANEL_ITEM( _( "Type" ), msg, DARKCYAN ) );
610 
611  // Display D_Code value with its attributes:
612  msg.Printf( _( "D Code %d" ), m_DCode );
613  D_CODE* apertDescr = GetDcodeDescr();
614 
615  if( !apertDescr || apertDescr->m_AperFunction.IsEmpty() )
616  text = _( "No attribute" );
617  else
618  text = apertDescr->m_AperFunction;
619 
620  aList.push_back( MSG_PANEL_ITEM( msg, text, RED ) );
621 
622  // Display graphic layer name
624  aList.push_back( MSG_PANEL_ITEM( _( "Graphic Layer" ), msg, DARKGREEN ) );
625 
626  // Display item rotation
627  // The full rotation is Image rotation + m_lyrRotation
628  // but m_lyrRotation is specific to this object
629  // so we display only this parameter
630  msg.Printf( wxT( "%f" ), m_lyrRotation );
631  aList.push_back( MSG_PANEL_ITEM( _( "Rotation" ), msg, BLUE ) );
632 
633  // Display item polarity (item specific)
634  msg = m_LayerNegative ? _("Clear") : _("Dark");
635  aList.push_back( MSG_PANEL_ITEM( _( "Polarity" ), msg, BLUE ) );
636 
637  // Display mirroring (item specific)
638  msg.Printf( wxT( "A:%s B:%s" ),
639  m_mirrorA ? _("Yes") : _("No"),
640  m_mirrorB ? _("Yes") : _("No"));
641  aList.push_back( MSG_PANEL_ITEM( _( "Mirror" ), msg, DARKRED ) );
642 
643  // Display AB axis swap (item specific)
644  msg = m_swapAxis ? wxT( "A=Y B=X" ) : wxT( "A=X B=Y" );
645  aList.push_back( MSG_PANEL_ITEM( _( "AB axis" ), msg, DARKRED ) );
646 
647  // Display net info, if exists
649  return;
650 
651  // Build full net info:
652  wxString net_msg;
653  wxString cmp_pad_msg;
654 
656  {
657  net_msg = _( "Net:" );
658  net_msg << " ";
659 
660  if( m_netAttributes.m_Netname.IsEmpty() )
661  net_msg << "<no net name>";
662  else
663  net_msg << m_netAttributes.m_Netname;
664  }
665 
667  {
668  cmp_pad_msg.Printf( _( "Cmp: %s; Pad: %s" ),
671  }
672 
674  {
675  cmp_pad_msg = _( "Cmp:" );
676  cmp_pad_msg << " " << m_netAttributes.m_Cmpref;
677  }
678 
679  aList.push_back( MSG_PANEL_ITEM( net_msg, cmp_pad_msg, DARKCYAN ) );
680 }
681 
682 
683 bool GERBER_DRAW_ITEM::HitTest( const wxPoint& aRefPos ) const
684 {
685  // calculate aRefPos in XY gerber axis:
686  wxPoint ref_pos = GetXYPosition( aRefPos );
687 
688  // TODO: a better analyze of the shape (perhaps create a D_CODE::HitTest for flashed items)
689  int radius = std::min( m_Size.x, m_Size.y ) >> 1;
690 
691  SHAPE_POLY_SET poly;
692 
693  switch( m_Shape )
694  {
695  case GBR_POLYGON:
696  poly = m_Polygon;
697  return poly.Contains( VECTOR2I( ref_pos ), 0 );
698  break;
699 
700  case GBR_SPOT_POLY:
701  poly = GetDcodeDescr()->m_Polygon;
702  poly.Move( m_Start );
703  return poly.Contains( VECTOR2I( ref_pos ), 0 );
704  break;
705 
706  case GBR_SPOT_RECT:
707  return GetBoundingBox().Contains( aRefPos );
708  break;
709 
710  case GBR_SPOT_MACRO:
711  // Aperture macro polygons are already in absolute coordinates
712  poly = GetDcodeDescr()->GetMacro()->m_shape;
713  for( int i = 0; i < poly.OutlineCount(); ++i )
714  {
715  if( poly.Contains( VECTOR2I( aRefPos ), i ) )
716  return true;
717  }
718  return false;
719  break;
720  }
721 
722  if( m_Flashed )
723  return HitTestPoints( m_Start, ref_pos, radius );
724  else
725  return TestSegmentHit( ref_pos, m_Start, m_End, radius );
726 }
727 
728 
729 bool GERBER_DRAW_ITEM::HitTest( const EDA_RECT& aRefArea ) const
730 {
731  wxPoint pos = GetABPosition( m_Start );
732 
733  if( aRefArea.Contains( pos ) )
734  return true;
735 
736  pos = GetABPosition( m_End );
737 
738  if( aRefArea.Contains( pos ) )
739  return true;
740 
741  return false;
742 }
743 
744 
745 #if defined(DEBUG)
746 
747 void GERBER_DRAW_ITEM::Show( int nestLevel, std::ostream& os ) const
748 {
749  NestedSpace( nestLevel, os ) << '<' << GetClass().Lower().mb_str() <<
750 
751  " shape=\"" << m_Shape << '"' <<
752  " addr=\"" << std::hex << this << std::dec << '"' <<
753  " layer=\"" << GetLayer() << '"' <<
754  " size=\"" << m_Size << '"' <<
755  " flags=\"" << m_Flags << '"' <<
756  " status=\"" << GetStatus() << '"' <<
757  "<start" << m_Start << "/>" <<
758  "<end" << m_End << "/>";
759 
760  os << "</" << GetClass().Lower().mb_str() << ">\n";
761 }
762 
763 #endif
764 
765 
766 void GERBER_DRAW_ITEM::ViewGetLayers( int aLayers[], int& aCount ) const
767 {
768  aCount = 2;
769 
770  aLayers[0] = GERBER_DRAW_LAYER( GetLayer() );
771  aLayers[1] = GERBER_DCODE_LAYER( aLayers[0] );
772 }
773 
774 
776 {
777  EDA_RECT bbox = GetBoundingBox();
778  return BOX2I( VECTOR2I( bbox.GetOrigin() ),
779  VECTOR2I( bbox.GetSize() ) );
780 }
781 
782 
783 unsigned int GERBER_DRAW_ITEM::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
784 {
785  // DCodes will be shown only if zoom is appropriate
786  if( IsDCodeLayer( aLayer ) )
787  {
788  return ( 400000 / ( m_Size.x + 1 ) );
789  }
790 
791  // Other layers are shown without any conditions
792  return 0;
793 }
794 
795 
796 SEARCH_RESULT GERBER_DRAW_ITEM::Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] )
797 {
798  KICAD_T stype = *scanTypes;
799 
800  // If caller wants to inspect my type
801  if( stype == Type() )
802  {
803  if( SEARCH_QUIT == inspector( this, testData ) )
804  return SEARCH_QUIT;
805  }
806 
807  return SEARCH_CONTINUE;
808 }
809 
810 
812 {
813  wxString text, layerName;
814 
816 
817  text.Printf( _( "%s (D%d) on layer %d: %s" ), ShowGBRShape(), m_DCode,
818  GetLayer() + 1, layerName );
819 
820  return text;
821 }
Definition: colors.h:57
COLOR4D GetPositiveDrawColor() const
void SetLayerParameters()
Function SetLayerParameters Initialize parameters from Image and Layer parameters found in the gerber...
KICAD_T Type() const
Function Type()
Definition: base_struct.h:212
void DrawGbrPoly(EDA_RECT *aClipBox, wxDC *aDC, COLOR4D aColor, const wxPoint &aOffset, bool aFilledShape)
Function DrawGbrPoly a helper function used to draw the polygon stored in m_PolyCorners.
bool m_DisplayPolygonsFill
Option to draw polygons (filled/sketch)
BOX2< VECTOR2I > BOX2I
Definition: box2.h:468
virtual unsigned int ViewGetLOD(int aLayer, KIGFX::VIEW *aView) const override
bool IsDCodeLayer(int aLayer)
wxString name
The name of the aperture macro.
wxString GetClass() const override
Function GetClass returns the class name.
double GetLineLength(const wxPoint &aPointA, const wxPoint &aPointB)
Function GetLineLength returns the length of a line segment defined by aPointA and aPointB...
Definition: trigo.h:183
D_CODE * GetDCODE(int aDCODE) const
Function GetDCODE returns a pointer to the D_CODE within this GERBER for the given aDCODE...
void MoveAB(const wxPoint &aMoveVector)
Function MoveAB move this object.
void GRSetDrawMode(wxDC *DC, GR_DRAWMODE draw_mode)
Definition: gr_basic.cpp:290
static int KiROUND(double v)
KiROUND rounds a floating point number to an int using "round halfway cases away from zero"...
Definition: common.h:107
print info associated to a component (TO.C attribute)
wxSize m_Size
Horizontal and vertical dimensions.
Definition: dcode.h:94
const wxString GetDisplayName(int aIdx, bool aNameOnly=false)
bool HasNegativeItems()
Function HasNegativeItems.
void GetMsgPanelInfo(std::vector< MSG_PANEL_ITEM > &aList) override
Function GetMsgPanelInfo populates aList of MSG_PANEL_ITEM objects with it's internal state for displ...
int PointCount() const
Function PointCount()
bool Contains(const wxPoint &aPoint) const
Function Contains.
APERTURE_T m_Shape
shape ( Line, rectangle, circle , oval .. )
Definition: dcode.h:95
void GRLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color)
Definition: gr_basic.cpp:352
virtual const BOX2I ViewBBox() const override
Class GERBER_FILE_IMAGE holds the Image data and parameters for one gerber file and layer parameters ...
GERBER_DRAW_ITEM(GERBER_FILE_IMAGE *aGerberparams)
wxString m_Cmpref
the component reference parent of the data
void SetOrigin(const wxPoint &pos)
void GRCSegm(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, int aPenSize, COLOR4D Color)
Definition: gr_basic.cpp:481
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
void SetNetAttributes(const GBR_NETLIST_METADATA &aNetAttributes)
ITERATOR Iterate(int aFirst, int aLast, bool aIterateHoles=false)
Function Iterate returns an object to iterate through the points of the polygons between aFirst and a...
int OutlineCount() const
Returns the number of outlines in the set
this class handle info which can be added in a gerber file as attribute of an obtect the GBR_INFO_TYP...
STATUS_FLAGS GetStatus() const
Definition: base_struct.h:264
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590
SHAPE_POLY_SET m_Polygon
virtual void ViewGetLayers(int aLayers[], int &aCount) const override
SEARCH_RESULT Visit(INSPECTOR inspector, void *testData, const KICAD_T scanTypes[]) override
>
void GRClosedPoly(EDA_RECT *ClipBox, wxDC *DC, int n, wxPoint Points[], bool Fill, COLOR4D Color, COLOR4D BgColor)
Function GRClosedPoly draws a closed polygon onto the drawing context aDC and optionally fills and/or...
Definition: gr_basic.cpp:777
static const int delta[8][2]
Definition: solve.cpp:112
Definition: dcode.h:52
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:90
Definition: colors.h:54
bool m_DisplayLinesFill
Option to draw line items (filled/sketch)
virtual wxString GetSelectMenuText() const override
Function GetSelectMenuText returns the text to display to be used in the selection clarification cont...
coord_type GetWidth() const
Definition: box2.h:185
#define LAST_DCODE
Definition: dcode.h:72
#define GERBER_DCODE_LAYER(x)
const INSPECTOR_FUNC & INSPECTOR
Definition: base_struct.h:118
D_CODE * GetDcodeDescr() const
Function GetDcodeDescr returns the GetDcodeDescr of this object, or NULL.
const wxPoint & GetOrigin() const
COLOR4D m_NegativeDrawColor
The color used to draw negative objects, usually the background color, but not always, when negative objects must be visible.
int GetLayer() const
Function GetLayer returns the layer this item is on.
wxString m_Padname
for a flashed pad: the pad name ((TO.P attribute)
wxString ShowGBRShape() const
void Move(const VECTOR2I &aVector) override
#define FIRST_DCODE
Definition: dcode.h:71
GR_DRAWMODE
Drawmode. Compositing mode plus a flag or two.
Definition: gr_basic.h:41
Class SHAPE_POLY_SET.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Returns the reference to aIndex-th outline in the set
void SetEnd(int x, int y)
bool m_DisplayFlashedItemsFill
Option to draw flashed items (filled/sketch)
static GERBER_FILE_IMAGE_LIST & GetImagesList()
GBR_NETLIST_METADATA m_netAttributes
the string given by a TO attribute set in aperture (dcode).
wxString m_Netname
for items associated to a net: the netname
EDA_RECT * GetClipBox()
Definition: colors.h:60
int NewOutline()
Creates a new empty polygon in the set and returns its index
void ConvertSegmentToPolygon()
Function ConvertSegmentToPolygon convert a line to an equivalent polygon.
std::map< wxString, int > m_NetnamesList
const wxPoint GetEnd() const
wxString m_AperFunction
the aperture attribute (created by a TA.AperFunction command) attached to the D_CODE ...
Definition: dcode.h:105
void Draw(EDA_DRAW_PANEL *aPanel, wxDC *aDC, GR_DRAWMODE aDrawMode, const wxPoint &aOffset, GBR_DISPLAY_OPTIONS *aDrawOptions)
void Normalize()
Function Normalize ensures that the height ant width are positive.
coord_type GetHeight() const
Definition: box2.h:186
SHAPE_POLY_SET m_shape
The shape of the item, calculated by GetApertureMacroShape.
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
Class D_CODE holds a gerber DCODE (also called Aperture) definition.
Definition: dcode.h:82
#define max(a, b)
Definition: auxiliary.h:86
void DrawFlashedShape(GERBER_DRAW_ITEM *aParent, EDA_RECT *aClipBox, wxDC *aDC, COLOR4D aColor, wxPoint aShapePos, bool aFilledShape)
Function DrawFlashedShape Draw the dcode shape for flashed items.
Definition: dcode.cpp:154
Class SHAPE_LINE_CHAIN.
EDA_RECT GetBoundingBox() const
Returns the bounding box of the shape.
void GRFilledSegment(EDA_RECT *aClipBox, wxDC *aDC, wxPoint aStart, wxPoint aEnd, int aWidth, COLOR4D aColor)
Definition: gr_basic.cpp:592
void GRCircle(EDA_RECT *ClipBox, wxDC *DC, int xc, int yc, int r, int width, COLOR4D Color)
Definition: gr_basic.cpp:791
bool HitTestPoints(const wxPoint &pointA, const wxPoint &pointB, double threshold)
Test, if two points are near each other.
Definition: trigo.h:142
STATUS_FLAGS m_Flags
Flag bits for editing and other uses.
Definition: base_struct.h:189
void RemoveAllContours()
Removes all outlines & holes (clears) the polygon set.
Class EDA_RECT handles the component boundary box.
SHAPE_POLY_SET m_Polygon
Definition: dcode.h:107
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:165
The common library.
const char * name
APERTURE_MACRO * GetMacro() const
Definition: dcode.h:157
print info associated to a flashed pad (TO.P attribute)
VECTOR2I & Point(int aIndex)
Function Point()
#define GERBER_DRAW_LAYER(x)
void ConvertShapeToPolygon()
Function ConvertShapeToPolygon convert a shape to an equivalent polygon.
Definition: dcode.cpp:303
bool HitTest(const wxPoint &aRefPos) const override
Function HitTest tests if the given wxPoint is within the bounds of this object.
Class EDA_MSG_ITEM is used EDA_MSG_PANEL as the item type for displaying messages.
Definition: msgpanel.h:53
Class VIEW.
Definition: view.h:58
bool TestSegmentHit(const wxPoint &aRefPoint, wxPoint aStart, wxPoint aEnd, int aDist)
Function TestSegmentHit test for hit on line segment i.e.
Definition: trigo.cpp:142
SEARCH_RESULT
Definition: base_struct.h:82
void MoveXY(const wxPoint &aMoveVector)
Function MoveXY move this object.
Message panel definition file.
wxPoint GetXYPosition(const wxPoint &aABPosition) const
Function GetXYPosition returns the image position of aPosition for this object.
const wxSize & GetSize() const
wxPoint GetABPosition(const wxPoint &aXYPosition) const
Function GetABPosition returns the image position of aPosition for this object.
print info associated to a net (TO.N attribute)
const BOX2I BBox(int aClearance=0) const override
Function BBox()
GERBER_FILE_IMAGE * m_GerberImageFile
std::map< wxString, int > m_ComponentsList
bool Contains(const VECTOR2I &aP, int aSubpolyIndex=-1) const
Returns true if a given subpolygon contains the point aP.
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
GERBER_LAYER & GetLayerParams()
Function GetLayerParams.
#define min(a, b)
Definition: auxiliary.h:85
int m_NetAttribType
the type of net info (used to define the gerber string to create)
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline) ...
void GRArc1(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int xc, int yc, COLOR4D Color)
Definition: gr_basic.cpp:873
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39