//========================================================================
//
// Gfx.cc
//
// Copyright 1996-2013 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 Jonathan Blandford <jrb@redhat.com>
// Copyright (C) 2005-2013, 2015-2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2006 Thorkild Stray <thorkild@ifi.uio.no>
// Copyright (C) 2006 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2006-2011 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2006, 2007 Jeff Muizelaar <jeff@infidigm.net>
// Copyright (C) 2007, 2008 Brad Hards <bradh@kde.org>
// Copyright (C) 2007, 2011, 2017 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2007, 2008 Iñigo Martínez <inigomartinez@gmail.com>
// Copyright (C) 2007 Koji Otani <sho@bbr.jp>
// Copyright (C) 2007 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
// Copyright (C) 2008 Pino Toscano <pino@kde.org>
// Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu>
// Copyright (C) 2008 Hib Eris <hib@hiberis.nl>
// Copyright (C) 2009 M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
// Copyright (C) 2009-2016 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2009 William Bader <williambader@hotmail.com>
// Copyright (C) 2009, 2010 David Benjamin <davidben@mit.edu>
// Copyright (C) 2010 Nils Höglund <nils.hoglund@gmail.com>
// Copyright (C) 2010 Christian Feuersänger <cfeuersaenger@googlemail.com>
// Copyright (C) 2011 Axel Strübing <axel.struebing@freenet.de>
// Copyright (C) 2012 Even Rouault <even.rouault@mines-paris.org>
// Copyright (C) 2012, 2013 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2012 Lu Wang <coolwanglu@gmail.com>
// Copyright (C) 2014 Jason Crain <jason@aquaticape.us>
// Copyright (C) 2017, 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
// Copyright (C) 2018, 2019 Adam Reichold <adam.reichold@t-online.de>
// Copyright (C) 2018 Denis Onishchenko <denis.onischenko@gmail.com>
// Copyright (C) 2019 LE GARREC Vincent <legarrec.vincent@gmail.com>
//
// 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
//
//========================================================================

#include <config.h>

#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <math.h>
#include <memory>
#include "goo/gmem.h"
#include "goo/GooTimer.h"
#include "GlobalParams.h"
#include "CharTypes.h"
#include "Object.h"
#include "PDFDoc.h"
#include "Array.h"
#include "Annot.h"
#include "Dict.h"
#include "Stream.h"
#include "Lexer.h"
#include "Parser.h"
#include "GfxFont.h"
#include "GfxState.h"
#include "OutputDev.h"
#include "Page.h"
#include "Annot.h"
#include "Error.h"
#include "Gfx.h"
#include "ProfileData.h"
#include "Catalog.h"
#include "OptionalContent.h"

// the MSVC math.h doesn't define this
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

//------------------------------------------------------------------------
// constants
//------------------------------------------------------------------------

// Max recursive depth for a function shading fill.
#define functionMaxDepth 6

// Max delta allowed in any color component for a function shading fill.
#define functionColorDelta (dblToCol(1 / 256.0))

// Max number of splits along the t axis for an axial shading fill.
#define axialMaxSplits 256

// Max delta allowed in any color component for an axial shading fill.
#define axialColorDelta (dblToCol(1 / 256.0))

// Max number of splits along the t axis for a radial shading fill.
#define radialMaxSplits 256

// Max delta allowed in any color component for a radial shading fill.
#define radialColorDelta (dblToCol(1 / 256.0))

// Max recursive depth for a Gouraud triangle shading fill.
//
// Triangles will be split at most gouraudMaxDepth times (each time into 4
// smaller ones). That makes pow(4,gouraudMaxDepth) many triangles for
// every triangle.
#define gouraudMaxDepth 6

// Max delta allowed in any color component for a Gouraud triangle
// shading fill.
#define gouraudColorDelta (dblToCol(3. / 256.0))

// Gouraud triangle: if the three color parameters differ by at more than this percend of 
// the total color parameter range, the triangle will be refined
#define gouraudParameterizedColorDelta 5e-3

// Max recursive depth for a patch mesh shading fill.
#define patchMaxDepth 6

// Max delta allowed in any color component for a patch mesh shading
// fill.
#define patchColorDelta (dblToCol((3. / 256.0)))

//------------------------------------------------------------------------
// Operator table
//------------------------------------------------------------------------

Operator Gfx::opTab[] = {
  {"\"",  3, {tchkNum,    tchkNum,    tchkString},
          &Gfx::opMoveSetShowText},
  {"'",   1, {tchkString},
          &Gfx::opMoveShowText},
  {"B",   0, {tchkNone},
          &Gfx::opFillStroke},
  {"B*",  0, {tchkNone},
          &Gfx::opEOFillStroke},
  {"BDC", 2, {tchkName,   tchkProps},
          &Gfx::opBeginMarkedContent},
  {"BI",  0, {tchkNone},
          &Gfx::opBeginImage},
  {"BMC", 1, {tchkName},
          &Gfx::opBeginMarkedContent},
  {"BT",  0, {tchkNone},
          &Gfx::opBeginText},
  {"BX",  0, {tchkNone},
          &Gfx::opBeginIgnoreUndef},
  {"CS",  1, {tchkName},
          &Gfx::opSetStrokeColorSpace},
  {"DP",  2, {tchkName,   tchkProps},
          &Gfx::opMarkPoint},
  {"Do",  1, {tchkName},
          &Gfx::opXObject},
  {"EI",  0, {tchkNone},
          &Gfx::opEndImage},
  {"EMC", 0, {tchkNone},
          &Gfx::opEndMarkedContent},
  {"ET",  0, {tchkNone},
          &Gfx::opEndText},
  {"EX",  0, {tchkNone},
          &Gfx::opEndIgnoreUndef},
  {"F",   0, {tchkNone},
          &Gfx::opFill},
  {"G",   1, {tchkNum},
          &Gfx::opSetStrokeGray},
  {"ID",  0, {tchkNone},
          &Gfx::opImageData},
  {"J",   1, {tchkInt},
          &Gfx::opSetLineCap},
  {"K",   4, {tchkNum,    tchkNum,    tchkNum,    tchkNum},
          &Gfx::opSetStrokeCMYKColor},
  {"M",   1, {tchkNum},
          &Gfx::opSetMiterLimit},
  {"MP",  1, {tchkName},
          &Gfx::opMarkPoint},
  {"Q",   0, {tchkNone},
          &Gfx::opRestore},
  {"RG",  3, {tchkNum,    tchkNum,    tchkNum},
          &Gfx::opSetStrokeRGBColor},
  {"S",   0, {tchkNone},
          &Gfx::opStroke},
  {"SC",  -4, {tchkNum,   tchkNum,    tchkNum,    tchkNum},
          &Gfx::opSetStrokeColor},
  {"SCN", -33, {tchkSCN,   tchkSCN,    tchkSCN,    tchkSCN,
	        tchkSCN,   tchkSCN,    tchkSCN,    tchkSCN,
	        tchkSCN,   tchkSCN,    tchkSCN,    tchkSCN,
	        tchkSCN,   tchkSCN,    tchkSCN,    tchkSCN,
	        tchkSCN,   tchkSCN,    tchkSCN,    tchkSCN,
	        tchkSCN,   tchkSCN,    tchkSCN,    tchkSCN,
	        tchkSCN,   tchkSCN,    tchkSCN,    tchkSCN,
	        tchkSCN,   tchkSCN,    tchkSCN,    tchkSCN,
	        tchkSCN},
          &Gfx::opSetStrokeColorN},
  {"T*",  0, {tchkNone},
          &Gfx::opTextNextLine},
  {"TD",  2, {tchkNum,    tchkNum},
          &Gfx::opTextMoveSet},
  {"TJ",  1, {tchkArray},
          &Gfx::opShowSpaceText},
  {"TL",  1, {tchkNum},
          &Gfx::opSetTextLeading},
  {"Tc",  1, {tchkNum},
          &Gfx::opSetCharSpacing},
  {"Td",  2, {tchkNum,    tchkNum},
          &Gfx::opTextMove},
  {"Tf",  2, {tchkName,   tchkNum},
          &Gfx::opSetFont},
  {"Tj",  1, {tchkString},
          &Gfx::opShowText},
  {"Tm",  6, {tchkNum,    tchkNum,    tchkNum,    tchkNum,
	      tchkNum,    tchkNum},
          &Gfx::opSetTextMatrix},
  {"Tr",  1, {tchkInt},
          &Gfx::opSetTextRender},
  {"Ts",  1, {tchkNum},
          &Gfx::opSetTextRise},
  {"Tw",  1, {tchkNum},
          &Gfx::opSetWordSpacing},
  {"Tz",  1, {tchkNum},
          &Gfx::opSetHorizScaling},
  {"W",   0, {tchkNone},
          &Gfx::opClip},
  {"W*",  0, {tchkNone},
          &Gfx::opEOClip},
  {"b",   0, {tchkNone},
          &Gfx::opCloseFillStroke},
  {"b*",  0, {tchkNone},
          &Gfx::opCloseEOFillStroke},
  {"c",   6, {tchkNum,    tchkNum,    tchkNum,    tchkNum,
	      tchkNum,    tchkNum},
          &Gfx::opCurveTo},
  {"cm",  6, {tchkNum,    tchkNum,    tchkNum,    tchkNum,
	      tchkNum,    tchkNum},
          &Gfx::opConcat},
  {"cs",  1, {tchkName},
          &Gfx::opSetFillColorSpace},
  {"d",   2, {tchkArray,  tchkNum},
          &Gfx::opSetDash},
  {"d0",  2, {tchkNum,    tchkNum},
          &Gfx::opSetCharWidth},
  {"d1",  6, {tchkNum,    tchkNum,    tchkNum,    tchkNum,
	      tchkNum,    tchkNum},
          &Gfx::opSetCacheDevice},
  {"f",   0, {tchkNone},
          &Gfx::opFill},
  {"f*",  0, {tchkNone},
          &Gfx::opEOFill},
  {"g",   1, {tchkNum},
          &Gfx::opSetFillGray},
  {"gs",  1, {tchkName},
          &Gfx::opSetExtGState},
  {"h",   0, {tchkNone},
          &Gfx::opClosePath},
  {"i",   1, {tchkNum},
          &Gfx::opSetFlat},
  {"j",   1, {tchkInt},
          &Gfx::opSetLineJoin},
  {"k",   4, {tchkNum,    tchkNum,    tchkNum,    tchkNum},
          &Gfx::opSetFillCMYKColor},
  {"l",   2, {tchkNum,    tchkNum},
          &Gfx::opLineTo},
  {"m",   2, {tchkNum,    tchkNum},
          &Gfx::opMoveTo},
  {"n",   0, {tchkNone},
          &Gfx::opEndPath},
  {"q",   0, {tchkNone},
          &Gfx::opSave},
  {"re",  4, {tchkNum,    tchkNum,    tchkNum,    tchkNum},
          &Gfx::opRectangle},
  {"rg",  3, {tchkNum,    tchkNum,    tchkNum},
          &Gfx::opSetFillRGBColor},
  {"ri",  1, {tchkName},
          &Gfx::opSetRenderingIntent},
  {"s",   0, {tchkNone},
          &Gfx::opCloseStroke},
  {"sc",  -4, {tchkNum,   tchkNum,    tchkNum,    tchkNum},
          &Gfx::opSetFillColor},
  {"scn", -33, {tchkSCN,   tchkSCN,    tchkSCN,    tchkSCN,
	        tchkSCN,   tchkSCN,    tchkSCN,    tchkSCN,
	        tchkSCN,   tchkSCN,    tchkSCN,    tchkSCN,
	        tchkSCN,   tchkSCN,    tchkSCN,    tchkSCN,
	        tchkSCN,   tchkSCN,    tchkSCN,    tchkSCN,
	        tchkSCN,   tchkSCN,    tchkSCN,    tchkSCN,
	        tchkSCN,   tchkSCN,    tchkSCN,    tchkSCN,
	        tchkSCN,   tchkSCN,    tchkSCN,    tchkSCN,
	        tchkSCN},
          &Gfx::opSetFillColorN},
  {"sh",  1, {tchkName},
          &Gfx::opShFill},
  {"v",   4, {tchkNum,    tchkNum,    tchkNum,    tchkNum},
          &Gfx::opCurveTo1},
  {"w",   1, {tchkNum},
          &Gfx::opSetLineWidth},
  {"y",   4, {tchkNum,    tchkNum,    tchkNum,    tchkNum},
          &Gfx::opCurveTo2},
};

#define numOps (sizeof(opTab) / sizeof(Operator))

static inline bool isSameGfxColor(const GfxColor &colorA, const GfxColor &colorB, unsigned int nComps, double delta) {
  for (unsigned int k = 0; k < nComps; ++k) {
    if (abs(colorA.c[k] - colorB.c[k]) > delta) {
      return false;
    }
  }
  return true;
}

//------------------------------------------------------------------------
// GfxResources
//------------------------------------------------------------------------

GfxResources::GfxResources(XRef *xrefA, Dict *resDictA, GfxResources *nextA) :
    gStateCache(2), xref(xrefA) {
  Ref r;

  if (resDictA) {

    // build font dictionary
    Dict *resDict = resDictA->copy(xref);
    fonts = nullptr;
    const Object &obj1 = resDict->lookupNF("Font");
    if (obj1.isRef()) {
      Object obj2 = obj1.fetch(xref);
      if (obj2.isDict()) {
	r = obj1.getRef();
	fonts = new GfxFontDict(xref, &r, obj2.getDict());
      }
    } else if (obj1.isDict()) {
      fonts = new GfxFontDict(xref, nullptr, obj1.getDict());
    }

    // get XObject dictionary
    xObjDict = resDict->lookup("XObject");

    // get color space dictionary
    colorSpaceDict = resDict->lookup("ColorSpace");

    // get pattern dictionary
    patternDict = resDict->lookup("Pattern");

    // get shading dictionary
    shadingDict = resDict->lookup("Shading");

    // get graphics state parameter dictionary
    gStateDict = resDict->lookup("ExtGState");

    // get properties dictionary
    propertiesDict = resDict->lookup("Properties");

    delete resDict;
  } else {
    fonts = nullptr;
    xObjDict.setToNull();
    colorSpaceDict.setToNull();
    patternDict.setToNull();
    shadingDict.setToNull();
    gStateDict.setToNull();
    propertiesDict.setToNull();
  }

  next = nextA;
}

GfxResources::~GfxResources() {
  delete fonts;
}

GfxFont *GfxResources::doLookupFont(const char *name) const
{
  GfxFont *font;
  const GfxResources *resPtr;

  for (resPtr = this; resPtr; resPtr = resPtr->next) {
    if (resPtr->fonts) {
      if ((font = resPtr->fonts->lookup(name)))
	return font;
    }
  }
  error(errSyntaxError, -1, "Unknown font tag '{0:s}'", name);
  return nullptr;
}

GfxFont *GfxResources::lookupFont(const char *name) {
  return doLookupFont(name);
}

const GfxFont *GfxResources::lookupFont(const char *name) const {
  return doLookupFont(name);
}

Object GfxResources::lookupXObject(const char *name) {
  GfxResources *resPtr;

  for (resPtr = this; resPtr; resPtr = resPtr->next) {
    if (resPtr->xObjDict.isDict()) {
      Object obj = resPtr->xObjDict.dictLookup(name);
      if (!obj.isNull())
	return obj;
    }
  }
  error(errSyntaxError, -1, "XObject '{0:s}' is unknown", name);
  return Object(objNull);
}

Object GfxResources::lookupXObjectNF(const char *name) {
  GfxResources *resPtr;

  for (resPtr = this; resPtr; resPtr = resPtr->next) {
    if (resPtr->xObjDict.isDict()) {
      Object obj = resPtr->xObjDict.dictLookupNF(name).copy();
      if (!obj.isNull())
	return obj;
    }
  }
  error(errSyntaxError, -1, "XObject '{0:s}' is unknown", name);
  return Object(objNull);
}

Object GfxResources::lookupMarkedContentNF(const char *name) {
  GfxResources *resPtr;

  for (resPtr = this; resPtr; resPtr = resPtr->next) {
    if (resPtr->propertiesDict.isDict()) {
      Object obj = resPtr->propertiesDict.dictLookupNF(name).copy();
      if (!obj.isNull())
	return obj;
    }
  }
  error(errSyntaxError, -1, "Marked Content '{0:s}' is unknown", name);
  return Object(objNull);
}

Object GfxResources::lookupColorSpace(const char *name) {
  GfxResources *resPtr;

  for (resPtr = this; resPtr; resPtr = resPtr->next) {
    if (resPtr->colorSpaceDict.isDict()) {
      Object obj = resPtr->colorSpaceDict.dictLookup(name);
      if (!obj.isNull()) {
	return obj;
      }
    }
  }
  return Object(objNull);
}

GfxPattern *GfxResources::lookupPattern(const char *name, OutputDev *out, GfxState *state) {
  GfxResources *resPtr;
  GfxPattern *pattern;

  for (resPtr = this; resPtr; resPtr = resPtr->next) {
    if (resPtr->patternDict.isDict()) {
      Object obj = resPtr->patternDict.dictLookupNF(name).copy();
      if (!obj.isNull()) {
	Ref patternRef = { -1, -1 };
	if (obj.isRef()) {
	  patternRef = obj.getRef();
	  obj = obj.fetch(resPtr->patternDict.getDict()->getXRef());
	}

	pattern = GfxPattern::parse(resPtr, &obj, out, state, patternRef.num);
	return pattern;
      }
    }
  }
  error(errSyntaxError, -1, "Unknown pattern '{0:s}'", name);
  return nullptr;
}

GfxShading *GfxResources::lookupShading(const char *name, OutputDev *out, GfxState *state) {
  GfxResources *resPtr;
  GfxShading *shading;

  for (resPtr = this; resPtr; resPtr = resPtr->next) {
    if (resPtr->shadingDict.isDict()) {
      Object obj = resPtr->shadingDict.dictLookup(name);
      if (!obj.isNull()) {
	shading = GfxShading::parse(resPtr, &obj, out, state);
	return shading;
      }
    }
  }
  error(errSyntaxError, -1, "ExtGState '{0:s}' is unknown", name);
  return nullptr;
}

Object GfxResources::lookupGState(const char *name) {
  Object obj = lookupGStateNF(name);
  if (obj.isNull())
    return Object(objNull);

  if (!obj.isRef())
    return obj;
  
  const Ref ref = obj.getRef();

  if (auto *item = gStateCache.lookup(ref)) {
    return item->copy();
  }

  auto *item = new Object{xref->fetch(ref)};
  gStateCache.put(ref, item);
  return item->copy();
}

Object GfxResources::lookupGStateNF(const char *name) {
  GfxResources *resPtr;

  for (resPtr = this; resPtr; resPtr = resPtr->next) {
    if (resPtr->gStateDict.isDict()) {
      Object obj = resPtr->gStateDict.dictLookupNF(name).copy();
      if (!obj.isNull()) {
	return obj;
      }
    }
  }
  error(errSyntaxError, -1, "ExtGState '{0:s}' is unknown", name);
  return Object(objNull);
}

//------------------------------------------------------------------------
// Gfx
//------------------------------------------------------------------------

Gfx::Gfx(PDFDoc *docA, OutputDev *outA, int pageNum, Dict *resDict,
	 double hDPI, double vDPI, const PDFRectangle *box,
	 const PDFRectangle *cropBox, int rotate,
	 bool (*abortCheckCbkA)(void *data),
	 void *abortCheckCbkDataA, XRef *xrefA)
{
  int i;

  doc = docA;
  xref = (xrefA == nullptr) ? doc->getXRef() : xrefA;
  catalog = doc->getCatalog();
  subPage = false;
  printCommands = globalParams->getPrintCommands();
  profileCommands = globalParams->getProfileCommands();
  mcStack = nullptr;
  parser = nullptr;

  // start the resource stack
  res = new GfxResources(xref, resDict, nullptr);

  // initialize
  out = outA;
  state = new GfxState(hDPI, vDPI, box, rotate, out->upsideDown());
  stackHeight = 1;
  pushStateGuard();
  fontChanged = false;
  clip = clipNone;
  ignoreUndef = 0;
  out->startPage(pageNum, state, xref);
  out->setDefaultCTM(state->getCTM());
  out->updateAll(state);
  for (i = 0; i < 6; ++i) {
    baseMatrix[i] = state->getCTM()[i];
  }
  formDepth = 0;
  ocState = true;
  parser = nullptr;
  abortCheckCbk = abortCheckCbkA;
  abortCheckCbkData = abortCheckCbkDataA;

  // set crop box
  if (cropBox) {
    state->moveTo(cropBox->x1, cropBox->y1);
    state->lineTo(cropBox->x2, cropBox->y1);
    state->lineTo(cropBox->x2, cropBox->y2);
    state->lineTo(cropBox->x1, cropBox->y2);
    state->closePath();
    state->clip();
    out->clip(state);
    state->clearPath();
  }
#ifdef USE_CMS
  initDisplayProfile();
#endif
}

Gfx::Gfx(PDFDoc *docA, OutputDev *outA, Dict *resDict,
	 const PDFRectangle *box, const PDFRectangle *cropBox,
	 bool (*abortCheckCbkA)(void *data),
	 void *abortCheckCbkDataA, Gfx *gfxA)
{
  int i;

  doc = docA;
  if (gfxA) {
    xref = gfxA->getXRef();
    formsDrawing = gfxA->formsDrawing;
    charProcDrawing = gfxA->charProcDrawing;
  } else {
    xref = doc->getXRef();
  }
  catalog = doc->getCatalog();
  subPage = true;
  printCommands = globalParams->getPrintCommands();
  profileCommands = globalParams->getProfileCommands();
  mcStack = nullptr;
  parser = nullptr;

  // start the resource stack
  res = new GfxResources(xref, resDict, nullptr);

  // initialize
  out = outA;
  state = new GfxState(72, 72, box, 0, false);
  stackHeight = 1;
  pushStateGuard();
  fontChanged = false;
  clip = clipNone;
  ignoreUndef = 0;
  for (i = 0; i < 6; ++i) {
    baseMatrix[i] = state->getCTM()[i];
  }
  formDepth = 0;
  ocState = true;
  parser = nullptr;
  abortCheckCbk = abortCheckCbkA;
  abortCheckCbkData = abortCheckCbkDataA;

  // set crop box
  if (cropBox) {
    state->moveTo(cropBox->x1, cropBox->y1);
    state->lineTo(cropBox->x2, cropBox->y1);
    state->lineTo(cropBox->x2, cropBox->y2);
    state->lineTo(cropBox->x1, cropBox->y2);
    state->closePath();
    state->clip();
    out->clip(state);
    state->clearPath();
  }
#ifdef USE_CMS
  initDisplayProfile();
#endif
}

