]> www.fi.muni.cz Git - evince.git/blobdiff - pdf/xpdf/GfxState.h
New file with some random thoughts.
[evince.git] / pdf / xpdf / GfxState.h
index 21bbec844042b287706006109cdb984143f6994f..f747a831b12b90837cf3d737476cf3abeb606bc3 100644 (file)
 //
 // GfxState.h
 //
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2003 Glyph & Cog, LLC
 //
 //========================================================================
 
 #ifndef GFXSTATE_H
 #define GFXSTATE_H
 
-#ifdef __GNUC__
+#include <aconf.h>
+
+#ifdef USE_GCC_PRAGMAS
 #pragma interface
 #endif
 
 #include "gtypes.h"
+#include "Object.h"
+#include "Function.h"
 
-class Object;
-class Function;
+class Array;
 class GfxFont;
+class PDFRectangle;
+class GfxShading;
 
 //------------------------------------------------------------------------
 // GfxColor
 //------------------------------------------------------------------------
 
-class GfxColor {
-public:
+#define gfxColorMaxComps funcMaxOutputs
 
-  GfxColor(): r(0), g(0), b(0) {}
+struct GfxColor {
+  double c[gfxColorMaxComps];
+};
 
-  // Set color.
-  void setGray(double gray)
-    { r = g = b = gray; }
-  void setCMYK(double c, double m, double y, double k);
-  void setRGB(double r1, double g1, double b1)
-    { r = r1; g = g1; b = b1; }
+//------------------------------------------------------------------------
+// GfxRGB
+//------------------------------------------------------------------------
 
-  // Accessors.
-  double getR() { return r; }
-  double getG() { return g; }
-  double getB() { return b; }
-  double getGray() { return 0.299 * r + 0.587 * g + 0.114 * b; }
+struct GfxRGB {
+  double r, g, b;
+};
 
-private:
+//------------------------------------------------------------------------
+// GfxCMYK
+//------------------------------------------------------------------------
 
-  double r, g, b;
+struct GfxCMYK {
+  double c, m, y, k;
 };
 
 //------------------------------------------------------------------------
 // GfxColorSpace
 //------------------------------------------------------------------------
 
-enum GfxColorMode {
-  colorGray, colorCMYK, colorRGB
+// NB: The nGfxColorSpaceModes constant and the gfxColorSpaceModeNames
+// array defined in GfxState.cc must match this enum.
+enum GfxColorSpaceMode {
+  csDeviceGray,
+  csCalGray,
+  csDeviceRGB,
+  csCalRGB,
+  csDeviceCMYK,
+  csLab,
+  csICCBased,
+  csIndexed,
+  csSeparation,
+  csDeviceN,
+  csPattern
 };
 
 class GfxColorSpace {
 public:
 
-  // Construct a colorspace.
-  GfxColorSpace(Object *colorSpace);
+  GfxColorSpace();
+  virtual ~GfxColorSpace();
+  virtual GfxColorSpace *copy() = 0;
+  virtual GfxColorSpaceMode getMode() = 0;
 
-  // Construct a simple colorspace: DeviceGray, DeviceCMYK, or
-  // DeviceRGB.
-  GfxColorSpace(GfxColorMode mode1);
+  // Construct a color space.  Returns NULL if unsuccessful.
+  static GfxColorSpace *parse(Object *csObj);
 
-  // Destructor.
-  ~GfxColorSpace();
+  // Convert to gray, RGB, or CMYK.
+  virtual void getGray(GfxColor *color, double *gray) = 0;
+  virtual void getRGB(GfxColor *color, GfxRGB *rgb) = 0;
+  virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk) = 0;
 
-  // Copy.
-  GfxColorSpace *copy() { return new GfxColorSpace(this); }
+  // Return the number of color components.
+  virtual int getNComps() = 0;
 
-  // Is color space valid?
-  GBool isOk() { return ok; }
+  // Return the default ranges for each component, assuming an image
+  // with a max pixel value of <maxImgPixel>.
+  virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
+                               int maxImgPixel);
+
+  // Return the number of color space modes
+  static int getNumColorSpaceModes();
+
+  // Return the name of the <idx>th color space mode.
+  static char *getColorSpaceModeName(int idx);
+
+private:
+};
+
+//------------------------------------------------------------------------
+// GfxDeviceGrayColorSpace
+//------------------------------------------------------------------------
+
+class GfxDeviceGrayColorSpace: public GfxColorSpace {
+public:
+
+  GfxDeviceGrayColorSpace();
+  virtual ~GfxDeviceGrayColorSpace();
+  virtual GfxColorSpace *copy();
+  virtual GfxColorSpaceMode getMode() { return csDeviceGray; }
+
+  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+  virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+  virtual int getNComps() { return 1; }
+
+private:
+};
+
+//------------------------------------------------------------------------
+// GfxCalGrayColorSpace
+//------------------------------------------------------------------------
+
+class GfxCalGrayColorSpace: public GfxColorSpace {
+public:
+
+  GfxCalGrayColorSpace();
+  virtual ~GfxCalGrayColorSpace();
+  virtual GfxColorSpace *copy();
+  virtual GfxColorSpaceMode getMode() { return csCalGray; }
+
+  // Construct a CalGray color space.  Returns NULL if unsuccessful.
+  static GfxColorSpace *parse(Array *arr);
+
+  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+  virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+  virtual int getNComps() { return 1; }
+
+  // CalGray-specific access.
+  double getWhiteX() { return whiteX; }
+  double getWhiteY() { return whiteY; }
+  double getWhiteZ() { return whiteZ; }
+  double getBlackX() { return blackX; }
+  double getBlackY() { return blackY; }
+  double getBlackZ() { return blackZ; }
+  double getGamma() { return gamma; }
+
+private:
+
+  double whiteX, whiteY, whiteZ;    // white point
+  double blackX, blackY, blackZ;    // black point
+  double gamma;                            // gamma value
+};
+
+//------------------------------------------------------------------------
+// GfxDeviceRGBColorSpace
+//------------------------------------------------------------------------
+
+class GfxDeviceRGBColorSpace: public GfxColorSpace {
+public:
+
+  GfxDeviceRGBColorSpace();
+  virtual ~GfxDeviceRGBColorSpace();
+  virtual GfxColorSpace *copy();
+  virtual GfxColorSpaceMode getMode() { return csDeviceRGB; }
+
+  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+  virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+  virtual int getNComps() { return 3; }
+
+private:
+};
+
+//------------------------------------------------------------------------
+// GfxCalRGBColorSpace
+//------------------------------------------------------------------------
+
+class GfxCalRGBColorSpace: public GfxColorSpace {
+public:
+
+  GfxCalRGBColorSpace();
+  virtual ~GfxCalRGBColorSpace();
+  virtual GfxColorSpace *copy();
+  virtual GfxColorSpaceMode getMode() { return csCalRGB; }
+
+  // Construct a CalRGB color space.  Returns NULL if unsuccessful.
+  static GfxColorSpace *parse(Array *arr);
+
+  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+  virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+  virtual int getNComps() { return 3; }
+
+  // CalRGB-specific access.
+  double getWhiteX() { return whiteX; }
+  double getWhiteY() { return whiteY; }
+  double getWhiteZ() { return whiteZ; }
+  double getBlackX() { return blackX; }
+  double getBlackY() { return blackY; }
+  double getBlackZ() { return blackZ; }
+  double getGammaR() { return gammaR; }
+  double getGammaG() { return gammaG; }
+  double getGammaB() { return gammaB; }
+  double *getMatrix() { return mat; }
+
+private:
+
+  double whiteX, whiteY, whiteZ;    // white point
+  double blackX, blackY, blackZ;    // black point
+  double gammaR, gammaG, gammaB;    // gamma values
+  double mat[9];               // ABC -> XYZ transform matrix
+};
+
+//------------------------------------------------------------------------
+// GfxDeviceCMYKColorSpace
+//------------------------------------------------------------------------
+
+class GfxDeviceCMYKColorSpace: public GfxColorSpace {
+public:
+
+  GfxDeviceCMYKColorSpace();
+  virtual ~GfxDeviceCMYKColorSpace();
+  virtual GfxColorSpace *copy();
+  virtual GfxColorSpaceMode getMode() { return csDeviceCMYK; }
+
+  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+  virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+  virtual int getNComps() { return 4; }
+
+private:
+};
+
+//------------------------------------------------------------------------
+// GfxLabColorSpace
+//------------------------------------------------------------------------
+
+class GfxLabColorSpace: public GfxColorSpace {
+public:
+
+  GfxLabColorSpace();
+  virtual ~GfxLabColorSpace();
+  virtual GfxColorSpace *copy();
+  virtual GfxColorSpaceMode getMode() { return csLab; }
+
+  // Construct a Lab color space.  Returns NULL if unsuccessful.
+  static GfxColorSpace *parse(Array *arr);
+
+  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+  virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+  virtual int getNComps() { return 3; }
 
-  // Get the color mode.
-  GfxColorMode getMode() { return mode; }
+  virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
+                               int maxImgPixel);
 
