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 <eda_shape.h>
38#include <plotters/plotter.h>
41#include <bezier_curves.h>
42#include <callback_gal.h>
43#include <math/util.h> // for KiROUND
45
46PLOTTER::PLOTTER( const PROJECT* aProject ) :
47 m_project( aProject )
48{
49 m_plotScale = 1;
50 m_currentPenWidth = -1; // To-be-set marker
51 m_penState = 'Z'; // End-of-path idle
52 m_plotMirror = false; // Plot mirror option flag
54 m_yaxisReversed = false;
55 m_outputFile = nullptr;
56 m_colorMode = false; // Starts as a BW plot
57 m_negativeMode = false;
58
59 // Temporary init to avoid not initialized vars, will be set later
60 m_IUsPerDecimil = 1; // will be set later to the actual value
61 m_iuPerDeviceUnit = 1; // will be set later to the actual value
62 m_renderSettings = nullptr;
64}
65
66
68{
69 // Emergency cleanup, but closing the file is usually made in EndPlot().
70 if( m_outputFile )
71 fclose( m_outputFile );
72}
73
74
75bool PLOTTER::OpenFile( const wxString& aFullFilename )
76{
77 m_filename = aFullFilename;
78
79 wxASSERT( !m_outputFile );
80
81 // Open the file in text mode (not suitable for all plotters but only for most of them.
82 m_outputFile = wxFopen( m_filename, wxT( "wt" ) );
83
84 if( m_outputFile == nullptr )
85 return false ;
86
87 return true;
88}
89
90
92{
93 VECTOR2I pos = aCoordinate - m_plotOffset;
94
95 double x = pos.x * m_plotScale;
96 double y = ( m_paperSize.y - pos.y * m_plotScale );
97
98 if( m_plotMirror )
99 {
101 x = ( m_paperSize.x - pos.x * m_plotScale );
102 else
103 y = pos.y * m_plotScale;
104 }
105
106 if( m_yaxisReversed )
107 y = m_paperSize.y - y;
108
111
112 return VECTOR2D( x, y );
113}
114
115
121
122
123double PLOTTER::userToDeviceSize( double size ) const
124{
125 return size * m_plotScale * m_iuPerDeviceUnit;
126}
127
128
129#define IU_PER_MILS ( m_IUsPerDecimil * 10 )
130
131
132double PLOTTER::GetDotMarkLenIU( int aLineWidth ) const
133{
134 return userToDeviceSize( m_renderSettings->GetDotLength( aLineWidth ) );
135}
136
137
138double PLOTTER::GetDashMarkLenIU( int aLineWidth ) const
139{
140 return userToDeviceSize( m_renderSettings->GetDashLength( aLineWidth ) );
141}
142
143
144double PLOTTER::GetDashGapLenIU( int aLineWidth ) const
145{
146 return userToDeviceSize( m_renderSettings->GetGapLength( aLineWidth ) );
147}
148
149
150void PLOTTER::Arc( const VECTOR2D& aStart, const VECTOR2D& aMid, const VECTOR2D& aEnd, FILL_T aFill,
151 int aWidth )
152{
153 VECTOR2D aCenter = CalcArcCenter( aStart, aMid, aEnd );
154
155 EDA_ANGLE startAngle( aStart - aCenter );
156 EDA_ANGLE endAngle( aEnd - aCenter );
157
158 // < 0: left, 0 : on the line, > 0 : right
159 double det = ( aEnd - aStart ).Cross( aMid - aStart );
160
161 int cw = det <= 0;
162 EDA_ANGLE angle = endAngle - startAngle;
163
164 if( cw )
165 angle.Normalize();
166 else
167 angle.NormalizeNegative();
168
169 double radius = ( aStart - aCenter ).EuclideanNorm();
170 Arc( aCenter, startAngle, angle, radius, aFill, aWidth );
171}
172
173
174void PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aAngle,
175 double aRadius, FILL_T aFill, int aWidth )
176{
177 polyArc( aCenter, aStartAngle, aAngle, aRadius, aFill, aWidth );
178}
179
180
181void PLOTTER::polyArc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
182 const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill, int aWidth )
183{
184 EDA_ANGLE startAngle = aStartAngle;
185 EDA_ANGLE endAngle = startAngle + aAngle;
186 const EDA_ANGLE delta( 5.0, DEGREES_T ); // increment to draw arc
187 VECTOR2I start, end;
188 const int sign = 1;
189
190 if( aAngle < ANGLE_0 )
191 std::swap( startAngle, endAngle );
192
193 SetCurrentLineWidth( aWidth );
194
195 start.x = KiROUND( aCenter.x + aRadius * startAngle.Cos() );
196 start.y = KiROUND( aCenter.y + sign * aRadius * startAngle.Sin() );
197
198 if( aFill != FILL_T::NO_FILL )
199 {
200 MoveTo( aCenter );
201 LineTo( start );
202 }
203 else
204 {
205 MoveTo( start );
206 }
207
208 for( EDA_ANGLE ii = startAngle + delta; ii < endAngle; ii += delta )
209 {
210 end.x = KiROUND( aCenter.x + aRadius * ii.Cos() );
211 end.y = KiROUND( aCenter.y + sign * aRadius * ii.Sin() );
212 LineTo( end );
213 }
214
215 end.x = KiROUND( aCenter.x + aRadius * endAngle.Cos() );
216 end.y = KiROUND( aCenter.y + sign * aRadius * endAngle.Sin() );
217
218 if( aFill != FILL_T::NO_FILL )
219 {
220 LineTo( end );
221 FinishTo( aCenter );
222 }
223 else
224 {
225 FinishTo( end );
226 }
227}
228
229
230void PLOTTER::BezierCurve( const VECTOR2I& aStart, const VECTOR2I& aControl1,
231 const VECTOR2I& aControl2, const VECTOR2I& aEnd,
232 int aTolerance, int aLineThickness )
233{
234 // Generic fallback: Quadratic Bezier curve plotted as a polyline
235 std::vector<VECTOR2I> ctrlPoints;
236 ctrlPoints.reserve( 4 );
237
238 ctrlPoints.push_back( aStart );
239 ctrlPoints.push_back( aControl1 );
240 ctrlPoints.push_back( aControl2 );
241 ctrlPoints.push_back( aEnd );
242
243 BEZIER_POLY bezier_converter( ctrlPoints );
244
245 std::vector<VECTOR2I> approxPoints;
246 bezier_converter.GetPoly( approxPoints, aTolerance );
247
248 SetCurrentLineWidth( aLineThickness );
249 MoveTo( aStart );
250
251 for( unsigned ii = 1; ii < approxPoints.size()-1; ii++ )
252 LineTo( approxPoints[ii] );
253
254 FinishTo( aEnd );
255}
256
257
258void PLOTTER::PlotImage( const wxImage& aImage, const VECTOR2I& aPos, double aScaleFactor )
259{
260 VECTOR2I size( aImage.GetWidth() * aScaleFactor, aImage.GetHeight() * aScaleFactor );
261
262 VECTOR2I start = aPos;
263 start.x -= size.x / 2;
264 start.y -= size.y / 2;
265
266 VECTOR2I end = start;
267 end.x += size.x;
268 end.y += size.y;
269
271}
272
273
274void PLOTTER::markerSquare( const VECTOR2I& position, int radius )
275{
276 double r = KiROUND( radius / 1.4142 );
277 std::vector<VECTOR2I> corner_list;
278 VECTOR2I corner;
279
280 corner_list.reserve( 4 );
281
282 corner.x = position.x + r;
283 corner.y = position.y + r;
284 corner_list.push_back( corner );
285 corner.x = position.x + r;
286 corner.y = position.y - r;
287 corner_list.push_back( corner );
288 corner.x = position.x - r;
289 corner.y = position.y - r;
290 corner_list.push_back( corner );
291 corner.x = position.x - r;
292 corner.y = position.y + r;
293 corner_list.push_back( corner );
294 corner.x = position.x + r;
295 corner.y = position.y + r;
296 corner_list.push_back( corner );
297
298 PlotPoly( corner_list, FILL_T::NO_FILL, GetCurrentLineWidth(), nullptr );
299}
300
301
302void PLOTTER::markerCircle( const VECTOR2I& position, int radius )
303{
305}
306
307
308void PLOTTER::markerLozenge( const VECTOR2I& position, int radius )
309{
310 std::vector<VECTOR2I> corner_list;
311 VECTOR2I corner;
312
313 corner_list.reserve( 4 );
314
315 corner.x = position.x;
316 corner.y = position.y + radius;
317 corner_list.push_back( corner );
318 corner.x = position.x + radius;
319 corner.y = position.y,
320 corner_list.push_back( corner );
321 corner.x = position.x;
322 corner.y = position.y - radius;
323 corner_list.push_back( corner );
324 corner.x = position.x - radius;
325 corner.y = position.y;
326 corner_list.push_back( corner );
327 corner.x = position.x;
328 corner.y = position.y + radius;
329 corner_list.push_back( corner );
330
331 PlotPoly( corner_list, FILL_T::NO_FILL, GetCurrentLineWidth(), nullptr );
332}
333
334
335void PLOTTER::markerHBar( const VECTOR2I& pos, int radius )
336{
337 MoveTo( VECTOR2I( pos.x - radius, pos.y ) );
338 FinishTo( VECTOR2I( pos.x + radius, pos.y ) );
339}
340
341
342void PLOTTER::markerSlash( const VECTOR2I& pos, int radius )
343{
344 MoveTo( VECTOR2I( pos.x - radius, pos.y - radius ) );
345 FinishTo( VECTOR2I( pos.x + radius, pos.y + radius ) );
346}
347
348
350{
351 MoveTo( VECTOR2I( pos.x + radius, pos.y - radius ) );
352 FinishTo( VECTOR2I( pos.x - radius, pos.y + radius ) );
353}
354
355
356void PLOTTER::markerVBar( const VECTOR2I& pos, int radius )
357{
358 MoveTo( VECTOR2I( pos.x, pos.y - radius ) );
359 FinishTo( VECTOR2I( pos.x, pos.y + radius ) );
360}
361
362
363void PLOTTER::Marker( const VECTOR2I& position, int diametre, unsigned aShapeId )
364{
365 const int radius = diametre / 2;
366
367 for( const DRILL_MARKERS::MARKER_PART& part : DRILL_MARKERS::BuildMarker( position, radius, aShapeId ) )
368 {
369 switch( part.m_Type )
370 {
372 MoveTo( part.m_Points.front() );
373 FinishTo( part.m_Points.back() );
374 break;
375
377 PlotPoly( part.m_Points, FILL_T::NO_FILL, GetCurrentLineWidth(), nullptr );
378 break;
379
381 Circle( position, part.m_Radius * 2, FILL_T::NO_FILL, GetCurrentLineWidth() );
382 break;
383 }
384 }
385}
386
387
388void PLOTTER::ThickOval( const VECTOR2I& aPos, const VECTOR2I& aSize, const EDA_ANGLE& aOrient,
389 int aWidth, void* aData )
390{
391 SetCurrentLineWidth( aWidth, aData );
392
393 EDA_ANGLE orient( aOrient );
394 VECTOR2I size( aSize );
395
396 if( size.x > size.y )
397 {
398 std::swap( size.x, size.y );
399 orient += ANGLE_90;
400 }
401
402 int deltaxy = size.y - size.x; /* distance between centers of the oval */
403 int radius = size.x / 2;
404
405 // Build a vertical oval shape giving the start and end points of arcs and edges,
406 // and the middle point of arcs
407 std::vector<VECTOR2I> corners;
408 corners.reserve( 6 );
409 // Shape is (x = corner and arc ends, c = arc centre)
410 // xcx
411 //
412 // xcx
413 int half_height = deltaxy / 2;
414 corners.emplace_back( -radius, -half_height );
415 corners.emplace_back( -radius, half_height );
416 corners.emplace_back( 0, half_height );
417 corners.emplace_back( radius, half_height );
418 corners.emplace_back( radius, -half_height );
419 corners.emplace_back( 0, -half_height );
420
421 // Rotate and move to the actual position
422 for( VECTOR2I& corner : corners )
423 {
424 RotatePoint( corner, orient );
425 corner += aPos;
426 }
427
428 // Gen shape (2 lines and 2 180 deg arcs):
429 MoveTo( corners[0] );
430 FinishTo( corners[1] );
431
432 Arc( corners[2], -orient, ANGLE_180, radius, FILL_T::NO_FILL, aWidth );
433
434 MoveTo( corners[3] );
435 FinishTo( corners[4] );
436
437 Arc( corners[5], -orient, -ANGLE_180, radius, FILL_T::NO_FILL, aWidth );
438}
439
440
441void PLOTTER::ThickSegment( const VECTOR2I& start, const VECTOR2I& end, int width, void* aData )
442{
443 if( start == end )
444 {
445 // The width parameter doubles as a sentinel. DO_NOT_SET_LINE_WIDTH means the
446 // caller already configured the pen so we use the live pen width as the diameter.
447 // USE_DEFAULT_LINE_WIDTH must be resolved through SetCurrentLineWidth so the pen
448 // is also set to the default value, otherwise we would emit whatever the prior
449 // pen width happened to be.
450 int diameter = width;
451
452 if( width == USE_DEFAULT_LINE_WIDTH )
453 {
454 SetCurrentLineWidth( width, aData );
455 diameter = GetCurrentLineWidth();
456 }
457 else if( width == DO_NOT_SET_LINE_WIDTH )
458 {
459 diameter = GetCurrentLineWidth();
460 }
461
462 wxCHECK2_MSG( diameter >= 0, return,
463 wxT( "Plotter called with unresolved line width sentinel" ) );
464
465 Circle( start, diameter, FILL_T::FILLED_SHAPE, 0 );
466 }
467 else
468 {
469 SetCurrentLineWidth( width );
470 MoveTo( start );
471 FinishTo( end );
472 }
473}
474
475
476void PLOTTER::ThickArc( const VECTOR2D& centre, const EDA_ANGLE& aStartAngle,
477 const EDA_ANGLE& aAngle, double aRadius, int aWidth, void* aData )
478{
479 Arc( centre, aStartAngle, aAngle, aRadius, FILL_T::NO_FILL, aWidth );
480}
481
482
483void PLOTTER::ThickArc( const EDA_SHAPE& aArcShape, void* aData, int aWidth )
484{
485 VECTOR2D center = aArcShape.getCenter();
486 VECTOR2D mid = aArcShape.GetArcMid();
487 VECTOR2D start = aArcShape.GetStart();
488 VECTOR2D end = aArcShape.GetEnd();
489
490 EDA_ANGLE startAngle( start - center );
491 EDA_ANGLE endAngle( end - center );
492 EDA_ANGLE angle = endAngle - startAngle;
493
494 // < 0: left, 0 : on the line, > 0 : right
495 double det = ( end - start ).Cross( mid - start );
496
497 if( det <= 0 ) // cw
498 angle.Normalize();
499 else
500 angle.NormalizeNegative();
501
502 double radius = ( start - center ).EuclideanNorm();
503
504 ThickArc( center, startAngle, angle, radius, aWidth, aData );
505}
506
507
508void PLOTTER::ThickRect( const VECTOR2I& p1, const VECTOR2I& p2, int width, void* aData )
509{
510 Rect( p1, p2, FILL_T::NO_FILL, width, 0 );
511}
512
513
514void PLOTTER::ThickCircle( const VECTOR2I& pos, int diametre, int width, void* aData )
515{
516 Circle( pos, diametre, FILL_T::NO_FILL, width );
517}
518
519
520void PLOTTER::FilledCircle( const VECTOR2I& pos, int diametre, void* aData )
521{
522 Circle( pos, diametre, FILL_T::FILLED_SHAPE, 0 );
523}
524
525
526void PLOTTER::ThickPoly( const SHAPE_POLY_SET& aPoly, int aWidth, void* aData )
527{
528 PlotPoly( aPoly.COutline( 0 ), FILL_T::NO_FILL, aWidth, aData );
529}
530
531
532void PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aLineChain, FILL_T aFill, int aWidth, void* aData )
533{
534 std::vector<VECTOR2I> cornerList;
535 cornerList.reserve( aLineChain.PointCount() );
536
537 for( int ii = 0; ii < aLineChain.PointCount(); ii++ )
538 cornerList.emplace_back( aLineChain.CPoint( ii ) );
539
540 if( aLineChain.IsClosed() && cornerList.front() != cornerList.back() )
541 cornerList.emplace_back( aLineChain.CPoint( 0 ) );
542
543 PlotPoly( cornerList, aFill, aWidth, aData );
544}
545
546
547void PLOTTER::Text( const VECTOR2I& aPos,
548 const COLOR4D& aColor,
549 const wxString& aText,
550 const EDA_ANGLE& aOrient,
551 const VECTOR2I& aSize,
552 enum GR_TEXT_H_ALIGN_T aH_justify,
553 enum GR_TEXT_V_ALIGN_T aV_justify,
554 int aPenWidth,
555 bool aItalic,
556 bool aBold,
557 bool aMultilineAllowed,
558 KIFONT::FONT* aFont,
559 const KIFONT::METRICS& aFontMetrics,
560 void* aData )
561{
563 wxString text( aText );
564
565 if( text.Contains( wxS( "@{" ) ) )
566 {
567 EXPRESSION_EVALUATOR evaluator;
568 text = evaluator.Evaluate( text );
569 }
570
571 SetColor( aColor );
572
573 if( aPenWidth == 0 && aBold ) // Use default values if aPenWidth == 0
574 aPenWidth = GetPenSizeForBold( std::min( aSize.x, aSize.y ) );
575
576 if( aPenWidth < 0 )
577 aPenWidth = -aPenWidth;
578
579 CALLBACK_GAL callback_gal( empty_opts,
580 // Stroke callback
581 [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
582 {
583 SetCurrentLineWidth( aPenWidth );
584 MoveTo( aPt1 );
585 LineTo( aPt2 );
586 PenFinish();
587 },
588 // Polygon callback
589 [&]( const SHAPE_LINE_CHAIN& aPoly )
590 {
591 PlotPoly( aPoly, FILL_T::FILLED_SHAPE, 0, aData );
592 } );
593
594 TEXT_ATTRIBUTES attributes;
595 attributes.m_Angle = aOrient;
596 attributes.m_StrokeWidth = aPenWidth;
597 attributes.m_Italic = aItalic;
598 attributes.m_Bold = aBold;
599 attributes.m_Halign = aH_justify;
600 attributes.m_Valign = aV_justify;
601 attributes.m_Size = aSize;
602
603 // if Size.x is < 0, the text is mirrored (we have no other param to know a text is mirrored)
604 if( attributes.m_Size.x < 0 )
605 {
606 attributes.m_Size.x = -attributes.m_Size.x;
607 attributes.m_Mirrored = true;
608 }
609
610 if( !aFont )
611 aFont = KIFONT::FONT::GetFont( m_renderSettings->GetDefaultFont() );
612
613 aFont->Draw( &callback_gal, text, aPos, attributes, aFontMetrics );
614}
615
616
617void PLOTTER::PlotText( const VECTOR2I& aPos,
618 const COLOR4D& aColor,
619 const wxString& aText,
620 const TEXT_ATTRIBUTES& aAttributes,
621 KIFONT::FONT* aFont,
622 const KIFONT::METRICS& aFontMetrics,
623 void* aData )
624{
626 wxString text( aText );
627
628 if( text.Contains( wxS( "@{" ) ) )
629 {
630 EXPRESSION_EVALUATOR evaluator;
631 text = evaluator.Evaluate( text );
632 }
633
634 TEXT_ATTRIBUTES attributes = aAttributes;
635 int penWidth = attributes.m_StrokeWidth;
636
637 SetColor( aColor );
638 SetCurrentLineWidth( penWidth, aData );
639
640 if( penWidth == 0 && attributes.m_Bold ) // Use default values if aPenWidth == 0
641 penWidth = GetPenSizeForBold( std::min( attributes.m_Size.x, attributes.m_Size.y ) );
642
643 if( penWidth < 0 )
644 penWidth = -penWidth;
645
646 attributes.m_StrokeWidth = penWidth;
647
648 CALLBACK_GAL callback_gal( empty_opts,
649 // Stroke callback
650 [&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
651 {
652 MoveTo( aPt1 );
653 LineTo( aPt2 );
654 PenFinish();
655 },
656 // Polygon callback
657 [&]( const SHAPE_LINE_CHAIN& aPoly )
658 {
659 PlotPoly( aPoly, FILL_T::FILLED_SHAPE, 0, aData );
660 } );
661
662 if( !aFont )
663 aFont = KIFONT::FONT::GetFont( m_renderSettings->GetDefaultFont() );
664
665 aFont->Draw( &callback_gal, text, aPos, attributes, aFontMetrics );
666}
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:995
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:325
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition eda_shape.h:275
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:240
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
double GetDotMarkLenIU(int aLineWidth) const
Definition plotter.cpp:132
virtual void PlotImage(const wxImage &aImage, const VECTOR2I &aPos, double aScaleFactor)
Only PostScript plotters can plot bitmaps.
Definition plotter.cpp:258
double GetDashGapLenIU(int aLineWidth) const
Definition plotter.cpp:144
const PROJECT * m_project
Definition plotter.h:738
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:75
bool m_mirrorIsHorizontal
Definition plotter.h:713
virtual void ThickPoly(const SHAPE_POLY_SET &aPoly, int aWidth, void *aData)
Definition plotter.cpp:526
bool m_plotMirror
Definition plotter.h:711
static const int USE_DEFAULT_LINE_WIDTH
Definition plotter.h:140
virtual void FilledCircle(const VECTOR2I &pos, int diametre, void *aData)
Definition plotter.cpp:520
void MoveTo(const VECTOR2I &pos)
Definition plotter.h:308
virtual void ThickOval(const VECTOR2I &aPos, const VECTOR2I &aSize, const EDA_ANGLE &aOrient, int aWidth, void *aData)
Definition plotter.cpp:388
void markerSlash(const VECTOR2I &pos, int radius)
Plot a / bar centered on the position.
Definition plotter.cpp:342
void FinishTo(const VECTOR2I &pos)
Definition plotter.h:318
bool m_yaxisReversed
Definition plotter.h:714
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:181
double m_iuPerDeviceUnit
Definition plotter.h:708
PCB_LAYER_ID m_layer
Definition plotter.h:741
VECTOR2I m_plotOffset
Definition plotter.h:710
virtual VECTOR2D userToDeviceCoordinates(const VECTOR2I &aCoordinate)
Modify coordinates according to the orientation, scale factor, and offsets trace.
Definition plotter.cpp:91
virtual ~PLOTTER()
Definition plotter.cpp:67
VECTOR2I m_paperSize
Definition plotter.h:732
virtual VECTOR2D userToDeviceSize(const VECTOR2I &size)
Modify size according to the plotter scale factors (VECTOR2I version, returns a VECTOR2D).
Definition plotter.cpp:116
virtual void ThickArc(const EDA_SHAPE &aArcShape, void *aData, int aWidth)
Definition plotter.cpp:483
virtual void Rect(const VECTOR2I &p1, const VECTOR2I &p2, FILL_T fill, int width, int aCornerRadius=0)=0
char m_penState
Definition plotter.h:723
void Marker(const VECTOR2I &position, int diametre, unsigned aShapeId)
Draw a pattern shape number aShapeId, to coord position.
Definition plotter.cpp:363
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:230
void markerHBar(const VECTOR2I &pos, int radius)
Plot a - bar centered on the position.
Definition plotter.cpp:335
int m_currentPenWidth
Definition plotter.h:722
double m_plotScale
Plot scale - chosen by the user (even implicitly with 'fit in a4')
Definition plotter.h:700
void markerCircle(const VECTOR2I &pos, int radius)
Plot a circle centered on the position.
Definition plotter.cpp:302
PLOTTER(const PROJECT *aProject=nullptr)
Definition plotter.cpp:46
FILE * m_outputFile
Output file.
Definition plotter.h:717
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:313
void PenFinish()
Definition plotter.h:324
static const int DO_NOT_SET_LINE_WIDTH
Definition plotter.h:139
virtual void ThickSegment(const VECTOR2I &start, const VECTOR2I &end, int width, void *aData)
Definition plotter.cpp:441
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:617
void markerLozenge(const VECTOR2I &position, int radius)
Plot a lozenge centered on the position.
Definition plotter.cpp:308
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:508
RENDER_SETTINGS * m_renderSettings
Definition plotter.h:736
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:547
void markerBackSlash(const VECTOR2I &pos, int radius)
Plot a \ bar centered on the position.
Definition plotter.cpp:349
bool m_negativeMode
Definition plotter.h:721
double m_IUsPerDecimil
Definition plotter.h:706
void markerVBar(const VECTOR2I &pos, int radius)
Plot a | bar centered on the position.
Definition plotter.cpp:356
void markerSquare(const VECTOR2I &position, int radius)
Plot a square centered on the position.
Definition plotter.cpp:274
virtual void ThickCircle(const VECTOR2I &pos, int diametre, int width, void *aData)
Definition plotter.cpp:514
virtual int GetCurrentLineWidth() const
Definition plotter.h:182
bool m_colorMode
Definition plotter.h:720
double GetDashMarkLenIU(int aLineWidth) const
Definition plotter.cpp:138
virtual void SetColor(const COLOR4D &color)=0
wxString m_filename
Definition plotter.h:727
virtual void Arc(const VECTOR2D &aStart, const VECTOR2D &aMid, const VECTOR2D &aEnd, FILL_T aFill, int aWidth)
Definition plotter.cpp:150
Container for project specific data.
Definition project.h:63
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:422
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:424
@ DEGREES_T
Definition eda_angle.h:31
static constexpr EDA_ANGLE ANGLE_180
Definition eda_angle.h:426
FILL_T
Definition eda_fill.h:29
@ NO_FILL
Definition eda_fill.h:30
@ FILLED_SHAPE
Fill with object color.
Definition eda_fill.h:31
int GetPenSizeForBold(int aTextSize)
Definition gr_text.cpp:33
@ UNDEFINED_LAYER
Definition layer_ids.h:57
std::vector< MARKER_PART > BuildMarker(const VECTOR2I &aPosition, int aRadius, unsigned aShapeId)
Decompose one mark, in the order the parts must be drawn.
One stroke of a mark.
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:562
constexpr int sign(T val)
Definition util.h:141
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683
VECTOR2< double > VECTOR2D
Definition vector2d.h:682