/* poppler-document.cc: glib wrapper for poppler
 * Copyright (C) 2005, Red Hat, Inc.
 *
 * Copyright (C) 2016 Jakub Alba <jakubalba@gmail.com>
 * Copyright (C) 2018-2019 Marek Kasik <mkasik@redhat.com>
 * Copyright (C) 2019 Masamichi Hosoda <trueroad@trueroad.jp>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include <string.h>

#ifndef __GI_SCANNER__
#include <memory>

#include <splash/SplashBitmap.h>
#include <DateInfo.h>
#include <GlobalParams.h>
#include <PDFDoc.h>
#include <Outline.h>
#include <ErrorCodes.h>
#include <UnicodeMap.h>
#include <GfxState.h>
#include <SplashOutputDev.h>
#include <Stream.h>
#include <FontInfo.h>
#include <PDFDocEncoding.h>
#include <OptionalContent.h>
#include <ViewerPreferences.h>
#endif

#include "poppler.h"
#include "poppler-private.h"
#include "poppler-enums.h"
#include "poppler-input-stream.h"
#include "poppler-cached-file-loader.h"

#ifdef G_OS_WIN32
  #include <stringapiset.h>
#endif

/**
 * SECTION:poppler-document
 * @short_description: Information about a document
 * @title: PopplerDocument
 *
 * The #PopplerDocument is an object used to refer to a main document.
 */

enum {
	PROP_0,
	PROP_TITLE,
	PROP_FORMAT,
	PROP_FORMAT_MAJOR,
	PROP_FORMAT_MINOR,
	PROP_SUBTYPE,
	PROP_SUBTYPE_STRING,
	PROP_SUBTYPE_PART,
	PROP_SUBTYPE_CONF,
	PROP_AUTHOR,
	PROP_SUBJECT,
	PROP_KEYWORDS,
	PROP_CREATOR,
	PROP_PRODUCER,
	PROP_CREATION_DATE,
	PROP_MOD_DATE,
	PROP_LINEARIZED,
	PROP_PAGE_LAYOUT,
	PROP_PAGE_MODE,
	PROP_VIEWER_PREFERENCES,
	PROP_PERMISSIONS,
	PROP_METADATA,
	PROP_PRINT_SCALING,
	PROP_PRINT_DUPLEX,
	PROP_PRINT_N_COPIES
};

static void poppler_document_layers_free (PopplerDocument *document);

typedef struct _PopplerDocumentClass PopplerDocumentClass;
struct _PopplerDocumentClass
{
  GObjectClass parent_class;
};

G_DEFINE_TYPE (PopplerDocument, poppler_document, G_TYPE_OBJECT)

static PopplerDocument *
_poppler_document_new_from_pdfdoc (PDFDoc  *newDoc,
                                   GError **error)
{
  PopplerDocument *document;

  if (!newDoc->isOk()) {
    int fopen_errno;
    switch (newDoc->getErrorCode())
      {
      case errOpenFile:
        // If there was an error opening the file, count it as a G_FILE_ERROR 
        // and set the GError parameters accordingly. (this assumes that the 
        // only way to get an errOpenFile error is if newDoc was created using 
        // a filename and thus fopen was called, which right now is true.
        fopen_errno = newDoc->getFopenErrno();
        g_set_error (error, G_FILE_ERROR,
		     g_file_error_from_errno (fopen_errno),
		     "%s", g_strerror (fopen_errno));
	break;
      case errBadCatalog:
        g_set_error (error, POPPLER_ERROR,
		     POPPLER_ERROR_BAD_CATALOG,
		     "Failed to read the document catalog");
	break;
      case errDamaged:
        g_set_error (error, POPPLER_ERROR,
		     POPPLER_ERROR_DAMAGED,
		     "PDF document is damaged");
	break;
      case errEncrypted:
        g_set_error (error, POPPLER_ERROR,
		     POPPLER_ERROR_ENCRYPTED,
		     "Document is encrypted");
	break;
      default:
        g_set_error (error, POPPLER_ERROR,
		     POPPLER_ERROR_INVALID,
		     "Failed to load document");
    }
    
    delete newDoc;
    return nullptr;
  }

  document = (PopplerDocument *) g_object_new (POPPLER_TYPE_DOCUMENT, nullptr);
  document->doc = newDoc;

  document->output_dev = new CairoOutputDev ();
  document->output_dev->startDoc(document->doc);

  return document;
}

static GooString *
poppler_password_to_latin1 (const gchar *password)
{
  gchar *password_latin;
  GooString *password_g;

  if (!password)
    return nullptr;

  password_latin = g_convert(password, -1, "ISO-8859-1", "UTF-8",
                             nullptr, nullptr, nullptr);
  password_g = new GooString (password_latin);
  g_free (password_latin);

  return password_g;
}

/**
 * poppler_document_new_from_file:
 * @uri: uri of the file to load
 * @password: (allow-none): password to unlock the file with, or %NULL
 * @error: (allow-none): Return location for an error, or %NULL
 * 
 * Creates a new #PopplerDocument.  If %NULL is returned, then @error will be
 * set. Possible errors include those in the #POPPLER_ERROR and #G_FILE_ERROR
 * domains.
 * 
 * Return value: A newly created #PopplerDocument, or %NULL
 **/
PopplerDocument *
poppler_document_new_from_file (const char  *uri,
				const char  *password,
				GError     **error)
{
  PDFDoc *newDoc;
  GooString *password_g;
  char *filename;

  if (!globalParams) {
    globalParams = new GlobalParams();
  }

  filename = g_filename_from_uri (uri, nullptr, error);
  if (!filename)
    return nullptr;

  password_g = poppler_password_to_latin1(password);

#ifdef G_OS_WIN32
  wchar_t *filenameW;
  int length;

  length = MultiByteToWideChar(CP_UTF8, 0, filename, -1, nullptr, 0);

  filenameW = new WCHAR[length];
  if (!filenameW)
      return NULL;

  length = MultiByteToWideChar(CP_UTF8, 0, filename, -1, filenameW, length);

  newDoc = new PDFDoc(filenameW, length, password_g, password_g);
  delete [] filenameW;
#else
  GooString *filename_g;
  filename_g = new GooString (filename);
  newDoc = new PDFDoc(filename_g, password_g, password_g);
#endif
  g_free (filename);

  delete password_g;

  return _poppler_document_new_from_pdfdoc (newDoc, error);
}

/**
 * poppler_document_new_from_data:
 * @data: (array length=length) (element-type guint8): the pdf data
 * @length: the length of #data
 * @password: (allow-none): password to unlock the file with, or %NULL
 * @error: (allow-none): Return location for an error, or %NULL
 * 
 * Creates a new #PopplerDocument.  If %NULL is returned, then @error will be
 * set. Possible errors include those in the #POPPLER_ERROR and #G_FILE_ERROR
 * domains.
 *
 * Note that @data must remain valid for as long as the returned document exists.
 * Prefer using poppler_document_new_from_bytes().
 * 
 * Return value: A newly created #PopplerDocument, or %NULL
 **/
PopplerDocument *
poppler_document_new_from_data (char        *data,
                                int          length,
                                const char  *password,
                                GError     **error)
{
  PDFDoc *newDoc;
  MemStream *str;
  GooString *password_g;

  if (!globalParams) {
    globalParams = new GlobalParams();
  }
  
  // create stream
  str = new MemStream(data, 0, length, Object(objNull));

  password_g = poppler_password_to_latin1(password);
  newDoc = new PDFDoc(str, password_g, password_g);
  delete password_g;

  return _poppler_document_new_from_pdfdoc (newDoc, error);
}

class BytesStream : public MemStream
{
  std::unique_ptr<GBytes, decltype(&g_bytes_unref)> m_bytes;

public:
  BytesStream(GBytes *bytes, Object &&dictA)
    : MemStream(static_cast<const char*>(g_bytes_get_data(bytes, nullptr)),
		0, g_bytes_get_size(bytes), std::move(dictA)),
      m_bytes{g_bytes_ref(bytes), &g_bytes_unref}
  { }
};

/**
 * poppler_document_new_from_bytes:
 * @bytes: a #GBytes
 * @password: (allow-none): password to unlock the file with, or %NULL
 * @error: (allow-none): Return location for an error, or %NULL
 *
 * Creates a new #PopplerDocument from @bytes. The returned document
 * will hold a reference to @bytes.
 *
 * On error,  %NULL is returned, with @error set. Possible errors include
 * those in the #POPPLER_ERROR and #G_FILE_ERROR domains.
 *
 * Return value: (transfer full): a newly created #PopplerDocument, or %NULL
 *
 * Since: 0.82
 **/
PopplerDocument *
poppler_document_new_from_bytes (GBytes      *bytes,
				 const char  *password,
				 GError     **error)
{
  PDFDoc *newDoc;
  BytesStream *str;
  GooString *password_g;

  g_return_val_if_fail(bytes != nullptr, nullptr);
  g_return_val_if_fail(error == nullptr || *error == nullptr, nullptr);

  if (!globalParams) {
    globalParams = new GlobalParams();
  }

  // create stream
  str = new BytesStream(bytes, Object(objNull));

  password_g = poppler_password_to_latin1(password);
  newDoc = new PDFDoc(str, password_g, password_g);
  delete password_g;

  return _poppler_document_new_from_pdfdoc (newDoc, error);
}

static inline gboolean
stream_is_memory_buffer_or_local_file (GInputStream *stream)
{
  return G_IS_MEMORY_INPUT_STREAM(stream) ||
    (G_IS_FILE_INPUT_STREAM(stream) && strcmp(g_type_name_from_instance((GTypeInstance*)stream), "GLocalFileInputStream") == 0);
}

/**
 * poppler_document_new_from_stream:
 * @stream: a #GInputStream to read from
 * @length: the stream length, or -1 if not known
 * @password: (allow-none): password to unlock the file with, or %NULL
 * @cancellable: (allow-none): a #GCancellable, or %NULL
 * @error: (allow-none): Return location for an error, or %NULL
 *
 * Creates a new #PopplerDocument reading the PDF contents from @stream.
 * Note that the given #GInputStream must be seekable or %G_IO_ERROR_NOT_SUPPORTED
 * will be returned.
 * Possible errors include those in the #POPPLER_ERROR, #G_FILE_ERROR
 * and #G_IO_ERROR domains.
 *
 * Returns: (transfer full): a new #PopplerDocument, or %NULL
 *
 * Since: 0.22
 */
PopplerDocument *
poppler_document_new_from_stream (GInputStream *stream,
                                  goffset       length,
                                  const char   *password,
                                  GCancellable *cancellable,
                                  GError      **error)
{
  PDFDoc *newDoc;
  BaseStream *str;
  GooString *password_g;

  g_return_val_if_fail(G_IS_INPUT_STREAM(stream), NULL);
  g_return_val_if_fail(length == (goffset)-1 || length > 0, NULL);

  if (!globalParams) {
    globalParams = new GlobalParams();
  }

  if (!G_IS_SEEKABLE(stream) || !g_seekable_can_seek(G_SEEKABLE(stream))) {
    g_set_error_literal(error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
                        "Stream is not seekable");
    return nullptr;
  }

  if (stream_is_memory_buffer_or_local_file(stream)) {
    if (length == (goffset)-1) {
      if (!g_seekable_seek(G_SEEKABLE(stream), 0, G_SEEK_END, cancellable, error)) {
        g_prefix_error(error, "Unable to determine length of stream: ");
        return nullptr;
      }
      length = g_seekable_tell(G_SEEKABLE(stream));
    }
    str = new PopplerInputStream(stream, cancellable, 0, false, length, Object(objNull));
  } else {
    CachedFile *cachedFile = new CachedFile(new PopplerCachedFileLoader(stream, cancellable, length), new GooString());
    str = new CachedFileStream(cachedFile, 0, false, cachedFile->getLength(), Object(objNull));
  }

  password_g = poppler_password_to_latin1(password);
  newDoc = new PDFDoc(str, password_g, password_g);
  delete password_g;

  return _poppler_document_new_from_pdfdoc (newDoc, error);
}

/**
 * poppler_document_new_from_gfile:
 * @file: a #GFile to load
 * @password: (allow-none): password to unlock the file with, or %NULL
 * @cancellable: (allow-none): a #GCancellable, or %NULL
 * @error: (allow-none): Return location for an error, or %NULL
 *
 * Creates a new #PopplerDocument reading the PDF contents from @file.
 * Possible errors include those in the #POPPLER_ERROR and #G_FILE_ERROR
 * domains.
 *
 * Returns: (transfer full): a new #PopplerDocument, or %NULL
 *
 * Since: 0.22
 */
