//========================================================================
//
// GfxState.h
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2006, 2007 Jeff Muizelaar <jeff@infidigm.net>
// Copyright (C) 2006 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2009 Koji Otani <sho@bbr.jp>
// Copyright (C) 2009-2011, 2013, 2016-2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2010 Christian Feuersänger <cfeuersaenger@googlemail.com>
// Copyright (C) 2011 Andrea Canciani <ranma42@gmail.com>
// Copyright (C) 2011-2014, 2016 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2013 Lu Wang <coolwanglu@gmail.com>
// Copyright (C) 2015, 2017 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2017, 2019 Oliver Sander <oliver.sander@tu-dresden.de>
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#ifndef GFXSTATE_H
#define GFXSTATE_H

#include "poppler-config.h"

#include "Object.h"
#include "Function.h"

#include <cassert>
#include <map>

class Array;
class Gfx;
class GfxFont;
class PDFRectangle;
class GfxShading;
class OutputDev;
class GfxState;
class GfxResources;
class GfxSeparationColorSpace;

class Matrix {
public:
  double m[6];

  void init(double xx, double yx, double xy, double yy, double x0, double y0) {
    m[0] = xx; m[1] = yx; m[2] = xy; m[3] = yy; m[4] = x0; m[5] = y0;
  }
  bool invertTo(Matrix *other) const;
  void translate(double tx, double ty);
  void scale(double sx, double sy);
  void transform(double x, double y, double *tx, double *ty) const;
  double determinant() const { return m[0] * m[3] - m[1] * m[2]; }
  double norm() const;
};

//------------------------------------------------------------------------
// GfxBlendMode
//------------------------------------------------------------------------
 
enum GfxBlendMode {
  gfxBlendNormal,
  gfxBlendMultiply,
  gfxBlendScreen,
  gfxBlendOverlay,
  gfxBlendDarken,
  gfxBlendLighten,
  gfxBlendColorDodge,
  gfxBlendColorBurn,
  gfxBlendHardLight,
  gfxBlendSoftLight,
  gfxBlendDifference,
  gfxBlendExclusion,
  gfxBlendHue,
  gfxBlendSaturation,
  gfxBlendColor,
  gfxBlendLuminosity
};

//------------------------------------------------------------------------
// GfxColorComp
//------------------------------------------------------------------------

// 16.16 fixed point color component
typedef int GfxColorComp;

#define gfxColorComp1 0x10000

static inline GfxColorComp dblToCol(double x) {
  return (GfxColorComp)(x * gfxColorComp1);
}

static inline double colToDbl(GfxColorComp x) {
  return (double)x / (double)gfxColorComp1;
}

static inline unsigned char dblToByte(double x) {
  return (x * 255.0);
}

static inline double byteToDbl(unsigned char x) {
  return (double)x / (double)255.0;
}

static inline GfxColorComp byteToCol(unsigned char x) {
  // (x / 255) << 16  =  (0.0000000100000001... * x) << 16
  //                  =  ((x << 8) + (x) + (x >> 8) + ...) << 16
  //                  =  (x << 8) + (x) + (x >> 7)
  //                                      [for rounding]
  return (GfxColorComp)((x << 8) + x + (x >> 7));
}

static inline unsigned char colToByte(GfxColorComp x) {
  // 255 * x + 0.5  =  256 * x - x + 0x8000
  return (unsigned char)(((x << 8) - x + 0x8000) >> 16);
}

static inline unsigned short colToShort(GfxColorComp x) {
  return (unsigned short)(x);
}

//------------------------------------------------------------------------
// GfxColor
//------------------------------------------------------------------------

#define gfxColorMaxComps funcMaxOutputs

struct GfxColor {
  GfxColorComp c[gfxColorMaxComps];
};

static inline void clearGfxColor(GfxColor *gfxColor) {
  memset(gfxColor->c, 0, sizeof(GfxColorComp) * gfxColorMaxComps);
}

//------------------------------------------------------------------------
// GfxGray
//------------------------------------------------------------------------

typedef GfxColorComp GfxGray;

//------------------------------------------------------------------------
// GfxRGB
//------------------------------------------------------------------------

struct GfxRGB {
  GfxColorComp r, g, b;
};

//------------------------------------------------------------------------
// GfxCMYK
//------------------------------------------------------------------------

struct GfxCMYK {
  GfxColorComp c, m, y, k;
};

//------------------------------------------------------------------------
// GfxColorSpace
//------------------------------------------------------------------------

// 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
};

// wrapper of cmsHTRANSFORM to copy
class GfxColorTransform {
public:
  void doTransform(void *in, void *out, unsigned int size);
  // transformA should be a cmsHTRANSFORM
  GfxColorTransform(void *transformA, int cmsIntent, unsigned int inputPixelType, unsigned int transformPixelType);
  ~GfxColorTransform();
  GfxColorTransform(const GfxColorTransform &) = delete;
  GfxColorTransform& operator=(const GfxColorTransform &) = delete;
  int getIntent() const { return cmsIntent; }
  int getInputPixelType() const { return inputPixelType; }
  int getTransformPixelType() const { return transformPixelType; }
  void ref();
  unsigned int unref();
private:
  GfxColorTransform() {}
  void *transform;
  unsigned int refCount;
  int cmsIntent;
  unsigned int inputPixelType;
  unsigned int transformPixelType;
};

class GfxColorSpace {
public:

  GfxColorSpace();
  virtual ~GfxColorSpace();

  GfxColorSpace(const GfxColorSpace &) = delete;
  GfxColorSpace& operator=(const GfxColorSpace &other) = delete;

  virtual GfxColorSpace *copy() const = 0;
  virtual GfxColorSpaceMode getMode() const = 0;

  // Construct a color space.  Returns nullptr if unsuccessful.
  static GfxColorSpace *parse(GfxResources *res, Object *csObj, OutputDev *out, GfxState *state, int recursion = 0);

  // Convert to gray, RGB, or CMYK.
  virtual void getGray(const GfxColor *color, GfxGray *gray) const = 0;
  virtual void getRGB(const GfxColor *color, GfxRGB *rgb) const = 0;
  virtual void getCMYK(const GfxColor *color, GfxCMYK *cmyk) const = 0;
  virtual void getDeviceN(const GfxColor *color, GfxColor *deviceN) const = 0;
  virtual void getGrayLine(unsigned char * /*in*/, unsigned char * /*out*/, int /*length*/) { error(errInternal, -1, "GfxColorSpace::getGrayLine this should not happen"); }
  virtual void getRGBLine(unsigned char * /*in*/, unsigned int * /*out*/, int /*length*/) { error(errInternal, -1, "GfxColorSpace::getRGBLine (first variant) this should not happen"); }
  virtual void getRGBLine(unsigned char * /*in*/, unsigned char * /*out*/, int /*length*/) {  error(errInternal, -1, "GfxColorSpace::getRGBLine (second variant) this should not happen"); }
  virtual void getRGBXLine(unsigned char * /*in*/, unsigned char * /*out*/, int /*length*/) {  error(errInternal, -1, "GfxColorSpace::getRGBXLine this should not happen"); }
  virtual void getCMYKLine(unsigned char * /*in*/, unsigned char * /*out*/, int /*length*/) {  error(errInternal, -1, "GfxColorSpace::getCMYKLine this should not happen"); }
  virtual void getDeviceNLine(unsigned char * /*in*/, unsigned char * /*out*/, int /*length*/) {  error(errInternal, -1, "GfxColorSpace::getDeviceNLine this should not happen"); }

