//========================================================================
//
// Annot.cc
//
// Copyright 2000-2003 Glyph & Cog, LLC
//
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2006 Scott Turner <scotty1024@mac.com>
// Copyright (C) 2007, 2008 Julien Rebetez <julienr@svn.gnome.org>
// Copyright (C) 2007-2013, 2015-2017 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2007-2013 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2007, 2008 Iñigo Martínez <inigomartinez@gmail.com>
// Copyright (C) 2007 Jeff Muizelaar <jeff@infidigm.net>
// Copyright (C) 2008, 2011 Pino Toscano <pino@kde.org>
// Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu>
// Copyright (C) 2008 Hugo Mercier <hmercier31@gmail.com>
// Copyright (C) 2009 Ilya Gorenbein <igorenbein@finjan.com>
// Copyright (C) 2011, 2013 José Aliste <jaliste@src.gnome.org>
// Copyright (C) 2012, 2013 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2012, 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2012, 2015 Tobias Koenig <tokoe@kdab.com>
// Copyright (C) 2013 Peter Breitenlohner <peb@mppmu.mpg.de>
// Copyright (C) 2013 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2014, 2015 Marek Kasik <mkasik@redhat.com>
// Copyright (C) 2014 Jiri Slaby <jirislaby@gmail.com>
// Copyright (C) 2014 Anuj Khare <khareanuj18@gmail.com>
// Copyright (C) 2015 Petr Gajdos <pgajdos@suse.cz>
// Copyright (C) 2015 Philipp Reinkemeier <philipp.reinkemeier@offis.de>
// Copyright (C) 2015 Tamas Szekeres <szekerest@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>

#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif

#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include "goo/gmem.h"
#include "goo/gstrtod.h"
#include "GooList.h"
#include "Error.h"
#include "Object.h"
#include "Catalog.h"
#include "Gfx.h"
#include "Lexer.h"
#include "PDFDoc.h"
#include "Page.h"
#include "Annot.h"
#include "GfxFont.h"
#include "CharCodeToUnicode.h"
#include "PDFDocEncoding.h"
#include "Form.h"
#include "Error.h"
#include "XRef.h"
#include "Movie.h"
#include "OptionalContent.h"
#include "Sound.h"
#include "FileSpec.h"
#include "DateInfo.h"
#include "Link.h"
#include <string.h>
#include <algorithm>

#if MULTITHREADED
#  define annotLocker()   MutexLocker locker(&mutex)
#  define annotCondLocker(X)  MutexLocker locker(&mutex, (X))
#else
#  define annotLocker()
#  define annotCondLocker(X)
#endif

#define fieldFlagReadOnly           0x00000001
#define fieldFlagRequired           0x00000002
#define fieldFlagNoExport           0x00000004
#define fieldFlagMultiline          0x00001000
#define fieldFlagPassword           0x00002000
#define fieldFlagNoToggleToOff      0x00004000
#define fieldFlagRadio              0x00008000
#define fieldFlagPushbutton         0x00010000
#define fieldFlagCombo              0x00020000
#define fieldFlagEdit               0x00040000
#define fieldFlagSort               0x00080000
#define fieldFlagFileSelect         0x00100000
#define fieldFlagMultiSelect        0x00200000
#define fieldFlagDoNotSpellCheck    0x00400000
#define fieldFlagDoNotScroll        0x00800000
#define fieldFlagComb               0x01000000
#define fieldFlagRichText           0x02000000
#define fieldFlagRadiosInUnison     0x02000000
#define fieldFlagCommitOnSelChange  0x04000000

#define fieldQuadLeft   0
#define fieldQuadCenter 1
#define fieldQuadRight  2

// distance of Bezier control point from center for circle approximation
// = (4 * (sqrt(2) - 1) / 3) * r
#define bezierCircle 0.55228475

AnnotLineEndingStyle parseAnnotLineEndingStyle(GooString *string) {
  if (string != NULL) {
    if (!string->cmp("Square")) {
      return annotLineEndingSquare;
    } else if (!string->cmp("Circle")) {
      return annotLineEndingCircle;
    } else if (!string->cmp("Diamond")) {
      return annotLineEndingDiamond;
    } else if (!string->cmp("OpenArrow")) {
      return annotLineEndingOpenArrow;
    } else if (!string->cmp("ClosedArrow")) {
      return annotLineEndingClosedArrow;
    } else if (!string->cmp("Butt")) {
      return annotLineEndingButt;
    } else if (!string->cmp("ROpenArrow")) {
      return annotLineEndingROpenArrow;
    } else if (!string->cmp("RClosedArrow")) {
      return annotLineEndingRClosedArrow;
    } else if (!string->cmp("Slash")) {
      return annotLineEndingSlash;
    } else {
      return annotLineEndingNone;
    }
  } else {
    return annotLineEndingNone;
  }  
}

const char* convertAnnotLineEndingStyle(AnnotLineEndingStyle style) {
  switch (style) {
    case annotLineEndingSquare:
      return "Square";
    case annotLineEndingCircle:
      return "Circle";
    case annotLineEndingDiamond:
      return "Diamond";
    case annotLineEndingOpenArrow:
      return "OpenArrow";
    case annotLineEndingClosedArrow:
      return "ClosedArrow";
    case annotLineEndingButt:
      return "Butt";
    case annotLineEndingROpenArrow:
      return "ROpenArrow";
    case annotLineEndingRClosedArrow:
      return "RClosedArrow";
    case annotLineEndingSlash:
      return "Slash";
    default:
      return "None";
  }
}

static AnnotExternalDataType parseAnnotExternalData(Dict* dict) {
  Object obj1;
  AnnotExternalDataType type;

  if (dict->lookup("Subtype", &obj1)->isName()) {
    const char *typeName = obj1.getName();

    if (!strcmp(typeName, "Markup3D")) {
      type = annotExternalDataMarkup3D;
    } else {
      type = annotExternalDataMarkupUnknown;
    }
  } else {
    type = annotExternalDataMarkupUnknown;
  }
  obj1.free();

  return type;
}

PDFRectangle *parseDiffRectangle(Array *array, PDFRectangle *rect) {
  PDFRectangle *newRect = NULL;
  if (array->getLength() == 4) {
    // deltas
    Object obj1;
    double dx1 = (array->get(0, &obj1)->isNum() ? obj1.getNum() : 0);
    obj1.free();
    double dy1 = (array->get(1, &obj1)->isNum() ? obj1.getNum() : 0);
    obj1.free();
    double dx2 = (array->get(2, &obj1)->isNum() ? obj1.getNum() : 0);
    obj1.free();
    double dy2 = (array->get(3, &obj1)->isNum() ? obj1.getNum() : 0);
    obj1.free();

    // checking that the numbers are valid (i.e. >= 0),
    // and that applying the differences still give us a valid rect
    if (dx1 >= 0 && dy1 >= 0 && dx2 >= 0 && dy2
        && (rect->x2 - rect->x1 - dx1 - dx2) >= 0
        && (rect->y2 - rect->y1 - dy1 - dy2) >= 0) {
      newRect = new PDFRectangle();
      newRect->x1 = rect->x1 + dx1;
      newRect->y1 = rect->y1 + dy1;
      newRect->x2 = rect->x2 - dx2;
      newRect->y2 = rect->y2 - dy2;
    }
  }
  return newRect;
}

static LinkAction* getAdditionalAction(Annot::AdditionalActionsType type, Object *additionalActions, PDFDoc *doc) {
  Object additionalActionsObject;
  LinkAction *linkAction = NULL;

  if (additionalActions->fetch(doc->getXRef(), &additionalActionsObject)->isDict()) {
    const char *key = (type == Annot::actionCursorEntering ? "E" :
                       type == Annot::actionCursorLeaving ?  "X" :
                       type == Annot::actionMousePressed ?   "D" :
                       type == Annot::actionMouseReleased ?  "U" :
                       type == Annot::actionFocusIn ?       "Fo" :
                       type == Annot::actionFocusOut ?      "BI" :
                       type == Annot::actionPageOpening ?   "PO" :
                       type == Annot::actionPageClosing ?   "PC" :
                       type == Annot::actionPageVisible ?   "PV" :
                       type == Annot::actionPageInvisible ? "PI" : NULL);

    Object actionObject;

    if (additionalActionsObject.dictLookup(key, &actionObject)->isDict())
      linkAction = LinkAction::parseAction(&actionObject, doc->getCatalog()->getBaseURI());
    actionObject.free();
  }

  additionalActionsObject.free();

  return linkAction;
}

static LinkAction* getFormAdditionalAction(Annot::FormAdditionalActionsType type, Object *additionalActions, PDFDoc *doc) {
  Object additionalActionsObject;
  LinkAction *linkAction = NULL;

  if (additionalActions->fetch(doc->getXRef(), &additionalActionsObject)->isDict()) {
    const char *key = (type == Annot::actionFieldModified ?  "K" :
                       type == Annot::actionFormatField ?    "F" :
                       type == Annot::actionValidateField ?  "V" :
                       type == Annot::actionCalculateField ? "C" : NULL);

    Object actionObject;

    if (additionalActionsObject.dictLookup(key, &actionObject)->isDict())
      linkAction = LinkAction::parseAction(&actionObject, doc->getCatalog()->getBaseURI());
    actionObject.free();
  }

  additionalActionsObject.free();

  return linkAction;
}

//------------------------------------------------------------------------
// AnnotBorderEffect
//------------------------------------------------------------------------

AnnotBorderEffect::AnnotBorderEffect(Dict *dict) {
  Object obj1;

  if (dict->lookup("S", &obj1)->isName()) {
    const char *effectName = obj1.getName();

    if (!strcmp(effectName, "C"))
      effectType = borderEffectCloudy;
    else
      effectType = borderEffectNoEffect;
  } else {
    effectType = borderEffectNoEffect;
  }
  obj1.free();

  if ((dict->lookup("I", &obj1)->isNum()) && effectType == borderEffectCloudy) {
    intensity = obj1.getNum();
  } else {
    intensity = 0;
  }
  obj1.free();
}

//------------------------------------------------------------------------
// AnnotPath
//------------------------------------------------------------------------

AnnotPath::AnnotPath() {
  coords = NULL;
  coordsLength = 0;
}

AnnotPath::AnnotPath(Array *array) {
  coords = NULL;
  coordsLength = 0;
  parsePathArray(array);
}

AnnotPath::AnnotPath(AnnotCoord **coords, int coordsLength) {
  this->coords = coords;
  this->coordsLength = coordsLength;
}

AnnotPath::~AnnotPath() {
  if (coords) {
    for (int i = 0; i < coordsLength; ++i)
      delete coords[i];
    gfree(coords);
  }
}

double AnnotPath::getX(int coord) const {
  if (coord >= 0 && coord < coordsLength)
    return coords[coord]->getX();
  return 0;
}

double AnnotPath::getY(int coord) const {
  if (coord >= 0 && coord < coordsLength)
    return coords[coord]->getY();
  return 0;
}

AnnotCoord *AnnotPath::getCoord(int coord) const {
  if (coord >= 0 && coord < coordsLength)
    return coords[coord];
  return NULL;
}

void AnnotPath::parsePathArray(Array *array) {
  int tempLength;
  AnnotCoord **tempCoords;
  GBool correct = gTrue;

  if (array->getLength() % 2) {
    error(errSyntaxError, -1, "Bad Annot Path");
    return;
  }

  tempLength = array->getLength() / 2;
  tempCoords = (AnnotCoord **) gmallocn (tempLength, sizeof(AnnotCoord *));
  memset(tempCoords, 0, tempLength * sizeof(AnnotCoord *));
  for (int i = 0; i < tempLength && correct; i++) {
    Object obj1;
    double x = 0, y = 0;

    if (array->get(i * 2, &obj1)->isNum()) {
      x = obj1.getNum();
    } else {
      correct = gFalse;
    }
    obj1.free();

    if (array->get((i * 2) + 1, &obj1)->isNum()) {
      y = obj1.getNum();
    } else {
      correct = gFalse;
    }
    obj1.free();

    if (!correct) {
      for (int j = i - 1; j >= 0; j--)
        delete tempCoords[j];
      gfree (tempCoords);
      return;
    }

    tempCoords[i] = new AnnotCoord(x, y);
  }

  coords = tempCoords;
  coordsLength = tempLength;
}

//------------------------------------------------------------------------
// AnnotCalloutLine
//------------------------------------------------------------------------

AnnotCalloutLine::AnnotCalloutLine(double x1, double y1, double x2, double y2)
    :  coord1(x1, y1), coord2(x2, y2) {
}

//------------------------------------------------------------------------
// AnnotCalloutMultiLine
//------------------------------------------------------------------------

AnnotCalloutMultiLine::AnnotCalloutMultiLine(double x1, double y1, double x2,
                                             double y2, double x3, double y3)
    : AnnotCalloutLine(x1, y1, x2, y2), coord3(x3, y3) {
}

//------------------------------------------------------------------------
// AnnotQuadrilateral
//------------------------------------------------------------------------

AnnotQuadrilaterals::AnnotQuadrilaterals(Array *array, PDFRectangle *rect) {
  int arrayLength = array->getLength();
  GBool correct = gTrue;
  int quadsLength = 0;
  AnnotQuadrilateral **quads;
  double quadArray[8];

  // default values
  quadrilaterals = NULL;
  quadrilateralsLength = 0;

  if ((arrayLength % 8) == 0) {
    int i;

    quadsLength = arrayLength / 8;
    quads = (AnnotQuadrilateral **) gmallocn
        ((quadsLength), sizeof(AnnotQuadrilateral *));
    memset(quads, 0, quadsLength * sizeof(AnnotQuadrilateral *));

    for (i = 0; i < quadsLength; i++) {
      for (int j = 0; j < 8; j++) {
        Object obj;
        if (array->get(i * 8 + j, &obj)->isNum()) {
          quadArray[j] = obj.getNum();
        } else {
            correct = gFalse;
	    obj.free();
	    error (errSyntaxError, -1, "Invalid QuadPoint in annot");
	    break;
        }
        obj.free();
      }

      if (!correct)
        break;

      quads[i] = new AnnotQuadrilateral(quadArray[0], quadArray[1],
					quadArray[2], quadArray[3],
					quadArray[4], quadArray[5],
					quadArray[6], quadArray[7]);
    }

    if (correct) {
      quadrilateralsLength = quadsLength;
      quadrilaterals = quads;
    } else {
      for (int j = 0; j < i; j++)
        delete quads[j];
      gfree (quads);
    }
  }
}

AnnotQuadrilaterals::AnnotQuadrilaterals(AnnotQuadrilaterals::AnnotQuadrilateral **quads, int quadsLength) {
  quadrilaterals = quads;
  quadrilateralsLength = quadsLength;
}

AnnotQuadrilaterals::~AnnotQuadrilaterals() {
  if (quadrilaterals) {
    for(int i = 0; i < quadrilateralsLength; i++)
      delete quadrilaterals[i];

    gfree (quadrilaterals);
  }
}

double AnnotQuadrilaterals::getX1(int quadrilateral) {
  if (quadrilateral >= 0  && quadrilateral < quadrilateralsLength)
    return quadrilaterals[quadrilateral]->coord1.getX();
  return 0;
}

double AnnotQuadrilaterals::getY1(int quadrilateral) {
  if (quadrilateral >= 0  && quadrilateral < quadrilateralsLength)
    return quadrilaterals[quadrilateral]->coord1.getY();
  return 0;
}

double AnnotQuadrilaterals::getX2(int quadrilateral) {
  if (quadrilateral >= 0  && quadrilateral < quadrilateralsLength)
    return quadrilaterals[quadrilateral]->coord2.getX();
  return 0;
}

double AnnotQuadrilaterals::getY2(int quadrilateral) {
  if (quadrilateral >= 0  && quadrilateral < quadrilateralsLength)
    return quadrilaterals[quadrilateral]->coord2.getY();
  return 0;
}

double AnnotQuadrilaterals::getX3(int quadrilateral) {
  if (quadrilateral >= 0  && quadrilateral < quadrilateralsLength)
    return quadrilaterals[quadrilateral]->coord3.getX();
  return 0;
}

double AnnotQuadrilaterals::getY3(int quadrilateral) {
  if (quadrilateral >= 0  && quadrilateral < quadrilateralsLength)
    return quadrilaterals[quadrilateral]->coord3.getY();
  return 0;
}

double AnnotQuadrilaterals::getX4(int quadrilateral) {
  if (quadrilateral >= 0  && quadrilateral < quadrilateralsLength)
    return quadrilaterals[quadrilateral]->coord4.getX();
  return 0;
}

double AnnotQuadrilaterals::getY4(int quadrilateral) {
  if (quadrilateral >= 0  && quadrilateral < quadrilateralsLength)
    return quadrilaterals[quadrilateral]->coord4.getY();
  return 0;
}

AnnotQuadrilaterals::AnnotQuadrilateral::AnnotQuadrilateral(double x1, double y1,
    double x2, double y2, double x3, double y3, double x4, double y4)
    : coord1(x1, y1), coord2(x2, y2), coord3(x3, y3), coord4(x4, y4) {
}

//------------------------------------------------------------------------
// AnnotBorder
//------------------------------------------------------------------------
AnnotBorder::AnnotBorder() {
  width = 1;
  dashLength = 0;
  dash = NULL;
  style = borderSolid;
}

GBool AnnotBorder::parseDashArray(Object *dashObj) {
  GBool correct = gTrue;
  int tempLength = dashObj->arrayGetLength();
  double *tempDash = (double *) gmallocn (tempLength, sizeof (double));

  // TODO: check not all zero (Line Dash Pattern Page 217 PDF 8.1)
  for (int i = 0; i < tempLength && i < DASH_LIMIT && correct; i++) {
    Object obj1;

    if (dashObj->arrayGet(i, &obj1)->isNum()) {
      tempDash[i] = obj1.getNum();

      correct = tempDash[i] >= 0;
      obj1.free();
    }
  }

  if (correct) {
    dashLength = tempLength;
    dash = tempDash;
    style = borderDashed;
  } else {
    gfree (tempDash);
  }

  return correct;
}

AnnotBorder::~AnnotBorder() {
  if (dash)
    gfree (dash); 
}
  
//------------------------------------------------------------------------
// AnnotBorderArray
//------------------------------------------------------------------------

AnnotBorderArray::AnnotBorderArray() {
  horizontalCorner = 0;
  verticalCorner = 0;
}

AnnotBorderArray::AnnotBorderArray(Array *array) {
  Object obj1;
  int arrayLength = array->getLength();

  GBool correct = gTrue;
  if (arrayLength == 3 || arrayLength == 4) {
    // implementation note 81 in Appendix H.

    if (array->get(0, &obj1)->isNum())
      horizontalCorner = obj1.getNum();
    else
      correct = gFalse;
    obj1.free();

    if (array->get(1, &obj1)->isNum())
      verticalCorner = obj1.getNum();
    else
      correct = gFalse;
    obj1.free();

    if (array->get(2, &obj1)->isNum())
      width = obj1.getNum();
    else
      correct = gFalse;
    obj1.free();

    if (arrayLength == 4) {
      if (array->get(3, &obj1)->isArray())
        correct = parseDashArray(&obj1);
      else
        correct = gFalse;
      obj1.free();
    }
  } else {
    correct = gFalse;
  }
  
  if (!correct) {
    width = 0;
  }
}

void AnnotBorderArray::writeToObject(XRef *xref, Object *obj1) const {
  Object obj2;

  obj1->initArray(xref);
  obj1->arrayAdd(obj2.initReal(horizontalCorner));
  obj1->arrayAdd(obj2.initReal(verticalCorner));
  obj1->arrayAdd(obj2.initReal(width));

  if (dashLength > 0) {
    Object obj3;

    obj1->arrayAdd(obj3.initArray(xref));
    for (int i = 0; i < dashLength; i++)
      obj3.arrayAdd(obj2.initReal(dash[i]));
  }
}

//------------------------------------------------------------------------
// AnnotBorderBS
//------------------------------------------------------------------------

AnnotBorderBS::AnnotBorderBS() {
}

AnnotBorderBS::AnnotBorderBS(Dict *dict) {
  Object obj1, obj2;

  // acroread 8 seems to need both W and S entries for
  // any border to be drawn, even though the spec
  // doesn't claim anything of that sort. We follow
  // that behaviour by veryifying both entries exist
  // otherwise we set the borderWidth to 0
  // --jrmuizel
  dict->lookup("W", &obj1);
  dict->lookup("S", &obj2);
  if (obj1.isNum() && obj2.isName()) {
    const char *styleName = obj2.getName();

    width = obj1.getNum();

    if (!strcmp(styleName, "S")) {
      style = borderSolid;
    } else if (!strcmp(styleName, "D")) {
      style = borderDashed;
    } else if (!strcmp(styleName, "B")) {
      style = borderBeveled;
    } else if (!strcmp(styleName, "I")) {
      style = borderInset;
    } else if (!strcmp(styleName, "U")) {
      style = borderUnderlined;
    } else {
      style = borderSolid;
    }
  } else {
    width = 0;
  }
  obj2.free();
  obj1.free();

  if (style == borderDashed) {
    if (dict->lookup("D", &obj1)->isArray())
      parseDashArray(&obj1);
    obj1.free();

    if (!dash) {
      dashLength = 1;
      dash = (double *) gmallocn (dashLength, sizeof (double));
      dash[0] = 3;
    }
  }
}

const char *AnnotBorderBS::getStyleName() const {
  switch (style) {
  case borderSolid:
    return "S";
  case borderDashed:
    return "D";
  case borderBeveled:
    return "B";
  case borderInset:
    return "I";
  case borderUnderlined:
    return "U";
  }

  return "S";
}

void AnnotBorderBS::writeToObject(XRef *xref, Object *obj1) const {
  Object obj2;

  obj1->initDict(xref);
  obj1->dictSet("W", obj2.initReal(width));
  obj1->dictSet("S", obj2.initName(getStyleName()));
  if (style == borderDashed && dashLength > 0) {
    Object obj3;

    obj1->dictSet("D", obj3.initArray(xref));
    for (int i = 0; i < dashLength; i++)
      obj3.arrayAdd(obj2.initReal(dash[i]));
  }
}

//------------------------------------------------------------------------
// AnnotColor
//------------------------------------------------------------------------

AnnotColor::AnnotColor() {
  length = 0;
}

AnnotColor::AnnotColor(double gray) {
  length = 1;

  values[0] = gray;
}

AnnotColor::AnnotColor(double r, double g, double b) {
  length = 3;

  values[0] = r;
  values[1] = g;
  values[2] = b;
}

AnnotColor::AnnotColor(double c, double m, double y, double k) {
  length = 4;

  values[0] = c;
  values[1] = m;
  values[2] = y;
  values[3] = k;
}

// If <adjust> is +1, color is brightened;
// if <adjust> is -1, color is darkened;
// otherwise color is not modified.
AnnotColor::AnnotColor(Array *array, int adjust) {
  int i;

  length = array->getLength();
  if (length > 4)
    length = 4;

  for (i = 0; i < length; i++) {
    Object obj1;

    if (array->get(i, &obj1)->isNum()) {
      values[i] = obj1.getNum();

      if (values[i] < 0 || values[i] > 1)
        values[i] = 0;
    } else {
      values[i] = 0;
    }
    obj1.free();
  }

  if (adjust != 0)
    adjustColor(adjust);
}

void AnnotColor::adjustColor(int adjust) {
  int i;

  if (length == 4) {
    adjust = -adjust;
  }
  if (adjust > 0) {
    for (i = 0; i < length; ++i) {
      values[i] = 0.5 * values[i] + 0.5;
    }
  } else if (adjust < 0) {
    for (i = 0; i < length; ++i) {
      values[i] = 0.5 * values[i];
    }
  }
}

void AnnotColor::writeToObject(XRef *xref, Object *obj1) const {
  Object obj2;
  int i;

  if (length == 0) {
    obj1->initNull(); // Transparent (no color)
  } else {
    obj1->initArray(xref);
    for (i = 0; i < length; ++i)
      obj1->arrayAdd( obj2.initReal( values[i] ) );
  }
}

//------------------------------------------------------------------------
// AnnotIconFit
//------------------------------------------------------------------------

AnnotIconFit::AnnotIconFit(Dict* dict) {
  Object obj1;

  if (dict->lookup("SW", &obj1)->isName()) {
    const char *scaleName = obj1.getName();

    if(!strcmp(scaleName, "B")) {
      scaleWhen = scaleBigger;
    } else if(!strcmp(scaleName, "S")) {
      scaleWhen = scaleSmaller;
    } else if(!strcmp(scaleName, "N")) {
      scaleWhen = scaleNever;
    } else {
      scaleWhen = scaleAlways;
    }
  } else {
    scaleWhen = scaleAlways;
  }
  obj1.free();

  if (dict->lookup("S", &obj1)->isName()) {
    const char *scaleName = obj1.getName();

    if(!strcmp(scaleName, "A")) {
      scale = scaleAnamorphic;
    } else {
      scale = scaleProportional;
    }
  } else {
    scale = scaleProportional;
  }
  obj1.free();

  if (dict->lookup("A", &obj1)->isArray() && obj1.arrayGetLength() == 2) {
    Object obj2;
    (obj1.arrayGet(0, &obj2)->isNum() ? left = obj2.getNum() : left = 0);
    obj2.free();
    (obj1.arrayGet(1, &obj2)->isNum() ? bottom = obj2.getNum() : bottom = 0);
    obj2.free();

    if (left < 0 || left > 1)
      left = 0.5;

    if (bottom < 0 || bottom > 1)
      bottom = 0.5;

  } else {
    left = bottom = 0.5;
  }
  obj1.free();

  if (dict->lookup("FB", &obj1)->isBool()) {
    fullyBounds = obj1.getBool();
  } else {
    fullyBounds = gFalse;
  }
  obj1.free();
}

//------------------------------------------------------------------------
// AnnotAppearance
//------------------------------------------------------------------------

AnnotAppearance::AnnotAppearance(PDFDoc *docA, Object *dict) {
  assert(dict->isDict());
  doc = docA;
  xref = docA->getXRef();
  dict->copy(&appearDict);
}

AnnotAppearance::~AnnotAppearance() {
  appearDict.free();
}

void AnnotAppearance::getAppearanceStream(AnnotAppearanceType type, const char *state, Object *dest) {
  Object apData, stream;
  apData.initNull();

  // Obtain dictionary or stream associated to appearance type
  switch (type) {
  case appearRollover:
    if (appearDict.dictLookupNF("R", &apData)->isNull())
      appearDict.dictLookupNF("N", &apData);
    break;
  case appearDown:
    if (appearDict.dictLookupNF("D", &apData)->isNull())
      appearDict.dictLookupNF("N", &apData);
    break;
  case appearNormal:
    appearDict.dictLookupNF("N", &apData);
    break;
  }

  dest->initNull();
  if (apData.isDict() && state)
    apData.dictLookupNF(state, dest);
  else if (apData.isRef())
    apData.copy(dest);
  apData.free();
}

GooString * AnnotAppearance::getStateKey(int i) {
  Object obj1;
  GooString * res = NULL;
  if (appearDict.dictLookupNF("N", &obj1)->isDict())
    res = new GooString(obj1.dictGetKey(i));
  obj1.free();
  return res;
}

int AnnotAppearance::getNumStates() {
  Object obj1;
  int res = 0;
  if (appearDict.dictLookupNF("N", &obj1)->isDict())
    res = obj1.dictGetLength();
  obj1.free();
  return res;
}

// Test if stateObj (a Ref or a Dict) points to the specified stream
GBool AnnotAppearance::referencesStream(Object *stateObj, Ref refToStream) {
  if (stateObj->isRef()) {
    Ref r = stateObj->getRef();
    if (r.num == refToStream.num && r.gen == refToStream.gen) {
      return gTrue;
    }
  } else if (stateObj->isDict()) { // Test each value
    const int size = stateObj->dictGetLength();
    for (int i = 0; i < size; ++i) {
      Object obj1;
      stateObj->dictGetValNF(i, &obj1);
      if (obj1.isRef()) {
        Ref r = obj1.getRef();
        if (r.num == refToStream.num && r.gen == refToStream.gen) {
          return gTrue;
        }
      }
      obj1.free();
    }
  }
  return gFalse; // Not found
}

// Test if this AnnotAppearance references the specified stream
GBool AnnotAppearance::referencesStream(Ref refToStream) {
  Object obj1;
  GBool found;

  // Scan each state's ref/subdictionary
  appearDict.dictLookupNF("N", &obj1);
  found = referencesStream(&obj1, refToStream);
  obj1.free();
  if (found)
    return gTrue;

  appearDict.dictLookupNF("R", &obj1);
  found = referencesStream(&obj1, refToStream);
  obj1.free();
  if (found)
    return gTrue;

  appearDict.dictLookupNF("D", &obj1);
  found = referencesStream(&obj1, refToStream);
  obj1.free();
  return found;
}