#ifdef USE_CMS

#include <lcms2.h>

void Gfx::initDisplayProfile() {
   Object catDict = xref->getCatalog();
   if (catDict.isDict()) {
     Object outputIntents = catDict.dictLookup("OutputIntents");
     if (outputIntents.isArray() && outputIntents.arrayGetLength() == 1) {
          Object firstElement = outputIntents.arrayGet(0);
          if (firstElement.isDict()) {
              Object profile = firstElement.dictLookup("DestOutputProfile");
              if (profile.isStream()) {
                Stream *iccStream = profile.getStream();
                int length = 0;
                unsigned char *profBuf = iccStream->toUnsignedChars(&length, 65536, 65536);
                cmsHPROFILE hp = cmsOpenProfileFromMem(profBuf,length);
                if (hp == nullptr) {
                  error(errSyntaxWarning, -1, "read ICCBased color space profile error");
                } else {
                  state->setDisplayProfile(hp);
                }
                gfree(profBuf);
              }
          }
     }
   }
}

#endif

Gfx::~Gfx() {
  while (stateGuards.size()) {
    popStateGuard();
  }
  if (!subPage) {
    out->endPage();
  }
  // There shouldn't be more saves, but pop them if there were any
  while (state->hasSaves()) {
    error(errSyntaxError, -1, "Found state under last state guard. Popping.");
    restoreState();
  }
  delete state;
  while (res) {
    popResources();
  }
  while (mcStack) {
    popMarkedContent();
  }
}

void Gfx::display(Object *obj, bool topLevel) {
  int i;

  if (obj->isArray()) {
    for (i = 0; i < obj->arrayGetLength(); ++i) {
      Object obj2 = obj->arrayGet(i);
      if (!obj2.isStream()) {
	error(errSyntaxError, -1, "Weird page contents");
	return;
      }
    }
  } else if (!obj->isStream()) {
    error(errSyntaxError, -1, "Weird page contents");
    return;
  }
  parser = new Parser(xref, obj, false);
  go(topLevel);
  delete parser;
  parser = nullptr;
}

void Gfx::go(bool topLevel) {
  Object obj;
  Object args[maxArgs];
  int numArgs, i;
  int lastAbortCheck;

  // scan a sequence of objects
  pushStateGuard();
  updateLevel = 1; // make sure even empty pages trigger a call to dump()
  lastAbortCheck = 0;
  numArgs = 0;
  obj = parser->getObj();
  while (!obj.isEOF()) {
    commandAborted = false;

    // got a command - execute it
    if (obj.isCmd()) {
      if (printCommands) {
	obj.print(stdout);
	for (i = 0; i < numArgs; ++i) {
	  printf(" ");
	  args[i].print(stdout);
	}
	printf("\n");
	fflush(stdout);
      }
      GooTimer *timer = nullptr;

      if (unlikely(profileCommands)) {
          timer = new GooTimer();
      }

      // Run the operation
      execOp(&obj, args, numArgs);

      // Update the profile information
      if (unlikely(profileCommands)) {
	if (auto* const hash = out->getProfileHash()) {
	  auto& data = (*hash)[obj.getCmd()];
	  data.addElement(timer->getElapsed());
	}
	delete timer;
      }
      for (i = 0; i < numArgs; ++i)
	args[i].setToNull(); // Free memory early
      numArgs = 0;

      // periodically update display
      if (++updateLevel >= 20000) {
	out->dump();
	updateLevel = 0;
	lastAbortCheck = 0;
      }

      // did the command throw an exception
      if (commandAborted) {
	// don't propogate; recursive drawing comes from Form XObjects which
	// should probably be drawn in a separate context anyway for caching
	commandAborted = false;
	break;
      }

      // check for an abort
      if (abortCheckCbk) {
	if (updateLevel - lastAbortCheck > 10) {
	  if ((*abortCheckCbk)(abortCheckCbkData)) {
	    break;
	  }
	  lastAbortCheck = updateLevel;
	}
      }

    // got an argument - save it
    } else if (numArgs < maxArgs) {
      args[numArgs++] = std::move(obj);
    // too many arguments - something is wrong
    } else {
      error(errSyntaxError, getPos(), "Too many args in content stream");
      if (printCommands) {
	printf("throwing away arg: ");
	obj.print(stdout);
	printf("\n");
	fflush(stdout);
      }
    }

    // grab the next object
    obj = parser->getObj();
  }

  // args at end with no command
  if (numArgs > 0) {
    error(errSyntaxError, getPos(), "Leftover args in content stream");
    if (printCommands) {
      printf("%d leftovers:", numArgs);
      for (i = 0; i < numArgs; ++i) {
	printf(" ");
	args[i].print(stdout);
      }
      printf("\n");
      fflush(stdout);
    }
  }

  popStateGuard();

  // update display
  if (topLevel && updateLevel > 0) {
    out->dump();
  }
}

void Gfx::execOp(Object *cmd, Object args[], int numArgs) {
  Operator *op;
  Object *argPtr;
  int i;

  // find operator
  const char *name = cmd->getCmd();
  if (!(op = findOp(name))) {
    if (ignoreUndef == 0)
      error(errSyntaxError, getPos(), "Unknown operator '{0:s}'", name);
    return;
  }

  // type check args
  argPtr = args;
  if (op->numArgs >= 0) {
    if (numArgs < op->numArgs) {
      error(errSyntaxError, getPos(), "Too few ({0:d}) args to '{1:s}' operator", numArgs, name);
      commandAborted = true;
      return;
    }
    if (numArgs > op->numArgs) {
#if 0
      error(errSyntaxWarning, getPos(),
	    "Too many ({0:d}) args to '{1:s}' operator", numArgs, name);
#endif
      argPtr += numArgs - op->numArgs;
      numArgs = op->numArgs;
    }
  } else {
    if (numArgs > -op->numArgs) {
      error(errSyntaxError, getPos(), "Too many ({0:d}) args to '{1:s}' operator",
	    numArgs, name);
      return;
    }
  }
  for (i = 0; i < numArgs; ++i) {
    if (!checkArg(&argPtr[i], op->tchk[i])) {
      error(errSyntaxError, getPos(), "Arg #{0:d} to '{1:s}' operator is wrong type ({2:s})",
	    i, name, argPtr[i].getTypeName());
      return;
    }
  }

  // do it
  (this->*op->func)(argPtr, numArgs);
}

Operator *Gfx::findOp(const char *name) {
  int a, b, m, cmp;

  a = -1;
  b = numOps;
  cmp = 0; // make gcc happy
  // invariant: opTab[a] < name < opTab[b]
  while (b - a > 1) {
    m = (a + b) / 2;
    cmp = strcmp(opTab[m].name, name);
    if (cmp < 0)
      a = m;
    else if (cmp > 0)
      b = m;
    else
      a = b = m;
  }
  if (cmp != 0)
    return nullptr;
  return &opTab[a];
}

bool Gfx::checkArg(Object *arg, TchkType type) {
  switch (type) {
  case tchkBool:   return arg->isBool();
  case tchkInt:    return arg->isInt();
  case tchkNum:    return arg->isNum();
  case tchkString: return arg->isString();
  case tchkName:   return arg->isName();
  case tchkArray:  return arg->isArray();
  case tchkProps:  return arg->isDict() || arg->isName();
  case tchkSCN:    return arg->isNum() || arg->isName();
  case tchkNone:   return false;
  }
  return false;
}

Goffset Gfx::getPos() {
  return parser ? parser->getPos() : -1;
}

//------------------------------------------------------------------------
// graphics state operators
//------------------------------------------------------------------------

void Gfx::opSave(Object args[], int numArgs) {
  saveState();
}

void Gfx::opRestore(Object args[], int numArgs) {
  restoreState();
}

void Gfx::opConcat(Object args[], int numArgs) {
  state->concatCTM(args[0].getNum(), args[1].getNum(),
		   args[2].getNum(), args[3].getNum(),
		   args[4].getNum(), args[5].getNum());
  out->updateCTM(state, args[0].getNum(), args[1].getNum(),
		 args[2].getNum(), args[3].getNum(),
		 args[4].getNum(), args[5].getNum());
  fontChanged = true;
}

void Gfx::opSetDash(Object args[], int numArgs) {
  Array *a;
  int length;
  double *dash;
  int i;

  a = args[0].getArray();
  length = a->getLength();
  if (length == 0) {
    dash = nullptr;
  } else {
    dash = (double *)gmallocn(length, sizeof(double));
    bool dummyOk;
    for (i = 0; i < length; ++i) {
      const Object obj = a->get(i);
      dash[i] = obj.getNum(&dummyOk);
    }
  }
  state->setLineDash(dash, length, args[1].getNum());
  out->updateLineDash(state);
}

void Gfx::opSetFlat(Object args[], int numArgs) {
  state->setFlatness((int)args[0].getNum());
  out->updateFlatness(state);
}

void Gfx::opSetLineJoin(Object args[], int numArgs) {
  state->setLineJoin(args[0].getInt());
  out->updateLineJoin(state);
}

void Gfx::opSetLineCap(Object args[], int numArgs) {
  state->setLineCap(args[0].getInt());
  out->updateLineCap(state);
}

void Gfx::opSetMiterLimit(Object args[], int numArgs) {
  state->setMiterLimit(args[0].getNum());
  out->updateMiterLimit(state);
}

void Gfx::opSetLineWidth(Object args[], int numArgs) {
  state->setLineWidth(args[0].getNum());
  out->updateLineWidth(state);
}

void Gfx::opSetExtGState(Object args[], int numArgs) {
  Object obj1, obj2;
  GfxBlendMode mode;
  bool haveFillOP;
  Function *funcs[4];
  GfxColor backdropColor;
  bool haveBackdropColor;
  bool alpha, isolated, knockout;
  double opac;
  int i;

  obj1 = res->lookupGState(args[0].getName());
  if (obj1.isNull()) {
    return;
  }
  if (!obj1.isDict()) {
    error(errSyntaxError, getPos(), "ExtGState '{0:s}' is wrong type", args[0].getName());
    return;
  }
  if (printCommands) {
    printf("  gfx state dict: ");
    obj1.print();
    printf("\n");
  }

  // parameters that are also set by individual PDF operators
  obj2 = obj1.dictLookup("LW");
  if (obj2.isNum()) {
    opSetLineWidth(&obj2, 1);
  }
  obj2 = obj1.dictLookup("LC");
  if (obj2.isInt()) {
    opSetLineCap(&obj2, 1);
  }
  obj2 = obj1.dictLookup("LJ");
  if (obj2.isInt()) {
    opSetLineJoin(&obj2, 1);
  }
  obj2 = obj1.dictLookup("ML");
  if (obj2.isNum()) {
    opSetMiterLimit(&obj2, 1);
  }
  obj2 = obj1.dictLookup("D");
  if (obj2.isArray() && obj2.arrayGetLength() == 2) {
    Object args2[2];
    args2[0] = obj2.arrayGet(0);
    args2[1] = obj2.arrayGet(1);
    if (args2[0].isArray() && args2[1].isNum()) {
      opSetDash(args2, 2);
    }
  }
#if 0 //~ need to add a new version of GfxResources::lookupFont() that
      //~ takes an indirect ref instead of a name
  if (obj1.dictLookup("Font", &obj2)->isArray() &&
      obj2.arrayGetLength() == 2) {
    obj2.arrayGet(0, &args2[0]);
    obj2.arrayGet(1, &args2[1]);
    if (args2[0].isDict() && args2[1].isNum()) {
      opSetFont(args2, 2);
    }
    args2[0].free();
    args2[1].free();
  }
  obj2.free();
#endif
  obj2 = obj1.dictLookup("FL");
  if (obj2.isNum()) {
    opSetFlat(&obj2, 1);
  }

  // transparency support: blend mode, fill/stroke opacity
  obj2 = obj1.dictLookup("BM");
  if (!obj2.isNull()) {
    if (state->parseBlendMode(&obj2, &mode)) {
      state->setBlendMode(mode);
      out->updateBlendMode(state);
    } else {
      error(errSyntaxError, getPos(), "Invalid blend mode in ExtGState");
    }
  }
  obj2 = obj1.dictLookup("ca");
  if (obj2.isNum()) {
    opac = obj2.getNum();
    state->setFillOpacity(opac < 0 ? 0 : opac > 1 ? 1 : opac);
    out->updateFillOpacity(state);
  }
  obj2 = obj1.dictLookup("CA");
  if (obj2.isNum()) {
    opac = obj2.getNum();
    state->setStrokeOpacity(opac < 0 ? 0 : opac > 1 ? 1 : opac);
    out->updateStrokeOpacity(state);
  }

  // fill/stroke overprint, overprint mode
  obj2 = obj1.dictLookup("op");
  if ((haveFillOP = obj2.isBool())) {
    state->setFillOverprint(obj2.getBool());
    out->updateFillOverprint(state);
  }
  obj2 = obj1.dictLookup("OP");
  if (obj2.isBool()) {
    state->setStrokeOverprint(obj2.getBool());
    out->updateStrokeOverprint(state);
    if (!haveFillOP) {
      state->setFillOverprint(obj2.getBool());
      out->updateFillOverprint(state);
    }
  }
  obj2 = obj1.dictLookup("OPM");
  if (obj2.isInt()) {
    state->setOverprintMode(obj2.getInt());
    out->updateOverprintMode(state);
  }

  // stroke adjust
  obj2 = obj1.dictLookup("SA");
  if (obj2.isBool()) {
    state->setStrokeAdjust(obj2.getBool());
    out->updateStrokeAdjust(state);
  }

  // transfer function
  obj2 = obj1.dictLookup("TR2");
  if (obj2.isNull()) {
    obj2 = obj1.dictLookup("TR");
  }
  if (obj2.isName("Default") ||
      obj2.isName("Identity")) {
    funcs[0] = funcs[1] = funcs[2] = funcs[3] = nullptr;
    state->setTransfer(funcs);
    out->updateTransfer(state);
  } else if (obj2.isArray() && obj2.arrayGetLength() == 4) {
    for (i = 0; i < 4; ++i) {
      Object obj3 = obj2.arrayGet(i);
      funcs[i] = Function::parse(&obj3);
      if (!funcs[i]) {
	break;
      }
    }
    if (i == 4) {
      state->setTransfer(funcs);
      out->updateTransfer(state);
    }
  } else if (obj2.isName() || obj2.isDict() || obj2.isStream()) {
    if ((funcs[0] = Function::parse(&obj2))) {
      funcs[1] = funcs[2] = funcs[3] = nullptr;
      state->setTransfer(funcs);
      out->updateTransfer(state);
    }
  } else if (!obj2.isNull()) {
    error(errSyntaxError, getPos(), "Invalid transfer function in ExtGState");
  }

  // alpha is shape
  obj2 = obj1.dictLookup("AIS");
  if (obj2.isBool()) {
    state->setAlphaIsShape(obj2.getBool());
    out->updateAlphaIsShape(state);
  }

  // text knockout
  obj2 = obj1.dictLookup("TK");
  if (obj2.isBool()) {
    state->setTextKnockout(obj2.getBool());
    out->updateTextKnockout(state);
  }

  // soft mask
  obj2 = obj1.dictLookup("SMask");
  if (!obj2.isNull()) {
    if (obj2.isName("None")) {
      out->clearSoftMask(state);
    } else if (obj2.isDict()) {
      Object obj3 = obj2.dictLookup("S");
      if (obj3.isName("Alpha")) {
	alpha = true;
      } else { // "Luminosity"
	alpha = false;
      }
      funcs[0] = nullptr;
      obj3 = obj2.dictLookup("TR");
      if (!obj3.isNull()) {
	if (obj3.isName("Default") ||
	    obj3.isName("Identity")) {
	  funcs[0] = nullptr;
	} else {
	  funcs[0] = Function::parse(&obj3);
	  if (funcs[0] == nullptr ||
	    funcs[0]->getInputSize() != 1 ||
	    funcs[0]->getOutputSize() != 1) {
	      error(errSyntaxError, getPos(),
		  "Invalid transfer function in soft mask in ExtGState");
	      delete funcs[0];
	      funcs[0] = nullptr;
	  }
	}
      }
      obj3 = obj2.dictLookup("BC");
      if ((haveBackdropColor = obj3.isArray())) {
	for (i = 0; i < gfxColorMaxComps; ++i) {
	  backdropColor.c[i] = 0;
	}
	for (i = 0; i < obj3.arrayGetLength() && i < gfxColorMaxComps; ++i) {
	  Object obj4 = obj3.arrayGet(i);
	  if (obj4.isNum()) {
	    backdropColor.c[i] = dblToCol(obj4.getNum());
	  }
	}
      }
      obj3 = obj2.dictLookup("G");
      if (obj3.isStream()) {
	Object obj4 = obj3.streamGetDict()->lookup("Group");
	if (obj4.isDict()) {
	  GfxColorSpace *blendingColorSpace = nullptr;
	  isolated = knockout = false;
	  Object obj5 = obj4.dictLookup("CS");
	  if (!obj5.isNull()) {
	    blendingColorSpace = GfxColorSpace::parse(res, &obj5, out, state);
	  }
	  obj5 = obj4.dictLookup("I");
	  if (obj5.isBool()) {
	    isolated = obj5.getBool();
	  }
	  obj5 = obj4.dictLookup("K");
	  if (obj5.isBool()) {
	    knockout = obj5.getBool();
	  }
	  if (!haveBackdropColor) {
	    if (blendingColorSpace) {
	      blendingColorSpace->getDefaultColor(&backdropColor);
	    } else {
	      //~ need to get the parent or default color space (?)
	      for (i = 0; i < gfxColorMaxComps; ++i) {
		backdropColor.c[i] = 0;
	      }
	    }
	  }
	  doSoftMask(&obj3, alpha, blendingColorSpace,
		     isolated, knockout, funcs[0], &backdropColor);
	  delete blendingColorSpace;
	} else {
	  error(errSyntaxError, getPos(), "Invalid soft mask in ExtGState - missing group");
	}
      } else {
	error(errSyntaxError, getPos(), "Invalid soft mask in ExtGState - missing group");
      }
      delete funcs[0];
    } else if (!obj2.isNull()) {
      error(errSyntaxError, getPos(), "Invalid soft mask in ExtGState");
    }
  }
  obj2 = obj1.dictLookup("Font");
  if (obj2.isArray()) {
    GfxFont *font;
    if (obj2.arrayGetLength() == 2) {
      const Object &fargs0 = obj2.arrayGetNF(0);
      Object fargs1 = obj2.arrayGet(1);
      if (fargs0.isRef() && fargs1.isNum()) {
	Object fobj = fargs0.fetch(xref);
	if (fobj.isDict()) {
	  Ref r = fargs0.getRef();
	  font = GfxFont::makeFont(xref,args[0].getName(),r,fobj.getDict());
	  state->setFont(font,fargs1.getNum());
	  fontChanged = true;
	}
      }
    } else {
      error(errSyntaxError, getPos(), "Number of args mismatch for /Font in ExtGState");
    }
  }
  obj2 = obj1.dictLookup("LW");
  if (obj2.isNum()) {
    opSetLineWidth(&obj2,1);
  }
  obj2 = obj1.dictLookup("LC");
  if (obj2.isInt()) {
    opSetLineCap(&obj2,1);
  }
  obj2 = obj1.dictLookup("LJ");
  if (obj2.isInt()) {
    opSetLineJoin(&obj2,1);
  }
  obj2 = obj1.dictLookup("ML");
  if (obj2.isNum()) {
    opSetMiterLimit(&obj2,1);
  }
  obj2 = obj1.dictLookup("D");
  if (obj2.isArray()) {
    if (obj2.arrayGetLength() == 2) {
      Object dargs[2];

      dargs[0] = obj2.arrayGetNF(0).copy();
      dargs[1] = obj2.arrayGet(1);
      if (dargs[0].isArray() && dargs[1].isInt()) {
	opSetDash(dargs,2);
      }
    } else {
      error(errSyntaxError, getPos(), "Number of args mismatch for /D in ExtGState");
    }
  }
  obj2 = obj1.dictLookup("RI");
  if (obj2.isName()) {
    opSetRenderingIntent(&obj2,1);
  }
  obj2 = obj1.dictLookup("FL");
  if (obj2.isNum()) {
    opSetFlat(&obj2,1);
  }
}

void Gfx::doSoftMask(Object *str, bool alpha,
		     GfxColorSpace *blendingColorSpace,
		     bool isolated, bool knockout,
		     Function *transferFunc, GfxColor *backdropColor) {
  Dict *dict, *resDict;
  double m[6], bbox[4];
  Object obj1;
  int i;

  // check for excessive recursion
  if (formDepth > 20) {
    return;
  }

  // get stream dict
  dict = str->streamGetDict();

  // check form type
  obj1 = dict->lookup("FormType");
  if (!(obj1.isNull() || (obj1.isInt() && obj1.getInt() == 1))) {
    error(errSyntaxError, getPos(), "Unknown form type");
  }

  // get bounding box
  obj1 = dict->lookup("BBox");
  if (!obj1.isArray()) {
    error(errSyntaxError, getPos(), "Bad form bounding box");
    return;
  }
  for (i = 0; i < 4; ++i) {
    Object obj2 = obj1.arrayGet(i);
    if (likely(obj2.isNum())) bbox[i] = obj2.getNum();
    else {
      error(errSyntaxError, getPos(), "Bad form bounding box (non number)");
      return;
    }
  }

  // get matrix
  obj1 = dict->lookup("Matrix");
  if (obj1.isArray()) {
    for (i = 0; i < 6; ++i) {
      Object obj2 = obj1.arrayGet(i);
      if (likely(obj2.isNum())) m[i] = obj2.getNum();
      else m[i] = 0;
    }
  } else {
    m[0] = 1; m[1] = 0;
    m[2] = 0; m[3] = 1;
    m[4] = 0; m[5] = 0;
  }

  // get resources
  obj1 = dict->lookup("Resources");
  resDict = obj1.isDict() ? obj1.getDict() : nullptr;

  // draw it
  ++formDepth;
  drawForm(str, resDict, m, bbox, true, true,
	  blendingColorSpace, isolated, knockout,
	  alpha, transferFunc, backdropColor);
  --formDepth;
}