PopplerDocument *
poppler_document_new_from_gfile (GFile        *file,
                                 const char   *password,
                                 GCancellable *cancellable,
                                 GError      **error)
{
  PopplerDocument *document;
  GFileInputStream *stream;

  g_return_val_if_fail(G_IS_FILE(file), NULL);

  if (g_file_is_native(file)) {
    gchar *uri;

    uri = g_file_get_uri(file);
    document = poppler_document_new_from_file(uri, password, error);
    g_free(uri);

    return document;
  }

  stream = g_file_read(file, cancellable, error);
  if (!stream)
    return nullptr;

  document = poppler_document_new_from_stream(G_INPUT_STREAM(stream), -1, password, cancellable, error);
  g_object_unref(stream);

  return document;
}

static gboolean
handle_save_error (int      err_code,
		   GError **error)
{
  switch (err_code)
    {
    case errNone:
      break;
    case errOpenFile:
      g_set_error (error, POPPLER_ERROR,
		   POPPLER_ERROR_OPEN_FILE,
		   "Failed to open file for writing");
      break;
    case errEncrypted:
      g_set_error (error, POPPLER_ERROR,
		   POPPLER_ERROR_ENCRYPTED,
		   "Document is encrypted");
      break;
    default:
      g_set_error (error, POPPLER_ERROR,
		   POPPLER_ERROR_INVALID,
		   "Failed to save document");
    }

  return err_code == errNone;
}

/**
 * poppler_document_save:
 * @document: a #PopplerDocument
 * @uri: uri of file to save
 * @error: (allow-none): return location for an error, or %NULL
 *
 * Saves @document. Any change made in the document such as
 * form fields filled, annotations added or modified
 * will be saved.
 * If @error is set, %FALSE will be returned. Possible errors
 * include those in the #G_FILE_ERROR domain.
 * 
 * Return value: %TRUE, if the document was successfully saved
 **/
gboolean
poppler_document_save (PopplerDocument  *document,
		       const char       *uri,
		       GError          **error)
{
  char *filename;
  gboolean retval = FALSE;

  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), FALSE);

  filename = g_filename_from_uri (uri, nullptr, error);
  if (filename != nullptr) {
    GooString *fname = new GooString (filename);
    int err_code;
    g_free (filename);

    err_code = document->doc->saveAs (fname);
    retval = handle_save_error (err_code, error);
    delete fname;
  }

  return retval;
}

/**
 * poppler_document_save_a_copy:
 * @document: a #PopplerDocument
 * @uri: uri of file to save
 * @error: (allow-none): return location for an error, or %NULL
 * 
 * Saves a copy of the original @document.
 * Any change made in the document such as 
 * form fields filled by the user will not be saved. 
 * If @error is set, %FALSE will be returned. Possible errors
 * include those in the #G_FILE_ERROR domain.
 * 
 * Return value: %TRUE, if the document was successfully saved
 **/
gboolean
poppler_document_save_a_copy (PopplerDocument  *document,
			      const char       *uri,
			      GError          **error)
{
  char *filename;
  gboolean retval = FALSE;

  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), FALSE);

  filename = g_filename_from_uri (uri, nullptr, error);
  if (filename != nullptr) {
    GooString *fname = new GooString (filename);
    int err_code;
    g_free (filename);

    err_code = document->doc->saveWithoutChangesAs (fname);
    retval = handle_save_error (err_code, error);
    delete fname;
  }

  return retval;
}

static void
poppler_document_finalize (GObject *object)
{
  PopplerDocument *document = POPPLER_DOCUMENT (object);

  poppler_document_layers_free (document);
  delete document->output_dev;
  delete document->doc;

  G_OBJECT_CLASS (poppler_document_parent_class)->finalize (object);
}

/**
 * poppler_document_get_id:
 * @document: A #PopplerDocument
 * @permanent_id: (out) (allow-none): location to store an allocated string, use g_free() to free the returned string
 * @update_id: (out) (allow-none): location to store an allocated string, use g_free() to free the returned string
 *
 * Returns the PDF file identifier represented as two byte string arrays of size 32.
 * @permanent_id is the permanent identifier that is built based on the file
 * contents at the time it was originally created, so that this identifer
 * never changes. @update_id is the update identifier that is built based on
 * the file contents at the time it was last updated.
 *
 * Note that returned strings are not null-terminated, they have a fixed
 * size of 32 bytes.
 *
 * Returns: %TRUE if the @document contains an id, %FALSE otherwise
 *
 * Since: 0.16
 */
gboolean
poppler_document_get_id (PopplerDocument *document,
			 gchar          **permanent_id,
			 gchar          **update_id)
{
  GooString permanent;
  GooString update;
  gboolean  retval = FALSE;

  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), FALSE);

  if (permanent_id)
    *permanent_id = nullptr;
  if (update_id)
    *update_id = nullptr;

  if (document->doc->getID (permanent_id ? &permanent : nullptr, update_id ? &update : nullptr)) {
    if (permanent_id)
      *permanent_id = (gchar *)g_memdup (permanent.c_str(), 32);
    if (update_id)
      *update_id = (gchar *)g_memdup (update.c_str(), 32);

    retval = TRUE;
  }

  return retval;
}

/**
 * poppler_document_get_n_pages:
 * @document: A #PopplerDocument
 * 
 * Returns the number of pages in a loaded document.
 * 
 * Return value: Number of pages
 **/
int
poppler_document_get_n_pages (PopplerDocument *document)
{
  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), 0);

  return document->doc->getNumPages();
}

/**
 * poppler_document_get_page:
 * @document: A #PopplerDocument
 * @index: a page index 
 * 
 * Returns the #PopplerPage indexed at @index.  This object is owned by the
 * caller.
 *
 * Return value: (transfer full) : The #PopplerPage at @index
 **/
PopplerPage *
poppler_document_get_page (PopplerDocument  *document,
			   int               index)
{
  Page *page;

  g_return_val_if_fail (0 <= index &&
			index < poppler_document_get_n_pages (document),
			NULL);

  page = document->doc->getPage (index + 1);
  if (!page) return nullptr;

  return _poppler_page_new (document, page, index);
}

/**
 * poppler_document_get_page_by_label:
 * @document: A #PopplerDocument
 * @label: a page label
 * 
 * Returns the #PopplerPage reference by @label.  This object is owned by the
 * caller.  @label is a human-readable string representation of the page number,
 * and can be document specific.  Typically, it is a value such as "iii" or "3".
 *
 * By default, "1" refers to the first page.
 * 
 * Return value: (transfer full) :The #PopplerPage referenced by @label
 **/
PopplerPage *
poppler_document_get_page_by_label (PopplerDocument  *document,
				    const char       *label)
{
  Catalog *catalog;
  GooString label_g(label);
  int index;

  catalog = document->doc->getCatalog();
  if (!catalog->labelToIndex (&label_g, &index))
    return nullptr;

  return poppler_document_get_page (document, index);
}

/**
 * poppler_document_get_n_attachments:
 * @document: A #PopplerDocument
 *
 * Returns the number of attachments in a loaded document.
 * See also poppler_document_get_attachments()
 *
 * Return value: Number of attachments
 *
 * Since: 0.18
 */
guint
poppler_document_get_n_attachments (PopplerDocument *document)
{
  Catalog *catalog;

  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), 0);

  catalog = document->doc->getCatalog ();

  return catalog && catalog->isOk () ? catalog->numEmbeddedFiles () : 0;
}

/**
 * poppler_document_has_attachments:
 * @document: A #PopplerDocument
 * 
 * Returns %TRUE of @document has any attachments.
 * 
 * Return value: %TRUE, if @document has attachments.
 **/
gboolean
poppler_document_has_attachments (PopplerDocument *document)
{
  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), FALSE);

  return (poppler_document_get_n_attachments (document) != 0);
}

/**
 * poppler_document_get_attachments:
 * @document: A #PopplerDocument
 *
 * Returns a #GList containing #PopplerAttachment<!-- -->s.  These attachments
 * are unowned, and must be unreffed, and the list must be freed with
 * g_list_free().
 *
 * Return value: (element-type PopplerAttachment) (transfer full): a list of available attachments.
 **/
GList *
poppler_document_get_attachments (PopplerDocument *document)
{
  Catalog *catalog;
  int n_files, i;
  GList *retval = nullptr;

  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);

  catalog = document->doc->getCatalog ();
  if (catalog == nullptr || ! catalog->isOk ())
    return nullptr;

  n_files = catalog->numEmbeddedFiles ();
  for (i = 0; i < n_files; i++)
    {
      PopplerAttachment *attachment;
      FileSpec *emb_file;

      emb_file = catalog->embeddedFile (i);
      if (!emb_file->isOk () || !emb_file->getEmbeddedFile()->isOk()) {
        delete emb_file;
	continue;
      }

      attachment = _poppler_attachment_new (emb_file);
      delete emb_file;

      if (attachment != nullptr)
        retval = g_list_prepend (retval, attachment);
    }
  return g_list_reverse (retval);
}

/**
 * poppler_named_dest_from_bytestring:
 * @data: (array length=length): the bytestring data
 * @length: the bytestring length
 *
 * Converts a bytestring into a zero-terminated string suitable to
 * pass to poppler_document_find_dest().
 *
 * Note that the returned string has no defined encoding and is not
 * suitable for display to the user.
 *
 * The returned data must be freed using g_free().
 *
 * Returns: (transfer full): the named dest
 *
 * Since: 0.73
 */
char *
poppler_named_dest_from_bytestring (const guint8 *data,
				    gsize         length)
{
  const guint8 *p, *pend;
  char *dest, *q;

  g_return_val_if_fail (length != 0 || data != nullptr, nullptr);
  /* Each source byte needs maximally 2 destination chars (\\ or \0) */
  q = dest = (gchar *)g_malloc (length * 2 + 1);

  pend = data + length;
  for (p = data; p < pend; ++p) {
    switch (*p) {
    case '\0':
      *q++ = '\\';
      *q++ = '0';
      break;
    case '\\':
      *q++ = '\\';
      *q++ = '\\';
      break;
    default:
      *q++ = *p;
      break;
    }
  }

  *q = 0; /* zero terminate */
  return dest;
}

/**
 * poppler_named_dest_to_bytestring:
 * @name: the named dest string
 * @length: (out): a location to store the length of the returned bytestring
 *
 * Converts a named dest string (e.g. from #PopplerDest.named_dest) into a
 * bytestring, inverting the transformation of
 * poppler_named_dest_from_bytestring().
 *
 * Note that the returned data is not zero terminated and may also
 * contains embedded NUL bytes.
 *
 * If @name is not a valid named dest string, returns %NULL.
 *
 * The returned data must be freed using g_free().
 *
 * Returns: (array length=length) (transfer full) (nullable): a new bytestring,
 *   or %NULL
 *
 * Since: 0.73
 */
guint8 *
poppler_named_dest_to_bytestring (const char *name,
				  gsize      *length)
{
  const char *p;
  guint8 *data, *q;
  gsize len;

  g_return_val_if_fail (name != nullptr, nullptr);
  g_return_val_if_fail (length != nullptr, nullptr);

  len = strlen (name);
  q = data = (guint8*) g_malloc (len);
  for (p = name; *p; ++p) {
    if (*p == '\\') {
      p++;
      len--;
      if (*p == '0')
	*q++ = '\0';
      else if (*p == '\\')
	*q++ = '\\';
      else
	goto invalid;
    } else {
      *q++ = *p;
    }
  }

  *length = len;
  return data;

invalid:
  g_free(data);
  *length = 0;
  return nullptr;
}

/**
 * poppler_document_find_dest:
 * @document: A #PopplerDocument
 * @link_name: a named destination
 *
 * Creates a #PopplerDest for the named destination @link_name in @document.
 *
 * Note that named destinations are bytestrings, not string. That means that
 * unless @link_name was returned by a poppler function (e.g. is
 * #PopplerDest.named_dest), it needs to be converted to string
 * using poppler_named_dest_from_bytestring() before being passed to this
 * function.
 *
 * The returned value must be freed with poppler_dest_free().
 *
 * Return value: (transfer full): a new #PopplerDest destination, or %NULL if
 *   @link_name is not a destination.
 **/
PopplerDest *
poppler_document_find_dest (PopplerDocument *document,
			    const gchar     *link_name)
{
  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), nullptr);
  g_return_val_if_fail (link_name != nullptr, nullptr);

  gsize len;
  guint8* data = poppler_named_dest_to_bytestring (link_name, &len);
  if (data == nullptr)
    return nullptr;

  GooString g_link_name ((const char*)data, (int)len);
  g_free (data);

  LinkDest *link_dest = document->doc->findDest (&g_link_name);
  if (link_dest == nullptr)
    return nullptr;

  PopplerDest *dest = _poppler_dest_new_goto (document, link_dest);
  delete link_dest;

  return dest;
}