  // create mapping for spot colorants
  virtual void createMapping(std::vector<GfxSeparationColorSpace*> *separationList, int maxSepComps);

  // Does this ColorSpace support getRGBLine?
  virtual bool useGetRGBLine() const { return false; }
  // Does this ColorSpace support getGrayLine?
  virtual bool useGetGrayLine() const { return false; }
  // Does this ColorSpace support getCMYKLine?
  virtual bool useGetCMYKLine() const { return false; }
  // Does this ColorSpace support getDeviceNLine?
  virtual bool useGetDeviceNLine() const { return false; }

  // Return the number of color components.
  virtual int getNComps() const = 0;

  // Get this color space's default color.
  virtual void getDefaultColor(GfxColor *color) const = 0;

  // 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) const;

  // Returns true if painting operations in this color space never
  // mark the page (e.g., the "None" colorant).
  virtual bool isNonMarking() const { return false; }

  // Return the color space's overprint mask.
  unsigned int getOverprintMask() const { return overprintMask; }

  // Return the number of color space modes
  static int getNumColorSpaceModes();

  // Return the name of the <idx>th color space mode.
  static const char *getColorSpaceModeName(int idx);

#ifdef USE_CMS
  static int setupColorProfiles();
  // displayProfileA should be a cmsHPROFILE 
  static void setDisplayProfile(void *displayProfileA);
  static void setDisplayProfileName(GooString *name);
  // result will be a cmsHPROFILE 
  static void *getRGBProfile();
  // result will be a cmsHPROFILE 
  static void *getDisplayProfile();
#endif
protected:

  unsigned int overprintMask;
  int *mapping;
};

//------------------------------------------------------------------------
// GfxDeviceGrayColorSpace
//------------------------------------------------------------------------

class GfxDeviceGrayColorSpace: public GfxColorSpace {
public:

  GfxDeviceGrayColorSpace();
  ~GfxDeviceGrayColorSpace() override;
  GfxColorSpace *copy() const override;
  GfxColorSpaceMode getMode() const override { return csDeviceGray; }

  void getGray(const GfxColor *color, GfxGray *gray) const override;
  void getRGB(const GfxColor *color, GfxRGB *rgb) const override;
  void getCMYK(const GfxColor *color, GfxCMYK *cmyk) const override;
  void getDeviceN(const GfxColor *color, GfxColor *deviceN) const override;
  void getGrayLine(unsigned char *in, unsigned char *out, int length) override;
  void getRGBLine(unsigned char *in, unsigned int *out, int length) override;
  void getRGBLine(unsigned char *in, unsigned char *out, int length) override;
  void getRGBXLine(unsigned char *in, unsigned char *out, int length) override;
  void getCMYKLine(unsigned char *in, unsigned char *out, int length) override;
  void getDeviceNLine(unsigned char *in, unsigned char *out, int length) override;

  bool useGetRGBLine() const override { return true; }
  bool useGetGrayLine() const override { return true; }
  bool useGetCMYKLine() const override { return true; }
  bool useGetDeviceNLine() const override { return true; }

  int getNComps() const override { return 1; }
  void getDefaultColor(GfxColor *color) const override;

private:
};

//------------------------------------------------------------------------
// GfxCalGrayColorSpace
//------------------------------------------------------------------------

class GfxCalGrayColorSpace: public GfxColorSpace {
public:

  GfxCalGrayColorSpace();
  ~GfxCalGrayColorSpace() override;
  GfxColorSpace *copy() const override;
  GfxColorSpaceMode getMode() const override { return csCalGray; }

  // Construct a CalGray color space.  Returns nullptr if unsuccessful.
  static GfxColorSpace *parse(Array *arr, GfxState *state);

  void getGray(const GfxColor *color, GfxGray *gray) const override;
  void getRGB(const GfxColor *color, GfxRGB *rgb) const override;
  void getCMYK(const GfxColor *color, GfxCMYK *cmyk) const override;
  void getDeviceN(const GfxColor *color, GfxColor *deviceN) const override;

  int getNComps() const override { return 1; }
  void getDefaultColor(GfxColor *color) const override;

  // CalGray-specific access.
  double getWhiteX() const { return whiteX; }
  double getWhiteY() const { return whiteY; }
  double getWhiteZ() const { return whiteZ; }
  double getBlackX() const { return blackX; }
  double getBlackY() const { return blackY; }
  double getBlackZ() const { return blackZ; }
  double getGamma() const { return gamma; }

private:

  double whiteX, whiteY, whiteZ;    // white point
  double blackX, blackY, blackZ;    // black point
  double gamma;			    // gamma value
  double kr, kg, kb;		    // gamut mapping mulitpliers
  void getXYZ(const GfxColor *color, double *pX, double *pY, double *pZ) const;
#ifdef USE_CMS
  GfxColorTransform *transform;
#endif
};

//------------------------------------------------------------------------
// GfxDeviceRGBColorSpace
//------------------------------------------------------------------------

class GfxDeviceRGBColorSpace: public GfxColorSpace {
public:

  GfxDeviceRGBColorSpace();
  ~GfxDeviceRGBColorSpace() override;
  GfxColorSpace *copy() const override;
  GfxColorSpaceMode getMode() const override { return csDeviceRGB; }

  void getGray(const GfxColor *color, GfxGray *gray) const override;
  void getRGB(const GfxColor *color, GfxRGB *rgb) const override;
  void getCMYK(const GfxColor *color, GfxCMYK *cmyk) const override;
  void getDeviceN(const GfxColor *color, GfxColor *deviceN) const override;
  void getGrayLine(unsigned char *in, unsigned char *out, int length) override;
  void getRGBLine(unsigned char *in, unsigned int *out, int length) override;
  void getRGBLine(unsigned char *in, unsigned char *out, int length) override;
  void getRGBXLine(unsigned char *in, unsigned char *out, int length) override;
  void getCMYKLine(unsigned char *in, unsigned char *out, int length) override;
  void getDeviceNLine(unsigned char *in, unsigned char *out, int length) override;

  bool useGetRGBLine() const override { return true; }
  bool useGetGrayLine() const override { return true; }
  bool useGetCMYKLine() const override { return true; }
  bool useGetDeviceNLine() const override { return true; }

  int getNComps() const override { return 3; }
  void getDefaultColor(GfxColor *color) const override;

private:
};

//------------------------------------------------------------------------
// GfxCalRGBColorSpace
//------------------------------------------------------------------------

class GfxCalRGBColorSpace: public GfxColorSpace {
public:

  GfxCalRGBColorSpace();
  ~GfxCalRGBColorSpace() override;
  GfxColorSpace *copy() const override;
  GfxColorSpaceMode getMode() const override { return csCalRGB; }

  // Construct a CalRGB color space.  Returns nullptr if unsuccessful.
  static GfxColorSpace *parse(Array *arr, GfxState *state);

  void getGray(const GfxColor *color, GfxGray *gray) const override;
  void getRGB(const GfxColor *color, GfxRGB *rgb) const override;
  void getCMYK(const GfxColor *color, GfxCMYK *cmyk) const override;
  void getDeviceN(const GfxColor *color, GfxColor *deviceN) const override;

  int getNComps() const override { return 3; }
  void getDefaultColor(GfxColor *color) const override;

