w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

drvpdf.cpp
Go to the documentation of this file.
1 /*
2  drvPDF.cpp : This file is part of pstoedit
3  Backend for PDF(TM) format
4 
5  Copyright (C) 1993 - 2020 Wolfgang Glunz, wglunz35_AT_pstoedit.net
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (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, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 /*
23  The PDF format and the corresponding operators are copyrighted
24  by Adobe Systems, Inc.
25 */
26 
27 #include "drvpdf.h"
28 #include I_iostream
29 #include I_iomanip
30 #include I_fstream
31 #include I_fstream
32 #include I_stdio
33 #include I_stdlib
34 
35 #include <time.h>
36 
37 // for sin and cos
38 #include <math.h>
39 
40 USESTD
41 using std::setw;
42 using std::setfill;
43 
44 static constexpr float rnd(const float f, const float roundnumber)
45 {
46  return ((long int) ((f * roundnumber) + ((f < 0.0f) ? -0.5f : 0.5f))) / roundnumber;
47 }
48 
49 static inline float RND3(const float f)
50 {
51  return rnd(f, 1000.0f);
52 }
53 
54 static const char *PDFFonts[] = { // predefined Fonts (see page 64 PDF Ref. Manual )
55  "Courier",
56  "Courier-Bold",
57  "Courier-Oblique",
58  "Courier-BoldOblique",
59  "Helvetica",
60  "Helvetica-Bold",
61  "Helvetica-Oblique",
62  "Helvetica-BoldOblique",
63  "Symbol",
64  "Times-Roman",
65  "Times-Bold",
66  "Times-Italic",
67  "Times-BoldItalic",
68  "ZapfDingbats",
69  nullptr
70 };
71 
72 const unsigned int numberOfFonts = sizeof(PDFFonts) / (sizeof(char *)) - 1;
73 
74 const char *const *drvPDF::knownFontNames() const
75 {
76  return PDFFonts;
77 }
78 
79 unsigned int drvPDF::newobject()
80 {
81  currentobject++;
82  if (currentobject >= maxobjects) {
83  errf << "Sorry, too many objects in this file" << endl;
84  exit(1);
85  }
86  startPosition[currentobject] = outf.tellp();
87  outf << currentobject << " 0 obj" << endl;
88  return currentobject;
89 }
90 
92 {
93  outf << "endobj" << endl;
94 }
95 
96 template <class T >inline T Max(T a, T b)
97 {
98  return (a > b ? a : b);
99 }
100 
101 template <class T >inline T Min(T a, T b)
102 {
103  return (a < b ? a : b);
104 }
105 void drvPDF::adjustbbox(float x, float y)
106 {
107  bb_llx = Min((int) x, bb_llx);
108  bb_lly = Min((int) y, bb_lly);
109  bb_urx = Max((int) x, bb_urx);
110  bb_ury = Max((int) y, bb_ury);
111 }
112 
113 // the following two functions avoid unneccessary ET BT sequences
115 {
116  if (!inTextMode) {
117  buffer << "BT" << endl;
118  inTextMode = true;
119  }
120 }
122 {
123  if (inTextMode) {
124  buffer << "ET" << endl;
125  inTextMode = false;
126  }
127 }
128 
129 
130 static std::streampos newlinebytes = 1; // how many bytes are a newline (1 or 2)
131 
132 static const char *const stdEncoding = "Standard";
133 
134 const int largeint = 32000;
137 currentobject(0),
138 pagenr(0),
139 inTextMode(false),
140 encodingName(stdEncoding),
141 buffer(tempFile.asOutput()),
142 bb_llx(largeint), bb_lly(largeint), bb_urx(-largeint), bb_ury(-largeint)
143 {
144  if (&outf == &cout) {
145  // Due to tell not working correctly on cout
146  errf << "Sorry, PDF cannot be written to standard output. Use a file instead\n";
147  exit(1);
148  }
149  const char *const header = "%PDF-1.1";
150  outf << header << endl;
151  newlinebytes = (long) outf.tellp() - (long) strlen(header);
152  if (Verbose())
153  outf << "% Driver options:" << endl;
154  for (unsigned int i = 0; i < d_argc; i++) {
155  assert(d_argv && d_argv[i]);
156  if (Verbose())
157  outf << "% " << d_argv[i] << endl;
158  if (strcmp(d_argv[i], "-e") == 0) {
159  encodingName = d_argv[i + 1];
160  }
161  }
162 
163  errf << "Info: This PDF driver is not very elaborated - consider using -f gs:pdfwrite instead." << endl;
164 
165 }
166 
168 {
169  // print trailer
170 
171  endtext(); // close text if open
172 
173  const unsigned int outlines = newobject();
174  outf << "<<" << endl;
175  outf << "/Type /Outlines" << endl;
176  outf << "/Count 0" << endl;
177  outf << ">>" << endl;
178  endobject();
179 
180  const unsigned int encoding = newobject();
181  // write the diffs between pdf-encoding and WinAnsiEncoding
182  outf << "<<" << endl;
183  outf << "/Type /Encoding" << endl;
184 
185 #ifdef basedonwinansi
186 // For some reasons this does not work.
187 // I haven't seen a working example using the /BaseEncoding feature
188  outf << "/BaseEncoding /WinAnsiEncoding" << endl;
189  outf << "%/Differences [" << endl;
190  outf << "% 24 /breve/caron/circumflex/dotaccent/hungarumlaut/ogonek/ring/tilde" << endl;
191  outf << "%127 /.notdef 129 /dagger/daggerdbl/ellipsis/emdash/endash/florin/fraction" << endl;
192  outf << "%/guilsinglleft/guilsinglright/minus/perthousand/quotedblbase/quotedblleft" << endl;
193  outf << "%/quotedblright/quoteleft/quoteright/quotesinglbase/trademark/fi/fl/Lslash" << endl;
194  outf <<
195  "%/OE/Scaron/Ydieresis/Zcaron/dotlessi/lslash/scaron/zcaron/.notdef/.notdef/.notdef"
196  << endl;
197  outf << "%]" << endl;
198 #endif
199 
200 // The following part (diffs between standard encoding and pdf encoding)
201 // was generated by a small PostScript program run through gs
202  outf << "/Differences [" << endl;
203  outf << "24 /breve" << endl;
204  outf << "25 /caron" << endl;
205  outf << "26 /circumflex" << endl;
206  outf << "27 /dotaccent" << endl;
207  outf << "28 /hungarumlaut" << endl;
208  outf << "29 /ogonek" << endl;
209  outf << "30 /ring" << endl;
210  outf << "31 /tilde" << endl;
211  outf << "39 /quotesingle" << endl;
212  outf << "96 /grave" << endl;
213  outf << "128 /bullet" << endl;
214  outf << "129 /dagger" << endl;
215  outf << "130 /daggerdbl" << endl;
216  outf << "131 /ellipsis" << endl;
217  outf << "132 /emdash" << endl;
218  outf << "133 /endash" << endl;
219  outf << "134 /florin" << endl;
220  outf << "135 /fraction" << endl;
221  outf << "136 /guilsinglleft" << endl;
222  outf << "137 /guilsinglright" << endl;
223  outf << "138 /minus" << endl;
224  outf << "139 /perthousand" << endl;
225  outf << "140 /quotedblbase" << endl;
226  outf << "141 /quotedblleft" << endl;
227  outf << "142 /quotedblright" << endl;
228  outf << "143 /quoteleft" << endl;
229  outf << "144 /quoteright" << endl;
230  outf << "145 /quotesinglbase" << endl;
231  outf << "146 /trademark" << endl;
232  outf << "147 /fi" << endl;
233  outf << "148 /fl" << endl;
234  outf << "149 /Lslash" << endl;
235  outf << "150 /OE" << endl;
236  outf << "151 /Scaron" << endl;
237  outf << "152 /Ydieresis" << endl;
238  outf << "153 /Zcaron" << endl;
239  outf << "154 /dotlessi" << endl;
240  outf << "155 /lslash" << endl;
241  outf << "156 /oe" << endl;
242  outf << "157 /scaron" << endl;
243  outf << "158 /zcaron" << endl;
244  outf << "164 /currency" << endl;
245  outf << "166 /brokenbar" << endl;
246  outf << "168 /dieresis" << endl;
247  outf << "169 /copyright" << endl;
248  outf << "170 /ordfeminine" << endl;
249  outf << "172 /logicalnot" << endl;
250  outf << "174 /registered" << endl;
251  outf << "175 /macron" << endl;
252  outf << "176 /degree" << endl;
253  outf << "177 /plusminus" << endl;
254  outf << "178 /twosuperior" << endl;
255  outf << "179 /threesuperior" << endl;
256  outf << "180 /acute" << endl;
257  outf << "181 /mu" << endl;
258  outf << "183 /periodcentered" << endl;
259  outf << "184 /cedilla" << endl;
260  outf << "185 /onesuperior" << endl;
261  outf << "186 /ordmasculine" << endl;
262  outf << "188 /onequarter" << endl;
263  outf << "189 /onehalf" << endl;
264  outf << "190 /threequarters" << endl;
265  outf << "192 /Agrave" << endl;
266  outf << "193 /Aacute" << endl;
267  outf << "194 /Acircumflex" << endl;
268  outf << "195 /Atilde" << endl;
269  outf << "196 /Adieresis" << endl;
270  outf << "197 /Aring" << endl;
271  outf << "198 /AE" << endl;
272  outf << "199 /Ccedilla" << endl;
273  outf << "200 /Egrave" << endl;
274  outf << "201 /Eacute" << endl;
275  outf << "202 /Ecircumflex" << endl;
276  outf << "203 /Edieresis" << endl;
277  outf << "204 /Igrave" << endl;
278  outf << "205 /Iacute" << endl;
279  outf << "206 /Icircumflex" << endl;
280  outf << "207 /Idieresis" << endl;
281  outf << "208 /Eth" << endl;
282  outf << "209 /Ntilde" << endl;
283  outf << "210 /Ograve" << endl;
284  outf << "211 /Oacute" << endl;
285  outf << "212 /Ocircumflex" << endl;
286  outf << "213 /Otilde" << endl;
287  outf << "214 /Odieresis" << endl;
288  outf << "215 /multiply" << endl;
289  outf << "216 /Oslash" << endl;
290  outf << "217 /Ugrave" << endl;
291  outf << "218 /Uacute" << endl;
292  outf << "219 /Ucircumflex" << endl;
293  outf << "220 /Udieresis" << endl;
294  outf << "221 /Yacute" << endl;
295  outf << "222 /Thorn" << endl;
296  outf << "223 /germandbls" << endl;
297  outf << "224 /agrave" << endl;
298  outf << "225 /aacute" << endl;
299  outf << "226 /acircumflex" << endl;
300  outf << "227 /atilde" << endl;
301  outf << "228 /adieresis" << endl;
302  outf << "229 /aring" << endl;
303  outf << "230 /ae" << endl;
304  outf << "231 /ccedilla" << endl;
305  outf << "232 /egrave" << endl;
306  outf << "233 /eacute" << endl;
307  outf << "234 /ecircumflex" << endl;
308  outf << "235 /edieresis" << endl;
309  outf << "236 /igrave" << endl;
310  outf << "237 /iacute" << endl;
311  outf << "238 /icircumflex" << endl;
312  outf << "239 /idieresis" << endl;
313  outf << "240 /eth" << endl;
314  outf << "241 /ntilde" << endl;
315  outf << "242 /ograve" << endl;
316  outf << "243 /oacute" << endl;
317  outf << "244 /ocircumflex" << endl;
318  outf << "245 /otilde" << endl;
319  outf << "246 /odieresis" << endl;
320  outf << "247 /divide" << endl;
321  outf << "248 /oslash" << endl;
322  outf << "249 /ugrave" << endl;
323  outf << "250 /uacute" << endl;
324  outf << "251 /ucircumflex" << endl;
325  outf << "252 /udieresis" << endl;
326  outf << "253 /yacute" << endl;
327  outf << "254 /thorn" << endl;
328  outf << "255 /ydieresis" << endl;
329  outf << "]" << endl;
330  outf << ">>" << endl;
331  endobject();
332 
333 
334  const unsigned int firstFontObject = currentobject + 1;
335  // Now define all the 14 standard fonts
336  for (unsigned int f = 0; f < numberOfFonts; f++) {
337  const unsigned int font = newobject();
338  unused(&font);
339  outf << "<<" << endl;
340  outf << "/Type /Font" << endl;
341  outf << "/Subtype /Type1" << endl;
342  outf << "/Name /F" << f << endl;
343  outf << "/BaseFont /" << PDFFonts[f] << endl;
344  if ((f == 8) || (f == 13)) {
345  // the special fonts symbol and ZapfDingbats
346 
347  // commented out based on a suggestion from Derek Noonburg
348  // outf << "/Encoding /" << encodingName << "Encoding" << endl;
349  } else {
350  outf << "/Encoding " << encoding << " 0 R" << endl;
351  }
352  outf << ">>" << endl;
353  endobject();
354  }
355 
356  const unsigned int catalog = newobject();
357  unsigned int pages = currentobject + 2; // will be next after resources;
358  outf << "<<" << endl;
359  outf << "/Type /Catalog" << endl;
360  outf << "/Pages " << pages << " 0 R" << endl;
361  outf << "/Outlines " << outlines << " 0 R" << endl;
362  outf << ">>" << endl;
363  endobject();
364 
365  const unsigned int nrOfPages = pagenr;
366 
367  const unsigned int resources = newobject();
368  outf << "<<" << endl;
369  outf << "/ProcSet [ /PDF /Text ]" << endl;
370  outf << "/Font <<" << endl;
371  for (unsigned int f2 = 0; f2 < numberOfFonts; f2++) {
372  outf << "/F" << f2 << " " << f2 + firstFontObject << " 0 R" << endl;
373  }
374  outf << ">>" << endl; // closing /Font
375  outf << ">>" << endl; // closing /Resources dictionary
376  endobject();
377 
378  pages = newobject();
379  outf << "<<" << endl;
380  outf << "/Type /Pages" << endl;
381  outf << "/Count " << nrOfPages << endl;
382  outf << "/Kids [ ";
383  for (unsigned int i = 1; i <= nrOfPages; i++) {
384  outf << i + pages << " 0 R ";
385  }
386  outf << " ] " << endl;
387  outf << "/MediaBox [0 0 " << (int) (currentDeviceWidth +
388  0.5) << ' ' <<
389  (int) (currentDeviceHeight + 0.5) << "]" << endl;
390 #if 0
391  const int width = bb_urx - bb_llx;
392  const int height = bb_ury - bb_lly;
393  // heuristically increase shown area by 20% in each direction
394  outf << "/MediaBox ["
395  << bb_llx - 0.2 * width << ' '
396  << bb_lly - 0.2 * height << ' '
397  << bb_urx + 0.2 * width << ' ' << bb_ury + 0.2 * height << " ]" << endl;
398 #endif
399  outf << "/Resources ";
400  outf << resources << " 0 R" << endl;
401  outf << ">>" << endl;
402  endobject();
403 
404 
405  // Now write the Page parts for each page
406  for (unsigned int j = 1; j <= nrOfPages; j++) {
407  const unsigned int pageobject = newobject();
408  unused(&pageobject);
409  outf << "<<" << endl;
410  outf << "/Type /Page" << endl;
411  outf << "/Parent " << pages << " 0 R" << endl;
412  outf << "/Contents " << j << " 0 R" << endl;
413  outf << "/Resources " << resources << " 0 R" << endl;
414  outf << ">>" << endl;
415  endobject();
416  }
417 
418  const unsigned int infoobject = newobject();
419  outf << "<<" << endl;
420 
421  outf << "/CreationDate (D:" << drvbase::DateString() << ")" << endl;
422 #if 0
423 // Comments by Rohan
424 // This is a hack
425 // Since Windows CE does not support, I am just putting a dummy date(i.e "01/01/18 09:00:00")
426 #ifndef OS_WIN32_WCE
427  const time_t t = time(nullptr);
428  const struct tm * const localt = localtime(&t);
429  // (D:YYYYMMDDHHmmSSOHH'mm')
430  // All parts of the date after the year are optional.
431  if (localt) {
432  outf << "/CreationDate (D:" << drvbase::DateString() << ")" << endl;
433 #if 0
434  << setw(4) << localt->tm_year + 1900
435  << setw(2) << setfill('0') << localt->tm_mon + 1
436  << setw(2) << setfill('0') << localt->tm_mday
437  << setw(2) << setfill('0') << localt->tm_hour
438  << setw(2) << setfill('0') << localt->tm_min
439  << setw(2) << setfill('0') << localt->tm_sec << ")" << endl;
440 #endif
441  }
442 #else
443  outf << "/CreationDate (D:"
444  << setw(4) << 2018
445  << setw(2) << setfill('0') << 1
446  << setw(2) << setfill('0') << 1
447  << setw(2) << setfill('0') << 9
448  << setw(2) << setfill('0') << 0
449  << setw(2) << setfill('0') << 0 << ")" << endl;
450 #endif
451 #endif
452 
453  outf << "/Producer (pstoedit by wglunz35_AT_pstoedit.net)" << endl;
454  outf << ">>" << endl;
455  endobject();
456 
457  const std::streampos xrefbegin = outf.tellp();
458  outf << "xref" << endl;
459  outf << "0 " << currentobject + 1 << endl;
460  outf << "0000000000 65535 f";
461  if ((long) newlinebytes == 1L) {
462  outf << " ";
463  }
464  outf << endl;
465 
466  for (unsigned int x = 1; x <= currentobject; x++) {
467  outf.width(10);
468  outf.fill('0');
469  outf << startPosition[x] << " 00000 n";
470  if ((long) newlinebytes == 1L) {
471  outf << " ";
472  }
473  outf << endl;
474  }
475  outf << "trailer" << endl;
476  outf << "<<" << endl;
477  outf << "/Size " << currentobject + 1 << endl;
478  outf << "/Info " << infoobject << " 0 R" << endl;
479  outf << "/Root " << catalog << " 0 R" << endl;
480  outf << ">>" << endl;
481  outf << "startxref" << endl;
482  outf << xrefbegin << endl;
483  outf << "%%EOF" << endl;
484  options=nullptr;
485  encodingName=nullptr;
486 }
487 
489 {
490 // buffer.precision(3);
491 // buffer.setf(ios::fixed);
492 // buffer.width(0); // to force minimal width
493 // buffer.unsetf(ios::showpoint);
494 
495  for (unsigned int n = 0; n < numberOfElementsInPath(); n++) {
496  const basedrawingelement & elem = pathElement(n);
497  switch (elem.getType()) {
498  case moveto:{
499  const Point & p = elem.getPoint(0);
500  adjustbbox(p.x_ + x_offset, p.y_ + y_offset);
501  buffer << RND3(p.x_ + x_offset) << " " << RND3(p.y_ + y_offset) << " ";
502  buffer << "m " << endl;
503  }
504  break;
505  case lineto:{
506  const Point & p = elem.getPoint(0);
507  adjustbbox(p.x_ + x_offset, p.y_ + y_offset);
508  buffer << RND3(p.x_ + x_offset) << " " << RND3(p.y_ + y_offset) << " ";
509  buffer << "l " << endl;
510  }
511  break;
512  case closepath:
513  buffer << "h " << endl;
514  break;
515  case curveto:{
516  for (unsigned int cp = 0; cp < 3; cp++) {
517  const Point & p = elem.getPoint(cp);
518  adjustbbox(p.x_ + x_offset, p.y_ + y_offset);
519  buffer << RND3(p.x_ + x_offset) << " " << RND3(p.y_ + y_offset) << " ";
520  }
521  buffer << "c " << endl;
522  }
523  break;
524  default:
525  errf << "Fatal: unexpected case in drvpdf " << endl;
526  abort();
527  break;
528  }
529  }
530 }
531 
532 
533 void drvPDF::open_page()
534 {
535  endtext(); // close text if open
536  const unsigned int currentpage = newobject();
538  pagenr++;
539  // provide a temp stream
541 }
542 
543 void drvPDF::close_page()
544 {
545  endtext(); // close text if open
546 
547  const std::streampos endpos = buffer.tellp();
548  outf << "<<" << endl;
549  outf << "/Length " << endpos << endl;
550  outf << ">>" << endl;
551  outf << "stream" << endl;
552  ifstream & instream = tempFile.asInput();
553  copy_file(instream, outf);
554 // int ret = 0;
555 // while ( (ret = instream.get()) != EOF ) {
556 // outf << (char) ret ;
557 // }
558  outf << "endstream" << endl;
559 
560  endobject();
561 }
562 
563 static int getFontNumber(const char *const fontname)
564 {
565  const size_t fntlength = strlen(fontname);
566  for (unsigned int i = 0; i < numberOfFonts; i++) {
567  const size_t pdfFntLengh = strlen(PDFFonts[i]);
568  if (fntlength == pdfFntLengh) {
569  if (strncmp(fontname, PDFFonts[i], fntlength) == 0) {
570  return i;
571  }
572  }
573  }
574  return -1;
575 }
576 
577 static int getSubStringFontNumber(const char *const fontname)
578 {
579  // searches for a font name which is the longest substring of the current font name
580  int index = -1;
581  size_t longest = 0;
582  const size_t fntlength = strlen(fontname);
583  for (unsigned int i = 0; i < numberOfFonts; i++) {
584  const size_t pdfFntLength = strlen(PDFFonts[i]);
585  if (fntlength >= pdfFntLength) {
586  if (strncmp(fontname, PDFFonts[i], pdfFntLength) == 0) {
587  if (pdfFntLength > longest) {
588  longest = pdfFntLength;
589  index = (int) i;
590  }
591  }
592  }
593  }
594  return index;
595 }
596 
597 void drvPDF::show_text(const TextInfo & textinfo)
598 {
599  const float toRadians = 3.14159265359f / 180.0f;
600  const float angleInRadians = textinfo.currentFontAngle * toRadians;
601  int PDFFontNum = getFontNumber(textinfo.currentFontName.c_str());
602  if (PDFFontNum == -1) {
603  PDFFontNum = getSubStringFontNumber(textinfo.currentFontName.c_str());
604  if (PDFFontNum == -1) {
606  if (PDFFontNum == -1) {
607  errf << "Warning, unsupported font " << textinfo.
608  currentFontName.c_str() << ", using Courier instead" << endl;
609  PDFFontNum = 0; // Courier
610  } else {
611  errf << "Warning, unsupported font " << textinfo.
612  currentFontName.c_str() << ", using " << defaultFontName << " instead" << endl;
613  }
614  } else {
615  errf << "Warning, unsupported font " << textinfo.
616  currentFontName.c_str() << ", using " << PDFFonts[PDFFontNum] << " instead" << endl;
617  }
618  }
619  starttext();
620 // define TFALWAYSONE
621 // note TFALWAYSONE does not work correctly with awidthshow. See showex.ps
622 #ifdef TFALWAYSONE
623  const float Sx = textinfo.currentFontSize;
624  const float Sy = textinfo.currentFontSize;
625  buffer << "/F" << PDFFontNum << ' ' << 1 << " Tf" << endl;
626  // use size 1 and scale via Tm
627 #else
628  // previously we used currentFontSize for SX and SY
629  // and fontsize 1 in Tm, now we use the fontsize in tm and set
630  // sx and sy to 1
631  const float Sx = 1.0f;
632  const float Sy = 1.0f;
633  buffer << "/F" << PDFFontNum << ' ' << textinfo.currentFontSize << " Tf" << endl;
634 #endif
635  const float cosphi = (float) cos(angleInRadians);
636  const float sinphi = (float) sin(angleInRadians);
637  // OK, we could get the real transformation matrix from the interpreter,
638  // but this approximation should do it in most cases.
639 // buffer.precision(3);
640 // buffer.setf(ios::fixed);
641 // buffer.width(0); // to force minimal width
642 // buffer.unsetf(ios::showpoint);
643 
644  adjustbbox(textinfo.x() + x_offset, textinfo.y() + y_offset);
645  buffer << RND3(Sx * cosphi) << " "
646  << RND3(Sx * sinphi) << " "
647  << RND3(-Sy * sinphi) << " "
648  << RND3(Sy * cosphi) << " "
649  << RND3(textinfo.x() + x_offset) << " " << RND3(textinfo.y() + y_offset) << " Tm" << endl;
650  buffer << RND3(textinfo.currentR) << " " << RND3(textinfo.
651  currentG) << " " <<
652  RND3(textinfo.currentB) << " rg" << endl;
653 #ifdef TFALWAYSONE
654  buffer << RND3(textinfo.cx /
655  textinfo.currentFontSize) << ' ' << RND3(textinfo.ax / textinfo.currentFontSize)
656  << ' ';
657 #else
658  buffer << RND3(textinfo.cx) << ' ' << RND3(textinfo.ax) << ' ';
659 #endif
660  buffer << "(";
661  const char *start_of_text = textinfo.thetext.c_str();
662  while (*start_of_text) {
663  if ((*start_of_text == '(') || (*start_of_text == ')') || (*start_of_text == '\\')) {
664  buffer << '\\';
665  }
666  buffer << *start_of_text;
667  start_of_text++;
668  }
669  buffer << ") \"" << endl;
670 // buffer << ") Tj" << endl;
671  // endtext(); // not done here to avoid ET BT, done on demand
672 }
673 
674 void drvPDF::show_path()
675 {
676  // add_to_page(); // is done in drvbase !!
677  endtext(); // close text if open
678  const char *setrgbcolor = nullptr;
679  const char *drawingop = nullptr;
680  switch (currentShowType()) {
681  case drvbase::stroke:
682  // it's a stroke
683  drawingop = "S";
684  setrgbcolor = "RG";
685  break;
686  case drvbase::fill:
687  drawingop = "f";
688  setrgbcolor = "rg";
689  break;
690  case drvbase::eofill:
691  drawingop = "f*";
692  setrgbcolor = "rg";
693  break;
694  default:
695  // cannot happen
696  errf << "unexpected ShowType " << (int) currentShowType() << endl;
697  exit(1);
698  break;
699  }
700 // buffer.precision(3);
701 // buffer.setf(ios::fixed);
702 // buffer.width(0); // to force minimal width
703 // buffer.unsetf(ios::showpoint);
704 
705  if (Verbose()) {
706  buffer << "% path " << currentNr() << endl;
707  }
708  buffer << RND3(currentR()) << " " << RND3(currentG()) << " " <<
709  RND3(currentB()) << " " << setrgbcolor << endl;
710  buffer << currentLineWidth() << " w" << endl;
711  buffer << currentLineCap() << " J" << endl;
712  buffer << currentLineJoin() << " j" << endl;
713  buffer << dashPattern() << " d" << endl;
714  print_coords();
715  buffer << drawingop << endl;
716 }
717 
718 static DriverDescriptionT < drvPDF > D_pdf("pdf", "Adobe's Portable Document Format", "","pdf", true, // if backend supports subpaths, else 0
719  // if subpaths are supported, the backend must deal with
720  // sequences of the following form
721  // moveto (start of subpath)
722  // lineto (a line segment)
723  // lineto
724  // moveto (start of a new subpath)
725  // lineto (a line segment)
726  // lineto
727  //
728  // If this argument is set to 0 each subpath is drawn
729  // individually which might not necessarily represent
730  // the original drawing.
731  1, // if backend supports curves, else 0
732  false, // if backend supports elements with fill and edges
733  true, // if backend supports text, else 0
734  DriverDescription::memoryeps, // no support for PNG file images
735  DriverDescription::normalopen, true, // if format supports multiple pages in one file
736  false /*clipping */
737  );
cp
Definition: action.c:1035
const char * fontname
Definition: afm2pl.c:186
#define width(a)
Definition: aptex-macros.h:198
#define height(a)
Definition: aptex-macros.h:200
const char * c_str() const
Definition: miscutil.h:127
ofstream & asOutput()
Definition: miscutil.cpp:476
ifstream & asInput()
Definition: miscutil.cpp:485
virtual const Point & getPoint(unsigned int i) const =0
virtual Dtype getType() const =0
Definition: drvpdf.h:29
int bb_urx
Definition: drvpdf.h:55
unsigned int currentobject
Definition: drvpdf.h:49
void show_text(const TextInfo &textinfo) override
Definition: drvpdf.cpp:597
void endobject()
Definition: drvpdf.cpp:91
const char *const * knownFontNames() const override
Definition: drvpdf.cpp:74
void adjustbbox(float x, float y)
Definition: drvpdf.cpp:105
void starttext()
Definition: drvpdf.cpp:114
void endtext()
Definition: drvpdf.cpp:121
unsigned int newobject()
Definition: drvpdf.cpp:79
int bb_llx
Definition: drvpdf.h:55
const char * encodingName
Definition: drvpdf.h:52
void print_coords()
Definition: drvpdf.cpp:488
unsigned int pagenr
Definition: drvpdf.h:50
int bb_lly
Definition: drvpdf.h:55
bool inTextMode
Definition: drvpdf.h:51
int bb_ury
Definition: drvpdf.h:55
TempFile tempFile
Definition: drvpdf.h:53
~drvPDF() override
Definition: drvpdf.cpp:167
std::streampos startPosition[maxobjects]
Definition: drvpdf.h:48
const basedrawingelement & pathElement(unsigned int index) const
Definition: drvbase.cpp:407
const char ** d_argv
Definition: drvbase.h:367
showtype currentShowType() const
Definition: drvbase.h:633
float currentDeviceHeight
Definition: drvbase.h:369
unsigned int d_argc
Definition: drvbase.h:366
unsigned int currentNr() const
Definition: drvbase.h:642
static bool Verbose()
Definition: drvbase.cpp:1707
float currentR() const
Definition: drvbase.h:651
ostream & errf
Definition: drvbase.h:360
float currentB() const
Definition: drvbase.h:653
float currentDeviceWidth
Definition: drvbase.h:370
float currentG() const
Definition: drvbase.h:652
const char * dashPattern() const
Definition: drvbase.h:650
const char * defaultFontName
Definition: drvbase.h:376
unsigned int currentLineCap() const
Definition: drvbase.h:635
static RSString DateString()
Definition: drvbase.cpp:283
ostream & outf
Definition: drvbase.h:359
unsigned int currentLineJoin() const
Definition: drvbase.h:636
float x_offset
Definition: drvbase.h:371
virtual void open_page()=0
float currentLineWidth() const
Definition: drvbase.h:641
@ fill
Definition: drvbase.h:162
@ stroke
Definition: drvbase.h:162
@ eofill
Definition: drvbase.h:162
virtual void close_page()=0
virtual void show_path()=0
float y_offset
Definition: drvbase.h:372
unsigned int & numberOfElementsInPath()
Definition: drvbase.h:513
#define n
Definition: t4ht.c:1290
#define b
Definition: jpegint.h:372
#define USESTD
Definition: cppcomp.h:199
@ closepath
Definition: cscommands.h:4
@ lineto
Definition: drvbase.h:749
@ moveto
Definition: drvbase.h:749
@ curveto
Definition: drvbase.h:749
#define constructBase
Definition: drvbase.h:884
#define derivedConstructor(Class)
Definition: drvbase.h:871
static DriverDescriptionT< drvPDF > D_pdf("pdf", "Adobe's Portable Document Format", "","pdf", true, 1, false, true, DriverDescription::memoryeps, DriverDescription::normalopen, true, false)
T Min(T a, T b)
Definition: drvpdf.cpp:101
static const char *const stdEncoding
Definition: drvpdf.cpp:132
static const char * PDFFonts[]
Definition: drvpdf.cpp:54
static float RND3(const float f)
Definition: drvpdf.cpp:49
static std::streampos newlinebytes
Definition: drvpdf.cpp:130
static constexpr float rnd(const float f, const float roundnumber)
Definition: drvpdf.cpp:44
const unsigned int numberOfFonts
Definition: drvpdf.cpp:72
const int largeint
Definition: drvpdf.cpp:134
static int getSubStringFontNumber(const char *const fontname)
Definition: drvpdf.cpp:577
static int getFontNumber(const char *const fontname)
Definition: drvpdf.cpp:563
T Max(T a, T b)
Definition: drvpdf.cpp:96
const unsigned int maxobjects
Definition: drvpdf.h:27
double cos()
double sin()
printlisttype * currentpage
Definition: dvi2tty.c:95
int strcmp()
Definition: coll.cpp:143
long pagenr
Definition: dvistuff.c:172
#define T
Definition: fmt.h:20
static void copy_file(char *s, char *d)
Definition: fmtutil.c:89
static void
Definition: fpif.c:118
mpz_t * f
Definition: gen-fib.c:34
#define a(n)
Definition: gpos-common.c:148
assert(pcxLoadImage24((char *)((void *) 0), fp, pinfo, hdr))
small capitals from c petite p
Definition: afcover.h:72
small capitals from c petite p scientific i
Definition: afcover.h:80
void exit()
#define false
Definition: ftrandom.c:52
kerning y
Definition: ttdriver.c:212
static struct res_cache resources[(sizeof(pdf_resource_categories)/sizeof(pdf_resource_categories[0]))]
Definition: pdfresource.c:92
static pdf_obj * catalog
Definition: pdfdoc.c:47
#define unused
Definition: main.c:29
long time_t
Definition: types.h:18
void abort()
int strncmp()
static char * start_of_text
Definition: lexyy.cpp:1541
struct tm * localtime(const time_t *const timep)
Definition: localtime.c:1332
static struct tm tm
Definition: localtime.c:216
float x
Definition: cordic.py:15
#define index(s, c)
Definition: plain2.h:351
time_t time()
Definition: utils.c:300
RSString currentFontName
Definition: drvbase.h:176
RSString thetext
Definition: drvbase.h:173
float currentFontSize
Definition: drvbase.h:181
float y() const
Definition: drvbase.h:168
float x() const
Definition: drvbase.h:167
float currentFontAngle
Definition: drvbase.h:182
Definition: pbmfont.h:11
Definition: mendex.h:20
Definition: pdfdoc.c:79
Definition: dvips.h:235
int j
Definition: t4ht.c:1589
*job_name strlen((char *) job_name) - 4)
return() int(((double) *(font_tbl[cur_fnt].wtbl+(int)(*(font_tbl[cur_fnt].char_wi+(int)(ch - font_tbl[cur_fnt].char_f)% 256)))/(double)(1L<< 20)) *(double) font_tbl[cur_fnt].scale)
static size_t longest
Definition: zdump.c:227