//========================================================================
//
// 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-2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2007-2013, 2018 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, 2019 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, 2017 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>
// Copyright (C) 2017 Hans-Ulrich Jüttner <huj@froreich-bioscientia.de>
// Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
// Copyright 2018 Andre Heinecke <aheinecke@intevation.de>
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
// Copyright (C) 2018 Dileep Sankhla <sankhla.dileep96@gmail.com>
// Copyright (C) 2018, 2019 Tobias Deiminger <haxtibal@posteo.de>
// Copyright (C) 2018, 2019 Oliver Sander <oliver.sander@tu-dresden.de>
// Copyright (C) 2019 Umang Malik <umang99m@gmail.com>
// Copyright (C) 2019 João Netto <joaonetto901@gmail.com>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#include <config.h>

#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include "goo/gmem.h"
#include "goo/gstrtod.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>

#ifndef M_PI
#define M_PI 3.14159265358979323846
#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

static AnnotLineEndingStyle parseAnnotLineEndingStyle(const GooString *string) {
  if (string != nullptr) {
    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;
  }  
}

static 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) {
  AnnotExternalDataType type;

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

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

  return type;
}

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

    // 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) {
      auto newRect = std::make_unique<PDFRectangle>();
      newRect->x1 = rect->x1 + dx1;
      newRect->y1 = rect->y1 + dy1;
      newRect->x2 = rect->x2 - dx2;
      newRect->y2 = rect->y2 - dy2;
      return newRect;
    }
  }
  return nullptr;
}

static LinkAction* getAdditionalAction(Annot::AdditionalActionsType type, Object *additionalActions, PDFDoc *doc) {
  LinkAction *linkAction = nullptr;
  Object additionalActionsObject = additionalActions->fetch(doc->getXRef());

  if (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 ?      "Bl" :
                       type == Annot::actionPageOpening ?   "PO" :
                       type == Annot::actionPageClosing ?   "PC" :
                       type == Annot::actionPageVisible ?   "PV" :
                       type == Annot::actionPageInvisible ? "PI" : nullptr);

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

  return linkAction;
}

static const char *getFormAdditionalActionKey(Annot::FormAdditionalActionsType type)
{
    return (type == Annot::actionFieldModified ?  "K" :
            type == Annot::actionFormatField ?    "F" :
            type == Annot::actionValidateField ?  "V" :
            type == Annot::actionCalculateField ? "C" : nullptr);
}

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

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

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

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

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

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

AnnotPath::AnnotPath() = default;

AnnotPath::AnnotPath(Array *array) {
  parsePathArray(array);
}

AnnotPath::AnnotPath(std::vector<AnnotCoord> &&coordsA) {
  coords = std::move(coordsA);
}

AnnotPath::~AnnotPath() = default;

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

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

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

void AnnotPath::parsePathArray(Array *array) {
  if (array->getLength() % 2) {
    error(errSyntaxError, -1, "Bad Annot Path");
    return;
  }

  const auto tempLength = array->getLength() / 2;
  std::vector<AnnotCoord> tempCoords;
  tempCoords.reserve(tempLength);
  for (int i = 0; i < tempLength; i++) {
    double x = 0, y = 0;

    Object obj1 = array->get(i * 2);
    if (obj1.isNum()) {
      x = obj1.getNum();
    } else {
      return;
    }

    obj1 = array->get((i * 2) + 1);
    if (obj1.isNum()) {
      y = obj1.getNum();
    } else {
      return;
    }

    tempCoords.emplace_back(x, y);
  }

  coords = std::move(tempCoords);
}

//------------------------------------------------------------------------
// 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();
  int quadsLength = 0;
  double quadArray[8];

  // default values
  quadrilateralsLength = 0;

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

    quadsLength = arrayLength / 8;
    auto quads = std::make_unique<AnnotQuadrilateral[]>(quadsLength);
    for (i = 0; i < quadsLength; i++) {
      for (int j = 0; j < 8; j++) {
        Object obj = array->get(i * 8 + j);
        if (obj.isNum()) {
          quadArray[j] = obj.getNum();
        } else {
	    error (errSyntaxError, -1, "Invalid QuadPoint in annot");
	    return;
        }
      }

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


    quadrilateralsLength = quadsLength;
    quadrilaterals = std::move(quads);
  }
}

AnnotQuadrilaterals::AnnotQuadrilaterals(std::unique_ptr<AnnotQuadrilateral[]> &&quads, int quadsLength) {
  quadrilaterals = std::move(quads);
  quadrilateralsLength = quadsLength;
}

AnnotQuadrilaterals::~AnnotQuadrilaterals() = default;

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() = default;

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 = nullptr;
  style = borderSolid;
}

bool AnnotBorder::parseDashArray(Object *dashObj) {
  bool correct = true;
  const 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++) {
    const Object obj1 = dashObj->arrayGet(i);
    if (obj1.isNum()) {
      tempDash[i] = obj1.getNum();

      correct = tempDash[i] >= 0;
    } else {
      correct = false;
    }
  }

  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();

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

    obj1 = array->get(0);
    if (obj1.isNum())
      horizontalCorner = obj1.getNum();
    else
      correct = false;

    obj1 = array->get(1);
    if (obj1.isNum())
      verticalCorner = obj1.getNum();
    else
      correct = false;

    obj1 = array->get(2);
    if (obj1.isNum())
      width = obj1.getNum();
    else
      correct = false;

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

Object AnnotBorderArray::writeToObject(XRef *xref) const {
  Array *borderArray = new Array(xref);
  borderArray->add(Object(horizontalCorner));
  borderArray->add(Object(verticalCorner));
  borderArray->add(Object(width));

  if (dashLength > 0) {
    Array *a = new Array(xref);

    for (int i = 0; i < dashLength; i++)
      a->add(Object(dash[i]));

    borderArray->add(Object(a));
  }

  return Object(borderArray);
}

//------------------------------------------------------------------------
// 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 verifying both entries exist
  // otherwise we set the borderWidth to 0
  // --jrmuizel
  obj1 = dict->lookup("W");
  obj2 = dict->lookup("S");
  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;
  }

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

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

Object AnnotBorderBS::writeToObject(XRef *xref) const {
  Dict *dict = new Dict(xref);
  dict->set("W", Object(width));
  dict->set("S", Object(objName, getStyleName()));
  if (style == borderDashed && dashLength > 0) {
    Array *a = new Array(xref);

    for (int i = 0; i < dashLength; i++)
      a->add(Object(dash[i]));
    dict->set("D", Object(a));
  }
  return Object(dict);
}

//------------------------------------------------------------------------
// 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 = array->get(i);
    if (obj1.isNum()) {
      values[i] = obj1.getNum();

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

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

Object AnnotColor::writeToObject(XRef *xref) const {
  if (length == 0) {
    return Object(objNull); // Transparent (no color)
  } else {
    Array *a = new Array(xref);
    for (int i = 0; i < length; ++i)
      a->add( Object( values[i] ) );
    return Object(a);
  }
}

//------------------------------------------------------------------------
// DefaultAppearance
//------------------------------------------------------------------------

DefaultAppearance::DefaultAppearance(Object &&fontNameA, double fontPtSizeA, std::unique_ptr<AnnotColor> fontColorA) :
    fontName(std::move(fontNameA)), fontPtSize(fontPtSizeA), fontColor(std::move(fontColorA)) {
}

DefaultAppearance::DefaultAppearance(GooString *da) {
  fontPtSize = -1;

  if (da) {
    std::vector<GooString*> * daToks = new std::vector<GooString*>();
    int i = FormFieldText::tokenizeDA(da, daToks, "Tf");

    if (i >= 1) {
      fontPtSize = gatof( (*daToks)[i-1]->c_str());
    }
    if (i >= 2) {
      // We are expecting a name, therefore the first letter should be '/'.
      const GooString* fontToken = (*daToks)[i-2];
      if (fontToken && fontToken->getLength() > 1 && fontToken->getChar(0) == '/') {
        // The +1 is here to skip the leading '/'.
        fontName = Object(objName, fontToken->c_str() + 1);
      }
    }
    // Scan backwards: we are looking for the last set value
    for (i = daToks->size()-1; i >= 0; --i) {
      if (!fontColor) {
        if (!((*daToks)[i])->cmp("g") && i >= 1) {
          fontColor = std::make_unique<AnnotColor>(gatof(( (*daToks)[i-1] )->c_str()));
        } else if (!((*daToks)[i])->cmp("rg") && i >= 3) {
          fontColor = std::make_unique<AnnotColor>(gatof(( (*daToks)[i-3] )->c_str()),
                                                   gatof(( (*daToks)[i-2] )->c_str()),
                                                   gatof(( (*daToks)[i-1] )->c_str()));
        } else if (!((*daToks)[i])->cmp("k") && i >= 4) {
          fontColor = std::make_unique<AnnotColor>(gatof(( (*daToks)[i-4] )->c_str()),
                                                   gatof(( (*daToks)[i-3] )->c_str()),
                                                   gatof(( (*daToks)[i-2] )->c_str()),
                                                   gatof(( (*daToks)[i-1] )->c_str()));
        }
      }
    }
    for (auto entry : *daToks) {
      delete entry;
    }
    delete daToks;
  }
}

void DefaultAppearance::setFontName(Object &&fontNameA) {
  fontName = std::move(fontNameA);
}

void DefaultAppearance::setFontPtSize(double fontPtSizeA) {
  fontPtSize = fontPtSizeA;
}

void DefaultAppearance::setFontColor(std::unique_ptr<AnnotColor> fontColorA) {
  fontColor = std::move(fontColorA);
}

GooString *DefaultAppearance::toAppearanceString() const {
  AnnotAppearanceBuilder appearBuilder;
  if (fontColor) {
    appearBuilder.setDrawColor(fontColor.get(), true);
  }
  appearBuilder.setTextFont(fontName, fontPtSize);
  return appearBuilder.buffer()->copy();
}

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

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

  obj1 = dict->lookup("SW");
  if (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 = dict->lookup("S");
  if (obj1.isName()) {
    const char *scaleName = obj1.getName();

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

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

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

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

  } else {
    left = bottom = 0.5;
  }

  obj1 = dict->lookup("FB");
  if (obj1.isBool()) {
    fullyBounds = obj1.getBool();
  } else {
    fullyBounds = false;
  }
}

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

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

AnnotAppearance::~AnnotAppearance() {
}

Object AnnotAppearance::getAppearanceStream(AnnotAppearanceType type, const char *state) {
  Object apData;

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

  if (apData.isDict() && state)
    return apData.dictLookupNF(state).copy();
  else if (apData.isRef())
    return apData;

  return Object();
}

std::unique_ptr<GooString> AnnotAppearance::getStateKey(int i) {
  const Object &obj1 = appearDict.dictLookupNF("N");
  if (obj1.isDict())
    return std::make_unique<GooString>(obj1.dictGetKey(i));
  return nullptr;
}

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

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

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

  // Scan each state's ref/subdictionary
  const Object &objN = appearDict.dictLookupNF("N");
  found = referencesStream(&objN, refToStream);
  if (found)
    return true;

  const Object &objR = appearDict.dictLookupNF("R");
  found = referencesStream(&objR, refToStream);
  if (found)
    return true;

  const Object &objD = appearDict.dictLookupNF("D");
  found = referencesStream(&objD, refToStream);
  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
  doc->getXRef()->removeIndirectObject(refToStream);
}

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

void AnnotAppearance::removeAllStreams() {
  const Object &objN = appearDict.dictLookupNF("N");
  removeStateStreams(&objN);
  const Object &objR = appearDict.dictLookupNF("R");
  removeStateStreams(&objR);
  const Object &objD = appearDict.dictLookupNF("D");
  removeStateStreams(&objD);
}

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

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

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

  obj1 = dict->lookup("BC");
  if (obj1.isArray()) {
    Array *colorComponents = obj1.getArray();
    if (colorComponents->getLength() > 0) {
      borderColor = std::make_unique<AnnotColor>(colorComponents);
    }
  }

  obj1 = dict->lookup("BG");
  if (obj1.isArray()) {
    Array *colorComponents = obj1.getArray();
    if (colorComponents->getLength() > 0) {
      backColor = std::make_unique<AnnotColor>(colorComponents);
    }
  }

  obj1 = dict->lookup("CA");
  if (obj1.isString()) {
    normalCaption = std::make_unique<GooString>(obj1.getString());
  }

  obj1 = dict->lookup("RC");
  if (obj1.isString()) {
    rolloverCaption = std::make_unique<GooString>(obj1.getString());
  }

  obj1 = dict->lookup("AC");
  if (obj1.isString()) {
    alternateCaption = std::make_unique<GooString>(obj1.getString());
  }

  obj1 = dict->lookup("IF");
  if (obj1.isDict()) {
    iconFit = std::make_unique<AnnotIconFit>(obj1.getDict());
  }

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

AnnotAppearanceCharacs::~AnnotAppearanceCharacs() = default;

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

#define annotLocker()   std::unique_lock<std::recursive_mutex> locker(mutex)

Annot::Annot(PDFDoc *docA, PDFRectangle *rectA) {

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

  Array *a = new Array(docA->getXRef());
  a->add(Object(rectA->x1));
  a->add(Object(rectA->y1));
  a->add(Object(rectA->x2));
  a->add(Object(rectA->y2));

  annotObj = Object(new Dict(docA->getXRef()));
  annotObj.dictSet ("Type", Object(objName, "Annot"));
  annotObj.dictSet ("Rect", Object(a));

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

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

Annot::Annot(PDFDoc *docA, Object &&dictObject) {
  refCnt = 1;
  hasRef = false;
  flags = flagUnknown;
  type = typeUnknown;
  annotObj = std::move(dictObject);
  initialize (docA, annotObj.getDict());
}

Annot::Annot(PDFDoc *docA, Object &&dictObject, const Object *obj) {
  refCnt = 1;
  if (obj->isRef()) {
    hasRef = true;
    ref = obj->getRef();
  } else {
    hasRef = false;
  }
  flags = flagUnknown;
  type = typeUnknown;
  annotObj = std::move(dictObject);
  initialize (docA, annotObj.getDict());
}

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

  ok = true;
  doc = docA;

  appearance.setToNull();

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

    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 = false;
  }

  obj1 = dict->lookup("Contents");
  if (obj1.isString()) {
    contents.reset(obj1.getString()->copy());
  } else {
    contents = std::make_unique<GooString>();
  }

  // Note: This value is overwritten by Annots ctor
  const Object &pObj = dict->lookupNF("P");
  if (pObj.isRef()) {
    const Ref pRef = pObj.getRef();

    page = doc->getCatalog()->findPage (pRef);
  } else {
    page = 0;
  }

  obj1 = dict->lookup("NM");
  if (obj1.isString()) {
    name.reset(obj1.getString()->copy());
  }

  obj1 = dict->lookup("M");
  if (obj1.isString()) {
    modified.reset(obj1.getString()->copy());
  }

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

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

  //----- get the appearance state
  asObj = dict->lookup("AS");
  if (asObj.isName()) {
    appearState = std::make_unique<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 = std::make_unique<GooString>("Off");
  }

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

  //----- 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.
  obj1 = dict->lookup("Border");
  if (obj1.isArray()) {
    border = std::make_unique<AnnotBorderArray>(obj1.getArray());
  }

  obj1 = dict->lookup("C");
  if (obj1.isArray()) {
    color = std::make_unique<AnnotColor>(obj1.getArray());
  }

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

  oc = dict->lookupNF("OC").copy();
}

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 *rectA) {
    setRect(rectA->x1, rectA->y1, rectA->x2, rectA->y2);
}

