1 #ifndef __drvbase_h
2 #define __drvbase_h
3 /*
4 drvbase.h : This file is part of pstoedit Base class for all specific
5 driver classes/backends. All virtual functions have to be implemented by
6 the specific driver class. See drvSAMPL.cpp
7
8 Copyright (C) 1993 - 2000 Wolfgang Glunz, wglunz@geocities.com
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24 */
25 /*
26 // ============================================================================
27 //
28 // = LIBRARY
29 // pstoedit
30 //
31 // = FILENAME
32 // drvbase.h
33 //
34 // = RCSID
35 // $Id$
36 */
37
38
39 #include "cppcomp.h"
40
41
42 #include I_fstream
43 #include I_stdio
44 #include I_stdlib
45 #include I_string_h
46 USESTD
47
48 #include <assert.h>
49 #include "miscutil.h"
50
51
52 // for compatibility checking
53 static const unsigned int drvbaseVersion = 106;
54 // 101 introduced the driverOK function
55 // 102 introduced the font optimization (lasttextinfo_)
56 // 103 introduced the -ssp support and the virtual pathscanbemerged
57 // 104 introduced the fontmatrix handling
58 // 105 introduced the miterlimit Info and outputPageSize
59 // 106 introduced some new utility functions for transformation (*_trans*)
60
61 const unsigned int maxFontNamesLength = 1000;
62 const unsigned int maxpoints = 200000; // twice the maximal number of points in a path
63 const unsigned int maxElements = maxpoints/2;
64 const unsigned int maxsegments = maxpoints/2;// at least half of maxpoints (if we only have segments with one point)
65
66
67 struct Point
68 {
69 public:
PointPoint70 Point(float x, float y) : x_(x),y_(y) {}
PointPoint71 Point() : x_(0.0f), y_(0.0f) {}; // for arrays
72 float x_;
73 float y_;
74 friend bool operator==(const Point & p1, const Point & p2) { return (p1.x_ == p2.x_) && (p1.y_ == p2.y_); }
75 Point transform(const float matrix[6]) const;
76 private:
77 };
78
79 // image needs Point !
80 #include "image.h"
81
82 static const char emptyDashPattern[] = "[ ] 0.0";
83
84 class basedrawingelement ; // forward
85 class DriverDescription ; // forward
86 class drvbase
87 // = TITLE
88 // Base class for backends to pstoedit
89 //
90 // = CLASS TYPE
91 // Abstract
92 //
93 // = AUDIENCE
94 // Developers of new backends
95 //
96 // = DESCRIPTION
97 // Abstract base class for backends to pstoedit.
98 // This class defines the virtual functions that every backend has
99 // to implement and some functions that are common to all backends
100 //
101 {
102 friend class sub_path; // needs PathInfo
103 friend class sub_path_list;
104 public:
105 // = PUBLIC TYPES
106
107 enum showtype { stroke, fill, eofill };
108 enum linetype { solid=0, dashed, dotted, dashdot, dashdotdot }; // corresponding to the CGM patterns
109
110 struct TextInfo {
111 float x;
112 float y;
113 float FontMatrix[6];
114 float x_end; // pen coordinates after show in PostScript
115 float y_end; //
116 RSString thetext;
117 bool is_non_standard_font;
118 RSString currentFontName;
119 RSString currentFontFamilyName;
120 RSString currentFontFullName;
121 RSString currentFontWeight;
122 float currentFontSize;
123 float currentFontAngle;
124 float currentR; // Colors
125 float currentG;
126 float currentB;
127 float cx; // next five items correspond to the
128 float cy; // params for the awidthshow operator
129 int Char; // of PostScript
130 float ax;
131 float ay;
132 bool mappedtoIsoLatin1;
samefontTextInfo133 bool samefont(const TextInfo& cmp) const {
134 return ( currentFontName == cmp.currentFontName ) &&
135 // ( currentFontFamilyName == cmp.currentFontFamilyName ) &&
136 // ( currentFontFullName == cmp.currentFontFullName ) &&
137 ( currentFontWeight == cmp.currentFontWeight ) &&
138 ( currentFontSize == cmp.currentFontSize ) &&
139 ( currentFontAngle == cmp.currentFontAngle ) ;
140 }
141
samecolorTextInfo142 bool samecolor(const TextInfo& cmp) const {
143 return ( currentR == cmp.currentR ) &&
144 ( currentG == cmp.currentG ) &&
145 ( currentB == cmp.currentB );
146 }
TextInfoTextInfo147 TextInfo() :
148 x(0.0f),
149 y(0.0f),
150 x_end(0.0f),
151 y_end(0.0f),
152 thetext(0),
153 is_non_standard_font(false),
154 currentFontSize(10.0f),
155 currentFontAngle(0.0f),
156 currentR(0.0f),
157 currentG(0.0f),
158 currentB(0.0f),
159 cx(0.0f),
160 cy(0.0f),
161 Char(32), // 32 means space
162 ax(0.0f),
163 ay(0.0f),
164 mappedtoIsoLatin1(true) {
165 for (int i = 0; i < 6 ; i++ ) FontMatrix[i] = 0.0f;
166 }
~TextInfoTextInfo167 ~TextInfo() { }
168 private:
169 // declared but not defined
170 // const TextInfo & operator = (const TextInfo &); // default is ok
171 // TextInfo(const TextInfo &); // default is ok
172 };
173
174 private:
175 // = PRIVATE TYPES
176
177 protected:
178 // = PROTECTED TYPES
179
180 struct PathInfo {
181 showtype currentShowType;
182 linetype currentLineType;
183 unsigned int currentLineCap;
184 unsigned int currentLineJoin;
185 float currentMiterLimit;
186 unsigned int nr;
187 basedrawingelement * * path; // a path is an array of pointers to basedrawingelements
188 bool isPolygon; // whether current path was closed via closepath or not
189 unsigned int numberOfElementsInPath;
190 unsigned int subpathoffset; // normally 0, but if subpathes are simulated
191 // then this is set to the begin of the current subpath
192 // before show_path is executed
193 float currentLineWidth;
194 float edgeR; // edge colors
195 float edgeG;
196 float edgeB;
197 float fillR; // fill colors
198 float fillG;
199 float fillB;
200 bool pathWasMerged; // true, if this path is a result of a merge operation
201 RSString dashPattern; // just the dump of currentdash as string
PathInfoPathInfo202 PathInfo() :
203 currentShowType(drvbase::stroke),
204 currentLineType(drvbase::solid),
205 currentLineCap(0),
206 currentLineJoin(0),
207 currentMiterLimit(10.0f),
208 nr(0),
209 path(0),
210 isPolygon(0),
211 numberOfElementsInPath(0),
212 subpathoffset(0),
213 currentLineWidth(0.0f),
214 edgeR(0.0f),
215 edgeG(0.0f),
216 edgeB(0.0f),
217 fillR(0.0f),
218 fillG(0.0f),
219 fillB(0.0f),
220 pathWasMerged(false),
221 dashPattern(emptyDashPattern)
222 {
223 path = new basedrawingelement *[maxElements];
224 }
~PathInfoPathInfo225 ~PathInfo() {
226 // the path content is deleted by clear
227 clear();
228 delete [] path;
229 }
230 void clear();
231 void copyInfo(const PathInfo & p);
232 // copies the whole path state except the path array
233 void rearrange();
234 // rearrange subpaths for backends which don't support them
235 private:
236 // Inhibitors (declared, but not defined)
237 const PathInfo& operator=(const PathInfo&);
238 PathInfo(const PathInfo &);
239 };
240
241 public:
242 // = PUBLIC DATA
243
244 const DriverDescription * Pdriverdesc; // pointer to the derived class' driverdescription
245 bool simulateSubPaths; // simulate sub paths for backend that don't support it directly
246 Image imageInfo;
247
248 static FontMapper theFontMapper;
249 static bool verbose;
250
251 protected:
252 // = PROTECTED DATA
253
254 ostream & outf; // the output stream
255 ostream & errf; // the error stream
256 const RSString inFileName; // full name of input file
257 const RSString outFileName; // full name of output file
258 char* outDirName; // output path with trailing slash or backslash
259 char* outBaseName; // just the basename (no path, no suffix)
260 unsigned int d_argc;
261 char ** d_argv;
262 float scale;
263 RSString outputPageSize; // set via -pagesize option
264 float currentDeviceHeight; // normally 792 pt; used for flipping y values.
265 float currentDeviceWidth;
266 float x_offset;
267 float y_offset;
268 unsigned int currentPageNumber;
269 bool domerge;
270 const char * defaultFontName; // name of default font
271 bool ctorOK; // indicated Constructor failure
272 // returned via driverOK() function
273
274
275 private:
276 // = PRIVATE DATA
277
278 bool page_empty; // indicates whether the current page is empty or not
279 char * driveroptions; // string containing options for backend
280 PathInfo p1,p2;
281 PathInfo * currentPath; // for filling from lexer
282 protected: // for drvrtf
283 PathInfo * outputPath; // for output driver
284 private:
285 PathInfo * lastPath; // for merging
286 TextInfo textInfo_;
287 TextInfo lasttextInfo_; // for saving font settings
288
289
290 public:
291 // = PUBLIC METHODS
292
293 // = CONSTRUCTION, DESTRUCTION AND COPYING
294
295 drvbase(
296 const char * driverOptions_p,
297 ostream & theoutStream,
298 ostream & theerrStream,
299 const char* nameOfInputFile_p,
300 const char* nameOfOutputFile_p,
301 const float scalefactor,
302 const RSString & pagesize,
303 const DriverDescription * Pdriverdesc_p
304 ); // constructor
305 virtual ~drvbase(); // destructor
306
307 // = BACKEND GENERIC FUNCTIONS
308 // These functions are not backend specific and shouldn't have to be
309 // changed for new backends
310
311 void startup(bool merge);
312
313 virtual void finalize();
314 // needed because base destructor will be called after derived destructor
315 // and thus the base destructor could no longer use the backend.
316 // virtual because so we can achieve that it is called in the
317 // context (DLL) of the real backend. Otherwise it would be called
318 // in the context of the main program which causes memory problems
319 // under windows since the plugins are NOT and extension DLL
320 //
321
setdefaultFontName(const char * n)322 void setdefaultFontName(const char * n) {defaultFontName = n;}
323
setCurrentDeviceHeight(const float deviceHeight)324 void setCurrentDeviceHeight(const float deviceHeight)
325 { currentDeviceHeight = deviceHeight; }
326
setCurrentDeviceWidth(const float deviceWidth)327 void setCurrentDeviceWidth(const float deviceWidth)
328 { currentDeviceWidth = deviceWidth; }
329
getScale()330 float getScale() const { return scale; }
331
l_transX(float x)332 inline long l_transX (float x) const {
333 return (long)((x + x_offset) + .5); // rounded long
334 }
335
l_transY(float y)336 inline long l_transY (float y) const {
337 return (long)((-1.0f*y + y_offset) + .5); // rounded long, mirrored
338 }
339
f_transX(float x)340 inline float f_transX (float x) const {
341 return (x + x_offset) ;
342 }
343
f_transY(float y)344 inline float f_transY (float y) const {
345 return (-1.0f*y + y_offset) ;
346 }
347
getPageSize()348 const RSString & getPageSize() const { return outputPageSize; }
349
fontchanged()350 bool fontchanged() const { return ! textInfo_.samefont(lasttextInfo_); }
textcolorchanged()351 bool textcolorchanged() const { return ! textInfo_.samecolor(lasttextInfo_); }
352
setRGB(const float R,const float G,const float B)353 void setRGB(const float R,const float G, const float B)
354 {
355 if ( ( R > 1.0 ) || ( G > 1.0 ) || ( B > 1.0 ) ||
356 ( R < 0.0 ) || ( G < 0.0 ) || ( B < 0.0 ) ) {
357 errf << "Warning: color value out of range (0..1). Color change ignored." << R << ' ' << G << ' ' << B << endl;
358 } else {
359 textInfo_.currentR = R ; textInfo_.currentG = G; textInfo_.currentB = B;
360 currentPath->edgeR = R ; currentPath->edgeG = G; currentPath->edgeB = B;
361 currentPath->fillR = R ; currentPath->fillG = G; currentPath->fillB = B;
362 }
363 }
364
365 void showpage();
366
367
368 // = DRAWING RELATED METHODS
369
370 void addtopath(basedrawingelement * newelement);
371
numberOfElementsInPath()372 unsigned int &numberOfElementsInPath() { return outputPath->numberOfElementsInPath; }
numberOfElementsInPath()373 unsigned int numberOfElementsInPath() const { return outputPath->numberOfElementsInPath; }
374
375 const basedrawingelement & pathElement(unsigned int index) const;
376
setCurrentLineType(const linetype how)377 void setCurrentLineType(const linetype how)
378 { currentPath->currentLineType = how; }
379
setCurrentLineWidth(const float linewidth)380 void setCurrentLineWidth(const float linewidth)
381 { currentPath->currentLineWidth = linewidth; }
382
setDash(const char * const dash)383 void setDash(const char * const dash)
384 { currentPath->dashPattern.copy(dash); }
385
setIsPolygon(bool what)386 void setIsPolygon(bool what) { currentPath->isPolygon=what; } // whether current path was closed via closepath or not
387
setPathNumber(unsigned int nr)388 void setPathNumber(unsigned int nr) { currentPath->nr=nr; }
389
setCurrentLineJoin(const unsigned int joinType)390 void setCurrentLineJoin(const unsigned int joinType)
391 { currentPath->currentLineJoin = joinType; }
392
setCurrentMiterLimit(const float miterLimit)393 void setCurrentMiterLimit(const float miterLimit)
394 { currentPath->currentMiterLimit = miterLimit; }
395
setCurrentLineCap(const unsigned int capType)396 void setCurrentLineCap(const unsigned int capType)
397 { currentPath->currentLineCap = capType; }
398
setCurrentShowType(const showtype how)399 void setCurrentShowType(const showtype how)
400 { currentPath->currentShowType = how; }
401
402 void dumpPath(); // shows current path
403
404 void dumpRearrangedPathes(); // show the current subpathes after calling rearrange
405
406 unsigned int nrOfSubpaths() const;
407
408 void dumpImage(); // shows current image
409
410 // = TEXT RELATED METHODS
411
412 void setCurrentWidthParams( const float ax,
413 const float ay,
414 const int Char,
415 const float cx,
416 const float cy,
417 const float x_end = 0.0f,
418 const float y_end = 0.0f);
419
setMappedtoisolatin1(const bool mapped)420 void setMappedtoisolatin1 ( const bool mapped )
421 { textInfo_.mappedtoIsoLatin1 = mapped; }
422
423 void setCurrentFontName(const char *const Name,bool is_non_standard_font);
424
425 void setCurrentFontFamilyName(const char *const Name);
426
427 void setCurrentFontFullName(const char *const Name);
428
429 void setCurrentFontWeight(const char *const Name);
430
431 void setCurrentFontSize(const float Size);
432
433 void setCurrentFontAngle(float value);
434
getCurrentFontMatrix()435 float * getCurrentFontMatrix() { return textInfo_.FontMatrix; }
436
437 void dumpText(const char *const thetext,
438 const float x,
439 const float y);
440
441
442
443 // = BACKEND SPECIFIC FUNCTIONS
444
445 // If a backend only deals with a special set of font names
446 // the following function must return a 0 terminated list
447 // of font names.
knownFontNames()448 virtual const char * const * knownFontNames() const { return 0; }
449
450 // The next functions are virtual with a default empty implementation
451
show_image(const Image & imageinfo)452 virtual void show_image(const Image & imageinfo) {
453 cerr << "show_image called, although backend does not support images" << endl;
454 unused(&imageinfo);
455 }
456
457 // if during construction something may go wrong, a backend can
458 // overwrite this function and return false in case of an error.
459 // or it can just set the ctorOK to false.
driverOK()460 virtual bool driverOK() const { return ctorOK; } // some
461
462 protected:
463 // = PROTECTED METHODS
464
currentShowType()465 showtype currentShowType() const { return outputPath->currentShowType; }
currentLineType()466 linetype currentLineType() const { return outputPath->currentLineType; }
currentLineCap()467 unsigned int currentLineCap() const { return outputPath->currentLineCap; }
currentLineJoin()468 unsigned int currentLineJoin() const { return outputPath->currentLineJoin; }
currentMiterLimit()469 float currentMiterLimit() const { return outputPath->currentMiterLimit; }
isPolygon()470 bool isPolygon() const { return outputPath->isPolygon;} // whether current path was closed via closepath or not
471 virtual bool pathsCanBeMerged (const PathInfo & p1, const PathInfo & p2) const;
pathWasMerged()472 bool pathWasMerged() const { return outputPath->pathWasMerged; }
currentLineWidth()473 float currentLineWidth() const { return outputPath->currentLineWidth; }
currentNr()474 unsigned int currentNr() const { return outputPath->nr; }
edgeR()475 float edgeR() const { return outputPath->edgeR; } // edge colors
edgeG()476 float edgeG() const { return outputPath->edgeG; }
edgeB()477 float edgeB() const { return outputPath->edgeB; }
fillR()478 float fillR() const { return outputPath->fillR; } // fill colors
fillG()479 float fillG() const { return outputPath->fillG; }
fillB()480 float fillB() const { return outputPath->fillB; }
dashPattern()481 const char * dashPattern() const { return outputPath->dashPattern.value(); }
currentR()482 float currentR() const { return outputPath->fillR; } // backends that don't support merging
currentG()483 float currentG() const { return outputPath->fillG; } // don't need to differentiate and
currentB()484 float currentB() const { return outputPath->fillB; } // can use these functions.
485
486 private:
487 // = PRIVATE METHODS
488
489 void guess_linetype();
490
491 bool is_a_rectangle() const;
492
493 void add_to_page();
494
495
496 // = BACKEND SPECIFIC FUNCTIONS
497
498 // These next functions are pure virtual and thus need to be implemented for every new backend.
499
500 virtual void close_page() = 0;
501 // writes a trailer whenever a page is finished (triggered by showpage)
502
503 virtual void open_page() = 0;
504 // writes a page header whenever a new page is needed
505
506 virtual void show_text(const TextInfo & textinfo) = 0;
507
508 virtual void show_path() = 0;
509
510 virtual void show_rectangle(
511 const float llx,
512 const float lly,
513 const float urx,
514 const float ury) = 0;
515 // writes a rectangle at points (llx,lly) (urx,ury)
516
517
518 // = INHIBITORS (declared, but not defined)
519 drvbase(); // avoid default ctor
520 drvbase(const drvbase &);
521 drvbase & operator=(const drvbase&);
522
523 };
524
525 class DashPattern {
526 public:
527 DashPattern(const char * patternAsSetDashString);
528 ~DashPattern();
529 const RSString dashString;
530 int nrOfEntries;
531 float * numbers;
532 float offset;
533
534 NOCOPYANDASSIGN(DashPattern)
535 };
536
537 typedef const char * (*makeColorNameType)(float r, float g, float b);
538 const unsigned int maxcolors = 1000 ; // 1000 colors maximum
539 class ColorTable
540 {
541 public:
542 ColorTable(const char * const * defaultColors,
543 const unsigned int numberOfDefaultColors,
544 makeColorNameType makeColorName);
545 ~ColorTable();
546 unsigned int getColorIndex(float r, float g, float b);
547 const char * const getColorString(float r, float g, float b);
548 bool isKnownColor(float r, float g, float b) const;
549 const char * const getColorString(unsigned int index) const;
550
551 private:
552 const char * const * const defaultColors_;
553 const unsigned int numberOfDefaultColors_;
554 char * newColors[maxcolors];
555 const makeColorNameType makeColorName_ ;
556
557 NOCOPYANDASSIGN(ColorTable)
558 };
559
560
561
562 #ifdef __TCPLUSPLUS__
563 // turbo C++ has problems with enum for template parameters
564 typedef unsigned int Dtype;
565 const Dtype moveto = 1;
566 const Dtype lineto = 2;
567 const Dtype closepath = 3;
568 const Dtype curveto = 4;
569 #else
570 enum Dtype {moveto, lineto, closepath, curveto};
571 #endif
572 // closepath is only generated if backend supportes subpathes
573 // curveto is only generated if backend supportes it
574
575
576 class basedrawingelement
577 {
578 public:
579 // basedrawingelement(unsigned int size_p) /*: size(size_p) */ {}
580 virtual const Point &getPoint(unsigned int i) const = 0;
581 virtual Dtype getType() const = 0;
582 friend ostream & operator<<(ostream & out,const basedrawingelement &elem);
583 friend bool operator==(const basedrawingelement & bd1, const basedrawingelement & bd2);
584 virtual unsigned int getNrOfPoints() const = 0;
585 virtual basedrawingelement* clone() const = 0; // make a copy
586 private:
587 // const unsigned int size;
588 };
589
590
copyPoints(unsigned int nr,const Point src[],Point target[])591 inline void copyPoints(unsigned int nr, const Point src[], Point target[])
592 {
593 // needed because CenterLine cannot inline for loops
594 for (unsigned int i = 0 ; i < nr ; i++ ) target[i] = src[i];
595 }
596
597 template <unsigned int nr, Dtype curtype>
598 class drawingelement : public basedrawingelement
599 {
600 public:
601 // CenterLine !!!!
602 // "drvbase.h", line 455: sorry, not implemented: cannot expand inline function drawingelement
603 // <1 , 0 >::drawingelement__pt__19_XCUiL11XC5DtypeL10(Point*) with for statement in inline
604
605 drawingelement(float x1 = 0.0 ,float y1 = 0.0 , float x2 = 0.0, float y2 = 0.0, float x3 = 0.0, float y3 = 0.0)
606 // : basedrawingelement(nr)
607 {
608 #if defined (__GNUG__) || defined (_MSC_VER) && _MSC_VER >= 1100
609 const Point p[] = {Point(x1,y1),Point(x2,y2),Point(x3,y3)};
610 copyPoints(nr,p,points);
611 #else
612 // Turbo C++ hangs if the other solution is used.
613 // and the HP CC compiler doesn't like it either
614 // so use this for all compilers besides GNU and MS VC++
615 // This, however, is somewhat slower than the solution above
616 Point * p = new Point[3];
617 p[0] = Point(x1,y1);
618 p[1] = Point(x2,y2);
619 p[2] = Point(x3,y3);
620 copyPoints(nr,p,points);
621 delete [] p;
622 #endif
623
624 }
625
drawingelement(const Point p[])626 drawingelement(const Point p[])
627 //: basedrawingelement(nr)
628 {
629 // for (unsigned int i = 0 ; i < nr ; i++ ) points[i] = p[i];
630 copyPoints(nr,p,points);
631 }
drawingelement(const drawingelement<nr,curtype> & orig)632 drawingelement(const drawingelement<nr,curtype> & orig)
633 //: basedrawingelement(nr)
634 { // copy ctor
635 if (orig.getType() != curtype ) {
636 cerr << "illegal usage of copy ctor of drawingelement" << endl;
637 exit(1);
638 } else {
639 copyPoints(nr,orig.points,points);
640 }
641 }
clone()642 virtual basedrawingelement* clone() const {
643 return new drawingelement<nr,curtype>(*this);
644 }
getPoint(unsigned int i)645 const Point &getPoint(unsigned int i) const {
646 // assert( (i+1) < (nr+1) );
647 return points[i];
648 }
getType()649 virtual Dtype getType() const { return (Dtype) curtype; }
650 // This cast (Dtype) is necessary
651 // to eliminate a compiler warning
652 // from the SparcCompiler 4.1.
653 // although curtype is of type Dtype
getNrOfPoints()654 virtual unsigned int getNrOfPoints() const { return nr; }
655 private:
656 Point points[nr > 0 ? nr : 1];
657 };
658
659
660 // CenterLine !!!!
661 // "drvbase.h", line 477: sorry, not implemented: cannot expand inline function
662 // drawingelement <3 , 3 >::drawingelement__pt__19_XCUiL13XC5DtypeL13(Point*) with for statement in inline
663
664 #if 0
665 template <unsigned int nr, Dtype curtype>
666 inline drawingelement<nr,curtype>::drawingelement(Point p[])
667 : basedrawingelement(nr)
668 {
669 for (unsigned int i = 0 ; i < nr ; i++ ) points[i] = p[i];
670 }
671 #endif
672
673 typedef drawingelement<(unsigned int) 1,moveto> Moveto;
674 typedef drawingelement<(unsigned int) 1,lineto> Lineto;
675 typedef drawingelement<(unsigned int) 0,closepath> Closepath;
676 typedef drawingelement<(unsigned int) 3,curveto> Curveto;
677
678
679 #define derivedConstructor(Class) \
680 Class(const char * driveroptions_p, \
681 ostream & theoutStream, \
682 ostream & theerrStream, \
683 const char* nameOfInputFile_p, \
684 const char* nameOfOutputFile_p, \
685 const float scalefactor_p, \
686 const RSString & pagesize, \
687 const DriverDescription * descptr)
688
689 #define constructBase drvbase(driveroptions_p,theoutStream,theerrStream,nameOfInputFile_p,nameOfOutputFile_p,scalefactor_p,pagesize,descptr)
690
691
692 class DescriptionRegister
693 {
694 enum {maxelems = 100 };
695 public:
DescriptionRegister()696 DescriptionRegister() {
697 ind = 0;
698 for (int i = 0; i < maxelems; i++) rp[i] = 0;
699 // cout << " R constructed " << (void *) this << endl;
700 }
~DescriptionRegister()701 ~DescriptionRegister() {
702 // cout << " R destructed " << (void *) this << endl;
703 }
704
705 static DescriptionRegister& getInstance();
706
707 void registerDriver(DriverDescription* xp);
708 void mergeRegister(ostream & out,const DescriptionRegister & src,const char * filename);
709 void explainformats(ostream & out) const;
710 const DriverDescription * getdriverdesc(const char * drivername) const;
711
712 DriverDescription* rp[maxelems];
713
nrOfDescriptions()714 int nrOfDescriptions() const { return ind; }
715 private:
716
717 int ind;
718
719 NOCOPYANDASSIGN(DescriptionRegister)
720 };
721
722 extern DescriptionRegister* globalRp;
723
724 //extern __declspec ( dllexport) "C" {
725 //not needed // DescriptionRegister* getglobalRp();
726 typedef DescriptionRegister* (*getglobalRpFuncPtr)();
727 //}
728
729 //class Rinit
730 //{
731 //public:
732 // Rinit() { if (!globalRp) {globalRp = new DescriptionRegister; ref = 1 ; } else { ref++;} }
733 // ~Rinit() { ref--; if (ref == 0) delete globalRp; }
734 //
735 //private:
736 // static int ref;
737 //};
738
739 //static Rinit Rinit_var;
740
741 //now in drvdesc.h typedef bool (*checkfuncptr)();
742 // static bool nocheck() { return true; }
743
744 typedef bool (*checkfuncptr)(void);
745 class drvbase;
746
747 class DriverDescription {
748 public:
749 enum opentype {noopen, normalopen, binaryopen};
750 DriverDescription(const char * s_name,
751 const char * expl,
752 const char * suffix_p,
753 const bool backendSupportsSubPathes_p,
754 const bool backendSupportsCurveto_p,
755 const bool backendSupportsMerging_p, // merge a separate outline and filling of a polygon -> 1. element
756 const bool backendSupportsText_p,
757 const bool backendSupportsImages_p, // supports bitmap images
758 const opentype backendFileOpenType_p,
759 const bool backendSupportsMultiplePages_p,
760 checkfuncptr checkfunc_p = 0);
~DriverDescription()761 virtual ~DriverDescription() {}
762
763 virtual drvbase * CreateBackend (const char * driveroptions_P,
764 ostream & theoutStream,
765 ostream & theerrStream,
766 const char* nameOfInputFile,
767 const char* nameOfOutputFile,
768 const float scalefactor,
769 const RSString & pagesize
770 ) const;
getdrvbaseVersion()771 virtual unsigned int getdrvbaseVersion() const { return 0; } // this is only needed for the driverless backends (ps/dump/gs)
772
773 // Data members
774 const char * const symbolicname;
775 const char * const explanation;
776 const char * const suffix;
777 const char * const additionalInfo;
778 const bool backendSupportsSubPathes;
779 const bool backendSupportsCurveto;
780 const bool backendSupportsMerging; // merge a separate outline and filling of a polygon -> 1. element
781 const bool backendSupportsText;
782 const bool backendSupportsImages; // supports bitmap images
783 const opentype backendFileOpenType;
784 const bool backendSupportsMultiplePages;
785 RSString filename; // where this driver is loaded from
786 const checkfuncptr checkfunc;
787
788 NOCOPYANDASSIGN(DriverDescription)
789 };
790
791 class DescriptionRegister;
792
793 template <class T>
794 class DriverDescriptionT : public DriverDescription {
795 public:
796 DriverDescriptionT(const char * s_name,
797 const char * expl,
798 const char * suffix_p,
799 const bool backendSupportsSubPathes_p,
800 const bool backendSupportsCurveto_p,
801 const bool backendSupportsMerging_p, // merge a separate outline and filling of a polygon -> 1. element
802 const bool backendSupportsText_p,
803 const bool backendSupportsImages_p, // supports bitmap images
804 const DriverDescription::opentype backendFileOpenType_p,
805 const bool backendSupportsMultiplePages_p,
806 checkfuncptr checkfunc_p = 0 ):
DriverDescription(s_name,expl,suffix_p,backendSupportsSubPathes_p,backendSupportsCurveto_p,backendSupportsMerging_p,backendSupportsText_p,backendSupportsImages_p,backendFileOpenType_p,backendSupportsMultiplePages_p,checkfunc_p)807 DriverDescription(
808 s_name,
809 expl,
810 suffix_p,
811 backendSupportsSubPathes_p,
812 backendSupportsCurveto_p,
813 backendSupportsMerging_p,
814 backendSupportsText_p,
815 backendSupportsImages_p,
816 backendFileOpenType_p,
817 backendSupportsMultiplePages_p,
818 checkfunc_p
819 )
820 {}
CreateBackend(const char * driveroptions_P,ostream & theoutStream,ostream & theerrStream,const char * nameOfInputFile,const char * nameOfOutputFile,const float scalefactor,const RSString & pagesize)821 drvbase * CreateBackend (
822 const char * driveroptions_P,
823 ostream & theoutStream,
824 ostream & theerrStream,
825 const char* nameOfInputFile,
826 const char* nameOfOutputFile,
827 const float scalefactor,
828 const RSString & pagesize
829 ) const
830 {
831 return new T(driveroptions_P, theoutStream, theerrStream,nameOfInputFile,nameOfOutputFile, scalefactor,pagesize,this);
832 }
833 // virtual void DeleteBackend(drvbase * & ptr) const { delete (T*) ptr; ptr = 0; }
getdrvbaseVersion()834 virtual unsigned int getdrvbaseVersion() const { return drvbaseVersion; }
835
836 private: typedef DriverDescriptionT<T> SHORTNAME;
837 NOCOPYANDASSIGN(SHORTNAME)
838 };
839
840
841 template <class T>
min(T x,T y)842 inline T min(T x, T y)
843 {
844 return (x<y) ? x:y;
845 }
846
847 template <class T>
max(T x,T y)848 inline T max(T x, T y)
849 {
850 return (x>y) ? x:y;
851 }
852
853
854 #endif
855
856
857
858