void Gfx::opSetRenderingIntent(Object args[], int numArgs) {
  state->setRenderingIntent(args[0].getName());
}

//------------------------------------------------------------------------
// color operators
//------------------------------------------------------------------------

void Gfx::opSetFillGray(Object args[], int numArgs) {
  GfxColor color;
  GfxColorSpace *colorSpace = nullptr;

  state->setFillPattern(nullptr);
  Object obj = res->lookupColorSpace("DefaultGray");
  if (!obj.isNull()) {
    colorSpace = GfxColorSpace::parse(res, &obj, out, state);
  }
  if (colorSpace == nullptr) {
    colorSpace = new GfxDeviceGrayColorSpace();
  }
  state->setFillColorSpace(colorSpace);
  out->updateFillColorSpace(state);
  color.c[0] = dblToCol(args[0].getNum());
  state->setFillColor(&color);
  out->updateFillColor(state);
}

void Gfx::opSetStrokeGray(Object args[], int numArgs) {
  GfxColor color;
  GfxColorSpace *colorSpace = nullptr;

  state->setStrokePattern(nullptr);
  Object obj = res->lookupColorSpace("DefaultGray");
  if (!obj.isNull()) {
    colorSpace = GfxColorSpace::parse(res, &obj, out, state);
  }
  if (colorSpace == nullptr) {
    colorSpace = new GfxDeviceGrayColorSpace();
  }
  state->setStrokeColorSpace(colorSpace);
  out->updateStrokeColorSpace(state);
  color.c[0] = dblToCol(args[0].getNum());
  state->setStrokeColor(&color);
  out->updateStrokeColor(state);
}

void Gfx::opSetFillCMYKColor(Object args[], int numArgs) {
  GfxColor color;
  GfxColorSpace *colorSpace = nullptr;
  int i;

  Object obj = res->lookupColorSpace("DefaultCMYK");
  if (!obj.isNull()) {
    colorSpace = GfxColorSpace::parse(res, &obj, out, state);
  }
  if (colorSpace == nullptr) {
    colorSpace = new GfxDeviceCMYKColorSpace();
  }
  state->setFillPattern(nullptr);
  state->setFillColorSpace(colorSpace);
  out->updateFillColorSpace(state);
  for (i = 0; i < 4; ++i) {
    color.c[i] = dblToCol(args[i].getNum());
  }
  state->setFillColor(&color);
  out->updateFillColor(state);
}

void Gfx::opSetStrokeCMYKColor(Object args[], int numArgs) {
  GfxColor color;
  GfxColorSpace *colorSpace = nullptr;
  int i;

  state->setStrokePattern(nullptr);
  Object obj = res->lookupColorSpace("DefaultCMYK");
  if (!obj.isNull()) {
    colorSpace = GfxColorSpace::parse(res, &obj, out, state);
  }
  if (colorSpace == nullptr) {
    colorSpace = new GfxDeviceCMYKColorSpace();
  }
  state->setStrokeColorSpace(colorSpace);
  out->updateStrokeColorSpace(state);
  for (i = 0; i < 4; ++i) {
    color.c[i] = dblToCol(args[i].getNum());
  }
  state->setStrokeColor(&color);
  out->updateStrokeColor(state);
}

void Gfx::opSetFillRGBColor(Object args[], int numArgs) {
  GfxColorSpace *colorSpace = nullptr;
  GfxColor color;
  int i;

  state->setFillPattern(nullptr);
  Object obj = res->lookupColorSpace("DefaultRGB");
  if (!obj.isNull()) {
    colorSpace = GfxColorSpace::parse(res, &obj, out, state);
  }
  if (colorSpace == nullptr) {
    colorSpace = new GfxDeviceRGBColorSpace();
  }
  state->setFillColorSpace(colorSpace);
  out->updateFillColorSpace(state);
  for (i = 0; i < 3; ++i) {
    color.c[i] = dblToCol(args[i].getNum());
  }
  state->setFillColor(&color);
  out->updateFillColor(state);
}

void Gfx::opSetStrokeRGBColor(Object args[], int numArgs) {
  GfxColorSpace *colorSpace = nullptr;
  GfxColor color;
  int i;

  state->setStrokePattern(nullptr);
  Object obj = res->lookupColorSpace("DefaultRGB");
  if (!obj.isNull()) {
    colorSpace = GfxColorSpace::parse(res, &obj, out, state);
  }
  if (colorSpace == nullptr) {
    colorSpace = new GfxDeviceRGBColorSpace();
  }
  state->setStrokeColorSpace(colorSpace);
  out->updateStrokeColorSpace(state);
  for (i = 0; i < 3; ++i) {
    color.c[i] = dblToCol(args[i].getNum());
  }
  state->setStrokeColor(&color);
  out->updateStrokeColor(state);
}

void Gfx::opSetFillColorSpace(Object args[], int numArgs) {
  GfxColorSpace *colorSpace;
  GfxColor color;

  Object obj = res->lookupColorSpace(args[0].getName());
  if (obj.isNull()) {
    colorSpace = GfxColorSpace::parse(res, &args[0], out, state);
  } else {
    colorSpace = GfxColorSpace::parse(res, &obj, out, state);
  }
  if (colorSpace) {
    state->setFillPattern(nullptr);
    state->setFillColorSpace(colorSpace);
    out->updateFillColorSpace(state);
    colorSpace->getDefaultColor(&color);
    state->setFillColor(&color);
    out->updateFillColor(state);
  } else {
    error(errSyntaxError, getPos(), "Bad color space (fill)");
  }
}

void Gfx::opSetStrokeColorSpace(Object args[], int numArgs) {
  GfxColorSpace *colorSpace;
  GfxColor color;

  state->setStrokePattern(nullptr);
  Object obj = res->lookupColorSpace(args[0].getName());
  if (obj.isNull()) {
    colorSpace = GfxColorSpace::parse(res, &args[0], out, state);
  } else {
    colorSpace = GfxColorSpace::parse(res, &obj, out, state);
  }
  if (colorSpace) {
    state->setStrokeColorSpace(colorSpace);
    out->updateStrokeColorSpace(state);
    colorSpace->getDefaultColor(&color);
    state->setStrokeColor(&color);
    out->updateStrokeColor(state);
  } else {
    error(errSyntaxError, getPos(), "Bad color space (stroke)");
  }
}

void Gfx::opSetFillColor(Object args[], int numArgs) {
  GfxColor color;
  int i;

  if (numArgs != state->getFillColorSpace()->getNComps()) {
    error(errSyntaxError, getPos(), "Incorrect number of arguments in 'sc' command");
    return;
  }
  state->setFillPattern(nullptr);
  for (i = 0; i < numArgs; ++i) {
    color.c[i] = dblToCol(args[i].getNum());
  }
  state->setFillColor(&color);
  out->updateFillColor(state);
}

void Gfx::opSetStrokeColor(Object args[], int numArgs) {
  GfxColor color;
  int i;

  if (numArgs != state->getStrokeColorSpace()->getNComps()) {
    error(errSyntaxError, getPos(), "Incorrect number of arguments in 'SC' command");
    return;
  }
  state->setStrokePattern(nullptr);
  for (i = 0; i < numArgs; ++i) {
    color.c[i] = dblToCol(args[i].getNum());
  }
  state->setStrokeColor(&color);
  out->updateStrokeColor(state);
}

void Gfx::opSetFillColorN(Object args[], int numArgs) {
  GfxColor color;
  GfxPattern *pattern;
  int i;

  if (state->getFillColorSpace()->getMode() == csPattern) {
    if (numArgs > 1) {
      if (!((GfxPatternColorSpace *)state->getFillColorSpace())->getUnder() ||
	  numArgs - 1 != ((GfxPatternColorSpace *)state->getFillColorSpace())
	                     ->getUnder()->getNComps()) {
	error(errSyntaxError, getPos(), "Incorrect number of arguments in 'scn' command");
	return;
      }
      for (i = 0; i < numArgs - 1 && i < gfxColorMaxComps; ++i) {
	if (args[i].isNum()) {
	  color.c[i] = dblToCol(args[i].getNum());
	} else {
	  color.c[i] = 0; // TODO Investigate if this is what Adobe does
	}
      }
      state->setFillColor(&color);
      out->updateFillColor(state);
    }
    if (numArgs > 0) {
      if (args[numArgs-1].isName() &&
	  (pattern = res->lookupPattern(args[numArgs-1].getName(), out, state))) {
        state->setFillPattern(pattern);
      }
    }

  } else {
    if (numArgs != state->getFillColorSpace()->getNComps()) {
      error(errSyntaxError, getPos(), "Incorrect number of arguments in 'scn' command");
      return;
    }
    state->setFillPattern(nullptr);
    for (i = 0; i < numArgs && i < gfxColorMaxComps; ++i) {
      if (args[i].isNum()) {
	color.c[i] = dblToCol(args[i].getNum());
      } else {
        color.c[i] = 0; // TODO Investigate if this is what Adobe does
      }
    }
    state->setFillColor(&color);
    out->updateFillColor(state);
  }
}

void Gfx::opSetStrokeColorN(Object args[], int numArgs) {
  GfxColor color;
  GfxPattern *pattern;
  int i;

  if (state->getStrokeColorSpace()->getMode() == csPattern) {
    if (numArgs > 1) {
      if (!((GfxPatternColorSpace *)state->getStrokeColorSpace())
	       ->getUnder() ||
	  numArgs - 1 != ((GfxPatternColorSpace *)state->getStrokeColorSpace())
	                     ->getUnder()->getNComps()) {
	error(errSyntaxError, getPos(), "Incorrect number of arguments in 'SCN' command");
	return;
      }
      for (i = 0; i < numArgs - 1 && i < gfxColorMaxComps; ++i) {
	if (args[i].isNum()) {
	  color.c[i] = dblToCol(args[i].getNum());
	} else {
	  color.c[i] = 0; // TODO Investigate if this is what Adobe does
	}
      }
      state->setStrokeColor(&color);
      out->updateStrokeColor(state);
    }
    if (unlikely(numArgs <= 0)) {
      error(errSyntaxError, getPos(), "Incorrect number of arguments in 'SCN' command");
      return;
    }
    if (args[numArgs-1].isName() &&
	(pattern = res->lookupPattern(args[numArgs-1].getName(), out, state))) {
      state->setStrokePattern(pattern);
    }

  } else {
    if (numArgs != state->getStrokeColorSpace()->getNComps()) {
      error(errSyntaxError, getPos(), "Incorrect number of arguments in 'SCN' command");
      return;
    }
    state->setStrokePattern(nullptr);
    for (i = 0; i < numArgs && i < gfxColorMaxComps; ++i) {
      if (args[i].isNum()) {
	color.c[i] = dblToCol(args[i].getNum());
      } else {
        color.c[i] = 0; // TODO Investigate if this is what Adobe does
      }
    }
    state->setStrokeColor(&color);
    out->updateStrokeColor(state);
  }
}

//------------------------------------------------------------------------
// path segment operators
//------------------------------------------------------------------------

void Gfx::opMoveTo(Object args[], int numArgs) {
  state->moveTo(args[0].getNum(), args[1].getNum());
}

void Gfx::opLineTo(Object args[], int numArgs) {
  if (!state->isCurPt()) {
    error(errSyntaxError, getPos(), "No current point in lineto");
    return;
  }
  state->lineTo(args[0].getNum(), args[1].getNum());
}

void Gfx::opCurveTo(Object args[], int numArgs) {
  double x1, y1, x2, y2, x3, y3;

  if (!state->isCurPt()) {
    error(errSyntaxError, getPos(), "No current point in curveto");
    return;
  }
  x1 = args[0].getNum();
  y1 = args[1].getNum();
  x2 = args[2].getNum();
  y2 = args[3].getNum();
  x3 = args[4].getNum();
  y3 = args[5].getNum();
  state->curveTo(x1, y1, x2, y2, x3, y3);
}

void Gfx::opCurveTo1(Object args[], int numArgs) {
  double x1, y1, x2, y2, x3, y3;

  if (!state->isCurPt()) {
    error(errSyntaxError, getPos(), "No current point in curveto1");
    return;
  }
  x1 = state->getCurX();
  y1 = state->getCurY();
  x2 = args[0].getNum();
  y2 = args[1].getNum();
  x3 = args[2].getNum();
  y3 = args[3].getNum();
  state->curveTo(x1, y1, x2, y2, x3, y3);
}

void Gfx::opCurveTo2(Object args[], int numArgs) {
  double x1, y1, x2, y2, x3, y3;

  if (!state->isCurPt()) {
    error(errSyntaxError, getPos(), "No current point in curveto2");
    return;
  }
  x1 = args[0].getNum();
  y1 = args[1].getNum();
  x2 = args[2].getNum();
  y2 = args[3].getNum();
  x3 = x2;
  y3 = y2;
  state->curveTo(x1, y1, x2, y2, x3, y3);
}

void Gfx::opRectangle(Object args[], int numArgs) {
  double x, y, w, h;

  x = args[0].getNum();
  y = args[1].getNum();
  w = args[2].getNum();
  h = args[3].getNum();
  state->moveTo(x, y);
  state->lineTo(x + w, y);
  state->lineTo(x + w, y + h);
  state->lineTo(x, y + h);
  state->closePath();
}

void Gfx::opClosePath(Object args[], int numArgs) {
  if (!state->isCurPt()) {
    error(errSyntaxError, getPos(), "No current point in closepath");
    return;
  }
  state->closePath();
}

//------------------------------------------------------------------------
// path painting operators
//------------------------------------------------------------------------

void Gfx::opEndPath(Object args[], int numArgs) {
  doEndPath();
}

void Gfx::opStroke(Object args[], int numArgs) {
  if (!state->isCurPt()) {
    //error(errSyntaxError, getPos(), "No path in stroke");
    return;
  }
  if (state->isPath()) {
    if (ocState) {
      if (state->getStrokeColorSpace()->getMode() == csPattern) {
	doPatternStroke();
      } else {
	out->stroke(state);
      }
    }
  }
  doEndPath();
}

void Gfx::opCloseStroke(Object * /*args[]*/, int /*numArgs*/) {
  if (!state->isCurPt()) {
    //error(errSyntaxError, getPos(), "No path in closepath/stroke");
    return;
  }
  if (state->isPath()) {
    state->closePath();
    if (ocState) {
      if (state->getStrokeColorSpace()->getMode() == csPattern) {
	doPatternStroke();
      } else {
	out->stroke(state);
      }
    }
  }
  doEndPath();
}

void Gfx::opFill(Object args[], int numArgs) {
  if (!state->isCurPt()) {
    //error(errSyntaxError, getPos(), "No path in fill");
    return;
  }
  if (state->isPath()) {
    if (ocState) {
      if (state->getFillColorSpace()->getMode() == csPattern) {
	doPatternFill(false);
      } else {
	out->fill(state);
      }
    }
  }
  doEndPath();
}

void Gfx::opEOFill(Object args[], int numArgs) {
  if (!state->isCurPt()) {
    //error(errSyntaxError, getPos(), "No path in eofill");
    return;
  }
  if (state->isPath()) {
    if (ocState) {
      if (state->getFillColorSpace()->getMode() == csPattern) {
	doPatternFill(true);
      } else {
	out->eoFill(state);
      }
    }
  }
  doEndPath();
}

void Gfx::opFillStroke(Object args[], int numArgs) {
  if (!state->isCurPt()) {
    //error(errSyntaxError, getPos(), "No path in fill/stroke");
    return;
  }
  if (state->isPath()) {
    if (ocState) {
      if (state->getFillColorSpace()->getMode() == csPattern) {
	doPatternFill(false);
      } else {
	out->fill(state);
      }
      if (state->getStrokeColorSpace()->getMode() == csPattern) {
	doPatternStroke();
      } else {
	out->stroke(state);
      }
    }
  }
  doEndPath();
}

void Gfx::opCloseFillStroke(Object args[], int numArgs) {
  if (!state->isCurPt()) {
    //error(errSyntaxError, getPos(), "No path in closepath/fill/stroke");
    return;
  }
  if (state->isPath()) {
    state->closePath();
    if (ocState) {
      if (state->getFillColorSpace()->getMode() == csPattern) {
	doPatternFill(false);
      } else {
	out->fill(state);
      }
      if (state->getStrokeColorSpace()->getMode() == csPattern) {
	doPatternStroke();
      } else {
	out->stroke(state);
      }
    }
  }
  doEndPath();
}

void Gfx::opEOFillStroke(Object args[], int numArgs) {
  if (!state->isCurPt()) {
    //error(errSyntaxError, getPos(), "No path in eofill/stroke");
    return;
  }
  if (state->isPath()) {
    if (ocState) {
      if (state->getFillColorSpace()->getMode() == csPattern) {
	doPatternFill(true);
      } else {
	out->eoFill(state);
      }
      if (state->getStrokeColorSpace()->getMode() == csPattern) {
	doPatternStroke();
      } else {
	out->stroke(state);
      }
    }
  }
  doEndPath();
}

void Gfx::opCloseEOFillStroke(Object args[], int numArgs) {
  if (!state->isCurPt()) {
    //error(errSyntaxError, getPos(), "No path in closepath/eofill/stroke");
    return;
  }
  if (state->isPath()) {
    state->closePath();
    if (ocState) {
      if (state->getFillColorSpace()->getMode() == csPattern) {
	doPatternFill(true);
      } else {
	out->eoFill(state);
      }
      if (state->getStrokeColorSpace()->getMode() == csPattern) {
	doPatternStroke();
      } else {
	out->stroke(state);
      }
    }
  }
  doEndPath();
}

void Gfx::doPatternFill(bool eoFill) {
  GfxPattern *pattern;

  // this is a bit of a kludge -- patterns can be really slow, so we
  // skip them if we're only doing text extraction, since they almost
  // certainly don't contain any text
  if (!out->needNonText()) {
    return;
  }

  if (!(pattern = state->getFillPattern())) {
    return;
  }
  switch (pattern->getType()) {
  case 1:
    doTilingPatternFill((GfxTilingPattern *)pattern, false, eoFill, false);
    break;
  case 2:
    doShadingPatternFill((GfxShadingPattern *)pattern, false, eoFill, false);
    break;
  default:
    error(errSyntaxError, getPos(), "Unknown pattern type ({0:d}) in fill",
	  pattern->getType());
    break;
  }
}

void Gfx::doPatternStroke() {
  GfxPattern *pattern;

  // this is a bit of a kludge -- patterns can be really slow, so we
  // skip them if we're only doing text extraction, since they almost
  // certainly don't contain any text
  if (!out->needNonText()) {
    return;
  }

  if (!(pattern = state->getStrokePattern())) {
    return;
  }
  switch (pattern->getType()) {
  case 1:
    doTilingPatternFill((GfxTilingPattern *)pattern, true, false, false);
    break;
  case 2:
    doShadingPatternFill((GfxShadingPattern *)pattern, true, false, false);
    break;
  default:
    error(errSyntaxError, getPos(), "Unknown pattern type ({0:d}) in stroke",
	  pattern->getType());
    break;
  }
}

void Gfx::doPatternText() {
  GfxPattern *pattern;

  // this is a bit of a kludge -- patterns can be really slow, so we
  // skip them if we're only doing text extraction, since they almost
  // certainly don't contain any text
  if (!out->needNonText()) {
    return;
  }

  if (!(pattern = state->getFillPattern())) {
    return;
  }
  switch (pattern->getType()) {
  case 1:
    doTilingPatternFill((GfxTilingPattern *)pattern, false, false, true);
    break;
  case 2:
    doShadingPatternFill((GfxShadingPattern *)pattern, false, false, true);
    break;
  default:
    error(errSyntaxError, getPos(), "Unknown pattern type ({0:d}) in fill",
	  pattern->getType());
    break;
  }
}

void Gfx::doPatternImageMask(Object *ref, Stream *str, int width, int height,
			     bool invert, bool inlineImg) {
  saveState();

  out->setSoftMaskFromImageMask(state, ref, str,
				width, height, invert, inlineImg, baseMatrix);

  state->clearPath();
  state->moveTo(0, 0);
  state->lineTo(1, 0);
  state->lineTo(1, 1);
  state->lineTo(0, 1);
  state->closePath();
  doPatternText();

  out->unsetSoftMaskFromImageMask(state, baseMatrix);
  restoreState();
}

