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