/* poppler-annot.cc: glib interface to poppler
 *
 * Copyright (C) 2007 Inigo Martinez <inigomartinez@gmail.com>
 * Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
 * Copyright (C) 2013 German Poo-Caamano <gpoo@gnome.org>
 * Copyright (C) 2025 Albert Astals Cid <aacid@kde.org>
 * Copyright (C) 2025 Markus Göllnitz <camelcasenick@bewares.it>
 * Copyright (C) 2025 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk>
 * Copyright (C) 2025 Lucas Baudin <lucas.baudin@ensae.fr>
 *
 * 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 "AnnotStampImageHelper.h"
#include "config.h"
#include "poppler.h"
#include "poppler-private.h"

#define ZERO_CROPBOX(c) (!((c) && ((c)->x1 > 0.01 || (c)->y1 > 0.01)))

const PDFRectangle *_poppler_annot_get_cropbox_and_page(PopplerAnnot *poppler_annot, Page **page_out);
std::unique_ptr<AnnotStampImageHelper> _poppler_convert_cairo_image_to_stamp_image_helper(cairo_surface_t *image, PDFDoc *doc, GError **error);

/**
 * SECTION:poppler-annot
 * @short_description: Annotations
 * @title: PopplerAnnot
 */

typedef struct _PopplerAnnotClass PopplerAnnotClass;
typedef struct _PopplerAnnotMarkupClass PopplerAnnotMarkupClass;
typedef struct _PopplerAnnotFreeTextClass PopplerAnnotFreeTextClass;
typedef struct _PopplerAnnotTextClass PopplerAnnotTextClass;
typedef struct _PopplerAnnotTextMarkupClass PopplerAnnotTextMarkupClass;
typedef struct _PopplerAnnotFileAttachmentClass PopplerAnnotFileAttachmentClass;
typedef struct _PopplerAnnotMovieClass PopplerAnnotMovieClass;
typedef struct _PopplerAnnotScreenClass PopplerAnnotScreenClass;
typedef struct _PopplerAnnotLineClass PopplerAnnotLineClass;
typedef struct _PopplerAnnotCircleClass PopplerAnnotCircleClass;
typedef struct _PopplerAnnotSquareClass PopplerAnnotSquareClass;
typedef struct _PopplerAnnotStampClass PopplerAnnotStampClass;
typedef struct _PopplerAnnotInkClass PopplerAnnotInkClass;

struct _PopplerAnnotClass
{
    GObjectClass parent_class;
};

struct _PopplerAnnotMarkup
{
    PopplerAnnot parent_instance;
};

struct _PopplerAnnotMarkupClass
{
    PopplerAnnotClass parent_class;
};

struct _PopplerAnnotText
{
    PopplerAnnotMarkup parent_instance;
};

struct _PopplerAnnotTextClass
{
    PopplerAnnotMarkupClass parent_class;
};

struct _PopplerAnnotTextMarkup
{
    PopplerAnnotMarkup parent_instance;
};

struct _PopplerAnnotTextMarkupClass
{
    PopplerAnnotMarkupClass parent_class;
};

struct _PopplerAnnotFreeText
{
    PopplerAnnotMarkup parent_instance;
    PopplerFontDescription *font_desc;
    PopplerColor font_color;
};

struct _PopplerAnnotFreeTextClass
{
    PopplerAnnotMarkupClass parent_class;
};

struct _PopplerAnnotFileAttachment
{
    PopplerAnnotMarkup parent_instance;
};

struct _PopplerAnnotFileAttachmentClass
{
    PopplerAnnotMarkupClass parent_class;
};

struct _PopplerAnnotMovie
{
    PopplerAnnot parent_instance;

    PopplerMovie *movie;
};

struct _PopplerAnnotMovieClass
{
    PopplerAnnotClass parent_class;
};

struct _PopplerAnnotScreen
{
    PopplerAnnot parent_instance;

    PopplerAction *action;
};

struct _PopplerAnnotScreenClass
{
    PopplerAnnotClass parent_class;
};

struct _PopplerAnnotLine
{
    PopplerAnnotMarkup parent_instance;
};

struct _PopplerAnnotLineClass
{
    PopplerAnnotMarkupClass parent_class;
};

struct _PopplerAnnotCircle
{
    PopplerAnnotMarkup parent_instance;
};

struct _PopplerAnnotCircleClass
{
    PopplerAnnotMarkupClass parent_class;
};

struct _PopplerAnnotSquare
{
    PopplerAnnotMarkup parent_instance;
};

struct _PopplerAnnotSquareClass
{
    PopplerAnnotMarkupClass parent_class;
};
struct _PopplerAnnotStamp
{
    PopplerAnnotMarkup parent_instance;
};
struct _PopplerAnnotStampClass
{
    PopplerAnnotMarkupClass parent_class;
};

struct _PopplerAnnotInk
{
    PopplerAnnot parent_instance;
};

struct _PopplerAnnotInkClass
{
    PopplerAnnotClass parent_class;
};

G_DEFINE_TYPE(PopplerAnnot, poppler_annot, G_TYPE_OBJECT)
G_DEFINE_TYPE(PopplerAnnotMarkup, poppler_annot_markup, POPPLER_TYPE_ANNOT)
G_DEFINE_TYPE(PopplerAnnotTextMarkup, poppler_annot_text_markup, POPPLER_TYPE_ANNOT_MARKUP)
G_DEFINE_TYPE(PopplerAnnotText, poppler_annot_text, POPPLER_TYPE_ANNOT_MARKUP)
G_DEFINE_TYPE(PopplerAnnotFreeText, poppler_annot_free_text, POPPLER_TYPE_ANNOT_MARKUP)
G_DEFINE_TYPE(PopplerAnnotFileAttachment, poppler_annot_file_attachment, POPPLER_TYPE_ANNOT_MARKUP)
G_DEFINE_TYPE(PopplerAnnotMovie, poppler_annot_movie, POPPLER_TYPE_ANNOT)
G_DEFINE_TYPE(PopplerAnnotScreen, poppler_annot_screen, POPPLER_TYPE_ANNOT)
G_DEFINE_TYPE(PopplerAnnotLine, poppler_annot_line, POPPLER_TYPE_ANNOT_MARKUP)
G_DEFINE_TYPE(PopplerAnnotCircle, poppler_annot_circle, POPPLER_TYPE_ANNOT_MARKUP)
G_DEFINE_TYPE(PopplerAnnotSquare, poppler_annot_square, POPPLER_TYPE_ANNOT_MARKUP)
G_DEFINE_TYPE(PopplerAnnotStamp, poppler_annot_stamp, POPPLER_TYPE_ANNOT_MARKUP)
G_DEFINE_TYPE(PopplerAnnotInk, poppler_annot_ink, POPPLER_TYPE_ANNOT_MARKUP)

static PopplerAnnot *_poppler_create_annot(GType annot_type, std::shared_ptr<Annot> annot)
{
    PopplerAnnot *poppler_annot;

    poppler_annot = POPPLER_ANNOT(g_object_new(annot_type, nullptr));
    poppler_annot->annot = std::move(annot);

    return poppler_annot;
}

static void poppler_annot_finalize(GObject *object)
{
    PopplerAnnot *poppler_annot = POPPLER_ANNOT(object);

    if (poppler_annot->annot) {
        poppler_annot->annot.reset();
    }

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

static void poppler_annot_init(PopplerAnnot *poppler_annot) { }

static void poppler_annot_class_init(PopplerAnnotClass *klass)
{
    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);

    gobject_class->finalize = poppler_annot_finalize;
}

PopplerAnnot *_poppler_annot_new(const std::shared_ptr<Annot> &annot)
{
    return _poppler_create_annot(POPPLER_TYPE_ANNOT, annot);
}

static void poppler_annot_markup_init(PopplerAnnotMarkup *poppler_annot) { }

static void poppler_annot_markup_class_init(PopplerAnnotMarkupClass *klass) { }

static void poppler_annot_text_init(PopplerAnnotText *poppler_annot) { }

static void poppler_annot_text_class_init(PopplerAnnotTextClass *klass) { }

PopplerAnnot *_poppler_annot_text_new(const std::shared_ptr<Annot> &annot)
{
    return _poppler_create_annot(POPPLER_TYPE_ANNOT_TEXT, annot);
}

/**
 * poppler_annot_text_new:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 *
 * Creates a new Text annotation that will be
 * located on @rect when added to a page. See
 * poppler_page_add_annot()
 *
 * Return value: A newly created #PopplerAnnotText annotation
 *
 * Since: 0.16
 */
PopplerAnnot *poppler_annot_text_new(PopplerDocument *doc, PopplerRectangle *rect)
{
    PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);

    auto annot = std::make_shared<AnnotText>(doc->doc, &pdf_rect);

    return _poppler_annot_text_new(annot);
}

PopplerAnnot *_poppler_annot_text_markup_new(const std::shared_ptr<Annot> &annot)
{
    return _poppler_create_annot(POPPLER_TYPE_ANNOT_TEXT_MARKUP, annot);
}

static AnnotQuadrilaterals *create_annot_quads_from_poppler_quads(GArray *quads)
{
    g_assert(quads->len > 0);

    auto quads_array = std::make_unique<AnnotQuadrilaterals::AnnotQuadrilateral[]>(quads->len);
    for (guint i = 0; i < quads->len; i++) {
        PopplerQuadrilateral *quadrilateral = &g_array_index(quads, PopplerQuadrilateral, i);

        quads_array[i] = AnnotQuadrilaterals::AnnotQuadrilateral(quadrilateral->p1.x, quadrilateral->p1.y, quadrilateral->p2.x, quadrilateral->p2.y, quadrilateral->p3.x, quadrilateral->p3.y, quadrilateral->p4.x, quadrilateral->p4.y);
    }

    return new AnnotQuadrilaterals(std::move(quads_array), quads->len);
}

/* If @crop_box parameter is non null, it will substract the crop_box offset
 * from the coordinates of the returned #PopplerQuadrilateral array */
static GArray *create_poppler_quads_from_annot_quads(AnnotQuadrilaterals *quads_array, const PDFRectangle *crop_box)
{
    GArray *quads;
    guint quads_len;
    PDFRectangle zerobox;

    if (!crop_box) {
        zerobox = PDFRectangle();
        crop_box = &zerobox;
    }

    quads_len = quads_array->getQuadrilateralsLength();
    quads = g_array_sized_new(FALSE, FALSE, sizeof(PopplerQuadrilateral), quads_len);
    g_array_set_size(quads, quads_len);

    for (guint i = 0; i < quads_len; ++i) {
        PopplerQuadrilateral *quadrilateral = &g_array_index(quads, PopplerQuadrilateral, i);

        quadrilateral->p1.x = quads_array->getX1(i) - crop_box->x1;
        quadrilateral->p1.y = quads_array->getY1(i) - crop_box->y1;
        quadrilateral->p2.x = quads_array->getX2(i) - crop_box->x1;
        quadrilateral->p2.y = quads_array->getY2(i) - crop_box->y1;
        quadrilateral->p3.x = quads_array->getX3(i) - crop_box->x1;
        quadrilateral->p3.y = quads_array->getY3(i) - crop_box->y1;
        quadrilateral->p4.x = quads_array->getX4(i) - crop_box->x1;
        quadrilateral->p4.y = quads_array->getY4(i) - crop_box->y1;
    }

    return quads;
}

static void poppler_annot_text_markup_init(PopplerAnnotTextMarkup *poppler_annot) { }

static void poppler_annot_text_markup_class_init(PopplerAnnotTextMarkupClass *klass) { }

/**
 * poppler_annot_text_markup_new_highlight:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 * @quadrilaterals: (element-type PopplerQuadrilateral): A #GArray of
 *   #PopplerQuadrilateral<!-- -->s
 *
 * Creates a new Highlight Text annotation that will be
 * located on @rect when added to a page. See poppler_page_add_annot()
 *
 * Return value: (transfer full): A newly created #PopplerAnnotTextMarkup annotation
 *
 * Since: 0.26
 */
PopplerAnnot *poppler_annot_text_markup_new_highlight(PopplerDocument *doc, PopplerRectangle *rect, GArray *quadrilaterals)
{
    PopplerAnnot *poppler_annot;
    PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);

    auto annot = std::make_shared<AnnotTextMarkup>(doc->doc, &pdf_rect, Annot::typeHighlight);

    poppler_annot = _poppler_annot_text_markup_new(annot);
    poppler_annot_text_markup_set_quadrilaterals(POPPLER_ANNOT_TEXT_MARKUP(poppler_annot), quadrilaterals);
    return poppler_annot;
}

