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