void Annot::setRect(double x1, double y1, double x2, double y2) {
  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;
  }

  Array *a = new Array(doc->getXRef());
  a->add(Object(rect->x1));
  a->add(Object(rect->y1));
  a->add(Object(rect->x2));
  a->add(Object(rect->y2));

  update("Rect", Object(a));
  invalidateAppearance();
}

bool 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) {
    modified.reset(timeToDateString(nullptr));

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

  annotObj.dictSet(const_cast<char*>(key), std::move(value));
  
  doc->getXRef()->setModifiedObject(&annotObj, ref);
}

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

  if (new_content) {
    contents = std::make_unique<GooString>(new_content);
    //append the unicode marker <FE FF> if needed	
    if (!contents->hasUnicodeMarker()) {
      contents->prependUnicodeMarker();
    }
  } else {
    contents = std::make_unique<GooString>();
  }
  
  update ("Contents", Object(contents->copy()));
}

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

  if (new_name) {
    name = std::make_unique<GooString>(new_name);
  } else {
    name = std::make_unique<GooString>();
  }

  update ("NM", Object(name->copy()));
}

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

  if (new_modified)
    modified = std::make_unique<GooString>(new_modified);
  else
    modified = std::make_unique<GooString>();

  update ("M", Object(modified->copy()));
}

void Annot::setFlags(unsigned int new_flags) {
  annotLocker();
  flags = new_flags;
  update ("F", Object(int(flags)));
}

void Annot::setBorder(std::unique_ptr<AnnotBorder> &&new_border) {
  annotLocker();

  if (new_border) {
    Object obj1 = new_border->writeToObject(doc->getXRef());
    update(new_border->getType() == AnnotBorder::typeArray ? "Border" : "BS", std::move(obj1));
    border = std::move(new_border);
  } else {
    border = nullptr;
  }
  invalidateAppearance();
}

void Annot::setColor(std::unique_ptr<AnnotColor> &&new_color) {
  annotLocker();

  if (new_color) {
    Object obj1 = new_color->writeToObject(doc->getXRef());
    update ("C", std::move(obj1));
    color = std::move(new_color);
  } else {
    color = nullptr;
  }
  invalidateAppearance();
}

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

  if (pageobj) {
    const Ref pageRef = pageobj->getRef();
    obj1 = Object(pageRef);
    page = pageIndex;
  } else {
    page = 0;
  }

  if (updateP) {
    update("P", std::move(obj1));
  }
}

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

  appearState = std::make_unique<GooString>(state);
  appearBBox = nullptr;

  update ("AS", Object(objName, state));

  // The appearance state determines the current appearance stream
  if (appearStreams) {
    appearance = appearStreams->getAppearanceStream(AnnotAppearance::appearNormal, appearState->c_str());
  } else {
    appearance.setToNull();
  }
}

void Annot::invalidateAppearance() {
  annotLocker();
  if (appearStreams) { // Remove existing appearance streams
    appearStreams->removeAllStreams();
  }
  appearStreams = nullptr;
  appearState = nullptr;
  appearBBox = nullptr;
  appearance.setToNull();

  Object obj2 = annotObj.dictLookup("AP");
  if (!obj2.isNull())
    update ("AP", Object(objNull)); // Remove AP

  obj2 = annotObj.dictLookup("AS");
  if (!obj2.isNull())
    update ("AS", Object(objNull)); // Remove AS
}

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);
  if (valueObject.isNum()) {
    *value = valueObject.getNum();
  } else {
    *value = 0;
    ok = false;
  }
}

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

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

void Annot::decRefCnt() {
  if (--refCnt == 0) {
    delete this;
  }
}

Annot::~Annot() {}

void AnnotAppearanceBuilder::setDrawColor(const AnnotColor *drawColor, bool fill) {
  const double *values = drawColor->getValues();

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

void AnnotAppearanceBuilder::setTextFont(const Object &fontName, double fontSize) {
  if (fontName.isName() && strlen(fontName.getName()) > 0)
    appearBuf->appendf("/{0:s} {1:.2f} Tf\n", fontName.getName(), fontSize);
}

void AnnotAppearanceBuilder::setLineStyleForBorder(const 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 AnnotAppearanceBuilder::drawCircle(double cx, double cy, double r, bool 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 AnnotAppearanceBuilder::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 AnnotAppearanceBuilder::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 AnnotAppearanceBuilder::drawLineEndSquare(double x, double y, double size, bool fill, const Matrix& m) {
  const double halfSize {size/2.};
  const double x1[3] {x - size, x - size, x};
  const double y1[3] {y + halfSize, y - halfSize, y - halfSize};
  double tx, ty;

  m.transform (x, y + halfSize, &tx, &ty);
  appendf ("{0:.2f} {1:.2f} m\n", tx, ty);
  for (int i = 0; i<3; i++) {
    m.transform (x1[i], y1[i], &tx, &ty);
    appendf ("{0:.2f} {1:.2f} l\n", tx, ty);
  }
  appearBuf->append(fill ? "b\n" : "s\n");
}

void AnnotAppearanceBuilder::drawLineEndCircle(double x, double y, double size, bool fill, const Matrix& m) {
  const double halfSize {size/2.};
  const double x1[4] {x, x - halfSize - bezierCircle * halfSize, x - size, x - halfSize + bezierCircle * halfSize};
  const double x2[4] {x - halfSize + bezierCircle * halfSize, x - size, x - halfSize- bezierCircle * halfSize, x};
  const double x3[4] {x - halfSize, x - size, x - halfSize, x};
  const double y1[4] {y + bezierCircle * halfSize, y + halfSize, y - bezierCircle * halfSize, y - halfSize};
  const double y2[4] {y + halfSize, y + bezierCircle * halfSize, y - halfSize, y - bezierCircle * halfSize};
  const double y3[4] {y + halfSize, y, y - halfSize, y};
  double tx[3];
  double ty[3];

  m.transform(x, y, &tx[0], &ty[0]);
  appearBuf->appendf("{0:.2f} {1:.2f} m\n", tx[0], ty[0]);
  for (int i=0; i<4; i++) {
    m.transform(x1[i], y1[i], &tx[0], &ty[0]);
    m.transform(x2[i], y2[i], &tx[1], &ty[1]);
    m.transform(x3[i], y3[i], &tx[2], &ty[2]);
    appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
        tx[0], ty[0], tx[1], ty[1], tx[2], ty[2]);
  }
  appearBuf->append(fill ? "b\n" : "s\n");
}

void AnnotAppearanceBuilder::drawLineEndDiamond(double x, double y, double size, bool fill, const Matrix& m) {
  const double halfSize {size/2.};
  const double x1[3] {x - halfSize, x - size, x - halfSize};
  const double y1[3] {y + halfSize, y, y - halfSize};
  double tx, ty;

  m.transform (x, y, &tx, &ty);
  appendf ("{0:.2f} {1:.2f} m\n", tx, ty);
  for (int i = 0; i<3; i++) {
    m.transform (x1[i], y1[i], &tx, &ty);
    appendf ("{0:.2f} {1:.2f} l\n", tx, ty);
  }
  appearBuf->append(fill ? "b\n" : "s\n");
}

void AnnotAppearanceBuilder::drawLineEndArrow(double x, double y, double size, int orientation, bool isOpen, bool fill, const Matrix& m) {
  const double alpha {M_PI/6.};
  const double xOffs {orientation * size};
  const double yOffs {tan(alpha) * size};
  double tx, ty;

  m.transform (x - xOffs, y+yOffs, &tx, &ty);
  appendf ("{0:.2f} {1:.2f} m\n", tx, ty);
  m.transform (x, y, &tx, &ty);
  appendf ("{0:.2f} {1:.2f} l\n", tx, ty);
  m.transform (x - xOffs, y-yOffs, &tx, &ty);
  appendf ("{0:.2f} {1:.2f} l\n", tx, ty);

  if (isOpen) {
    appearBuf->append("S\n");
  } else {
    appearBuf->append(fill ? "b\n" : "s\n");
  }
}

void AnnotAppearanceBuilder::drawLineEndSlash(double x, double y, double size, const Matrix& m) {
  const double halfSize {size/2.};
  const double xOffs {cos(M_PI/3.) * halfSize};
  double tx, ty;

  m.transform (x - xOffs, y - halfSize, &tx, &ty);
  appendf ("{0:.2f} {1:.2f} m\n", tx, ty);
  m.transform (x + xOffs, y + halfSize, &tx, &ty);
  appendf ("{0:.2f} {1:.2f} l\n", tx, ty);
  appearBuf->append("S\n");
}

void AnnotAppearanceBuilder::drawLineEnding(AnnotLineEndingStyle endingStyle, double x, double y, double size, bool fill, const Matrix& m) {
  switch(endingStyle) {
  case annotLineEndingSquare:
    drawLineEndSquare(x, y, size, fill, m);
    break;
  case annotLineEndingCircle:
    drawLineEndCircle(x, y, size, fill, m);
    break;
  case annotLineEndingDiamond:
    drawLineEndDiamond(x, y, size, fill, m);
    break;
  case annotLineEndingOpenArrow:
    drawLineEndArrow(x, y, size, 1, true, fill, m);
    break;
  case annotLineEndingClosedArrow:
    drawLineEndArrow(x, y, size, 1, false, fill, m);
    break;
  case annotLineEndingButt:
    {
      const double halfSize {size/2.};
      double tx, ty;
      m.transform (x, y + halfSize, &tx, &ty);
      appendf ("{0:.2f} {1:.2f} m\n", tx, ty);
      m.transform (x, y - halfSize, &tx, &ty);
      appendf ("{0:.2f} {1:.2f} l S\n", tx, ty);
    }
    break;
  case annotLineEndingROpenArrow:
    drawLineEndArrow(x, y, size, -1, true, fill, m);
    break;
  case annotLineEndingRClosedArrow:
    drawLineEndArrow(x, y, size, -1, false, fill, m);
    break;
  case annotLineEndingSlash:
    drawLineEndSlash(x, y, size, m);
    break;
  default:
    break;
  }
}

double AnnotAppearanceBuilder::lineEndingXShorten(AnnotLineEndingStyle endingStyle, double size) {
  switch(endingStyle) {
  case annotLineEndingCircle:
  case annotLineEndingClosedArrow:
  case annotLineEndingDiamond:
  case annotLineEndingSquare:
    return size;
  default:
    break;
  }
  return 0;
}

double AnnotAppearanceBuilder::lineEndingXExtendBBox(AnnotLineEndingStyle endingStyle, double size) {
  switch(endingStyle) {
  case annotLineEndingRClosedArrow:
  case annotLineEndingROpenArrow:
    return size;
  case annotLineEndingSlash:
    return cos(M_PI/3.) * size/2.;
  default:
    break;
  }
  return 0;
}

Object Annot::createForm(const GooString *appearBuf, double *bbox, bool transparencyGroup, Dict *resDict) {
  return createForm(appearBuf, bbox, transparencyGroup, resDict ? Object(resDict) : Object());
}

Object Annot::createForm(const GooString *appearBuf, double *bbox, bool transparencyGroup, Object &&resDictObject) {
  Dict *appearDict = new Dict(doc->getXRef());
  appearDict->set("Length", Object(appearBuf->getLength()));
  appearDict->set("Subtype", Object(objName, "Form"));

  Array *a = new Array(doc->getXRef());
  a->add(Object(bbox[0]));
  a->add(Object(bbox[1]));
  a->add(Object(bbox[2]));
  a->add(Object(bbox[3]));
  appearDict->set("BBox", Object(a));
  if (transparencyGroup) {
    Dict *d = new Dict(doc->getXRef());
    d->set("S", Object(objName, "Transparency"));
    appearDict->set("Group", Object(d));
  }
  if (resDictObject.isDict())
    appearDict->set("Resources", std::move(resDictObject));

  Stream *mStream = new AutoFreeMemStream(copyString(appearBuf->c_str()), 0,
				     appearBuf->getLength(), Object(appearDict));
  return Object(mStream);
}

Dict *Annot::createResourcesDict(const char *formName, Object &&formStream,
				const char *stateName,
				double opacity, const char *blendMode) {
  Dict *gsDict = new Dict(doc->getXRef());
  if (opacity != 1) {
    gsDict->set("CA", Object(opacity));
    gsDict->set("ca", Object(opacity));
  }
  if (blendMode)
    gsDict->set("BM", Object(objName, blendMode));
  Dict *stateDict = new Dict(doc->getXRef());
  stateDict->set(stateName, Object(gsDict));
  Dict *formDict = new Dict(doc->getXRef());
  formDict->set(formName, std::move(formStream));

  Dict *resDict = new Dict(doc->getXRef());
  resDict->set("ExtGState", Object(stateDict));
  resDict->set("XObject", Object(formDict));

  return resDict;
}

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

  // Fetch appearance's resource dict (if any)
  obj1 = appearance.fetch(doc->getXRef());
  if (obj1.isStream()) {
    obj2 = obj1.streamGetDict()->lookup("Resources");
    if (obj2.isDict()) {
      return obj2;
    }
  }

  return Object(objNull);
}

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

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

  return true;
}

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

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

