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