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