-  // Get number of components in pixels of this colorspace.
-  int getNumPixelComps() { return indexed ? 1 : numComps; }
+  // Lab-specific access.
+  double getWhiteX() { return whiteX; }
+  double getWhiteY() { return whiteY; }
+  double getWhiteZ() { return whiteZ; }
+  double getBlackX() { return blackX; }
+  double getBlackY() { return blackY; }
+  double getBlackZ() { return blackZ; }
+  double getAMin() { return aMin; }
+  double getAMax() { return aMax; }
+  double getBMin() { return bMin; }
+  double getBMax() { return bMax; }
 
-  // Get number of components in colors of this colorspace.
-  int getNumColorComps() { return numComps; }
+private:
+
+  double whiteX, whiteY, whiteZ;    // white point
+  double blackX, blackY, blackZ;    // black point
+  double aMin, aMax, bMin, bMax;    // range for the a and b components
+  double kr, kg, kb;               // gamut mapping mulitpliers
+};
+
+//------------------------------------------------------------------------
+// GfxICCBasedColorSpace
+//------------------------------------------------------------------------
+
+class GfxICCBasedColorSpace: public GfxColorSpace {
+public:
+
+  GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA,
+                       Ref *iccProfileStreamA);
+  virtual ~GfxICCBasedColorSpace();
+  virtual GfxColorSpace *copy();
+  virtual GfxColorSpaceMode getMode() { return csICCBased; }
+
+  // Construct an ICCBased color space.  Returns NULL if unsuccessful.
+  static GfxColorSpace *parse(Array *arr);
+
+  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+  virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+  virtual int getNComps() { return nComps; }
+
+  virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
+                               int maxImgPixel);
+
+  // ICCBased-specific access.
+  GfxColorSpace *getAlt() { return alt; }
+
+private:
+
+  int nComps;                  // number of color components (1, 3, or 4)
+  GfxColorSpace *alt;          // alternate color space
+  double rangeMin[4];          // min values for each component
+  double rangeMax[4];          // max values for each component
+  Ref iccProfileStream;                // the ICC profile
+};
+
+//------------------------------------------------------------------------
+// GfxIndexedColorSpace
+//------------------------------------------------------------------------
+
+class GfxIndexedColorSpace: public GfxColorSpace {
+public:
 
-  // Return true if colorspace is indexed.
-  GBool isIndexed() { return indexed; }
+  GfxIndexedColorSpace(GfxColorSpace *baseA, int indexHighA);
+  virtual ~GfxIndexedColorSpace();
+  virtual GfxColorSpace *copy();
+  virtual GfxColorSpaceMode getMode() { return csIndexed; }
 
-  // Get lookup table (only for indexed colorspaces).
+  // Construct a Lab color space.  Returns NULL if unsuccessful.
+  static GfxColorSpace *parse(Array *arr);
+
+  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+  virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+  virtual int getNComps() { return 1; }
+
+  virtual void getDefaultRanges(double *decodeLow, double *decodeRange,
+                               int maxImgPixel);
+
+  // Indexed-specific access.
+  GfxColorSpace *getBase() { return base; }
   int getIndexHigh() { return indexHigh; }
-  Guchar *getLookupVal(int i) { return lookup[i]; }
+  Guchar *getLookup() { return lookup; }
+  GfxColor *mapColorToBase(GfxColor *color, GfxColor *baseColor);
+
+private:
+
+  GfxColorSpace *base;         // base color space
+  int indexHigh;               // max pixel value
+  Guchar *lookup;              // lookup table
+};
+
+//------------------------------------------------------------------------
+// GfxSeparationColorSpace
+//------------------------------------------------------------------------
+
+class GfxSeparationColorSpace: public GfxColorSpace {
+public:
+
+  GfxSeparationColorSpace(GString *nameA, GfxColorSpace *altA,
+                         Function *funcA);
+  virtual ~GfxSeparationColorSpace();
+  virtual GfxColorSpace *copy();
+  virtual GfxColorSpaceMode getMode() { return csSeparation; }
+
+  // Construct a Separation color space.  Returns NULL if unsuccessful.
+  static GfxColorSpace *parse(Array *arr);
 
-  // Convert a pixel to a color.
-  void getColor(double x[4], GfxColor *color);
+  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+  virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+  virtual int getNComps() { return 1; }
+
+  // Separation-specific access.
+  GString *getName() { return name; }
+  GfxColorSpace *getAlt() { return alt; }
+  Function *getFunc() { return func; }
 
 private:
 
-  Function *sepFunc;           // separation tint transform function
-  GfxColorMode mode;           // color mode
-  GBool indexed;               // set for indexed colorspaces
-  int numComps;                        // number of components in colors
-  int indexHigh;               // max pixel for indexed colorspace
-  Guchar (*lookup)[4];         // lookup table (only for indexed
-                               //   colorspaces)
-  GBool ok;                    // is color space valid?
-
-  GfxColorSpace(GfxColorSpace *colorSpace);
-  void setMode(Object *colorSpace);
+  GString *name;               // colorant name
+  GfxColorSpace *alt;          // alternate color space
+  Function *func;              // tint transform (into alternate color space)
 };
 
 //------------------------------------------------------------------------