static gint
_poppler_dest_compare_keys (gconstpointer a,
			    gconstpointer b,
			    gpointer user_data)
{
	return g_strcmp0 (static_cast<const gchar*>(a),
			  static_cast<const gchar*>(b));
}

static void
_poppler_dest_destroy_value (gpointer value)
{
	poppler_dest_free (static_cast<PopplerDest*>(value));
}

/**
 * poppler_document_create_dests_tree:
 * @document: A #PopplerDocument
 *
 * Creates named destinations balanced binary tree in @document
 *
 * The tree key is strings in the form returned by
 * poppler_named_dest_bytestring() which constains a destination name.
 * The tree value is the #PopplerDest* which contains a named destination.
 * The return value must be freed with #g_tree_destroy.
 *
 * Returns: (transfer full) (nullable): the #GTree, or %NULL
 * Since: 0.78
 **/
GTree *
poppler_document_create_dests_tree (PopplerDocument *document)
{
	GTree *tree;
	Catalog *catalog;
	LinkDest *link_dest;
	PopplerDest *dest;
	int i;
	gchar *key;

	g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), nullptr);

	catalog = document->doc->getCatalog ();
	if (catalog == nullptr)
		return nullptr;

	tree = g_tree_new_full (_poppler_dest_compare_keys, nullptr,
				g_free,
				_poppler_dest_destroy_value);

	// Iterate from name-dict
	const int nDests = catalog->numDests ();
	for (i = 0; i < nDests; ++i) {
		// The names of name-dict cannot contain \0,
		// so we can use strlen().
		auto name = catalog->getDestsName (i);
		key = poppler_named_dest_from_bytestring
			(reinterpret_cast<const guint8*> (name),
			 strlen (name));
		link_dest = catalog->getDestsDest (i);
		if (link_dest) {
			dest = _poppler_dest_new_goto (document, link_dest);
			delete link_dest;
			g_tree_insert (tree, key, dest);
		}
	}

	// Iterate form name-tree
	const int nDestsNameTree = catalog->numDestNameTree ();
	for (i = 0; i < nDestsNameTree; ++i) {
		auto name = catalog->getDestNameTreeName (i);
		key = poppler_named_dest_from_bytestring
			(reinterpret_cast<const guint8*> (name->c_str ()),
			 name->getLength ());
		link_dest = catalog->getDestNameTreeDest (i);
		if (link_dest) {
			dest = _poppler_dest_new_goto (document, link_dest);
			delete link_dest;
			g_tree_insert (tree, key, dest);
		}
	}

	return tree;
}

char *_poppler_goo_string_to_utf8(const GooString *s)
{
  if (s == nullptr) {
    return nullptr;
  }

  char *result;

  if (s->hasUnicodeMarker()) {
    result = g_convert (s->c_str () + 2,
			s->getLength () - 2,
			"UTF-8", "UTF-16BE", nullptr, nullptr, nullptr);
  } else if (s->hasUnicodeMarkerLE()) {
    result = g_convert (s->c_str () + 2,
			s->getLength () - 2,
			"UTF-8", "UTF-16LE", nullptr, nullptr, nullptr);
  } else {
    int len;
    gunichar *ucs4_temp;
    int i;
    
    len = s->getLength ();
    ucs4_temp = g_new (gunichar, len + 1);
    for (i = 0; i < len; ++i) {
      ucs4_temp[i] = pdfDocEncoding[(unsigned char)s->getChar(i)];
    }
    ucs4_temp[i] = 0;

    result = g_ucs4_to_utf8 (ucs4_temp, -1, nullptr, nullptr, nullptr);

    g_free (ucs4_temp);
  }

  return result;
}

static GooString *
_poppler_goo_string_from_utf8(const gchar *src)
{
  if (src == nullptr) {
    return nullptr;
  }

  gsize outlen;

  gchar *utf16 = g_convert (src, -1, "UTF-16BE", "UTF-8", nullptr, &outlen, nullptr);
  if (utf16 == nullptr) {
    return nullptr;
  }

  GooString *result = new GooString (utf16, outlen);
  g_free (utf16);

  if (!result->hasUnicodeMarker()) {
    result->prependUnicodeMarker();
  }

  return result;
}

static PopplerPageLayout
convert_page_layout (Catalog::PageLayout pageLayout)
{
  switch (pageLayout)
    {
    case Catalog::pageLayoutSinglePage:
      return POPPLER_PAGE_LAYOUT_SINGLE_PAGE;
    case Catalog::pageLayoutOneColumn:
      return POPPLER_PAGE_LAYOUT_ONE_COLUMN;
    case Catalog::pageLayoutTwoColumnLeft:
      return POPPLER_PAGE_LAYOUT_TWO_COLUMN_LEFT;
    case Catalog::pageLayoutTwoColumnRight:
      return POPPLER_PAGE_LAYOUT_TWO_COLUMN_RIGHT;
    case Catalog::pageLayoutTwoPageLeft:
      return POPPLER_PAGE_LAYOUT_TWO_PAGE_LEFT;
    case Catalog::pageLayoutTwoPageRight:
      return POPPLER_PAGE_LAYOUT_TWO_PAGE_RIGHT;
    case Catalog::pageLayoutNone:
    default:
      return POPPLER_PAGE_LAYOUT_UNSET;
    }
}

static PopplerPageMode
convert_page_mode (Catalog::PageMode pageMode)
{
  switch (pageMode)
    {
    case Catalog::pageModeOutlines:
      return POPPLER_PAGE_MODE_USE_OUTLINES;
    case Catalog::pageModeThumbs:
      return POPPLER_PAGE_MODE_USE_THUMBS;
    case Catalog::pageModeFullScreen:
      return POPPLER_PAGE_MODE_FULL_SCREEN;
    case Catalog::pageModeOC:
      return POPPLER_PAGE_MODE_USE_OC;
    case Catalog::pageModeAttach:
      return POPPLER_PAGE_MODE_USE_ATTACHMENTS;
    case Catalog::pageModeNone:
    default:
      return POPPLER_PAGE_MODE_UNSET;
    }
}

static PopplerPDFSubtype
convert_pdf_subtype (PDFSubtype pdfSubtype)
{
  switch (pdfSubtype)
    {
    case subtypePDFA:
      return POPPLER_PDF_SUBTYPE_PDF_A;
    case subtypePDFE:
      return POPPLER_PDF_SUBTYPE_PDF_E;
    case subtypePDFUA:
      return POPPLER_PDF_SUBTYPE_PDF_UA;
    case subtypePDFVT:
      return POPPLER_PDF_SUBTYPE_PDF_VT;
    case subtypePDFX:
      return POPPLER_PDF_SUBTYPE_PDF_X;
    case subtypeNone:
      return POPPLER_PDF_SUBTYPE_NONE;
    case subtypeNull:
    default:
      return POPPLER_PDF_SUBTYPE_UNSET;
    }
}

static PopplerPDFPart
convert_pdf_subtype_part (PDFSubtypePart pdfSubtypePart)
{
  switch (pdfSubtypePart)
    {
    case subtypePart1:
      return POPPLER_PDF_SUBTYPE_PART_1;
    case subtypePart2:
      return POPPLER_PDF_SUBTYPE_PART_2;
    case subtypePart3:
      return POPPLER_PDF_SUBTYPE_PART_3;
    case subtypePart4:
      return POPPLER_PDF_SUBTYPE_PART_4;
    case subtypePart5:
      return POPPLER_PDF_SUBTYPE_PART_5;
    case subtypePart6:
      return POPPLER_PDF_SUBTYPE_PART_6;
    case subtypePart7:
      return POPPLER_PDF_SUBTYPE_PART_7;
    case subtypePart8:
      return POPPLER_PDF_SUBTYPE_PART_8;
    case subtypePartNone:
      return POPPLER_PDF_SUBTYPE_PART_NONE;
    case subtypePartNull:
    default:
      return POPPLER_PDF_SUBTYPE_PART_UNSET;
    }
}

static PopplerPDFConformance
convert_pdf_subtype_conformance (PDFSubtypeConformance pdfSubtypeConf)
{
  switch (pdfSubtypeConf)
    {
    case subtypeConfA:
      return POPPLER_PDF_SUBTYPE_CONF_A;
    case subtypeConfB:
      return POPPLER_PDF_SUBTYPE_CONF_B;
    case subtypeConfG:
      return POPPLER_PDF_SUBTYPE_CONF_G;
    case subtypeConfN:
      return POPPLER_PDF_SUBTYPE_CONF_N;
    case subtypeConfP:
      return POPPLER_PDF_SUBTYPE_CONF_P;
    case subtypeConfPG:
      return POPPLER_PDF_SUBTYPE_CONF_PG;
    case subtypeConfU:
      return POPPLER_PDF_SUBTYPE_CONF_U;
    case subtypeConfNone:
      return POPPLER_PDF_SUBTYPE_CONF_NONE;
    case subtypeConfNull:
    default:
      return POPPLER_PDF_SUBTYPE_CONF_UNSET;
    }
}

/**
 * poppler_document_get_pdf_version_string:
 * @document: A #PopplerDocument
 *
 * Returns the PDF version of @document as a string (e.g. PDF-1.6)
 *
 * Return value: a new allocated string containing the PDF version
 *               of @document, or %NULL
 *
 * Since: 0.16
 **/
gchar *
poppler_document_get_pdf_version_string (PopplerDocument *document)
{
  gchar *retval;

  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);

  retval = g_strndup ("PDF-", 15); /* allocates 16 chars, pads with \0s */
  g_ascii_formatd (retval + 4, 15 + 1 - 4, "%.2g",
		   document->doc->getPDFMajorVersion () + document->doc->getPDFMinorVersion() / 10.0);
  return retval;
}

/**
 * poppler_document_get_pdf_version:
 * @document: A #PopplerDocument
 * @major_version: (out) (allow-none): return location for the PDF major version number
 * @minor_version: (out) (allow-none): return location for the PDF minor version number
 *
 * Returns: the major and minor PDF version numbers
 *
 * Since: 0.16
 **/
void
poppler_document_get_pdf_version (PopplerDocument *document,
				  guint           *major_version,
				  guint           *minor_version)
{
  g_return_if_fail (POPPLER_IS_DOCUMENT (document));

  if (major_version)
    *major_version = document->doc->getPDFMajorVersion ();
  if (minor_version)
    *minor_version = document->doc->getPDFMinorVersion();
}

/**
 * poppler_document_get_title:
 * @document: A #PopplerDocument
 *
 * Returns the document's title
 *
 * Return value: a new allocated string containing the title
 *               of @document, or %NULL
 *
 * Since: 0.16
 **/
gchar *
poppler_document_get_title (PopplerDocument *document)
{
  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);

  GooString *goo_title = document->doc->getDocInfoTitle();
  gchar *utf8 = _poppler_goo_string_to_utf8(goo_title);
  delete goo_title;

  return utf8;
}

/**
 * poppler_document_set_title:
 * @document: A #PopplerDocument
 * @title: A new title
 *
 * Sets the document's title. If @title is %NULL, Title entry
 * is removed from the document's Info dictionary.
 *
 * Since: 0.46
 **/
void
poppler_document_set_title (PopplerDocument *document, const gchar *title)
{
  g_return_if_fail (POPPLER_IS_DOCUMENT (document));

  GooString *goo_title;
  if (!title) {
    goo_title = nullptr;
  } else {
    goo_title = _poppler_goo_string_from_utf8(title);
    if (!goo_title)
      return;
  }
  document->doc->setDocInfoTitle(goo_title);
}

/**
 * poppler_document_get_author:
 * @document: A #PopplerDocument
 *
 * Returns the author of the document
 *
 * Return value: a new allocated string containing the author
 *               of @document, or %NULL
 *
 * Since: 0.16
 **/
gchar *
poppler_document_get_author (PopplerDocument *document)
{
  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);

  GooString *goo_author = document->doc->getDocInfoAuthor();
  gchar *utf8 = _poppler_goo_string_to_utf8(goo_author);
  delete goo_author;

  return utf8;
}

/**
 * poppler_document_set_author:
 * @document: A #PopplerDocument
 * @author: A new author
 *
 * Sets the document's author. If @author is %NULL, Author
 * entry is removed from the document's Info dictionary.
 *
 * Since: 0.46
 **/