// If this is the only annotation in the document that references the
// specified appearance stream, remove the appearance stream
void AnnotAppearance::removeStream(Ref refToStream) {
  const int lastpage = doc->getNumPages();
  for (int pg = 1; pg <= lastpage; ++pg) { // Scan all annotations in the document
    Page *page = doc->getPage(pg);
    if (!page) {
      error(errSyntaxError, -1, "Failed check for shared annotation stream at page {0:d}", pg);
      continue;
    }
    Annots *annots = page->getAnnots();
    for (int i = 0; i < annots->getNumAnnots(); ++i) {
      AnnotAppearance *annotAp = annots->getAnnot(i)->getAppearStreams();
      if (annotAp && annotAp != this && annotAp->referencesStream(refToStream)) {
        return; // Another annotation points to the stream -> Don't delete it
      }
    }
  }

  // TODO: stream resources (e.g. font), AP name tree
  xref->removeIndirectObject(refToStream);
}

// Removes stream if obj is a Ref, or removes pointed streams if obj is a Dict
void AnnotAppearance::removeStateStreams(Object *obj1) {
  if (obj1->isRef()) {
    removeStream(obj1->getRef());
  } else if (obj1->isDict()) {
    const int size = obj1->dictGetLength();
    for (int i = 0; i < size; ++i) {
      Object obj2;
      obj1->dictGetValNF(i, &obj2);
      if (obj2.isRef()) {
        removeStream(obj2.getRef());
      }
      obj2.free();
    }
  }
}

void AnnotAppearance::removeAllStreams() {
  Object obj1;
  appearDict.dictLookupNF("N", &obj1);
  removeStateStreams(&obj1);
  obj1.free();
  appearDict.dictLookupNF("R", &obj1);
  removeStateStreams(&obj1);
  obj1.free();
  appearDict.dictLookupNF("D", &obj1);
  removeStateStreams(&obj1);
  obj1.free();
}

//------------------------------------------------------------------------
// AnnotAppearanceCharacs
//------------------------------------------------------------------------

AnnotAppearanceCharacs::AnnotAppearanceCharacs(Dict *dict) {
  Object obj1;

  if (dict->lookup("R", &obj1)->isInt()) {
    rotation = obj1.getInt();
  } else {
    rotation = 0;
  }
  obj1.free();

  if (dict->lookup("BC", &obj1)->isArray()) {
    Array *colorComponents = obj1.getArray();
    if (colorComponents->getLength() > 0) {
      borderColor = new AnnotColor(colorComponents);
    } else {
      borderColor = NULL;
    }
  } else {
    borderColor = NULL;
  }
  obj1.free();

  if (dict->lookup("BG", &obj1)->isArray()) {
    Array *colorComponents = obj1.getArray();
    if (colorComponents->getLength() > 0) {
      backColor = new AnnotColor(colorComponents);
    } else {
      backColor = NULL;
    }
  } else {
    backColor = NULL;
  }
  obj1.free();

  if (dict->lookup("CA", &obj1)->isString()) {
    normalCaption = new GooString(obj1.getString());
  } else {
    normalCaption = NULL;
  }
  obj1.free();

  if (dict->lookup("RC", &obj1)->isString()) {
    rolloverCaption = new GooString(obj1.getString());
  } else {
    rolloverCaption = NULL;
  }
  obj1.free();

  if (dict->lookup("AC", &obj1)->isString()) {
    alternateCaption = new GooString(obj1.getString());
  } else {
    alternateCaption = NULL;
  }
  obj1.free();

  if (dict->lookup("IF", &obj1)->isDict()) {
    iconFit = new AnnotIconFit(obj1.getDict());
  } else {
    iconFit = NULL;
  }
  obj1.free();

  if (dict->lookup("TP", &obj1)->isInt()) {
    position = (AnnotAppearanceCharacsTextPos) obj1.getInt();
  } else {
    position = captionNoIcon;
  }
  obj1.free();
}

AnnotAppearanceCharacs::~AnnotAppearanceCharacs() {
  if (borderColor)
    delete borderColor;

  if (backColor)
    delete backColor;

  if (normalCaption)
    delete normalCaption;

  if (rolloverCaption)
    delete rolloverCaption;

  if (alternateCaption)
    delete alternateCaption;

  if (iconFit)
    delete iconFit;
}

//------------------------------------------------------------------------
// AnnotAppearanceBBox
//------------------------------------------------------------------------

AnnotAppearanceBBox::AnnotAppearanceBBox(PDFRectangle *rect) {
  origX = rect->x1;
  origY = rect->y1;
  borderWidth = 0;

  // Initially set the same size as rect
  minX = 0;
  minY = 0;
  maxX = rect->x2 - rect->x1;
  maxY = rect->y2 - rect->y1;
}

void AnnotAppearanceBBox::extendTo(double x, double y) {
  if (x < minX) {
    minX = x;
  } else if (x > maxX) {
    maxX = x;
  }
  if (y < minY) {
    minY = y;
  } else if (y > maxY) {
    maxY = y;
  }
}

void AnnotAppearanceBBox::getBBoxRect(double bbox[4]) const {
  bbox[0] = minX - borderWidth;
  bbox[1] = minY - borderWidth;
  bbox[2] = maxX + borderWidth;
  bbox[3] = maxY + borderWidth;
}

double AnnotAppearanceBBox::getPageXMin() const {
  return origX + minX - borderWidth;
}

double AnnotAppearanceBBox::getPageYMin() const {
  return origY + minY - borderWidth;
}

double AnnotAppearanceBBox::getPageXMax() const {
  return origX + maxX + borderWidth;
}

double AnnotAppearanceBBox::getPageYMax() const {
  return origY + maxY + borderWidth;
}

//------------------------------------------------------------------------
// Annot
//------------------------------------------------------------------------

Annot::Annot(PDFDoc *docA, PDFRectangle *rectA) {
  Object obj1;

  refCnt = 1;
  flags = flagUnknown;
  type = typeUnknown;

  obj1.initArray (docA->getXRef());
  Object obj2;
  obj1.arrayAdd (obj2.initReal (rectA->x1));
  obj1.arrayAdd (obj2.initReal (rectA->y1));
  obj1.arrayAdd (obj2.initReal (rectA->x2));
  obj1.arrayAdd (obj2.initReal (rectA->y2));
  obj2.free ();

  annotObj.initDict (docA->getXRef());
  annotObj.dictSet ("Type", obj2.initName ("Annot"));
  annotObj.dictSet ("Rect", &obj1);
  // obj1 is owned by the dict

  ref = docA->getXRef()->addIndirectObject (&annotObj);

  initialize (docA, annotObj.getDict());
}

Annot::Annot(PDFDoc *docA, Dict *dict) {
  refCnt = 1;
  hasRef = false;
  flags = flagUnknown;
  type = typeUnknown;
  annotObj.initDict (dict);
  initialize (docA, dict);
}

Annot::Annot(PDFDoc *docA, Dict *dict, Object *obj) {
  refCnt = 1;
  if (obj->isRef()) {
    hasRef = gTrue;
    ref = obj->getRef();
  } else {
    hasRef = gFalse;
  }
  flags = flagUnknown;
  type = typeUnknown;
  annotObj.initDict (dict);
  initialize (docA, dict);
}

void Annot::initialize(PDFDoc *docA, Dict *dict) {
  Object apObj, asObj, obj1, obj2;

  ok = gTrue;
  doc = docA;
  xref = doc->getXRef();
  appearStreams = NULL;
  appearBBox = NULL;
  appearState = NULL;
  appearBuf = NULL;
  fontSize = 0;

  appearance.initNull();

  //----- parse the rectangle
  rect = new PDFRectangle();
  if (dict->lookup("Rect", &obj1)->isArray() && obj1.arrayGetLength() == 4) {
    Object obj2;
    (obj1.arrayGet(0, &obj2)->isNum() ? rect->x1 = obj2.getNum() : rect->x1 = 0);
    obj2.free();
    (obj1.arrayGet(1, &obj2)->isNum() ? rect->y1 = obj2.getNum() : rect->y1 = 0);
    obj2.free();
    (obj1.arrayGet(2, &obj2)->isNum() ? rect->x2 = obj2.getNum() : rect->x2 = 1);
    obj2.free();
    (obj1.arrayGet(3, &obj2)->isNum() ? rect->y2 = obj2.getNum() : rect->y2 = 1);
    obj2.free();

    if (rect->x1 > rect->x2) {
      double t = rect->x1;
      rect->x1 = rect->x2;
      rect->x2 = t;
    }

    if (rect->y1 > rect->y2) {
      double t = rect->y1;
      rect->y1 = rect->y2;
      rect->y2 = t;
    }
  } else {
    rect->x1 = rect->y1 = 0;
    rect->x2 = rect->y2 = 1;
    error(errSyntaxError, -1, "Bad bounding box for annotation");
    ok = gFalse;
  }
  obj1.free();

  if (dict->lookup("Contents", &obj1)->isString()) {
    contents = obj1.getString()->copy();
  } else {
    contents = new GooString();
  }
  obj1.free();

  // Note: This value is overwritten by Annots ctor
  if (dict->lookupNF("P", &obj1)->isRef()) {
    Ref ref = obj1.getRef();

    page = doc->getCatalog()->findPage (ref.num, ref.gen);
  } else {
    page = 0;
  }
  obj1.free();

  if (dict->lookup("NM", &obj1)->isString()) {
    name = obj1.getString()->copy();
  } else {
    name = NULL;
  }
  obj1.free();

  if (dict->lookup("M", &obj1)->isString()) {
    modified = obj1.getString()->copy();
  } else {
    modified = NULL;
  }
  obj1.free();

  //----- get the flags
  if (dict->lookup("F", &obj1)->isInt()) {
    flags |= obj1.getInt();
  } else {
    flags = flagUnknown;
  }
  obj1.free();

  //----- get the annotation appearance dictionary
  dict->lookup("AP", &apObj);
  if (apObj.isDict()) {
    appearStreams = new AnnotAppearance(doc, &apObj);
  }
  apObj.free();

  //----- get the appearance state
  dict->lookup("AS", &asObj);
  if (asObj.isName()) {
    appearState = new GooString(asObj.getName());
  } else if (appearStreams && appearStreams->getNumStates() != 0) {
    error (errSyntaxError, -1, "Invalid or missing AS value in annotation containing one or more appearance subdictionaries");
    // AS value is required in this case, but if the
    // N dictionary contains only one entry
    // take it as default appearance.
    if (appearStreams->getNumStates() == 1) {
      appearState = appearStreams->getStateKey(0);
    }
  }
  if (!appearState) {
    appearState = new GooString("Off");
  }
  asObj.free();

  //----- get the annotation appearance
  if (appearStreams) {
    appearStreams->getAppearanceStream(AnnotAppearance::appearNormal, appearState->getCString(), &appearance);
  }

  //----- parse the border style
  // According to the spec if neither the Border nor the BS entry is present,
  // the border shall be drawn as a solid line with a width of 1 point. But acroread
  // seems to ignore the Border entry for annots that can't have a BS entry. So, we only
  // follow this rule for annots tha can have a BS entry.
  if (dict->lookup("Border", &obj1)->isArray())
    border = new AnnotBorderArray(obj1.getArray());
  else
    border = NULL;
  obj1.free();

  if (dict->lookup("C", &obj1)->isArray()) {
    color = new AnnotColor(obj1.getArray());
  } else {
    color = NULL;
  }
  obj1.free();

  if (dict->lookup("StructParent", &obj1)->isInt()) {
    treeKey = obj1.getInt();
  } else {
    treeKey = 0;
  }
  obj1.free();

  dict->lookupNF("OC", &oc);

#if MULTITHREADED
  gInitMutex(&mutex);
#endif
}

void Annot::getRect(double *x1, double *y1, double *x2, double *y2) const {
  *x1 = rect->x1;
  *y1 = rect->y1;
  *x2 = rect->x2;
  *y2 = rect->y2;
}

void Annot::setRect(PDFRectangle *rect) {
    setRect(rect->x1, rect->y1, rect->x2, rect->y2);
}

void Annot::setRect(double x1, double y1, double x2, double y2) {
  Object obj1, obj2;

  if (x1 < x2) {
    rect->x1 = x1;
    rect->x2 = x2;
  } else {
    rect->x1 = x2;
    rect->x2 = x1;
  }

  if (y1 < y2) {
    rect->y1 = y1;
    rect->y2 = y2;
  } else {
    rect->y1 = y2;
    rect->y2 = y1;
  }

  obj1.initArray (xref);
  obj1.arrayAdd (obj2.initReal (rect->x1));
  obj1.arrayAdd (obj2.initReal (rect->y1));
  obj1.arrayAdd (obj2.initReal (rect->x2));
  obj1.arrayAdd (obj2.initReal (rect->y2));

  update("Rect", &obj1);
  invalidateAppearance();
}

GBool Annot::inRect(double x, double y) const {
  return rect->contains(x, y);
}

void Annot::update(const char *key, Object *value) {
  annotLocker();
  /* Set M to current time, unless we are updating M itself */
  if (strcmp(key, "M") != 0) {
    delete modified;
    modified = timeToDateString(NULL);

    Object obj1;
    obj1.initString (modified->copy());
    annotObj.dictSet("M", &obj1);
  }

  annotObj.dictSet(const_cast<char*>(key), value);
  
  xref->setModifiedObject(&annotObj, ref);
}

void Annot::setContents(GooString *new_content) {
  annotLocker();
  delete contents;

  if (new_content) {
    contents = new GooString(new_content);
    //append the unicode marker <FE FF> if needed	
    if (!contents->hasUnicodeMarker()) {
      contents->insert(0, 0xff);
      contents->insert(0, 0xfe);
    }
  } else {
    contents = new GooString();
  }
  
  Object obj1;
  obj1.initString(contents->copy());
  update ("Contents", &obj1);
}

void Annot::setName(GooString *new_name) {
  annotLocker();
  delete name;

  if (new_name) {
    name = new GooString(new_name);
  } else {
    name = new GooString();
  }

  Object obj1;
  obj1.initString(name->copy());
  update ("NM", &obj1);
}

void Annot::setModified(GooString *new_modified) {
  annotLocker();
  delete modified;

  if (new_modified)
    modified = new GooString(new_modified);
  else
    modified = new GooString();

  Object obj1;
  obj1.initString(modified->copy());
  update ("M", &obj1);
}

void Annot::setFlags(Guint new_flags) {
  annotLocker();
  Object obj1;
  flags = new_flags;
  obj1.initInt(flags);
  update ("F", &obj1);
}

void Annot::setBorder(AnnotBorder *new_border) {
  annotLocker();
  delete border;

  if (new_border) {
    Object obj1;
    new_border->writeToObject(xref, &obj1);
    update(new_border->getType() == AnnotBorder::typeArray ? "Border" : "BS", &obj1);
    border = new_border;
  } else {
    border = NULL;
  }
  invalidateAppearance();
}

void Annot::setColor(AnnotColor *new_color) {
  annotLocker();
  delete color;

  if (new_color) {
    Object obj1;
    new_color->writeToObject(xref, &obj1);
    update ("C", &obj1);
    color = new_color;
  } else {
    color = NULL;
  }
  invalidateAppearance();
}

void Annot::setPage(int pageIndex, GBool updateP) {
  annotLocker();
  Page *pageobj = doc->getPage(pageIndex);
  Object obj1;

  if (pageobj) {
    Ref pageRef = pageobj->getRef();
    obj1.initRef(pageRef.num, pageRef.gen);
    page = pageIndex;
  } else {
    obj1.initNull();
    page = 0;
  }

  if (updateP) {
    update("P", &obj1);
  }
}

void Annot::setAppearanceState(const char *state) {
  annotLocker();
  if (!state)
    return;

  delete appearState;
  appearState = new GooString(state);

  delete appearBBox;
  appearBBox = NULL;

  Object obj1;
  obj1.initName(state);
  update ("AS", &obj1);

  // The appearance state determines the current appearance stream
  appearance.free();
  if (appearStreams) {
    appearStreams->getAppearanceStream(AnnotAppearance::appearNormal, appearState->getCString(), &appearance);
  } else {
    appearance.initNull();
  }
}

void Annot::invalidateAppearance() {
  annotLocker();
  if (appearStreams) { // Remove existing appearance streams
    appearStreams->removeAllStreams();
  }
  delete appearStreams;
  appearStreams = NULL;

  delete appearState;
  appearState = NULL;

  delete appearBBox;
  appearBBox = NULL;

  appearance.free();
  appearance.initNull();

  Object obj1, obj2;
  obj1.initNull();
  if (!annotObj.dictLookup("AP", &obj2)->isNull())
    update ("AP", &obj1); // Remove AP
  obj2.free();

  if (!annotObj.dictLookup("AS", &obj2)->isNull())
    update ("AS", &obj1); // Remove AS
  obj2.free();
}

double Annot::getXMin() {
  return rect->x1;
}

double Annot::getYMin() {
  return rect->y1;
}

double Annot::getXMax() {
  return rect->x2;
}

double Annot::getYMax() {
  return rect->y2;
}

void Annot::readArrayNum(Object *pdfArray, int key, double *value) {
  Object valueObject;

  pdfArray->arrayGet(key, &valueObject);
  if (valueObject.isNum()) {
    *value = valueObject.getNum();
  } else {
    *value = 0;
    ok = gFalse;
  }
  valueObject.free();
}

void Annot::removeReferencedObjects() {
  // Remove appearance streams (if any)
  invalidateAppearance();
}

void Annot::incRefCnt() {
  annotLocker();
  refCnt++;
}

void Annot::decRefCnt() {
#if MULTITHREADED
  gLockMutex(&mutex);
#endif
  if (--refCnt == 0) {
#if MULTITHREADED
    gUnlockMutex(&mutex);
#endif
    delete this;
    return;
  }
#if MULTITHREADED
  gUnlockMutex(&mutex);
#endif
}

Annot::~Annot() {
  annotObj.free();
  
  delete rect;
  delete contents;

  if (name)
    delete name;

  if (modified)
    delete modified;

  delete appearStreams;
  delete appearBBox;
  appearance.free();

  if (appearState)
    delete appearState;

  if (border)
    delete border;

  if (color)
    delete color;

  oc.free();

#if MULTITHREADED
    gDestroyMutex(&mutex);
#endif
}

void Annot::setColor(AnnotColor *color, GBool fill) {
  const double *values = color->getValues();

  switch (color->getSpace()) {
  case AnnotColor::colorCMYK:
    appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:c}\n",
		       values[0], values[1], values[2], values[3],
		       fill ? 'k' : 'K');
    break;
  case AnnotColor::colorRGB:
    appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:s}\n",
		       values[0], values[1], values[2],
		       fill ? "rg" : "RG");
    break;
  case AnnotColor::colorGray:
    appearBuf->appendf("{0:.2f} {1:c}\n",
		       values[0],
		       fill ? 'g' : 'G');
    break;
  case AnnotColor::colorTransparent:
  default:
    break;
  }
}

void Annot::setLineStyleForBorder(AnnotBorder *border) {
  int i, dashLength;
  double *dash;

  switch (border->getStyle()) {
  case AnnotBorder::borderDashed:
    appearBuf->append("[");
    dashLength = border->getDashLength();
    dash = border->getDash();
    for (i = 0; i < dashLength; ++i)
      appearBuf->appendf(" {0:.2f}", dash[i]);
    appearBuf->append(" ] 0 d\n");
    break;
  default:
    appearBuf->append("[] 0 d\n");
    break;
  }
  appearBuf->appendf("{0:.2f} w\n", border->getWidth());
}

// Draw an (approximate) circle of radius <r> centered at (<cx>, <cy>).
// If <fill> is true, the circle is filled; otherwise it is stroked.
void Annot::drawCircle(double cx, double cy, double r, GBool fill) {
  appearBuf->appendf("{0:.2f} {1:.2f} m\n",
      cx + r, cy);
  appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
      cx + r, cy + bezierCircle * r,
      cx + bezierCircle * r, cy + r,
      cx, cy + r);
  appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
      cx - bezierCircle * r, cy + r,
      cx - r, cy + bezierCircle * r,
      cx - r, cy);
  appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
      cx - r, cy - bezierCircle * r,
      cx - bezierCircle * r, cy - r,
      cx, cy - r);
  appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
      cx + bezierCircle * r, cy - r,
      cx + r, cy - bezierCircle * r,
      cx + r, cy);
  appearBuf->append(fill ? "f\n" : "s\n");
}

// Draw the top-left half of an (approximate) circle of radius <r>
// centered at (<cx>, <cy>).
void Annot::drawCircleTopLeft(double cx, double cy, double r) {
  double r2;

  r2 = r / sqrt(2.0);
  appearBuf->appendf("{0:.2f} {1:.2f} m\n",
      cx + r2, cy + r2);
  appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
      cx + (1 - bezierCircle) * r2,
      cy + (1 + bezierCircle) * r2,
      cx - (1 - bezierCircle) * r2,
      cy + (1 + bezierCircle) * r2,
      cx - r2,
      cy + r2);
  appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
      cx - (1 + bezierCircle) * r2,
      cy + (1 - bezierCircle) * r2,
      cx - (1 + bezierCircle) * r2,
      cy - (1 - bezierCircle) * r2,
      cx - r2,
      cy - r2);
  appearBuf->append("S\n");
}

// Draw the bottom-right half of an (approximate) circle of radius <r>
// centered at (<cx>, <cy>).
void Annot::drawCircleBottomRight(double cx, double cy, double r) {
  double r2;

  r2 = r / sqrt(2.0);
  appearBuf->appendf("{0:.2f} {1:.2f} m\n",
      cx - r2, cy - r2);
  appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
      cx - (1 - bezierCircle) * r2,
      cy - (1 + bezierCircle) * r2,
      cx + (1 - bezierCircle) * r2,
      cy - (1 + bezierCircle) * r2,
      cx + r2,
      cy - r2);
  appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
      cx + (1 + bezierCircle) * r2,
      cy - (1 - bezierCircle) * r2,
      cx + (1 + bezierCircle) * r2,
      cy + (1 - bezierCircle) * r2,
      cx + r2,
      cy + r2);
  appearBuf->append("S\n");
}

void Annot::createForm(double *bbox, GBool transparencyGroup, Object *resDict, Object *aStream) {
  Object obj1, obj2;
  Object appearDict;

  appearDict.initDict(xref);
  appearDict.dictSet("Length", obj1.initInt(appearBuf->getLength()));
  appearDict.dictSet("Subtype", obj1.initName("Form"));
  obj1.initArray(xref);
  obj1.arrayAdd(obj2.initReal(bbox[0]));
  obj1.arrayAdd(obj2.initReal(bbox[1]));
  obj1.arrayAdd(obj2.initReal(bbox[2]));
  obj1.arrayAdd(obj2.initReal(bbox[3]));
  appearDict.dictSet("BBox", &obj1);
  if (transparencyGroup) {
    Object transDict;
    transDict.initDict(xref);
    transDict.dictSet("S", obj1.initName("Transparency"));
    appearDict.dictSet("Group", &transDict);
  }
  if (resDict)
    appearDict.dictSet("Resources", resDict);

  MemStream *mStream = new MemStream(copyString(appearBuf->getCString()), 0,
				     appearBuf->getLength(), &appearDict);
  mStream->setNeedFree(gTrue);
  aStream->initStream(mStream);
}

void Annot::createResourcesDict(const char *formName, Object *formStream,
				const char *stateName,
				double opacity, const char *blendMode,
				Object *resDict) {
  Object gsDict, stateDict, formDict, obj1;

  gsDict.initDict(xref);
  if (opacity != 1) {
    gsDict.dictSet("CA", obj1.initReal(opacity));
    gsDict.dictSet("ca", obj1.initReal(opacity));
  }
  if (blendMode)
    gsDict.dictSet("BM", obj1.initName(blendMode));
  stateDict.initDict(xref);
  stateDict.dictSet(stateName, &gsDict);
  formDict.initDict(xref);
  formDict.dictSet(formName, formStream);

  resDict->initDict(xref);
  resDict->dictSet("ExtGState", &stateDict);
  resDict->dictSet("XObject", &formDict);
}

Object *Annot::getAppearanceResDict(Object *dest) {
  Object obj1, obj2;

  dest->initNull(); // Default value

  // Fetch appearance's resource dict (if any)
  appearance.fetch(xref, &obj1);
  if (obj1.isStream()) {
    obj1.streamGetDict()->lookup("Resources", &obj2);
    if (obj2.isDict()) {
      obj2.copy(dest);
    }
    obj2.free();
  }
  obj1.free();

  return dest;
}

GBool Annot::isVisible(GBool printing) {
  // check the flags
  if ((flags & flagHidden) ||
      (printing && !(flags & flagPrint)) ||
      (!printing && (flags & flagNoView))) {
    return gFalse;
  }

  // check the OC
  OCGs *optContentConfig = doc->getCatalog()->getOptContentConfig();
  if (optContentConfig) {
    if (! optContentConfig->optContentIsVisible(&oc))
      return gFalse;
  }

  return gTrue;
}

int Annot::getRotation() const
{
  Page *pageobj = doc->getPage(page);
  assert(pageobj != NULL);

  if (flags & flagNoRotate) {
    return (360 - pageobj->getRotate()) % 360;
  } else {
    return 0;
  }
}

void Annot::draw(Gfx *gfx, GBool printing) {
  Object obj;

  annotLocker();
  if (!isVisible (printing))
    return;

  // draw the appearance stream
  appearance.fetch(gfx->getXRef(), &obj);
  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
      rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
  obj.free();
}

//------------------------------------------------------------------------
// AnnotPopup
//------------------------------------------------------------------------

AnnotPopup::AnnotPopup(PDFDoc *docA, PDFRectangle *rect) :
    Annot(docA, rect) {
  Object obj1;

  type = typePopup;

  annotObj.dictSet ("Subtype", obj1.initName ("Popup"));
  initialize (docA, annotObj.getDict());
}

AnnotPopup::AnnotPopup(PDFDoc *docA, Dict *dict, Object *obj) :
    Annot(docA, dict, obj) {
  type = typePopup;
  initialize(docA, dict);
}

AnnotPopup::~AnnotPopup() {
  parent.free();
}

void AnnotPopup::initialize(PDFDoc *docA, Dict *dict) {
  Object obj1;

  if (!dict->lookupNF("Parent", &parent)->isRef()) {
    parent.initNull();
  }

  if (dict->lookup("Open", &obj1)->isBool()) {
    open = obj1.getBool();
  } else {
    open = gFalse;
  }
  obj1.free();
}

void AnnotPopup::setParent(Object *parentA) {
  parentA->copy(&parent);
  update ("Parent", &parent);
}

void AnnotPopup::setParent(Annot *parentA) {
  Ref parentRef = parentA->getRef();
  parent.initRef(parentRef.num, parentRef.gen);
  update ("Parent", &parent);
}

void AnnotPopup::setOpen(GBool openA) {
  Object obj1;

  open = openA;
  obj1.initBool(open);
  update ("Open", &obj1);
}

//------------------------------------------------------------------------
// AnnotMarkup
//------------------------------------------------------------------------
AnnotMarkup::AnnotMarkup(PDFDoc *docA, PDFRectangle *rect) :
    Annot(docA, rect) {
  initialize(docA, annotObj.getDict(), &annotObj);
}

AnnotMarkup::AnnotMarkup(PDFDoc *docA, Dict *dict, Object *obj) :
    Annot(docA, dict, obj) {
  initialize(docA, dict, obj);
}

AnnotMarkup::~AnnotMarkup() {
  if (label)
    delete label;

  if (popup)
    delete popup;

  if (date)
    delete date;

  if (subject)
    delete subject;
}

void AnnotMarkup::initialize(PDFDoc *docA, Dict *dict, Object *obj) {
  Object obj1, obj2;

  if (dict->lookup("T", &obj1)->isString()) {
    label = obj1.getString()->copy();
  } else {
    label = NULL;
  }
  obj1.free();

  if (dict->lookup("Popup", &obj1)->isDict() && dict->lookupNF("Popup", &obj2)->isRef()) {
    popup = new AnnotPopup(docA, obj1.getDict(), &obj2);
  } else {
    popup = NULL;
  }
  obj1.free();

  if (dict->lookup("CA", &obj1)->isNum()) {
    opacity = obj1.getNum();
  } else {
    opacity = 1.0;
  }
  obj1.free();

  if (dict->lookup("CreationDate", &obj1)->isString()) {
    date = obj1.getString()->copy();
  } else {
    date = NULL;
  }
  obj1.free();

  if (dict->lookupNF("IRT", &obj1)->isRef()) {
    inReplyTo = obj1.getRef();
  } else {
    inReplyTo.num = 0;
    inReplyTo.gen = 0;
  }
  obj1.free();

  if (dict->lookup("Subj", &obj1)->isString()) {
    subject = obj1.getString()->copy();
  } else {
    subject = NULL;
  }
  obj1.free();

  if (dict->lookup("RT", &obj1)->isName()) {
    const char *replyName = obj1.getName();

    if (!strcmp(replyName, "R")) {
      replyTo = replyTypeR;
    } else if (!strcmp(replyName, "Group")) {
      replyTo = replyTypeGroup;
    } else {
      replyTo = replyTypeR;
    }
  } else {
    replyTo = replyTypeR;
  }
  obj1.free();

  if (dict->lookup("ExData", &obj1)->isDict()) {
    exData = parseAnnotExternalData(obj1.getDict());
  } else {
    exData = annotExternalDataMarkupUnknown;
  }
  obj1.free();
}