-// Function
+// GfxDeviceNColorSpace
 //------------------------------------------------------------------------
 
-class Function {
+class GfxDeviceNColorSpace: public GfxColorSpace {
 public:
 
-  // Create a PDF function object.
-  Function(Object *funcObj);
+  GfxDeviceNColorSpace(int nCompsA, GfxColorSpace *alt, Function *func);
+  virtual ~GfxDeviceNColorSpace();
+  virtual GfxColorSpace *copy();
+  virtual GfxColorSpaceMode getMode() { return csDeviceN; }
 
-  ~Function();
-  
-  Function *copy() { return new Function(this); }
+  // Construct a DeviceN color space.  Returns NULL if unsuccessful.
+  static GfxColorSpace *parse(Array *arr);
 
-  GBool isOk() { return ok; }
+  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+  virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
 
-  // Return size of input and output tuples.
-  int getInputSize() { return m; }
-  int getOutputSize() { return n; }
+  virtual int getNComps() { return nComps; }
 
-  // Transform an input tuple into an output tuple.
-  void transform(double *in, double *out);
+  // DeviceN-specific access.
+  GString *getColorantName(int i) { return names[i]; }
+  GfxColorSpace *getAlt() { return alt; }
+  Function *getTintTransformFunc() { return func; }
 
 private:
 
-  Function(Function *func);
+  int nComps;                  // number of components
+  GString                      // colorant names
+    *names[gfxColorMaxComps];
+  GfxColorSpace *alt;          // alternate color space
+  Function *func;              // tint transform (into alternate color space)
+};
 
-  int m, n;
-  double domain[1][2];
-  double range[4][2];
-  int sampleSize[1];
-  double encode[1][2];
-  double decode[4][2];
-  double *samples;
-  GBool ok;
+//------------------------------------------------------------------------
+// GfxPatternColorSpace
+//------------------------------------------------------------------------
+
+class GfxPatternColorSpace: public GfxColorSpace {
+public:
+
+  GfxPatternColorSpace(GfxColorSpace *underA);
+  virtual ~GfxPatternColorSpace();
+  virtual GfxColorSpace *copy();
+  virtual GfxColorSpaceMode getMode() { return csPattern; }
+
+  // Construct a Pattern color space.  Returns NULL if unsuccessful.
+  static GfxColorSpace *parse(Array *arr);
+
+  virtual void getGray(GfxColor *color, double *gray);
+  virtual void getRGB(GfxColor *color, GfxRGB *rgb);
+  virtual void getCMYK(GfxColor *color, GfxCMYK *cmyk);
+
+  virtual int getNComps() { return 0; }
+
+  // Pattern-specific access.
+  GfxColorSpace *getUnder() { return under; }
+
+private:
+
+  GfxColorSpace *under;                // underlying color space (for uncolored
+                               //   patterns)
+};
+
+//------------------------------------------------------------------------
+// GfxPattern
+//------------------------------------------------------------------------
+
+class GfxPattern {
+public:
+
+  GfxPattern(int typeA);
+  virtual ~GfxPattern();
+
+  static GfxPattern *parse(Object *obj);
+
+  virtual GfxPattern *copy() = 0;
+
+  int getType() { return type; }
+
+private:
+
+  int type;
+};
+
+//------------------------------------------------------------------------
+// GfxTilingPattern
+//------------------------------------------------------------------------
+
+class GfxTilingPattern: public GfxPattern {
+public:
+
+  static GfxTilingPattern *parse(Object *patObj);
+  virtual ~GfxTilingPattern();
+
+  virtual GfxPattern *copy();
+
+  int getPaintType() { return paintType; }
+  int getTilingType() { return tilingType; }
+  double *getBBox() { return bbox; }
+  double getXStep() { return xStep; }
+  double getYStep() { return yStep; }
+  Dict *getResDict()
+    { return resDict.isDict() ? resDict.getDict() : (Dict *)NULL; }
+  double *getMatrix() { return matrix; }
+  Object *getContentStream() { return &contentStream; }
+
+private:
+
+  GfxTilingPattern(int paintTypeA, int tilingTypeA,
+                  double *bboxA, double xStepA, double yStepA,
+                  Object *resDictA, double *matrixA,
+                  Object *contentStreamA);
+
+  int paintType;
+  int tilingType;
+  double bbox[4];
+  double xStep, yStep;
+  Object resDict;
+  double matrix[6];
+  Object contentStream;
+};
+
+//------------------------------------------------------------------------
+// GfxShadingPattern
+//------------------------------------------------------------------------
+
+class GfxShadingPattern: public GfxPattern {
+public:
+
+  static GfxShadingPattern *parse(Object *patObj);
+  virtual ~GfxShadingPattern();
+
+  virtual GfxPattern *copy();
+
+  GfxShading *getShading() { return shading; }
+  double *getMatrix() { return matrix; }
+
+private:
+
+  GfxShadingPattern(GfxShading *shadingA, double *matrixA);
+
+  GfxShading *shading;
+  double matrix[6];
+};
+
+//------------------------------------------------------------------------
+// GfxShading
+//------------------------------------------------------------------------
+
+class GfxShading {
+public:
+
+  GfxShading(int typeA);
+  GfxShading(GfxShading *shading);
+  virtual ~GfxShading();
+
+  static GfxShading *parse(Object *obj);
+
+  virtual GfxShading *copy() = 0;
+
+  int getType() { return type; }
+  GfxColorSpace *getColorSpace() { return colorSpace; }
+  GfxColor *getBackground() { return &background; }
+  GBool getHasBackground() { return hasBackground; }
+  void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA)
+    { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; }
+  GBool getHasBBox() { return hasBBox; }
+
+protected:
+
+  GBool init(Dict *dict);
+
+  int type;
+  GfxColorSpace *colorSpace;
+  GfxColor background;
+  GBool hasBackground;
+  double xMin, yMin, xMax, yMax;
+  GBool hasBBox;
+};
+
+//------------------------------------------------------------------------
+// GfxFunctionShading
+//------------------------------------------------------------------------
+
+class GfxFunctionShading: public GfxShading {
+public:
+
+  GfxFunctionShading(double x0A, double y0A,
+                    double x1A, double y1A,
+                    double *matrixA,
+                    Function **funcsA, int nFuncsA);
+  GfxFunctionShading(GfxFunctionShading *shading);
+  virtual ~GfxFunctionShading();
+
+  static GfxFunctionShading *parse(Dict *dict);
+
+  virtual GfxShading *copy();
+
+  void getDomain(double *x0A, double *y0A, double *x1A, double *y1A)
+    { *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; }
+  double *getMatrix() { return matrix; }
+  void getColor(double x, double y, GfxColor *color);
+
+private:
+
+  double x0, y0, x1, y1;
+  double matrix[6];
+  Function *funcs[gfxColorMaxComps];
+  int nFuncs;
+};
+
+//------------------------------------------------------------------------
+// GfxAxialShading
+//------------------------------------------------------------------------
+
+class GfxAxialShading: public GfxShading {
+public:
+
+  GfxAxialShading(double x0A, double y0A,
+                 double x1A, double y1A,
+                 double t0A, double t1A,
+                 Function **funcsA, int nFuncsA,
+                 GBool extend0A, GBool extend1A);
+  GfxAxialShading(GfxAxialShading *shading);
+  virtual ~GfxAxialShading();
+
+  static GfxAxialShading *parse(Dict *dict);
+
+  virtual GfxShading *copy();
+
+  void getCoords(double *x0A, double *y0A, double *x1A, double *y1A)
+    { *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; }
+  double getDomain0() { return t0; }
+  double getDomain1() { return t1; }
+  void getColor(double t, GfxColor *color);
+  GBool getExtend0() { return extend0; }
+  GBool getExtend1() { return extend1; }
+
+private:
+
+  double x0, y0, x1, y1;
+  double t0, t1;
+  Function *funcs[gfxColorMaxComps];
+  int nFuncs;
+  GBool extend0, extend1;
+};
+
+//------------------------------------------------------------------------
+// GfxRadialShading
+//------------------------------------------------------------------------
+
+class GfxRadialShading: public GfxShading {
+public:
+
+  GfxRadialShading(double x0A, double y0A, double r0A,
+                  double x1A, double y1A, double r1A,
+                  double t0A, double t1A,
+                  Function **funcsA, int nFuncsA,
+                  GBool extend0A, GBool extend1A);
+  GfxRadialShading(GfxRadialShading *shading);
+  virtual ~GfxRadialShading();
+
+  static GfxRadialShading *parse(Dict *dict);
+
+  virtual GfxShading *copy();
+
+  void getCoords(double *x0A, double *y0A, double *r0A,
+                double *x1A, double *y1A, double *r1A)
+    { *x0A = x0; *y0A = y0; *r0A = r0; *x1A = x1; *y1A = y1; *r1A = r1; }
+  double getDomain0() { return t0; }
+  double getDomain1() { return t1; }
+  void getColor(double t, GfxColor *color);
+  GBool getExtend0() { return extend0; }
+  GBool getExtend1() { return extend1; }
+
+private:
+
+  double x0, y0, r0, x1, y1, r1;
+  double t0, t1;
+  Function *funcs[gfxColorMaxComps];
+  int nFuncs;
+  GBool extend0, extend1;
 };
 
 //------------------------------------------------------------------------