void Annot::draw(Gfx *gfx, bool printing) {
  annotLocker();
  if (!isVisible (printing))
    return;

  // draw the appearance stream
  Object obj = appearance.fetch(gfx->getXRef());
  gfx->drawAnnot(&obj, nullptr, color.get(),
      rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
}

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

AnnotPopup::AnnotPopup(PDFDoc *docA, PDFRectangle *rectA) :
    Annot(docA, rectA) {
  type = typePopup;

  annotObj.dictSet ("Subtype", Object(objName, "Popup"));
  initialize (docA, annotObj.getDict());
}

AnnotPopup::AnnotPopup(PDFDoc *docA, Object &&dictObject, const Object *obj) :
    Annot(docA, std::move(dictObject), obj) {
  type = typePopup;
  initialize(docA, annotObj.getDict());
}

AnnotPopup::~AnnotPopup() {
}

void AnnotPopup::initialize(PDFDoc *docA, Dict *dict) {
  const Object &parentObj = dict->lookupNF("Parent");
  if (parentObj.isRef()) {
    parentRef = parentObj.getRef();
  } else {
    parentRef = Ref::INVALID();
  }

  Object obj1 = dict->lookup("Open");
  if (obj1.isBool()) {
    open = obj1.getBool();
  } else {
    open = false;
  }
}

void AnnotPopup::setParent(Annot *parentA) {
  parentRef = parentA->getRef();
  update ("Parent", Object(parentRef));
}

void AnnotPopup::setOpen(bool openA) {
  open = openA;
  update ("Open", Object(open));
}

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

AnnotMarkup::AnnotMarkup(PDFDoc *docA, Object &&dictObject, const Object *obj) :
    Annot(docA, std::move(dictObject), obj) {
  initialize(docA, annotObj.getDict());
}

AnnotMarkup::~AnnotMarkup() = default;

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

  obj1 = dict->lookup("T");
  if (obj1.isString()) {
    label.reset(obj1.getString()->copy());
  }

  Object popupObj = dict->lookup("Popup");
  const Object &obj2 = dict->lookupNF("Popup");
  if (popupObj.isDict() && obj2.isRef()) {
    popup = std::make_unique<AnnotPopup>(docA, std::move(popupObj), &obj2);
  }

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

  obj1 = dict->lookup("CreationDate");
  if (obj1.isString()) {
    date.reset(obj1.getString()->copy());
  }

  const Object &irtObj = dict->lookupNF("IRT");
  if (irtObj.isRef()) {
    inReplyTo = irtObj.getRef();
  } else {
    inReplyTo = Ref::INVALID();
  }

  obj1 = dict->lookup("Subj");
  if (obj1.isString()) {
    subject.reset(obj1.getString()->copy());
  }

  obj1 = dict->lookup("RT");
  if (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 = dict->lookup("ExData");
  if (obj1.isDict()) {
    exData = parseAnnotExternalData(obj1.getDict());
  } else {
    exData = annotExternalDataMarkupUnknown;
  }
}

void AnnotMarkup::setLabel(GooString *new_label) {
  if (new_label) {
    label = std::make_unique<GooString>(new_label);
    //append the unicode marker <FE FF> if needed
    if (!label->hasUnicodeMarker()) {
      label->prependUnicodeMarker();
    }
  } else {
    label = std::make_unique<GooString>();
  }

  update ("T", Object(label->copy()));
}

void AnnotMarkup::setPopup(std::unique_ptr<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 && popup->getPageNum() != 0) {
    Page *pageobj = doc->getPage(popup->getPageNum());
    if (pageobj) {
      pageobj->removeAnnot(popup.get());
    }
  }

  if (new_popup) {
    const Ref popupRef = new_popup->getRef();
    update ("Popup", Object(popupRef));

    new_popup->setParent(this);
    popup = std::move(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 != nullptr); // pageobj should exist in doc (see setPage())

      pageobj->addAnnot(popup.get());
    }
  } else {
    popup = nullptr;
  }
}

void AnnotMarkup::setOpacity(double opacityA) {
  opacity = opacityA;
  update ("CA", Object(opacity));
  invalidateAppearance();
}

void AnnotMarkup::setDate(GooString *new_date) {
  if (new_date)
    date = std::make_unique<GooString>(new_date);
  else
    date = std::make_unique<GooString>();

  update ("CreationDate", Object(date->copy()));
}

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

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

  Annot::removeReferencedObjects();
}

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

AnnotText::AnnotText(PDFDoc *docA, PDFRectangle *rectA) :
    AnnotMarkup(docA, rectA) {
  type = typeText;
  flags |= flagNoZoom | flagNoRotate;

  annotObj.dictSet ("Subtype", Object(objName, "Text"));
  initialize (docA, annotObj.getDict());
}

AnnotText::AnnotText(PDFDoc *docA, Object &&dictObject, const Object *obj) :
    AnnotMarkup(docA, std::move(dictObject), obj) {

  type = typeText;
  flags |= flagNoZoom | flagNoRotate;
  initialize (docA, annotObj.getDict());
}

AnnotText::~AnnotText() = default;

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

  obj1 = dict->lookup("Open");
  if (obj1.isBool())
    open = obj1.getBool();
  else
    open = false;

  obj1 = dict->lookup("Name");
  if (obj1.isName()) {
    icon = std::make_unique<GooString>(obj1.getName());
  } else {
    icon = std::make_unique<GooString>("Note");
  }

  obj1 = dict->lookup("StateModel");
  if (obj1.isString()) {
    const GooString *modelName = obj1.getString();

    Object obj2 = dict->lookup("State");
    if (obj2.isString()) {
      const 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;
    }

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

void AnnotText::setOpen(bool openA) {
  open = openA;
  update ("Open", Object(open));
}

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

  if (new_icon) {
    icon = std::make_unique<GooString>(new_icon);
  } else {
    icon = std::make_unique<GooString>("Note");
  }

  update("Name", Object(objName, icon->c_str()));
  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, bool printing) {
  double ca = 1;

  if (!isVisible (printing))
    return;

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

    AnnotAppearanceBuilder appearBuilder;

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

    // Force 24x24 rectangle
    PDFRectangle fixedRect(rect->x1, rect->y2 - 24, rect->x1 + 24, rect->y2);
    appearBBox = std::make_unique<AnnotAppearanceBBox>(&fixedRect);
    double bbox[4];
    appearBBox->getBBoxRect(bbox);
    if (ca == 1) {
      appearance = createForm(appearBuilder.buffer(), bbox, false, nullptr);
    } else {
      Object aStream = createForm(appearBuilder.buffer(), bbox, true, nullptr);

      GooString appearBuf("/GS0 gs\n/Fm0 Do");
      Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, nullptr);
      appearance = createForm(&appearBuf, bbox, false, resDict);
    }
  }

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

//------------------------------------------------------------------------
// AnnotLink
//------------------------------------------------------------------------
AnnotLink::AnnotLink(PDFDoc *docA, PDFRectangle *rectA) :
    Annot(docA, rectA) {
  type = typeLink;
  annotObj.dictSet ("Subtype", Object(objName, "Link"));
  initialize (docA, annotObj.getDict());
}

AnnotLink::AnnotLink(PDFDoc *docA, Object &&dictObject, const Object *obj) :
    Annot(docA, std::move(dictObject), obj) {

  type = typeLink;
  initialize (docA, annotObj.getDict());
}

AnnotLink::~AnnotLink() = default;

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

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

  obj1 = dict->lookup("H");
  if (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 = dict->lookup("PA");
  if (obj1.isDict()) {
    uriAction = NULL;
  } else {
    uriAction = NULL;
  }
  obj1.free();
  */
  obj1 = dict->lookup("QuadPoints");
  if (obj1.isArray()) {
    quadrilaterals = std::make_unique<AnnotQuadrilaterals>(obj1.getArray(), rect.get());
  }

  obj1 = dict->lookup("BS");
  if (obj1.isDict()) {
    border = std::make_unique<AnnotBorderBS>(obj1.getDict());
  } else if (!border) {
    border = std::make_unique<AnnotBorderBS>();
  }
}

void AnnotLink::draw(Gfx *gfx, bool printing) {
  if (!isVisible (printing))
    return;

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

//------------------------------------------------------------------------
// AnnotFreeText
//------------------------------------------------------------------------
const double AnnotFreeText::undefinedFontPtSize = 10.;

AnnotFreeText::AnnotFreeText(PDFDoc *docA, PDFRectangle *rectA, const DefaultAppearance &da) :
    AnnotMarkup(docA, rectA) {
  type = typeFreeText;

  GooString *daStr = da.toAppearanceString();
  annotObj.dictSet ("Subtype", Object(objName, "FreeText"));
  annotObj.dictSet("DA", Object(daStr));

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

AnnotFreeText::AnnotFreeText(PDFDoc *docA, Object &&dictObject, const Object *obj) :
    AnnotMarkup(docA, std::move(dictObject), obj) {
  type = typeFreeText;
  initialize(docA, annotObj.getDict());
}

AnnotFreeText::~AnnotFreeText() = default;

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

  obj1 = dict->lookup("DA");
  if (obj1.isString()) {
    appearanceString.reset(obj1.getString()->copy());
  } else {
    appearanceString = std::make_unique<GooString>();
    error(errSyntaxWarning, -1, "Bad appearance for annotation");
  }

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

  obj1 = dict->lookup("DS");
  if (obj1.isString()) {
    styleString.reset(obj1.getString()->copy());
  }

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

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

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

  obj1 = dict->lookup("IT");
  if (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 = dict->lookup("BS");
  if (obj1.isDict()) {
    border = std::make_unique<AnnotBorderBS>(obj1.getDict());
  } else if (!border) {
    border = std::make_unique<AnnotBorderBS>();
  }

  obj1 = dict->lookup("BE");
  if (obj1.isDict()) {
    borderEffect = std::make_unique<AnnotBorderEffect>(obj1.getDict());
  }

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

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

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

void AnnotFreeText::setDefaultAppearance(const DefaultAppearance &da) {
  appearanceString = std::unique_ptr<GooString>(da.toAppearanceString());

  update ("DA", Object(appearanceString->copy()));
  invalidateAppearance();
}

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

void AnnotFreeText::setStyleString(GooString *new_string) {
  if (new_string) {
    styleString = std::make_unique<GooString>(new_string);
    //append the unicode marker <FE FF> if needed
    if (!styleString->hasUnicodeMarker()) {
      styleString->prependUnicodeMarker();
    }
  } else {
    styleString = std::make_unique<GooString>();
  }

  update ("DS", Object(styleString->copy()));
}

void AnnotFreeText::setCalloutLine(AnnotCalloutLine *line) {
  Object obj1;
  if (line == nullptr) {
    obj1.setToNull();
    calloutLine = nullptr;
  } else {
    double x1 = line->getX1(), y1 = line->getY1();
    double x2 = line->getX2(), y2 = line->getY2();
    obj1 = Object( new Array(doc->getXRef()) );
    obj1.arrayAdd( Object(x1) );
    obj1.arrayAdd( Object(y1) );
    obj1.arrayAdd( Object(x2) );
    obj1.arrayAdd( Object(y2) );

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

  update("CL", std::move(obj1));
  invalidateAppearance();
}

void AnnotFreeText::setIntent(AnnotFreeTextIntent new_intent) {
  const char *intentName;

  intent = new_intent;
  if (new_intent == intentFreeText)
    intentName = "FreeText";
  else if (new_intent == intentFreeTextCallout)
    intentName = "FreeTextCallout";
  else // intentFreeTextTypeWriter
    intentName = "FreeTextTypeWriter";
  update ("IT", Object(objName, intentName));
}

std::unique_ptr<DefaultAppearance> AnnotFreeText::getDefaultAppearance() const {
  return std::make_unique<DefaultAppearance>(appearanceString.get());
}

static GfxFont * createAnnotDrawFont(XRef * xref, Dict *fontResDict, const char* resourceName = "AnnotDrawFont", const char* fontname = "Helvetica")
{
  const Ref dummyRef = {-1, -1};

  Dict *fontDict = new Dict(xref);
  fontDict->add("BaseFont", Object(objName, fontname));
  fontDict->add("Subtype", Object(objName, "Type0"));
  fontDict->add("Encoding", Object(objName, "WinAnsiEncoding"));

  Dict *fontsDict = new Dict(xref);
  fontsDict->add(resourceName, Object(fontDict));

  fontResDict->add("Font", Object(fontsDict));

  return GfxFont::makeFont(xref, resourceName, dummyRef, fontDict);
}

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

  AnnotAppearanceBuilder appearBuilder;
  appearBuilder.append ("q\n");

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

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

  // Parse some properties from the appearance string
  DefaultAppearance da{appearanceString.get()};

  // Default values
  if (!da.getFontName().isName())
    da.setFontName(Object(objName, "AnnotDrawFont"));
  if (da.getFontPtSize() <= 0)
    da.setFontPtSize(undefinedFontPtSize);
  if (!da.getFontColor())
    da.setFontColor(std::make_unique<AnnotColor>(0, 0, 0));
  if (!contents)
    contents = std::make_unique<GooString>();

  // Draw box
  bool doFill = (color && color->getSpace() != AnnotColor::colorTransparent);
  bool doStroke = (borderWidth != 0);
  if (doFill || doStroke) {
    if (doStroke) {
      appearBuilder.setDrawColor(da.getFontColor(), false); // Border color: same as font color
    }
    appearBuilder.appendf ("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re\n", borderWidth/2, width-borderWidth, height-borderWidth);
    if (doFill) {
      appearBuilder.setDrawColor(color.get(), true);
      appearBuilder.append(doStroke ? "B\n" : "f\n");
    } else {
      appearBuilder.append("S\n");
    }
  }

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

  GfxFont *font = nullptr;

  // look for font name in the default resources
  Form *form = doc->getCatalog()->getForm(); // form is owned by catalog, no need to clean it up

  Object resourceObj;
  if (form && form->getDefaultResourcesObj() && form->getDefaultResourcesObj()->isDict()) {
    resourceObj = form->getDefaultResourcesObj()->copy(); // No real copy, but increment refcount of /DR Dict

    Dict *resDict = resourceObj.getDict();
    Object fontResources = resDict->lookup("Font");  // The 'Font' subdictionary

    if (!fontResources.isDict()) {
      error(errSyntaxWarning, -1, "Font subdictionary is not a dictionary");
    } else {
      // Get the font dictionary for the actual requested font
      Ref fontReference;
      Object fontDictionary = fontResources.getDict()->lookup(da.getFontName().getName(), &fontReference);

      if (fontDictionary.isDict()) {
        font = GfxFont::makeFont(doc->getXRef(), da.getFontName().getName(), fontReference, fontDictionary.getDict());
      } else {
        error(errSyntaxWarning, -1, "Font dictionary is not a dictionary");
      }
    }
  }

  // if fontname is not in the default resources, create a Helvetica fake font
  if (!font) {
    Dict *fontResDict = new Dict(doc->getXRef());
    resourceObj = Object(fontResDict);
    font = createAnnotDrawFont(doc->getXRef(), fontResDict, da.getFontName().getName());
  }

  // Set font state
  appearBuilder.setDrawColor(da.getFontColor(), true);
  appearBuilder.appendf ("BT 1 0 0 1 {0:.2f} {1:.2f} Tm\n", textmargin, height - textmargin - da.getFontPtSize() * font->getDescent());
  appearBuilder.setTextFont(da.getFontName(), da.getFontPtSize());

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

  font->decRefCnt();
  appearBuilder.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) {
    appearance = createForm(appearBuilder.buffer(), bbox, false, std::move(resourceObj));
  } else {
    Object aStream = createForm(appearBuilder.buffer(), bbox, true, std::move(resourceObj));

    GooString appearBuf("/GS0 gs\n/Fm0 Do");
    Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, nullptr);
    appearance = createForm(&appearBuf, bbox, false, resDict);
  }
}

void AnnotFreeText::draw(Gfx *gfx, bool printing) {
  if (!isVisible (printing))
    return;

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

  // draw the appearance stream
  Object obj = appearance.fetch(gfx->getXRef());
  gfx->drawAnnot(&obj, nullptr, color.get(),
                 rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
}

// 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() {
  if (appearance.isNull()) {
    generateFreeTextAppearance();
  }
  return Annot::getAppearanceResDict();
}

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

AnnotLine::AnnotLine(PDFDoc *docA, PDFRectangle *rectA) :
    AnnotMarkup(docA, rectA) {
  type = typeLine;
  annotObj.dictSet ("Subtype", Object(objName, "Line"));

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

AnnotLine::AnnotLine(PDFDoc *docA, Object &&dictObject, const Object *obj) :
    AnnotMarkup(docA, std::move(dictObject), obj) {
  type = typeLine;
  initialize(docA, annotObj.getDict());
}

AnnotLine::~AnnotLine() = default;

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

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

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

    coord1 = std::make_unique<AnnotCoord>(x1, y1);
    coord2 = std::make_unique<AnnotCoord>(x2, y2);
  } else {
    coord1 = std::make_unique<AnnotCoord>();
    coord2 = std::make_unique<AnnotCoord>();
  }

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

    obj2 = obj1.arrayGet(0);
    if (obj2.isName()) {
      GooString leName(obj2.getName());
      startStyle = parseAnnotLineEndingStyle(&leName);
    } else {
      startStyle = annotLineEndingNone;
    }

    obj2 = obj1.arrayGet(1);
    if (obj2.isName()) {
      GooString leName(obj2.getName());
      endStyle = parseAnnotLineEndingStyle(&leName);
    } else {
      endStyle = annotLineEndingNone;
    }

  } else {
    startStyle = endStyle = annotLineEndingNone;
  }

  obj1 = dict->lookup("IC");
  if (obj1.isArray()) {
    interiorColor = std::make_unique<AnnotColor>(obj1.getArray());
  }

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

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

    if (leaderLineExtension < 0)
      leaderLineExtension = 0;
  } else {
    leaderLineExtension = 0;
  }

  obj1 = dict->lookup("Cap");
  if (obj1.isBool()) {
    caption = obj1.getBool();
  } else {
    caption = false;
  }

  obj1 = dict->lookup("IT");
  if (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 = dict->lookup("LLO");
  if (obj1.isNum()) {
    leaderLineOffset = obj1.getNum();

    if (leaderLineOffset < 0)
      leaderLineOffset = 0;
  } else {
    leaderLineOffset = 0;
  }

  obj1 = dict->lookup("CP");
  if (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 = dict->lookup("Measure");
  if (obj1.isDict()) {
    measure = nullptr;
  } else {
    measure = nullptr;
  }

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

    obj2 = obj1.arrayGet(0);
    captionTextHorizontal = obj2.isNum() ? obj2.getNum() : 0;
    obj2 = obj1.arrayGet(1);
    captionTextVertical = obj2.isNum() ? obj2.getNum() : 0;
  } else {
    captionTextHorizontal = captionTextVertical = 0;
  }

  obj1 = dict->lookup("BS");
  if (obj1.isDict()) {
    border = std::make_unique<AnnotBorderBS>(obj1.getDict());
  } else if (!border) {
    border = std::make_unique<AnnotBorderBS>();
  }
}

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