/**
 * poppler_annot_text_markup_new_squiggly:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 * @quadrilaterals: (element-type PopplerQuadrilateral): A #GArray of
 *   #PopplerQuadrilateral<!-- -->s
 *
 * Creates a new Squiggly Text annotation that will be
 * located on @rect when added to a page. See poppler_page_add_annot()
 *
 * Return value: (transfer full): A newly created #PopplerAnnotTextMarkup annotation
 *
 * Since: 0.26
 */
PopplerAnnot *poppler_annot_text_markup_new_squiggly(PopplerDocument *doc, PopplerRectangle *rect, GArray *quadrilaterals)
{
    PopplerAnnot *poppler_annot;
    PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);

    g_return_val_if_fail(quadrilaterals != nullptr && quadrilaterals->len > 0, NULL);

    auto annot = std::make_shared<AnnotTextMarkup>(doc->doc, &pdf_rect, Annot::typeSquiggly);

    poppler_annot = _poppler_annot_text_markup_new(annot);
    poppler_annot_text_markup_set_quadrilaterals(POPPLER_ANNOT_TEXT_MARKUP(poppler_annot), quadrilaterals);
    return poppler_annot;
}

/**
 * poppler_annot_text_markup_new_strikeout:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 * @quadrilaterals: (element-type PopplerQuadrilateral): A #GArray of
 *   #PopplerQuadrilateral<!-- -->s
 *
 * Creates a new Strike Out Text annotation that will be
 * located on @rect when added to a page. See poppler_page_add_annot()
 *
 * Return value: (transfer full): A newly created #PopplerAnnotTextMarkup annotation
 *
 * Since: 0.26
 */
PopplerAnnot *poppler_annot_text_markup_new_strikeout(PopplerDocument *doc, PopplerRectangle *rect, GArray *quadrilaterals)
{
    PopplerAnnot *poppler_annot;
    PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);

    g_return_val_if_fail(quadrilaterals != nullptr && quadrilaterals->len > 0, NULL);

    auto annot = std::make_shared<AnnotTextMarkup>(doc->doc, &pdf_rect, Annot::typeStrikeOut);

    poppler_annot = _poppler_annot_text_markup_new(annot);
    poppler_annot_text_markup_set_quadrilaterals(POPPLER_ANNOT_TEXT_MARKUP(poppler_annot), quadrilaterals);
    return poppler_annot;
}

/**
 * poppler_annot_text_markup_new_underline:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 * @quadrilaterals: (element-type PopplerQuadrilateral): A #GArray of
 *   #PopplerQuadrilateral<!-- -->s
 *
 * Creates a new Underline Text annotation that will be
 * located on @rect when added to a page. See poppler_page_add_annot()
 *
 * Return value: (transfer full): A newly created #PopplerAnnotTextMarkup annotation
 *
 * Since: 0.26
 */
PopplerAnnot *poppler_annot_text_markup_new_underline(PopplerDocument *doc, PopplerRectangle *rect, GArray *quadrilaterals)
{
    PopplerAnnot *poppler_annot;
    PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);

    g_return_val_if_fail(quadrilaterals != nullptr && quadrilaterals->len > 0, NULL);

    auto annot = std::make_shared<AnnotTextMarkup>(doc->doc, &pdf_rect, Annot::typeUnderline);

    poppler_annot = _poppler_annot_text_markup_new(annot);
    poppler_annot_text_markup_set_quadrilaterals(POPPLER_ANNOT_TEXT_MARKUP(poppler_annot), quadrilaterals);
    return poppler_annot;
}

PopplerColor *_poppler_convert_annot_color_to_poppler_color(const AnnotColor *color)
{
    PopplerColor *poppler_color = nullptr;

    if (color) {
        const std::array<double, 4> &values = color->getValues();

        switch (color->getSpace()) {
        case AnnotColor::colorGray:
            poppler_color = g_new(PopplerColor, 1);

            poppler_color->red = CLAMP((guint16)(values[0] * 65535), 0, 65535);
            poppler_color->green = poppler_color->red;
            poppler_color->blue = poppler_color->red;

            break;
        case AnnotColor::colorRGB:
            poppler_color = g_new(PopplerColor, 1);

            poppler_color->red = CLAMP((guint16)(values[0] * 65535), 0, 65535);
            poppler_color->green = CLAMP((guint16)(values[1] * 65535), 0, 65535);
            poppler_color->blue = CLAMP((guint16)(values[2] * 65535), 0, 65535);

            break;
        case AnnotColor::colorCMYK:
            g_warning("Unsupported Annot Color: colorCMYK");
            break;
        case AnnotColor::colorTransparent:
            break;
        }
    }

    return poppler_color;
}

std::unique_ptr<AnnotColor> _poppler_convert_poppler_color_to_annot_color(const PopplerColor *poppler_color)
{
    if (!poppler_color) {
        return nullptr;
    }

    return std::make_unique<AnnotColor>(CLAMP((double)poppler_color->red / 65535, 0., 1.), CLAMP((double)poppler_color->green / 65535, 0., 1.), CLAMP((double)poppler_color->blue / 65535, 0., 1.));
}

static void poppler_annot_free_text_init(PopplerAnnotFreeText *poppler_annot) { }

static void poppler_annot_free_text_class_init(PopplerAnnotFreeTextClass *klass) { }

// Single map with string keys and enum values
enum FontPropType
{
    TYPE_STYLE,
    TYPE_WEIGHT,
    TYPE_STRETCH,
    TYPE_NORMAL
};

typedef std::map<std::string, std::pair<FontPropType, int>> FontstyleMap;

static const FontstyleMap string_to_fontstyle = { { "UltraCondensed", std::pair(TYPE_STRETCH, POPPLER_STRETCH_ULTRA_CONDENSED) },
                                                  { "ExtraCondensed", std::pair(TYPE_STRETCH, POPPLER_STRETCH_EXTRA_CONDENSED) },
                                                  { "Condensed", std::pair(TYPE_STRETCH, POPPLER_STRETCH_CONDENSED) },
                                                  { "SemiCondensed", std::pair(TYPE_STRETCH, POPPLER_STRETCH_SEMI_CONDENSED) },
                                                  { "SemiExpanded", std::pair(TYPE_STRETCH, POPPLER_STRETCH_SEMI_EXPANDED) },
                                                  { "Expanded", std::pair(TYPE_STRETCH, POPPLER_STRETCH_EXPANDED) },
                                                  { "UltraExpanded", std::pair(TYPE_STRETCH, POPPLER_STRETCH_ULTRA_EXPANDED) },
                                                  { "ExtraExpanded", std::pair(TYPE_STRETCH, POPPLER_STRETCH_EXTRA_EXPANDED) },
                                                  { "Thin", std::pair(TYPE_WEIGHT, POPPLER_WEIGHT_THIN) },
                                                  { "UltraLight", std::pair(TYPE_WEIGHT, POPPLER_WEIGHT_ULTRALIGHT) },
                                                  { "Light", std::pair(TYPE_WEIGHT, POPPLER_WEIGHT_LIGHT) },
                                                  { "Medium", std::pair(TYPE_WEIGHT, POPPLER_WEIGHT_MEDIUM) },
                                                  { "SemiBold", std::pair(TYPE_WEIGHT, POPPLER_WEIGHT_SEMIBOLD) },
                                                  { "Bold", std::pair(TYPE_WEIGHT, POPPLER_WEIGHT_BOLD) },
                                                  { "UltraBold", std::pair(TYPE_WEIGHT, POPPLER_WEIGHT_ULTRABOLD) },
                                                  { "Heavy", std::pair(TYPE_WEIGHT, POPPLER_WEIGHT_HEAVY) },
                                                  { "Italic", std::pair(TYPE_STYLE, POPPLER_STYLE_ITALIC) },
                                                  { "Oblique", std::pair(TYPE_STYLE, POPPLER_STYLE_OBLIQUE) },
                                                  { "Regular", std::pair(TYPE_NORMAL, 0) },
                                                  { "Normal", std::pair(TYPE_NORMAL, 0) } };

static const char *stretch_to_str[] = { "UltraCondensed", "ExtraCondensed", "Condensed", "SemiCondensed", /* Normal */ "", "SemiExpanded", "Expanded", "ExtraExpanded", "UltraExpanded" };

const std::map<std::string, std::string> fallback_fonts = {
    { "/Helvetica", "Helvetica" }, /* iOS */
    { "Helv", "Helvetica" } /* Firefox */
};

static bool update_font_desc_with_word(PopplerFontDescription &font_desc, std::string &word)
{
    FontstyleMap::const_iterator a = string_to_fontstyle.find(word);
    if (a != string_to_fontstyle.end()) {
        std::pair<FontPropType, int> elt = a->second;
        switch (elt.first) {
        case TYPE_STYLE:
            font_desc.style = (PopplerStyle)elt.second;
            return true;
        case TYPE_WEIGHT:
            font_desc.weight = (PopplerWeight)elt.second;
            return true;
        case TYPE_STRETCH:
            font_desc.stretch = (PopplerStretch)elt.second;
            return true;
        case TYPE_NORMAL:
            return true;
        }
    }
    return false;
}

static void poppler_font_name_to_description(const std::string &name, PopplerFontDescription &font_desc)
{
    /* Last three words of the font name may be style indications */
    size_t end = name.size();
    size_t start;

    for (int i = 3; i >= 1; --i) {
        start = name.find_last_of(' ', end - 1);
        if (start == std::string::npos) {
            break;
        }
        std::string word = name.substr(start + 1, end - start - 1);

        if (!update_font_desc_with_word(font_desc, word)) {
            break;
        }

        end = start;
    }
    font_desc.font_name = g_strdup(name.substr(0, end).c_str());
}

PopplerAnnot *_poppler_annot_free_text_new(const std::shared_ptr<Annot> &annot)
{
    PopplerAnnot *poppler_annot = _poppler_create_annot(POPPLER_TYPE_ANNOT_FREE_TEXT, annot);
    PopplerAnnotFreeText *ft_annot = POPPLER_ANNOT_FREE_TEXT(poppler_annot);
    std::unique_ptr<DefaultAppearance> da = ((AnnotFreeText *)annot.get())->getDefaultAppearance();
    PopplerFontDescription *desc = nullptr;
    if (da->getFontName().isName()) {
        desc = poppler_font_description_new(da->getFontName().getName());
        desc->size_pt = da->getFontPtSize();

        /* Attempt to resolve the actual font name. */
        Form *form = annot->getDoc()->getCatalog()->getCreateForm();
        if (form) {
            GfxResources *res = form->getDefaultResources();
            if (res) {
                std::shared_ptr<GfxFont> font = res->lookupFont(desc->font_name);
                if (font) {
                    const std::optional<std::string> &fontName = font->getName();
                    if (fontName) {
                        poppler_font_name_to_description(fontName.value(), *desc);
                    }
                }
            }
        }

        std::map<std::string, std::string>::const_iterator fallback_font = fallback_fonts.find(std::string(desc->font_name));
        if (fallback_font != fallback_fonts.end()) {
            desc->font_name = g_strdup(fallback_font->second.c_str());
        }
    }

    ft_annot->font_desc = desc;

    const AnnotColor *ac = da->getFontColor();

    if (ac) {
        PopplerColor *font_color = _poppler_convert_annot_color_to_poppler_color(ac);
        ft_annot->font_color = *font_color;
        poppler_color_free(font_color);
    }

    return poppler_annot;
}

/**
 * poppler_annot_free_text_new:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 *
 * Creates a new Free Text annotation that will be
 * located on @rect when added to a page. See
 * poppler_page_add_annot(). It initially has no content. Font family, size and
 * color are initially undefined and must be set, see
 * poppler_annot_free_text_set_font_desc() and
 * poppler_annot_free_text_set_font_color().
 *
 * Returns: (transfer full): A newly created #PopplerAnnotFreeText annotation
 */
PopplerAnnot *poppler_annot_free_text_new(PopplerDocument *doc, PopplerRectangle *rect)
{
    PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);

    auto annot = std::make_shared<AnnotFreeText>(doc->doc, &pdf_rect);

    PopplerAnnot *poppler_annot = _poppler_annot_free_text_new(annot);

    return poppler_annot;
}

static void poppler_annot_file_attachment_init(PopplerAnnotFileAttachment *poppler_annot) { }

static void poppler_annot_file_attachment_class_init(PopplerAnnotFileAttachmentClass *klass) { }

PopplerAnnot *_poppler_annot_file_attachment_new(const std::shared_ptr<Annot> &annot)
{
    return _poppler_create_annot(POPPLER_TYPE_ANNOT_FILE_ATTACHMENT, annot);
}