void Gfx::doTilingPatternFill(GfxTilingPattern *tPat,
			      bool stroke, bool eoFill, bool text) {
  GfxPatternColorSpace *patCS;
  GfxColorSpace *cs;
  GfxColor color;
  GfxState *savedState;
  double xMin, yMin, xMax, yMax, x, y, x1, y1;
  double cxMin, cyMin, cxMax, cyMax;
  int xi0, yi0, xi1, yi1, xi, yi;
  const double *ctm, *btm, *ptm;
  double m[6], ictm[6], m1[6], imb[6];
  double det;
  double xstep, ystep;
  int i;

  // get color space
  patCS = (GfxPatternColorSpace *)(stroke ? state->getStrokeColorSpace()
				          : state->getFillColorSpace());

  // construct a (pattern space) -> (current space) transform matrix
  ctm = state->getCTM();
  btm = baseMatrix;
  ptm = tPat->getMatrix();
  // iCTM = invert CTM
  det = ctm[0] * ctm[3] - ctm[1] * ctm[2];
  if (fabs(det) < 0.000001) {
    error(errSyntaxError, getPos(), "Singular matrix in tiling pattern fill");
    return;
  }
  det = 1 / det;
  ictm[0] = ctm[3] * det;
  ictm[1] = -ctm[1] * det;
  ictm[2] = -ctm[2] * det;
  ictm[3] = ctm[0] * det;
  ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det;
  ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det;
  // m1 = PTM * BTM = PTM * base transform matrix
  m1[0] = ptm[0] * btm[0] + ptm[1] * btm[2];
  m1[1] = ptm[0] * btm[1] + ptm[1] * btm[3];
  m1[2] = ptm[2] * btm[0] + ptm[3] * btm[2];
  m1[3] = ptm[2] * btm[1] + ptm[3] * btm[3];
  m1[4] = ptm[4] * btm[0] + ptm[5] * btm[2] + btm[4];
  m1[5] = ptm[4] * btm[1] + ptm[5] * btm[3] + btm[5];
  // m = m1 * iCTM = (PTM * BTM) * (iCTM)
  m[0] = m1[0] * ictm[0] + m1[1] * ictm[2];
  m[1] = m1[0] * ictm[1] + m1[1] * ictm[3];
  m[2] = m1[2] * ictm[0] + m1[3] * ictm[2];
  m[3] = m1[2] * ictm[1] + m1[3] * ictm[3];
  m[4] = m1[4] * ictm[0] + m1[5] * ictm[2] + ictm[4];
  m[5] = m1[4] * ictm[1] + m1[5] * ictm[3] + ictm[5];

  // construct a (device space) -> (pattern space) transform matrix
  det = m1[0] * m1[3] - m1[1] * m1[2];
  if (fabs(det) < 0.000001) {
    error(errSyntaxError, getPos(), "Singular matrix in tiling pattern fill");
    return;
  }
  det = 1 / det;
  imb[0] = m1[3] * det;
  imb[1] = -m1[1] * det;
  imb[2] = -m1[2] * det;
  imb[3] = m1[0] * det;
  imb[4] = (m1[2] * m1[5] - m1[3] * m1[4]) * det;
  imb[5] = (m1[1] * m1[4] - m1[0] * m1[5]) * det;

  // save current graphics state
  savedState = saveStateStack();

  // set underlying color space (for uncolored tiling patterns); set
  // various other parameters (stroke color, line width) to match
  // Adobe's behavior
  state->setFillPattern(nullptr);
  state->setStrokePattern(nullptr);
  if (tPat->getPaintType() == 2 && (cs = patCS->getUnder())) {
    state->setFillColorSpace(cs->copy());
    out->updateFillColorSpace(state);
    state->setStrokeColorSpace(cs->copy());
    out->updateStrokeColorSpace(state);
    if (stroke) {
	state->setFillColor(state->getStrokeColor());
    } else {
	state->setStrokeColor(state->getFillColor());
    }
    out->updateFillColor(state);
    out->updateStrokeColor(state);
  } else {
    cs = new GfxDeviceGrayColorSpace();
    state->setFillColorSpace(cs);
    cs->getDefaultColor(&color);
    state->setFillColor(&color);
    out->updateFillColorSpace(state);
    state->setStrokeColorSpace(new GfxDeviceGrayColorSpace());
    state->setStrokeColor(&color);
    out->updateStrokeColorSpace(state);
  }
  if (!stroke) {
    state->setLineWidth(0);
    out->updateLineWidth(state);
  }

  // clip to current path
  if (stroke) {
    state->clipToStrokePath();
    out->clipToStrokePath(state);
  } else if (!text) {
    state->clip();
    if (eoFill) {
      out->eoClip(state);
    } else {
      out->clip(state);
    }
  }
  state->clearPath();

  // get the clip region, check for empty
  state->getClipBBox(&cxMin, &cyMin, &cxMax, &cyMax);
  if (cxMin > cxMax || cyMin > cyMax) {
    goto restore;
  }

  // transform clip region bbox to pattern space
  xMin = xMax = cxMin * imb[0] + cyMin * imb[2] + imb[4];
  yMin = yMax = cxMin * imb[1] + cyMin * imb[3] + imb[5];
  x1 = cxMin * imb[0] + cyMax * imb[2] + imb[4];
  y1 = cxMin * imb[1] + cyMax * imb[3] + imb[5];
  if (x1 < xMin) {
    xMin = x1;
  } else if (x1 > xMax) {
    xMax = x1;
  }
  if (y1 < yMin) {
    yMin = y1;
  } else if (y1 > yMax) {
    yMax = y1;
  }
  x1 = cxMax * imb[0] + cyMin * imb[2] + imb[4];
  y1 = cxMax * imb[1] + cyMin * imb[3] + imb[5];
  if (x1 < xMin) {
    xMin = x1;
  } else if (x1 > xMax) {
    xMax = x1;
  }
  if (y1 < yMin) {
    yMin = y1;
  } else if (y1 > yMax) {
    yMax = y1;
  }
  x1 = cxMax * imb[0] + cyMax * imb[2] + imb[4];
  y1 = cxMax * imb[1] + cyMax * imb[3] + imb[5];
  if (x1 < xMin) {
    xMin = x1;
  } else if (x1 > xMax) {
    xMax = x1;
  }
  if (y1 < yMin) {
    yMin = y1;
  } else if (y1 > yMax) {
    yMax = y1;
  }

  // draw the pattern
  //~ this should treat negative steps differently -- start at right/top
  //~ edge instead of left/bottom (?)
  xstep = fabs(tPat->getXStep());
  ystep = fabs(tPat->getYStep());
  if (unlikely(xstep == 0 || ystep == 0)) {
      goto restore;
  }
  if (tPat->getBBox()[0] < tPat->getBBox()[2]) {
    xi0 = (int)ceil((xMin - tPat->getBBox()[2]) / xstep);
    xi1 = (int)floor((xMax - tPat->getBBox()[0]) / xstep) + 1;
  } else {
    xi0 = (int)ceil((xMin - tPat->getBBox()[0]) / xstep);
    xi1 = (int)floor((xMax - tPat->getBBox()[2]) / xstep) + 1;
  }
  if (tPat->getBBox()[1] < tPat->getBBox()[3]) {
    yi0 = (int)ceil((yMin - tPat->getBBox()[3]) / ystep);
    yi1 = (int)floor((yMax - tPat->getBBox()[1]) / ystep) + 1;
  } else {
    yi0 = (int)ceil((yMin - tPat->getBBox()[1]) / ystep);
    yi1 = (int)floor((yMax - tPat->getBBox()[3]) / ystep) + 1;
  }
  for (i = 0; i < 4; ++i) {
    m1[i] = m[i];
  }
  m1[4] = m[4];
  m1[5] = m[5];
  {
    bool shouldDrawPattern = true;
    std::set<int>::iterator patternRefIt;
    const int patternRefNum = tPat->getPatternRefNum();
    if (patternRefNum != -1) {
      if (formsDrawing.find(patternRefNum) == formsDrawing.end()) {
	patternRefIt = formsDrawing.insert(patternRefNum).first;
      } else {
	shouldDrawPattern = false;
      }
    }
    if (shouldDrawPattern) {
      if (out->useTilingPatternFill() &&
	  out->tilingPatternFill(state, this, catalog, tPat->getContentStream(),
			tPat->getMatrix(), tPat->getPaintType(), tPat->getTilingType(),
			tPat->getResDict(), m1, tPat->getBBox(),
			xi0, yi0, xi1, yi1, xstep, ystep)) {
	// do nothing
      } else {
	out->updatePatternOpacity(state);
	for (yi = yi0; yi < yi1; ++yi) {
	  for (xi = xi0; xi < xi1; ++xi) {
	    x = xi * xstep;
	    y = yi * ystep;
	    m1[4] = x * m[0] + y * m[2] + m[4];
	    m1[5] = x * m[1] + y * m[3] + m[5];
	    drawForm(tPat->getContentStream(), tPat->getResDict(),
		    m1, tPat->getBBox());
	  }
	}
	out->clearPatternOpacity(state);
      }
      if (patternRefNum != -1) {
	formsDrawing.erase(patternRefIt);
      }
    }
  }

  // restore graphics state
 restore:
  restoreStateStack(savedState);
}

void Gfx::doShadingPatternFill(GfxShadingPattern *sPat,
			       bool stroke, bool eoFill, bool text) {
  GfxShading *shading;
  GfxState *savedState;
  const double *ctm, *btm, *ptm;
  double m[6], ictm[6], m1[6];
  double xMin, yMin, xMax, yMax;
  double det;

  shading = sPat->getShading();

  // save current graphics state
  savedState = saveStateStack();

  // clip to current path
  if (stroke) {
    state->clipToStrokePath();
    out->clipToStrokePath(state);
  } else if (!text) {
    state->clip();
    if (eoFill) {
      out->eoClip(state);
    } else {
      out->clip(state);
    }
  }
  state->clearPath();

  // construct a (pattern space) -> (current space) transform matrix
  ctm = state->getCTM();
  btm = baseMatrix;
  ptm = sPat->getMatrix();
  // iCTM = invert CTM
  det = ctm[0] * ctm[3] - ctm[1] * ctm[2];
  if (fabs(det) < 0.000001) {
    error(errSyntaxError, getPos(), "Singular matrix in shading pattern fill");
    restoreStateStack(savedState);
    return;
  }
  det = 1 / det;
  ictm[0] = ctm[3] * det;
  ictm[1] = -ctm[1] * det;
  ictm[2] = -ctm[2] * det;
  ictm[3] = ctm[0] * det;
  ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det;
  ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det;
  // m1 = PTM * BTM = PTM * base transform matrix
  m1[0] = ptm[0] * btm[0] + ptm[1] * btm[2];
  m1[1] = ptm[0] * btm[1] + ptm[1] * btm[3];
  m1[2] = ptm[2] * btm[0] + ptm[3] * btm[2];
  m1[3] = ptm[2] * btm[1] + ptm[3] * btm[3];
  m1[4] = ptm[4] * btm[0] + ptm[5] * btm[2] + btm[4];
  m1[5] = ptm[4] * btm[1] + ptm[5] * btm[3] + btm[5];
  // m = m1 * iCTM = (PTM * BTM) * (iCTM)
  m[0] = m1[0] * ictm[0] + m1[1] * ictm[2];
  m[1] = m1[0] * ictm[1] + m1[1] * ictm[3];
  m[2] = m1[2] * ictm[0] + m1[3] * ictm[2];
  m[3] = m1[2] * ictm[1] + m1[3] * ictm[3];
  m[4] = m1[4] * ictm[0] + m1[5] * ictm[2] + ictm[4];
  m[5] = m1[4] * ictm[1] + m1[5] * ictm[3] + ictm[5];

  // set the new matrix
  state->concatCTM(m[0], m[1], m[2], m[3], m[4], m[5]);
  out->updateCTM(state, m[0], m[1], m[2], m[3], m[4], m[5]);

  // clip to bbox
  if (shading->getHasBBox()) {
    shading->getBBox(&xMin, &yMin, &xMax, &yMax);
    state->moveTo(xMin, yMin);
    state->lineTo(xMax, yMin);
    state->lineTo(xMax, yMax);
    state->lineTo(xMin, yMax);
    state->closePath();
    state->clip();
    out->clip(state);
    state->clearPath();
  }

  // set the color space
  state->setFillColorSpace(shading->getColorSpace()->copy());
  out->updateFillColorSpace(state);

  // background color fill
  if (shading->getHasBackground()) {
    state->setFillColor(shading->getBackground());
    out->updateFillColor(state);
    state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
    state->moveTo(xMin, yMin);
    state->lineTo(xMax, yMin);
    state->lineTo(xMax, yMax);
    state->lineTo(xMin, yMax);
    state->closePath();
    out->fill(state);
    state->clearPath();
  }

#if 1 //~tmp: turn off anti-aliasing temporarily
  bool vaa = out->getVectorAntialias();
  if (vaa) {
    out->setVectorAntialias(false);
  }
#endif

  // do shading type-specific operations
  switch (shading->getType()) {
  case 1:
    doFunctionShFill((GfxFunctionShading *)shading);
    break;
  case 2:
    doAxialShFill((GfxAxialShading *)shading);
    break;
  case 3:
    doRadialShFill((GfxRadialShading *)shading);
    break;
  case 4:
  case 5:
    doGouraudTriangleShFill((GfxGouraudTriangleShading *)shading);
    break;
  case 6:
  case 7:
    doPatchMeshShFill((GfxPatchMeshShading *)shading);
    break;
  }

#if 1 //~tmp: turn off anti-aliasing temporarily
  if (vaa) {
    out->setVectorAntialias(true);
  }
#endif

  // restore graphics state
  restoreStateStack(savedState);
}

void Gfx::opShFill(Object args[], int numArgs) {
  GfxShading *shading;
  GfxState *savedState;
  double xMin, yMin, xMax, yMax;

  if (!ocState) {
    return;
  }

  if (!(shading = res->lookupShading(args[0].getName(), out, state))) {
    return;
  }

  // save current graphics state
  savedState = saveStateStack();

  // clip to bbox
  if (shading->getHasBBox()) {
    shading->getBBox(&xMin, &yMin, &xMax, &yMax);
    state->moveTo(xMin, yMin);
    state->lineTo(xMax, yMin);
    state->lineTo(xMax, yMax);
    state->lineTo(xMin, yMax);
    state->closePath();
    state->clip();
    out->clip(state);
    state->clearPath();
  }

  // set the color space
  state->setFillColorSpace(shading->getColorSpace()->copy());
  out->updateFillColorSpace(state);

#if 1 //~tmp: turn off anti-aliasing temporarily
  bool vaa = out->getVectorAntialias();
  if (vaa) {
    out->setVectorAntialias(false);
  }
#endif

  // do shading type-specific operations
  switch (shading->getType()) {
  case 1:
    doFunctionShFill((GfxFunctionShading *)shading);
    break;
  case 2:
    doAxialShFill((GfxAxialShading *)shading);
    break;
  case 3:
    doRadialShFill((GfxRadialShading *)shading);
    break;
  case 4:
  case 5:
    doGouraudTriangleShFill((GfxGouraudTriangleShading *)shading);
    break;
  case 6:
  case 7:
    doPatchMeshShFill((GfxPatchMeshShading *)shading);
    break;
  }

#if 1 //~tmp: turn off anti-aliasing temporarily
  if (vaa) {
    out->setVectorAntialias(true);
  }
#endif

  // restore graphics state
  restoreStateStack(savedState);

  delete shading;
}

void Gfx::doFunctionShFill(GfxFunctionShading *shading) {
  double x0, y0, x1, y1;
  GfxColor colors[4];

  if (out->useShadedFills( shading->getType() ) &&
      out->functionShadedFill(state, shading)) {
    return;
  }

  shading->getDomain(&x0, &y0, &x1, &y1);
  shading->getColor(x0, y0, &colors[0]);
  shading->getColor(x0, y1, &colors[1]);
  shading->getColor(x1, y0, &colors[2]);
  shading->getColor(x1, y1, &colors[3]);
  doFunctionShFill1(shading, x0, y0, x1, y1, colors, 0);
}

void Gfx::doFunctionShFill1(GfxFunctionShading *shading,
			    double x0, double y0,
			    double x1, double y1,
			    GfxColor *colors, int depth) {
  GfxColor fillColor;
  GfxColor color0M, color1M, colorM0, colorM1, colorMM;
  GfxColor colors2[4];
  double xM, yM;
  int nComps, i, j;

  nComps = shading->getColorSpace()->getNComps();
  const double *matrix = shading->getMatrix();

  // compare the four corner colors
  for (i = 0; i < 4; ++i) {
    for (j = 0; j < nComps; ++j) {
      if (abs(colors[i].c[j] - colors[(i+1)&3].c[j]) > functionColorDelta) {
	break;
      }
    }
    if (j < nComps) {
      break;
    }
  }

  // center of the rectangle
  xM = 0.5 * (x0 + x1);
  yM = 0.5 * (y0 + y1);

  // the four corner colors are close (or we hit the recursive limit)
  // -- fill the rectangle; but require at least one subdivision
  // (depth==0) to avoid problems when the four outer corners of the
  // shaded region are the same color
  if ((i == 4 && depth > 0) || depth == functionMaxDepth) {

    // use the center color
    shading->getColor(xM, yM, &fillColor);
    state->setFillColor(&fillColor);
    out->updateFillColor(state);

    // fill the rectangle
    state->moveTo(x0 * matrix[0] + y0 * matrix[2] + matrix[4],
		  x0 * matrix[1] + y0 * matrix[3] + matrix[5]);
    state->lineTo(x1 * matrix[0] + y0 * matrix[2] + matrix[4],
		  x1 * matrix[1] + y0 * matrix[3] + matrix[5]);
    state->lineTo(x1 * matrix[0] + y1 * matrix[2] + matrix[4],
		  x1 * matrix[1] + y1 * matrix[3] + matrix[5]);
    state->lineTo(x0 * matrix[0] + y1 * matrix[2] + matrix[4],
		  x0 * matrix[1] + y1 * matrix[3] + matrix[5]);
    state->closePath();
    out->fill(state);
    state->clearPath();

  // the four corner colors are not close enough -- subdivide the
  // rectangle
  } else {

    // colors[0]       colorM0       colors[2]
    //   (x0,y0)       (xM,y0)       (x1,y0)
    //         +----------+----------+
    //         |          |          |
    //         |    UL    |    UR    |
    // color0M |       colorMM       | color1M
    // (x0,yM) +----------+----------+ (x1,yM)
    //         |       (xM,yM)       |
    //         |    LL    |    LR    |
    //         |          |          |
    //         +----------+----------+
    // colors[1]       colorM1       colors[3]
    //   (x0,y1)       (xM,y1)       (x1,y1)

    shading->getColor(x0, yM, &color0M);
    shading->getColor(x1, yM, &color1M);
    shading->getColor(xM, y0, &colorM0);
    shading->getColor(xM, y1, &colorM1);
    shading->getColor(xM, yM, &colorMM);

    // upper-left sub-rectangle
    colors2[0] = colors[0];
    colors2[1] = color0M;
    colors2[2] = colorM0;
    colors2[3] = colorMM;
    doFunctionShFill1(shading, x0, y0, xM, yM, colors2, depth + 1);
    
    // lower-left sub-rectangle
    colors2[0] = color0M;
    colors2[1] = colors[1];
    colors2[2] = colorMM;
    colors2[3] = colorM1;
    doFunctionShFill1(shading, x0, yM, xM, y1, colors2, depth + 1);
    
    // upper-right sub-rectangle
    colors2[0] = colorM0;
    colors2[1] = colorMM;
    colors2[2] = colors[2];
    colors2[3] = color1M;
    doFunctionShFill1(shading, xM, y0, x1, yM, colors2, depth + 1);

    // lower-right sub-rectangle
    colors2[0] = colorMM;
    colors2[1] = colorM1;
    colors2[2] = color1M;
    colors2[3] = colors[3];
    doFunctionShFill1(shading, xM, yM, x1, y1, colors2, depth + 1);
  }
}

static void bubbleSort(double array[])
{
  for (int j = 0; j < 3; ++j) {
    int kk = j;
    for (int k = j + 1; k < 4; ++k) {
      if (array[k] < array[kk]) {
        kk = k;
      }
    }
    double tmp = array[j];
    array[j] = array[kk];
    array[kk] = tmp;
  }
}

