[poppler] glib/CMakeLists.txt glib/demo glib/poppler-document.cc glib/poppler-document.h glib/poppler-form-field.cc glib/poppler-form-field.h glib/poppler.h glib/reference

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jun 29 20:18:42 UTC 2023


 glib/CMakeLists.txt                 |    6 
 glib/demo/CMakeLists.txt            |    1 
 glib/demo/main.c                    |    4 
 glib/demo/signature.c               |  437 ++++++++++++++
 glib/demo/signature.h               |   31 +
 glib/poppler-document.cc            |   98 +++
 glib/poppler-document.h             |    5 
 glib/poppler-form-field.cc          | 1088 ++++++++++++++++++++++++++++++++++++
 glib/poppler-form-field.h           |  114 +++
 glib/poppler.h                      |    5 
 glib/reference/poppler-sections.txt |   51 +
 glib/reference/poppler.types        |    2 
 12 files changed, 1840 insertions(+), 2 deletions(-)

New commits:
commit bdd922b7caaa965828e0e45a6cde0b1585c9740e
Author: Jan-Michael Brummer <jan.brummer at tabos.org>
Date:   Wed Oct 5 08:20:13 2022 +0200

    Signatures: Add signing API to glib part
    
    Rectangle corrections by Marek Kasik

diff --git a/glib/CMakeLists.txt b/glib/CMakeLists.txt
index 52e8687a..4e17440c 100644
--- a/glib/CMakeLists.txt
+++ b/glib/CMakeLists.txt
@@ -99,6 +99,10 @@ target_link_libraries(poppler-glib poppler PkgConfig::GLIB2 ${CAIRO_LIBRARIES} F
 target_include_directories(poppler-glib SYSTEM PRIVATE ${CAIRO_INCLUDE_DIRS})
 install(TARGETS poppler-glib RUNTIME DESTINATION bin LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
 
+if (ENABLE_NSS3)
+    target_include_directories(poppler-glib SYSTEM PRIVATE ${NSS3_INCLUDE_DIRS})
+endif()
+
 install(FILES
   ${poppler_glib_public_headers}
   ${CMAKE_CURRENT_BINARY_DIR}/poppler-enums.h
@@ -150,3 +154,5 @@ endif ()
 if(ENABLE_GTK_DOC)
   add_subdirectory(reference)
 endif()
+
+check_function_exists(explicit_bzero HAVE_EXPLICIT_BZERO)
\ No newline at end of file
diff --git a/glib/demo/CMakeLists.txt b/glib/demo/CMakeLists.txt
index 4c1ae9a5..1520d840 100644
--- a/glib/demo/CMakeLists.txt
+++ b/glib/demo/CMakeLists.txt
@@ -18,6 +18,7 @@ set(poppler_glib_demo_SRCS
   layers.c
   selections.c
   taggedstruct.c
+  signature.c
 )
 poppler_add_test(poppler-glib-demo BUILD_GTK_TESTS ${poppler_glib_demo_SRCS})
 
diff --git a/glib/demo/main.c b/glib/demo/main.c
index e7fdea13..9b95b3ed 100644
--- a/glib/demo/main.c
+++ b/glib/demo/main.c
@@ -38,6 +38,7 @@
 #include "find.h"
 #include "print.h"
 #include "selections.h"
+#include "signature.h"
 
 enum
 {
@@ -69,7 +70,8 @@ static const PopplerGlibDemo demo_list[] = { { "Info", pgd_info_create_widget },
                                              { "Text", pgd_text_create_widget },
                                              { "Tagged Structure", pgd_taggedstruct_create_widget },
                                              { "Find", pgd_find_create_widget },
-                                             { "Print", pgd_print_create_widget } };
+                                             { "Print", pgd_print_create_widget },
+                                             { "Signature", pgd_signature_create_widget } };
 
 static void pgd_demo_changed(GtkTreeSelection *selection, GtkNotebook *notebook)
 {
diff --git a/glib/demo/signature.c b/glib/demo/signature.c
new file mode 100644
index 00000000..15c68c5a
--- /dev/null
+++ b/glib/demo/signature.c
@@ -0,0 +1,437 @@
+/*
+ * Copyright (C) 2022-2023 Jan-Michael Brummer <jan.brummer at tabos.org>
+ *
+ * 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 <gtk/gtk.h>
+#include <string.h>
+
+#include "signature.h"
+#include "utils.h"
+
+typedef struct
+{
+    PopplerDocument *doc;
+    PopplerPage *page;
+    GtkWidget *darea;
+    cairo_surface_t *surface;
+    gint num_page;
+    gint redraw_idle;
+    GdkPoint start;
+    GdkPoint stop;
+    gboolean started;
+    GdkCursorType cursor;
+    GtkWidget *main_box;
+    gdouble scale;
+} PgdSignatureDemo;
+
+/* Render area */
+static cairo_surface_t *pgd_signature_render_page(PgdSignatureDemo *demo)
+{
+    cairo_t *cr;
+    PopplerPage *page;
+    gdouble width, height;
+    cairo_surface_t *surface = NULL;
+
+    page = poppler_document_get_page(demo->doc, demo->num_page);
+    if (!page) {
+        return NULL;
+    }
+
+    poppler_page_get_size(page, &width, &height);
+
+    width *= demo->scale;
+    height *= demo->scale;
+    gtk_widget_set_size_request(demo->darea, width, height);
+
+    surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
+    cr = cairo_create(surface);
+
+    if (demo->scale != 1.0) {
+        cairo_scale(cr, demo->scale, demo->scale);
+    }
+
+    cairo_save(cr);
+    cairo_set_source_rgb(cr, 1, 1, 1);
+
+    cairo_rectangle(cr, 0, 0, width, height);
+    cairo_fill(cr);
+    cairo_restore(cr);
+
+    cairo_save(cr);
+    poppler_page_render(page, cr);
+    cairo_restore(cr);
+
+    cairo_destroy(cr);
+    g_object_unref(page);
+
+    return surface;
+}
+
+static void draw_selection_rect(PgdSignatureDemo *demo, cairo_t *cr)
+{
+    gint pos_x1, pos_x2, pos_y1, pos_y2;
+    gint x, y, w, h;
+
+    pos_x1 = demo->start.x;
+    pos_y1 = demo->start.y;
+    pos_x2 = demo->stop.x;
+    pos_y2 = demo->stop.y;
+
+    x = MIN(pos_x1, pos_x2);
+    y = MIN(pos_y1, pos_y2);
+    w = ABS(pos_x1 - pos_x2);
+    h = ABS(pos_y1 - pos_y2);
+
+    if (w <= 0 || h <= 0) {
+        return;
+    }
+
+    cairo_save(cr);
+
+    cairo_rectangle(cr, x + 1, y + 1, w - 2, h - 2);
+    cairo_set_source_rgba(cr, 0.2, 0.6, 0.8, 0.2);
+    cairo_fill(cr);
+
+    cairo_rectangle(cr, x + 0.5, y + 0.5, w - 1, h - 1);
+    cairo_set_source_rgba(cr, 0.2, 0.6, 0.8, 0.35);
+    cairo_set_line_width(cr, 1);
+    cairo_stroke(cr);
+
+    cairo_restore(cr);
+}
+
+static gboolean pgd_signature_view_drawing_area_draw(GtkWidget *area, cairo_t *cr, PgdSignatureDemo *demo)
+{
+    if (demo->num_page == -1) {
+        return FALSE;
+    }
+
+    if (!demo->surface) {
+        demo->surface = pgd_signature_render_page(demo);
+        if (!demo->surface) {
+            return FALSE;
+        }
+    }
+
+    cairo_set_source_surface(cr, demo->surface, 0, 0);
+    cairo_paint(cr);
+
+    if (demo->started) {
+        draw_selection_rect(demo, cr);
+    }
+
+    return TRUE;
+}
+
+static gboolean pgd_signature_viewer_redraw(PgdSignatureDemo *demo)
+{
+    cairo_surface_destroy(demo->surface);
+    demo->surface = NULL;
+
+    gtk_widget_queue_draw(demo->darea);
+
+    demo->redraw_idle = 0;
+
+    return FALSE;
+}
+
+static void pgd_signature_viewer_queue_redraw(PgdSignatureDemo *demo)
+{
+    if (demo->redraw_idle == 0) {
+        demo->redraw_idle = g_idle_add((GSourceFunc)pgd_signature_viewer_redraw, demo);
+    }
+}
+
+static void pgd_signature_page_selector_value_changed(GtkSpinButton *spinbutton, PgdSignatureDemo *demo)
+{
+    demo->num_page = (gint)gtk_spin_button_get_value(spinbutton) - 1;
+    pgd_signature_viewer_queue_redraw(demo);
+
+    demo->page = poppler_document_get_page(demo->doc, demo->num_page);
+}
+
+static void pgd_signature_drawing_area_realize(GtkWidget *area, PgdSignatureDemo *demo)
+{
+    gtk_widget_add_events(area, GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+}
+
+char *password_callback(const char *in)
+{
+    GtkWidget *dialog;
+    GtkWidget *box;
+    GtkWidget *entry;
+    char *ret;
+
+    dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, "Enter password");
+    gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "Enter password to open: %s", in);
+    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
+
+    box = gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(dialog));
+    entry = gtk_entry_new();
+    gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
+    gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
+    gtk_box_pack_end(GTK_BOX(box), entry, TRUE, TRUE, 6);
+    gtk_widget_show_all(box);
+
+    gtk_dialog_run(GTK_DIALOG(dialog));
+    ret = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
+    gtk_widget_destroy(dialog);
+
+    return ret;
+}
+
+static void pgd_signature_update_cursor(PgdSignatureDemo *demo, GdkCursorType cursor_type)
+{
+    GdkCursor *cursor = NULL;
+
+    if (cursor_type == demo->cursor) {
+        return;
+    }
+
+    if (cursor_type != GDK_LAST_CURSOR) {
+        cursor = gdk_cursor_new_for_display(gtk_widget_get_display(demo->main_box), cursor_type);
+    }
+
+    demo->cursor = cursor_type;
+
+    gdk_window_set_cursor(gtk_widget_get_window(demo->main_box), cursor);
+    gdk_display_flush(gtk_widget_get_display(demo->main_box));
+    if (cursor) {
+        g_object_unref(cursor);
+    }
+}
+
+static void pgd_signature_start_signing(GtkWidget *button, PgdSignatureDemo *demo)
+{
+    demo->start.x = 0;
+    demo->start.y = 0;
+    demo->stop.x = 0;
+    demo->stop.y = 0;
+    demo->started = TRUE;
+    pgd_signature_update_cursor(demo, GDK_TCROSS);
+}
+
+static gboolean pgd_signature_drawing_area_button_press(GtkWidget *area, GdkEventButton *event, PgdSignatureDemo *demo)
+{
+    if (!demo->page || event->button != 1 || !demo->started) {
+        return FALSE;
+    }
+
+    demo->start.x = event->x;
+    demo->start.y = event->y;
+    demo->stop = demo->start;
+
+    pgd_signature_viewer_queue_redraw(demo);
+
+    return TRUE;
+}
+
+static gboolean pgd_signature_drawing_area_motion_notify(GtkWidget *area, GdkEventMotion *event, PgdSignatureDemo *demo)
+{
+    gdouble width, height;
+
+    if (!demo->page || demo->start.x == -1 || !demo->started) {
+        return FALSE;
+    }
+
+    demo->stop.x = event->x;
+    demo->stop.y = event->y;
+
+    poppler_page_get_size(demo->page, &width, &height);
+    width *= demo->scale;
+    height *= demo->scale;
+
+    /* Keep the drawing within the page */
+    demo->stop.x = CLAMP(demo->stop.x, 0, width);
+    demo->stop.y = CLAMP(demo->stop.y, 0, height);
+
+    pgd_signature_viewer_queue_redraw(demo);
+
+    return TRUE;
+}
+
+static void on_signing_done(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+    PopplerDocument *document = POPPLER_DOCUMENT(source);
+    g_autoptr(GError) error = NULL;
+    gboolean ret = poppler_document_sign_finish(document, result, &error);
+
+    g_print("%s: result %d\n", __FUNCTION__, ret);
+    if (error) {
+        g_print("Error: %s", error->message);
+    }
+}
+
+static gboolean pgd_signature_drawing_area_button_release(GtkWidget *area, GdkEventButton *event, PgdSignatureDemo *demo)
+{
+    if (!demo->page || event->button != 1 || !demo->started) {
+        return FALSE;
+    }
+
+    demo->started = FALSE;
+    pgd_signature_update_cursor(demo, GDK_LAST_CURSOR);
+
+    /* poppler_certificate_set_nss_dir ("./glib/demo/cert"); */
+    poppler_set_nss_password_callback(password_callback);
+    GList *available_certificates = poppler_get_available_signing_certificates();
+
+    if (available_certificates) {
+        g_autofree char *signature = NULL;
+        g_autofree char *signature_left = NULL;
+        PopplerSigningData *data = poppler_signing_data_new();
+        PopplerRectangle rect;
+        PopplerCertificateInfo *certificate_info;
+        time_t t;
+        double width, height;
+
+        certificate_info = available_certificates->data;
+        time(&t);
+
+        poppler_signing_data_set_certificate_info(data, certificate_info);
+        poppler_signing_data_set_page(data, demo->num_page);
+        poppler_signing_data_set_field_partial_name(data, g_uuid_string_random());
+        poppler_signing_data_set_destination_filename(data, "test.pdf");
+        poppler_signing_data_set_reason(data, "I'm the author");
+        poppler_signing_data_set_location(data, "At my desk");
+
+        poppler_page_get_size(demo->page, &width, &height);
+
+        rect.x1 = demo->start.x > demo->stop.x ? demo->stop.x : demo->start.x;
+        rect.y1 = demo->start.y > demo->stop.y ? demo->stop.y : demo->start.y;
+        rect.x2 = demo->start.x > demo->stop.x ? demo->start.x : demo->stop.x;
+        rect.y2 = demo->start.y > demo->stop.y ? demo->start.y : demo->stop.y;
+
+        /* Adjust scale */
+        rect.x1 /= demo->scale;
+        rect.y1 /= demo->scale;
+        rect.x2 /= demo->scale;
+        rect.y2 /= demo->scale;
+
+        rect.y1 = height - rect.y1;
+        rect.y2 = height - rect.y2;
+
+        poppler_signing_data_set_signature_rectangle(data, &rect);
+
+        signature = g_strdup_printf("Digitally signed by %s\nDate: %s", poppler_certificate_info_get_subject_common_name(certificate_info), ctime(&t));
+        poppler_signing_data_set_signature_text(data, signature);
+
+        signature_left = g_strdup_printf("%s", poppler_certificate_info_get_subject_common_name(certificate_info));
+        poppler_signing_data_set_signature_text_left(data, signature_left);
+
+        poppler_document_sign(demo->doc, data, NULL, on_signing_done, NULL);
+    }
+
+    return TRUE;
+}
+
+static void pgd_signature_scale_selector_value_changed(GtkSpinButton *spinbutton, PgdSignatureDemo *demo)
+{
+    demo->scale = gtk_spin_button_get_value(spinbutton);
+    pgd_signature_viewer_queue_redraw(demo);
+}
+
+/* Main UI */
+GtkWidget *pgd_signature_create_widget(PopplerDocument *document)
+{
+    PgdSignatureDemo *demo;
+    GtkWidget *label;
+    GtkWidget *vbox;
+    GtkWidget *button;
+    GtkWidget *hbox, *page_selector;
+    GtkWidget *scale_hbox, *scale_selector;
+    GtkWidget *swindow;
+    gchar *str;
+    gint n_pages;
+
+    demo = g_new0(PgdSignatureDemo, 1);
+    demo->cursor = GDK_LAST_CURSOR;
+    demo->doc = g_object_ref(document);
+    demo->scale = 1.0;
+
+    n_pages = poppler_document_get_n_pages(document);
+
+    vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12);
+
+    hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
+
+    label = gtk_label_new("Page:");
+    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
+    gtk_widget_show(label);
+
+    page_selector = gtk_spin_button_new_with_range(1, n_pages, 1);
+    g_signal_connect(G_OBJECT(page_selector), "value-changed", G_CALLBACK(pgd_signature_page_selector_value_changed), (gpointer)demo);
+    gtk_box_pack_start(GTK_BOX(hbox), page_selector, FALSE, TRUE, 0);
+    gtk_widget_show(page_selector);
+
+    str = g_strdup_printf("of %d", n_pages);
+    label = gtk_label_new(str);
+    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
+    gtk_widget_show(label);
+    g_free(str);
+
+    scale_hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
+
+    label = gtk_label_new("Scale:");
+    gtk_box_pack_start(GTK_BOX(scale_hbox), label, TRUE, TRUE, 0);
+    gtk_widget_show(label);
+
+    scale_selector = gtk_spin_button_new_with_range(0, 10.0, 0.1);
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(scale_selector), 1.0);
+    g_signal_connect(G_OBJECT(scale_selector), "value-changed", G_CALLBACK(pgd_signature_scale_selector_value_changed), (gpointer)demo);
+    gtk_box_pack_start(GTK_BOX(scale_hbox), scale_selector, TRUE, TRUE, 0);
+    gtk_widget_show(scale_selector);
+
+    gtk_box_pack_start(GTK_BOX(hbox), scale_hbox, FALSE, TRUE, 0);
+    gtk_widget_show(scale_hbox);
+
+    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
+
+    button = gtk_button_new_with_mnemonic("_Sign");
+    g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(pgd_signature_start_signing), (gpointer)demo);
+    gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0);
+    gtk_widget_show(button);
+
+    gtk_widget_show(hbox);
+
+    /* Demo Area (Render) */
+    demo->darea = gtk_drawing_area_new();
+    g_signal_connect(demo->darea, "draw", G_CALLBACK(pgd_signature_view_drawing_area_draw), demo);
+    g_signal_connect(demo->darea, "realize", G_CALLBACK(pgd_signature_drawing_area_realize), (gpointer)demo);
+    g_signal_connect(demo->darea, "button_press_event", G_CALLBACK(pgd_signature_drawing_area_button_press), (gpointer)demo);
+    g_signal_connect(demo->darea, "motion_notify_event", G_CALLBACK(pgd_signature_drawing_area_motion_notify), (gpointer)demo);
+    g_signal_connect(demo->darea, "button_release_event", G_CALLBACK(pgd_signature_drawing_area_button_release), (gpointer)demo);
+
+    swindow = gtk_scrolled_window_new(NULL, NULL);
+#if GTK_CHECK_VERSION(3, 7, 8)
+    gtk_container_add(GTK_CONTAINER(swindow), demo->darea);
+#else
+    gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swindow), demo->darea);
+#endif
+    gtk_widget_show(demo->darea);
+
+    gtk_widget_show(swindow);
+
+    gtk_box_pack_start(GTK_BOX(vbox), swindow, TRUE, TRUE, 0);
+
+    demo->main_box = vbox;
+
+    demo->num_page = 0;
+    demo->page = poppler_document_get_page(demo->doc, demo->num_page);
+    pgd_signature_viewer_queue_redraw(demo);
+
+    return vbox;
+}
diff --git a/glib/demo/signature.h b/glib/demo/signature.h
new file mode 100644
index 00000000..cbdf7f43
--- /dev/null
+++ b/glib/demo/signature.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 Jan-Michael Brummer <jan.brummer at tabos.org>
+ *
+ * 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 <gtk/gtk.h>
+#include <poppler.h>
+
+#ifndef _SIGNATURE_H_
+#    define _SIGNATURE_H_
+
+G_BEGIN_DECLS
+
+GtkWidget *pgd_signature_create_widget(PopplerDocument *document);
+
+G_END_DECLS
+
+#endif /* _SIGNATURE_H_ */
diff --git a/glib/poppler-document.cc b/glib/poppler-document.cc
index 7505a6fe..4092e51d 100644
--- a/glib/poppler-document.cc
+++ b/glib/poppler-document.cc
@@ -56,6 +56,7 @@
 #    include <PDFDocEncoding.h>
 #    include <OptionalContent.h>
 #    include <ViewerPreferences.h>