void
poppler_document_set_author (PopplerDocument *document, const gchar *author)
{
  g_return_if_fail (POPPLER_IS_DOCUMENT (document));

  GooString *goo_author;
  if (!author) {
    goo_author = nullptr;
  } else {
    goo_author = _poppler_goo_string_from_utf8(author);
    if (!goo_author)
      return;
  }
  document->doc->setDocInfoAuthor(goo_author);
}

/**
 * poppler_document_get_subject:
 * @document: A #PopplerDocument
 *
 * Returns the subject of the document
 *
 * Return value: a new allocated string containing the subject
 *               of @document, or %NULL
 *
 * Since: 0.16
 **/
gchar *
poppler_document_get_subject (PopplerDocument *document)
{
  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);

  GooString *goo_subject = document->doc->getDocInfoSubject();
  gchar *utf8 = _poppler_goo_string_to_utf8(goo_subject);
  delete goo_subject;

  return utf8;
}

/**
 * poppler_document_set_subject:
 * @document: A #PopplerDocument
 * @subject: A new subject
 *
 * Sets the document's subject. If @subject is %NULL, Subject
 * entry is removed from the document's Info dictionary.
 *
 * Since: 0.46
 **/
void
poppler_document_set_subject (PopplerDocument *document, const gchar *subject)
{
  g_return_if_fail (POPPLER_IS_DOCUMENT (document));

  GooString *goo_subject;
  if (!subject) {
    goo_subject = nullptr;
  } else {
    goo_subject = _poppler_goo_string_from_utf8(subject);
    if (!goo_subject)
      return;
  }
  document->doc->setDocInfoSubject(goo_subject);
}

/**
 * poppler_document_get_keywords:
 * @document: A #PopplerDocument
 *
 * Returns the keywords associated to the document
 *
 * Return value: a new allocated string containing keywords associated
 *               to @document, or %NULL
 *
 * Since: 0.16
 **/
gchar *
poppler_document_get_keywords (PopplerDocument *document)
{
  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);

  GooString *goo_keywords = document->doc->getDocInfoKeywords();
  gchar *utf8 = _poppler_goo_string_to_utf8(goo_keywords);
  delete goo_keywords;

  return utf8;
}

/**
 * poppler_document_set_keywords:
 * @document: A #PopplerDocument
 * @keywords: New keywords
 *
 * Sets the document's keywords. If @keywords is %NULL,
 * Keywords entry is removed from the document's Info dictionary.
 *
 * Since: 0.46
 **/
void
poppler_document_set_keywords (PopplerDocument *document, const gchar *keywords)
{
  g_return_if_fail (POPPLER_IS_DOCUMENT (document));

  GooString *goo_keywords;
  if (!keywords) {
    goo_keywords = nullptr;
  } else {
    goo_keywords = _poppler_goo_string_from_utf8(keywords);
    if (!goo_keywords)
      return;
  }
  document->doc->setDocInfoKeywords(goo_keywords);
}

/**
 * poppler_document_get_creator:
 * @document: A #PopplerDocument
 *
 * Returns the creator of the document. If the document was converted
 * from another format, the creator is the name of the product
 * that created the original document from which it was converted.
 *
 * Return value: a new allocated string containing the creator
 *               of @document, or %NULL
 *
 * Since: 0.16
 **/
gchar *
poppler_document_get_creator (PopplerDocument *document)
{
  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);

  GooString *goo_creator = document->doc->getDocInfoCreator();
  gchar *utf8 = _poppler_goo_string_to_utf8(goo_creator);
  delete goo_creator;

  return utf8;
}

/**
 * poppler_document_set_creator:
 * @document: A #PopplerDocument
 * @creator: A new creator
 *
 * Sets the document's creator. If @creator is %NULL, Creator
 * entry is removed from the document's Info dictionary.
 *
 * Since: 0.46
 **/
void
poppler_document_set_creator (PopplerDocument *document, const gchar *creator)
{
  g_return_if_fail (POPPLER_IS_DOCUMENT (document));

  GooString *goo_creator;
  if (!creator) {
    goo_creator = nullptr;
  } else {
    goo_creator = _poppler_goo_string_from_utf8(creator);
    if (!goo_creator)
      return;
  }
  document->doc->setDocInfoCreator(goo_creator);
}

/**
 * poppler_document_get_producer:
 * @document: A #PopplerDocument
 *
 * Returns the producer of the document. If the document was converted
 * from another format, the producer is the name of the product
 * that converted it to PDF
 *
 * Return value: a new allocated string containing the producer
 *               of @document, or %NULL
 *
 * Since: 0.16
 **/
gchar *
poppler_document_get_producer (PopplerDocument *document)
{
  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);

  GooString *goo_producer = document->doc->getDocInfoProducer();
  gchar *utf8 = _poppler_goo_string_to_utf8(goo_producer);
  delete goo_producer;

  return utf8;
}

/**
 * poppler_document_set_producer:
 * @document: A #PopplerDocument
 * @producer: A new producer
 *
 * Sets the document's producer. If @producer is %NULL,
 * Producer entry is removed from the document's Info dictionary.
 *
 * Since: 0.46
 **/
void
poppler_document_set_producer (PopplerDocument *document, const gchar *producer)
{
  g_return_if_fail (POPPLER_IS_DOCUMENT (document));

  GooString *goo_producer;
  if (!producer) {
    goo_producer = nullptr;
  } else {
    goo_producer = _poppler_goo_string_from_utf8(producer);
    if (!goo_producer)
      return;
  }
  document->doc->setDocInfoProducer(goo_producer);
}

/**
 * poppler_document_get_creation_date:
 * @document: A #PopplerDocument
 *
 * Returns the date the document was created as seconds since the Epoch
 *
 * Return value: the date the document was created, or -1
 *
 * Since: 0.16
 **/
time_t
poppler_document_get_creation_date (PopplerDocument *document)
{
  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), (time_t)-1);

  GooString *str = document->doc->getDocInfoCreatDate();
  if (str == nullptr) {
    return (time_t)-1;
  }

  time_t date;
  gboolean success = _poppler_convert_pdf_date_to_gtime (str, &date);
  delete str;

  return (success) ? date : (time_t)-1;
}

/**
 * poppler_document_set_creation_date:
 * @document: A #PopplerDocument
 * @creation_date: A new creation date
 *
 * Sets the document's creation date. If @creation_date is -1, CreationDate
 * entry is removed from the document's Info dictionary.
 *
 * Since: 0.46
 **/
void
poppler_document_set_creation_date (PopplerDocument *document,
                                    time_t creation_date)
{
  g_return_if_fail (POPPLER_IS_DOCUMENT (document));

  GooString *str = creation_date == (time_t)-1 ? nullptr : timeToDateString (&creation_date);
  document->doc->setDocInfoCreatDate (str);
}

/**
 * poppler_document_get_modification_date:
 * @document: A #PopplerDocument
 *
 * Returns the date the document was most recently modified as seconds since the Epoch
 *
 * Return value: the date the document was most recently modified, or -1
 *
 * Since: 0.16
 **/
time_t
poppler_document_get_modification_date (PopplerDocument *document)
{
  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), (time_t)-1);

  GooString *str = document->doc->getDocInfoModDate();
  if (str == nullptr) {
    return (time_t)-1;
  }

  time_t date;
  gboolean success = _poppler_convert_pdf_date_to_gtime (str, &date);
  delete str;

  return (success) ? date : (time_t)-1;
}

/**
 * poppler_document_set_modification_date:
 * @document: A #PopplerDocument
 * @modification_date: A new modification date
 *
 * Sets the document's modification date. If @modification_date is -1, ModDate
 * entry is removed from the document's Info dictionary.
 *
 * Since: 0.46
 **/
void
poppler_document_set_modification_date (PopplerDocument *document,
                                        time_t modification_date)
{
  g_return_if_fail (POPPLER_IS_DOCUMENT (document));

  GooString *str = modification_date == (time_t)-1 ? nullptr : timeToDateString (&modification_date);
  document->doc->setDocInfoModDate (str);
}

/**
 * poppler_document_is_linearized:
 * @document: A #PopplerDocument
 *
 * Returns whether @document is linearized or not. Linearization of PDF
 * enables efficient incremental access of the PDF file in a network environment.
 *
 * Return value: %TRUE if @document is linearized, %FALSE otherwise
 *
 * Since: 0.16
 **/
gboolean
poppler_document_is_linearized (PopplerDocument *document)
{
  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), FALSE);

  return document->doc->isLinearized ();
}

/**
 * poppler_document_get_page_layout:
 * @document: A #PopplerDocument
 *
 * Returns the page layout that should be used when the document is opened
 *
 * Return value: a #PopplerPageLayout that should be used when the document is opened
 *
 * Since: 0.16
 **/
PopplerPageLayout
poppler_document_get_page_layout (PopplerDocument *document)
{
  Catalog *catalog;

  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), POPPLER_PAGE_LAYOUT_UNSET);

  catalog = document->doc->getCatalog ();
  if (catalog && catalog->isOk ())
    return convert_page_layout (catalog->getPageLayout ());

  return POPPLER_PAGE_LAYOUT_UNSET;
}

/**
 * poppler_document_get_page_mode:
 * @document: A #PopplerDocument
 *
 * Returns a #PopplerPageMode representing how the document should
 * be initially displayed when opened.
 *
 * Return value: a #PopplerPageMode that should be used when document is opened
 *
 * Since: 0.16
 **/
PopplerPageMode
poppler_document_get_page_mode (PopplerDocument *document)
{
  Catalog *catalog;

  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), POPPLER_PAGE_MODE_UNSET);

  catalog = document->doc->getCatalog ();
  if (catalog && catalog->isOk ())
    return convert_page_mode (catalog->getPageMode ());

  return POPPLER_PAGE_MODE_UNSET;
}

/**
 * poppler_document_get_print_scaling:
 * @document: A #PopplerDocument
 *
 * Returns the print scaling value suggested by author of the document.
 *
 * Return value: a #PopplerPrintScaling that should be used when document is printed
 *
 * Since: 0.73
 **/
PopplerPrintScaling
poppler_document_get_print_scaling (PopplerDocument *document)
{
  Catalog *catalog;
  ViewerPreferences *preferences;
  PopplerPrintScaling print_scaling = POPPLER_PRINT_SCALING_APP_DEFAULT;

  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), POPPLER_PRINT_SCALING_APP_DEFAULT);

  catalog = document->doc->getCatalog ();
  if (catalog && catalog->isOk ()) {
    preferences = catalog->getViewerPreferences();
    if (preferences) {
      switch (preferences->getPrintScaling()) {
        default:
        case ViewerPreferences::PrintScaling::printScalingAppDefault:
          print_scaling = POPPLER_PRINT_SCALING_APP_DEFAULT;
          break;
        case ViewerPreferences::PrintScaling::printScalingNone:
          print_scaling = POPPLER_PRINT_SCALING_NONE;
          break;
      }
    }
  }

  return print_scaling;
}

/**
 * poppler_document_get_print_duplex:
 * @document: A #PopplerDocument
 *
 * Returns the duplex mode value suggested for printing by author of the document.
 * Value POPPLER_PRINT_DUPLEX_NONE means that the document does not specify this
 * preference.
 *
 * Returns: a #PopplerPrintDuplex that should be used when document is printed
 *
 * Since: 0.80
 **/
PopplerPrintDuplex
poppler_document_get_print_duplex (PopplerDocument *document)
{
  Catalog *catalog;
  ViewerPreferences *preferences;
  PopplerPrintDuplex duplex = POPPLER_PRINT_DUPLEX_NONE;

  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), POPPLER_PRINT_DUPLEX_NONE);

  catalog = document->doc->getCatalog ();
  if (catalog && catalog->isOk ()) {
    preferences = catalog->getViewerPreferences();
    if (preferences) {
      switch (preferences->getDuplex()) {
        default:
        case ViewerPreferences::Duplex::duplexNone:
          duplex = POPPLER_PRINT_DUPLEX_NONE;
          break;
        case ViewerPreferences::Duplex::duplexSimplex:
          duplex = POPPLER_PRINT_DUPLEX_SIMPLEX;
          break;
        case ViewerPreferences::Duplex::duplexDuplexFlipShortEdge:
          duplex = POPPLER_PRINT_DUPLEX_DUPLEX_FLIP_SHORT_EDGE;
          break;
        case ViewerPreferences::Duplex::duplexDuplexFlipLongEdge:
          duplex = POPPLER_PRINT_DUPLEX_DUPLEX_FLIP_LONG_EDGE;
          break;
      }
    }
  }

  return duplex;
}

