casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
PSDriver.h
Go to the documentation of this file.
00001 //# PSDriver.h: Defines PSDriver, a low-level PostScript interface for the DL.
00002 //# Copyright (C) 1999,2000,2001,2002,2003
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id$
00027 
00028 #ifndef TRIALDISPLAY_PSDRIVER_H
00029 #define TRIALDISPLAY_PSDRIVER_H
00030 
00031 #include <casa/aips.h>
00032 #include <display/Display/DisplayEnums.h>
00033 #include <casa/BasicSL/String.h>
00034 
00035 //# Forward declarations
00036 #include <casa/iosfwd.h>
00037 
00038 namespace casa { //# NAMESPACE CASA - BEGIN
00039 
00040 // <summary>
00041 // Low level interface between PSPixelCanvas{ColorTable} and PostScript.
00042 // </summary>
00043 
00044 // <use visibility=local>
00045 
00046 //<a name="Synopsis"></a>
00047 // <synopsis>
00048 // PSDriver takes graphics requests from
00049 // <linkto class="PSPixelCanvas"> PSPixelCanvas </linkto> and
00050 // <linkto class="PSPixelCanvasColorTable"> PSPixelCanvasColorTable </linkto>
00051 // and generates PostScript code. It might be thought of as playing an
00052 // analogous role to what Xlib does for the X11PixelCanvas{ColorTable}.
00053 // It could be used separately, but mostly programers will just
00054 // create a PSDriver object to pass to PSPixelCanvas{ColorTable}.
00055 //
00056 // While there are many constructors, PSDrivers will probably most frequently
00057 // be created using something like:
00058 //
00059 // <srcblock>
00060 //      PSdriver *ps = new PSDriver("filename", PSDriver::LETTER,
00061 //                                  PSDriver::PORTRAIT);
00062 // </srcblock>
00063 //
00064 // If it were desired to use RGB colormode rather than INDEXED,
00065 // the following could be added.
00066 //
00067 //<srcblock>
00068 //      ps->setColorSpace(PSDriver::RGB);
00069 //</srcblock>
00070 //
00071 // PSDriver is logically split into two sections. The 'upper' level
00072 // contains public functions, such as drawLine(). These do various
00073 // amounts of bookkeeping, such as bounding box calculations, then call
00074 // the 'lower' level routines, typically with names starting with emit.
00075 // (eg. emitLine() in this example).
00076 //
00077 // There are many public routines that will rarely be called from outside
00078 // of PSDriver. Typical of these are the various xxxToAscii85 routines
00079 // that are used internally to generate image data.
00080 
00081 // </synopsis>
00082 //
00083 // <thrown>
00084 // PSDriver does not currently explicitly throw any exceptions.
00085 // </thrown>
00086 //
00087 //<a name="ToDo"></a>
00088 // <todo>
00089 // <ol>
00090 // <li> EPS support is preliminary.
00091 // <li> Vertical text justification doesn't look correct, presumably because
00092 //      the character's bounding box includes interline space.
00093 // <li> No display list support.
00094 // <li> Clipping support is disabled since it is currently possible to
00095 //      only reduce the size of the clipping path, not replace it.
00096 // <li> Points are drawn as filled circles of fixed size.
00097 // </ol>
00098 // </todo>
00099 //
00100 // Notes:
00101 // <ol>
00102 // <li> It is possible to switch between Index, RGB and HSV modes at will.
00103 // <li> The length of the color table is 4096 entries.
00104 // <li> PostScript doesn't deal with pixels.
00105 // <li> The transform matrix affects virtually everything.
00106 // <li> Font names must be known by the PostScript interpreter.
00107 // </ol>
00108 
00109 class PSDriver {
00110   public:
00111         // The various color spaces PSDriver knows about.
00112         enum ColorSpace { UNKNOWNSPACE=-1, INDEXED, GRAY, RGB, HSV, HSB=HSV};
00113         // Different line types that can be drawn.
00114         enum LineStyle { UNKNOWNSTYPE=-1, SOLID, DASHED, DASHDASH};
00115         // Constants describing the the length of the indexed color table and the number of bits per color component.
00116         enum {NUMCOLORS = 4096, BITSPERCOMPONENT=12};
00117         enum Dimension { POINTS, INCHES, MM};
00118         enum Layout {   PORTRAIT=1, LANDSCAPE=2, EPS=0x4, EPS_PORTRAIT=0x5,
00119                         EPS_LANDSCAPE=0x6};
00120 
00121 //<srcblock>
00122         //              Options for drawImage.
00123         // SMOOTH        Pixels are interpolated. Not supported by all
00124         //              interpreters. Old versions of ghostscript may core
00125         //              dump if this is selected.
00126 //</srcblock>
00127         enum ImageOptions { NOIMGOPTS=0, SMOOTH=0x1};
00128 
00129         enum MediaSize {
00130         // USERPAGE is used internally. It is not a valid media type.
00131           USERPAGE=-1,
00132           // The following lists the known media types (paper sizes).
00133           LETTER=0, NA_LETTER=LETTER, LEGAL, NA_LEGAL=LEGAL,
00134           NA_10X13_ENVELOPE, NA_9X12_ENVELOPE,
00135           NA_NUMBER_10_ENVELOPE, NA_7X9_ENVELOPE, NA_9X11_ENVELOPE,
00136           NA_10X14_ENVELOPE, NA_6X9_ENVELOPE, NA_10X15_ENVELOPE,
00137           A, B, C, D, E,
00138           ISO_A0, ISO_A1, ISO_A2, ISO_A3, ISO_A4, A4=ISO_A4, ISO_A5, ISO_A6,
00139           ISO_A7, ISO_A8, ISO_A9, ISO_A10, ISO_B0, ISO_B1, ISO_B2, ISO_B3,
00140           ISO_B4, ISO_B5, ISO_B6, ISO_B7, ISO_B8, ISO_B9, ISO_B10, ISO_C0,
00141           ISO_C1, ISO_C2, ISO_C3, ISO_C4, ISO_C5, ISO_C6, ISO_C7, ISO_C8,
00142           ISO_DESIGNATED,
00143           JIS_B0, JIS_B1, JIS_B2, JIS_B3, JIS_B4, JIS_B5, JIS_B6, JIS_B7,
00144           JIS_B8, JIS_B9, JIS_B10};
00145 //
00146           enum TextAlign {
00147             AlignCenter = Display::AlignCenter,
00148             AlignLeft = Display::AlignLeft,
00149             AlignTop = Display::AlignTop,
00150             AlignRight = Display::AlignRight,
00151             AlignBottom = Display::AlignBottom,
00152             AlignTopLeft = Display::AlignTopLeft,
00153             AlignTopRight = Display::AlignTopRight,
00154             AlignBottomLeft = Display::AlignBottomLeft,
00155             AlignBottomRight = Display::AlignBottomRight
00156         };
00157 
00158 //      PSInfo is used to supply comment fields for the PostScript header
00159 //      and other information that needs to be available when the PSDriver
00160 //      object is created. Its use is optional.
00161         class PSInfo {
00162           public:
00163                 PSInfo();
00164                 ~PSInfo();
00165                 void Creator(const char *);
00166                 void Creator(const String &);
00167                 const String &Creator()const{return creator_;}
00168                 void For(const char *);
00169                 void For(const String &);
00170                 const String &For()const {return for_;}
00171                 void Title(const char *);
00172                 void Title(const String &);
00173                 const String &Title()const {return title_;}
00174                 void Comment(const String &);
00175                 void Comment(const char *);
00176                 const String &Comment()const {return comment_;}
00177 
00178                 void setMargins(const float lm, const float rm,
00179                                 const float tm, const float bm,
00180                                 const Dimension dim= PSDriver::INCHES);
00181                 // If setMargins has been called, returns True and the
00182                 // margin values. Otherwise, returns False and does not
00183                 // change the arguments.
00184                 Bool getMargins(float &lm, float &rm,
00185                                 float &tm, float &bm);
00186          private:
00187                 String  for_;
00188                 String  title_;
00189                 String  creator_;
00190                 String  comment_;
00191                 float   lm_, rm_, tm_, bm_;     // Margins.
00192                 Bool    haveMargins_;           // setMargins has been called.
00193         };
00194         // Generic PostScript
00195 
00196   public:
00197 // Arguments to the various constructors:
00198 // <ul>
00199 // <li> out             is an ostream that the PostScript code is written to.
00200 // <li> fname           it the name of the output file to be written to.
00201 // <li> MediaSize       is the paper size. Each paper size has default margins.
00202 // <li> Dimension       is POINTS, INCHES or MM. Describes values of x0,y0,x1,y1.
00203 // <li> x0,y0,x1,y1     are used instead of MediaSize to explicitly give
00204 //                      the lower left and upper right corners of the
00205 //                      drawing surface.
00206 // <li> Layout          is PORTRAIT or LANDSCAPE.
00207 // <li> PSInfo          supplies optional header comments or margins.
00208 //                      Optional argument.
00209 // </ul>
00210 // 
00211         // INDEXED, PORTRAIT to a default file.
00212         PSDriver();
00213         PSDriver(ostream &out);
00214         PSDriver(const char *filename);
00215         PSDriver(ostream &out, const MediaSize, const Layout=PORTRAIT,
00216                  PSInfo *info=NULL);
00217         PSDriver(const String &fname, const MediaSize, const Layout=PORTRAIT,
00218                  PSInfo *info=NULL);
00219         PSDriver(const char *fname, const MediaSize, const Layout=PORTRAIT,
00220                  PSInfo *info=NULL);
00221 
00222         PSDriver(ostream &out, const Dimension dim,
00223                  const float x0, const float y0,
00224                  const float x1, const float y1,
00225                  const Layout=PORTRAIT, PSInfo *info=NULL);
00226         PSDriver(const String &outname, const Dimension dim,
00227                  const float x0, const float y0,
00228                  const float x1, const float y1,
00229                  const Layout=PORTRAIT, PSInfo *info=NULL);
00230         PSDriver(const String &outname, const MediaSize,
00231                  const Dimension dim,
00232                  const float x0, const float y0,
00233                  const float x1, const float y1,
00234                  const Layout=PORTRAIT, PSInfo *info=NULL);
00235         PSDriver(const char *outname, const Dimension dim,
00236                  const float x0, const float y0,
00237                  const float x1, const float y1,
00238                  const Layout=PORTRAIT, PSInfo *info=NULL);
00239         ~PSDriver();
00240 
00241 //#     ////////////////////////////////////////////////////////////////
00242 //
00243         // Set/get desired color space. (Default is INDEXED).
00244 //<group>
00245         void setColorSpace(const ColorSpace);
00246         inline ColorSpace colorSpace()const{return colorSpace_;}
00247 //</group>
00248         // Set current color used for text and vectors. Only the first
00249         // argument is used for indexed & gray.
00250         // For Indexed mode, color should be in the range (0..ncolors-1)
00251         // where ncolors is the number of colors in the table. color
00252         // is truncated to an integer.
00253         // For the others, color should be in the range (0..1).
00254         void setColor(const float rh, const float gs, const float bv);
00255         // Set color value for indexed and gray scale modes.
00256         // If called when not in indexed or gray modes, the same value
00257         // is used for all three components.
00258         void setColor(const float color);
00259         // Color to be used for dashes.
00260         void setBackgroundColor(const float rh, const float gs,
00261                                 const float bv, const ColorSpace=RGB);
00262         // Set color value for indexed and gray scale modes.
00263         void setBackgroundColor(const float color, const ColorSpace=INDEXED);
00264 
00265         // Change color space then set color.
00266         void setIndexColor(const float indx);
00267         void setRGBColor(const float r, const float g, const float b);
00268         void setHSVColor(const float h, const float s, const float v)
00269                         { setHSBColor(h, s, v);}
00270         void setHSBColor(const float h, const float s, const float b);
00271 
00272         // Load color tables with contents of a, b & c. Typically, a holds
00273         // red, b holds green & c holds blue. Values should be in the
00274         // range (0..1).
00275         // May be called anytime, but values are only used in INDEXED mode.
00276         // Start is starting index in the color table. Len is the
00277         // number of entries to set.
00278         void storeColors(const int start, const int len,
00279                          const float *r, const float *g, const float *b);
00280         // Scatter load the colortable. Much more effecient if indexes are
00281         // consecutive.
00282         void storeColorValues(const int len, const int *indexes,
00283                               const float *a, const float *b, const float *c);
00284         // Store 1 color.
00285         void storeColor(const int index,
00286                         const float r, const float g, const float b);
00287         // Load linear ramps (0..1.0) into the first ncolors entries.
00288         void setLinearRamps(const int ncolors);
00289 //#     ////////////////////////////////////////////////////////////////
00290 //#     //              Coordinate commands.
00291         // Current transform matrix is changed by the given values, not
00292         // replaced.
00293 // <group>
00294         // Change origin to x/y.
00295         void translate(const float x, const float y);
00296         // Change scale by x/y.
00297         void scale(const float x, const float y);
00298         // Rotate by # degrees.
00299         void rotate(const float degrees);
00300 // </group>
00301 
00302         // Set the length of dashes.
00303         void setDashLength(const float length);
00304   public:
00305 //#     ////////////////////////////////////////////////////////////////
00306 //<srcblock>
00307         //                      Draw an Image
00308         // x0,y0        Image is drawn with lower left corner at x0, y0.
00309         //              (In current user coordinates).
00310         // width,height Size of source image in elements.
00311         // xsize,ysize  Size of output image. (Eg. If current user
00312         //              coordinates were in inches, a size of 2 would create
00313         //              a two inch output square regardless of the size of the
00314         //              input image).
00315         // data         Data for an image that is width pixels wide by
00316         //              height pixels high. The actual length of the array
00317         //              depends on the ColorSpace argument:
00318         //              INDEXED:        The array contains width*height
00319         //                              indexes in the range 0.. 2^bpc -1.
00320         //                              (0..255 or 0..4095).
00321         //              RGB or HSV:     The array contains width*height
00322         //                              RGB (HSV) triples in the range
00323         //                              0..255 for bpc=8 or 0..1023 otherwise.
00324         //                              The length of the array is
00325         //                              width*height*3.
00326         // bpc          Used to determing how data is encoded.
00327         //              If (0 < bpc <= 8) 8 bit encoding is used.
00328         //              If bpc > 8, 12 bit encoding is used.
00329         //              If bpc <= 0, the array is scanned to determine the
00330         //              encoding method.
00331         // ColorSpace   Whether image is INDEXED, RGB or HSV.
00332         // imageopts    Bitwise OR of IMAGEOPTS.
00333         //               Currently only whether to smooth image.
00334 //</srcblock>
00335 
00336         void drawImage( const float x0, const float y0,
00337                         const int width, const int height,
00338                         const float xsize, const float ysize,
00339                         const uShort *data,
00340                         const int bpc=0, const ColorSpace=INDEXED,
00341                         const int imageopts=0);
00342 
00343         // Save/restore graphics state.
00344 //<group>
00345         void gsave();
00346         void grestore();
00347 //</group>
00348 //
00349 //<srcblock>
00350         //                       Graphics
00351 //</srcblock>
00352 //
00353 
00354         void setLineStyle(const LineStyle);
00355         // w = 1.0 means 0.005".
00356         void lineWidth(const float w);
00357 
00358         void moveTo(const float x, const float y);
00359         void lineTo(const float x, const float y, const int stroke=1);
00360 
00361         void drawPolygon(const int len, const float *x, const float *y,
00362                          const int fill=0);
00363         void drawPolyline(const int len, const float *x, const float *y,
00364                           const int close=0, const int fill=0);
00365         void drawLine(  const float x0, const float y0,
00366                         const float x1, const float y1);
00367         void drawLines(const int len,   const float *x1, const float *y1,
00368                                         const float *x2, const float *y2);
00369         void drawRectangle(const float x0, const float y0,
00370                            const float x1, const float y1, const int fill=0);
00371         void drawFilledRectangle(const float x0, const float y0,
00372                                  const float x1, const float y1);
00373         void drawPoint( const float x, const float y, const float radius=1.0);
00374         void drawPoints(const int len, const float *x, const float *y,
00375                         const float radius=1.0);
00376         void drawColoredPoints( const int len, const float *x, const float *y,
00377                                 const float *colors, const float radius=1.0);
00378 
00379 
00380 //#     ////////////////////////////////////////////////////////////////
00381 //
00382 //<srcblock>
00383         //                              Text
00384 //</srcblock>
00385 //#
00386 
00387 //   Display a line of text. Tabs, newlines, etc. are not handled.
00388         void drawText(const float x, const float y, const char *str,
00389                       const TextAlign algn=AlignBottomLeft,
00390                       const float angle = 0);
00391 //<note role=caution> PSDriver just passes the name to the output file.
00392 //      It can't know whether the font really exists on the output device.
00393 //</note>
00394         // Set font using current font scaling.
00395         void setFont(const char *fn);
00396         // Use font with supplied scaling.
00397         void findFont(const char *fn, const float scale);
00398 
00399         // Set/Get font scaling used with setFont.
00400         void setDefaultFontScale(const float scl);
00401         float getDefaultFontScale()const{return defaultFontSize_;}
00402 //
00403 //#     ////////////////////////////////////////////////////////////////
00404 //<srcblock>
00405         //                              Misc.
00406 //</srcblock>
00407 //
00408         // Return page size (drawable area - margins).
00409         // If userCoords is True, values are in current user coordinates.
00410         // Otherwise, they are in transformed coordinates ( points).
00411         void pageSize(float &width, float &height,
00412                       const Bool userCoords=True);
00413 
00414         // Return bounding box.
00415         // Return is True if a bounding box was declared initially. Otherwise,
00416         // False and the current value of the bounding box will be returned.
00417         // If userCoords is True, values are in current user coordinates.
00418         // Otherwise, transformed coords.
00419         Bool getBoundingBox( float &x0, float &y0, float &x1, float &y1,
00420                              const Bool userCoords=True)const;
00421 
00422         // Returns True if bounding box size was given to the constructor.
00423         inline Bool haveBoundingBox()const{return haveBoundingBox_;}
00424 
00425         // Put a comment in the output file.
00426         // The comment may include newlines.
00427 //<group>
00428         void comment(const char *);
00429         void comment(const String &);
00430 //</group>
00431         // Push/pop transform matrix.
00432 //<group>
00433         void pushMatrix();
00434         void popMatrix();
00435 //</group>
00436         void newPage();
00437         // Flush the output.
00438         void flush();
00439         // Done. Called by the destructor.
00440         void finish();
00441         // Set clipping rectangle.
00442         // Subsequent calls can only make the clipping rectangle smaller.
00443         void clipRect(  const float x0, const float y0,
00444                         const float width, const float height);
00445   public:
00446 //
00447 //<srcblock>
00448 //              The following, while public, will almost will almost
00449 // never be called from outside of PSDriver.
00450 //</srcblock>
00451 
00452         // Routines to encode non negative binary numbers in ASCII85 format.
00453         // There will be upto 5/4 as many output characters as input bytes.
00454         // Returns the number of bytes written to out.
00455 
00456         static int bytesToAscii85(const char *in, const int inlength,
00457                                 char *out);
00458         static int uShorts8ToAscii85(const uShort *in,
00459                                    const int inlength, char *out);
00460 
00461 
00462         // Converts in to ASCII85 bytes using only lower 12 bits of each
00463         // integer. Out must be at least 1.75*inlength rounded up to
00464         // a multiple of 5 bytes long.
00465         // ( <1.5bytes/entry>*<inlength entries>*<1.25 expansion>).
00466         // If inlength is odd, a 0 valued entry will be implicitly added.
00467         static int uShorts12ToAscii85(const uShort *in,
00468                                           const int width,
00469                                           const int height, char *out);
00470 
00471         // Encode data as ASCII85 chars. Function return is an array of
00472         // chars. (use delete [] to free). outlen is set to the number of
00473         // bytes in the array.
00474         // On input, if bpc is 8, data is treated as containing 1 byte per
00475         // element. If bpc is 12, data is assumed to contain 12 bits/element.
00476         // If bpc is 0, the array is scanned.
00477         // On return, bpc is set the the value actually used.
00478         static char *encodeUShorts(const int width, const int height,
00479                                          int &bpc, const uShort *data,
00480                                          int &outlen);
00481 
00482 //#     ////////////////////////////////////////////////////////////////
00483         // Miscellaneous functions to convert between typical scalings.
00484         static inline float pointsToInches(const float in){return in/72.0;}
00485         static inline float pointsToMM(const float in){return in*(25.4/72.0);}
00486         static inline float inchesToPoints(const float in){return in*72.0;}
00487         static inline float mmToPoints(const float in){return in*(72./25.4);}
00488 
00489         static float toPoints(const float in, const Dimension indem);
00490         static float fromPoints(const float in, const Dimension indem);
00491 //#     ////////////////////////////////////////////////////////////////
00492 
00493         // Do forward or reverse transformation on a point.
00494         // If absolute is False, the translations aren't done.
00495         void toPoints(const float xin, const float yin,
00496                       float &xout, float &yout,
00497                       const Bool absolute=True)const
00498                 {       state_.toPoints(xin, yin, xout, yout, absolute);}
00499 
00500         void fromPoints(const float xin, const float yin,
00501                         float &xout, float &yout,
00502                         const Bool absolute=True)const
00503                 {       state_.fromPoints(xin, yin, xout, yout, absolute);}
00504 
00505 
00506         // Return a string representation of a dimension.
00507         static const char *dimensionToString(const PSDriver::Dimension dim);
00508         const char *dimensionToString()const
00509                 {return dimensionToString(dimension_);}
00510         Dimension dimension()const{return dimension_;}
00511 
00512         // Is the output EPS? Portrait?
00513 //<group>
00514         Bool isEPS()const{return eps_;}
00515         Bool isPortrait()const{return portrait_;}
00516 //</group>
00517 
00518         // The PageInfo struct is used internally to supply descriptions
00519         // of the various page types.
00520         typedef struct PageInfo {
00521                 PSDriver::MediaSize     media;          // A4, LETTER, etc.
00522                 float                   width;
00523                 float                   height;
00524                 float                   lrmargin;
00525                 float                   tbmargin;
00526                 PSDriver::Dimension     dimension;      // MM or INCHES.
00527                 char                    *name; //"North American letter", etc.
00528                 char                    *alias1;        // "NA_LETTER", etc.
00529                 char                    *alias2;        // "LETTER", etc.
00530                 } pageinfo_;
00531         // Given a paper type, return a pointer to its description.
00532         static const PSDriver::PageInfo *pageInfo(const PSDriver::MediaSize);
00533         // Return page description for index indx.
00534         static const PSDriver::PageInfo *getPageInfo(const int indx);
00535         // Lookup for a page description using the name field.
00536         static const PSDriver::PageInfo *lookupPageInfo(const char *name);
00537         static int numPageTypes();                      // # of page types.
00538   private:
00539 //<srcblock>
00540         // Similar to the public drawImage but uses a transform matrix instead of
00541         // position and scaling.
00542         // imagematrix          6 element array that defines transformation
00543         //                      from user space to image space:
00544         //                      m = [ a b c d tx ty ]
00545         //                       x' = ax + cy + tx
00546         //                       y' = bx + dy + ty
00547         //      The transformation is such that [ width 0 0 height 0 0] will
00548         //      map the image into a unit square which would then be scaled
00549         //      by the current scale() values.
00550         //      To invert the image, use: [ width 0 0 -height 0 height].
00551         //      If imagematrix is NULL, the image will be mapped into the
00552         //      unit square.
00553         // bpc is as above.
00554         // If smooth is 0, no smoothing is done. Otherwise, pixels are
00555         // interpolated.
00556         // Caution: This routine bypasses boundary box checks! If
00557         // BB checks are not important, then this routine could be public.
00558 //</srcblock>
00559 #if 0
00560         void drawImage(const float imagematrix[6],
00561                        const int width, const int height,
00562                        const uShort *data,
00563                        const int bpc=-1, const ColorSpace cs=INDEXED,
00564                        const int smooth=0);
00565 #endif
00566 //#     ////////////////////////////////////////////////////////////////
00567         void newPath();         // These are used internally.
00568         void stroke();
00569         void closePath();
00570 //#     ////////////////////////////////////////////////////////////////
00571         void init(ostream &output, const ColorSpace cs,
00572                   const PageInfo *, const Layout, PSInfo *);
00573         void initname(const String &name, const ColorSpace cs,
00574                       const PageInfo *, const Layout, PSInfo *);
00575         // Compare x/y to current bounding box. x and y are in current
00576         // user coordinates unless userCoords is False in which case they
00577         // have already been transformed.
00578         void bbCheck(const float x, const float y, const Bool userCoords=True);
00579         void bbCheck(); // Do bbCheck on current position.
00580 
00581         void setCurrXY( const float x, const float y,
00582                         const Bool userCoords = True)
00583                        { state_.setXY(x, y, userCoords);}
00584         void getCurrXY( float &x, float &y, const Bool userCoords=True)
00585                         { state_.getXY(x, y, userCoords);}
00586   private:
00587         void startDocument();
00588         // Code writers.
00589         void emitHeader();
00590         void emitProlog();
00591         void emitTrailer();
00592         void emitShowPage(const int force=0);
00593         void emitPageNum();
00594         void emitSetup();
00595 
00596         void emitColorSpace(const ColorSpace);
00597         void emitLineStyle(const LineStyle);
00598         void emitDashLength(const float length);
00599         void emitLineWidth(const float w);
00600         void emitMoveTo(const float x, const float y);
00601         void emitLineTo(const float x, const float y, const int stroke=1);
00602         void emitPolyline(const int len, const float *x, const float *y,
00603                           const int close, const int fill);
00604         void emitPolygon(const int len, const float *x, const float *y,
00605                          const int fill);
00606         void emitLine(const float x0, const float y0,
00607                       const float x1, const float y1);
00608         void emitLines(const int len, const float *x1, const float *y1,
00609                                       const float *x2, const float *y2);
00610         void emitRectangle(const float x, const float y,
00611                            const float width, const float height,
00612                            const int fill);
00613         void emitPoint(const float x, const float y, const float radius=1.0);
00614         void emitPoints(const int len, const float *x, const float *y,
00615                         const float radius=1.0);
00616         // Rotate by degrees.
00617         void emitRotate(const float degrees);
00618         // Scale. (new scale = <old scale>*<new scale>.
00619         void emitScale(const float x, const float y);
00620         // Change origin.
00621         void emitTranslate(const float x, const float y);
00622 
00623         void emitFindFont(const char *fn, const float scale);   // Load font.
00624         // Draw text starting at point x, y.
00625         // Newlines, tabs, etc. are not handled.
00626         void emitText(const float x, const float y, const char *str,
00627                         const TextAlign=AlignBottomLeft,
00628                       const float angle = 0);
00629         // Just throw a string on the stack and leave it there.
00630         void emitString(const char *str);
00631 
00632         // Draw a width x height PS image.
00633         // matrix               Matrix to convert between user & image space.
00634         // width, height        size of input image in pixels.
00635         // bpc                  bits per color component. ( 8 or 12)
00636         // smooth               0 - no smoothing, 1 - smooth pixels.
00637         //                      ghostscript may core dump if not 0.
00638         //  ascii85             data encoded as ASCII85 chars.
00639         //  len                 length of data array.
00640         void emitImage( const float matrix[6],
00641                         const int width, const int height, const int bpc,
00642                         const int smooth, const char *ascii85, const int len,
00643                         const ColorSpace=INDEXED);
00644         // Load color tables with contents of a, b & c. Typically, a holds
00645         // red, b holds green & c holds blue. Values should be in the
00646         // range (0..1).
00647         void emitStoreColors(const int start, const int len,
00648                              const float *a, const float *b, const float *c);
00649         // Load color tables given an array of colors and their corresponding
00650         // indexes. Much more effecient if indexes are consecutive.
00651         void emitStoreColorValues(const int len, const int *indexes,
00652                               const float *a, const float *b, const float *c);
00653         // Internal helper function.
00654         void emitStoreColors(const int color, const int start, const int len,
00655                              const float *ary);
00656 
00657         // Load one value into color table.
00658         void emitStoreColor(const int index,
00659                             const float r, const float g, const float b);
00660         // Set curren`t color.
00661         void emitSetColor(const ColorSpace cs, const int index);
00662         void emitSetColor(const ColorSpace cs,
00663                           const float a, const float b, const float c);
00664         // Load color first ncolors entries in the tables with linear
00665         // ramps scaled 0..1.
00666         void emitSetLinearRamps(const int ncolors);
00667         void emitGSave();
00668         void emitGRestore();
00669         void emitPushMatrix();
00670         void emitPopMatrix();
00671         void emitClipRect(const float x0, const float y0,
00672                           const float width, const float height);
00673         void emitBackgroundColor(const float a, const float b, const float c,
00674                                  const ColorSpace cs);
00675         // Write value of bounding box to output.
00676         void emitBoundingBox();
00677   private:
00678         // Holds our copy of the current transformation matrix. Used for
00679         // bounding box computations.
00680         class PSState {
00681         public:
00682                 PSState();
00683                 ~PSState();
00684                 void scale( const float x, const float y);
00685                 void translate( const float x, const float y);
00686                 void rotate(const float degrees);
00687                 // [ x' y' 1 ] = [ x y 1] * CTM
00688                 inline void toPoints(const float xin, const float yin,
00689                                     float &xout, float &yout,
00690                                     const Bool absolute=True)const
00691                         {       xout = (float)(a_*xin + c_*yin);
00692                                 yout = (float)(b_*xin + d_*yin);
00693                                 if(absolute)
00694                                 {       xout += (float)tx_;
00695                                         yout += (float)ty_;
00696                                 }
00697                         }
00698 
00699                 // [ x y 1 ] = [ x' y' 1] * inverse(CTM);
00700                 inline void fromPoints(const float xin, const float yin,
00701                                       float &xout, float &yout,
00702                                       const Bool absolute=True)const
00703                         {       xout = (float)(ai_*xin + ci_*yin);
00704                                 yout = (float)(bi_*xin + di_*yin);
00705                                 if(absolute)
00706                                 {       xout += (float)txi_;
00707                                         yout += (float)tyi_;
00708                                 }
00709                         }
00710 
00711                 void setIdentity();
00712                 void operator=(const PSState &);
00713                 // Set/Get the current position.
00714                 void setXY(const float x, const float y,
00715                            const Bool userCoords=True);
00716                 void getXY(float &x, float &y, const Bool userCoords=True);
00717         private:
00718                 void invert();
00719 
00720                 double  a_, b_, c_, d_, tx_, ty_;       // Forward
00721                 double  ai_, bi_, ci_, di_, txi_, tyi_; // Inverse
00722                 float   currX_, currY_;                 // Current x/y in pnts
00723 
00724         };
00725         void pushState();
00726         void popState();
00727         // Length of internal state(transform) stack.
00728         enum {STATESTACKLENGTH=16};
00729         int             statestackindex_;
00730         PSState         state_;
00731         PSState         statestack_[STATESTACKLENGTH];
00732         ostream         *out;
00733         std::fstream    *mystream_;
00734         ColorSpace      colorSpace_;
00735         Dimension       dimension_;
00736         Bool            portrait_;
00737         Bool            eps_;
00738         LineStyle       lineStyle_;
00739         float           defaultFontSize_;
00740         float           xscale_, yscale_; // Paper size scale.
00741         // Bounding box in points.
00742         float           bbx0_, bby0_;
00743         float           bbx1_, bby1_;
00744         Bool            boxCheck0_;             // Has anything been checked?
00745         Bool            haveBoundingBox_;
00746         Bool            checkBoundingBox_;
00747                                                 // user coords.
00748         // Page boundaries in points;
00749         float           xll_, yll_;
00750         float           xur_, yur_;
00751 
00752         // Clipping rectangle in points.
00753         float           clipXll_, clipXur_;
00754         float           clipYll_, clipYur_;
00755 
00756         unsigned int    pageNum_;               // Current page number.
00757         int             finished_;              // Set when finished called.
00758         PSInfo          *info_;
00759 };
00760 
00761 
00762 } //# NAMESPACE CASA - END
00763 
00764 #endif