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