KiCad PCB EDA Suite
Loading...
Searching...
No Matches
plotter.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) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
34
35#include <trigo.h>
36#include <plotters/plotter.h>
39#include <bezier_curves.h>
40#include <callback_gal.h>
41#include <math/util.h> // for KiROUND
43
44PLOTTER::PLOTTER( const PROJECT* aProject ) :
45 m_project( aProject )
46{
47 m_plotScale = 1;
48 m_currentPenWidth = -1; // To-be-set marker
49 m_penState = 'Z'; // End-of-path idle
50 m_plotMirror = false; // Plot mirror option flag
52 m_yaxisReversed = false;
53 m_outputFile = nullptr;
54 m_colorMode = false; // Starts as a BW plot
55 m_negativeMode = false;
56
57 // Temporary init to avoid not initialized vars, will be set later
58 m_IUsPerDecimil = 1; // will be set later to the actual value
59 m_iuPerDeviceUnit = 1; // will be set later to the actual value
60 m_renderSettings = nullptr;
62}
63
64
66{
67 // Emergency cleanup, but closing the file is usually made in EndPlot().
68 if( m_outputFile )
69 fclose( m_outputFile );
70}
71
72
73bool PLOTTER::OpenFile( const wxString& aFullFilename )
74{
75 m_filename = aFullFilename;
76
77 wxASSERT( !m_outputFile );
78
79 // Open the file in text mode (not suitable for all plotters but only for most of them.
80 m_outputFile = wxFopen( m_filename, wxT( "wt" ) );
81
82 if( m_outputFile == nullptr )
83 return false ;
84
85 return true;
86}
87
88
90{
91 VECTOR2I pos = aCoordinate - m_plotOffset;
92
93 double x = pos.x * m_plotScale;
94 double y = ( m_paperSize.y - pos.y * m_plotScale );
95
96 if( m_plotMirror )
97 {
99 x = ( m_paperSize.x - pos.x * m_plotScale );
100 else
101 y = pos.y * m_plotScale;
102 }
103
104 if( m_yaxisReversed )
105 y = m_paperSize.y - y;
106
109
110 return VECTOR2D( x, y );
111}
112
113
119
120
121double PLOTTER::userToDeviceSize( double size ) const
122{
123 return size * m_plotScale * m_iuPerDeviceUnit;
124}
125
126
127#define IU_PER_MILS ( m_IUsPerDecimil * 10 )
128
129
130double PLOTTER::GetDotMarkLenIU( int aLineWidth ) const
131{
132 return userToDeviceSize( m_renderSettings->GetDotLength( aLineWidth ) );
133}
134
135
136double PLOTTER::GetDashMarkLenIU( int aLineWidth ) const
137{
138 return userToDeviceSize( m_renderSettings->GetDashLength( aLineWidth ) );
139}
140
141
142double PLOTTER::GetDashGapLenIU( int aLineWidth ) const
143{
144 return userToDeviceSize( m_renderSettings->GetGapLength( aLineWidth ) );
145}
146
147
148void PLOTTER::Arc( const VECTOR2D& aStart, const VECTOR2D& aMid, const VECTOR2D& aEnd, FILL_T aFill,
149 int aWidth )
150{
151 VECTOR2D aCenter = CalcArcCenter( aStart, aMid, aEnd );
152
153 EDA_ANGLE startAngle( aStart - aCenter );
154 EDA_ANGLE endAngle( aEnd - aCenter );
155
156 // < 0: left, 0 : on the line, > 0 : right
157 double det = ( aEnd - aStart ).Cross( aMid - aStart );
158
159 int cw = det <= 0;
160 EDA_ANGLE angle = endAngle - startAngle;
161
162 if( cw )
163 angle.Normalize();
164 else
165 angle.NormalizeNegative();
166
167 double radius = ( aStart - aCenter ).EuclideanNorm();
168 Arc( aCenter, startAngle, angle, radius, aFill, aWidth );
169}
170
171
172void PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aAngle,
173 double aRadius, FILL_T aFill, int aWidth )
174{
175 polyArc( aCenter, aStartAngle, aAngle, aRadius, aFill, aWidth );
176}
177
178
179void PLOTTER::polyArc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
180 const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill, int aWidth )
181{
182 EDA_ANGLE startAngle = aStartAngle;
183 EDA_ANGLE endAngle = startAngle + aAngle;
184 const EDA_ANGLE delta( 5.0, DEGREES_T ); // increment to draw arc
185 VECTOR2I start, end;
186 const int sign = 1;
187
188 if( aAngle < ANGLE_0 )
189 std::swap( startAngle, endAngle );
190
191 SetCurrentLineWidth( aWidth );
192
193 start.x = KiROUND( aCenter.x + aRadius * startAngle.Cos() );
194 start.y = KiROUND( aCenter.y + sign * aRadius * startAngle.Sin() );
195
196 if( aFill != FILL_T::NO_FILL )
197 {
198 MoveTo( aCenter );
199 LineTo( start );
200 }
201 else
202 {
203 MoveTo( start );
204 }
205
206 for( EDA_ANGLE ii = startAngle + delta; ii < endAngle; ii += delta )
207 {
208 end.x = KiROUND( aCenter.x + aRadius * ii.Cos() );
209 end.y = KiROUND( aCenter.y + sign * aRadius * ii.Sin() );
210 LineTo( end );
211 }
212
213 end.x = KiROUND( aCenter.x + aRadius * endAngle.Cos() );
214 end.y = KiROUND( aCenter.y + sign * aRadius * endAngle.Sin() );
215
216 if( aFill != FILL_T::NO_FILL )
217 {
218 LineTo( end );
219 FinishTo( aCenter );
220 }
221 else
222 {
223 FinishTo( end );
224 }
225}
226
227
228void PLOTTER::BezierCurve( const VECTOR2I& aStart, const VECTOR2I& aControl1,
229 const VECTOR2I& aControl2, const VECTOR2I& aEnd,
230 int aTolerance, int aLineThickness )
231{
232 // Generic fallback: Quadratic Bezier curve plotted as a polyline
233 std::vector<VECTOR2I> ctrlPoints;
234 ctrlPoints.reserve( 4 );
235
236 ctrlPoints.push_back( aStart );
237 ctrlPoints.push_back( aControl1 );
238 ctrlPoints.push_back( aControl2 );
239 ctrlPoints.push_back( aEnd );
240
241 BEZIER_POLY bezier_converter( ctrlPoints );
242
243 std::vector<VECTOR2I> approxPoints;
244 bezier_converter.GetPoly( approxPoints, aTolerance );
245
246 SetCurrentLineWidth( aLineThickness );
247 MoveTo( aStart );
248
249 for( unsigned ii = 1; ii < approxPoints.size()-1; ii++ )
250 LineTo( approxPoints[ii] );
251
252 FinishTo( aEnd );
253}
254
255
256void PLOTTER::PlotImage( const wxImage& aImage, const VECTOR2I& aPos, double aScaleFactor )
257{
258 VECTOR2I size( aImage.GetWidth() * aScaleFactor, aImage.GetHeight() * aScaleFactor );
259
260 VECTOR2I start = aPos;
261 start.x -= size.x / 2;
262 start.y -= size.y / 2;
263
264 VECTOR2I end = start;
265 end.x += size.x;
266 end.y += size.y;
267
269}
270
271
272void PLOTTER::markerSquare( const VECTOR2I& position, int radius )
273{
274 double r = KiROUND( radius / 1.4142 );
275 std::vector<VECTOR2I> corner_list;
276 VECTOR2I corner;
277
278 corner_list.reserve( 4 );
279
280 corner.x = position.x + r;
281 corner.y = position.y + r;
282 corner_list.push_back( corner );
283 corner.x = position.x + r;
284 corner.y = position.y - r;
285 corner_list.push_back( corner );
286 corner.x = position.x - r;
287 corner.y = position.y - r;
288 corner_list.push_back( corner );
289 corner.x = position.x - r;
290 corner.y = position.y + r;
291 corner_list.push_back( corner );
292 corner.x = position.x + r;
293 corner.y = position.y + r;
294 corner_list.push_back( corner );
295
296 PlotPoly( corner_list, FILL_T::NO_FILL, GetCurrentLineWidth(), nullptr );
297}
298
299
300void PLOTTER::markerCircle( const VECTOR2I& position, int radius )
301{
303}
304
305
306void PLOTTER::markerLozenge( const VECTOR2I& position, int radius )
307{
308 std::vector<VECTOR2I> corner_list;
309 VECTOR2I corner;
310
311 corner_list.reserve( 4 );
312
313 corner.x = position.x;
314 corner.y = position.y + radius;
315 corner_list.push_back( corner );
316 corner.x = position.x + radius;
317 corner.y = position.y,
318 corner_list.push_back( corner );
319 corner.x = position.x;
320 corner.y = position.y - radius;
321 corner_list.push_back( corner );
322 corner.x = position.x - radius;
323 corner.y = position.y;
324 corner_list.push_back( corner );
325 corner.x = position.x;
326 corner.y = position.y + radius;
327 corner_list.push_back( corner );
328
329 PlotPoly( corner_list, FILL_T::NO_FILL, GetCurrentLineWidth(), nullptr );
330}
331
332
333void PLOTTER::markerHBar( const VECTOR2I& pos, int radius )
334{
335 MoveTo( VECTOR2I( pos.x - radius, pos.y ) );
336 FinishTo( VECTOR2I( pos.x + radius, pos.y ) );
337}
338
339
340void PLOTTER::markerSlash( const VECTOR2I& pos, int radius )
341{
342 MoveTo( VECTOR2I( pos.x - radius, pos.y - radius ) );
343 FinishTo( VECTOR2I( pos.x + radius, pos.y + radius ) );
344}
345
346
348{
349 MoveTo( VECTOR2I( pos.x + radius, pos.y - radius ) );
350 FinishTo( VECTOR2I( pos.x - radius, pos.y + radius ) );
351}
352
353
354void PLOTTER::markerVBar( const VECTOR2I& pos, int radius )
355{
356 MoveTo( VECTOR2I( pos.x, pos.y - radius ) );
357 FinishTo( VECTOR2I( pos.x, pos.y + radius ) );
358}
359
360
361void PLOTTER::Marker( const VECTOR2I& position, int diametre, unsigned aShapeId )
362{
363 int radius = diametre / 2;
364
365 /* Marker are composed by a series of 'parts' superimposed; not every
366 combination make sense, obviously. Since they are used in order I
367 tried to keep the uglier/more complex constructions at the end.
368 Also I avoided the |/ |\ -/ -\ construction because they're *very*
369 ugly... if needed they could be added anyway... I'd like to see
370 a board with more than 58 drilling/slotting tools!
371 If Visual C++ supported the 0b literals they would be optimally
372 and easily encoded as an integer array. We have to do with octal */
373 static const unsigned char marker_patterns[MARKER_COUNT] = {
374
375 // Bit order: O Square Lozenge - | \ /
376 // First choice: simple shapes
377 0003, // X
378 0100, // O
379 0014, // +
380 0040, // Sq
381 0020, // Lz
382
383 // Two simple shapes
384 0103, // X O
385 0017, // X +
386 0043, // X Sq
387 0023, // X Lz
388 0114, // O +
389 0140, // O Sq
390 0120, // O Lz
391 0054, // + Sq
392 0034, // + Lz
393 0060, // Sq Lz
394
395 // Three simple shapes
396 0117, // X O +
397 0143, // X O Sq
398 0123, // X O Lz
399 0057, // X + Sq
400 0037, // X + Lz
401 0063, // X Sq Lz
402 0154, // O + Sq
403 0134, // O + Lz
404 0074, // + Sq Lz
405
406 // Four simple shapes
407 0174, // O Sq Lz +
408 0163, // X O Sq Lz
409 0157, // X O Sq +
410 0137, // X O Lz +
411 0077, // X Sq Lz +
412
413 // This draws *everything *
414 0177, // X O Sq Lz +
415
416 // Here we use the single bars... so the cross is forbidden
417 0110, // O -
418 0104, // O |
419 0101, // O /
420 0050, // Sq -
421 0044, // Sq |
422 0041, // Sq /
423 0030, // Lz -
424 0024, // Lz |
425 0021, // Lz /
426 0150, // O Sq -
427 0144, // O Sq |
428 0141, // O Sq /
429 0130, // O Lz -
430 0124, // O Lz |
431 0121, // O Lz /
432 0070, // Sq Lz -
433 0064, // Sq Lz |
434 0061, // Sq Lz /
435 0170, // O Sq Lz -
436 0164, // O Sq Lz |
437 0161, // O Sq Lz /
438
439 // Last resort: the backlash component (easy to confound)
440 0102, // \ O
441 0042, // \ Sq
442 0022, // \ Lz
443 0142, // \ O Sq
444 0122, // \ O Lz
445 0062, // \ Sq Lz
446 0162 // \ O Sq Lz
447 };
448
449 if( aShapeId >= MARKER_COUNT )
450 {
451 // Fallback shape
452 markerCircle( position, radius );
453 }
454 else
455 {
456 // Decode the pattern and draw the corresponding parts
457 unsigned char pat = marker_patterns[aShapeId];
458
459 if( pat & 0001 )
460 markerSlash( position, radius );
461
462 if( pat & 0002 )
463 markerBackSlash( position, radius );
464
465 if( pat & 0004 )
466 markerVBar( position, radius );
467
468 if( pat & 0010 )
469 markerHBar( position, radius );
470
471 if( pat & 0020 )
472 markerLozenge( position, radius );
473
474 if( pat & 0040 )
475 markerSquare( position, radius );
476
477 if( pat & 0100 )
478 markerCircle( position, radius );
479 }
480}
481
482
483void PLOTTER::ThickOval( const VECTOR2I& aPos, const VECTOR2I& aSize, const EDA_ANGLE& aOrient,
484 int aWidth, void* aData )
485{
486 SetCurrentLineWidth( aWidth, aData );
487
488 EDA_ANGLE orient( aOrient );
489 VECTOR2I size( aSize );
490
491 if( size.x > size.y )
492 {
493 std::swap( size.x, size.y );
494 orient += ANGLE_90;
495 }
496
497 int deltaxy = size.y - size.x; /* distance between centers of the oval */
498 int radius = size.x / 2;
499
500 // Build a vertical oval shape giving the start and end points of arcs and edges,
501 // and the middle point of arcs
502 std::vector<VECTOR2I> corners;
503 corners.reserve( 6 );
504 // Shape is (x = corner and arc ends, c = arc centre)
505 // xcx
506 //
507 // xcx
508 int half_height = deltaxy / 2;
509 corners.emplace_back( -radius, -half_height );
510 corners.emplace_back( -radius, half_height );
511 corners.emplace_back( 0, half_height );
512 corners.emplace_back( radius, half_height );
513 corners.emplace_back( radius, -half_height );
514 corners.emplace_back( 0, -half_height );
515
516 // Rotate and move to the actual position
517 for( VECTOR2I& corner : corners )
518 {
519 RotatePoint( corner, orient );
520 corner += aPos;
521 }
522
523 // Gen shape (2 lines and 2 180 deg arcs):
524 MoveTo( corners[0] );
525 FinishTo( corners[1] );
526
527 Arc( corners[2], -orient, ANGLE_180, radius, FILL_T::NO_FILL, aWidth );
528
529 MoveTo( corners[3] );
530 FinishTo( corners[4] );
531
532 Arc( corners[5], -orient, -ANGLE_180, radius, FILL_T::NO_FILL, aWidth );
533}
534
535
536void PLOTTER::ThickSegment( const VECTOR2I& start, const VECTOR2I& end, int width, void* aData )
537{
538 if( start == end )
539 {
540 // The width parameter doubles as a sentinel. DO_NOT_SET_LINE_WIDTH means the
541 // caller already configured the pen so we use the live pen width as the diameter.
542 // USE_DEFAULT_LINE_WIDTH must be resolved through SetCurrentLineWidth so the pen
543 // is also set to the default value, otherwise we would emit whatever the prior
544 // pen width happened to be.
545 int diameter = width;
546
547 if( width == USE_DEFAULT_LINE_WIDTH )
548 {
549 SetCurrentLineWidth( width, aData );
550 diameter = GetCurrentLineWidth();
551 }
552 else if( width == DO_NOT_SET_LINE_WIDTH )
553 {
554 diameter = GetCurrentLineWidth();
555 }
556
557 wxCHECK2_MSG( diameter >= 0, return,
558 wxT( "Plotter called with unresolved line width sentinel" ) );
559
560 Circle( start, diameter, FILL_T::FILLED_SHAPE, 0 );
561 }
562 else
563 {
564 SetCurrentLineWidth( width );
565 MoveTo( start );
566 FinishTo( end );
567 }
568}
569
570
571void PLOTTER::ThickArc( const VECTOR2D& centre, const EDA_ANGLE& aStartAngle,
572 const EDA_ANGLE& aAngle, double aRadius, int aWidth, void* aData )
573{
574 Arc( centre, aStartAngle, aAngle, aRadius, FILL_T::NO_FILL, aWidth );
575}
576
577
578void PLOTTER::ThickArc( const EDA_SHAPE& aArcShape, void* aData, int aWidth )
579{
580 VECTOR2D center = aArcShape.getCenter();
581 VECTOR2D mid = aArcShape.GetArcMid();
582 VECTOR2D start = aArcShape.GetStart();
583 VECTOR2D end = aArcShape.GetEnd();
584
585 EDA_ANGLE startAngle( start - center );
586 EDA_ANGLE endAngle( end - center );
587 EDA_ANGLE angle = endAngle - startAngle;
588
589 // < 0: left, 0 : on the line, > 0 : right
590 double det = ( end - start ).Cross( mid - start );
591
592 if( det <= 0 ) // cw
593 angle.Normalize();
594 else
595 angle.NormalizeNegative();
596
597 double radius = ( start - center ).EuclideanNorm();
598
599 ThickArc( center, startAngle, angle, radius, aWidth, aData );
600}
601
602
603void PLOTTER::ThickRect( const VECTOR2I& p1, const VECTOR2I& p2, int width, void* aData )
604{
605 Rect( p1, p2, FILL_T::NO_FILL, width, 0 );
606}
607
608
609void PLOTTER::ThickCircle( const VECTOR2I& pos, int diametre, int width, void* aData )
610{
611 Circle( pos, diametre, FILL_T::NO_FILL, width );
612}
613
614
615void PLOTTER::FilledCircle( const VECTOR2I& pos, int diametre, void* aData )
616{
617 Circle( pos, diametre, FILL_T::FILLED_SHAPE, 0 );
618}
619
620
621void PLOTTER::ThickPoly( const SHAPE_POLY_SET& aPoly, int aWidth, void* aData )
622{
623 PlotPoly( aPoly.COutline( 0 ), FILL_T::NO_FILL, aWidth, aData );
624}
625
626
627void PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aLineChain, FILL_T aFill, int aWidth, void* aData )
628{
629 std::vector<VECTOR2I> cornerList;
630 cornerList.reserve( aLineChain.PointCount() );
631
632 for( int ii = 0; ii < aLineChain.PointCount(); ii++ )
633 cornerList.emplace_back( aLineChain.CPoint( ii ) );
634
635 if( aLineChain.IsClosed() && cornerList.front() != cornerList.back() )
636 cornerList.emplace_back( aLineChain.CPoint( 0 ) );
637
638 PlotPoly( cornerList, aFill, aWidth, aData );
639}
640
641
642void PLOTTER::Text( const VECTOR2I& aPos,
643 const COLOR4D& aColor,
644 const wxString& aText,
645 const EDA_ANGLE& aOrient,
646 const VECTOR2I& aSize,
647 enum GR_TEXT_H_ALIGN_T aH_justify,
648 enum GR_TEXT_V_ALIGN_T aV_justify,
649 int aPenWidth,
650 bool aItalic,
651 bool aBold,
652 bool aMultilineAllowed,
653 KIFONT::FONT* aFont,
654 const KIFONT::METRICS& aFontMetrics,
655 void* aData )
656{
658 wxString text( aText );
659
660 if( text.Contains( wxS( "@{" ) ) )
661 {
662 EXPRESSION_EVALUATOR evaluator;
663 text = evaluator.Evaluate( text );
664 }
665
666 SetColor( aColor );
667
668 if( aPenWidth == 0 && aBold ) // Use default values if aPenWidth == 0
669 aPenWidth = GetPenSizeForBold( std::min( aSize.x, aSize.y ) );
670
671 if( aPenWidth < 0 )
672 aPenWidth = -aPenWidth;
673
674 CALLBACK_GAL callback_gal( empty_opts,
675 // Stroke callback
676 [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
677 {
678 SetCurrentLineWidth( aPenWidth );
679 MoveTo( aPt1 );
680 LineTo( aPt2 );
681 PenFinish();
682 },
683 // Polygon callback
684 [&]( const SHAPE_LINE_CHAIN& aPoly )
685 {
686 PlotPoly( aPoly, FILL_T::FILLED_SHAPE, 0, aData );
687 } );
688
689 TEXT_ATTRIBUTES attributes;
690 attributes.m_Angle = aOrient;
691 attributes.m_StrokeWidth = aPenWidth;
692 attributes.m_Italic = aItalic;
693 attributes.m_Bold = aBold;
694 attributes.m_Halign = aH_justify;
695 attributes.m_Valign = aV_justify;
696 attributes.m_Size = aSize;
697
698 // if Size.x is < 0, the text is mirrored (we have no other param to know a text is mirrored)
699 if( attributes.m_Size.x < 0 )
700 {
701 attributes.m_Size.x = -attributes.m_Size.x;
702 attributes.m_Mirrored = true;
703 }
704
705 if( !aFont )
706 aFont = KIFONT::FONT::GetFont( m_renderSettings->GetDefaultFont() );
707
708 aFont->Draw( &callback_gal, text, aPos, attributes, aFontMetrics );
709}
710
711
712void PLOTTER::PlotText( const VECTOR2I& aPos,
713 const COLOR4D& aColor,
714 const wxString& aText,
715 const TEXT_ATTRIBUTES& aAttributes,
716 KIFONT::FONT* aFont,
717 const KIFONT::METRICS& aFontMetrics,
718 void* aData )
719{
721 wxString text( aText );
722
723 if( text.Contains( wxS( "@{" ) ) )
724 {
725 EXPRESSION_EVALUATOR evaluator;
726 text = evaluator.Evaluate( text );
727 }
728
729 TEXT_ATTRIBUTES attributes = aAttributes;
730 int penWidth = attributes.m_StrokeWidth;
731
732 SetColor( aColor );
733 SetCurrentLineWidth( penWidth, aData );
734
735 if( penWidth == 0 && attributes.m_Bold ) // Use default values if aPenWidth == 0
736 penWidth = GetPenSizeForBold( std::min( attributes.m_Size.x, attributes.m_Size.y ) );
737
738 if( penWidth < 0 )
739 penWidth = -penWidth;
740
741 attributes.m_StrokeWidth = penWidth;
742
743 CALLBACK_GAL callback_gal( empty_opts,
744 // Stroke callback
745 [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
746 {
747 MoveTo( aPt1 );
748 LineTo( aPt2 );
749 PenFinish();
750 },
751 // Polygon callback
752 [&]( const SHAPE_LINE_CHAIN& aPoly )
753 {
754 PlotPoly( aPoly, FILL_T::FILLED_SHAPE, 0, aData );
755 } );
756
757 if( !aFont )
758 aFont = KIFONT::FONT::GetFont( m_renderSettings->GetDefaultFont() );
759
760 aFont->Draw( &callback_gal, text, aPos, attributes, aFontMetrics );
761}
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:986
Bezier curves to polygon converter.
void GetPoly(std::vector< VECTOR2I > &aOutput, int aMaxError=10)
Convert a Bezier curve to a polygon.
EDA_ANGLE Normalize()
Definition eda_angle.h:229
EDA_ANGLE NormalizeNegative()
Definition eda_angle.h:246
double Sin() const
Definition eda_angle.h:178
double Cos() const
Definition eda_angle.h:197
VECTOR2I getCenter() const
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition eda_shape.h:240
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition eda_shape.h:190
VECTOR2I GetArcMid() const
High-level wrapper for evaluating mathematical and string expressions in wxString format.
wxString Evaluate(const wxString &aInput)
Main evaluation function - processes input string and evaluates all} expressions.
FONT is an abstract base class for both outline and stroke fonts.
Definition font.h:94
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
Definition font.cpp:143
void Draw(KIGFX::GAL *aGal, const wxString &aText, const VECTOR2I &aPosition, const VECTOR2I &aCursor, const TEXT_ATTRIBUTES &aAttributes, const METRICS &aFontMetrics, std::optional< VECTOR2I > aMousePos=std::nullopt, wxString *aActiveUrl=nullptr) const
Draw a string.
Definition font.cpp:246
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
double GetDotMarkLenIU(int aLineWidth) const
Definition plotter.cpp:130
virtual void PlotImage(const wxImage &aImage, const VECTOR2I &aPos, double aScaleFactor)
Only PostScript plotters can plot bitmaps.
Definition plotter.cpp:256
static const unsigned MARKER_COUNT
Draw a marker (used for the drill map).
Definition plotter.h:534
double GetDashGapLenIU(int aLineWidth) const
Definition plotter.cpp:142
const PROJECT * m_project
Definition plotter.h:724
virtual void Circle(const VECTOR2I &pos, int diametre, FILL_T fill, int width)=0
virtual bool OpenFile(const wxString &aFullFilename)
Open or create the plot file aFullFilename.
Definition plotter.cpp:73
bool m_mirrorIsHorizontal
Definition plotter.h:699
virtual void ThickPoly(const SHAPE_POLY_SET &aPoly, int aWidth, void *aData)
Definition plotter.cpp:621
bool m_plotMirror
Definition plotter.h:697
static const int USE_DEFAULT_LINE_WIDTH
Definition plotter.h:137
virtual void FilledCircle(const VECTOR2I &pos, int diametre, void *aData)
Definition plotter.cpp:615
void MoveTo(const VECTOR2I &pos)
Definition plotter.h:305
virtual void ThickOval(const VECTOR2I &aPos, const VECTOR2I &aSize, const EDA_ANGLE &aOrient, int aWidth, void *aData)
Definition plotter.cpp:483
void markerSlash(const VECTOR2I &pos, int radius)
Plot a / bar centered on the position.
Definition plotter.cpp:340
void FinishTo(const VECTOR2I &pos)
Definition plotter.h:315
bool m_yaxisReversed
Definition plotter.h:700
virtual void polyArc(const VECTOR2D &aCentre, const EDA_ANGLE &aStartAngle, const EDA_ANGLE &aAngle, double aRadius, FILL_T aFill, int aWidth)
Generic fallback: arc rendered as a polyline.
Definition plotter.cpp:179
double m_iuPerDeviceUnit
Definition plotter.h:694
PCB_LAYER_ID m_layer
Definition plotter.h:727
VECTOR2I m_plotOffset
Definition plotter.h:696
virtual VECTOR2D userToDeviceCoordinates(const VECTOR2I &aCoordinate)
Modify coordinates according to the orientation, scale factor, and offsets trace.
Definition plotter.cpp:89
virtual ~PLOTTER()
Definition plotter.cpp:65
VECTOR2I m_paperSize
Definition plotter.h:718
virtual VECTOR2D userToDeviceSize(const VECTOR2I &size)
Modify size according to the plotter scale factors (VECTOR2I version, returns a VECTOR2D).
Definition plotter.cpp:114
virtual void ThickArc(const EDA_SHAPE &aArcShape, void *aData, int aWidth)
Definition plotter.cpp:578
virtual void Rect(const VECTOR2I &p1, const VECTOR2I &p2, FILL_T fill, int width, int aCornerRadius=0)=0
char m_penState
Definition plotter.h:709
void Marker(const VECTOR2I &position, int diametre, unsigned aShapeId)
Draw a pattern shape number aShapeId, to coord position.
Definition plotter.cpp:361
virtual void BezierCurve(const VECTOR2I &aStart, const VECTOR2I &aControl1, const VECTOR2I &aControl2, const VECTOR2I &aEnd, int aTolerance, int aLineThickness)
Generic fallback: Cubic Bezier curve rendered as a polyline.
Definition plotter.cpp:228
void markerHBar(const VECTOR2I &pos, int radius)
Plot a - bar centered on the position.
Definition plotter.cpp:333
int m_currentPenWidth
Definition plotter.h:708
double m_plotScale
Plot scale - chosen by the user (even implicitly with 'fit in a4')
Definition plotter.h:686
void markerCircle(const VECTOR2I &pos, int radius)
Plot a circle centered on the position.
Definition plotter.cpp:300
PLOTTER(const PROJECT *aProject=nullptr)
Definition plotter.cpp:44
FILE * m_outputFile
Output file.
Definition plotter.h:703
virtual void SetCurrentLineWidth(int width, void *aData=nullptr)=0
Set the line width for the next drawing.
void LineTo(const VECTOR2I &pos)
Definition plotter.h:310
void PenFinish()
Definition plotter.h:321
static const int DO_NOT_SET_LINE_WIDTH
Definition plotter.h:136
virtual void ThickSegment(const VECTOR2I &start, const VECTOR2I &end, int width, void *aData)
Definition plotter.cpp:536
virtual void PlotText(const VECTOR2I &aPos, const COLOR4D &aColor, const wxString &aText, const TEXT_ATTRIBUTES &aAttributes, KIFONT::FONT *aFont=nullptr, const KIFONT::METRICS &aFontMetrics=KIFONT::METRICS::Default(), void *aData=nullptr)
Definition plotter.cpp:712
void markerLozenge(const VECTOR2I &position, int radius)
Plot a lozenge centered on the position.
Definition plotter.cpp:306
virtual void PlotPoly(const std::vector< VECTOR2I > &aCornerList, FILL_T aFill, int aWidth, void *aData)=0
Draw a polygon ( filled or not ).
virtual void ThickRect(const VECTOR2I &p1, const VECTOR2I &p2, int width, void *aData)
Definition plotter.cpp:603
RENDER_SETTINGS * m_renderSettings
Definition plotter.h:722
virtual void Text(const VECTOR2I &aPos, const COLOR4D &aColor, const wxString &aText, const EDA_ANGLE &aOrient, const VECTOR2I &aSize, enum GR_TEXT_H_ALIGN_T aH_justify, enum GR_TEXT_V_ALIGN_T aV_justify, int aPenWidth, bool aItalic, bool aBold, bool aMultilineAllowed, KIFONT::FONT *aFont, const KIFONT::METRICS &aFontMetrics, void *aData=nullptr)
Draw text with the plotter.
Definition plotter.cpp:642
void markerBackSlash(const VECTOR2I &pos, int radius)
Plot a \ bar centered on the position.
Definition plotter.cpp:347
bool m_negativeMode
Definition plotter.h:707
double m_IUsPerDecimil
Definition plotter.h:692
void markerVBar(const VECTOR2I &pos, int radius)
Plot a | bar centered on the position.
Definition plotter.cpp:354
void markerSquare(const VECTOR2I &position, int radius)
Plot a square centered on the position.
Definition plotter.cpp:272
virtual void ThickCircle(const VECTOR2I &pos, int diametre, int width, void *aData)
Definition plotter.cpp:609
virtual int GetCurrentLineWidth() const
Definition plotter.h:179
bool m_colorMode
Definition plotter.h:706
double GetDashMarkLenIU(int aLineWidth) const
Definition plotter.cpp:136
virtual void SetColor(const COLOR4D &color)=0
wxString m_filename
Definition plotter.h:713
virtual void Arc(const VECTOR2D &aStart, const VECTOR2D &aMid, const VECTOR2D &aEnd, FILL_T aFill, int aWidth)
Definition plotter.cpp:148
Container for project specific data.
Definition project.h:62
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
bool IsClosed() const override
int PointCount() const
Return the number of points (vertices) in this line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
Represent a set of closed polygons.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:411
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:413
@ DEGREES_T
Definition eda_angle.h:31
static constexpr EDA_ANGLE ANGLE_180
Definition eda_angle.h:415
FILL_T
Definition eda_shape.h:59
@ NO_FILL
Definition eda_shape.h:60
@ FILLED_SHAPE
Fill with object color.
Definition eda_shape.h:61
int GetPenSizeForBold(int aTextSize)
Definition gr_text.cpp:33
@ UNDEFINED_LAYER
Definition layer_ids.h:57
bool cw
VECTOR2I center
int radius
VECTOR2I end
int delta
GR_TEXT_H_ALIGN_T
This is API surface mapped to common.types.HorizontalAlignment.
GR_TEXT_V_ALIGN_T
This is API surface mapped to common.types.VertialAlignment.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition trigo.cpp:225
const VECTOR2I CalcArcCenter(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Determine the center of an arc or circle given three points on its circumference.
Definition trigo.cpp:530
constexpr int sign(T val)
Definition util.h:141
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683
VECTOR2< double > VECTOR2D
Definition vector2d.h:682