static void poppler_annot_movie_finalize(GObject *object)
{
    PopplerAnnotMovie *annot_movie = POPPLER_ANNOT_MOVIE(object);

    if (annot_movie->movie) {
        g_object_unref(annot_movie->movie);
        annot_movie->movie = nullptr;
    }

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

static void poppler_annot_movie_init(PopplerAnnotMovie *poppler_annot) { }

static void poppler_annot_movie_class_init(PopplerAnnotMovieClass *klass)
{
    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);

    gobject_class->finalize = poppler_annot_movie_finalize;
}

PopplerAnnot *_poppler_annot_movie_new(const std::shared_ptr<Annot> &annot)
{
    PopplerAnnot *poppler_annot;
    AnnotMovie *annot_movie;

    poppler_annot = _poppler_create_annot(POPPLER_TYPE_ANNOT_MOVIE, annot);
    annot_movie = static_cast<AnnotMovie *>(poppler_annot->annot.get());
    POPPLER_ANNOT_MOVIE(poppler_annot)->movie = _poppler_movie_new(annot_movie->getMovie());

    return poppler_annot;
}

static void poppler_annot_screen_finalize(GObject *object)
{
    PopplerAnnotScreen *annot_screen = POPPLER_ANNOT_SCREEN(object);

    if (annot_screen->action) {
        poppler_action_free(annot_screen->action);
        annot_screen->action = nullptr;
    }

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

static void poppler_annot_screen_init(PopplerAnnotScreen *poppler_annot) { }

static void poppler_annot_screen_class_init(PopplerAnnotScreenClass *klass)
{
    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);

    gobject_class->finalize = poppler_annot_screen_finalize;
}

PopplerAnnot *_poppler_annot_screen_new(PopplerDocument *doc, const std::shared_ptr<Annot> &annot)
{
    PopplerAnnot *poppler_annot;
    AnnotScreen *annot_screen;
    LinkAction *action;

    poppler_annot = _poppler_create_annot(POPPLER_TYPE_ANNOT_SCREEN, annot);
    annot_screen = static_cast<AnnotScreen *>(poppler_annot->annot.get());
    action = annot_screen->getAction();
    if (action) {
        POPPLER_ANNOT_SCREEN(poppler_annot)->action = _poppler_action_new(doc, action, nullptr);
    }

    return poppler_annot;
}

PopplerAnnot *_poppler_annot_line_new(const std::shared_ptr<Annot> &annot)
{
    return _poppler_create_annot(POPPLER_TYPE_ANNOT_LINE, annot);
}

static void poppler_annot_line_init(PopplerAnnotLine *poppler_annot) { }

static void poppler_annot_line_class_init(PopplerAnnotLineClass *klass) { }

/**
 * poppler_annot_line_new:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 * @start: a #PopplerPoint of the starting vertice
 * @end: a #PopplerPoint of the ending vertice
 *
 * Creates a new Line annotation that will be
 * located on @rect when added to a page. See
 * poppler_page_add_annot()
 *
 * Return value: A newly created #PopplerAnnotLine annotation
 *
 * Since: 0.26
 */
PopplerAnnot *poppler_annot_line_new(PopplerDocument *doc, PopplerRectangle *rect, PopplerPoint *start, PopplerPoint *end)
{
    PopplerAnnot *poppler_annot;
    PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);

    auto annot = std::make_shared<AnnotLine>(doc->doc, &pdf_rect);

    poppler_annot = _poppler_annot_line_new(annot);
    poppler_annot_line_set_vertices(POPPLER_ANNOT_LINE(poppler_annot), start, end);
    return poppler_annot;
}

PopplerAnnot *_poppler_annot_circle_new(const std::shared_ptr<Annot> &annot)
{
    return _poppler_create_annot(POPPLER_TYPE_ANNOT_CIRCLE, annot);
}

static void poppler_annot_circle_init(PopplerAnnotCircle *poppler_annot) { }

static void poppler_annot_circle_class_init(PopplerAnnotCircleClass *klass) { }

/**
 * poppler_annot_circle_new:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 *
 * Creates a new Circle annotation that will be
 * located on @rect when added to a page. See
 * poppler_page_add_annot()
 *
 * Return value: a newly created #PopplerAnnotCircle annotation
 *
 * Since: 0.26
 **/
PopplerAnnot *poppler_annot_circle_new(PopplerDocument *doc, PopplerRectangle *rect)
{
    PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);

    auto annot = std::make_shared<AnnotGeometry>(doc->doc, &pdf_rect, Annot::typeCircle);

    return _poppler_annot_circle_new(annot);
}

PopplerAnnot *_poppler_annot_square_new(const std::shared_ptr<Annot> &annot)
{
    return _poppler_create_annot(POPPLER_TYPE_ANNOT_SQUARE, annot);
}

static void poppler_annot_square_init(PopplerAnnotSquare *poppler_annot) { }

static void poppler_annot_square_class_init(PopplerAnnotSquareClass *klass) { }

/**
 * poppler_annot_square_new:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 *
 * Creates a new Square annotation that will be
 * located on @rect when added to a page. See
 * poppler_page_add_annot()
 *
 * Return value: a newly created #PopplerAnnotSquare annotation
 *
 * Since: 0.26
 **/
PopplerAnnot *poppler_annot_square_new(PopplerDocument *doc, PopplerRectangle *rect)
{
    PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);

    auto annot = std::make_shared<AnnotGeometry>(doc->doc, &pdf_rect, Annot::typeSquare);

    return _poppler_annot_square_new(annot);
}

static void poppler_annot_stamp_finalize(GObject *object)
{
    G_OBJECT_CLASS(poppler_annot_stamp_parent_class)->finalize(object);
}

static void poppler_annot_stamp_init(PopplerAnnotStamp *poppler_annot) { }

static void poppler_annot_stamp_class_init(PopplerAnnotStampClass *klass)
{
    GObjectClass *gobject_class = G_OBJECT_CLASS(klass);

    gobject_class->finalize = poppler_annot_stamp_finalize;
}

PopplerAnnot *_poppler_annot_stamp_new(const std::shared_ptr<Annot> &annot)
{
    PopplerAnnot *poppler_annot;

    poppler_annot = _poppler_create_annot(POPPLER_TYPE_ANNOT_STAMP, annot);

    return poppler_annot;
}

/**
 * poppler_annot_stamp_new:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 *
 * Creates a new Stamp annotation that will be
 * located on @rect when added to a page. See
 * poppler_page_add_annot()
 *
 * Return value: a newly created #PopplerAnnotStamp annotation
 *
 * Since: 22.07.0
 **/
PopplerAnnot *poppler_annot_stamp_new(PopplerDocument *doc, PopplerRectangle *rect)
{
    PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);

    auto annot = std::make_shared<AnnotStamp>(doc->doc, &pdf_rect);

    return _poppler_annot_stamp_new(annot);
}

static gboolean get_raw_data_from_cairo_image(cairo_surface_t *image, cairo_format_t format, const int width, const int height, const size_t rowstride_c, GByteArray *data, GByteArray *soft_mask_data)
{
    gboolean has_alpha = format == CAIRO_FORMAT_ARGB32;

#if G_BYTE_ORDER == G_LITTLE_ENDIAN
    static const size_t CAIRO_B = 0;
    static const size_t CAIRO_G = 1;
    static const size_t CAIRO_R = 2;
    static const size_t CAIRO_A = 3;
#elif G_BYTE_ORDER == G_BIG_ENDIAN
    static const size_t CAIRO_A = 0;
    static const size_t CAIRO_R = 1;
    static const size_t CAIRO_G = 2;
    static const size_t CAIRO_B = 3;
#else
#    error "Unsupported endian type"
#endif

    cairo_surface_flush(image);
    unsigned char *pixels_c = cairo_image_surface_get_data(image);

    if (format == CAIRO_FORMAT_ARGB32 || format == CAIRO_FORMAT_RGB24) {
        unsigned char pixel[3];

        for (int h = 0; h < height; h++) {
            unsigned char *iter_c = pixels_c + h * rowstride_c;
            for (int w = 0; w < width; w++) {
                pixel[0] = iter_c[CAIRO_R];
                pixel[1] = iter_c[CAIRO_G];
                pixel[2] = iter_c[CAIRO_B];
                iter_c += 4;

                g_byte_array_append(data, (guint8 *)pixel, 3);
                if (has_alpha) {
                    g_byte_array_append(soft_mask_data, (guint8 *)&iter_c[CAIRO_A], 1);
                }
            }
        }
        return TRUE;
    }

    return FALSE;
}

std::unique_ptr<AnnotStampImageHelper> _poppler_convert_cairo_image_to_stamp_image_helper(cairo_surface_t *image, PDFDoc *doc, GError **error)
{
    std::unique_ptr<AnnotStampImageHelper> annotImg;
    GByteArray *data;
    GByteArray *sMaskData;

    int bitsPerComponent;
    const int width = cairo_image_surface_get_width(image);
    const int height = cairo_image_surface_get_height(image);
    const size_t rowstride_c = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
    cairo_format_t format = cairo_image_surface_get_format(image);

    ColorSpace colorSpace;

    if (format == CAIRO_FORMAT_ARGB32 || format == CAIRO_FORMAT_RGB24) {
        colorSpace = ColorSpace::DeviceRGB;
        bitsPerComponent = 8;
    } else {
        g_set_error(error, POPPLER_ERROR, POPPLER_ERROR_INVALID, "Invalid or unsupported cairo image type %u", (unsigned int)format);
        return nullptr;
    }

    data = g_byte_array_sized_new((guint)((width * 4) + rowstride_c) * height);
    sMaskData = g_byte_array_sized_new((guint)((width * 4) + rowstride_c) * height);

    if (!get_raw_data_from_cairo_image(image, format, width, height, rowstride_c, data, sMaskData)) {
        g_set_error(error, POPPLER_ERROR, POPPLER_ERROR_INVALID, "Failed to get raw data from cairo image");
        g_byte_array_unref(data);
        g_byte_array_unref(sMaskData);
        return nullptr;
    }

    if (sMaskData->len > 0) {
        AnnotStampImageHelper sMask(doc, width, height, ColorSpace::DeviceGray, 8, (char *)sMaskData->data, (int)sMaskData->len);
        annotImg = std::make_unique<AnnotStampImageHelper>(doc, width, height, colorSpace, bitsPerComponent, (char *)data->data, (int)data->len, sMask.getRef());
    } else {
        annotImg = std::make_unique<AnnotStampImageHelper>(doc, width, height, colorSpace, bitsPerComponent, (char *)data->data, (int)data->len);
    }

    g_byte_array_unref(data);
    g_byte_array_unref(sMaskData);

    return annotImg;
}

/* Public methods */
/**
 * poppler_annot_get_annot_type:
 * @poppler_annot: a #PopplerAnnot
 *
 * Gets the type of @poppler_annot
 *
 * Return value: #PopplerAnnotType of @poppler_annot.
 **/
PopplerAnnotType poppler_annot_get_annot_type(PopplerAnnot *poppler_annot)
{
    g_return_val_if_fail(POPPLER_IS_ANNOT(poppler_annot), POPPLER_ANNOT_UNKNOWN);

    switch (poppler_annot->annot->getType()) {
    case Annot::typeText:
        return POPPLER_ANNOT_TEXT;
    case Annot::typeLink:
        return POPPLER_ANNOT_LINK;
    case Annot::typeFreeText:
        return POPPLER_ANNOT_FREE_TEXT;
    case Annot::typeLine:
        return POPPLER_ANNOT_LINE;
    case Annot::typeSquare:
        return POPPLER_ANNOT_SQUARE;
    case Annot::typeCircle:
        return POPPLER_ANNOT_CIRCLE;
    case Annot::typePolygon:
        return POPPLER_ANNOT_POLYGON;
    case Annot::typePolyLine:
        return POPPLER_ANNOT_POLY_LINE;
    case Annot::typeHighlight:
        return POPPLER_ANNOT_HIGHLIGHT;
    case Annot::typeUnderline:
        return POPPLER_ANNOT_UNDERLINE;
    case Annot::typeSquiggly:
        return POPPLER_ANNOT_SQUIGGLY;
    case Annot::typeStrikeOut:
        return POPPLER_ANNOT_STRIKE_OUT;
    case Annot::typeStamp:
        return POPPLER_ANNOT_STAMP;
    case Annot::typeCaret:
        return POPPLER_ANNOT_CARET;
    case Annot::typeInk:
        return POPPLER_ANNOT_INK;
    case Annot::typePopup:
        return POPPLER_ANNOT_POPUP;
    case Annot::typeFileAttachment:
        return POPPLER_ANNOT_FILE_ATTACHMENT;
    case Annot::typeSound:
        return POPPLER_ANNOT_SOUND;
    case Annot::typeMovie:
        return POPPLER_ANNOT_MOVIE;
    case Annot::typeWidget:
        return POPPLER_ANNOT_WIDGET;
    case Annot::typeScreen:
        return POPPLER_ANNOT_SCREEN;
    case Annot::typePrinterMark:
        return POPPLER_ANNOT_PRINTER_MARK;
    case Annot::typeTrapNet:
        return POPPLER_ANNOT_TRAP_NET;
    case Annot::typeWatermark:
        return POPPLER_ANNOT_WATERMARK;
    case Annot::type3D:
        return POPPLER_ANNOT_3D;
    default:
        g_warning("Unsupported Annot Type");
    }

    return POPPLER_ANNOT_UNKNOWN;
}