void AnnotLine::setVertices(double x1, double y1, double x2, double y2) {
  coord1 = std::make_unique<AnnotCoord>(x1, y1);
  coord2 = std::make_unique<AnnotCoord>(x2, y2);

  Array *lArray = new Array(doc->getXRef());
  lArray->add( Object(x1) );
  lArray->add( Object(y1) );
  lArray->add( Object(x2) );
  lArray->add( Object(y2) );

  update("L", Object(lArray));
  invalidateAppearance();
}

void AnnotLine::setStartEndStyle(AnnotLineEndingStyle start, AnnotLineEndingStyle end) {
  startStyle = start;
  endStyle = end;

  Array *leArray = new Array(doc->getXRef());
  leArray->add( Object(objName, convertAnnotLineEndingStyle( startStyle )) );
  leArray->add( Object(objName, convertAnnotLineEndingStyle( endStyle )) );

  update("LE", Object(leArray));
  invalidateAppearance();
}

void AnnotLine::setInteriorColor(std::unique_ptr<AnnotColor> &&new_color) {
  if (new_color) {
    Object obj1 = new_color->writeToObject(doc->getXRef());
    update ("IC", std::move(obj1));
    interiorColor = std::move(new_color);
  } else {
    interiorColor = nullptr;
  }
  invalidateAppearance();
}

void AnnotLine::setLeaderLineLength(double len) {
  leaderLineLength = len;
  update ("LL", Object(len));
  invalidateAppearance();
}

void AnnotLine::setLeaderLineExtension(double len) {
  leaderLineExtension = len;
  update ("LLE", Object(len));

  // LL is required if LLE is present
  update ("LL", Object(leaderLineLength));
  invalidateAppearance();
}

void AnnotLine::setCaption(bool new_cap) {
  caption = new_cap;
  update ("Cap", Object(new_cap));
  invalidateAppearance();
}

void AnnotLine::setIntent(AnnotLineIntent new_intent) {
  const char *intentName;

  intent = new_intent;
  if (new_intent == intentLineArrow)
    intentName = "LineArrow";
  else // intentLineDimension
    intentName = "LineDimension";
  update ("IT", Object(objName, intentName));
}


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

  appearBBox = std::make_unique<AnnotAppearanceBBox>(rect.get());
  AnnotAppearanceBuilder appearBuilder;
  appearBuilder.append ("q\n");
  if (color) {
    appearBuilder.setDrawColor(color.get(), false);
  }
  if (interiorColor) {
    appearBuilder.setDrawColor(interiorColor.get(), true);
    fill = true;
  }
  appearBuilder.setLineStyleForBorder(border.get());
  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;
  const double lineendingSize = std::min(6. * borderWidth, main_len/2);

  Dict *fontResDict;
  GfxFont *font;

  // Calculate caption width and height
  if (caption) {
    fontResDict = new Dict(doc->getXRef());
    font = createAnnotDrawFont(doc->getXRef(), fontResDict);
    int lines = 0;
    int i = 0;
    while (i < contents->getLength()) {
      GooString out;
      double linewidth;
      layoutText(contents.get(), &out, &i, font, &linewidth, 0, nullptr, false);
      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 = nullptr;
    font = nullptr;
  }

  // Draw main segment
  matr.transform (AnnotAppearanceBuilder::lineEndingXShorten(startStyle, lineendingSize), leaderLineLength, &tx, &ty);
  appearBuilder.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);
    appearBuilder.appendf ("{0:.2f} {1:.2f} l S\n", tx, ty);

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

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

  if (startStyle != annotLineEndingNone) {
    const double extendX {-AnnotAppearanceBuilder::lineEndingXExtendBBox(startStyle, lineendingSize)};
    appearBuilder.drawLineEnding(startStyle, 0, leaderLineLength, -lineendingSize, fill, matr);
    matr.transform (extendX, leaderLineLength + lineendingSize/2., &tx, &ty);
    appearBBox->extendTo (tx, ty);
    matr.transform (extendX, leaderLineLength - lineendingSize/2., &tx, &ty);
    appearBBox->extendTo (tx, ty);
  }

  if (endStyle != annotLineEndingNone) {
    const double extendX {AnnotAppearanceBuilder::lineEndingXExtendBBox(endStyle, lineendingSize)};
    appearBuilder.drawLineEnding(endStyle, main_len, leaderLineLength, lineendingSize, fill, matr);
    matr.transform (main_len + extendX, leaderLineLength + lineendingSize/2., &tx, &ty);
    appearBBox->extendTo (tx, ty);
    matr.transform (main_len + extendX, leaderLineLength - lineendingSize/2., &tx, &ty);
    appearBBox->extendTo (tx, ty);
  }

  // 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)
    appearBuilder.appendf ("0 g BT /AnnotDrawFont {0:.2f} Tf\n", fontsize); // Font color: black
    appearBuilder.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);
    appearBuilder.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.get(), &out, &i, font, &linewidth, 0, nullptr, false);
      linewidth *= fontsize;
      xpos = (captionwidth - linewidth) / 2;
      appearBuilder.appendf("{0:.2f} {1:.2f} Td\n", xpos - xposPrev, -fontsize);
      appearBuilder.writeString(out);
      appearBuilder.append ("Tj\n");
      xposPrev = xpos;
    }
    appearBuilder.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);
    appearBuilder.appendf ("{0:.2f} {1:.2f} m\n", tx, ty);
    appearBBox->extendTo (tx, ty);
    matr.transform (0, sign*ll_len, &tx, &ty);
    appearBuilder.appendf ("{0:.2f} {1:.2f} l S\n", tx, ty);
    appearBBox->extendTo (tx, ty);

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

  appearBuilder.append ("Q\n");

  double bbox[4];
  appearBBox->getBBoxRect(bbox);
  if (ca == 1) {
    appearance = createForm(appearBuilder.buffer(), bbox, false, fontResDict);
  } else {
    Object aStream = createForm(appearBuilder.buffer(), bbox, true, fontResDict);

    GooString appearBuf("/GS0 gs\n/Fm0 Do");
    Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, nullptr);
    appearance = createForm(&appearBuf, bbox, false, resDict);
  }
}

void AnnotLine::draw(Gfx *gfx, bool printing) {
  if (!isVisible (printing))
    return;

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

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

// 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() {
  if (appearance.isNull()) {
    generateLineAppearance();
  }
  return Annot::getAppearanceResDict();
}

//------------------------------------------------------------------------
// AnnotTextMarkup
//------------------------------------------------------------------------
AnnotTextMarkup::AnnotTextMarkup(PDFDoc *docA, PDFRectangle *rectA, AnnotSubtype subType) :
    AnnotMarkup(docA, rectA) {
  switch (subType) {
    case typeHighlight:
      annotObj.dictSet ("Subtype", Object(objName, "Highlight"));
      break;
    case typeUnderline:
      annotObj.dictSet ("Subtype", Object(objName, "Underline"));
      break;
    case typeSquiggly:
      annotObj.dictSet ("Subtype", Object(objName, "Squiggly"));
      break;
    case typeStrikeOut:
      annotObj.dictSet ("Subtype", Object(objName, "StrikeOut"));
      break;
    default:
      assert (0 && "Invalid subtype for AnnotTextMarkup\n");
  }

  // Store dummy quadrilateral with null coordinates
  Array *quadPoints = new Array(doc->getXRef());
  for (int i = 0; i < 4*2; ++i) {
    quadPoints->add(Object(0.));
  }
  annotObj.dictSet ("QuadPoints", Object(quadPoints));

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

AnnotTextMarkup::AnnotTextMarkup(PDFDoc *docA, Object &&dictObject, const Object *obj) :
  AnnotMarkup(docA, std::move(dictObject), obj) {
  // the real type will be read in initialize()
  type = typeHighlight;
  initialize(docA, annotObj.getDict());
}

AnnotTextMarkup::~AnnotTextMarkup() = default;

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

  obj1 = dict->lookup("Subtype");
  if (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 = dict->lookup("QuadPoints");
  if (obj1.isArray()) {
    quadrilaterals = std::make_unique<AnnotQuadrilaterals>(obj1.getArray(), rect.get());
  } else {
    error(errSyntaxError, -1, "Bad Annot Text Markup QuadPoints");
    ok = false;
  }
}

void AnnotTextMarkup::setType(AnnotSubtype new_type) {
  const char *typeName = nullptr; /* squelch bogus compiler warning */

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

  type = new_type;
  update("Subtype", Object(objName, typeName));
  invalidateAppearance();
}

void AnnotTextMarkup::setQuadrilaterals(AnnotQuadrilaterals *quadPoints) {
  Array *a = new Array(doc->getXRef());

  for (int i = 0; i < quadPoints->getQuadrilateralsLength(); ++i) {
    a->add(Object(quadPoints->getX1(i)));
    a->add(Object(quadPoints->getY1(i)));
    a->add(Object(quadPoints->getX2(i)));
    a->add(Object(quadPoints->getY2(i)));
    a->add(Object(quadPoints->getX3(i)));
    a->add(Object(quadPoints->getY3(i)));
    a->add(Object(quadPoints->getX4(i)));
    a->add(Object(quadPoints->getY4(i)));
  }

  quadrilaterals = std::make_unique<AnnotQuadrilaterals>(a, rect.get());

  annotObj.dictSet ("QuadPoints", Object(a));
  invalidateAppearance();
}

void AnnotTextMarkup::draw(Gfx *gfx, bool printing) {
  double ca = 1;
  int i;

  if (!isVisible (printing))
    return;

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

    AnnotAppearanceBuilder appearBuilder;
    appearBuilder.append ("q\n");

    /* Adjust BBox */
    appearBBox = std::make_unique<AnnotAppearanceBBox>(rect.get());
    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) {
        appearBuilder.setDrawColor(color.get(), false);
      }
      appearBuilder.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);

	appearBuilder.appendf ("{0:.2f} {1:.2f} m\n", x3, y3);
	appearBuilder.appendf ("{0:.2f} {1:.2f} l\n", x4, y4);
	appearBuilder.append ("S\n");
      }
      break;
    case typeStrikeOut:
      if (color) {
        appearBuilder.setDrawColor(color.get(), false);
      }
      blendMultiply = false;
      appearBuilder.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);

	appearBuilder.appendf ("{0:.2f} {1:.2f} m\n", (x1+x3)/2., (y1+y3)/2.);
	appearBuilder.appendf ("{0:.2f} {1:.2f} l\n", (x2+x4)/2., (y2+y4)/2.);
	appearBuilder.append ("S\n");
      }
      break;
    case typeSquiggly:
      if (color) {
        appearBuilder.setDrawColor(color.get(), false);
      }
      appearBuilder.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;

        appearBuilder.appendf ("{0:.2f} {1:.2f} m\n", x1, y3+h6);
        bool down = false;
        do {
          down = !down; // Zigzag line
          x1 += 2;
          appearBuilder.appendf ("{0:.2f} {1:.2f} l\n", x1, y3 + (down ? 0 : h6));
        } while (x1 < x2);
        appearBuilder.append ("S\n");
      }
      break;
    default:
    case typeHighlight:
      if (color)
        appearBuilder.setDrawColor(color.get(), true);

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

	appearBuilder.appendf ("{0:.2f} {1:.2f} m\n", x3, y3);
	appearBuilder.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);
	appearBuilder.appendf ("{0:.2f} {1:.2f} l\n", x2, y2);
	appearBuilder.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);
	appearBuilder.append ("f\n");
      }
      appearBBox->setBorderWidth(biggestBorder);
      break;
    }
    appearBuilder.append ("Q\n");

    double bbox[4];
    bbox[0] = appearBBox->getPageXMin();
    bbox[1] = appearBBox->getPageYMin();
    bbox[2] = appearBBox->getPageXMax();
    bbox[3] = appearBBox->getPageYMax();
    Object aStream = createForm(appearBuilder.buffer(), bbox, true, nullptr);

    GooString appearBuf("/GS0 gs\n/Fm0 Do");
    Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", 1, blendMultiply ? "Multiply" : nullptr);
    if (ca == 1) {
      appearance = createForm(&appearBuf, bbox, false, resDict);
    } else {
      aStream = createForm(&appearBuf, bbox, true, resDict);

      Dict *resDict2 = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, nullptr);
      appearance = createForm(&appearBuf, bbox, false, resDict2);
    }
  }

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

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

AnnotWidget::AnnotWidget(PDFDoc *docA, Object &&dictObject, const Object *obj) :
    Annot(docA, std::move(dictObject), obj) {
  type = typeWidget;
  field = nullptr;
  initialize(docA, annotObj.getDict());
}

AnnotWidget::AnnotWidget(PDFDoc *docA, Object *dictObject, Object *obj, FormField *fieldA) :
    Annot(docA, dictObject->copy(), obj) {
  type = typeWidget;
  field = fieldA;
  initialize(docA, dictObject->getDict());
}

