//========================================================================
//
// 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 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 Tobias Deiminger <haxtibal@posteo.de>
// Copyright (C) 2018 Oliver Sander <oliver.sander@tu-dresden.de>
// Copyright (C) 2019 Umang Malik <umang99m@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 LinkAction* getFormAdditionalAction(Annot::FormAdditionalActionsType type, Object *additionalActions, PDFDoc *doc) {
  LinkAction *linkAction = nullptr;
  Object additionalActionsObject = additionalActions->fetch(doc->getXRef());

  if (additionalActionsObject.isDict()) {
    const char *key = (type == Annot::actionFieldModified ?  "K" :
                       type == Annot::actionFormatField ?    "F" :
                       type == Annot::actionValidateField ?  "V" :
                       type == Annot::actionCalculateField ? "C" : nullptr);

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

  return linkAction;
}

//------------------------------------------------------------------------
// 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> &&coords) {
  this->coords = std::move(coords);
}

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 '/'.
      if ((*daToks)[i-2] && ((const char*)((*daToks)[i-2]))[0] == '/') {
        // The +1 is here to skip the leading '/'.
        fontName = Object(objName, ((const char*)(*daToks)[i-2])+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;
  xref = docA->getXRef();
  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()) {
    Ref r = stateObj->getRef();
    if (r.num == refToStream.num && r.gen == refToStream.gen) {
      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()) {
        Ref r = obj1.getRef();
        if (r.num == refToStream.num && r.gen == refToStream.gen) {
          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
  xref->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;
  xref = doc->getXRef();

  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()) {
    Ref ref = pObj.getRef();

    page = doc->getCatalog()->findPage (ref.num, ref.gen);
  } 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 *rect) {
    setRect(rect->x1, rect->y1, rect->x2, rect->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(xref);
  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));
  
  xref->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(xref);
    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(xref);
    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 x1[3] {x - size/2., x - size/2., x + size/2.};
  const double y1[3] {y + size/2., y - size/2., y - size/2.};
  double tx, ty;

  m.transform (x + size/2., y + size/2., &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 r = size/2.;
  const double x1[4] {x + r, x - bezierCircle * r, x - r, x + bezierCircle * r};
  const double x2[4] {x + bezierCircle*r, x - r, x - bezierCircle*r, x + r};
  const double x3[4] {x, x - r, x, x + r};
  const double y1[4] {y + bezierCircle * r, y + r, y - bezierCircle * r, y - r};
  const double y2[4] {y + r, y + bezierCircle * r, y - r, y - bezierCircle * r};
  const double y3[4] {y + r, y, y - r, y};
  double tx[3];
  double ty[3];

  m.transform(x + r, 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 x1[3] {x, x - size/2., x};
  const double y1[3] {y + size/2., y, y - size/2.};
  double tx, ty;

  m.transform (x + size/2., 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/2.};
  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 + xOffs, 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 alpha {M_PI/3.};
  const double xOffs { cos(alpha)*size };
  double tx, ty;

  m.transform (x + size/2. - xOffs, y - size/2., &tx, &ty);
  appendf ("{0:.2f} {1:.2f} m\n", tx, ty);
  m.transform (x + size/2., y + size/2., &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:
    {
      double tx, ty;
      m.transform (x + size/2., y + size/2., &tx, &ty);
      appendf ("{0:.2f} {1:.2f} m\n", tx, ty);
      m.transform (x + size/2., y - size/2., &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::shortenLineSegmentForEnding(AnnotLineEndingStyle endingStyle, double x, double size) {
  switch(endingStyle) {
  case annotLineEndingSquare:
  case annotLineEndingCircle:
  case annotLineEndingDiamond:
  case annotLineEndingOpenArrow:
  case annotLineEndingButt:
    return x;
  case annotLineEndingClosedArrow:
  case annotLineEndingRClosedArrow:
  case annotLineEndingROpenArrow:
    return x - size;
  case annotLineEndingSlash:
    return x - cos(M_PI/3.)*size/2.;
  default:
    break;
  }
  return x;
}

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(xref);
  appearDict->set("Length", Object(appearBuf->getLength()));
  appearDict->set("Subtype", Object(objName, "Form"));

  Array *a = new Array(xref);
  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(xref);
    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(xref);
  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(xref);
  stateDict->set(stateName, Object(gsDict));
  Dict *formDict = new Dict(xref);
  formDict->set(formName, std::move(formStream));

  Dict *resDict = new Dict(xref);
  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(xref);
  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 *rect) :
    Annot(docA, rect) {
  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) {
  parent = dict->lookupNF("Parent").copy();
  if (!parent.isRef()) {
    parent.setToNull();
  }

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

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

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

//------------------------------------------------------------------------
// AnnotMarkup
//------------------------------------------------------------------------
AnnotMarkup::AnnotMarkup(PDFDoc *docA, PDFRectangle *rect) :
    Annot(docA, rect) {
  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.num = 0;
    inReplyTo.gen = 0;
  }

  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 *rect) :
    AnnotMarkup(docA, rect) {
  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 *rect) :
    Annot(docA, rect) {
  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
//------------------------------------------------------------------------
AnnotFreeText::AnnotFreeText(PDFDoc *docA, PDFRectangle *rect, const DefaultAppearance &da) :
    AnnotMarkup(docA, rect) {
  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(errSyntaxError, -1, "Bad appearance for annotation");
    ok = false;
  }

  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(xref) );
    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(10);
  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(xref, 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(xref);
    resourceObj = Object(fontResDict);
    font = createAnnotDrawFont(xref, 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 *rect) :
    AnnotMarkup(docA, rect) {
  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(xref);
  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(xref);
  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(xref);
    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(xref);
    font = createAnnotDrawFont(xref, 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::shortenLineSegmentForEnding(startStyle, 0, -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 (AnnotAppearanceBuilder::shortenLineSegmentForEnding(endStyle, main_len, lineendingSize), leaderLineLength, &tx, &ty);
  appearBuilder.appendf ("{0:.2f} {1:.2f} l S\n", tx, ty);
  appearBBox->extendTo (tx, ty);

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

  if (endStyle != annotLineEndingNone) {
    appearBuilder.drawLineEnding(endStyle, main_len - lineendingSize/2., leaderLineLength, lineendingSize, fill, matr);
    matr.transform (main_len, leaderLineLength+lineendingSize/2., &tx, &ty);
    appearBBox->extendTo (tx, ty);
    matr.transform (main_len, 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 *rect, AnnotSubtype subType) :
    AnnotMarkup(docA, rect) {
  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(xref);

  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.num = updatedAppearanceStream.gen = -1;
}

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

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

// Grand unified handler for preparing text strings to be drawn into form
// fields.  Takes as input a text string (in PDFDocEncoding or UTF-16).
// Converts some or all of this string to the appropriate encoding for the
// specified font, and computes the width of the text.  Can optionally stop
// converting when a specified width has been reached, to perform line-breaking
// for multi-line fields.
//
// Parameters:
//   text: input text string to convert
//   outBuf: buffer for writing re-encoded string
//   i: index at which to start converting; will be updated to point just after
//      last character processed
//   font: the font which will be used for display
//   width: computed width (unscaled by font size) will be stored here
//   widthLimit: if non-zero, stop converting to keep width under this value
//      (should be scaled down by font size)
//   charCount: count of number of characters will be stored here
//   noReencode: if set, do not try to translate the character encoding
//      (useful for Zapf Dingbats or other unusual encodings)
//      can only be used with simple fonts, not CID-keyed fonts
//
// TODO: Handle surrogate pairs in UTF-16.
//       Should be able to generate output for any CID-keyed font.
//       Doesn't handle vertical fonts--should it?
void Annot::layoutText(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, i, 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*>();
    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; // dummy Ref, it's not used at all in this codepath
          r.num = -1;
          r.gen = -1;
          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 (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;
        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 (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
    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);
        }
      }

      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 dx, dy, ox, oy;

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

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

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

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

      // regular (non-comb) formatting
    } else {
      i = 0;
      Annot::layoutText(text, &convertedText, &i, 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 i = 2; i < 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;
  }

  // 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 j = 0; j < daToks->size(); ++j) {
        appearBuf->append((*daToks)[j])->append(' ');
      }
    }

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

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

    // write the text string
    writeString(convertedText);
    appearBuf->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(), xref, addedDingbatsResource);
  if (!success && da != form->getDefaultAppearance()) {
    da = form->getDefaultAppearance();
    appearBuilder.drawFormField(field, form, resources, da, border.get(), appearCharacs.get(), rect.get(), appearState.get(), xref, addedDingbatsResource);
  }

  const GooString *appearBuf = appearBuilder.buffer();
  // build the appearance stream dictionary
  Dict *appearDict = new Dict(xref);
  appearDict->add("Length", Object(appearBuf->getLength()));
  appearDict->add("Subtype", Object(objName, "Form"));
  Array *bbox = new Array(xref);
  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.num == -1) {
    invalidateAppearance(); // Delete AP dictionary and all referenced streams
  }

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

  // Create the new appearance
  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(xref);

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

    // Write the AP dictionary
    obj1 = Object(new Dict(xref));
    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
    xref->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 *rect, Movie *movieA) :
    Annot(docA, rect) {
  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 *rect) :
    Annot(docA, rect) {
  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 type)
{
  if (type == actionFocusIn || type == actionFocusOut) // not defined for screen annotation
    return nullptr;

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

//------------------------------------------------------------------------
// AnnotStamp
//------------------------------------------------------------------------
AnnotStamp::AnnotStamp(PDFDoc *docA, PDFRectangle *rect) :
  AnnotMarkup(docA, rect) {
  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 *rect, AnnotSubtype subType) :
    AnnotMarkup(docA, rect) {
  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(xref);
    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 *rect, AnnotSubtype subType) :
    AnnotMarkup(docA, rect) {
  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(xref);
  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(xref);
  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(xref);
    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::shortenLineSegmentForEnding(startStyle, 0, -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 (AnnotAppearanceBuilder::shortenLineSegmentForEnding(endStyle, len_2, lineEndingSize2), 0, &tx, &ty);
      appearBuilder->appendf ("{0:.2f} {1:.2f} l S\n", tx, ty);
      appearBBox->extendTo (tx, ty);
    }
  }

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

  if (endStyle != annotLineEndingNone) {
    double tx, ty;
    appearBuilder->drawLineEnding(endStyle, len_2 - lineEndingSize2/2., 0, lineEndingSize2, fill, matr2);
    matr2.transform (len_2, lineEndingSize2/2., &tx, &ty);
    appearBBox->extendTo (tx, ty);
    matr2.transform (len_2, -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 *rect) :
    AnnotMarkup(docA, rect) {
  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 *rect) :
    AnnotMarkup(docA, rect) {
  type = typeInk;

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

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

  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");
    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(xref);
    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(xref);
  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 *rect, GooString *filename) :
    AnnotMarkup(docA, rect) {
  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 *rect, Sound *soundA) :
    AnnotMarkup(docA, rect) {
  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 *rect) :
    Annot(docA, rect) {
  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 *rect) :
    Annot(docA, rect) {
  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 *name = obj1.getName();

    if (!strcmp(name, "3D")) {
      type = type3D;
    } else if (!strcmp(name, "Flash")) {
      type = typeFlash;
    } else if (!strcmp(name, "Sound")) {
      type = typeSound;
    } else if (!strcmp(name, "Video")) {
      type = typeVideo;
    } else {
      // determine from first 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;
}