  // CalRGB-specific access.
  double getWhiteX() const { return whiteX; }
  double getWhiteY() const { return whiteY; }
  double getWhiteZ() const { return whiteZ; }
  double getBlackX() const { return blackX; }
  double getBlackY() const { return blackY; }
  double getBlackZ() const { return blackZ; }
  double getGammaR() const { return gammaR; }
  double getGammaG() const { return gammaG; }
  double getGammaB() const { return gammaB; }
  const double *getMatrix() const { 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
  double kr, kg, kb;		    // gamut mapping mulitpliers
  void getXYZ(const GfxColor *color, double *pX, double *pY, double *pZ) const;
#ifdef USE_CMS
  GfxColorTransform *transform;
#endif
};

//------------------------------------------------------------------------
// GfxDeviceCMYKColorSpace
//------------------------------------------------------------------------

class GfxDeviceCMYKColorSpace: public GfxColorSpace {
public:

  GfxDeviceCMYKColorSpace();
  ~GfxDeviceCMYKColorSpace() override;
  GfxColorSpace *copy() const override;
  GfxColorSpaceMode getMode() const override { return csDeviceCMYK; }

  void getGray(const GfxColor *color, GfxGray *gray) const override;
  void getRGB(const GfxColor *color, GfxRGB *rgb) const override;
  void getCMYK(const GfxColor *color, GfxCMYK *cmyk) const override;
  void getDeviceN(const GfxColor *color, GfxColor *deviceN) const override;
  void getRGBLine(unsigned char *in, unsigned int *out, int length) override;
  void getRGBLine(unsigned char *, unsigned char *out, int length) override;
  void getRGBXLine(unsigned char *in, unsigned char *out, int length) override;
  void getCMYKLine(unsigned char *in, unsigned char *out, int length) override;
  void getDeviceNLine(unsigned char *in, unsigned char *out, int length) override;
  bool useGetRGBLine() const override { return true; }
  bool useGetCMYKLine() const override { return true; }
  bool useGetDeviceNLine() const override { return true; }

  int getNComps() const override { return 4; }
  void getDefaultColor(GfxColor *color) const override;

private:
};

//------------------------------------------------------------------------
// GfxLabColorSpace
//------------------------------------------------------------------------

class GfxLabColorSpace: public GfxColorSpace {
public:

  GfxLabColorSpace();
  ~GfxLabColorSpace() override;
  GfxColorSpace *copy() const override;
  GfxColorSpaceMode getMode() const override { return csLab; }

  // Construct a Lab color space.  Returns nullptr if unsuccessful.
  static GfxColorSpace *parse(Array *arr, GfxState *state);

  void getGray(const GfxColor *color, GfxGray *gray) const override;
  void getRGB(const GfxColor *color, GfxRGB *rgb) const override;
  void getCMYK(const GfxColor *color, GfxCMYK *cmyk) const override;
  void getDeviceN(const GfxColor *color, GfxColor *deviceN) const override;

  int getNComps() const override { return 3; }
  void getDefaultColor(GfxColor *color) const override;

  void getDefaultRanges(double *decodeLow, double *decodeRange,
				int maxImgPixel) const override;

  // Lab-specific access.
  double getWhiteX() const { return whiteX; }
  double getWhiteY() const { return whiteY; }
  double getWhiteZ() const { return whiteZ; }
  double getBlackX() const { return blackX; }
  double getBlackY() const { return blackY; }
  double getBlackZ() const { return blackZ; }
  double getAMin() const { return aMin; }
  double getAMax() const { return aMax; }
  double getBMin() const { return bMin; }
  double getBMax() const { return bMax; }

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
  void getXYZ(const GfxColor *color, double *pX, double *pY, double *pZ) const;
#ifdef USE_CMS
  GfxColorTransform *transform;
#endif
};

//------------------------------------------------------------------------
// GfxICCBasedColorSpace
//------------------------------------------------------------------------

class GfxICCBasedColorSpace: public GfxColorSpace {
public:

  GfxICCBasedColorSpace(int nCompsA, GfxColorSpace *altA);
  ~GfxICCBasedColorSpace() override;
  GfxColorSpace *copy() const override;
  GfxColorSpaceMode getMode() const override { return csICCBased; }

  // Construct an ICCBased color space.  Returns nullptr if unsuccessful.
  static GfxColorSpace *parse(Array *arr, OutputDev *out, GfxState *state, int recursion);

  void getGray(const GfxColor *color, GfxGray *gray) const override;
  void getRGB(const GfxColor *color, GfxRGB *rgb) const override;
  void getCMYK(const GfxColor *color, GfxCMYK *cmyk) const override;
  void getDeviceN(const GfxColor *color, GfxColor *deviceN) const override;
  void getRGBLine(unsigned char *in, unsigned int *out, int length) override;
  void getRGBLine(unsigned char *in, unsigned char *out, int length) override;
  void getRGBXLine(unsigned char *in, unsigned char *out, int length) override;
  void getCMYKLine(unsigned char *in, unsigned char *out, int length) override;
  void getDeviceNLine(unsigned char *in, unsigned char *out, int length) override;

  bool useGetRGBLine() const override;
  bool useGetCMYKLine() const override;
  bool useGetDeviceNLine() const override;

  int getNComps() const override { return nComps; }
  void getDefaultColor(GfxColor *color) const override;

  void getDefaultRanges(double *decodeLow, double *decodeRange,
				int maxImgPixel) const override;

  // 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
#ifdef USE_CMS
  int getIntent() { return (transform != nullptr) ? transform->getIntent() : 0; }
  GfxColorTransform *transform;
  GfxColorTransform *lineTransform; // color transform for line
  mutable std::map<unsigned int, unsigned int> cmsCache;
#endif
};
//------------------------------------------------------------------------
// GfxIndexedColorSpace
//------------------------------------------------------------------------

class GfxIndexedColorSpace: public GfxColorSpace {
public:

  GfxIndexedColorSpace(GfxColorSpace *baseA, int indexHighA);
  ~GfxIndexedColorSpace() override;
  GfxColorSpace *copy() const override;
  GfxColorSpaceMode getMode() const override { return csIndexed; }

  // Construct an Indexed color space.  Returns nullptr if unsuccessful.
  static GfxColorSpace *parse(GfxResources *res, Array *arr, OutputDev *out, GfxState *state, int recursion);

  void getGray(const GfxColor *color, GfxGray *gray) const override;
  void getRGB(const GfxColor *color, GfxRGB *rgb) const override;
  void getCMYK(const GfxColor *color, GfxCMYK *cmyk) const override;
  void getDeviceN(const GfxColor *color, GfxColor *deviceN) const override;
  void getRGBLine(unsigned char *in, unsigned int *out, int length) override;
  void getRGBLine(unsigned char *in, unsigned char *out, int length) override;
  void getRGBXLine(unsigned char *in, unsigned char *out, int length) override;
  void getCMYKLine(unsigned char *in, unsigned char *out, int length) override;
  void getDeviceNLine(unsigned char *in, unsigned char *out, int length) override;

  bool useGetRGBLine() const override { return true; }
  bool useGetCMYKLine() const override { return true; }
  bool useGetDeviceNLine() const override { return true; }

  int getNComps() const override { return 1; }
  void getDefaultColor(GfxColor *color) const override;

  void getDefaultRanges(double *decodeLow, double *decodeRange,
				int maxImgPixel) const override;