void AnnotMarkup::setLabel(GooString *new_label) {
  delete label;

  if (new_label) {
    label = new GooString(new_label);
    //append the unicode marker <FE FF> if needed
    if (!label->hasUnicodeMarker()) {
      label->insert(0, 0xff);
      label->insert(0, 0xfe);
    }
  } else {
    label = new GooString();
  }

  Object obj1;
  obj1.initString(label->copy());
  update ("T", &obj1);
}

void AnnotMarkup::setPopup(AnnotPopup *new_popup) {
  // If there exists an old popup annotation that is already
  // associated with a page, then we need to remove that
  // popup annotation from the page. Otherwise we would have
  // dangling references to it.
  if (popup != NULL && popup->getPageNum() != 0) {
    Page *pageobj = doc->getPage(popup->getPageNum());
    if (pageobj) {
      pageobj->removeAnnot(popup);
    }
  }
  delete popup;

  if (new_popup) {
    Object obj1;
    Ref popupRef = new_popup->getRef();

    obj1.initRef (popupRef.num, popupRef.gen);
    update ("Popup", &obj1);

    new_popup->setParent(this);
    popup = new_popup;

    // If this annotation is already added to a page, then we
    // add the new popup annotation to the same page.
    if (page != 0) {
      Page *pageobj = doc->getPage(page);
      assert(pageobj != NULL); // pageobj should exist in doc (see setPage())

      pageobj->addAnnot(popup);
    }
  } else {
    popup = NULL;
  }
}

void AnnotMarkup::setOpacity(double opacityA) {
  Object obj1;

  opacity = opacityA;
  obj1.initReal(opacity);
  update ("CA", &obj1);
  invalidateAppearance();
}

void AnnotMarkup::setDate(GooString *new_date) {
  delete date;

  if (new_date)
    date = new GooString(new_date);
  else
    date = new GooString();

  Object obj1;
  obj1.initString(date->copy());
  update ("CreationDate", &obj1);
}

void AnnotMarkup::removeReferencedObjects() {
  Page *pageobj = doc->getPage(page);
  assert(pageobj != NULL); // We're called when removing an annot from a page

  // Remove popup
  if (popup) {
    pageobj->removeAnnot(popup);
  }

  Annot::removeReferencedObjects();
}

//------------------------------------------------------------------------
// AnnotText
//------------------------------------------------------------------------

AnnotText::AnnotText(PDFDoc *docA, PDFRectangle *rect) :
    AnnotMarkup(docA, rect) {
  Object obj1;

  type = typeText;
  flags |= flagNoZoom | flagNoRotate;

  annotObj.dictSet ("Subtype", obj1.initName ("Text"));
  initialize (docA, annotObj.getDict());
}

AnnotText::AnnotText(PDFDoc *docA, Dict *dict, Object *obj) :
    AnnotMarkup(docA, dict, obj) {

  type = typeText;
  flags |= flagNoZoom | flagNoRotate;
  initialize (docA, dict);
}

AnnotText::~AnnotText() {
  delete icon;
}

void AnnotText::initialize(PDFDoc *docA, Dict *dict) {
  Object obj1;

  if (dict->lookup("Open", &obj1)->isBool())
    open = obj1.getBool();
  else
    open = gFalse;
  obj1.free();

  if (dict->lookup("Name", &obj1)->isName()) {
    icon = new GooString(obj1.getName());
  } else {
    icon = new GooString("Note");
  }
  obj1.free();

  if (dict->lookup("StateModel", &obj1)->isString()) {
    Object obj2;
    GooString *modelName = obj1.getString();

    if (dict->lookup("State", &obj2)->isString()) {
      GooString *stateName = obj2.getString();

      if (!stateName->cmp("Marked")) {
        state = stateMarked;
      } else if (!stateName->cmp("Unmarked")) {
        state = stateUnmarked;
      } else if (!stateName->cmp("Accepted")) {
        state = stateAccepted;
      } else if (!stateName->cmp("Rejected")) {
        state = stateRejected;
      } else if (!stateName->cmp("Cancelled")) {
        state = stateCancelled;
      } else if (!stateName->cmp("Completed")) {
        state = stateCompleted;
      } else if (!stateName->cmp("None")) {
        state = stateNone;
      } else {
        state = stateUnknown;
      }
    } else {
      state = stateUnknown;
    }
    obj2.free();

    if (!modelName->cmp("Marked")) {
      switch (state) {
        case stateUnknown:
          state = stateMarked;
          break;
        case stateAccepted:
        case stateRejected:
        case stateCancelled:
        case stateCompleted:
        case stateNone:
          state = stateUnknown;
          break;
        default:
          break;
      }
    } else if (!modelName->cmp("Review")) {
      switch (state) {
        case stateUnknown:
          state = stateNone;
          break;
        case stateMarked:
        case stateUnmarked:
          state = stateUnknown;
          break;
        default:
          break;
      }
    } else {
      state = stateUnknown;
    }
  } else {
    state = stateUnknown;
  }
  obj1.free();
}

void AnnotText::setOpen(GBool openA) {
  Object obj1;

  open = openA;
  obj1.initBool(open);
  update ("Open", &obj1);
}

void AnnotText::setIcon(GooString *new_icon) {
  if (new_icon && icon->cmp(new_icon) == 0)
    return;

  delete icon;

  if (new_icon) {
    icon = new GooString (new_icon);
  } else {
    icon = new GooString("Note");
  }

  Object obj1;
  obj1.initName (icon->getCString());
  update("Name", &obj1);
  invalidateAppearance();
}

#define ANNOT_TEXT_AP_NOTE                                                    \
  "3.602 24 m 20.398 24 l 22.387 24 24 22.387 24 20.398 c 24 3.602 l 24\n"    \
  "1.613 22.387 0 20.398 0 c 3.602 0 l 1.613 0 0 1.613 0 3.602 c 0 20.398\n"  \
  "l 0 22.387 1.613 24 3.602 24 c h\n"                                        \
  "3.602 24 m f\n"                                                            \
  "0.533333 0.541176 0.521569 RG 2 w\n"                                       \
  "1 J\n"                                                                     \
  "1 j\n"                                                                     \
  "[] 0.0 d\n"                                                                \
  "4 M 9 18 m 4 18 l 4 7 4 4 6 3 c 20 3 l 18 4 18 7 18 18 c 17 18 l S\n"      \
  "1.5 w\n"                                                                   \
  "0 j\n"                                                                     \
  "10 16 m 14 21 l S\n"                                                       \
  "1.85625 w\n"                                                               \
  "1 j\n"                                                                     \
  "15.07 20.523 m 15.07 19.672 14.379 18.977 13.523 18.977 c 12.672 18.977\n" \
  "11.977 19.672 11.977 20.523 c 11.977 21.379 12.672 22.07 13.523 22.07 c\n" \
  "14.379 22.07 15.07 21.379 15.07 20.523 c h\n"                              \
  "15.07 20.523 m S\n"                                                        \
  "1 w\n"                                                                     \
  "0 j\n"                                                                     \
  "6.5 13.5 m 15.5 13.5 l S\n"                                                \
  "6.5 10.5 m 13.5 10.5 l S\n"                                                \
  "6.801 7.5 m 15.5 7.5 l S\n"                                                \
  "0.729412 0.741176 0.713725 RG 2 w\n"                                       \
  "1 j\n"                                                                     \
  "9 19 m 4 19 l 4 8 4 5 6 4 c 20 4 l 18 5 18 8 18 19 c 17 19 l S\n"          \
  "1.5 w\n"                                                                   \
  "0 j\n"                                                                     \
  "10 17 m 14 22 l S\n"                                                       \
  "1.85625 w\n"                                                               \
  "1 j\n"                                                                     \
  "15.07 21.523 m 15.07 20.672 14.379 19.977 13.523 19.977 c 12.672 19.977\n" \
  "11.977 20.672 11.977 21.523 c 11.977 22.379 12.672 23.07 13.523 23.07 c\n" \
  "14.379 23.07 15.07 22.379 15.07 21.523 c h\n"                              \
  "15.07 21.523 m S\n"                                                        \
  "1 w\n"                                                                     \
  "0 j\n"                                                                     \
  "6.5 14.5 m 15.5 14.5 l S\n"                                                \
  "6.5 11.5 m 13.5 11.5 l S\n"                                                \
  "6.801 8.5 m 15.5 8.5 l S\n"

#define ANNOT_TEXT_AP_COMMENT                                                   \
  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"      \
  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n"    \
  "l 1 21.523 2.477 23 4.301 23 c h\n"                                          \
  "4.301 23 m f\n"                                                              \
  "0.533333 0.541176 0.521569 RG 2 w\n"                                         \
  "0 J\n"                                                                       \
  "1 j\n"                                                                       \
  "[] 0.0 d\n"                                                                  \
  "4 M 8 20 m 16 20 l 18.363 20 20 18.215 20 16 c 20 13 l 20 10.785 18.363 9\n" \
  "16 9 c 13 9 l 8 3 l 8 9 l 8 9 l 5.637 9 4 10.785 4 13 c 4 16 l 4 18.215\n"   \
  "5.637 20 8 20 c h\n"                                                         \
  "8 20 m S\n"                                                                  \
  "0.729412 0.741176 0.713725 RG 8 21 m 16 21 l 18.363 21 20 19.215 20 17\n"    \
  "c 20 14 l 20 11.785 18.363 10\n"                                             \
  "16 10 c 13 10 l 8 4 l 8 10 l 8 10 l 5.637 10 4 11.785 4 14 c 4 17 l 4\n"     \
  "19.215 5.637 21 8 21 c h\n"                                                  \
  "8 21 m S\n"

#define ANNOT_TEXT_AP_KEY                                                    \
  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"   \
  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n" \
  "l 1 21.523 2.477 23 4.301 23 c h\n"                                       \
  "4.301 23 m f\n"                                                           \
  "0.533333 0.541176 0.521569 RG 2 w\n"                                      \
  "1 J\n"                                                                    \
  "0 j\n"                                                                    \
  "[] 0.0 d\n"                                                               \
  "4 M 11.895 18.754 m 13.926 20.625 17.09 20.496 18.961 18.465 c 20.832\n"  \
  "16.434 20.699 13.27 18.668 11.398 c 17.164 10.016 15.043 9.746 13.281\n"  \
  "10.516 c 12.473 9.324 l 11.281 10.078 l 9.547 8.664 l 9.008 6.496 l\n"    \
  "7.059 6.059 l 6.34 4.121 l 5.543 3.668 l 3.375 4.207 l 2.938 6.156 l\n"   \
  "10.57 13.457 l 9.949 15.277 10.391 17.367 11.895 18.754 c h\n"            \
  "11.895 18.754 m S\n"                                                      \
  "1.5 w\n"                                                                  \
  "16.059 15.586 m 16.523 15.078 17.316 15.043 17.824 15.512 c 18.332\n"     \
  "15.98 18.363 16.77 17.895 17.277 c 17.43 17.785 16.637 17.816 16.129\n"   \
  "17.352 c 15.621 16.883 15.59 16.094 16.059 15.586 c h\n"                  \
  "16.059 15.586 m S\n"                                                      \
  "0.729412 0.741176 0.713725 RG 2 w\n"                                      \
  "11.895 19.754 m 13.926 21.625 17.09 21.496 18.961 19.465 c 20.832\n"      \
  "17.434 20.699 14.27 18.668 12.398 c 17.164 11.016 15.043 10.746 13.281\n" \
  "11.516 c 12.473 10.324 l 11.281 11.078 l 9.547 9.664 l 9.008 7.496 l\n"   \
  "7.059 7.059 l 6.34 5.121 l 5.543 4.668 l 3.375 5.207 l 2.938 7.156 l\n"   \
  "10.57 14.457 l 9.949 16.277 10.391 18.367 11.895 19.754 c h\n"            \
  "11.895 19.754 m S\n"                                                      \
  "1.5 w\n"                                                                  \
  "16.059 16.586 m 16.523 16.078 17.316 16.043 17.824 16.512 c 18.332\n"     \
  "16.98 18.363 17.77 17.895 18.277 c 17.43 18.785 16.637 18.816 16.129\n"   \
  "18.352 c 15.621 17.883 15.59 17.094 16.059 16.586 c h\n"                  \
  "16.059 16.586 m S\n"

#define ANNOT_TEXT_AP_HELP                                                        \
  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"        \
  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n"      \
  "l 1 21.523 2.477 23 4.301 23 c h\n"                                            \
  "4.301 23 m f\n"                                                                \
  "0.533333 0.541176 0.521569 RG 2.5 w\n"                                         \
  "1 J\n"                                                                         \
  "1 j\n"                                                                         \
  "[] 0.0 d\n"                                                                    \
  "4 M 8.289 16.488 m 8.824 17.828 10.043 18.773 11.473 18.965 c 12.902 19.156\n" \
  "14.328 18.559 15.195 17.406 c 16.062 16.254 16.242 14.723 15.664 13.398\n"     \
  "c S\n"                                                                         \
  "0 j\n"                                                                         \
  "12 8 m 12 12 16 11 16 15 c S\n"                                                \
  "1.539286 w\n"                                                                  \
  "1 j\n"                                                                         \
  "q 1 0 0 -0.999991 0 24 cm\n"                                                   \
  "12.684 20.891 m 12.473 21.258 12.004 21.395 11.629 21.196 c 11.254\n"          \
  "20.992 11.105 20.531 11.297 20.149 c 11.488 19.77 11.945 19.61 12.332\n"       \
  "19.789 c 12.719 19.969 12.891 20.426 12.719 20.817 c S Q\n"                    \
  "0.729412 0.741176 0.713725 RG 2.5 w\n"                                         \
  "8.289 17.488 m 9.109 19.539 11.438 20.535 13.488 19.711 c 15.539 18.891\n"     \
  "16.535 16.562 15.711 14.512 c 15.699 14.473 15.684 14.438 15.664 14.398\n"     \
  "c S\n"                                                                         \
  "0 j\n"                                                                         \
  "12 9 m 12 13 16 12 16 16 c S\n"                                                \
  "1.539286 w\n"                                                                  \
  "1 j\n"                                                                         \
  "q 1 0 0 -0.999991 0 24 cm\n"                                                   \
  "12.684 19.891 m 12.473 20.258 12.004 20.395 11.629 20.195 c 11.254\n"          \
  "19.992 11.105 19.531 11.297 19.149 c 11.488 18.77 11.945 18.61 12.332\n"       \
  "18.789 c 12.719 18.969 12.891 19.426 12.719 19.817 c S Q\n"

#define ANNOT_TEXT_AP_NEW_PARAGRAPH                                               \
  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"        \
  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n"      \
  "l 1 21.523 2.477 23 4.301 23 c h\n"                                            \
  "4.301 23 m f\n"                                                                \
  "0.533333 0.541176 0.521569 RG 4 w\n"                                           \
  "0 J\n"                                                                         \
  "2 j\n"                                                                         \
  "[] 0.0 d\n"                                                                    \
  "4 M q 1 0 0 -1 0 24 cm\n"                                                      \
  "9.211 11.988 m 8.449 12.07 7.711 11.707 7.305 11.059 c 6.898 10.41\n"          \
  "6.898 9.59 7.305 8.941 c 7.711 8.293 8.449 7.93 9.211 8.012 c S Q\n"           \
  "1.004413 w\n"                                                                  \
  "1 J\n"                                                                         \
  "1 j\n"                                                                         \
  "q 1 0 0 -0.991232 0 24 cm\n"                                                   \
  "18.07 11.511 m 15.113 10.014 l 12.199 11.602 l 12.711 8.323 l 10.301\n"        \
  "6.045 l 13.574 5.517 l 14.996 2.522 l 16.512 5.474 l 19.801 5.899 l\n"         \
  "17.461 8.252 l 18.07 11.511 l h\n"                                             \
  "18.07 11.511 m S Q\n"                                                          \
  "2 w\n"                                                                         \
  "0 j\n"                                                                         \
  "11 17 m 10 17 l 10 3 l S\n"                                                    \
  "14 3 m 14 13 l S\n"                                                            \
  "0.729412 0.741176 0.713725 RG 4 w\n"                                           \
  "0 J\n"                                                                         \
  "2 j\n"                                                                         \
  "q 1 0 0 -1 0 24 cm\n"                                                          \
  "9.211 10.988 m 8.109 11.105 7.125 10.309 7.012 9.211 c 6.895 8.109\n"          \
  "7.691 7.125 8.789 7.012 c 8.93 6.996 9.07 6.996 9.211 7.012 c S Q\n"           \
  "1.004413 w\n"                                                                  \
  "1 J\n"                                                                         \
  "1 j\n"                                                                         \
  "q 1 0 0 -0.991232 0 24 cm\n"                                                   \
  "18.07 10.502 m 15.113 9.005 l 12.199 10.593 l 12.711 7.314 l 10.301\n"         \
  "5.036 l 13.574 4.508 l 14.996 1.513 l 16.512 4.465 l 19.801 4.891 l\n"         \
  "17.461 7.243 l 18.07 10.502 l h\n"                                             \
  "18.07 10.502 m S Q\n"                                                          \
  "2 w\n"                                                                         \
  "0 j\n"                                                                         \
  "11 18 m 10 18 l 10 4 l S\n"                                                    \
  "14 4 m 14 14 l S\n"

#define ANNOT_TEXT_AP_PARAGRAPH                                              \
  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"   \
  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n" \
  "l 1 21.523 2.477 23 4.301 23 c h\n"                                       \
  "4.301 23 m f\n"                                                           \
  "0.533333 0.541176 0.521569 RG 2 w\n"                                      \
  "1 J\n"                                                                    \
  "1 j\n"                                                                    \
  "[] 0.0 d\n"                                                               \
  "4 M 15 3 m 15 18 l 11 18 l 11 3 l S\n"                                    \
  "4 w\n"                                                                    \
  "q 1 0 0 -1 0 24 cm\n"                                                     \
  "9.777 10.988 m 8.746 10.871 7.973 9.988 8 8.949 c 8.027 7.91 8.844\n"     \
  "7.066 9.879 7.004 c S Q\n"                                                \
  "0.729412 0.741176 0.713725 RG 2 w\n"                                      \
  "15 4 m 15 19 l 11 19 l 11 4 l S\n"                                        \
  "4 w\n"                                                                    \
  "q 1 0 0 -1 0 24 cm\n"                                                     \
  "9.777 9.988 m 8.746 9.871 7.973 8.988 8 7.949 c 8.027 6.91 8.844 6.066\n" \
  "9.879 6.004 c S Q\n"

#define ANNOT_TEXT_AP_INSERT                                                 \
  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"   \
  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n" \
  "l 1 21.523 2.477 23 4.301 23 c h\n"                                       \
  "4.301 23 m f\n"                                                           \
  "0.533333 0.541176 0.521569 RG 2 w\n"                                      \
  "1 J\n"                                                                    \
  "0 j\n"                                                                    \
  "[] 0.0 d\n"                                                               \
  "4 M 12 18.012 m 20 18 l S\n"                                              \
  "9 10 m 17 10 l S\n"                                                       \
  "12 14.012 m 20 14 l S\n"                                                  \
  "12 6.012 m 20 6.012 l S\n"                                                \
  "4 12 m 6 10 l 4 8 l S\n"                                                  \
  "4 12 m 4 8 l S\n"                                                         \
  "0.729412 0.741176 0.713725 RG 12 19.012 m 20 19 l S\n"                    \
  "9 11 m 17 11 l S\n"                                                       \
  "12 15.012 m 20 15 l S\n"                                                  \
  "12 7.012 m 20 7.012 l S\n"                                                \
  "4 13 m 6 11 l 4 9 l S\n"                                                  \
  "4 13 m 4 9 l S\n"

#define ANNOT_TEXT_AP_CROSS                                                  \
  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"   \
  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n" \
  "l 1 21.523 2.477 23 4.301 23 c h\n"                                       \
  "4.301 23 m f\n"                                                           \
  "0.533333 0.541176 0.521569 RG 2.5 w\n"                                    \
  "1 J\n"                                                                    \
  "0 j\n"                                                                    \
  "[] 0.0 d\n"                                                               \
  "4 M 18 5 m 6 17 l S\n"                                                    \
  "6 5 m 18 17 l S\n"                                                        \
  "0.729412 0.741176 0.713725 RG 18 6 m 6 18 l S\n"                          \
  "6 6 m 18 18 l S\n"

#define ANNOT_TEXT_AP_CIRCLE                                                      \
  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"        \
  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n"      \
  "l 1 21.523 2.477 23 4.301 23 c h\n"                                            \
  "4.301 23 m f\n"                                                                \
  "0.533333 0.541176 0.521569 RG 2.5 w\n"                                         \
  "1 J\n"                                                                         \
  "1 j\n"                                                                         \
  "[] 0.0 d\n"                                                                    \
  "4 M 19.5 11.5 m 19.5 7.359 16.141 4 12 4 c 7.859 4 4.5 7.359 4.5 11.5 c 4.5\n" \
  "15.641 7.859 19 12 19 c 16.141 19 19.5 15.641 19.5 11.5 c h\n"                 \
  "19.5 11.5 m S\n"                                                               \
  "0.729412 0.741176 0.713725 RG 19.5 12.5 m 19.5 8.359 16.141 5 12 5 c\n"        \
  "7.859 5 4.5 8.359 4.5 12.5 c 4.5\n"                                            \
  "16.641 7.859 20 12 20 c 16.141 20 19.5 16.641 19.5 12.5 c h\n"                 \
  "19.5 12.5 m S\n"

void AnnotText::draw(Gfx *gfx, GBool printing) {
  Object obj;
  double ca = 1;

  if (!isVisible (printing))
    return;

  annotLocker();
  if (appearance.isNull()) {
    ca = opacity;

    appearBuf = new GooString ();

    appearBuf->append ("q\n");
    if (color)
      setColor(color, gTrue);
    else
      appearBuf->append ("1 1 1 rg\n");
    if (!icon->cmp("Note"))
      appearBuf->append (ANNOT_TEXT_AP_NOTE);
    else if (!icon->cmp("Comment"))
      appearBuf->append (ANNOT_TEXT_AP_COMMENT);
    else if (!icon->cmp("Key"))
      appearBuf->append (ANNOT_TEXT_AP_KEY);
    else if (!icon->cmp("Help"))
      appearBuf->append (ANNOT_TEXT_AP_HELP);
    else if (!icon->cmp("NewParagraph"))
      appearBuf->append (ANNOT_TEXT_AP_NEW_PARAGRAPH);
    else if (!icon->cmp("Paragraph"))
      appearBuf->append (ANNOT_TEXT_AP_PARAGRAPH);
    else if (!icon->cmp("Insert"))
      appearBuf->append (ANNOT_TEXT_AP_INSERT);
    else if (!icon->cmp("Cross"))
      appearBuf->append (ANNOT_TEXT_AP_CROSS);
    else if (!icon->cmp("Circle"))
      appearBuf->append (ANNOT_TEXT_AP_CIRCLE);
    appearBuf->append ("Q\n");

    // Force 24x24 rectangle
    PDFRectangle fixedRect(rect->x1, rect->y2 - 24, rect->x1 + 24, rect->y2);
    appearBBox = new AnnotAppearanceBBox(&fixedRect);
    double bbox[4];
    appearBBox->getBBoxRect(bbox);
    if (ca == 1) {
      createForm(bbox, gFalse, NULL, &appearance);
    } else {
      Object aStream, resDict;

      createForm(bbox, gTrue, NULL, &aStream);
      delete appearBuf;

      appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
      createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
      createForm(bbox, gFalse, &resDict, &appearance);
    }
    delete appearBuf;
  }

  // draw the appearance stream
  appearance.fetch(gfx->getXRef(), &obj);
  if (appearBBox) {
    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
                   appearBBox->getPageXMin(), appearBBox->getPageYMin(),
                   appearBBox->getPageXMax(), appearBBox->getPageYMax(),
                   getRotation());
  } else {
    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
                   rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
  }
  obj.free();
}

//------------------------------------------------------------------------
// AnnotLink
//------------------------------------------------------------------------
AnnotLink::AnnotLink(PDFDoc *docA, PDFRectangle *rect) :
    Annot(docA, rect) {
  Object obj1;

  type = typeLink;
  annotObj.dictSet ("Subtype", obj1.initName ("Link"));
  initialize (docA, annotObj.getDict());
}

AnnotLink::AnnotLink(PDFDoc *docA, Dict *dict, Object *obj) :
    Annot(docA, dict, obj) {

  type = typeLink;
  initialize (docA, dict);
}

AnnotLink::~AnnotLink() {
  delete action;
  /*
  if (uriAction)
    delete uriAction;
  */
  if (quadrilaterals)
    delete quadrilaterals;
}

void AnnotLink::initialize(PDFDoc *docA, Dict *dict) {
  Object obj1;

  action = NULL;

  // look for destination
  if (!dict->lookup("Dest", &obj1)->isNull()) {
    action = LinkAction::parseDest(&obj1);
  // look for action
  } else {
    obj1.free();
    if (dict->lookup("A", &obj1)->isDict()) {
      action = LinkAction::parseAction(&obj1, doc->getCatalog()->getBaseURI());
    }
  }
  obj1.free();

  if (dict->lookup("H", &obj1)->isName()) {
    const char *effect = obj1.getName();

    if (!strcmp(effect, "N")) {
      linkEffect = effectNone;
    } else if (!strcmp(effect, "I")) {
      linkEffect = effectInvert;
    } else if (!strcmp(effect, "O")) {
      linkEffect = effectOutline;
    } else if (!strcmp(effect, "P")) {
      linkEffect = effectPush;
    } else {
      linkEffect = effectInvert;
    }
  } else {
    linkEffect = effectInvert;
  }
  obj1.free();
  /*
  if (dict->lookup("PA", &obj1)->isDict()) {
    uriAction = NULL;
  } else {
    uriAction = NULL;
  }
  obj1.free();
  */
  if (dict->lookup("QuadPoints", &obj1)->isArray()) {
    quadrilaterals = new AnnotQuadrilaterals(obj1.getArray(), rect);
  } else {
    quadrilaterals = NULL;
  }
  obj1.free();

  if (dict->lookup("BS", &obj1)->isDict()) {
    delete border;
    border = new AnnotBorderBS(obj1.getDict());
  } else if (!border) {
    border = new AnnotBorderBS();
  }
  obj1.free();
}