+#    include "UTF.h"
 #endif
 
 #include "poppler.h"
@@ -3814,3 +3815,100 @@ GooString *_poppler_convert_date_time_to_pdf_date(GDateTime *datetime)
     g_free(date_str);
     return out_str.release();
 }
+
+static void _poppler_sign_document_thread(GTask *task, PopplerDocument *document, const PopplerSigningData *signing_data, GCancellable *cancellable)
+{
+    const PopplerCertificateInfo *certificate_info;
+    const char *signing_data_signature_text;
+    const PopplerColor *font_color;
+    const PopplerColor *border_color;
+    const PopplerColor *background_color;
+    gboolean ret;
+
+    g_return_if_fail(POPPLER_IS_DOCUMENT(document));
+    g_return_if_fail(signing_data != nullptr);
+
+    signing_data_signature_text = poppler_signing_data_get_signature_text(signing_data);
+    if (signing_data_signature_text == nullptr) {
+        g_task_return_new_error(task, POPPLER_ERROR, POPPLER_ERROR_SIGNING, "No signature given");
+        return;
+    }
+
+    certificate_info = poppler_signing_data_get_certificate_info(signing_data);
+    if (certificate_info == nullptr) {
+        g_task_return_new_error(task, POPPLER_ERROR, POPPLER_ERROR_SIGNING, "Invalid certificate information provided for signing");
+        return;
+    }
+
+    PopplerPage *page = poppler_document_get_page(document, poppler_signing_data_get_page(signing_data));
+    if (page == nullptr) {
+        g_task_return_new_error(task, POPPLER_ERROR, POPPLER_ERROR_SIGNING, "Invalid page number selected for signing");
+        return;
+    }
+
+    font_color = poppler_signing_data_get_font_color(signing_data);
+    border_color = poppler_signing_data_get_border_color(signing_data);
+    background_color = poppler_signing_data_get_background_color(signing_data);
+
+    std::unique_ptr<GooString> signature_text = std::unique_ptr<GooString>(utf8ToUtf16WithBom(signing_data_signature_text));
+    std::unique_ptr<GooString> signature_text_left = std::unique_ptr<GooString>(utf8ToUtf16WithBom(poppler_signing_data_get_signature_text_left(signing_data)));
+    const auto field_partial_name = new GooString(poppler_signing_data_get_field_partial_name(signing_data), strlen(poppler_signing_data_get_field_partial_name(signing_data)));
+    const auto owner_pwd = std::optional<GooString>(poppler_signing_data_get_document_owner_password(signing_data));
+    const auto user_pwd = std::optional<GooString>(poppler_signing_data_get_document_user_password(signing_data));
+    const auto reason = std::unique_ptr<GooString>(poppler_signing_data_get_reason(signing_data) ? new GooString(poppler_signing_data_get_reason(signing_data), strlen(poppler_signing_data_get_reason(signing_data))) : nullptr);
+    const auto location = std::unique_ptr<GooString>(poppler_signing_data_get_location(signing_data) ? new GooString(poppler_signing_data_get_location(signing_data), strlen(poppler_signing_data_get_location(signing_data))) : nullptr);
+    const PopplerRectangle *rect = poppler_signing_data_get_signature_rectangle(signing_data);
+
+    ret = document->doc->sign(poppler_signing_data_get_destination_filename(signing_data), poppler_certificate_info_get_id((PopplerCertificateInfo *)certificate_info),
+                              poppler_signing_data_get_password(signing_data) ? poppler_signing_data_get_password(signing_data) : "", field_partial_name, poppler_signing_data_get_page(signing_data) + 1,
+                              PDFRectangle(rect->x1, rect->y1, rect->x2, rect->y2), *signature_text, *signature_text_left, poppler_signing_data_get_font_size(signing_data), poppler_signing_data_get_left_font_size(signing_data),
+                              std::make_unique<AnnotColor>(font_color->red, font_color->green, font_color->blue), poppler_signing_data_get_border_width(signing_data),
+                              std::make_unique<AnnotColor>(border_color->red, border_color->green, border_color->blue), std::make_unique<AnnotColor>(background_color->red, background_color->green, background_color->blue), reason.get(),
+                              location.get(), poppler_signing_data_get_image_path(signing_data) ? poppler_signing_data_get_image_path(signing_data) : "", owner_pwd, user_pwd);
+
+    g_task_return_boolean(task, ret);
+}
+
+/**
+ * poppler_document_sign:
+ * @document: a #PopplerDocument
+ * @signing_data: a #PopplerSigningData
+ * @cancellable: a #GCancellable
+ * @callback: a #GAsyncReadyCallback
+ * @user_data: user data used by callback function
+ *
+ * Sign #document using #signing_data.
+ *
+ * Since: 23.07.0
+ **/
+void poppler_document_sign(PopplerDocument *document, const PopplerSigningData *signing_data, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
+{
+    g_autoptr(GTask) task = nullptr;
+
+    g_return_if_fail(POPPLER_IS_DOCUMENT(document));
+    g_return_if_fail(signing_data != nullptr);
+
+    task = g_task_new(document, cancellable, callback, user_data);
+    g_task_set_task_data(task, (void *)signing_data, nullptr);
+
+    g_task_run_in_thread(task, (GTaskThreadFunc)_poppler_sign_document_thread);
+}
+
+/**
+ * poppler_document_sign_finish:
+ * @document: a #PopplerDocument
+ * @result: a #GAsyncResult
+ * @error: a #GError
+ *
+ * Finish poppler_sign_document and get return status or error.
+ *
+ * Returns: %TRUE on successful signing a document, otherwise %FALSE and error is set.
+ *
+ * Since: 23.07.0
+ **/
+gboolean poppler_document_sign_finish(PopplerDocument *document, GAsyncResult *result, GError **error)
+{
+    g_return_val_if_fail(g_task_is_valid(result, document), FALSE);
+
+    return g_task_propagate_boolean(G_TASK(result), error);
+}
diff --git a/glib/poppler-document.h b/glib/poppler-document.h
index 3dabfa2f..a793e08b 100644
--- a/glib/poppler-document.h
+++ b/glib/poppler-document.h
@@ -521,6 +521,11 @@ void poppler_ps_file_set_duplex(PopplerPSFile *ps_file, gboolean duplex);
 POPPLER_PUBLIC
 void poppler_ps_file_free(PopplerPSFile *ps_file);
 
+POPPLER_PUBLIC
+void poppler_document_sign(PopplerDocument *document, const PopplerSigningData *signing_data, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+POPPLER_PUBLIC
+gboolean poppler_document_sign_finish(PopplerDocument *document, GAsyncResult *result, GError **error);
+
 /**
  * PopplerPageRange:
  * @start_page: first page in the range of pages
diff --git a/glib/poppler-form-field.cc b/glib/poppler-form-field.cc
index 5ff189a0..d2206288 100644
--- a/glib/poppler-form-field.cc
+++ b/glib/poppler-form-field.cc
@@ -27,6 +27,12 @@
 #include "poppler.h"
 #include "poppler-private.h"
 
+#include <CertificateInfo.h>
+#ifdef ENABLE_NSS3
+#    include <NSSCryptoSignBackend.h>
+#endif
+#include <CryptoSignBackend.h>
+
 /**
  * SECTION:poppler-form-field
  * @short_description: Form Field
@@ -1033,3 +1039,1085 @@ gchar *poppler_form_field_choice_get_text(PopplerFormField *field)
     tmp = static_cast<FormWidgetChoice *>(field->widget)->getEditChoice();
     return tmp ? _poppler_goo_string_to_utf8(tmp) : nullptr;
 }
+
+/* Signing Data */
+
+struct _PopplerSigningData
+{
+    char *destination_filename;
+    PopplerCertificateInfo *certificate_info;
+    int page;
+
+    char *signature_text;
+    char *signature_text_left;
+    PopplerRectangle signature_rect;
+
+    PopplerColor font_color;
+    gdouble font_size;
+    gdouble left_font_size;
+
+    PopplerColor border_color;
+    gdouble border_width;
+
+    PopplerColor background_color;
+
+    char *field_partial_name;
+    char *reason;
+    char *location;
+    char *image_path;
+    char *password;
+    char *document_owner_password;
+    char *document_user_password;
+};
+
+typedef struct _PopplerSigningData PopplerSigningData;
+
+G_DEFINE_BOXED_TYPE(PopplerSigningData, poppler_signing_data, poppler_signing_data_copy, poppler_signing_data_free)
+
+/**
+ * poppler_signing_data_new:
+ *
+ * Creates a new #PopplerSigningData with default content.
+ *
+ * Return value: a new #PopplerSigningData. It must be freed with poppler_signing_data_free() when done.
+ *
+ * Since: 23.07.0
+ **/
+PopplerSigningData *poppler_signing_data_new(void)
+{
+    PopplerSigningData *data = (PopplerSigningData *)g_malloc0(sizeof(PopplerSigningData));
+
+    data->password = g_strdup("");
+    data->page = 0;
+
+    data->font_size = 10.0;
+    data->left_font_size = 20.0;
+    data->border_width = 1.5;
+
+    /* Grey background */
+    auto background_color = PopplerColor();
+    background_color.red = 0xEF;
+    background_color.green = 0xEF;
+    background_color.blue = 0xEF;
+    poppler_signing_data_set_background_color(data, &background_color);
+
+    /* Red border color */
+    auto border_color = PopplerColor();
+    border_color.red = 0xFF;
+    border_color.green = 0x00;
+    border_color.blue = 0x00;
+    poppler_signing_data_set_border_color(data, &border_color);
+
+    /* Red font color */
+    auto font_color = PopplerColor();
+    font_color.red = 0xFF;
+    font_color.green = 0x00;
+    border_color.blue = 0x00;
+    poppler_signing_data_set_font_color(data, &font_color);
+
+    return data;
+}
+
+/**
+ * poppler_signing_data_copy:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Copies @signing_data, creating an identical #PopplerSigningData.
+ *
+ * Return value: (transfer full): a new #PopplerSigningData structure identical to @signing_data
+ *
+ * Since: 23.07.0
+ **/
+PopplerSigningData *poppler_signing_data_copy(const PopplerSigningData *signing_data)
+{
+    PopplerSigningData *data;
+
+    g_return_val_if_fail(signing_data != nullptr, nullptr);
+
+    data = (PopplerSigningData *)g_malloc0(sizeof(PopplerSigningData));
+    data->destination_filename = g_strdup(signing_data->destination_filename);
+    data->certificate_info = poppler_certificate_info_copy(signing_data->certificate_info);
+    data->page = signing_data->page;
+
+    data->signature_text = g_strdup(signing_data->signature_text);
+    data->signature_text_left = g_strdup(signing_data->signature_text_left);
+    memcpy(&data->signature_rect, &signing_data->signature_rect, sizeof(PopplerRectangle));
+
+    memcpy(&data->font_color, &signing_data->font_color, sizeof(PopplerColor));
+    data->font_size = signing_data->font_size;
+    data->left_font_size = signing_data->left_font_size;
+
+    memcpy(&data->border_color, &signing_data->border_color, sizeof(PopplerColor));
+    data->border_width = signing_data->border_width;
+
+    memcpy(&data->background_color, &signing_data->background_color, sizeof(PopplerColor));
+
+    data->field_partial_name = g_strdup(signing_data->field_partial_name);
+    data->reason = g_strdup(signing_data->reason);
+    data->location = g_strdup(signing_data->location);
+    data->image_path = g_strdup(signing_data->image_path);
+    data->password = g_strdup(signing_data->password);
+    data->document_owner_password = g_strdup(signing_data->document_owner_password);
+    data->document_user_password = g_strdup(signing_data->document_user_password);
+
+    return data;
+}
+
+/**
+ * poppler_signing_data_free:
+ * @signing_data: (nullable): a #PopplerSigningData structure containing signing data
+ *
+ * Frees @signing_data
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_free(PopplerSigningData *signing_data)
+{
+    if (!signing_data) {
+        return;
+    }
+
+    g_clear_pointer(&signing_data->destination_filename, g_free);
+    g_clear_pointer(&signing_data->certificate_info, poppler_certificate_info_free);
+    g_clear_pointer(&signing_data->signature_text, g_free);
+    g_clear_pointer(&signing_data->signature_text_left, g_free);
+    g_clear_pointer(&signing_data->field_partial_name, g_free);
+    g_clear_pointer(&signing_data->reason, g_free);
+    g_clear_pointer(&signing_data->location, g_free);
+    g_clear_pointer(&signing_data->image_path, g_free);
+
+    if (signing_data->password) {
+#ifdef HAVE_EXPLICIT_BZERO
+        explicit_bzero(signing_data->password, strlen(signing_data->password));
+#else
+        memset(signing_data->password, 0, strlen(signing_data->password));
+#endif
+        g_clear_pointer(&signing_data->password, g_free);
+    }
+
+    if (signing_data->document_owner_password) {
+#ifdef HAVE_EXPLICIT_BZERO
+        explicit_bzero(signing_data->document_owner_password, strlen(signing_data->document_owner_password));
+#else
+        memset(signing_data->document_owner_password, 0, strlen(signing_data->document_owner_password));
+#endif
+        g_clear_pointer(&signing_data->document_owner_password, g_free);
+    }
+
+    if (signing_data->document_user_password) {
+#ifdef HAVE_EXPLICIT_BZERO
+        explicit_bzero(signing_data->document_user_password, strlen(signing_data->document_user_password));
+#else
+        memset(signing_data->document_user_password, 0, strlen(signing_data->document_user_password));
+#endif
+        g_clear_pointer(&signing_data->document_user_password, g_free);
+    }
+
+    g_free(signing_data);
+}
+
+/**
+ * poppler_signing_data_set_destination_filename:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @filename: destination filename
+ *
+ * Set destination file name.
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_destination_filename(PopplerSigningData *signing_data, const gchar *filename)
+{
+    g_return_if_fail(signing_data != nullptr);
+    g_return_if_fail(filename != nullptr);
+
+    if (signing_data->destination_filename == filename) {
+        return;
+    }
+
+    g_clear_pointer(&signing_data->destination_filename, g_free);
+    signing_data->destination_filename = g_strdup(filename);
+}
+
+/**
+ * poppler_signing_data_get_destination_filename:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get destination file name.
+ *
+ * Return value: destination filename
+ *
+ * Since: 23.07.0
+ **/
+const gchar *poppler_signing_data_get_destination_filename(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, nullptr);
+
+    return signing_data->destination_filename;
+}
+
+/**
+ * poppler_signing_data_set_certificate_info:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @certificate_info: a #PopplerCertificateInfo
+ *
+ * Set certification information.
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_certificate_info(PopplerSigningData *signing_data, const PopplerCertificateInfo *certificate_info)
+{
+    g_return_if_fail(signing_data != nullptr);
+    g_return_if_fail(certificate_info != nullptr);
+
+    if (signing_data->certificate_info == certificate_info) {
+        return;
+    }
+
+    g_clear_pointer(&signing_data->certificate_info, poppler_certificate_info_free);
+    signing_data->certificate_info = poppler_certificate_info_copy(certificate_info);
+}
+
+/**
+ * poppler_signing_data_get_certificate_info:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get certification information.
+ *
+ * Return value: a #PopplerCertificateInfo
+ *
+ * Since: 23.07.0
+ **/
+const PopplerCertificateInfo *poppler_signing_data_get_certificate_info(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, nullptr);
+    return signing_data->certificate_info;
+}
+
+/**
+ * poppler_signing_data_set_page:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @page: a page number
+ *
+ * Set page (>=0).
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_page(PopplerSigningData *signing_data, int page)
+{
+    g_return_if_fail(signing_data != nullptr);
+
+    if (page < 0) {
+        return;
+    }
+
+    signing_data->page = page;
+}
+
+/**
+ * poppler_signing_data_get_page:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get page.
+ *
+ * Return value: page number
+ *
+ * Since: 23.07.0
+ **/
+int poppler_signing_data_get_page(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, 0);
+    return signing_data->page;
+}
+
+/**
+ * poppler_signing_data_set_signature_text:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @signature_text: text to show as main signature
+ *
+ * Set signature text.
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_signature_text(PopplerSigningData *signing_data, const gchar *signature_text)
+{
+    g_return_if_fail(signing_data != nullptr);
+    g_return_if_fail(signature_text != nullptr);
+
+    if (signing_data->signature_text == signature_text) {
+        return;
+    }
+
+    g_clear_pointer(&signing_data->signature_text, g_free);
+    signing_data->signature_text = g_strdup(signature_text);
+}
+
+/**
+ * poppler_signing_data_get_signature_text:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get signature text.
+ *
+ * Return value: signature text
+ *
+ * Since: 23.07.0
+ **/
+const gchar *poppler_signing_data_get_signature_text(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, nullptr);
+    return signing_data->signature_text;
+}
+
+/**
+ * poppler_signing_data_set_signature_text_left:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @signature_text_left: text to show as small left signature
+ *
+ * Set small signature text on the left hand.
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_signature_text_left(PopplerSigningData *signing_data, const gchar *signature_text_left)
+{
+    g_return_if_fail(signing_data != nullptr);
+    g_return_if_fail(signature_text_left != nullptr);
+
+    if (signing_data->signature_text_left == signature_text_left) {
+        return;
+    }
+
+    g_clear_pointer(&signing_data->signature_text_left, g_free);
+    signing_data->signature_text_left = g_strdup(signature_text_left);
+}
+
+/**
+ * poppler_signing_data_get_signature_text_left:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get signature text left.
+ *
+ * Return value: signature text left
+ *
+ * Since: 23.07.0
+ **/
+const gchar *poppler_signing_data_get_signature_text_left(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, nullptr);
+    return signing_data->signature_text_left;
+}
+
+/**
+ * poppler_signing_data_set_signature_rectangle:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @signature_rect: a #PopplerRectangle where signature should be shown
+ *
+ * Set signature rectangle.
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_signature_rectangle(PopplerSigningData *signing_data, const PopplerRectangle *signature_rect)
+{
+    g_return_if_fail(signing_data != nullptr);
+    g_return_if_fail(signature_rect != nullptr);
+
+    memcpy(&signing_data->signature_rect, signature_rect, sizeof(PopplerRectangle));
+}
+
+/**
+ * poppler_signing_data_get_signature_rectangle:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get signature rectangle.
+ *
+ * Return value: a #PopplerRectangle
+ *
+ * Since: 23.07.0
+ **/
+const PopplerRectangle *poppler_signing_data_get_signature_rectangle(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, nullptr);
+    return &signing_data->signature_rect;
+}
+
+/**
+ * poppler_signing_data_set_font_color:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @font_color: a #PopplerColor to be used as signature font color
+ *
+ * Set signature font color.
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_font_color(PopplerSigningData *signing_data, const PopplerColor *font_color)
+{
+    g_return_if_fail(signing_data != nullptr);
+    g_return_if_fail(font_color != nullptr);
+
+    memcpy(&signing_data->font_color, font_color, sizeof(PopplerColor));
+}
+
+/**
+ * poppler_signing_data_get_font_color:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get signature font color.
+ *
+ * Return value: a #PopplerColor
+ *
+ * Since: 23.07.0
+ **/
+const PopplerColor *poppler_signing_data_get_font_color(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, nullptr);
+    return &signing_data->font_color;
+}
+
+/**
+ * poppler_signing_data_set_font_size:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @font_size: signature font size
+ *
+ * Set signature font size (>0).
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_font_size(PopplerSigningData *signing_data, gdouble font_size)
+{
+    g_return_if_fail(signing_data != nullptr);
+
+    if (font_size <= 0) {
+        return;
+    }
+
+    signing_data->font_size = font_size;
+}
+
+/**
+ * poppler_signing_data_get_font_size:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get signature font size.
+ *
+ * Return value: font size
+ *
+ * Since: 23.07.0
+ **/
+gdouble poppler_signing_data_get_font_size(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, 20.0f);
+    return signing_data->font_size;
+}
+
+/**
+ * poppler_signing_data_set_left_font_size:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @font_size: signature font size
+ *
+ * Set signature left font size (> 0).
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_left_font_size(PopplerSigningData *signing_data, gdouble left_font_size)
+{
+    g_return_if_fail(signing_data != nullptr);
+
+    if (left_font_size <= 0) {
+        return;
+    }
+
+    signing_data->left_font_size = left_font_size;
+}
+
+/**
+ * poppler_signing_data_get_left_font_size:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get signature left font size.
+ *
+ * Return value: left font size
+ *
+ * Since: 23.07.0
+ **/
+gdouble poppler_signing_data_get_left_font_size(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, 12.0);
+    return signing_data->left_font_size;
+}
+
+/**
+ * poppler_signing_data_set_border_color:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @border_color: a #PopplerColor to be used for signature border
+ *
+ * Set signature border color.
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_border_color(PopplerSigningData *signing_data, const PopplerColor *border_color)
+{
+    g_return_if_fail(signing_data != nullptr);
+    g_return_if_fail(border_color != nullptr);
+
+    memcpy(&signing_data->border_color, border_color, sizeof(PopplerColor));
+}
+
+/**
+ * poppler_signing_data_get_border_color:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get signature border color.
+ *
+ * Return value: a #PopplerColor
+ *
+ * Since: 23.07.0
+ **/
+const PopplerColor *poppler_signing_data_get_border_color(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, nullptr);
+    return &signing_data->border_color;
+}
+
+/**
+ * poppler_signing_data_set_border_width:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @border_width: border width
+ *
+ * Set signature border width.
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_border_width(PopplerSigningData *signing_data, gdouble border_width)
+{
+    g_return_if_fail(signing_data != nullptr);
+
+    if (border_width < 0) {
+        return;
+    }
+
+    signing_data->border_width = border_width;
+}
+
+/**
+ * poppler_signing_data_get_border_width:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get signature border width.
+ *
+ * Return value: border width
+ *
+ * Since: 23.07.0
+ **/
+gdouble poppler_signing_data_get_border_width(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, 12);
+    return signing_data->border_width;
+}
+
+/**
+ * poppler_signing_data_set_background_color:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @background_color: a #PopplerColor to be used for signature background
+ *
+ * Set signature background color.
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_background_color(PopplerSigningData *signing_data, const PopplerColor *background_color)
+{
+    g_return_if_fail(signing_data != nullptr);
+    g_return_if_fail(background_color != nullptr);
+
+    memcpy(&signing_data->background_color, background_color, sizeof(PopplerColor));
+}
+
+/**
+ * poppler_signing_data_get_background_color:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get signature background color.
+ *
+ * Return value: a #PopplerColor
+ *
+ * Since: 23.07.0
+ **/
+const PopplerColor *poppler_signing_data_get_background_color(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, nullptr);
+    return &signing_data->background_color;
+}
+
+/**
+ * poppler_signing_data_set_field_partial_name:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @field_partial_name: a field partial name
+ *
+ * Set field partial name (existing field id or a new one) where signature is placed.
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_field_partial_name(PopplerSigningData *signing_data, const gchar *field_partial_name)
+{
+    g_return_if_fail(signing_data != nullptr);
+    g_return_if_fail(field_partial_name != nullptr);
+
+    g_clear_pointer(&signing_data->field_partial_name, g_free);
+    signing_data->field_partial_name = g_strdup(field_partial_name);
+}
+
+/**
+ * poppler_signing_data_get_field_partial_name:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get field partial name.
+ *
+ * Return value: field partial name
+ *
+ * Since: 23.07.0
+ **/
+const gchar *poppler_signing_data_get_field_partial_name(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, "");
+    return signing_data->field_partial_name;
+}
+
+/**
+ * poppler_signing_data_set_reason:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @reason: a reason
+ *
+ * Set reason for signature (e.g. I'm approver).
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_reason(PopplerSigningData *signing_data, const gchar *reason)
+{
+    g_return_if_fail(signing_data != nullptr);
+    g_return_if_fail(reason != nullptr);
+
+    if (signing_data->reason == reason) {
+        return;
+    }
+
+    g_clear_pointer(&signing_data->reason, g_free);
+    signing_data->reason = g_strdup(reason);
+}
+
+/**
+ * poppler_signing_data_get_reason:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get reason.
+ *
+ * Return value: reason
+ *
+ * Since: 23.07.0
+ **/
+const gchar *poppler_signing_data_get_reason(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, nullptr);
+    return signing_data->reason;
+}
+
+/**
+ * poppler_signing_data_set_location:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @location: a location
+ *
+ * Set signature location (e.g. "At my desk").
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_location(PopplerSigningData *signing_data, const gchar *location)
+{
+    g_return_if_fail(signing_data != nullptr);
+    g_return_if_fail(location != nullptr);
+
+    if (signing_data->location == location) {
+        return;
+    }
+
+    g_clear_pointer(&signing_data->location, g_free);
+    signing_data->location = g_strdup(location);
+}
+
+/**
+ * poppler_signing_data_get_location:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get location.
+ *
+ * Return value: location
+ *
+ * Since: 23.07.0
+ **/
+const gchar *poppler_signing_data_get_location(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, nullptr);
+    return signing_data->location;
+}
+
+/**
+ * poppler_signing_data_set_image_path:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @image_path: signature image path
+ *
+ * Set signature background (watermark) image path.
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_image_path(PopplerSigningData *signing_data, const gchar *image_path)
+{
+    g_return_if_fail(signing_data != nullptr);
+    g_return_if_fail(image_path != nullptr);
+
+    if (signing_data->image_path == image_path) {
+        return;
+    }
+
+    g_clear_pointer(&signing_data->image_path, g_free);
+    signing_data->image_path = g_strdup(image_path);
+}
+
+/**
+ * poppler_signing_data_get_image_path:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get image path.
+ *
+ * Return value: image path
+ *
+ * Since: 23.07.0
+ **/
+const gchar *poppler_signing_data_get_image_path(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, nullptr);
+    return signing_data->image_path;
+}
+
+/**
+ * poppler_signing_data_set_password:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @password: a password
+ *
+ * Set password for the signing key.
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_password(PopplerSigningData *signing_data, const gchar *password)
+{
+    g_return_if_fail(signing_data != nullptr);
+    g_return_if_fail(password != nullptr);
+
+    if (signing_data->password == password) {
+        return;
+    }
+
+    g_clear_pointer(&signing_data->password, g_free);
+    signing_data->password = g_strdup(password);
+}
+
+/**
+ * poppler_signing_data_get_password:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get signing key password.
+ *
+ * Return value: password
+ *
+ * Since: 23.07.0
+ **/
+const gchar *poppler_signing_data_get_password(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, nullptr);
+    return signing_data->password;
+}
+
+/**
+ * poppler_signing_data_set_document_owner_password:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @document_owner_password: document owner password
+ *
+ * Set document owner password (for encrypted files).
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_document_owner_password(PopplerSigningData *signing_data, const gchar *document_owner_password)
+{
+    g_return_if_fail(signing_data != nullptr);
+    g_return_if_fail(document_owner_password != nullptr);
+
+    if (signing_data->document_owner_password == document_owner_password) {
+        return;
+    }
+
+    g_clear_pointer(&signing_data->document_owner_password, g_free);
+    signing_data->document_owner_password = g_strdup(document_owner_password);
+}
+
+/**
+ * poppler_signing_data_get_document_owner_password:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get document owner password.
+ *
+ * Return value: document owner password (for encrypted files)
+ *
+ * Since: 23.07.0
+ **/
+const gchar *poppler_signing_data_get_document_owner_password(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, nullptr);
+    return signing_data->document_owner_password;
+}
+
+/**
+ * poppler_signing_data_set_document_user_password:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ * @document_user_password: document user password
+ *
+ * Set document user password (for encrypted files).
+ *
+ * Since: 23.07.0
+ **/
+void poppler_signing_data_set_document_user_password(PopplerSigningData *signing_data, const gchar *document_user_password)
+{
+    g_return_if_fail(signing_data != nullptr);
+    g_return_if_fail(document_user_password != nullptr);
+
+    if (signing_data->document_user_password == document_user_password) {
+        return;
+    }
+
+    g_clear_pointer(&signing_data->document_user_password, g_free);
+    signing_data->document_user_password = g_strdup(document_user_password);
+}
+
+/**
+ * poppler_signing_data_get_document_user_password:
+ * @signing_data: a #PopplerSigningData structure containing signing data
+ *
+ * Get document user password.
+ *
+ * Return value: document user password (for encrypted files)
+ *
+ * Since: 23.07.0
+ **/
+const gchar *poppler_signing_data_get_document_user_password(const PopplerSigningData *signing_data)
+{
+    g_return_val_if_fail(signing_data != nullptr, "");
+    return signing_data->document_user_password;
+}
+
+/* Certificate Information */
+
+struct _PopplerCertificateInfo
+{
+    char *id;
+    char *subject_common_name;
+};
+
+typedef struct _PopplerCertificateInfo PopplerCertificateInfo;
+
+G_DEFINE_BOXED_TYPE(PopplerCertificateInfo, poppler_certificate_info, poppler_certificate_info_copy, poppler_certificate_info_free)
+
+/**
+ * poppler_certificate_info_new:
+ *
+ * Creates a new #PopplerCertificateInfo
+ *
+ * Return value: a new #PopplerCertificateInfo. It must be freed with poppler_certificate_info_free() when done.
+ *
+ * Since: 23.07.0
+ **/
+PopplerCertificateInfo *poppler_certificate_info_new(void)
+{
+    return (PopplerCertificateInfo *)g_malloc0(sizeof(PopplerCertificateInfo));
+}
+
+/**
+ * poppler_certificate_info_get_id:
+ * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
+ *
+ * Get certificate nick name
+ *
+ * Return value: certificate nick name
+ *
+ * Since: 23.07.0
+ **/
+const char *poppler_certificate_info_get_id(const PopplerCertificateInfo *certificate_info)
+{
+    g_return_val_if_fail(certificate_info != nullptr, nullptr);
+    return certificate_info->id;
+}
+
+/**
+ * poppler_certificate_info_get_subject_common_name:
+ * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
+ *
+ * Get certificate subject common name
+ *
+ * Return value: certificate subject common name
+ *
+ * Since: 23.07.0
+ **/
+const char *poppler_certificate_info_get_subject_common_name(const PopplerCertificateInfo *certificate_info)
+{
+    g_return_val_if_fail(certificate_info != nullptr, nullptr);
+    return certificate_info->subject_common_name;
+}
+
+static PopplerCertificateInfo *create_certificate_info(const X509CertificateInfo *ci)
+{
+    PopplerCertificateInfo *certificate_info;
+
+    g_return_val_if_fail(ci != nullptr, nullptr);
+
+    certificate_info = poppler_certificate_info_new();
+    certificate_info->id = g_strdup(ci->getNickName().c_str());
+    certificate_info->subject_common_name = g_strdup(ci->getSubjectInfo().commonName.c_str());
+    return certificate_info;
+}
+
+/**
+ * poppler_certificate_info_copy:
+ * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
+ *
+ * Copies @certificate_info, creating an identical #PopplerCertificateInfo.
+ *
+ * Return value: (transfer full): a new #PopplerCertificateInfo structure identical to @certificate_info
+ *
+ * Since: 23.07.0
+ **/
+PopplerCertificateInfo *poppler_certificate_info_copy(const PopplerCertificateInfo *certificate_info)
+{
+    PopplerCertificateInfo *dup;
+
+    g_return_val_if_fail(certificate_info != nullptr, nullptr);
+
+    dup = (PopplerCertificateInfo *)g_malloc0(sizeof(PopplerCertificateInfo));
+    dup->id = g_strdup(certificate_info->id);
+    dup->subject_common_name = g_strdup(certificate_info->subject_common_name);
+
+    return dup;
+}
+
+/**
+ * poppler_certificate_info_free:
+ * @certificate_info: a #PopplerCertificateInfo structure containing certificate information
+ *
+ * Frees @certificate_info
+ *
+ * Since: 23.07.0
+ **/
+void poppler_certificate_info_free(PopplerCertificateInfo *certificate_info)
+{
+    if (certificate_info == nullptr) {
+        return;
+    }
+
+    g_clear_pointer(&certificate_info->id, g_free);
+    g_clear_pointer(&certificate_info->subject_common_name, g_free);
+
+    g_free(certificate_info);
+}
+
+/**
+ * poppler_get_available_signing_certificates:
+ *
+ * Get all available signing certificate information
+ *
+ * Returns: (transfer full) (element-type PopplerCertificateInfo): all available signing certificate information
+ **/
+GList *poppler_get_available_signing_certificates(void)
+{
+    GList *list = nullptr;
+#ifdef ENABLE_NSS3
+    std::vector<std::unique_ptr<X509CertificateInfo>> vCerts = CryptoSign::Factory::createActive()->getAvailableSigningCertificates();
+
+    for (auto &cert : vCerts) {
+        PopplerCertificateInfo *certificate_info = create_certificate_info(cert.get());
+        list = g_list_append(list, certificate_info);
+    }
+#endif
+    return list;
+}
+
+/**
+ * poppler_get_certificate_info_by_id:
+ *
+ * Get certificate by nick name
+ *
+ * Returns: (transfer full): a #PopplerCertificateInfo or %NULL if not found
+ **/
+PopplerCertificateInfo *poppler_get_certificate_info_by_id(const char *id)
+{
+    PopplerCertificateInfo *ret = nullptr;
+    GList *certificate_info = poppler_get_available_signing_certificates();
+    GList *list;
+
+    for (list = certificate_info; list != nullptr; list = list->next) {
+        PopplerCertificateInfo *info = (PopplerCertificateInfo *)list->data;
+
+        if (g_strcmp0(info->id, id) == 0) {
+            ret = poppler_certificate_info_copy(info);
+            break;
+        }
+    }
+
+    g_list_free_full(certificate_info, (GDestroyNotify)poppler_certificate_info_free);
+
+    return ret;
+}
+
+/* NSS functions */
+
+/**
+ * poppler_set_nss_dir:
+ *
+ * Set NSS directory
+ *
+ * Since: 23.07.0
+ **/
+void poppler_set_nss_dir(const char *path)
+{
+#ifdef ENABLE_NSS3
+    NSSSignatureConfiguration::setNSSDir(GooString(path));
+#else
+    (void)path;
+#endif
+}
+
+/**
+ * poppler_get_nss_dir:
+ *
+ * Get NSS directory
+ *
+ * Return value: (transfer full): nss directroy.
+ *
+ * Since: 23.07.0
+ **/
+char *poppler_get_nss_dir(void)
+{
+#ifdef ENABLE_NSS3
+    return g_strdup(NSSSignatureConfiguration::getNSSDir().c_str());
+#else
+    return nullptr;
+#endif
+}
+
+/**
+ * poppler_set_nss_password_callback:
+ * @func: (scope call): a #PopplerNssPasswordFunc that represents a signature annotation
+ *
+ * A callback which asks for certificate password
+ *
+ * Since: 23.07.0
+ **/
+void poppler_set_nss_password_callback(PopplerNssPasswordFunc func)
+{
+#ifdef ENABLE_NSS3
+    NSSSignatureConfiguration::setNSSPasswordCallback(func);
+#else
+    g_warning("poppler_set_nss_password_callback called but this poppler is built without NSS support");
+    (void)func;
+#endif
+}
diff --git a/glib/poppler-form-field.h b/glib/poppler-form-field.h
index b48c5064..d6218ab0 100644
--- a/glib/poppler-form-field.h
+++ b/glib/poppler-form-field.h
@@ -249,6 +249,120 @@ const gchar *poppler_signature_info_get_signer_name(const PopplerSignatureInfo *
 POPPLER_PUBLIC
 GDateTime *poppler_signature_info_get_local_signing_time(const PopplerSignatureInfo *siginfo);
 
+/* Signing Data */
+#define POPPLER_TYPE_SIGNING_DATA (poppler_signing_data_get_type())
+POPPLER_PUBLIC
+GType poppler_signing_data_get_type(void) G_GNUC_CONST;
+POPPLER_PUBLIC
+PopplerSigningData *poppler_signing_data_new(void);
+POPPLER_PUBLIC
+PopplerSigningData *poppler_signing_data_copy(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_free(PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_destination_filename(PopplerSigningData *signing_data, const gchar *filename);
+POPPLER_PUBLIC
+const gchar *poppler_signing_data_get_destination_filename(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_certificate_info(PopplerSigningData *signing_data, const PopplerCertificateInfo *certificate_info);
+POPPLER_PUBLIC
+const PopplerCertificateInfo *poppler_signing_data_get_certificate_info(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_page(PopplerSigningData *signing_data, int page);
+POPPLER_PUBLIC
+int poppler_signing_data_get_page(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_signature_text(PopplerSigningData *signing_data, const gchar *signature_text);
+POPPLER_PUBLIC
+const gchar *poppler_signing_data_get_signature_text(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_signature_text_left(PopplerSigningData *signing_data, const gchar *signature_text_left);
+POPPLER_PUBLIC
+const gchar *poppler_signing_data_get_signature_text_left(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_signature_rectangle(PopplerSigningData *signing_data, const PopplerRectangle *signature_rect);
+POPPLER_PUBLIC
+const PopplerRectangle *poppler_signing_data_get_signature_rectangle(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_font_color(PopplerSigningData *signing_data, const PopplerColor *font_color);
+POPPLER_PUBLIC
+const PopplerColor *poppler_signing_data_get_font_color(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_font_size(PopplerSigningData *signing_data, gdouble font_size);
+POPPLER_PUBLIC
+gdouble poppler_signing_data_get_font_size(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_left_font_size(PopplerSigningData *signing_data, gdouble font_size);
+POPPLER_PUBLIC
+gdouble poppler_signing_data_get_left_font_size(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_border_color(PopplerSigningData *signing_data, const PopplerColor *border_color);
+POPPLER_PUBLIC
+const PopplerColor *poppler_signing_data_get_border_color(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_border_width(PopplerSigningData *signing_data, gdouble border_width);
+POPPLER_PUBLIC
+gdouble poppler_signing_data_get_border_width(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_background_color(PopplerSigningData *signing_data, const PopplerColor *background_color);
+POPPLER_PUBLIC
+const PopplerColor *poppler_signing_data_get_background_color(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_field_partial_name(PopplerSigningData *signing_data, const gchar *field_partial_name);
+POPPLER_PUBLIC
+const gchar *poppler_signing_data_get_field_partial_name(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_reason(PopplerSigningData *signing_data, const gchar *reason);
+POPPLER_PUBLIC
+const gchar *poppler_signing_data_get_reason(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_location(PopplerSigningData *signing_data, const gchar *location);
+POPPLER_PUBLIC
+const gchar *poppler_signing_data_get_location(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_image_path(PopplerSigningData *signing_data, const gchar *image_path);
+POPPLER_PUBLIC
+const gchar *poppler_signing_data_get_image_path(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_password(PopplerSigningData *signing_data, const gchar *password);
+POPPLER_PUBLIC
+const gchar *poppler_signing_data_get_password(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_document_owner_password(PopplerSigningData *signing_data, const gchar *document_owner_password);
+POPPLER_PUBLIC
+const gchar *poppler_signing_data_get_document_owner_password(const PopplerSigningData *signing_data);
+POPPLER_PUBLIC
+void poppler_signing_data_set_document_user_password(PopplerSigningData *signing_data, const gchar *document_user_password);
+POPPLER_PUBLIC
+const gchar *poppler_signing_data_get_document_user_password(const PopplerSigningData *signing_data);
+
+/* Certificate Information */
+#define POPPLER_TYPE_CERTIFICATE_INFO (poppler_certificate_info_get_type())
+POPPLER_PUBLIC
+GType poppler_certificate_info_get_type(void) G_GNUC_CONST;
+PopplerCertificateInfo *poppler_certificate_info_new(void);
+POPPLER_PUBLIC
+PopplerCertificateInfo *poppler_certificate_info_copy(const PopplerCertificateInfo *certificate_info);
+POPPLER_PUBLIC
+void poppler_certificate_info_free(PopplerCertificateInfo *certificate_info);
+POPPLER_PUBLIC
+const char *poppler_certificate_info_get_id(const PopplerCertificateInfo *certificate_info);
+POPPLER_PUBLIC
+const char *poppler_certificate_info_get_subject_common_name(const PopplerCertificateInfo *certificate_info);
+POPPLER_PUBLIC
+PopplerCertificateInfo *poppler_get_certificate_info_by_id(const char *id);
+POPPLER_PUBLIC
+GList *poppler_get_available_signing_certificates(void);
+
+/* NSS */
+POPPLER_PUBLIC
+void poppler_set_nss_dir(const char *path);
+POPPLER_PUBLIC
+char *poppler_get_nss_dir(void);
+typedef char *(*PopplerNssPasswordFunc)(const gchar *text);
+POPPLER_PUBLIC
+void poppler_set_nss_password_callback(PopplerNssPasswordFunc func);
+
 G_END_DECLS
 
 #endif /* __POPPLER_FORM_FIELD_H__ */
diff --git a/glib/poppler.h b/glib/poppler.h
index 710b7b23..70f2172a 100644
--- a/glib/poppler.h
+++ b/glib/poppler.h
@@ -47,7 +47,8 @@ typedef enum
     POPPLER_ERROR_ENCRYPTED,
     POPPLER_ERROR_OPEN_FILE,
     POPPLER_ERROR_BAD_CATALOG,
-    POPPLER_ERROR_DAMAGED
+    POPPLER_ERROR_DAMAGED,
+    POPPLER_ERROR_SIGNING
 } PopplerError;
 
 /**
@@ -220,6 +221,8 @@ typedef struct _PopplerTextSpan PopplerTextSpan;
 typedef struct _PopplerPageRange PopplerPageRange;
 typedef struct _PopplerSignatureInfo PopplerSignatureInfo;
 typedef struct _PopplerAnnotStamp PopplerAnnotStamp;
+typedef struct _PopplerCertificateInfo PopplerCertificateInfo;
+typedef struct _PopplerSigningData PopplerSigningData;
 
 /**
  * PopplerBackend:
diff --git a/glib/reference/poppler-sections.txt b/glib/reference/poppler-sections.txt
index f027cd03..aa09e2d5 100644
--- a/glib/reference/poppler-sections.txt
+++ b/glib/reference/poppler-sections.txt
@@ -417,6 +417,57 @@ poppler_signature_info_get_certificate_status
 poppler_signature_info_get_signature_status
 poppler_signature_info_get_signer_name
 poppler_signature_info_get_local_signing_time
+poppler_signing_data_new
+poppler_signing_data_copy
+poppler_signing_data_free
+poppler_signing_data_set_destination_filename
+poppler_signing_data_set_certificate_info
+poppler_signing_data_set_page
+poppler_signing_data_set_signature_text
+poppler_signing_data_set_signature_text_left
+poppler_signing_data_set_signature_rectangle
+poppler_signing_data_set_font_color
+poppler_signing_data_set_font_size
+poppler_signing_data_set_left_font_size
+poppler_signing_data_set_border_color
+poppler_signing_data_set_border_width
+poppler_signing_data_set_background_color
+poppler_signing_data_set_field_partial_name
+poppler_signing_data_set_reason
+poppler_signing_data_set_location
+poppler_signing_data_set_image_path
+poppler_signing_data_set_password
+poppler_signing_data_set_document_owner_password
+poppler_signing_data_set_document_user_password
+poppler_signing_data_get_destination_filename
+poppler_signing_data_get_certificate_info
+poppler_signing_data_get_page
+poppler_signing_data_get_signature_text
+poppler_signing_data_get_signature_text_left
+poppler_signing_data_get_signature_rectangle
+poppler_signing_data_get_font_color
+poppler_signing_data_get_font_size
+poppler_signing_data_get_left_font_size
+poppler_signing_data_get_border_color
+poppler_signing_data_get_border_width
+poppler_signing_data_get_background_color
+poppler_signing_data_get_field_partial_name
+poppler_signing_data_get_reason
+poppler_signing_data_get_location
+poppler_signing_data_get_image_path
+poppler_signing_data_get_password
+poppler_signing_data_get_document_owner_password
+poppler_signing_data_get_document_user_password
+poppler_certificate_info_new
+poppler_certificate_info_copy
+poppler_certificate_info_get_nick_name
+poppler_certificate_info_get_subject_common_name
+poppler_get_certificate_info_by_nick_name
+poppler_set_nss_dir
+poppler_get_nss_dir
+poppler_set_nss_password_callback
+poppler_get_available_signing_certificates
+poppler_certificate_info_free
 
 <SUBSECTION Standard>
 POPPLER_FORM_FIELD
diff --git a/glib/reference/poppler.types b/glib/reference/poppler.types
index 1ab636b3..216633f4 100644
--- a/glib/reference/poppler.types
+++ b/glib/reference/poppler.types
@@ -92,3 +92,5 @@ poppler_structure_writing_mode_get_type
 poppler_text_attributes_get_type
 poppler_text_span_get_type
 poppler_viewer_preferences_get_type
+poppler_signing_data_get_type
+poppler_certificate_info_get_type
\ No newline at end of file


More information about the poppler mailing list