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