1/* poppler-annot.cc: glib interface to poppler
2 *
3 * Copyright (C) 2007 Inigo Martinez <inigomartinez@gmail.com>
4 * Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
5 * Copyright (C) 2013 German Poo-Caamano <gpoo@gnome.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
20 */
21
22#include "config.h"
23#include "poppler.h"
24#include "poppler-private.h"
25
26#define ZERO_CROPBOX(c) (!(c && (c->x1 > 0.01 || c->y1 > 0.01)))
27
28const PDFRectangle *_poppler_annot_get_cropbox_and_page(PopplerAnnot *poppler_annot, Page **page_out);
29AnnotStampImageHelper *_poppler_convert_cairo_image_to_stamp_image_helper(cairo_surface_t *image, PDFDoc *doc, GError **error);
30
31/**
32 * SECTION:poppler-annot
33 * @short_description: Annotations
34 * @title: PopplerAnnot
35 */
36
37typedef struct _PopplerAnnotClass PopplerAnnotClass;
38typedef struct _PopplerAnnotMarkupClass PopplerAnnotMarkupClass;
39typedef struct _PopplerAnnotFreeTextClass PopplerAnnotFreeTextClass;
40typedef struct _PopplerAnnotTextClass PopplerAnnotTextClass;
41typedef struct _PopplerAnnotTextMarkupClass PopplerAnnotTextMarkupClass;
42typedef struct _PopplerAnnotFileAttachmentClass PopplerAnnotFileAttachmentClass;
43typedef struct _PopplerAnnotMovieClass PopplerAnnotMovieClass;
44typedef struct _PopplerAnnotScreenClass PopplerAnnotScreenClass;
45typedef struct _PopplerAnnotLineClass PopplerAnnotLineClass;
46typedef struct _PopplerAnnotCircleClass PopplerAnnotCircleClass;
47typedef struct _PopplerAnnotSquareClass PopplerAnnotSquareClass;
48typedef struct _PopplerAnnotStampClass PopplerAnnotStampClass;
49
50struct _PopplerAnnotClass
51{
52 GObjectClass parent_class;
53};
54
55struct _PopplerAnnotMarkup
56{
57 PopplerAnnot parent_instance;
58};
59
60struct _PopplerAnnotMarkupClass
61{
62 PopplerAnnotClass parent_class;
63};
64
65struct _PopplerAnnotText
66{
67 PopplerAnnotMarkup parent_instance;
68};
69
70struct _PopplerAnnotTextClass
71{
72 PopplerAnnotMarkupClass parent_class;
73};
74
75struct _PopplerAnnotTextMarkup
76{
77 PopplerAnnotMarkup parent_instance;
78};
79
80struct _PopplerAnnotTextMarkupClass
81{
82 PopplerAnnotMarkupClass parent_class;
83};
84
85struct _PopplerAnnotFreeText
86{
87 PopplerAnnotMarkup parent_instance;
88};
89
90struct _PopplerAnnotFreeTextClass
91{
92 PopplerAnnotMarkupClass parent_class;
93};
94
95struct _PopplerAnnotFileAttachment
96{
97 PopplerAnnotMarkup parent_instance;
98};
99
100struct _PopplerAnnotFileAttachmentClass
101{
102 PopplerAnnotMarkupClass parent_class;
103};
104
105struct _PopplerAnnotMovie
106{
107 PopplerAnnot parent_instance;
108
109 PopplerMovie *movie;
110};
111
112struct _PopplerAnnotMovieClass
113{
114 PopplerAnnotClass parent_class;
115};
116
117struct _PopplerAnnotScreen
118{
119 PopplerAnnot parent_instance;
120
121 PopplerAction *action;
122};
123
124struct _PopplerAnnotScreenClass
125{
126 PopplerAnnotClass parent_class;
127};
128
129struct _PopplerAnnotLine
130{
131 PopplerAnnotMarkup parent_instance;
132};
133
134struct _PopplerAnnotLineClass
135{
136 PopplerAnnotMarkupClass parent_class;
137};
138
139struct _PopplerAnnotCircle
140{
141 PopplerAnnotMarkup parent_instance;
142};
143
144struct _PopplerAnnotCircleClass
145{
146 PopplerAnnotMarkupClass parent_class;
147};
148
149struct _PopplerAnnotSquare
150{
151 PopplerAnnotMarkup parent_instance;
152};
153
154struct _PopplerAnnotSquareClass
155{
156 PopplerAnnotMarkupClass parent_class;
157};
158struct _PopplerAnnotStamp
159{
160 PopplerAnnot parent_instance;
161};
162struct _PopplerAnnotStampClass
163{
164 PopplerAnnotClass parent_class;
165};
166
167G_DEFINE_TYPE(PopplerAnnot, poppler_annot, G_TYPE_OBJECT)
168G_DEFINE_TYPE(PopplerAnnotMarkup, poppler_annot_markup, POPPLER_TYPE_ANNOT)
169G_DEFINE_TYPE(PopplerAnnotTextMarkup, poppler_annot_text_markup, POPPLER_TYPE_ANNOT_MARKUP)
170G_DEFINE_TYPE(PopplerAnnotText, poppler_annot_text, POPPLER_TYPE_ANNOT_MARKUP)
171G_DEFINE_TYPE(PopplerAnnotFreeText, poppler_annot_free_text, POPPLER_TYPE_ANNOT_MARKUP)
172G_DEFINE_TYPE(PopplerAnnotFileAttachment, poppler_annot_file_attachment, POPPLER_TYPE_ANNOT_MARKUP)
173G_DEFINE_TYPE(PopplerAnnotMovie, poppler_annot_movie, POPPLER_TYPE_ANNOT)
174G_DEFINE_TYPE(PopplerAnnotScreen, poppler_annot_screen, POPPLER_TYPE_ANNOT)
175G_DEFINE_TYPE(PopplerAnnotLine, poppler_annot_line, POPPLER_TYPE_ANNOT_MARKUP)
176G_DEFINE_TYPE(PopplerAnnotCircle, poppler_annot_circle, POPPLER_TYPE_ANNOT_MARKUP)
177G_DEFINE_TYPE(PopplerAnnotSquare, poppler_annot_square, POPPLER_TYPE_ANNOT_MARKUP)
178G_DEFINE_TYPE(PopplerAnnotStamp, poppler_annot_stamp, POPPLER_TYPE_ANNOT)
179
180static PopplerAnnot *_poppler_create_annot(GType annot_type, Annot *annot)
181{
182 PopplerAnnot *poppler_annot;
183
184 poppler_annot = POPPLER_ANNOT(g_object_new(annot_type, nullptr));
185 poppler_annot->annot = annot;
186 annot->incRefCnt();
187
188 return poppler_annot;
189}
190
191static void poppler_annot_finalize(GObject *object)
192{
193 PopplerAnnot *poppler_annot = POPPLER_ANNOT(object);
194
195 if (poppler_annot->annot) {
196 poppler_annot->annot->decRefCnt();
197 poppler_annot->annot = nullptr;
198 }
199
200 G_OBJECT_CLASS(poppler_annot_parent_class)->finalize(object);
201}
202
203static void poppler_annot_init(PopplerAnnot *poppler_annot) { }
204
205static void poppler_annot_class_init(PopplerAnnotClass *klass)
206{
207 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
208
209 gobject_class->finalize = poppler_annot_finalize;
210}
211
212PopplerAnnot *_poppler_annot_new(Annot *annot)
213{
214 return _poppler_create_annot(POPPLER_TYPE_ANNOT, annot);
215}
216
217static void poppler_annot_markup_init(PopplerAnnotMarkup *poppler_annot) { }
218
219static void poppler_annot_markup_class_init(PopplerAnnotMarkupClass *klass) { }
220
221static void poppler_annot_text_init(PopplerAnnotText *poppler_annot) { }
222
223static void poppler_annot_text_class_init(PopplerAnnotTextClass *klass) { }
224
225PopplerAnnot *_poppler_annot_text_new(Annot *annot)
226{
227 return _poppler_create_annot(POPPLER_TYPE_ANNOT_TEXT, annot);
228}
229
230/**
231 * poppler_annot_text_new:
232 * @doc: a #PopplerDocument
233 * @rect: a #PopplerRectangle
234 *
235 * Creates a new Text annotation that will be
236 * located on @rect when added to a page. See
237 * poppler_page_add_annot()
238 *
239 * Return value: A newly created #PopplerAnnotText annotation
240 *
241 * Since: 0.16
242 */
243PopplerAnnot *poppler_annot_text_new(PopplerDocument *doc, PopplerRectangle *rect)
244{
245 Annot *annot;
246 PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);
247
248 annot = new AnnotText(doc->doc, &pdf_rect);
249
250 return _poppler_annot_text_new(annot);
251}
252
253PopplerAnnot *_poppler_annot_text_markup_new(Annot *annot)
254{
255 return _poppler_create_annot(POPPLER_TYPE_ANNOT_TEXT_MARKUP, annot);
256}
257
258static AnnotQuadrilaterals *create_annot_quads_from_poppler_quads(GArray *quads)
259{
260 g_assert(quads->len > 0);
261
262 auto quads_array = std::make_unique<AnnotQuadrilaterals::AnnotQuadrilateral[]>(num: quads->len);
263 for (guint i = 0; i < quads->len; i++) {
264 PopplerQuadrilateral *quadrilateral = &g_array_index(quads, PopplerQuadrilateral, i);
265
266 quads_array[i] = AnnotQuadrilaterals::AnnotQuadrilateral(quadrilateral->p1.x, quadrilateral->p1.y, quadrilateral->p2.x, quadrilateral->p2.y, quadrilateral->p3.x, quadrilateral->p3.y, quadrilateral->p4.x, quadrilateral->p4.y);
267 }
268
269 return new AnnotQuadrilaterals(std::move(quads_array), quads->len);
270}
271
272/* If @crop_box parameter is non null, it will substract the crop_box offset
273 * from the coordinates of the returned #PopplerQuadrilateral array */
274static GArray *create_poppler_quads_from_annot_quads(AnnotQuadrilaterals *quads_array, const PDFRectangle *crop_box)
275{
276 GArray *quads;
277 guint quads_len;
278 PDFRectangle zerobox;
279
280 if (!crop_box) {
281 zerobox = PDFRectangle();
282 crop_box = &zerobox;
283 }
284
285 quads_len = quads_array->getQuadrilateralsLength();
286 quads = g_array_sized_new(FALSE, FALSE, element_size: sizeof(PopplerQuadrilateral), reserved_size: quads_len);
287 g_array_set_size(array: quads, length: quads_len);
288
289 for (guint i = 0; i < quads_len; ++i) {
290 PopplerQuadrilateral *quadrilateral = &g_array_index(quads, PopplerQuadrilateral, i);
291
292 quadrilateral->p1.x = quads_array->getX1(quadrilateral: i) - crop_box->x1;
293 quadrilateral->p1.y = quads_array->getY1(quadrilateral: i) - crop_box->y1;
294 quadrilateral->p2.x = quads_array->getX2(quadrilateral: i) - crop_box->x1;
295 quadrilateral->p2.y = quads_array->getY2(quadrilateral: i) - crop_box->y1;
296 quadrilateral->p3.x = quads_array->getX3(quadrilateral: i) - crop_box->x1;
297 quadrilateral->p3.y = quads_array->getY3(quadrilateral: i) - crop_box->y1;
298 quadrilateral->p4.x = quads_array->getX4(quadrilateral: i) - crop_box->x1;
299 quadrilateral->p4.y = quads_array->getY4(quadrilateral: i) - crop_box->y1;
300 }
301
302 return quads;
303}
304
305static void poppler_annot_text_markup_init(PopplerAnnotTextMarkup *poppler_annot) { }
306
307static void poppler_annot_text_markup_class_init(PopplerAnnotTextMarkupClass *klass) { }
308
309/**
310 * poppler_annot_text_markup_new_highlight:
311 * @doc: a #PopplerDocument
312 * @rect: a #PopplerRectangle
313 * @quadrilaterals: (element-type PopplerQuadrilateral): A #GArray of
314 * #PopplerQuadrilateral<!-- -->s
315 *
316 * Creates a new Highlight Text annotation that will be
317 * located on @rect when added to a page. See poppler_page_add_annot()
318 *
319 * Return value: (transfer full): A newly created #PopplerAnnotTextMarkup annotation
320 *
321 * Since: 0.26
322 */
323PopplerAnnot *poppler_annot_text_markup_new_highlight(PopplerDocument *doc, PopplerRectangle *rect, GArray *quadrilaterals)
324{
325 PopplerAnnot *poppler_annot;
326 AnnotTextMarkup *annot;
327 PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);
328
329 annot = new AnnotTextMarkup(doc->doc, &pdf_rect, Annot::typeHighlight);
330
331 poppler_annot = _poppler_annot_text_markup_new(annot);
332 poppler_annot_text_markup_set_quadrilaterals(POPPLER_ANNOT_TEXT_MARKUP(poppler_annot), quadrilaterals);
333 return poppler_annot;
334}
335
336/**
337 * poppler_annot_text_markup_new_squiggly:
338 * @doc: a #PopplerDocument
339 * @rect: a #PopplerRectangle
340 * @quadrilaterals: (element-type PopplerQuadrilateral): A #GArray of
341 * #PopplerQuadrilateral<!-- -->s
342 *
343 * Creates a new Squiggly Text annotation that will be
344 * located on @rect when added to a page. See poppler_page_add_annot()
345 *
346 * Return value: (transfer full): A newly created #PopplerAnnotTextMarkup annotation
347 *
348 * Since: 0.26
349 */
350PopplerAnnot *poppler_annot_text_markup_new_squiggly(PopplerDocument *doc, PopplerRectangle *rect, GArray *quadrilaterals)
351{
352 PopplerAnnot *poppler_annot;
353 AnnotTextMarkup *annot;
354 PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);
355
356 g_return_val_if_fail(quadrilaterals != nullptr && quadrilaterals->len > 0, NULL);
357
358 annot = new AnnotTextMarkup(doc->doc, &pdf_rect, Annot::typeSquiggly);
359
360 poppler_annot = _poppler_annot_text_markup_new(annot);
361 poppler_annot_text_markup_set_quadrilaterals(POPPLER_ANNOT_TEXT_MARKUP(poppler_annot), quadrilaterals);
362 return poppler_annot;
363}
364
365/**
366 * poppler_annot_text_markup_new_strikeout:
367 * @doc: a #PopplerDocument
368 * @rect: a #PopplerRectangle
369 * @quadrilaterals: (element-type PopplerQuadrilateral): A #GArray of
370 * #PopplerQuadrilateral<!-- -->s
371 *
372 * Creates a new Strike Out Text annotation that will be
373 * located on @rect when added to a page. See poppler_page_add_annot()
374 *
375 * Return value: (transfer full): A newly created #PopplerAnnotTextMarkup annotation
376 *
377 * Since: 0.26
378 */
379PopplerAnnot *poppler_annot_text_markup_new_strikeout(PopplerDocument *doc, PopplerRectangle *rect, GArray *quadrilaterals)
380{
381 PopplerAnnot *poppler_annot;
382 AnnotTextMarkup *annot;
383 PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);
384
385 g_return_val_if_fail(quadrilaterals != nullptr && quadrilaterals->len > 0, NULL);
386
387 annot = new AnnotTextMarkup(doc->doc, &pdf_rect, Annot::typeStrikeOut);
388
389 poppler_annot = _poppler_annot_text_markup_new(annot);
390 poppler_annot_text_markup_set_quadrilaterals(POPPLER_ANNOT_TEXT_MARKUP(poppler_annot), quadrilaterals);
391 return poppler_annot;
392}
393
394/**
395 * poppler_annot_text_markup_new_underline:
396 * @doc: a #PopplerDocument
397 * @rect: a #PopplerRectangle
398 * @quadrilaterals: (element-type PopplerQuadrilateral): A #GArray of
399 * #PopplerQuadrilateral<!-- -->s
400 *
401 * Creates a new Underline Text annotation that will be
402 * located on @rect when added to a page. See poppler_page_add_annot()
403 *
404 * Return value: (transfer full): A newly created #PopplerAnnotTextMarkup annotation
405 *
406 * Since: 0.26
407 */
408PopplerAnnot *poppler_annot_text_markup_new_underline(PopplerDocument *doc, PopplerRectangle *rect, GArray *quadrilaterals)
409{
410 PopplerAnnot *poppler_annot;
411 AnnotTextMarkup *annot;
412 PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);
413
414 g_return_val_if_fail(quadrilaterals != nullptr && quadrilaterals->len > 0, NULL);
415
416 annot = new AnnotTextMarkup(doc->doc, &pdf_rect, Annot::typeUnderline);
417
418 poppler_annot = _poppler_annot_text_markup_new(annot);
419 poppler_annot_text_markup_set_quadrilaterals(POPPLER_ANNOT_TEXT_MARKUP(poppler_annot), quadrilaterals);
420 return poppler_annot;
421}
422
423static void poppler_annot_free_text_init(PopplerAnnotFreeText *poppler_annot) { }
424
425static void poppler_annot_free_text_class_init(PopplerAnnotFreeTextClass *klass) { }
426
427PopplerAnnot *_poppler_annot_free_text_new(Annot *annot)
428{
429 return _poppler_create_annot(POPPLER_TYPE_ANNOT_FREE_TEXT, annot);
430}
431
432static void poppler_annot_file_attachment_init(PopplerAnnotFileAttachment *poppler_annot) { }
433
434static void poppler_annot_file_attachment_class_init(PopplerAnnotFileAttachmentClass *klass) { }
435
436PopplerAnnot *_poppler_annot_file_attachment_new(Annot *annot)
437{
438 return _poppler_create_annot(POPPLER_TYPE_ANNOT_FILE_ATTACHMENT, annot);
439}
440
441static void poppler_annot_movie_finalize(GObject *object)
442{
443 PopplerAnnotMovie *annot_movie = POPPLER_ANNOT_MOVIE(object);
444
445 if (annot_movie->movie) {
446 g_object_unref(object: annot_movie->movie);
447 annot_movie->movie = nullptr;
448 }
449
450 G_OBJECT_CLASS(poppler_annot_movie_parent_class)->finalize(object);
451}
452
453static void poppler_annot_movie_init(PopplerAnnotMovie *poppler_annot) { }
454
455static void poppler_annot_movie_class_init(PopplerAnnotMovieClass *klass)
456{
457 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
458
459 gobject_class->finalize = poppler_annot_movie_finalize;
460}
461
462PopplerAnnot *_poppler_annot_movie_new(Annot *annot)
463{
464 PopplerAnnot *poppler_annot;
465 AnnotMovie *annot_movie;
466
467 poppler_annot = _poppler_create_annot(POPPLER_TYPE_ANNOT_MOVIE, annot);
468 annot_movie = static_cast<AnnotMovie *>(poppler_annot->annot);
469 POPPLER_ANNOT_MOVIE(poppler_annot)->movie = _poppler_movie_new(movie: annot_movie->getMovie());
470
471 return poppler_annot;
472}
473
474static void poppler_annot_screen_finalize(GObject *object)
475{
476 PopplerAnnotScreen *annot_screen = POPPLER_ANNOT_SCREEN(object);
477
478 if (annot_screen->action) {
479 poppler_action_free(action: annot_screen->action);
480 annot_screen->action = nullptr;
481 }
482
483 G_OBJECT_CLASS(poppler_annot_screen_parent_class)->finalize(object);
484}
485
486static void poppler_annot_screen_init(PopplerAnnotScreen *poppler_annot) { }
487
488static void poppler_annot_screen_class_init(PopplerAnnotScreenClass *klass)
489{
490 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
491
492 gobject_class->finalize = poppler_annot_screen_finalize;
493}
494
495PopplerAnnot *_poppler_annot_screen_new(PopplerDocument *doc, Annot *annot)
496{
497 PopplerAnnot *poppler_annot;
498 AnnotScreen *annot_screen;
499 LinkAction *action;
500
501 poppler_annot = _poppler_create_annot(POPPLER_TYPE_ANNOT_SCREEN, annot);
502 annot_screen = static_cast<AnnotScreen *>(poppler_annot->annot);
503 action = annot_screen->getAction();
504 if (action) {
505 POPPLER_ANNOT_SCREEN(poppler_annot)->action = _poppler_action_new(document: doc, link: action, title: nullptr);
506 }
507
508 return poppler_annot;
509}
510
511PopplerAnnot *_poppler_annot_line_new(Annot *annot)
512{
513 return _poppler_create_annot(POPPLER_TYPE_ANNOT_LINE, annot);
514}
515
516static void poppler_annot_line_init(PopplerAnnotLine *poppler_annot) { }
517
518static void poppler_annot_line_class_init(PopplerAnnotLineClass *klass) { }
519
520/**
521 * poppler_annot_line_new:
522 * @doc: a #PopplerDocument
523 * @rect: a #PopplerRectangle
524 * @start: a #PopplerPoint of the starting vertice
525 * @end: a #PopplerPoint of the ending vertice
526 *
527 * Creates a new Line annotation that will be
528 * located on @rect when added to a page. See
529 * poppler_page_add_annot()
530 *
531 * Return value: A newly created #PopplerAnnotLine annotation
532 *
533 * Since: 0.26
534 */
535PopplerAnnot *poppler_annot_line_new(PopplerDocument *doc, PopplerRectangle *rect, PopplerPoint *start, PopplerPoint *end)
536{
537 PopplerAnnot *poppler_annot;
538 Annot *annot;
539 PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);
540
541 annot = new AnnotLine(doc->doc, &pdf_rect);
542
543 poppler_annot = _poppler_annot_line_new(annot);
544 poppler_annot_line_set_vertices(POPPLER_ANNOT_LINE(poppler_annot), start, end);
545 return poppler_annot;
546}
547
548PopplerAnnot *_poppler_annot_circle_new(Annot *annot)
549{
550 return _poppler_create_annot(POPPLER_TYPE_ANNOT_CIRCLE, annot);
551}
552
553static void poppler_annot_circle_init(PopplerAnnotCircle *poppler_annot) { }
554
555static void poppler_annot_circle_class_init(PopplerAnnotCircleClass *klass) { }
556
557/**
558 * poppler_annot_circle_new:
559 * @doc: a #PopplerDocument
560 * @rect: a #PopplerRectangle
561 *
562 * Creates a new Circle annotation that will be
563 * located on @rect when added to a page. See
564 * poppler_page_add_annot()
565 *
566 * Return value: a newly created #PopplerAnnotCircle annotation
567 *
568 * Since: 0.26
569 **/
570PopplerAnnot *poppler_annot_circle_new(PopplerDocument *doc, PopplerRectangle *rect)
571{
572 Annot *annot;
573 PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);
574
575 annot = new AnnotGeometry(doc->doc, &pdf_rect, Annot::typeCircle);
576
577 return _poppler_annot_circle_new(annot);
578}
579
580PopplerAnnot *_poppler_annot_square_new(Annot *annot)
581{
582 return _poppler_create_annot(POPPLER_TYPE_ANNOT_SQUARE, annot);
583}
584
585static void poppler_annot_square_init(PopplerAnnotSquare *poppler_annot) { }
586
587static void poppler_annot_square_class_init(PopplerAnnotSquareClass *klass) { }
588
589/**
590 * poppler_annot_square_new:
591 * @doc: a #PopplerDocument
592 * @rect: a #PopplerRectangle
593 *
594 * Creates a new Square annotation that will be
595 * located on @rect when added to a page. See
596 * poppler_page_add_annot()
597 *
598 * Return value: a newly created #PopplerAnnotSquare annotation
599 *
600 * Since: 0.26
601 **/
602PopplerAnnot *poppler_annot_square_new(PopplerDocument *doc, PopplerRectangle *rect)
603{
604 Annot *annot;
605 PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);
606
607 annot = new AnnotGeometry(doc->doc, &pdf_rect, Annot::typeSquare);
608
609 return _poppler_annot_square_new(annot);
610}
611
612static void poppler_annot_stamp_finalize(GObject *object)
613{
614 G_OBJECT_CLASS(poppler_annot_stamp_parent_class)->finalize(object);
615}
616
617static void poppler_annot_stamp_init(PopplerAnnotStamp *poppler_annot) { }
618
619static void poppler_annot_stamp_class_init(PopplerAnnotStampClass *klass)
620{
621 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
622
623 gobject_class->finalize = poppler_annot_stamp_finalize;
624}
625
626PopplerAnnot *_poppler_annot_stamp_new(Annot *annot)
627{
628 PopplerAnnot *poppler_annot;
629
630 poppler_annot = _poppler_create_annot(POPPLER_TYPE_ANNOT_STAMP, annot);
631
632 return poppler_annot;
633}
634
635/**
636 * poppler_annot_stamp_new:
637 * @doc: a #PopplerDocument
638 * @rect: a #PopplerRectangle
639 *
640 * Creates a new Stamp annotation that will be
641 * located on @rect when added to a page. See
642 * poppler_page_add_annot()
643 *
644 * Return value: a newly created #PopplerAnnotStamp annotation
645 *
646 * Since: 22.07.0
647 **/
648PopplerAnnot *poppler_annot_stamp_new(PopplerDocument *doc, PopplerRectangle *rect)
649{
650 Annot *annot;
651 PDFRectangle pdf_rect(rect->x1, rect->y1, rect->x2, rect->y2);
652
653 annot = new AnnotStamp(doc->doc, &pdf_rect);
654
655 return _poppler_annot_stamp_new(annot);
656}
657
658static gboolean get_raw_data_from_cairo_image(cairo_surface_t *image, cairo_format_t format, const int width, const int height, const size_t rowstride_c, GByteArray *data, GByteArray *soft_mask_data)
659{
660 gboolean has_alpha = format == CAIRO_FORMAT_ARGB32;
661
662#if G_BYTE_ORDER == G_LITTLE_ENDIAN
663 static const size_t CAIRO_B = 0;
664 static const size_t CAIRO_G = 1;
665 static const size_t CAIRO_R = 2;
666 static const size_t CAIRO_A = 3;
667#elif G_BYTE_ORDER == G_BIG_ENDIAN
668 static const size_t CAIRO_A = 0;
669 static const size_t CAIRO_R = 1;
670 static const size_t CAIRO_G = 2;
671 static const size_t CAIRO_B = 3;
672#else
673# error "Unsupported endian type"
674#endif
675
676 cairo_surface_flush(surface: image);
677 unsigned char *pixels_c = cairo_image_surface_get_data(surface: image);
678
679 if (format == CAIRO_FORMAT_ARGB32 || format == CAIRO_FORMAT_RGB24) {
680 unsigned char pixel[3];
681
682 for (int h = 0; h < height; h++) {
683 unsigned char *iter_c = pixels_c + h * rowstride_c;
684 for (int w = 0; w < width; w++) {
685 pixel[0] = iter_c[CAIRO_R];
686 pixel[1] = iter_c[CAIRO_G];
687 pixel[2] = iter_c[CAIRO_B];
688 iter_c += 4;
689
690 g_byte_array_append(array: data, data: (guint8 *)pixel, len: 3);
691 if (has_alpha) {
692 g_byte_array_append(array: soft_mask_data, data: (guint8 *)&iter_c[CAIRO_A], len: 1);
693 }
694 }
695 }
696 return TRUE;
697 }
698
699 return FALSE;
700}
701
702AnnotStampImageHelper *_poppler_convert_cairo_image_to_stamp_image_helper(cairo_surface_t *image, PDFDoc *doc, GError **error)
703{
704 AnnotStampImageHelper *annotImg;
705 GByteArray *data;
706 GByteArray *sMaskData;
707
708 int bitsPerComponent;
709 const int width = cairo_image_surface_get_width(surface: image);
710 const int height = cairo_image_surface_get_height(surface: image);
711 const size_t rowstride_c = cairo_format_stride_for_width(format: CAIRO_FORMAT_ARGB32, width);
712 cairo_format_t format = cairo_image_surface_get_format(surface: image);
713
714 ColorSpace colorSpace;
715
716 if (format == CAIRO_FORMAT_ARGB32 || format == CAIRO_FORMAT_RGB24) {
717 colorSpace = ColorSpace::DeviceRGB;
718 bitsPerComponent = 8;
719 } else {
720 g_set_error(err: error, POPPLER_ERROR, code: POPPLER_ERROR_INVALID, format: "Invalid or unsupported cairo image type %u", (unsigned int)format);
721 return nullptr;
722 }
723
724 data = g_byte_array_sized_new(reserved_size: (guint)((width * 4) + rowstride_c) * height);
725 sMaskData = g_byte_array_sized_new(reserved_size: (guint)((width * 4) + rowstride_c) * height);
726
727 if (!get_raw_data_from_cairo_image(image, format, width, height, rowstride_c, data, soft_mask_data: sMaskData)) {
728 g_set_error(err: error, POPPLER_ERROR, code: POPPLER_ERROR_INVALID, format: "Failed to get raw data from cairo image");
729 g_byte_array_unref(array: data);
730 g_byte_array_unref(array: sMaskData);
731 return nullptr;
732 }
733
734 if (sMaskData->len > 0) {
735 AnnotStampImageHelper sMask(doc, width, height, ColorSpace::DeviceGray, 8, (char *)sMaskData->data, (int)sMaskData->len);
736 annotImg = new AnnotStampImageHelper(doc, width, height, colorSpace, bitsPerComponent, (char *)data->data, (int)data->len, sMask.getRef());
737 } else {
738 annotImg = new AnnotStampImageHelper(doc, width, height, colorSpace, bitsPerComponent, (char *)data->data, (int)data->len);
739 }
740
741 g_byte_array_unref(array: data);
742 g_byte_array_unref(array: sMaskData);
743
744 return annotImg;
745}
746
747/* Public methods */
748/**
749 * poppler_annot_get_annot_type:
750 * @poppler_annot: a #PopplerAnnot
751 *
752 * Gets the type of @poppler_annot
753 *
754 * Return value: #PopplerAnnotType of @poppler_annot.
755 **/
756PopplerAnnotType poppler_annot_get_annot_type(PopplerAnnot *poppler_annot)
757{
758 g_return_val_if_fail(POPPLER_IS_ANNOT(poppler_annot), POPPLER_ANNOT_UNKNOWN);
759
760 switch (poppler_annot->annot->getType()) {
761 case Annot::typeText:
762 return POPPLER_ANNOT_TEXT;
763 case Annot::typeLink:
764 return POPPLER_ANNOT_LINK;
765 case Annot::typeFreeText:
766 return POPPLER_ANNOT_FREE_TEXT;
767 case Annot::typeLine:
768 return POPPLER_ANNOT_LINE;
769 case Annot::typeSquare:
770 return POPPLER_ANNOT_SQUARE;
771 case Annot::typeCircle:
772 return POPPLER_ANNOT_CIRCLE;
773 case Annot::typePolygon:
774 return POPPLER_ANNOT_POLYGON;
775 case Annot::typePolyLine:
776 return POPPLER_ANNOT_POLY_LINE;
777 case Annot::typeHighlight:
778 return POPPLER_ANNOT_HIGHLIGHT;
779 case Annot::typeUnderline:
780 return POPPLER_ANNOT_UNDERLINE;
781 case Annot::typeSquiggly:
782 return POPPLER_ANNOT_SQUIGGLY;
783 case Annot::typeStrikeOut:
784 return POPPLER_ANNOT_STRIKE_OUT;
785 case Annot::typeStamp:
786 return POPPLER_ANNOT_STAMP;
787 case Annot::typeCaret:
788 return POPPLER_ANNOT_CARET;
789 case Annot::typeInk:
790 return POPPLER_ANNOT_INK;
791 case Annot::typePopup:
792 return POPPLER_ANNOT_POPUP;
793 case Annot::typeFileAttachment:
794 return POPPLER_ANNOT_FILE_ATTACHMENT;
795 case Annot::typeSound:
796 return POPPLER_ANNOT_SOUND;
797 case Annot::typeMovie:
798 return POPPLER_ANNOT_MOVIE;
799 case Annot::typeWidget:
800 return POPPLER_ANNOT_WIDGET;
801 case Annot::typeScreen:
802 return POPPLER_ANNOT_SCREEN;
803 case Annot::typePrinterMark:
804 return POPPLER_ANNOT_PRINTER_MARK;
805 case Annot::typeTrapNet:
806 return POPPLER_ANNOT_TRAP_NET;
807 case Annot::typeWatermark:
808 return POPPLER_ANNOT_WATERMARK;
809 case Annot::type3D:
810 return POPPLER_ANNOT_3D;
811 default:
812 g_warning("Unsupported Annot Type");
813 }
814
815 return POPPLER_ANNOT_UNKNOWN;
816}
817
818/**
819 * poppler_annot_get_contents:
820 * @poppler_annot: a #PopplerAnnot
821 *
822 * Retrieves the contents of @poppler_annot.
823 *
824 * Return value: a new allocated string with the contents of @poppler_annot. It
825 * must be freed with g_free() when done.
826 **/
827gchar *poppler_annot_get_contents(PopplerAnnot *poppler_annot)
828{
829 const GooString *contents;
830
831 g_return_val_if_fail(POPPLER_IS_ANNOT(poppler_annot), NULL);
832
833 contents = poppler_annot->annot->getContents();
834
835 return contents && contents->getLength() > 0 ? _poppler_goo_string_to_utf8(s: contents) : nullptr;
836}
837
838/**
839 * poppler_annot_set_contents:
840 * @poppler_annot: a #PopplerAnnot
841 * @contents: a text string containing the new contents
842 *
843 * Sets the contents of @poppler_annot to the given value,
844 * replacing the current contents.
845 *
846 * Since: 0.12
847 **/
848void poppler_annot_set_contents(PopplerAnnot *poppler_annot, const gchar *contents)
849{
850 gchar *tmp;
851 gsize length = 0;
852
853 g_return_if_fail(POPPLER_IS_ANNOT(poppler_annot));
854
855 tmp = contents ? g_convert(str: contents, len: -1, to_codeset: "UTF-16BE", from_codeset: "UTF-8", bytes_read: nullptr, bytes_written: &length, error: nullptr) : nullptr;
856 poppler_annot->annot->setContents(std::make_unique<GooString>(args&: tmp, args&: length));
857 g_free(mem: tmp);
858}
859
860/**
861 * poppler_annot_get_name:
862 * @poppler_annot: a #PopplerAnnot
863 *
864 * Retrieves the name of @poppler_annot.
865 *
866 * Return value: a new allocated string with the name of @poppler_annot. It must
867 * be freed with g_free() when done.
868 **/
869gchar *poppler_annot_get_name(PopplerAnnot *poppler_annot)
870{
871 const GooString *name;
872
873 g_return_val_if_fail(POPPLER_IS_ANNOT(poppler_annot), NULL);
874
875 name = poppler_annot->annot->getName();
876
877 return name ? _poppler_goo_string_to_utf8(s: name) : nullptr;
878}
879
880/**
881 * poppler_annot_get_modified:
882 * @poppler_annot: a #PopplerAnnot
883 *
884 * Retrieves the last modification data of @poppler_annot. The returned
885 * string will be either a PDF format date or a text string.
886 * See also #poppler_date_parse()
887 *
888 * Return value: a new allocated string with the last modification data of
889 * @poppler_annot. It must be freed with g_free() when done.
890 **/
891gchar *poppler_annot_get_modified(PopplerAnnot *poppler_annot)
892{
893 const GooString *text;
894
895 g_return_val_if_fail(POPPLER_IS_ANNOT(poppler_annot), NULL);
896
897 text = poppler_annot->annot->getModified();
898
899 return text ? _poppler_goo_string_to_utf8(s: text) : nullptr;
900}
901
902/**
903 * poppler_annot_get_flags:
904 * @poppler_annot: a #PopplerAnnot
905 *
906 * Retrieves the flag field specifying various characteristics of the
907 * @poppler_annot.
908 *
909 * Return value: the flag field of @poppler_annot.
910 **/
911PopplerAnnotFlag poppler_annot_get_flags(PopplerAnnot *poppler_annot)
912{
913 g_return_val_if_fail(POPPLER_IS_ANNOT(poppler_annot), (PopplerAnnotFlag)0);
914
915 return (PopplerAnnotFlag)poppler_annot->annot->getFlags();
916}
917
918/**
919 * poppler_annot_set_flags:
920 * @poppler_annot: a #PopplerAnnot
921 * @flags: a #PopplerAnnotFlag
922 *
923 * Sets the flag field specifying various characteristics of the
924 * @poppler_annot.
925 *
926 * Since: 0.22
927 **/
928void poppler_annot_set_flags(PopplerAnnot *poppler_annot, PopplerAnnotFlag flags)
929{
930 g_return_if_fail(POPPLER_IS_ANNOT(poppler_annot));
931
932 if (poppler_annot_get_flags(poppler_annot) == flags) {
933 return;
934 }
935
936 poppler_annot->annot->setFlags((guint)flags);
937}
938
939static PopplerColor *create_poppler_color_from_annot_color(AnnotColor *color)
940{
941 PopplerColor *poppler_color = nullptr;
942
943 if (color) {
944 const double *values = color->getValues();
945
946 switch (color->getSpace()) {
947 case AnnotColor::colorGray:
948 poppler_color = g_new(PopplerColor, 1);
949
950 poppler_color->red = (guint16)(values[0] * 65535);
951 poppler_color->green = poppler_color->red;
952 poppler_color->blue = poppler_color->red;
953
954 break;
955 case AnnotColor::colorRGB:
956 poppler_color = g_new(PopplerColor, 1);
957
958 poppler_color->red = (guint16)(values[0] * 65535);
959 poppler_color->green = (guint16)(values[1] * 65535);
960 poppler_color->blue = (guint16)(values[2] * 65535);
961
962 break;
963 case AnnotColor::colorCMYK:
964 g_warning("Unsupported Annot Color: colorCMYK");
965 case AnnotColor::colorTransparent:
966 break;
967 }
968 }
969
970 return poppler_color;
971}
972
973static std::unique_ptr<AnnotColor> create_annot_color_from_poppler_color(PopplerColor *poppler_color)
974{
975 if (!poppler_color) {
976 return nullptr;
977 }
978
979 return std::make_unique<AnnotColor>(args: (double)poppler_color->red / 65535, args: (double)poppler_color->green / 65535, args: (double)poppler_color->blue / 65535);
980}
981
982/**
983 * poppler_annot_get_color:
984 * @poppler_annot: a #PopplerAnnot
985 *
986 * Retrieves the color of @poppler_annot.
987 *
988 * Return value: a new allocated #PopplerColor with the color values of
989 * @poppler_annot, or %NULL. It must be freed with g_free() when done.
990 **/
991PopplerColor *poppler_annot_get_color(PopplerAnnot *poppler_annot)
992{
993 g_return_val_if_fail(POPPLER_IS_ANNOT(poppler_annot), NULL);
994
995 return create_poppler_color_from_annot_color(color: poppler_annot->annot->getColor());
996}
997
998/**
999 * poppler_annot_set_color:
1000 * @poppler_annot: a #PopplerAnnot
1001 * @poppler_color: (allow-none): a #PopplerColor, or %NULL
1002 *
1003 * Sets the color of @poppler_annot.
1004 *
1005 * Since: 0.16
1006 */
1007void poppler_annot_set_color(PopplerAnnot *poppler_annot, PopplerColor *poppler_color)
1008{
1009 poppler_annot->annot->setColor(create_annot_color_from_poppler_color(poppler_color));
1010}
1011
1012/**
1013 * poppler_annot_get_page_index:
1014 * @poppler_annot: a #PopplerAnnot
1015 *
1016 * Returns the page index to which @poppler_annot is associated, or -1 if unknown
1017 *
1018 * Return value: page index or -1
1019 *
1020 * Since: 0.14
1021 **/
1022gint poppler_annot_get_page_index(PopplerAnnot *poppler_annot)
1023{
1024 gint page_num;
1025
1026 g_return_val_if_fail(POPPLER_IS_ANNOT(poppler_annot), -1);
1027
1028 page_num = poppler_annot->annot->getPageNum();
1029 return page_num <= 0 ? -1 : page_num - 1;
1030}
1031
1032/* Returns cropbox rect for the page where the passed in @poppler_annot is in,
1033 * or NULL when could not retrieve the cropbox. If @page_out is non-null then
1034 * it will be set with the page that @poppler_annot is in. */
1035const PDFRectangle *_poppler_annot_get_cropbox_and_page(PopplerAnnot *poppler_annot, Page **page_out)
1036{
1037 int page_index;
1038
1039 /* A returned zero means annot is not added to any page yet */
1040 page_index = poppler_annot->annot->getPageNum();
1041
1042 if (page_index) {
1043 Page *page;
1044
1045 page = poppler_annot->annot->getDoc()->getPage(page: page_index);
1046 if (page) {
1047 if (page_out) {
1048 *page_out = page;
1049 }
1050
1051 return page->getCropBox();
1052 }
1053 }
1054
1055 return nullptr;
1056}
1057
1058/* Returns cropbox rect for the page where the passed in @poppler_annot is in,
1059 * or NULL when could not retrieve the cropbox */
1060const PDFRectangle *_poppler_annot_get_cropbox(PopplerAnnot *poppler_annot)
1061{
1062 return _poppler_annot_get_cropbox_and_page(poppler_annot, page_out: nullptr);
1063}
1064
1065/**
1066 * poppler_annot_get_rectangle:
1067 * @poppler_annot: a #PopplerAnnot
1068 * @poppler_rect: (out): a #PopplerRectangle to store the annotation's coordinates
1069 *
1070 * Retrieves the rectangle representing the page coordinates where the
1071 * annotation @poppler_annot is placed.
1072 *
1073 * Since: 0.26
1074 */
1075void poppler_annot_get_rectangle(PopplerAnnot *poppler_annot, PopplerRectangle *poppler_rect)
1076{
1077 const PDFRectangle *crop_box;
1078 PDFRectangle zerobox;
1079 Page *page = nullptr;
1080
1081 g_return_if_fail(POPPLER_IS_ANNOT(poppler_annot));
1082 g_return_if_fail(poppler_rect != nullptr);
1083
1084 crop_box = _poppler_annot_get_cropbox_and_page(poppler_annot, page_out: &page);
1085 if (!crop_box) {
1086 zerobox = PDFRectangle();
1087 crop_box = &zerobox;
1088 }
1089
1090 const PDFRectangle &annot_rect = poppler_annot->annot->getRect();
1091 poppler_rect->x1 = annot_rect.x1 - crop_box->x1;
1092 poppler_rect->x2 = annot_rect.x2 - crop_box->x1;
1093 poppler_rect->y1 = annot_rect.y1 - crop_box->y1;
1094 poppler_rect->y2 = annot_rect.y2 - crop_box->y1;
1095}
1096
1097/**
1098 * poppler_annot_set_rectangle:
1099 * @poppler_annot: a #PopplerAnnot
1100 * @poppler_rect: a #PopplerRectangle with the new annotation's coordinates
1101 *
1102 * Move the annotation to the rectangle representing the page coordinates
1103 * where the annotation @poppler_annot should be placed.
1104 *
1105 * Since: 0.26
1106 */
1107void poppler_annot_set_rectangle(PopplerAnnot *poppler_annot, PopplerRectangle *poppler_rect)
1108{
1109 const PDFRectangle *crop_box;
1110 PDFRectangle zerobox;
1111 double x1, y1, x2, y2;
1112 Page *page = nullptr;
1113
1114 g_return_if_fail(POPPLER_IS_ANNOT(poppler_annot));
1115 g_return_if_fail(poppler_rect != nullptr);
1116
1117 crop_box = _poppler_annot_get_cropbox_and_page(poppler_annot, page_out: &page);
1118 if (!crop_box) {
1119 zerobox = PDFRectangle();
1120 crop_box = &zerobox;
1121 }
1122
1123 x1 = poppler_rect->x1;
1124 y1 = poppler_rect->y1;
1125 x2 = poppler_rect->x2;
1126 y2 = poppler_rect->y2;
1127
1128 if (page && SUPPORTED_ROTATION(page->getRotate())) {
1129 /* annot is inside a rotated page, as core poppler rect must be saved
1130 * un-rotated, let's proceed to un-rotate rect before saving */
1131 _unrotate_rect_for_annot_and_page(page, annot: poppler_annot->annot, x1: &x1, y1: &y1, x2: &x2, y2: &y2);
1132 }
1133
1134 poppler_annot->annot->setRect(x1: x1 + crop_box->x1, y1: y1 + crop_box->y1, x2: x2 + crop_box->x1, y2: y2 + crop_box->y1);
1135}
1136
1137/* PopplerAnnotMarkup */
1138/**
1139 * poppler_annot_markup_get_label:
1140 * @poppler_annot: a #PopplerAnnotMarkup
1141 *
1142 * Retrieves the label text of @poppler_annot.
1143 *
1144 * Return value: the label text of @poppler_annot.
1145 */
1146gchar *poppler_annot_markup_get_label(PopplerAnnotMarkup *poppler_annot)
1147{
1148 AnnotMarkup *annot;
1149 const GooString *text;
1150
1151 g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), NULL);
1152
1153 annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
1154
1155 text = annot->getLabel();
1156
1157 return text ? _poppler_goo_string_to_utf8(s: text) : nullptr;
1158}
1159
1160/**
1161 * poppler_annot_markup_set_label:
1162 * @poppler_annot: a #PopplerAnnotMarkup
1163 * @label: (allow-none): a text string containing the new label, or %NULL
1164 *
1165 * Sets the label text of @poppler_annot, replacing the current one
1166 *
1167 * Since: 0.16
1168 */
1169void poppler_annot_markup_set_label(PopplerAnnotMarkup *poppler_annot, const gchar *label)
1170{
1171 AnnotMarkup *annot;
1172 gchar *tmp;
1173 gsize length = 0;
1174
1175 g_return_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot));
1176
1177 annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
1178
1179 tmp = label ? g_convert(str: label, len: -1, to_codeset: "UTF-16BE", from_codeset: "UTF-8", bytes_read: nullptr, bytes_written: &length, error: nullptr) : nullptr;
1180 annot->setLabel(std::make_unique<GooString>(args&: tmp, args&: length));
1181 g_free(mem: tmp);
1182}
1183
1184/**
1185 * poppler_annot_markup_has_popup:
1186 * @poppler_annot: a #PopplerAnnotMarkup
1187 *
1188 * Return %TRUE if the markup annotation has a popup window associated
1189 *
1190 * Return value: %TRUE, if @poppler_annot has popup, %FALSE otherwise
1191 *
1192 * Since: 0.12
1193 **/
1194gboolean poppler_annot_markup_has_popup(PopplerAnnotMarkup *poppler_annot)
1195{
1196 AnnotMarkup *annot;
1197
1198 g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), FALSE);
1199
1200 annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
1201
1202 return annot->getPopup() != nullptr;
1203}
1204
1205/**
1206 * poppler_annot_markup_set_popup:
1207 * @poppler_annot: a #PopplerAnnotMarkup
1208 * @popup_rect: a #PopplerRectangle
1209 *
1210 * Associates a new popup window for editing contents of @poppler_annot.
1211 * Popup window shall be displayed by viewers at @popup_rect on the page.
1212 *
1213 * Since: 0.16
1214 */
1215void poppler_annot_markup_set_popup(PopplerAnnotMarkup *poppler_annot, PopplerRectangle *popup_rect)
1216{
1217 AnnotMarkup *annot;
1218 PDFRectangle pdf_rect(popup_rect->x1, popup_rect->y1, popup_rect->x2, popup_rect->y2);
1219
1220 g_return_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot));
1221
1222 annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
1223 annot->setPopup(std::make_unique<AnnotPopup>(args: annot->getDoc(), args: &pdf_rect));
1224}
1225
1226/**
1227 * poppler_annot_markup_get_popup_is_open:
1228 * @poppler_annot: a #PopplerAnnotMarkup
1229 *
1230 * Retrieves the state of the popup window related to @poppler_annot.
1231 *
1232 * Return value: the state of @poppler_annot. %TRUE if it's open, %FALSE in
1233 * other case.
1234 **/
1235gboolean poppler_annot_markup_get_popup_is_open(PopplerAnnotMarkup *poppler_annot)
1236{
1237 AnnotMarkup *annot;
1238 AnnotPopup *annot_popup;
1239
1240 g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), FALSE);
1241
1242 annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
1243
1244 if ((annot_popup = annot->getPopup())) {
1245 return annot_popup->getOpen();
1246 }
1247
1248 return FALSE;
1249}
1250
1251/**
1252 * poppler_annot_markup_set_popup_is_open:
1253 * @poppler_annot: a #PopplerAnnotMarkup
1254 * @is_open: whether popup window should initially be displayed open
1255 *
1256 * Sets the state of the popup window related to @poppler_annot.
1257 *
1258 * Since: 0.16
1259 **/
1260void poppler_annot_markup_set_popup_is_open(PopplerAnnotMarkup *poppler_annot, gboolean is_open)
1261{
1262 AnnotMarkup *annot;
1263 AnnotPopup *annot_popup;
1264
1265 g_return_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot));
1266
1267 annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
1268
1269 annot_popup = annot->getPopup();
1270 if (!annot_popup) {
1271 return;
1272 }
1273
1274 if (annot_popup->getOpen() != is_open) {
1275 annot_popup->setOpen(is_open);
1276 }
1277}
1278
1279/**
1280 * poppler_annot_markup_get_popup_rectangle:
1281 * @poppler_annot: a #PopplerAnnotMarkup
1282 * @poppler_rect: (out): a #PopplerRectangle to store the popup rectangle
1283 *
1284 * Retrieves the rectangle of the popup window related to @poppler_annot.
1285 *
1286 * Return value: %TRUE if #PopplerRectangle was correctly filled, %FALSE otherwise
1287 *
1288 * Since: 0.12
1289 **/
1290gboolean poppler_annot_markup_get_popup_rectangle(PopplerAnnotMarkup *poppler_annot, PopplerRectangle *poppler_rect)
1291{
1292 AnnotMarkup *annot;
1293 Annot *annot_popup;
1294
1295 g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), FALSE);
1296 g_return_val_if_fail(poppler_rect != nullptr, FALSE);
1297
1298 annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
1299 annot_popup = annot->getPopup();
1300 if (!annot_popup) {
1301 return FALSE;
1302 }
1303
1304 const PDFRectangle &annot_rect = annot_popup->getRect();
1305 poppler_rect->x1 = annot_rect.x1;
1306 poppler_rect->x2 = annot_rect.x2;
1307 poppler_rect->y1 = annot_rect.y1;
1308 poppler_rect->y2 = annot_rect.y2;
1309
1310 return TRUE;
1311}
1312
1313/**
1314 * poppler_annot_markup_set_popup_rectangle:
1315 * @poppler_annot: a #PopplerAnnotMarkup
1316 * @poppler_rect: a #PopplerRectangle to set
1317 *
1318 * Sets the rectangle of the popup window related to @poppler_annot.
1319 * This doesn't have any effect if @poppler_annot doesn't have a
1320 * popup associated, use poppler_annot_markup_set_popup() to associate
1321 * a popup window to a #PopplerAnnotMarkup.
1322 *
1323 * Since: 0.33
1324 */
1325void poppler_annot_markup_set_popup_rectangle(PopplerAnnotMarkup *poppler_annot, PopplerRectangle *poppler_rect)
1326{
1327 AnnotMarkup *annot;
1328 Annot *annot_popup;
1329
1330 g_return_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot));
1331 g_return_if_fail(poppler_rect != nullptr);
1332
1333 annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
1334 annot_popup = annot->getPopup();
1335 if (!annot_popup) {
1336 return;
1337 }
1338
1339 annot_popup->setRect(x1: poppler_rect->x1, y1: poppler_rect->y1, x2: poppler_rect->x2, y2: poppler_rect->y2);
1340}
1341
1342/**
1343 * poppler_annot_markup_get_opacity:
1344 * @poppler_annot: a #PopplerAnnotMarkup
1345 *
1346 * Retrieves the opacity value of @poppler_annot.
1347 *
1348 * Return value: the opacity value of @poppler_annot,
1349 * between 0 (transparent) and 1 (opaque)
1350 */
1351gdouble poppler_annot_markup_get_opacity(PopplerAnnotMarkup *poppler_annot)
1352{
1353 AnnotMarkup *annot;
1354
1355 g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), 0);
1356
1357 annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
1358
1359 return annot->getOpacity();
1360}
1361
1362/**
1363 * poppler_annot_markup_set_opacity:
1364 * @poppler_annot: a #PopplerAnnotMarkup
1365 * @opacity: a constant opacity value, between 0 (transparent) and 1 (opaque)
1366 *
1367 * Sets the opacity of @poppler_annot. This value applies to
1368 * all visible elements of @poppler_annot in its closed state,
1369 * but not to the pop-up window that appears when it's openened
1370 *
1371 * Since: 0.16
1372 */
1373void poppler_annot_markup_set_opacity(PopplerAnnotMarkup *poppler_annot, gdouble opacity)
1374{
1375 AnnotMarkup *annot;
1376
1377 g_return_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot));
1378
1379 annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
1380 annot->setOpacity(opacity);
1381}
1382
1383/**
1384 * poppler_annot_markup_get_date:
1385 * @poppler_annot: a #PopplerAnnotMarkup
1386 *
1387 * Returns the date and time when the annotation was created
1388 *
1389 * Return value: (transfer full): a #GDate representing the date and time
1390 * when the annotation was created, or %NULL
1391 */
1392GDate *poppler_annot_markup_get_date(PopplerAnnotMarkup *poppler_annot)
1393{
1394 AnnotMarkup *annot;
1395 const GooString *annot_date;
1396 time_t timet;
1397
1398 g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), NULL);
1399
1400 annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
1401 annot_date = annot->getDate();
1402 if (!annot_date) {
1403 return nullptr;
1404 }
1405
1406 if (_poppler_convert_pdf_date_to_gtime(date: annot_date, gdate: &timet)) {
1407 GDate *date;
1408
1409 date = g_date_new();
1410 g_date_set_time_t(date, timet);
1411
1412 return date;
1413 }
1414
1415 return nullptr;
1416}
1417
1418/**
1419 * poppler_annot_markup_get_subject:
1420 * @poppler_annot: a #PopplerAnnotMarkup
1421 *
1422 * Retrives the subject text of @poppler_annot.
1423 *
1424 * Return value: the subject text of @poppler_annot.
1425 */
1426gchar *poppler_annot_markup_get_subject(PopplerAnnotMarkup *poppler_annot)
1427{
1428 AnnotMarkup *annot;
1429 const GooString *text;
1430
1431 g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), NULL);
1432
1433 annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
1434
1435 text = annot->getSubject();
1436
1437 return text ? _poppler_goo_string_to_utf8(s: text) : nullptr;
1438}
1439
1440/**
1441 * poppler_annot_markup_get_reply_to:
1442 * @poppler_annot: a #PopplerAnnotMarkup
1443 *
1444 * Gets the reply type of @poppler_annot.
1445 *
1446 * Return value: #PopplerAnnotMarkupReplyType of @poppler_annot.
1447 */
1448PopplerAnnotMarkupReplyType poppler_annot_markup_get_reply_to(PopplerAnnotMarkup *poppler_annot)
1449{
1450 AnnotMarkup *annot;
1451
1452 g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), POPPLER_ANNOT_MARKUP_REPLY_TYPE_R);
1453
1454 annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
1455
1456 switch (annot->getReplyTo()) {
1457 case AnnotMarkup::replyTypeR:
1458 return POPPLER_ANNOT_MARKUP_REPLY_TYPE_R;
1459 case AnnotMarkup::replyTypeGroup:
1460 return POPPLER_ANNOT_MARKUP_REPLY_TYPE_GROUP;
1461 default:
1462 g_warning("Unsupported Annot Markup Reply To Type");
1463 }
1464
1465 return POPPLER_ANNOT_MARKUP_REPLY_TYPE_R;
1466}
1467
1468/**
1469 * poppler_annot_markup_get_external_data:
1470 * @poppler_annot: a #PopplerAnnotMarkup
1471 *
1472 * Gets the external data type of @poppler_annot.
1473 *
1474 * Return value: #PopplerAnnotExternalDataType of @poppler_annot.
1475 */
1476PopplerAnnotExternalDataType poppler_annot_markup_get_external_data(PopplerAnnotMarkup *poppler_annot)
1477{
1478 AnnotMarkup *annot;
1479
1480 g_return_val_if_fail(POPPLER_IS_ANNOT_MARKUP(poppler_annot), POPPLER_ANNOT_EXTERNAL_DATA_MARKUP_UNKNOWN);
1481
1482 annot = static_cast<AnnotMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
1483
1484 switch (annot->getExData()) {
1485 case annotExternalDataMarkup3D:
1486 return POPPLER_ANNOT_EXTERNAL_DATA_MARKUP_3D;
1487 case annotExternalDataMarkupUnknown:
1488 return POPPLER_ANNOT_EXTERNAL_DATA_MARKUP_UNKNOWN;
1489 default:
1490 g_warning("Unsupported Annot Markup External Data");
1491 }
1492
1493 return POPPLER_ANNOT_EXTERNAL_DATA_MARKUP_UNKNOWN;
1494}
1495
1496/* PopplerAnnotText */
1497/**
1498 * poppler_annot_text_get_is_open:
1499 * @poppler_annot: a #PopplerAnnotText
1500 *
1501 * Retrieves the state of @poppler_annot.
1502 *
1503 * Return value: the state of @poppler_annot. %TRUE if it's open, %FALSE in
1504 * other case.
1505 **/
1506gboolean poppler_annot_text_get_is_open(PopplerAnnotText *poppler_annot)
1507{
1508 AnnotText *annot;
1509
1510 g_return_val_if_fail(POPPLER_IS_ANNOT_TEXT(poppler_annot), FALSE);
1511
1512 annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot);
1513
1514 return annot->getOpen();
1515}
1516
1517/**
1518 * poppler_annot_text_set_is_open:
1519 * @poppler_annot: a #PopplerAnnotText
1520 * @is_open: whether annotation should initially be displayed open
1521 *
1522 * Sets whether @poppler_annot should initially be displayed open
1523 *
1524 * Since: 0.16
1525 */
1526void poppler_annot_text_set_is_open(PopplerAnnotText *poppler_annot, gboolean is_open)
1527{
1528 AnnotText *annot;
1529
1530 g_return_if_fail(POPPLER_IS_ANNOT_TEXT(poppler_annot));
1531
1532 annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot);
1533 annot->setOpen(is_open);
1534}
1535
1536/**
1537 * poppler_annot_text_get_icon:
1538 * @poppler_annot: a #PopplerAnnotText
1539 *
1540 * Gets name of the icon of @poppler_annot.
1541 *
1542 * Return value: a new allocated string containing the icon name
1543 */
1544gchar *poppler_annot_text_get_icon(PopplerAnnotText *poppler_annot)
1545{
1546 AnnotText *annot;
1547 const GooString *text;
1548
1549 g_return_val_if_fail(POPPLER_IS_ANNOT_TEXT(poppler_annot), NULL);
1550
1551 annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot);
1552
1553 text = annot->getIcon();
1554
1555 return text ? _poppler_goo_string_to_utf8(s: text) : nullptr;
1556}
1557
1558/**
1559 * poppler_annot_text_set_icon:
1560 * @poppler_annot: a #PopplerAnnotText
1561 * @icon: the name of an icon
1562 *
1563 * Sets the icon of @poppler_annot. The following predefined
1564 * icons are currently supported:
1565 * <variablelist>
1566 * <varlistentry>
1567 * <term>#POPPLER_ANNOT_TEXT_ICON_NOTE</term>
1568 * </varlistentry>
1569 * <varlistentry>
1570 * <term>#POPPLER_ANNOT_TEXT_ICON_COMMENT</term>
1571 * </varlistentry>
1572 * <varlistentry>
1573 * <term>#POPPLER_ANNOT_TEXT_ICON_KEY</term>
1574 * </varlistentry>
1575 * <varlistentry>
1576 * <term>#POPPLER_ANNOT_TEXT_ICON_HELP</term>
1577 * </varlistentry>
1578 * <varlistentry>
1579 * <term>#POPPLER_ANNOT_TEXT_ICON_NEW_PARAGRAPH</term>
1580 * </varlistentry>
1581 * <varlistentry>
1582 * <term>#POPPLER_ANNOT_TEXT_ICON_PARAGRAPH</term>
1583 * </varlistentry>
1584 * <varlistentry>
1585 * <term>#POPPLER_ANNOT_TEXT_ICON_INSERT</term>
1586 * </varlistentry>
1587 * <varlistentry>
1588 * <term>#POPPLER_ANNOT_TEXT_ICON_CROSS</term>
1589 * </varlistentry>
1590 * <varlistentry>
1591 * <term>#POPPLER_ANNOT_TEXT_ICON_CIRCLE</term>
1592 * </varlistentry>
1593 * </variablelist>
1594 *
1595 * Since: 0.16
1596 */
1597void poppler_annot_text_set_icon(PopplerAnnotText *poppler_annot, const gchar *icon)
1598{
1599 AnnotText *annot;
1600 GooString *text;
1601
1602 g_return_if_fail(POPPLER_IS_ANNOT_TEXT(poppler_annot));
1603
1604 annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot);
1605
1606 text = new GooString(icon);
1607 annot->setIcon(text);
1608 delete text;
1609}
1610
1611/**
1612 * poppler_annot_text_get_state:
1613 * @poppler_annot: a #PopplerAnnotText
1614 *
1615 * Retrieves the state of @poppler_annot.
1616 *
1617 * Return value: #PopplerAnnotTextState of @poppler_annot.
1618 **/
1619PopplerAnnotTextState poppler_annot_text_get_state(PopplerAnnotText *poppler_annot)
1620{
1621 AnnotText *annot;
1622
1623 g_return_val_if_fail(POPPLER_IS_ANNOT_TEXT(poppler_annot), POPPLER_ANNOT_TEXT_STATE_UNKNOWN);
1624
1625 annot = static_cast<AnnotText *>(POPPLER_ANNOT(poppler_annot)->annot);
1626
1627 switch (annot->getState()) {
1628 case AnnotText::stateUnknown:
1629 return POPPLER_ANNOT_TEXT_STATE_UNKNOWN;
1630 case AnnotText::stateMarked:
1631 return POPPLER_ANNOT_TEXT_STATE_MARKED;
1632 case AnnotText::stateUnmarked:
1633 return POPPLER_ANNOT_TEXT_STATE_UNMARKED;
1634 case AnnotText::stateAccepted:
1635 return POPPLER_ANNOT_TEXT_STATE_ACCEPTED;
1636 case AnnotText::stateRejected:
1637 return POPPLER_ANNOT_TEXT_STATE_REJECTED;
1638 case AnnotText::stateCancelled:
1639 return POPPLER_ANNOT_TEXT_STATE_CANCELLED;
1640 case AnnotText::stateCompleted:
1641 return POPPLER_ANNOT_TEXT_STATE_COMPLETED;
1642 case AnnotText::stateNone:
1643 return POPPLER_ANNOT_TEXT_STATE_NONE;
1644 default:
1645 g_warning("Unsupported Annot Text State");
1646 }
1647
1648 return POPPLER_ANNOT_TEXT_STATE_UNKNOWN;
1649}
1650
1651/* PopplerAnnotTextMarkup */
1652/**
1653 * poppler_annot_text_markup_set_quadrilaterals:
1654 * @poppler_annot: A #PopplerAnnotTextMarkup
1655 * @quadrilaterals: (element-type PopplerQuadrilateral): A #GArray of
1656 * #PopplerQuadrilateral<!-- -->s
1657 *
1658 * Set the regions (Quadrilaterals) to apply the text markup in @poppler_annot.
1659 *
1660 * Since: 0.26
1661 **/
1662void poppler_annot_text_markup_set_quadrilaterals(PopplerAnnotTextMarkup *poppler_annot, GArray *quadrilaterals)
1663{
1664 AnnotQuadrilaterals *quads, *quads_temp;
1665 AnnotTextMarkup *annot;
1666 const PDFRectangle *crop_box;
1667 Page *page = nullptr;
1668
1669 g_return_if_fail(POPPLER_IS_ANNOT_TEXT_MARKUP(poppler_annot));
1670 g_return_if_fail(quadrilaterals != nullptr && quadrilaterals->len > 0);
1671
1672 annot = static_cast<AnnotTextMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
1673 crop_box = _poppler_annot_get_cropbox_and_page(POPPLER_ANNOT(poppler_annot), page_out: &page);
1674 quads = create_annot_quads_from_poppler_quads(quads: quadrilaterals);
1675
1676 if (page && SUPPORTED_ROTATION(page->getRotate())) {
1677 quads_temp = _page_new_quads_unrotated(page, quads);
1678 delete quads;
1679 quads = quads_temp;
1680 }
1681
1682 if (!ZERO_CROPBOX(crop_box)) {
1683 quads_temp = quads;
1684 quads = new_quads_from_offset_cropbox(crop_box, quads, TRUE);
1685 delete quads_temp;
1686 }
1687
1688 annot->setQuadrilaterals(quads);
1689 delete quads;
1690}
1691
1692/**
1693 * poppler_annot_text_markup_get_quadrilaterals:
1694 * @poppler_annot: A #PopplerAnnotTextMarkup
1695 *
1696 * Returns a #GArray of #PopplerQuadrilateral items that map from a
1697 * location on @page to a #PopplerAnnotTextMarkup. This array must be freed
1698 * when done.
1699 *
1700 * Return value: (element-type PopplerQuadrilateral) (transfer full): A #GArray of #PopplerQuadrilateral
1701 *
1702 * Since: 0.26
1703 **/
1704GArray *poppler_annot_text_markup_get_quadrilaterals(PopplerAnnotTextMarkup *poppler_annot)
1705{
1706 const PDFRectangle *crop_box;
1707 AnnotTextMarkup *annot;
1708
1709 g_return_val_if_fail(POPPLER_IS_ANNOT_TEXT_MARKUP(poppler_annot), NULL);
1710
1711 annot = static_cast<AnnotTextMarkup *>(POPPLER_ANNOT(poppler_annot)->annot);
1712 crop_box = _poppler_annot_get_cropbox(POPPLER_ANNOT(poppler_annot));
1713 AnnotQuadrilaterals *quads = annot->getQuadrilaterals();
1714
1715 return create_poppler_quads_from_annot_quads(quads_array: quads, crop_box);
1716}
1717
1718/* PopplerAnnotFreeText */
1719/**
1720 * poppler_annot_free_text_get_quadding:
1721 * @poppler_annot: a #PopplerAnnotFreeText
1722 *
1723 * Retrieves the justification of the text of @poppler_annot.
1724 *
1725 * Return value: #PopplerAnnotFreeTextQuadding of @poppler_annot.
1726 **/
1727PopplerAnnotFreeTextQuadding poppler_annot_free_text_get_quadding(PopplerAnnotFreeText *poppler_annot)
1728{
1729 AnnotFreeText *annot;
1730
1731 g_return_val_if_fail(POPPLER_IS_ANNOT_FREE_TEXT(poppler_annot), POPPLER_ANNOT_FREE_TEXT_QUADDING_LEFT_JUSTIFIED);
1732
1733 annot = static_cast<AnnotFreeText *>(POPPLER_ANNOT(poppler_annot)->annot);
1734
1735 switch (annot->getQuadding()) {
1736 case VariableTextQuadding::leftJustified:
1737 return POPPLER_ANNOT_FREE_TEXT_QUADDING_LEFT_JUSTIFIED;
1738 case VariableTextQuadding::centered:
1739 return POPPLER_ANNOT_FREE_TEXT_QUADDING_CENTERED;
1740 case VariableTextQuadding::rightJustified:
1741 return POPPLER_ANNOT_FREE_TEXT_QUADDING_RIGHT_JUSTIFIED;
1742 default:
1743 g_warning("Unsupported Annot Free Text Quadding");
1744 }
1745
1746 return POPPLER_ANNOT_FREE_TEXT_QUADDING_LEFT_JUSTIFIED;
1747}
1748
1749/**
1750 * poppler_annot_free_text_get_callout_line:
1751 * @poppler_annot: a #PopplerAnnotFreeText
1752 *
1753 * Retrieves a #PopplerAnnotCalloutLine of four or six numbers specifying a callout
1754 * line attached to the @poppler_annot.
1755 *
1756 * Return value: a new allocated #PopplerAnnotCalloutLine if the annot has a callout
1757 * line, %NULL in other case. It must be freed with g_free() when
1758 * done.
1759 **/
1760PopplerAnnotCalloutLine *poppler_annot_free_text_get_callout_line(PopplerAnnotFreeText *poppler_annot)
1761{
1762 AnnotFreeText *annot;
1763 AnnotCalloutLine *line;
1764
1765 g_return_val_if_fail(POPPLER_IS_ANNOT_FREE_TEXT(poppler_annot), NULL);
1766
1767 annot = static_cast<AnnotFreeText *>(POPPLER_ANNOT(poppler_annot)->annot);
1768
1769 if ((line = annot->getCalloutLine())) {
1770 AnnotCalloutMultiLine *multiline;
1771 PopplerAnnotCalloutLine *callout = g_new0(PopplerAnnotCalloutLine, 1);
1772
1773 callout->x1 = line->getX1();
1774 callout->y1 = line->getY1();
1775 callout->x2 = line->getX2();
1776 callout->y2 = line->getY2();
1777
1778 if ((multiline = dynamic_cast<AnnotCalloutMultiLine *>(line))) {
1779 callout->multiline = TRUE;
1780 callout->x3 = multiline->getX3();
1781 callout->y3 = multiline->getY3();
1782 return callout;
1783 }
1784
1785 callout->multiline = FALSE;
1786 return callout;
1787 }
1788
1789 return nullptr;
1790}
1791
1792/* PopplerAnnotFileAttachment */
1793/**
1794 * poppler_annot_file_attachment_get_attachment:
1795 * @poppler_annot: a #PopplerAnnotFileAttachment
1796 *
1797 * Creates a #PopplerAttachment for the file of the file attachment annotation @annot.
1798 * The #PopplerAttachment must be unrefed with g_object_unref by the caller.
1799 *
1800 * Return value: (transfer full): @PopplerAttachment
1801 *
1802 * Since: 0.14
1803 **/
1804PopplerAttachment *poppler_annot_file_attachment_get_attachment(PopplerAnnotFileAttachment *poppler_annot)
1805{
1806 AnnotFileAttachment *annot;
1807 PopplerAttachment *attachment;
1808
1809 g_return_val_if_fail(POPPLER_IS_ANNOT_FILE_ATTACHMENT(poppler_annot), NULL);
1810
1811 annot = static_cast<AnnotFileAttachment *>(POPPLER_ANNOT(poppler_annot)->annot);
1812
1813 FileSpec *file = new FileSpec(annot->getFile());
1814 attachment = _poppler_attachment_new(file);
1815 delete file;
1816
1817 return attachment;
1818}
1819
1820/**
1821 * poppler_annot_file_attachment_get_name:
1822 * @poppler_annot: a #PopplerAnnotFileAttachment
1823 *
1824 * Retrieves the name of @poppler_annot.
1825 *
1826 * Return value: a new allocated string with the name of @poppler_annot. It must
1827 * be freed with g_free() when done.
1828 * Since: 0.14
1829 **/
1830gchar *poppler_annot_file_attachment_get_name(PopplerAnnotFileAttachment *poppler_annot)
1831{
1832 AnnotFileAttachment *annot;
1833 const GooString *name;
1834
1835 g_return_val_if_fail(POPPLER_IS_ANNOT_FILE_ATTACHMENT(poppler_annot), NULL);
1836
1837 annot = static_cast<AnnotFileAttachment *>(POPPLER_ANNOT(poppler_annot)->annot);
1838 name = annot->getName();
1839
1840 return name ? _poppler_goo_string_to_utf8(s: name) : nullptr;
1841}
1842
1843/* PopplerAnnotCalloutLine */
1844G_DEFINE_BOXED_TYPE(PopplerAnnotCalloutLine, poppler_annot_callout_line, poppler_annot_callout_line_copy, poppler_annot_callout_line_free)
1845
1846/**
1847 * poppler_annot_callout_line_new:
1848 *
1849 * Creates a new empty #PopplerAnnotCalloutLine.
1850 *
1851 * Return value: a new allocated #PopplerAnnotCalloutLine, %NULL in other case.
1852 * It must be freed when done.
1853 **/
1854PopplerAnnotCalloutLine *poppler_annot_callout_line_new(void)
1855{
1856 return g_new0(PopplerAnnotCalloutLine, 1);
1857}
1858
1859/**
1860 * poppler_annot_callout_line_copy:
1861 * @callout: the #PopplerAnnotCalloutLine to be copied.
1862 *
1863 * It does copy @callout to a new #PopplerAnnotCalloutLine.
1864 *
1865 * Return value: a new allocated #PopplerAnnotCalloutLine as exact copy of
1866 * @callout, %NULL in other case. It must be freed when done.
1867 **/
1868PopplerAnnotCalloutLine *poppler_annot_callout_line_copy(PopplerAnnotCalloutLine *callout)
1869{
1870 PopplerAnnotCalloutLine *new_callout;
1871
1872 g_return_val_if_fail(callout != nullptr, NULL);
1873
1874 new_callout = g_new0(PopplerAnnotCalloutLine, 1);
1875 *new_callout = *callout;
1876
1877 return new_callout;
1878}
1879
1880/**
1881 * poppler_annot_callout_line_free:
1882 * @callout: a #PopplerAnnotCalloutLine
1883 *
1884 * Frees the memory used by #PopplerAnnotCalloutLine.
1885 **/
1886void poppler_annot_callout_line_free(PopplerAnnotCalloutLine *callout)
1887{
1888 g_free(mem: callout);
1889}
1890
1891/* PopplerAnnotMovie */
1892/**
1893 * poppler_annot_movie_get_title:
1894 * @poppler_annot: a #PopplerAnnotMovie
1895 *
1896 * Retrieves the movie title of @poppler_annot.
1897 *
1898 * Return value: the title text of @poppler_annot.
1899 *
1900 * Since: 0.14
1901 */
1902gchar *poppler_annot_movie_get_title(PopplerAnnotMovie *poppler_annot)
1903{
1904 AnnotMovie *annot;
1905 const GooString *title;
1906
1907 g_return_val_if_fail(POPPLER_IS_ANNOT_MOVIE(poppler_annot), NULL);
1908
1909 annot = static_cast<AnnotMovie *>(POPPLER_ANNOT(poppler_annot)->annot);
1910
1911 title = annot->getTitle();
1912
1913 return title ? _poppler_goo_string_to_utf8(s: title) : nullptr;
1914}
1915
1916/**
1917 * poppler_annot_movie_get_movie:
1918 * @poppler_annot: a #PopplerAnnotMovie
1919 *
1920 * Retrieves the movie object (PopplerMovie) stored in the @poppler_annot.
1921 *
1922 * Return value: (transfer none): the movie object stored in the @poppler_annot. The returned
1923 * object is owned by #PopplerAnnotMovie and should not be freed
1924 *
1925 * Since: 0.14
1926 */
1927PopplerMovie *poppler_annot_movie_get_movie(PopplerAnnotMovie *poppler_annot)
1928{
1929 return poppler_annot->movie;
1930}
1931
1932/* PopplerAnnotScreen */
1933/**
1934 * poppler_annot_screen_get_action:
1935 * @poppler_annot: a #PopplerAnnotScreen
1936 *
1937 * Retrieves the action (#PopplerAction) that shall be performed when @poppler_annot is activated
1938 *
1939 * Return value: (transfer none): the action to perform. The returned
1940 * object is owned by @poppler_annot and should not be freed
1941 *
1942 * Since: 0.14
1943 */
1944PopplerAction *poppler_annot_screen_get_action(PopplerAnnotScreen *poppler_annot)
1945{
1946 return poppler_annot->action;
1947}
1948
1949/* PopplerAnnotLine */
1950/**
1951 * poppler_annot_line_set_vertices:
1952 * @poppler_annot: a #PopplerAnnotLine
1953 * @start: a #PopplerPoint of the starting vertice
1954 * @end: a #PopplerPoint of the ending vertice
1955 *
1956 * Set the coordinate points where the @poppler_annot starts and ends.
1957 *
1958 * Since: 0.26
1959 */
1960void poppler_annot_line_set_vertices(PopplerAnnotLine *poppler_annot, PopplerPoint *start, PopplerPoint *end)
1961{
1962 AnnotLine *annot;
1963
1964 g_return_if_fail(POPPLER_IS_ANNOT_LINE(poppler_annot));
1965 g_return_if_fail(start != nullptr);
1966 g_return_if_fail(end != nullptr);
1967
1968 annot = static_cast<AnnotLine *>(POPPLER_ANNOT(poppler_annot)->annot);
1969 annot->setVertices(x1: start->x, y1: start->y, x2: end->x, y2: end->y);
1970}
1971
1972/* PopplerAnnotCircle and PopplerAnnotSquare helpers */
1973static PopplerColor *poppler_annot_geometry_get_interior_color(PopplerAnnot *poppler_annot)
1974{
1975 AnnotGeometry *annot;
1976
1977 annot = static_cast<AnnotGeometry *>(POPPLER_ANNOT(poppler_annot)->annot);
1978
1979 return create_poppler_color_from_annot_color(color: annot->getInteriorColor());
1980}
1981
1982static void poppler_annot_geometry_set_interior_color(PopplerAnnot *poppler_annot, PopplerColor *poppler_color)
1983{
1984 AnnotGeometry *annot;
1985
1986 annot = static_cast<AnnotGeometry *>(POPPLER_ANNOT(poppler_annot)->annot);
1987
1988 annot->setInteriorColor(create_annot_color_from_poppler_color(poppler_color));
1989}
1990
1991/* PopplerAnnotCircle */
1992/**
1993 * poppler_annot_circle_get_interior_color:
1994 * @poppler_annot: a #PopplerAnnotCircle
1995 *
1996 * Retrieves the interior color of @poppler_annot.
1997 *
1998 * Return value: a new allocated #PopplerColor with the color values of
1999 * @poppler_annot, or %NULL. It must be freed with g_free() when done.
2000 *
2001 * Since: 0.26
2002 */
2003PopplerColor *poppler_annot_circle_get_interior_color(PopplerAnnotCircle *poppler_annot)
2004{
2005 g_return_val_if_fail(POPPLER_IS_ANNOT_CIRCLE(poppler_annot), NULL);
2006
2007 return poppler_annot_geometry_get_interior_color(POPPLER_ANNOT(poppler_annot));
2008}
2009
2010/**
2011 * poppler_annot_circle_set_interior_color:
2012 * @poppler_annot: a #PopplerAnnotCircle
2013 * @poppler_color: (allow-none): a #PopplerColor, or %NULL
2014 *
2015 * Sets the interior color of @poppler_annot.
2016 *
2017 * Since: 0.26
2018 */
2019void poppler_annot_circle_set_interior_color(PopplerAnnotCircle *poppler_annot, PopplerColor *poppler_color)
2020{
2021 g_return_if_fail(POPPLER_IS_ANNOT_CIRCLE(poppler_annot));
2022
2023 poppler_annot_geometry_set_interior_color(POPPLER_ANNOT(poppler_annot), poppler_color);
2024}
2025
2026/* PopplerAnnotSquare */
2027/**
2028 * poppler_annot_square_get_interior_color:
2029 * @poppler_annot: a #PopplerAnnotSquare
2030 *
2031 * Retrieves the interior color of @poppler_annot.
2032 *
2033 * Return value: a new allocated #PopplerColor with the color values of
2034 * @poppler_annot, or %NULL. It must be freed with g_free() when done.
2035 *
2036 * Since: 0.26
2037 */
2038PopplerColor *poppler_annot_square_get_interior_color(PopplerAnnotSquare *poppler_annot)
2039{
2040 g_return_val_if_fail(POPPLER_IS_ANNOT_SQUARE(poppler_annot), NULL);
2041
2042 return poppler_annot_geometry_get_interior_color(POPPLER_ANNOT(poppler_annot));
2043}
2044
2045/**
2046 * poppler_annot_square_set_interior_color:
2047 * @poppler_annot: a #PopplerAnnotSquare
2048 * @poppler_color: (allow-none): a #PopplerColor, or %NULL
2049 *
2050 * Sets the interior color of @poppler_annot.
2051 *
2052 * Since: 0.26
2053 */
2054void poppler_annot_square_set_interior_color(PopplerAnnotSquare *poppler_annot, PopplerColor *poppler_color)
2055{
2056 g_return_if_fail(POPPLER_IS_ANNOT_SQUARE(poppler_annot));
2057
2058 poppler_annot_geometry_set_interior_color(POPPLER_ANNOT(poppler_annot), poppler_color);
2059}
2060
2061/**
2062 * poppler_annot_stamp_get_icon:
2063 * @poppler_annot: a #PopplerAnnotStamp
2064 *
2065 * Return value: the corresponding #PopplerAnnotStampIcon of the icon
2066 *
2067 * Since: 22.07.0
2068 */
2069PopplerAnnotStampIcon poppler_annot_stamp_get_icon(PopplerAnnotStamp *poppler_annot)
2070{
2071 AnnotStamp *annot;
2072 const GooString *text;
2073
2074 g_return_val_if_fail(POPPLER_IS_ANNOT_STAMP(poppler_annot), POPPLER_ANNOT_STAMP_ICON_UNKNOWN);
2075
2076 annot = static_cast<AnnotStamp *>(POPPLER_ANNOT(poppler_annot)->annot);
2077
2078 text = annot->getIcon();
2079
2080 if (!text) {
2081 return POPPLER_ANNOT_STAMP_ICON_NONE;
2082 }
2083
2084 if (!text->cmp(sA: "Approved")) {
2085 return POPPLER_ANNOT_STAMP_ICON_APPROVED;
2086 } else if (!text->cmp(sA: "AsIs")) {
2087 return POPPLER_ANNOT_STAMP_ICON_AS_IS;
2088 } else if (!text->cmp(sA: "Confidential")) {
2089 return POPPLER_ANNOT_STAMP_ICON_CONFIDENTIAL;
2090 } else if (!text->cmp(sA: "Final")) {
2091 return POPPLER_ANNOT_STAMP_ICON_FINAL;
2092 } else if (!text->cmp(sA: "Experimental")) {
2093 return POPPLER_ANNOT_STAMP_ICON_EXPERIMENTAL;
2094 } else if (!text->cmp(sA: "Expired")) {
2095 return POPPLER_ANNOT_STAMP_ICON_EXPIRED;
2096 } else if (!text->cmp(sA: "NotApproved")) {
2097 return POPPLER_ANNOT_STAMP_ICON_NOT_APPROVED;
2098 } else if (!text->cmp(sA: "NotForPublicRelease")) {
2099 return POPPLER_ANNOT_STAMP_ICON_NOT_FOR_PUBLIC_RELEASE;
2100 } else if (!text->cmp(sA: "Sold")) {
2101 return POPPLER_ANNOT_STAMP_ICON_SOLD;
2102 } else if (!text->cmp(sA: "Departmental")) {
2103 return POPPLER_ANNOT_STAMP_ICON_DEPARTMENTAL;
2104 } else if (!text->cmp(sA: "ForComment")) {
2105 return POPPLER_ANNOT_STAMP_ICON_FOR_COMMENT;
2106 } else if (!text->cmp(sA: "ForPublicRelease")) {
2107 return POPPLER_ANNOT_STAMP_ICON_FOR_PUBLIC_RELEASE;
2108 } else if (!text->cmp(sA: "TopSecret")) {
2109 return POPPLER_ANNOT_STAMP_ICON_TOP_SECRET;
2110 }
2111
2112 return POPPLER_ANNOT_STAMP_ICON_UNKNOWN;
2113}
2114
2115/**
2116 * poppler_annot_stamp_set_icon:
2117 * @poppler_annot: a #PopplerAnnotStamp
2118 * @icon: the #PopplerAnnotStampIcon type of the icon
2119 *
2120 * Sets the icon of @poppler_annot to be one of the predefined values in #PopplerAnnotStampIcon
2121 *
2122 * Since: 22.07.0
2123 */
2124void poppler_annot_stamp_set_icon(PopplerAnnotStamp *poppler_annot, PopplerAnnotStampIcon icon)
2125{
2126 AnnotStamp *annot;
2127 GooString *goo_str;
2128 const gchar *text;
2129
2130 g_return_if_fail(POPPLER_IS_ANNOT_STAMP(poppler_annot));
2131
2132 annot = static_cast<AnnotStamp *>(POPPLER_ANNOT(poppler_annot)->annot);
2133
2134 if (icon == POPPLER_ANNOT_STAMP_ICON_NONE) {
2135 annot->setIcon(nullptr);
2136 return;
2137 }
2138
2139 if (icon == POPPLER_ANNOT_STAMP_ICON_APPROVED) {
2140 text = "Approved";
2141 } else if (icon == POPPLER_ANNOT_STAMP_ICON_AS_IS) {
2142 text = "AsIs";
2143 } else if (icon == POPPLER_ANNOT_STAMP_ICON_CONFIDENTIAL) {
2144 text = "Confidential";
2145 } else if (icon == POPPLER_ANNOT_STAMP_ICON_FINAL) {
2146 text = "Final";
2147 } else if (icon == POPPLER_ANNOT_STAMP_ICON_EXPERIMENTAL) {
2148 text = "Experimental";
2149 } else if (icon == POPPLER_ANNOT_STAMP_ICON_EXPIRED) {
2150 text = "Expired";
2151 } else if (icon == POPPLER_ANNOT_STAMP_ICON_NOT_APPROVED) {
2152 text = "NotApproved";
2153 } else if (icon == POPPLER_ANNOT_STAMP_ICON_NOT_FOR_PUBLIC_RELEASE) {
2154 text = "NotForPublicRelease";
2155 } else if (icon == POPPLER_ANNOT_STAMP_ICON_SOLD) {
2156 text = "Sold";
2157 } else if (icon == POPPLER_ANNOT_STAMP_ICON_DEPARTMENTAL) {
2158 text = "Departmental";
2159 } else if (icon == POPPLER_ANNOT_STAMP_ICON_FOR_COMMENT) {
2160 text = "ForComment";
2161 } else if (icon == POPPLER_ANNOT_STAMP_ICON_FOR_PUBLIC_RELEASE) {
2162 text = "ForPublicRelease";
2163 } else if (icon == POPPLER_ANNOT_STAMP_ICON_TOP_SECRET) {
2164 text = "TopSecret";
2165 } else {
2166 return; /* POPPLER_ANNOT_STAMP_ICON_UNKNOWN */
2167 }
2168
2169 goo_str = new GooString(text);
2170 annot->setIcon(goo_str);
2171 delete goo_str;
2172}
2173
2174/**
2175 * poppler_annot_stamp_set_custom_image:
2176 * @poppler_annot: a #PopplerAnnotStamp
2177 * @image: an image cairo surface
2178 * @error: (nullable): return location for error, or %NULL.
2179 *
2180 * Sets the custom image of @poppler_annot to be @image
2181 *
2182 * Return value: %TRUE on success, %FALSE otherwise.
2183 *
2184 * Since: 22.07.0
2185 */
2186gboolean poppler_annot_stamp_set_custom_image(PopplerAnnotStamp *poppler_annot, cairo_surface_t *image, GError **error)
2187{
2188 AnnotStamp *annot;
2189 AnnotStampImageHelper *annot_image_helper;
2190
2191 g_return_val_if_fail(POPPLER_IS_ANNOT_STAMP(poppler_annot), FALSE);
2192
2193 annot = static_cast<AnnotStamp *>(POPPLER_ANNOT(poppler_annot)->annot);
2194 annot_image_helper = _poppler_convert_cairo_image_to_stamp_image_helper(image, doc: annot->getDoc(), error);
2195 if (!annot_image_helper) {
2196 return FALSE;
2197 }
2198 annot->setCustomImage(annot_image_helper);
2199
2200 return TRUE;
2201}
2202

source code of poppler/glib/poppler-annot.cc