AnnotWidget::~AnnotWidget() = default;

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

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

  obj1 = dict->lookup("H");
  if (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 = dict->lookup("MK");
  if (obj1.isDict()) {
    appearCharacs = std::make_unique<AnnotAppearanceCharacs>(obj1.getDict());
  }

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

  additionalActions = dict->lookupNF("AA").copy();

  obj1 = dict->lookup("Parent");
  if (obj1.isDict()) {
    parent = nullptr;
  } else {
    parent = nullptr;
  }

  obj1 = dict->lookup("BS");
  if (obj1.isDict()) {
    border = std::make_unique<AnnotBorderBS>(obj1.getDict());
  }

  updatedAppearanceStream = Ref::INVALID();
}

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

LinkAction* AnnotWidget::getFormAdditionalAction(FormAdditionalActionsType formAdditionalActionType)
{
  LinkAction *linkAction = nullptr;
  Object additionalActionsObject = additionalActions.fetch(doc->getXRef());

  if (additionalActionsObject.isDict()) {
    const char *key = getFormAdditionalActionKey(formAdditionalActionType);

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

  return linkAction;
}

bool AnnotWidget::setFormAdditionalAction(FormAdditionalActionsType formAdditionalActionType, const GooString &js)
{
  Object additionalActionsObject = additionalActions.fetch(doc->getXRef());

  if (!additionalActionsObject.isDict()) {
    additionalActionsObject = Object(new Dict(doc->getXRef()));
    annotObj.dictSet("AA", additionalActionsObject.copy());
  }

  additionalActionsObject.dictSet(getFormAdditionalActionKey(formAdditionalActionType),
                                  LinkJavaScript::createObject(doc->getXRef(), js));

  if (additionalActions.isRef()) {
    doc->getXRef()->setModifiedObject(&additionalActionsObject, additionalActions.getRef());
  } else if (hasRef) {
    doc->getXRef()->setModifiedObject(&annotObj, ref);
  } else {
    error(errInternal, -1, "AnnotWidget::setFormAdditionalAction, where neither additionalActions is ref nor annotobj itself is ref");
    return false;
  }
  return true;
}

void AnnotWidget::setNewAppearance(Object &&newAppearance)
{
  if (!newAppearance.isNull()) {
    appearStreams = std::make_unique<AnnotAppearance>(doc, &newAppearance);
    update("AP", std::move(newAppearance));
  }

  if (appearStreams)
    appearance = appearStreams->getAppearanceStream(AnnotAppearance::appearNormal, appearState->c_str());
}

// 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(const GooString *text, GooString *outBuf, int *i,
                             const GfxFont *font, double *width, double widthLimit,
                             int *charCount, bool noReencode)
{
  CharCode c;
  Unicode uChar, *uAux;
  double w = 0.0;
  int uLen, n;
  double dx, dy, ox, oy;
  if (!text) {
    return;
  }
  bool unicode = text->hasUnicodeMarker();
  bool 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 = false;
  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 {
      const 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)) {
        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 {
        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 = true;
    } else {
      spacePrev = false;
    }

    // Compute width of character just output
    if (outBuf->getLength() > last_o2) {
      dx = 0.0;
      font->getNextChar(outBuf->c_str() + 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 != nullptr || charCount != nullptr) {
    const char *s = outBuf->c_str();
    int len = outBuf->getLength();

    if (width != nullptr)
      *width = 0.0;
    if (charCount != nullptr)
      *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 != nullptr)
        *width += dx;
      if (charCount != nullptr)
        *charCount += 1;

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

// Copy the given string to appearBuf, adding parentheses around it and
// escaping characters as appropriate.
void AnnotAppearanceBuilder::writeString(const GooString &str)
{
  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.
bool AnnotAppearanceBuilder::drawText(const GooString *text, const GooString *da, const GfxResources *resources,
    const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect,
    bool multiline, int comb, int quadding,
    bool txField, bool forceZapfDingbats,
    XRef *xref, bool *addedDingbatsResource,
    bool password) {
  std::vector<GooString*> *daToks;
  GooString *tok;
  GooString convertedText;
  const GfxFont *font;
  double dx, dy;
  double fontSize, fontSize2, borderWidth, x, xPrev, y, w, wMax;
  int tfPos, tmPos, j;
  int rot;
  bool freeText = false;      // true if text should be freed before return
  GfxFont *fontToFree = nullptr;

  //~ 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 std::vector<GooString*>();
    int 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->push_back(new GooString(da, i, j - i));
        i = j;
      }
    }
    for (i = 2; i < (int)daToks->size(); ++i) {
      if (i >= 2 && !((*daToks)[i])->cmp("Tf")) {
        tfPos = i - 2;
      } else if (i >= 6 && !((*daToks)[i])->cmp("Tm")) {
        tmPos = i - 6;
      }
    }
  } else {
    daToks = nullptr;
  }

  // force ZapfDingbats
  if (forceZapfDingbats) {
    assert(xref != nullptr);
    assert(addedDingbatsResource != nullptr);
    *addedDingbatsResource = false;

    if (tfPos >= 0) {
      tok = (*daToks)[tfPos];
      if (tok->cmp("/ZaDb")) {
        tok->clear();
        tok->append("/ZaDb");
      }
    }
  }
  // get the font and font size
  font = nullptr;
  fontSize = 0;
  if (tfPos >= 0) {
    tok = (*daToks)[tfPos];
    if (tok->getLength() >= 1 && tok->getChar(0) == '/') {
      if (!resources || !(font = resources->lookupFont(tok->c_str() + 1))) {
        if (forceZapfDingbats) {
          // We are forcing ZaDb but the font does not exist
          // so create a fake one
          Ref r = Ref::INVALID(); // dummy Ref, it's not used at all in this codepath
          Dict *d = new Dict(xref);
          fontToFree = new Gfx8BitFont(xref, "ZaDb", r, new GooString("ZapfDingbats"), fontType1, r, d);
          delete d;
          font = fontToFree;
          *addedDingbatsResource = true;
        } 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 = (*daToks)[tfPos + 1];
    fontSize = gatof(tok->c_str());
  } else {
    error(errSyntaxError, -1, "Missing 'Tf' operator in field's DA string");
  }
  if (!font) {
    if (daToks) {
      for (auto entry : *daToks) {
        delete entry;
      }
      delete daToks;
    }
    return false;
  }

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

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

  // 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;
        int i = 0;
        while (i < text->getLength()) {
          Annot::layoutText(text, &convertedText, &i, font, &w, wMax / fontSize, nullptr,
                     forceZapfDingbats);
          y -= fontSize;
        }
        // approximate the descender for the last line
        if (y >= 0.33 * fontSize) {
          break;
        }
      }
      if (tfPos >= 0) {
        tok = (*daToks)[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 = (*daToks)[tmPos + 4];
      tok->clear();
      tok->append('0');
      tok = (*daToks)[tmPos + 5];
      tok->clear();
      tok->appendf("{0:.2f}", y);
    }

    // write the DA string
    if (daToks) {
      for (int i = 0; i < (int)daToks->size(); ++i) {
        appearBuf->append((*daToks)[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
    int i = 0;
    xPrev = 0;
    while (i < text->getLength()) {
      Annot::layoutText(text, &convertedText, &i, font, &w, wMax / fontSize, nullptr,
                 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->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 = (*daToks)[tfPos + 1];
          tok->clear();
          tok->appendf("{0:.2f}", fontSize);
        }
      }

      int i = 0;
      Annot::layoutText(text, &convertedText, &i, font, nullptr, 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 = (*daToks)[tmPos + 4];
        tok->clear();
        tok->appendf("{0:.2f}", x);
        tok = (*daToks)[tmPos + 5];
        tok->clear();
        tok->appendf("{0:.2f}", y);
      }

      // write the DA string
      if (daToks) {
        for (i = 0; i < (int)daToks->size(); ++i) {
          appearBuf->append((*daToks)[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
      const char *s = convertedText.c_str();
      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 char_dx, char_dy, ox, oy;

        char_dx = 0.0;
        n = font->getNextChar(s, len, &code, &uAux, &uLen, &char_dx, &char_dy, &ox, &oy);
        char_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 - char_dx);
        appearBuf->appendf("{0:.2f} 0 Td\n", x - xPrev + w);

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

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

      // regular (non-comb) formatting
    } else {
      int ii = 0;
      Annot::layoutText(text, &convertedText, &ii, font, &w, 0.0, nullptr,
                 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 = (*daToks)[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 = (*daToks)[tmPos + 4];
        tok->clear();
        tok->appendf("{0:.2f}", x);
        tok = (*daToks)[tmPos + 5];
        tok->clear();
        tok->appendf("{0:.2f}", y);
      }

      // write the DA string
      if (daToks) {
        for (std::size_t i = 0; i < daToks->size(); ++i) {
          appearBuf->append((*daToks)[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->append(" Tj\n");
    }
  }
  // cleanup
  appearBuf->append("ET\n");
  appearBuf->append("Q\n");
  if (txField) {
    appearBuf->append("EMC\n");
  }
  if (daToks) {
    for (auto entry : *daToks) {
      delete entry;
    }
    delete daToks;
  }
  if (freeText) {
    delete text;
  }
  if (fontToFree) {
    fontToFree->decRefCnt();
  }

  return true;
}

// Draw the variable text or caption for a field.
bool AnnotAppearanceBuilder::drawListBox(const FormFieldChoice *fieldChoice, const AnnotBorder *border, const PDFRectangle *rect,
			      const GooString *da, const GfxResources *resources, int quadding) {
  std::vector<GooString*> *daToks;
  GooString *tok;
  GooString convertedText;
  const 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 std::vector<GooString*>();
    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->push_back(new GooString(da, i, j - i));
	i = j;
      }
    }
    for (std::size_t k = 2; k < daToks->size(); ++k) {
      if (k >= 2 && !((*daToks)[k])->cmp("Tf")) {
	tfPos = k - 2;
      } else if (k >= 6 && !((*daToks)[k])->cmp("Tm")) {
	tmPos = k - 6;
      }
    }
  } else {
    daToks = nullptr;
  }

  // get the font and font size
  font = nullptr;
  fontSize = 0;
  if (tfPos >= 0) {
    tok = (*daToks)[tfPos];
    if (tok->getLength() >= 1 && tok->getChar(0) == '/') {
      if (!resources || !(font = resources->lookupFont(tok->c_str() + 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 = (*daToks)[tfPos + 1];
    fontSize = gatof(tok->c_str());
  } else {
    error(errSyntaxError, -1, "Missing 'Tf' operator in field's DA string");
  }
  if (!font) {
    if (daToks) {
      for (auto entry : *daToks) {
        delete entry;
      }
      delete daToks;
    }
    return false;
  }

  // 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) == nullptr) {
        error(errSyntaxError, -1, "Invalid annotation listbox");
        if (daToks) {
          for (auto entry : *daToks) {
            delete entry;
          }
          delete daToks;
        }
        return false;
      }
      Annot::layoutText(fieldChoice->getChoice(i), &convertedText, &j, font, &w, 0.0, nullptr, false);
      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 = (*daToks)[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;
    Annot::layoutText(fieldChoice->getChoice(i), &convertedText, &j, font, &w, 0.0, nullptr, false);
    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 = (*daToks)[tmPos + 4];
      tok->clear();
      tok->appendf("{0:.2f}", x);
      tok = (*daToks)[tmPos + 5];
      tok->clear();
      tok->appendf("{0:.2f}", y);
    }

    // write the DA string
    if (daToks) {
      for (std::size_t k = 0; k < daToks->size(); ++k) {
        appearBuf->append((*daToks)[k])->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->append(" Tj\n");

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

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

  if (daToks) {
    for (auto entry : *daToks) {
      delete entry;
    }
    delete daToks;
  }

  return true;
}

void AnnotAppearanceBuilder::drawFieldBorder(const FormField *field, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect) {
  int dashLength;
  double *dash;
  AnnotColor adjustedColor;
  const double w = border->getWidth();

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

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

  // radio buttons with no caption have a round border
  const bool hasCaption = appearCharacs->getNormalCaption() != nullptr;
  if (field->getType() == formButton &&
      static_cast<const 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");
      // fallthrough
    case AnnotBorder::borderSolid:
    case AnnotBorder::borderUnderlined:
      appearBuf->appendf("{0:.2f} w\n", w);
      setDrawColor(aColor, false);
      drawCircle(0.5 * dx, 0.5 * dy, r - 0.5 * w, false);
      break;
    case AnnotBorder::borderBeveled:
    case AnnotBorder::borderInset:
      appearBuf->appendf("{0:.2f} w\n", 0.5 * w);
      setDrawColor(aColor, false);
      drawCircle(0.5 * dx, 0.5 * dy, r - 0.25 * w, false);
      adjustedColor = AnnotColor(*aColor);
      adjustedColor.adjustColor(border->getStyle() == AnnotBorder::borderBeveled ? 1 : -1);
      setDrawColor(&adjustedColor, false);
      drawCircleTopLeft(0.5 * dx, 0.5 * dy, r - 0.75 * w);
      adjustedColor = AnnotColor(*aColor);
      adjustedColor.adjustColor(border->getStyle() == AnnotBorder::borderBeveled ? -1 : 1);
      setDrawColor(&adjustedColor, false);
      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");
      // fallthrough
    case AnnotBorder::borderSolid:
      appearBuf->appendf("{0:.2f} w\n", w);
      setDrawColor(aColor, false);
      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);
      setDrawColor(&adjustedColor, true);
      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);
      setDrawColor(&adjustedColor, true);
      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);
      setDrawColor(aColor, false);
      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);
  }
}

bool AnnotAppearanceBuilder::drawFormField(const FormField *field, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect, const GooString *appearState, XRef *xref, bool *addedDingbatsResource)
{
  // draw the field contents
  switch (field->getType()) {
  case formButton:
    return drawFormFieldButton(static_cast<const FormFieldButton *>(field), resources, da, border, appearCharacs, rect, appearState, xref, addedDingbatsResource);
    break;
  case formText:
    return drawFormFieldText(static_cast<const FormFieldText *>(field), form, resources, da, border, appearCharacs, rect);
  case formChoice:
    return drawFormFieldChoice(static_cast<const FormFieldChoice *>(field), form, resources, da, border, appearCharacs, rect);
    break;
  case formSignature:
    //~unimp
    break;
  case formUndef:
  default:
    error(errSyntaxError, -1, "Unknown field type");
  }

  return false;
}


bool AnnotAppearanceBuilder::drawFormFieldButton(const FormFieldButton *field, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect, const GooString *appearState, XRef *xref, bool *addedDingbatsResource) {
  const GooString *caption = nullptr;
  if (appearCharacs)
    caption = appearCharacs->getNormalCaption();

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

  return true;
}

bool AnnotAppearanceBuilder::drawFormFieldText(const FormFieldText *fieldText, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect) {
  VariableTextQuadding quadding;
  const GooString *contents;

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

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

    return drawText(contents, da, resources, border, appearCharacs, rect,
             fieldText->isMultiline(), comb, quadding, true, false, nullptr, nullptr, fieldText->isPassword());
  }

  return true;
}

bool AnnotAppearanceBuilder::drawFormFieldChoice(const FormFieldChoice *fieldChoice, const Form *form, const GfxResources *resources, const GooString *da, const AnnotBorder *border, const AnnotAppearanceCharacs *appearCharacs, const PDFRectangle *rect) {
  const GooString *selected;
  VariableTextQuadding quadding;

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

  if (fieldChoice->isCombo()) {
    selected = fieldChoice->getSelectedChoice();
    if (selected) {
      return drawText(selected, da, resources, border, appearCharacs, rect, false, 0, quadding, true, false, nullptr, nullptr, false);
      //~ Acrobat draws a popup icon on the right side
    }
  // list box
  } else {
    return drawListBox(fieldChoice, border, rect, da, resources, quadding);
  }

  return true;
}

void AnnotWidget::generateFieldAppearance(bool *addedDingbatsResource) {
  GfxResources *resources;
  const GooString *da;

  AnnotAppearanceBuilder appearBuilder;

  // draw the background
  if (appearCharacs) {
    const AnnotColor *aColor = appearCharacs->getBackColor();
    if (aColor) {
      appearBuilder.setDrawColor(aColor, true);
      appearBuilder.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)
    appearBuilder.drawFieldBorder(field, border.get(), appearCharacs.get(), rect.get());

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

  resources = form->getDefaultResources();

  const bool success = appearBuilder.drawFormField(field, form, resources, da, border.get(), appearCharacs.get(), rect.get(), appearState.get(), doc->getXRef(), addedDingbatsResource);
  if (!success && da != form->getDefaultAppearance()) {
    da = form->getDefaultAppearance();
    appearBuilder.drawFormField(field, form, resources, da, border.get(), appearCharacs.get(), rect.get(), appearState.get(), doc->getXRef(), addedDingbatsResource);
  }

  const GooString *appearBuf = appearBuilder.buffer();
  // build the appearance stream dictionary
  Dict *appearDict = new Dict(doc->getXRef());
  appearDict->add("Length", Object(appearBuf->getLength()));
  appearDict->add("Subtype", Object(objName, "Form"));
  Array *bbox = new Array(doc->getXRef());
  bbox->add(Object(0));
  bbox->add(Object(0));
  bbox->add(Object(rect->x2 - rect->x1));
  bbox->add(Object(rect->y2 - rect->y1));
  appearDict->add("BBox", Object(bbox));

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

  // build the appearance stream
  Stream *appearStream = new AutoFreeMemStream(copyString(appearBuf->c_str()), 0,
      appearBuf->getLength(), Object(appearDict));
  appearance = Object(appearStream);
}

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 == Ref::INVALID()) {
    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
  bool dummyAddDingbatsResource = false; // This is only update so if we didn't need to add
                                         // the dingbats resource we should not need it now
  generateFieldAppearance(&dummyAddDingbatsResource);

  // Fetch the appearance stream we've just created
  Object obj1 = appearance.fetch(doc->getXRef());

  // 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 == Ref::INVALID()) {
    // Write the appearance stream
    updatedAppearanceStream = doc->getXRef()->addIndirectObject(&obj1);

    // Write the AP dictionary
    obj1 = Object(new Dict(doc->getXRef()));
    obj1.dictAdd("N", Object(updatedAppearanceStream));

    // Update our internal pointers to the appearance dictionary
    appearStreams = std::make_unique<AnnotAppearance>(doc, &obj1);

    update("AP", std::move(obj1));
  } else {
    // Replace the existing appearance stream
    doc->getXRef()->setModifiedObject(&obj1, updatedAppearanceStream);
  }
}

void AnnotWidget::draw(Gfx *gfx, bool printing) {
  if (!isVisible (printing))
    return;
  
  annotLocker();
  bool addDingbatsResource = false;

  // 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(&addDingbatsResource);
  }

  // draw the appearance stream
  Object obj = appearance.fetch(gfx->getXRef());
  if (addDingbatsResource) {
    // We are forcing ZaDb but the font does not exist
    // so create a fake one
    Dict *fontDict = new Dict(gfx->getXRef());
    fontDict->add("BaseFont", Object(objName, "ZapfDingbats"));
    fontDict->add("Subtype", Object(objName, "Type1"));

    Dict *fontsDict = new Dict(gfx->getXRef());
    fontsDict->add("ZaDb", Object(fontDict));

    Dict *dict = new Dict(gfx->getXRef());
    dict->add("Font", Object(fontsDict));
    gfx->pushResources(dict);
    delete dict;
  }
  gfx->drawAnnot(&obj, nullptr, color.get(),
		 rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
  if (addDingbatsResource) {
    gfx->popResources();
  }
}


//------------------------------------------------------------------------
// AnnotMovie
//------------------------------------------------------------------------
AnnotMovie::AnnotMovie(PDFDoc *docA, PDFRectangle *rectA, Movie *movieA) :
    Annot(docA, rectA) {
  type = typeMovie;
  annotObj.dictSet ("Subtype", Object(objName, "Movie"));

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

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

AnnotMovie::AnnotMovie(PDFDoc *docA, Object &&dictObject, const Object *obj) :
  Annot(docA, std::move(dictObject), obj) {
  type = typeMovie;
  initialize(docA, annotObj.getDict());
}

AnnotMovie::~AnnotMovie() = default;

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

  obj1 = dict->lookup("T");
  if (obj1.isString()) {
    title.reset(obj1.getString()->copy());
  }

  Object movieDict = dict->lookup("Movie");
  if (movieDict.isDict()) {
    Object obj2 = dict->lookup("A");
    if (obj2.isDict())
      movie = std::make_unique<Movie>(&movieDict, &obj2);
    else
      movie = std::make_unique<Movie>(&movieDict);
    if (!movie->isOk()) {
      movie = nullptr;
      ok = false;
    }
  } else {
    error(errSyntaxError, -1, "Bad Annot Movie");
    ok = false;
  }
}

void AnnotMovie::draw(Gfx *gfx, bool printing) {
  if (!isVisible (printing))
    return;

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

    if (width != -1 && height != -1 && !poster.isNone()) {
      auto appearBuf = std::make_unique<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");

      Dict *imgDict = new Dict(gfx->getXRef());
      imgDict->set("MImg", std::move(poster));

      Dict *resDict = new Dict(gfx->getXRef());
      resDict->set("XObject", Object(imgDict));

      Dict *formDict = new Dict(gfx->getXRef());
      formDict->set("Length", Object(appearBuf->getLength()));
      formDict->set("Subtype", Object(objName, "Form"));
      formDict->set("Name", Object(objName, "FRM"));
      Array *bboxArray = new Array(gfx->getXRef());
      bboxArray->add(Object(0));
      bboxArray->add(Object(0));
      bboxArray->add(Object(width));
      bboxArray->add(Object(height));
      formDict->set("BBox", Object(bboxArray));
      Array *matrix = new Array(gfx->getXRef());
      matrix->add(Object(1));
      matrix->add(Object(0));
      matrix->add(Object(0));
      matrix->add(Object(1));
      matrix->add(Object(-width / 2));
      matrix->add(Object(-height / 2));
      formDict->set("Matrix", Object(matrix));
      formDict->set("Resources", Object(resDict));

      Stream *mStream = new AutoFreeMemStream(copyString(appearBuf->c_str()), 0,
			      appearBuf->getLength(), Object(formDict));

      Dict *dict = new Dict(gfx->getXRef());
      dict->set("FRM", Object(mStream));

      Dict *resDict2 = new Dict(gfx->getXRef());
      resDict2->set("XObject", Object(dict));

      appearBuf = std::make_unique<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;
      appearance = createForm(appearBuf.get(), bbox, false, resDict2);
    }
  }

  // draw the appearance stream
  Object obj = appearance.fetch(gfx->getXRef());
  gfx->drawAnnot(&obj, nullptr, color.get(),
		 rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
}

//------------------------------------------------------------------------
// AnnotScreen
//------------------------------------------------------------------------
AnnotScreen::AnnotScreen(PDFDoc *docA, PDFRectangle *rectA) :
    Annot(docA, rectA) {
  type = typeScreen;

  annotObj.dictSet ("Subtype", Object(objName, "Screen"));
  initialize(docA, annotObj.getDict());
}

AnnotScreen::AnnotScreen(PDFDoc *docA, Object &&dictObject, const Object *obj) :
  Annot(docA, std::move(dictObject), obj) {
  type = typeScreen;
  initialize(docA, annotObj.getDict());
}

AnnotScreen::~AnnotScreen() = default;

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

  obj1 = dict->lookup("T");
  if (obj1.isString()) {
    title.reset(obj1.getString()->copy());
  }

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

  additionalActions = dict->lookupNF("AA").copy();

  obj1 = dict->lookup("MK");
  if (obj1.isDict()) {
    appearCharacs = std::make_unique<AnnotAppearanceCharacs>(obj1.getDict());
  }
}

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

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

//------------------------------------------------------------------------
// AnnotStamp
//------------------------------------------------------------------------
AnnotStamp::AnnotStamp(PDFDoc *docA, PDFRectangle *rectA) :
  AnnotMarkup(docA, rectA) {
  type = typeStamp;
  annotObj.dictSet ("Subtype", Object(objName, "Stamp"));
  initialize(docA, annotObj.getDict());
}

AnnotStamp::AnnotStamp(PDFDoc *docA, Object &&dictObject, const Object *obj) :
  AnnotMarkup(docA, std::move(dictObject), obj) {
  type = typeStamp;
  initialize(docA, annotObj.getDict());
}

AnnotStamp::~AnnotStamp() = default;

void AnnotStamp::initialize(PDFDoc *docA, Dict* dict) {
  Object obj1 = dict->lookup("Name");
  if (obj1.isName()) {
    icon = std::make_unique<GooString>(obj1.getName());
  } else {
    icon = std::make_unique<GooString>("Draft");
  }

}

void AnnotStamp::setIcon(GooString *new_icon) {
  if (new_icon) {
    icon = std::make_unique<GooString>(new_icon);
  } else {
    icon = std::make_unique<GooString>();
  }

  update("Name", Object(objName, icon->c_str()));
  invalidateAppearance();
}

//------------------------------------------------------------------------
// AnnotGeometry
//------------------------------------------------------------------------
AnnotGeometry::AnnotGeometry(PDFDoc *docA, PDFRectangle *rectA, AnnotSubtype subType) :
    AnnotMarkup(docA, rectA) {
  switch (subType) {
    case typeSquare:
      annotObj.dictSet ("Subtype", Object(objName, "Square"));
      break;
    case typeCircle:
      annotObj.dictSet ("Subtype", Object(objName, "Circle"));
      break;
    default:
      assert (0 && "Invalid subtype for AnnotGeometry\n");
  }

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

AnnotGeometry::AnnotGeometry(PDFDoc *docA, Object &&dictObject, const Object *obj) :
  AnnotMarkup(docA, std::move(dictObject), obj) {
  // the real type will be read in initialize()
  type = typeSquare;
  initialize(docA, annotObj.getDict());
}

AnnotGeometry::~AnnotGeometry() = default;

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

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

  obj1 = dict->lookup("IC");
  if (obj1.isArray()) {
    interiorColor = std::make_unique<AnnotColor>(obj1.getArray());
  }

  obj1 = dict->lookup("BS");
  if (obj1.isDict()) {
    border = std::make_unique<AnnotBorderBS>(obj1.getDict());
  } else if (!border) {
    border = std::make_unique<AnnotBorderBS>();
  }

  obj1 = dict->lookup("BE");
  if (obj1.isDict()) {
    borderEffect = std::make_unique<AnnotBorderEffect>(obj1.getDict());
  }

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

void AnnotGeometry::setType(AnnotSubtype new_type) {
  const char *typeName = nullptr; /* squelch bogus compiler warning */

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

  type = new_type;
  update("Subtype", Object(objName, typeName));
  invalidateAppearance();
}

void AnnotGeometry::setInteriorColor(std::unique_ptr<AnnotColor> &&new_color) {
  if (new_color) {
    Object obj1 = new_color->writeToObject(doc->getXRef());
    update ("IC", std::move(obj1));
    interiorColor = std::move(new_color);
  } else {
    interiorColor = nullptr;
  }
  invalidateAppearance();
}

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

  if (!isVisible (printing))
    return;

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

    AnnotAppearanceBuilder appearBuilder;
    appearBuilder.append ("q\n");
    if (color)
      appearBuilder.setDrawColor(color.get(), false);

    double borderWidth = border->getWidth();
    appearBuilder.setLineStyleForBorder(border.get());

    if (interiorColor)
      appearBuilder.setDrawColor(interiorColor.get(), true);

    if (type == typeSquare) {
      appearBuilder.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;
      appearBuilder.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;
      appearBuilder.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;
      appearBuilder.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;
      appearBuilder.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;
      appearBuilder.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)
      appearBuilder.append ("b\n");
    else
      appearBuilder.append ("S\n");

    appearBuilder.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) {
      appearance = createForm(appearBuilder.buffer(), bbox, false, nullptr);
    } else {
      Object aStream = createForm(appearBuilder.buffer(), bbox, true, nullptr);

      GooString appearBuf("/GS0 gs\n/Fm0 Do");
      Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, nullptr);
      appearance = createForm(&appearBuf, bbox, false, resDict);
    }
  }

  // draw the appearance stream
  Object obj = appearance.fetch(gfx->getXRef());
  gfx->drawAnnot(&obj, nullptr, color.get(),
		 rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
}

//------------------------------------------------------------------------
// AnnotPolygon
//------------------------------------------------------------------------
AnnotPolygon::AnnotPolygon(PDFDoc *docA, PDFRectangle *rectA, AnnotSubtype subType) :
    AnnotMarkup(docA, rectA) {
  switch (subType) {
    case typePolygon:
      annotObj.dictSet ("Subtype", Object(objName, "Polygon"));
      break;
    case typePolyLine:
      annotObj.dictSet ("Subtype", Object(objName, "PolyLine"));
      break;
    default:
      assert (0 && "Invalid subtype for AnnotGeometry\n");
  }

  // Store dummy path with one null vertex only
  Array *a = new Array(doc->getXRef());
  a->add(Object(0.));
  a->add(Object(0.));
  annotObj.dictSet("Vertices", Object(a));

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

AnnotPolygon::AnnotPolygon(PDFDoc *docA, Object &&dictObject, const Object *obj) :
  AnnotMarkup(docA, std::move(dictObject), obj) {
  // the real type will be read in initialize()
  type = typePolygon;
  initialize(docA, annotObj.getDict());
}

AnnotPolygon::~AnnotPolygon() = default;

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

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

  obj1 = dict->lookup("Vertices");
  if (obj1.isArray()) {
    vertices = std::make_unique<AnnotPath>(obj1.getArray());
  } else {
    vertices = std::make_unique<AnnotPath>();
    error(errSyntaxError, -1, "Bad Annot Polygon Vertices");
    ok = false;
  }

  obj1 = dict->lookup("LE");
  if (obj1.isArray() && obj1.arrayGetLength() == 2) {
    Object obj2 = obj1.arrayGet(0);
    if (obj2.isName()) {
      const GooString leName(obj2.getName());
      startStyle = parseAnnotLineEndingStyle(&leName);
    } else {
      startStyle = annotLineEndingNone;
    }
    obj2 = obj1.arrayGet(1);
    if (obj2.isName()) {
      const GooString leName(obj2.getName());
      endStyle = parseAnnotLineEndingStyle(&leName);
    } else {
      endStyle = annotLineEndingNone;
    }
  } else {
    startStyle = endStyle = annotLineEndingNone;
  }

  obj1 = dict->lookup("IC");
  if (obj1.isArray()) {
    interiorColor = std::make_unique<AnnotColor>(obj1.getArray());
  }

  obj1 = dict->lookup("BS");
  if (obj1.isDict()) {
    border = std::make_unique<AnnotBorderBS>(obj1.getDict());
  } else if (!border) {
    border = std::make_unique<AnnotBorderBS>();
  }

  obj1 = dict->lookup("BE");
  if (obj1.isDict()) {
    borderEffect = std::make_unique<AnnotBorderEffect>(obj1.getDict());
  }

  obj1 = dict->lookup("IT");
  if (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;
  }
}

void AnnotPolygon::setType(AnnotSubtype new_type) {
  const char *typeName = nullptr; /* squelch bogus compiler warning */

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

  type = new_type;
  update("Subtype", Object(objName, typeName));
  invalidateAppearance();
}

void AnnotPolygon::setVertices(AnnotPath *path) {
  Array *a = new Array(doc->getXRef());
  for (int i = 0; i < path->getCoordsLength(); i++) {
    a->add(Object(path->getX(i)));
    a->add(Object(path->getY(i)));
  }

  vertices = std::make_unique<AnnotPath>(a);

  update("Vertices", Object(a));
  invalidateAppearance();
}

void AnnotPolygon::setStartEndStyle(AnnotLineEndingStyle start, AnnotLineEndingStyle end) {
  startStyle = start;
  endStyle = end;

  Array *a = new Array(doc->getXRef());
  a->add( Object(objName, convertAnnotLineEndingStyle( startStyle )) );
  a->add( Object(objName, convertAnnotLineEndingStyle( endStyle )) );

  update("LE", Object(a));
  invalidateAppearance();
}

void AnnotPolygon::setInteriorColor(std::unique_ptr<AnnotColor> &&new_color) {
  if (new_color) {
    Object obj1 = new_color->writeToObject(doc->getXRef());
    update ("IC", std::move(obj1));
    interiorColor = std::move(new_color);
  }
  invalidateAppearance();
}

void AnnotPolygon::setIntent(AnnotPolygonIntent new_intent) {
  const char *intentName;

  intent = new_intent;
  if (new_intent == polygonCloud)
    intentName = "PolygonCloud";
  else if (new_intent == polylineDimension)
    intentName = "PolyLineDimension";
  else // polygonDimension
    intentName = "PolygonDimension";
  update ("IT", Object(objName, intentName));
}

void AnnotPolygon::generatePolyLineAppearance(AnnotAppearanceBuilder* appearBuilder){
  const bool fill = (bool) interiorColor;
  const double x1 = vertices->getX(0);
  const double y1 = vertices->getY(0);
  const double x2 = vertices->getX(1);
  const double y2 = vertices->getY(1);
  const double x3 = vertices->getX(vertices->getCoordsLength()-2);
  const double y3 = vertices->getY(vertices->getCoordsLength()-2);
  const double x4 = vertices->getX(vertices->getCoordsLength()-1);
  const double y4 = vertices->getY(vertices->getCoordsLength()-1);

  const double len_1 = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
  // length of last segment
  const double len_2 = sqrt((x4-x3)*(x4-x3) + (y4-y3)*(y4-y3));

  // segments become positive x direction, coord1 becomes (0,0).
  Matrix matr1,matr2;
  const double angle1 = atan2(y2 - y1, x2 - x1);
  const double angle2 = atan2(y4 - y3, x4 - x3);

  matr1.m[0] = matr1.m[3] = cos(angle1);
  matr1.m[1] = sin(angle1);
  matr1.m[2] = -matr1.m[1];
  matr1.m[4] = x1-rect->x1;
  matr1.m[5] = y1-rect->y1;

  matr2.m[0] = matr2.m[3] = cos(angle2);
  matr2.m[1] = sin(angle2);
  matr2.m[2] = -matr2.m[1];
  matr2.m[4] = x3-rect->x1;
  matr2.m[5] = y3-rect->y1;

  const double lineEndingSize1 {std::min(6. * border->getWidth(), len_1/2)};
  const double lineEndingSize2 {std::min(6. * border->getWidth(), len_2/2)};

  if (vertices->getCoordsLength() != 0) {
    double tx, ty;
    matr1.transform (AnnotAppearanceBuilder::lineEndingXShorten(startStyle, lineEndingSize1), 0, &tx, &ty);
    appearBuilder->appendf ("{0:.2f} {1:.2f} m\n", tx,ty);
    appearBBox->extendTo (tx,ty);

    for (int i = 1; i < vertices->getCoordsLength() - 1; ++i) {
      appearBuilder->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(vertices->getCoordsLength() > 1) {
      matr2.transform (len_2 - AnnotAppearanceBuilder::lineEndingXShorten(endStyle, lineEndingSize2), 0, &tx, &ty);
      appearBuilder->appendf ("{0:.2f} {1:.2f} l S\n", tx, ty);
      appearBBox->extendTo (tx, ty);
    }
  }

  if (startStyle != annotLineEndingNone) {
    const double extendX {-AnnotAppearanceBuilder::lineEndingXExtendBBox(startStyle, lineEndingSize1)};
    double tx, ty;
    appearBuilder->drawLineEnding(startStyle, 0, 0, -lineEndingSize1, fill, matr1);
    matr1.transform (extendX, lineEndingSize1/2., &tx, &ty);
    appearBBox->extendTo (tx, ty);
    matr1.transform (extendX, -lineEndingSize1/2., &tx, &ty);
    appearBBox->extendTo (tx, ty);
  }

  if (endStyle != annotLineEndingNone) {
    const double extendX {AnnotAppearanceBuilder::lineEndingXExtendBBox(endStyle, lineEndingSize2)};
    double tx, ty;
    appearBuilder->drawLineEnding(endStyle, len_2, 0, lineEndingSize2, fill, matr2);
    matr2.transform (len_2 + extendX, lineEndingSize2/2., &tx, &ty);
    appearBBox->extendTo (tx, ty);
    matr2.transform (len_2 + extendX, -lineEndingSize2/2., &tx, &ty);
    appearBBox->extendTo (tx, ty);
  }

}

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

  if (!isVisible (printing))
    return;

  annotLocker();
  if (appearance.isNull()) {
    appearBBox = std::make_unique<AnnotAppearanceBBox>(rect.get());
    ca = opacity;

    AnnotAppearanceBuilder appearBuilder;
    appearBuilder.append ("q\n");

    if (color) {
      appearBuilder.setDrawColor(color.get(), false);
    }

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

    if (interiorColor) {
      appearBuilder.setDrawColor(interiorColor.get(), true);
    }

    if(type == typePolyLine){
      generatePolyLineAppearance(&appearBuilder);
    } else {
      if (vertices->getCoordsLength() != 0) {
        appearBuilder.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) {
          appearBuilder.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 (interiorColor && interiorColor->getSpace() != AnnotColor::colorTransparent) {
          appearBuilder.append ("b\n");
        } else {
          appearBuilder.append ("s\n");
        }
      }
    }
    appearBuilder.append ("Q\n");

    double bbox[4];
    appearBBox->getBBoxRect(bbox);
    if (ca == 1) {
      appearance = createForm(appearBuilder.buffer(), bbox, false, nullptr);
    } else {
      Object aStream = createForm(appearBuilder.buffer(), bbox, true, nullptr);

      GooString appearBuf("/GS0 gs\n/Fm0 Do");
      Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, nullptr);
      appearance = createForm(&appearBuf, bbox, false, resDict);
    }
  }

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

//------------------------------------------------------------------------
// AnnotCaret
//------------------------------------------------------------------------
AnnotCaret::AnnotCaret(PDFDoc *docA, PDFRectangle *rectA) :
    AnnotMarkup(docA, rectA) {
  type = typeCaret;

  annotObj.dictSet ("Subtype", Object(objName, "Caret"));
  initialize(docA, annotObj.getDict());
}

AnnotCaret::AnnotCaret(PDFDoc *docA, Object &&dictObject, const Object *obj) :
  AnnotMarkup(docA, std::move(dictObject), obj) {
  type = typeCaret;
  initialize(docA, annotObj.getDict());
}

AnnotCaret::~AnnotCaret() = default;

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

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

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

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

//------------------------------------------------------------------------
// AnnotInk
//------------------------------------------------------------------------
AnnotInk::AnnotInk(PDFDoc *docA, PDFRectangle *rectA) :
    AnnotMarkup(docA, rectA) {
  type = typeInk;

  annotObj.dictSet ("Subtype", Object(objName, "Ink"));

  // Store dummy path with one null vertex only
  Array *inkListArray = new Array(doc->getXRef());
  Array *vList = new Array(doc->getXRef());
  vList->add(Object(0.));
  vList->add(Object(0.));
  inkListArray->add(Object(vList));
  annotObj.dictSet("InkList", Object(inkListArray));

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

AnnotInk::AnnotInk(PDFDoc *docA, Object &&dictObject, const Object *obj) :
  AnnotMarkup(docA, std::move(dictObject), obj) {
  type = typeInk;
  initialize(docA, annotObj.getDict());
}

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

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

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

    obj1 = dict->lookup("AP");
    // Although InkList is required, it should be ignored
    // when there is an AP entry in the Annot, so do not fail
    // when that happens
    if (!obj1.isDict()) {
      ok = false;
    }
  }

  obj1 = dict->lookup("BS");
  if (obj1.isDict()) {
    border = std::make_unique<AnnotBorderBS>(obj1.getDict());
  } else if (!border) {
    border = std::make_unique<AnnotBorderBS>();
  }
}

void AnnotInk::writeInkList(AnnotPath **paths, int n_paths, Array *dest_array) {
  for (int i = 0; i < n_paths; ++i) {
    AnnotPath *path = paths[i];
    Array *a = new Array(doc->getXRef());
    for (int j = 0; j < path->getCoordsLength(); ++j) {
      a->add(Object(path->getX(j)));
      a->add(Object(path->getY(j)));
    }
    dest_array->add(Object(a));
  }
}

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 = array->get(i);
    if (obj2.isArray())
      inkList[i] = new AnnotPath(obj2.getArray());
  }
}

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) {
  freeInkList();

  Array *a = new Array(doc->getXRef());
  writeInkList(paths, n_paths, a);

  parseInkList(a);
  annotObj.dictSet ("InkList", Object(a));
  invalidateAppearance();
}

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

  if (!isVisible (printing))
    return;

  annotLocker();
  if (appearance.isNull()) {
    appearBBox = std::make_unique<AnnotAppearanceBBox>(rect.get());
    ca = opacity;

    AnnotAppearanceBuilder appearBuilder;
    appearBuilder.append ("q\n");

    if (color) {
      appearBuilder.setDrawColor(color.get(), false);
    }

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

    for (int i = 0; i < inkListLength; ++i) {
      const AnnotPath * path = inkList[i];
      if (path && path->getCoordsLength() != 0) {
        appearBuilder.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) {
          appearBuilder.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);
        }

        appearBuilder.append ("S\n");
      }
    }

    appearBuilder.append ("Q\n");

    double bbox[4];
    appearBBox->getBBoxRect(bbox);
    if (ca == 1) {
      appearance = createForm(appearBuilder.buffer(), bbox, false, nullptr);
    } else {
      Object aStream = createForm(appearBuilder.buffer(), bbox, true, nullptr);

      GooString appearBuf("/GS0 gs\n/Fm0 Do");
      Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, nullptr);
      appearance = createForm(&appearBuf, bbox, false, resDict);
    }
  }

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

