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