@@ -152,11 +690,14 @@ class GfxImageColorMap {
 public:
 
   // Constructor.
-  GfxImageColorMap(int bits1, Object *decode, GfxColorSpace *colorSpace1);
+  GfxImageColorMap(int bitsA, Object *decode, GfxColorSpace *colorSpaceA);
 
   // Destructor.
   ~GfxImageColorMap();
 
+  // Return a copy of this color map.
+  GfxImageColorMap *copy() { return new GfxImageColorMap(this); }
+
   // Is color map valid?
   GBool isOk() { return ok; }
 
@@ -164,26 +705,33 @@ public:
   GfxColorSpace *getColorSpace() { return colorSpace; }
 
   // Get stream decoding info.
-  int getNumPixelComps() { return numComps; }
+  int getNumPixelComps() { return nComps; }
   int getBits() { return bits; }
 
   // Get decode table.
   double getDecodeLow(int i) { return decodeLow[i]; }
   double getDecodeHigh(int i) { return decodeLow[i] + decodeRange[i]; }
 
-  // Convert a pixel to a color.
-  void getColor(Guchar x[4], GfxColor *color);
+  // Convert an image pixel to a color.
+  void getGray(Guchar *x, double *gray);
+  void getRGB(Guchar *x, GfxRGB *rgb);
+  void getCMYK(Guchar *x, GfxCMYK *cmyk);
+  void getColor(Guchar *x, GfxColor *color);
 
 private:
 
-  GfxColorSpace *colorSpace;   // the image colorspace
+  GfxImageColorMap(GfxImageColorMap *colorMap);
+
+  GfxColorSpace *colorSpace;   // the image color space
   int bits;                    // bits per component
-  int numComps;                        // number of components in a pixel
-  GBool indexed;               // set for indexed color space
-  GfxColorMode mode;           // color mode
-  double (*lookup)[4];         // lookup table
-  double decodeLow[4];         // minimum values for each component
-  double decodeRange[4];       // max - min value for each component
+  int nComps;                  // number of components in a pixel
+  GfxColorSpace *colorSpace2;  // secondary color space
+  int nComps2;                 // number of components in colorSpace2
+  double *lookup;              // lookup table
+  double                       // minimum values for each component
+    decodeLow[gfxColorMaxComps];
+  double                       // max - min value for each component
+    decodeRange[gfxColorMaxComps];
   GBool ok;
 };
 
