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  wxDash dots[2] = { 1, 3 };
212  // Under OSX and while printing when wxPen is set to 0, renderer follows the request drawing
213  // nothing & in the bitmap world the minimum is enough to light a pixel, in vectorial one not
214  if( width <= 1 )
215  width = DC->DeviceToLogicalXRel( 1 );
216 
217  if( s_ForceBlackPen )
218  Color = COLOR4D::BLACK;
219 
220  const wxPen& curr_pen = DC->GetPen();
221 
222  if( !curr_pen.IsOk() || curr_pen.GetColour() != Color.ToColour()
223  || curr_pen.GetWidth() != width
224  || curr_pen.GetStyle() != style )
225  {
226  wxPen pen;
227  pen.SetColour( Color.ToColour() );
228  if( style == wxPENSTYLE_DOT )
229  {
230  style = wxPENSTYLE_USER_DASH;
231  pen.SetDashes( 2, dots );
232  }
233  pen.SetWidth( width );
234  pen.SetStyle( style );
235  DC->SetPen( pen );
236  }
237  else
238  // Should be not needed, but on Linux, in printing process
239  // the curr pen settings needs to be sometimes re-initialized
240  // Clearly, this is due to a bug, related to SetBrush(),
241  // but we have to live with it, at least on wxWidgets 3.0
242  DC->SetPen( curr_pen );
243 }
244 
245 
246 void GRSetBrush( wxDC* DC, COLOR4D Color, bool fill )
247 {
248  if( s_ForceBlackPen )
249  Color = COLOR4D::BLACK;
250 
251  if( s_DC_lastbrushcolor != Color
252  || s_DC_lastbrushfill != fill
253  || s_DC_lastDC != DC )
254  {
255  wxBrush brush;
256 
257  brush.SetColour( Color.ToColour() );
258 
259  if( fill )
260  brush.SetStyle( wxBRUSHSTYLE_SOLID );
261  else
262  brush.SetStyle( wxBRUSHSTYLE_TRANSPARENT );
263 
264  DC->SetBrush( brush );
265 
266  s_DC_lastbrushcolor = Color;
267  s_DC_lastbrushfill = fill;
268  s_DC_lastDC = DC;
269  }
270 }
271 
272 
277 void GRForceBlackPen( bool flagforce )
278 {
279  s_ForceBlackPen = flagforce;
280 }
281 
282 
288 {
289  return s_ForceBlackPen;
290 }
291 
292 
293 /*************************************/
294 /* Set the device context draw mode. */
295 /*************************************/
296 void GRSetDrawMode( wxDC* DC, GR_DRAWMODE draw_mode )
297 {
298  if( draw_mode & GR_OR )
299 #if defined(__WXMAC__) && (wxMAC_USE_CORE_GRAPHICS || wxCHECK_VERSION( 2, 9, 0 ) )
300 
301  DC->SetLogicalFunction( wxCOPY );
302 #elif defined( USE_WX_GRAPHICS_CONTEXT )
303 
304  DC->SetLogicalFunction( wxCOPY );
305 #else
306 
307  DC->SetLogicalFunction( wxOR );
308 #endif
309  else if( draw_mode & GR_XOR )
310 #if defined( USE_WX_GRAPHICS_CONTEXT )
311 
312  DC->SetLogicalFunction( wxCOPY );
313 #else
314 
315  DC->SetLogicalFunction( wxXOR );
316 #endif
317  else if( draw_mode & GR_NXOR )
318 #if defined(__WXMAC__) && (wxMAC_USE_CORE_GRAPHICS || wxCHECK_VERSION( 2, 9, 0 ) )
319 
320  DC->SetLogicalFunction( wxXOR );
321 #elif defined( USE_WX_GRAPHICS_CONTEXT )
322 
323  DC->SetLogicalFunction( wxCOPY );
324 #else
325 
326  DC->SetLogicalFunction( wxEQUIV );
327 #endif
328  else if( draw_mode & GR_INVERT )
329 #if defined( USE_WX_GRAPHICS_CONTEXT )
330 
331  DC->SetLogicalFunction( wxCOPY );
332 #else
333 
334  DC->SetLogicalFunction( wxINVERT );
335 #endif
336  else if( draw_mode & GR_COPY )
337  DC->SetLogicalFunction( wxCOPY );
338 
339 #ifdef USE_WX_OVERLAY
340  DC->SetLogicalFunction( wxCOPY );
341 #endif
342 }
343 
344 
345 void GRPutPixel( EDA_RECT* ClipBox, wxDC* DC, int x, int y, COLOR4D Color )
346 {
347  if( ClipBox && !ClipBox->Contains( x, y ) )
348  return;
349 
350  GRSetColorPen( DC, Color );
351  DC->DrawPoint( x, y );
352 }
353 
354 
355 /*
356  * Draw a line, in object space.
357  */
358 void GRLine( EDA_RECT* ClipBox,
359  wxDC* DC,
360  int x1,
361  int y1,
362  int x2,
363  int y2,
364  int width,
365  COLOR4D Color,
366  wxPenStyle aStyle)
367 {
368  GRSetColorPen( DC, Color, width, aStyle );
369  WinClipAndDrawLine( ClipBox, DC, x1, y1, x2, y2, width );
370  GRLastMoveToX = x2;
371  GRLastMoveToY = y2;
372 }
373 
374 
375 void GRLine( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aStart, wxPoint aEnd, int aWidth, COLOR4D aColor, wxPenStyle aStyle )
376 {
377  GRLine( aClipBox, aDC, aStart.x, aStart.y, aEnd.x, aEnd.y, aWidth, aColor, aStyle );
378 }
379 
380 
381 void GRDashedLine( EDA_RECT* ClipBox, wxDC* DC,
382  int x1, int y1, int x2, int y2,
383  int width, COLOR4D Color )
384 {
385  GRLine( ClipBox, DC, x1, y1, x2, y2, width, Color, wxPENSTYLE_SHORT_DASH );
386 }
387 
388 
389 void GRDottedLine( EDA_RECT* ClipBox, wxDC* DC,
390  int x1, int y1, int x2, int y2,
391  int width, COLOR4D Color )
392 {
393  GRLine( ClipBox, DC, x1, y1, x2, y2, width, Color, wxPENSTYLE_DOT );
394 }
395 
396 
397 /*
398  * Move to a new position, in object space.
399  */
400 void GRMoveTo( int x, int y )
401 {
402  GRLastMoveToX = x;
403  GRLastMoveToY = y;
404 }
405 
406 
407 /*
408  * Draw line to a new position, in object space.
409  */
410 void GRLineTo( EDA_RECT* ClipBox, wxDC* DC, int x, int y, int width, COLOR4D Color )
411 {
412  GRLine( ClipBox, DC, GRLastMoveToX, GRLastMoveToY, x, y, width, Color );
413 }
414 
415 
416 void GRMixedLine( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
417  int width, COLOR4D Color )
418 {
419  GRLine( ClipBox, DC, x1, y1, x2, y2, width, Color, wxPENSTYLE_DOT_DASH );
420 }
421 
422 
423 
434 void GRLineArray( EDA_RECT* aClipBox, wxDC* aDC, std::vector<wxPoint>& aLines,
435  int aWidth, COLOR4D aColor )
436 {
437  if( aLines.empty() )
438  return;
439 
440  GRSetColorPen( aDC, aColor, aWidth );
441 
442  if( aClipBox )
443  aClipBox->Inflate( aWidth / 2 );
444 
445 #if defined( __WXMAC__ ) && defined( USE_WX_GRAPHICS_CONTEXT )
446  wxGCDC *gcdc = wxDynamicCast( aDC, wxGCDC );
447  if( gcdc )
448  {
449  wxGraphicsContext *gc = gcdc->GetGraphicsContext();
450 
451  // create path
452  wxGraphicsPath path = gc->CreatePath();
453  for( unsigned i = 0; i < aLines.size(); i += 2 )
454  {
455  int x1 = aLines[i].x;
456  int y1 = aLines[i].y;
457  int x2 = aLines[i+1].x;
458  int y2 = aLines[i+1].y;
459  if( ( aClipBox == NULL ) || !clipLine( aClipBox, x1, y1, x2, y2 ) )
460  {
461  path.MoveToPoint( x1, y1 );
462  path.AddLineToPoint( x2, y2 );
463  }
464  }
465  // draw path
466  gc->StrokePath( path );
467  }
468  else
469 #endif
470  {
471  for( unsigned i = 0; i < aLines.size(); i += 2 )
472  {
473  int x1 = aLines[i].x;
474  int y1 = aLines[i].y;
475  int x2 = aLines[i+1].x;
476  int y2 = aLines[i+1].y;
477  if( ( aClipBox == NULL ) || !clipLine( aClipBox, x1, y1, x2, y2 ) )
478  aDC->DrawLine( x1, y1, x2, y2 );
479  }
480  }
481  GRMoveTo( aLines[aLines.size() - 1].x, aLines[aLines.size() - 1].y );
482 
483  if( aClipBox )
484  aClipBox->Inflate(-aWidth/2);
485 }
486 
487 // Draw the outline of a thick segment wih rounded ends
488 void GRCSegm( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
489  int width, int aPenSize, COLOR4D Color )
490 {
491  GRLastMoveToX = x2;
492  GRLastMoveToY = y2;
493 
494  if( ClipBox )
495  {
496  EDA_RECT clipbox(*ClipBox);
497  clipbox.Inflate(width/2);
498 
499  if( clipLine( &clipbox, x1, y1, x2, y2 ) )
500  return;
501  }
502 
503 
504  if( width <= 2 ) /* single line or 2 pixels */
505  {
506  GRSetColorPen( DC, Color, width );
507  DC->DrawLine( x1, y1, x2, y2 );
508  return;
509  }
510 
511  GRSetBrush( DC, Color, NOT_FILLED );
512  GRSetColorPen( DC, Color, aPenSize );
513 
514  int radius = (width + 1) >> 1;
515  int dx = x2 - x1;
516  int dy = y2 - y1;
517  double angle = -ArcTangente( dy, dx );
518  wxPoint start;
519  wxPoint end;
520  wxPoint org( x1, y1);
521  int len = (int) hypot( dx, dy );
522 
523  // We know if the DC is mirrored, to draw arcs
524  int slx = DC->DeviceToLogicalX( 1 ) - DC->DeviceToLogicalX( 0 );
525  int sly = DC->DeviceToLogicalY( 1 ) - DC->DeviceToLogicalY( 0 );
526  bool mirrored = (slx > 0 && sly < 0) || (slx < 0 && sly > 0);
527 
528  // first edge
529  start.x = 0;
530  start.y = radius;
531  end.x = len;
532  end.y = radius;
533  RotatePoint( &start, angle);
534  RotatePoint( &end, angle);
535 
536  start += org;
537  end += org;
538 
539  DC->DrawLine( start, end );
540 
541  // first rounded end
542  end.x = 0;
543  end.y = -radius;
544  RotatePoint( &end, angle);
545  end += org;
546 
547  if( !mirrored )
548  DC->DrawArc( end, start, org );
549  else
550  DC->DrawArc( start, end, org );
551 
552 
553  // second edge
554  start.x = len;
555  start.y = -radius;
556  RotatePoint( &start, angle);
557  start += org;
558 
559  DC->DrawLine( start, end );
560 
561  // second rounded end
562  end.x = len;
563  end.y = radius;
564  RotatePoint( &end, angle);
565  end += org;
566 
567  if( !mirrored )
568  DC->DrawArc( end.x, end.y, start.x, start.y, x2, y2 );
569  else
570  DC->DrawArc( start.x, start.y, end.x, end.y, x2, y2 );
571 }
572 
573 
574 void GRCSegm( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
575  int width, COLOR4D Color )
576 {
577  GRCSegm( ClipBox, DC, x1, y1, x2, y2, width, 0, Color );
578 }
579 
580 
581 void GRCSegm( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aStart, wxPoint aEnd,
582  int aWidth, COLOR4D aColor )
583 {
584  GRCSegm( aClipBox, aDC, aStart.x, aStart.y, aEnd.x, aEnd.y, aWidth, 0, aColor );
585 }
586 
587 
588 /*
589  * Draw segment (full) with rounded ends in object space (real coords.).
590  */
591 void GRFillCSegm( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
592  int width, COLOR4D Color )
593 {
594  GRSetColorPen( DC, Color, width );
595  WinClipAndDrawLine( ClipBox, DC, x1, y1, x2, y2, width );
596 }
597 
598 
599 void GRFilledSegment( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aStart, wxPoint aEnd,
600  int aWidth, COLOR4D aColor )
601 {
602  GRSetColorPen( aDC, aColor, aWidth );
603  WinClipAndDrawLine( aClipBox, aDC, aStart.x, aStart.y, aEnd.x, aEnd.y, aWidth );
604 }
605 
606 
607 static bool IsGRSPolyDrawable( EDA_RECT* ClipBox, int n, wxPoint Points[] )
608 {
609  if( !ClipBox )
610  return true;
611 
612  if( n <= 0 )
613  return false;
614 
615  int Xmin, Xmax, Ymin, Ymax;
616 
617  Xmin = Xmax = Points[0].x;
618  Ymin = Ymax = Points[0].y;
619 
620  for( int ii = 1; ii < n; ii++ ) // calculate rectangle
621  {
622  Xmin = std::min( Xmin, Points[ii].x );
623  Xmax = std::max( Xmax, Points[ii].x );
624  Ymin = std::min( Ymin, Points[ii].y );
625  Ymax = std::max( Ymax, Points[ii].y );
626  }
627 
628  xcliplo = ClipBox->GetX();
629  ycliplo = ClipBox->GetY();
630  xcliphi = ClipBox->GetRight();
631  ycliphi = ClipBox->GetBottom();
632 
633  if( Xmax < xcliplo )
634  return false;
635  if( Xmin > xcliphi )
636  return false;
637  if( Ymax < ycliplo )
638  return false;
639  if( Ymin > ycliphi )
640  return false;
641 
642  return true;
643 }
644 
645 
646 /*
647  * Draw a new polyline and fill it if Fill, in screen space.
648  */
649 static void GRSPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[],
650  bool Fill, int width,
651  COLOR4D Color, COLOR4D BgColor )
652 {
653  if( !IsGRSPolyDrawable( ClipBox, n, Points ) )
654  return;
655 
656  if( Fill && ( n > 2 ) )
657  {
658  GRSetBrush( DC, BgColor, FILLED );
659  GRSetColorPen( DC, Color, width );
660 
661  /* clip before send the filled polygon to wxDC, because under linux
662  * (GTK?) polygons having large coordinates are incorrectly drawn
663  * (integer overflow in coordinates, I am guessing)
664  */
665  ClipAndDrawPoly( ClipBox, DC, Points, n );
666  }
667  else
668  {
669 #if defined( __WXMAC__ ) && defined( USE_WX_GRAPHICS_CONTEXT )
670  wxGCDC *gcdc = wxDynamicCast( DC, wxGCDC );
671  if( gcdc )
672  {
673  wxGraphicsContext *gc = gcdc->GetGraphicsContext();
674 
675  // set pen
676  GRSetColorPen( DC, Color, width );
677 
678  // create path
679  wxGraphicsPath path = gc->CreatePath();
680  path.MoveToPoint( Points[0].x, Points[0].y );
681  for( int i = 1; i < n; ++i )
682  {
683  path.AddLineToPoint( Points[i].x, Points[i].y );
684  }
685  // draw path
686  gc->StrokePath( path );
687 
688  // correctly update last position
689  GRMoveTo( Points[n - 1].x, Points[n - 1].y );
690  }
691  else
692 #endif
693  {
694  GRMoveTo( Points[0].x, Points[0].y );
695  for( int i = 1; i < n; ++i )
696  {
697  GRLineTo( ClipBox, DC, Points[i].x, Points[i].y, width, Color );
698  }
699  }
700  }
701 }
702 
703 
704 /*
705  * Draw a new closed polyline and fill it if Fill, in screen space.
706  */
707 static void GRSClosedPoly( EDA_RECT* aClipBox, wxDC* aDC,
708  int aPointCount, wxPoint aPoints[],
709  bool aFill, int aWidth,
710  COLOR4D aColor,
711  COLOR4D aBgColor )
712 {
713  if( !IsGRSPolyDrawable( aClipBox, aPointCount, aPoints ) )
714  return;
715 
716  if( aFill && ( aPointCount > 2 ) )
717  {
718  GRLastMoveToX = aPoints[aPointCount - 1].x;
719  GRLastMoveToY = aPoints[aPointCount - 1].y;
720  GRSetBrush( aDC, aBgColor, FILLED );
721  GRSetColorPen( aDC, aColor, aWidth );
722  ClipAndDrawPoly( aClipBox, aDC, aPoints, aPointCount );
723  }
724  else
725  {
726 #if defined( __WXMAC__ ) && defined( USE_WX_GRAPHICS_CONTEXT )
727  wxGCDC *gcdc = wxDynamicCast( aDC, wxGCDC );
728  if( gcdc )
729  {
730  wxGraphicsContext *gc = gcdc->GetGraphicsContext();
731 
732  // set pen
733  GRSetColorPen( aDC, aColor, aWidth );
734 
735  // create path
736  wxGraphicsPath path = gc->CreatePath();
737  path.MoveToPoint( aPoints[0].x, aPoints[0].y );
738  for( int i = 1; i < aPointCount; ++i )
739  {
740  path.AddLineToPoint( aPoints[i].x, aPoints[i].y );
741  }
742  if( aPoints[aPointCount - 1] != aPoints[0] )
743  path.AddLineToPoint( aPoints[0].x, aPoints[0].y );
744  // draw path
745  gc->StrokePath( path );
746 
747  // correctly update last position
748  GRMoveTo( aPoints[aPointCount - 1].x, aPoints[aPointCount - 1].y );
749  }
750  else
751 #endif
752  {
753  GRMoveTo( aPoints[0].x, aPoints[0].y );
754  for( int i = 1; i < aPointCount; ++i )
755  {
756  GRLineTo( aClipBox, aDC, aPoints[i].x, aPoints[i].y, aWidth, aColor );
757  }
758 
759  int lastpt = aPointCount - 1;
760 
761  // Close the polygon
762  if( aPoints[lastpt] != aPoints[0] )
763  {
764  GRLineTo( aClipBox, aDC, aPoints[0].x, aPoints[0].y, aWidth, aColor );
765  }
766  }
767  }
768 }
769 
770 
771 /*
772  * Draw a new polyline and fill it if Fill, in drawing space.
773  */
774 void GRPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[],
775  bool Fill, int width, COLOR4D Color, COLOR4D BgColor )
776 {
777  GRSPoly( ClipBox, DC, n, Points, Fill, width, Color, BgColor );
778 }
779 
780 
781 /*
782  * Draw a closed polyline and fill it if Fill, in object space.
783  */
784 void GRClosedPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[],
785  bool Fill, COLOR4D Color, COLOR4D BgColor )
786 {
787  GRClosedPoly( ClipBox, DC, n, Points, Fill, 0, Color, BgColor );
788 }
789 
790 
791 void GRClosedPoly( EDA_RECT* ClipBox, wxDC* DC, int n, wxPoint Points[],
792  bool Fill, int width, COLOR4D Color, COLOR4D BgColor )
793 {
794  GRSClosedPoly( ClipBox, DC, n, Points, Fill, width, Color, BgColor );
795 }
796 
797 
798 static bool clipCircle( EDA_RECT* aClipBox, int xc, int yc, int r, int aWidth )
799 {
800  // Clip circles that are outside the ClipBox.
801  if( aClipBox )
802  {
803  int x0, y0, xm, ym;
804  x0 = aClipBox->GetX();
805  y0 = aClipBox->GetY();
806  xm = aClipBox->GetRight();
807  ym = aClipBox->GetBottom();
808 
809  r += aWidth;
810 
811  if( xc < ( x0 - r ) )
812  return true;
813 
814  if( yc < ( y0 - r ) )
815  return true;
816 
817  if( xc > ( r + xm ) )
818  return true;
819 
820  if( yc > ( r + ym ) )
821  return true;
822  }
823 
824  return false;
825 }
826 
827 
828 void GRCircle( EDA_RECT* ClipBox, wxDC* DC, int xc, int yc, int r, int width, COLOR4D Color )
829 {
830  if( clipCircle( ClipBox, xc, yc, r, width ) )
831  return;
832 
833  GRSetBrush( DC, Color, NOT_FILLED );
834  GRSetColorPen( DC, Color, width );
835  DC->DrawEllipse( xc - r, yc - r, r + r, r + r );
836 }
837 
838 
839 void GRCircle( EDA_RECT* ClipBox, wxDC* DC, int x, int y, int r, COLOR4D Color )
840 {
841  GRCircle( ClipBox, DC, x, y, r, 0, Color );
842 }
843 
844 
845 void GRCircle( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aPos, int aRadius, int aWidth, COLOR4D aColor )
846 {
847  GRCircle( aClipBox, aDC, aPos.x, aPos.y, aRadius, aWidth, aColor );
848 }
849 
850 
851 void GRFilledCircle( EDA_RECT* ClipBox, wxDC* DC, int x, int y, int r,
852  int width, COLOR4D Color, COLOR4D BgColor )
853 {
854  if( clipCircle( ClipBox, x, y, r, width ) )
855  return;
856 
857  GRSetBrush( DC, BgColor, FILLED );
858  GRSetColorPen( DC, Color, width );
859  DC->DrawEllipse( x - r, y - r, r + r, r + r );
860 }
861 
862 
863 void GRFilledCircle( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aPos, int aRadius, COLOR4D aColor )
864 {
865  GRFilledCircle( aClipBox, aDC, aPos.x, aPos.y, aRadius, 0, aColor, aColor );
866 }
867 
868 
869 /*
870  * Draw an arc in user space.
871  */
872 void GRArc1( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
873  int xc, int yc, COLOR4D Color )
874 {
875  GRArc1( ClipBox, DC, x1, y1, x2, y2, xc, yc, 0, Color );
876 }
877 
878 
879 /*
880  * Draw an arc, width = width in user space.
881  */
882 void GRArc1( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
883  int xc, int yc, int width, COLOR4D Color )
884 {
885  /* Clip arcs off screen. */
886  if( ClipBox )
887  {
888  int x0, y0, xm, ym, r;
889  x0 = ClipBox->GetX();
890  y0 = ClipBox->GetY();
891  xm = ClipBox->GetRight();
892  ym = ClipBox->GetBottom();
893  r = KiROUND( Distance( x1, y1, xc, yc ) );
894  if( xc < ( x0 - r ) )
895  return;
896  if( yc < ( y0 - r ) )
897  return;
898  if( xc > ( r + xm ) )
899  return;
900  if( yc > ( r + ym ) )
901  return;
902  }
903 
904  GRSetBrush( DC, Color );
905  GRSetColorPen( DC, Color, width );
906  DC->DrawArc( x1, y1, x2, y2, xc, yc );
907 }
908 
909 
910 void GRArc1( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aStart, wxPoint aEnd,
911  wxPoint aCenter, int aWidth, COLOR4D aColor )
912 {
913  GRArc1( aClipBox, aDC, aStart.x, aStart.y, aEnd.x, aEnd.y, aCenter.x, aCenter.y,
914  aWidth, aColor );
915 }
916 
917 
918 /*
919  * Draw a filled arc in drawing space.
920  */
921 void GRFilledArc( EDA_RECT* ClipBox,
922  wxDC* DC,
923  int x,
924  int y,
925  double StAngle,
926  double EndAngle,
927  int r,
928  int width,
929  COLOR4D Color,
930  COLOR4D BgColor )
931 {
932  int x1, y1, x2, y2;
933 
934  /* Clip arcs off screen */
935  if( ClipBox )
936  {
937  int x0, y0, xm, ym;
938  x0 = ClipBox->GetX();
939  y0 = ClipBox->GetY();
940  xm = ClipBox->GetRight();
941  ym = ClipBox->GetBottom();
942 
943  if( x < ( x0 - r - 1 ) )
944  return;
945 
946  if( y < ( y0 - r - 1 ) )
947  return;
948 
949  if( x > ( r + xm + 1 ) )
950  return;
951 
952  if( y > ( r + ym + 1 ) )
953  return;
954  }
955 
956  x1 = r;
957  y1 = 0;
958  RotatePoint( &x1, &y1, EndAngle );
959 
960  x2 = r;
961  y2 = 0;
962  RotatePoint( &x2, &y2, StAngle );
963 
964  GRSetBrush( DC, BgColor, FILLED );
965  GRSetColorPen( DC, Color, width );
966  DC->DrawArc( x + x1, y - y1, x + x2, y - y2, x, y );
967 }
968 
969 
970 void GRFilledArc( EDA_RECT* ClipBox, wxDC* DC, int x, int y,
971  double StAngle, double EndAngle, int r,
972  COLOR4D Color, COLOR4D BgColor )
973 {
974  GRFilledArc( ClipBox, DC, x, y, StAngle, EndAngle, r, 0, Color, BgColor );
975 }
976 
977 
978 /*
979  * Draw an arc in drawing space.
980  */
981 void GRArc( EDA_RECT* ClipBox, wxDC* DC, int xc, int yc, double StAngle,
982  double EndAngle, int r, COLOR4D Color )
983 {
984  int x1, y1, x2, y2;
985 
986  /* Clip arcs off screen */
987  if( ClipBox )
988  {
989  int radius = r + 1;
990  int x0, y0, xm, ym, x, y;
991  x0 = ClipBox->GetX();
992  y0 = ClipBox->GetY();
993  xm = ClipBox->GetRight();
994  ym = ClipBox->GetBottom();
995  x = xc;
996  y = yc;
997 
998  if( x < ( x0 - radius ) )
999  return;
1000  if( y < ( y0 - radius ) )
1001  return;
1002  if( x > ( xm + radius ) )
1003  return;
1004  if( y > ( ym + radius ) )
1005  return;
1006  }
1007 
1008  x1 = r;
1009  y1 = 0;
1010  RotatePoint( &x1, &y1, EndAngle );
1011 
1012  x2 = r;
1013  y2 = 0;
1014  RotatePoint( &x2, &y2, StAngle );
1015 
1016  GRSetBrush( DC, Color, NOT_FILLED );
1017  GRSetColorPen( DC, Color );
1018  DC->DrawArc( xc + x1, yc - y1, xc + x2, yc - y2, xc, yc );
1019 }
1020 
1021 
1022 /*
1023  * Draw an arc with width = width in drawing space.
1024  */
1025 void GRArc( EDA_RECT* ClipBox,
1026  wxDC* DC,
1027  int x,
1028  int y,
1029  double StAngle,
1030  double EndAngle,
1031  int r,
1032  int width,
1033  COLOR4D Color )
1034 {
1035  int x1, y1, x2, y2;
1036 
1037  /* Clip arcs off screen. */
1038  if( ClipBox )
1039  {
1040  int x0, y0, xm, ym;
1041  x0 = ClipBox->GetX();
1042  y0 = ClipBox->GetY();
1043  xm = ClipBox->GetRight();
1044  ym = ClipBox->GetBottom();
1045 
1046  if( x < ( x0 - r - width ) )
1047  return;
1048 
1049  if( y < ( y0 - r - width ) )
1050  return;
1051 
1052  if( x > ( r + xm + width ) )
1053  return;
1054 
1055  if( y > ( r + ym + width ) )
1056  return;
1057  }
1058 
1059  x1 = r;
1060  y1 = 0;
1061  RotatePoint( &x1, &y1, EndAngle );
1062 
1063  x2 = r;
1064  y2 = 0;
1065  RotatePoint( &x2, &y2, StAngle );
1066 
1067  GRSetBrush( DC, Color );
1068  GRSetColorPen( DC, Color, width );
1069  DC->DrawArc( x + x1, y - y1, x + x2, y - y2, x, y );
1070 }
1071 
1072 
1073 /*
1074  * Draw a rectangle in drawing space.
1075  */
1076 void GRRect( EDA_RECT* aClipBox, wxDC* aDC, int x1, int y1, int x2, int y2, COLOR4D aColor )
1077 {
1078  GRSRect( aClipBox, aDC, x1, y1, x2, y2, 0, aColor );
1079 }
1080 
1081 
1082 void GRRectPs( EDA_RECT* aClipBox, wxDC* aDC, const EDA_RECT& aRect, COLOR4D aColor, wxPenStyle aStyle )
1083 {
1084  int x1 = aRect.GetX();
1085  int y1 = aRect.GetY();
1086  int x2 = aRect.GetRight();
1087  int y2 = aRect.GetBottom();
1088 
1089  GRSRect( aClipBox, aDC, x1, y1, x2, y2, 0, aColor, aStyle );
1090 }
1091 
1092 
1093 /*
1094  * Draw a rectangle (thick lines) in drawing space.
1095  */
1096 void GRRect( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color )
1097 {
1098  GRSRect( ClipBox, DC, x1, y1, x2, y2, width, Color );
1099 }
1100 
1101 
1102 void GRRect( EDA_RECT* aClipBox, wxDC* aDC, const EDA_RECT& aRect, int aWidth, COLOR4D aColor )
1103 {
1104  int x1 = aRect.GetX();
1105  int y1 = aRect.GetY();
1106  int x2 = aRect.GetRight();
1107  int y2 = aRect.GetBottom();
1108 
1109  GRSRect( aClipBox, aDC, x1, y1, x2, y2, aWidth, aColor );
1110 }
1111 
1112 
1113 /*
1114  * Draw a rectangle (filled with AreaColor) in drawing space.
1115  */
1116 void GRFilledRect( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
1117  COLOR4D Color, COLOR4D BgColor )
1118 {
1119  GRSFilledRect( ClipBox, DC, x1, y1, x2, y2, 0, Color, BgColor );
1120 }
1121 
1122 
1123 /*
1124  * Draw a rectangle (filled with AreaColor) in drawing space.
1125  */
1126 void GRFilledRect( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
1127  int width, COLOR4D Color, COLOR4D BgColor )
1128 {
1129  GRSFilledRect( ClipBox, DC, x1, y1, x2, y2, width, Color, BgColor );
1130 }
1131 
1132 
1133 /*
1134  * Draw a rectangle in screen space.
1135  */
1136 
1137 void GRSRect( EDA_RECT* aClipBox, wxDC* aDC, int x1, int y1, int x2, int y2,
1138  int aWidth, COLOR4D aColor, wxPenStyle aStyle )
1139 {
1140  wxPoint points[5];
1141  points[0] = wxPoint(x1, y1);
1142  points[1] = wxPoint(x1, y2);
1143  points[2] = wxPoint(x2, y2);
1144  points[3] = wxPoint(x2, y1);
1145  points[4] = points[0];
1146  GRSClosedPoly( aClipBox, aDC, 5, points, NOT_FILLED, aWidth,
1147  aColor, aColor );
1148 }
1149 
1150 
1151 void GRSFilledRect( EDA_RECT* aClipBox, wxDC* aDC, int x1, int y1, int x2, int y2,
1152  int aWidth, COLOR4D aColor, COLOR4D aBgColor )
1153 {
1154  wxPoint points[5];
1155  points[0] = wxPoint(x1, y1);
1156  points[1] = wxPoint(x1, y2);
1157  points[2] = wxPoint(x2, y2);
1158  points[3] = wxPoint(x2, y1);
1159  points[4] = points[0];
1160 
1161  GRSetBrush( aDC, aBgColor, FILLED );
1162  GRSetColorPen( aDC, aBgColor, aWidth );
1163 
1164  if( aClipBox && (aWidth > 0) )
1165  {
1166  EDA_RECT clipbox(*aClipBox);
1167  clipbox.Inflate(aWidth);
1168  ClipAndDrawPoly(&clipbox, aDC, points, 5); // polygon approach is more accurate
1169  }
1170  else
1171  ClipAndDrawPoly(aClipBox, aDC, points, 5 );
1172 }
1173 
1184 /* Note: aClipBox == NULL is legal, so if aClipBox == NULL,
1185  * the polygon is drawn, but not clipped
1186  */
1187 #include <SutherlandHodgmanClipPoly.h>
1188 
1189 void ClipAndDrawPoly( EDA_RECT* aClipBox, wxDC* aDC, wxPoint aPoints[], int n )
1190 {
1191  if( aClipBox == NULL )
1192  {
1193  aDC->DrawPolygon( n, aPoints );
1194  return;
1195  }
1196 
1197  // A clip box exists: clip and draw the polygon.
1198  static std::vector<wxPoint> clippedPolygon;
1199  static pointVector inputPolygon, outputPolygon;
1200 
1201  inputPolygon.clear();
1202  outputPolygon.clear();
1203  clippedPolygon.clear();
1204 
1205  for( int ii = 0; ii < n; ii++ )
1206  inputPolygon.push_back( PointF( (REAL) aPoints[ii].x, (REAL) aPoints[ii].y ) );
1207 
1208  RectF window( (REAL) aClipBox->GetX(), (REAL) aClipBox->GetY(),
1209  (REAL) aClipBox->GetWidth(), (REAL) aClipBox->GetHeight() );
1210 
1211  SutherlandHodgman sh( window );
1212  sh.Clip( inputPolygon, outputPolygon );
1213 
1214  for( cpointIterator cit = outputPolygon.begin(); cit != outputPolygon.end(); ++cit )
1215  {
1216  clippedPolygon.push_back( wxPoint( KiROUND( cit->X ), KiROUND( cit->Y ) ) );
1217  }
1218 
1219  if( clippedPolygon.size() )
1220  aDC->DrawPolygon( clippedPolygon.size(), &clippedPolygon[0] );
1221 }
1222 
1223 
1224 void GRBezier( EDA_RECT* ClipBox,
1225  wxDC* DC,
1226  int x1,
1227  int y1,
1228  int x2,
1229  int y2,
1230  int x3,
1231  int y3,
1232  int width,
1233  COLOR4D Color )
1234 {
1235  std::vector<wxPoint> points;
1236 
1237  BEZIER_POLY converter( x1, y1, x2, y2, x3, y3 );
1238  converter.GetPoly( points );
1239 
1240  GRPoly( ClipBox, DC, points.size(), &points[0], false, width, Color, Color );
1241 }
1242 
1243 
1244 void GRBezier( EDA_RECT* ClipBox,
1245  wxDC* DC,
1246  int x1,
1247  int y1,
1248  int x2,
1249  int y2,
1250  int x3,
1251  int y3,
1252  int x4,
1253  int y4,
1254  int width,
1255  COLOR4D Color )
1256 {
1257  std::vector<wxPoint> points;
1258 
1259  BEZIER_POLY converter( x1, y1, x2, y2, x3, y3, x4, y4 );
1260  converter.GetPoly( points );
1261 
1262  GRPoly( ClipBox, DC, points.size(), &points[0], false, width, Color, Color );
1263 }
1264 
1265 
1266 void GRDrawAnchor( EDA_RECT *aClipBox, wxDC *aDC, int x, int y,
1267  int aSize, COLOR4D aColor )
1268 {
1269  int anchor_size = aDC->DeviceToLogicalXRel( aSize );
1270 
1271  GRLine( aClipBox, aDC,
1272  x - anchor_size, y,
1273  x + anchor_size, y, 0, aColor );
1274  GRLine( aClipBox, aDC,
1275  x, y - anchor_size,
1276  x, y + anchor_size, 0, aColor );
1277 }
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:1189
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:774
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:1224
void GRSetDrawMode(wxDC *DC, GR_DRAWMODE draw_mode)
Definition: gr_basic.cpp:296
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:1151
bool Contains(const wxPoint &aPoint) const
Function Contains.
static bool clipCircle(EDA_RECT *aClipBox, int xc, int yc, int r, int aWidth)
Definition: gr_basic.cpp:798
void GRFilledRect(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, COLOR4D Color, COLOR4D BgColor)
Definition: gr_basic.cpp:1116
void GetPoly(std::vector< wxPoint > &aOutput)
Converts Bezier curve to a polygon.
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:416
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:488
void GRDrawAnchor(EDA_RECT *aClipBox, wxDC *aDC, int x, int y, int aSize, COLOR4D aColor)
Definition: gr_basic.cpp:1266
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:607
void GRFilledCircle(EDA_RECT *ClipBox, wxDC *DC, int x, int y, int r, int width, COLOR4D Color, COLOR4D BgColor)
Definition: gr_basic.cpp:851
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:784
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:410
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:1076
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:277
static void GRSClosedPoly(EDA_RECT *aClipBox, wxDC *aDC, int aPointCount, wxPoint aPoints[], bool aFill, int aWidth, COLOR4D aColor, COLOR4D aBgColor)
Definition: gr_basic.cpp:707
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:591
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:981
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
void GRLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color, wxPenStyle aStyle)
Definition: gr_basic.cpp:358
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:921
void GRSetBrush(wxDC *DC, COLOR4D Color, bool fill)
Definition: gr_basic.cpp:246
void GRPutPixel(EDA_RECT *ClipBox, wxDC *DC, int x, int y, COLOR4D Color)
Definition: gr_basic.cpp:345
Definition: gr_basic.h:42
void GRMoveTo(int x, int y)
Definition: gr_basic.cpp:400
static int clipOutCode(const EDA_RECT *aClipBox, int x, int y)
Definition: gr_basic.cpp:84
Bezier curves to polygon converter.
Definition: bezier_curves.h:34
void GRDashedLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color)
Definition: gr_basic.cpp:381
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:649
void GRFilledSegment(EDA_RECT *aClipBox, wxDC *aDC, wxPoint aStart, wxPoint aEnd, int aWidth, COLOR4D aColor)
Definition: gr_basic.cpp:599
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:828
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:434
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:1137
void GRDottedLine(EDA_RECT *ClipBox, wxDC *DC, int x1, int y1, int x2, int y2, int width, COLOR4D Color)
Definition: gr_basic.cpp:389
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:287
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:1082
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:872
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39