void Gfx::doAxialShFill(GfxAxialShading *shading) {
  double xMin, yMin, xMax, yMax;
  double x0, y0, x1, y1;
  double dx, dy, mul;
  bool dxZero, dyZero;
  double bboxIntersections[4];
  double tMin, tMax, tx, ty;
  double s[4], sMin, sMax, tmp;
  double ux0, uy0, ux1, uy1, vx0, vy0, vx1, vy1;
  double t0, t1, tt;
  double ta[axialMaxSplits + 1];
  int next[axialMaxSplits + 1];
  GfxColor color0 = {}, color1 = {};
  int nComps;
  int i, j, k;
  bool needExtend = true;

  // get the clip region bbox
  state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);

  // compute min and max t values, based on the four corners of the
  // clip region bbox
  shading->getCoords(&x0, &y0, &x1, &y1);
  dx = x1 - x0;
  dy = y1 - y0;
  dxZero = fabs(dx) < 0.01;
  dyZero = fabs(dy) < 0.01;
  if (dxZero && dyZero) {
    tMin = tMax = 0;
  } else {
    mul = 1 / (dx * dx + dy * dy);
    bboxIntersections[0] = ((xMin - x0) * dx + (yMin - y0) * dy) * mul;
    bboxIntersections[1] = ((xMin - x0) * dx + (yMax - y0) * dy) * mul;
    bboxIntersections[2] = ((xMax - x0) * dx + (yMin - y0) * dy) * mul;
    bboxIntersections[3] = ((xMax - x0) * dx + (yMax - y0) * dy) * mul;
    bubbleSort(bboxIntersections);
    tMin = bboxIntersections[0];
    tMax = bboxIntersections[3];
    if (tMin < 0 && !shading->getExtend0()) {
      tMin = 0;
    }
    if (tMax > 1 && !shading->getExtend1()) {
      tMax = 1;
    }
  }

  if (out->useShadedFills( shading->getType() ) &&
      out->axialShadedFill(state, shading, tMin, tMax)) {
	  return;
  }

  // get the function domain
  t0 = shading->getDomain0();
  t1 = shading->getDomain1();

  // Traverse the t axis and do the shading.
  //
  // For each point (tx, ty) on the t axis, consider a line through
  // that point perpendicular to the t axis:
  //
  //     x(s) = tx + s * -dy   -->   s = (x - tx) / -dy
  //     y(s) = ty + s * dx    -->   s = (y - ty) / dx
  //
  // Then look at the intersection of this line with the bounding box
  // (xMin, yMin, xMax, yMax).  In the general case, there are four
  // intersection points:
  //
  //     s0 = (xMin - tx) / -dy
  //     s1 = (xMax - tx) / -dy
  //     s2 = (yMin - ty) / dx
  //     s3 = (yMax - ty) / dx
  //
  // and we want the middle two s values.
  //
  // In the case where dx = 0, take s0 and s1; in the case where dy =
  // 0, take s2 and s3.
  //
  // Each filled polygon is bounded by two of these line segments
  // perpdendicular to the t axis.
  //
  // The t axis is bisected into smaller regions until the color
  // difference across a region is small enough, and then the region
  // is painted with a single color.

  // set up: require at least one split to avoid problems when the two
  // ends of the t axis have the same color
  nComps = shading->getColorSpace()->getNComps();
  ta[0] = tMin;
  next[0] = axialMaxSplits / 2;
  ta[axialMaxSplits / 2] = 0.5 * (tMin + tMax);
  next[axialMaxSplits / 2] = axialMaxSplits;
  ta[axialMaxSplits] = tMax;

  // compute the color at t = tMin
  if (tMin < 0) {
    tt = t0;
  } else if (tMin > 1) {
    tt = t1;
  } else {
    tt = t0 + (t1 - t0) * tMin;
  }
  shading->getColor(tt, &color0);

  if (out->useFillColorStop()) {
    // make sure we add stop color when t = tMin
    state->setFillColor(&color0);
    out->updateFillColorStop(state, 0);
  }

  // compute the coordinates of the point on the t axis at t = tMin;
  // then compute the intersection of the perpendicular line with the
  // bounding box
  tx = x0 + tMin * dx;
  ty = y0 + tMin * dy;
  if (dxZero && dyZero) {
    sMin = sMax = 0;
  } else if (dxZero) {
    sMin = (xMin - tx) / -dy;
    sMax = (xMax - tx) / -dy;
    if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
  } else if (dyZero) {
    sMin = (yMin - ty) / dx;
    sMax = (yMax - ty) / dx;
    if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
  } else {
    s[0] = (yMin - ty) / dx;
    s[1] = (yMax - ty) / dx;
    s[2] = (xMin - tx) / -dy;
    s[3] = (xMax - tx) / -dy;
    bubbleSort(s);
    sMin = s[1];
    sMax = s[2];
  }
  ux0 = tx - sMin * dy;
  uy0 = ty + sMin * dx;
  vx0 = tx - sMax * dy;
  vy0 = ty + sMax * dx;

  i = 0;
  bool doneBBox1, doneBBox2;
  if (dxZero && dyZero) {
    doneBBox1 = doneBBox2 = true;
  } else {
    doneBBox1 = bboxIntersections[1] < tMin;
    doneBBox2 = bboxIntersections[2] > tMax;
  }

  // If output device doesn't support the extended mode required
  // we have to do it here
  needExtend = !out->axialShadedSupportExtend(state, shading);

  while (i < axialMaxSplits) {

    // bisect until color difference is small enough or we hit the
    // bisection limit
    j = next[i];
    while (j > i + 1) {
      if (ta[j] < 0) {
	tt = t0;
      } else if (ta[j] > 1) {
	tt = t1;
      } else {
	tt = t0 + (t1 - t0) * ta[j];
      }
      shading->getColor(tt, &color1);
      if (isSameGfxColor(color1, color0, nComps, axialColorDelta)) {
         // in these two if what we guarantee is that if we are skipping lots of 
         // positions because the colors are the same, we still create a region
         // with vertexs passing by bboxIntersections[1] and bboxIntersections[2]
         // otherwise we can have empty regions that should really be painted 
         // like happened in bug 19896
         // What we do to ensure that we pass a line through this points
         // is making sure use the exact bboxIntersections[] value as one of the used ta[] values
         if (!doneBBox1 && ta[i] < bboxIntersections[1] && ta[j] > bboxIntersections[1]) {
           int teoricalj = (int) ((bboxIntersections[1] - tMin) * axialMaxSplits / (tMax - tMin));
           if (teoricalj <= i) teoricalj = i + 1;
           if (teoricalj < j) {
             next[i] = teoricalj;
             next[teoricalj] = j;
           }
           else {
             teoricalj = j;
           }
           ta[teoricalj] = bboxIntersections[1];
           j = teoricalj;
           doneBBox1 = true;
         }
         if (!doneBBox2 && ta[i] < bboxIntersections[2] && ta[j] > bboxIntersections[2]) {
           int teoricalj = (int) ((bboxIntersections[2] - tMin) * axialMaxSplits / (tMax - tMin));
           if (teoricalj <= i) teoricalj = i + 1;
           if (teoricalj < j) {
             next[i] = teoricalj;
             next[teoricalj] = j;
           }
           else {
             teoricalj = j;
           }
           ta[teoricalj] = bboxIntersections[2];
           j = teoricalj;
           doneBBox2 = true;
         }
         break;
      }
      k = (i + j) / 2;
      ta[k] = 0.5 * (ta[i] + ta[j]);
      next[i] = k;
      next[k] = j;
      j = k;
    }

    // use the average of the colors of the two sides of the region
    for (k = 0; k < nComps; ++k) {
      color0.c[k] = safeAverage(color0.c[k], color1.c[k]);
    }

    // compute the coordinates of the point on the t axis; then
    // compute the intersection of the perpendicular line with the
    // bounding box
    tx = x0 + ta[j] * dx;
    ty = y0 + ta[j] * dy;
    if (dxZero && dyZero) {
      sMin = sMax = 0;
    } else if (dxZero) {
      sMin = (xMin - tx) / -dy;
      sMax = (xMax - tx) / -dy;
      if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
    } else if (dyZero) {
      sMin = (yMin - ty) / dx;
      sMax = (yMax - ty) / dx;
      if (sMin > sMax) { tmp = sMin; sMin = sMax; sMax = tmp; }
    } else {
      s[0] = (yMin - ty) / dx;
      s[1] = (yMax - ty) / dx;
      s[2] = (xMin - tx) / -dy;
      s[3] = (xMax - tx) / -dy;
      bubbleSort(s);
      sMin = s[1];
      sMax = s[2];
    }
    ux1 = tx - sMin * dy;
    uy1 = ty + sMin * dx;
    vx1 = tx - sMax * dy;
    vy1 = ty + sMax * dx;

    // set the color
    state->setFillColor(&color0);
    if (out->useFillColorStop())
      out->updateFillColorStop(state, (ta[j] - tMin)/(tMax - tMin));
    else
      out->updateFillColor(state);

    if (needExtend) {
      // fill the region
      state->moveTo(ux0, uy0);
      state->lineTo(vx0, vy0);
      state->lineTo(vx1, vy1);
      state->lineTo(ux1, uy1);
      state->closePath();
    }

    if (!out->useFillColorStop()) {
      out->fill(state);
      state->clearPath();
    }

    // set up for next region
    ux0 = ux1;
    uy0 = uy1;
    vx0 = vx1;
    vy0 = vy1;
    color0 = color1;
    i = next[i];
  }

  if (out->useFillColorStop()) {
    if (!needExtend) {
      state->moveTo(xMin, yMin);
      state->lineTo(xMin, yMax);
      state->lineTo(xMax, yMax);
      state->lineTo(xMax, yMin);
      state->closePath();
    }
    out->fill(state);
    state->clearPath();
  }
}

static inline void getShadingColorRadialHelper(double t0, double t1, double t, GfxRadialShading *shading, GfxColor *color)
{
  if (t0 < t1) {
    if (t < t0) {
      shading->getColor(t0, color);
    } else if (t > t1) {
      shading->getColor(t1, color);
    } else {
      shading->getColor(t, color);
    }
  } else {
    if (t > t0) {
      shading->getColor(t0, color);
    } else if (t < t1) {
      shading->getColor(t1, color);
    } else {
      shading->getColor(t, color);
    }
  }
}

void Gfx::doRadialShFill(GfxRadialShading *shading) {
  double xMin, yMin, xMax, yMax;
  double x0, y0, r0, x1, y1, r1, t0, t1;
  int nComps;
  GfxColor colorA = {}, colorB = {}, colorC = {};
  double xa, ya, xb, yb, ra, rb;
  double ta, tb, sa, sb;
  double sz, xz, yz, sMin, sMax;
  bool enclosed;
  int ia, ib, k, n;
  double theta, alpha, angle, t;
  bool needExtend = true;

  // get the shading info
  shading->getCoords(&x0, &y0, &r0, &x1, &y1, &r1);
  t0 = shading->getDomain0();
  t1 = shading->getDomain1();
  nComps = shading->getColorSpace()->getNComps();

  // Compute the point at which r(s) = 0; check for the enclosed
  // circles case; and compute the angles for the tangent lines.
  if (x0 == x1 && y0 == y1) {
    enclosed = true;
    theta = 0; // make gcc happy
    sz = 0; // make gcc happy
  } else if (r0 == r1) {
    enclosed = false;
    theta = 0;
    sz = 0; // make gcc happy
  } else {
    sz = (r1 > r0) ? -r0 / (r1 - r0) : -r1 / (r0 - r1);
    xz = x0 + sz * (x1 - x0);
    yz = y0 + sz * (y1 - y0);
    enclosed = (xz - x0) * (xz - x0) + (yz - y0) * (yz - y0) <= r0 * r0;
    const double theta_aux = sqrt((x0 - xz) * (x0 - xz) + (y0 - yz) * (y0 - yz));
    if (likely(theta_aux != 0)) {
      theta = asin(r0 / theta_aux);
    } else {
      theta = 0;
    }
    if (r0 > r1) {
      theta = -theta;
    }
  }
  if (enclosed) {
    alpha = 0;
  } else {
    alpha = atan2(y1 - y0, x1 - x0);
  }

  // compute the (possibly extended) s range
  state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
  if (enclosed) {
    sMin = 0;
    sMax = 1;
  } else {
    sMin = 1;
    sMax = 0;
    // solve for x(s) + r(s) = xMin
    if ((x1 + r1) - (x0 + r0) != 0) {
      sa = (xMin - (x0 + r0)) / ((x1 + r1) - (x0 + r0));
      if (sa < sMin) {
	sMin = sa;
      } else if (sa > sMax) {
	sMax = sa;
      }
    }
    // solve for x(s) - r(s) = xMax
    if ((x1 - r1) - (x0 - r0) != 0) {
      sa = (xMax - (x0 - r0)) / ((x1 - r1) - (x0 - r0));
      if (sa < sMin) {
	sMin = sa;
      } else if (sa > sMax) {
	sMax = sa;
      }
    }
    // solve for y(s) + r(s) = yMin
    if ((y1 + r1) - (y0 + r0) != 0) {
      sa = (yMin - (y0 + r0)) / ((y1 + r1) - (y0 + r0));
      if (sa < sMin) {
	sMin = sa;
      } else if (sa > sMax) {
	sMax = sa;
      }
    }
    // solve for y(s) - r(s) = yMax
    if ((y1 - r1) - (y0 - r0) != 0) {
      sa = (yMax - (y0 - r0)) / ((y1 - r1) - (y0 - r0));
      if (sa < sMin) {
	sMin = sa;
      } else if (sa > sMax) {
	sMax = sa;
      }
    }
    // check against sz
    if (r0 < r1) {
      if (sMin < sz) {
	sMin = sz;
      }
    } else if (r0 > r1) {
      if (sMax > sz) {
	sMax = sz;
      }
    }
    // check the 'extend' flags
    if (!shading->getExtend0() && sMin < 0) {
      sMin = 0;
    }
    if (!shading->getExtend1() && sMax > 1) {
      sMax = 1;
    }
  }

  if (out->useShadedFills( shading->getType() ) &&
      out->radialShadedFill(state, shading, sMin, sMax)) {
    return;
  }

  // compute the number of steps into which circles must be divided to
  // achieve a curve flatness of 0.1 pixel in device space for the
  // largest circle (note that "device space" is 72 dpi when generating
  // PostScript, hence the relatively small 0.1 pixel accuracy)
  const double *ctm = state->getCTM();
  t = fabs(ctm[0]);
  if (fabs(ctm[1]) > t) {
    t = fabs(ctm[1]);
  }
  if (fabs(ctm[2]) > t) {
    t = fabs(ctm[2]);
  }
  if (fabs(ctm[3]) > t) {
    t = fabs(ctm[3]);
  }
  if (r0 > r1) {
    t *= r0;
  } else {
    t *= r1;
  }
  if (t < 1) {
    n = 3;
  } else {
    const double tmp = 1 - 0.1 / t;
    if (unlikely(tmp == 1))
      n = 200;
    else
      n = (int)(M_PI / acos(tmp));
    if (n < 3) {
      n = 3;
    } else if (n > 200) {
      n = 200;
    }
  }

  // setup for the start circle
  ia = 0;
  sa = sMin;
  ta = t0 + sa * (t1 - t0);
  xa = x0 + sa * (x1 - x0);
  ya = y0 + sa * (y1 - y0);
  ra = r0 + sa * (r1 - r0);
  getShadingColorRadialHelper(t0, t1, ta, shading, &colorA);

  needExtend = !out->radialShadedSupportExtend(state, shading);

  // fill the circles
  while (ia < radialMaxSplits) {

    // go as far along the t axis (toward t1) as we can, such that the
    // color difference is within the tolerance (radialColorDelta) --
    // this uses bisection (between the current value, t, and t1),
    // limited to radialMaxSplits points along the t axis; require at
    // least one split to avoid problems when the innermost and
    // outermost colors are the same
    ib = radialMaxSplits;
    sb = sMax;
    tb = t0 + sb * (t1 - t0);
    getShadingColorRadialHelper(t0, t1, tb, shading, &colorB);
    while (ib - ia > 1) {
      if (isSameGfxColor(colorB, colorA, nComps, radialColorDelta)) {
        // The shading is not necessarily lineal so having two points with the
        // same color does not mean all the areas in between have the same color too
        int ic = ia + 1;
        for (; ic <= ib; ic++) {
          const double sc = sMin + ((double)ic / (double)radialMaxSplits) * (sMax - sMin);
          const double tc = t0 + sc * (t1 - t0);
          getShadingColorRadialHelper(t0, t1, tc, shading, &colorC);
          if (!isSameGfxColor(colorC, colorA, nComps, radialColorDelta)) {
            break;
          }
        }
        ib = (ic > ia + 1) ? ic - 1 : ia + 1;
        sb = sMin + ((double)ib / (double)radialMaxSplits) * (sMax - sMin);
        tb = t0 + sb * (t1 - t0);
        getShadingColorRadialHelper(t0, t1, tb, shading, &colorB);
        break;
      }
      ib = (ia + ib) / 2;
      sb = sMin + ((double)ib / (double)radialMaxSplits) * (sMax - sMin);
      tb = t0 + sb * (t1 - t0);
      getShadingColorRadialHelper(t0, t1, tb, shading, &colorB);
    }

    // compute center and radius of the circle
    xb = x0 + sb * (x1 - x0);
    yb = y0 + sb * (y1 - y0);
    rb = r0 + sb * (r1 - r0);

    // use the average of the colors at the two circles
    for (k = 0; k < nComps; ++k) {
      colorA.c[k] = safeAverage(colorA.c[k], colorB.c[k]);
    }
    state->setFillColor(&colorA);
    if (out->useFillColorStop())
      out->updateFillColorStop(state, (sa - sMin)/(sMax - sMin));
    else
      out->updateFillColor(state);

    if (needExtend) {
      if (enclosed) {
        // construct path for first circle (counterclockwise)
        state->moveTo(xa + ra, ya);
        for (k = 1; k < n; ++k) {
	  angle = ((double)k / (double)n) * 2 * M_PI;
	  state->lineTo(xa + ra * cos(angle), ya + ra * sin(angle));
        }
        state->closePath();

        // construct and append path for second circle (clockwise)
        state->moveTo(xb + rb, yb);
        for (k = 1; k < n; ++k) {
	  angle = -((double)k / (double)n) * 2 * M_PI;
	  state->lineTo(xb + rb * cos(angle), yb + rb * sin(angle));
        }
        state->closePath();
      } else {
        // construct the first subpath (clockwise)
        state->moveTo(xa + ra * cos(alpha + theta + 0.5 * M_PI),
		      ya + ra * sin(alpha + theta + 0.5 * M_PI));
        for (k = 0; k < n; ++k) {
	  angle = alpha + theta + 0.5 * M_PI
		  - ((double)k / (double)n) * (2 * theta + M_PI);
	  state->lineTo(xb + rb * cos(angle), yb + rb * sin(angle));
        }
	for (k = 0; k < n; ++k) {
	  angle = alpha - theta - 0.5 * M_PI
		  + ((double)k / (double)n) * (2 * theta - M_PI);
	  state->lineTo(xa + ra * cos(angle), ya + ra * sin(angle));
	}
	state->closePath();

        // construct the second subpath (counterclockwise)
	state->moveTo(xa + ra * cos(alpha + theta + 0.5 * M_PI),
		      ya + ra * sin(alpha + theta + 0.5 * M_PI));
	for (k = 0; k < n; ++k) {
	  angle = alpha + theta + 0.5 * M_PI
		  + ((double)k / (double)n) * (-2 * theta + M_PI);
	  state->lineTo(xb + rb * cos(angle), yb + rb * sin(angle));
	}
	for (k = 0; k < n; ++k) {
	  angle = alpha - theta - 0.5 * M_PI
		  + ((double)k / (double)n) * (2 * theta + M_PI);
	  state->lineTo(xa + ra * cos(angle), ya + ra * sin(angle));
	}
	state->closePath();
      }
    }

    if (!out->useFillColorStop()) {
      // fill the path
      out->fill(state);
      state->clearPath();
    }

    // step to the next value of t
    ia = ib;
    sa = sb;
    ta = tb;
    xa = xb;
    ya = yb;
    ra = rb;
    colorA = colorB;
  }

  if (out->useFillColorStop()) {
    // make sure we add stop color when sb = sMax
    state->setFillColor(&colorA);
    out->updateFillColorStop(state, (sb - sMin)/(sMax - sMin));

    // fill the path
    state->moveTo(xMin, yMin);
    state->lineTo(xMin, yMax);
    state->lineTo(xMax, yMax);
    state->lineTo(xMax, yMin);
    state->closePath();

    out->fill(state);
    state->clearPath();
  }

  if (!needExtend)
    return;

  if (enclosed) {
    // extend the smaller circle
    if ((shading->getExtend0() && r0 <= r1) ||
	(shading->getExtend1() && r1 < r0)) {
      if (r0 <= r1) {
	ta = t0;
	ra = r0;
	xa = x0;
	ya = y0;
      } else {
	ta = t1;
	ra = r1;
	xa = x1;
	ya = y1;
      }
      shading->getColor(ta, &colorA);
      state->setFillColor(&colorA);
      out->updateFillColor(state);
      state->moveTo(xa + ra, ya);
      for (k = 1; k < n; ++k) {
	angle = ((double)k / (double)n) * 2 * M_PI;
	state->lineTo(xa + ra * cos(angle), ya + ra * sin(angle));
      }
      state->closePath();
      out->fill(state);
      state->clearPath();
    }

    // extend the larger circle
    if ((shading->getExtend0() && r0 > r1) ||
	(shading->getExtend1() && r1 >= r0)) {
      if (r0 > r1) {
	ta = t0;
	ra = r0;
	xa = x0;
	ya = y0;
      } else {
	ta = t1;
	ra = r1;
	xa = x1;
	ya = y1;
      }
      shading->getColor(ta, &colorA);
      state->setFillColor(&colorA);
      out->updateFillColor(state);
      state->moveTo(xMin, yMin);
      state->lineTo(xMin, yMax);
      state->lineTo(xMax, yMax);
      state->lineTo(xMax, yMin);
      state->closePath();
      state->moveTo(xa + ra, ya);
      for (k = 1; k < n; ++k) {
	angle = ((double)k / (double)n) * 2 * M_PI;
	state->lineTo(xa + ra * cos(angle), ya + ra * sin(angle));
      }
      state->closePath();
      out->fill(state);
      state->clearPath();
    }
  }
}

void Gfx::doGouraudTriangleShFill(GfxGouraudTriangleShading *shading) {
  double x0, y0, x1, y1, x2, y2;
  int i;

  if (out->useShadedFills( shading->getType())) {
    if (out->gouraudTriangleShadedFill( state, shading))
      return;
  }

  // preallocate a path (speed improvements)
  state->moveTo(0., 0.);
  state->lineTo(1., 0.);
  state->lineTo(0., 1.);
  state->closePath();

  GfxState::ReusablePathIterator *reusablePath = state->getReusablePath();

  if (shading->isParameterized()) {
    // work with parameterized values:
    double color0, color1, color2;
    // a relative threshold:
    const double refineColorThreshold = gouraudParameterizedColorDelta *
                                        (shading->getParameterDomainMax() - shading->getParameterDomainMin());
    for (i = 0; i < shading->getNTriangles(); ++i) {
      shading->getTriangle(i, &x0, &y0, &color0,
                              &x1, &y1, &color1,
                              &x2, &y2, &color2);
      gouraudFillTriangle(x0, y0, color0, x1, y1, color1, x2, y2, color2, refineColorThreshold, 0, shading, reusablePath);
    }

  } else {
    // this always produces output -- even for parameterized ranges.
    // But it ignores the parameterized color map (the function). 
    //
    // Note that using this code in for parameterized shadings might be
    // correct in circumstances (namely if the function is linear in the actual
    // triangle), but in general, it will simply be wrong.
    GfxColor color0, color1, color2;
    for (i = 0; i < shading->getNTriangles(); ++i) {
      shading->getTriangle(i, &x0, &y0, &color0,
                              &x1, &y1, &color1,
                              &x2, &y2, &color2);
      gouraudFillTriangle(x0, y0, &color0, x1, y1, &color1, x2, y2, &color2, shading->getColorSpace()->getNComps(), 0, reusablePath);
    }
  }

  delete reusablePath;
}

static inline void checkTrue(bool b, const char *message) {
  if (unlikely(!b)) {
    error(errSyntaxError, -1, message);
  }
}