/**
 * poppler_annot_get_contents:
 * @poppler_annot: a #PopplerAnnot
 *
 * Retrieves the contents of @poppler_annot.
 *
 * Return value: a new allocated string with the contents of @poppler_annot. It
 *               must be freed with g_free() when done.
 **/
gchar *poppler_annot_get_contents(PopplerAnnot *poppler_annot)
{
    const GooString *contents;

    g_return_val_if_fail(POPPLER_IS_ANNOT(poppler_annot), NULL);

    contents = poppler_annot->annot->getContents();

    return contents && !contents->empty() ? _poppler_goo_string_to_utf8(contents) : nullptr;
}

/**
 * poppler_annot_set_contents:
 * @poppler_annot: a #PopplerAnnot
 * @contents: a text string containing the new contents
 *
 * Sets the contents of @poppler_annot to the given value,
 * replacing the current contents.
 *
 * Since: 0.12
 **/
void poppler_annot_set_contents(PopplerAnnot *poppler_annot, const gchar *contents)
{
    gchar *tmp;
    gsize length = 0;

    g_return_if_fail(POPPLER_IS_ANNOT(poppler_annot));

    tmp = contents ? g_convert(contents, -1, "UTF-16BE", "UTF-8", nullptr, &length, nullptr) : nullptr;
    poppler_annot->annot->setContents(std::make_unique<GooString>(tmp, length));
    g_free(tmp);
}

/**
 * poppler_annot_get_name:
 * @poppler_annot: a #PopplerAnnot
 *
 * Retrieves the name of @poppler_annot.
 *
 * Return value: a new allocated string with the name of @poppler_annot. It must
 *               be freed with g_free() when done.
 **/
gchar *poppler_annot_get_name(PopplerAnnot *poppler_annot)
{
    const GooString *name;

    g_return_val_if_fail(POPPLER_IS_ANNOT(poppler_annot), NULL);

    name = poppler_annot->annot->getName();

    return name ? _poppler_goo_string_to_utf8(name) : nullptr;
}

/**
 * poppler_annot_get_modified:
 * @poppler_annot: a #PopplerAnnot
 *
 * Retrieves the last modification data of @poppler_annot. The returned
 * string will be either a PDF format date or a text string.
 * See also #poppler_date_parse()
 *
 * Return value: a new allocated string with the last modification data of
 *               @poppler_annot. It must be freed with g_free() when done.
 **/
gchar *poppler_annot_get_modified(PopplerAnnot *poppler_annot)
{
    const GooString *text;

    g_return_val_if_fail(POPPLER_IS_ANNOT(poppler_annot), NULL);

    text = poppler_annot->annot->getModified();

    return text ? _poppler_goo_string_to_utf8(text) : nullptr;
}

/**
 * poppler_annot_get_flags:
 * @poppler_annot: a #PopplerAnnot
 *
 * Retrieves the flag field specifying various characteristics of the
 * @poppler_annot.
 *
 * Return value: the flag field of @poppler_annot.
 **/
PopplerAnnotFlag poppler_annot_get_flags(PopplerAnnot *poppler_annot)
{
    g_return_val_if_fail(POPPLER_IS_ANNOT(poppler_annot), (PopplerAnnotFlag)0);

    return (PopplerAnnotFlag)poppler_annot->annot->getFlags();
}

/**
 * poppler_annot_set_flags:
 * @poppler_annot: a #PopplerAnnot
 * @flags: a #PopplerAnnotFlag
 *
 * Sets the flag field specifying various characteristics of the
 * @poppler_annot.
 *
 * Since: 0.22
 **/
void poppler_annot_set_flags(PopplerAnnot *poppler_annot, PopplerAnnotFlag flags)
{
    g_return_if_fail(POPPLER_IS_ANNOT(poppler_annot));

    if (poppler_annot_get_flags(poppler_annot) == flags) {
        return;
    }

    poppler_annot->annot->setFlags((guint)flags);
}

/**
 * poppler_annot_get_color:
 * @poppler_annot: a #PopplerAnnot
 *
 * Retrieves the color of @poppler_annot.
 *
 * Return value: a new allocated #PopplerColor with the color values of
 *               @poppler_annot, or %NULL. It must be freed with g_free() when done.
 **/
PopplerColor *poppler_annot_get_color(PopplerAnnot *poppler_annot)
{
    g_return_val_if_fail(POPPLER_IS_ANNOT(poppler_annot), NULL);

    return _poppler_convert_annot_color_to_poppler_color(poppler_annot->annot->getColor());
}

/**
 * poppler_annot_set_color:
 * @poppler_annot: a #PopplerAnnot
 * @poppler_color: (allow-none): a #PopplerColor, or %NULL
 *
 * Sets the color of @poppler_annot.
 *
 * Since: 0.16
 */
void poppler_annot_set_color(PopplerAnnot *poppler_annot, PopplerColor *poppler_color)
{
    poppler_annot->annot->setColor(_poppler_convert_poppler_color_to_annot_color(poppler_color));
}

/**
 * poppler_annot_get_page_index:
 * @poppler_annot: a #PopplerAnnot
 *
 * Returns the page index to which @poppler_annot is associated, or -1 if unknown
 *
 * Return value: page index or -1
 *
 * Since: 0.14
 **/
gint poppler_annot_get_page_index(PopplerAnnot *poppler_annot)
{
    gint page_num;

    g_return_val_if_fail(POPPLER_IS_ANNOT(poppler_annot), -1);

    page_num = poppler_annot->annot->getPageNum();
    return page_num <= 0 ? -1 : page_num - 1;
}

/* Returns cropbox rect for the page where the passed in @poppler_annot is in,
 * or NULL when could not retrieve the cropbox. If @page_out is non-null then
 * it will be set with the page that @poppler_annot is in. */
const PDFRectangle *_poppler_annot_get_cropbox_and_page(PopplerAnnot *poppler_annot, Page **page_out)
{
    int page_index;

    /* A returned zero means annot is not added to any page yet */
    page_index = poppler_annot->annot->getPageNum();

    if (page_index) {
        Page *page;

        page = poppler_annot->annot->getDoc()->getPage(page_index);
        if (page) {
            if (page_out) {
                *page_out = page;
            }

            return page->getCropBox();
        }
    }

    return nullptr;
}

/* Returns cropbox rect for the page where the passed in @poppler_annot is in,
 * or NULL when could not retrieve the cropbox */
const PDFRectangle *_poppler_annot_get_cropbox(PopplerAnnot *poppler_annot)
{
    return _poppler_annot_get_cropbox_and_page(poppler_annot, nullptr);
}

/**
 * poppler_annot_get_rectangle:
 * @poppler_annot: a #PopplerAnnot
 * @poppler_rect: (out): a #PopplerRectangle to store the annotation's coordinates
 *
 * Retrieves the rectangle representing the page coordinates where the
 * annotation @poppler_annot is placed.
 *
 * Since: 0.26
 */
void poppler_annot_get_rectangle(PopplerAnnot *poppler_annot, PopplerRectangle *poppler_rect)
{
    const PDFRectangle *crop_box;
    PDFRectangle zerobox;
    Page *page = nullptr;

    g_return_if_fail(POPPLER_IS_ANNOT(poppler_annot));
    g_return_if_fail(poppler_rect != nullptr);

    crop_box = _poppler_annot_get_cropbox_and_page(poppler_annot, &page);
    if (!crop_box) {
        zerobox = PDFRectangle();
        crop_box = &zerobox;
    }

    const PDFRectangle &annot_rect = poppler_annot->annot->getRect();
    poppler_rect->x1 = annot_rect.x1 - crop_box->x1;
    poppler_rect->x2 = annot_rect.x2 - crop_box->x1;
    poppler_rect->y1 = annot_rect.y1 - crop_box->y1;
    poppler_rect->y2 = annot_rect.y2 - crop_box->y1;
}

/**
 * poppler_annot_set_rectangle:
 * @poppler_annot: a #PopplerAnnot
 * @poppler_rect: a #PopplerRectangle with the new annotation's coordinates
 *
 * Move the annotation to the rectangle representing the page coordinates
 * where the annotation @poppler_annot should be placed.
 *
 * Since: 0.26
 */
void poppler_annot_set_rectangle(PopplerAnnot *poppler_annot, PopplerRectangle *poppler_rect)
{
    const PDFRectangle *crop_box;
    PDFRectangle zerobox;
    double x1, y1, x2, y2;
    Page *page = nullptr;

    g_return_if_fail(POPPLER_IS_ANNOT(poppler_annot));
    g_return_if_fail(poppler_rect != nullptr);

    crop_box = _poppler_annot_get_cropbox_and_page(poppler_annot, &page);
    if (!crop_box) {
        zerobox = PDFRectangle();
        crop_box = &zerobox;
    }

    x1 = poppler_rect->x1;
    y1 = poppler_rect->y1;
    x2 = poppler_rect->x2;
    y2 = poppler_rect->y2;

    if (page && SUPPORTED_ROTATION(page->getRotate())) {
        /* annot is inside a rotated page, as core poppler rect must be saved
         * un-rotated, let's proceed to un-rotate rect before saving */
        _unrotate_rect_for_annot_and_page(page, poppler_annot->annot.get(), &x1, &y1, &x2, &y2);
    }

    poppler_annot->annot->setRect(x1 + crop_box->x1, y1 + crop_box->y1, x2 + crop_box->x1, y2 + crop_box->y1);
}

/* PopplerAnnotMarkup */
/**
 * poppler_annot_markup_get_label:
 * @poppler_annot: a #PopplerAnnotMarkup
 *
 * Retrieves the label text of @poppler_annot.
 *
 * Return value: the label text of @poppler_annot.
 */
gchar *poppler_annot_markup_get_label(PopplerAnnotMarkup *poppler_annot)
{
    AnnotMarkup *annot;
    const GooString *text;

    g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), NULL);

    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    text = annot->getLabel();

    return text ? _poppler_goo_string_to_utf8(text) : nullptr;
}

/**
 * poppler_annot_markup_set_label:
 * @poppler_annot: a #PopplerAnnotMarkup
 * @label: (allow-none): a text string containing the new label, or %NULL
 *
 * Sets the label text of @poppler_annot, replacing the current one
 *
 * Since: 0.16
 */
void poppler_annot_markup_set_label(PopplerAnnotMarkup *poppler_annot, const gchar *label)
{
    AnnotMarkup *annot;
    gchar *tmp;
    gsize length = 0;

    g_return_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot));

    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    tmp = label ? g_convert(label, -1, "UTF-16BE", "UTF-8", nullptr, &length, nullptr) : nullptr;
    annot->setLabel(std::make_unique<GooString>(tmp, length));
    g_free(tmp);
}

/**
 * poppler_annot_markup_has_popup:
 * @poppler_annot: a #PopplerAnnotMarkup
 *
 * Return %TRUE if the markup annotation has a popup window associated
 *
 * Return value: %TRUE, if @poppler_annot has popup, %FALSE otherwise
 *
 * Since: 0.12
 **/
gboolean poppler_annot_markup_has_popup(PopplerAnnotMarkup *poppler_annot)
{
    AnnotMarkup *annot;

    g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), FALSE);

    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    return annot->getPopup() != nullptr;
}

/**
 * poppler_annot_markup_set_popup:
 * @poppler_annot: a #PopplerAnnotMarkup
 * @popup_rect: a #PopplerRectangle
 *
 * Associates a new popup window for editing contents of @poppler_annot.
 * Popup window shall be displayed by viewers at @popup_rect on the page.
 *
 * Since: 0.16
 */
void poppler_annot_markup_set_popup(PopplerAnnotMarkup *poppler_annot, PopplerRectangle *popup_rect)
{
    AnnotMarkup *annot;
    PDFRectangle pdf_rect(popup_rect->x1, popup_rect->y1, popup_rect->x2, popup_rect->y2);

    g_return_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot));

    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
    annot->setPopup(std::make_shared<AnnotPopup>(annot->getDoc(), &pdf_rect));
}

