[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