  // Indexed-specific access.
  GfxColorSpace *getBase() { return base; }
  int getIndexHigh() const { return indexHigh; }
  unsigned char *getLookup() { return lookup; }
  GfxColor *mapColorToBase(const GfxColor *color, GfxColor *baseColor) const;
  unsigned int getOverprintMask() const { return base->getOverprintMask(); }
  void createMapping(std::vector<GfxSeparationColorSpace*> *separationList, int maxSepComps) override
    { base->createMapping(separationList, maxSepComps); }


private:

  GfxColorSpace *base;		// base color space
  int indexHigh;		// max pixel value
  unsigned char *lookup;		// lookup table
};

//------------------------------------------------------------------------
// GfxSeparationColorSpace
//------------------------------------------------------------------------

class GfxSeparationColorSpace: public GfxColorSpace {
public:

  GfxSeparationColorSpace(GooString *nameA, GfxColorSpace *altA,
			  Function *funcA);
  ~GfxSeparationColorSpace() override;
  GfxColorSpace *copy() const override;
  GfxColorSpaceMode getMode() const override { return csSeparation; }

  // Construct a Separation color space.  Returns nullptr if unsuccessful.
  static GfxColorSpace *parse(GfxResources *res, Array *arr, OutputDev *out, GfxState *state, int recursion);

  void getGray(const GfxColor *color, GfxGray *gray) const override;
  void getRGB(const GfxColor *color, GfxRGB *rgb) const override;
  void getCMYK(const GfxColor *color, GfxCMYK *cmyk) const override;
  void getDeviceN(const GfxColor *color, GfxColor *deviceN) const override;

  void createMapping(std::vector<GfxSeparationColorSpace*> *separationList, int maxSepComps) override;

  int getNComps() const override { return 1; }
  void getDefaultColor(GfxColor *color) const override;

  bool isNonMarking() const override { return nonMarking; }

  // Separation-specific access.
  const GooString *getName() const { return name; }
  GfxColorSpace *getAlt() { return alt; }
  const Function *getFunc() const { return func; }

private:

  GfxSeparationColorSpace(GooString *nameA, GfxColorSpace *altA,
			  Function *funcA, bool nonMarkingA,
			  unsigned int overprintMaskA, int *mappingA);

  GooString *name;		// colorant name
  GfxColorSpace *alt;		// alternate color space
  Function *func;		// tint transform (into alternate color space)
  bool nonMarking;
};

//------------------------------------------------------------------------
// GfxDeviceNColorSpace
//------------------------------------------------------------------------

class GfxDeviceNColorSpace: public GfxColorSpace {
public:

  GfxDeviceNColorSpace(int nCompsA, std::vector<std::string> &&namesA,
		       GfxColorSpace *alt, Function *func, std::vector<GfxSeparationColorSpace*> *sepsCS);
  ~GfxDeviceNColorSpace() override;
  GfxColorSpace *copy() const override;
  GfxColorSpaceMode getMode() const override { return csDeviceN; }

  // Construct a DeviceN color space.  Returns nullptr if unsuccessful.
  static GfxColorSpace *parse(GfxResources *res, Array *arr, OutputDev *out, GfxState *state, int recursion);

  void getGray(const GfxColor *color, GfxGray *gray) const override;
  void getRGB(const GfxColor *color, GfxRGB *rgb) const override;
  void getCMYK(const GfxColor *color, GfxCMYK *cmyk) const override;
  void getDeviceN(const GfxColor *color, GfxColor *deviceN) const override;

  void createMapping(std::vector<GfxSeparationColorSpace*> *separationList, int maxSepComps) override;

  int getNComps() const override { return nComps; }
  void getDefaultColor(GfxColor *color) const override;

  bool isNonMarking() const override { return nonMarking; }

  // DeviceN-specific access.
  const std::string &getColorantName(int i) const { return names[i]; }
  GfxColorSpace *getAlt() { return alt; }
  const Function *getTintTransformFunc() const { return func; }

private:

  GfxDeviceNColorSpace(int nCompsA, const std::vector<std::string> &namesA,
		       GfxColorSpace *alt, Function *func, std::vector<GfxSeparationColorSpace*> *sepsCSA,
		       int *mappingA, bool nonMarkingA, unsigned int overprintMaskA);

  const int nComps;			// number of components
  const std::vector<std::string> names;	// colorant names
  GfxColorSpace *alt;		// alternate color space
  Function *func;		// tint transform (into alternate color space)
  bool nonMarking;
  std::vector<GfxSeparationColorSpace*> *sepsCS; // list of separation cs for spot colorants;
};

//------------------------------------------------------------------------
// GfxPatternColorSpace
//------------------------------------------------------------------------

class GfxPatternColorSpace: public GfxColorSpace {
public:

  GfxPatternColorSpace(GfxColorSpace *underA);
  ~GfxPatternColorSpace() override;
  GfxColorSpace *copy() const override;
  GfxColorSpaceMode getMode() const override { return csPattern; }

  // Construct a Pattern color space.  Returns nullptr if unsuccessful.
  static GfxColorSpace *parse(GfxResources *res, Array *arr, OutputDev *out, GfxState *state, int recursion);

  void getGray(const GfxColor *color, GfxGray *gray) const override;
  void getRGB(const GfxColor *color, GfxRGB *rgb) const override;
  void getCMYK(const GfxColor *color, GfxCMYK *cmyk) const override;
  void getDeviceN(const GfxColor *color, GfxColor *deviceN) const override;

  int getNComps() const override { return 0; }
  void getDefaultColor(GfxColor *color) const override;

  // Pattern-specific access.
  GfxColorSpace *getUnder() { return under; }

private:

  GfxColorSpace *under;		// underlying color space (for uncolored
				//   patterns)
};

//------------------------------------------------------------------------
// GfxPattern
//------------------------------------------------------------------------

class GfxPattern {
public:

  GfxPattern(int typeA, int patternRefNumA);
  virtual ~GfxPattern();

  GfxPattern(const GfxPattern &) = delete;
  GfxPattern& operator=(const GfxPattern &other) = delete;

  static GfxPattern *parse(GfxResources *res, Object *obj, OutputDev *out, GfxState *state, int patternRefNum);

  virtual GfxPattern *copy() const = 0;

  int getType() const { return type; }

  int getPatternRefNum() const { return patternRefNum; }

private:

  int type;
  int patternRefNum;
};

//------------------------------------------------------------------------
// GfxTilingPattern
//------------------------------------------------------------------------

class GfxTilingPattern: public GfxPattern {
public:

  static GfxTilingPattern *parse(Object *patObj, int patternRefNum);
  ~GfxTilingPattern() override;

  GfxPattern *copy() const override;

  int getPaintType() const { return paintType; }
  int getTilingType() const { return tilingType; }
  const double *getBBox() const { return bbox; }
  double getXStep() const { return xStep; }
  double getYStep() const { return yStep; }
  Dict *getResDict()
    { return resDict.isDict() ? resDict.getDict() : (Dict *)nullptr; }
  const double *getMatrix() const { return matrix; }
  Object *getContentStream() { return &contentStream; }

private:

  GfxTilingPattern(int paintTypeA, int tilingTypeA,
		   const double *bboxA, double xStepA, double yStepA,
		   const Object *resDictA, const double *matrixA,
		   const Object *contentStreamA, int patternRefNumA);

  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(GfxResources *res, Object *patObj, OutputDev *out, GfxState *state, int patternRefNum);
  ~GfxShadingPattern() override;

