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