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