  GfxPattern *copy() const override;

  GfxShading *getShading() { return shading; }
  const double *getMatrix() const { return matrix; }

private:

  GfxShadingPattern(GfxShading *shadingA, const double *matrixA, int patternRefNumA);

  GfxShading *shading;
  double matrix[6];
};

//------------------------------------------------------------------------
// GfxShading
//------------------------------------------------------------------------

class GfxShading {
public:

  GfxShading(int typeA);
  GfxShading(const GfxShading *shading);
  virtual ~GfxShading();

  GfxShading(const GfxShading &) = delete;
  GfxShading& operator=(const GfxShading &other) = delete;

  static GfxShading *parse(GfxResources *res, Object *obj, OutputDev *out, GfxState *state);

  virtual GfxShading *copy() const = 0;

  int getType() const { return type; }
  GfxColorSpace *getColorSpace() { return colorSpace; }
  const GfxColor *getBackground() const { return &background; }
  bool getHasBackground() const { return hasBackground; }
  void getBBox(double *xMinA, double *yMinA, double *xMaxA, double *yMaxA) const
    { *xMinA = bbox_xMin; *yMinA = bbox_yMin; *xMaxA = bbox_xMax; *yMaxA = bbox_yMax; }
  bool getHasBBox() const { return hasBBox; }

protected:

  bool init(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state);

  // 1: Function-based shading
  // 2: Axial shading
  // 3: Radial shading
  // 4: Free-form Gouraud-shaded triangle mesh
  // 5: Lattice-form Gouraud-shaded triangle mesh
  // 6: Coons patch mesh
  // 7: Tensor-product patch mesh
  int type;
  bool hasBackground;
  bool hasBBox;
  GfxColorSpace *colorSpace;
  GfxColor background;
  double bbox_xMin, bbox_yMin, bbox_xMax, bbox_yMax;
};

//------------------------------------------------------------------------
// GfxUnivariateShading
//------------------------------------------------------------------------

class GfxUnivariateShading: public GfxShading {
public:

  GfxUnivariateShading(int typeA,
		       double t0A, double t1A,
		       Function **funcsA, int nFuncsA,
		       bool extend0A, bool extend1A);
  GfxUnivariateShading(const GfxUnivariateShading *shading);
  ~GfxUnivariateShading() override;

  double getDomain0() const { return t0; }
  double getDomain1() const { return t1; }
  bool getExtend0() const { return extend0; }
  bool getExtend1() const { return extend1; }
  int getNFuncs() const { return nFuncs; }
  const Function *getFunc(int i) const { return funcs[i]; }
  // returns the nComps of the shading
  // i.e. how many positions of color have been set
  int getColor(double t, GfxColor *color);

  void setupCache(const Matrix *ctm,
		  double xMin, double yMin,
		  double xMax, double yMax);

  virtual void getParameterRange(double *lower, double *upper,
				 double xMin, double yMin,
				 double xMax, double yMax) = 0;

  virtual double getDistance(double sMin, double sMax) const = 0;

private:

  double t0, t1;
  Function *funcs[gfxColorMaxComps];
  int nFuncs;
  bool extend0, extend1;

  int cacheSize, lastMatch;
  double *cacheBounds;
  double *cacheCoeff;
  double *cacheValues;
};

//------------------------------------------------------------------------
// GfxFunctionShading
//------------------------------------------------------------------------

class GfxFunctionShading: public GfxShading {
public:

  GfxFunctionShading(double x0A, double y0A,
		     double x1A, double y1A,
		     const double *matrixA,
		     Function **funcsA, int nFuncsA);
  GfxFunctionShading(const GfxFunctionShading *shading);
  ~GfxFunctionShading() override;

  static GfxFunctionShading *parse(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state);

  GfxShading *copy() const override;

  void getDomain(double *x0A, double *y0A, double *x1A, double *y1A) const
    { *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; }
  const double *getMatrix() const { return matrix; }
  int getNFuncs() const { return nFuncs; }
  const Function *getFunc(int i) const { return funcs[i]; }
  void getColor(double x, double y, GfxColor *color) const;

private:

  double x0, y0, x1, y1;
  double matrix[6];
  Function *funcs[gfxColorMaxComps];
  int nFuncs;
};

//------------------------------------------------------------------------
// GfxAxialShading
//------------------------------------------------------------------------

class GfxAxialShading: public GfxUnivariateShading {
public:

  GfxAxialShading(double x0A, double y0A,
		  double x1A, double y1A,
		  double t0A, double t1A,
		  Function **funcsA, int nFuncsA,
		  bool extend0A, bool extend1A);
  GfxAxialShading(const GfxAxialShading *shading);
  ~GfxAxialShading() override;

  static GfxAxialShading *parse(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state);

  GfxShading *copy() const override;

  void getCoords(double *x0A, double *y0A, double *x1A, double *y1A) const
    { *x0A = x0; *y0A = y0; *x1A = x1; *y1A = y1; }

  void getParameterRange(double *lower, double *upper,
				 double xMin, double yMin,
				 double xMax, double yMax) override;

  double getDistance(double sMin, double sMax) const override;

private:

  double x0, y0, x1, y1;
};

//------------------------------------------------------------------------
// GfxRadialShading
//------------------------------------------------------------------------

class GfxRadialShading: public GfxUnivariateShading {
public:

  GfxRadialShading(double x0A, double y0A, double r0A,
		   double x1A, double y1A, double r1A,
		   double t0A, double t1A,
		   Function **funcsA, int nFuncsA,
		   bool extend0A, bool extend1A);
  GfxRadialShading(const GfxRadialShading *shading);
  ~GfxRadialShading() override;

  static GfxRadialShading *parse(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state);

  GfxShading *copy() const override;

  void getCoords(double *x0A, double *y0A, double *r0A,
		 double *x1A, double *y1A, double *r1A) const
    { *x0A = x0; *y0A = y0; *r0A = r0; *x1A = x1; *y1A = y1; *r1A = r1; }

  void getParameterRange(double *lower, double *upper,
				 double xMin, double yMin,
				 double xMax, double yMax) override;

  double getDistance(double sMin, double sMax) const override;

private:

  double x0, y0, r0, x1, y1, r1;
};

//------------------------------------------------------------------------
// GfxGouraudTriangleShading
//------------------------------------------------------------------------

struct GfxGouraudVertex {
  double x, y;
  GfxColor color;
};

class GfxGouraudTriangleShading: public GfxShading {
public:

  GfxGouraudTriangleShading(int typeA,
			    GfxGouraudVertex *verticesA, int nVerticesA,
			    int (*trianglesA)[3], int nTrianglesA,
			    Function **funcsA, int nFuncsA);
  GfxGouraudTriangleShading(const GfxGouraudTriangleShading *shading);
  ~GfxGouraudTriangleShading() override;

  static GfxGouraudTriangleShading *parse(GfxResources *res, int typeA, Dict *dict, Stream *str, OutputDev *out, GfxState *state);

  GfxShading *copy() const override;

  int getNTriangles() const { return nTriangles; }

  bool isParameterized() const { return nFuncs > 0; }

  /**
   * @precondition isParameterized() == true
   */
  double getParameterDomainMin() const { assert(isParameterized()); return funcs[0]->getDomainMin(0); }

  /**
   * @precondition isParameterized() == true
   */
  double getParameterDomainMax() const { assert(isParameterized()); return funcs[0]->getDomainMax(0); }