//------------------------------------------------------------------------
// AnnotFileAttachment
//------------------------------------------------------------------------
AnnotFileAttachment::AnnotFileAttachment(PDFDoc *docA, PDFRectangle *rectA, GooString *filename) :
    AnnotMarkup(docA, rectA) {
  type = typeFileAttachment;

  annotObj.dictSet("Subtype", Object(objName, "FileAttachment"));
  annotObj.dictSet("FS", Object(filename->copy()));

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

AnnotFileAttachment::AnnotFileAttachment(PDFDoc *docA, Object &&dictObject, const Object *obj) :
  AnnotMarkup(docA, std::move(dictObject), obj) {
  type = typeFileAttachment;
  initialize(docA, annotObj.getDict());
}

AnnotFileAttachment::~AnnotFileAttachment() = default;

void AnnotFileAttachment::initialize(PDFDoc *docA, Dict* dict) {
  Object objFS = dict->lookup("FS");
  if (objFS.isDict() || objFS.isString()) {
    file = std::move(objFS);
  } else {
    error(errSyntaxError, -1, "Bad Annot File Attachment");
    ok = false;
  }

  Object objName = dict->lookup("Name");
  if (objName.isName()) {
    name = std::make_unique<GooString>(objName.getName());
  } else {
    name = std::make_unique<GooString>("PushPin");
  }
}

#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, bool printing) {
  double ca = 1;

  if (!isVisible (printing))
    return;

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

    AnnotAppearanceBuilder appearBuilder;

    appearBuilder.append ("q\n");
    if (color)
      appearBuilder.setDrawColor(color.get(), true);
    else
      appearBuilder.append ("1 1 1 rg\n");
    if (!name->cmp("PushPin"))
      appearBuilder.append (ANNOT_FILE_ATTACHMENT_AP_PUSHPIN);
    else if (!name->cmp("Paperclip"))
      appearBuilder.append (ANNOT_FILE_ATTACHMENT_AP_PAPERCLIP);
    else if (!name->cmp("Graph"))
      appearBuilder.append (ANNOT_FILE_ATTACHMENT_AP_GRAPH);
    else if (!name->cmp("Tag"))
      appearBuilder.append (ANNOT_FILE_ATTACHMENT_AP_TAG);
    appearBuilder.append ("Q\n");

    double bbox[4];
    bbox[0] = bbox[1] = 0;
    bbox[2] = bbox[3] = 24;
    if (ca == 1) {
      appearance = createForm (appearBuilder.buffer(), bbox, false, nullptr);
    } else {
      Object aStream = createForm (appearBuilder.buffer(), bbox, true, nullptr);

      GooString appearBuf("/GS0 gs\n/Fm0 Do");
      Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, nullptr);
      appearance = createForm(&appearBuf, bbox, false, resDict);
    }
  }

  // draw the appearance stream
  Object obj = appearance.fetch(gfx->getXRef());
  gfx->drawAnnot(&obj, nullptr, color.get(),
		 rect->x1, rect->y1, rect->x2, rect->y2, getRotation());
}