void AnnotLink::draw(Gfx *gfx, GBool printing) {
  Object obj;

  if (!isVisible (printing))
    return;

  annotLocker();
  // draw the appearance stream
  appearance.fetch(gfx->getXRef(), &obj);
  gfx->drawAnnot(&obj, border, color,
		 rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
  obj.free();
}

//------------------------------------------------------------------------
// AnnotFreeText
//------------------------------------------------------------------------
AnnotFreeText::AnnotFreeText(PDFDoc *docA, PDFRectangle *rect, GooString *da) :
    AnnotMarkup(docA, rect) {
  Object obj1;

  type = typeFreeText;

  annotObj.dictSet ("Subtype", obj1.initName ("FreeText"));

  Object obj2;
  obj2.initString (da->copy());
  annotObj.dictSet("DA", &obj2);

  initialize (docA, annotObj.getDict());
}

AnnotFreeText::AnnotFreeText(PDFDoc *docA, Dict *dict, Object *obj) :
    AnnotMarkup(docA, dict, obj) {
  type = typeFreeText;
  initialize(docA, dict);
}

AnnotFreeText::~AnnotFreeText() {
  delete appearanceString;

  if (styleString)
    delete styleString;

  if (calloutLine)
    delete calloutLine;

  if (borderEffect)
    delete borderEffect;

  if (rectangle)
    delete rectangle;
}

void AnnotFreeText::initialize(PDFDoc *docA, Dict *dict) {
  Object obj1;

  if (dict->lookup("DA", &obj1)->isString()) {
    appearanceString = obj1.getString()->copy();
  } else {
    appearanceString = new GooString();
    error(errSyntaxError, -1, "Bad appearance for annotation");
    ok = gFalse;
  }
  obj1.free();

  if (dict->lookup("Q", &obj1)->isInt()) {
    quadding = (AnnotFreeTextQuadding) obj1.getInt();
  } else {
    quadding = quaddingLeftJustified;
  }
  obj1.free();

  if (dict->lookup("DS", &obj1)->isString()) {
    styleString = obj1.getString()->copy();
  } else {
    styleString = NULL;
  }
  obj1.free();

  if (dict->lookup("CL", &obj1)->isArray() && obj1.arrayGetLength() >= 4) {
    double x1, y1, x2, y2;
    Object obj2;

    (obj1.arrayGet(0, &obj2)->isNum() ? x1 = obj2.getNum() : x1 = 0);
    obj2.free();
    (obj1.arrayGet(1, &obj2)->isNum() ? y1 = obj2.getNum() : y1 = 0);
    obj2.free();
    (obj1.arrayGet(2, &obj2)->isNum() ? x2 = obj2.getNum() : x2 = 0);
    obj2.free();
    (obj1.arrayGet(3, &obj2)->isNum() ? y2 = obj2.getNum() : y2 = 0);
    obj2.free();

    if (obj1.arrayGetLength() == 6) {
      double x3, y3;
      (obj1.arrayGet(4, &obj2)->isNum() ? x3 = obj2.getNum() : x3 = 0);
      obj2.free();
      (obj1.arrayGet(5, &obj2)->isNum() ? y3 = obj2.getNum() : y3 = 0);
      obj2.free();
      calloutLine = new AnnotCalloutMultiLine(x1, y1, x2, y2, x3, y3);
    } else {
      calloutLine = new AnnotCalloutLine(x1, y1, x2, y2);
    }
  } else {
    calloutLine = NULL;
  }
  obj1.free();

  if (dict->lookup("IT", &obj1)->isName()) {
    const char *intentName = obj1.getName();

    if (!strcmp(intentName, "FreeText")) {
      intent = intentFreeText;
    } else if (!strcmp(intentName, "FreeTextCallout")) {
      intent = intentFreeTextCallout;
    } else if (!strcmp(intentName, "FreeTextTypeWriter")) {
      intent = intentFreeTextTypeWriter;
    } else {
      intent = intentFreeText;
    }
  } else {
    intent = intentFreeText;
  }
  obj1.free();

  if (dict->lookup("BS", &obj1)->isDict()) {
    delete border;
    border = new AnnotBorderBS(obj1.getDict());
  } else if (!border) {
    border = new AnnotBorderBS();
  }
  obj1.free();

  if (dict->lookup("BE", &obj1)->isDict()) {
    borderEffect = new AnnotBorderEffect(obj1.getDict());
  } else {
    borderEffect = NULL;
  }
  obj1.free();

  if (dict->lookup("RD", &obj1)->isArray()) {
    rectangle = parseDiffRectangle(obj1.getArray(), rect);
  } else {
    rectangle = NULL;
  }
  obj1.free();

  if (dict->lookup("LE", &obj1)->isName()) {
    GooString styleName(obj1.getName());
    endStyle = parseAnnotLineEndingStyle(&styleName);
  } else {
    endStyle = annotLineEndingNone;
  }
  obj1.free();
}

void AnnotFreeText::setContents(GooString *new_content) {
  Annot::setContents(new_content);
  invalidateAppearance();
}

void AnnotFreeText::setAppearanceString(GooString *new_string) {
  delete appearanceString;

  if (new_string) {
    appearanceString = new GooString(new_string);
  } else {
    appearanceString = new GooString();
  }

  Object obj1;
  obj1.initString(appearanceString->copy());
  update ("DA", &obj1);
  invalidateAppearance();
}

void AnnotFreeText::setQuadding(AnnotFreeTextQuadding new_quadding) {
  Object obj1;
  quadding = new_quadding;
  obj1.initInt((int)quadding);
  update ("Q", &obj1);
  invalidateAppearance();
}

void AnnotFreeText::setStyleString(GooString *new_string) {
  delete styleString;

  if (new_string) {
    styleString = new GooString(new_string);
    //append the unicode marker <FE FF> if needed
    if (!styleString->hasUnicodeMarker()) {
      styleString->insert(0, 0xff);
      styleString->insert(0, 0xfe);
    }
  } else {
    styleString = new GooString();
  }

  Object obj1;
  obj1.initString(styleString->copy());
  update ("DS", &obj1);
}

void AnnotFreeText::setCalloutLine(AnnotCalloutLine *line) {
  delete calloutLine;

  Object obj1;
  if (line == NULL) {
    obj1.initNull();
    calloutLine = NULL;
  } else {
    double x1 = line->getX1(), y1 = line->getY1();
    double x2 = line->getX2(), y2 = line->getY2();
    Object obj2;
    obj1.initArray(xref);
    obj1.arrayAdd( obj2.initReal(x1) );
    obj1.arrayAdd( obj2.initReal(y1) );
    obj1.arrayAdd( obj2.initReal(x2) );
    obj1.arrayAdd( obj2.initReal(y2) );

    AnnotCalloutMultiLine *mline = dynamic_cast<AnnotCalloutMultiLine*>(line);
    if (mline) {
      double x3 = mline->getX3(), y3 = mline->getY3();
      obj1.arrayAdd( obj2.initReal(x3) );
      obj1.arrayAdd( obj2.initReal(y3) );
      calloutLine = new AnnotCalloutMultiLine(x1, y1, x2, y2, x3, y3);
    } else {
      calloutLine = new AnnotCalloutLine(x1, y1, x2, y2);
    }
  }

  update("CL", &obj1);
  invalidateAppearance();
}

void AnnotFreeText::setIntent(AnnotFreeTextIntent new_intent) {
  Object obj1;

  intent = new_intent;
  if (new_intent == intentFreeText)
    obj1.initName("FreeText");
  else if (new_intent == intentFreeTextCallout)
    obj1.initName("FreeTextCallout");
  else // intentFreeTextTypeWriter
    obj1.initName("FreeTextTypeWriter");
  update ("IT", &obj1);
}

static GfxFont * createAnnotDrawFont(XRef * xref, Object *fontResDict)
{
  Ref dummyRef = { -1, -1 };

  Object baseFontObj, subtypeObj, encodingObj;
  baseFontObj.initName("Helvetica");
  subtypeObj.initName("Type0");
  encodingObj.initName("WinAnsiEncoding");

  Object fontDictObj;
  Dict *fontDict = new Dict(xref);
  fontDict->decRef();
  fontDict->add(copyString("BaseFont"), &baseFontObj);
  fontDict->add(copyString("Subtype"), &subtypeObj);
  fontDict->add(copyString("Encoding"), &encodingObj);
  fontDictObj.initDict(fontDict);

  Object fontsDictObj;
  Dict *fontsDict = new Dict(xref);
  fontsDict->decRef();
  fontsDict->add(copyString("AnnotDrawFont"), &fontDictObj);
  fontsDictObj.initDict(fontsDict);

  Dict *dict = new Dict(xref);
  dict->add(copyString("Font"), &fontsDictObj);

  fontResDict->initDict(dict);
  return GfxFont::makeFont(xref, "AnnotDrawFont", dummyRef, fontDict);
}

void AnnotFreeText::parseAppearanceString(GooString *da, double &fontsize, AnnotColor* &fontcolor) {
  fontsize = -1;
  fontcolor = NULL;
  if (da) {
    GooList * daToks = new GooList();
    int j, i = 0;

    // Tokenize
    while (i < da->getLength()) {
      while (i < da->getLength() && Lexer::isSpace(da->getChar(i))) {
        ++i;
      }
      if (i < da->getLength()) {
        for (j = i + 1; j < da->getLength() && !Lexer::isSpace(da->getChar(j)); ++j) {
        }
        daToks->append(new GooString(da, i, j - i));
        i = j;
      }
    }

    // Scan backwards: we are looking for the last set value
    for (i = daToks->getLength()-1; i >= 0; --i) {
      if (fontsize == -1) {
        if (!((GooString *)daToks->get(i))->cmp("Tf") && i >= 2) {
            // TODO: Font name
            fontsize = gatof(( (GooString *)daToks->get(i-1) )->getCString());
        }
      }
      if (fontcolor == NULL) {
        if (!((GooString *)daToks->get(i))->cmp("g") && i >= 1) {
          fontcolor = new AnnotColor(gatof(( (GooString *)daToks->get(i-1) )->getCString()));
        } else if (!((GooString *)daToks->get(i))->cmp("rg") && i >= 3) {
          fontcolor = new AnnotColor(gatof(( (GooString *)daToks->get(i-3) )->getCString()),
                                     gatof(( (GooString *)daToks->get(i-2) )->getCString()),
                                     gatof(( (GooString *)daToks->get(i-1) )->getCString()));
        } else if (!((GooString *)daToks->get(i))->cmp("k") && i >= 4) {
          fontcolor = new AnnotColor(gatof(( (GooString *)daToks->get(i-4) )->getCString()),
                                     gatof(( (GooString *)daToks->get(i-3) )->getCString()),
                                     gatof(( (GooString *)daToks->get(i-2) )->getCString()),
                                     gatof(( (GooString *)daToks->get(i-1) )->getCString()));
        }
      }
    }
    deleteGooList(daToks, GooString);
  }
}

void AnnotFreeText::generateFreeTextAppearance()
{
  double borderWidth, ca = opacity;

  appearBuf = new GooString ();
  appearBuf->append ("q\n");

  borderWidth = border->getWidth();
  if (borderWidth > 0)
    setLineStyleForBorder(border);

  // Box size
  const double width = rect->x2 - rect->x1;
  const double height = rect->y2 - rect->y1;

  // Parse some properties from the appearance string
  double fontsize;
  AnnotColor *fontcolor;
  parseAppearanceString(appearanceString, fontsize, fontcolor);
  // Default values
  if (fontsize <= 0)
    fontsize = 10;
  if (fontcolor == NULL)
    fontcolor = new AnnotColor(0, 0, 0); // Black
  if (!contents)
    contents = new GooString ();

  // Draw box
  GBool doFill = (color && color->getSpace() != AnnotColor::colorTransparent);
  GBool doStroke = (borderWidth != 0);
  if (doFill || doStroke) {
    if (doStroke) {
      setColor(fontcolor, gFalse); // Border color: same as font color
    }
    appearBuf->appendf ("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re\n", borderWidth/2, width-borderWidth, height-borderWidth);
    if (doFill) {
      setColor(color, gTrue);
      appearBuf->append(doStroke ? "B\n" : "f\n");
    } else {
      appearBuf->append("S\n");
    }
  }

  // Setup text clipping
  const double textmargin = borderWidth * 2;
  const double textwidth = width - 2*textmargin;
  appearBuf->appendf ("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re W n\n", textmargin, textwidth, height - 2*textmargin);

  Object fontResDict;
  GfxFont *font = createAnnotDrawFont(xref, &fontResDict);

  // Set font state
  setColor(fontcolor, gTrue);
  appearBuf->appendf ("BT 1 0 0 1 {0:.2f} {1:.2f} Tm\n", textmargin, height - textmargin - fontsize * font->getDescent());
  appearBuf->appendf ("/AnnotDrawFont {0:.2f} Tf\n", fontsize);

  int i = 0;
  double xposPrev = 0;
  while (i < contents->getLength()) {
    GooString out;
    double linewidth, xpos;
    layoutText(contents, &out, &i, font, &linewidth, textwidth/fontsize, NULL, gFalse);
    linewidth *= fontsize;
    switch (quadding) {
    case quaddingCentered:
      xpos = (textwidth - linewidth) / 2;
      break;
    case quaddingRightJustified:
      xpos = textwidth - linewidth;
      break;
    default: // quaddingLeftJustified:
      xpos = 0;
      break;
    }
    appearBuf->appendf("{0:.2f} {1:.2f} Td\n", xpos - xposPrev, -fontsize);
    writeString(&out, appearBuf);
    appearBuf->append("Tj\n");
    xposPrev = xpos;
  }

  font->decRefCnt();
  delete fontcolor;
  appearBuf->append ("ET Q\n");

  double bbox[4];
  bbox[0] = bbox[1] = 0;
  bbox[2] = rect->x2 - rect->x1;
  bbox[3] = rect->y2 - rect->y1;

  if (ca == 1) {
    createForm(bbox, gFalse, &fontResDict, &appearance);
  } else {
    Object aStream, resDict;

    createForm(bbox, gTrue, &fontResDict, &aStream);
    delete appearBuf;

    appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
    createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
    createForm(bbox, gFalse, &resDict, &appearance);
  }
  delete appearBuf;
}

void AnnotFreeText::draw(Gfx *gfx, GBool printing) {
  Object obj;

  if (!isVisible (printing))
    return;

  annotLocker();
  if (appearance.isNull()) {
    generateFreeTextAppearance();
  }

  // draw the appearance stream
  appearance.fetch(gfx->getXRef(), &obj);
  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
                 rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
  obj.free();
}

// Before retrieving the res dict, regenerate the appearance stream if needed,
// because AnnotFreeText::draw needs to store font info in the res dict
Object *AnnotFreeText::getAppearanceResDict(Object *dest) {
  if (appearance.isNull()) {
    generateFreeTextAppearance();
  }
  return Annot::getAppearanceResDict(dest);
}

//------------------------------------------------------------------------
// AnnotLine
//------------------------------------------------------------------------

AnnotLine::AnnotLine(PDFDoc *docA, PDFRectangle *rect) :
    AnnotMarkup(docA, rect) {
  Object obj1;

  type = typeLine;
  annotObj.dictSet ("Subtype", obj1.initName ("Line"));

  initialize (docA, annotObj.getDict());
}

AnnotLine::AnnotLine(PDFDoc *docA, Dict *dict, Object *obj) :
    AnnotMarkup(docA, dict, obj) {
  type = typeLine;
  initialize(docA, dict);
}

AnnotLine::~AnnotLine() {
  delete coord1;
  delete coord2;

  if (interiorColor)
    delete interiorColor;

  if (measure)
    delete measure;
}

void AnnotLine::initialize(PDFDoc *docA, Dict *dict) {
  Object obj1;

  if (dict->lookup("L", &obj1)->isArray() && obj1.arrayGetLength() == 4) {
    Object obj2;
    double x1, y1, x2, y2;

    (obj1.arrayGet(0, &obj2)->isNum() ? x1 = obj2.getNum() : x1 = 0);
    obj2.free();
    (obj1.arrayGet(1, &obj2)->isNum() ? y1 = obj2.getNum() : y1 = 0);
    obj2.free();
    (obj1.arrayGet(2, &obj2)->isNum() ? x2 = obj2.getNum() : x2 = 0);
    obj2.free();
    (obj1.arrayGet(3, &obj2)->isNum() ? y2 = obj2.getNum() : y2 = 0);
    obj2.free();

    coord1 = new AnnotCoord(x1, y1);
    coord2 = new AnnotCoord(x2, y2);
  } else {
    coord1 = new AnnotCoord();
    coord2 = new AnnotCoord();
  }
  obj1.free();

  if (dict->lookup("LE", &obj1)->isArray() && obj1.arrayGetLength() == 2) {
    Object obj2;

    if(obj1.arrayGet(0, &obj2)->isString())
      startStyle = parseAnnotLineEndingStyle(obj2.getString());
    else
      startStyle = annotLineEndingNone;
    obj2.free();

    if(obj1.arrayGet(1, &obj2)->isString())
      endStyle = parseAnnotLineEndingStyle(obj2.getString());
    else
      endStyle = annotLineEndingNone;
    obj2.free();

  } else {
    startStyle = endStyle = annotLineEndingNone;
  }
  obj1.free();

  if (dict->lookup("IC", &obj1)->isArray()) {
    interiorColor = new AnnotColor(obj1.getArray());
  } else {
    interiorColor = NULL;
  }
  obj1.free();

  if (dict->lookup("LL", &obj1)->isNum()) {
    leaderLineLength = obj1.getNum();
  } else {
    leaderLineLength = 0;
  }
  obj1.free();

  if (dict->lookup("LLE", &obj1)->isNum()) {
    leaderLineExtension = obj1.getNum();

    if (leaderLineExtension < 0)
      leaderLineExtension = 0;
  } else {
    leaderLineExtension = 0;
  }
  obj1.free();

  if (dict->lookup("Cap", &obj1)->isBool()) {
    caption = obj1.getBool();
  } else {
    caption = gFalse;
  }
  obj1.free();

  if (dict->lookup("IT", &obj1)->isName()) {
    const char *intentName = obj1.getName();

    if(!strcmp(intentName, "LineArrow")) {
      intent = intentLineArrow;
    } else if(!strcmp(intentName, "LineDimension")) {
      intent = intentLineDimension;
    } else {
      intent = intentLineArrow;
    }
  } else {
    intent = intentLineArrow;
  }
  obj1.free();

  if (dict->lookup("LLO", &obj1)->isNum()) {
    leaderLineOffset = obj1.getNum();

    if (leaderLineOffset < 0)
      leaderLineOffset = 0;
  } else {
    leaderLineOffset = 0;
  }
  obj1.free();

  if (dict->lookup("CP", &obj1)->isName()) {
    const char *captionName = obj1.getName();

    if(!strcmp(captionName, "Inline")) {
      captionPos = captionPosInline;
    } else if(!strcmp(captionName, "Top")) {
      captionPos = captionPosTop;
    } else {
      captionPos = captionPosInline;
    }
  } else {
    captionPos = captionPosInline;
  }
  obj1.free();

  if (dict->lookup("Measure", &obj1)->isDict()) {
    measure = NULL;
  } else {
    measure = NULL;
  }
  obj1.free();

  if ((dict->lookup("CO", &obj1)->isArray()) && (obj1.arrayGetLength() == 2)) {
    Object obj2;

    (obj1.arrayGet(0, &obj2)->isNum() ? captionTextHorizontal = obj2.getNum() :
      captionTextHorizontal = 0);
    obj2.free();
    (obj1.arrayGet(1, &obj2)->isNum() ? captionTextVertical = obj2.getNum() :
      captionTextVertical = 0);
    obj2.free();
  } else {
    captionTextHorizontal = captionTextVertical = 0;
  }
  obj1.free();

  if (dict->lookup("BS", &obj1)->isDict()) {
    delete border;
    border = new AnnotBorderBS(obj1.getDict());
  } else if (!border) {
    border = new AnnotBorderBS();
  }
  obj1.free();
}

void AnnotLine::setContents(GooString *new_content) {
  Annot::setContents(new_content);
  if (caption)
    invalidateAppearance();
}

void AnnotLine::setVertices(double x1, double y1, double x2, double y2) {
  Object obj1, obj2;

  delete coord1;
  coord1 = new AnnotCoord(x1, y1);
  delete coord2;
  coord2 = new AnnotCoord(x2, y2);

  obj1.initArray(xref);
  obj1.arrayAdd( obj2.initReal(x1) );
  obj1.arrayAdd( obj2.initReal(y1) );
  obj1.arrayAdd( obj2.initReal(x2) );
  obj1.arrayAdd( obj2.initReal(y2) );

  update("L", &obj1);
  invalidateAppearance();
}

void AnnotLine::setStartEndStyle(AnnotLineEndingStyle start, AnnotLineEndingStyle end) {
  Object obj1, obj2;

  startStyle = start;
  endStyle = end;

  obj1.initArray(xref);
  obj1.arrayAdd( obj2.initName(convertAnnotLineEndingStyle( startStyle )) );
  obj1.arrayAdd( obj2.initName(convertAnnotLineEndingStyle( endStyle )) );

  update("LE", &obj1);
  invalidateAppearance();
}

void AnnotLine::setInteriorColor(AnnotColor *new_color) {
  delete interiorColor;

  if (new_color) {
    Object obj1;
    new_color->writeToObject(xref, &obj1);
    update ("IC", &obj1);
    interiorColor = new_color;
  } else {
    interiorColor = NULL;
  }
  invalidateAppearance();
}

void AnnotLine::setLeaderLineLength(double len) {
  Object obj1;

  leaderLineLength = len;
  obj1.initReal(len);
  update ("LL", &obj1);
  invalidateAppearance();
}

void AnnotLine::setLeaderLineExtension(double len) {
  Object obj1;

  leaderLineExtension = len;
  obj1.initReal(len);
  update ("LLE", &obj1);

  // LL is required if LLE is present
  obj1.initReal(leaderLineLength);
  update ("LL", &obj1);
  invalidateAppearance();
}

void AnnotLine::setCaption(bool new_cap) {
  Object obj1;

  caption = new_cap;
  obj1.initBool(new_cap);
  update ("Cap", &obj1);
  invalidateAppearance();
}

void AnnotLine::setIntent(AnnotLineIntent new_intent) {
  Object obj1;

  intent = new_intent;
  if (new_intent == intentLineArrow)
    obj1.initName("LineArrow");
  else // intentLineDimension
    obj1.initName("LineDimension");
  update ("IT", &obj1);
}

void AnnotLine::generateLineAppearance()
{
  double borderWidth, ca = opacity;

  appearBBox = new AnnotAppearanceBBox(rect);
  appearBuf = new GooString ();
  appearBuf->append ("q\n");
  if (color) {
    setColor(color, gFalse);
  }

  setLineStyleForBorder(border);
  borderWidth = border->getWidth();
  appearBBox->setBorderWidth(std::max(1., borderWidth));

  const double x1 = coord1->getX();
  const double y1 = coord1->getY();
  const double x2 = coord2->getX();
  const double y2 = coord2->getY();

  // Main segment length
  const double main_len = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));

  // Main segment becomes positive x direction, coord1 becomes (0,0)
  Matrix matr;
  const double angle = atan2(y2 - y1, x2 - x1);
  matr.m[0] = matr.m[3] = cos(angle);
  matr.m[1] = sin(angle);
  matr.m[2] = -matr.m[1];
  matr.m[4] = x1-rect->x1;
  matr.m[5] = y1-rect->y1;

  double tx, ty, captionwidth = 0, captionheight = 0;
  AnnotLineCaptionPos actualCaptionPos = captionPos;
  const double fontsize = 9;
  const double captionhmargin = 2; // Left and right margin (inline caption only)
  const double captionmaxwidth = main_len - 2 * captionhmargin;

  Object fontResDict;
  GfxFont *font;

  // Calculate caption width and height
  if (caption) {
    font = createAnnotDrawFont(xref, &fontResDict);
    int lines = 0;
    int i = 0;
    while (i < contents->getLength()) {
      GooString out;
      double linewidth;
      layoutText(contents, &out, &i, font, &linewidth, 0, NULL, gFalse);
      linewidth *= fontsize;
      if (linewidth > captionwidth) {
        captionwidth = linewidth;
      }
      ++lines;
    }
    captionheight = lines * fontsize;
    // If text is longer than available space, turn into captionPosTop
    if (captionwidth > captionmaxwidth) {
      actualCaptionPos = captionPosTop;
    }
  } else {
    fontResDict.initNull();
    font = NULL;
  }

  // Draw main segment
  matr.transform (0, leaderLineLength, &tx, &ty);
  appearBuf->appendf ("{0:.2f} {1:.2f} m\n", tx, ty);
  appearBBox->extendTo (tx, ty);

  if (captionwidth != 0 && actualCaptionPos == captionPosInline) { // Break in the middle
    matr.transform ((main_len-captionwidth)/2 - captionhmargin, leaderLineLength, &tx, &ty);
    appearBuf->appendf ("{0:.2f} {1:.2f} l S\n", tx, ty);

    matr.transform ((main_len+captionwidth)/2 + captionhmargin, leaderLineLength, &tx, &ty);
    appearBuf->appendf ("{0:.2f} {1:.2f} m\n", tx, ty);
  }

  matr.transform (main_len, leaderLineLength, &tx, &ty);
  appearBuf->appendf ("{0:.2f} {1:.2f} l S\n", tx, ty);
  appearBBox->extendTo (tx, ty);

  // TODO: Line endings

  // Draw caption text
  if (caption) {
    double tlx = (main_len - captionwidth) / 2, tly; // Top-left coords
    if (actualCaptionPos == captionPosInline) {
      tly = leaderLineLength + captionheight / 2;
    } else {
      tly = leaderLineLength + captionheight + 2*borderWidth;
    }

    tlx += captionTextHorizontal;
    tly += captionTextVertical;

    // Adjust bounding box
    matr.transform (tlx, tly-captionheight, &tx, &ty);
    appearBBox->extendTo (tx, ty);
    matr.transform (tlx+captionwidth, tly-captionheight, &tx, &ty);
    appearBBox->extendTo (tx, ty);
    matr.transform (tlx+captionwidth, tly, &tx, &ty);
    appearBBox->extendTo (tx, ty);
    matr.transform (tlx, tly, &tx, &ty);
    appearBBox->extendTo (tx, ty);

    // Setup text state (reusing transformed top-left coord)
    appearBuf->appendf ("0 g BT /AnnotDrawFont {0:.2f} Tf\n", fontsize); // Font color: black
    appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} Tm\n",
                        matr.m[0], matr.m[1], matr.m[2], matr.m[3], tx, ty);
    appearBuf->appendf ("0 {0:.2f} Td\n",  -fontsize * font->getDescent());
    // Draw text
    int i = 0;
    double xposPrev = 0;
    while (i < contents->getLength()) {
      GooString out;
      double linewidth, xpos;
      layoutText(contents, &out, &i, font, &linewidth, 0, NULL, gFalse);
      linewidth *= fontsize;
      xpos = (captionwidth - linewidth) / 2;
      appearBuf->appendf("{0:.2f} {1:.2f} Td\n", xpos - xposPrev, -fontsize);
      writeString(&out, appearBuf);
      appearBuf->append ("Tj\n");
      xposPrev = xpos;
    }
    appearBuf->append ("ET\n");
    font->decRefCnt();
  }

  // Draw leader lines
  double ll_len = fabs(leaderLineLength) + leaderLineExtension;
  double sign = leaderLineLength >= 0 ? 1 : -1;
  if (ll_len != 0) {
    matr.transform (0, 0, &tx, &ty);
    appearBuf->appendf ("{0:.2f} {1:.2f} m\n", tx, ty);
    appearBBox->extendTo (tx, ty);
    matr.transform (0, sign*ll_len, &tx, &ty);
    appearBuf->appendf ("{0:.2f} {1:.2f} l S\n", tx, ty);
    appearBBox->extendTo (tx, ty);

    matr.transform (main_len, 0, &tx, &ty);
    appearBuf->appendf ("{0:.2f} {1:.2f} m\n", tx, ty);
    appearBBox->extendTo (tx, ty);
    matr.transform (main_len, sign*ll_len, &tx, &ty);
    appearBuf->appendf ("{0:.2f} {1:.2f} l S\n", tx, ty);
    appearBBox->extendTo (tx, ty);
  }

  appearBuf->append ("Q\n");

  double bbox[4];
  appearBBox->getBBoxRect(bbox);
  if (ca == 1) {
    createForm(bbox, gFalse, &fontResDict, &appearance);
  } else {
    Object aStream, resDict;

    createForm(bbox, gTrue, &fontResDict, &aStream);
    delete appearBuf;

    appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
    createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
    createForm(bbox, gFalse, &resDict, &appearance);
  }
  delete appearBuf;
}

void AnnotLine::draw(Gfx *gfx, GBool printing) {
  Object obj;

  if (!isVisible (printing))
    return;

  annotLocker();
  if (appearance.isNull()) {
    generateLineAppearance();
  }

  // draw the appearance stream
  appearance.fetch(gfx->getXRef(), &obj);
  if (appearBBox) {
    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
                   appearBBox->getPageXMin(), appearBBox->getPageYMin(),
                   appearBBox->getPageXMax(), appearBBox->getPageYMax(),
                   getRotation());
  } else {
    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
                   rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
  }
  obj.free();
}

// Before retrieving the res dict, regenerate the appearance stream if needed,
// because AnnotLine::draw may need to store font info in the res dict
Object *AnnotLine::getAppearanceResDict(Object *dest) {
  if (appearance.isNull()) {
    generateLineAppearance();
  }
  return Annot::getAppearanceResDict(dest);
}

//------------------------------------------------------------------------
// AnnotTextMarkup
//------------------------------------------------------------------------
AnnotTextMarkup::AnnotTextMarkup(PDFDoc *docA, PDFRectangle *rect, AnnotSubtype subType) :
    AnnotMarkup(docA, rect) {
  Object obj1;

  switch (subType) {
    case typeHighlight:
      annotObj.dictSet ("Subtype", obj1.initName ("Highlight"));
      break;
    case typeUnderline:
      annotObj.dictSet ("Subtype", obj1.initName ("Underline"));
      break;
    case typeSquiggly:
      annotObj.dictSet ("Subtype", obj1.initName ("Squiggly"));
      break;
    case typeStrikeOut:
      annotObj.dictSet ("Subtype", obj1.initName ("StrikeOut"));
      break;
    default:
      assert (0 && "Invalid subtype for AnnotTextMarkup\n");
  }

  // Store dummy quadrilateral with null coordinates
  Object obj2, obj3;
  obj2.initArray (doc->getXRef());
  for (int i = 0; i < 4*2; ++i) {
    obj2.arrayAdd (obj3.initReal (0));
  }
  annotObj.dictSet ("QuadPoints", &obj2);

  initialize(docA, annotObj.getDict());
}

