home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / pstoedit.zip / source.zip / pstoedit.2.50 / src / drvbase.h < prev    next >
C/C++ Source or Header  |  1996-11-22  |  15KB  |  498 lines

  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,1994,1995,1996 Wolfgang Glunz, Wolfgang.Glunz@zfe.siemens.de
  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. #include <fstream.h>
  39. #include <stdio.h>
  40.  
  41. // for free
  42. #include <stdlib.h>
  43. // for strcpy
  44. #include <string.h>
  45.  
  46.  
  47. const unsigned int       maxFontNamesLength = 1000;
  48. const unsigned int       maxpoints = 20000;    // twice the maximal number of points in a path
  49. const unsigned int    maxElements = maxpoints/2;
  50. const unsigned int       maxsegments  = maxpoints/2;// at least half of maxpoints (if we only have segments with one point)
  51.  
  52. #if defined (__GNUG__) || defined (__BCPLUSPLUS__) || defined (INTERNALBOOL)
  53. // no need to define bool
  54. #else
  55. typedef int bool;
  56. const bool false = 0;
  57. const bool true  = 1;
  58. #endif
  59.  
  60.  
  61. static const char emptyDashPattern[] =  "[ ] 0.0";
  62.  
  63. class basedrawingelement ; // forward
  64.  
  65. class           drvbase 
  66.     // = TITLE
  67.     // Base class for backends to pstoedit
  68.     //
  69.     // = CLASS TYPE
  70.     // Abstract
  71.     //
  72.     // = AUDIENCE
  73.     // Developers of new backends
  74.     //
  75.     // = DESCRIPTION
  76.     //  Abstract base class for backends to pstoedit. 
  77.     // This class defines the virtual functions that every backend has
  78.     // to implement and some functions that are common to all backends
  79.     //
  80. {
  81.  
  82.                     
  83. public:
  84.  
  85.     // = CONSTRUCTION, DESTRUCTION AND COPYING
  86.  
  87.     drvbase(
  88.         const char * driverOptions_p,
  89.         ostream & theoutStream,
  90.         ostream & theerrStream,
  91.         bool backendSupportsSubPathes_p,
  92.         bool backendSupportsCurveto_p,
  93.         bool backendSupportsMerging_p); // constructor
  94.     virtual ~drvbase();          // destructor
  95.  
  96.     void run(bool merge);    // do the conversion
  97. public:
  98.  
  99.     const bool     backendSupportsSubPathes;
  100.     const bool     backendSupportsCurveto;
  101.     const bool     backendSupportsMerging; // merge a separate outline and filling of a polygon -> 1. element
  102.  
  103.     enum showtype { stroke, fill, eofill };
  104.     enum linetype { solid, dashed, dotted, dashdot, dashdotdot }; // corresponding to the CGM patterns
  105.  
  106. // need to make RSString public because of problem with SparcCompiler
  107.     class  RSString {
  108.     public:
  109.         // a very very simple resizing string
  110.         RSString(const char * arg = 0) : 
  111.             content(0),
  112.             allocatedLength(0) { if (arg) this->copy(arg); }
  113.         ~RSString() { delete [] content; content = 0; allocatedLength = 0; }
  114.         const char * value() const { return content; }
  115.         void copy(const char *src) {
  116.             if ((strlen(src)+1) <= allocatedLength) {
  117.                 // we have enough space
  118.                 ::strcpy(content,src);
  119.             } else {
  120.                 // resize
  121.                 delete [] content;
  122.                 allocatedLength = strlen(src) + 1;
  123.                 content = new char[allocatedLength];
  124.                 ::strcpy(content,src);
  125.             }
  126.         }
  127.     private:
  128.         char * content;
  129.         unsigned int allocatedLength;
  130.         // declared but not defined
  131.         RSString(const RSString &);
  132.         const RSString & operator == (const RSString &);
  133.     };
  134.  
  135. protected:
  136.     // = PROTECTED TYPES 
  137.  
  138.     struct TextInfo {
  139.         float         x;
  140.         float        y;
  141.         const char *    thetext;
  142.         int        is_non_standard_font;
  143.         RSString        currentFontName;
  144.         RSString        currentFontFamilyName;
  145.         RSString        currentFontFullName;
  146.         RSString        currentFontWeight;
  147.         float           currentFontSize;
  148.         float        currentFontAngle;
  149.         float           currentR; // Colors
  150.         float           currentG;
  151.         float           currentB;
  152.         float        cx; // next five items correspond to the 
  153.         float        cy; // params for the awidthshow operator
  154.         int        Char; // of PostScript
  155.         float        ax; 
  156.         float        ay;
  157.         TextInfo() :
  158.             x(0.0f),
  159.             y(0.0f),
  160.             thetext(0),
  161.             is_non_standard_font(0),
  162.             currentFontSize(0.0f),
  163.             currentFontAngle(0.0f),
  164.             currentR(0.0f),
  165.             currentG(0.0f),
  166.             currentB(0.0f),
  167.             cx(0.0f),
  168.             cy(0.0f),
  169.             Char(0),
  170.             ax(0.0f),
  171.             ay(0.0f) { 
  172.             }
  173.     };
  174.  
  175.     // = PROTECTED ATTRIBUTES
  176.     unsigned int    d_argc;
  177.     const char * *    d_argv;
  178.     bool        page_empty;    // indicates whether the current page is empty or not
  179.     ostream &    outf;           // the output stream
  180.     ostream &    errf;           // the error stream
  181.  
  182.     float           scale;
  183.     float           currentDeviceHeight; // normally 792 pt; used for flipping y values.
  184.     float           currentDeviceWidth;  
  185.     float           x_offset;
  186.     float           y_offset;
  187.     unsigned int    currentPageNumber;
  188.     unsigned int    pathnumber; // number of path (for debugging)
  189.     bool        verbose;
  190.     bool        domerge;
  191.  
  192.     // = PROTECTED ACCESS FUNCTIONS
  193.  
  194.     const basedrawingelement & pathElement(unsigned int index) const;
  195.     showtype    currentShowType() { return outputPath->currentShowType; }
  196.     linetype    currentLineType() { return outputPath->currentLineType; }
  197.     unsigned int    currentLineCap() { return outputPath->currentLineCap; }
  198.     bool         isPolygon() { return outputPath->isPolygon;} // whether current path was closed via closepath or not
  199.     unsigned int     &numberOfElementsInPath() { return outputPath->numberOfElementsInPath; }
  200.     float           currentLineWidth() { return outputPath->currentLineWidth; }
  201.     unsigned int    currentNr() { return outputPath->nr; } 
  202.     float           edgeR() { return outputPath->edgeR; } // edge colors
  203.     float           edgeG() { return outputPath->edgeG; }
  204.     float           edgeB() { return outputPath->edgeB; }
  205.     float           fillR() { return outputPath->fillR; } // fill colors
  206.     float           fillG() { return outputPath->fillG; }
  207.     float           fillB() { return outputPath->fillB; }
  208.  
  209.     const char *    dashPattern() { return outputPath->dashPattern.value(); }
  210.  
  211.     float           currentR() { return outputPath->fillR; } // backends that don't support merging 
  212.     float           currentG() { return outputPath->fillG; } // don't need to differentiate and
  213.     float           currentB() { return outputPath->fillB; } // can use these functions.
  214.  
  215.     float           get_scale() const { return scale; }
  216.  
  217.  
  218. private:
  219.     // = PRIVATE TYPES
  220.     struct PathInfo {
  221.         showtype    currentShowType;
  222.         linetype    currentLineType;
  223.         unsigned int    currentLineCap;
  224.         unsigned int    nr;
  225.         basedrawingelement * * path; // a path is an array of pointers to basedrawingelements
  226.         bool         isPolygon; // whether current path was closed via closepath or not
  227.         unsigned int    numberOfElementsInPath;
  228.         float           currentLineWidth;
  229.         float           edgeR; // edge colors
  230.         float           edgeG;
  231.         float           edgeB;
  232.         float           fillR; // fill colors
  233.         float           fillG;
  234.         float           fillB;
  235.         RSString    dashPattern; // just the dump of currentdash as string
  236.         PathInfo() :
  237.             currentShowType(drvbase::stroke),
  238.             currentLineType(drvbase::solid),
  239.             currentLineCap(0),
  240.             nr(0),
  241.             path(0),
  242.             isPolygon(0),
  243.             numberOfElementsInPath(0),
  244.             currentLineWidth(0.0f),
  245.             edgeR(0.0f),
  246.             edgeG(0.0f),
  247.             edgeB(0.0f),
  248.             fillR(0.0f),
  249.             fillG(0.0f),
  250.             fillB(0.0f), 
  251.             dashPattern(emptyDashPattern)
  252.             {
  253.                 path = new basedrawingelement *[maxElements];
  254.             }
  255.         ~PathInfo() {
  256.             // the path content is deleted by clear
  257.             clear();
  258.             delete [] path;
  259.         }
  260.         void clear();
  261.         void copyInfo(const PathInfo & p);
  262.             // copies the whole path state except the path array
  263.     private:
  264.         // Inhibitors (declared, but not defined)
  265.         const PathInfo& operator=(const PathInfo&);
  266.         PathInfo(const PathInfo &);
  267.     };
  268.  
  269.     // = PRIVATE ATTRIBUTES
  270.     char         *driveroptions; // string containing options for backend
  271.     float           *numbers; // The number stack [maxpoints]
  272.     unsigned int    nextFreeNumber;
  273.  
  274.     PathInfo     p1,p2;
  275.     PathInfo *currentPath; // for filling from lexer
  276.     PathInfo *lastPath;    // for merging
  277.     PathInfo *outputPath;  // for output driver
  278.  
  279. protected:
  280.     TextInfo textInfo_;
  281. private:
  282.  
  283.     // = BACKEND GENERIC FUNCTIONS 
  284.         // These functions are not backend specific and shouldn't have to be
  285.         // changed for new backends
  286.  
  287.     friend void backendtest(); // allow access to private from a test function
  288.  
  289.     int yylex();    // read the input and call the backend specific
  290.             // functions
  291.     void yylexcleanup(); // called from destructor
  292.  
  293.     bool        pathsCanBeMerged(const PathInfo & p1, const PathInfo & p2);
  294.  
  295.     void        addtopath(basedrawingelement * newelement);
  296.  
  297.     void            add_to_page();
  298.  
  299.     void         guess_linetype();
  300.  
  301.     bool        is_a_rectangle();
  302.  
  303.     void            addNumber(float value); // add a number to the current path
  304.  
  305.     void         dumpPath();  // shows current path
  306.  
  307.     void        dumpText(const char *const thetext);
  308.  
  309.     float           pop(); // pops and returns last value on stack
  310.  
  311.      void        setCurrentWidthParams(float ax,float ay,int Char,float cx,float cy);
  312.  
  313.     void            setCurrentFontName(const char *const,bool is_non_standard_font);
  314.  
  315.     void            setCurrentFontFamilyName(const char *const);
  316.  
  317.     void            setCurrentFontFullName(const char *const);
  318.  
  319.     void            setCurrentFontWeight(const char *const);
  320.  
  321.     void            setCurrentFontSize(const float Size);
  322.  
  323.     void        setCurrentFontAngle(float value);
  324.  
  325.     void            setCurrentLineCap(const unsigned int capType) 
  326.             { currentPath->currentLineCap = capType; }
  327.  
  328.     void            setCurrentShowType(const showtype how) 
  329.             { currentPath->currentShowType = how; }
  330.  
  331.     void            setCurrentLineType(const linetype how) 
  332.             { currentPath->currentLineType = how; }
  333.  
  334.     void            setCurrentLineWidth(const float linewidth) 
  335.             { currentPath->currentLineWidth = linewidth; }
  336.  
  337.     void            setCurrentDeviceHeight(const float deviceHeight) 
  338.             { currentDeviceHeight = deviceHeight; }
  339.  
  340.     void            setCurrentDeviceWidth(const float deviceWidth) 
  341.             { currentDeviceWidth = deviceWidth; }
  342.  
  343.     void        setRGB(const float R,const float G, const float B)
  344.             { textInfo_.currentR = R ; textInfo_.currentG = G; textInfo_.currentB = B; 
  345.              currentPath->edgeR = R ; currentPath->edgeG = G; currentPath->edgeB = B; 
  346.              currentPath->fillR = R ; currentPath->fillG = G; currentPath->fillB = B; }
  347.             
  348.     void         setDash(const char * const dash)
  349.             { currentPath->dashPattern.copy(dash); }
  350.  
  351.     // = BACKEND SPECIFIC FUNCTIONS
  352.         //  These are backend specific and thus have to be implemented for every new backend.
  353.  
  354.     virtual void    close_page() = 0;
  355.     // writes a trailer whenever a page is finished (triggered by showpage)
  356.  
  357.     virtual void    open_page() = 0;
  358.     // writes a page header whenever a new page is needed
  359.  
  360.     virtual void    show_text(const TextInfo & textinfo) = 0;
  361.  
  362.     virtual void    show_path() = 0;
  363.  
  364.     virtual void    show_rectangle(
  365.                        const float llx,
  366.                        const float lly,
  367.                        const float urx,
  368.                        const float ury) = 0;
  369.     // writes a rectangle at points (llx,lly) (urx,ury)
  370.     // fillpat is the FillValue if the rectangle is filled or noFillValue
  371.     // if not.
  372.  
  373. public:
  374.     // If a backend only deals with a special set of font names
  375.     // the following function must return a 0 terminated list
  376.     // of font names.
  377.     virtual const char * const *     knownFontNames() const { return 0; }
  378.  
  379.  
  380. private:
  381.     // Inhibitors (declared, but not defined)
  382.     drvbase(const drvbase &);
  383.     drvbase & operator=(const drvbase&);
  384. };
  385.  
  386.  
  387. typedef const char * (*makeColorNameType)(float r, float g, float b);
  388. const unsigned int maxcolors = 1000 ; // 1000 colors maximum
  389. class ColorTable 
  390. {
  391. public:
  392.     ColorTable(const char * const * defaultColors,
  393.            const unsigned int numberOfDefaultColors,
  394.            makeColorNameType makeColorName);
  395.     ~ColorTable();
  396.     unsigned int getColorIndex(float r, float g, float b);
  397.     const char * const getColorString(float r, float g, float b);
  398.     bool     isKnownColor(float r, float g, float b) const;
  399.     const char * const getColorString(unsigned int index) const;
  400.         
  401. private:
  402.     const char * const * const defaultColors_;
  403.     const unsigned int  numberOfDefaultColors_;
  404.     char * newColors[maxcolors];
  405.         makeColorNameType makeColorName_ ;
  406. };
  407.  
  408.  
  409. struct Point
  410. {
  411. public:
  412.     Point(float x, float y) : x_(x),y_(y) {}
  413.     Point() : x_(0.0f), y_(0.0f) {}; // for arrays
  414.     float x_;
  415.     float y_;
  416.     friend bool operator==(const Point & p1, const Point & p2) { return (p1.x_ == p2.x_) && (p1.y_ == p2.y_); }
  417. private:
  418. };
  419.  
  420. #ifdef __TCPLUSPLUS__
  421. // turbo C++ has problems with enum for template parameters
  422. typedef unsigned int Dtype;
  423. const Dtype moveto = 1;
  424. const Dtype lineto = 2;
  425. const Dtype closepath = 3;
  426. const Dtype curveto = 4;
  427. #else
  428. enum  Dtype {moveto, lineto, closepath, curveto};
  429. #endif
  430. // closepath is only generated if backend supportes subpathes
  431. // curveto   is only generated if backend supportes it
  432.  
  433.  
  434. class basedrawingelement 
  435. {
  436. public:
  437.     basedrawingelement(unsigned int size_p) : size(size_p) {}
  438.     virtual const Point &getPoint(unsigned int i) const = 0;
  439.     virtual Dtype getType() const = 0;
  440.     friend ostream & operator<<(ostream & out,const basedrawingelement &elem);
  441.     friend bool operator==(const basedrawingelement & bd1, const basedrawingelement & bd2);
  442. protected:
  443.     const unsigned int size;
  444. };
  445.  
  446.  
  447. template <unsigned int nr, Dtype curtype>
  448. class drawingelement : public basedrawingelement
  449. {
  450. public:
  451.     drawingelement(Point p[]);
  452.     const Point &getPoint(unsigned int i) const  { return points[i]; }
  453.     Dtype getType() const              { return (Dtype) curtype; }
  454.                         // This cast (Dtype) is necessary
  455.                         // to eliminate a compiler warning
  456.                         // from the SparcCompiler 4.1.
  457.                         // although curtype is of type Dtype
  458. private:
  459.     Point points[nr > 0 ? nr : 1];
  460. };
  461.  
  462. template <unsigned int nr, Dtype curtype>
  463. drawingelement<nr,curtype>::drawingelement(Point p[]) 
  464.     : basedrawingelement(nr)
  465. {
  466.     for (unsigned int i = 0 ; i < nr ; i++ ) points[i] = p[i]; 
  467. }
  468.  
  469. typedef drawingelement<(unsigned int) 1,moveto>      Moveto;
  470. typedef drawingelement<(unsigned int) 1,lineto>     Lineto;
  471. typedef drawingelement<(unsigned int) 0,closepath>      Closepath;
  472. typedef drawingelement<(unsigned int) 3,curveto>     Curveto;
  473.  
  474. // A temporary file, that is automatically removed after usage
  475. class TempFile {
  476. public:
  477.     TempFile()  { tempFileName = tempnam(0,"pstmp"); }
  478.     ~TempFile() { close(); remove(tempFileName); free(tempFileName); }
  479.     ofstream & asOutput() { close(); outFileStream.open(tempFileName); return outFileStream; }
  480.     ifstream & asInput()  { close(); inFileStream.open(tempFileName);  return  inFileStream; }
  481. private:
  482.     void close() { inFileStream.close(); outFileStream.close(); }
  483.     char * tempFileName;
  484.     ofstream outFileStream;
  485.     ifstream inFileStream;
  486. };
  487.  
  488. // used to eliminate compiler warnings about unused parameters
  489. inline void unused(const void * const) { }
  490. class istream;
  491. class ostream;
  492. inline void copy_file(istream& infile,ostream& outfile) 
  493. {
  494.     outfile << infile.rdbuf();
  495. }
  496.  
  497. #endif
  498.