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;
384 }
385
386 switch( aV_justify )
387 {
388 case GR_TEXT_V_ALIGN_CENTER: dy = th / 2; break;
389 case GR_TEXT_V_ALIGN_TOP: dy = th; break;
390 case GR_TEXT_V_ALIGN_BOTTOM: dy = 0; break;
391 }
392
393 RotatePoint( &dx, &dy, aOrient );
394 RotatePoint( &tw, &th, aOrient );
395 start_pos.x += dx;
396 start_pos.y += dy;
397 VECTOR2D pos_dev = userToDeviceCoordinates( start_pos );
398 VECTOR2D sz_dev = userToDeviceSize( aSize );
399
400 // Now returns the final values... the widening factor
401 *wideningFactor = sz_dev.x / sz_dev.y;
402
403 // Mirrored texts must be plotted as mirrored!
404 if( m_plotMirror ^ aMirror )
405 *wideningFactor = -*wideningFactor;
406
407 // The CTM transformation matrix
408 double alpha = m_plotMirror ? aOrient.Invert().AsRadians() : aOrient.AsRadians();
409 double sinalpha = sin( alpha );
410 double cosalpha = cos( alpha );
411
412 *ctm_a = cosalpha;
413 *ctm_b = sinalpha;
414 *ctm_c = -sinalpha;
415 *ctm_d = cosalpha;
416 *ctm_e = pos_dev.x;
417 *ctm_f = pos_dev.y;
418
419 // This is because the letters are less than 1 unit high
420 *heightFactor = sz_dev.y / postscriptTextAscent;
421}
422
423
424void PS_PLOTTER::SetCurrentLineWidth( int aWidth, void* aData )
425{
426 wxASSERT( m_outputFile );
427
428 if( aWidth == DO_NOT_SET_LINE_WIDTH )
429 return;
430 else if( aWidth == USE_DEFAULT_LINE_WIDTH )
432 else if( aWidth == 0 )
433 aWidth = 1;
434
435 wxASSERT_MSG( aWidth > 0, "Plotter called to set negative pen width" );
436
437 if( aWidth != GetCurrentLineWidth() )
438 fprintf( m_outputFile, "%g setlinewidth\n", userToDeviceSize( aWidth ) );
439
440 m_currentPenWidth = aWidth;
441}
442
443
444void PS_PLOTTER::emitSetRGBColor( double r, double g, double b, double a )
445{
446 wxASSERT( m_outputFile );
447
448 // Postscript treats all colors as opaque, so the best we can do with alpha is generate
449 // an appropriate blended color assuming white paper. (It's possible that a halftone would
450 // work better on *some* drivers, but most drivers are known to still treat halftones as
451 // opaque and remove any colors underneath them.)
452 if( a < 1.0 )
453 {
454 r = ( r * a ) + ( 1 - a );
455 g = ( g * a ) + ( 1 - a );
456 b = ( b * a ) + ( 1 - a );
457 }
458
459 // XXX why %.3g ? shouldn't %g suffice? who cares...
460 fprintf( m_outputFile, "%.3g %.3g %.3g setrgbcolor\n", r, g, b );
461}
462
463
464void PS_PLOTTER::SetDash( int aLineWidth, LINE_STYLE aLineStyle )
465{
466 switch( aLineStyle )
467 {
468 case LINE_STYLE::DASH:
469 fprintf( m_outputFile, "[%d %d] 0 setdash\n",
470 (int) GetDashMarkLenIU( aLineWidth ), (int) GetDashGapLenIU( aLineWidth ) );
471 break;
472
473 case LINE_STYLE::DOT:
474 fprintf( m_outputFile, "[%d %d] 0 setdash\n",
475 (int) GetDotMarkLenIU( aLineWidth ), (int) GetDashGapLenIU( aLineWidth ) );
476 break;
477
478 case LINE_STYLE::DASHDOT:
479 fprintf( m_outputFile, "[%d %d %d %d] 0 setdash\n",
480 (int) GetDashMarkLenIU( aLineWidth ), (int) GetDashGapLenIU( aLineWidth ),
481 (int) GetDotMarkLenIU( aLineWidth ), (int) GetDashGapLenIU( aLineWidth ) );
482 break;
483
484 case LINE_STYLE::DASHDOTDOT:
485 fprintf( m_outputFile, "[%d %d %d %d %d %d] 0 setdash\n",
486 (int) GetDashMarkLenIU( aLineWidth ), (int) GetDashGapLenIU( aLineWidth ),
487 (int) GetDotMarkLenIU( aLineWidth ), (int) GetDashGapLenIU( aLineWidth ),
488 (int) GetDotMarkLenIU( aLineWidth ), (int) GetDashGapLenIU( aLineWidth ) );
489 break;
490
491 default:
492 fputs( "solidline\n", m_outputFile );
493 }
494}
495
496
497void PS_PLOTTER::Rect( const VECTOR2I& p1, const VECTOR2I& p2, FILL_T fill, int width )
498{
499 if( fill == FILL_T::NO_FILL && width <= 0 )
500 return;
501
502 VECTOR2D p1_dev = userToDeviceCoordinates( p1 );
503 VECTOR2D p2_dev = userToDeviceCoordinates( p2 );
504
505 SetCurrentLineWidth( width );
506 fprintf( m_outputFile, "%g %g %g %g rect%d\n", p1_dev.x, p1_dev.y,
507 p2_dev.x - p1_dev.x, p2_dev.y - p1_dev.y, getFillId( fill ) );
508}
509
510
511void PS_PLOTTER::Circle( const VECTOR2I& pos, int diametre, FILL_T fill, int width )
512{
513 if( fill == FILL_T::NO_FILL && width <= 0 )
514 return;
515
516 wxASSERT( m_outputFile );
517 VECTOR2D pos_dev = userToDeviceCoordinates( pos );
518 double radius = userToDeviceSize( diametre / 2.0 );
519
520 SetCurrentLineWidth( width );
521 fprintf( m_outputFile, "%g %g %g cir%d\n", pos_dev.x, pos_dev.y, radius, getFillId( fill ) );
522}
523
524
525VECTOR2D mapCoords( const VECTOR2D& aSource )
526{
527 return VECTOR2D( aSource.x, aSource.y );
528}
529
530
531void PS_PLOTTER::Arc( const VECTOR2D& aCenter, const EDA_ANGLE& aStartAngle,
532 const EDA_ANGLE& aAngle, double aRadius, FILL_T aFill, int aWidth )
533{
534 wxASSERT( m_outputFile );
535
536 VECTOR2D center_device = userToDeviceCoordinates( aCenter );
537 double radius_device = userToDeviceSize( aRadius );
538
539 EDA_ANGLE endA = aStartAngle + aAngle;
540 VECTOR2D start( aRadius * aStartAngle.Cos(), aRadius * aStartAngle.Sin() );
541 VECTOR2D end( aRadius * endA.Cos(), aRadius * endA.Sin() );
542
543 start += aCenter;
544 end += aCenter;
545
546 VECTOR2D start_device = userToDeviceCoordinates( start );
547 VECTOR2D end_device = userToDeviceCoordinates( end );
548 EDA_ANGLE startAngle( mapCoords( start_device - center_device ) );
549 EDA_ANGLE endAngle( mapCoords( end_device - center_device ) );
550
551 // userToDeviceCoordinates gets our start/ends out of order
552 if( !m_plotMirror ^ ( aAngle < ANGLE_0 ) )
553 std::swap( startAngle, endAngle );
554
555 SetCurrentLineWidth( aWidth );
556
557 fprintf( m_outputFile, "%g %g %g %g %g arc%d\n", center_device.x, center_device.y,
558 radius_device, startAngle.AsDegrees(), endAngle.AsDegrees(), getFillId( aFill ) );
559}
560
561void PS_PLOTTER::PlotPoly( const std::vector<VECTOR2I>& aCornerList, FILL_T aFill, int aWidth,
562 void* aData )
563{
564 if( aCornerList.size() <= 1 )
565 return;
566
567 SetCurrentLineWidth( aWidth );
568
569 VECTOR2D pos = userToDeviceCoordinates( aCornerList[0] );
570 fprintf( m_outputFile, "newpath\n%g %g moveto\n", pos.x, pos.y );
571
572 for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
573 {
574 pos = userToDeviceCoordinates( aCornerList[ii] );
575 fprintf( m_outputFile, "%g %g lineto\n", pos.x, pos.y );
576 }
577
578 // Close/(fill) the path
579 fprintf( m_outputFile, "poly%d\n", getFillId( aFill ) );
580}
581
582
583void PS_PLOTTER::PlotImage( const wxImage& aImage, const VECTOR2I& aPos, double aScaleFactor )
584{
585 VECTOR2I pix_size; // size of the bitmap in pixels
586 pix_size.x = aImage.GetWidth();
587 pix_size.y = aImage.GetHeight();
588 VECTOR2D drawsize( aScaleFactor * pix_size.x,
589 aScaleFactor * pix_size.y ); // requested size of image
590
591 // calculate the bottom left corner position of bitmap
592 VECTOR2I start = aPos;
593 start.x -= drawsize.x / 2; // left
594 start.y += drawsize.y / 2; // bottom (Y axis reversed)
595
596 // calculate the top right corner position of bitmap
597 VECTOR2I end;
598 end.x = start.x + drawsize.x;
599 end.y = start.y - drawsize.y;
600
601 fprintf( m_outputFile, "/origstate save def\n" );
602 fprintf( m_outputFile, "/pix %d string def\n", pix_size.x );
603
604 // Locate lower-left corner of image
605 VECTOR2D start_dev = userToDeviceCoordinates( start );
606 fprintf( m_outputFile, "%g %g translate\n", start_dev.x, start_dev.y );
607
608 // Map image size to device
609 VECTOR2D end_dev = userToDeviceCoordinates( end );
610 fprintf( m_outputFile, "%g %g scale\n",
611 std::abs( end_dev.x - start_dev.x ),
612 std::abs( end_dev.y - start_dev.y ) );
613
614 // Dimensions of source image (in pixels
615 fprintf( m_outputFile, "%d %d 8", pix_size.x, pix_size.y );
616
617 // Map unit square to source
618 fprintf( m_outputFile, " [%d 0 0 %d 0 %d]\n", pix_size.x, -pix_size.y , pix_size.y);
619
620 // include image data in ps file
621 fprintf( m_outputFile, "{currentfile pix readhexstring pop}\n" );
622
623 if( m_colorMode )
624 fputs( "false 3 colorimage\n", m_outputFile );
625 else
626 fputs( "image\n", m_outputFile );
627
628 // Single data source, 3 colors, Output RGB data (hexadecimal)
629 // (or the same downscaled to gray)
630 int jj = 0;
631
632 for( int yy = 0; yy < pix_size.y; yy ++ )
633 {
634 for( int xx = 0; xx < pix_size.x; xx++, jj++ )
635 {
636 if( jj >= 16 )
637 {
638 jj = 0;
639 fprintf( m_outputFile, "\n");
640 }
641
642 int red, green, blue;
643 red = aImage.GetRed( xx, yy) & 0xFF;
644 green = aImage.GetGreen( xx, yy) & 0xFF;
645 blue = aImage.GetBlue( xx, yy) & 0xFF;
646
647 // PS doesn't support alpha, so premultiply against white background
648 if( aImage.HasAlpha() )
649 {
650 unsigned char alpha = aImage.GetAlpha( xx, yy ) & 0xFF;
651
652 if( alpha < 0xFF )
653 {
654 float a = 1.0 - ( (float) alpha / 255.0 );
655 red = ( int )( red + ( a * 0xFF ) ) & 0xFF;
656 green = ( int )( green + ( a * 0xFF ) ) & 0xFF;
657 blue = ( int )( blue + ( a * 0xFF ) ) & 0xFF;
658 }
659 }
660
661 if( aImage.HasMask() )
662 {
663 if( red == aImage.GetMaskRed() && green == aImage.GetMaskGreen()
664 && blue == aImage.GetMaskBlue() )
665 {
666 red = 0xFF;
667 green = 0xFF;
668 blue = 0xFF;
669 }
670 }
671
672 if( m_colorMode )
673 {
674 fprintf( m_outputFile, "%2.2X%2.2X%2.2X", red, green, blue );
675 }
676 else
677 {
678 // Greyscale conversion (CIE 1931)
679 unsigned char grey = KiROUND( red * 0.2126 + green * 0.7152 + blue * 0.0722 );
680
681 fprintf( m_outputFile, "%2.2X", grey );
682 }
683 }
684 }
685
686 fprintf( m_outputFile, "\n");
687 fprintf( m_outputFile, "origstate restore\n" );
688}
689
690
691void PS_PLOTTER::PenTo( const VECTOR2I& pos, char plume )
692{
693 wxASSERT( m_outputFile );
694
695 if( plume == 'Z' )
696 {
697 if( m_penState != 'Z' )
698 {
699 fputs( "stroke\n", m_outputFile );
700 m_penState = 'Z';
701 m_penLastpos.x = -1;
702 m_penLastpos.y = -1;
703 }
704
705 return;
706 }
707
708 if( m_penState == 'Z' )
709 {
710 fputs( "newpath\n", m_outputFile );
711 }
712
713 if( m_penState != plume || pos != m_penLastpos )
714 {
715 VECTOR2D pos_dev = userToDeviceCoordinates( pos );
716 fprintf( m_outputFile, "%g %g %sto\n",
717 pos_dev.x, pos_dev.y,
718 ( plume=='D' ) ? "line" : "move" );
719 }
720
721 m_penState = plume;
722 m_penLastpos = pos;
723}
724
725
726bool PS_PLOTTER::StartPlot( const wxString& aPageNumber )
727{
728 wxASSERT( m_outputFile );
729
730 static const char* PSMacro[] =
731 {
732 "%%BeginProlog\n",
733 "/line { newpath moveto lineto stroke } bind def\n",
734 "/cir0 { newpath 0 360 arc stroke } bind def\n",
735 "/cir1 { newpath 0 360 arc gsave fill grestore stroke } bind def\n",
736 "/cir2 { newpath 0 360 arc gsave fill grestore stroke } bind def\n",
737 "/arc0 { newpath arc stroke } bind def\n",
738 "/arc1 { newpath 4 index 4 index moveto arc closepath gsave fill\n",
739 " grestore stroke } bind def\n",
740 "/arc2 { newpath 4 index 4 index moveto arc closepath gsave fill\n",
741 " grestore stroke } bind def\n",
742 "/poly0 { stroke } bind def\n",
743 "/poly1 { closepath gsave fill grestore stroke } bind def\n",
744 "/poly2 { closepath gsave fill grestore stroke } bind def\n",
745 "/rect0 { rectstroke } bind def\n",
746 "/rect1 { rectfill } bind def\n",
747 "/rect2 { rectfill } bind def\n",
748 "/linemode0 { 0 setlinecap 0 setlinejoin 0 setlinewidth } bind def\n",
749 "/linemode1 { 1 setlinecap 1 setlinejoin } bind def\n",
750 "/dashedline { [200] 100 setdash } bind def\n",
751 "/solidline { [] 0 setdash } bind def\n",
752
753 // This is for 'hidden' text (search anchors for PDF)
754 "/phantomshow { moveto\n",
755 " /KicadFont findfont 0.000001 scalefont setfont\n",
756 " show } bind def\n",
757
758 // This is for regular postscript text
759 "/textshow { gsave\n",
760 " findfont exch scalefont setfont concat 1 scale 0 0 moveto show\n",
761 " } bind def\n",
762
763 // Utility for getting Latin1 encoded fonts
764 "/reencodefont {\n",
765 " findfont dup length dict begin\n",
766 " { 1 index /FID ne\n",
767 " { def }\n",
768 " { pop pop } ifelse\n",
769 " } forall\n",
770 " /Encoding ISOLatin1Encoding def\n",
771 " currentdict\n",
772 " end } bind def\n"
773
774 // Remap AdobeStandard fonts to Latin1
775 "/KicadFont /Helvetica reencodefont definefont pop\n",
776 "/KicadFont-Bold /Helvetica-Bold reencodefont definefont pop\n",
777 "/KicadFont-Oblique /Helvetica-Oblique reencodefont definefont pop\n",
778 "/KicadFont-BoldOblique /Helvetica-BoldOblique reencodefont definefont pop\n",
779 "%%EndProlog\n",
780 nullptr
781 };
782
783 time_t time1970 = time( nullptr );
784
785 fputs( "%!PS-Adobe-3.0\n", m_outputFile ); // Print header
786
787 fprintf( m_outputFile, "%%%%Creator: %s\n", TO_UTF8( m_creator ) );
788
789 /* A "newline" character ("\n") is not included in the following string,
790 because it is provided by the ctime() function. */
791 fprintf( m_outputFile, "%%%%CreationDate: %s", ctime( &time1970 ) );
792 fprintf( m_outputFile, "%%%%Title: %s\n", encodeStringForPlotter( m_title ).c_str() );
793 fprintf( m_outputFile, "%%%%Pages: 1\n" );
794 fprintf( m_outputFile, "%%%%PageOrder: Ascend\n" );
795
796 // Print boundary box in 1/72 pixels per inch, box is in mils
797 const double BIGPTsPERMIL = 0.072;
798
799 /* The coordinates of the lower left corner of the boundary
800 box need to be "rounded down", but the coordinates of its
801 upper right corner need to be "rounded up" instead. */
802 VECTOR2I psPaperSize = m_pageInfo.GetSizeMils();
803
804 if( !m_pageInfo.IsPortrait() )
805 {
806 psPaperSize.x = m_pageInfo.GetHeightMils();
807 psPaperSize.y = m_pageInfo.GetWidthMils();
808 }
809
810 fprintf( m_outputFile, "%%%%BoundingBox: 0 0 %d %d\n",
811 (int) ceil( psPaperSize.x * BIGPTsPERMIL ),
812 (int) ceil( psPaperSize.y * BIGPTsPERMIL ) );
813
814 // Specify the size of the sheet and the name associated with that size.
815 // (If the "User size" option has been selected for the sheet size,
816 // identify the sheet size as "Custom" (rather than as "User"), but
817 // otherwise use the name assigned by KiCad for each sheet size.)
818 //
819 // (The Document Structuring Convention also supports sheet weight,
820 // sheet color, and sheet type properties being specified within a
821 // %%DocumentMedia comment, but they are not being specified here;
822 // a zero and two null strings are subsequently provided instead.)
823 //
824 // (NOTE: m_Size.y is *supposed* to be listed before m_Size.x;
825 // the order in which they are specified is not wrong!)
826 // Also note pageSize is given in mils, not in internal units and must be
827 // converted to internal units.
828
829 if( m_pageInfo.IsCustom() )
830 {
831 fprintf( m_outputFile, "%%%%DocumentMedia: Custom %d %d 0 () ()\n",
832 KiROUND( psPaperSize.x * BIGPTsPERMIL ),
833 KiROUND( psPaperSize.y * BIGPTsPERMIL ) );
834 }
835 else // a standard paper size
836 {
837 fprintf( m_outputFile, "%%%%DocumentMedia: %s %d %d 0 () ()\n",
839 KiROUND( psPaperSize.x * BIGPTsPERMIL ),
840 KiROUND( psPaperSize.y * BIGPTsPERMIL ) );
841 }
842
843 if( m_pageInfo.IsPortrait() )
844 fprintf( m_outputFile, "%%%%Orientation: Portrait\n" );
845 else
846 fprintf( m_outputFile, "%%%%Orientation: Landscape\n" );
847
848 fprintf( m_outputFile, "%%%%EndComments\n" );
849
850 // Now specify various other details.
851
852 for( int ii = 0; PSMacro[ii] != nullptr; ii++ )
853 {
854 fputs( PSMacro[ii], m_outputFile );
855 }
856
857 // The following strings are output here (rather than within PSMacro[])
858 // to highlight that it has been provided to ensure that the contents of
859 // the postscript file comply with the Document Structuring Convention.
860 std::string page_num = encodeStringForPlotter( aPageNumber );
861
862 fprintf( m_outputFile, "%%Page: %s 1\n", page_num.c_str() );
863
864 fputs( "%%BeginPageSetup\n"
865 "gsave\n"
866 "0.0072 0.0072 scale\n" // Configure postscript for decimils coordinates
867 "linemode1\n", m_outputFile );
868
869
870 // Rototranslate the coordinate to achieve the landscape layout
871 if( !m_pageInfo.IsPortrait() )
872 fprintf( m_outputFile, "%d 0 translate 90 rotate\n", 10 * psPaperSize.x );
873
874 // Apply the user fine scale adjustments
875 if( plotScaleAdjX != 1.0 || plotScaleAdjY != 1.0 )
876 fprintf( m_outputFile, "%g %g scale\n", plotScaleAdjX, plotScaleAdjY );
877
878 // Set default line width
879 fprintf( m_outputFile, "%g setlinewidth\n",
881 fputs( "%%EndPageSetup\n", m_outputFile );
882
883 return true;
884}
885
886
888{
889 wxASSERT( m_outputFile );
890 fputs( "showpage\n"
891 "grestore\n"
892 "%%EOF\n", m_outputFile );
893 fclose( m_outputFile );
894 m_outputFile = nullptr;
895
896 return true;
897}
898
899
900
901void PS_PLOTTER::Text( const VECTOR2I& aPos,
902 const COLOR4D& aColor,
903 const wxString& aText,
904 const EDA_ANGLE& aOrient,
905 const VECTOR2I& aSize,
906 enum GR_TEXT_H_ALIGN_T aH_justify,
907 enum GR_TEXT_V_ALIGN_T aV_justify,
908 int aWidth,
909 bool aItalic,
910 bool aBold,
911 bool aMultilineAllowed,
912 KIFONT::FONT* aFont,
913 const KIFONT::METRICS& aFontMetrics,
914 void* aData )
915{
916 SetCurrentLineWidth( aWidth );
917 SetColor( aColor );
918
919 // Draw the hidden postscript text (if requested)
920 if( m_textMode == PLOT_TEXT_MODE::PHANTOM )
921 {
922 std::string ps_test = encodeStringForPlotter( aText );
923 VECTOR2D pos_dev = userToDeviceCoordinates( aPos );
924 fprintf( m_outputFile, "%s %g %g phantomshow\n", ps_test.c_str(), pos_dev.x, pos_dev.y );
925 }
926
927 PLOTTER::Text( aPos, aColor, aText, aOrient, aSize, aH_justify, aV_justify, aWidth, aItalic,
928 aBold, aMultilineAllowed, aFont, aFontMetrics, aData );
929}
930
931
933 const COLOR4D& aColor,
934 const wxString& aText,
935 const TEXT_ATTRIBUTES& aAttributes,
936 KIFONT::FONT* aFont,
937 const KIFONT::METRICS& aFontMetrics,
938 void* aData )
939{
940 SetCurrentLineWidth( aAttributes.m_StrokeWidth );
941 SetColor( aColor );
942
943 // Draw the hidden postscript text (if requested)
944 if( m_textMode == PLOT_TEXT_MODE::PHANTOM )
945 {
946 std::string ps_test = encodeStringForPlotter( aText );
947 VECTOR2D pos_dev = userToDeviceCoordinates( aPos );
948 fprintf( m_outputFile, "%s %g %g phantomshow\n", ps_test.c_str(), pos_dev.x, pos_dev.y );
949 }
950
951 PLOTTER::PlotText( aPos, aColor, aText, aAttributes, aFont, aFontMetrics, aData );
952}
953
954
958const double hv_widths[256] = {
959 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
960 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
961 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
962 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
963 0.278, 0.278, 0.355, 0.556, 0.556, 0.889, 0.667, 0.191,
964 0.333, 0.333, 0.389, 0.584, 0.278, 0.333, 0.278, 0.278,
965 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556,
966 0.556, 0.556, 0.278, 0.278, 0.584, 0.584, 0.584, 0.556,
967 1.015, 0.667, 0.667, 0.722, 0.722, 0.667, 0.611, 0.778,
968 0.722, 0.278, 0.500, 0.667, 0.556, 0.833, 0.722, 0.778,
969 0.667, 0.778, 0.722, 0.667, 0.611, 0.722, 0.667, 0.944,
970 0.667, 0.667, 0.611, 0.278, 0.278, 0.278, 0.469, 0.556,
971 0.333, 0.556, 0.556, 0.500, 0.556, 0.556, 0.278, 0.556,
972 0.556, 0.222, 0.222, 0.500, 0.222, 0.833, 0.556, 0.556,
973 0.556, 0.556, 0.333, 0.500, 0.278, 0.556, 0.500, 0.722,
974 0.500, 0.500, 0.500, 0.334, 0.260, 0.334, 0.584, 0.278,
975 0.278, 0.278, 0.222, 0.556, 0.333, 1.000, 0.556, 0.556,
976 0.333, 1.000, 0.667, 0.333, 1.000, 0.278, 0.278, 0.278,
977 0.278, 0.222, 0.222, 0.333, 0.333, 0.350, 0.556, 1.000,
978 0.333, 1.000, 0.500, 0.333, 0.944, 0.278, 0.278, 0.667,
979 0.278, 0.333, 0.556, 0.556, 0.556, 0.556, 0.260, 0.556,
980 0.333, 0.737, 0.370, 0.556, 0.584, 0.333, 0.737, 0.333,
981 0.400, 0.584, 0.333, 0.333, 0.333, 0.556, 0.537, 0.278,
982 0.333, 0.333, 0.365, 0.556, 0.834, 0.834, 0.834, 0.611,
983 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 1.000, 0.722,
984 0.667, 0.667, 0.667, 0.667, 0.278, 0.278, 0.278, 0.278,
985 0.722, 0.722, 0.778, 0.778, 0.778, 0.778, 0.778, 0.584,
986 0.778, 0.722, 0.722, 0.722, 0.722, 0.667, 0.667, 0.611,
987 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.889, 0.500,
988 0.556, 0.556, 0.556, 0.556, 0.278, 0.278, 0.278, 0.278,
989 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.584,
990 0.611, 0.556, 0.556, 0.556, 0.556, 0.500, 0.556, 0.500
991};
992
993
997const double hvb_widths[256] = {
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.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1001 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1002 0.278, 0.333, 0.474, 0.556, 0.556, 0.889, 0.722, 0.238,
1003 0.333, 0.333, 0.389, 0.584, 0.278, 0.333, 0.278, 0.278,
1004 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556,
1005 0.556, 0.556, 0.333, 0.333, 0.584, 0.584, 0.584, 0.611,
1006 0.975, 0.722, 0.722, 0.722, 0.722, 0.667, 0.611, 0.778,
1007 0.722, 0.278, 0.556, 0.722, 0.611, 0.833, 0.722, 0.778,
1008 0.667, 0.778, 0.722, 0.667, 0.611, 0.722, 0.667, 0.944,
1009 0.667, 0.667, 0.611, 0.333, 0.278, 0.333, 0.584, 0.556,
1010 0.333, 0.556, 0.611, 0.556, 0.611, 0.556, 0.333, 0.611,
1011 0.611, 0.278, 0.278, 0.556, 0.278, 0.889, 0.611, 0.611,
1012 0.611, 0.611, 0.389, 0.556, 0.333, 0.611, 0.556, 0.778,
1013 0.556, 0.556, 0.500, 0.389, 0.280, 0.389, 0.584, 0.278,
1014 0.278, 0.278, 0.278, 0.556, 0.500, 1.000, 0.556, 0.556,
1015 0.333, 1.000, 0.667, 0.333, 1.000, 0.278, 0.278, 0.278,
1016 0.278, 0.278, 0.278, 0.500, 0.500, 0.350, 0.556, 1.000,
1017 0.333, 1.000, 0.556, 0.333, 0.944, 0.278, 0.278, 0.667,
1018 0.278, 0.333, 0.556, 0.556, 0.556, 0.556, 0.280, 0.556,
1019 0.333, 0.737, 0.370, 0.556, 0.584, 0.333, 0.737, 0.333,
1020 0.400, 0.584, 0.333, 0.333, 0.333, 0.611, 0.556, 0.278,
1021 0.333, 0.333, 0.365, 0.556, 0.834, 0.834, 0.834, 0.611,
1022 0.722, 0.722, 0.722, 0.722, 0.722, 0.722, 1.000, 0.722,
1023 0.667, 0.667, 0.667, 0.667, 0.278, 0.278, 0.278, 0.278,
1024 0.722, 0.722, 0.778, 0.778, 0.778, 0.778, 0.778, 0.584,
1025 0.778, 0.722, 0.722, 0.722, 0.722, 0.667, 0.667, 0.611,
1026 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.889, 0.556,
1027 0.556, 0.556, 0.556, 0.556, 0.278, 0.278, 0.278, 0.278,
1028 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.584,
1029 0.611, 0.611, 0.611, 0.611, 0.611, 0.556, 0.611, 0.556
1030};
1031
1032
1036const double hvo_widths[256] = {
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.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1040 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1041 0.278, 0.278, 0.355, 0.556, 0.556, 0.889, 0.667, 0.191,
1042 0.333, 0.333, 0.389, 0.584, 0.278, 0.333, 0.278, 0.278,
1043 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556,
1044 0.556, 0.556, 0.278, 0.278, 0.584, 0.584, 0.584, 0.556,
1045 1.015, 0.667, 0.667, 0.722, 0.722, 0.667, 0.611, 0.778,
1046 0.722, 0.278, 0.500, 0.667, 0.556, 0.833, 0.722, 0.778,
1047 0.667, 0.778, 0.722, 0.667, 0.611, 0.722, 0.667, 0.944,
1048 0.667, 0.667, 0.611, 0.278, 0.278, 0.278, 0.469, 0.556,
1049 0.333, 0.556, 0.556, 0.500, 0.556, 0.556, 0.278, 0.556,
1050 0.556, 0.222, 0.222, 0.500, 0.222, 0.833, 0.556, 0.556,
1051 0.556, 0.556, 0.333, 0.500, 0.278, 0.556, 0.500, 0.722,
1052 0.500, 0.500, 0.500, 0.334, 0.260, 0.334, 0.584, 0.278,
1053 0.278, 0.278, 0.222, 0.556, 0.333, 1.000, 0.556, 0.556,
1054 0.333, 1.000, 0.667, 0.333, 1.000, 0.278, 0.278, 0.278,
1055 0.278, 0.222, 0.222, 0.333, 0.333, 0.350, 0.556, 1.000,
1056 0.333, 1.000, 0.500, 0.333, 0.944, 0.278, 0.278, 0.667,
1057 0.278, 0.333, 0.556, 0.556, 0.556, 0.556, 0.260, 0.556,
1058 0.333, 0.737, 0.370, 0.556, 0.584, 0.333, 0.737, 0.333,
1059 0.400, 0.584, 0.333, 0.333, 0.333, 0.556, 0.537, 0.278,
1060 0.333, 0.333, 0.365, 0.556, 0.834, 0.834, 0.834, 0.611,
1061 0.667, 0.667, 0.667, 0.667, 0.667, 0.667, 1.000, 0.722,
1062 0.667, 0.667, 0.667, 0.667, 0.278, 0.278, 0.278, 0.278,
1063 0.722, 0.722, 0.778, 0.778, 0.778, 0.778, 0.778, 0.584,
1064 0.778, 0.722, 0.722, 0.722, 0.722, 0.667, 0.667, 0.611,
1065 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.889, 0.500,
1066 0.556, 0.556, 0.556, 0.556, 0.278, 0.278, 0.278, 0.278,
1067 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.584,
1068 0.611, 0.556, 0.556, 0.556, 0.556, 0.500, 0.556, 0.500
1069};
1070
1071
1075const double hvbo_widths[256] = {
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.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1079 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278, 0.278,
1080 0.278, 0.333, 0.474, 0.556, 0.556, 0.889, 0.722, 0.238,
1081 0.333, 0.333, 0.389, 0.584, 0.278, 0.333, 0.278, 0.278,
1082 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.556,
1083 0.556, 0.556, 0.333, 0.333, 0.584, 0.584, 0.584, 0.611,
1084 0.975, 0.722, 0.722, 0.722, 0.722, 0.667, 0.611, 0.778,
1085 0.722, 0.278, 0.556, 0.722, 0.611, 0.833, 0.722, 0.778,
1086 0.667, 0.778, 0.722, 0.667, 0.611, 0.722, 0.667, 0.944,
1087 0.667, 0.667, 0.611, 0.333, 0.278, 0.333, 0.584, 0.556,
1088 0.333, 0.556, 0.611, 0.556, 0.611, 0.556, 0.333, 0.611,
1089 0.611, 0.278, 0.278, 0.556, 0.278, 0.889, 0.611, 0.611,
1090 0.611, 0.611, 0.389, 0.556, 0.333, 0.611, 0.556, 0.778,
1091 0.556, 0.556, 0.500, 0.389, 0.280, 0.389, 0.584, 0.278,
1092 0.278, 0.278, 0.278, 0.556, 0.500, 1.000, 0.556, 0.556,
1093 0.333, 1.000, 0.667, 0.333, 1.000, 0.278, 0.278, 0.278,
1094 0.278, 0.278, 0.278, 0.500, 0.500, 0.350, 0.556, 1.000,
1095 0.333, 1.000, 0.556, 0.333, 0.944, 0.278, 0.278, 0.667,
1096 0.278, 0.333, 0.556, 0.556, 0.556, 0.556, 0.280, 0.556,
1097 0.333, 0.737, 0.370, 0.556, 0.584, 0.333, 0.737, 0.333,
1098 0.400, 0.584, 0.333, 0.333, 0.333, 0.611, 0.556, 0.278,
1099 0.333, 0.333, 0.365, 0.556, 0.834, 0.834, 0.834, 0.611,
1100 0.722, 0.722, 0.722, 0.722, 0.722, 0.722, 1.000, 0.722,
1101 0.667, 0.667, 0.667, 0.667, 0.278, 0.278, 0.278, 0.278,
1102 0.722, 0.722, 0.778, 0.778, 0.778, 0.778, 0.778, 0.584,
1103 0.778, 0.722, 0.722, 0.722, 0.722, 0.667, 0.667, 0.611,
1104 0.556, 0.556, 0.556, 0.556, 0.556, 0.556, 0.889, 0.556,
1105 0.556, 0.556, 0.556, 0.556, 0.278, 0.278, 0.278, 0.278,
1106 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.611, 0.584,
1107 0.611, 0.611, 0.611, 0.611, 0.611, 0.556, 0.611, 0.556
1108};
int color
Definition: DXF_plotter.cpp:58
VECTOR2D mapCoords(const VECTOR2D &aSource)
Definition: PS_plotter.cpp:525
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.
Definition: PS_plotter.cpp:997
const double hv_widths[256]
Character widths for Helvetica.
Definition: PS_plotter.cpp:958
const double hvo_widths[256]
Character widths for Helvetica-Oblique.
double Sin() const
Definition: eda_angle.h:206
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
double Cos() const
Definition: eda_angle.h:221
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:143
double GetHeightMils() const
Definition: page_info.h:140
const wxString & GetType() const
Definition: page_info.h:98
double GetWidthMils() const
Definition: page_info.h:135
bool IsCustom() const
Definition: page_info.cpp:183
bool IsPortrait() const
Definition: page_info.h:121
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:665
bool m_plotMirror
Definition: plotter.h:647
static const int USE_DEFAULT_LINE_WIDTH
Definition: plotter.h:108
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
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:501
int GetPlotterArcHighDef() const
Definition: plotter.h:207
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
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:107
RENDER_SETTINGS * m_renderSettings
Definition: plotter.h:670
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:657
double m_IUsPerDecimil
Definition: plotter.h:642
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:664
virtual int GetCurrentLineWidth() const
Definition: plotter.h:147
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: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:887
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:901
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:561
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:932
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:583
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:497
virtual void Circle(const VECTOR2I &pos, int diametre, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH) override
Definition: PS_plotter.cpp:511
virtual void SetDash(int aLineWidth, LINE_STYLE aLineStyle) override
PostScript supports dashed lines.
Definition: PS_plotter.cpp:464
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:726
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:531
virtual void emitSetRGBColor(double r, double g, double b, double a) override
Virtual primitive for emitting the setrgbcolor operator.
Definition: PS_plotter.cpp:444
virtual void SetCurrentLineWidth(int width, void *aData=nullptr) override
Set the current line width (in IUs) for the next plot.
Definition: PS_plotter.cpp:424
virtual void PenTo(const VECTOR2I &pos, char plume) override
Moveto/lineto primitive, moves the 'pen' to the specified direction.
Definition: PS_plotter.cpp:691
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:439
static constexpr EDA_ANGLE & ANGLE_0
Definition: eda_angle.h:437
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
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:426
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_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)
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:85
VECTOR2< double > VECTOR2D
Definition: vector2d.h:587