  /**
   * @precondition isParameterized() == false
   */
  void getTriangle(int i, double *x0, double *y0, GfxColor *color0,
		   double *x1, double *y1, GfxColor *color1,
		   double *x2, double *y2, GfxColor *color2);

  /**
   * Variant for functions.
   *
   * @precondition isParameterized() == true
   */
  void getTriangle(int i, double *x0, double *y0, double *color0,
		   double *x1, double *y1, double *color1,
		   double *x2, double *y2, double *color2);

  void getParameterizedColor(double t, GfxColor *color) const;

private:

  GfxGouraudVertex *vertices;
  int nVertices;
  int (*triangles)[3];
  int nTriangles;
  Function *funcs[gfxColorMaxComps];
  int nFuncs;
};

//------------------------------------------------------------------------
// GfxPatchMeshShading
//------------------------------------------------------------------------

/**
 * A tensor product cubic bezier patch consisting of 4x4 points and 4 color
 * values.
 *
 * See the Shading Type 7 specifications. Note that Shading Type 6 is also
 * represented using GfxPatch.
 */
struct GfxPatch {
  /**
   * Represents a single color value for the patch.
   */
  struct ColorValue {
    /**
     * For parameterized patches, only element 0 is valid; it contains
     * the single parameter.
     *
     * For non-parameterized patches, c contains all color components
     * as decoded from the input stream. In this case, you will need to
     * use dblToCol() before assigning them to GfxColor.
     */
    double c[gfxColorMaxComps];
  };

  double x[4][4];
  double y[4][4];
  ColorValue color[2][2];
};

class GfxPatchMeshShading: public GfxShading {
public:

  GfxPatchMeshShading(int typeA, GfxPatch *patchesA, int nPatchesA,
		      Function **funcsA, int nFuncsA);
  GfxPatchMeshShading(const GfxPatchMeshShading *shading);
  ~GfxPatchMeshShading() override;

  static GfxPatchMeshShading *parse(GfxResources *res, int typeA, Dict *dict, Stream *str, OutputDev *out, GfxState *state);

  GfxShading *copy() const override;

  int getNPatches() const { return nPatches; }
  const GfxPatch *getPatch(int i) const { return &patches[i]; }

  bool isParameterized() const { return nFuncs > 0; }

  /**
   * @precondition isParameterized() == true
   */
  double getParameterDomainMin() const { assert(isParameterized()); return funcs[0]->getDomainMin(0); }

  /**
   * @precondition isParameterized() == true
   */
  double getParameterDomainMax() const { assert(isParameterized()); return funcs[0]->getDomainMax(0); }

  void getParameterizedColor(double t, GfxColor *color) const;

private:

  GfxPatch *patches;
  int nPatches;
  Function *funcs[gfxColorMaxComps];
  int nFuncs;
};

//------------------------------------------------------------------------
// GfxImageColorMap
//------------------------------------------------------------------------

class GfxImageColorMap {
public:

  // Constructor.
  GfxImageColorMap(int bitsA, Object *decode, GfxColorSpace *colorSpaceA);

  // Destructor.
  ~GfxImageColorMap();

  GfxImageColorMap(const GfxImageColorMap &) = delete;
  GfxImageColorMap& operator=(const GfxImageColorMap &) = delete;

  // Return a copy of this color map.
  GfxImageColorMap *copy() const { return new GfxImageColorMap(this); }

  // Is color map valid?
  bool isOk() const { return ok; }

  // Get the color space.
  GfxColorSpace *getColorSpace() { return colorSpace; }

  // Get stream decoding info.
  int getNumPixelComps() const { return nComps; }
  int getBits() const { return bits; }

  // Get decode table.
  double getDecodeLow(int i) const { return decodeLow[i]; }
  double getDecodeHigh(int i) const { return decodeLow[i] + decodeRange[i]; }
  
  bool useRGBLine() const { return (colorSpace2 && colorSpace2->useGetRGBLine ()) || (!colorSpace2 && colorSpace->useGetRGBLine ()); }
  bool useCMYKLine() const { return (colorSpace2 && colorSpace2->useGetCMYKLine ()) || (!colorSpace2 && colorSpace->useGetCMYKLine ()); }
  bool useDeviceNLine() const { return (colorSpace2 && colorSpace2->useGetDeviceNLine ()) || (!colorSpace2 && colorSpace->useGetDeviceNLine ()); }

  // Convert an image pixel to a color.
  void getGray(const unsigned char *x, GfxGray *gray);
  void getRGB(const unsigned char *x, GfxRGB *rgb);
  void getRGBLine(unsigned char *in, unsigned int *out, int length);
  void getRGBLine(unsigned char *in, unsigned char *out, int length);
  void getRGBXLine(unsigned char *in, unsigned char *out, int length);
  void getGrayLine(unsigned char *in, unsigned char *out, int length);
  void getCMYKLine(unsigned char *in, unsigned char *out, int length);
  void getDeviceNLine(unsigned char *in, unsigned char *out, int length);
  void getCMYK(const unsigned char *x, GfxCMYK *cmyk);
  void getDeviceN(const unsigned char *x, GfxColor *deviceN);
  void getColor(const unsigned char *x, GfxColor *color);

  // Matte color ops
  void setMatteColor(const GfxColor *color) { useMatte = true; matteColor = *color; }
  const GfxColor *getMatteColor() const { return (useMatte) ? &matteColor : nullptr; }
private:

  GfxImageColorMap(const GfxImageColorMap *colorMap);

  GfxColorSpace *colorSpace;	// the image color space
  int bits;			// bits per component
  int nComps;			// number of components in a pixel
  GfxColorSpace *colorSpace2;	// secondary color space
  int nComps2;			// number of components in colorSpace2
  GfxColorComp *		// lookup table
    lookup[gfxColorMaxComps];
  GfxColorComp *		// optimized case lookup table
    lookup2[gfxColorMaxComps];
  unsigned char *byte_lookup;
  double			// minimum values for each component
    decodeLow[gfxColorMaxComps];
  double			// max - min value for each component
    decodeRange[gfxColorMaxComps];
  bool useMatte;
  GfxColor matteColor;
  bool ok;
};

//------------------------------------------------------------------------
// GfxSubpath and GfxPath
//------------------------------------------------------------------------

class GfxSubpath {
public:

  // Constructor.
  GfxSubpath(double x1, double y1);

  // Destructor.
  ~GfxSubpath();

  GfxSubpath(const GfxSubpath &) = delete;
  GfxSubpath& operator=(const GfxSubpath &) = delete;

  // Copy.
  GfxSubpath *copy() const { return new GfxSubpath(this); }

  // Get points.
  int getNumPoints() const { return n; }
  double getX(int i) const { return x[i]; }
  double getY(int i) const { return y[i]; }
  bool getCurve(int i) const { return curve[i]; }

  void setX(int i, double a) { x[i] = a; }
  void setY(int i, double a) { y[i] = a; }

  // Get last point.
  double getLastX() const { return x[n-1]; }
  double getLastY() const { return y[n-1]; }

  // Add a line segment.
  void lineTo(double x1, double y1);

  // Add a Bezier curve.
  void curveTo(double x1, double y1, double x2, double y2,
	       double x3, double y3);

  // Close the subpath.
  void close();
  bool isClosed() const { return closed; }

  // Add (<dx>, <dy>) to each point in the subpath.
  void offset(double dx, double dy);

private:

