#ifndef __drvbase_h #define __drvbase_h /* drvbase.h : This file is part of pstoedit Base class for all specific driver classes/backends. All virtual functions have to be implemented by the specific driver class. See drvSAMPL.cpp Copyright (C) 1993,1994,1995,1996 Wolfgang Glunz, Wolfgang.Glunz@zfe.siemens.de This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* // ============================================================================ // // = LIBRARY // pstoedit // // = FILENAME // drvbase.h // // = RCSID // $Id$ */ #include #include const unsigned int maxFontNamesLength = 1000; const unsigned int maxpoints = 20000; // twice the maximal number of points in a path const unsigned int maxElements = maxpoints/2; const unsigned int maxsegments = maxpoints/2;// at least half of maxpoints (if we only have segments with one point) #ifndef __GNUG__ typedef int bool; const bool false = 0; const bool true = 1; #endif class basedrawingelement ; // forward class drvbase // = TITLE // Base class for backends to pstoedit // // = CLASS TYPE // Abstract // // = AUDIENCE // Developers of new backends // // = DESCRIPTION // Abstract base class for backends to pstoedit. // This class defines the virtual functions that every backend has // to implement and some functions that are common to all backends // { public: // = CONSTRUCTION, DESTRUCTION AND COPYING drvbase(ostream & theoutStream, bool backendSupportsSubPathes_p, bool backendSupportsCurveto_p, bool backendSupportsMerging_p); // constructor virtual ~drvbase(); // destructor void run(bool merge); // do the conversion public: const bool backendSupportsSubPathes; const bool backendSupportsCurveto; const bool backendSupportsMerging; // merge a separate outline and filling of a polygon -> 1. element enum showtype { stroke, fill, eofill }; protected: // = PROTECTED TYPES struct TextInfo { float x; float y; const char * thetext; int is_non_standard_font; char currentFontName[maxFontNamesLength]; char currentFontFamilyName[maxFontNamesLength]; char currentFontFullName[maxFontNamesLength]; char currentFontWeight[maxFontNamesLength]; float currentFontSize; float currentFontAngle; float currentR; // Colors float currentG; float currentB; TextInfo() : x(0), y(0), thetext(0), is_non_standard_font(0), currentFontSize(0), currentFontAngle(0), currentR(0), currentG(0), currentB(0) { currentFontName[0]='\0'; currentFontFamilyName[0]='\0'; currentFontFullName[0]='\0'; currentFontWeight[0]='\0'; } }; // = PROTECTED ATTRIBUTES bool page_empty; // indicates whether the current page is empty or not ostream & outf; // the output stream float scale; float currentDeviceHeight; // normally 792 pt; used for flipping y values. float x_offset; float y_offset; unsigned int currentPageNumber; unsigned int pathnumber; // number of path (for debugging) bool verbose; bool domerge; // = PROTECTED ACCESS FUNCTIONS const basedrawingelement & pathElement(unsigned int index) const; showtype currentShowType() { return outputPath->currentShowType; } bool isPolygon() { return outputPath->isPolygon;} // whether current path was closed via closepath or not unsigned int &numberOfElementsInPath() { return outputPath->numberOfElementsInPath; } float currentLineWidth() { return outputPath->currentLineWidth; } unsigned int currentNr() { return outputPath->nr; } float edgeR() { return outputPath->edgeR; } // edge colors float edgeG() { return outputPath->edgeG; } float edgeB() { return outputPath->edgeB; } float fillR() { return outputPath->fillR; } // fill colors float fillG() { return outputPath->fillG; } float fillB() { return outputPath->fillB; } float currentR() { return outputPath->fillR; } // backends that don't support merging float currentG() { return outputPath->fillG; } // don't need to differentiate and float currentB() { return outputPath->fillB; } // can use these functions. float get_scale() const { return scale; } private: // = PRIVATE TYPES struct PathInfo { showtype currentShowType; unsigned int nr; basedrawingelement * * path; // a path is an array of pointers to basedrawingelements bool isPolygon; // whether current path was closed via closepath or not unsigned int numberOfElementsInPath; float currentLineWidth; float edgeR; // edge colors float edgeG; float edgeB; float fillR; // fill colors float fillG; float fillB; PathInfo() : currentShowType(drvbase::stroke), nr(0), path(0), isPolygon(0), numberOfElementsInPath(0), currentLineWidth(0), edgeR(0), edgeG(0), edgeB(0), fillR(0), fillG(0), fillB(0) { path = new basedrawingelement *[maxElements]; } ~PathInfo() { // the path content is deleted by clear clear(); delete [] path; } void clear(); private: // Inhibitors (declared, but not defined) const PathInfo& operator=(const PathInfo&); PathInfo(const PathInfo &); }; // = PRIVATE ATTRIBUTES float *numbers; // The number stack [maxpoints] unsigned int nextFreeNumber; PathInfo p1,p2; PathInfo *currentPath; // for filling from lexer PathInfo *lastPath; // for merging PathInfo *outputPath; // for output driver protected: TextInfo textInfo_; private: // = BACKEND GENERIC FUNCTIONS // These functions are not backend specific and shouldn't have to be // changed for new backends int yylex(); // read the input and call the backend specific // functions bool pathsCanBeMerged(const PathInfo & p1, const PathInfo & p2); void addtopath(basedrawingelement * newelement); void add_to_page(); bool is_a_rectangle(); void addNumber(float value); // add a number to the current path void dumpPath(); // shows current path void dumpText(const char *const thetext); float pop(); // pops and returns last value on stack void setCurrentFontName(const char *const,bool is_non_standard_font); void setCurrentFontFamilyName(const char *const); void setCurrentFontFullName(const char *const); void setCurrentFontWeight(const char *const); void setCurrentFontSize(const float Size); void setCurrentFontAngle(float value); void setcurrentShowType(const showtype how) { currentPath->currentShowType = how; } void setcurrentLineWidth(const float linewidth) { currentPath->currentLineWidth = linewidth; } void setCurrentDeviceHeight(const float deviceheight) { currentDeviceHeight = deviceheight; } void setRGB(const float R,const float G, const float B) { textInfo_.currentR = R ; textInfo_.currentG = G; textInfo_.currentB = B; currentPath->edgeR = R ; currentPath->edgeG = G; currentPath->edgeB = B; currentPath->fillR = R ; currentPath->fillG = G; currentPath->fillB = B; } // = BACKEND SPECIFIC FUNCTIONS // These are backend specific and thus have to be implemented for every new backend. virtual void close_page() = 0; // writes a trailer whenever a page is finished (triggered by showpage) virtual void open_page() = 0; // writes a page header whenever a new page is needed virtual void show_text(const TextInfo & textinfo) = 0; virtual void show_path() = 0; virtual void show_rectangle( const float llx, const float lly, const float urx, const float ury) = 0; // writes a rectangle at points (llx,lly) (urx,ury) // fillpat is the FillValue if the rectangle is filled or noFillValue // if not. private: // Inhibitors (declared, but not defined) drvbase(const drvbase &); drvbase & operator=(const drvbase&); }; // some general functions defined in pstoedit.cc class istream; class ostream; void copy_file(istream& infile,ostream& outfile); typedef const char * (*makeColorNameType)(float r, float g, float b); const unsigned int maxcolors = 1000 ; // 1000 colors maximum class ColorTable { public: ColorTable(const char * const * defaultColors, const unsigned int numberOfDefaultColors, makeColorNameType makeColorName); ~ColorTable(); unsigned int getColorIndex(float r, float g, float b); const char * const getColorString(float r, float g, float b); bool isKnownColor(float r, float g, float b) const; const char * const getColorString(unsigned int index) const; private: const char * const * const defaultColors_; const unsigned int numberOfDefaultColors_; char * newColors[maxcolors]; makeColorNameType makeColorName_ ; }; struct Point { public: Point(float x, float y) : x_(x),y_(y) {} Point() : x_(0.0), y_(0.0) {}; // for arrays float x_; float y_; friend bool operator==(const Point & p1, const Point & p2) { return (p1.x_ == p2.x_) && (p1.y_ == p2.y_); } private: }; #ifdef __TCPLUSPLUS__ // turbo C++ has problems with enum for template parameters typedef unsigned int Dtype; const Dtype moveto = 1; const Dtype lineto = 2; const Dtype closepath = 3; const Dtype curveto = 4; #else enum Dtype {moveto, lineto, closepath, curveto}; #endif // closepath is only generated if backend supportes subpathes // curveto is only generated if backend supportes it class basedrawingelement { public: basedrawingelement(unsigned int size_p) : size(size_p) {} virtual const Point &getPoint(unsigned int i) const = 0; virtual Dtype getType() const = 0; friend ostream & operator<<(ostream & out,const basedrawingelement &elem); friend bool operator==(const basedrawingelement & bd1, const basedrawingelement & bd2); protected: const unsigned int size; }; template class drawingelement : public basedrawingelement { public: drawingelement(Point p[]); const Point &getPoint(unsigned int i) const { return points[i]; } Dtype getType() const { return curtype; } private: Point points[nr > 0 ? nr : 1]; }; template drawingelement::drawingelement(Point p[]) : basedrawingelement(nr) { for (unsigned int i = 0 ; i < nr ; i++ ) points[i] = p[i]; } typedef drawingelement<(unsigned int) 1,moveto> Moveto; typedef drawingelement<(unsigned int) 1,lineto> Lineto; typedef drawingelement<(unsigned int) 0,closepath> Closepath; typedef drawingelement<(unsigned int) 3,curveto> Curveto; // A temporary file, that is automatically removed after usage class TempFile { public: TempFile() { tmpnam(tempFileName); } ~TempFile() { close(); remove(tempFileName); } ofstream & asOutput() { close(); outFileStream.open(tempFileName); return outFileStream; } ifstream & asInput() { close(); inFileStream.open(tempFileName); return inFileStream; } private: void close() { inFileStream.close(); outFileStream.close(); } char tempFileName[L_tmpnam]; ofstream outFileStream; ifstream inFileStream; }; #endif