/**
 * poppler_annot_markup_get_popup_is_open:
 * @poppler_annot: a #PopplerAnnotMarkup
 *
 * Retrieves the state of the popup window related to @poppler_annot.
 *
 * Return value: the state of @poppler_annot. %TRUE if it's open, %FALSE in
 *               other case.
 **/
gboolean poppler_annot_markup_get_popup_is_open(PopplerAnnotMarkup *poppler_annot)
{
    AnnotMarkup *annot;
    AnnotPopup *annot_popup;

    g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), FALSE);

    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    if ((annot_popup = annot->getPopup().get())) {
        return annot_popup->getOpen();
    }

    return FALSE;
}

/**
 * poppler_annot_markup_set_popup_is_open:
 * @poppler_annot: a #PopplerAnnotMarkup
 * @is_open: whether popup window should initially be displayed open
 *
 * Sets the state of the popup window related to @poppler_annot.
 *
 * Since: 0.16
 **/
void poppler_annot_markup_set_popup_is_open(PopplerAnnotMarkup *poppler_annot, gboolean is_open)
{
    AnnotMarkup *annot;
    AnnotPopup *annot_popup;

    g_return_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot));

    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    annot_popup = annot->getPopup().get();
    if (!annot_popup) {
        return;
    }

    if (annot_popup->getOpen() != is_open) {
        annot_popup->setOpen(is_open);
    }
}

/**
 * poppler_annot_markup_get_popup_rectangle:
 * @poppler_annot: a #PopplerAnnotMarkup
 * @poppler_rect: (out): a #PopplerRectangle to store the popup rectangle
 *
 * Retrieves the rectangle of the popup window related to @poppler_annot.
 *
 * Return value: %TRUE if #PopplerRectangle was correctly filled, %FALSE otherwise
 *
 * Since: 0.12
 **/
gboolean poppler_annot_markup_get_popup_rectangle(PopplerAnnotMarkup *poppler_annot, PopplerRectangle *poppler_rect)
{
    AnnotMarkup *annot;
    Annot *annot_popup;

    g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), FALSE);
    g_return_val_if_fail(poppler_rect != nullptr, FALSE);

    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
    annot_popup = annot->getPopup().get();
    if (!annot_popup) {
        return FALSE;
    }

    const PDFRectangle &annot_rect = annot_popup->getRect();
    poppler_rect->x1 = annot_rect.x1;
    poppler_rect->x2 = annot_rect.x2;
    poppler_rect->y1 = annot_rect.y1;
    poppler_rect->y2 = annot_rect.y2;

    return TRUE;
}

/**
 * poppler_annot_markup_set_popup_rectangle:
 * @poppler_annot: a #PopplerAnnotMarkup
 * @poppler_rect: a #PopplerRectangle to set
 *
 * Sets the rectangle of the popup window related to @poppler_annot.
 * This doesn't have any effect if @poppler_annot doesn't have a
 * popup associated, use poppler_annot_markup_set_popup() to associate
 * a popup window to a #PopplerAnnotMarkup.
 *
 * Since: 0.33
 */
void poppler_annot_markup_set_popup_rectangle(PopplerAnnotMarkup *poppler_annot, PopplerRectangle *poppler_rect)
{
    AnnotMarkup *annot;
    Annot *annot_popup;

    g_return_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot));
    g_return_if_fail(poppler_rect != nullptr);

    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
    annot_popup = annot->getPopup().get();
    if (!annot_popup) {
        return;
    }

    annot_popup->setRect(poppler_rect->x1, poppler_rect->y1, poppler_rect->x2, poppler_rect->y2);
}

/**
 * poppler_annot_markup_get_opacity:
 * @poppler_annot: a #PopplerAnnotMarkup
 *
 * Retrieves the opacity value of @poppler_annot.
 *
 * Return value: the opacity value of @poppler_annot,
 *               between 0 (transparent) and 1 (opaque)
 */
gdouble poppler_annot_markup_get_opacity(PopplerAnnotMarkup *poppler_annot)
{
    AnnotMarkup *annot;

    g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), 0);

    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    return annot->getOpacity();
}

/**
 * poppler_annot_markup_set_opacity:
 * @poppler_annot: a #PopplerAnnotMarkup
 * @opacity: a constant opacity value, between 0 (transparent) and 1 (opaque)
 *
 * Sets the opacity of @poppler_annot. This value applies to
 * all visible elements of @poppler_annot in its closed state,
 * but not to the pop-up window that appears when it's openened
 *
 * Since: 0.16
 */
void poppler_annot_markup_set_opacity(PopplerAnnotMarkup *poppler_annot, gdouble opacity)
{
    AnnotMarkup *annot;

    g_return_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot));

    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
    annot->setOpacity(opacity);
}

/**
 * poppler_annot_markup_get_date:
 * @poppler_annot: a #PopplerAnnotMarkup
 *
 * Returns the date and time when the annotation was created
 *
 * Return value: (transfer full): a #GDate representing the date and time
 *               when the annotation was created, or %NULL
 */
GDate *poppler_annot_markup_get_date(PopplerAnnotMarkup *poppler_annot)
{
    AnnotMarkup *annot;
    const GooString *annot_date;
    time_t timet;

    g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), NULL);

    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
    annot_date = annot->getDate();
    if (!annot_date) {
        return nullptr;
    }

    if (_poppler_convert_pdf_date_to_gtime(annot_date, &timet)) {
        GDate *date;

        date = g_date_new();
        g_date_set_time_t(date, timet);

        return date;
    }

    return nullptr;
}

/**
 * poppler_annot_markup_get_subject:
 * @poppler_annot: a #PopplerAnnotMarkup
 *
 * Retrives the subject text of @poppler_annot.
 *
 * Return value: the subject text of @poppler_annot.
 */
gchar *poppler_annot_markup_get_subject(PopplerAnnotMarkup *poppler_annot)
{
    AnnotMarkup *annot;
    const GooString *text;

    g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), NULL);

    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    text = annot->getSubject();

    return text ? _poppler_goo_string_to_utf8(text) : nullptr;
}

/**
 * poppler_annot_markup_get_reply_to:
 * @poppler_annot: a #PopplerAnnotMarkup
 *
 * Gets the reply type of @poppler_annot.
 *
 * Return value: #PopplerAnnotMarkupReplyType of @poppler_annot.
 */
PopplerAnnotMarkupReplyType poppler_annot_markup_get_reply_to(PopplerAnnotMarkup *poppler_annot)
{
    AnnotMarkup *annot;

    g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), POPPLER_ANNOT_MARKUP_REPLY_TYPE_R);

    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    switch (annot->getReplyTo()) {
    case AnnotMarkup::replyTypeR:
        return POPPLER_ANNOT_MARKUP_REPLY_TYPE_R;
    case AnnotMarkup::replyTypeGroup:
        return POPPLER_ANNOT_MARKUP_REPLY_TYPE_GROUP;
    default:
        g_warning("Unsupported Annot Markup Reply To Type");
    }

    return POPPLER_ANNOT_MARKUP_REPLY_TYPE_R;
}

/**
 * poppler_annot_markup_get_external_data:
 * @poppler_annot: a #PopplerAnnotMarkup
 *
 * Gets the external data type of @poppler_annot.
 *
 * Return value: #PopplerAnnotExternalDataType of @poppler_annot.
 */
PopplerAnnotExternalDataType poppler_annot_markup_get_external_data(PopplerAnnotMarkup *poppler_annot)
{
    AnnotMarkup *annot;

    g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), POPPLER_ANNOT_EXTERNAL_DATA_MARKUP_UNKNOWN);

    annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    switch (annot->getExData()) {
    case annotExternalDataMarkup3D:
        return POPPLER_ANNOT_EXTERNAL_DATA_MARKUP_3D;
    case annotExternalDataMarkupUnknown:
        return POPPLER_ANNOT_EXTERNAL_DATA_MARKUP_UNKNOWN;
    default:
        g_warning("Unsupported Annot Markup External Data");
    }

    return POPPLER_ANNOT_EXTERNAL_DATA_MARKUP_UNKNOWN;
}

/* PopplerAnnotText */
/**
 * poppler_annot_text_get_is_open:
 * @poppler_annot: a #PopplerAnnotText
 *
 * Retrieves the state of @poppler_annot.
 *
 * Return value: the state of @poppler_annot. %TRUE if it's open, %FALSE in
 *               other case.
 **/
gboolean poppler_annot_text_get_is_open(PopplerAnnotText *poppler_annot)
{
    AnnotText *annot;

    g_return_val_if_fail(POPPLER_IS_ANNOT_TEXT(poppler_annot), FALSE);

    annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    return annot->getOpen();
}

/**
 * poppler_annot_text_set_is_open:
 * @poppler_annot: a #PopplerAnnotText
 * @is_open: whether annotation should initially be displayed open
 *
 * Sets whether @poppler_annot should initially be displayed open
 *
 * Since: 0.16
 */
void poppler_annot_text_set_is_open(PopplerAnnotText *poppler_annot, gboolean is_open)
{
    AnnotText *annot;

    g_return_if_fail(POPPLER_IS_ANNOT_TEXT(poppler_annot));

    annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot.get());
    annot->setOpen(is_open);
}

/**
 * poppler_annot_text_get_icon:
 * @poppler_annot: a #PopplerAnnotText
 *
 * Gets name of the icon of @poppler_annot.
 *
 * Return value: a new allocated string containing the icon name
 */
gchar *poppler_annot_text_get_icon(PopplerAnnotText *poppler_annot)
{
    AnnotText *annot;

    g_return_val_if_fail(POPPLER_IS_ANNOT_TEXT(poppler_annot), NULL);

    annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    const std::string &text = annot->getIcon();

    return text.empty() ? nullptr : g_strdup(text.c_str());
}

/**
 * poppler_annot_text_set_icon:
 * @poppler_annot: a #PopplerAnnotText
 * @icon: the name of an icon
 *
 * Sets the icon of @poppler_annot. The following predefined
 * icons are currently supported:
 * <variablelist>
 *  <varlistentry>
 *   <term>#POPPLER_ANNOT_TEXT_ICON_NOTE</term>
 *  </varlistentry>
 *  <varlistentry>
 *   <term>#POPPLER_ANNOT_TEXT_ICON_COMMENT</term>
 *  </varlistentry>
 *  <varlistentry>
 *   <term>#POPPLER_ANNOT_TEXT_ICON_KEY</term>
 *  </varlistentry>
 *  <varlistentry>
 *   <term>#POPPLER_ANNOT_TEXT_ICON_HELP</term>
 *  </varlistentry>
 *  <varlistentry>
 *   <term>#POPPLER_ANNOT_TEXT_ICON_NEW_PARAGRAPH</term>
 *  </varlistentry>
 *  <varlistentry>
 *   <term>#POPPLER_ANNOT_TEXT_ICON_PARAGRAPH</term>
 *  </varlistentry>
 *  <varlistentry>
 *   <term>#POPPLER_ANNOT_TEXT_ICON_INSERT</term>
 *  </varlistentry>
 *  <varlistentry>
 *   <term>#POPPLER_ANNOT_TEXT_ICON_CROSS</term>
 *  </varlistentry>
 *  <varlistentry>
 *   <term>#POPPLER_ANNOT_TEXT_ICON_CIRCLE</term>
 *  </varlistentry>
 * </variablelist>
 *
 * Since: 0.16
 */
void poppler_annot_text_set_icon(PopplerAnnotText *poppler_annot, const gchar *icon)
{
    AnnotText *annot;

    g_return_if_fail(POPPLER_IS_ANNOT_TEXT(poppler_annot));

    annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    std::string text = icon ? std::string { icon } : std::string {};
    annot->setIcon(text);
}

/**
 * poppler_annot_text_get_state:
 * @poppler_annot: a #PopplerAnnotText
 *
 * Retrieves the state of @poppler_annot.
 *
 * Return value: #PopplerAnnotTextState of @poppler_annot.
 **/