@@ -221,8 +769,11 @@ public:
               double x3, double y3);
 
   // Close the subpath.
-  void close()
-    { if (x[n-1] != x[0] || y[n-1] != y[0]) lineTo(x[0], y[0]); }
+  void close();
+  GBool isClosed() { return closed; }
+
+  // Add (<dx>, <dy>) to each point in the subpath.
+  void offset(double dx, double dy);
 
 private:
 
@@ -231,6 +782,7 @@ private:
                                //   for a Bezier curve
   int n;                       // number of points
   int size;                    // size of x/y arrays
+  GBool closed;                        // set if path is closed
 
   GfxSubpath(GfxSubpath *subpath);
 };
@@ -273,7 +825,13 @@ public:
               double x3, double y3);
 
   // Close the last subpath.
-  void close() { subpaths[n-1]->close(); }
+  void close();
+
+  // Append <path> to <this>.
+  void append(GfxPath *path);
+
+  // Add (<dx>, <dy>) to each point in the path.
+  void offset(double dx, double dy);
 
 private:
 
@@ -294,10 +852,10 @@ private:
 class GfxState {
 public:
 
-  // Construct a default GfxState, for a device with resolution <dpi>,
-  // page box (<x1>,<y1>)-(<x2>,<y2>), page rotation <rotate>, and
+  // Construct a default GfxState, for a device with resolution <hDPI>
+  // x <vDPI>, page box <pageBox>, page rotation <rotate>, and
   // coordinate system specified by <upsideDown>.
-  GfxState(int dpi, double px1a, double py1a, double px2a, double py2a,
+  GfxState(double hDPI, double vDPI, PDFRectangle *pageBox,
           int rotate, GBool upsideDown);
 
   // Destructor.
@@ -316,6 +874,24 @@ public:
   double getPageHeight() { return pageHeight; }
   GfxColor *getFillColor() { return &fillColor; }
   GfxColor *getStrokeColor() { return &strokeColor; }
+  void getFillGray(double *gray)
+    { fillColorSpace->getGray(&fillColor, gray); }
+  void getStrokeGray(double *gray)
+    { strokeColorSpace->getGray(&strokeColor, gray); }
+  void getFillRGB(GfxRGB *rgb)
+    { fillColorSpace->getRGB(&fillColor, rgb); }
+  void getStrokeRGB(GfxRGB *rgb)
+    { strokeColorSpace->getRGB(&strokeColor, rgb); }
+  void getFillCMYK(GfxCMYK *cmyk)
+    { fillColorSpace->getCMYK(&fillColor, cmyk); }
+  void getStrokeCMYK(GfxCMYK *cmyk)
+    { strokeColorSpace->getCMYK(&strokeColor, cmyk); }
+  GfxColorSpace *getFillColorSpace() { return fillColorSpace; }
+  GfxColorSpace *getStrokeColorSpace() { return strokeColorSpace; }
+  GfxPattern *getFillPattern() { return fillPattern; }
+  GfxPattern *getStrokePattern() { return strokePattern; }
+  double getFillOpacity() { return fillOpacity; }
+  double getStrokeOpacity() { return strokeOpacity; }
   double getLineWidth() { return lineWidth; }
   void getLineDash(double **dash, int *length, double *start)
     { *dash = lineDash; *length = lineDashLength; *start = lineDashStart; }
@@ -333,8 +909,12 @@ public:
   double getRise() { return rise; }
   int getRender() { return render; }
   GfxPath *getPath() { return path; }
+  void setPath(GfxPath *pathA);
   double getCurX() { return curX; }
   double getCurY() { return curY; }
+  void getClipBBox(double *xMin, double *yMin, double *xMax, double *yMax)
+    { *xMin = clipXMin; *yMin = clipYMin; *xMax = clipXMax; *yMax = clipYMax; }
+  void getUserClipBBox(double *xMin, double *yMin, double *xMax, double *yMax);
   double getLineX() { return lineX; }
   double getLineY() { return lineY; }
 
@@ -362,35 +942,26 @@ public:
   void getFontTransMat(double *m11, double *m12, double *m21, double *m22);
 
   // Change state parameters.
+  void setCTM(double a, double b, double c,
+             double d, double e, double f);
   void concatCTM(double a, double b, double c,
                 double d, double e, double f);
-  void setFillGray(double gray)
-    { fillColor.setGray(gray); }
-  void setFillCMYK(double c, double m, double y, double k)
-    { fillColor.setCMYK(c, m, y, k); }
-  void setFillRGB(double r, double g, double b)
-    { fillColor.setRGB(r, g, b); }
-  void setStrokeGray(double gray)
-    { strokeColor.setGray(gray); }
-  void setStrokeCMYK(double c, double m, double y, double k)
-    { strokeColor.setCMYK(c, m, y, k); }
-  void setStrokeRGB(double r, double g, double b)
-    { strokeColor.setRGB(r, g, b); }
   void setFillColorSpace(GfxColorSpace *colorSpace);
   void setStrokeColorSpace(GfxColorSpace *colorSpace);
-  void setFillColor(double x[4])
-    { fillColorSpace->getColor(x, &fillColor); }
-  void setStrokeColor(double x[4])
-    { strokeColorSpace->getColor(x, &strokeColor); }
-  void setLineWidth(double width)
-    { lineWidth = width; }
+  void setFillColor(GfxColor *color) { fillColor = *color; }
+  void setStrokeColor(GfxColor *color) { strokeColor = *color; }
+  void setFillPattern(GfxPattern *pattern);
+  void setStrokePattern(GfxPattern *pattern);
+  void setFillOpacity(double opac) { fillOpacity = opac; }
+  void setStrokeOpacity(double opac) { strokeOpacity = opac; }
+  void setLineWidth(double width) { lineWidth = width; }
   void setLineDash(double *dash, int length, double start);
   void setFlatness(int flatness1) { flatness = flatness1; }
   void setLineJoin(int lineJoin1) { lineJoin = lineJoin1; }
   void setLineCap(int lineCap1) { lineCap = lineCap1; }
-  void setMiterLimit(double miterLimit1) { miterLimit = miterLimit1; }
-  void setFont(GfxFont *font1, double fontSize1)
-    { font = font1; fontSize = fontSize1; }
+  void setMiterLimit(double limit) { miterLimit = limit; }
+  void setFont(GfxFont *fontA, double fontSizeA)
+    { font = fontA; fontSize = fontSizeA; }
   void setTextMat(double a, double b, double c,
                  double d, double e, double f)
     { textMat[0] = a; textMat[1] = b; textMat[2] = c;
@@ -401,12 +972,12 @@ public:
     { wordSpace = space; }
   void setHorizScaling(double scale)
     { horizScaling = 0.01 * scale; }
-  void setLeading(double leading1)
-    { leading = leading1; }
-  void setRise(double rise1)
-    { rise = rise1; }
-  void setRender(int render1)
-    { render = render1; }
+  void setLeading(double leadingA)
+    { leading = leadingA; }
+  void setRise(double riseA)
+    { rise = riseA; }
+  void setRender(int renderA)
+    { render = renderA; }
 
   // Add to path.
   void moveTo(double x, double y)
@@ -420,10 +991,15 @@ public:
     { path->close(); curX = path->getLastX(); curY = path->getLastY(); }
   void clearPath();
 
+  // Update clip region.
+  void clip();
+
   // Text position.
+  void textSetPos(double tx, double ty) { lineX = tx; lineY = ty; }
   void textMoveTo(double tx, double ty)
     { lineX = tx; lineY = ty; textTransform(tx, ty, &curX, &curY); }
-  void textShift(double tx);
+  void textShift(double tx, double ty);
+  void shift(double dx, double dy);
 
   // Push/pop GfxState on/off stack.
   GfxState *save();
@@ -440,6 +1016,10 @@ private:
   GfxColorSpace *strokeColorSpace; // stroke color space
   GfxColor fillColor;          // fill color
   GfxColor strokeColor;                // stroke color
+  GfxPattern *fillPattern;     // fill pattern
+  GfxPattern *strokePattern;   // stroke pattern
+  double fillOpacity;          // fill opacity
+  double strokeOpacity;                // stroke opacity
 
   double lineWidth;            // line width
   double *lineDash;            // line dash
@@ -464,6 +1044,9 @@ private:
   double curX, curY;           // current point (user coords)
   double lineX, lineY;         // start of current text line (text coords)
 
+  double clipXMin, clipYMin,   // bounding box for clip region
+         clipXMax, clipYMax;
+
   GfxState *saved;             // next GfxState on stack
 
   GfxState(GfxState *state);