  double *x, *y;		// points
  bool *curve;			// curve[i] => point i is a control point
				//   for a Bezier curve
  int n;			// number of points
  int size;			// size of x/y arrays
  bool closed;			// set if path is closed

  GfxSubpath(const GfxSubpath *subpath);
};

class GfxPath {
public:

  // Constructor.
  GfxPath();

  // Destructor.
  ~GfxPath();

  GfxPath(const GfxPath &) = delete;
  GfxPath& operator=(const GfxPath &) = delete;

  // Copy.
  GfxPath *copy() const
    { return new GfxPath(justMoved, firstX, firstY, subpaths, n, size); }

  // Is there a current point?
  bool isCurPt() const { return n > 0 || justMoved; }

  // Is the path non-empty, i.e., is there at least one segment?
  bool isPath() const { return n > 0; }

  // Get subpaths.
  int getNumSubpaths() const { return n; }
  GfxSubpath *getSubpath(int i) { return subpaths[i]; }
  const GfxSubpath *getSubpath(int i) const { return subpaths[i]; }

  // Get last point on last subpath.
  double getLastX() const { return subpaths[n-1]->getLastX(); }
  double getLastY() const { return subpaths[n-1]->getLastY(); }

  // Move the current point.
  void moveTo(double x, double y);

  // Add a segment to the last subpath.
  void lineTo(double x, double y);

  // Add a Bezier curve to the last subpath
  void curveTo(double x1, double y1, double x2, double y2,
	       double x3, double y3);

  // Close the last subpath.
  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:

  bool justMoved;		// set if a new subpath was just started
  double firstX, firstY;	// first point in new subpath
  GfxSubpath **subpaths;	// subpaths
  int n;			// number of subpaths
  int size;			// size of subpaths array

  GfxPath(bool justMoved1, double firstX1, double firstY1,
	  GfxSubpath **subpaths1, int n1, int size1);
};

//------------------------------------------------------------------------
// GfxState
//------------------------------------------------------------------------

class GfxState {
public:
  /**
   * When GfxState::getReusablePath() is invoked, the currently active
   * path is taken per reference and its coordinates can be re-edited.
   *
   * A ReusablePathIterator is intended to reduce overhead when the same
   * path type is used a lot of times, only with different coordinates. It
   * allows just to update the coordinates (occurring in the same order as
   * in the original path).
   */
  class ReusablePathIterator {
  public:
    /**
     * Creates the ReusablePathIterator. This should only be done from
     * GfxState::getReusablePath().
     *
     * @param path the path as it is used so far. Changing this path,
     * deleting it or starting a new path from scratch will most likely
     * invalidate the iterator (and may cause serious problems). Make
     * sure the path's memory structure is not changed during the
     * lifetime of the ReusablePathIterator.
     */
    ReusablePathIterator( GfxPath* path );

    /**
     * Returns true if and only if the current iterator position is
     * beyond the last valid point.
     *
     * A call to setCoord() will be undefined.
     */
    bool isEnd() const;

    /**
     * Advances the iterator.
     */
    void next();

     /**
     * Updates the coordinates associated to the current iterator
     * position.
     */
     void setCoord( double x, double y );

    /**
     * Resets the iterator.
     */
    void reset();
  private:
    GfxPath *path;
    int subPathOff;

    int coordOff;
    int numCoords;

    GfxSubpath *curSubPath;
  };

  // Construct a default GfxState, for a device with resolution <hDPI>
  // x <vDPI>, page box <pageBox>, page rotation <rotateA>, and
  // coordinate system specified by <upsideDown>.
  GfxState(double hDPIA, double vDPIA, const PDFRectangle *pageBox,
	   int rotateA, bool upsideDown);

  // Destructor.
  ~GfxState();

  GfxState(const GfxState &) = delete;
  GfxState& operator=(const GfxState &) = delete;

  // Copy.
  GfxState *copy(bool copyPath = false) const
    { return new GfxState(this, copyPath); }

  // Accessors.
  double getHDPI() const { return hDPI; }
  double getVDPI() const { return vDPI; }
  const double *getCTM() const { return ctm; }
  void getCTM(Matrix *m) const { memcpy (m->m, ctm, sizeof m->m); }
  double getX1() const { return px1; }
  double getY1() const { return py1; }
  double getX2() const { return px2; }
  double getY2() const { return py2; }
  double getPageWidth() const { return pageWidth; }
  double getPageHeight() const { return pageHeight; }
  int getRotate() const { return rotate; }
  const GfxColor *getFillColor() const { return &fillColor; }
  const GfxColor *getStrokeColor() const { return &strokeColor; }
  void getFillGray(GfxGray *gray)
    { fillColorSpace->getGray(&fillColor, gray); }
  void getStrokeGray(GfxGray *gray)
    { strokeColorSpace->getGray(&strokeColor, gray); }
  void getFillRGB(GfxRGB *rgb) const
    { fillColorSpace->getRGB(&fillColor, rgb); }
  void getStrokeRGB(GfxRGB *rgb) const
    { strokeColorSpace->getRGB(&strokeColor, rgb); }
  void getFillCMYK(GfxCMYK *cmyk)
    { fillColorSpace->getCMYK(&fillColor, cmyk); }
  void getFillDeviceN(GfxColor *deviceN)
    { fillColorSpace->getDeviceN(&fillColor, deviceN); }
  void getStrokeCMYK(GfxCMYK *cmyk)
    { strokeColorSpace->getCMYK(&strokeColor, cmyk); }
  void getStrokeDeviceN(GfxColor *deviceN)
    { strokeColorSpace->getDeviceN(&strokeColor, deviceN); }
  GfxColorSpace *getFillColorSpace() { return fillColorSpace; }
  GfxColorSpace *getStrokeColorSpace() { return strokeColorSpace; }
  GfxPattern *getFillPattern() { return fillPattern; }
  GfxPattern *getStrokePattern() { return strokePattern; }
  GfxBlendMode getBlendMode() const { return blendMode; }
  double getFillOpacity() const { return fillOpacity; }
  double getStrokeOpacity() const { return strokeOpacity; }
  bool getFillOverprint() const { return fillOverprint; }
  bool getStrokeOverprint() const { return strokeOverprint; }
  int getOverprintMode() const { return overprintMode; }
  Function **getTransfer() { return transfer; }
  double getLineWidth() const { return lineWidth; }
  void getLineDash(double **dash, int *length, double *start)
    { *dash = lineDash; *length = lineDashLength; *start = lineDashStart; }
  int getFlatness() const { return flatness; }
  int getLineJoin() const { return lineJoin; }
  int getLineCap() const { return lineCap; }
  double getMiterLimit() const { return miterLimit; }
  bool getStrokeAdjust() const { return strokeAdjust; }
  bool getAlphaIsShape() const { return alphaIsShape; }
  bool getTextKnockout() const { return textKnockout; }
  GfxFont *getFont() const { return font; }
  double getFontSize() const { return fontSize; }
  const double *getTextMat() const { return textMat; }
  double getCharSpace() const { return charSpace; }
  double getWordSpace() const { return wordSpace; }
  double getHorizScaling() const { return horizScaling; }
  double getLeading() const { return leading; }
  double getRise() const { return rise; }
  int getRender() const { return render; }
  const char *getRenderingIntent() const { return renderingIntent; }
  const GfxPath *getPath() const { return path; }
  void setPath(GfxPath *pathA);
  double getCurX() const { return curX; }
  double getCurY() const { return curY; }
  void getClipBBox(double *xMin, double *yMin, double *xMax, double *yMax) const
    { *xMin = clipXMin; *yMin = clipYMin; *xMax = clipXMax; *yMax = clipYMax; }
  void getUserClipBBox(double *xMin, double *yMin, double *xMax, double *yMax) const;
  double getLineX() const { return lineX; }
  double getLineY() const { return lineY; }