AnnotTextMarkup::AnnotTextMarkup(PDFDoc *docA, Dict *dict, Object *obj) :
  AnnotMarkup(docA, dict, obj) {
  // the real type will be read in initialize()
  type = typeHighlight;
  initialize(docA, dict);
}

void AnnotTextMarkup::initialize(PDFDoc *docA, Dict *dict) {
  Object obj1;

  if (dict->lookup("Subtype", &obj1)->isName()) {
    GooString typeName(obj1.getName());
    if (!typeName.cmp("Highlight")) {
      type = typeHighlight;
    } else if (!typeName.cmp("Underline")) {
      type = typeUnderline;
    } else if (!typeName.cmp("Squiggly")) {
      type = typeSquiggly;
    } else if (!typeName.cmp("StrikeOut")) {
      type = typeStrikeOut;
    }
  }
  obj1.free();

  if(dict->lookup("QuadPoints", &obj1)->isArray()) {
    quadrilaterals = new AnnotQuadrilaterals(obj1.getArray(), rect);
  } else {
    error(errSyntaxError, -1, "Bad Annot Text Markup QuadPoints");
    quadrilaterals = NULL;
    ok = gFalse;
  }
  obj1.free();
}

AnnotTextMarkup::~AnnotTextMarkup() {
  if(quadrilaterals) {
    delete quadrilaterals;
  }
}

void AnnotTextMarkup::setType(AnnotSubtype new_type) {
  Object obj1;

  switch (new_type) {
    case typeHighlight:
      obj1.initName("Highlight");
      break;
    case typeUnderline:
      obj1.initName("Underline");
      break;
    case typeSquiggly:
      obj1.initName("Squiggly");
      break;
    case typeStrikeOut:
      obj1.initName("StrikeOut");
      break;
    default:
      assert(!"Invalid subtype");
  }

  type = new_type;
  update("Subtype", &obj1);
  invalidateAppearance();
}

void AnnotTextMarkup::setQuadrilaterals(AnnotQuadrilaterals *quadPoints) {
  Object obj1, obj2;
  obj1.initArray (xref);

  for (int i = 0; i < quadPoints->getQuadrilateralsLength(); ++i) {
    obj1.arrayAdd (obj2.initReal (quadPoints->getX1(i)));
    obj1.arrayAdd (obj2.initReal (quadPoints->getY1(i)));
    obj1.arrayAdd (obj2.initReal (quadPoints->getX2(i)));
    obj1.arrayAdd (obj2.initReal (quadPoints->getY2(i)));
    obj1.arrayAdd (obj2.initReal (quadPoints->getX3(i)));
    obj1.arrayAdd (obj2.initReal (quadPoints->getY3(i)));
    obj1.arrayAdd (obj2.initReal (quadPoints->getX4(i)));
    obj1.arrayAdd (obj2.initReal (quadPoints->getY4(i)));
  }

  delete quadrilaterals;
  quadrilaterals = new AnnotQuadrilaterals(obj1.getArray(), rect);

  annotObj.dictSet ("QuadPoints", &obj1);
  invalidateAppearance();
}

void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) {
  Object obj;
  double ca = 1;
  int i;
  Object obj1, obj2;

  if (!isVisible (printing))
    return;

  annotLocker();
  if (appearance.isNull() || type == typeHighlight) {
    GBool blendMultiply = gTrue;
    ca = opacity;

    appearBuf = new GooString ();
    appearBuf->append ("q\n");

    /* Adjust BBox */
    delete appearBBox;
    appearBBox = new AnnotAppearanceBBox(rect);
    for (i = 0; i < quadrilaterals->getQuadrilateralsLength(); ++i) {
      appearBBox->extendTo (quadrilaterals->getX1(i) - rect->x1, quadrilaterals->getY1(i) - rect->y1);
      appearBBox->extendTo (quadrilaterals->getX2(i) - rect->x1, quadrilaterals->getY2(i) - rect->y1);
      appearBBox->extendTo (quadrilaterals->getX3(i) - rect->x1, quadrilaterals->getY3(i) - rect->y1);
      appearBBox->extendTo (quadrilaterals->getX4(i) - rect->x1, quadrilaterals->getY4(i) - rect->y1);
    }

    switch (type) {
    case typeUnderline:
      if (color) {
        setColor(color, gFalse);
      }
      appearBuf->append ("[] 0 d 1 w\n");

      for (i = 0; i < quadrilaterals->getQuadrilateralsLength(); ++i) {
	double x3, y3, x4, y4;

	x3 = quadrilaterals->getX3(i);
	y3 = quadrilaterals->getY3(i);
	x4 = quadrilaterals->getX4(i);
	y4 = quadrilaterals->getY4(i);

	appearBuf->appendf ("{0:.2f} {1:.2f} m\n", x3, y3);
	appearBuf->appendf ("{0:.2f} {1:.2f} l\n", x4, y4);
	appearBuf->append ("S\n");
      }
      break;
    case typeStrikeOut:
      if (color) {
        setColor(color, gFalse);
      }
      blendMultiply = gFalse;
      appearBuf->append ("[] 0 d 1 w\n");

      for (i = 0; i < quadrilaterals->getQuadrilateralsLength(); ++i) {
	double x1, y1, x2, y2;
	double x3, y3, x4, y4;

	x1 = quadrilaterals->getX1(i);
	y1 = quadrilaterals->getY1(i);
	x2 = quadrilaterals->getX2(i);
	y2 = quadrilaterals->getY2(i);

	x3 = quadrilaterals->getX3(i);
	y3 = quadrilaterals->getY3(i);
	x4 = quadrilaterals->getX4(i);
	y4 = quadrilaterals->getY4(i);

	appearBuf->appendf ("{0:.2f} {1:.2f} m\n", (x1+x3)/2., (y1+y3)/2.);
	appearBuf->appendf ("{0:.2f} {1:.2f} l\n", (x2+x4)/2., (y2+y4)/2.);
	appearBuf->append ("S\n");
      }
      break;
    case typeSquiggly:
      if (color) {
        setColor(color, gFalse);
      }
      appearBuf->append ("[] 0 d 1 w\n");

      for (i = 0; i < quadrilaterals->getQuadrilateralsLength(); ++i) {
        double x1, y1, x2, y3;
        double h6;

        x1 = quadrilaterals->getX1(i);
        y1 = quadrilaterals->getY1(i);
        x2 = quadrilaterals->getX2(i);
        y3 = quadrilaterals->getY3(i);
        h6 = (y1 - y3) / 6.0;

        appearBuf->appendf ("{0:.2f} {1:.2f} m\n", x1, y3+h6);
        bool down = false;
        do {
          down = !down; // Zigzag line
          x1 += 2;
          appearBuf->appendf ("{0:.2f} {1:.2f} l\n", x1, y3 + (down ? 0 : h6));
        } while (x1 < x2);
        appearBuf->append ("S\n");
      }
      break;
    default:
    case typeHighlight:
      appearance.free();

      if (color)
        setColor(color, gTrue);

      double biggestBorder = 0;
      for (i = 0; i < quadrilaterals->getQuadrilateralsLength(); ++i) {
        double x1, y1, x2, y2, x3, y3, x4, y4;
	double h4;

	x1 = quadrilaterals->getX1(i);
	y1 = quadrilaterals->getY1(i);
	x2 = quadrilaterals->getX2(i);
	y2 = quadrilaterals->getY2(i);
	x3 = quadrilaterals->getX3(i);
	y3 = quadrilaterals->getY3(i);
	x4 = quadrilaterals->getX4(i);
	y4 = quadrilaterals->getY4(i);
	h4 = fabs(y1 - y3) / 4.0;

	if (h4 > biggestBorder) {
	  biggestBorder = h4;
	}

	appearBuf->appendf ("{0:.2f} {1:.2f} m\n", x3, y3);
	appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
			    x3 - h4, y3 + h4, x1 - h4, y1 - h4, x1, y1);
	appearBuf->appendf ("{0:.2f} {1:.2f} l\n", x2, y2);
	appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
			    x2 + h4, y2 - h4, x4 + h4, y4 + h4, x4, y4);
	appearBuf->append ("f\n");
      }
      appearBBox->setBorderWidth(biggestBorder);
      break;
    }
    appearBuf->append ("Q\n");

    Object aStream, resDict;
    double bbox[4];
    bbox[0] = appearBBox->getPageXMin();
    bbox[1] = appearBBox->getPageYMin();
    bbox[2] = appearBBox->getPageXMax();
    bbox[3] = appearBBox->getPageYMax();
    createForm(bbox, gTrue, NULL, &aStream);
    delete appearBuf;

    appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
    createResourcesDict("Fm0", &aStream, "GS0", 1, blendMultiply ? "Multiply" : NULL, &resDict);
    if (ca == 1) {
      createForm(bbox, gFalse, &resDict, &appearance);
    } else {
      createForm(bbox, gTrue, &resDict, &aStream);
      delete appearBuf;

      appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
      createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
      createForm(bbox, gFalse, &resDict, &appearance);
    }
    delete appearBuf;
  }

  // draw the appearance stream
  appearance.fetch(gfx->getXRef(), &obj);
  if (appearBBox) {
    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
                   appearBBox->getPageXMin(), appearBBox->getPageYMin(),
                   appearBBox->getPageXMax(), appearBBox->getPageYMax(),
                   getRotation());
  } else {
    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
                   rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
  }
  obj.free();
}

//------------------------------------------------------------------------
// AnnotWidget
//------------------------------------------------------------------------

AnnotWidget::AnnotWidget(PDFDoc *docA, Dict *dict, Object *obj) :
    Annot(docA, dict, obj) {
  type = typeWidget;
  field = NULL;
  initialize(docA, dict);
}

AnnotWidget::AnnotWidget(PDFDoc *docA, Dict *dict, Object *obj, FormField *fieldA) :
    Annot(docA, dict, obj) {
  type = typeWidget;
  field = fieldA;
  initialize(docA, dict);
}

AnnotWidget::~AnnotWidget() {
  if (appearCharacs)
    delete appearCharacs;
  
  if (action)
    delete action;

  additionalActions.free();

  if (parent)
    delete parent;
}

void AnnotWidget::initialize(PDFDoc *docA, Dict *dict) {
  Object obj1;

  form = doc->getCatalog()->getForm();

  if(dict->lookup("H", &obj1)->isName()) {
    const char *modeName = obj1.getName();

    if(!strcmp(modeName, "N")) {
      mode = highlightModeNone;
    } else if(!strcmp(modeName, "O")) {
      mode = highlightModeOutline;
    } else if(!strcmp(modeName, "P") || !strcmp(modeName, "T")) {
      mode = highlightModePush;
    } else {
      mode = highlightModeInvert;
    }
  } else {
    mode = highlightModeInvert;
  }
  obj1.free();

  if(dict->lookup("MK", &obj1)->isDict()) {
    appearCharacs = new AnnotAppearanceCharacs(obj1.getDict());
  } else {
    appearCharacs = NULL;
  }
  obj1.free();

  action = NULL;
  if(dict->lookup("A", &obj1)->isDict()) {
    action = LinkAction::parseAction(&obj1, doc->getCatalog()->getBaseURI());
  }
  obj1.free();

  dict->lookupNF("AA", &additionalActions);

  if(dict->lookup("Parent", &obj1)->isDict()) {
    parent = NULL;
  } else {
    parent = NULL;
  }
  obj1.free();

  if (dict->lookup("BS", &obj1)->isDict()) {
    delete border;
    border = new AnnotBorderBS(obj1.getDict());
  }
  obj1.free();

  updatedAppearanceStream.num = updatedAppearanceStream.gen = -1;
}

LinkAction* AnnotWidget::getAdditionalAction(AdditionalActionsType type)
{
  return ::getAdditionalAction(type, &additionalActions, doc);
}

LinkAction* AnnotWidget::getFormAdditionalAction(FormAdditionalActionsType type)
{
  return ::getFormAdditionalAction(type, &additionalActions, doc);
}

// Grand unified handler for preparing text strings to be drawn into form
// fields.  Takes as input a text string (in PDFDocEncoding or UTF-16).
// Converts some or all of this string to the appropriate encoding for the
// specified font, and computes the width of the text.  Can optionally stop
// converting when a specified width has been reached, to perform line-breaking
// for multi-line fields.
//
// Parameters:
//   text: input text string to convert
//   outBuf: buffer for writing re-encoded string
//   i: index at which to start converting; will be updated to point just after
//      last character processed
//   font: the font which will be used for display
//   width: computed width (unscaled by font size) will be stored here
//   widthLimit: if non-zero, stop converting to keep width under this value
//      (should be scaled down by font size)
//   charCount: count of number of characters will be stored here
//   noReencode: if set, do not try to translate the character encoding
//      (useful for Zapf Dingbats or other unusual encodings)
//      can only be used with simple fonts, not CID-keyed fonts
//
// TODO: Handle surrogate pairs in UTF-16.
//       Should be able to generate output for any CID-keyed font.
//       Doesn't handle vertical fonts--should it?
void Annot::layoutText(GooString *text, GooString *outBuf, int *i,
                             GfxFont *font, double *width, double widthLimit,
                             int *charCount, GBool noReencode)
{
  CharCode c;
  Unicode uChar, *uAux;
  double w = 0.0;
  int uLen, n;
  double dx, dy, ox, oy;
  if (!text) {
    return;
  }
  GBool unicode = text->hasUnicodeMarker();
  GBool spacePrev;              // previous character was a space

  // State for backtracking when more text has been processed than fits within
  // widthLimit.  We track for both input (text) and output (outBuf) the offset
  // to the first character to discard.
  //
  // We keep track of several points:
  //   1 - end of previous completed word which fits
  //   2 - previous character which fit
  int last_i1, last_i2, last_o1, last_o2;

  if (unicode && text->getLength() % 2 != 0) {
    error(errSyntaxError, -1, "AnnotWidget::layoutText, bad unicode string");
    return;
  }

  // skip Unicode marker on string if needed
  if (unicode && *i == 0)
    *i = 2;

  // Start decoding and copying characters, until either:
  //   we reach the end of the string
  //   we reach the maximum width
  //   we reach a newline character
  // As we copy characters, keep track of the last full word to fit, so that we
  // can backtrack if we exceed the maximum width.
  last_i1 = last_i2 = *i;
  last_o1 = last_o2 = 0;
  spacePrev = gFalse;
  outBuf->clear();

  while (*i < text->getLength()) {
    last_i2 = *i;
    last_o2 = outBuf->getLength();

    if (unicode) {
      uChar = (unsigned char)(text->getChar(*i)) << 8;
      uChar += (unsigned char)(text->getChar(*i + 1));
      *i += 2;
    } else {
      if (noReencode)
        uChar = text->getChar(*i) & 0xff;
      else
        uChar = pdfDocEncoding[text->getChar(*i) & 0xff];
      *i += 1;
    }

    // Explicit line break?
    if (uChar == '\r' || uChar == '\n') {
      // Treat a <CR><LF> sequence as a single line break
      if (uChar == '\r' && *i < text->getLength()) {
        if (unicode && text->getChar(*i) == '\0'
            && text->getChar(*i + 1) == '\n')
          *i += 2;
        else if (!unicode && text->getChar(*i) == '\n')
          *i += 1;
      }

      break;
    }

    if (noReencode) {
      outBuf->append(uChar);
    } else {
      CharCodeToUnicode *ccToUnicode = font->getToUnicode();
      if (!ccToUnicode) {
        // This assumes an identity CMap.
        outBuf->append((uChar >> 8) & 0xff);
        outBuf->append(uChar & 0xff);
      } else if (ccToUnicode->mapToCharCode(&uChar, &c, 1)) {
        ccToUnicode->decRefCnt();
        if (font->isCIDFont()) {
          // TODO: This assumes an identity CMap.  It should be extended to
          // handle the general case.
          outBuf->append((c >> 8) & 0xff);
          outBuf->append(c & 0xff);
        } else {
          // 8-bit font
          outBuf->append(c);
        }
      } else {
        ccToUnicode->decRefCnt();
        error(errSyntaxError, -1, "AnnotWidget::layoutText, cannot convert U+{0:04uX}", uChar);
      }
    }

    // If we see a space, then we have a linebreak opportunity.
    if (uChar == ' ') {
      last_i1 = *i;
      if (!spacePrev)
        last_o1 = last_o2;
      spacePrev = gTrue;
    } else {
      spacePrev = gFalse;
    }

    // Compute width of character just output
    if (outBuf->getLength() > last_o2) {
      dx = 0.0;
      font->getNextChar(outBuf->getCString() + last_o2,
                        outBuf->getLength() - last_o2,
                        &c, &uAux, &uLen, &dx, &dy, &ox, &oy);
      w += dx;
    }

    // Current line over-full now?
    if (widthLimit > 0.0 && w > widthLimit) {
      if (last_o1 > 0) {
        // Back up to the previous word which fit, if there was a previous
        // word.
        *i = last_i1;
        outBuf->del(last_o1, outBuf->getLength() - last_o1);
      } else if (last_o2 > 0) {
        // Otherwise, back up to the previous character (in the only word on
        // this line)
        *i = last_i2;
        outBuf->del(last_o2, outBuf->getLength() - last_o2);
      } else {
        // Otherwise, we were trying to fit the first character; include it
        // anyway even if it overflows the space--no updates to make.
      }
      break;
    }
  }

  // If splitting input into lines because we reached the width limit, then
  // consume any remaining trailing spaces that would go on this line from the
  // input.  If in doing so we reach a newline, consume that also.  This code
  // won't run if we stopped at a newline above, since in that case w <=
  // widthLimit still.
  if (widthLimit > 0.0 && w > widthLimit) {
    if (unicode) {
      while (*i < text->getLength()
             && text->getChar(*i) == '\0' && text->getChar(*i + 1) == ' ')
        *i += 2;
      if (*i < text->getLength()
          && text->getChar(*i) == '\0' && text->getChar(*i + 1) == '\r')
        *i += 2;
      if (*i < text->getLength()
          && text->getChar(*i) == '\0' && text->getChar(*i + 1) == '\n')
        *i += 2;
    } else {
      while (*i < text->getLength() && text->getChar(*i) == ' ')
        *i += 1;
      if (*i < text->getLength() && text->getChar(*i) == '\r')
        *i += 1;
      if (*i < text->getLength() && text->getChar(*i) == '\n')
        *i += 1;
    }
  }

  // Compute the actual width and character count of the final string, based on
  // breakpoint, if this information is requested by the caller.
  if (width != NULL || charCount != NULL) {
    char *s = outBuf->getCString();
    int len = outBuf->getLength();

    if (width != NULL)
      *width = 0.0;
    if (charCount != NULL)
      *charCount = 0;

    while (len > 0) {
      dx = 0.0;
      n = font->getNextChar(s, len, &c, &uAux, &uLen, &dx, &dy, &ox, &oy);

      if (n == 0) {
        break;
      }

      if (width != NULL)
        *width += dx;
      if (charCount != NULL)
        *charCount += 1;

      s += n;
      len -= n;
    }
  }
}

// Copy the given string to appearBuf, adding parentheses around it and
// escaping characters as appropriate.
void Annot::writeString(GooString *str, GooString *appearBuf)
{
  char c;
  int i;

  appearBuf->append('(');

  for (i = 0; i < str->getLength(); ++i) {
    c = str->getChar(i);
    if (c == '(' || c == ')' || c == '\\') {
      appearBuf->append('\\');
      appearBuf->append(c);
    } else if (c < 0x20) {
      appearBuf->appendf("\\{0:03o}", (unsigned char)c);
    } else {
      appearBuf->append(c);
    }
  }

  appearBuf->append(')');
}

// Draw the variable text or caption for a field.
void AnnotWidget::drawText(GooString *text, GooString *da, GfxResources *resources,
    GBool multiline, int comb, int quadding,
    GBool txField, GBool forceZapfDingbats,
    GBool password) {
  GooList *daToks;
  GooString *tok, *convertedText;
  GfxFont *font;
  double dx, dy;
  double fontSize, fontSize2, borderWidth, x, xPrev, y, w, wMax;
  int tfPos, tmPos, i, j;
  int rot;
  GBool freeText = gFalse;      // true if text should be freed before return
  GBool freeFont = gFalse;

  //~ if there is no MK entry, this should use the existing content stream,
  //~ and only replace the marked content portion of it
  //~ (this is only relevant for Tx fields)
  
  // parse the default appearance string
  tfPos = tmPos = -1;
  if (da) {
    daToks = new GooList();
    i = 0;
    while (i < da->getLength()) {
      while (i < da->getLength() && Lexer::isSpace(da->getChar(i))) {
        ++i;
      }
      if (i < da->getLength()) {
        for (j = i + 1;
            j < da->getLength() && !Lexer::isSpace(da->getChar(j));
            ++j) ;
        daToks->append(new GooString(da, i, j - i));
        i = j;
      }
    }
    for (i = 2; i < daToks->getLength(); ++i) {
      if (i >= 2 && !((GooString *)daToks->get(i))->cmp("Tf")) {
        tfPos = i - 2;
      } else if (i >= 6 && !((GooString *)daToks->get(i))->cmp("Tm")) {
        tmPos = i - 6;
      }
    }
  } else {
    daToks = NULL;
  }

  // force ZapfDingbats
  if (forceZapfDingbats) {
    if (tfPos >= 0) {
      tok = (GooString *)daToks->get(tfPos);
      if (tok->cmp("/ZaDb")) {
        tok->clear();
        tok->append("/ZaDb");
      }
    }
  }
  // get the font and font size
  font = NULL;
  fontSize = 0;
  if (tfPos >= 0) {
    tok = (GooString *)daToks->get(tfPos);
    if (tok->getLength() >= 1 && tok->getChar(0) == '/') {
      if (!resources || !(font = resources->lookupFont(tok->getCString() + 1))) {
        if (forceZapfDingbats) {
          // We are forcing ZaDb but the font does not exist
          // so create a fake one
          Ref r; // dummy Ref, it's not used at all in this codepath
          r.num = -1;
          r.gen = -1;
          Dict *d = new Dict(xref);
          font = new Gfx8BitFont(xref, "ZaDb", r, new GooString("ZapfDingbats"), fontType1, r, d);
          delete d;
          freeFont = gTrue;
          addDingbatsResource = gTrue;
        } else {
          error(errSyntaxError, -1, "Unknown font in field's DA string");
        }
      }
    } else {
      error(errSyntaxError, -1, "Invalid font name in 'Tf' operator in field's DA string");
    }
    tok = (GooString *)daToks->get(tfPos + 1);
    fontSize = gatof(tok->getCString());
  } else {
    error(errSyntaxError, -1, "Missing 'Tf' operator in field's DA string");
  }
  if (!font) {
    if (daToks) {
      deleteGooList(daToks, GooString);
    }
    return;
  }

  // get the border width
  borderWidth = border ? border->getWidth() : 0;

  // for a password field, replace all characters with asterisks
  if (password) {
    int len;
    if (text->hasUnicodeMarker())
      len = (text->getLength() - 2) / 2;
    else
      len = text->getLength();

    text = new GooString;
    for (i = 0; i < len; ++i)
      text->append('*');
    freeText = gTrue;
  }

  convertedText = new GooString;

  // setup
  if (txField) {
    appearBuf->append("/Tx BMC\n");
  }
  appearBuf->append("q\n");
  rot = appearCharacs ? appearCharacs->getRotation() : 0;
  switch (rot) {
  case 90:
    appearBuf->appendf("0 1 -1 0 {0:.2f} 0 cm\n", rect->x2 - rect->x1);
    dx = rect->y2 - rect->y1;
    dy = rect->x2 - rect->x1;
    break;
  case 180:
    appearBuf->appendf("-1 0 0 -1 {0:.2f} {1:.2f} cm\n",
		       rect->x2 - rect->x1, rect->y2 - rect->y1);
    dx = rect->x2 - rect->y2;
    dy = rect->y2 - rect->y1;
    break;
  case 270:
    appearBuf->appendf("0 -1 1 0 0 {0:.2f} cm\n", rect->y2 - rect->y1);
    dx = rect->y2 - rect->y1;
    dy = rect->x2 - rect->x1;
    break;
  default: // assume rot == 0
    dx = rect->x2 - rect->x1;
    dy = rect->y2 - rect->y1;
    break;
  }
  appearBuf->append("BT\n");
  // multi-line text
  if (multiline) {
    // note: the comb flag is ignored in multiline mode

    wMax = dx - 2 * borderWidth - 4;

    // compute font autosize
    if (fontSize == 0) {
      for (fontSize = 20; fontSize > 1; --fontSize) {
        y = dy - 3;
        i = 0;
        while (i < text->getLength()) {
          layoutText(text, convertedText, &i, font, &w, wMax / fontSize, NULL,
                     forceZapfDingbats);
          y -= fontSize;
        }
        // approximate the descender for the last line
        if (y >= 0.33 * fontSize) {
          break;
        }
      }
      if (tfPos >= 0) {
        tok = (GooString *)daToks->get(tfPos + 1);
        tok->clear();
        tok->appendf("{0:.2f}", fontSize);
      }
    }

    // starting y coordinate
    // (note: each line of text starts with a Td operator that moves
    // down a line)
    y = dy - 3;

    // set the font matrix
    if (tmPos >= 0) {
      tok = (GooString *)daToks->get(tmPos + 4);
      tok->clear();
      tok->append('0');
      tok = (GooString *)daToks->get(tmPos + 5);
      tok->clear();
      tok->appendf("{0:.2f}", y);
    }

    // write the DA string
    if (daToks) {
      for (i = 0; i < daToks->getLength(); ++i) {
        appearBuf->append((GooString *)daToks->get(i))->append(' ');
      }
    }

    // write the font matrix (if not part of the DA string)
    if (tmPos < 0) {
      appearBuf->appendf("1 0 0 1 0 {0:.2f} Tm\n", y);
    }

    // write a series of lines of text
    i = 0;
    xPrev = 0;
    while (i < text->getLength()) {
      layoutText(text, convertedText, &i, font, &w, wMax / fontSize, NULL,
                 forceZapfDingbats);
      w *= fontSize;

      // compute text start position
      switch (quadding) {
      case quaddingLeftJustified:
      default:
        x = borderWidth + 2;
        break;
      case quaddingCentered:
        x = (dx - w) / 2;
        break;
      case quaddingRightJustified:
        x = dx - borderWidth - 2 - w;
        break;
      }

      // draw the line
      appearBuf->appendf("{0:.2f} {1:.2f} Td\n", x - xPrev, -fontSize);
      writeString(convertedText, appearBuf);
      appearBuf->append(" Tj\n");

      // next line
      xPrev = x;
    }

    // single-line text
  } else {
    //~ replace newlines with spaces? - what does Acrobat do?

    // comb formatting
    if (comb > 0) {
      int charCount;

      // compute comb spacing
      w = (dx - 2 * borderWidth) / comb;

      // compute font autosize
      if (fontSize == 0) {
        fontSize = dy - 2 * borderWidth;
        if (w < fontSize) {
          fontSize = w;
        }
        fontSize = floor(fontSize);
        if (tfPos >= 0) {
          tok = (GooString *)daToks->get(tfPos + 1);
          tok->clear();
          tok->appendf("{0:.2f}", fontSize);
        }
      }

      i = 0;
      layoutText(text, convertedText, &i, font, NULL, 0.0, &charCount,
                 forceZapfDingbats);
      if (charCount > comb)
        charCount = comb;

      // compute starting text cell
      switch (quadding) {
      case quaddingLeftJustified:
      default:
          x = borderWidth;
        break;
      case quaddingCentered:
        x = borderWidth + (comb - charCount) / 2 * w;
        break;
      case quaddingRightJustified:
        x = borderWidth + (comb - charCount) * w;
        break;
      }
      y = 0.5 * dy - 0.4 * fontSize;

      // set the font matrix
      if (tmPos >= 0) {
        tok = (GooString *)daToks->get(tmPos + 4);
        tok->clear();
        tok->appendf("{0:.2f}", x);
        tok = (GooString *)daToks->get(tmPos + 5);
        tok->clear();
        tok->appendf("{0:.2f}", y);
      }

      // write the DA string
      if (daToks) {
        for (i = 0; i < daToks->getLength(); ++i) {
          appearBuf->append((GooString *)daToks->get(i))->append(' ');
        }
      }

      // write the font matrix (if not part of the DA string)
      if (tmPos < 0) {
        appearBuf->appendf("1 0 0 1 {0:.2f} {1:.2f} Tm\n", x, y);
      }

      // write the text string
      char *s = convertedText->getCString();
      int len = convertedText->getLength();
      i = 0;
      xPrev = w;                // so that first character is placed properly
      while (i < comb && len > 0) {
        CharCode code;
        Unicode *uAux;
        int uLen, n;
        double dx, dy, ox, oy;

        dx = 0.0;
        n = font->getNextChar(s, len, &code, &uAux, &uLen, &dx, &dy, &ox, &oy);
        dx *= fontSize;

        // center each character within its cell, by advancing the text
        // position the appropriate amount relative to the start of the
        // previous character
        x = 0.5 * (w - dx);
        appearBuf->appendf("{0:.2f} 0 Td\n", x - xPrev + w);

        GooString *charBuf = new GooString(s, n);
        writeString(charBuf, appearBuf);
        appearBuf->append(" Tj\n");
        delete charBuf;

        i++;
        s += n;
        len -= n;
        xPrev = x;
      }

      // regular (non-comb) formatting
    } else {
      i = 0;
      layoutText(text, convertedText, &i, font, &w, 0.0, NULL,
                 forceZapfDingbats);

      // compute font autosize
      if (fontSize == 0) {
        fontSize = dy - 2 * borderWidth;
        fontSize2 = (dx - 4 - 2 * borderWidth) / w;
        if (fontSize2 < fontSize) {
          fontSize = fontSize2;
        }
        fontSize = floor(fontSize);
        if (tfPos >= 0) {
          tok = (GooString *)daToks->get(tfPos + 1);
          tok->clear();
          tok->appendf("{0:.2f}", fontSize);
        }
      }

      // compute text start position
      w *= fontSize;
      switch (quadding) {
      case quaddingLeftJustified:
      default:
        x = borderWidth + 2;
        break;
      case quaddingCentered:
        x = (dx - w) / 2;
        break;
      case quaddingRightJustified:
        x = dx - borderWidth - 2 - w;
        break;
      }
      y = 0.5 * dy - 0.4 * fontSize;

      // set the font matrix
      if (tmPos >= 0) {
        tok = (GooString *)daToks->get(tmPos + 4);
        tok->clear();
        tok->appendf("{0:.2f}", x);
        tok = (GooString *)daToks->get(tmPos + 5);
        tok->clear();
        tok->appendf("{0:.2f}", y);
      }

      // write the DA string
      if (daToks) {
        for (i = 0; i < daToks->getLength(); ++i) {
          appearBuf->append((GooString *)daToks->get(i))->append(' ');
        }
      }

      // write the font matrix (if not part of the DA string)
      if (tmPos < 0) {
        appearBuf->appendf("1 0 0 1 {0:.2f} {1:.2f} Tm\n", x, y);
      }

      // write the text string
      writeString(convertedText, appearBuf);
      appearBuf->append(" Tj\n");
    }
  }
  // cleanup
  appearBuf->append("ET\n");
  appearBuf->append("Q\n");
  if (txField) {
    appearBuf->append("EMC\n");
  }
  if (daToks) {
    deleteGooList(daToks, GooString);
  }
  if (freeText) {
    delete text;
  }
  delete convertedText;
  if (freeFont) {
    font->decRefCnt();
  }
}