PopplerAnnotTextState poppler_annot_text_get_state(PopplerAnnotText *poppler_annot)
{
    AnnotText *annot;

    g_return_val_if_fail(POPPLER_IS_ANNOT_TEXT(poppler_annot), POPPLER_ANNOT_TEXT_STATE_UNKNOWN);

    annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    switch (annot->getState()) {
    case AnnotText::stateUnknown:
        return POPPLER_ANNOT_TEXT_STATE_UNKNOWN;
    case AnnotText::stateMarked:
        return POPPLER_ANNOT_TEXT_STATE_MARKED;
    case AnnotText::stateUnmarked:
        return POPPLER_ANNOT_TEXT_STATE_UNMARKED;
    case AnnotText::stateAccepted:
        return POPPLER_ANNOT_TEXT_STATE_ACCEPTED;
    case AnnotText::stateRejected:
        return POPPLER_ANNOT_TEXT_STATE_REJECTED;
    case AnnotText::stateCancelled:
        return POPPLER_ANNOT_TEXT_STATE_CANCELLED;
    case AnnotText::stateCompleted:
        return POPPLER_ANNOT_TEXT_STATE_COMPLETED;
    case AnnotText::stateNone:
        return POPPLER_ANNOT_TEXT_STATE_NONE;
    default:
        g_warning("Unsupported Annot Text State");
    }

    return POPPLER_ANNOT_TEXT_STATE_UNKNOWN;
}

/* PopplerAnnotTextMarkup */
/**
 * poppler_annot_text_markup_set_quadrilaterals:
 * @poppler_annot: A #PopplerAnnotTextMarkup
 * @quadrilaterals: (element-type PopplerQuadrilateral): A #GArray of
 *   #PopplerQuadrilateral<!-- -->s
 *
 * Set the regions (Quadrilaterals) to apply the text markup in @poppler_annot.
 *
 * Since: 0.26
 **/
void poppler_annot_text_markup_set_quadrilaterals(PopplerAnnotTextMarkup *poppler_annot, GArray *quadrilaterals)
{
    AnnotQuadrilaterals *quads, *quads_temp;
    AnnotTextMarkup *annot;
    const PDFRectangle *crop_box;
    Page *page = nullptr;

    g_return_if_fail(POPPLER_IS_ANNOT_TEXT_MARKUP(poppler_annot));
    g_return_if_fail(quadrilaterals != nullptr && quadrilaterals->len > 0);

    annot = static_cast<AnnotTextMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
    crop_box = _poppler_annot_get_cropbox_and_page(POPPLER_ANNOT(poppler_annot), &page);
    quads = create_annot_quads_from_poppler_quads(quadrilaterals);

    if (page && SUPPORTED_ROTATION(page->getRotate())) {
        quads_temp = _page_new_quads_unrotated(page, quads);
        delete quads;
        quads = quads_temp;
    }

    if (!ZERO_CROPBOX(crop_box)) {
        quads_temp = quads;
        quads = new_quads_from_offset_cropbox(crop_box, quads, TRUE);
        delete quads_temp;
    }

    annot->setQuadrilaterals(*quads);
    delete quads;
}

/**
 * poppler_annot_text_markup_get_quadrilaterals:
 * @poppler_annot: A #PopplerAnnotTextMarkup
 *
 * Returns a #GArray of #PopplerQuadrilateral items that map from a
 * location on @page to a #PopplerAnnotTextMarkup.  This array must be freed
 * when done.
 *
 * Return value: (element-type PopplerQuadrilateral) (transfer full): A #GArray of #PopplerQuadrilateral
 *
 * Since: 0.26
 **/
GArray *poppler_annot_text_markup_get_quadrilaterals(PopplerAnnotTextMarkup *poppler_annot)
{
    const PDFRectangle *crop_box;
    AnnotTextMarkup *annot;

    g_return_val_if_fail(POPPLER_IS_ANNOT_TEXT_MARKUP(poppler_annot), NULL);

    annot = static_cast<AnnotTextMarkup *>(POPPLER_ANNOT(poppler_annot)->annot.get());
    crop_box = _poppler_annot_get_cropbox(POPPLER_ANNOT(poppler_annot));
    AnnotQuadrilaterals *quads = annot->getQuadrilaterals();

    return create_poppler_quads_from_annot_quads(quads, crop_box);
}

/* PopplerAnnotFreeText */
/**
 * poppler_annot_free_text_get_quadding:
 * @poppler_annot: a #PopplerAnnotFreeText
 *
 * Retrieves the justification of the text of @poppler_annot.
 *
 * Return value: #PopplerAnnotFreeTextQuadding of @poppler_annot.
 **/
PopplerAnnotFreeTextQuadding poppler_annot_free_text_get_quadding(PopplerAnnotFreeText *poppler_annot)
{
    AnnotFreeText *annot;

    g_return_val_if_fail(POPPLER_IS_ANNOT_FREE_TEXT(poppler_annot), POPPLER_ANNOT_FREE_TEXT_QUADDING_LEFT_JUSTIFIED);

    annot = static_cast<AnnotFreeText *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    switch (annot->getQuadding()) {
    case VariableTextQuadding::leftJustified:
        return POPPLER_ANNOT_FREE_TEXT_QUADDING_LEFT_JUSTIFIED;
    case VariableTextQuadding::centered:
        return POPPLER_ANNOT_FREE_TEXT_QUADDING_CENTERED;
    case VariableTextQuadding::rightJustified:
        return POPPLER_ANNOT_FREE_TEXT_QUADDING_RIGHT_JUSTIFIED;
    default:
        g_warning("Unsupported Annot Free Text Quadding");
    }

    return POPPLER_ANNOT_FREE_TEXT_QUADDING_LEFT_JUSTIFIED;
}

/**
 * poppler_annot_free_text_get_callout_line:
 * @poppler_annot: a #PopplerAnnotFreeText
 *
 * Retrieves a #PopplerAnnotCalloutLine of four or six numbers specifying a callout
 * line attached to the @poppler_annot.
 *
 * Return value: a new allocated #PopplerAnnotCalloutLine if the annot has a callout
 *               line, %NULL in other case. It must be freed with g_free() when
 *               done.
 **/
PopplerAnnotCalloutLine *poppler_annot_free_text_get_callout_line(PopplerAnnotFreeText *poppler_annot)
{
    AnnotFreeText *annot;
    AnnotCalloutLine *line;

    g_return_val_if_fail(POPPLER_IS_ANNOT_FREE_TEXT(poppler_annot), NULL);

    annot = static_cast<AnnotFreeText *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    if ((line = annot->getCalloutLine())) {
        AnnotCalloutMultiLine *multiline;
        PopplerAnnotCalloutLine *callout = g_new0(PopplerAnnotCalloutLine, 1);

        callout->x1 = line->getX1();
        callout->y1 = line->getY1();
        callout->x2 = line->getX2();
        callout->y2 = line->getY2();

        if ((multiline = dynamic_cast<AnnotCalloutMultiLine *>(line))) {
            callout->multiline = TRUE;
            callout->x3 = multiline->getX3();
            callout->y3 = multiline->getY3();
            return callout;
        }

        callout->multiline = FALSE;
        return callout;
    }

    return nullptr;
}

static std::string poppler_font_description_to_style(PopplerFontDescription *font_desc)
{
    std::string style;
    std::function<void(const char *)> add_style = [&style](const char *a) {
        if (strcmp(a, "") != 0) {
            if (!style.empty()) {
                style += " ";
            }
            style += a;
        }
    };

    /* Stretch */
    add_style(stretch_to_str[font_desc->stretch]);

    /* Don't use a map so that intermediate pango weights are correctly mapped */
    PopplerWeight w = font_desc->weight;
    if (w <= POPPLER_WEIGHT_THIN) {
        add_style("Thin");
    } else if (w <= POPPLER_WEIGHT_ULTRALIGHT) {
        add_style("UltraLight");
    } else if (w <= POPPLER_WEIGHT_LIGHT) {
        add_style("Light");
    } else if (w <= POPPLER_WEIGHT_NORMAL) {
        add_style("");
    } else if (w <= POPPLER_WEIGHT_MEDIUM) {
        add_style("Medium");
    } else if (w <= POPPLER_WEIGHT_SEMIBOLD) {
        add_style("SemiBold");
    } else if (w <= POPPLER_WEIGHT_BOLD) {
        add_style("Bold");
    } else if (w <= POPPLER_WEIGHT_ULTRABOLD) {
        add_style("UltraBold");
    } else {
        add_style("Heavy");
    }

    /* Style, i.e. italic, oblique or normal */
    if (font_desc->style == POPPLER_STYLE_ITALIC) {
        add_style("Italic");
    } else if (font_desc->style == POPPLER_STYLE_OBLIQUE) {
        add_style("Oblique");
    }

    return style;
}

static void poppler_annot_free_text_set_da_to_native(PopplerAnnotFreeText *poppler_annot)
{
    Annot *annot = POPPLER_ANNOT(poppler_annot)->annot.get();

    std::string font_name = "Sans";
    double size = 11.;

    if (poppler_annot->font_desc) {
        const char *family = poppler_annot->font_desc->font_name;
        const std::string style = poppler_font_description_to_style(poppler_annot->font_desc);

        Form *form = annot->getDoc()->getCatalog()->getCreateForm();
        if (form) {
            font_name = form->findFontInDefaultResources(family, style);
            if (font_name.empty()) {
                font_name = form->addFontToDefaultResources(family, style).fontName;
            }

            if (!font_name.empty()) {
                form->ensureFontsForAllCharacters(annot->getContents(), font_name);
            }
        }
        size = poppler_annot->font_desc->size_pt;
    }

    DefaultAppearance da { { objName, font_name.c_str() }, size, _poppler_convert_poppler_color_to_annot_color(&(poppler_annot->font_color)) };
    ((AnnotFreeText *)annot)->setDefaultAppearance(da);
}

/**
 * poppler_annot_free_text_set_font_desc:
 * @poppler_annot: a #PopplerAnnotFreeText
 * @font_desc: a #PopplerFontDescription
 *
 * Sets the font description (i.e. font family name, style, weight, stretch and size).
 *
 * Since: 24.12.0
 **/
void poppler_annot_free_text_set_font_desc(PopplerAnnotFreeText *poppler_annot, PopplerFontDescription *font_desc)
{
    if (poppler_annot->font_desc) {
        poppler_font_description_free(poppler_annot->font_desc);
    }
    poppler_annot->font_desc = poppler_font_description_copy(font_desc);
    poppler_annot_free_text_set_da_to_native(poppler_annot);
}

/**
 * poppler_annot_free_text_get_font_desc:
 * @poppler_annot: a #PopplerAnnotFreeText
 *
 * Gets the font description (i.e. font family name, style, weight, stretch and size).
 *
 * Returns: (nullable) (transfer full): a copy of the annotation font description, or NULL if there is
 * no font description set.
 *
 * Since: 24.12.0
 **/
PopplerFontDescription *poppler_annot_free_text_get_font_desc(PopplerAnnotFreeText *poppler_annot)
{
    if (poppler_annot->font_desc) {
        return poppler_font_description_copy(poppler_annot->font_desc);
    }
    return nullptr;
}

/**
 * poppler_annot_free_text_set_font_color:
 * @poppler_annot: a #PopplerAnnotFreeText
 * @color: a #PopplerColor
 *
 * Sets the font color.
 *
 * Since: 24.12.0
 **/
void poppler_annot_free_text_set_font_color(PopplerAnnotFreeText *poppler_annot, PopplerColor *color)
{
    poppler_annot->font_color = *color;
    poppler_annot_free_text_set_da_to_native(poppler_annot);
}

/**
 * poppler_annot_free_text_get_font_color:
 * @poppler_annot: a #PopplerAnnotFreeText
 *
 * Gets the font color.
 *
 * Returns: (transfer full): a copy of the font's #PopplerColor.
 *
 * Since: 24.12.0
 **/
PopplerColor *poppler_annot_free_text_get_font_color(PopplerAnnotFreeText *poppler_annot)
{
    PopplerColor *color = g_new(PopplerColor, 1);
    *color = poppler_annot->font_color;
    return color;
}

/* PopplerAnnotFileAttachment */
/**
 * poppler_annot_file_attachment_get_attachment:
 * @poppler_annot: a #PopplerAnnotFileAttachment
 *
 * Creates a #PopplerAttachment for the file of the file attachment annotation @annot.
 * The #PopplerAttachment must be unrefed with g_object_unref by the caller.
 *
 * Return value: (transfer full): @PopplerAttachment
 *
 * Since: 0.14
 **/
PopplerAttachment *poppler_annot_file_attachment_get_attachment(PopplerAnnotFileAttachment *poppler_annot)
{
    AnnotFileAttachment *annot;
    PopplerAttachment *attachment;

    g_return_val_if_fail(POPPLER_IS_ANNOT_FILE_ATTACHMENT(poppler_annot), NULL);

    annot = static_cast<AnnotFileAttachment *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    FileSpec file { annot->getFile() };
    attachment = _poppler_attachment_new(&file);

    return attachment;
}

/**
 * poppler_annot_file_attachment_get_name:
 * @poppler_annot: a #PopplerAnnotFileAttachment
 *
 * Retrieves the name of @poppler_annot.
 *
 * Return value: a new allocated string with the name of @poppler_annot. It must
 *               be freed with g_free() when done.
 * Since: 0.14
 **/