  // Is there a current point/path?
  bool isCurPt() const { return path->isCurPt(); }
  bool isPath() const { return path->isPath(); }

  // Transforms.
  void transform(double x1, double y1, double *x2, double *y2) const
    { *x2 = ctm[0] * x1 + ctm[2] * y1 + ctm[4];
      *y2 = ctm[1] * x1 + ctm[3] * y1 + ctm[5]; }
  void transformDelta(double x1, double y1, double *x2, double *y2) const
    { *x2 = ctm[0] * x1 + ctm[2] * y1;
      *y2 = ctm[1] * x1 + ctm[3] * y1; }
  void textTransform(double x1, double y1, double *x2, double *y2) const
    { *x2 = textMat[0] * x1 + textMat[2] * y1 + textMat[4];
      *y2 = textMat[1] * x1 + textMat[3] * y1 + textMat[5]; }
  void textTransformDelta(double x1, double y1, double *x2, double *y2) const
    { *x2 = textMat[0] * x1 + textMat[2] * y1;
      *y2 = textMat[1] * x1 + textMat[3] * y1; }
  double transformWidth(double w) const;
  double getTransformedLineWidth() const
    { return transformWidth(lineWidth); }
  double getTransformedFontSize() const;
  void getFontTransMat(double *m11, double *m12, double *m21, double *m22) const;

  // 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 shiftCTMAndClip(double tx, double ty);
  void setFillColorSpace(GfxColorSpace *colorSpace);
  void setStrokeColorSpace(GfxColorSpace *colorSpace);
  void setFillColor(const GfxColor *color) { fillColor = *color; }
  void setStrokeColor(const GfxColor *color) { strokeColor = *color; }
  void setFillPattern(GfxPattern *pattern);
  void setStrokePattern(GfxPattern *pattern);
  void setBlendMode(GfxBlendMode mode) { blendMode = mode; }
  void setFillOpacity(double opac) { fillOpacity = opac; }
  void setStrokeOpacity(double opac) { strokeOpacity = opac; }
  void setFillOverprint(bool op) { fillOverprint = op; }
  void setStrokeOverprint(bool op) { strokeOverprint = op; }
  void setOverprintMode(int op) { overprintMode = op; }
  void setTransfer(Function **funcs);
  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 limit) { miterLimit = limit; }
  void setStrokeAdjust(bool sa) { strokeAdjust = sa; }
  void setAlphaIsShape(bool ais) { alphaIsShape = ais; }
  void setTextKnockout(bool tk) { textKnockout = tk; }
  void setFont(GfxFont *fontA, double fontSizeA);
  void setTextMat(double a, double b, double c,
		  double d, double e, double f)
    { textMat[0] = a; textMat[1] = b; textMat[2] = c;
      textMat[3] = d; textMat[4] = e; textMat[5] = f; }
  void setCharSpace(double space)
    { charSpace = space; }
  void setWordSpace(double space)
    { wordSpace = space; }
  void setHorizScaling(double scale)
    { horizScaling = 0.01 * scale; }
  void setLeading(double leadingA)
    { leading = leadingA; }
  void setRise(double riseA)
    { rise = riseA; }
  void setRender(int renderA)
    { render = renderA; }
  void setRenderingIntent(const char *intent)
    { strncpy(renderingIntent, intent, 31); }

#ifdef USE_CMS
  void setDisplayProfile(void *localDisplayProfileA);
  void *getDisplayProfile() { return localDisplayProfile; }
  GfxColorTransform *getXYZ2DisplayTransform();
#endif

  // Add to path.
  void moveTo(double x, double y)
    { path->moveTo(curX = x, curY = y); }
  void lineTo(double x, double y)
    { path->lineTo(curX = x, curY = y); }
  void curveTo(double x1, double y1, double x2, double y2,
	       double x3, double y3)
    { path->curveTo(x1, y1, x2, y2, curX = x3, curY = y3); }
  void closePath()
    { path->close(); curX = path->getLastX(); curY = path->getLastY(); }
  void clearPath();

  // Update clip region.
  void clip();
  void clipToStrokePath();
  void clipToRect(double xMin, double yMin, double xMax, double yMax);

  // 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, double ty);
  void shift(double dx, double dy);

  // Push/pop GfxState on/off stack.
  GfxState *save();
  GfxState *restore();
  bool hasSaves() const { return saved != nullptr; }
  bool isParentState(GfxState *state) { return saved == state || (saved && saved->isParentState(state)); }

  // Misc
  bool parseBlendMode(Object *obj, GfxBlendMode *mode);

  ReusablePathIterator *getReusablePath() { return new ReusablePathIterator(path); }
private:

  double hDPI, vDPI;		// resolution
  double ctm[6];		// coord transform matrix
  double px1, py1, px2, py2;	// page corners (user coords)
  double pageWidth, pageHeight;	// page size (pixels)
  int rotate;			// page rotation angle

  GfxColorSpace *fillColorSpace;   // fill color space
  GfxColorSpace *strokeColorSpace; // stroke color space
  GfxColor fillColor;		// fill color
  GfxColor strokeColor;		// stroke color
  GfxPattern *fillPattern;	// fill pattern
  GfxPattern *strokePattern;	// stroke pattern
  GfxBlendMode blendMode;	// transparency blend mode
  double fillOpacity;		// fill opacity
  double strokeOpacity;		// stroke opacity
  bool fillOverprint;		// fill overprint
  bool strokeOverprint;	// stroke overprint
  int overprintMode;		// overprint mode
  Function *transfer[4];	// transfer function (entries may be: all
				//   nullptr = identity; last three nullptr =
				//   single function; all four non-nullptr =
				//   R,G,B,gray functions)

  double lineWidth;		// line width
  double *lineDash;		// line dash
  int lineDashLength;
  double lineDashStart;
  int flatness;			// curve flatness
  int lineJoin;			// line join style
  int lineCap;			// line cap style
  double miterLimit;		// line miter limit
  bool strokeAdjust;		// stroke adjustment
  bool alphaIsShape;		// alpha is shape
  bool textKnockout;		// text knockout

  GfxFont *font;		// font
  double fontSize;		// font size
  double textMat[6];		// text matrix
  double charSpace;		// character spacing
  double wordSpace;		// word spacing
  double horizScaling;		// horizontal scaling
  double leading;		// text leading
  double rise;			// text rise
  int render;			// text rendering mode

  GfxPath *path;		// array of path elements
  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;
  char renderingIntent[32];

  GfxState *saved;		// next GfxState on stack

  GfxState(const GfxState *state, bool copyPath);

#ifdef USE_CMS
  void *localDisplayProfile;
  int displayProfileRef;
  GfxColorTransform *XYZ2DisplayTransformRelCol;
  GfxColorTransform *XYZ2DisplayTransformAbsCol;
  GfxColorTransform *XYZ2DisplayTransformSat;
  GfxColorTransform *XYZ2DisplayTransformPerc;
#endif
};

#endif