void Gfx::gouraudFillTriangle(double x0, double y0, GfxColor *color0,
			      double x1, double y1, GfxColor *color1,
			      double x2, double y2, GfxColor *color2,
			      int nComps, int depth, GfxState::ReusablePathIterator *path) {
  double x01, y01, x12, y12, x20, y20;
  GfxColor color01, color12, color20;
  int i;

  for (i = 0; i < nComps; ++i) {
    if (abs(color0->c[i] - color1->c[i]) > gouraudColorDelta ||
	abs(color1->c[i] - color2->c[i]) > gouraudColorDelta) {
      break;
    }
  }
  if (i == nComps || depth == gouraudMaxDepth) {
    state->setFillColor(color0);
    out->updateFillColor(state);

    path->reset();                         checkTrue(!path->isEnd(), "Path should not be at end");
    path->setCoord(x0,y0);  path->next();  checkTrue(!path->isEnd(), "Path should not be at end");
    path->setCoord(x1,y1);  path->next();  checkTrue(!path->isEnd(), "Path should not be at end");
    path->setCoord(x2,y2);  path->next();  checkTrue(!path->isEnd(), "Path should not be at end");
    path->setCoord(x0,y0);  path->next();  checkTrue( path->isEnd(), "Path should be at end");
    out->fill(state);

  } else {
    x01 = 0.5 * (x0 + x1);
    y01 = 0.5 * (y0 + y1);
    x12 = 0.5 * (x1 + x2);
    y12 = 0.5 * (y1 + y2);
    x20 = 0.5 * (x2 + x0);
    y20 = 0.5 * (y2 + y0);
    for (i = 0; i < nComps; ++i) {
      color01.c[i] = safeAverage(color0->c[i], color1->c[i]);
      color12.c[i] = safeAverage(color1->c[i], color2->c[i]);
      color20.c[i] = safeAverage(color2->c[i], color0->c[i]);
    }
    gouraudFillTriangle(x0, y0, color0, x01, y01, &color01,
			x20, y20, &color20, nComps, depth + 1, path);
    gouraudFillTriangle(x01, y01, &color01, x1, y1, color1,
			x12, y12, &color12, nComps, depth + 1, path);
    gouraudFillTriangle(x01, y01, &color01, x12, y12, &color12,
			x20, y20, &color20, nComps, depth + 1, path);
    gouraudFillTriangle(x20, y20, &color20, x12, y12, &color12,
			x2, y2, color2, nComps, depth + 1, path);
  }
}
void Gfx::gouraudFillTriangle(double x0, double y0, double color0,
                              double x1, double y1, double color1,
                              double x2, double y2, double color2,
                              double refineColorThreshold, int depth, GfxGouraudTriangleShading *shading, GfxState::ReusablePathIterator *path) {
  const double meanColor = (color0 + color1 + color2) / 3;

  const bool isFineEnough = 
       fabs(color0 - meanColor) < refineColorThreshold &&
       fabs(color1 - meanColor) < refineColorThreshold &&
       fabs(color2 - meanColor) < refineColorThreshold;

  if (isFineEnough || depth == gouraudMaxDepth) {
    GfxColor color;

    shading->getParameterizedColor(meanColor, &color);
    state->setFillColor(&color);
    out->updateFillColor(state);

    path->reset();                         checkTrue(!path->isEnd(), "Path should not be at end");
    path->setCoord(x0,y0);  path->next();  checkTrue(!path->isEnd(), "Path should not be at end");
    path->setCoord(x1,y1);  path->next();  checkTrue(!path->isEnd(), "Path should not be at end");
    path->setCoord(x2,y2);  path->next();  checkTrue(!path->isEnd(), "Path should not be at end");
    path->setCoord(x0,y0);  path->next();  checkTrue( path->isEnd(), "Path should be at end");
    out->fill(state);

  } else {
    const double x01 = 0.5 * (x0 + x1);
    const double y01 = 0.5 * (y0 + y1);
    const double x12 = 0.5 * (x1 + x2);
    const double y12 = 0.5 * (y1 + y2);
    const double x20 = 0.5 * (x2 + x0);
    const double y20 = 0.5 * (y2 + y0);
    const double color01 = (color0 + color1) / 2.;
    const double color12 = (color1 + color2) / 2.; 
    const double color20 = (color2 + color0) / 2.;
    ++depth;
    gouraudFillTriangle(x0, y0, color0, 
                        x01, y01, color01,
                        x20, y20, color20, 
                        refineColorThreshold, depth, shading, path);
    gouraudFillTriangle(x01, y01, color01, 
                        x1, y1, color1,
                        x12, y12, color12, 
                        refineColorThreshold, depth, shading, path);
    gouraudFillTriangle(x01, y01, color01, 
                        x12, y12, color12,
                        x20, y20, color20, 
                        refineColorThreshold, depth, shading, path);
    gouraudFillTriangle(x20, y20, color20, 
                        x12, y12, color12,
                        x2, y2, color2, 
                        refineColorThreshold, depth, shading, path);
  }
}

void Gfx::doPatchMeshShFill(GfxPatchMeshShading *shading) {
  int start, i;

  if (out->useShadedFills( shading->getType())) {
    if (out->patchMeshShadedFill( state, shading))
      return;
  }

  if (shading->getNPatches() > 128) {
    start = 3;
  } else if (shading->getNPatches() > 64) {
    start = 2;
  } else if (shading->getNPatches() > 16) {
    start = 1;
  } else {
    start = 0;
  }
  /*
   * Parameterized shadings take one parameter [t_0,t_e]
   * and map it into the color space.
   *
   * Consequently, all color values are stored as doubles.
   *
   * These color values are interpreted as parameters for parameterized
   * shadings and as colorspace entities otherwise.
   *
   * The only difference is that color space entities are stored into
   * DOUBLE arrays, not into arrays of type GfxColorComp.
   */
  const int colorComps = shading->getColorSpace()->getNComps();
  double refineColorThreshold;
  if( shading->isParameterized() ) {
	  refineColorThreshold = gouraudParameterizedColorDelta *
		  (shading->getParameterDomainMax() - shading->getParameterDomainMin());

  } else {
	  refineColorThreshold = patchColorDelta;
  }

  for (i = 0; i < shading->getNPatches(); ++i) {
    fillPatch(shading->getPatch(i),
             colorComps, 
             shading->isParameterized() ? 1 : colorComps,
             refineColorThreshold,
             start,
             shading);
  }
}


void Gfx::fillPatch(const GfxPatch *patch, int colorComps, int patchColorComps, double refineColorThreshold, int depth, const GfxPatchMeshShading *shading) {
  GfxPatch patch00, patch01, patch10, patch11;
  double xx[4][8], yy[4][8];
  double xxm, yym;
  int i;

  for (i = 0; i < patchColorComps; ++i) {
    // these comparisons are done in double arithmetics.
    //
    // For non-parameterized shadings, they are done in color space
    // components.
    if (fabs(patch->color[0][0].c[i] - patch->color[0][1].c[i]) > refineColorThreshold ||
        fabs(patch->color[0][1].c[i] - patch->color[1][1].c[i]) > refineColorThreshold ||
        fabs(patch->color[1][1].c[i] - patch->color[1][0].c[i]) > refineColorThreshold ||
        fabs(patch->color[1][0].c[i] - patch->color[0][0].c[i]) > refineColorThreshold) {
      break;
    }
  }
  if (i == patchColorComps || depth == patchMaxDepth) {
    GfxColor flatColor;
    if( shading->isParameterized() ) {
      shading->getParameterizedColor( patch->color[0][0].c[0], &flatColor );
    } else {
      for( i = 0; i<colorComps; ++i ) {
        // simply cast to the desired type; that's all what is needed.
        flatColor.c[i] = GfxColorComp(patch->color[0][0].c[i]);
      }
    }
    state->setFillColor(&flatColor);
    out->updateFillColor(state);
    state->moveTo(patch->x[0][0], patch->y[0][0]);
    state->curveTo(patch->x[0][1], patch->y[0][1],
		   patch->x[0][2], patch->y[0][2],
		   patch->x[0][3], patch->y[0][3]);
    state->curveTo(patch->x[1][3], patch->y[1][3],
		   patch->x[2][3], patch->y[2][3],
		   patch->x[3][3], patch->y[3][3]);
    state->curveTo(patch->x[3][2], patch->y[3][2],
		   patch->x[3][1], patch->y[3][1],
		   patch->x[3][0], patch->y[3][0]);
    state->curveTo(patch->x[2][0], patch->y[2][0],
		   patch->x[1][0], patch->y[1][0],
		   patch->x[0][0], patch->y[0][0]);
    state->closePath();
    out->fill(state);
    state->clearPath();
  } else {
    for (i = 0; i < 4; ++i) {
      xx[i][0] = patch->x[i][0];
      yy[i][0] = patch->y[i][0];
      xx[i][1] = 0.5 * (patch->x[i][0] + patch->x[i][1]);
      yy[i][1] = 0.5 * (patch->y[i][0] + patch->y[i][1]);
      xxm = 0.5 * (patch->x[i][1] + patch->x[i][2]);
      yym = 0.5 * (patch->y[i][1] + patch->y[i][2]);
      xx[i][6] = 0.5 * (patch->x[i][2] + patch->x[i][3]);
      yy[i][6] = 0.5 * (patch->y[i][2] + patch->y[i][3]);
      xx[i][2] = 0.5 * (xx[i][1] + xxm);
      yy[i][2] = 0.5 * (yy[i][1] + yym);
      xx[i][5] = 0.5 * (xxm + xx[i][6]);
      yy[i][5] = 0.5 * (yym + yy[i][6]);
      xx[i][3] = xx[i][4] = 0.5 * (xx[i][2] + xx[i][5]);
      yy[i][3] = yy[i][4] = 0.5 * (yy[i][2] + yy[i][5]);
      xx[i][7] = patch->x[i][3];
      yy[i][7] = patch->y[i][3];
    }
    for (i = 0; i < 4; ++i) {
      patch00.x[0][i] = xx[0][i];
      patch00.y[0][i] = yy[0][i];
      patch00.x[1][i] = 0.5 * (xx[0][i] + xx[1][i]);
      patch00.y[1][i] = 0.5 * (yy[0][i] + yy[1][i]);
      xxm = 0.5 * (xx[1][i] + xx[2][i]);
      yym = 0.5 * (yy[1][i] + yy[2][i]);
      patch10.x[2][i] = 0.5 * (xx[2][i] + xx[3][i]);
      patch10.y[2][i] = 0.5 * (yy[2][i] + yy[3][i]);
      patch00.x[2][i] = 0.5 * (patch00.x[1][i] + xxm);
      patch00.y[2][i] = 0.5 * (patch00.y[1][i] + yym);
      patch10.x[1][i] = 0.5 * (xxm + patch10.x[2][i]);
      patch10.y[1][i] = 0.5 * (yym + patch10.y[2][i]);
      patch00.x[3][i] = 0.5 * (patch00.x[2][i] + patch10.x[1][i]);
      patch00.y[3][i] = 0.5 * (patch00.y[2][i] + patch10.y[1][i]);
      patch10.x[0][i] = patch00.x[3][i];
      patch10.y[0][i] = patch00.y[3][i];
      patch10.x[3][i] = xx[3][i];
      patch10.y[3][i] = yy[3][i];
    }
    for (i = 4; i < 8; ++i) {
      patch01.x[0][i-4] = xx[0][i];
      patch01.y[0][i-4] = yy[0][i];
      patch01.x[1][i-4] = 0.5 * (xx[0][i] + xx[1][i]);
      patch01.y[1][i-4] = 0.5 * (yy[0][i] + yy[1][i]);
      xxm = 0.5 * (xx[1][i] + xx[2][i]);
      yym = 0.5 * (yy[1][i] + yy[2][i]);
      patch11.x[2][i-4] = 0.5 * (xx[2][i] + xx[3][i]);
      patch11.y[2][i-4] = 0.5 * (yy[2][i] + yy[3][i]);
      patch01.x[2][i-4] = 0.5 * (patch01.x[1][i-4] + xxm);
      patch01.y[2][i-4] = 0.5 * (patch01.y[1][i-4] + yym);
      patch11.x[1][i-4] = 0.5 * (xxm + patch11.x[2][i-4]);
      patch11.y[1][i-4] = 0.5 * (yym + patch11.y[2][i-4]);
      patch01.x[3][i-4] = 0.5 * (patch01.x[2][i-4] + patch11.x[1][i-4]);
      patch01.y[3][i-4] = 0.5 * (patch01.y[2][i-4] + patch11.y[1][i-4]);
      patch11.x[0][i-4] = patch01.x[3][i-4];
      patch11.y[0][i-4] = patch01.y[3][i-4];
      patch11.x[3][i-4] = xx[3][i];
      patch11.y[3][i-4] = yy[3][i];
    }
    for (i = 0; i < patchColorComps; ++i) {
      patch00.color[0][0].c[i] = patch->color[0][0].c[i];
      patch00.color[0][1].c[i] = (patch->color[0][0].c[i] +
				  patch->color[0][1].c[i]) / 2.;
      patch01.color[0][0].c[i] = patch00.color[0][1].c[i];
      patch01.color[0][1].c[i] = patch->color[0][1].c[i];
      patch01.color[1][1].c[i] = (patch->color[0][1].c[i] +
				  patch->color[1][1].c[i]) / 2.;
      patch11.color[0][1].c[i] = patch01.color[1][1].c[i];
      patch11.color[1][1].c[i] = patch->color[1][1].c[i];
      patch11.color[1][0].c[i] = (patch->color[1][1].c[i] +
				  patch->color[1][0].c[i]) / 2.;
      patch10.color[1][1].c[i] = patch11.color[1][0].c[i];
      patch10.color[1][0].c[i] = patch->color[1][0].c[i];
      patch10.color[0][0].c[i] = (patch->color[1][0].c[i] +
				  patch->color[0][0].c[i]) / 2.;
      patch00.color[1][0].c[i] = patch10.color[0][0].c[i];
      patch00.color[1][1].c[i] = (patch00.color[1][0].c[i] +
				  patch01.color[1][1].c[i]) / 2.;
      patch01.color[1][0].c[i] = patch00.color[1][1].c[i];
      patch11.color[0][0].c[i] = patch00.color[1][1].c[i];
      patch10.color[0][1].c[i] = patch00.color[1][1].c[i];
    }
    fillPatch(&patch00, colorComps, patchColorComps, refineColorThreshold, depth + 1, shading);
    fillPatch(&patch10, colorComps, patchColorComps, refineColorThreshold, depth + 1, shading);
    fillPatch(&patch01, colorComps, patchColorComps, refineColorThreshold, depth + 1, shading);
    fillPatch(&patch11, colorComps, patchColorComps, refineColorThreshold, depth + 1, shading);
  }
}

void Gfx::doEndPath() {
  if (state->isCurPt() && clip != clipNone) {
    state->clip();
    if (clip == clipNormal) {
      out->clip(state);
    } else {
      out->eoClip(state);
    }
  }
  clip = clipNone;
  state->clearPath();
}

//------------------------------------------------------------------------
// path clipping operators
//------------------------------------------------------------------------

void Gfx::opClip(Object args[], int numArgs) {
  clip = clipNormal;
}

void Gfx::opEOClip(Object args[], int numArgs) {
  clip = clipEO;
}

//------------------------------------------------------------------------
// text object operators
//------------------------------------------------------------------------

void Gfx::opBeginText(Object args[], int numArgs) {
  out->beginTextObject(state);
  state->setTextMat(1, 0, 0, 1, 0, 0);
  state->textMoveTo(0, 0);
  out->updateTextMat(state);
  out->updateTextPos(state);
  fontChanged = true;
}

void Gfx::opEndText(Object args[], int numArgs) {
  out->endTextObject(state);
}

//------------------------------------------------------------------------
// text state operators
//------------------------------------------------------------------------

void Gfx::opSetCharSpacing(Object args[], int numArgs) {
  state->setCharSpace(args[0].getNum());
  out->updateCharSpace(state);
}

void Gfx::opSetFont(Object args[], int numArgs) {
  GfxFont *font;

  if (!(font = res->lookupFont(args[0].getName()))) {
    // unsetting the font (drawing no text) is better than using the
    // previous one and drawing random glyphs from it
    state->setFont(nullptr, args[1].getNum());
    fontChanged = true;
    return;
  }
  if (printCommands) {
    printf("  font: tag=%s name='%s' %g\n",
	   font->getTag()->c_str(),
	   font->getName() ? font->getName()->c_str() : "???",
	   args[1].getNum());
    fflush(stdout);
  }

  font->incRefCnt();
  state->setFont(font, args[1].getNum());
  fontChanged = true;
}

void Gfx::opSetTextLeading(Object args[], int numArgs) {
  state->setLeading(args[0].getNum());
}

void Gfx::opSetTextRender(Object args[], int numArgs) {
  state->setRender(args[0].getInt());
  out->updateRender(state);
}

void Gfx::opSetTextRise(Object args[], int numArgs) {
  state->setRise(args[0].getNum());
  out->updateRise(state);
}

void Gfx::opSetWordSpacing(Object args[], int numArgs) {
  state->setWordSpace(args[0].getNum());
  out->updateWordSpace(state);
}

void Gfx::opSetHorizScaling(Object args[], int numArgs) {
  state->setHorizScaling(args[0].getNum());
  out->updateHorizScaling(state);
  fontChanged = true;
}

//------------------------------------------------------------------------
// text positioning operators
//------------------------------------------------------------------------

void Gfx::opTextMove(Object args[], int numArgs) {
  double tx, ty;

  tx = state->getLineX() + args[0].getNum();
  ty = state->getLineY() + args[1].getNum();
  state->textMoveTo(tx, ty);
  out->updateTextPos(state);
}

void Gfx::opTextMoveSet(Object args[], int numArgs) {
  double tx, ty;

  tx = state->getLineX() + args[0].getNum();
  ty = args[1].getNum();
  state->setLeading(-ty);
  ty += state->getLineY();
  state->textMoveTo(tx, ty);
  out->updateTextPos(state);
}

void Gfx::opSetTextMatrix(Object args[], int numArgs) {
  state->setTextMat(args[0].getNum(), args[1].getNum(),
		    args[2].getNum(), args[3].getNum(),
		    args[4].getNum(), args[5].getNum());
  state->textMoveTo(0, 0);
  out->updateTextMat(state);
  out->updateTextPos(state);
  fontChanged = true;
}

void Gfx::opTextNextLine(Object args[], int numArgs) {
  double tx, ty;

  tx = state->getLineX();
  ty = state->getLineY() - state->getLeading();
  state->textMoveTo(tx, ty);
  out->updateTextPos(state);
}

//------------------------------------------------------------------------
// text string operators
//------------------------------------------------------------------------

void Gfx::opShowText(Object args[], int numArgs) {
  if (!state->getFont()) {
    error(errSyntaxError, getPos(), "No font in show");
    return;
  }
  if (fontChanged) {
    out->updateFont(state);
    fontChanged = false;
  }
  out->beginStringOp(state);
  doShowText(args[0].getString());
  out->endStringOp(state);
  if (!ocState) {
    doIncCharCount(args[0].getString());
  }
}

void Gfx::opMoveShowText(Object args[], int numArgs) {
  double tx, ty;

  if (!state->getFont()) {
    error(errSyntaxError, getPos(), "No font in move/show");
    return;
  }
  if (fontChanged) {
    out->updateFont(state);
    fontChanged = false;
  }
  tx = state->getLineX();
  ty = state->getLineY() - state->getLeading();
  state->textMoveTo(tx, ty);
  out->updateTextPos(state);
  out->beginStringOp(state);
  doShowText(args[0].getString());
  out->endStringOp(state);
  if (!ocState) {
    doIncCharCount(args[0].getString());
  }
}

void Gfx::opMoveSetShowText(Object args[], int numArgs) {
  double tx, ty;

  if (!state->getFont()) {
    error(errSyntaxError, getPos(), "No font in move/set/show");
    return;
  }
  if (fontChanged) {
    out->updateFont(state);
    fontChanged = false;
  }
  state->setWordSpace(args[0].getNum());
  state->setCharSpace(args[1].getNum());
  tx = state->getLineX();
  ty = state->getLineY() - state->getLeading();
  state->textMoveTo(tx, ty);
  out->updateWordSpace(state);
  out->updateCharSpace(state);
  out->updateTextPos(state);
  out->beginStringOp(state);
  doShowText(args[2].getString());
  out->endStringOp(state);
  if (ocState) {
    doIncCharCount(args[2].getString());
  }
}

void Gfx::opShowSpaceText(Object args[], int numArgs) {
  Array *a;
  int wMode;
  int i;

  if (!state->getFont()) {
    error(errSyntaxError, getPos(), "No font in show/space");
    return;
  }
  if (fontChanged) {
    out->updateFont(state);
    fontChanged = false;
  }
  out->beginStringOp(state);
  wMode = state->getFont()->getWMode();
  a = args[0].getArray();
  for (i = 0; i < a->getLength(); ++i) {
    Object obj = a->get(i);
    if (obj.isNum()) {
      // this uses the absolute value of the font size to match
      // Acrobat's behavior
      if (wMode) {
        state->textShift(0, -obj.getNum() * 0.001 *
          state->getFontSize());
      } else {
        state->textShift(-obj.getNum() * 0.001 *
          state->getFontSize() *
          state->getHorizScaling(), 0);
      }
      out->updateTextShift(state, obj.getNum());
    } else if (obj.isString()) {
      doShowText(obj.getString());
    } else {
      error(errSyntaxError, getPos(),
        "Element of show/space array must be number or string");
    }
  }
  out->endStringOp(state);
  if (!ocState) {
    a = args[0].getArray();
    for (i = 0; i < a->getLength(); ++i) {
      Object obj = a->get(i);
      if (obj.isString()) {
	doIncCharCount(obj.getString());
      }
    }
  }
}

