/* 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>
 * Copyright (C) 2019, Oliver Sander <oliver.sander@tu-dresden.de>
 *
 * 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 (size_t 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.resize(iter->items.size());
	for (std::size_t i = 0; i < iter->items.size(); i++) {
		FontInfo *info = iter->items[i];
		new_iter->items[i] = 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;
        }
        iter->items.~vector<FontInfo*>();

	g_slice_free (PopplerFontsIter, iter);
}

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

	iter = g_slice_new (PopplerFontsIter);
	new ((void*)&iter->items) std::vector<FontInfo*>(std::move(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)
{
	g_return_val_if_fail (iter != nullptr, FALSE);

	std::vector<FontInfo*> items = font_info->scanner->scan(n_pages);

	if (items.empty()) {
		*iter = nullptr;
		return FALSE;
	} else {
		*iter = poppler_fonts_iter_new(std::move(items));
	}
	
	return TRUE;
}

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