KiCad PCB EDA Suite
gr_basic.cpp
Go to the documentation of this file.
1 /********************************/
2 /* Low level graphics routines */
3 /********************************/
4 
5 
6 #include <fctsys.h>
7 #include <gr_basic.h>
8 #include <common.h>
9 #include <trigo.h>
10 #include <macros.h>
11 #include <base_struct.h>
12 #include <class_base_screen.h>
13 #include <bezier_curves.h>
14 #include <math_for_graphics.h>
15 #include <wx/graphics.h>
16 #if defined(__WXMAC__) && defined(USE_WX_GRAPHICS_CONTEXT)
17 #include <wx/dcgraph.h>
18 #endif
19 
20 static const bool FILLED = true;
21 static const bool NOT_FILLED = false;
22 
23 /* Important Note:
24  * These drawing functions clip draw item before send these items to wxDC draw
25  * functions. For guy who asks why i did it, see a sample of problems encountered
26  * when pixels
27  * coordinates overflow 16 bits values:
28  * http://trac.wxwidgets.org/ticket/10446
29  * Problems can be found under Windows **and** Linux (mainly when drawing arcs)
30  * (mainly at low zoom values (2, 1 or 0.5), in Pcbnew)
31  * some of these problems could be now fixed in recent distributions.
32  *
33  * Currently (feb 2009) there are overflow problems when drawing solid (filled)
34  * polygons under linux without clipping
35  *
36  * So before removing clipping functions, be aware these bug (they are not in
37  * KiCad or wxWidgets) are fixed by testing how are drawn complex lines arcs
38  * and solid polygons under Windows and Linux and remember users can have old
39  * versions with bugs
40  */
41 
42 
43 /* Definitions for enabling and disabling debugging features in gr_basic.cpp.
44  * Please remember to set these back to 0 before making LAUNCHPAD commits.
45  */
46 #define DEBUG_DUMP_CLIP_ERROR_COORDS 0 // Set to 1 to dump clip algorithm errors.
47 #define DEBUG_DUMP_CLIP_COORDS 0 // Set to 1 to dump clipped coordinates.
48 
49 
50 // For draw mode = XOR GR_XOR or GR_NXOR by background color
52 
53 
54 static void ClipAndDrawPoly( EDA_RECT * ClipBox, wxDC * DC, wxPoint Points[],
55  int n );
56 
57 /* These functions are used by corresponding functions
58  * ( GRSCircle is called by GRCircle for instance) after mapping coordinates
59  * from user units to screen units(pixels coordinates)
60  */
61 static void GRSRect( EDA_RECT* aClipBox, wxDC* aDC, int x1, int y1,
62  int x2, int y2, int aWidth, COLOR4D aColor,
63  wxPenStyle aStyle = wxPENSTYLE_SOLID );
64 
65 
66 
68 static bool s_ForceBlackPen; /* if true: draws in black instead of
69  * color for printing. */
70 static int xcliplo = 0,
71  ycliplo = 0,
72  xcliphi = 2000,
73  ycliphi = 2000;
74 
75 static COLOR4D s_DC_lastcolor( 0, 0, 0, 0 );
76 static COLOR4D s_DC_lastbrushcolor( 0, 0, 0, 0 );
77 static bool s_DC_lastbrushfill = false;
78 static wxDC* s_DC_lastDC = NULL;
79 
80 /***
81  * Utility for the line clipping code, returns the boundary code of
82  * a point. Bit allocation is arbitrary
83  */
84 static inline int clipOutCode( const EDA_RECT *aClipBox, int x, int y )
85 {
86  int code;
87  if( y < aClipBox->GetY() )
88  code = 2;
89  else if( y > aClipBox->GetBottom() )
90  code = 1;
91  else
92  code = 0;
93  if( x < aClipBox->GetX() )
94  code |= 4;
95  else if( x > aClipBox->GetRight() )
96  code |= 8;
97  return code;
98 }
99 
100 
114 static bool clipLine( const EDA_RECT *aClipBox, int &x1, int &y1, int &x2, int &y2 )
115 {
116  // Stock Cohen-Sutherland algorithm; check *any* CG book for details
117  int outcode1 = clipOutCode( aClipBox, x1, y1 );
118  int outcode2 = clipOutCode( aClipBox, x2, y2 );
119 
120  while( outcode1 || outcode2 )
121  {
122  // Fast reject
123  if( outcode1 & outcode2 )
124  return true;
125 
126  // Choose a side to clip
127  int thisoutcode, x, y;
128  if( outcode1 )
129  thisoutcode = outcode1;
130  else
131  thisoutcode = outcode2;
132 
133  /* One clip round
134  * Since we use the full range of 32 bit ints, the proportion
135  * computation has to be done in 64 bits to avoid horrible
136  * results */
137  if( thisoutcode & 1 ) // Clip the bottom
138  {
139  y = aClipBox->GetBottom();
140  x = x1 + (x2 - x1) * int64_t(y - y1) / (y2 - y1);
141  }
142  else if( thisoutcode & 2 ) // Clip the top
143  {
144  y = aClipBox->GetY();
145  x = x1 + (x2 - x1) * int64_t(y - y1) / (y2 - y1);
146  }
147  else if( thisoutcode & 8 ) // Clip the right
148  {
149  x = aClipBox->GetRight();
150  y = y1 + (y2 - y1) * int64_t(x - x1) / (x2 - x1);
151  }
152  else // if( thisoutcode & 4), obviously, clip the left
153  {
154  x = aClipBox->GetX();
155  y = y1 + (y2 - y1) * int64_t(x - x1) / (x2 - x1);
156  }
157 
158  // Put the result back and update the boundary code
159  // No ambiguity, otherwise it would have been a fast reject
160  if( thisoutcode == outcode1 )
161  {
162  x1 = x;
163  y1 = y;
164  outcode1 = clipOutCode( aClipBox, x1, y1 );
165  }
166  else
167  {
168  x2 = x;
169  y2 = y;
170  outcode2 = clipOutCode( aClipBox, x2, y2 );
171  }
172  }
173  return false;
174 }
175 
176 static void WinClipAndDrawLine( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2, int width )
177 {
178  GRLastMoveToX = x2;
179  GRLastMoveToY = y2;
180 
181  if( ClipBox )
182  {
183  EDA_RECT clipbox(*ClipBox);
184  clipbox.Inflate(width/2);
185  if( clipLine( &clipbox, x1, y1, x2, y2 ) )
186  return;
187  }
188 
189  DC->DrawLine( x1, y1, x2, y2 );
190 }
191 
192 
193 /* Forcing a reset of the current pen.
194  * Must be called after changing the graphical device before any trace.
195  */
196 void GRResetPenAndBrush( wxDC* DC )
197 {
198  GRSetBrush( DC, BLACK ); // Force no fill
199  s_DC_lastbrushcolor = COLOR4D::UNSPECIFIED;
200  s_DC_lastcolor = COLOR4D::UNSPECIFIED;
201  s_DC_lastDC = NULL;
202 }
203 
204 
209 void GRSetColorPen( wxDC* DC, COLOR4D Color, int width, wxPenStyle style )
210 {
211  // Under OSX and while printing when wxPen is set to 0, renderer follows the request drawing
212  // nothing & in the bitmap world the minimum is enough to light a pixel, in vectorial one not
213  if( width <= 1 )
214  width = DC->DeviceToLogicalXRel( 1 );
215 
216  if( s_ForceBlackPen )
217  Color = COLOR4D::BLACK;
218 
219  const wxPen& curr_pen = DC->GetPen();
220 
221  if( !curr_pen.IsOk() || curr_pen.GetColour() != Color.ToColour()
222  || curr_pen.GetWidth() != width
223  || curr_pen.GetStyle() != style )
224  {
225  wxPen pen;
226  pen.SetColour( Color.ToColour() );
227  pen.SetWidth( width );
228  pen.SetStyle( style );
229  DC->SetPen( pen );
230  }
231  else
232  // Should be not needed, but on Linux, in printing process
233  // the curr pen settings needs to be sometimes re-initialized
234  // Clearly, this is due to a bug, related to SetBrush(),
235  // but we have to live with it, at least on wxWidgets 3.0
236  DC->SetPen( curr_pen );
237 }
238 
239 
240 void GRSetBrush( wxDC* DC, COLOR4D Color, bool fill )
241 {
242  if( s_ForceBlackPen )
243  Color = COLOR4D::BLACK;
244 
245  if( s_DC_lastbrushcolor != Color
246  || s_DC_lastbrushfill != fill
247  || s_DC_lastDC != DC )
248  {
249  wxBrush brush;
250 
251  brush.SetColour( Color.ToColour() );
252 
253  if( fill )
254  brush.SetStyle( wxBRUSHSTYLE_SOLID );
255  else
256  brush.SetStyle( wxBRUSHSTYLE_TRANSPARENT );
257 
258  DC->SetBrush( brush );
259 
260  s_DC_lastbrushcolor = Color;
261  s_DC_lastbrushfill = fill;
262  s_DC_lastDC = DC;
263  }
264 }
265 
266 
271 void GRForceBlackPen( bool flagforce )
272 {
273  s_ForceBlackPen = flagforce;
274 }
275 
276 
282 {
283  return s_ForceBlackPen;
284 }
285 
286 
287 /*************************************/
288 /* Set the device context draw mode. */
289 /*************************************/
290 void GRSetDrawMode( wxDC* DC, GR_DRAWMODE draw_mode )
291 {
292  if( draw_mode & GR_OR )
293 #if defined(__WXMAC__) && (wxMAC_USE_CORE_GRAPHICS || wxCHECK_VERSION( 2, 9, 0 ) )
294 
295  DC->SetLogicalFunction( wxCOPY );
296 #elif defined( USE_WX_GRAPHICS_CONTEXT )
297 
298  DC->SetLogicalFunction( wxCOPY );
299 #else
300 
301  DC->SetLogicalFunction( wxOR );
302 #endif
303  else if( draw_mode & GR_XOR )
304 #if defined( USE_WX_GRAPHICS_CONTEXT )
305 
306  DC->SetLogicalFunction( wxCOPY );
307 #else
308 
309  DC->SetLogicalFunction( wxXOR );
310 #endif
311  else if( draw_mode & GR_NXOR )
312 #if defined(__WXMAC__) && (wxMAC_USE_CORE_GRAPHICS || wxCHECK_VERSION( 2, 9, 0 ) )
313 
314  DC->SetLogicalFunction( wxXOR );
315 #elif defined( USE_WX_GRAPHICS_CONTEXT )
316 
317  DC->SetLogicalFunction( wxCOPY );
318 #else
319 
320  DC->SetLogicalFunction( wxEQUIV );
321 #endif
322  else if( draw_mode & GR_INVERT )
323 #if defined( USE_WX_GRAPHICS_CONTEXT )
324 
325  DC->SetLogicalFunction( wxCOPY );
326 #else
327 
328  DC->SetLogicalFunction( wxINVERT );
329 #endif
330  else if( draw_mode & GR_COPY )
331  DC->SetLogicalFunction( wxCOPY );
332 
333 #ifdef USE_WX_OVERLAY
334  DC->SetLogicalFunction( wxCOPY );
335 #endif
336 }
337 
338 
339 void GRPutPixel( EDA_RECT* ClipBox, wxDC* DC, int x, int y, COLOR4D Color )
340 {
341  if( ClipBox && !ClipBox->Contains( x, y ) )
342  return;
343 
344  GRSetColorPen( DC, Color );
345  DC->DrawPoint( x, y );
346 }
347 
348 
349 /*
350  * Draw a line, in object space.
351  */
352 void GRLine( EDA_RECT* ClipBox,
353  wxDC* DC,
354  int x1,
355  int y1,
356  int x2,
357  int y2,
358  int width,
359  COLOR4D Color )
360 {
361  GRSetColorPen( DC, Color, width );
362  WinClipAndDrawLine( ClipBox, DC, x1, y1, x2, y2, width );
363  GRLastMoveToX = x2;
364  GRLastMoveToY = y2;
365 }
366 
367 
368 void GRLine( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aStart, wxPoint aEnd, int aWidth, COLOR4D aColor )
369 {
370  GRLine( aClipBox, aDC, aStart.x, aStart.y, aEnd.x, aEnd.y, aWidth, aColor );
371 }
372 
373 
374 void GRDashedLine( EDA_RECT* ClipBox, wxDC* DC,
375  int x1, int y1, int x2, int y2,
376  int width, COLOR4D Color )
377 {
378  GRLastMoveToX = x2;
379  GRLastMoveToY = y2;
380  s_DC_lastcolor = COLOR4D::UNSPECIFIED;
381  GRSetColorPen( DC, Color, width, wxPENSTYLE_SHORT_DASH );
382  WinClipAndDrawLine( ClipBox, DC, x1, y1, x2, y2, width );
383  s_DC_lastcolor = COLOR4D::UNSPECIFIED;
384  GRSetColorPen( DC, Color, width );
385 }
386 
387 
388 /*
389  * Move to a new position, in object space.
390  */
391 void GRMoveTo( int x, int y )
392 {
393  GRLastMoveToX = x;
394  GRLastMoveToY = y;
395 }
396 
397 
398 /*
399  * Draw line to a new position, in object space.
400  */
401 void GRLineTo( EDA_RECT* ClipBox, wxDC* DC, int x, int y, int width, COLOR4D Color )
402 {
403  GRLine( ClipBox, DC, GRLastMoveToX, GRLastMoveToY, x, y, width, Color );
404 }
405 
406 
407 void GRMixedLine( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
408  int width, COLOR4D Color )
409 {
410  GRSetColorPen( DC, Color, width, wxPENSTYLE_DOT_DASH );
411  GRLine( ClipBox, DC, x1, y1, x2, y2, width, Color );
412  GRSetColorPen( DC, Color, width );
413 }
414 
415 
416 
427 void GRLineArray( EDA_RECT* aClipBox, wxDC* aDC, std::vector<wxPoint>& aLines,
428  int aWidth, COLOR4D aColor )
429 {
430  if( aLines.empty() )
431  return;
432 
433  GRSetColorPen( aDC, aColor, aWidth );
434 
435  if( aClipBox )
436  aClipBox->Inflate( aWidth / 2 );
437 
438 #if defined( __WXMAC__ ) && defined( USE_WX_GRAPHICS_CONTEXT )
439  wxGCDC *gcdc = wxDynamicCast( aDC, wxGCDC );
440  if( gcdc )
441  {
442  wxGraphicsContext *gc = gcdc->GetGraphicsContext();
443 
444  // create path
445  wxGraphicsPath path = gc->CreatePath();
446  for( unsigned i = 0; i < aLines.size(); i += 2 )
447  {
448  int x1 = aLines[i].x;
449  int y1 = aLines[i].y;
450  int x2 = aLines[i+1].x;
451  int y2 = aLines[i+1].y;
452  if( ( aClipBox == NULL ) || !clipLine( aClipBox, x1, y1, x2, y2 ) )
453  {
454  path.MoveToPoint( x1, y1 );
455  path.AddLineToPoint( x2, y2 );
456  }
457  }
458  // draw path
459  gc->StrokePath( path );
460  }
461  else
462 #endif
463  {
464  for( unsigned i = 0; i < aLines.size(); i += 2 )
465  {
466  int x1 = aLines[i].x;
467  int y1 = aLines[i].y;
468  int x2 = aLines[i+1].x;
469  int y2 = aLines[i+1].y;
470  if( ( aClipBox == NULL ) || !clipLine( aClipBox, x1, y1, x2, y2 ) )
471  aDC->DrawLine( x1, y1, x2, y2 );
472  }
473  }
474  GRMoveTo( aLines[aLines.size() - 1].x, aLines[aLines.size() - 1].y );
475 
476  if( aClipBox )
477  aClipBox->Inflate(-aWidth/2);
478 }
479 
480 // Draw the outline of a thick segment wih rounded ends
481 void GRCSegm( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
482  int width, int aPenSize, COLOR4D Color )
483 {
484  GRLastMoveToX = x2;
485  GRLastMoveToY = y2;
486 
487  if( ClipBox )
488  {
489  EDA_RECT clipbox(*ClipBox);
490  clipbox.Inflate(width/2);
491 
492  if( clipLine( &clipbox, x1, y1, x2, y2 ) )
493  return;
494  }
495 
496 
497  if( width <= 2 ) /* single line or 2 pixels */
498  {
499  GRSetColorPen( DC, Color, width );
500  DC->DrawLine( x1, y1, x2, y2 );
501  return;
502  }
503 
504  GRSetBrush( DC, Color, NOT_FILLED );
505  GRSetColorPen( DC, Color, aPenSize );
506 
507  int radius = (width + 1) >> 1;
508  int dx = x2 - x1;
509  int dy = y2 - y1;
510  double angle = -ArcTangente( dy, dx );
511  wxPoint start;
512  wxPoint end;
513  wxPoint org( x1, y1);
514  int len = (int) hypot( dx, dy );
515 
516  // We know if the DC is mirrored, to draw arcs
517  int slx = DC->DeviceToLogicalX( 1 ) - DC->DeviceToLogicalX( 0 );
518  int sly = DC->DeviceToLogicalY( 1 ) - DC->DeviceToLogicalY( 0 );
519  bool mirrored = (slx > 0 && sly < 0) || (slx < 0 && sly > 0);
520 
521  // first edge
522  start.x = 0;
523  start.y = radius;
524  end.x = len;
525  end.y = radius;
526  RotatePoint( &start, angle);
527  RotatePoint( &end, angle);
528 
529  start += org;
530  end += org;
531 
532  DC->DrawLine( start, end );
533 
534  // first rounded end
535  end.x = 0;
536  end.y = -radius;
537  RotatePoint( &end, angle);
538  end += org;
539 
540  if( !mirrored )
541  DC->DrawArc( end, start, org );
542  else
543  DC->DrawArc( start, end, org );
544 
545 
546  // second edge
547  start.x = len;
548  start.y = -radius;
549  RotatePoint( &start, angle);
550  start += org;
551 
552  DC->DrawLine( start, end );
553 
554  // second rounded end
555  end.x = len;
556  end.y = radius;
557  RotatePoint( &end, angle);
558  end += org;
559 
560  if( !mirrored )
561  DC->DrawArc( end.x, end.y, start.x, start.y, x2, y2 );
562  else
563  DC->DrawArc( start.x, start.y, end.x, end.y, x2, y2 );
564 }
565 
566 
567 void GRCSegm( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
568  int width, COLOR4D Color )
569 {
570  GRCSegm( ClipBox, DC, x1, y1, x2, y2, width, 0, Color );
571 }
572 
573 
574 void GRCSegm( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aStart, wxPoint aEnd,
575  int aWidth, COLOR4D aColor )
576 {
577  GRCSegm( aClipBox, aDC, aStart.x, aStart.y, aEnd.x, aEnd.y, aWidth, 0, aColor );
578 }
579 
580 
581 /*
582  * Draw segment (full) with rounded ends in object space (real coords.).
583  */
584 void GRFillCSegm( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
585  int width, COLOR4D Color )
586 {
587  GRSetColorPen( DC, Color, width );
588  WinClipAndDrawLine( ClipBox, DC, x1, y1, x2, y2, width );
589 }
590 
591 
592 void GRFilledSegment( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aStart, wxPoint aEnd,
593  int aWidth, COLOR4D aColor )
594 {
595  GRSetColorPen( aDC, aColor, aWidth );
596  WinClipAndDrawLine( aClipBox, aDC, aStart.x, aStart.y, aEnd.x, aEnd.y, aWidth );
597 }
598 
599 
600 static bool IsGRSPolyDrawable( EDA_RECT* ClipBox, int n, wxPoint Points[] )
601 {
602  if( !ClipBox )
603  return true;
604 
605  if( n <= 0 )
606  return false;
607 
608  int Xmin, Xmax, Ymin, Ymax;
609 
610  Xmin = Xmax = Points[0].x;
611  Ymin = Ymax = Points[0].y;
612 
613  for( int ii = 1; ii < n; ii++ ) // calculate rectangle
614  {
615  Xmin = std::min( Xmin, Points[ii].x );
616  Xmax = std::max( Xmax, Points[ii].x );
617  Ymin = std::min( Ymin, Points[ii].y );
618  Ymax = std::max( Ymax, Points[ii].y );
619  }
620 
621  xcliplo = ClipBox->GetX();
622  ycliplo = ClipBox->GetY();
623  xcliphi = ClipBox->GetRight();
624  ycliphi = ClipBox->GetBottom();
625 
626  if( Xmax < xcliplo )
627  return false;
628  if( Xmin > xcliphi )
629  return false;
630  if( Ymax < ycliplo )
631  return false;
632  if( Ymin > ycliphi )
633  return false;
634 
635  return true;
636 }
637 
638 
639 /*
640  * Draw a new polyline and fill it if Fill, in screen space.
641  */
642 static void GRSPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[],
643  bool Fill, int width,
644  COLOR4D Color, COLOR4D BgColor )
645 {
646  if( !IsGRSPolyDrawable( ClipBox, n, Points ) )
647  return;
648 
649  if( Fill && ( n > 2 ) )
650  {
651  GRSetBrush( DC, BgColor, FILLED );
652  GRSetColorPen( DC, Color, width );
653 
654  /* clip before send the filled polygon to wxDC, because under linux
655  * (GTK?) polygons having large coordinates are incorrectly drawn
656  * (integer overflow in coordinates, I am guessing)
657  */
658  ClipAndDrawPoly( ClipBox, DC, Points, n );
659  }
660  else
661  {
662 #if defined( __WXMAC__ ) && defined( USE_WX_GRAPHICS_CONTEXT )
663  wxGCDC *gcdc = wxDynamicCast( DC, wxGCDC );
664  if( gcdc )
665  {
666  wxGraphicsContext *gc = gcdc->GetGraphicsContext();
667 
668  // set pen
669  GRSetColorPen( DC, Color, width );
670 
671  // create path
672  wxGraphicsPath path = gc->CreatePath();
673  path.MoveToPoint( Points[0].x, Points[0].y );
674  for( int i = 1; i < n; ++i )
675  {
676  path.AddLineToPoint( Points[i].x, Points[i].y );
677  }
678  // draw path
679  gc->StrokePath( path );
680 
681  // correctly update last position
682  GRMoveTo( Points[n - 1].x, Points[n - 1].y );
683  }
684  else
685 #endif
686  {
687  GRMoveTo( Points[0].x, Points[0].y );
688  for( int i = 1; i < n; ++i )
689  {
690  GRLineTo( ClipBox, DC, Points[i].x, Points[i].y, width, Color );
691  }
692  }
693  }
694 }
695 
696 
697 /*
698  * Draw a new closed polyline and fill it if Fill, in screen space.
699  */
700 static void GRSClosedPoly( EDA_RECT* aClipBox, wxDC* aDC,
701  int aPointCount, wxPoint aPoints[],
702  bool aFill, int aWidth,
703  COLOR4D aColor,
704  COLOR4D aBgColor )
705 {
706  if( !IsGRSPolyDrawable( aClipBox, aPointCount, aPoints ) )
707  return;
708 
709  if( aFill && ( aPointCount > 2 ) )
710  {
711  GRLastMoveToX = aPoints[aPointCount - 1].x;
712  GRLastMoveToY = aPoints[aPointCount - 1].y;
713  GRSetBrush( aDC, aBgColor, FILLED );
714  GRSetColorPen( aDC, aColor, aWidth );
715  ClipAndDrawPoly( aClipBox, aDC, aPoints, aPointCount );
716  }
717  else
718  {
719 #if defined( __WXMAC__ ) && defined( USE_WX_GRAPHICS_CONTEXT )
720  wxGCDC *gcdc = wxDynamicCast( aDC, wxGCDC );
721  if( gcdc )
722  {
723  wxGraphicsContext *gc = gcdc->GetGraphicsContext();
724 
725  // set pen
726  GRSetColorPen( aDC, aColor, aWidth );
727 
728  // create path
729  wxGraphicsPath path = gc->CreatePath();
730  path.MoveToPoint( aPoints[0].x, aPoints[0].y );
731  for( int i = 1; i < aPointCount; ++i )
732  {
733  path.AddLineToPoint( aPoints[i].x, aPoints[i].y );
734  }
735  if( aPoints[aPointCount - 1] != aPoints[0] )
736  path.AddLineToPoint( aPoints[0].x, aPoints[0].y );
737  // draw path
738  gc->StrokePath( path );
739 
740  // correctly update last position
741  GRMoveTo( aPoints[aPointCount - 1].x, aPoints[aPointCount - 1].y );
742  }
743  else
744 #endif
745  {
746  GRMoveTo( aPoints[0].x, aPoints[0].y );
747  for( int i = 1; i < aPointCount; ++i )
748  {
749  GRLineTo( aClipBox, aDC, aPoints[i].x, aPoints[i].y, aWidth, aColor );
750  }
751 
752  int lastpt = aPointCount - 1;
753 
754  // Close the polygon
755  if( aPoints[lastpt] != aPoints[0] )
756  {
757  GRLineTo( aClipBox, aDC, aPoints[0].x, aPoints[0].y, aWidth, aColor );
758  }
759  }
760  }
761 }
762 
763 
764 /*
765  * Draw a new polyline and fill it if Fill, in drawing space.
766  */
767 void GRPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[],
768  bool Fill, int width, COLOR4D Color, COLOR4D BgColor )
769 {
770  GRSPoly( ClipBox, DC, n, Points, Fill, width, Color, BgColor );
771 }
772 
773 
774 /*
775  * Draw a closed polyline and fill it if Fill, in object space.
776  */
777 void GRClosedPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[],
778  bool Fill, COLOR4D Color, COLOR4D BgColor )
779 {
780  GRClosedPoly( ClipBox, DC, n, Points, Fill, 0, Color, BgColor );
781 }
782 
783 
784 void GRClosedPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[],
785  bool Fill, int width, COLOR4D Color, COLOR4D BgColor )
786 {
787  GRSClosedPoly( ClipBox, DC, n, Points, Fill, width, Color, BgColor );
788 }
789 
790 
791 void GRCircle( EDA_RECT* ClipBox, wxDC* DC, int xc, int yc, int r, int width, COLOR4D Color )
792 {
793  /* Clip circles off screen. */
794  if( ClipBox )
795  {
796  int x0, y0, xm, ym;
797  x0 = ClipBox->GetX();
798  y0 = ClipBox->GetY();
799  xm = ClipBox->GetRight();
800  ym = ClipBox->GetBottom();
801 
802  if( xc < ( x0 - r - width ) )
803  return;
804 
805  if( yc < ( y0 - r - width ) )
806  return;
807 
808  if( xc > ( r + xm + width ) )
809  return;
810 
811  if( yc > ( r + ym + width ) )
812  return;
813  }
814 
815  GRSetBrush( DC, Color, NOT_FILLED );
816  GRSetColorPen( DC, Color, width );
817  DC->DrawEllipse( xc - r, yc - r, r + r, r + r );
818 }
819 
820 
821 void GRCircle( EDA_RECT* ClipBox, wxDC* DC, int x, int y, int r, COLOR4D Color )
822 {
823  GRCircle( ClipBox, DC, x, y, r, 0, Color );
824 }
825 
826 
827 void GRCircle( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aPos, int aRadius, int aWidth, COLOR4D aColor )
828 {
829  GRCircle( aClipBox, aDC, aPos.x, aPos.y, aRadius, aWidth, aColor );
830 }
831 
832 
833 void GRFilledCircle( EDA_RECT* ClipBox, wxDC* DC, int x, int y, int r,
834  int width, COLOR4D Color, COLOR4D BgColor )
835 {
836  /* Clip circles off screen. */
837  if( ClipBox )
838  {
839  int x0, y0, xm, ym;
840  x0 = ClipBox->GetX();
841  y0 = ClipBox->GetY();
842  xm = ClipBox->GetRight();
843  ym = ClipBox->GetBottom();
844 
845  if( x < ( x0 - r ) )
846  return;
847 
848  if( y < ( y0 - r ) )
849  return;
850 
851  if( x > ( r + xm ) )
852  return;
853 
854  if( y > ( r + ym ) )
855  return;
856  }
857 
858  GRSetBrush( DC, BgColor, FILLED );
859  GRSetColorPen( DC, Color, width );
860  DC->DrawEllipse( x - r, y - r, r + r, r + r );
861 }
862 
863 
864 void GRFilledCircle( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aPos, int aRadius, COLOR4D aColor )
865 {
866  GRFilledCircle( aClipBox, aDC, aPos.x, aPos.y, aRadius, 0, aColor, aColor );
867 }
868 
869 
870 /*
871  * Draw an arc in user space.
872  */
873 void GRArc1( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
874  int xc, int yc, COLOR4D Color )
875 {
876  GRArc1( ClipBox, DC, x1, y1, x2, y2, xc, yc, 0, Color );
877 }
878 
879 
880 /*
881  * Draw an arc, width = width in user space.
882  */
883 void GRArc1( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
884  int xc, int yc, int width, COLOR4D Color )
885 {
886  /* Clip arcs off screen. */
887  if( ClipBox )
888  {
889  int x0, y0, xm, ym, r;
890  x0 = ClipBox->GetX();
891  y0 = ClipBox->GetY();
892  xm = ClipBox->GetRight();
893  ym = ClipBox->GetBottom();
894  r = KiROUND( Distance( x1, y1, xc, yc ) );
895  if( xc < ( x0 - r ) )
896  return;
897  if( yc < ( y0 - r ) )
898  return;
899  if( xc > ( r + xm ) )
900  return;
901  if( yc > ( r + ym ) )
902  return;
903  }
904 
905  GRSetBrush( DC, Color );
906  GRSetColorPen( DC, Color, width );
907  DC->DrawArc( x1, y1, x2, y2, xc, yc );
908 }
909 
910 
911 void GRArc1( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aStart, wxPoint aEnd,
912  wxPoint aCenter, int aWidth, COLOR4D aColor )
913 {
914  GRArc1( aClipBox, aDC, aStart.x, aStart.y, aEnd.x, aEnd.y, aCenter.x, aCenter.y,
915  aWidth, aColor );
916 }
917 
918 
919 /*
920  * Draw a filled arc in drawing space.
921  */
922 void GRFilledArc( EDA_RECT* ClipBox,
923  wxDC* DC,
924  int x,
925  int y,
926  double StAngle,
927  double EndAngle,
928  int r,
929  int width,
930  COLOR4D Color,
931  COLOR4D BgColor )
932 {
933  int x1, y1, x2, y2;
934 
935  /* Clip arcs off screen */
936  if( ClipBox )
937  {
938  int x0, y0, xm, ym;
939  x0 = ClipBox->GetX();
940  y0 = ClipBox->GetY();
941  xm = ClipBox->GetRight();
942  ym = ClipBox->GetBottom();
943 
944  if( x < ( x0 - r - 1 ) )
945  return;
946 
947  if( y < ( y0 - r - 1 ) )
948  return;
949 
950  if( x > ( r + xm + 1 ) )
951  return;
952 
953  if( y > ( r + ym + 1 ) )
954  return;
955  }
956 
957  x1 = r;
958  y1 = 0;
959  RotatePoint( &x1, &y1, EndAngle );
960 
961  x2 = r;
962  y2 = 0;
963  RotatePoint( &x2, &y2, StAngle );
964 
965  GRSetBrush( DC, BgColor, FILLED );
966  GRSetColorPen( DC, Color, width );
967  DC->DrawArc( x + x1, y - y1, x + x2, y - y2, x, y );
968 }
969 
970 
971 void GRFilledArc( EDA_RECT* ClipBox, wxDC* DC, int x, int y,
972  double StAngle, double EndAngle, int r,
973  COLOR4D Color, COLOR4D BgColor )
974 {
975  GRFilledArc( ClipBox, DC, x, y, StAngle, EndAngle, r, 0, Color, BgColor );
976 }
977 
978 
979 /*
980  * Draw an arc in drawing space.
981  */
982 void GRArc( EDA_RECT* ClipBox, wxDC* DC, int xc, int yc, double StAngle,
983  double EndAngle, int r, COLOR4D Color )
984 {
985  int x1, y1, x2, y2;
986 
987  /* Clip arcs off screen */
988  if( ClipBox )
989  {
990  int radius = r + 1;
991  int x0, y0, xm, ym, x, y;
992  x0 = ClipBox->GetX();
993  y0 = ClipBox->GetY();
994  xm = ClipBox->GetRight();
995  ym = ClipBox->GetBottom();
996  x = xc;
997  y = yc;
998 
999  if( x < ( x0 - radius ) )
1000  return;
1001  if( y < ( y0 - radius ) )
1002  return;
1003  if( x > ( xm + radius ) )
1004  return;
1005  if( y > ( ym + radius ) )
1006  return;
1007  }
1008 
1009  x1 = r;
1010  y1 = 0;
1011  RotatePoint( &x1, &y1, EndAngle );
1012 
1013  x2 = r;
1014  y2 = 0;
1015  RotatePoint( &x2, &y2, StAngle );
1016 
1017  GRSetBrush( DC, Color, NOT_FILLED );
1018  GRSetColorPen( DC, Color );
1019  DC->DrawArc( xc + x1, yc - y1, xc + x2, yc - y2, xc, yc );
1020 }
1021 
1022 
1023 /*
1024  * Draw an arc with width = width in drawing space.
1025  */
1026 void GRArc( EDA_RECT* ClipBox,
1027  wxDC* DC,
1028  int x,
1029  int y,
1030  double StAngle,
1031  double EndAngle,
1032  int r,
1033  int width,
1034  COLOR4D Color )
1035 {
1036  int x1, y1, x2, y2;
1037 
1038  /* Clip arcs off screen. */
1039  if( ClipBox )
1040  {
1041  int x0, y0, xm, ym;
1042  x0 = ClipBox->GetX();
1043  y0 = ClipBox->GetY();
1044  xm = ClipBox->GetRight();
1045  ym = ClipBox->GetBottom();
1046 
1047  if( x < ( x0 - r - width ) )
1048  return;
1049 
1050  if( y < ( y0 - r - width ) )
1051  return;
1052 
1053  if( x > ( r + xm + width ) )
1054  return;
1055 
1056  if( y > ( r + ym + width ) )
1057  return;
1058  }
1059 
1060  x1 = r;
1061  y1 = 0;
1062  RotatePoint( &x1, &y1, EndAngle );
1063 
1064  x2 = r;
1065  y2 = 0;
1066  RotatePoint( &x2, &y2, StAngle );
1067 
1068  GRSetBrush( DC, Color );
1069  GRSetColorPen( DC, Color, width );
1070  DC->DrawArc( x + x1, y - y1, x + x2, y - y2, x, y );
1071 }
1072 
1073 
1074 /*
1075  * Draw a rectangle in drawing space.
1076  */
1077 void GRRect( EDA_RECT* aClipBox, wxDC* aDC, int x1, int y1, int x2, int y2, COLOR4D aColor )
1078 {
1079  GRSRect( aClipBox, aDC, x1, y1, x2, y2, 0, aColor );
1080 }
1081 
1082 
1083 void GRRectPs( EDA_RECT* aClipBox, wxDC* aDC, const EDA_RECT& aRect, COLOR4D aColor, wxPenStyle aStyle )
1084 {
1085  int x1 = aRect.GetX();
1086  int y1 = aRect.GetY();
1087  int x2 = aRect.GetRight();
1088  int y2 = aRect.GetBottom();
1089 
1090  GRSRect( aClipBox, aDC, x1, y1, x2, y2, 0, aColor, aStyle );
1091 }
1092 
1093 
1094 /*
1095  * Draw a rectangle (thick lines) in drawing space.
1096  */
1097 void GRRect( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color )
1098 {
1099  GRSRect( ClipBox, DC, x1, y1, x2, y2, width, Color );
1100 }
1101 
1102 
1103 void GRRect( EDA_RECT* aClipBox, wxDC* aDC, const EDA_RECT& aRect, int aWidth, COLOR4D aColor )
1104 {
1105  int x1 = aRect.GetX();
1106  int y1 = aRect.GetY();
1107  int x2 = aRect.GetRight();
1108  int y2 = aRect.GetBottom();
1109 
1110  GRSRect( aClipBox, aDC, x1, y1, x2, y2, aWidth, aColor );
1111 }
1112 
1113 
1114 /*
1115  * Draw a rectangle (filled with AreaColor) in drawing space.
1116  */
1117 void GRFilledRect( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
1118  COLOR4D Color, COLOR4D BgColor )
1119 {
1120  GRSFilledRect( ClipBox, DC, x1, y1, x2, y2, 0, Color, BgColor );
1121 }
1122 
1123 
1124 /*
1125  * Draw a rectangle (filled with AreaColor) in drawing space.
1126  */
1127 void GRFilledRect( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
1128  int width, COLOR4D Color, COLOR4D BgColor )
1129 {
1130  GRSFilledRect( ClipBox, DC, x1, y1, x2, y2, width, Color, BgColor );
1131 }
1132 
1133 
1134 /*
1135  * Draw a rectangle in screen space.
1136  */
1137 
1138 void GRSRect( EDA_RECT* aClipBox, wxDC* aDC, int x1, int y1, int x2, int y2,
1139  int aWidth, COLOR4D aColor, wxPenStyle aStyle )
1140 {
1141  wxPoint points[5];
1142  points[0] = wxPoint(x1, y1);
1143  points[1] = wxPoint(x1, y2);
1144  points[2] = wxPoint(x2, y2);
1145  points[3] = wxPoint(x2, y1);
1146  points[4] = points[0];
1147  GRSClosedPoly( aClipBox, aDC, 5, points, NOT_FILLED, aWidth,
1148  aColor, aColor );
1149 }
1150 
1151 
1152 void GRSFilledRect( EDA_RECT* aClipBox, wxDC* aDC, int x1, int y1, int x2, int y2,
1153  int aWidth, COLOR4D aColor, COLOR4D aBgColor )
1154 {
1155  wxPoint points[5];
1156  points[0] = wxPoint(x1, y1);
1157  points[1] = wxPoint(x1, y2);
1158  points[2] = wxPoint(x2, y2);
1159  points[3] = wxPoint(x2, y1);
1160  points[4] = points[0];
1161 
1162  GRSetBrush( aDC, aBgColor, FILLED );
1163  GRSetColorPen( aDC, aBgColor, aWidth );
1164 
1165  if( aClipBox && (aWidth > 0) )
1166  {
1167  EDA_RECT clipbox(*aClipBox);
1168  clipbox.Inflate(aWidth);
1169  ClipAndDrawPoly(&clipbox, aDC, points, 5); // polygon approach is more accurate
1170  }
1171  else
1172  ClipAndDrawPoly(aClipBox, aDC, points, 5 );
1173 }
1174 
1185 /* Note: aClipBox == NULL is legal, so if aClipBox == NULL,
1186  * the polygon is drawn, but not clipped
1187  */
1188 #include <SutherlandHodgmanClipPoly.h>
1189 
1190 void ClipAndDrawPoly( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aPoints[], int n )
1191 {
1192  if( aClipBox == NULL )
1193  {
1194  aDC->DrawPolygon( n, aPoints );
1195  return;
1196  }
1197 
1198  // A clip box exists: clip and draw the polygon.
1199  static std::vector<wxPoint> clippedPolygon;
1200  static pointVector inputPolygon, outputPolygon;
1201 
1202  inputPolygon.clear();
1203  outputPolygon.clear();
1204  clippedPolygon.clear();
1205 
1206  for( int ii = 0; ii < n; ii++ )
1207  inputPolygon.push_back( PointF( (REAL) aPoints[ii].x, (REAL) aPoints[ii].y ) );
1208 
1209  RectF window( (REAL) aClipBox->GetX(), (REAL) aClipBox->GetY(),
1210  (REAL) aClipBox->GetWidth(), (REAL) aClipBox->GetHeight() );
1211 
1212  SutherlandHodgman sh( window );
1213  sh.Clip( inputPolygon, outputPolygon );
1214 
1215  for( cpointIterator cit = outputPolygon.begin(); cit != outputPolygon.end(); ++cit )
1216  {
1217  clippedPolygon.push_back( wxPoint( KiROUND( cit->X ), KiROUND( cit->Y ) ) );
1218  }
1219 
1220  if( clippedPolygon.size() )
1221  aDC->DrawPolygon( clippedPolygon.size(), &clippedPolygon[0] );
1222 }
1223 
1224 
1225 void GRBezier( EDA_RECT* ClipBox,
1226  wxDC* DC,
1227  int x1,
1228  int y1,
1229  int x2,
1230  int y2,
1231  int x3,
1232  int y3,
1233  int width,
1234  COLOR4D Color )
1235 {
1236  std::vector<wxPoint> Points = Bezier2Poly( x1, y1, x2, y2, x3, y3 );
1237  GRPoly( ClipBox, DC, Points.size(), &Points[0], false, width, Color, Color );
1238 }
1239 
1240 
1241 void GRBezier( EDA_RECT* ClipBox,
1242  wxDC* DC,
1243  int x1,
1244  int y1,
1245  int x2,
1246  int y2,
1247  int x3,
1248  int y3,
1249  int x4,
1250  int y4,
1251  int width,
1252  COLOR4D Color )
1253 {
1254  std::vector<wxPoint> Points = Bezier2Poly( x1, y1, x2, y2, x3, y3, x4, y4 );
1255  GRPoly( ClipBox, DC, Points.size(), &Points[0], false, width, Color, Color );
1256 }
1257 
1258 
1259 void GRDrawAnchor( EDA_RECT *aClipBox, wxDC *aDC, int x, int y,
1260  int aSize, COLOR4D aColor )
1261 {
1262  int anchor_size = aDC->DeviceToLogicalXRel( aSize );
1263 
1264  GRLine( aClipBox, aDC,
1265  x - anchor_size, y,
1266  x + anchor_size, y, 0, aColor );
1267  GRLine( aClipBox, aDC,
1268  x, y - anchor_size,
1269  x, y + anchor_size, 0, aColor );
1270 }
GR_DRAWMODE g_XorMode
Definition: gr_basic.cpp:51
void GRResetPenAndBrush(wxDC *DC)
Definition: gr_basic.cpp:196
static void ClipAndDrawPoly(EDA_RECT *ClipBox, wxDC *DC, wxPoint Points[], int n)
Function ClipAndDrawPoly Used to clip a polygon and draw it as Filled Polygon uses the Sutherland and...
Definition: gr_basic.cpp:1190
static int ycliplo
Definition: gr_basic.cpp:71
void GRPoly(EDA_RECT *ClipBox, wxDC *DC, int n, wxPoint Points[], bool Fill, int width, COLOR4D Color, COLOR4D BgColor)
Definition: gr_basic.cpp:767
static const bool FILLED
Definition: gr_basic.cpp:20
void GRBezier(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int x3, int y3, int width, COLOR4D Color)
Definition: gr_basic.cpp:1225
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
static int ycliphi
Definition: gr_basic.cpp:73
std::vector< PointF > pointVector
void GRSFilledRect(EDA_RECT *aClipBox, wxDC *aDC, int x1, int y1, int x2, int y2, int aWidth, COLOR4D aColor, COLOR4D aBgColor)
Definition: gr_basic.cpp:1152
bool Contains(const wxPoint &aPoint) const
Function Contains.
void GRLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color)
Definition: gr_basic.cpp:352
void GRFilledRect(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, COLOR4D Color, COLOR4D BgColor)
Definition: gr_basic.cpp:1117
double REAL
int GetHeight() const
void GRMixedLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color)
Definition: gr_basic.cpp:407
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
void GRDrawAnchor(EDA_RECT *aClipBox, wxDC *aDC, int x, int y, int aSize, COLOR4D aColor)
Definition: gr_basic.cpp:1259
void RotatePoint(int *pX, int *pY, double angle)
Definition: trigo.cpp:317
static bool IsGRSPolyDrawable(EDA_RECT *ClipBox, int n, wxPoint Points[])
Definition: gr_basic.cpp:600
void GRFilledCircle(EDA_RECT *ClipBox, wxDC *DC, int x, int y, int r, int width, COLOR4D Color, COLOR4D BgColor)
Definition: gr_basic.cpp:833
static int xcliphi
Definition: gr_basic.cpp:72
static int GRLastMoveToX
Definition: gr_basic.cpp:67
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
std::vector< PointF >::const_iterator cpointIterator
This file contains miscellaneous commonly used macros and functions.
void GRLineTo(EDA_RECT *ClipBox, wxDC *DC, int x, int y, int width, COLOR4D Color)
Definition: gr_basic.cpp:401
std::vector< wxPoint > Bezier2Poly(wxPoint c1, wxPoint c2, wxPoint c3, wxPoint c4)
Function Bezier2Poly convert a Bezier curve to a polyline.
static int xcliplo
Definition: gr_basic.cpp:70
static const bool NOT_FILLED
Definition: gr_basic.cpp:21
void GRRect(EDA_RECT *aClipBox, wxDC *aDC, int x1, int y1, int x2, int y2, COLOR4D aColor)
Definition: gr_basic.cpp:1077
static int GRLastMoveToY
Definition: gr_basic.cpp:67
double ArcTangente(int dy, int dx)
Definition: trigo.cpp:271
void GRForceBlackPen(bool flagforce)
Function GRForceBlackPen.
Definition: gr_basic.cpp:271
static void GRSClosedPoly(EDA_RECT *aClipBox, wxDC *aDC, int aPointCount, wxPoint aPoints[], bool aFill, int aWidth, COLOR4D aColor, COLOR4D aBgColor)
Definition: gr_basic.cpp:700
GR_DRAWMODE
Drawmode. Compositing mode plus a flag or two.
Definition: gr_basic.h:41
void GRFillCSegm(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color)
Definition: gr_basic.cpp:584
static void WinClipAndDrawLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width)
Definition: gr_basic.cpp:176
static wxDC * s_DC_lastDC
Definition: gr_basic.cpp:78
void GRArc(EDA_RECT *ClipBox, wxDC *DC, int xc, int yc, double StAngle, double EndAngle, int r, COLOR4D Color)
Definition: gr_basic.cpp:982
static 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.
Definition: gr_basic.cpp:114
int GetBottom() const
int GetRight() const
static COLOR4D s_DC_lastbrushcolor(0, 0, 0, 0)
static COLOR4D s_DC_lastcolor(0, 0, 0, 0)
void GRFilledArc(EDA_RECT *ClipBox, wxDC *DC, int x, int y, double StAngle, double EndAngle, int r, int width, COLOR4D Color, COLOR4D BgColor)
Definition: gr_basic.cpp:922
void GRSetBrush(wxDC *DC, COLOR4D Color, bool fill)
Definition: gr_basic.cpp:240
void GRPutPixel(EDA_RECT *ClipBox, wxDC *DC, int x, int y, COLOR4D Color)
Definition: gr_basic.cpp:339
Definition: gr_basic.h:42
void GRMoveTo(int x, int y)
Definition: gr_basic.cpp:391
static int clipOutCode(const EDA_RECT *aClipBox, int x, int y)
Definition: gr_basic.cpp:84
void GRDashedLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color)
Definition: gr_basic.cpp:374
BASE_SCREEN class implementation.
#define max(a, b)
Definition: auxiliary.h:86
static void GRSPoly(EDA_RECT *ClipBox, wxDC *DC, int n, wxPoint Points[], bool Fill, int width, COLOR4D Color, COLOR4D BgColor)
Definition: gr_basic.cpp:642
void GRFilledSegment(EDA_RECT *aClipBox, wxDC *aDC, wxPoint aStart, wxPoint aEnd, int aWidth, COLOR4D aColor)
Definition: gr_basic.cpp:592
static DIRECTION_45::AngleType angle(const VECTOR2I &a, const VECTOR2I &b)
void GRCircle(EDA_RECT *ClipBox, wxDC *DC, int xc, int yc, int r, int width, COLOR4D Color)
Definition: gr_basic.cpp:791
void GRSetColorPen(wxDC *DC, COLOR4D Color, int width, wxPenStyle style)
Function GRSetColorPen sets a pen style, width, color, and alpha into the given device context...
Definition: gr_basic.cpp:209
Class EDA_RECT handles the component boundary box.
int GetX() const
The common library.
void GRLineArray(EDA_RECT *aClipBox, wxDC *aDC, std::vector< wxPoint > &aLines, int aWidth, COLOR4D aColor)
Function GRLineArray draws an array of lines (not a polygon).
Definition: gr_basic.cpp:427
int GetWidth() const
int GetY() const
static void GRSRect(EDA_RECT *aClipBox, wxDC *aDC, int x1, int y1, int x2, int y2, int aWidth, COLOR4D aColor, wxPenStyle aStyle=wxPENSTYLE_SOLID)
Definition: gr_basic.cpp:1138
Definition: colors.h:45
Basic classes for most KiCad items.
double Distance(double x1, double y1, double x2, double y2)
bool GetGRForceBlackPenState(void)
Function GetGRForceBlackPenState.
Definition: gr_basic.cpp:281
static bool s_DC_lastbrushfill
Definition: gr_basic.cpp:77
EDA_RECT & Inflate(wxCoord dx, wxCoord dy)
Function Inflate inflates the rectangle horizontally by dx and vertically by dy.
#define min(a, b)
Definition: auxiliary.h:85
static bool s_ForceBlackPen
Definition: gr_basic.cpp:68
void GRRectPs(EDA_RECT *aClipBox, wxDC *aDC, const EDA_RECT &aRect, COLOR4D aColor, wxPenStyle aStyle)
Definition: gr_basic.cpp:1083
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