void Gfx::doShowText(const GooString *s) {
  GfxFont *font;
  int wMode;
  double riseX, riseY;
  CharCode code;
  Unicode *u = nullptr;
  double x, y, dx, dy, dx2, dy2, curX, curY, tdx, tdy, ddx, ddy;
  double originX, originY, tOriginX, tOriginY;
  double x0, y0, x1, y1;
  double tmp[4], newCTM[6];
  const double *oldCTM, *mat;
  Dict *resDict;
  Parser *oldParser;
  GfxState *savedState;
  const char *p;
  int render;
  bool patternFill;
  int len, n, uLen, nChars, nSpaces;

  font = state->getFont();
  wMode = font->getWMode();

  if (out->useDrawChar()) {
    out->beginString(state, s);
  }

  // if we're doing a pattern fill, set up clipping
  render = state->getRender();
  if (!(render & 1) &&
      state->getFillColorSpace()->getMode() == csPattern) {
    patternFill = true;
    saveState();
    // disable fill, enable clipping, leave stroke unchanged
    if ((render ^ (render >> 1)) & 1) {
      render = 5;
    } else {
      render = 7;
    }
    state->setRender(render);
    out->updateRender(state);
  } else {
    patternFill = false;
  }

  state->textTransformDelta(0, state->getRise(), &riseX, &riseY);
  x0 = state->getCurX() + riseX;
  y0 = state->getCurY() + riseY;

  // handle a Type 3 char
  if (font->getType() == fontType3 && out->interpretType3Chars()) {
    oldCTM = state->getCTM();
    mat = state->getTextMat();
    tmp[0] = mat[0] * oldCTM[0] + mat[1] * oldCTM[2];
    tmp[1] = mat[0] * oldCTM[1] + mat[1] * oldCTM[3];
    tmp[2] = mat[2] * oldCTM[0] + mat[3] * oldCTM[2];
    tmp[3] = mat[2] * oldCTM[1] + mat[3] * oldCTM[3];
    mat = font->getFontMatrix();
    newCTM[0] = mat[0] * tmp[0] + mat[1] * tmp[2];
    newCTM[1] = mat[0] * tmp[1] + mat[1] * tmp[3];
    newCTM[2] = mat[2] * tmp[0] + mat[3] * tmp[2];
    newCTM[3] = mat[2] * tmp[1] + mat[3] * tmp[3];
    newCTM[0] *= state->getFontSize();
    newCTM[1] *= state->getFontSize();
    newCTM[2] *= state->getFontSize();
    newCTM[3] *= state->getFontSize();
    newCTM[0] *= state->getHorizScaling();
    newCTM[1] *= state->getHorizScaling();
    curX = state->getCurX();
    curY = state->getCurY();
    oldParser = parser;
    p = s->c_str();
    len = s->getLength();
    while (len > 0) {
      n = font->getNextChar(p, len, &code,
			    &u, &uLen,
			    &dx, &dy, &originX, &originY);
      dx = dx * state->getFontSize() + state->getCharSpace();
      if (n == 1 && *p == ' ') {
	dx += state->getWordSpace();
      }
      dx *= state->getHorizScaling();
      dy *= state->getFontSize();
      state->textTransformDelta(dx, dy, &tdx, &tdy);
      state->transform(curX + riseX, curY + riseY, &x, &y);
      savedState = saveStateStack();
      state->setCTM(newCTM[0], newCTM[1], newCTM[2], newCTM[3], x, y);
      //~ the CTM concat values here are wrong (but never used)
      out->updateCTM(state, 1, 0, 0, 1, 0, 0);
      state->transformDelta(dx, dy, &ddx, &ddy);
      if (!out->beginType3Char(state, curX + riseX, curY + riseY, ddx, ddy,
			       code, u, uLen)) {
	Object charProc = ((Gfx8BitFont *)font)->getCharProcNF(code);
	int refNum = -1;
	if (charProc.isRef()) {
	  refNum = charProc.getRef().num;
	  charProc = charProc.fetch(((Gfx8BitFont *)font)->getCharProcs()->getXRef());
	}
	if ((resDict = ((Gfx8BitFont *)font)->getResources())) {
	  pushResources(resDict);
	}
	if (charProc.isStream()) {
	  std::set<int>::iterator charProcDrawingIt;
	  bool displayCharProc = true;
	  if (refNum != -1) {
	    if (charProcDrawing.find(refNum) == charProcDrawing.end()) {
	      charProcDrawingIt = charProcDrawing.insert(refNum).first;
	    } else {
	      displayCharProc = false;
	      error(errSyntaxError, -1, "CharProc wants to draw a CharProc that is already beign drawn");
	    }
	  }
	  if (displayCharProc) {
	    display(&charProc, false);

	    if (refNum != -1) {
	      charProcDrawing.erase(charProcDrawingIt);
	    }
	  }
	} else {
	  error(errSyntaxError, getPos(), "Missing or bad Type3 CharProc entry");
	}
	out->endType3Char(state);
	if (resDict) {
	  popResources();
	}
      }
      restoreStateStack(savedState);
      // GfxState::restore() does *not* restore the current position,
      // so we deal with it here using (curX, curY) and (lineX, lineY)
      curX += tdx;
      curY += tdy;
      state->moveTo(curX, curY);
      out->updateCTM(state, 0, 0, 0, 0, 0, 0);
      p += n;
      len -= n;
    }
    parser = oldParser;

  } else if (out->useDrawChar()) {
    p = s->c_str();
    len = s->getLength();
    while (len > 0) {
      n = font->getNextChar(p, len, &code,
			    &u, &uLen,
			    &dx, &dy, &originX, &originY);
      if (wMode) {
	dx *= state->getFontSize();
	dy = dy * state->getFontSize() + state->getCharSpace();
	if (n == 1 && *p == ' ') {
	  dy += state->getWordSpace();
	}
      } else {
	dx = dx * state->getFontSize() + state->getCharSpace();
	if (n == 1 && *p == ' ') {
	  dx += state->getWordSpace();
	}
	dx *= state->getHorizScaling();
	dy *= state->getFontSize();
      }
      state->textTransformDelta(dx, dy, &tdx, &tdy);
      originX *= state->getFontSize();
      originY *= state->getFontSize();
      state->textTransformDelta(originX, originY, &tOriginX, &tOriginY);
      if (ocState)
        out->drawChar(state, state->getCurX() + riseX, state->getCurY() + riseY,
		      tdx, tdy, tOriginX, tOriginY, code, n, u, uLen);
      state->shift(tdx, tdy);
      p += n;
      len -= n;
    }
  } else {
    dx = dy = 0;
    p = s->c_str();
    len = s->getLength();
    nChars = nSpaces = 0;
    while (len > 0) {
      n = font->getNextChar(p, len, &code,
			    &u, &uLen,
			    &dx2, &dy2, &originX, &originY);
      dx += dx2;
      dy += dy2;
      if (n == 1 && *p == ' ') {
	++nSpaces;
      }
      ++nChars;
      p += n;
      len -= n;
    }
    if (wMode) {
      dx *= state->getFontSize();
      dy = dy * state->getFontSize()
	   + nChars * state->getCharSpace()
	   + nSpaces * state->getWordSpace();
    } else {
      dx = dx * state->getFontSize()
	   + nChars * state->getCharSpace()
	   + nSpaces * state->getWordSpace();
      dx *= state->getHorizScaling();
      dy *= state->getFontSize();
    }
    state->textTransformDelta(dx, dy, &tdx, &tdy);
    if (ocState)
      out->drawString(state, s);
    state->shift(tdx, tdy);
  }

  if (out->useDrawChar()) {
    out->endString(state);
  }

  if (patternFill && ocState) {
    out->saveTextPos(state);
    // tell the OutputDev to do the clipping
    out->endTextObject(state);
    // set up a clipping bbox so doPatternText will work -- assume
    // that the text bounding box does not extend past the baseline in
    // any direction by more than twice the font size
    x1 = state->getCurX() + riseX;
    y1 = state->getCurY() + riseY;
    if (x0 > x1) {
      x = x0; x0 = x1; x1 = x;
    }
    if (y0 > y1) {
      y = y0; y0 = y1; y1 = y;
    }
    state->textTransformDelta(0, state->getFontSize(), &dx, &dy);
    state->textTransformDelta(state->getFontSize(), 0, &dx2, &dy2);
    dx = fabs(dx);
    dx2 = fabs(dx2);
    if (dx2 > dx) {
      dx = dx2;
    }
    dy = fabs(dy);
    dy2 = fabs(dy2);
    if (dy2 > dy) {
      dy = dy2;
    }
    state->clipToRect(x0 - 2 * dx, y0 - 2 * dy, x1 + 2 * dx, y1 + 2 * dy);
    // set render mode to fill-only
    state->setRender(0);
    out->updateRender(state);
    doPatternText();
    restoreState();
    out->restoreTextPos(state);
  }

  updateLevel += 10 * s->getLength();
}

// NB: this is only called when ocState is false.
void Gfx::doIncCharCount(const GooString *s) {
  if (out->needCharCount()) {
    out->incCharCount(s->getLength());
  }
}

//------------------------------------------------------------------------
// XObject operators
//------------------------------------------------------------------------

void Gfx::opXObject(Object args[], int numArgs) {
  const char *name;

  if (!ocState && !out->needCharCount()) {
    return;
  }
  name = args[0].getName();
  Object obj1 = res->lookupXObject(name);
  if (obj1.isNull()) {
    return;
  }
  if (!obj1.isStream()) {
      error(errSyntaxError, getPos(), "XObject '{0:s}' is wrong type", name);
    return;
  }

#ifdef OPI_SUPPORT
  Object opiDict = obj1.streamGetDict()->lookup("OPI");
  if (opiDict.isDict()) {
    out->opiBegin(state, opiDict.getDict());
  }
#endif
  Object obj2 = obj1.streamGetDict()->lookup("Subtype");
  if (obj2.isName("Image")) {
    if (out->needNonText()) {
      Object refObj = res->lookupXObjectNF(name);
      doImage(&refObj, obj1.getStream(), false);
    }
  } else if (obj2.isName("Form")) {
    Object refObj = res->lookupXObjectNF(name);
    bool shouldDoForm = true;
    std::set<int>::iterator drawingFormIt;
    if (refObj.isRef()) {
      const int num = refObj.getRef().num;
      if (formsDrawing.find(num) == formsDrawing.end()) {
	drawingFormIt = formsDrawing.insert(num).first;
      } else {
	shouldDoForm = false;	
      }
    }
    if (shouldDoForm) {
      if (out->useDrawForm() && refObj.isRef()) {
	out->drawForm(refObj.getRef());
      } else {
	doForm(&obj1);
      }
    }
    if (refObj.isRef() && shouldDoForm) {
      formsDrawing.erase(drawingFormIt);
    }
  } else if (obj2.isName("PS")) {
    Object obj3 = obj1.streamGetDict()->lookup("Level1");
    out->psXObject(obj1.getStream(),
		   obj3.isStream() ? obj3.getStream() : nullptr);
  } else if (obj2.isName()) {
    error(errSyntaxError, getPos(), "Unknown XObject subtype '{0:s}'", obj2.getName());
  } else {
    error(errSyntaxError, getPos(), "XObject subtype is missing or wrong type");
  }
#ifdef OPI_SUPPORT
  if (opiDict.isDict()) {
    out->opiEnd(state, opiDict.getDict());
  }
#endif
}

void Gfx::doImage(Object *ref, Stream *str, bool inlineImg) {
  Dict *dict, *maskDict;
  int width, height;
  int bits, maskBits;
  bool interpolate;
  StreamColorSpaceMode csMode;
  bool mask;
  bool invert;
  GfxColorSpace *colorSpace, *maskColorSpace;
  bool haveColorKeyMask, haveExplicitMask, haveSoftMask;
  int maskColors[2*gfxColorMaxComps] = {};
  int maskWidth, maskHeight;
  bool maskInvert;
  bool maskInterpolate;
  Stream *maskStr;
  int i, n;

  // get info from the stream
  bits = 0;
  csMode = streamCSNone;
  str->getImageParams(&bits, &csMode);

  // get stream dict
  dict = str->getDict();

  // check for optional content key
  if (ref) {
    const Object &objOC = dict->lookupNF("OC");
    if (catalog->getOptContentConfig() && !catalog->getOptContentConfig()->optContentIsVisible(&objOC)) {
      return;
    }
  }

  // get size
  Object obj1 = dict->lookup("Width");
  if (obj1.isNull()) {
    obj1 = dict->lookup("W");
  }
  if (obj1.isInt())
    width = obj1.getInt();
  else if (obj1.isReal())
    width = (int)obj1.getReal();
  else
    goto err1;
  obj1 = dict->lookup("Height");
  if (obj1.isNull()) {
    obj1 = dict->lookup("H");
  }
  if (obj1.isInt())
    height = obj1.getInt();
  else if (obj1.isReal())
    height = (int)obj1.getReal();
  else
    goto err1;

  if (width < 1 || height < 1)
    goto err1;

  // image interpolation
  obj1 = dict->lookup("Interpolate");
  if (obj1.isNull()) {
    obj1 = dict->lookup("I");
  }
  if (obj1.isBool())
    interpolate = obj1.getBool();
  else
    interpolate = false;
  maskInterpolate = false;

  // image or mask?
  obj1 = dict->lookup("ImageMask");
  if (obj1.isNull()) {
    obj1 = dict->lookup("IM");
  }
  mask = false;
  if (obj1.isBool())
    mask = obj1.getBool();
  else if (!obj1.isNull())
    goto err1;

  // bit depth
  if (bits == 0) {
    obj1 = dict->lookup("BitsPerComponent");
    if (obj1.isNull()) {
      obj1 = dict->lookup("BPC");
    }
    if (obj1.isInt()) {
      bits = obj1.getInt();
    } else if (mask) {
      bits = 1;
    } else {
      goto err1;
    }
  }

  // display a mask
  if (mask) {

    // check for inverted mask
    if (bits != 1)
      goto err1;
    invert = false;
    obj1 = dict->lookup("Decode");
    if (obj1.isNull()) {
      obj1 = dict->lookup("D");
    }
    if (obj1.isArray()) {
      Object obj2;
      obj2 = obj1.arrayGet(0);
      // Table 4.39 says /Decode must be [1 0] or [0 1]. Adobe
      // accepts [1.0 0.0] as well.
      if (obj2.isNum() && obj2.getNum() >= 0.9)
	invert = true;
    } else if (!obj1.isNull()) {
      goto err1;
    }

    // if drawing is disabled, skip over inline image data
    if (!ocState || !out->needNonText()) {
      str->reset();
      n = height * ((width + 7) / 8);
      for (i = 0; i < n; ++i) {
	str->getChar();
      }
      str->close();

    // draw it
    } else {
      if (state->getFillColorSpace()->getMode() == csPattern) {
	doPatternImageMask(ref, str, width, height, invert, inlineImg);
      } else {
	out->drawImageMask(state, ref, str, width, height, invert, interpolate, inlineImg);
      }
    }
  } else {
    if (bits == 0) {
      goto err1;
    }

    // get color space and color map
    obj1 = dict->lookup("ColorSpace");
    if (obj1.isNull()) {
      obj1 = dict->lookup("CS");
    }
    if (obj1.isName() && inlineImg) {
      Object obj2 = res->lookupColorSpace(obj1.getName());
      if (!obj2.isNull()) {
	obj1 = std::move(obj2);
      }
    }
    if (!obj1.isNull()) {
      char *tempIntent = nullptr;
      Object objIntent = dict->lookup("Intent");
      if (objIntent.isName()) {
        tempIntent = state->getRenderingIntent();
        if (tempIntent != nullptr) {
          tempIntent = strdup(tempIntent);
        }
        state->setRenderingIntent(objIntent.getName());
      }
      colorSpace = GfxColorSpace::parse(res, &obj1, out, state);
      if (objIntent.isName()) {
        state->setRenderingIntent(tempIntent);
        free(tempIntent);
      }
    } else if (csMode == streamCSDeviceGray) {
      Object objCS = res->lookupColorSpace("DefaultGray");
      if (objCS.isNull()) {
        colorSpace = new GfxDeviceGrayColorSpace();
      } else {
        colorSpace = GfxColorSpace::parse(res, &objCS, out, state);
      }
    } else if (csMode == streamCSDeviceRGB) {
      Object objCS = res->lookupColorSpace("DefaultRGB");
      if (objCS.isNull()) {
        colorSpace = new GfxDeviceRGBColorSpace();
      } else {
        colorSpace = GfxColorSpace::parse(res, &objCS, out, state);
      }
    } else if (csMode == streamCSDeviceCMYK) {
      Object objCS = res->lookupColorSpace("DefaultCMYK");
      if (objCS.isNull()) {
        colorSpace = new GfxDeviceCMYKColorSpace();
      } else {
        colorSpace = GfxColorSpace::parse(res, &objCS, out, state);
      }
    } else {
      colorSpace = nullptr;
    }
    if (!colorSpace) {
      goto err1;
    }
    obj1 = dict->lookup("Decode");
    if (obj1.isNull()) {
      obj1 = dict->lookup("D");
    }
    GfxImageColorMap colorMap(bits, &obj1, colorSpace);
    if (!colorMap.isOk()) {
      goto err1;
    }

    // get the mask
    haveColorKeyMask = haveExplicitMask = haveSoftMask = false;
    maskStr = nullptr; // make gcc happy
    maskWidth = maskHeight = 0; // make gcc happy
    maskInvert = false; // make gcc happy
    std::unique_ptr<GfxImageColorMap> maskColorMap;
    Object maskObj = dict->lookup("Mask");
    Object smaskObj = dict->lookup("SMask");
    if (smaskObj.isStream()) {
      // soft mask
      if (inlineImg) {
	goto err1;
      }
      maskStr = smaskObj.getStream();
      maskDict = smaskObj.streamGetDict();
      obj1 = maskDict->lookup("Width");
      if (obj1.isNull()) {
	obj1 = maskDict->lookup("W");
      }
      if (!obj1.isInt()) {
	goto err1;
      }
      maskWidth = obj1.getInt();
      obj1 = maskDict->lookup("Height");
      if (obj1.isNull()) {
	obj1 = maskDict->lookup("H");
      }
      if (!obj1.isInt()) {
	goto err1;
      }
      maskHeight = obj1.getInt();
      obj1 = maskDict->lookup("Interpolate");
      if (obj1.isNull()) {
        obj1 = maskDict->lookup("I");
      }
      if (obj1.isBool())
        maskInterpolate = obj1.getBool();
      else
        maskInterpolate = false;
      obj1 = maskDict->lookup("BitsPerComponent");
      if (obj1.isNull()) {
	obj1 = maskDict->lookup("BPC");
      }
      if (!obj1.isInt()) {
	goto err1;
      }
      maskBits = obj1.getInt();
      obj1 = maskDict->lookup("ColorSpace");
      if (obj1.isNull()) {
	obj1 = maskDict->lookup("CS");
      }
      if (obj1.isName()) {
	Object obj2 = res->lookupColorSpace(obj1.getName());
	if (!obj2.isNull()) {
	  obj1 = std::move(obj2);
	}
      }
      maskColorSpace = GfxColorSpace::parse(nullptr, &obj1, out, state);
      if (!maskColorSpace || maskColorSpace->getMode() != csDeviceGray) {
	delete maskColorSpace;
	goto err1;
      }
      obj1 = maskDict->lookup("Decode");
      if (obj1.isNull()) {
	obj1 = maskDict->lookup("D");
      }
      maskColorMap.reset(new GfxImageColorMap(maskBits, &obj1, maskColorSpace));
      if (!maskColorMap->isOk()) {
	goto err1;
      }
      // handle the Matte entry
      obj1 = maskDict->lookup("Matte");
      if (obj1.isArray()) {
        if (obj1.getArray()->getLength() != colorSpace->getNComps()) {
          error(errSyntaxError, -1, "Matte entry should have {0:d} components but has {1:d}",
            colorSpace->getNComps(), obj1.getArray()->getLength());
        } else if (maskWidth != width || maskHeight != height) {
          error(errSyntaxError, -1, "Softmask with matte entry {0:d} x {1:d} must have same geometry as the image {2:d} x {3:d}",
            maskWidth, maskHeight, width, height);
        } else {
          GfxColor matteColor;
          for (i = 0; i < colorSpace->getNComps(); i++) {
            Object obj2 = obj1.getArray()->get(i);
            if (!obj2.isNum()) {
              error(errSyntaxError, -1, "Matte entry {0:d} should be a number but it's of type {1:d}", i, obj2.getType());

              break;
            }
            matteColor.c[i] = dblToCol(obj2.getNum());
          }
          if (i == colorSpace->getNComps()) {
            maskColorMap->setMatteColor(&matteColor);
          }
        }
      }
      haveSoftMask = true;
    } else if (maskObj.isArray()) {
      // color key mask
      for (i = 0;
	   i < maskObj.arrayGetLength() && i < 2*gfxColorMaxComps;
	   ++i) {
	obj1 = maskObj.arrayGet(i);
	if (obj1.isInt()) {
	  maskColors[i] = obj1.getInt();
	} else if (obj1.isReal()) {
	  error(errSyntaxError, -1, "Mask entry should be an integer but it's a real, trying to use it");
	  maskColors[i] = (int) obj1.getReal();
	} else {
	  error(errSyntaxError, -1, "Mask entry should be an integer but it's of type {0:d}", obj1.getType());
	  goto err1;
	}
      }
      haveColorKeyMask = true;
    } else if (maskObj.isStream()) {
      // explicit mask
      if (inlineImg) {
	goto err1;
      }
      maskStr = maskObj.getStream();
      maskDict = maskObj.streamGetDict();
      obj1 = maskDict->lookup("Width");
      if (obj1.isNull()) {
	obj1 = maskDict->lookup("W");
      }
      if (!obj1.isInt()) {
	goto err1;
      }
      maskWidth = obj1.getInt();
      obj1 = maskDict->lookup("Height");
      if (obj1.isNull()) {
	obj1 = maskDict->lookup("H");
      }
      if (!obj1.isInt()) {
	goto err1;
      }
      maskHeight = obj1.getInt();
      obj1 = maskDict->lookup("Interpolate");
      if (obj1.isNull()) {
	obj1 = maskDict->lookup("I");
      }
      if (obj1.isBool())
        maskInterpolate = obj1.getBool();
      else
        maskInterpolate = false;
      obj1 = maskDict->lookup("ImageMask");
      if (obj1.isNull()) {
	obj1 = maskDict->lookup("IM");
      }
      if (!obj1.isBool() || !obj1.getBool()) {
	goto err1;
      }
      maskInvert = false;
      obj1 = maskDict->lookup("Decode");
      if (obj1.isNull()) {
	obj1 = maskDict->lookup("D");
      }
      if (obj1.isArray()) {
	Object obj2 = obj1.arrayGet(0);
	// Table 4.39 says /Decode must be [1 0] or [0 1]. Adobe
	// accepts [1.0 0.0] as well.
	if (obj2.isNum() && obj2.getNum() >= 0.9) {
	  maskInvert = true;
	}
      } else if (!obj1.isNull()) {
	goto err1;
      }
      haveExplicitMask = true;
    }

    // if drawing is disabled, skip over inline image data
    if (!ocState || !out->needNonText()) {
      str->reset();
      n = height * ((width * colorMap.getNumPixelComps() *
		     colorMap.getBits() + 7) / 8);
      for (i = 0; i < n; ++i) {
	str->getChar();
      }
      str->close();

    // draw it
    } else {
      if (haveSoftMask) {
	out->drawSoftMaskedImage(state, ref, str, width, height, &colorMap, interpolate,
				 maskStr, maskWidth, maskHeight, maskColorMap.get(), maskInterpolate);
      } else if (haveExplicitMask) {
	out->drawMaskedImage(state, ref, str, width, height, &colorMap, interpolate,
			     maskStr, maskWidth, maskHeight, maskInvert, maskInterpolate);
      } else {
	out->drawImage(state, ref, str, width, height, &colorMap, interpolate,
		       haveColorKeyMask ? maskColors : nullptr, inlineImg);
      }
    }
  }

  if ((i = width * height) > 1000) {
    i = 1000;
  }
  updateLevel += i;

  return;

 err1:
  error(errSyntaxError, getPos(), "Bad image parameters");
}