// Draw the variable text or caption for a field.
void AnnotWidget::drawListBox(FormFieldChoice *fieldChoice,
			      GooString *da, GfxResources *resources, int quadding) {
  GooList *daToks;
  GooString *tok, *convertedText;
  GfxFont *font;
  double fontSize, fontSize2, borderWidth, x, y, w, wMax;
  int tfPos, tmPos, i, j;

  //~ if there is no MK entry, this should use the existing content stream,
  //~ and only replace the marked content portion of it
  //~ (this is only relevant for Tx fields)

  // parse the default appearance string
  tfPos = tmPos = -1;
  if (da) {
    daToks = new GooList();
    i = 0;
    while (i < da->getLength()) {
      while (i < da->getLength() && Lexer::isSpace(da->getChar(i))) {
	++i;
       }
      if (i < da->getLength()) {
	for (j = i + 1;
	     j < da->getLength() && !Lexer::isSpace(da->getChar(j));
	     ++j) ;
	daToks->append(new GooString(da, i, j - i));
	i = j;
      }
    }
    for (i = 2; i < daToks->getLength(); ++i) {
      if (i >= 2 && !((GooString *)daToks->get(i))->cmp("Tf")) {
	tfPos = i - 2;
      } else if (i >= 6 && !((GooString *)daToks->get(i))->cmp("Tm")) {
	tmPos = i - 6;
      }
    }
  } else {
    daToks = NULL;
  }

  // get the font and font size
  font = NULL;
  fontSize = 0;
  if (tfPos >= 0) {
    tok = (GooString *)daToks->get(tfPos);
    if (tok->getLength() >= 1 && tok->getChar(0) == '/') {
      if (!resources || !(font = resources->lookupFont(tok->getCString() + 1))) {
        error(errSyntaxError, -1, "Unknown font in field's DA string");
      }
    } else {
      error(errSyntaxError, -1, "Invalid font name in 'Tf' operator in field's DA string");
    }
    tok = (GooString *)daToks->get(tfPos + 1);
    fontSize = gatof(tok->getCString());
  } else {
    error(errSyntaxError, -1, "Missing 'Tf' operator in field's DA string");
  }
  if (!font) {
    if (daToks) {
      deleteGooList(daToks, GooString);
    }
    return;
  }

  convertedText = new GooString;

  // get the border width
  borderWidth = border ? border->getWidth() : 0;

  // compute font autosize
  if (fontSize == 0) {
    wMax = 0;
    for (i = 0; i < fieldChoice->getNumChoices(); ++i) {
      j = 0;
      if (fieldChoice->getChoice(i) == NULL) {
        error(errSyntaxError, -1, "Invalid annotation listbox");
        if (daToks) {
          deleteGooList(daToks, GooString);
        }
        delete convertedText;
        return;
      }
      layoutText(fieldChoice->getChoice(i), convertedText, &j, font, &w, 0.0, NULL, gFalse);
      if (w > wMax) {
        wMax = w;
      }
    }
    fontSize = rect->y2 - rect->y1 - 2 * borderWidth;
    fontSize2 = (rect->x2 - rect->x1 - 4 - 2 * borderWidth) / wMax;
    if (fontSize2 < fontSize) {
      fontSize = fontSize2;
    }
    fontSize = floor(fontSize);
    if (tfPos >= 0) {
      tok = (GooString *)daToks->get(tfPos + 1);
      tok->clear();
      tok->appendf("{0:.2f}", fontSize);
    }
  }
  // draw the text
  y = rect->y2 - rect->y1 - 1.1 * fontSize;
  for (i = fieldChoice->getTopIndex(); i < fieldChoice->getNumChoices(); ++i) {
    // setup
    appearBuf->append("q\n");

    // draw the background if selected
    if (fieldChoice->isSelected(i)) {
      appearBuf->append("0 g f\n");
      appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} re f\n",
          borderWidth,
          y - 0.2 * fontSize,
          rect->x2 - rect->x1 - 2 * borderWidth,
          1.1 * fontSize);
    }

    // setup
    appearBuf->append("BT\n");

    // compute text width and start position
    j = 0;
    layoutText(fieldChoice->getChoice(i), convertedText, &j, font, &w, 0.0, NULL, gFalse);
    w *= fontSize;
    switch (quadding) {
    case quaddingLeftJustified:
    default:
      x = borderWidth + 2;
      break;
    case quaddingCentered:
      x = (rect->x2 - rect->x1 - w) / 2;
      break;
    case quaddingRightJustified:
      x = rect->x2 - rect->x1 - borderWidth - 2 - w;
      break;
    }

    // set the font matrix
    if (tmPos >= 0) {
      tok = (GooString *)daToks->get(tmPos + 4);
      tok->clear();
      tok->appendf("{0:.2f}", x);
      tok = (GooString *)daToks->get(tmPos + 5);
      tok->clear();
      tok->appendf("{0:.2f}", y);
    }

    // write the DA string
    if (daToks) {
      for (j = 0; j < daToks->getLength(); ++j) {
        appearBuf->append((GooString *)daToks->get(j))->append(' ');
      }
    }

    // write the font matrix (if not part of the DA string)
    if (tmPos < 0) {
      appearBuf->appendf("1 0 0 1 {0:.2f} {1:.2f} Tm\n", x, y);
    }

    // change the text color if selected
    if (fieldChoice->isSelected(i)) {
      appearBuf->append("1 g\n");
    }

    // write the text string
    writeString(convertedText, appearBuf);
    appearBuf->append(" Tj\n");

    // cleanup
    appearBuf->append("ET\n");
    appearBuf->append("Q\n");

    // next line
    y -= 1.1 * fontSize;
  }

  if (daToks) {
    deleteGooList(daToks, GooString);
  }

  delete convertedText;
}

void AnnotWidget::drawBorder() {
  int dashLength;
  double *dash;
  AnnotColor adjustedColor;
  double w = border->getWidth();

  AnnotColor *aColor = appearCharacs->getBorderColor();
  if (!aColor)
    aColor = appearCharacs->getBackColor();
  if (!aColor)
    return;

  double dx = rect->x2 - rect->x1;
  double dy = rect->y2 - rect->y1;

  // radio buttons with no caption have a round border
  GBool hasCaption = appearCharacs->getNormalCaption() != NULL;
  if (field->getType() == formButton &&
      static_cast<FormFieldButton*>(field)->getButtonType() == formButtonRadio && !hasCaption) {
    double r = 0.5 * (dx < dy ? dx : dy);
    switch (border->getStyle()) {
    case AnnotBorder::borderDashed:
      appearBuf->append("[");
      dashLength = border->getDashLength();
      dash = border->getDash();
      for (int i = 0; i < dashLength; ++i) {
        appearBuf->appendf(" {0:.2f}", dash[i]);
      }
      appearBuf->append("] 0 d\n");
      // fall through to the solid case
    case AnnotBorder::borderSolid:
    case AnnotBorder::borderUnderlined:
      appearBuf->appendf("{0:.2f} w\n", w);
      setColor(aColor, gFalse);
      drawCircle(0.5 * dx, 0.5 * dy, r - 0.5 * w, gFalse);
      break;
    case AnnotBorder::borderBeveled:
    case AnnotBorder::borderInset:
      appearBuf->appendf("{0:.2f} w\n", 0.5 * w);
      setColor(aColor, gFalse);
      drawCircle(0.5 * dx, 0.5 * dy, r - 0.25 * w, gFalse);
      adjustedColor = AnnotColor(*aColor);
      adjustedColor.adjustColor(border->getStyle() == AnnotBorder::borderBeveled ? 1 : -1);
      setColor(&adjustedColor, gFalse);
      drawCircleTopLeft(0.5 * dx, 0.5 * dy, r - 0.75 * w);
      adjustedColor = AnnotColor(*aColor);
      adjustedColor.adjustColor(border->getStyle() == AnnotBorder::borderBeveled ? -1 : 1);
      setColor(&adjustedColor, gFalse);
      drawCircleBottomRight(0.5 * dx, 0.5 * dy, r - 0.75 * w);
      break;
    }
  } else {
    switch (border->getStyle()) {
    case AnnotBorder::borderDashed:
      appearBuf->append("[");
      dashLength = border->getDashLength();
      dash = border->getDash();
      for (int i = 0; i < dashLength; ++i) {
        appearBuf->appendf(" {0:.2f}", dash[i]);
      }
      appearBuf->append("] 0 d\n");
      // fall through to the solid case
    case AnnotBorder::borderSolid:
      appearBuf->appendf("{0:.2f} w\n", w);
      setColor(aColor, gFalse);
      appearBuf->appendf("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re s\n",
                         0.5 * w, dx - w, dy - w);
      break;
    case AnnotBorder::borderBeveled:
    case AnnotBorder::borderInset:
      adjustedColor = AnnotColor(*aColor);
      adjustedColor.adjustColor(border->getStyle() == AnnotBorder::borderBeveled ? 1 : -1);
      setColor(&adjustedColor, gTrue);
      appearBuf->append("0 0 m\n");
      appearBuf->appendf("0 {0:.2f} l\n", dy);
      appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx, dy);
      appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx - w, dy - w);
      appearBuf->appendf("{0:.2f} {1:.2f} l\n", w, dy - w);
      appearBuf->appendf("{0:.2f} {0:.2f} l\n", w);
      appearBuf->append("f\n");
      adjustedColor = AnnotColor(*aColor);
      adjustedColor.adjustColor(border->getStyle() == AnnotBorder::borderBeveled ? -1 : 1);
      setColor(&adjustedColor, gTrue);
      appearBuf->append("0 0 m\n");
      appearBuf->appendf("{0:.2f} 0 l\n", dx);
      appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx, dy);
      appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx - w, dy - w);
      appearBuf->appendf("{0:.2f} {1:.2f} l\n", dx - w, w);
      appearBuf->appendf("{0:.2f} {0:.2f} l\n", w);
      appearBuf->append("f\n");
      break;
    case AnnotBorder::borderUnderlined:
      appearBuf->appendf("{0:.2f} w\n", w);
      setColor(aColor, gFalse);
      appearBuf->appendf("0 0 m {0:.2f} 0 l s\n", dx);
      break;
    }

    // clip to the inside of the border
    appearBuf->appendf("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re W n\n",
                       w, dx - 2 * w, dy - 2 * w);
  }
}

void AnnotWidget::drawFormFieldButton(GfxResources *resources, GooString *da) {
  GooString *caption = NULL;
  if (appearCharacs)
    caption = appearCharacs->getNormalCaption();

  switch (static_cast<FormFieldButton *>(field)->getButtonType()) {
  case formButtonRadio: {
    //~ Acrobat doesn't draw a caption if there is no AP dict (?)
    if (appearState && appearState->cmp("Off") != 0 &&
        static_cast<FormFieldButton *>(field)->getState(appearState->getCString())) {
      if (caption) {
        drawText(caption, da, resources, gFalse, 0, fieldQuadCenter,
                 gFalse, gTrue);
      } else if (appearCharacs) {
        AnnotColor *aColor = appearCharacs->getBorderColor();
        if (aColor) {
          double dx = rect->x2 - rect->x1;
          double dy = rect->y2 - rect->y1;
          setColor(aColor, gTrue);
          drawCircle(0.5 * dx, 0.5 * dy, 0.2 * (dx < dy ? dx : dy), gTrue);
        }
      }
    }
  }
    break;
  case formButtonPush:
    if (caption)
      drawText(caption, da, resources, gFalse, 0, fieldQuadCenter, gFalse, gFalse);
    break;
  case formButtonCheck:
    if (appearState && appearState->cmp("Off") != 0) {
      if (!caption) {
        GooString checkMark("3");
        drawText(&checkMark, da, resources, gFalse, 0, fieldQuadCenter, gFalse, gTrue);
      } else {
        drawText(caption, da, resources, gFalse, 0, fieldQuadCenter, gFalse, gTrue);
      }
    }
    break;
  }
}

void AnnotWidget::drawFormFieldText(GfxResources *resources, GooString *da) {
  VariableTextQuadding quadding;
  GooString *contents;
  FormFieldText *fieldText = static_cast<FormFieldText *>(field);

  contents = fieldText->getContent();
  if (contents) {
    quadding = field->hasTextQuadding() ? field->getTextQuadding() : form->getTextQuadding();

    int comb = 0;
    if (fieldText->isComb())
      comb = fieldText->getMaxLen();

    drawText(contents, da, resources,
             fieldText->isMultiline(), comb, quadding, gTrue, gFalse, fieldText->isPassword());
  }
}

void AnnotWidget::drawFormFieldChoice(GfxResources *resources, GooString *da) {
  GooString *selected;
  VariableTextQuadding quadding;
  FormFieldChoice *fieldChoice = static_cast<FormFieldChoice *>(field);

  quadding = field->hasTextQuadding() ? field->getTextQuadding() : form->getTextQuadding();

  if (fieldChoice->isCombo()) {
    selected = fieldChoice->getSelectedChoice();
    if (selected) {
      drawText(selected, da, resources, gFalse, 0, quadding, gTrue, gFalse);
      //~ Acrobat draws a popup icon on the right side
    }
  // list box
  } else {
    drawListBox(fieldChoice, da, resources, quadding);
  }
}

void AnnotWidget::generateFieldAppearance() {
  Object appearDict, obj1, obj2;
  GfxResources *resources;
  MemStream *appearStream;
  GooString *da;

  appearBuf = new GooString ();

  // draw the background
  if (appearCharacs) {
    AnnotColor *aColor = appearCharacs->getBackColor();
    if (aColor) {
      setColor(aColor, gTrue);
      appearBuf->appendf("0 0 {0:.2f} {1:.2f} re f\n",
                         rect->x2 - rect->x1, rect->y2 - rect->y1);
    }
  }

  // draw the border
  if (appearCharacs && border && border->getWidth() > 0)
    drawBorder();

  da = field->getDefaultAppearance();
  if (!da)
    da = form->getDefaultAppearance();

  resources = form->getDefaultResources();

  // draw the field contents
  switch (field->getType()) {
  case formButton:
    drawFormFieldButton(resources, da);
    break;
  case formText:
    drawFormFieldText(resources, da);
    break;
  case formChoice:
    drawFormFieldChoice(resources, da);
    break;
  case formSignature:
    //~unimp
    break;
  case formUndef:
  default:
    error(errSyntaxError, -1, "Unknown field type");
  }

  // build the appearance stream dictionary
  appearDict.initDict(xref);
  appearDict.dictAdd(copyString("Length"),
      obj1.initInt(appearBuf->getLength()));
  appearDict.dictAdd(copyString("Subtype"), obj1.initName("Form"));
  obj1.initArray(xref);
  obj1.arrayAdd(obj2.initReal(0));
  obj1.arrayAdd(obj2.initReal(0));
  obj1.arrayAdd(obj2.initReal(rect->x2 - rect->x1));
  obj1.arrayAdd(obj2.initReal(rect->y2 - rect->y1));
  appearDict.dictAdd(copyString("BBox"), &obj1);

  // set the resource dictionary
  Object *resDict = form->getDefaultResourcesObj();
  if (resDict->isDict()) {
    appearDict.dictAdd(copyString("Resources"), resDict->copy(&obj1));
  }

  // build the appearance stream
  appearStream = new MemStream(copyString(appearBuf->getCString()), 0,
      appearBuf->getLength(), &appearDict);
  appearance.free();
  appearance.initStream(appearStream);
  delete appearBuf;

  appearStream->setNeedFree(gTrue);
}

void AnnotWidget::updateAppearanceStream()
{
  // If this the first time updateAppearanceStream() is called on this widget,
  // destroy the AP dictionary because we are going to create a new one.
  if (updatedAppearanceStream.num == -1) {
    invalidateAppearance(); // Delete AP dictionary and all referenced streams
  }

  // There's no need to create a new appearance stream if NeedAppearances is
  // set, because it will be ignored next time anyway.
  if (form && form->getNeedAppearances())
    return;

  // Create the new appearance
  generateFieldAppearance();

  // Fetch the appearance stream we've just created
  Object obj1;
  appearance.fetch(xref, &obj1);

  // If this the first time updateAppearanceStream() is called on this widget,
  // create a new AP dictionary containing the new appearance stream.
  // Otherwise, just update the stream we had created previously.
  if (updatedAppearanceStream.num == -1) {
    // Write the appearance stream
    updatedAppearanceStream = xref->addIndirectObject(&obj1);
    obj1.free();

    // Write the AP dictionary
    Object obj2;
    obj1.initDict(xref);
    obj1.dictAdd(copyString("N"), obj2.initRef(updatedAppearanceStream.num, updatedAppearanceStream.gen));
    update("AP", &obj1);

    // Update our internal pointers to the appearance dictionary
    appearStreams = new AnnotAppearance(doc, &obj1);
  } else {
    // Replace the existing appearance stream
    xref->setModifiedObject(&obj1, updatedAppearanceStream);
    obj1.free();
  }
}

void AnnotWidget::draw(Gfx *gfx, GBool printing) {
  Object obj;

  if (!isVisible (printing))
    return;

  annotLocker();
  addDingbatsResource = gFalse;

  // Only construct the appearance stream when
  // - annot doesn't have an AP or
  // - NeedAppearances is true
  if (field) {
    if (appearance.isNull() || (form && form->getNeedAppearances()))
      generateFieldAppearance();
  }

  // draw the appearance stream
  appearance.fetch(gfx->getXRef(), &obj);
  if (addDingbatsResource) {
    // We are forcing ZaDb but the font does not exist
    // so create a fake one
    Object baseFontObj, subtypeObj;
    baseFontObj.initName("ZapfDingbats");
    subtypeObj.initName("Type1");

    Object fontDictObj;
    Dict *fontDict = new Dict(gfx->getXRef());
    fontDict->decRef();
    fontDict->add(copyString("BaseFont"), &baseFontObj);
    fontDict->add(copyString("Subtype"), &subtypeObj);
    fontDictObj.initDict(fontDict);

    Object fontsDictObj;
    Dict *fontsDict = new Dict(gfx->getXRef());
    fontsDict->decRef();
    fontsDict->add(copyString("ZaDb"), &fontDictObj);
    fontsDictObj.initDict(fontsDict);

    Dict *dict = new Dict(gfx->getXRef());
    dict->add(copyString("Font"), &fontsDictObj);
    gfx->pushResources(dict);
    delete dict;
  }
  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
		 rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
  if (addDingbatsResource) {
    gfx->popResources();
  }
  obj.free();
}


//------------------------------------------------------------------------
// AnnotMovie
//------------------------------------------------------------------------
AnnotMovie::AnnotMovie(PDFDoc *docA, PDFRectangle *rect, Movie *movieA) :
    Annot(docA, rect) {
  Object obj1;

  type = typeMovie;
  annotObj.dictSet ("Subtype", obj1.initName ("Movie"));

  movie = movieA->copy();
  // TODO: create movie dict from movieA

  initialize(docA, annotObj.getDict());
}

AnnotMovie::AnnotMovie(PDFDoc *docA, Dict *dict, Object *obj) :
  Annot(docA, dict, obj) {
  type = typeMovie;
  initialize(docA, dict);
}

AnnotMovie::~AnnotMovie() {
  if (title)
    delete title;
  delete movie;
}

void AnnotMovie::initialize(PDFDoc *docA, Dict* dict) {
  Object obj1;

  if (dict->lookup("T", &obj1)->isString()) {
    title = obj1.getString()->copy();
  } else {
    title = NULL;
  }
  obj1.free();

  Object movieDict;
  if (dict->lookup("Movie", &movieDict)->isDict()) {
    Object obj2;
    dict->lookup("A", &obj2);
    if (obj2.isDict())
      movie = new Movie (&movieDict, &obj2);
    else
      movie = new Movie (&movieDict);
    if (!movie->isOk()) {
      delete movie;
      movie = NULL;
      ok = gFalse;
    }
    obj2.free();
  } else {
    error(errSyntaxError, -1, "Bad Annot Movie");
    movie = NULL;
    ok = gFalse;
  }
  movieDict.free();
}

void AnnotMovie::draw(Gfx *gfx, GBool printing) {
  Object obj;

  if (!isVisible (printing))
    return;

  annotLocker();
  if (appearance.isNull() && movie->getShowPoster()) {
    int width, height;
    Object poster;
    movie->getPoster(&poster);
    movie->getAspect(&width, &height);

    if (width != -1 && height != -1 && !poster.isNone()) {
      MemStream *mStream;

      appearBuf = new GooString ();
      appearBuf->append ("q\n");
      appearBuf->appendf ("{0:d} 0 0 {1:d} 0 0 cm\n", width, height);
      appearBuf->append ("/MImg Do\n");
      appearBuf->append ("Q\n");

      Object imgDict;
      imgDict.initDict(gfx->getXRef());
      imgDict.dictSet ("MImg", &poster);

      Object resDict;
      resDict.initDict(gfx->getXRef());
      resDict.dictSet ("XObject", &imgDict);

      Object formDict, obj1, obj2;
      formDict.initDict(gfx->getXRef());
      formDict.dictSet("Length", obj1.initInt(appearBuf->getLength()));
      formDict.dictSet("Subtype", obj1.initName("Form"));
      formDict.dictSet("Name", obj1.initName("FRM"));
      obj1.initArray(gfx->getXRef());
      obj1.arrayAdd(obj2.initInt(0));
      obj1.arrayAdd(obj2.initInt(0));
      obj1.arrayAdd(obj2.initInt(width));
      obj1.arrayAdd(obj2.initInt(height));
      formDict.dictSet("BBox", &obj1);
      obj1.initArray(gfx->getXRef());
      obj1.arrayAdd(obj2.initInt(1));
      obj1.arrayAdd(obj2.initInt(0));
      obj1.arrayAdd(obj2.initInt(0));
      obj1.arrayAdd(obj2.initInt(1));
      obj1.arrayAdd(obj2.initInt(-width / 2));
      obj1.arrayAdd(obj2.initInt(-height / 2));
      formDict.dictSet("Matrix", &obj1);
      formDict.dictSet("Resources", &resDict);

      Object aStream;
      mStream = new MemStream(copyString(appearBuf->getCString()), 0,
			      appearBuf->getLength(), &formDict);
      mStream->setNeedFree(gTrue);
      aStream.initStream(mStream);
      delete appearBuf;

      Object objDict;
      objDict.initDict(gfx->getXRef());
      objDict.dictSet ("FRM", &aStream);

      resDict.initDict(gfx->getXRef());
      resDict.dictSet ("XObject", &objDict);

      appearBuf = new GooString ();
      appearBuf->append ("q\n");
      appearBuf->appendf ("0 0 {0:d} {1:d} re W n\n", width, height);
      appearBuf->append ("q\n");
      appearBuf->appendf ("0 0 {0:d} {1:d} re W n\n", width, height);
      appearBuf->appendf ("1 0 0 1 {0:d} {1:d} cm\n", width / 2, height / 2);
      appearBuf->append ("/FRM Do\n");
      appearBuf->append ("Q\n");
      appearBuf->append ("Q\n");

      double bbox[4];
      bbox[0] = bbox[1] = 0;
      bbox[2] = width;
      bbox[3] = height;
      createForm(bbox, gFalse, &resDict, &appearance);
      delete appearBuf;
    }
    poster.free();
  }

  // draw the appearance stream
  appearance.fetch(gfx->getXRef(), &obj);
  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
		 rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
  obj.free();
}

//------------------------------------------------------------------------
// AnnotScreen
//------------------------------------------------------------------------
AnnotScreen::AnnotScreen(PDFDoc *docA, PDFRectangle *rect) :
    Annot(docA, rect) {
  Object obj1;

  type = typeScreen;

  annotObj.dictSet ("Subtype", obj1.initName ("Screen"));
  initialize(docA, annotObj.getDict());
}

AnnotScreen::AnnotScreen(PDFDoc *docA, Dict *dict, Object *obj) :
  Annot(docA, dict, obj) {
  type = typeScreen;
  initialize(docA, dict);
}

AnnotScreen::~AnnotScreen() {
  if (title)
    delete title;
  if (appearCharacs)
    delete appearCharacs;
  if (action)
    delete action;

  additionalActions.free();
}

void AnnotScreen::initialize(PDFDoc *docA, Dict* dict) {
  Object obj1;

  title = NULL;
  if (dict->lookup("T", &obj1)->isString()) {
    title = obj1.getString()->copy();
  }
  obj1.free();

  action = NULL;
  if (dict->lookup("A", &obj1)->isDict()) {
    action = LinkAction::parseAction(&obj1, doc->getCatalog()->getBaseURI());
    if (action && action->getKind() == actionRendition && page == 0) {
      error (errSyntaxError, -1, "Invalid Rendition action: associated screen annotation without P");
      delete action;
      action = NULL;
      ok = gFalse;
    }
  }
  obj1.free();

  dict->lookupNF("AA", &additionalActions);

  appearCharacs = NULL;
  if(dict->lookup("MK", &obj1)->isDict()) {
    appearCharacs = new AnnotAppearanceCharacs(obj1.getDict());
  }
  obj1.free();
}

LinkAction* AnnotScreen::getAdditionalAction(AdditionalActionsType type)
{
  if (type == actionFocusIn || type == actionFocusOut) // not defined for screen annotation
    return NULL;

  return ::getAdditionalAction(type, &additionalActions, doc);
}

//------------------------------------------------------------------------
// AnnotStamp
//------------------------------------------------------------------------
AnnotStamp::AnnotStamp(PDFDoc *docA, PDFRectangle *rect) :
  AnnotMarkup(docA, rect) {
  Object obj1;

  type = typeStamp;
  annotObj.dictSet ("Subtype", obj1.initName ("Stamp"));
  initialize(docA, annotObj.getDict());
}

AnnotStamp::AnnotStamp(PDFDoc *docA, Dict *dict, Object *obj) :
  AnnotMarkup(docA, dict, obj) {
  type = typeStamp;
  initialize(docA, dict);
}

AnnotStamp::~AnnotStamp() {
  delete icon;
}

void AnnotStamp::initialize(PDFDoc *docA, Dict* dict) {
  Object obj1;

  if (dict->lookup("Name", &obj1)->isName()) {
    icon = new GooString(obj1.getName());
  } else {
    icon = new GooString("Draft");
  }
  obj1.free();

}