//------------------------------------------------------------------------
// AnnotSound
//------------------------------------------------------------------------
AnnotSound::AnnotSound(PDFDoc *docA, PDFRectangle *rectA, Sound *soundA) :
    AnnotMarkup(docA, rectA) {
  type = typeSound;

  annotObj.dictSet ("Subtype", Object(objName, "Sound"));
  annotObj.dictSet ("Sound", soundA->getObject()->copy());

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

AnnotSound::AnnotSound(PDFDoc *docA, Object &&dictObject, const Object *obj) :
  AnnotMarkup(docA, std::move(dictObject), obj) {
  type = typeSound;
  initialize(docA, annotObj.getDict());
}

AnnotSound::~AnnotSound() = default;

void AnnotSound::initialize(PDFDoc *docA, Dict* dict) {
  Object obj1 = dict->lookup("Sound");

  sound.reset(Sound::parseSound(&obj1));
  if (!sound) {
    error(errSyntaxError, -1, "Bad Annot Sound");
    ok = false;
  }

  obj1 = dict->lookup("Name");
  if (obj1.isName()) {
    name = std::make_unique<GooString>(obj1.getName());
  } else {
    name = std::make_unique<GooString>("Speaker");
  }
}

#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, bool printing) {
  Object obj;
  double ca = 1;

  if (!isVisible (printing))
    return;

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

    AnnotAppearanceBuilder appearBuilder;

    appearBuilder.append ("q\n");
    if (color)
      appearBuilder.setDrawColor(color.get(), true);
    else
      appearBuilder.append ("1 1 1 rg\n");
    if (!name->cmp("Speaker"))
      appearBuilder.append (ANNOT_SOUND_AP_SPEAKER);
    else if (!name->cmp("Mic"))
      appearBuilder.append (ANNOT_SOUND_AP_MIC);
    appearBuilder.append ("Q\n");

    double bbox[4];
    bbox[0] = bbox[1] = 0;
    bbox[2] = bbox[3] = 24;
    if (ca == 1) {
      appearance = createForm(appearBuilder.buffer(), bbox, false, nullptr);
    } else {
      Object aStream = createForm(appearBuilder.buffer(), bbox, true, nullptr);

      GooString appearBuf("/GS0 gs\n/Fm0 Do");
      Dict *resDict = createResourcesDict("Fm0", std::move(aStream), "GS0", ca, nullptr);
      appearance = createForm(&appearBuf, bbox, false, resDict);
    }
  }

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