/**
 * poppler_document_get_print_n_copies:
 * @document: A #PopplerDocument
 *
 * Returns the suggested number of copies to be printed.
 * This preference should be applied only if returned value
 * is greater than 1 since value 1 usually means that
 * the document does not specify it.
 *
 * Returns: Number of copies
 *
 * Since: 0.80
 **/
gint
poppler_document_get_print_n_copies (PopplerDocument *document)
{
  Catalog *catalog;
  ViewerPreferences *preferences;
  gint retval = 1;

  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), 1);

  catalog = document->doc->getCatalog ();
  if (catalog && catalog->isOk ()) {
    preferences = catalog->getViewerPreferences();
    if (preferences) {
      retval = preferences->getNumCopies();
    }
  }

  return retval;
}

/**
 * poppler_document_get_print_page_ranges:
 * @document: A #PopplerDocument
 * @n_ranges: (out): return location for number of ranges
 *
 * Returns the suggested page ranges to print in the form of array
 * of #PopplerPageRanges and number of ranges.
 * NULL pointer means that the document does not specify page ranges
 * for printing.
 *
 * Returns: (array length=n_ranges) (transfer full): an array
 *          of #PopplerPageRanges or NULL. Free the array when
 *          it is no longer needed.
 *
 * Since: 0.80
 **/
PopplerPageRange *
poppler_document_get_print_page_ranges (PopplerDocument *document,
                                        int             *n_ranges)
{
  Catalog *catalog;
  ViewerPreferences *preferences;
  std::vector<std::pair<int, int>> ranges;
  PopplerPageRange *result = nullptr;

  g_return_val_if_fail (n_ranges != nullptr, nullptr);
  *n_ranges = 0;
  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), nullptr);

  catalog = document->doc->getCatalog ();
  if (catalog && catalog->isOk ()) {
    preferences = catalog->getViewerPreferences ();
    if (preferences) {
      ranges = preferences->getPrintPageRange ();

      *n_ranges = ranges.size ();
      result = g_new (PopplerPageRange, ranges.size ());
      for (guint i = 0; i < ranges.size (); ++i) {
        result[i].start_page = ranges[i].first;
        result[i].end_page = ranges[i].second;
      }
    }
  }

  return result;
}

/**
 * poppler_document_get_permissions:
 * @document: A #PopplerDocument
 *
 * Returns the flags specifying which operations are permitted when the document is opened.
 *
 * Return value: a set of flags from  #PopplerPermissions enumeration
 *
 * Since: 0.16
 **/
PopplerPermissions
poppler_document_get_permissions (PopplerDocument *document)
{
  guint flag = 0;

  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), POPPLER_PERMISSIONS_FULL);

  if (document->doc->okToPrint ())
    flag |= POPPLER_PERMISSIONS_OK_TO_PRINT;
  if (document->doc->okToChange ())
    flag |= POPPLER_PERMISSIONS_OK_TO_MODIFY;
  if (document->doc->okToCopy ())
    flag |= POPPLER_PERMISSIONS_OK_TO_COPY;
  if (document->doc->okToAddNotes ())
    flag |= POPPLER_PERMISSIONS_OK_TO_ADD_NOTES;
  if (document->doc->okToFillForm ())
    flag |= POPPLER_PERMISSIONS_OK_TO_FILL_FORM;
  if (document->doc->okToAccessibility())
    flag |= POPPLER_PERMISSIONS_OK_TO_EXTRACT_CONTENTS;
  if (document->doc->okToAssemble())
    flag |= POPPLER_PERMISSIONS_OK_TO_ASSEMBLE;
  if (document->doc->okToPrintHighRes())
    flag |= POPPLER_PERMISSIONS_OK_TO_PRINT_HIGH_RESOLUTION;

  return (PopplerPermissions)flag;
}

/**
 * poppler_document_get_pdf_subtype_string:
 * @document: A #PopplerDocument
 *
 * Returns the PDF subtype version of @document as a string.
 *
 * Returns: (transfer full) (nullable): a newly allocated string containing
 * the PDF subtype version of @document, or %NULL
 *
 * Since: 0.70
 **/
gchar *
poppler_document_get_pdf_subtype_string (PopplerDocument *document)
{
  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);

  GooString *infostring;

  switch (document->doc->getPDFSubtype ())
    {
    case subtypePDFA:
      infostring = document->doc->getDocInfoStringEntry ("GTS_PDFA1Version");
      break;
    case subtypePDFE:
      infostring = document->doc->getDocInfoStringEntry ("GTS_PDFEVersion");
      break;
    case subtypePDFUA:
      infostring = document->doc->getDocInfoStringEntry ("GTS_PDFUAVersion");
      break;
    case subtypePDFVT:
      infostring = document->doc->getDocInfoStringEntry ("GTS_PDFVTVersion");
      break;
    case subtypePDFX:
      infostring = document->doc->getDocInfoStringEntry ("GTS_PDFXVersion");
      break;
    case subtypeNone:
    case subtypeNull:
    default:
      infostring = nullptr;
    }

  gchar *utf8 = _poppler_goo_string_to_utf8 (infostring);
  delete infostring;

  return utf8;
}

/**
 * poppler_document_get_pdf_subtype:
 * @document: A #PopplerDocument
 *
 * Returns the subtype of @document as a #PopplerPDFSubtype.
 *
 * Returns: the document's subtype
 *
 * Since: 0.70
 **/
PopplerPDFSubtype
poppler_document_get_pdf_subtype (PopplerDocument *document)
{
  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), POPPLER_PDF_SUBTYPE_NONE);

  return convert_pdf_subtype (document->doc->getPDFSubtype ());
}

/**
 * poppler_document_get_pdf_part:
 * @document: A #PopplerDocument
 *
 * Returns the part of the conforming standard that the @document adheres to
 * as a #PopplerPDFSubtype.
 *
 * Returns: the document's subtype part
 *
 * Since: 0.70
 **/
PopplerPDFPart
poppler_document_get_pdf_part (PopplerDocument *document)
{
  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), POPPLER_PDF_SUBTYPE_PART_NONE);

  return convert_pdf_subtype_part (document->doc->getPDFSubtypePart ());
}

/**
 * poppler_document_get_pdf_conformance:
 * @document: A #PopplerDocument
 *
 * Returns the conformance level of the @document as #PopplerPDFConformance.
 *
 * Returns: the document's subtype conformance level
 *
 * Since: 0.70
 **/
PopplerPDFConformance
poppler_document_get_pdf_conformance (PopplerDocument *document)
{
  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), POPPLER_PDF_SUBTYPE_CONF_NONE);

  return convert_pdf_subtype_conformance (document->doc->getPDFSubtypeConformance ());
}

/**
 * poppler_document_get_metadata:
 * @document: A #PopplerDocument
 *
 * Returns the XML metadata string of the document
 *
 * Return value: a new allocated string containing the XML
 *               metadata, or %NULL
 *
 * Since: 0.16
 **/
gchar *
poppler_document_get_metadata (PopplerDocument *document)
{
  Catalog *catalog;
  gchar *retval = nullptr;

  g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);

  catalog = document->doc->getCatalog ();
  if (catalog && catalog->isOk ()) {
    GooString *s = catalog->readMetadata ();

    if (s != nullptr) {
      retval = g_strdup (s->c_str());
      delete s;
    }
  }

  return retval;
}