void AnnotStamp::setIcon(GooString *new_icon) {
  delete icon;

  if (new_icon) {
    icon = new GooString (new_icon);
  } else {
    icon = new GooString();
  }

  Object obj1;
  obj1.initName (icon->getCString());
  update("Name", &obj1);
  invalidateAppearance();
}

//------------------------------------------------------------------------
// AnnotGeometry
//------------------------------------------------------------------------
AnnotGeometry::AnnotGeometry(PDFDoc *docA, PDFRectangle *rect, AnnotSubtype subType) :
    AnnotMarkup(docA, rect) {
  Object obj1;

  switch (subType) {
    case typeSquare:
      annotObj.dictSet ("Subtype", obj1.initName ("Square"));
      break;
    case typeCircle:
      annotObj.dictSet ("Subtype", obj1.initName ("Circle"));
      break;
    default:
      assert (0 && "Invalid subtype for AnnotGeometry\n");
  }

  initialize(docA, annotObj.getDict());
}

AnnotGeometry::AnnotGeometry(PDFDoc *docA, Dict *dict, Object *obj) :
  AnnotMarkup(docA, dict, obj) {
  // the real type will be read in initialize()
  type = typeSquare;
  initialize(docA, dict);
}

AnnotGeometry::~AnnotGeometry() {
  delete interiorColor;
  delete borderEffect;
  delete geometryRect;
}

void AnnotGeometry::initialize(PDFDoc *docA, Dict* dict) {
  Object obj1;

  if (dict->lookup("Subtype", &obj1)->isName()) {
    GooString typeName(obj1.getName());
    if (!typeName.cmp("Square")) {
      type = typeSquare;
    } else if (!typeName.cmp("Circle")) {
      type = typeCircle;
    }
  }
  obj1.free();

  if (dict->lookup("IC", &obj1)->isArray()) {
    interiorColor = new AnnotColor(obj1.getArray());
  } else {
    interiorColor = NULL;
  }
  obj1.free();

  if (dict->lookup("BS", &obj1)->isDict()) {
    delete border;
    border = new AnnotBorderBS(obj1.getDict());
  } else if (!border) {
    border = new AnnotBorderBS();
  }
  obj1.free();

  if (dict->lookup("BE", &obj1)->isDict()) {
    borderEffect = new AnnotBorderEffect(obj1.getDict());
  } else {
    borderEffect = NULL;
  }
  obj1.free();

  geometryRect = NULL;
  if (dict->lookup("RD", &obj1)->isArray()) {
    geometryRect = parseDiffRectangle(obj1.getArray(), rect);
  }
  obj1.free();

}

void AnnotGeometry::setType(AnnotSubtype new_type) {
  Object obj1;

  switch (new_type) {
    case typeSquare:
      obj1.initName("Square");
      break;
    case typeCircle:
      obj1.initName("Circle");
      break;
    default:
      assert(!"Invalid subtype");
  }

  type = new_type;
  update("Subtype", &obj1);
  invalidateAppearance();
}

void AnnotGeometry::setInteriorColor(AnnotColor *new_color) {
  delete interiorColor;

  if (new_color) {
    Object obj1;
    new_color->writeToObject(xref, &obj1);
    update ("IC", &obj1);
    interiorColor = new_color;
  } else {
    interiorColor = NULL;
  }
  invalidateAppearance();
}

void AnnotGeometry::draw(Gfx *gfx, GBool printing) {
  Object obj;
  double ca = 1;

  if (!isVisible (printing))
    return;

  annotLocker();
  if (appearance.isNull()) {
    ca = opacity;

    appearBuf = new GooString ();
    appearBuf->append ("q\n");
    if (color)
      setColor(color, gFalse);

    double borderWidth = border->getWidth();
    setLineStyleForBorder(border);

    if (interiorColor)
      setColor(interiorColor, gTrue);

    if (type == typeSquare) {
      appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} re\n",
                          borderWidth / 2.0, borderWidth / 2.0,
                          (rect->x2 - rect->x1) - borderWidth,
                          (rect->y2 - rect->y1) - borderWidth);
    } else {
      double width, height;
      double b;
      double x1, y1, x2, y2, x3, y3;

      width = rect->x2 - rect->x1;
      height = rect->y2 - rect->y1;
      b = borderWidth / 2.0;

      x1 = b;
      y1 = height / 2.0;
      appearBuf->appendf ("{0:.2f} {1:.2f} m\n", x1, y1);

      y1 += height / 4.0;
      x2 = width / 4.0;
      y2 = height - b;
      x3 = width / 2.0;
      y3 = y2;
      appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
                          x1, y1, x2, y2, x3, y3);
      x2 = width - b;
      y2 = y1;
      x1 = x3 + (width / 4.0);
      y1 = y3;
      x3 = x2;
      y3 = height / 2.0;
      appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
                          x1, y1, x2, y2, x3, y3);

      x2 = x1;
      y2 = b;
      x1 = x3;
      y1 = height / 4.0;
      x3 = width / 2.0;
      y3 = b;
      appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
                          x1, y1, x2, y2, x3, y3);

      x2 = b;
      y2 = y1;
      x1 = width / 4.0;
      y1 = b;
      x3 = b;
      y3 = height / 2.0;
      appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
                          x1, y1, x2, y2, x3, y3);
    }

    if (interiorColor && interiorColor->getSpace() != AnnotColor::colorTransparent)
      appearBuf->append ("b\n");
    else
      appearBuf->append ("S\n");

    appearBuf->append ("Q\n");

    double bbox[4];
    bbox[0] = bbox[1] = 0;
    bbox[2] = rect->x2 - rect->x1;
    bbox[3] = rect->y2 - rect->y1;
    if (ca == 1) {
      createForm(bbox, gFalse, NULL, &appearance);
    } else {
      Object aStream;

      createForm(bbox, gTrue, NULL, &aStream);
      delete appearBuf;

      Object resDict;
      appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
      createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
      createForm(bbox, gFalse, &resDict, &appearance);
    }
    delete appearBuf;
  }

  // draw the appearance stream
  appearance.fetch(gfx->getXRef(), &obj);
  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
		 rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
  obj.free();
}

//------------------------------------------------------------------------
// AnnotPolygon
//------------------------------------------------------------------------
AnnotPolygon::AnnotPolygon(PDFDoc *docA, PDFRectangle *rect, AnnotSubtype subType) :
    AnnotMarkup(docA, rect) {
  Object obj1;

  switch (subType) {
    case typePolygon:
      annotObj.dictSet ("Subtype", obj1.initName ("Polygon"));
      break;
    case typePolyLine:
      annotObj.dictSet ("Subtype", obj1.initName ("PolyLine"));
      break;
    default:
      assert (0 && "Invalid subtype for AnnotGeometry\n");
  }

  // Store dummy path with one null vertex only
  Object obj2, obj3;
  obj2.initArray (doc->getXRef());
  obj2.arrayAdd (obj3.initReal (0));
  obj2.arrayAdd (obj3.initReal (0));
  annotObj.dictSet ("Vertices", &obj2);

  initialize(docA, annotObj.getDict());
}

AnnotPolygon::AnnotPolygon(PDFDoc *docA, Dict *dict, Object *obj) :
  AnnotMarkup(docA, dict, obj) {
  // the real type will be read in initialize()
  type = typePolygon;
  initialize(docA, dict);
}

AnnotPolygon::~AnnotPolygon() {
  delete vertices;

  if (interiorColor)
    delete interiorColor;

  if (borderEffect)
    delete borderEffect;
}

void AnnotPolygon::initialize(PDFDoc *docA, Dict* dict) {
  Object obj1;

  if (dict->lookup("Subtype", &obj1)->isName()) {
    GooString typeName(obj1.getName());
    if (!typeName.cmp("Polygon")) {
      type = typePolygon;
    } else if (!typeName.cmp("PolyLine")) {
      type = typePolyLine;
    }
  }
  obj1.free();

  if (dict->lookup("Vertices", &obj1)->isArray()) {
    vertices = new AnnotPath(obj1.getArray());
  } else {
    vertices = new AnnotPath();
    error(errSyntaxError, -1, "Bad Annot Polygon Vertices");
    ok = gFalse;
  }
  obj1.free();

  if (dict->lookup("LE", &obj1)->isArray() && obj1.arrayGetLength() == 2) {
    Object obj2;

    if(obj1.arrayGet(0, &obj2)->isString())
      startStyle = parseAnnotLineEndingStyle(obj2.getString());
    else
      startStyle = annotLineEndingNone;
    obj2.free();

    if(obj1.arrayGet(1, &obj2)->isString())
      endStyle = parseAnnotLineEndingStyle(obj2.getString());
    else
      endStyle = annotLineEndingNone;
    obj2.free();

  } else {
    startStyle = endStyle = annotLineEndingNone;
  }
  obj1.free();

  if (dict->lookup("IC", &obj1)->isArray()) {
    interiorColor = new AnnotColor(obj1.getArray());
  } else {
    interiorColor = NULL;
  }
  obj1.free();

  if (dict->lookup("BS", &obj1)->isDict()) {
    delete border;
    border = new AnnotBorderBS(obj1.getDict());
  } else if (!border) {
    border = new AnnotBorderBS();
  }
  obj1.free();

  if (dict->lookup("BE", &obj1)->isDict()) {
    borderEffect = new AnnotBorderEffect(obj1.getDict());
  } else {
    borderEffect = NULL;
  }
  obj1.free();

  if (dict->lookup("IT", &obj1)->isName()) {
    const char *intentName = obj1.getName();

    if(!strcmp(intentName, "PolygonCloud")) {
      intent = polygonCloud;
    } else if(!strcmp(intentName, "PolyLineDimension")) {
      intent = polylineDimension;
    } else {
      intent = polygonDimension;
    }
  } else {
    intent = polygonCloud;
  }
  obj1.free();
}

void AnnotPolygon::setType(AnnotSubtype new_type) {
  Object obj1;

  switch (new_type) {
    case typePolygon:
      obj1.initName("Polygon");
      break;
    case typePolyLine:
      obj1.initName("PolyLine");
      break;
    default:
      assert(!"Invalid subtype");
  }

  type = new_type;
  update("Subtype", &obj1);
  invalidateAppearance();
}

void AnnotPolygon::setVertices(AnnotPath *path) {
  Object obj1, obj2;
  delete vertices;

  obj1.initArray(xref);

  for (int i = 0; i < path->getCoordsLength(); i++) {
    obj1.arrayAdd (obj2.initReal (path->getX(i)));
    obj1.arrayAdd (obj2.initReal (path->getY(i)));
  }

  vertices = new AnnotPath(obj1.getArray());

  update("Vertices", &obj1);
  invalidateAppearance();
}

void AnnotPolygon::setStartEndStyle(AnnotLineEndingStyle start, AnnotLineEndingStyle end) {
  Object obj1, obj2;

  startStyle = start;
  endStyle = end;

  obj1.initArray(xref);
  obj1.arrayAdd( obj2.initName(convertAnnotLineEndingStyle( startStyle )) );
  obj1.arrayAdd( obj2.initName(convertAnnotLineEndingStyle( endStyle )) );

  update("LE", &obj1);
  invalidateAppearance();
}

void AnnotPolygon::setInteriorColor(AnnotColor *new_color) {
  delete interiorColor;

  if (new_color) {
    Object obj1;
    new_color->writeToObject(xref, &obj1);
    update ("IC", &obj1);
    interiorColor = new_color;
  } else {
    interiorColor = NULL;
  }
  invalidateAppearance();
}

void AnnotPolygon::setIntent(AnnotPolygonIntent new_intent) {
  Object obj1;

  intent = new_intent;
  if (new_intent == polygonCloud)
    obj1.initName("PolygonCloud");
  else if (new_intent == polylineDimension)
    obj1.initName("PolyLineDimension");
  else // polygonDimension
    obj1.initName("PolygonDimension");
  update ("IT", &obj1);
}

void AnnotPolygon::draw(Gfx *gfx, GBool printing) {
  Object obj;
  double ca = 1;

  if (!isVisible (printing))
    return;

  annotLocker();
  if (appearance.isNull()) {
    appearBBox = new AnnotAppearanceBBox(rect);
    ca = opacity;

    appearBuf = new GooString ();
    appearBuf->append ("q\n");

    if (color) {
      setColor(color, gFalse);
    }

    setLineStyleForBorder(border);
    appearBBox->setBorderWidth(std::max(1., border->getWidth()));

    if (interiorColor) {
      setColor(interiorColor, gTrue);
    }

    if (vertices->getCoordsLength() != 0) {
      appearBuf->appendf ("{0:.2f} {1:.2f} m\n", vertices->getX(0) - rect->x1, vertices->getY(0) - rect->y1);
      appearBBox->extendTo (vertices->getX(0) - rect->x1, vertices->getY(0) - rect->y1);

      for (int i = 1; i < vertices->getCoordsLength(); ++i) {
        appearBuf->appendf ("{0:.2f} {1:.2f} l\n", vertices->getX(i) - rect->x1, vertices->getY(i) - rect->y1);
        appearBBox->extendTo (vertices->getX(i) - rect->x1, vertices->getY(i) - rect->y1);
      }

      if (type == typePolygon) {
        if (interiorColor && interiorColor->getSpace() != AnnotColor::colorTransparent) {
          appearBuf->append ("b\n");
        } else {
          appearBuf->append ("s\n");
        }
      } else {
        appearBuf->append ("S\n");
      }
    }

    appearBuf->append ("Q\n");

    double bbox[4];
    appearBBox->getBBoxRect(bbox);
    if (ca == 1) {
      createForm(bbox, gFalse, NULL, &appearance);
    } else {
      Object aStream, resDict;

      createForm(bbox, gTrue, NULL, &aStream);
      delete appearBuf;

      appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
      createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
      createForm(bbox, gFalse, &resDict, &appearance);
    }
    delete appearBuf;
  }

  // draw the appearance stream
  appearance.fetch(gfx->getXRef(), &obj);
  if (appearBBox) {
    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
                   appearBBox->getPageXMin(), appearBBox->getPageYMin(),
                   appearBBox->getPageXMax(), appearBBox->getPageYMax(),
                   getRotation());
  } else {
    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
                   rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
  }
  obj.free();
}

//------------------------------------------------------------------------
// AnnotCaret
//------------------------------------------------------------------------
AnnotCaret::AnnotCaret(PDFDoc *docA, PDFRectangle *rect) :
    AnnotMarkup(docA, rect) {
  Object obj1;

  type = typeCaret;

  annotObj.dictSet ("Subtype", obj1.initName ("Caret"));
  initialize(docA, annotObj.getDict());
}

AnnotCaret::AnnotCaret(PDFDoc *docA, Dict *dict, Object *obj) :
  AnnotMarkup(docA, dict, obj) {
  type = typeCaret;
  initialize(docA, dict);
}

AnnotCaret::~AnnotCaret() {
  delete caretRect;
}

void AnnotCaret::initialize(PDFDoc *docA, Dict* dict) {
  Object obj1;

  symbol = symbolNone;
  if (dict->lookup("Sy", &obj1)->isName()) {
    GooString typeName(obj1.getName());
    if (!typeName.cmp("P")) {
      symbol = symbolP;
    } else if (!typeName.cmp("None")) {
      symbol = symbolNone;
    }
  }
  obj1.free();

  if (dict->lookup("RD", &obj1)->isArray()) {
    caretRect = parseDiffRectangle(obj1.getArray(), rect);
  } else {
    caretRect = NULL;
  }
  obj1.free();

}

void AnnotCaret::setSymbol(AnnotCaretSymbol new_symbol) {
  Object obj1;
  obj1.initName( new_symbol == symbolP ? "P" : "None" );
  symbol = new_symbol;
  update("Sy", &obj1);
  invalidateAppearance();
}

//------------------------------------------------------------------------
// AnnotInk
//------------------------------------------------------------------------
AnnotInk::AnnotInk(PDFDoc *docA, PDFRectangle *rect) :
    AnnotMarkup(docA, rect) {
  Object obj1;

  type = typeInk;

  annotObj.dictSet ("Subtype", obj1.initName ("Ink"));

  // Store dummy path with one null vertex only
  Object obj2, obj3, obj4;
  obj2.initArray (doc->getXRef());
  obj2.arrayAdd (obj3.initArray (doc->getXRef()));
  obj3.arrayAdd (obj4.initReal (0));
  obj3.arrayAdd (obj4.initReal (0));
  annotObj.dictSet ("InkList", &obj2);

  initialize(docA, annotObj.getDict());
}

AnnotInk::AnnotInk(PDFDoc *docA, Dict *dict, Object *obj) :
  AnnotMarkup(docA, dict, obj) {
  type = typeInk;
  initialize(docA, dict);
}

AnnotInk::~AnnotInk() {
  freeInkList();
}

void AnnotInk::initialize(PDFDoc *docA, Dict* dict) {
  Object obj1;

  if (dict->lookup("InkList", &obj1)->isArray()) {
    parseInkList(obj1.getArray());
  } else {
    inkListLength = 0;
    inkList = NULL;
    error(errSyntaxError, -1, "Bad Annot Ink List");
    ok = gFalse;
  }
  obj1.free();

  if (dict->lookup("BS", &obj1)->isDict()) {
    delete border;
    border = new AnnotBorderBS(obj1.getDict());
  } else if (!border) {
    border = new AnnotBorderBS();
  }
  obj1.free();
}

void AnnotInk::writeInkList(AnnotPath **paths, int n_paths, Array *dest_array) {
  Object obj1, obj2;
  for (int i = 0; i < n_paths; ++i) {
    AnnotPath *path = paths[i];
    obj1.initArray (xref);
    for (int j = 0; j < path->getCoordsLength(); ++j) {
      obj1.arrayAdd (obj2.initReal (path->getX(j)));
      obj1.arrayAdd (obj2.initReal (path->getY(j)));
    }
    dest_array->add (&obj1);
  }
}

void AnnotInk::parseInkList(Array *array) {
  inkListLength = array->getLength();
  inkList = (AnnotPath **) gmallocn ((inkListLength), sizeof(AnnotPath *));
  memset(inkList, 0, inkListLength * sizeof(AnnotPath *));
  for (int i = 0; i < inkListLength; i++) {
    Object obj2;
    if (array->get(i, &obj2)->isArray())
      inkList[i] = new AnnotPath(obj2.getArray());
    obj2.free();
  }
}

void AnnotInk::freeInkList() {
  if (inkList) {
    for (int i = 0; i < inkListLength; ++i)
      delete inkList[i];
    gfree(inkList);
  }
}

void AnnotInk::setInkList(AnnotPath **paths, int n_paths) {
  Object obj1;

  freeInkList();

  obj1.initArray (xref);
  writeInkList(paths, n_paths, obj1.getArray());

  parseInkList(obj1.getArray());
  annotObj.dictSet ("InkList", &obj1);
  invalidateAppearance();
}

void AnnotInk::draw(Gfx *gfx, GBool printing) {
  Object obj;
  double ca = 1;

  if (!isVisible (printing))
    return;

  annotLocker();
  if (appearance.isNull()) {
    appearBBox = new AnnotAppearanceBBox(rect);
    ca = opacity;

    appearBuf = new GooString ();
    appearBuf->append ("q\n");

    if (color) {
      setColor(color, gFalse);
    }

    setLineStyleForBorder(border);
    appearBBox->setBorderWidth(std::max(1., border->getWidth()));

    for (int i = 0; i < inkListLength; ++i) {
      const AnnotPath * path = inkList[i];
      if (path && path->getCoordsLength() != 0) {
        appearBuf->appendf ("{0:.2f} {1:.2f} m\n", path->getX(0) - rect->x1, path->getY(0) - rect->y1);
        appearBBox->extendTo (path->getX(0) - rect->x1, path->getY(0) - rect->y1);

        for (int j = 1; j < path->getCoordsLength(); ++j) {
          appearBuf->appendf ("{0:.2f} {1:.2f} l\n", path->getX(j) - rect->x1, path->getY(j) - rect->y1);
          appearBBox->extendTo (path->getX(j) - rect->x1, path->getY(j) - rect->y1);
        }

        appearBuf->append ("S\n");
      }
    }

    appearBuf->append ("Q\n");

    double bbox[4];
    appearBBox->getBBoxRect(bbox);
    if (ca == 1) {
      createForm(bbox, gFalse, NULL, &appearance);
    } else {
      Object aStream, resDict;

      createForm(bbox, gTrue, NULL, &aStream);
      delete appearBuf;

      appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
      createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
      createForm(bbox, gFalse, &resDict, &appearance);
    }
    delete appearBuf;
  }

  // draw the appearance stream
  appearance.fetch(gfx->getXRef(), &obj);
  if (appearBBox) {
    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
                   appearBBox->getPageXMin(), appearBBox->getPageYMin(),
                   appearBBox->getPageXMax(), appearBBox->getPageYMax(),
                   getRotation());
  } else {
    gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
                   rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
  }
  obj.free();
}

//------------------------------------------------------------------------
// AnnotFileAttachment
//------------------------------------------------------------------------
AnnotFileAttachment::AnnotFileAttachment(PDFDoc *docA, PDFRectangle *rect, GooString *filename) :
    AnnotMarkup(docA, rect) {
  Object obj1;

  type = typeFileAttachment;

  annotObj.dictSet ("Subtype", obj1.initName ("FileAttachment"));

  Object obj2;
  obj2.initString(filename->copy());
  annotObj.dictSet ("FS", &obj2);

  initialize(docA, annotObj.getDict());
}

AnnotFileAttachment::AnnotFileAttachment(PDFDoc *docA, Dict *dict, Object *obj) :
  AnnotMarkup(docA, dict, obj) {
  type = typeFileAttachment;
  initialize(docA, dict);
}

AnnotFileAttachment::~AnnotFileAttachment() {
  file.free();

  if (name)
    delete name;
}

void AnnotFileAttachment::initialize(PDFDoc *docA, Dict* dict) {
  Object obj1;

  if (dict->lookup("FS", &obj1)->isDict() || dict->lookup("FS", &obj1)->isString()) {
    obj1.copy(&file);
  } else {
    error(errSyntaxError, -1, "Bad Annot File Attachment");
    ok = gFalse;
  }
  obj1.free();

  if (dict->lookup("Name", &obj1)->isName()) {
    name = new GooString(obj1.getName());
  } else {
    name = new GooString("PushPin");
  }
  obj1.free();
}

#define ANNOT_FILE_ATTACHMENT_AP_PUSHPIN                                         \
  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"       \
  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n"     \
  "l 1 21.523 2.477 23 4.301 23 c h\n"                                           \
  "4.301 23 m f\n"                                                               \
  "0.533333 0.541176 0.521569 RG 2 w\n"                                          \
  "1 J\n"                                                                        \
  "1 j\n"                                                                        \
  "[] 0.0 d\n"                                                                   \
  "4 M 5 4 m 6 5 l S\n"                                                          \
  "2 w\n"                                                                        \
  "11 14 m 9 12 l 6 12 l 13 5 l 13 8 l 15 10 l 18 11 l 20 11 l 12 19 l 12\n"     \
  "17 l 11 14 l h\n"                                                             \
  "11 14 m S\n"                                                                  \
  "3 w\n"                                                                        \
  "6 5 m 9 8 l S\n"                                                              \
  "0.729412 0.741176 0.713725 RG 2 w\n"                                          \
  "5 5 m 6 6 l S\n"                                                              \
  "2 w\n"                                                                        \
  "11 15 m 9 13 l 6 13 l 13 6 l 13 9 l 15 11 l 18 12 l 20 12 l 12 20 l 12\n"     \
  "18 l 11 15 l h\n"                                                             \
  "11 15 m S\n"                                                                  \
  "3 w\n"                                                                        \
  "6 6 m 9 9 l S\n"

#define ANNOT_FILE_ATTACHMENT_AP_PAPERCLIP                                       \
  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"       \
  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n"     \
  "l 1 21.523 2.477 23 4.301 23 c h\n"                                           \
  "4.301 23 m f\n"                                                               \
  "0.533333 0.541176 0.521569 RG 2 w\n"                                          \
  "1 J\n"                                                                        \
  "1 j\n"                                                                        \
  "[] 0.0 d\n"                                                                   \
  "4 M 16.645 12.035 m 12.418 7.707 l 10.902 6.559 6.402 11.203 8.09 12.562 c\n" \
  "14.133 18.578 l 14.949 19.387 16.867 19.184 17.539 18.465 c 20.551\n"         \
  "15.23 l 21.191 14.66 21.336 12.887 20.426 12.102 c 13.18 4.824 l 12.18\n"     \
  "3.82 6.25 2.566 4.324 4.461 c 3 6.395 3.383 11.438 4.711 12.801 c 9.648\n"    \
  "17.887 l S\n"                                                                 \
  "0.729412 0.741176 0.713725 RG 16.645 13.035 m 12.418 8.707 l\n"               \
  "10.902 7.559 6.402 12.203 8.09 13.562 c\n"                                    \
  "14.133 19.578 l 14.949 20.387 16.867 20.184 17.539 19.465 c 20.551\n"         \
  "16.23 l 21.191 15.66 21.336 13.887 20.426 13.102 c 13.18 5.824 l 12.18\n"     \
  "4.82 6.25 3.566 4.324 5.461 c 3 7.395 3.383 12.438 4.711 13.801 c 9.648\n"    \
  "18.887 l S\n"

#define ANNOT_FILE_ATTACHMENT_AP_GRAPH                                           \
  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"       \
  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n"     \
  "l 1 21.523 2.477 23 4.301 23 c h\n"                                           \
  "4.301 23 m f\n"                                                               \
  "0.533333 0.541176 0.521569 RG 1 w\n"                                          \
  "1 J\n"                                                                        \
  "0 j\n"                                                                        \
  "[] 0.0 d\n"                                                                   \
  "4 M 18.5 15.5 m 18.5 13.086 l 16.086 15.5 l 18.5 15.5 l h\n"                  \
  "18.5 15.5 m S\n"                                                              \
  "7 7 m 10 11 l 13 9 l 18 15 l S\n"                                             \
  "0.729412 0.741176 0.713725 RG 7 8 m 10 12 l 13 10 l 18 16 l S\n"              \
  "18.5 16.5 m 18.5 14.086 l 16.086 16.5 l 18.5 16.5 l h\n"                      \
  "18.5 16.5 m S\n"                                                              \
  "0.533333 0.541176 0.521569 RG 2 w\n"                                          \
  "1 j\n"                                                                        \
  "3 19 m 3 3 l 21 3 l S\n"                                                      \
  "0.729412 0.741176 0.713725 RG 3 20 m 3 4 l 21 4 l S\n"

#define ANNOT_FILE_ATTACHMENT_AP_TAG                                             \
  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"       \
  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n"     \
  "l 1 21.523 2.477 23 4.301 23 c h\n"                                           \
  "4.301 23 m f\n"                                                               \
  "0.533333 0.541176 0.521569 RG 0.999781 w\n"                                   \
  "1 J\n"                                                                        \
  "1 j\n"                                                                        \
  "[] 0.0 d\n"                                                                   \
  "4 M q 1 0 0 -1 0 24 cm\n"                                                     \
  "8.492 8.707 m 8.492 9.535 7.82 10.207 6.992 10.207 c 6.164 10.207 5.492\n"    \
  "9.535 5.492 8.707 c 5.492 7.879 6.164 7.207 6.992 7.207 c 7.82 7.207\n"       \
  "8.492 7.879 8.492 8.707 c h\n"                                                \
  "8.492 8.707 m S Q\n"                                                          \
  "2 w\n"                                                                        \
  "20.078 11.414 m 20.891 10.602 20.785 9.293 20.078 8.586 c 14.422 2.93 l\n"    \
  "13.715 2.223 12.301 2.223 11.594 2.93 c 3.816 10.707 l 3.109 11.414\n"        \
  "2.402 17.781 3.816 19.195 c 5.23 20.609 11.594 19.902 12.301 19.195 c\n"      \
  "20.078 11.414 l h\n"                                                          \
  "20.078 11.414 m S\n"                                                          \
  "0.729412 0.741176 0.713725 RG 20.078 12.414 m\n"                              \
  "20.891 11.605 20.785 10.293 20.078 9.586 c 14.422 3.93 l\n"                   \
  "13.715 3.223 12.301 3.223 11.594 3.93 c 3.816 11.707 l 3.109 12.414\n"        \
  "2.402 18.781 3.816 20.195 c 5.23 21.609 11.594 20.902 12.301 20.195 c\n"      \
  "20.078 12.414 l h\n"                                                          \
  "20.078 12.414 m S\n"                                                          \
  "0.533333 0.541176 0.521569 RG 1 w\n"                                          \
  "0 j\n"                                                                        \
  "11.949 13.184 m 16.191 8.941 l S\n"                                           \
  "0.729412 0.741176 0.713725 RG 11.949 14.184 m 16.191 9.941 l S\n"             \
  "0.533333 0.541176 0.521569 RG 14.07 6.82 m 9.828 11.062 l S\n"                \
  "0.729412 0.741176 0.713725 RG 14.07 7.82 m 9.828 12.062 l S\n"                \
  "0.533333 0.541176 0.521569 RG 6.93 15.141 m 8 20 14.27 20.5 16 20.5 c\n"      \
  "18.094 20.504 19.5 20 19.5 18 c 19.5 16.699 20.91 16.418 22.5 16.5 c S\n"     \
  "0.729412 0.741176 0.713725 RG 0.999781 w\n"                                   \
  "1 j\n"                                                                        \
  "q 1 0 0 -1 0 24 cm\n"                                                         \
  "8.492 7.707 m 8.492 8.535 7.82 9.207 6.992 9.207 c 6.164 9.207 5.492\n"       \
  "8.535 5.492 7.707 c 5.492 6.879 6.164 6.207 6.992 6.207 c 7.82 6.207\n"       \
  "8.492 6.879 8.492 7.707 c h\n"                                                \
  "8.492 7.707 m S Q\n"                                                          \
  "1 w\n"                                                                        \
  "0 j\n"                                                                        \
  "6.93 16.141 m 8 21 14.27 21.5 16 21.5 c 18.094 21.504 19.5 21 19.5 19 c\n"    \
  "19.5 17.699 20.91 17.418 22.5 17.5 c S\n"