//------------------------------------------------------------------------
// Annot3D
//------------------------------------------------------------------------
Annot3D::Annot3D(PDFDoc *docA, PDFRectangle *rectA) :
    Annot(docA, rectA) {
  type = type3D;

  annotObj.dictSet ("Subtype", Object(objName, "3D"));

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

Annot3D::Annot3D(PDFDoc *docA, Object &&dictObject, const Object *obj) :
  Annot(docA, std::move(dictObject), obj) {
  type = type3D;
  initialize(docA, annotObj.getDict());
}

Annot3D::~Annot3D() = default;

void Annot3D::initialize(PDFDoc *docA, Dict* dict) {
  Object obj1 = dict->lookup("3DA");
  if (obj1.isDict()) {
    activation = std::make_unique<Activation>(obj1.getDict());
  }
}

Annot3D::Activation::Activation(Dict *dict) {
  Object obj1;

  obj1 = dict->lookup("A");
  if (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 = dict->lookup("AIS");
  if (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 = dict->lookup("D");
  if (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 = dict->lookup("DIS");
  if (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 = dict->lookup("TB");
  if (obj1.isBool()) {
    displayToolbar = obj1.getBool();
  } else {
    displayToolbar = true;
  }

  obj1 = dict->lookup("NP");
  if (obj1.isBool()) {
    displayNavigation = obj1.getBool();
  } else {
    displayNavigation = false;
  }
}

//------------------------------------------------------------------------
// AnnotRichMedia
//------------------------------------------------------------------------
AnnotRichMedia::AnnotRichMedia(PDFDoc *docA, PDFRectangle *rectA) :
    Annot(docA, rectA) {
  type = typeRichMedia;

  annotObj.dictSet ("Subtype", Object(objName, "RichMedia"));

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

AnnotRichMedia::AnnotRichMedia(PDFDoc *docA, Object &&dictObject, const Object *obj) :
  Annot(docA, std::move(dictObject), obj) {
  type = typeRichMedia;
  initialize(docA, annotObj.getDict());
}

AnnotRichMedia::~AnnotRichMedia() = default;

void AnnotRichMedia::initialize(PDFDoc *docA, Dict* dict) {
  Object obj1 = dict->lookup("RichMediaContent");
  if (obj1.isDict()) {
    content = std::make_unique<AnnotRichMedia::Content>(obj1.getDict());
  }

  obj1 = dict->lookup("RichMediaSettings");
  if (obj1.isDict()) {
    settings = std::make_unique<AnnotRichMedia::Settings>(obj1.getDict());
  }
}

AnnotRichMedia::Content* AnnotRichMedia::getContent() const {
  return content.get();
}

AnnotRichMedia::Settings* AnnotRichMedia::getSettings() const {
  return settings.get();
}

AnnotRichMedia::Settings::Settings(Dict *dict) {
  Object obj1 = dict->lookup("Activation");
  if (obj1.isDict()) {
    activation = std::make_unique<AnnotRichMedia::Activation>(obj1.getDict());
  }

  obj1 = dict->lookup("Deactivation");
  if (obj1.isDict()) {
    deactivation = std::make_unique<AnnotRichMedia::Deactivation>(obj1.getDict());
  }
}

AnnotRichMedia::Settings::~Settings() = default;

AnnotRichMedia::Activation* AnnotRichMedia::Settings::getActivation() const {
  return activation.get();
}

AnnotRichMedia::Deactivation* AnnotRichMedia::Settings::getDeactivation() const {
  return deactivation.get();
}

AnnotRichMedia::Activation::Activation(Dict *dict) {
  Object obj1 = dict->lookup("Condition");
  if (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;
  }
}

AnnotRichMedia::Activation::Condition AnnotRichMedia::Activation::getCondition() const {
  return condition;
}

AnnotRichMedia::Deactivation::Deactivation(Dict *dict) {
  Object obj1 = dict->lookup("Condition");
  if (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;
  }
}

AnnotRichMedia::Deactivation::Condition AnnotRichMedia::Deactivation::getCondition() const {
  return condition;
}

AnnotRichMedia::Content::Content(Dict *dict) {
  Object obj1 = dict->lookup("Configurations");
  if (obj1.isArray()) {
    nConfigurations = obj1.arrayGetLength();

    configurations = (Configuration **)gmallocn(nConfigurations, sizeof(Configuration *));

    for (int i = 0; i < nConfigurations; ++i) {
      Object obj2 = obj1.arrayGet(i);
      if (obj2.isDict()) {
        configurations[i] = new AnnotRichMedia::Configuration(obj2.getDict());
      } else {
        configurations[i] = nullptr;
      }
    }
  } else {
    nConfigurations = 0;
    configurations = nullptr;
  }

  nAssets = 0;
  assets = nullptr;
  obj1 = dict->lookup("Assets");
  if (obj1.isDict()) {
    Object obj2 = obj1.getDict()->lookup("Names");
    if (obj2.isArray()) {
      const int length = obj2.arrayGetLength() / 2;

      assets = (Asset **)gmallocn(length, sizeof(Asset *));
      for (int i = 0; i < length; ++i) {
	Object objKey = obj2.arrayGet(2 * i);
	Object objVal = obj2.arrayGet(2 * i + 1);

	if (!objKey.isString() || objVal.isNull()) {
	  error(errSyntaxError, -1, "Bad Annot Asset");
	  continue;
	}

	assets[nAssets] = new AnnotRichMedia::Asset;
	assets[nAssets]->name = std::make_unique<GooString>( objKey.getString() );
	assets[nAssets]->fileSpec = std::move(objVal);
	++nAssets;
      }
    }
  }
}

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 nullptr;

  return configurations[index];
}

int AnnotRichMedia::Content::getAssetsCount() const {
  return nAssets;
}

AnnotRichMedia::Asset* AnnotRichMedia::Content::getAsset(int index) const {
  if (index < 0 || index >= nAssets)
    return nullptr;

  return assets[index];
}

AnnotRichMedia::Asset::Asset() = default;

AnnotRichMedia::Asset::~Asset() = default;

const GooString* AnnotRichMedia::Asset::getName() const {
  return name.get();
}

Object* AnnotRichMedia::Asset::getFileSpec() const {
  return const_cast<Object*>(&fileSpec);
}

AnnotRichMedia::Configuration::Configuration(Dict *dict)
{
  Object obj1 = dict->lookup("Instances");
  if (obj1.isArray()) {
    nInstances = obj1.arrayGetLength();

    instances = (Instance **)gmallocn(nInstances, sizeof(Instance *));

    for (int i = 0; i < nInstances; ++i) {
      Object obj2 = obj1.arrayGet(i);
      if (obj2.isDict()) {
        instances[i] = new AnnotRichMedia::Instance(obj2.getDict());
      } else {
        instances[i] = nullptr;
      }
    }
  } else {
    instances = nullptr;
  }

  obj1 = dict->lookup("Name");
  if (obj1.isString()) {
    name = std::make_unique<GooString>(obj1.getString());
  }

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

    if (!strcmp(subtypeName, "3D")) {
      type = type3D;
    } else if (!strcmp(subtypeName, "Flash")) {
      type = typeFlash;
    } else if (!strcmp(subtypeName, "Sound")) {
      type = typeSound;
    } else if (!strcmp(subtypeName, "Video")) {
      type = typeVideo;
    } else {
      // determine from first non null instance
      type = typeFlash; // default in case all instances are null
      if (instances && nInstances > 0) {
	for (int i = 0; i < nInstances; ++i) {
	  AnnotRichMedia::Instance *instance = instances[i];
	  if (instance) {
	    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;
	    }
	    // break the loop since we found the first non null instance
	    break;
	  }
	}
      }
    }
  }
}

AnnotRichMedia::Configuration::~Configuration()
{
  if (instances) {
    for (int i = 0; i < nInstances; ++i)
      delete instances[i];
    gfree(instances);
  }
}

int AnnotRichMedia::Configuration::getInstancesCount() const {
  return nInstances;
}

AnnotRichMedia::Instance* AnnotRichMedia::Configuration::getInstance(int index) const {
  if (index < 0 || index >= nInstances)
    return nullptr;

  return instances[index];
}

const GooString* AnnotRichMedia::Configuration::getName() const {
  return name.get();
}

AnnotRichMedia::Configuration::Type AnnotRichMedia::Configuration::getType() const {
  return type;
}

AnnotRichMedia::Instance::Instance(Dict *dict)
{
  Object obj1 = dict->lookup("Subtype");
  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 = dict->lookup("Params");
  if (obj1.isDict()) {
    params = std::make_unique<AnnotRichMedia::Params>(obj1.getDict());
  }
}

AnnotRichMedia::Instance::~Instance() = default;

AnnotRichMedia::Instance::Type AnnotRichMedia::Instance::getType() const {
  return type;
}

AnnotRichMedia::Params* AnnotRichMedia::Instance::getParams() const {
  return params.get();
}

AnnotRichMedia::Params::Params(Dict *dict)
{
  Object obj1 = dict->lookup("FlashVars");
  if (obj1.isString()) {
    flashVars = std::make_unique<GooString>(obj1.getString());
  }
}

AnnotRichMedia::Params::~Params() = default;

const GooString* AnnotRichMedia::Params::getFlashVars() const {
  return flashVars.get();
}

//------------------------------------------------------------------------
// Annots
//------------------------------------------------------------------------

Annots::Annots(PDFDoc *docA, int page, Object *annotsObj) {
  Annot *annot;
  int i;

  doc = docA;

  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 obj1 = annotsObj->arrayGet(i);
      if (obj1.isDict()) {
	const Object &obj2 = annotsObj->arrayGetNF(i);
        annot = createAnnot (std::move(obj1), &obj2);
        if (annot) {
          if (annot->isOk()) {
            annot->setPage(page, false); // Don't change /P
            appendAnnot(annot);
          }
          annot->decRefCnt();
        }
      }
    }
  }
}

void Annots::appendAnnot(Annot *annot) {
  if (annot && annot->isOk()) {
    annots.push_back(annot);
    annot->incRefCnt();
  }
}

bool Annots::removeAnnot(Annot *annot) {
  auto idx = std::find(annots.begin(), annots.end(), annot);

  if (idx == annots.end()) {
    return false;
  } else {
    annot->decRefCnt();
    annots.erase(idx);
    return true;
  }
}

Annot *Annots::createAnnot(Object &&dictObject, const Object *obj) {
  Annot *annot = nullptr;
  Object obj1 = dictObject.dictLookup("Subtype");
  if (obj1.isName()) {
    const char *typeName = obj1.getName();

    if (!strcmp(typeName, "Text")) {
      annot = new AnnotText(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "Link")) {
      annot = new AnnotLink(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "FreeText")) {
      annot = new AnnotFreeText(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "Line")) {
      annot = new AnnotLine(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "Square")) {
      annot = new AnnotGeometry(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "Circle")) {
      annot = new AnnotGeometry(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "Polygon")) {
      annot = new AnnotPolygon(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "PolyLine")) {
      annot = new AnnotPolygon(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "Highlight")) {
      annot = new AnnotTextMarkup(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "Underline")) {
      annot = new AnnotTextMarkup(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "Squiggly")) {
      annot = new AnnotTextMarkup(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "StrikeOut")) {
      annot = new AnnotTextMarkup(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "Stamp")) {
      annot = new AnnotStamp(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "Caret")) {
      annot = new AnnotCaret(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "Ink")) {
      annot = new AnnotInk(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "FileAttachment")) {
      annot = new AnnotFileAttachment(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "Sound")) {
      annot = new AnnotSound(doc, std::move(dictObject), obj);
    } else if(!strcmp(typeName, "Movie")) {
      annot = new AnnotMovie(doc, std::move(dictObject), 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, std::move(dictObject), obj);
    } else if(!strcmp(typeName, "Screen")) {
      annot = new AnnotScreen(doc, std::move(dictObject), obj);
    } else if(!strcmp(typeName, "PrinterMark")) {
      annot = new Annot(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "TrapNet")) {
      annot = new Annot(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "Watermark")) {
      annot = new Annot(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "3D")) {
      annot = new Annot3D(doc, std::move(dictObject), obj);
    } else if (!strcmp(typeName, "RichMedia")) {
      annot = new AnnotRichMedia(doc, std::move(dictObject), 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 = dictObject.dictLookup("Parent");
      if (obj2.isNull())
        annot = new AnnotPopup(doc, std::move(dictObject), obj);
      else
        annot = nullptr;
    } else {
      annot = new Annot(doc, std::move(dictObject), obj);
    }
  }

  return annot;
}

Annot *Annots::findAnnot(Ref *ref) {
  for (auto* annot : annots) {
    if (annot->match(ref)) {
      return annot;
    }
  }
  return nullptr;
}


Annots::~Annots() {
  for (auto* annot : annots) {
    annot->decRefCnt();
  }
}


//------------------------------------------------------------------------
// AnnotAppearanceBuilder
//------------------------------------------------------------------------

AnnotAppearanceBuilder::AnnotAppearanceBuilder()
 : appearBuf(new GooString())
{
}

AnnotAppearanceBuilder::~AnnotAppearanceBuilder()
{
    delete appearBuf;
}

void AnnotAppearanceBuilder::append(const char *text)
{
    appearBuf->append(text);
}

void AnnotAppearanceBuilder::appendf(const char *fmt, ...) GOOSTRING_FORMAT
{
  va_list argList;

  va_start(argList, fmt);
  appearBuf->appendfv(fmt, argList);
  va_end(argList);
}

const GooString *AnnotAppearanceBuilder::buffer() const
{
    return appearBuf;
}
