KiCad PCB EDA Suite
Loading...
Searching...
No Matches
PS_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 (C) 2020-2022 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, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
31#include <macros.h>
32#include <math/util.h> // for KiROUND
33#include <trigo.h>
34
36
37
38/* Forward declaration of the font width metrics
39 (yes extern! this is the way to forward declare variables */
40extern const double hv_widths[256];
41extern const double hvb_widths[256];
42extern const double hvo_widths[256];
43extern const double hvbo_widths[256];
44
45const double PSLIKE_PLOTTER::postscriptTextAscent = 0.718;
46
47
48// return a id used to select a ps macro (see StartPlot() ) from a FILL_TYPE
49// fill mode, for arc, rect, circle and poly draw primitives
50static int getFillId( FILL_T aFill )
51{
52 if( aFill == FILL_T::NO_FILL )
53 return 0;
54
55 if( aFill == FILL_T::FILLED_SHAPE )
56 return 1;
57
58 return 2;
59}
60
61
63{
64 if( m_colorMode )
65 {
66 if( m_negativeMode )
67 emitSetRGBColor( 1 - color.r, 1 - color.g, 1 - color.b, color.a );
68 else
70 }
71 else
72 {
73 /* B/W Mode - Use BLACK or WHITE for all items
74 * note the 2 colors are used in B&W mode, mainly by Pcbnew to draw
75 * holes in white on pads in black
76 */
77 double k = 1; // White
78
79 if( color != COLOR4D::WHITE )
80 k = 0;
81
82 if( m_negativeMode )
83 emitSetRGBColor( 1 - k, 1 - k, 1 - k, 1.0 );
84 else
85 emitSetRGBColor( k, k, k, 1.0 );
86 }
87}
88
89
90void PSLIKE_PLOTTER::FlashPadOval( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
91 const EDA_ANGLE& aPadOrient, OUTLINE_MODE aTraceMode,
92 void* aData )
93{
94 wxASSERT( m_outputFile );
95
96 VECTOR2I size( aSize );
97 EDA_ANGLE orient( aPadOrient );
98
99 // The pad is reduced to an oval by dy > dx
100 if( size.x > size.y )
101 {
102 std::swap( size.x, size.y );
103 orient += ANGLE_90;
104 }
105
106 int delta = size.y - size.x;
107 VECTOR2I a( 0, -delta / 2 );
108 VECTOR2I b( 0, delta / 2 );
109
110 RotatePoint( a, orient );
111 RotatePoint( b, orient );
112
113 if( aTraceMode == FILLED )
114 ThickSegment( a + aPadPos, b + aPadPos, size.x, aTraceMode, nullptr );
115 else
116 sketchOval( aPadPos, size, orient, -1 );
117}
118
119
120void PSLIKE_PLOTTER::FlashPadCircle( const VECTOR2I& aPadPos, int aDiameter,
121 OUTLINE_MODE aTraceMode, void* aData )
122{
123 if( aTraceMode == FILLED )
124 {
125 Circle( aPadPos, aDiameter, FILL_T::FILLED_SHAPE, 0 );
126 }
127 else // Plot a ring:
128 {
130 Circle( aPadPos, aDiameter, FILL_T::NO_FILL, GetCurrentLineWidth() );
131 }
132
134}
135
136
137void PSLIKE_PLOTTER::FlashPadRect( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
138 const EDA_ANGLE& aPadOrient, OUTLINE_MODE aTraceMode,
139 void* aData )
140{
141 std::vector<VECTOR2I> cornerList;
142 VECTOR2I size( aSize );
143 cornerList.reserve( 4 );
144
145 if( aTraceMode == FILLED )
147 else
149
150 int dx = size.x / 2;
151 int dy = size.y / 2;
152
153 VECTOR2I corner;
154 corner.x = aPadPos.x - dx;
155 corner.y = aPadPos.y + dy;
156 cornerList.push_back( corner );
157 corner.x = aPadPos.x - dx;
158 corner.y = aPadPos.y - dy;
159 cornerList.push_back( corner );
160 corner.x = aPadPos.x + dx;
161 corner.y = aPadPos.y - dy;
162 cornerList.push_back( corner );
163 corner.x = aPadPos.x + dx;
164 corner.y = aPadPos.y + dy,
165 cornerList.push_back( corner );
166
167 for( unsigned ii = 0; ii < cornerList.size(); ii++ )
168 RotatePoint( cornerList[ii], aPadPos, aPadOrient );
169
170 cornerList.push_back( cornerList[0] );
171
172 PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL,
174}
175
176
177void PSLIKE_PLOTTER::FlashPadRoundRect( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
178 int aCornerRadius, const EDA_ANGLE& aOrient,
179 OUTLINE_MODE aTraceMode, void* aData )
180{
181 VECTOR2I size( aSize );
182
183 if( aTraceMode == FILLED )
184 {
186 }
187 else
188 {
190 }
191
192
193 SHAPE_POLY_SET outline;
194 TransformRoundChamferedRectToPolygon( outline, aPadPos, size, aOrient, aCornerRadius, 0.0, 0,
196
197 std::vector<VECTOR2I> cornerList;
198
199 // TransformRoundRectToPolygon creates only one convex polygon
200 SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
201 cornerList.reserve( poly.PointCount() );
202
203 for( int ii = 0; ii < poly.PointCount(); ++ii )
204 cornerList.emplace_back( poly.CPoint( ii ).x, poly.CPoint( ii ).y );
205
206 // Close polygon
207 cornerList.push_back( cornerList[0] );
208
209 PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL,
211}
212
213
214void PSLIKE_PLOTTER::FlashPadCustom( const VECTOR2I& aPadPos, const VECTOR2I& aSize,
215 const EDA_ANGLE& aOrient, SHAPE_POLY_SET* aPolygons,
216 OUTLINE_MODE aTraceMode, void* aData )
217{
218 VECTOR2I size( aSize );
219
220 if( aTraceMode == FILLED )
221 {
223 }
224 else
225 {
227 }
228
229
230 std::vector<VECTOR2I> cornerList;
231
232 for( int cnt = 0; cnt < aPolygons->OutlineCount(); ++cnt )
233 {
234 SHAPE_LINE_CHAIN& poly = aPolygons->Outline( cnt );
235 cornerList.clear();
236
237 for( int ii = 0; ii < poly.PointCount(); ++ii )
238 cornerList.emplace_back( poly.CPoint( ii ).x, poly.CPoint( ii ).y );
239
240 // Close polygon
241 cornerList.push_back( cornerList[0] );
242
243 PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL,
245 }
246}
247
248
249void PSLIKE_PLOTTER::FlashPadTrapez( const VECTOR2I& aPadPos, const VECTOR2I* aCorners,
250 const EDA_ANGLE& aPadOrient, OUTLINE_MODE aTraceMode,
251 void* aData )
252{
253 static std::vector<VECTOR2I> cornerList;
254 cornerList.clear();
255
256 for( int ii = 0; ii < 4; ii++ )
257 cornerList.push_back( aCorners[ii] );
258
259 if( aTraceMode == FILLED )
260 {
262 }
263 else
264 {
266 }
267
268 for( int ii = 0; ii < 4; ii++ )
269 {
270 RotatePoint( cornerList[ii], aPadOrient );
271 cornerList[ii] += aPadPos;
272 }
273
274 cornerList.push_back( cornerList[0] );
275 PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILL_T::FILLED_SHAPE : FILL_T::NO_FILL,
277}
278
279
280void PSLIKE_PLOTTER::FlashRegularPolygon( const VECTOR2I& aShapePos, int aRadius, int aCornerCount,
281 const EDA_ANGLE& aOrient, OUTLINE_MODE aTraceMode,
282 void* aData )
283{
284 // Do nothing
285 wxASSERT( 0 );
286}
287
288
289std::string PSLIKE_PLOTTER::encodeStringForPlotter( const wxString& aUnicode )
290{
291 // Write on a std::string a string escaped for postscript/PDF
292 std::string converted;
293
294 converted += '(';
295
296 for( unsigned i = 0; i < aUnicode.Len(); i++ )
297 {
298 // Laziness made me use stdio buffering yet another time...
299 wchar_t ch = aUnicode[i];
300
301 if( ch < 256 )
302 {
303 switch (ch)
304 {
305 // The ~ shouldn't reach the outside
306 case '~':
307 break;
308
309 // These characters must be escaped
310 case '(':
311 case ')':
312 case '\\':
313 converted += '\\';
315
316 default:
317 converted += ch;
318 break;
319 }
320 }
321 }
322
323 converted += ')';
324
325 return converted;
326}
327
328
329int PSLIKE_PLOTTER::returnPostscriptTextWidth( const wxString& aText, int aXSize,
330 bool aItalic, bool aBold )
331{
332 const double *width_table = aBold ? ( aItalic ? hvbo_widths : hvb_widths )
333 : ( aItalic ? hvo_widths : hv_widths );
334 double tally = 0;
335
336 for( unsigned i = 0; i < aText.length(); i++ )
337 {
338 wchar_t AsciiCode = aText[i];
339
340 // Skip the negation marks and untabled points.
341 if( AsciiCode != '~' && AsciiCode < 256 )
342 {
343 tally += width_table[AsciiCode];
344 }
345 }
346
347 // Widths are proportional to height, but height is enlarged by a scaling factor.
348 return KiROUND( aXSize * tally / postscriptTextAscent );
349}
350
351
352void PSLIKE_PLOTTER::postscriptOverlinePositions( const wxString& aText, int aXSize,
353 bool aItalic, bool aBold,
354 std::vector<int> *pos_pairs )
355{
356 /* XXX This function is *too* similar to returnPostscriptTextWidth.
357 Consider merging them... */
358 const double *width_table = aBold ? ( aItalic ? hvbo_widths : hvb_widths )
359 : ( aItalic ? hvo_widths : hv_widths );
360 double tally = 0;
361
362 for( unsigned i = 0; i < aText.length(); i++ )
363 {
364 wchar_t AsciiCode = aText[i];
365
366 // Skip the negation marks and untabled points
367 if( AsciiCode != '~' && AsciiCode < 256 )
368 {
369 tally += width_table[AsciiCode];
370 }
371 else
372 {
373 if( AsciiCode == '~' )
374 pos_pairs->push_back( KiROUND( aXSize * tally / postscriptTextAscent ) );
375 }
376 }
377
378 // Special rule: we have to complete the last bar if the ~ aren't matched
379 if( pos_pairs->size() % 2 == 1 )
380 pos_pairs->push_back( KiROUND( aXSize * tally / postscriptTextAscent ) );
381}
382
383
384void PS_PLOTTER::SetViewport( const VECTOR2I& aOffset, double aIusPerDecimil,
385 double aScale, bool aMirror )
386{
387 wxASSERT( !m_outputFile );
388 m_plotMirror = aMirror;
389 m_plotOffset = aOffset;
390 m_plotScale = aScale;
391 m_IUsPerDecimil = aIusPerDecimil;
392 m_iuPerDeviceUnit = 1.0 / aIusPerDecimil;
393
394 /* Compute the paper size in IUs */
396 m_paperSize.x *= 10.0 * aIusPerDecimil;
397 m_paperSize.y *= 10.0 * aIusPerDecimil;
398}
399
400
402 const wxString& aText,
403 const EDA_ANGLE& aOrient,
404 const VECTOR2I& aSize,
405 bool aMirror,
406 enum GR_TEXT_H_ALIGN_T aH_justify,
407 enum GR_TEXT_V_ALIGN_T aV_justify,
408 int aWidth,
409 bool aItalic,
410 bool aBold,
411 double *wideningFactor,
412 double *ctm_a,
413 double *ctm_b,
414 double *ctm_c,
415 double *ctm_d,
416 double *ctm_e,
417 double *ctm_f,
418 double *heightFactor )
419{
420 // Compute the starting position (compensated for alignment)
421 VECTOR2I start_pos = aPos;
422
423 // This is an approximation of the text bounds (in IUs)
424 int tw = returnPostscriptTextWidth( aText, aSize.x, aItalic, aWidth );
425 int th = aSize.y;
426 int dx, dy;
427
428 switch( aH_justify )
429 {
430 case GR_TEXT_H_ALIGN_CENTER: dx = -tw / 2; break;
431 case GR_TEXT_H_ALIGN_RIGHT: dx = -tw; break;
432 case GR_TEXT_H_ALIGN_LEFT: dx = 0; break;
433 }
434
435 switch( aV_justify )
436 {
437 case GR_TEXT_V_ALIGN_CENTER: dy = th / 2; break;
438 case GR_TEXT_V_ALIGN_TOP: dy = th; break;
439 case GR_TEXT_V_ALIGN_BOTTOM: dy = 0; break;
440 }
441
442 RotatePoint( &dx, &dy, aOrient );
443 RotatePoint( &tw, &th, aOrient );
444 start_pos.x += dx;
445 start_pos.y += dy;
446 VECTOR2D pos_dev = userToDeviceCoordinates( start_pos );
447 VECTOR2D sz_dev = userToDeviceSize( aSize );
448
449 // Now returns the final values... the widening factor
450 *wideningFactor = sz_dev.x / sz_dev.y;
451
452 // Mirrored texts must be plotted as mirrored!
453 if( m_plotMirror )
454 *wideningFactor = -*wideningFactor;
455
456 // The CTM transformation matrix
457 double alpha = m_plotMirror ? aOrient.Invert().AsRadians() : aOrient.AsRadians();
458 double sinalpha = sin( alpha );
459 double cosalpha = cos( alpha );
460
461 *ctm_a = cosalpha;
462 *ctm_b = sinalpha;
463 *ctm_c = -sinalpha;
464 *ctm_d = cosalpha;
465 *ctm_e = pos_dev.x;
466 *ctm_f = pos_dev.y;
467
468 // This is because the letters are less than 1 unit high
469 *heightFactor = sz_dev.y / postscriptTextAscent;
470}
471
472
473void PS_PLOTTER::SetCurrentLineWidth( int aWidth, void* aData )
474{
475 wxASSERT( m_outputFile );
476
477 if( aWidth == DO_NOT_SET_LINE_WIDTH )
478 return;
479 else if( aWidth == USE_DEFAULT_LINE_WIDTH )
481 else if( aWidth == 0 )
482 aWidth = 1;
483
484 wxASSERT_MSG( aWidth > 0, "Plotter called to set negative pen width" );
485
486 if( aWidth != GetCurrentLineWidth() )
487 fprintf( m_outputFile, "%g setlinewidth\n", userToDeviceSize( aWidth ) );
488
489 m_currentPenWidth = aWidth;
490}
491
492
493void PS_PLOTTER::emitSetRGBColor( double r, double g, double b, double a )
494{
495 wxASSERT( m_outputFile );
496
497 // Postscript treats all colors as opaque, so the best we can do with alpha is generate
498 // an appropriate blended color assuming white paper. (It's possible that a halftone would
499 // work better on *some* drivers, but most drivers are known to still treat halftones as
500 // opaque and remove any colors underneath them.)
501 if( a < 1.0 )
502 {
503 r = ( r * a ) + ( 1 - a );
504 g = ( g * a ) + ( 1 - a );
505 b = ( b * a ) + ( 1 - a );
506 }
507
508 // XXX why %.3g ? shouldn't %g suffice? who cares...
509 fprintf( m_outputFile, "%.3g %.3g %.3g setrgbcolor\n", r, g, b );
510}
511
512
513void PS_PLOTTER::SetDash( int aLineWidth, PLOT_DASH_TYPE aLineStyle )
514{
515 switch( aLineStyle )
516 {
517 case PLOT_DASH_TYPE::DASH:
518 fprintf( m_outputFile, "[%d %d] 0 setdash\n",
519 (int) GetDashMarkLenIU( aLineWidth ), (int) GetDashGapLenIU( aLineWidth ) );
520 break;
521
522 case PLOT_DASH_TYPE::DOT:
523 fprintf( m_outputFile, "[%d %d] 0 setdash\n",
524 (int) GetDotMarkLenIU( aLineWidth ), (int) GetDashGapLenIU( aLineWidth ) );
525 break;
526
527 case PLOT_DASH_TYPE::DASHDOT:
528 fprintf( m_outputFile, "[%d %d %d %d] 0 setdash\n",
529 (int) GetDashMarkLenIU( aLineWidth ), (int) GetDashGapLenIU( aLineWidth ),
530 (int) GetDotMarkLenIU( aLineWidth ), (int) GetDashGapLenIU( aLineWidth ) );
531 break;
532
533 case PLOT_DASH_TYPE::DASHDOTDOT:
534 fprintf( m_outputFile, "[%d %d %d %d %d %d] 0 setdash\n",
535 (int) GetDashMarkLenIU( aLineWidth ), (int) GetDashGapLenIU( aLineWidth ),
536 (int) GetDotMarkLenIU( aLineWidth ), (int) GetDashGapLenIU( aLineWidth ),
537 (int) GetDotMarkLenIU( aLineWidth ), (int) GetDashGapLenIU( aLineWidth ) );
538 break;
539
540 default:
541 fputs( "solidline\n", m_outputFile );
542 }
543}
544
545
546void PS_PLOTTER::Rect( const VECTOR2I& p1, const VECTOR2I& p2, FILL_T fill, int width )
547{
548 VECTOR2D p1_dev = userToDeviceCoordinates( p1 );
549 VECTOR2D p2_dev = userToDeviceCoordinates( p2 );
550
551 SetCurrentLineWidth( width );
552 fprintf( m_outputFile, "%g %g %g %g rect%d\n", p1_dev.x, p1_dev.y,
553 p2_dev.x - p1_dev.x, p2_dev.y - p1_dev.y, getFillId( fill ) );
554}
555
556
557void PS_PLOTTER::Circle( const VECTOR2I& pos, int diametre, FILL_T fill, int width )
558{
559 wxASSERT( m_outputFile );
560 VECTOR2D pos_dev = userToDeviceCoordinates( pos );
561 double radius = userToDeviceSize( diametre / 2.0 );
562
563 SetCurrentLineWidth( width );
564 fprintf( m_outputFile, "%g %g %g cir%d\n", pos_dev.x, pos_dev.y, radius, getFillId( fill ) );
565}
566
567
568VECTOR2D mapCoords( const VECTOR2D& aSource )
569{
570 return VECTOR2D( aSource.x, aSource.y );
571}
572
573
574void PS_PLOTTER::Arc( const VECTOR2I& aCenter, const VECTOR2I& aStart, const VECTOR2I& aEnd,
575 FILL_T aFill, int aWidth, int aMaxError )
576{
577 wxASSERT( m_outputFile );
578
579 VECTOR2D center_device = userToDeviceCoordinates( aCenter );
580 VECTOR2D start_device = userToDeviceCoordinates( aStart );
581 VECTOR2D end_device = userToDeviceCoordinates( aEnd );
582 double radius_device = ( start_device - center_device ).EuclideanNorm();
583 EDA_ANGLE startAngle( mapCoords( start_device - center_device ) );
584 EDA_ANGLE endAngle( mapCoords( end_device - center_device ) );
585
586 // userToDeviceCoordinates gets our start/ends out of order
587 std::swap( startAngle, endAngle );
588
589 SetCurrentLineWidth( aWidth );
590
591 fprintf( m_outputFile, "%g %g %g %g %g arc%d\n",
592 center_device.x,
593 center_device.y,
594 radius_device,
595 startAngle.AsDegrees(),
596 endAngle.AsDegrees(),
597 getFillId( aFill ) );
598}
599
600void PS_PLOTTER::PlotPoly( const std::vector<VECTOR2I>& aCornerList, FILL_T aFill, int aWidth,
601 void* aData )
602{
603 if( aCornerList.size() <= 1 )
604 return;
605
606 SetCurrentLineWidth( aWidth );
607
608 VECTOR2D pos = userToDeviceCoordinates( aCornerList[0] );
609 fprintf( m_outputFile, "newpath\n%g %g moveto\n", pos.x, pos.y );
610
611 for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
612 {
613 pos = userToDeviceCoordinates( aCornerList[ii] );
614 fprintf( m_outputFile, "%g %g lineto\n", pos.x, pos.y );
615 }
616
617 // Close/(fill) the path
618 fprintf( m_outputFile, "poly%d\n", getFillId( aFill ) );
619}
620
621
622void PS_PLOTTER::PlotImage( const wxImage& aImage, const VECTOR2I& aPos, double aScaleFactor )
623{
624 VECTOR2I pix_size; // size of the bitmap in pixels
625 pix_size.x = aImage.GetWidth();
626 pix_size.y = aImage.GetHeight();
627 VECTOR2D drawsize( aScaleFactor * pix_size.x,
628 aScaleFactor * pix_size.y ); // requested size of image
629
630 // calculate the bottom left corner position of bitmap
631 VECTOR2I start = aPos;
632 start.x -= drawsize.x / 2; // left
633 start.y += drawsize.y / 2; // bottom (Y axis reversed)
634
635 // calculate the top right corner position of bitmap
636 VECTOR2I end;
637 end.x = start.x + drawsize.x;
638 end.y = start.y - drawsize.y;
639
640 fprintf( m_outputFile, "/origstate save def\n" );
641 fprintf( m_outputFile, "/pix %d string def\n", pix_size.x );
642
643 // Locate lower-left corner of image
644 VECTOR2D start_dev = userToDeviceCoordinates( start );
645 fprintf( m_outputFile, "%g %g translate\n", start_dev.x, start_dev.y );
646
647 // Map image size to device
648 VECTOR2D end_dev = userToDeviceCoordinates( end );
649 fprintf( m_outputFile, "%g %g scale\n",
650 std::abs( end_dev.x - start_dev.x ),
651 std::abs( end_dev.y - start_dev.y ) );
652
653 // Dimensions of source image (in pixels
654 fprintf( m_outputFile, "%d %d 8", pix_size.x, pix_size.y );
655
656 // Map unit square to source
657 fprintf( m_outputFile, " [%d 0 0 %d 0 %d]\n", pix_size.x, -pix_size.y , pix_size.y);
658
659 // include image data in ps file
660 fprintf( m_outputFile, "{currentfile pix readhexstring pop}\n" );
661
662 if( m_colorMode )
663 fputs( "false 3 colorimage\n", m_outputFile );
664 else
665 fputs( "image\n", m_outputFile );
666
667 // Single data source, 3 colors, Output RGB data (hexadecimal)
668 // (or the same downscaled to gray)
669 int jj = 0;
670
671 for( int yy = 0; yy < pix_size.y; yy ++ )
672 {
673 for( int xx = 0; xx < pix_size.x; xx++, jj++ )
674 {
675 if( jj >= 16 )
676 {
677 jj = 0;
678 fprintf( m_outputFile, "\n");
679 }
680
681 int red, green, blue;
682 red = aImage.GetRed( xx, yy) & 0xFF;
683 green = aImage.GetGreen( xx, yy) & 0xFF;
684 blue = aImage.GetBlue( xx, yy) & 0xFF;
685
686 // PS doesn't support alpha, so premultiply against white background
687 if( aImage.HasAlpha() )
688 {
689 unsigned char alpha = aImage.GetAlpha( xx, yy ) & 0xFF;
690
691 if( alpha < 0xFF )
692 {
693 float a = 1.0 - ( (float) alpha / 255.0 );
694 red = ( int )( red + ( a * 0xFF ) ) & 0xFF;
695 green = ( int )( green + ( a * 0xFF ) ) & 0xFF;
696 blue = ( int )( blue + ( a * 0xFF ) ) & 0xFF;
697 }
698 }
699
700 if( aImage.HasMask() )
701 {
702 if( red == aImage.GetMaskRed() && green == aImage.GetMaskGreen()
703 && blue == aImage.GetMaskBlue() )
704 {
705 red = 0xFF;
706 green = 0xFF;
707 blue = 0xFF;
708 }
709 }
710
711 if( m_colorMode )
712 {
713 fprintf( m_outputFile, "%2.2X%2.2X%2.2X", red, green, blue );
714 }
715 else
716 {
717 // Greyscale conversion (CIE 1931)
718 unsigned char grey = KiROUND( red * 0.2126 + green * 0.7152 + blue * 0.0722 );
719
720 fprintf( m_outputFile, "%2.2X", grey );
721 }
722 }
723 }
724
725 fprintf( m_outputFile, "\n");
726 fprintf( m_outputFile, "origstate restore\n" );
727}
728
729
730void PS_PLOTTER::PenTo( const VECTOR2I& pos, char plume )
731{
732 wxASSERT( m_outputFile );
733
734 if( plume == 'Z' )
735 {
736 if( m_penState != 'Z' )
737 {
738 fputs( "stroke\n", m_outputFile );
739 m_penState = 'Z';
740 m_penLastpos.x = -1;
741 m_penLastpos.y = -1;
742 }
743
744 return;
745 }
746
747 if( m_penState == 'Z' )
748 {
749 fputs( "newpath\n", m_outputFile );
750 }
751
752 if( m_penState != plume || pos != m_penLastpos )
753 {
754 VECTOR2D pos_dev = userToDeviceCoordinates( pos );
755 fprintf( m_outputFile, "%g %g %sto\n",
756 pos_dev.x, pos_dev.y,
757 ( plume=='D' ) ? "line" : "move" );
758 }
759
760 m_penState = plume;
761 m_penLastpos = pos;
762}
763
764
765bool PS_PLOTTER::StartPlot( const wxString& aPageNumber )
766{
767 wxASSERT( m_outputFile );
768
769 static const char* PSMacro[] =
770 {
771 "%%BeginProlog\n",
772 "/line { newpath moveto lineto stroke } bind def\n",
773 "/cir0 { newpath 0 360 arc stroke } bind def\n",
774 "/cir1 { newpath 0 360 arc gsave fill grestore stroke } bind def\n",
775 "/cir2 { newpath 0 360 arc gsave fill grestore stroke } bind def\n",
776 "/arc0 { newpath arc stroke } bind def\n",
777 "/arc1 { newpath 4 index 4 index moveto arc closepath gsave fill\n",
778 " grestore stroke } bind def\n",
779 "/arc2 { newpath 4 index 4 index moveto arc closepath gsave fill\n",
780 " grestore stroke } bind def\n",
781 "/poly0 { stroke } bind def\n",
782 "/poly1 { closepath gsave fill grestore stroke } bind def\n",
783 "/poly2 { closepath gsave fill grestore stroke } bind def\n",
784 "/rect0 { rectstroke } bind def\n",
785 "/rect1 { rectfill } bind def\n",
786 "/rect2 { rectfill } bind def\n",
787 "/linemode0 { 0 setlinecap 0 setlinejoin 0 setlinewidth } bind def\n",
788 "/linemode1 { 1 setlinecap 1 setlinejoin } bind def\n",
789 "/dashedline { [200] 100 setdash } bind def\n",
790 "/solidline { [] 0 setdash } bind def\n",
791
792 // This is for 'hidden' text (search anchors for PDF)
793 "/phantomshow { moveto\n",
794 " /KicadFont findfont 0.000001 scalefont setfont\n",
795 " show } bind def\n",
796
797 // This is for regular postscript text
798 "/textshow { gsave\n",
799 " findfont exch scalefont setfont concat 1 scale 0 0 moveto show\n",
800 " } bind def\n",
801
802 // Utility for getting Latin1 encoded fonts
803 "/reencodefont {\n",
804 " findfont dup length dict begin\n",
805 " { 1 index /FID ne\n",
806 " { def }\n",
807 " { pop pop } ifelse\n",
808 " } forall\n",
809 " /Encoding ISOLatin1Encoding def\n",
810 " currentdict\n",
811 " end } bind def\n"
812
813 // Remap AdobeStandard fonts to Latin1
814 "/KicadFont /Helvetica reencodefont definefont pop\n",
815 "/KicadFont-Bold /Helvetica-Bold reencodefont definefont pop\n",
816 "/KicadFont-Oblique /Helvetica-Oblique reencodefont definefont pop\n",
817 "/KicadFont-BoldOblique /Helvetica-BoldOblique reencodefont definefont pop\n",
818 "%%EndProlog\n",
819 nullptr
820 };
821
822 time_t time1970 = time( nullptr );
823
824 fputs( "%!PS-Adobe-3.0\n", m_outputFile ); // Print header
825
826 fprintf( m_outputFile, "%%%%Creator: %s\n", TO_UTF8( m_creator ) );
827
828 /* A "newline" character ("\n") is not included in the following string,
829 because it is provided by the ctime() function. */
830 fprintf( m_outputFile, "%%%%CreationDate: %s", ctime( &time1970 ) );
831 fprintf( m_outputFile, "%%%%Title: %s\n", encodeStringForPlotter( m_title ).c_str() );
832 fprintf( m_outputFile, "%%%%Pages: 1\n" );
833 fprintf( m_outputFile, "%%%%PageOrder: Ascend\n" );
834
835 // Print boundary box in 1/72 pixels per inch, box is in mils
836 const double BIGPTsPERMIL = 0.072;
837
838 /* The coordinates of the lower left corner of the boundary
839 box need to be "rounded down", but the coordinates of its
840 upper right corner need to be "rounded up" instead. */
841 VECTOR2I psPaperSize = m_pageInfo.GetSizeMils();
842
843 if( !m_pageInfo.IsPortrait() )
844 {
845 psPaperSize.x = m_pageInfo.GetHeightMils();
846 psPaperSize.y = m_pageInfo.GetWidthMils();
847 }
848
849 fprintf( m_outputFile, "%%%%BoundingBox: 0 0 %d %d\n",
850 (int) ceil( psPaperSize.x * BIGPTsPERMIL ),
851 (int) ceil( psPaperSize.y * BIGPTsPERMIL ) );
852
853 // Specify the size of the sheet and the name associated with that size.
854 // (If the "User size" option has been selected for the sheet size,
855 // identify the sheet size as "Custom" (rather than as "User"), but
856 // otherwise use the name assigned by KiCad for each sheet size.)
857 //
858 // (The Document Structuring Convention also supports sheet weight,
859 // sheet color, and sheet type properties being specified within a
860 // %%DocumentMedia comment, but they are not being specified here;
861 // a zero and two null strings are subsequently provided instead.)
862 //
863 // (NOTE: m_Size.y is *supposed* to be listed before m_Size.x;
864 // the order in which they are specified is not wrong!)
865 // Also note pageSize is given in mils, not in internal units and must be
866 // converted to internal units.
867
868 if( m_pageInfo.IsCustom() )
869 {
870 fprintf( m_outputFile, "%%%%DocumentMedia: Custom %d %d 0 () ()\n",
871 KiROUND( psPaperSize.x * BIGPTsPERMIL ),
872 KiROUND( psPaperSize.y * BIGPTsPERMIL ) );
873 }
874 else // a standard paper size
875 {
876 fprintf( m_outputFile, "%%%%DocumentMedia: %s %d %d 0 () ()\n",
878 KiROUND( psPaperSize.x * BIGPTsPERMIL ),
879 KiROUND( psPaperSize.y * BIGPTsPERMIL ) );
880 }
881
882 if( m_pageInfo.IsPortrait() )
883 fprintf( m_outputFile, "%%%%Orientation: Portrait\n" );
884 else
885 fprintf( m_outputFile, "%%%%Orientation: Landscape\n" );
886
887 fprintf( m_outputFile, "%%%%EndComments\n" );
888
889 // Now specify various other details.
890
891 for( int ii = 0; PSMacro[ii] != nullptr; ii++ )
892 {
893 fputs( PSMacro[ii], m_outputFile );
894 }
895
896 // The following strings are output here (rather than within PSMacro[])
897 // to highlight that it has been provided to ensure that the contents of
898 // the postscript file comply with the Document Structuring Convention.
899 std::string page_num = encodeStringForPlotter( aPageNumber );
900
901 fprintf( m_outputFile, "%%Page: %s 1\n", page_num.c_str() );
902
903 fputs( "%%BeginPageSetup\n"
904 "gsave\n"
905 "0.0072 0.0072 scale\n" // Configure postscript for decimils coordinates
906 "linemode1\n", m_outputFile );
907
908
909 // Rototranslate the coordinate to achieve the landscape layout
910 if( !m_pageInfo.IsPortrait() )
911 fprintf( m_outputFile, "%d 0 translate 90 rotate\n", 10 * psPaperSize.x );
912
913 // Apply the user fine scale adjustments
914 if( plotScaleAdjX != 1.0 || plotScaleAdjY != 1.0 )
915 fprintf( m_outputFile, "%g %g scale\n", plotScaleAdjX, plotScaleAdjY );
916
917 // Set default line width
918 fprintf( m_outputFile, "%g setlinewidth\n",
920 fputs( "%%EndPageSetup\n", m_outputFile );
921
922 return true;
923}
924
925
927{
928 wxASSERT( m_outputFile );
929 fputs( "showpage\n"
930 "grestore\n"
931 "%%EOF\n", m_outputFile );
932 fclose( m_outputFile );
933 m_outputFile = nullptr;
934
935 return true;
936}
937
938
939
940void PS_PLOTTER::Text( const VECTOR2I& aPos,
941 const COLOR4D& aColor,
942 const wxString& aText,
943 const EDA_ANGLE& aOrient,
944 const VECTOR2I& aSize,
945 enum GR_TEXT_H_ALIGN_T aH_justify,
946 enum GR_TEXT_V_ALIGN_T aV_justify,
947 int aWidth,
948 bool aItalic,
949 bool aBold,
950 bool aMultilineAllowed,
951 KIFONT::FONT* aFont,
952 void* aData )
953{
954 SetCurrentLineWidth( aWidth );
955 SetColor( aColor );
956
957 // Draw the hidden postscript text (if requested)
958 if( m_textMode == PLOT_TEXT_MODE::PHANTOM )
959 {
960 std::string ps_test = encodeStringForPlotter( aText );
961 VECTOR2D pos_dev = userToDeviceCoordinates( aPos );
962 fprintf( m_outputFile, "%s %g %g phantomshow\n", ps_test.c_str(), pos_dev.x, pos_dev.y );
963 }
964
965 PLOTTER::Text( aPos, aColor, aText, aOrient, aSize, aH_justify, aV_justify, aWidth, aItalic,
966 aBold, aMultilineAllowed, aFont, aData );
967}
968
969
971 const COLOR4D& aColor,
972 const wxString& aText,
973 const TEXT_ATTRIBUTES& aAttributes,
974 KIFONT::FONT* aFont,
975 void* aData )
976{
977 SetCurrentLineWidth( aAttributes.m_StrokeWidth );
978 SetColor( aColor );
979
980 // Draw the hidden postscript text (if requested)
981 if( m_textMode == PLOT_TEXT_MODE::PHANTOM )
982 {
983 std::string ps_test = encodeStringForPlotter( aText );
984 VECTOR2D pos_dev = userToDeviceCoordinates( aPos );
985 fprintf( m_outputFile, "%s %g %g phantomshow\n", ps_test.c_str(), pos_dev.x, pos_dev.y );
986 }
987
988 PLOTTER::PlotText( aPos, aColor, aText, aAttributes, aFont, aData );
989}
990
991
995const double hv_widths[256] = {
996 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
997 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
998 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
999 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1000 0.278, 0.278, 0.355, 0.556, 0.556, 0.889, 0.667, 0.191,
1001 0.333, 0.333, 0.389, 0.584, 0.278, 0.333, 0.278, 0.278,
1002 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556,
1003 0.556, 0.556, 0.278, 0.278, 0.584, 0.584, 0.584, 0.556,
1004 1.015, 0.667, 0.667, 0.722, 0.722, 0.667, 0.611, 0.778,
1005 0.722, 0.278, 0.500, 0.667, 0.556, 0.833, 0.722, 0.778,
1006 0.667, 0.778, 0.722, 0.667, 0.611, 0.722, 0.667, 0.944,
1007 0.667, 0.667, 0.611, 0.278, 0.278, 0.278, 0.469, 0.556,
1008 0.333, 0.556, 0.556, 0.500, 0.556, 0.556, 0.278, 0.556,
1009 0.556, 0.222, 0.222, 0.500, 0.222, 0.833, 0.556, 0.556,
1010 0.556, 0.556, 0.333, 0.500, 0.278, 0.556, 0.500, 0.722,
1011 0.500, 0.500, 0.500, 0.334, 0.260, 0.334, 0.584, 0.278,
1012 0.278, 0.278, 0.222, 0.556, 0.333, 1.000, 0.556, 0.556,
1013 0.333, 1.000, 0.667, 0.333, 1.000, 0.278, 0.278, 0.278,
1014 0.278, 0.222, 0.222, 0.333, 0.333, 0.350, 0.556, 1.000,
1015 0.333, 1.000, 0.500, 0.333, 0.944, 0.278, 0.278, 0.667,
1016 0.278, 0.333, 0.556, 0.556, 0.556, 0.556, 0.260, 0.556,
1017 0.333, 0.737, 0.370, 0.556, 0.584, 0.333, 0.737, 0.333,
1018 0.400, 0.584, 0.333, 0.333, 0.333, 0.556, 0.537, 0.278,
1019 0.333, 0.333, 0.365, 0.556, 0.834, 0.834, 0.834, 0.611,
1020 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 1.000, 0.722,
1021 0.667, 0.667, 0.667, 0.667, 0.278, 0.278, 0.278, 0.278,
1022 0.722, 0.722, 0.778, 0.778, 0.778, 0.778, 0.778, 0.584,
1023 0.778, 0.722, 0.722, 0.722, 0.722, 0.667, 0.667, 0.611,
1024 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.889, 0.500,
1025 0.556, 0.556, 0.556, 0.556, 0.278, 0.278, 0.278, 0.278,
1026 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.584,
1027 0.611, 0.556, 0.556, 0.556, 0.556, 0.500, 0.556, 0.500
1028};
1029
1030
1034const double hvb_widths[256] = {
1035 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1036 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1037 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1038 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1039 0.278, 0.333, 0.474, 0.556, 0.556, 0.889, 0.722, 0.238,
1040 0.333, 0.333, 0.389, 0.584, 0.278, 0.333, 0.278, 0.278,
1041 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556,
1042 0.556, 0.556, 0.333, 0.333, 0.584, 0.584, 0.584, 0.611,
1043 0.975, 0.722, 0.722, 0.722, 0.722, 0.667, 0.611, 0.778,
1044 0.722, 0.278, 0.556, 0.722, 0.611, 0.833, 0.722, 0.778,
1045 0.667, 0.778, 0.722, 0.667, 0.611, 0.722, 0.667, 0.944,
1046 0.667, 0.667, 0.611, 0.333, 0.278, 0.333, 0.584, 0.556,
1047 0.333, 0.556, 0.611, 0.556, 0.611, 0.556, 0.333, 0.611,
1048 0.611, 0.278, 0.278, 0.556, 0.278, 0.889, 0.611, 0.611,
1049 0.611, 0.611, 0.389, 0.556, 0.333, 0.611, 0.556, 0.778,
1050 0.556, 0.556, 0.500, 0.389, 0.280, 0.389, 0.584, 0.278,
1051 0.278, 0.278, 0.278, 0.556, 0.500, 1.000, 0.556, 0.556,
1052 0.333, 1.000, 0.667, 0.333, 1.000, 0.278, 0.278, 0.278,
1053 0.278, 0.278, 0.278, 0.500, 0.500, 0.350, 0.556, 1.000,
1054 0.333, 1.000, 0.556, 0.333, 0.944, 0.278, 0.278, 0.667,
1055 0.278, 0.333, 0.556, 0.556, 0.556, 0.556, 0.280, 0.556,
1056 0.333, 0.737, 0.370, 0.556, 0.584, 0.333, 0.737, 0.333,
1057 0.400, 0.584, 0.333, 0.333, 0.333, 0.611, 0.556, 0.278,
1058 0.333, 0.333, 0.365, 0.556, 0.834, 0.834, 0.834, 0.611,
1059 0.722, 0.722, 0.722, 0.722, 0.722, 0.722, 1.000, 0.722,
1060 0.667, 0.667, 0.667, 0.667, 0.278, 0.278, 0.278, 0.278,
1061 0.722, 0.722, 0.778, 0.778, 0.778, 0.778, 0.778, 0.584,
1062 0.778, 0.722, 0.722, 0.722, 0.722, 0.667, 0.667, 0.611,
1063 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.889, 0.556,
1064 0.556, 0.556, 0.556, 0.556, 0.278, 0.278, 0.278, 0.278,
1065 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.584,
1066 0.611, 0.611, 0.611, 0.611, 0.611, 0.556, 0.611, 0.556
1067};
1068
1069
1073const double hvo_widths[256] = {
1074 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1075 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1076 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1077 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1078 0.278, 0.278, 0.355, 0.556, 0.556, 0.889, 0.667, 0.191,
1079 0.333, 0.333, 0.389, 0.584, 0.278, 0.333, 0.278, 0.278,
1080 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556,
1081 0.556, 0.556, 0.278, 0.278, 0.584, 0.584, 0.584, 0.556,
1082 1.015, 0.667, 0.667, 0.722, 0.722, 0.667, 0.611, 0.778,
1083 0.722, 0.278, 0.500, 0.667, 0.556, 0.833, 0.722, 0.778,
1084 0.667, 0.778, 0.722, 0.667, 0.611, 0.722, 0.667, 0.944,
1085 0.667, 0.667, 0.611, 0.278, 0.278, 0.278, 0.469, 0.556,
1086 0.333, 0.556, 0.556, 0.500, 0.556, 0.556, 0.278, 0.556,
1087 0.556, 0.222, 0.222, 0.500, 0.222, 0.833, 0.556, 0.556,
1088 0.556, 0.556, 0.333, 0.500, 0.278, 0.556, 0.500, 0.722,
1089 0.500, 0.500, 0.500, 0.334, 0.260, 0.334, 0.584, 0.278,
1090 0.278, 0.278, 0.222, 0.556, 0.333, 1.000, 0.556, 0.556,
1091 0.333, 1.000, 0.667, 0.333, 1.000, 0.278, 0.278, 0.278,
1092 0.278, 0.222, 0.222, 0.333, 0.333, 0.350, 0.556, 1.000,
1093 0.333, 1.000, 0.500, 0.333, 0.944, 0.278, 0.278, 0.667,
1094 0.278, 0.333, 0.556, 0.556, 0.556, 0.556, 0.260, 0.556,
1095 0.333, 0.737, 0.370, 0.556, 0.584, 0.333, 0.737, 0.333,
1096 0.400, 0.584, 0.333, 0.333, 0.333, 0.556, 0.537, 0.278,
1097 0.333, 0.333, 0.365, 0.556, 0.834, 0.834, 0.834, 0.611,
1098 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 1.000, 0.722,
1099 0.667, 0.667, 0.667, 0.667, 0.278, 0.278, 0.278, 0.278,
1100 0.722, 0.722, 0.778, 0.778, 0.778, 0.778, 0.778, 0.584,
1101 0.778, 0.722, 0.722, 0.722, 0.722, 0.667, 0.667, 0.611,
1102 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.889, 0.500,
1103 0.556, 0.556, 0.556, 0.556, 0.278, 0.278, 0.278, 0.278,
1104 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.584,
1105 0.611, 0.556, 0.556, 0.556, 0.556, 0.500, 0.556, 0.500
1106};
1107
1108
1112const double hvbo_widths[256] = {
1113 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1114 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1115 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1116 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1117 0.278, 0.333, 0.474, 0.556, 0.556, 0.889, 0.722, 0.238,
1118 0.333, 0.333, 0.389, 0.584, 0.278, 0.333, 0.278, 0.278,
1119 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556,
1120 0.556, 0.556, 0.333, 0.333, 0.584, 0.584, 0.584, 0.611,
1121 0.975, 0.722, 0.722, 0.722, 0.722, 0.667, 0.611, 0.778,
1122 0.722, 0.278, 0.556, 0.722, 0.611, 0.833, 0.722, 0.778,
1123 0.667, 0.778, 0.722, 0.667, 0.611, 0.722, 0.667, 0.944,
1124 0.667, 0.667, 0.611, 0.333, 0.278, 0.333, 0.584, 0.556,
1125 0.333, 0.556, 0.611, 0.556, 0.611, 0.556, 0.333, 0.611,
1126 0.611, 0.278, 0.278, 0.556, 0.278, 0.889, 0.611, 0.611,
1127 0.611, 0.611, 0.389, 0.556, 0.333, 0.611, 0.556, 0.778,
1128 0.556, 0.556, 0.500, 0.389, 0.280, 0.389, 0.584, 0.278,
1129 0.278, 0.278, 0.278, 0.556, 0.500, 1.000, 0.556, 0.556,
1130 0.333, 1.000, 0.667, 0.333, 1.000, 0.278, 0.278, 0.278,
1131 0.278, 0.278, 0.278, 0.500, 0.500, 0.350, 0.556, 1.000,
1132 0.333, 1.000, 0.556, 0.333, 0.944, 0.278, 0.278, 0.667,
1133 0.278, 0.333, 0.556, 0.556, 0.556, 0.556, 0.280, 0.556,
1134 0.333, 0.737, 0.370, 0.556, 0.584, 0.333, 0.737, 0.333,
1135 0.400, 0.584, 0.333, 0.333, 0.333, 0.611, 0.556, 0.278,
1136 0.333, 0.333, 0.365, 0.556, 0.834, 0.834, 0.834, 0.611,
1137 0.722, 0.722, 0.722, 0.722, 0.722, 0.722, 1.000, 0.722,
1138 0.667, 0.667, 0.667, 0.667, 0.278, 0.278, 0.278, 0.278,
1139 0.722, 0.722, 0.778, 0.778, 0.778, 0.778, 0.778, 0.584,
1140 0.778, 0.722, 0.722, 0.722, 0.722, 0.667, 0.667, 0.611,
1141 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.889, 0.556,
1142 0.556, 0.556, 0.556, 0.556, 0.278, 0.278, 0.278, 0.278,
1143 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.584,
1144 0.611, 0.611, 0.611, 0.611, 0.611, 0.556, 0.611, 0.556
1145};
int color
Definition: DXF_plotter.cpp:57
VECTOR2D mapCoords(const VECTOR2D &aSource)
Definition: PS_plotter.cpp:568
const double hvbo_widths[256]
Character widths for Helvetica-BoldOblique.
static int getFillId(FILL_T aFill)
Definition: PS_plotter.cpp:50
const double hvb_widths[256]
Character widths for Helvetica-Bold.
const double hv_widths[256]
Character widths for Helvetica.
Definition: PS_plotter.cpp:995
const double hvo_widths[256]
Character widths for Helvetica-Oblique.
double AsDegrees() const
Definition: eda_angle.h:149
EDA_ANGLE Invert() const
Definition: eda_angle.h:201
double AsRadians() const
Definition: eda_angle.h:153
FONT is an abstract base class for both outline and stroke fonts.
Definition: font.h:105
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:103
int GetDefaultPenWidth() const
const VECTOR2I & GetSizeMils() const
Definition: page_info.h:135
int GetHeightMils() const
Definition: page_info.h:133
int GetWidthMils() const
Definition: page_info.h:130
const wxString & GetType() const
Definition: page_info.h:94
bool IsCustom() const
Definition: page_info.cpp:182
bool IsPortrait() const
Definition: page_info.h:117
double GetDotMarkLenIU(int aLineWidth) const
Definition: plotter.cpp:131
virtual void ThickSegment(const VECTOR2I &start, const VECTOR2I &end, int width, OUTLINE_MODE tracemode, void *aData)
Definition: plotter.cpp:549
double GetDashGapLenIU(int aLineWidth) const
Definition: plotter.cpp:143
virtual void Circle(const VECTOR2I &pos, int diametre, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH)=0
PAGE_INFO m_pageInfo
Definition: plotter.h:665
bool m_plotMirror
Definition: plotter.h:647
static const int USE_DEFAULT_LINE_WIDTH
Definition: plotter.h:114
double m_iuPerDeviceUnit
Definition: plotter.h:644
VECTOR2I m_plotOffset
Definition: plotter.h:646
VECTOR2I m_penLastpos
Definition: plotter.h:660
virtual VECTOR2D userToDeviceCoordinates(const VECTOR2I &aCoordinate)
Modify coordinates according to the orientation, scale factor, and offsets trace.
Definition: plotter.cpp:90
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, void *aData=nullptr)
Draw text with the plotter.
Definition: plotter.cpp:697
VECTOR2I m_paperSize
Definition: plotter.h:666
virtual VECTOR2D userToDeviceSize(const VECTOR2I &size)
Modify size according to the plotter scale factors (VECTOR2I version, returns a VECTOR2D).
Definition: plotter.cpp:115
void sketchOval(const VECTOR2I &aPos, const VECTOR2I &aSize, const EDA_ANGLE &aOrient, int aWidth)
Definition: plotter.cpp:496
int GetPlotterArcHighDef() const
Definition: plotter.h:213
char m_penState
Definition: plotter.h:659
wxString m_creator
Definition: plotter.h:662
int m_currentPenWidth
Definition: plotter.h:658
double m_plotScale
Plot scale - chosen by the user (even implicitly with 'fit in a4')
Definition: plotter.h:636
virtual void PlotText(const VECTOR2I &aPos, const COLOR4D &aColor, const wxString &aText, const TEXT_ATTRIBUTES &aAttributes, KIFONT::FONT *aFont, void *aData=nullptr)
Definition: plotter.cpp:758
FILE * m_outputFile
Output file.
Definition: plotter.h:653
virtual void SetCurrentLineWidth(int width, void *aData=nullptr)=0
Set the line width for the next drawing.
virtual void PlotPoly(const std::vector< VECTOR2I > &aCornerList, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH, void *aData=nullptr)=0
Draw a polygon ( filled or not ).
static const int DO_NOT_SET_LINE_WIDTH
Definition: plotter.h:113
RENDER_SETTINGS * m_renderSettings
Definition: plotter.h:670
bool m_negativeMode
Definition: plotter.h:657
double m_IUsPerDecimil
Definition: plotter.h:642
wxString m_title
Definition: plotter.h:664
virtual int GetCurrentLineWidth() const
Definition: plotter.h:153
bool m_colorMode
Definition: plotter.h:656
double GetDashMarkLenIU(int aLineWidth) const
Definition: plotter.cpp:137
static const double postscriptTextAscent
Height of the postscript font (from the AFM)
virtual void FlashRegularPolygon(const VECTOR2I &aShapePos, int aDiameter, int aCornerCount, const EDA_ANGLE &aOrient, OUTLINE_MODE aTraceMode, void *aData) override
Flash a regular polygon.
Definition: PS_plotter.cpp:280
virtual void SetColor(const COLOR4D &color) override
The SetColor implementation is split with the subclasses: The PSLIKE computes the rgb values,...
Definition: PS_plotter.cpp:62
virtual void FlashPadRoundRect(const VECTOR2I &aPadPos, const VECTOR2I &aSize, int aCornerRadius, const EDA_ANGLE &aOrient, OUTLINE_MODE aTraceMode, void *aData) override
Definition: PS_plotter.cpp:177
virtual void FlashPadCustom(const VECTOR2I &aPadPos, const VECTOR2I &aSize, const EDA_ANGLE &aOrient, SHAPE_POLY_SET *aPolygons, OUTLINE_MODE aTraceMode, void *aData) override
Definition: PS_plotter.cpp:214
virtual void FlashPadCircle(const VECTOR2I &aPadPos, int aDiameter, OUTLINE_MODE aTraceMode, void *aData) override
Definition: PS_plotter.cpp:120
virtual void emitSetRGBColor(double r, double g, double b, double a)=0
Virtual primitive for emitting the setrgbcolor operator.
PLOT_TEXT_MODE m_textMode
How to draw text.
virtual void FlashPadTrapez(const VECTOR2I &aPadPos, const VECTOR2I *aCorners, const EDA_ANGLE &aPadOrient, OUTLINE_MODE aTraceMode, void *aData) override
Flash a trapezoidal pad.
Definition: PS_plotter.cpp:249
virtual void FlashPadRect(const VECTOR2I &aPadPos, const VECTOR2I &aSize, const EDA_ANGLE &aPadOrient, OUTLINE_MODE aTraceMode, void *aData) override
Definition: PS_plotter.cpp:137
int returnPostscriptTextWidth(const wxString &aText, int aXSize, bool aItalic, bool aBold)
Sister function for the GraphicTextWidth in drawtxt.cpp Does the same processing (i....
Definition: PS_plotter.cpp:329
double plotScaleAdjX
Fine user scale adjust ( = 1.0 if no correction)
void computeTextParameters(const VECTOR2I &aPos, const wxString &aText, const EDA_ANGLE &aOrient, const VECTOR2I &aSize, bool aMirror, enum GR_TEXT_H_ALIGN_T aH_justify, enum GR_TEXT_V_ALIGN_T aV_justify, int aWidth, bool aItalic, bool aBold, double *wideningFactor, double *ctm_a, double *ctm_b, double *ctm_c, double *ctm_d, double *ctm_e, double *ctm_f, double *heightFactor)
This is the core for postscript/PDF text alignment.
Definition: PS_plotter.cpp:401
virtual std::string encodeStringForPlotter(const wxString &aUnicode)
convert a wxString unicode string to a char string compatible with the accepted string plotter format...
Definition: PS_plotter.cpp:289
virtual void FlashPadOval(const VECTOR2I &aPadPos, const VECTOR2I &aSize, const EDA_ANGLE &aPadOrient, OUTLINE_MODE aTraceMode, void *aData) override
Definition: PS_plotter.cpp:90
void postscriptOverlinePositions(const wxString &aText, int aXSize, bool aItalic, bool aBold, std::vector< int > *pos_pairs)
Computes the x coordinates for the overlining in a string of text.
Definition: PS_plotter.cpp:352
virtual void Arc(const VECTOR2I &aCenter, const VECTOR2I &aStart, const VECTOR2I &aEnd, FILL_T aFill, int aWidth, int aMaxError) override
Generic fallback: arc rendered as a polyline.
Definition: PS_plotter.cpp:574
virtual void PlotText(const VECTOR2I &aPos, const COLOR4D &aColor, const wxString &aText, const TEXT_ATTRIBUTES &aAttributes, KIFONT::FONT *aFont, void *aData=nullptr) override
Definition: PS_plotter.cpp:970
virtual bool EndPlot() override
Definition: PS_plotter.cpp:926
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 aWidth, bool aItalic, bool aBold, bool aMultilineAllowed=false, KIFONT::FONT *aFont=nullptr, void *aData=nullptr) override
Draw text with the plotter.
Definition: PS_plotter.cpp:940
virtual void PlotPoly(const std::vector< VECTOR2I > &aCornerList, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH, void *aData=nullptr) override
Draw a polygon ( filled or not ).
Definition: PS_plotter.cpp:600
virtual void PlotImage(const wxImage &aImage, const VECTOR2I &aPos, double aScaleFactor) override
PostScript-likes at the moment are the only plot engines supporting bitmaps.
Definition: PS_plotter.cpp:622
virtual void SetViewport(const VECTOR2I &aOffset, double aIusPerDecimil, double aScale, bool aMirror) override
Set the plot offset and scaling for the current plot.
Definition: PS_plotter.cpp:384
virtual void Rect(const VECTOR2I &p1, const VECTOR2I &p2, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH) override
Definition: PS_plotter.cpp:546
virtual void SetDash(int aLineWidth, PLOT_DASH_TYPE aLineStyle) override
PostScript supports dashed lines.
Definition: PS_plotter.cpp:513
virtual void Circle(const VECTOR2I &pos, int diametre, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH) override
Definition: PS_plotter.cpp:557
virtual bool StartPlot(const wxString &aPageNumber) override
The code within this function (and the CloseFilePS function) creates postscript files whose contents ...
Definition: PS_plotter.cpp:765
virtual void emitSetRGBColor(double r, double g, double b, double a) override
Virtual primitive for emitting the setrgbcolor operator.
Definition: PS_plotter.cpp:493
virtual void SetCurrentLineWidth(int width, void *aData=nullptr) override
Set the current line width (in IUs) for the next plot.
Definition: PS_plotter.cpp:473
virtual void PenTo(const VECTOR2I &pos, char plume) override
Moveto/lineto primitive, moves the 'pen' to the specified direction.
Definition: PS_plotter.cpp:730
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
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.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int OutlineCount() const
Return the number of outlines in the set.
void TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aPosition, const VECTOR2I &aSize, const EDA_ANGLE &aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aInflate, int aError, ERROR_LOC aErrorLoc)
Convert a rectangle with rounded corners and/or chamfered corners to a polygon.
static constexpr EDA_ANGLE & ANGLE_90
Definition: eda_angle.h:431
FILL_T
Definition: eda_shape.h:54
@ FILLED_SHAPE
@ ERROR_INSIDE
static const bool FILLED
Definition: gr_basic.cpp:30
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:418
OUTLINE_MODE
Definition: outline_mode.h:25
Plotting engines similar to ps (PostScript, Gerber, svg)
PLOT_DASH_TYPE
Dashed line types.
Definition: stroke_params.h:48
constexpr int delta
GR_TEXT_H_ALIGN_T
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
GR_TEXT_V_ALIGN_T
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Definition: trigo.cpp:183
double EuclideanNorm(const VECTOR2I &vector)
Definition: trigo.h:129
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:85
VECTOR2< double > VECTOR2D
Definition: vector2d.h:587