gchar *poppler_annot_file_attachment_get_name(PopplerAnnotFileAttachment *poppler_annot)
{
    AnnotFileAttachment *annot;
    const GooString *name;

    g_return_val_if_fail(POPPLER_IS_ANNOT_FILE_ATTACHMENT(poppler_annot), NULL);

    annot = static_cast<AnnotFileAttachment *>(POPPLER_ANNOT(poppler_annot)->annot.get());
    name = annot->getName();

    return name ? _poppler_goo_string_to_utf8(name) : nullptr;
}

/* PopplerAnnotCalloutLine */
G_DEFINE_BOXED_TYPE(PopplerAnnotCalloutLine, poppler_annot_callout_line, poppler_annot_callout_line_copy, poppler_annot_callout_line_free)

/**
 * poppler_annot_callout_line_new:
 *
 * Creates a new empty #PopplerAnnotCalloutLine.
 *
 * Return value: a new allocated #PopplerAnnotCalloutLine, %NULL in other case.
 *               It must be freed when done.
 **/
PopplerAnnotCalloutLine *poppler_annot_callout_line_new(void)
{
    return g_new0(PopplerAnnotCalloutLine, 1);
}

/**
 * poppler_annot_callout_line_copy:
 * @callout: the #PopplerAnnotCalloutLine to be copied.
 *
 * It does copy @callout to a new #PopplerAnnotCalloutLine.
 *
 * Return value: a new allocated #PopplerAnnotCalloutLine as exact copy of
 *               @callout, %NULL in other case. It must be freed when done.
 **/
PopplerAnnotCalloutLine *poppler_annot_callout_line_copy(PopplerAnnotCalloutLine *callout)
{
    PopplerAnnotCalloutLine *new_callout;

    g_return_val_if_fail(callout != nullptr, NULL);

    new_callout = g_new0(PopplerAnnotCalloutLine, 1);
    *new_callout = *callout;

    return new_callout;
}

/**
 * poppler_annot_callout_line_free:
 * @callout: a #PopplerAnnotCalloutLine
 *
 * Frees the memory used by #PopplerAnnotCalloutLine.
 **/
void poppler_annot_callout_line_free(PopplerAnnotCalloutLine *callout)
{
    g_free(callout);
}

/* PopplerAnnotMovie */
/**
 * poppler_annot_movie_get_title:
 * @poppler_annot: a #PopplerAnnotMovie
 *
 * Retrieves the movie title of @poppler_annot.
 *
 * Return value: the title text of @poppler_annot.
 *
 * Since: 0.14
 */
gchar *poppler_annot_movie_get_title(PopplerAnnotMovie *poppler_annot)
{
    AnnotMovie *annot;
    const GooString *title;

    g_return_val_if_fail(POPPLER_IS_ANNOT_MOVIE(poppler_annot), NULL);

    annot = static_cast<AnnotMovie *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    title = annot->getTitle();

    return title ? _poppler_goo_string_to_utf8(title) : nullptr;
}

/**
 * poppler_annot_movie_get_movie:
 * @poppler_annot: a #PopplerAnnotMovie
 *
 * Retrieves the movie object (PopplerMovie) stored in the @poppler_annot.
 *
 * Return value: (transfer none): the movie object stored in the @poppler_annot. The returned
 *               object is owned by #PopplerAnnotMovie and should not be freed
 *
 * Since: 0.14
 */
PopplerMovie *poppler_annot_movie_get_movie(PopplerAnnotMovie *poppler_annot)
{
    return poppler_annot->movie;
}

/* PopplerAnnotScreen */
/**
 * poppler_annot_screen_get_action:
 * @poppler_annot: a #PopplerAnnotScreen
 *
 * Retrieves the action (#PopplerAction) that shall be performed when @poppler_annot is activated
 *
 * Return value: (transfer none): the action to perform. The returned
 *               object is owned by @poppler_annot and should not be freed
 *
 * Since: 0.14
 */
PopplerAction *poppler_annot_screen_get_action(PopplerAnnotScreen *poppler_annot)
{
    return poppler_annot->action;
}

/* PopplerAnnotLine */
/**
 * poppler_annot_line_set_vertices:
 * @poppler_annot: a #PopplerAnnotLine
 * @start: a #PopplerPoint of the starting vertice
 * @end: a #PopplerPoint of the ending vertice
 *
 * Set the coordinate points where the @poppler_annot starts and ends.
 *
 * Since: 0.26
 */
void poppler_annot_line_set_vertices(PopplerAnnotLine *poppler_annot, PopplerPoint *start, PopplerPoint *end)
{
    AnnotLine *annot;

    g_return_if_fail(POPPLER_IS_ANNOT_LINE(poppler_annot));
    g_return_if_fail(start != nullptr);
    g_return_if_fail(end != nullptr);

    annot = static_cast<AnnotLine *>(POPPLER_ANNOT(poppler_annot)->annot.get());
    annot->setVertices(start->x, start->y, end->x, end->y);
}

/* PopplerAnnotCircle and PopplerAnnotSquare helpers */
static PopplerColor *poppler_annot_geometry_get_interior_color(PopplerAnnot *poppler_annot)
{
    AnnotGeometry *annot;

    annot = static_cast<AnnotGeometry *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    return _poppler_convert_annot_color_to_poppler_color(annot->getInteriorColor());
}

static void poppler_annot_geometry_set_interior_color(PopplerAnnot *poppler_annot, PopplerColor *poppler_color)
{
    AnnotGeometry *annot;

    annot = static_cast<AnnotGeometry *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    annot->setInteriorColor(_poppler_convert_poppler_color_to_annot_color(poppler_color));
}

/* PopplerAnnotCircle */
/**
 * poppler_annot_circle_get_interior_color:
 * @poppler_annot: a #PopplerAnnotCircle
 *
 * Retrieves the interior color of @poppler_annot.
 *
 * Return value: a new allocated #PopplerColor with the color values of
 *               @poppler_annot, or %NULL. It must be freed with g_free() when done.
 *
 * Since: 0.26
 */
PopplerColor *poppler_annot_circle_get_interior_color(PopplerAnnotCircle *poppler_annot)
{
    g_return_val_if_fail(POPPLER_IS_ANNOT_CIRCLE(poppler_annot), NULL);

    return poppler_annot_geometry_get_interior_color(POPPLER_ANNOT(poppler_annot));
}

/**
 * poppler_annot_circle_set_interior_color:
 * @poppler_annot: a #PopplerAnnotCircle
 * @poppler_color: (allow-none): a #PopplerColor, or %NULL
 *
 * Sets the interior color of @poppler_annot.
 *
 * Since: 0.26
 */
void poppler_annot_circle_set_interior_color(PopplerAnnotCircle *poppler_annot, PopplerColor *poppler_color)
{
    g_return_if_fail(POPPLER_IS_ANNOT_CIRCLE(poppler_annot));

    poppler_annot_geometry_set_interior_color(POPPLER_ANNOT(poppler_annot), poppler_color);
}

/* PopplerAnnotSquare */
/**
 * poppler_annot_square_get_interior_color:
 * @poppler_annot: a #PopplerAnnotSquare
 *
 * Retrieves the interior color of @poppler_annot.
 *
 * Return value: a new allocated #PopplerColor with the color values of
 *               @poppler_annot, or %NULL. It must be freed with g_free() when done.
 *
 * Since: 0.26
 */
PopplerColor *poppler_annot_square_get_interior_color(PopplerAnnotSquare *poppler_annot)
{
    g_return_val_if_fail(POPPLER_IS_ANNOT_SQUARE(poppler_annot), NULL);

    return poppler_annot_geometry_get_interior_color(POPPLER_ANNOT(poppler_annot));
}

/**
 * poppler_annot_square_set_interior_color:
 * @poppler_annot: a #PopplerAnnotSquare
 * @poppler_color: (allow-none): a #PopplerColor, or %NULL
 *
 * Sets the interior color of @poppler_annot.
 *
 * Since: 0.26
 */
void poppler_annot_square_set_interior_color(PopplerAnnotSquare *poppler_annot, PopplerColor *poppler_color)
{
    g_return_if_fail(POPPLER_IS_ANNOT_SQUARE(poppler_annot));

    poppler_annot_geometry_set_interior_color(POPPLER_ANNOT(poppler_annot), poppler_color);
}

/**
 * poppler_annot_stamp_get_icon:
 * @poppler_annot: a #PopplerAnnotStamp
 *
 * Return value: the corresponding #PopplerAnnotStampIcon of the icon
 *
 * Since: 22.07.0
 */
PopplerAnnotStampIcon poppler_annot_stamp_get_icon(PopplerAnnotStamp *poppler_annot)
{
    AnnotStamp *annot;

    g_return_val_if_fail(POPPLER_IS_ANNOT_STAMP(poppler_annot), POPPLER_ANNOT_STAMP_ICON_UNKNOWN);

    annot = static_cast<AnnotStamp *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    std::string text = annot->getIcon();

    if (text.empty()) {
        return POPPLER_ANNOT_STAMP_ICON_NONE;
    }

    if (text == "Approved") {
        return POPPLER_ANNOT_STAMP_ICON_APPROVED;
    } else if (text == "AsIs") {
        return POPPLER_ANNOT_STAMP_ICON_AS_IS;
    } else if (text == "Confidential") {
        return POPPLER_ANNOT_STAMP_ICON_CONFIDENTIAL;
    } else if (text == "Final") {
        return POPPLER_ANNOT_STAMP_ICON_FINAL;
    } else if (text == "Experimental") {
        return POPPLER_ANNOT_STAMP_ICON_EXPERIMENTAL;
    } else if (text == "Expired") {
        return POPPLER_ANNOT_STAMP_ICON_EXPIRED;
    } else if (text == "NotApproved") {
        return POPPLER_ANNOT_STAMP_ICON_NOT_APPROVED;
    } else if (text == "NotForPublicRelease") {
        return POPPLER_ANNOT_STAMP_ICON_NOT_FOR_PUBLIC_RELEASE;
    } else if (text == "Sold") {
        return POPPLER_ANNOT_STAMP_ICON_SOLD;
    } else if (text == "Departmental") {
        return POPPLER_ANNOT_STAMP_ICON_DEPARTMENTAL;
    } else if (text == "ForComment") {
        return POPPLER_ANNOT_STAMP_ICON_FOR_COMMENT;
    } else if (text == "ForPublicRelease") {
        return POPPLER_ANNOT_STAMP_ICON_FOR_PUBLIC_RELEASE;
    } else if (text == "TopSecret") {
        return POPPLER_ANNOT_STAMP_ICON_TOP_SECRET;
    }

    return POPPLER_ANNOT_STAMP_ICON_UNKNOWN;
}

/**
 * poppler_annot_stamp_set_icon:
 * @poppler_annot: a #PopplerAnnotStamp
 * @icon: the #PopplerAnnotStampIcon type of the icon
 *
 * Sets the icon of @poppler_annot to be one of the predefined values in #PopplerAnnotStampIcon
 *
 * Since: 22.07.0
 */
void poppler_annot_stamp_set_icon(PopplerAnnotStamp *poppler_annot, PopplerAnnotStampIcon icon)
{
    AnnotStamp *annot;
    const gchar *text;

    g_return_if_fail(POPPLER_IS_ANNOT_STAMP(poppler_annot));

    annot = static_cast<AnnotStamp *>(POPPLER_ANNOT(poppler_annot)->annot.get());

    if (icon == POPPLER_ANNOT_STAMP_ICON_NONE) {
        annot->setIcon(std::string {});
        return;
    }

    if (icon == POPPLER_ANNOT_STAMP_ICON_APPROVED) {
        text = "Approved";
    } else if (icon == POPPLER_ANNOT_STAMP_ICON_AS_IS) {
        text = "AsIs";
    } else if (icon == POPPLER_ANNOT_STAMP_ICON_CONFIDENTIAL) {
        text = "Confidential";
    } else if (icon == POPPLER_ANNOT_STAMP_ICON_FINAL) {
        text = "Final";
    } else if (icon == POPPLER_ANNOT_STAMP_ICON_EXPERIMENTAL) {
        text = "Experimental";
    } else if (icon == POPPLER_ANNOT_STAMP_ICON_EXPIRED) {
        text = "Expired";
    } else if (icon == POPPLER_ANNOT_STAMP_ICON_NOT_APPROVED) {
        text = "NotApproved";
    } else if (icon == POPPLER_ANNOT_STAMP_ICON_NOT_FOR_PUBLIC_RELEASE) {
        text = "NotForPublicRelease";
    } else if (icon == POPPLER_ANNOT_STAMP_ICON_SOLD) {
        text = "Sold";
    } else if (icon == POPPLER_ANNOT_STAMP_ICON_DEPARTMENTAL) {
        text = "Departmental";
    } else if (icon == POPPLER_ANNOT_STAMP_ICON_FOR_COMMENT) {
        text = "ForComment";
    } else if (icon == POPPLER_ANNOT_STAMP_ICON_FOR_PUBLIC_RELEASE) {
        text = "ForPublicRelease";
    } else if (icon == POPPLER_ANNOT_STAMP_ICON_TOP_SECRET) {
        text = "TopSecret";
    } else {
        return; /* POPPLER_ANNOT_STAMP_ICON_UNKNOWN */
    }

    annot->setIcon(std::string { text });
}