bool Gfx::checkTransparencyGroup(Dict *resDict) {
  // check the effect of compositing objects as a group:
  // look for ExtGState entries with ca != 1 or CA != 1 or BM != normal
  bool transpGroup = false;
  double opac;

  if (resDict == nullptr)
    return false;
  pushResources(resDict);
  Object extGStates = resDict->lookup("ExtGState");
  if (extGStates.isDict()) {
    Dict *dict = extGStates.getDict();
    for (int i = 0; i < dict->getLength() && !transpGroup; i++) {
      GfxBlendMode mode;

      Object obj1 = res->lookupGState(dict->getKey(i));
      if (obj1.isDict()) {
        Object obj2 = obj1.dictLookup("BM");
        if (!obj2.isNull()) {
          if (state->parseBlendMode(&obj2, &mode)) {
            if (mode != gfxBlendNormal)
              transpGroup = true;
          } else {
            error(errSyntaxError, getPos(), "Invalid blend mode in ExtGState");
          }
        }
        obj2 = obj1.dictLookup("ca");
	if (obj2.isNum()) {
          opac = obj2.getNum();
          opac = opac < 0 ? 0 : opac > 1 ? 1 : opac;
          if (opac != 1)
            transpGroup = true;
        }
        obj2 = obj1.dictLookup("CA");
	if (obj2.isNum()) {
          opac = obj2.getNum();
          opac = opac < 0 ? 0 : opac > 1 ? 1 : opac;
          if (opac != 1)
            transpGroup = true;
        }
        // alpha is shape
	obj2 = obj1.dictLookup("AIS");
        if (!transpGroup && obj2.isBool()) {
          transpGroup = obj2.getBool();
        }
        // soft mask
	obj2 = obj1.dictLookup("SMask");
        if (!transpGroup && !obj2.isNull()) {
          if (!obj2.isName("None")) {
            transpGroup = true;
          }
        }
      }
    }
  }
  popResources();
  return transpGroup;
}

void Gfx::doForm(Object *str) {
  Dict *dict;
  bool transpGroup, isolated, knockout;
  GfxColorSpace *blendingColorSpace;
  double m[6], bbox[4];
  Dict *resDict;
  bool ocSaved;
  Object obj1;
  int i;

  // check for excessive recursion
  if (formDepth > 100) {
    return;
  }

  // get stream dict
  dict = str->streamGetDict();

  // check form type
  obj1 = dict->lookup("FormType");
  if (!(obj1.isNull() || (obj1.isInt() && obj1.getInt() == 1))) {
    error(errSyntaxError, getPos(), "Unknown form type");
  }

  // check for optional content key
  ocSaved = ocState;
  const Object &objOC = dict->lookupNF("OC");
  if (catalog->getOptContentConfig() && !catalog->getOptContentConfig()->optContentIsVisible(&objOC)) {
    if (out->needCharCount()) {
      ocState = false;
    } else {
      return;
    }
  }

  // get bounding box
  Object bboxObj = dict->lookup("BBox");
  if (!bboxObj.isArray()) {
    error(errSyntaxError, getPos(), "Bad form bounding box");
    ocState = ocSaved;
    return;
  }
  for (i = 0; i < 4; ++i) {
    obj1 = bboxObj.arrayGet(i);
    if (likely(obj1.isNum())) {
      bbox[i] = obj1.getNum();
    } else {
      error(errSyntaxError, getPos(), "Bad form bounding box value");
      return;
    }
  }

  // get matrix
  Object matrixObj = dict->lookup("Matrix");
  if (matrixObj.isArray()) {
    for (i = 0; i < 6; ++i) {
      obj1 = matrixObj.arrayGet(i);
      if (likely(obj1.isNum())) m[i] = obj1.getNum();
      else m[i] = 0;
    }
  } else {
    m[0] = 1; m[1] = 0;
    m[2] = 0; m[3] = 1;
    m[4] = 0; m[5] = 0;
  }

  // get resources
  Object resObj = dict->lookup("Resources");
  resDict = resObj.isDict() ? resObj.getDict() : nullptr;

  // check for a transparency group
  transpGroup = isolated = knockout = false;
  blendingColorSpace = nullptr;
  obj1 = dict->lookup("Group");
  if (obj1.isDict()) {
    Object obj2 = obj1.dictLookup("S");
    if (obj2.isName("Transparency")) {
      Object obj3 = obj1.dictLookup("CS");
      if (!obj3.isNull()) {
	blendingColorSpace = GfxColorSpace::parse(res, &obj3, out, state);
      }
      obj3 = obj1.dictLookup("I");
      if (obj3.isBool()) {
	isolated = obj3.getBool();
      }
      obj3 = obj1.dictLookup("K");
      if (obj3.isBool()) {
	knockout = obj3.getBool();
      }
      transpGroup = isolated || out->checkTransparencyGroup(state, knockout) || checkTransparencyGroup(resDict);
    }
  }

  // draw it
  ++formDepth;
  drawForm(str, resDict, m, bbox,
	  transpGroup, false, blendingColorSpace, isolated, knockout);
  --formDepth;

  if (blendingColorSpace) {
    delete blendingColorSpace;
  }

  ocState = ocSaved;
}

void Gfx::drawForm(Object *str, Dict *resDict, const double *matrix, const double *bbox,
		  bool transpGroup, bool softMask,
		  GfxColorSpace *blendingColorSpace,
		  bool isolated, bool knockout,
		  bool alpha, Function *transferFunc,
		  GfxColor *backdropColor) {
  Parser *oldParser;
  GfxState *savedState;
  double oldBaseMatrix[6];
  int i;

  // push new resources on stack
  pushResources(resDict);

  // save current graphics state
  savedState = saveStateStack();

  // kill any pre-existing path
  state->clearPath();

  // save current parser
  oldParser = parser;

  // set form transformation matrix
  state->concatCTM(matrix[0], matrix[1], matrix[2],
		   matrix[3], matrix[4], matrix[5]);
  out->updateCTM(state, matrix[0], matrix[1], matrix[2],
		 matrix[3], matrix[4], matrix[5]);

  // set form bounding box
  state->moveTo(bbox[0], bbox[1]);
  state->lineTo(bbox[2], bbox[1]);
  state->lineTo(bbox[2], bbox[3]);
  state->lineTo(bbox[0], bbox[3]);
  state->closePath();
  state->clip();
  out->clip(state);
  state->clearPath();

  if (softMask || transpGroup) {
    if (state->getBlendMode() != gfxBlendNormal) {
      state->setBlendMode(gfxBlendNormal);
      out->updateBlendMode(state);
    }
    if (state->getFillOpacity() != 1) {
      state->setFillOpacity(1);
      out->updateFillOpacity(state);
    }
    if (state->getStrokeOpacity() != 1) {
      state->setStrokeOpacity(1);
      out->updateStrokeOpacity(state);
    }
    out->clearSoftMask(state);
    out->beginTransparencyGroup(state, bbox, blendingColorSpace,
				isolated, knockout, softMask);
  }

  // set new base matrix
  for (i = 0; i < 6; ++i) {
    oldBaseMatrix[i] = baseMatrix[i];
    baseMatrix[i] = state->getCTM()[i];
  }

  GfxState *stateBefore = state;

  // draw the form
  display(str, false);
  
  if (stateBefore != state) {
    if (state->isParentState(stateBefore)) {
      error(errSyntaxError, -1, "There's a form with more q than Q, trying to fix");
      while (stateBefore != state) {
        restoreState();
      }
    } else {
      error(errSyntaxError, -1, "There's a form with more Q than q");
    }
  }

  if (softMask || transpGroup) {
    out->endTransparencyGroup(state);
  }

  // restore base matrix
  for (i = 0; i < 6; ++i) {
    baseMatrix[i] = oldBaseMatrix[i];
  }

  // restore parser
  parser = oldParser;

  // restore graphics state
  restoreStateStack(savedState);

  // pop resource stack
  popResources();

  if (softMask) {
    out->setSoftMask(state, bbox, alpha, transferFunc, backdropColor);
  } else if (transpGroup) {
    out->paintTransparencyGroup(state, bbox);
  }

  return;
}

//------------------------------------------------------------------------
// in-line image operators
//------------------------------------------------------------------------

void Gfx::opBeginImage(Object args[], int numArgs) {
  Stream *str;
  int c1, c2;

  // NB: this function is run even if ocState is false -- doImage() is
  // responsible for skipping over the inline image data

  // build dict/stream
  str = buildImageStream();

  // display the image
  if (str) {
    doImage(nullptr, str, true);
  
    // skip 'EI' tag
    c1 = str->getUndecodedStream()->getChar();
    c2 = str->getUndecodedStream()->getChar();
    while (!(c1 == 'E' && c2 == 'I') && c2 != EOF) {
      c1 = c2;
      c2 = str->getUndecodedStream()->getChar();
    }
    delete str;
  }
}

Stream *Gfx::buildImageStream() {
  Stream *str;

  // build dictionary
  Object dict(new Dict(xref));
  Object obj = parser->getObj();
  while (!obj.isCmd("ID") && !obj.isEOF()) {
    if (!obj.isName()) {
      error(errSyntaxError, getPos(), "Inline image dictionary key must be a name object");
    } else {
      auto val = parser->getObj();
      if (val.isEOF() || val.isError()) {
	break;
      }
      dict.dictAdd(obj.getName(), std::move(val));
    }
    obj = parser->getObj();
  }
  if (obj.isEOF()) {
    error(errSyntaxError, getPos(), "End of file in inline image");
    return nullptr;
  }

  // make stream
  if (parser->getStream()) {
    str = new EmbedStream(parser->getStream(), std::move(dict), false, 0, true);
    str = str->addFilters(str->getDict());
  } else {
    str = nullptr;
  }

  return str;
}

void Gfx::opImageData(Object args[], int numArgs) {
  error(errInternal, getPos(), "Got 'ID' operator");
}

void Gfx::opEndImage(Object args[], int numArgs) {
  error(errInternal, getPos(), "Got 'EI' operator");
}

//------------------------------------------------------------------------
// type 3 font operators
//------------------------------------------------------------------------

void Gfx::opSetCharWidth(Object args[], int numArgs) {
  out->type3D0(state, args[0].getNum(), args[1].getNum());
}

void Gfx::opSetCacheDevice(Object args[], int numArgs) {
  out->type3D1(state, args[0].getNum(), args[1].getNum(),
	       args[2].getNum(), args[3].getNum(),
	       args[4].getNum(), args[5].getNum());
}

//------------------------------------------------------------------------
// compatibility operators
//------------------------------------------------------------------------

void Gfx::opBeginIgnoreUndef(Object args[], int numArgs) {
  ++ignoreUndef;
}

void Gfx::opEndIgnoreUndef(Object args[], int numArgs) {
  if (ignoreUndef > 0)
    --ignoreUndef;
}

//------------------------------------------------------------------------
// marked content operators
//------------------------------------------------------------------------

enum GfxMarkedContentKind {
  gfxMCOptionalContent,
  gfxMCActualText,
  gfxMCOther
};

struct MarkedContentStack {
  GfxMarkedContentKind kind;
  bool ocSuppressed;       // are we ignoring content based on OptionalContent?
  MarkedContentStack *next; // next object on stack
};

void Gfx::popMarkedContent() {
  MarkedContentStack *mc = mcStack;
  mcStack = mc->next;
  delete mc;
}

void Gfx::pushMarkedContent() {
  MarkedContentStack *mc = new MarkedContentStack();
  mc->ocSuppressed = false;
  mc->kind = gfxMCOther;
  mc->next = mcStack;
  mcStack = mc;
}

bool Gfx::contentIsHidden() {
  MarkedContentStack *mc = mcStack;
  bool hidden = mc && mc->ocSuppressed;
  while (!hidden && mc && mc->next) {
    mc = mc->next;
    hidden = mc->ocSuppressed;
  }
  return hidden;
}

void Gfx::opBeginMarkedContent(Object args[], int numArgs) {
  // push a new stack entry
  pushMarkedContent();
  
  OCGs *contentConfig = catalog->getOptContentConfig();
  const char* name0 = args[0].getName();
  if ( strncmp( name0, "OC", 2) == 0 && contentConfig) {
    if ( numArgs >= 2 ) {
      if (args[1].isName()) {
        const char* name1 = args[1].getName();
        MarkedContentStack *mc = mcStack;
        mc->kind = gfxMCOptionalContent;
        Object markedContent = res->lookupMarkedContentNF( name1 );
        if (!markedContent.isNull()) {
          bool visible = contentConfig->optContentIsVisible(&markedContent);
          mc->ocSuppressed = !(visible);
        } else {
          error(errSyntaxError, getPos(), "DID NOT find {0:s}", name1);
        }
      } else {
	error(errSyntaxError, getPos(), "Unexpected MC Type: {0:d}", args[1].getType());
      }
    } else {
      error(errSyntaxError, getPos(), "insufficient arguments for Marked Content");
    }
  } else if (args[0].isName("Span") && numArgs == 2 && args[1].isDict()) {
    Object obj = args[1].dictLookup("ActualText");
    if (obj.isString()) {
      out->beginActualText(state, obj.getString());
      MarkedContentStack *mc = mcStack;
      mc->kind = gfxMCActualText;
    }
  }

  if (printCommands) {
    printf("  marked content: %s ", args[0].getName());
    if (numArgs == 2)
      args[1].print(stdout);
    printf("\n");
    fflush(stdout);
  }
  ocState = !contentIsHidden();
  
  if (numArgs == 2 && args[1].isDict()) {
    out->beginMarkedContent(args[0].getName(), args[1].getDict());
  } else if(numArgs == 1) {
    out->beginMarkedContent(args[0].getName(), nullptr);
  }
}

void Gfx::opEndMarkedContent(Object args[], int numArgs) {
  if (!mcStack) {
    error(errSyntaxWarning, getPos(), "Mismatched EMC operator");
    return;
  }

  MarkedContentStack *mc = mcStack;
  GfxMarkedContentKind mcKind = mc->kind;

  // pop the stack
  popMarkedContent();

  if (mcKind == gfxMCActualText)
    out->endActualText(state);
  ocState = !contentIsHidden();
  
  out->endMarkedContent(state);
}

void Gfx::opMarkPoint(Object args[], int numArgs) {
  if (printCommands) {
    printf("  mark point: %s ", args[0].getName());
    if (numArgs == 2)
      args[1].print(stdout);
    printf("\n");
    fflush(stdout);
  }

  if(numArgs == 2 && args[1].isDict()) {
    out->markPoint(args[0].getName(),args[1].getDict());
  } else {
    out->markPoint(args[0].getName());
  }

}

//------------------------------------------------------------------------
// misc
//------------------------------------------------------------------------

struct GfxStackStateSaver {
  GfxStackStateSaver(Gfx *gfxA) : gfx(gfxA) {
    gfx->saveState();
  }

  ~GfxStackStateSaver() {
    gfx->restoreState();
  }

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

  Gfx * const gfx;
};

void Gfx::drawAnnot(Object *str, AnnotBorder *border, AnnotColor *aColor,
		    double xMin, double yMin, double xMax, double yMax, int rotate) {
  Dict *dict, *resDict;
  double formXMin, formYMin, formXMax, formYMax;
  double x, y, sx, sy, tx, ty;
  double m[6], bbox[4];
  double r, g, b;
  GfxColor color;
  double *dash, *dash2;
  int dashLength;
  int i;

  // this function assumes that we are in the default user space,
  // i.e., baseMatrix = ctm

  // if the bounding box has zero width or height, don't draw anything
  // at all
  if (xMin == xMax || yMin == yMax) {
    return;
  }

  // saves gfx state and automatically restores it on return
  GfxStackStateSaver stackStateSaver(this);

  // Rotation around the topleft corner (for the NoRotate flag)
  if (rotate != 0) {
    const double angle_rad = rotate * M_PI / 180;
    const double c = cos(angle_rad);
    const double s = sin(angle_rad);

    // (xMin, yMax) is the pivot
    const double unrotateMTX[6] = {
        +c, -s,
        +s, +c,
        -c*xMin - s*yMax + xMin, -c*yMax + s*xMin + yMax
    };

    state->concatCTM(unrotateMTX[0], unrotateMTX[1], unrotateMTX[2],
                     unrotateMTX[3], unrotateMTX[4], unrotateMTX[5]);
    out->updateCTM(state, unrotateMTX[0], unrotateMTX[1], unrotateMTX[2],
                          unrotateMTX[3], unrotateMTX[4], unrotateMTX[5]);
  }

  // draw the appearance stream (if there is one)
  if (str->isStream()) {

    // get stream dict
    dict = str->streamGetDict();

    // get the form bounding box
    Object bboxObj = dict->lookup("BBox");
    if (!bboxObj.isArray()) {
      error(errSyntaxError, getPos(), "Bad form bounding box");
      return;
    }
    for (i = 0; i < 4; ++i) {
      Object obj1 = bboxObj.arrayGet(i);
      if (likely(obj1.isNum())) {
        bbox[i] = obj1.getNum();
      } else {
        error(errSyntaxError, getPos(), "Bad form bounding box value");
        return;
      }
    }

    // get the form matrix
    Object matrixObj = dict->lookup("Matrix");
    if (matrixObj.isArray() && matrixObj.arrayGetLength() >= 6) {
      for (i = 0; i < 6; ++i) {
	Object obj1 = matrixObj.arrayGet(i);
	if (likely(obj1.isNum())) {
	  m[i] = obj1.getNum();
	} else {
	  error(errSyntaxError, getPos(), "Bad form matrix");
	  return;
	}
      }
    } else {
      m[0] = 1; m[1] = 0;
      m[2] = 0; m[3] = 1;
      m[4] = 0; m[5] = 0;
    }

    // transform the four corners of the form bbox to default user
    // space, and construct the transformed bbox
    x = bbox[0] * m[0] + bbox[1] * m[2] + m[4];
    y = bbox[0] * m[1] + bbox[1] * m[3] + m[5];
    formXMin = formXMax = x;
    formYMin = formYMax = y;
    x = bbox[0] * m[0] + bbox[3] * m[2] + m[4];
    y = bbox[0] * m[1] + bbox[3] * m[3] + m[5];
    if (x < formXMin) {
      formXMin = x;
    } else if (x > formXMax) {
      formXMax = x;
    }
    if (y < formYMin) {
      formYMin = y;
    } else if (y > formYMax) {
      formYMax = y;
    }
    x = bbox[2] * m[0] + bbox[1] * m[2] + m[4];
    y = bbox[2] * m[1] + bbox[1] * m[3] + m[5];
    if (x < formXMin) {
      formXMin = x;
    } else if (x > formXMax) {
      formXMax = x;
    }
    if (y < formYMin) {
      formYMin = y;
    } else if (y > formYMax) {
      formYMax = y;
    }
    x = bbox[2] * m[0] + bbox[3] * m[2] + m[4];
    y = bbox[2] * m[1] + bbox[3] * m[3] + m[5];
    if (x < formXMin) {
      formXMin = x;
    } else if (x > formXMax) {
      formXMax = x;
    }
    if (y < formYMin) {
      formYMin = y;
    } else if (y > formYMax) {
      formYMax = y;
    }

    // construct a mapping matrix, [sx 0  0], which maps the transformed
    //                             [0  sy 0]
    //                             [tx ty 1]
    // bbox to the annotation rectangle
    if (formXMin == formXMax) {
      // this shouldn't happen
      sx = 1;
    } else {
      sx = (xMax - xMin) / (formXMax - formXMin);
    }
    if (formYMin == formYMax) {
      // this shouldn't happen
      sy = 1;
    } else {
      sy = (yMax - yMin) / (formYMax - formYMin);
    }
    tx = -formXMin * sx + xMin;
    ty = -formYMin * sy + yMin;

    // the final transform matrix is (form matrix) * (mapping matrix)
    m[0] *= sx;
    m[1] *= sy;
    m[2] *= sx;
    m[3] *= sy;
    m[4] = m[4] * sx + tx;
    m[5] = m[5] * sy + ty;

    // get the resources
    Object resObj = dict->lookup("Resources");
    resDict = resObj.isDict() ? resObj.getDict() : nullptr;

    // draw it
    drawForm(str, resDict, m, bbox);
  }

  // draw the border
  if (border && border->getWidth() > 0) {
    if (state->getStrokeColorSpace()->getMode() != csDeviceRGB) {
      state->setStrokePattern(nullptr);
      state->setStrokeColorSpace(new GfxDeviceRGBColorSpace());
      out->updateStrokeColorSpace(state);
    }
    if (aColor && (aColor->getSpace() == AnnotColor::colorRGB)) {
      const double *values = aColor->getValues();
      r = values[0];
      g = values[1];
      b = values[2];
    } else {
      r = g = b = 0;
    };
    color.c[0] = dblToCol(r);
    color.c[1] = dblToCol(g);
    color.c[2] = dblToCol(b);
    state->setStrokeColor(&color);
    out->updateStrokeColor(state);
    state->setLineWidth(border->getWidth());
    out->updateLineWidth(state);
    dashLength = border->getDashLength();
    dash = border->getDash();
    if (border->getStyle() == AnnotBorder::borderDashed && dashLength > 0) {
      dash2 = (double *)gmallocn(dashLength, sizeof(double));
      memcpy(dash2, dash, dashLength * sizeof(double));
      state->setLineDash(dash2, dashLength, 0);
      out->updateLineDash(state);
    }
    //~ this doesn't currently handle the beveled and engraved styles
    state->clearPath();
    state->moveTo(xMin, yMin);
    state->lineTo(xMax, yMin);
    if (border->getStyle() != AnnotBorder::borderUnderlined) {
      state->lineTo(xMax, yMax);
      state->lineTo(xMin, yMax);
      state->closePath();
    }
    out->stroke(state);
  }
}

int Gfx::bottomGuard() {
    return stateGuards[stateGuards.size()-1];
}

void Gfx::pushStateGuard() {
    stateGuards.push_back(stackHeight);
}

void Gfx::popStateGuard() {
    while (stackHeight > bottomGuard() && state->hasSaves())
	restoreState();
    stateGuards.pop_back();
}

void Gfx::saveState() {
  out->saveState(state);
  state = state->save();
  stackHeight++;
}

void Gfx::restoreState() {
  if (stackHeight <= bottomGuard() || !state->hasSaves()) {
    error(errSyntaxError, -1, "Restoring state when no valid states to pop");
    commandAborted = true;
    return;
  }
  state = state->restore();
  out->restoreState(state);
  stackHeight--;
}

// Create a new state stack, and initialize it with a copy of the
// current state.
GfxState *Gfx::saveStateStack() {
  GfxState *oldState;

  out->saveState(state);
  oldState = state;
  state = state->copy(true);
  return oldState;
}

// Switch back to the previous state stack.
void Gfx::restoreStateStack(GfxState *oldState) {
  while (state->hasSaves()) {
    restoreState();
  }
  delete state;
  state = oldState;
  out->restoreState(state);
}

void Gfx::pushResources(Dict *resDict) {
  res = new GfxResources(xref, resDict, res);
}

void Gfx::popResources() {
  GfxResources *resPtr;

  resPtr = res->getNext();
  delete res;
  res = resPtr;
}