static void
poppler_document_get_property (GObject    *object,
			       guint       prop_id,
			       GValue     *value,
			       GParamSpec *pspec)
{
  PopplerDocument *document = POPPLER_DOCUMENT (object);
  guint version;

  switch (prop_id)
    {
    case PROP_TITLE:
      g_value_take_string (value, poppler_document_get_title (document));
      break;
    case PROP_FORMAT:
      g_value_take_string (value, poppler_document_get_pdf_version_string (document));
      break;
    case PROP_FORMAT_MAJOR:
      poppler_document_get_pdf_version (document, &version, nullptr);
      g_value_set_uint (value, version);
      break;
    case PROP_FORMAT_MINOR:
      poppler_document_get_pdf_version (document, nullptr, &version);
      g_value_set_uint (value, version);
      break;
    case PROP_AUTHOR:
      g_value_take_string (value, poppler_document_get_author (document));
      break;
    case PROP_SUBJECT:
      g_value_take_string (value, poppler_document_get_subject (document));
      break;
    case PROP_KEYWORDS:
      g_value_take_string (value, poppler_document_get_keywords (document));
      break;
    case PROP_CREATOR:
      g_value_take_string (value, poppler_document_get_creator (document));
      break;
    case PROP_PRODUCER:
      g_value_take_string (value, poppler_document_get_producer (document));
      break;
    case PROP_CREATION_DATE:
      g_value_set_int (value, poppler_document_get_creation_date (document));
      break;
    case PROP_MOD_DATE:
      g_value_set_int (value, poppler_document_get_modification_date (document));
      break;
    case PROP_LINEARIZED:
      g_value_set_boolean (value, poppler_document_is_linearized (document));
      break;
    case PROP_PAGE_LAYOUT:
      g_value_set_enum (value, poppler_document_get_page_layout (document));
      break;
    case PROP_PAGE_MODE:
      g_value_set_enum (value, poppler_document_get_page_mode (document));
      break;
    case PROP_VIEWER_PREFERENCES:
      /* FIXME: write... */
      g_value_set_flags (value, POPPLER_VIEWER_PREFERENCES_UNSET);
      break;
    case PROP_PRINT_SCALING:
      g_value_set_enum (value, poppler_document_get_print_scaling (document));
      break;
    case PROP_PRINT_DUPLEX:
      g_value_set_enum (value, poppler_document_get_print_duplex (document));
      break;
    case PROP_PRINT_N_COPIES:
      g_value_set_int (value, poppler_document_get_print_n_copies (document));
      break;
    case PROP_PERMISSIONS:
      g_value_set_flags (value, poppler_document_get_permissions (document));
      break;
    case PROP_SUBTYPE:
      g_value_set_enum (value, poppler_document_get_pdf_subtype (document));
      break;
    case PROP_SUBTYPE_STRING:
      g_value_take_string (value, poppler_document_get_pdf_subtype_string (document));
      break;
    case PROP_SUBTYPE_PART:
      g_value_set_enum (value, poppler_document_get_pdf_part (document));
      break;
    case PROP_SUBTYPE_CONF:
      g_value_set_enum (value, poppler_document_get_pdf_conformance (document));
      break;
    case PROP_METADATA:
      g_value_take_string (value, poppler_document_get_metadata (document));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

static void
poppler_document_set_property (GObject      *object,
			       guint         prop_id,
			       const GValue *value,
			       GParamSpec   *pspec)
{
  PopplerDocument *document = POPPLER_DOCUMENT (object);

  switch (prop_id)
    {
    case PROP_TITLE:
      poppler_document_set_title (document, g_value_get_string (value));
      break;
    case PROP_AUTHOR:
      poppler_document_set_author (document, g_value_get_string (value));
      break;
    case PROP_SUBJECT:
      poppler_document_set_subject (document, g_value_get_string (value));
      break;
    case PROP_KEYWORDS:
      poppler_document_set_keywords (document, g_value_get_string (value));
      break;
    case PROP_CREATOR:
      poppler_document_set_creator (document, g_value_get_string (value));
      break;
    case PROP_PRODUCER:
      poppler_document_set_producer (document, g_value_get_string (value));
      break;
    case PROP_CREATION_DATE:
      poppler_document_set_creation_date (document, g_value_get_int (value));
      break;
    case PROP_MOD_DATE:
      poppler_document_set_modification_date (document, g_value_get_int (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

static void
poppler_document_class_init (PopplerDocumentClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

  gobject_class->finalize = poppler_document_finalize;
  gobject_class->get_property = poppler_document_get_property;
  gobject_class->set_property = poppler_document_set_property;

  /**
   * PopplerDocument:title:
   *
   * The document's title or %NULL
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_TITLE,
				   g_param_spec_string ("title",
							"Document Title",
							"The title of the document",
							nullptr,
							G_PARAM_READWRITE));

  /**
   * PopplerDocument:format:
   *
   * The PDF version as string. See also poppler_document_get_pdf_version_string()
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_FORMAT,
				   g_param_spec_string ("format",
							"PDF Format",
							"The PDF version of the document",
							nullptr,
							G_PARAM_READABLE));

  /**
   * PopplerDocument:format-major:
   *
   * The PDF major version number. See also poppler_document_get_pdf_version()
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_FORMAT_MAJOR,
				   g_param_spec_uint ("format-major",
						      "PDF Format Major",
						      "The PDF major version number of the document",
						      0, G_MAXUINT, 1,
						      G_PARAM_READABLE));

  /**
   * PopplerDocument:format-minor:
   *
   * The PDF minor version number. See also poppler_document_get_pdf_version()
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_FORMAT_MINOR,
				   g_param_spec_uint ("format-minor",
						      "PDF Format Minor",
						      "The PDF minor version number of the document",
						      0, G_MAXUINT, 0,
						      G_PARAM_READABLE));

  /**
   * PopplerDocument:author:
   *
   * The author of the document
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_AUTHOR,
				   g_param_spec_string ("author",
							"Author",
							"The author of the document",
							nullptr,
							G_PARAM_READWRITE));

  /**
   * PopplerDocument:subject:
   *
   * The subject of the document
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_SUBJECT,
				   g_param_spec_string ("subject",
							"Subject",
							"Subjects the document touches",
							nullptr,
							G_PARAM_READWRITE));

  /**
   * PopplerDocument:keywords:
   *
   * The keywords associated to the document
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_KEYWORDS,
				   g_param_spec_string ("keywords",
							"Keywords",
							"Keywords",
							nullptr,
							G_PARAM_READWRITE));

  /**
   * PopplerDocument:creator:
   *
   * The creator of the document. See also poppler_document_get_creator()
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_CREATOR,
				   g_param_spec_string ("creator",
							"Creator",
							"The software that created the document",
							nullptr,
							G_PARAM_READWRITE));

  /**
   * PopplerDocument:producer:
   *
   * The producer of the document. See also poppler_document_get_producer()
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_PRODUCER,
				   g_param_spec_string ("producer",
							"Producer",
							"The software that converted the document",
							nullptr,
							G_PARAM_READWRITE));

  /**
   * PopplerDocument:creation-date:
   *
   * The date the document was created as seconds since the Epoch, or -1
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_CREATION_DATE,
				   g_param_spec_int ("creation-date",
						     "Creation Date",
						     "The date and time the document was created",
						     -1, G_MAXINT, -1,
						     G_PARAM_READWRITE));

  /**
   * PopplerDocument:mod-date:
   *
   * The date the document was most recently modified as seconds since the Epoch, or -1
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_MOD_DATE,
				   g_param_spec_int ("mod-date",
						     "Modification Date",
						     "The date and time the document was modified",
						     -1, G_MAXINT, -1,
						     G_PARAM_READWRITE));

  /**
   * PopplerDocument:linearized:
   *
   * Whether document is linearized. See also poppler_document_is_linearized()
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_LINEARIZED,
				   g_param_spec_boolean ("linearized",
							 "Fast Web View Enabled",
							 "Is the document optimized for web viewing?",
							 FALSE,
							 G_PARAM_READABLE));

  /**
   * PopplerDocument:page-layout:
   *
   * The page layout that should be used when the document is opened
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_PAGE_LAYOUT,
				   g_param_spec_enum ("page-layout",
						      "Page Layout",
						      "Initial Page Layout",
						      POPPLER_TYPE_PAGE_LAYOUT,
						      POPPLER_PAGE_LAYOUT_UNSET,
						      G_PARAM_READABLE));

  /**
   * PopplerDocument:page-mode:
   *
   * The mode that should be used when the document is opened
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_PAGE_MODE,
				   g_param_spec_enum ("page-mode",
						      "Page Mode",
						      "Page Mode",
						      POPPLER_TYPE_PAGE_MODE,
						      POPPLER_PAGE_MODE_UNSET,
						      G_PARAM_READABLE));

  /**
   * PopplerDocument:viewer-preferences:
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_VIEWER_PREFERENCES,
				   g_param_spec_flags ("viewer-preferences",
						       "Viewer Preferences",
						       "Viewer Preferences",
						       POPPLER_TYPE_VIEWER_PREFERENCES,
						       POPPLER_VIEWER_PREFERENCES_UNSET,
						       G_PARAM_READABLE));

  /**
   * PopplerDocument:print-scaling:
   *
   * Since: 0.73
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_PRINT_SCALING,
				   g_param_spec_enum ("print-scaling",
						      "Print Scaling",
						      "Print Scaling Viewer Preference",
						      POPPLER_TYPE_PRINT_SCALING,
						      POPPLER_PRINT_SCALING_APP_DEFAULT,
						      (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));

  /**
   * PopplerDocument:print-duplex:
   *
   * Since: 0.80
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_PRINT_DUPLEX,
				   g_param_spec_enum ("print-duplex",
						      "Print Duplex",
						      "Duplex Viewer Preference",
						      POPPLER_TYPE_PRINT_DUPLEX,
						      POPPLER_PRINT_DUPLEX_NONE,
						      (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));

  /**
   * PopplerDocument:print-n-copies:
   *
   * Suggested number of copies to be printed for this document
   *
   * Since: 0.80
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_PRINT_N_COPIES,
				   g_param_spec_int ("print-n-copies",
						     "Number of Copies to Print",
						     "Number of Copies Viewer Preference",
						     1, G_MAXINT, 1,
						     (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));

  /**
   * PopplerDocument:permissions:
   *
   * Flags specifying which operations are permitted when the document is opened
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_PERMISSIONS,
				   g_param_spec_flags ("permissions",
						       "Permissions",
						       "Permissions",
						       POPPLER_TYPE_PERMISSIONS,
						       POPPLER_PERMISSIONS_FULL,
						       G_PARAM_READABLE));

  /**
   * PopplerDocument:subtype:
   *
   *  Document PDF subtype type
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_SUBTYPE,
				   g_param_spec_enum ("subtype",
						       "PDF Format Subtype Type",
						       "The PDF subtype of the document",
						       POPPLER_TYPE_PDF_SUBTYPE,
						       POPPLER_PDF_SUBTYPE_UNSET,
						       G_PARAM_READABLE));

  /**
   * PopplerDocument:subtype-string:
   *
   *  Document PDF subtype. See also poppler_document_get_pdf_subtype_string()
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_SUBTYPE_STRING,
				   g_param_spec_string ("subtype-string",
						       "PDF Format Subtype",
						       "The PDF subtype of the document",
						       nullptr,
						       G_PARAM_READABLE));

  /**
   * PopplerDocument:subtype-part:
   *
   *  Document PDF subtype part
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_SUBTYPE_PART,
						       g_param_spec_enum ("subtype-part",
						       "PDF Format Subtype Part",
						       "The part of PDF conformance",
						       POPPLER_TYPE_PDF_PART,
						       POPPLER_PDF_SUBTYPE_PART_UNSET,
						       G_PARAM_READABLE));

  /**
   * PopplerDocument:subtype-conformance:
   *
   *  Document PDF subtype conformance
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_SUBTYPE_CONF,
				   g_param_spec_enum ("subtype-conformance",
						       "PDF Format Subtype Conformance",
						       "The conformance level of PDF subtype",
						       POPPLER_TYPE_PDF_CONFORMANCE,
						       POPPLER_PDF_SUBTYPE_CONF_UNSET,
						       G_PARAM_READABLE));

  /**
   * PopplerDocument:metadata:
   *
   * Document metadata in XML format, or %NULL
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass),
				   PROP_METADATA,
				   g_param_spec_string ("metadata",
							"XML Metadata",
							"Embedded XML metadata",
							nullptr,
							G_PARAM_READABLE));
}

static void
poppler_document_init (PopplerDocument *document)
{
}

/* PopplerIndexIter: For determining the index of a tree */
struct _PopplerIndexIter
{
	PopplerDocument *document;
	const std::vector<OutlineItem*> *items;
	int index;
};


POPPLER_DEFINE_BOXED_TYPE (PopplerIndexIter, poppler_index_iter,
			   poppler_index_iter_copy,
			   poppler_index_iter_free)

/**
 * poppler_index_iter_copy:
 * @iter: a #PopplerIndexIter
 * 
 * Creates a new #PopplerIndexIter as a copy of @iter.  This must be freed with
 * poppler_index_iter_free().
 * 
 * Return value: a new #PopplerIndexIter
 **/
PopplerIndexIter *
poppler_index_iter_copy (PopplerIndexIter *iter)
{
	PopplerIndexIter *new_iter;

	g_return_val_if_fail (iter != nullptr, NULL);

	new_iter = g_slice_dup (PopplerIndexIter, iter);
	new_iter->document = (PopplerDocument *) g_object_ref (new_iter->document);

	return new_iter;
}

/**
 * poppler_index_iter_new:
 * @document: a #PopplerDocument
 * 
 * Returns the root #PopplerIndexIter for @document, or %NULL.  This must be
 * freed with poppler_index_iter_free().
 *
 * Certain documents have an index associated with them.  This index can be used
 * to help the user navigate the document, and is similar to a table of
 * contents.  Each node in the index will contain a #PopplerAction that can be
 * displayed to the user &mdash; typically a #POPPLER_ACTION_GOTO_DEST or a
 * #POPPLER_ACTION_URI<!-- -->.
 *
 * Here is a simple example of some code that walks the full index:
 *
 * <informalexample><programlisting>
 * static void
 * walk_index (PopplerIndexIter *iter)
 * {
 *   do
 *     {
 *       /<!-- -->* Get the action and do something with it *<!-- -->/
 *       PopplerIndexIter *child = poppler_index_iter_get_child (iter);
 *       if (child)
 *         walk_index (child);
 *       poppler_index_iter_free (child);
 *     }
 *   while (poppler_index_iter_next (iter));
 * }
 * ...
 * {
 *   iter = poppler_index_iter_new (document);
 *   walk_index (iter);
 *   poppler_index_iter_free (iter);
 * }
 *</programlisting></informalexample>
 *
 * Return value: a new #PopplerIndexIter
 **/
PopplerIndexIter *
poppler_index_iter_new (PopplerDocument *document)
{
	PopplerIndexIter *iter;
	Outline *outline;
	const std::vector<OutlineItem*> *items;

	outline = document->doc->getOutline();
	if (outline == nullptr)
		return nullptr;

	items = outline->getItems();
	if (items == nullptr)
		return nullptr;

	iter = g_slice_new (PopplerIndexIter);
	iter->document = (PopplerDocument *) g_object_ref (document);
	iter->items = items;
	iter->index = 0;

	return iter;
}

/**
 * poppler_index_iter_get_child:
 * @parent: a #PopplerIndexIter
 * 
 * Returns a newly created child of @parent, or %NULL if the iter has no child.
 * See poppler_index_iter_new() for more information on this function.
 * 
 * Return value: a new #PopplerIndexIter
 **/
PopplerIndexIter *
poppler_index_iter_get_child (PopplerIndexIter *parent)
{
	PopplerIndexIter *child;
	OutlineItem *item;

	g_return_val_if_fail (parent != nullptr, NULL);
	
	item = (*parent->items)[parent->index];
	item->open ();
	if (! (item->hasKids() && item->getKids()) )
		return nullptr;

	child = g_slice_new0 (PopplerIndexIter);
	child->document = (PopplerDocument *)g_object_ref (parent->document);
	child->items = item->getKids ();

	g_assert (child->items);

	return child;
}

static gchar *
unicode_to_char (const Unicode *unicode,
		 int      len)
{
	static UnicodeMap *uMap = nullptr;
	if (uMap == nullptr) {
		GooString *enc = new GooString("UTF-8");
		uMap = globalParams->getUnicodeMap(enc);
		uMap->incRefCnt ();
		delete enc;
	}
		
	GooString gstr;
	gchar buf[8]; /* 8 is enough for mapping an unicode char to a string */
	int i, n;

	for (i = 0; i < len; ++i) {
		n = uMap->mapUnicode(unicode[i], buf, sizeof(buf));
		gstr.append(buf, n);
	}

	return g_strdup (gstr.c_str ());
}

/**
 * poppler_index_iter_is_open:
 * @iter: a #PopplerIndexIter
 * 
 * Returns whether this node should be expanded by default to the user.  The
 * document can provide a hint as to how the document's index should be expanded
 * initially.
 * 
 * Return value: %TRUE, if the document wants @iter to be expanded
 **/
gboolean
poppler_index_iter_is_open (PopplerIndexIter *iter)
{
	OutlineItem *item;

	item = (*iter->items)[iter->index];

	return item->isOpen();
}

/**
 * poppler_index_iter_get_action:
 * @iter: a #PopplerIndexIter
 * 
 * Returns the #PopplerAction associated with @iter.  It must be freed with
 * poppler_action_free().
 * 
 * Return value: a new #PopplerAction
 **/
PopplerAction *
poppler_index_iter_get_action (PopplerIndexIter  *iter)
{
	OutlineItem *item;
	const LinkAction *link_action;
	PopplerAction *action;
	gchar *title;

	g_return_val_if_fail (iter != nullptr, NULL);

	item = (*iter->items)[iter->index];
	link_action = item->getAction ();

	title = unicode_to_char (item->getTitle(),
				 item->getTitleLength ());

	action = _poppler_action_new (iter->document, link_action, title);
	g_free (title);

	return action;
}

/**
 * poppler_index_iter_next:
 * @iter: a #PopplerIndexIter
 * 
 * Sets @iter to point to the next action at the current level, if valid.  See
 * poppler_index_iter_new() for more information.
 * 
 * Return value: %TRUE, if @iter was set to the next action
 **/
gboolean
poppler_index_iter_next (PopplerIndexIter *iter)
{
	g_return_val_if_fail (iter != nullptr, FALSE);

	iter->index++;
	if (iter->index >= (int)iter->items->size())
		return FALSE;

	return TRUE;
}

/**
 * poppler_index_iter_free:
 * @iter: a #PopplerIndexIter
 * 
 * Frees @iter.
 **/
void
poppler_index_iter_free (PopplerIndexIter *iter)
{
	if (G_UNLIKELY (iter == nullptr))
		return;

	g_object_unref (iter->document);
	g_slice_free (PopplerIndexIter, iter);
}

struct _PopplerFontsIter
{
	std::vector<FontInfo*> *items;
	int index;
};

POPPLER_DEFINE_BOXED_TYPE (PopplerFontsIter, poppler_fonts_iter,
			   poppler_fonts_iter_copy,
			   poppler_fonts_iter_free)

/**
 * poppler_fonts_iter_get_full_name:
 * @iter: a #PopplerFontsIter
 *
 * Returns the full name of the font associated with @iter
 *
 * Returns: the font full name
 */
const char *
poppler_fonts_iter_get_full_name (PopplerFontsIter *iter)
{
	GooString *name;
	FontInfo *info;

	info = (*iter->items)[iter->index];

	name = info->getName();
	if (name != nullptr) {
		return info->getName()->c_str();
	} else {
		return nullptr;
	}
}

/**
 * poppler_fonts_iter_get_name:
 * @iter: a #PopplerFontsIter
 *
 * Returns the name of the font associated with @iter
 *
 * Returns: the font name
 */
const char *
poppler_fonts_iter_get_name (PopplerFontsIter *iter)
{
	FontInfo *info;
	const char *name;

	name = poppler_fonts_iter_get_full_name (iter);
	info = (*iter->items)[iter->index];

	if (info->getSubset() && name) {
		while (*name && *name != '+')
			name++;

		if (*name)
			name++;
	}

	return name;
}

/**
 * poppler_fonts_iter_get_substitute_name:
 * @iter: a #PopplerFontsIter
 *
 * The name of the substitute font of the font associated with @iter or %NULL if
 * the font is embedded
 *
 * Returns: the name of the substitute font or %NULL if font is embedded
 *
 * Since: 0.20
 */
const char *
poppler_fonts_iter_get_substitute_name (PopplerFontsIter *iter)
{
	GooString *name;
	FontInfo *info;

	info = (*iter->items)[iter->index];

	name = info->getSubstituteName();
	if (name != nullptr) {
		return name->c_str();
	} else {
		return nullptr;
	}
}

/**
 * poppler_fonts_iter_get_file_name:
 * @iter: a #PopplerFontsIter
 *
 * The filename of the font associated with @iter or %NULL if
 * the font is embedded
 *
 * Returns: the filename of the font or %NULL if font is embedded
 */
const char *
poppler_fonts_iter_get_file_name (PopplerFontsIter *iter)
{
	GooString *file;
	FontInfo *info;

	info = (*iter->items)[iter->index];

	file = info->getFile();
	if (file != nullptr) {
		return file->c_str();
	} else {
		return nullptr;
	}
}

/**
 * poppler_fonts_iter_get_font_type:
 * @iter: a #PopplerFontsIter
 *
 * Returns the type of the font associated with @iter
 *
 * Returns: the font type
 */
PopplerFontType
poppler_fonts_iter_get_font_type (PopplerFontsIter *iter)
{
	FontInfo *info;

	g_return_val_if_fail (iter != nullptr, POPPLER_FONT_TYPE_UNKNOWN);

	info = (*iter->items)[iter->index];

	return (PopplerFontType)info->getType ();
}

/**
 * poppler_fonts_iter_get_encoding:
 * @iter: a #PopplerFontsIter
 *
 * Returns the encoding of the font associated with @iter
 *
 * Returns: the font encoding
 *
 * Since: 0.20
 */
const char *
poppler_fonts_iter_get_encoding (PopplerFontsIter *iter)
{
	GooString *encoding;
	FontInfo *info;

	info = (*iter->items)[iter->index];

	encoding = info->getEncoding();
	if (encoding != nullptr) {
		return encoding->c_str();
	} else {
		return nullptr;
	}
}

/**
 * poppler_fonts_iter_is_embedded:
 * @iter: a #PopplerFontsIter
 *
 * Returns whether the font associated with @iter is embedded in the document
 *
 * Returns: %TRUE if font is embedded, %FALSE otherwise
 */
gboolean
poppler_fonts_iter_is_embedded (PopplerFontsIter *iter)
{
	FontInfo *info;

	info = (*iter->items)[iter->index];

	return info->getEmbedded();
}

/**
 * poppler_fonts_iter_is_subset:
 * @iter: a #PopplerFontsIter
 *
 * Returns whether the font associated with @iter is a subset of another font
 *
 * Returns: %TRUE if font is a subset, %FALSE otherwise
 */
gboolean
poppler_fonts_iter_is_subset (PopplerFontsIter *iter)
{
	FontInfo *info;

	info = (*iter->items)[iter->index];

	return info->getSubset();
}

/**
 * poppler_fonts_iter_next:
 * @iter: a #PopplerFontsIter
 *
 * Sets @iter to point to the next font
 *
 * Returns: %TRUE, if @iter was set to the next font
 **/
gboolean
poppler_fonts_iter_next (PopplerFontsIter *iter)
{
	g_return_val_if_fail (iter != nullptr, FALSE);

	iter->index++;
	if (iter->index >= (int)iter->items->size())
		return FALSE;

	return TRUE;
}

/**
 * poppler_fonts_iter_copy:
 * @iter: a #PopplerFontsIter to copy
 *
 * Creates a copy of @iter
 *
 * Returns: a new allocated copy of @iter
 */
PopplerFontsIter *
poppler_fonts_iter_copy (PopplerFontsIter *iter)
{
	PopplerFontsIter *new_iter;

	g_return_val_if_fail (iter != nullptr, NULL);

	new_iter = g_slice_dup (PopplerFontsIter, iter);

	new_iter->items = new std::vector<FontInfo*> ();
	for (std::size_t i = 0; i < iter->items->size(); i++) {
		FontInfo *info = (*iter->items)[i];
		new_iter->items->push_back (new FontInfo (*info));
	}

	return new_iter;
}

/**
 * poppler_fonts_iter_free:
 * @iter: a #PopplerFontsIter
 *
 * Frees the given #PopplerFontsIter
 */
void
poppler_fonts_iter_free (PopplerFontsIter *iter)
{
	if (G_UNLIKELY (iter == nullptr))
		return;

        for (auto entry : *iter->items) {
          delete entry;
        }
        delete iter->items;

	g_slice_free (PopplerFontsIter, iter);
}

static PopplerFontsIter *
poppler_fonts_iter_new (std::vector<FontInfo*> *items)
{
	PopplerFontsIter *iter;

	iter = g_slice_new (PopplerFontsIter);
	iter->items = items;
	iter->index = 0;

	return iter;
}


typedef struct _PopplerFontInfoClass PopplerFontInfoClass;
struct _PopplerFontInfoClass
{
        GObjectClass parent_class;
};

G_DEFINE_TYPE (PopplerFontInfo, poppler_font_info, G_TYPE_OBJECT)

static void poppler_font_info_finalize (GObject *object);


static void
poppler_font_info_class_init (PopplerFontInfoClass *klass)
{
        GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

        gobject_class->finalize = poppler_font_info_finalize;
}

static void
poppler_font_info_init (PopplerFontInfo *font_info)
{
        font_info->document = nullptr;
        font_info->scanner = nullptr;
}

static void
poppler_font_info_finalize (GObject *object)
{
        PopplerFontInfo *font_info = POPPLER_FONT_INFO (object);

        delete font_info->scanner;
        g_object_unref (font_info->document);

        G_OBJECT_CLASS (poppler_font_info_parent_class)->finalize (object);
}

/**
 * poppler_font_info_new:
 * @document: a #PopplerDocument
 *
 * Creates a new #PopplerFontInfo object
 *
 * Returns: a new #PopplerFontInfo instance
 */
PopplerFontInfo *
poppler_font_info_new (PopplerDocument *document)
{
	PopplerFontInfo *font_info;

	g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);

	font_info = (PopplerFontInfo *) g_object_new (POPPLER_TYPE_FONT_INFO,
						      nullptr);
	font_info->document = (PopplerDocument *) g_object_ref (document);
	font_info->scanner = new FontInfoScanner(document->doc);

	return font_info;
}

/**
 * poppler_font_info_scan:
 * @font_info: a #PopplerFontInfo
 * @n_pages: number of pages to scan
 * @iter: (out): return location for a #PopplerFontsIter
 *
 * Scans the document associated with @font_info for fonts. At most
 * @n_pages will be scanned starting from the current iterator. @iter will
 * point to the first font scanned.
 *
 * Here is a simple example of code to scan fonts in a document
 *
 * <informalexample><programlisting>
 * font_info = poppler_font_info_new (document);
 * while (poppler_font_info_scan (font_info, 20, &fonts_iter)) {
 *         if (!fonts_iter)
 *                 continue; /<!-- -->* No fonts found in these 20 pages *<!-- -->/
 *         do {
 *                 /<!-- -->* Do something with font iter *<!-- -->/
 *                 g_print ("Font Name: %s\n", poppler_fonts_iter_get_name (fonts_iter));
 *         } while (poppler_fonts_iter_next (fonts_iter));
 *         poppler_fonts_iter_free (fonts_iter);
 * }
 * </programlisting></informalexample>
 *
 * Returns: %TRUE, if there are more fonts left to scan
 */
gboolean
poppler_font_info_scan (PopplerFontInfo   *font_info,
			int                n_pages,
			PopplerFontsIter **iter)
{
	std::vector<FontInfo*> *items;

	g_return_val_if_fail (iter != nullptr, FALSE);

	items = font_info->scanner->scan(n_pages);

	if (items == nullptr) {
		*iter = nullptr;
	} else if (items->empty()) {
		*iter = nullptr;
		delete items;
	} else {
		*iter = poppler_fonts_iter_new(items);
	}
	
	return (items != nullptr);
}

/* For backward compatibility */
void
poppler_font_info_free (PopplerFontInfo *font_info)
{
	g_return_if_fail (font_info != nullptr);

	g_object_unref (font_info);
}


/* Optional content (layers) */
static Layer *
layer_new (OptionalContentGroup *oc)
{
  Layer *layer;

  layer = g_slice_new0 (Layer);
  layer->oc = oc;

  return layer;
}

static void
layer_free (Layer *layer)
{
  if (G_UNLIKELY (!layer))
    return;

  if (layer->kids) {
	  g_list_foreach (layer->kids, (GFunc)layer_free, nullptr);
	  g_list_free (layer->kids);
  }

  if (layer->label) {
	  g_free (layer->label);
  }

  g_slice_free (Layer, layer);
}

static GList *
get_optional_content_rbgroups (OCGs *ocg)
{
  Array *rb;
  GList *groups = nullptr;
  
  rb = ocg->getRBGroupsArray ();
  
  if (rb) {
    int i, j;

    for (i = 0; i < rb->getLength (); ++i) {
      Array *rb_array;
      GList *group = nullptr;

      Object obj = rb->get (i);
      if (!obj.isArray ()) {
	continue;
      }

      rb_array = obj.getArray ();
      for (j = 0; j < rb_array->getLength (); ++j) {
	OptionalContentGroup *oc;

        const Object &ref = rb_array->getNF (j);
	if (!ref.isRef ()) {
	  continue;
	}

	oc = ocg->findOcgByRef (ref.getRef ());
	group = g_list_prepend (group, oc);
      }

      groups = g_list_prepend (groups, group);
    }
  }

  return groups;
}

GList *
_poppler_document_get_layer_rbgroup (PopplerDocument *document,
				    Layer           *layer)
{
  GList *l;

  for (l = document->layers_rbgroups; l && l->data; l = g_list_next (l)) {
    GList *group = (GList *)l->data;

    if (g_list_find (group, layer->oc))
      return group;
  }

  return nullptr;
}

static GList *
get_optional_content_items_sorted (OCGs *ocg, Layer *parent, Array *order)
{
  GList *items = nullptr;
  Layer *last_item = parent;
  int i;

  for (i = 0; i < order->getLength (); ++i) {
    Object orderItem = order->get (i);

    if (orderItem.isDict ()) {
      const Object &ref = order->getNF (i);
      if (ref.isRef ()) {
        OptionalContentGroup *oc = ocg->findOcgByRef (ref.getRef ());
	Layer *layer = layer_new (oc);

	items = g_list_prepend (items, layer);
	last_item = layer;
      }
    } else if (orderItem.isArray () && orderItem.arrayGetLength () > 0) {
      if (!last_item) {
        last_item = layer_new (nullptr);
	items = g_list_prepend (items, last_item);
      }
      last_item->kids = get_optional_content_items_sorted (ocg, last_item, orderItem.getArray ());
      last_item = nullptr;
    } else if (orderItem.isString ()) {
      last_item->label = _poppler_goo_string_to_utf8 (orderItem.getString ());
    }
  }
  
  return g_list_reverse (items);
}
		
static GList *
get_optional_content_items (OCGs *ocg)
{
  Array *order;
  GList *items = nullptr;
  
  order = ocg->getOrderArray ();

  if (order) {
    items = get_optional_content_items_sorted (ocg, nullptr, order);
  } else {
    const auto &ocgs = ocg->getOCGs ();

    for (const auto &oc : ocgs) {
      Layer *layer = layer_new (oc.second.get());

      items = g_list_prepend (items, layer);
    }
    
    items = g_list_reverse (items);
  }

  return items;
}

GList *
_poppler_document_get_layers (PopplerDocument *document)
{
  if (!document->layers) {
    Catalog *catalog = document->doc->getCatalog ();
    OCGs *ocg = catalog->getOptContentConfig ();

    if (!ocg)
      return nullptr;
    
    document->layers = get_optional_content_items (ocg);
    document->layers_rbgroups = get_optional_content_rbgroups (ocg);
  }

  return document->layers;
}

static void
poppler_document_layers_free (PopplerDocument *document)
{
  if (G_UNLIKELY (!document->layers))
    return;

  g_list_foreach (document->layers, (GFunc)layer_free, nullptr);
  g_list_free (document->layers);

  g_list_foreach (document->layers_rbgroups, (GFunc)g_list_free, nullptr);
  g_list_free (document->layers_rbgroups);

  document->layers = nullptr;
  document->layers_rbgroups = nullptr;
}

/* PopplerLayersIter */
struct _PopplerLayersIter {
  PopplerDocument *document;
  GList *items;
  int index;
};

POPPLER_DEFINE_BOXED_TYPE (PopplerLayersIter, poppler_layers_iter,
			   poppler_layers_iter_copy,
			   poppler_layers_iter_free)

/**
 * poppler_layers_iter_copy:
 * @iter: a #PopplerLayersIter
 * 
 * Creates a new #PopplerLayersIter as a copy of @iter.  This must be freed with
 * poppler_layers_iter_free().
 * 
 * Return value: a new #PopplerLayersIter
 *
 * Since 0.12
 **/
PopplerLayersIter *
poppler_layers_iter_copy (PopplerLayersIter *iter)
{
  PopplerLayersIter *new_iter;

  g_return_val_if_fail (iter != nullptr, NULL);
  
  new_iter = g_slice_dup (PopplerLayersIter, iter);
  new_iter->document = (PopplerDocument *) g_object_ref (new_iter->document);
  
  return new_iter;
}

/**
 * poppler_layers_iter_free:
 * @iter: a #PopplerLayersIter
 * 
 * Frees @iter.
 *
 * Since: 0.12
 **/
void
poppler_layers_iter_free (PopplerLayersIter *iter)
{
  if (G_UNLIKELY (iter == nullptr))
    return;

  g_object_unref (iter->document);
  g_slice_free (PopplerLayersIter, iter);
}

/**
 * poppler_layers_iter_new:
 * @document: a #PopplerDocument
 *
 * Since: 0.12
 **/
PopplerLayersIter *
poppler_layers_iter_new (PopplerDocument *document)
{
  PopplerLayersIter *iter;
  GList *items;

  items = _poppler_document_get_layers (document);

  if (!items)
    return nullptr;

  iter = g_slice_new0 (PopplerLayersIter);
  iter->document = (PopplerDocument *)g_object_ref (document);
  iter->items = items;

  return iter;
}

/**
 * poppler_layers_iter_get_child:
 * @parent: a #PopplerLayersIter
 * 
 * Returns a newly created child of @parent, or %NULL if the iter has no child.
 * See poppler_layers_iter_new() for more information on this function.
 * 
 * Return value: a new #PopplerLayersIter, or %NULL
 *
 * Since: 0.12
 **/
PopplerLayersIter *
poppler_layers_iter_get_child (PopplerLayersIter *parent)
{
  PopplerLayersIter *child;
  Layer *layer;

  g_return_val_if_fail (parent != nullptr, NULL);
	
  layer = (Layer *) g_list_nth_data (parent->items, parent->index);
  if (!layer || !layer->kids)
    return nullptr;

  child = g_slice_new0 (PopplerLayersIter);
  child->document = (PopplerDocument *)g_object_ref (parent->document);
  child->items = layer->kids;

  g_assert (child->items);

  return child;
}

/**
 * poppler_layers_iter_get_title:
 * @iter: a #PopplerLayersIter
 * 
 * Returns the title associated with @iter.  It must be freed with
 * g_free().
 * 
 * Return value: a new string containing the @iter's title or %NULL if @iter doesn't have a title.
 * The returned string should be freed with g_free() when no longer needed.
 *
 * Since: 0.12
 **/
gchar *
poppler_layers_iter_get_title (PopplerLayersIter *iter)
{
  Layer *layer;
  
  g_return_val_if_fail (iter != nullptr, NULL);
  
  layer = (Layer *)g_list_nth_data (iter->items, iter->index);

  return layer->label ? g_strdup (layer->label) : nullptr;
}

/**
 * poppler_layers_iter_get_layer:
 * @iter: a #PopplerLayersIter
 *
 * Returns the #PopplerLayer associated with @iter.
 *
 * Return value: (transfer full): a new #PopplerLayer, or %NULL if
 * there isn't any layer associated with @iter
 *
 * Since: 0.12
 **/
PopplerLayer *
poppler_layers_iter_get_layer (PopplerLayersIter *iter)
{
  Layer *layer;
  PopplerLayer *poppler_layer = nullptr;
  
  g_return_val_if_fail (iter != nullptr, NULL);
  
  layer = (Layer *)g_list_nth_data (iter->items, iter->index);
  if (layer->oc) {
    GList *rb_group = nullptr;

    rb_group = _poppler_document_get_layer_rbgroup (iter->document, layer);
    poppler_layer = _poppler_layer_new (iter->document, layer, rb_group);
  }
  
  return poppler_layer;
}

/**
 * poppler_layers_iter_next:
 * @iter: a #PopplerLayersIter
 * 
 * Sets @iter to point to the next action at the current level, if valid.  See
 * poppler_layers_iter_new() for more information.
 * 
 * Return value: %TRUE, if @iter was set to the next action
 *
 * Since: 0.12
 **/
gboolean
poppler_layers_iter_next (PopplerLayersIter *iter)
{
  g_return_val_if_fail (iter != nullptr, FALSE);

  iter->index++;
  if (iter->index >= (gint)g_list_length (iter->items))
    return FALSE;
  
  return TRUE;
}

typedef struct _PopplerPSFileClass PopplerPSFileClass;
struct _PopplerPSFileClass
{
        GObjectClass parent_class;
};

G_DEFINE_TYPE (PopplerPSFile, poppler_ps_file, G_TYPE_OBJECT)

static void poppler_ps_file_finalize (GObject *object);


static void
poppler_ps_file_class_init (PopplerPSFileClass *klass)
{
        GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

        gobject_class->finalize = poppler_ps_file_finalize;
}

static void
poppler_ps_file_init (PopplerPSFile *ps_file)
{
        ps_file->out = nullptr;
        ps_file->paper_width = -1;
        ps_file->paper_height = -1;
        ps_file->duplex = FALSE;
}

static void
poppler_ps_file_finalize (GObject *object)
{
        PopplerPSFile *ps_file = POPPLER_PS_FILE (object);

        delete ps_file->out;
        g_object_unref (ps_file->document);
        g_free (ps_file->filename);

        G_OBJECT_CLASS (poppler_ps_file_parent_class)->finalize (object);
}

/**
 * poppler_ps_file_new:
 * @document: a #PopplerDocument
 * @filename: the path of the output filename
 * @first_page: the first page to print
 * @n_pages: the number of pages to print
 * 
 * Create a new postscript file to render to
 * 
 * Return value: a PopplerPSFile 
 **/
PopplerPSFile *
poppler_ps_file_new (PopplerDocument *document, const char *filename,
		     int first_page, int n_pages)
{
	PopplerPSFile *ps_file;

	g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);
	g_return_val_if_fail (filename != nullptr, NULL);
	g_return_val_if_fail (n_pages > 0, NULL);

        ps_file = (PopplerPSFile *) g_object_new (POPPLER_TYPE_PS_FILE, nullptr);
	ps_file->document = (PopplerDocument *) g_object_ref (document);
        ps_file->filename = g_strdup (filename);
        ps_file->first_page = first_page + 1;
        ps_file->last_page = first_page + 1 + n_pages - 1;

	return ps_file;
}

/**
 * poppler_ps_file_set_paper_size:
 * @ps_file: a PopplerPSFile which was not yet printed to.
 * @width: the paper width in 1/72 inch
 * @height: the paper height in 1/72 inch
 *
 * Set the output paper size. These values will end up in the
 * DocumentMedia, the BoundingBox DSC comments and other places in the
 * generated PostScript.
 *
 **/
void
poppler_ps_file_set_paper_size (PopplerPSFile *ps_file,
                                double width, double height)
{
        g_return_if_fail (ps_file->out == nullptr);
        
        ps_file->paper_width = width;
        ps_file->paper_height = height;
}

/**
 * poppler_ps_file_set_duplex:
 * @ps_file: a PopplerPSFile which was not yet printed to
 * @duplex: whether to force duplex printing (on printers which support this)
 *
 * Enable or disable Duplex printing. 
 *
 **/
void
poppler_ps_file_set_duplex (PopplerPSFile *ps_file, gboolean duplex)
{
        g_return_if_fail (ps_file->out == nullptr);

        ps_file->duplex = duplex;
}

/**
 * poppler_ps_file_free:
 * @ps_file: a PopplerPSFile
 * 
 * Frees @ps_file
 * 
 **/
void
poppler_ps_file_free (PopplerPSFile *ps_file)
{
	g_return_if_fail (ps_file != nullptr);
        g_object_unref (ps_file);
}

/**
 * poppler_document_get_form_field:
 * @document: a #PopplerDocument
 * @id: an id of a #PopplerFormField
 *
 * Returns the #PopplerFormField for the given @id. It must be freed with
 * g_object_unref()
 *
 * Return value: (transfer full): a new #PopplerFormField or %NULL if
 * not found
 **/
PopplerFormField *
poppler_document_get_form_field (PopplerDocument *document,
				 gint             id)
{
  Page *page;
  unsigned pageNum;
  unsigned fieldNum;
  FormPageWidgets *widgets;
  FormWidget *field;

  FormWidget::decodeID (id, &pageNum, &fieldNum);

  page = document->doc->getPage (pageNum);
  if (!page)
    return nullptr;

  widgets = page->getFormWidgets ();
  if (!widgets)
    return nullptr;

  field = widgets->getWidget (fieldNum);
  if (field)
    return _poppler_form_field_new (document, field);

  return nullptr;
}

gboolean
_poppler_convert_pdf_date_to_gtime (const GooString *date,
				    time_t    *gdate) 
{
  gchar *date_string;
  gboolean retval;

  if (date->hasUnicodeMarker()) {
    date_string = g_convert (date->c_str () + 2,
			     date->getLength () - 2,
			     "UTF-8", "UTF-16BE", nullptr, nullptr, nullptr);		
  } else {
    date_string = g_strndup (date->c_str (), date->getLength ());
  }

  retval = poppler_date_parse (date_string, gdate);
  g_free (date_string);

  return retval;
}