void AnnotFileAttachment::draw(Gfx *gfx, GBool printing) {
  Object obj;
  double ca = 1;

  if (!isVisible (printing))
    return;

  annotLocker();
  if (appearance.isNull()) {
    ca = opacity;

    appearBuf = new GooString ();

    appearBuf->append ("q\n");
    if (color)
      setColor(color, gTrue);
    else
      appearBuf->append ("1 1 1 rg\n");
    if (!name->cmp("PushPin"))
      appearBuf->append (ANNOT_FILE_ATTACHMENT_AP_PUSHPIN);
    else if (!name->cmp("Paperclip"))
      appearBuf->append (ANNOT_FILE_ATTACHMENT_AP_PAPERCLIP);
    else if (!name->cmp("Graph"))
      appearBuf->append (ANNOT_FILE_ATTACHMENT_AP_GRAPH);
    else if (!name->cmp("Tag"))
      appearBuf->append (ANNOT_FILE_ATTACHMENT_AP_TAG);
    appearBuf->append ("Q\n");

    double bbox[4];
    bbox[0] = bbox[1] = 0;
    bbox[2] = bbox[3] = 24;
    if (ca == 1) {
      createForm (bbox, gFalse, NULL, &appearance);
    } else {
      Object aStream;

      createForm (bbox, gTrue, NULL, &aStream);
      delete appearBuf;

      Object resDict;
      appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
      createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
      createForm(bbox, gFalse, &resDict, &appearance);
    }
    delete appearBuf;
  }

  // draw the appearance stream
  appearance.fetch(gfx->getXRef(), &obj);
  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
		 rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
  obj.free();
}

//------------------------------------------------------------------------
// AnnotSound
//------------------------------------------------------------------------
AnnotSound::AnnotSound(PDFDoc *docA, PDFRectangle *rect, Sound *soundA) :
    AnnotMarkup(docA, rect) {
  Object obj1;

  type = typeSound;

  annotObj.dictSet ("Subtype", obj1.initName ("Sound"));

  Object obj2;
  Stream *str = soundA->getStream();
  obj2.initStream (str);
  str->incRef(); //FIXME: initStream should do this?
  annotObj.dictSet ("Sound", &obj2);

  initialize(docA, annotObj.getDict());
}

AnnotSound::AnnotSound(PDFDoc *docA, Dict *dict, Object *obj) :
  AnnotMarkup(docA, dict, obj) {
  type = typeSound;
  initialize(docA, dict);
}

AnnotSound::~AnnotSound() {
  delete sound;

  delete name;
}

void AnnotSound::initialize(PDFDoc *docA, Dict* dict) {
  Object obj1;

  sound = Sound::parseSound(dict->lookup("Sound", &obj1));
  if (!sound) {
    error(errSyntaxError, -1, "Bad Annot Sound");
    ok = gFalse;
  }
  obj1.free();

  if (dict->lookup("Name", &obj1)->isName()) {
    name = new GooString(obj1.getName());
  } else {
    name = new GooString("Speaker");
  }
  obj1.free();
}

#define ANNOT_SOUND_AP_SPEAKER                                               \
  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"   \
  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n" \
  "l 1 21.523 2.477 23 4.301 23 c h\n"                                       \
  "4.301 23 m f\n"                                                           \
  "0.533333 0.541176 0.521569 RG 2 w\n"                                      \
  "0 J\n"                                                                    \
  "1 j\n"                                                                    \
  "[] 0.0 d\n"                                                               \
  "4 M 4 14 m 4.086 8.043 l 7 8 l 11 4 l 11 18 l 7 14 l 4 14 l h\n"          \
  "4 14 m S\n"                                                               \
  "1 w\n"                                                                    \
  "1 J\n"                                                                    \
  "0 j\n"                                                                    \
  "13.699 15.398 m 14.699 13.398 14.699 9.398 13.699 7.398 c S\n"            \
  "18.199 19.398 m 21.199 17.398 21.199 5.398 18.199 3.398 c S\n"            \
  "16 17.398 m 18 16.398 18 7.398 16 5.398 c S\n"                            \
  "0.729412 0.741176 0.713725 RG 2 w\n"                                      \
  "0 J\n"                                                                    \
  "1 j\n"                                                                    \
  "4 15 m 4.086 9.043 l 7 9 l 11 5 l 11 19 l 7 15 l 4 15 l h\n"              \
  "4 15 m S\n"                                                               \
  "1 w\n"                                                                    \
  "1 J\n"                                                                    \
  "0 j\n"                                                                    \
  "13.699 16 m 14.699 14 14.699 10 13.699 8 c S\n"                           \
  "18.199 20 m 21.199 18 21.199 6 18.199 4 c S\n"                            \
  "16 18 m 18 17 18 8 16 6 c S\n"

#define ANNOT_SOUND_AP_MIC                                                        \
  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"        \
  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n"      \
  "l 1 21.523 2.477 23 4.301 23 c h\n"                                            \
  "4.301 23 m f\n"                                                                \
  "0.533333 0.541176 0.521569 RG 2 w\n"                                           \
  "1 J\n"                                                                         \
  "0 j\n"                                                                         \
  "[] 0.0 d\n"                                                                    \
  "4 M 12 20 m 12 20 l 13.656 20 15 18.656 15 17 c 15 13 l 15 11.344 13.656 10\n" \
  "12 10 c 12 10 l 10.344 10 9 11.344 9 13 c 9 17 l 9 18.656 10.344 20 12\n"      \
  "20 c h\n"                                                                      \
  "12 20 m S\n"                                                                   \
  "1 w\n"                                                                         \
  "17.5 14.5 m 17.5 11.973 l 17.5 8.941 15.047 6.5 12 6.5 c 8.953 6.5 6.5\n"      \
  "8.941 6.5 11.973 c 6.5 14.5 l S\n"                                             \
  "2 w\n"                                                                         \
  "0 J\n"                                                                         \
  "12 6.52 m 12 3 l S\n"                                                          \
  "1 J\n"                                                                         \
  "8 3 m 16 3 l S\n"                                                              \
  "0.729412 0.741176 0.713725 RG 12 21 m 12 21 l 13.656 21 15 19.656 15 18 c\n"   \
  "15 14 l 15 12.344 13.656 11 12 11 c 12 11 l 10.344 11 9 12.344 9 14 c\n"       \
  "9 18 l 9 19.656 10.344 21 12 21 c h\n"                                         \
  "12 21 m S\n"                                                                   \
  "1 w\n"                                                                         \
  "17.5 15.5 m 17.5 12.973 l 17.5 9.941 15.047 7.5 12 7.5 c 8.953 7.5 6.5\n"      \
  "9.941 6.5 12.973 c 6.5 15.5 l S\n"                                             \
  "2 w\n"                                                                         \
  "0 J\n"                                                                         \
  "12 7.52 m 12 4 l S\n"                                                          \
  "1 J\n"                                                                         \
  "8 4 m 16 4 l S\n"

void AnnotSound::draw(Gfx *gfx, GBool printing) {
  Object obj;
  double ca = 1;

  if (!isVisible (printing))
    return;

  annotLocker();
  if (appearance.isNull()) {
    ca = opacity;

    appearBuf = new GooString ();

    appearBuf->append ("q\n");
    if (color)
      setColor(color, gTrue);
    else
      appearBuf->append ("1 1 1 rg\n");
    if (!name->cmp("Speaker"))
      appearBuf->append (ANNOT_SOUND_AP_SPEAKER);
    else if (!name->cmp("Mic"))
      appearBuf->append (ANNOT_SOUND_AP_MIC);
    appearBuf->append ("Q\n");

    double bbox[4];
    bbox[0] = bbox[1] = 0;
    bbox[2] = bbox[3] = 24;
    if (ca == 1) {
      createForm(bbox, gFalse, NULL, &appearance);
    } else {
      Object aStream, resDict;

      createForm(bbox, gTrue, NULL, &aStream);
      delete appearBuf;

      appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
      createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
      createForm(bbox, gFalse, &resDict, &appearance);
    }
    delete appearBuf;
  }

  // draw the appearance stream
  appearance.fetch(gfx->getXRef(), &obj);
  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
		 rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
  obj.free();
}

//------------------------------------------------------------------------
// Annot3D
//------------------------------------------------------------------------
Annot3D::Annot3D(PDFDoc *docA, PDFRectangle *rect) :
    Annot(docA, rect) {
  Object obj1;

  type = type3D;

  annotObj.dictSet ("Subtype", obj1.initName ("3D"));

  initialize(docA, annotObj.getDict());
}

Annot3D::Annot3D(PDFDoc *docA, Dict *dict, Object *obj) :
  Annot(docA, dict, obj) {
  type = type3D;
  initialize(docA, dict);
}

Annot3D::~Annot3D() {
  if (activation)
    delete activation;
}

void Annot3D::initialize(PDFDoc *docA, Dict* dict) {
  Object obj1;

  if (dict->lookup("3DA", &obj1)->isDict()) {
    activation = new Activation(obj1.getDict());
  } else {
    activation = NULL;
  }
  obj1.free();
}

Annot3D::Activation::Activation(Dict *dict) {
  Object obj1;

  if (dict->lookup("A", &obj1)->isName()) {
    const char *name = obj1.getName();

    if(!strcmp(name, "PO")) {
      aTrigger = aTriggerPageOpened;
    } else if(!strcmp(name, "PV")) {
      aTrigger = aTriggerPageVisible;
    } else if(!strcmp(name, "XA")) {
      aTrigger = aTriggerUserAction;
    } else {
      aTrigger = aTriggerUnknown;
    }
  } else {
    aTrigger = aTriggerUnknown;
  }
  obj1.free();

  if(dict->lookup("AIS", &obj1)->isName()) {
    const char *name = obj1.getName();

    if(!strcmp(name, "I")) {
      aState = aStateEnabled;
    } else if(!strcmp(name, "L")) {
      aState = aStateDisabled;
    } else {
      aState = aStateUnknown;
    }
  } else {
    aState = aStateUnknown;
  }
  obj1.free();

  if(dict->lookup("D", &obj1)->isName()) {
    const char *name = obj1.getName();

    if(!strcmp(name, "PC")) {
      dTrigger = dTriggerPageClosed;
    } else if(!strcmp(name, "PI")) {
      dTrigger = dTriggerPageInvisible;
    } else if(!strcmp(name, "XD")) {
      dTrigger = dTriggerUserAction;
    } else {
      dTrigger = dTriggerUnknown;
    }
  } else {
    dTrigger = dTriggerUnknown;
  }
  obj1.free();

  if(dict->lookup("DIS", &obj1)->isName()) {
    const char *name = obj1.getName();

    if(!strcmp(name, "U")) {
      dState = dStateUninstantiaded;
    } else if(!strcmp(name, "I")) {
      dState = dStateInstantiated;
    } else if(!strcmp(name, "L")) {
      dState = dStateLive;
    } else {
      dState = dStateUnknown;
    }
  } else {
    dState = dStateUnknown;
  }
  obj1.free();

  if (dict->lookup("TB", &obj1)->isBool()) {
    displayToolbar = obj1.getBool();
  } else {
    displayToolbar = gTrue;
  }
  obj1.free();

  if (dict->lookup("NP", &obj1)->isBool()) {
    displayNavigation = obj1.getBool();
  } else {
    displayNavigation = gFalse;
  }
  obj1.free();
}

//------------------------------------------------------------------------
// AnnotRichMedia
//------------------------------------------------------------------------
AnnotRichMedia::AnnotRichMedia(PDFDoc *docA, PDFRectangle *rect) :
    Annot(docA, rect) {
  Object obj1;

  type = typeRichMedia;

  annotObj.dictSet ("Subtype", obj1.initName ("RichMedia"));

  initialize(docA, annotObj.getDict());
}

AnnotRichMedia::AnnotRichMedia(PDFDoc *docA, Dict *dict, Object *obj) :
  Annot(docA, dict, obj) {
  type = typeRichMedia;
  initialize(docA, dict);
}

AnnotRichMedia::~AnnotRichMedia() {
  delete content;
  delete settings;
}

void AnnotRichMedia::initialize(PDFDoc *docA, Dict* dict) {
  Object obj1;

  if (dict->lookup("RichMediaContent", &obj1)->isDict()) {
    content = new AnnotRichMedia::Content(obj1.getDict());
  } else {
    content = NULL;
  }
  obj1.free();

  if (dict->lookup("RichMediaSettings", &obj1)->isDict()) {
    settings = new AnnotRichMedia::Settings(obj1.getDict());
  } else {
    settings = NULL;
  }
  obj1.free();
}

AnnotRichMedia::Content* AnnotRichMedia::getContent() const {
  return content;
}

AnnotRichMedia::Settings* AnnotRichMedia::getSettings() const {
  return settings;
}

AnnotRichMedia::Settings::Settings(Dict *dict) {
  Object obj1;

  if (dict->lookup("Activation", &obj1)->isDict()) {
    activation = new AnnotRichMedia::Activation(obj1.getDict());
  } else {
    activation = NULL;
  }
  obj1.free();

  if (dict->lookup("Deactivation", &obj1)->isDict()) {
    deactivation = new AnnotRichMedia::Deactivation(obj1.getDict());
  } else {
    deactivation = NULL;
  }
  obj1.free();
}

AnnotRichMedia::Settings::~Settings() {
  delete activation;
  delete deactivation;
}

AnnotRichMedia::Activation* AnnotRichMedia::Settings::getActivation() const {
  return activation;
}

AnnotRichMedia::Deactivation* AnnotRichMedia::Settings::getDeactivation() const {
  return deactivation;
}

AnnotRichMedia::Activation::Activation(Dict *dict) {
  Object obj1;

  if (dict->lookup("Condition", &obj1)->isName()) {
    const char *name = obj1.getName();

    if (!strcmp(name, "PO")) {
      condition = conditionPageOpened;
    } else if (!strcmp(name, "PV")) {
      condition = conditionPageVisible;
    } else if (!strcmp(name, "XA")) {
      condition = conditionUserAction;
    } else {
      condition = conditionUserAction;
    }
  } else {
    condition = conditionUserAction;
  }
  obj1.free();
}

AnnotRichMedia::Activation::Condition AnnotRichMedia::Activation::getCondition() const {
  return condition;
}

AnnotRichMedia::Deactivation::Deactivation(Dict *dict) {
  Object obj1;

  if (dict->lookup("Condition", &obj1)->isName()) {
    const char *name = obj1.getName();

    if (!strcmp(name, "PC")) {
      condition = conditionPageClosed;
    } else if (!strcmp(name, "PI")) {
      condition = conditionPageInvisible;
    } else if (!strcmp(name, "XD")) {
      condition = conditionUserAction;
    } else {
      condition = conditionUserAction;
    }
  } else {
    condition = conditionUserAction;
  }
  obj1.free();
}

AnnotRichMedia::Deactivation::Condition AnnotRichMedia::Deactivation::getCondition() const {
  return condition;
}

AnnotRichMedia::Content::Content(Dict *dict) {
  Object obj1;

  if (dict->lookup("Configurations", &obj1)->isArray()) {
    nConfigurations = obj1.arrayGetLength();

    configurations = (Configuration **)gmallocn(nConfigurations, sizeof(Configuration *));

    for (int i = 0; i < nConfigurations; ++i) {
      Object obj2;

      if (obj1.arrayGet(i, &obj2)->isDict()) {
        configurations[i] = new AnnotRichMedia::Configuration(obj2.getDict());
      } else {
        configurations[i] = NULL;
      }
      obj2.free();
    }
  } else {
    nConfigurations = 0;
    configurations = NULL;
  }
  obj1.free();

  nAssets = 0;
  assets = NULL;
  if (dict->lookup("Assets", &obj1)->isDict()) {
    Object obj2;

    if (obj1.getDict()->lookup("Names", &obj2)->isArray()) {
      nAssets = obj2.arrayGetLength() / 2;

      assets = (Asset **)gmallocn(nAssets, sizeof(Asset *));

      int counter = 0;
      for (int i = 0; i < obj2.arrayGetLength(); i += 2) {
        Object objKey;

        assets[counter] = new AnnotRichMedia::Asset;

        obj2.arrayGet(i, &objKey);
        obj2.arrayGet(i + 1, &assets[counter]->fileSpec);

        assets[counter]->name = new GooString( objKey.getString() );
        ++counter;

        objKey.free();
      }
    }
    obj2.free();
  }
  obj1.free();
}

AnnotRichMedia::Content::~Content() {
  if (configurations) {
    for (int i = 0; i < nConfigurations; ++i)
      delete configurations[i];
    gfree(configurations);
  }

  if (assets) {
    for (int i = 0; i < nAssets; ++i)
      delete assets[i];
    gfree(assets);
  }
}

int AnnotRichMedia::Content::getConfigurationsCount() const {
  return nConfigurations;
}

AnnotRichMedia::Configuration* AnnotRichMedia::Content::getConfiguration(int index) const {
  if (index < 0 || index >= nConfigurations)
    return NULL;

  return configurations[index];
}

int AnnotRichMedia::Content::getAssetsCount() const {
  return nAssets;
}

AnnotRichMedia::Asset* AnnotRichMedia::Content::getAsset(int index) const {
  if (index < 0 || index >= nAssets)
    return NULL;

  return assets[index];
}

AnnotRichMedia::Asset::Asset()
  : name(NULL)
{
}

AnnotRichMedia::Asset::~Asset()
{
  delete name;
  fileSpec.free();
}

GooString* AnnotRichMedia::Asset::getName() const {
  return name;
}

Object* AnnotRichMedia::Asset::getFileSpec() const {
  return const_cast<Object*>(&fileSpec);
}

AnnotRichMedia::Configuration::Configuration(Dict *dict)
{
  Object obj1;

  if (dict->lookup("Instances", &obj1)->isArray()) {
    nInstances = obj1.arrayGetLength();

    instances = (Instance **)gmallocn(nInstances, sizeof(Instance *));

    for (int i = 0; i < nInstances; ++i) {
      Object obj2;

      if (obj1.arrayGet(i, &obj2)->isDict()) {
        instances[i] = new AnnotRichMedia::Instance(obj2.getDict());
      } else {
        instances[i] = NULL;
      }
      obj2.free();
    }
  } else {
    instances = NULL;
  }
  obj1.free();

  if (dict->lookup("Name", &obj1)->isString()) {
    name = new GooString(obj1.getString());
  } else {
    name = NULL;
  }
  obj1.free();

  if (dict->lookup("Subtype", &obj1)->isName()) {
    const char *name = obj1.getName();

    if (!strcmp(name, "3D")) {
      type = type3D;
    } else if (!strcmp(name, "Flash")) {
      type = typeFlash;
    } else if (!strcmp(name, "Sound")) {
      type = typeSound;
    } else if (!strcmp(name, "Video")) {
      type = typeVideo;
    } else {
      // determine from first instance
      if (instances && nInstances > 0) {
        AnnotRichMedia::Instance *instance = instances[0];
        switch (instance->getType()) {
          case AnnotRichMedia::Instance::type3D:
            type = type3D;
            break;
          case AnnotRichMedia::Instance::typeFlash:
            type = typeFlash;
            break;
          case AnnotRichMedia::Instance::typeSound:
            type = typeSound;
            break;
          case AnnotRichMedia::Instance::typeVideo:
            type = typeVideo;
            break;
          default:
            type = typeFlash;
            break;
        }
      }
    }
  }
  obj1.free();
}

AnnotRichMedia::Configuration::~Configuration()
{
  if (instances) {
    for (int i = 0; i < nInstances; ++i)
      delete instances[i];
    gfree(instances);
  }

  delete name;
}

int AnnotRichMedia::Configuration::getInstancesCount() const {
  return nInstances;
}

AnnotRichMedia::Instance* AnnotRichMedia::Configuration::getInstance(int index) const {
  if (index < 0 || index >= nInstances)
    return NULL;

  return instances[index];
}

GooString* AnnotRichMedia::Configuration::getName() const {
  return name;
}

AnnotRichMedia::Configuration::Type AnnotRichMedia::Configuration::getType() const {
  return type;
}

AnnotRichMedia::Instance::Instance(Dict *dict)
{
  Object obj1;

  dict->lookup("Subtype", &obj1);
  const char *name = obj1.isName() ? obj1.getName() : "";

  if (!strcmp(name, "3D")) {
    type = type3D;
  } else if (!strcmp(name, "Flash")) {
    type = typeFlash;
  } else if (!strcmp(name, "Sound")) {
    type = typeSound;
  } else if (!strcmp(name, "Video")) {
    type = typeVideo;
  } else {
    type = typeFlash;
  }
  obj1.free();

  if (dict->lookup("Params", &obj1)->isDict()) {
    params = new AnnotRichMedia::Params(obj1.getDict());
  } else {
    params = NULL;
  }
  obj1.free();
}

AnnotRichMedia::Instance::~Instance()
{
  delete params;
}

AnnotRichMedia::Instance::Type AnnotRichMedia::Instance::getType() const {
  return type;
}

AnnotRichMedia::Params* AnnotRichMedia::Instance::getParams() const {
  return params;
}

AnnotRichMedia::Params::Params(Dict *dict)
{
  Object obj1;

  if (dict->lookup("FlashVars", &obj1)->isString()) {
    flashVars = new GooString(obj1.getString());
  } else {
    flashVars = NULL;
  }
  obj1.free();
}

AnnotRichMedia::Params::~Params()
{
  delete flashVars;
}

GooString* AnnotRichMedia::Params::getFlashVars() const {
  return flashVars;
}

//------------------------------------------------------------------------
// Annots
//------------------------------------------------------------------------

Annots::Annots(PDFDoc *docA, int page, Object *annotsObj) {
  Annot *annot;
  Object obj1;
  int i;

  doc = docA;
  annots = NULL;
  size = 0;
  nAnnots = 0;

  if (annotsObj->isArray()) {
    for (i = 0; i < annotsObj->arrayGetLength(); ++i) {
      //get the Ref to this annot and pass it to Annot constructor 
      //this way, it'll be possible for the annot to retrieve the corresponding
      //form widget
      Object obj2;
      if (annotsObj->arrayGet(i, &obj1)->isDict()) {
        annotsObj->arrayGetNF(i, &obj2);
        annot = createAnnot (obj1.getDict(), &obj2);
        if (annot) {
          if (annot->isOk()) {
            annot->setPage(page, gFalse); // Don't change /P
            appendAnnot(annot);
          }
          annot->decRefCnt();
        }
      }
      obj2.free();
      obj1.free();
    }
  }
}

void Annots::appendAnnot(Annot *annot) {
  if (annot && annot->isOk()) {
    if (nAnnots >= size) {
      size += 16;
      annots = (Annot **)greallocn(annots, size, sizeof(Annot *));
    }
    annots[nAnnots++] = annot;
    annot->incRefCnt();
  }
}

GBool Annots::removeAnnot(Annot *annot) {
  int idx = -1;
  // Search annot and determine its index
  for (int i = 0; idx == -1 && i < nAnnots; i++) {
    if (annots[i] == annot) {
      idx = i;
    }
  }
  if (idx == -1) {
    return gFalse;
  } else {
    --nAnnots;
    memmove( annots + idx, annots + idx + 1, sizeof(annots[0]) * (nAnnots - idx) );
    annot->decRefCnt();
    return gTrue;
  }
}

Annot *Annots::createAnnot(Dict* dict, Object *obj) {
  Annot *annot = NULL;
  Object obj1;

  if (dict->lookup("Subtype", &obj1)->isName()) {
    const char *typeName = obj1.getName();

    if (!strcmp(typeName, "Text")) {
      annot = new AnnotText(doc, dict, obj);
    } else if (!strcmp(typeName, "Link")) {
      annot = new AnnotLink(doc, dict, obj);
    } else if (!strcmp(typeName, "FreeText")) {
      annot = new AnnotFreeText(doc, dict, obj);
    } else if (!strcmp(typeName, "Line")) {
      annot = new AnnotLine(doc, dict, obj);
    } else if (!strcmp(typeName, "Square")) {
      annot = new AnnotGeometry(doc, dict, obj);
    } else if (!strcmp(typeName, "Circle")) {
      annot = new AnnotGeometry(doc, dict, obj);
    } else if (!strcmp(typeName, "Polygon")) {
      annot = new AnnotPolygon(doc, dict, obj);
    } else if (!strcmp(typeName, "PolyLine")) {
      annot = new AnnotPolygon(doc, dict, obj);
    } else if (!strcmp(typeName, "Highlight")) {
      annot = new AnnotTextMarkup(doc, dict, obj);
    } else if (!strcmp(typeName, "Underline")) {
      annot = new AnnotTextMarkup(doc, dict, obj);
    } else if (!strcmp(typeName, "Squiggly")) {
      annot = new AnnotTextMarkup(doc, dict, obj);
    } else if (!strcmp(typeName, "StrikeOut")) {
      annot = new AnnotTextMarkup(doc, dict, obj);
    } else if (!strcmp(typeName, "Stamp")) {
      annot = new AnnotStamp(doc, dict, obj);
    } else if (!strcmp(typeName, "Caret")) {
      annot = new AnnotCaret(doc, dict, obj);
    } else if (!strcmp(typeName, "Ink")) {
      annot = new AnnotInk(doc, dict, obj);
    } else if (!strcmp(typeName, "FileAttachment")) {
      annot = new AnnotFileAttachment(doc, dict, obj);
    } else if (!strcmp(typeName, "Sound")) {
      annot = new AnnotSound(doc, dict, obj);
    } else if(!strcmp(typeName, "Movie")) {
      annot = new AnnotMovie(doc, dict, obj);
    } else if(!strcmp(typeName, "Widget")) {
      // Find the annot in forms
      if (obj->isRef()) {
        Form *form = doc->getCatalog()->getForm();
        if (form) {
          FormWidget *widget = form->findWidgetByRef(obj->getRef());
          if (widget) {
            annot = widget->getWidgetAnnotation();
            annot->incRefCnt();
          }
        }
      }
      if (!annot)
        annot = new AnnotWidget(doc, dict, obj);
    } else if(!strcmp(typeName, "Screen")) {
      annot = new AnnotScreen(doc, dict, obj);
    } else if(!strcmp(typeName, "PrinterMark")) {
      annot = new Annot(doc, dict, obj);
    } else if (!strcmp(typeName, "TrapNet")) {
      annot = new Annot(doc, dict, obj);
    } else if (!strcmp(typeName, "Watermark")) {
      annot = new Annot(doc, dict, obj);
    } else if (!strcmp(typeName, "3D")) {
      annot = new Annot3D(doc, dict, obj);
    } else if (!strcmp(typeName, "RichMedia")) {
      annot = new AnnotRichMedia(doc, dict, obj);
    } else if (!strcmp(typeName, "Popup")) {
      /* Popup annots are already handled by markup annots
       * Here we only care about popup annots without a
       * markup annotation associated
       */
      Object obj2;

      if (dict->lookup("Parent", &obj2)->isNull())
        annot = new AnnotPopup(doc, dict, obj);
      else
        annot = NULL;
      
      obj2.free();
    } else {
      annot = new Annot(doc, dict, obj);
    }
  }
  obj1.free();

  return annot;
}

Annot *Annots::findAnnot(Ref *ref) {
  int i;

  for (i = 0; i < nAnnots; ++i) {
    if (annots[i]->match(ref)) {
      return annots[i];
    }
  }
  return NULL;
}


Annots::~Annots() {
  int i;

  for (i = 0; i < nAnnots; ++i) {
    annots[i]->decRefCnt();
  }
  gfree(annots);
}