/**
 * poppler_annot_stamp_set_custom_image:
 * @poppler_annot: a #PopplerAnnotStamp
 * @image: an image cairo surface
 * @error: (nullable): return location for error, or %NULL.
 *
 * Sets the custom image of @poppler_annot to be @image
 *
 * Return value: %TRUE on success, %FALSE otherwise.
 *
 * Since: 22.07.0
 */
gboolean poppler_annot_stamp_set_custom_image(PopplerAnnotStamp *poppler_annot, cairo_surface_t *image, GError **error)
{
    AnnotStamp *annot;

    g_return_val_if_fail(POPPLER_IS_ANNOT_STAMP(poppler_annot), FALSE);

    annot = static_cast<AnnotStamp *>(POPPLER_ANNOT(poppler_annot)->annot.get());
    std::unique_ptr<AnnotStampImageHelper> annot_image_helper = _poppler_convert_cairo_image_to_stamp_image_helper(image, annot->getDoc(), error);
    if (!annot_image_helper) {
        return FALSE;
    }
    annot->setCustomImage(std::move(annot_image_helper));

    return TRUE;
}

/**
 * poppler_annot_get_border_width:
 * @poppler_annot: a #PopplerAnnot
 * @width: a valid pointer to a double
 *
 * Returns the border width of the annotation. Some PDF editors set a border
 * width even if the border is not actually drawn.
 *
 * Returns: true and sets @border_width to the actual border width if a border
 * is defined, otherwise returns false and sets @border_width to 0.
 *
 * Since: 24.12.0
 */
gboolean poppler_annot_get_border_width(PopplerAnnot *poppler_annot, double *width)
{
    AnnotBorder *b = poppler_annot->annot->getBorder();
    if (b) {
        *width = b->getWidth();
        return TRUE;
    } else {
        *width = 0.;
        return FALSE;
    }
}
/**
 * poppler_annot_set_border_width:
 * @poppler_annot: a #PopplerAnnot
 * @width: the new border width
 *
 * Sets the border width of the annotation. Since there is currently no
 * mechanism in the GLib binding to control the appearance of the border width,
 * this should generally only be used to disable the border, although the
 * API might be completed in the future.
 *
 * Since: 24.12.0
 */
void poppler_annot_set_border_width(PopplerAnnot *poppler_annot, double width)
{
    std::unique_ptr<AnnotBorderArray> border = std::make_unique<AnnotBorderArray>();
    border->setWidth(width);
    poppler_annot->annot->setBorder(std::move(border));
}

/**
 * SECTION:poppler-font-description
 * @short_description: FontDescription
 * @title: PopplerFontDescription
 */

/* PopplerFontDescription type */
G_DEFINE_BOXED_TYPE(PopplerFontDescription, poppler_font_description, poppler_font_description_copy, poppler_font_description_free)

/**
 * poppler_font_description_new:
 * @font_name: the family name of the font
 *
 * Creates a new #PopplerFontDescriptions
 *
 * Returns: a new #PopplerFontDescription, use poppler_font_description_free() to free it
 */
PopplerFontDescription *poppler_font_description_new(const char *font_name)
{
    PopplerFontDescription *font_desc = (PopplerFontDescription *)g_new0(PopplerFontDescription, 1);
    font_desc->font_name = g_strdup(font_name);
    font_desc->size_pt = 11.;
    font_desc->stretch = POPPLER_STRETCH_NORMAL;
    font_desc->style = POPPLER_STYLE_NORMAL;
    font_desc->weight = POPPLER_WEIGHT_NORMAL;
    return font_desc;
}

/**
 * poppler_font_description_free:
 * @font_desc: a #PopplerFontDescription
 *
 * Frees the given #PopplerFontDescription
 */
void poppler_font_description_free(PopplerFontDescription *font_desc)
{
    g_free(font_desc->font_name);
    g_free(font_desc);
}

/**
 * poppler_font_description_copy:
 * @font_desc: a #PopplerFontDescription to copy
 *
 * Creates a copy of @font_desc
 *
 * Returns: a new allocated copy of @font_desc
 */
PopplerFontDescription *poppler_font_description_copy(PopplerFontDescription *font_desc)
{
    PopplerFontDescription *new_font_desc;

    new_font_desc = g_new(PopplerFontDescription, 1);
    *new_font_desc = *font_desc;

    new_font_desc->font_name = g_strdup(font_desc->font_name);

    return new_font_desc;
}

/**
 * SECTION:poppler-path
 * @short_description: Path
 * @title: PopplerPath
 */
G_DEFINE_BOXED_TYPE(PopplerPath, poppler_path, poppler_path_copy, poppler_path_free)

/**
 * poppler_path_new_from_list:
 * @points: (element-type PopplerPoint) (array length=n_points) (transfer full): a #GSList of #PopplerPoint
 *
 * Creates a new #PopplerPath from a list of points.
 *
 * Returns: a new #PopplerPath containing the given points.
 *
 * Since: 25.06.0
 */
PopplerPath *poppler_path_new_from_array(PopplerPoint *points, gsize n_points)
{
    PopplerPath *path = (PopplerPath *)g_new(PopplerPath, 1);
    path->points = points;
    path->n_points = n_points;
    return path;
}

/**
 * poppler_path_free:
 * @path: a #PopplerPath
 *
 * Frees the given #PopplerPath.
 *
 * Since: 25.06.0
 */
void poppler_path_free(PopplerPath *path)
{
    g_free(path->points);
    g_free(path);
}

/**
 * poppler_path_copy:
 * @path: a #PopplerPath to copy
 *
 * Creates a copy of @path.
 *
 * Returns: a new allocated copy of @path
 *
 * Since: 25.06.0
 */
PopplerPath *poppler_path_copy(PopplerPath *path)
{
    PopplerPath *new_path;

    new_path = g_new(PopplerPath, 1);
    new_path->points = g_new(PopplerPoint, path->n_points);
    new_path->n_points = path->n_points;
    memcpy(new_path->points, path->points, sizeof(PopplerPoint) * path->n_points);

    return new_path;
}

/**
 * poppler_path_get_points:
 * @path: a #PopplerPath
 * @n_points: to store the length of the returned path
 *
 * Returns the array of points of @path.
 *
 * Returns: (array length=n_points) (transfer none): all the points of @path
 *
 * Since: 25.06.0
 */
PopplerPoint *poppler_path_get_points(PopplerPath *path, gsize *n_points)
{
    *n_points = path->n_points;
    return path->points;
}

static void poppler_annot_ink_class_init(PopplerAnnotInkClass *klass) { }

static void poppler_annot_ink_init(PopplerAnnotInk *annot) { }

/**
 * poppler_annot_ink_set_ink_list:
 * @annot: a #PopplerAnnotInk
 * @ink_list: (array length=n_paths) (transfer none): a list of #PopplerPath
 *
 * Each element of @ink_list is a path. The annotation must have
 * already been added to a page, otherwise the annotation may be
 * wrongly positioned if the page is rotated or has a cropbox.
 *
 * This function computes and set the appropriate smallest rectangle
 * area that contains all the points of @ink_list. Setting the rectangle
 * afterwards with #poppler_annot_set_rectangle should not be done
 * to preserve scaling and positioning.
 *
 * Since: 25.06.0
 */
void poppler_annot_ink_set_ink_list(PopplerAnnotInk *annot, PopplerPath **ink_list, gsize n_paths)
{
    double border_width;
    PopplerRectangle r = { G_MAXDOUBLE, G_MAXDOUBLE, 0, 0 };
    const PDFRectangle *crop_box;
    const PDFRectangle zerobox = PDFRectangle();
    Page *page = nullptr;
    AnnotInk *ink_annot = static_cast<AnnotInk *>(POPPLER_ANNOT(annot)->annot.get());
    std::vector<std::unique_ptr<AnnotPath>> paths;
    poppler_annot_get_border_width(POPPLER_ANNOT(annot), &border_width);

    crop_box = _poppler_annot_get_cropbox_and_page(POPPLER_ANNOT(annot), &page);
    if (!crop_box) {
        crop_box = &zerobox;
    }

    if (!page) {
        g_warning("An inklist of an ink annotation was set while the annotation was not"
                  " in a page, the computed coordinates may be wrong.");
    }

    for (gsize j = 0; j < n_paths; j++) {
        std::vector<AnnotCoord> coords;
        gsize n_points;
        PopplerPoint *points = poppler_path_get_points(ink_list[j], &n_points);

        for (gsize i = 0; i < n_points; i++) {
            PopplerPoint p = points[i];
            r.x1 = MIN(r.x1, p.x);
            r.y1 = MIN(r.y1, p.y);

            r.x2 = MAX(r.x2, p.x);
            r.y2 = MAX(r.y2, p.y);

            if (page) {
                _page_unrotate_xy(page, &p.x, &p.y);
            }
            p.x += crop_box->x1;
            p.y += crop_box->y1;
            coords.emplace_back(p.x, p.y);
        }
        paths.emplace_back(new AnnotPath(std::move(coords)));
    }

    r.x1 -= border_width;
    r.y1 -= border_width;
    r.x2 += border_width;
    r.y2 += border_width;
    poppler_annot_set_rectangle(POPPLER_ANNOT(annot), &r);
    ink_annot->setInkList(paths);
}

/**
 * poppler_annot_ink_get_ink_list:
 * @annot: a #PopplerAnnotInk
 * @n_paths: (out): to store the number of paths returned
 *
 * Each element of the return value is a path.
 *
 * Returns: (transfer full) (array length=n_paths): a GSList of PopplerPath
 *
 * Since: 25.06.0
 */
PopplerPath **poppler_annot_ink_get_ink_list(PopplerAnnotInk *annot, gsize *n_paths)
{
    PopplerPath **ink_list = nullptr;
    const PDFRectangle *crop_box;
    const PDFRectangle zerobox = PDFRectangle();
    Page *page = nullptr;
    int i = 0;

    AnnotInk *ink_annot = static_cast<AnnotInk *>(POPPLER_ANNOT(annot)->annot.get());
    const std::vector<std::unique_ptr<AnnotPath>> &paths = ink_annot->getInkList();

    *n_paths = paths.size();
    ink_list = g_new(PopplerPath *, paths.size());

    crop_box = _poppler_annot_get_cropbox_and_page(POPPLER_ANNOT(annot), &page);
    if (!crop_box) {
        crop_box = &zerobox;
    }

    for (const std::unique_ptr<AnnotPath> &path : paths) {
        PopplerPoint *points = g_new(PopplerPoint, path->getCoordsLength());

        for (int j = 0; j < path->getCoordsLength(); ++j) {
            points[j].x = path->getX(j) - crop_box->x1;
            points[j].y = path->getY(j) - crop_box->y1;
            if (page) {
                _page_rotate_xy(page, &points[j].x, &points[j].y);
            }
        }
        ink_list[i] = poppler_path_new_from_array(points, path->getCoordsLength());
        i++;
    }

    return ink_list;
}

/**
 * poppler_annot_ink_new:
 * @doc: a #PopplerDocument
 * @rect: a #PopplerRectangle
 *
 * Creates a new ink annotation that will be
 * located on @rect when added to a page. See
 * poppler_page_add_annot()
 *
 * Return value: A newly created #PopplerAnnotInk annotation
 *
 * Since: 25.06.0
 */
PopplerAnnot *poppler_annot_ink_new(PopplerDocument *doc, PopplerRectangle *rect)
{
    PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);

    auto annot = std::make_shared<AnnotInk>(doc->doc, &pdf_rect);

    return _poppler_annot_ink_new(annot);
}

PopplerAnnot *_poppler_annot_ink_new(const std::shared_ptr<Annot> &annot)
{
    PopplerAnnot *poppler_annot;

    poppler_annot = _poppler_create_annot(POPPLER_TYPE_ANNOT_INK, annot);

    return poppler_annot;
}
