1
/* poppler-page.cc: glib wrapper for poppler
2
* Copyright (C) 2005, Red Hat, Inc.
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2, or (at your option)
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
22
#ifndef __GI_SCANNER__
23
#include <goo/GooList.h>
24
#include <GlobalParams.h>
27
#include <ErrorCodes.h>
28
#include <UnicodeMap.h>
30
#include <PageTransition.h>
34
#include "poppler-private.h"
37
* SECTION:poppler-page
38
* @short_description: Information about a page in a document
48
typedef struct _PopplerPageClass PopplerPageClass;
49
struct _PopplerPageClass
51
GObjectClass parent_class;
54
G_DEFINE_TYPE (PopplerPage, poppler_page, G_TYPE_OBJECT)
57
_poppler_page_new (PopplerDocument *document, Page *page, int index)
59
PopplerPage *poppler_page;
61
g_return_val_if_fail (POPPLER_IS_DOCUMENT (document), NULL);
63
poppler_page = (PopplerPage *) g_object_new (POPPLER_TYPE_PAGE, NULL, NULL);
64
poppler_page->document = (PopplerDocument *) g_object_ref (document);
65
poppler_page->page = page;
66
poppler_page->index = index;
72
poppler_page_finalize (GObject *object)
74
PopplerPage *page = POPPLER_PAGE (object);
76
g_object_unref (page->document);
77
page->document = NULL;
79
if (page->annots != NULL)
81
if (page->text != NULL)
82
page->text->decRefCnt();
83
/* page->page is owned by the document */
87
* poppler_page_get_size:
88
* @page: A #PopplerPage
89
* @width: (out) (allow-none): return location for the width of @page
90
* @height: (out) (allow-none): return location for the height of @page
92
* Gets the size of @page at the current scale and rotation.
95
poppler_page_get_size (PopplerPage *page,
99
double page_width, page_height;
102
g_return_if_fail (POPPLER_IS_PAGE (page));
104
rotate = page->page->getRotate ();
105
if (rotate == 90 || rotate == 270) {
106
page_height = page->page->getCropWidth ();
107
page_width = page->page->getCropHeight ();
109
page_width = page->page->getCropWidth ();
110
page_height = page->page->getCropHeight ();
116
*height = page_height;
120
* poppler_page_get_index:
121
* @page: a #PopplerPage
123
* Returns the index of @page
125
* Return value: index value of @page
128
poppler_page_get_index (PopplerPage *page)
130
g_return_val_if_fail (POPPLER_IS_PAGE (page), 0);
136
* poppler_page_get_label:
137
* @page: a #PopplerPage
139
* Returns the label of @page. Note that page labels
140
* and page indices might not coincide.
142
* Return value: a new allocated string containing the label of @page,
143
* or %NULL if @page doesn't have a label
148
poppler_page_get_label (PopplerPage *page)
152
g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);
154
page->document->doc->getCatalog ()->indexToLabel (page->index, &label);
155
return _poppler_goo_string_to_utf8 (&label);
159
* poppler_page_get_duration:
160
* @page: a #PopplerPage
162
* Returns the duration of @page
164
* Return value: duration in seconds of @page or -1.
167
poppler_page_get_duration (PopplerPage *page)
169
g_return_val_if_fail (POPPLER_IS_PAGE (page), -1);
171
return page->page->getDuration ();
175
* poppler_page_get_transition:
176
* @page: a #PopplerPage
178
* Returns the transition effect of @page
180
* Return value: a #PopplerPageTransition or NULL.
182
PopplerPageTransition *
183
poppler_page_get_transition (PopplerPage *page)
185
PageTransition *trans;
186
PopplerPageTransition *transition;
189
g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);
191
trans = new PageTransition (page->page->getTrans (&obj));
194
if (!trans->isOk ()) {
199
transition = poppler_page_transition_new ();
201
switch (trans->getType ())
203
case transitionReplace:
204
transition->type = POPPLER_PAGE_TRANSITION_REPLACE;
206
case transitionSplit:
207
transition->type = POPPLER_PAGE_TRANSITION_SPLIT;
209
case transitionBlinds:
210
transition->type = POPPLER_PAGE_TRANSITION_BLINDS;
213
transition->type = POPPLER_PAGE_TRANSITION_BOX;
216
transition->type = POPPLER_PAGE_TRANSITION_WIPE;
218
case transitionDissolve:
219
transition->type = POPPLER_PAGE_TRANSITION_DISSOLVE;
221
case transitionGlitter:
222
transition->type = POPPLER_PAGE_TRANSITION_GLITTER;
225
transition->type = POPPLER_PAGE_TRANSITION_FLY;
228
transition->type = POPPLER_PAGE_TRANSITION_PUSH;
230
case transitionCover:
231
transition->type = POPPLER_PAGE_TRANSITION_COVER;
233
case transitionUncover:
234
transition->type = POPPLER_PAGE_TRANSITION_UNCOVER;
237
transition->type = POPPLER_PAGE_TRANSITION_FADE;
240
g_assert_not_reached ();
243
transition->alignment = (trans->getAlignment() == transitionHorizontal) ?
244
POPPLER_PAGE_TRANSITION_HORIZONTAL :
245
POPPLER_PAGE_TRANSITION_VERTICAL;
247
transition->direction = (trans->getDirection() == transitionInward) ?
248
POPPLER_PAGE_TRANSITION_INWARD :
249
POPPLER_PAGE_TRANSITION_OUTWARD;
251
transition->duration = trans->getDuration();
252
transition->angle = trans->getAngle();
253
transition->scale = trans->getScale();
254
transition->rectangular = trans->isRectangular();
262
poppler_page_get_text_page (PopplerPage *page)
264
if (page->text == NULL) {
265
TextOutputDev *text_dev;
268
text_dev = new TextOutputDev (NULL, gTrue, gFalse, gFalse);
269
gfx = page->page->createGfx(text_dev,
271
gFalse, /* useMediaBox */
274
gFalse, /* printing */
275
page->document->doc->getCatalog (),
276
NULL, NULL, NULL, NULL);
277
page->page->display(gfx);
280
page->text = text_dev->takeText();
288
#ifdef POPPLER_WITH_GDK
290
copy_cairo_surface_to_pixbuf (cairo_surface_t *surface,
293
int cairo_width, cairo_height, cairo_rowstride;
294
unsigned char *pixbuf_data, *dst, *cairo_data;
295
int pixbuf_rowstride, pixbuf_n_channels;
299
cairo_width = cairo_image_surface_get_width (surface);
300
cairo_height = cairo_image_surface_get_height (surface);
301
cairo_rowstride = cairo_image_surface_get_stride (surface);
302
cairo_data = cairo_image_surface_get_data (surface);
304
pixbuf_data = gdk_pixbuf_get_pixels (pixbuf);
305
pixbuf_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
306
pixbuf_n_channels = gdk_pixbuf_get_n_channels (pixbuf);
308
if (cairo_width > gdk_pixbuf_get_width (pixbuf))
309
cairo_width = gdk_pixbuf_get_width (pixbuf);
310
if (cairo_height > gdk_pixbuf_get_height (pixbuf))
311
cairo_height = gdk_pixbuf_get_height (pixbuf);
312
for (y = 0; y < cairo_height; y++)
314
src = (unsigned int *) (cairo_data + y * cairo_rowstride);
315
dst = pixbuf_data + y * pixbuf_rowstride;
316
for (x = 0; x < cairo_width; x++)
318
dst[0] = (*src >> 16) & 0xff;
319
dst[1] = (*src >> 8) & 0xff;
320
dst[2] = (*src >> 0) & 0xff;
321
if (pixbuf_n_channels == 4)
322
dst[3] = (*src >> 24) & 0xff;
323
dst += pixbuf_n_channels;
328
#endif /* POPPLER_WITH_GDK */
331
annot_is_markup (Annot *annot)
333
switch (annot->getType())
335
case Annot::typeLink:
336
case Annot::typePopup:
337
case Annot::typeMovie:
338
case Annot::typeScreen:
339
case Annot::typePrinterMark:
340
case Annot::typeTrapNet:
341
case Annot::typeWatermark:
343
case Annot::typeWidget:
351
poppler_print_annot_cb (Annot *annot, void *user_data)
353
PopplerPrintFlags user_print_flags = (PopplerPrintFlags)GPOINTER_TO_INT (user_data);
355
if (annot->getFlags () & Annot::flagHidden)
358
if (user_print_flags & POPPLER_PRINT_STAMP_ANNOTS_ONLY) {
359
return (annot->getType() == Annot::typeStamp) ?
360
(annot->getFlags () & Annot::flagPrint) :
361
(annot->getType() == Annot::typeWidget);
364
if (user_print_flags & POPPLER_PRINT_MARKUP_ANNOTS) {
365
return annot_is_markup (annot) ?
366
(annot->getFlags () & Annot::flagPrint) :
367
(annot->getType() == Annot::typeWidget);
370
/* Print document only, form fields are always printed */
371
return (annot->getType() == Annot::typeWidget);
375
_poppler_page_render (PopplerPage *page,
378
PopplerPrintFlags print_flags)
380
CairoOutputDev *output_dev;
382
g_return_if_fail (POPPLER_IS_PAGE (page));
384
output_dev = page->document->output_dev;
385
output_dev->setCairo (cairo);
386
output_dev->setPrinting (printing);
389
output_dev->setTextPage (page->text);
391
/* NOTE: instead of passing -1 we should/could use cairo_clip_extents()
392
* to get a bounding box */
394
page->page->displaySlice(output_dev,
396
gFalse, /* useMediaBox */
401
page->document->doc->getCatalog (),
403
printing ? poppler_print_annot_cb : NULL,
404
printing ? GINT_TO_POINTER ((gint)print_flags) : NULL);
405
cairo_restore (cairo);
407
output_dev->setCairo (NULL);
408
output_dev->setTextPage (NULL);
412
* poppler_page_render:
413
* @page: the page to render from
414
* @cairo: cairo context to render to
416
* Render the page to the given cairo context. This function
417
* is for rendering a page that will be displayed. If you want
418
* to render a page that will be printed use
419
* poppler_page_render_for_printing() instead
422
poppler_page_render (PopplerPage *page,
425
g_return_if_fail (POPPLER_IS_PAGE (page));
428
page->text = new TextPage(gFalse);
430
_poppler_page_render (page, cairo, gFalse, (PopplerPrintFlags)0);
434
* poppler_page_render_for_printing_with_options:
435
* @page: the page to render from
436
* @cairo: cairo context to render to
437
* @options: print options
439
* Render the page to the given cairo context for printing
440
* with the specified options
445
poppler_page_render_for_printing_with_options (PopplerPage *page,
447
PopplerPrintFlags options)
449
g_return_if_fail (POPPLER_IS_PAGE (page));
451
_poppler_page_render (page, cairo, gTrue, options);
455
* poppler_page_render_for_printing:
456
* @page: the page to render from
457
* @cairo: cairo context to render to
459
* Render the page to the given cairo context for printing.
462
poppler_page_render_for_printing (PopplerPage *page,
465
g_return_if_fail (POPPLER_IS_PAGE (page));
467
_poppler_page_render (page, cairo, gTrue, POPPLER_PRINT_ALL);
470
static cairo_surface_t *
471
create_surface_from_thumbnail_data (guchar *data,
476
guchar *cairo_pixels;
478
cairo_surface_t *surface;
481
surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
482
if (cairo_surface_status (surface))
485
cairo_pixels = cairo_image_surface_get_data (surface);
486
cairo_stride = cairo_image_surface_get_stride (surface);
488
for (j = height; j; j--) {
490
guchar *q = cairo_pixels;
491
guchar *end = p + 3 * width;
494
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
508
cairo_pixels += cairo_stride;
516
* poppler_page_get_thumbnail:
517
* @page: the #PopperPage to get the thumbnail for
519
* Get the embedded thumbnail for the specified page. If the document
520
* doesn't have an embedded thumbnail for the page, this function
523
* Return value: the tumbnail as a cairo_surface_t or %NULL if the document
524
* doesn't have a thumbnail for this page.
527
poppler_page_get_thumbnail (PopplerPage *page)
530
int width, height, rowstride;
531
cairo_surface_t *surface;
533
g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);
535
if (!page->page->loadThumb (&data, &width, &height, &rowstride))
538
surface = create_surface_from_thumbnail_data (data, width, height, rowstride);
545
* poppler_page_render_selection:
546
* @page: the #PopplerPage for which to render selection
547
* @cairo: cairo context to render to
548
* @selection: start and end point of selection as a rectangle
549
* @old_selection: previous selection
550
* @style: a #PopplerSelectionStyle
551
* @glyph_color: color to use for drawing glyphs
552
* @background_color: color to use for the selection background
554
* Render the selection specified by @selection for @page to
555
* the given cairo context. The selection will be rendered, using
556
* @glyph_color for the glyphs and @background_color for the selection
559
* If non-NULL, @old_selection specifies the selection that is already
560
* rendered to @cairo, in which case this function will (some day)
561
* only render the changed part of the selection.
564
poppler_page_render_selection (PopplerPage *page,
566
PopplerRectangle *selection,
567
PopplerRectangle *old_selection,
568
PopplerSelectionStyle style,
569
PopplerColor *glyph_color,
570
PopplerColor *background_color)
572
CairoOutputDev *output_dev;
574
SelectionStyle selection_style = selectionStyleGlyph;
575
PDFRectangle pdf_selection(selection->x1, selection->y1,
576
selection->x2, selection->y2);
578
GfxColor gfx_background_color = {
580
background_color->red,
581
background_color->green,
582
background_color->blue
585
GfxColor gfx_glyph_color = {
595
case POPPLER_SELECTION_GLYPH:
596
selection_style = selectionStyleGlyph;
598
case POPPLER_SELECTION_WORD:
599
selection_style = selectionStyleWord;
601
case POPPLER_SELECTION_LINE:
602
selection_style = selectionStyleLine;
606
output_dev = page->document->output_dev;
607
output_dev->setCairo (cairo);
609
text = poppler_page_get_text_page (page);
610
text->drawSelection (output_dev, 1.0, 0,
611
&pdf_selection, selection_style,
612
&gfx_glyph_color, &gfx_background_color);
614
output_dev->setCairo (NULL);
617
#ifdef POPPLER_WITH_GDK
619
_poppler_page_render_to_pixbuf (PopplerPage *page,
620
int src_x, int src_y,
621
int src_width, int src_height,
628
cairo_surface_t *surface;
630
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
631
src_width, src_height);
632
cr = cairo_create (surface);
636
cairo_translate (cr, src_x + src_width, -src_y);
639
cairo_translate (cr, src_x + src_width, src_y + src_height);
642
cairo_translate (cr, -src_x, src_y + src_height);
645
cairo_translate (cr, -src_x, -src_y);
649
cairo_scale (cr, scale, scale);
652
cairo_rotate (cr, rotation * G_PI / 180.0);
655
poppler_page_render_for_printing (page, cr);
657
poppler_page_render (page, cr);
660
cairo_set_operator (cr, CAIRO_OPERATOR_DEST_OVER);
661
cairo_set_source_rgb (cr, 1., 1., 1.);
666
copy_cairo_surface_to_pixbuf (surface, pixbuf);
667
cairo_surface_destroy (surface);
671
* poppler_page_render_to_pixbuf:
672
* @page: the page to render from
673
* @src_x: x coordinate of upper left corner
674
* @src_y: y coordinate of upper left corner
675
* @src_width: width of rectangle to render
676
* @src_height: height of rectangle to render
677
* @scale: scale specified as pixels per point
678
* @rotation: rotate the document by the specified degree
679
* @pixbuf: pixbuf to render into
681
* First scale the document to match the specified pixels per point,
682
* then render the rectangle given by the upper left corner at
683
* (src_x, src_y) and src_width and src_height.
684
* This function is for rendering a page that will be displayed.
685
* If you want to render a page that will be printed use
686
* poppler_page_render_to_pixbuf_for_printing() instead
691
poppler_page_render_to_pixbuf (PopplerPage *page,
692
int src_x, int src_y,
693
int src_width, int src_height,
698
g_return_if_fail (POPPLER_IS_PAGE (page));
699
g_return_if_fail (scale > 0.0);
700
g_return_if_fail (pixbuf != NULL);
702
_poppler_page_render_to_pixbuf (page, src_x, src_y,
703
src_width, src_height,
710
* poppler_page_render_to_pixbuf_for_printing:
711
* @page: the page to render from
712
* @src_x: x coordinate of upper left corner
713
* @src_y: y coordinate of upper left corner
714
* @src_width: width of rectangle to render
715
* @src_height: height of rectangle to render
716
* @scale: scale specified as pixels per point
717
* @rotation: rotate the document by the specified degree
718
* @pixbuf: pixbuf to render into
720
* First scale the document to match the specified pixels per point,
721
* then render the rectangle given by the upper left corner at
722
* (src_x, src_y) and src_width and src_height.
723
* This function is for rendering a page that will be printed.
728
poppler_page_render_to_pixbuf_for_printing (PopplerPage *page,
729
int src_x, int src_y,
730
int src_width, int src_height,
735
g_return_if_fail (POPPLER_IS_PAGE (page));
736
g_return_if_fail (scale > 0.0);
737
g_return_if_fail (pixbuf != NULL);
739
_poppler_page_render_to_pixbuf (page, src_x, src_y,
740
src_width, src_height,
747
* poppler_page_get_thumbnail_pixbuf:
748
* @page: the #PopperPage to get the thumbnail for
750
* Get the embedded thumbnail for the specified page. If the document
751
* doesn't have an embedded thumbnail for the page, this function
754
* Return value: the tumbnail as a #GdkPixbuf or %NULL if the document
755
* doesn't have a thumbnail for this page.
760
poppler_page_get_thumbnail_pixbuf (PopplerPage *page)
763
int width, height, rowstride;
765
g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);
767
if (!page->page->loadThumb (&data, &width, &height, &rowstride))
770
return gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB,
771
FALSE, 8, width, height, rowstride,
772
(GdkPixbufDestroyNotify)gfree, NULL);
776
* poppler_page_render_selection_to_pixbuf:
777
* @page: the #PopplerPage for which to render selection
778
* @scale: scale specified as pixels per point
779
* @rotation: rotate the document by the specified degree
780
* @pixbuf: pixbuf to render to
781
* @selection: start and end point of selection as a rectangle
782
* @old_selection: previous selection
783
* @style: a #PopplerSelectionStyle
784
* @glyph_color: color to use for drawing glyphs
785
* @background_color: color to use for the selection background
787
* Render the selection specified by @selection for @page into
788
* @pixbuf. The selection will be rendered at @scale, using
789
* @glyph_color for the glyphs and @background_color for the selection
792
* If non-NULL, @old_selection specifies the selection that is already
793
* rendered in @pixbuf, in which case this function will (some day)
794
* only render the changed part of the selection.
799
poppler_page_render_selection_to_pixbuf (PopplerPage *page,
803
PopplerRectangle *selection,
804
PopplerRectangle *old_selection,
805
PopplerSelectionStyle style,
806
GdkColor *glyph_color,
807
GdkColor *background_color)
810
cairo_surface_t *surface;
811
double width, height;
812
int cairo_width, cairo_height, rotate;
813
PopplerColor poppler_background_color;
814
PopplerColor poppler_glyph_color;
816
poppler_background_color.red = background_color->red;
817
poppler_background_color.green = background_color->green;
818
poppler_background_color.blue = background_color->blue;
819
poppler_glyph_color.red = glyph_color->red;
820
poppler_glyph_color.green = glyph_color->green;
821
poppler_glyph_color.blue = glyph_color->blue;
823
rotate = rotation + page->page->getRotate ();
824
if (rotate == 90 || rotate == 270) {
825
height = page->page->getCropWidth ();
826
width = page->page->getCropHeight ();
828
width = page->page->getCropWidth ();
829
height = page->page->getCropHeight ();
832
cairo_width = (int) ceil(width * scale);
833
cairo_height = (int) ceil(height * scale);
835
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
836
cairo_width, cairo_height);
837
cr = cairo_create (surface);
838
cairo_set_source_rgba (cr, 0, 0, 0, 0);
843
cairo_translate (cr, cairo_width, 0);
846
cairo_translate (cr, cairo_width, cairo_height);
849
cairo_translate (cr, 0, cairo_height);
852
cairo_translate (cr, 0, 0);
855
cairo_scale (cr, scale, scale);
858
cairo_rotate (cr, rotation * G_PI / 180.0);
860
poppler_page_render_selection (page, cr, selection, old_selection, style,
861
&poppler_glyph_color, &poppler_background_color);
865
copy_cairo_surface_to_pixbuf (surface, pixbuf);
866
cairo_surface_destroy (surface);
869
#endif /* POPPLER_WITH_GDK */
872
* poppler_page_get_thumbnail_size:
873
* @page: A #PopplerPage
874
* @width: (out) return location for width
875
* @height: (out) return location for height
877
* Returns %TRUE if @page has a thumbnail associated with it. It also
878
* fills in @width and @height with the width and height of the
879
* thumbnail. The values of width and height are not changed if no
880
* appropriate thumbnail exists.
882
* Return value: %TRUE, if @page has a thumbnail associated with it.
885
poppler_page_get_thumbnail_size (PopplerPage *page,
891
gboolean retval = FALSE;
893
g_return_val_if_fail (POPPLER_IS_PAGE (page), FALSE);
894
g_return_val_if_fail (width != NULL, FALSE);
895
g_return_val_if_fail (height != NULL, FALSE);
897
page->page->getThumb (&thumb);
898
if (!thumb.isStream ())
904
dict = thumb.streamGetDict();
906
/* Theoretically, this could succeed and you would still fail when
907
* loading the thumb */
908
if (dict->lookupInt ("Width", "W", width) &&
909
dict->lookupInt ("Height", "H", height))
918
* poppler_page_get_selection_region:
919
* @page: a #PopplerPage
920
* @scale: scale specified as pixels per point
921
* @style: a #PopplerSelectionStyle
922
* @selection: start and end point of selection as a rectangle
924
* Returns a region containing the area that would be rendered by
925
* poppler_page_render_selection() or
926
* poppler_page_render_selection_to_pixbuf() as a #GList of
927
* #PopplerRectangle. The returned list must be freed with
928
* poppler_page_selection_region_free().
930
* Return value: (element-type PopplerRectangle) (transfer full): a #GList of #PopplerRectangle
932
* Deprecated: 0.16: Use poppler_page_get_selected_region() instead.
935
poppler_page_get_selection_region (PopplerPage *page,
937
PopplerSelectionStyle style,
938
PopplerRectangle *selection)
940
PDFRectangle poppler_selection;
942
SelectionStyle selection_style = selectionStyleGlyph;
944
GList *region = NULL;
947
poppler_selection.x1 = selection->x1;
948
poppler_selection.y1 = selection->y1;
949
poppler_selection.x2 = selection->x2;
950
poppler_selection.y2 = selection->y2;
954
case POPPLER_SELECTION_GLYPH:
955
selection_style = selectionStyleGlyph;
957
case POPPLER_SELECTION_WORD:
958
selection_style = selectionStyleWord;
960
case POPPLER_SELECTION_LINE:
961
selection_style = selectionStyleLine;
965
text = poppler_page_get_text_page (page);
966
list = text->getSelectionRegion(&poppler_selection,
967
selection_style, scale);
969
for (i = 0; i < list->getLength(); i++) {
970
PDFRectangle *selection_rect = (PDFRectangle *) list->get(i);
971
PopplerRectangle *rect;
973
rect = poppler_rectangle_new ();
975
rect->x1 = selection_rect->x1;
976
rect->y1 = selection_rect->y1;
977
rect->x2 = selection_rect->x2;
978
rect->y2 = selection_rect->y2;
980
region = g_list_prepend (region, rect);
982
delete selection_rect;
987
return g_list_reverse (region);
991
* poppler_page_selection_region_free:
992
* @region: a #GList of #PopplerRectangle
999
poppler_page_selection_region_free (GList *region)
1001
if (G_UNLIKELY (!region))
1004
g_list_foreach (region, (GFunc)poppler_rectangle_free, NULL);
1005
g_list_free (region);
1009
* poppler_page_get_selected_region:
1010
* @page: a #PopplerPage
1011
* @scale: scale specified as pixels per point
1012
* @style: a #PopplerSelectionStyle
1013
* @selection: start and end point of selection as a rectangle
1015
* Returns a region containing the area that would be rendered by
1016
* poppler_page_render_selection() or
1017
* poppler_page_render_selection_to_pixbuf().
1018
* The returned region must be freed with cairo_region_destroy()
1020
* Return value: (transfer full): a cairo_region_t
1025
poppler_page_get_selected_region (PopplerPage *page,
1027
PopplerSelectionStyle style,
1028
PopplerRectangle *selection)
1030
PDFRectangle poppler_selection;
1032
SelectionStyle selection_style = selectionStyleGlyph;
1034
cairo_region_t *region;
1037
poppler_selection.x1 = selection->x1;
1038
poppler_selection.y1 = selection->y1;
1039
poppler_selection.x2 = selection->x2;
1040
poppler_selection.y2 = selection->y2;
1044
case POPPLER_SELECTION_GLYPH:
1045
selection_style = selectionStyleGlyph;
1047
case POPPLER_SELECTION_WORD:
1048
selection_style = selectionStyleWord;
1050
case POPPLER_SELECTION_LINE:
1051
selection_style = selectionStyleLine;
1055
text = poppler_page_get_text_page (page);
1056
list = text->getSelectionRegion(&poppler_selection,
1057
selection_style, 1.0);
1059
region = cairo_region_create ();
1061
for (i = 0; i < list->getLength(); i++) {
1062
PDFRectangle *selection_rect = (PDFRectangle *) list->get(i);
1063
cairo_rectangle_int_t rect;
1065
rect.x = (gint) ((selection_rect->x1 * scale) + 0.5);
1066
rect.y = (gint) ((selection_rect->y1 * scale) + 0.5);
1067
rect.width = (gint) (((selection_rect->x2 - selection_rect->x1) * scale) + 0.5);
1068
rect.height = (gint) (((selection_rect->y2 - selection_rect->y1) * scale) + 0.5);
1069
cairo_region_union_rectangle (region, &rect);
1071
delete selection_rect;
1080
* poppler_page_get_selected_text:
1081
* @page: a #PopplerPage
1082
* @style: a #PopplerSelectionStyle
1083
* @selection: the #PopplerRectangle including the text
1085
* Retrieves the contents of the specified @selection as text.
1087
* Return value: a pointer to the contents of the @selection
1092
poppler_page_get_selected_text (PopplerPage *page,
1093
PopplerSelectionStyle style,
1094
PopplerRectangle *selection)
1096
GooString *sel_text;
1099
SelectionStyle selection_style = selectionStyleGlyph;
1100
PDFRectangle pdf_selection;
1102
g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);
1103
g_return_val_if_fail (selection != NULL, NULL);
1105
pdf_selection.x1 = selection->x1;
1106
pdf_selection.y1 = selection->y1;
1107
pdf_selection.x2 = selection->x2;
1108
pdf_selection.y2 = selection->y2;
1112
case POPPLER_SELECTION_GLYPH:
1113
selection_style = selectionStyleGlyph;
1115
case POPPLER_SELECTION_WORD:
1116
selection_style = selectionStyleWord;
1118
case POPPLER_SELECTION_LINE:
1119
selection_style = selectionStyleLine;
1123
text = poppler_page_get_text_page (page);
1124
sel_text = text->getSelectionText (&pdf_selection, selection_style);
1125
result = g_strdup (sel_text->getCString ());
1132
* poppler_page_get_text:
1133
* @page: a #PopplerPage
1135
* Retrieves the text of @page.
1137
* Return value: a pointer to the text of the @page
1142
poppler_page_get_text (PopplerPage *page)
1144
PopplerRectangle rectangle = {0, 0, 0, 0};
1146
g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);
1148
poppler_page_get_size (page, &rectangle.x2, &rectangle.y2);
1150
return poppler_page_get_selected_text (page, POPPLER_SELECTION_GLYPH, &rectangle);
1154
* poppler_page_find_text:
1155
* @page: a #PopplerPage
1156
* @text: the text to search for (UTF-8 encoded)
1158
* A #GList of rectangles for each occurance of the text on the page.
1159
* The coordinates are in PDF points.
1161
* Return value: (element-type PopplerRectangle) (transfer full): a #GList of #PopplerRectangle,
1164
poppler_page_find_text (PopplerPage *page,
1167
PopplerRectangle *match;
1169
double xMin, yMin, xMax, yMax;
1175
g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);
1176
g_return_val_if_fail (text != NULL, NULL);
1178
text_dev = poppler_page_get_text_page (page);
1180
ucs4 = g_utf8_to_ucs4_fast (text, -1, &ucs4_len);
1181
poppler_page_get_size (page, NULL, &height);
1187
while (text_dev->findText (ucs4, ucs4_len,
1188
gFalse, gTrue, // startAtTop, stopAtBottom
1189
gFalse, gFalse, // startAtLast, stopAtLast
1190
gFalse, gFalse, // caseSensitive, backwards
1191
&xMin, &yMin, &xMax, &yMax))
1193
match = poppler_rectangle_new ();
1195
match->y1 = height - yMax;
1197
match->y2 = height - yMin;
1198
matches = g_list_prepend (matches, match);
1203
return g_list_reverse (matches);
1206
static CairoImageOutputDev *
1207
poppler_page_get_image_output_dev (PopplerPage *page,
1208
GBool (*imgDrawDeviceCbk)(int img_id, void *data),
1209
void *imgDrawCbkData)
1211
CairoImageOutputDev *image_dev;
1214
image_dev = new CairoImageOutputDev ();
1216
if (imgDrawDeviceCbk) {
1217
image_dev->setImageDrawDecideCbk (imgDrawDeviceCbk,
1221
gfx = page->page->createGfx(image_dev,
1223
gFalse, /* useMediaBox */
1226
gFalse, /* printing */
1227
page->document->doc->getCatalog (),
1228
NULL, NULL, NULL, NULL);
1229
page->page->display(gfx);
1236
* poppler_page_get_image_mapping:
1237
* @page: A #PopplerPage
1239
* Returns a list of #PopplerImageMapping items that map from a
1240
* location on @page to an image of the page. This list must be freed
1241
* with poppler_page_free_image_mapping() when done.
1243
* Return value: (element-type PopplerImageMapping) (transfer full): A #GList of #PopplerImageMapping
1246
poppler_page_get_image_mapping (PopplerPage *page)
1248
GList *map_list = NULL;
1249
CairoImageOutputDev *out;
1252
g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);
1254
out = poppler_page_get_image_output_dev (page, NULL, NULL);
1256
for (i = 0; i < out->getNumImages (); i++) {
1257
PopplerImageMapping *mapping;
1260
image = out->getImage (i);
1262
/* Create the mapping */
1263
mapping = poppler_image_mapping_new ();
1265
image->getRect (&(mapping->area.x1), &(mapping->area.y1),
1266
&(mapping->area.x2), &(mapping->area.y2));
1267
mapping->image_id = i;
1269
mapping->area.x1 -= page->page->getCropBox()->x1;
1270
mapping->area.x2 -= page->page->getCropBox()->x1;
1271
mapping->area.y1 -= page->page->getCropBox()->y1;
1272
mapping->area.y2 -= page->page->getCropBox()->y1;
1274
map_list = g_list_prepend (map_list, mapping);
1283
image_draw_decide_cb (int image_id, void *data)
1285
return (image_id == GPOINTER_TO_INT (data));
1289
* poppler_page_get_image:
1290
* @page: A #PopplerPage
1291
* @image_id: The image identificator
1293
* Returns a cairo surface for the image of the @page
1295
* Return value: A cairo surface for the image
1298
poppler_page_get_image (PopplerPage *page,
1301
CairoImageOutputDev *out;
1302
cairo_surface_t *image;
1304
g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);
1306
out = poppler_page_get_image_output_dev (page,
1307
image_draw_decide_cb,
1308
GINT_TO_POINTER (image_id));
1310
if (image_id >= out->getNumImages ()) {
1316
image = out->getImage (image_id)->getImage ();
1323
cairo_surface_reference (image);
1330
* poppler_page_free_image_mapping:
1331
* @list: A list of #PopplerImageMapping<!-- -->s
1333
* Frees a list of #PopplerImageMapping<!-- -->s allocated by
1334
* poppler_page_get_image_mapping().
1337
poppler_page_free_image_mapping (GList *list)
1339
if (G_UNLIKELY (list == NULL))
1342
g_list_foreach (list, (GFunc)poppler_image_mapping_free, NULL);
1347
* poppler_page_render_to_ps:
1348
* @page: a #PopplerPage
1349
* @ps_file: the PopplerPSFile to render to
1351
* Render the page on a postscript file
1355
poppler_page_render_to_ps (PopplerPage *page,
1356
PopplerPSFile *ps_file)
1358
g_return_if_fail (POPPLER_IS_PAGE (page));
1359
g_return_if_fail (ps_file != NULL);
1362
ps_file->out = new PSOutputDev (ps_file->filename,
1363
ps_file->document->doc,
1364
ps_file->document->doc->getXRef(),
1365
ps_file->document->doc->getCatalog(),
1367
ps_file->first_page, ps_file->last_page,
1368
psModePS, (int)ps_file->paper_width,
1369
(int)ps_file->paper_height, ps_file->duplex,
1370
0, 0, 0, 0, gFalse, gFalse);
1373
ps_file->document->doc->displayPage (ps_file->out, page->index + 1, 72.0, 72.0,
1374
0, gFalse, gTrue, gFalse);
1378
poppler_page_get_property (GObject *object,
1383
PopplerPage *page = POPPLER_PAGE (object);
1388
g_value_take_string (value, poppler_page_get_label (page));
1391
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1396
poppler_page_class_init (PopplerPageClass *klass)
1398
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
1400
gobject_class->finalize = poppler_page_finalize;
1401
gobject_class->get_property = poppler_page_get_property;
1404
* PopplerPage:label:
1406
* The label of the page or %NULL. See also poppler_page_get_label()
1408
g_object_class_install_property (G_OBJECT_CLASS (klass),
1410
g_param_spec_string ("label",
1412
"The label of the page",
1418
poppler_page_init (PopplerPage *page)
1423
* poppler_page_get_link_mapping:
1424
* @page: A #PopplerPage
1426
* Returns a list of #PopplerLinkMapping items that map from a
1427
* location on @page to a #PopplerAction. This list must be freed
1428
* with poppler_page_free_link_mapping() when done.
1430
* Return value: (element-type PopplerLinkMapping) (transfer full): A #GList of #PopplerLinkMapping
1433
poppler_page_get_link_mapping (PopplerPage *page)
1435
GList *map_list = NULL;
1439
double width, height;
1441
g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);
1443
links = new Links (page->page->getAnnots (&obj),
1444
page->document->doc->getCatalog ()->getBaseURI ());
1450
poppler_page_get_size (page, &width, &height);
1452
for (i = 0; i < links->getNumLinks (); i++)
1454
PopplerLinkMapping *mapping;
1455
PopplerRectangle rect;
1456
LinkAction *link_action;
1459
link = links->getLink (i);
1460
link_action = link->getAction ();
1462
/* Create the mapping */
1463
mapping = poppler_link_mapping_new ();
1464
mapping->action = _poppler_action_new (page->document, link_action, NULL);
1466
link->getRect (&rect.x1, &rect.y1, &rect.x2, &rect.y2);
1468
rect.x1 -= page->page->getCropBox()->x1;
1469
rect.x2 -= page->page->getCropBox()->x1;
1470
rect.y1 -= page->page->getCropBox()->y1;
1471
rect.y2 -= page->page->getCropBox()->y1;
1473
switch (page->page->getRotate ())
1476
mapping->area.x1 = rect.y1;
1477
mapping->area.y1 = height - rect.x2;
1478
mapping->area.x2 = mapping->area.x1 + (rect.y2 - rect.y1);
1479
mapping->area.y2 = mapping->area.y1 + (rect.x2 - rect.x1);
1483
mapping->area.x1 = width - rect.x2;
1484
mapping->area.y1 = height - rect.y2;
1485
mapping->area.x2 = mapping->area.x1 + (rect.x2 - rect.x1);
1486
mapping->area.y2 = mapping->area.y1 + (rect.y2 - rect.y1);
1490
mapping->area.x1 = width - rect.y2;
1491
mapping->area.y1 = rect.x1;
1492
mapping->area.x2 = mapping->area.x1 + (rect.y2 - rect.y1);
1493
mapping->area.y2 = mapping->area.y1 + (rect.x2 - rect.x1);
1497
mapping->area.x1 = rect.x1;
1498
mapping->area.y1 = rect.y1;
1499
mapping->area.x2 = rect.x2;
1500
mapping->area.y2 = rect.y2;
1503
map_list = g_list_prepend (map_list, mapping);
1512
* poppler_page_free_link_mapping:
1513
* @list: A list of #PopplerLinkMapping<!-- -->s
1515
* Frees a list of #PopplerLinkMapping<!-- -->s allocated by
1516
* poppler_page_get_link_mapping(). It also frees the #PopplerAction<!-- -->s
1517
* that each mapping contains, so if you want to keep them around, you need to
1518
* copy them with poppler_action_copy().
1521
poppler_page_free_link_mapping (GList *list)
1523
if (G_UNLIKELY (list == NULL))
1526
g_list_foreach (list, (GFunc)poppler_link_mapping_free, NULL);
1531
* poppler_page_get_form_field_mapping:
1532
* @page: A #PopplerPage
1534
* Returns a list of #PopplerFormFieldMapping items that map from a
1535
* location on @page to a form field. This list must be freed
1536
* with poppler_page_free_form_field_mapping() when done.
1538
* Return value: (element-type PopplerFormFieldMapping) (transfer full): A #GList of #PopplerFormFieldMapping
1541
poppler_page_get_form_field_mapping (PopplerPage *page)
1543
GList *map_list = NULL;
1544
FormPageWidgets *forms;
1547
g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);
1549
forms = page->page->getPageWidgets ();
1553
for (i = 0; i < forms->getNumWidgets (); i++) {
1554
PopplerFormFieldMapping *mapping;
1557
mapping = poppler_form_field_mapping_new ();
1559
field = forms->getWidget (i);
1561
mapping->field = _poppler_form_field_new (page->document, field);
1562
field->getRect (&(mapping->area.x1), &(mapping->area.y1),
1563
&(mapping->area.x2), &(mapping->area.y2));
1565
mapping->area.x1 -= page->page->getCropBox()->x1;
1566
mapping->area.x2 -= page->page->getCropBox()->x1;
1567
mapping->area.y1 -= page->page->getCropBox()->y1;
1568
mapping->area.y2 -= page->page->getCropBox()->y1;
1570
map_list = g_list_prepend (map_list, mapping);
1577
* poppler_page_free_form_field_mapping:
1578
* @list: A list of #PopplerFormFieldMapping<!-- -->s
1580
* Frees a list of #PopplerFormFieldMapping<!-- -->s allocated by
1581
* poppler_page_get_form_field_mapping().
1584
poppler_page_free_form_field_mapping (GList *list)
1586
if (G_UNLIKELY (list == NULL))
1589
g_list_foreach (list, (GFunc) poppler_form_field_mapping_free, NULL);
1594
* poppler_page_get_annot_mapping:
1595
* @page: A #PopplerPage
1597
* Returns a list of #PopplerAnnotMapping items that map from a location on
1598
* @page to a #PopplerAnnot. This list must be freed with
1599
* poppler_page_free_annot_mapping() when done.
1601
* Return value: (element-type PopplerAnnotMapping) (transfer full): A #GList of #PopplerAnnotMapping
1604
poppler_page_get_annot_mapping (PopplerPage *page)
1606
GList *map_list = NULL;
1607
double width, height;
1610
g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);
1613
page->annots = page->page->getAnnots (page->document->doc->getCatalog ());
1618
poppler_page_get_size (page, &width, &height);
1620
for (i = 0; i < page->annots->getNumAnnots (); i++) {
1621
PopplerAnnotMapping *mapping;
1622
PopplerRectangle rect;
1624
PDFRectangle *annot_rect;
1627
annot = page->annots->getAnnot (i);
1629
/* Create the mapping */
1630
mapping = poppler_annot_mapping_new ();
1632
switch (annot->getType ())
1634
case Annot::typeText:
1635
mapping->annot = _poppler_annot_text_new (annot);
1637
case Annot::typeFreeText:
1638
mapping->annot = _poppler_annot_free_text_new (annot);
1640
case Annot::typeFileAttachment:
1641
mapping->annot = _poppler_annot_file_attachment_new (annot);
1643
case Annot::typeMovie:
1644
mapping->annot = _poppler_annot_movie_new (annot);
1646
case Annot::typeScreen:
1647
mapping->annot = _poppler_annot_screen_new (annot);
1650
mapping->annot = _poppler_annot_new (annot);
1654
annot_rect = annot->getRect ();
1655
rect.x1 = annot_rect->x1 - page->page->getCropBox()->x1;
1656
rect.y1 = annot_rect->y1 - page->page->getCropBox()->y1;
1657
rect.x2 = annot_rect->x2 - page->page->getCropBox()->x1;
1658
rect.y2 = annot_rect->y2 - page->page->getCropBox()->y1;
1660
if (! (annot->getFlags () & Annot::flagNoRotate))
1661
rotation = page->page->getRotate ();
1666
mapping->area.x1 = rect.y1;
1667
mapping->area.y1 = height - rect.x2;
1668
mapping->area.x2 = mapping->area.x1 + (rect.y2 - rect.y1);
1669
mapping->area.y2 = mapping->area.y1 + (rect.x2 - rect.x1);
1672
mapping->area.x1 = width - rect.x2;
1673
mapping->area.y1 = height - rect.y2;
1674
mapping->area.x2 = mapping->area.x1 + (rect.x2 - rect.x1);
1675
mapping->area.y2 = mapping->area.y1 + (rect.y2 - rect.y1);
1678
mapping->area.x1 = width - rect.y2;
1679
mapping->area.y1 = rect.x1;
1680
mapping->area.x2 = mapping->area.x1 + (rect.y2 - rect.y1);
1681
mapping->area.y2 = mapping->area.y1 + (rect.x2 - rect.x1);
1684
mapping->area.x1 = rect.x1;
1685
mapping->area.y1 = rect.y1;
1686
mapping->area.x2 = rect.x2;
1687
mapping->area.y2 = rect.y2;
1690
map_list = g_list_prepend (map_list, mapping);
1693
return g_list_reverse (map_list);
1697
* poppler_page_free_annot_mapping:
1698
* @list: A list of #PopplerAnnotMapping<!-- -->s
1700
* Frees a list of #PopplerAnnotMapping<!-- -->s allocated by
1701
* poppler_page_get_annot_mapping(). It also frees the #PopplerAnnot<!-- -->s
1702
* that each mapping contains, so if you want to keep them around, you need to
1703
* copy them with poppler_annot_copy().
1706
poppler_page_free_annot_mapping (GList *list)
1708
if (G_UNLIKELY (!list))
1711
g_list_foreach (list, (GFunc)poppler_annot_mapping_free, NULL);
1716
* poppler_page_add_annot:
1717
* @page: a #PopplerPage
1718
* @annot: a #PopplerAnnot to add
1720
* Adds annotation @annot to @page.
1725
poppler_page_add_annot (PopplerPage *page,
1726
PopplerAnnot *annot)
1728
g_return_if_fail (POPPLER_IS_PAGE (page));
1729
g_return_if_fail (POPPLER_IS_ANNOT (annot));
1731
page->page->addAnnot (annot->annot);
1734
/* PopplerRectangle type */
1736
POPPLER_DEFINE_BOXED_TYPE (PopplerRectangle, poppler_rectangle,
1737
poppler_rectangle_copy,
1738
poppler_rectangle_free)
1741
* poppler_rectangle_new:
1743
* Creates a new #PopplerRectangle
1745
* Returns: a new #PopplerRectangle, use poppler_rectangle_free() to free it
1748
poppler_rectangle_new (void)
1750
return g_slice_new0 (PopplerRectangle);
1754
* poppler_rectangle_copy:
1755
* @rectangle: a #PopplerRectangle to copy
1757
* Creates a copy of @rectangle
1759
* Returns: a new allocated copy of @rectangle
1762
poppler_rectangle_copy (PopplerRectangle *rectangle)
1764
g_return_val_if_fail (rectangle != NULL, NULL);
1766
return g_slice_dup (PopplerRectangle, rectangle);
1770
* poppler_rectangle_free:
1771
* @rectangle: a #PopplerRectangle
1773
* Frees the given #PopplerRectangle
1776
poppler_rectangle_free (PopplerRectangle *rectangle)
1778
g_slice_free (PopplerRectangle, rectangle);
1781
/* PopplerColor type */
1782
POPPLER_DEFINE_BOXED_TYPE (PopplerColor, poppler_color, poppler_color_copy, poppler_color_free)
1785
* poppler_color_new:
1787
* Creates a new #PopplerColor
1789
* Returns: a new #PopplerColor, use poppler_color_free() to free it
1792
poppler_color_new (void)
1794
return (PopplerColor *) g_new0 (PopplerColor, 1);
1798
* poppler_color_copy:
1799
* @color: a #PopplerColor to copy
1801
* Creates a copy of @color
1803
* Returns: a new allocated copy of @color
1806
poppler_color_copy (PopplerColor *color)
1808
PopplerColor *new_color;
1810
new_color = g_new (PopplerColor, 1);
1811
*new_color = *color;
1817
* poppler_color_free:
1818
* @color: a #PopplerColor
1820
* Frees the given #PopplerColor
1823
poppler_color_free (PopplerColor *color)
1828
/* PopplerLinkMapping type */
1829
POPPLER_DEFINE_BOXED_TYPE (PopplerLinkMapping, poppler_link_mapping,
1830
poppler_link_mapping_copy,
1831
poppler_link_mapping_free)
1834
* poppler_link_mapping_new:
1836
* Creates a new #PopplerLinkMapping
1838
* Returns: a new #PopplerLinkMapping, use poppler_link_mapping_free() to free it
1840
PopplerLinkMapping *
1841
poppler_link_mapping_new (void)
1843
return g_slice_new0 (PopplerLinkMapping);
1847
* poppler_link_mapping_copy:
1848
* @mapping: a #PopplerLinkMapping to copy
1850
* Creates a copy of @mapping
1852
* Returns: a new allocated copy of @mapping
1854
PopplerLinkMapping *
1855
poppler_link_mapping_copy (PopplerLinkMapping *mapping)
1857
PopplerLinkMapping *new_mapping;
1859
new_mapping = g_slice_dup (PopplerLinkMapping, mapping);
1861
if (new_mapping->action)
1862
new_mapping->action = poppler_action_copy (new_mapping->action);
1868
* poppler_link_mapping_free:
1869
* @mapping: a #PopplerLinkMapping
1871
* Frees the given #PopplerLinkMapping
1874
poppler_link_mapping_free (PopplerLinkMapping *mapping)
1876
if (G_UNLIKELY (!mapping))
1879
if (mapping->action)
1880
poppler_action_free (mapping->action);
1882
g_slice_free (PopplerLinkMapping, mapping);
1885
/* Poppler Image mapping type */
1886
POPPLER_DEFINE_BOXED_TYPE (PopplerImageMapping, poppler_image_mapping,
1887
poppler_image_mapping_copy,
1888
poppler_image_mapping_free)
1891
* poppler_image_mapping_new:
1893
* Creates a new #PopplerImageMapping
1895
* Returns: a new #PopplerImageMapping, use poppler_image_mapping_free() to free it
1897
PopplerImageMapping *
1898
poppler_image_mapping_new (void)
1900
return g_slice_new0 (PopplerImageMapping);
1904
* poppler_image_mapping_copy:
1905
* @mapping: a #PopplerImageMapping to copy
1907
* Creates a copy of @mapping
1909
* Returns: a new allocated copy of @mapping
1911
PopplerImageMapping *
1912
poppler_image_mapping_copy (PopplerImageMapping *mapping)
1914
return g_slice_dup (PopplerImageMapping, mapping);
1918
* poppler_image_mapping_free:
1919
* @mapping: a #PopplerImageMapping
1921
* Frees the given #PopplerImageMapping
1924
poppler_image_mapping_free (PopplerImageMapping *mapping)
1926
g_slice_free (PopplerImageMapping, mapping);
1929
/* Page Transition */
1930
POPPLER_DEFINE_BOXED_TYPE (PopplerPageTransition, poppler_page_transition,
1931
poppler_page_transition_copy,
1932
poppler_page_transition_free)
1935
* poppler_page_transition_new:
1937
* Creates a new #PopplerPageTransition
1939
* Returns: a new #PopplerPageTransition, use poppler_page_transition_free() to free it
1941
PopplerPageTransition *
1942
poppler_page_transition_new (void)
1944
return (PopplerPageTransition *) g_new0 (PopplerPageTransition, 1);
1948
* poppler_page_transition_copy:
1949
* @transition: a #PopplerPageTransition to copy
1951
* Creates a copy of @transition
1953
* Returns: a new allocated copy of @transition
1955
PopplerPageTransition *
1956
poppler_page_transition_copy (PopplerPageTransition *transition)
1958
PopplerPageTransition *new_transition;
1960
new_transition = poppler_page_transition_new ();
1961
*new_transition = *transition;
1963
return new_transition;
1967
* poppler_page_transition_free:
1968
* @transition: a #PopplerPageTransition
1970
* Frees the given #PopplerPageTransition
1973
poppler_page_transition_free (PopplerPageTransition *transition)
1975
g_free (transition);
1978
/* Form Field Mapping Type */
1979
POPPLER_DEFINE_BOXED_TYPE (PopplerFormFieldMapping, poppler_form_field_mapping,
1980
poppler_form_field_mapping_copy,
1981
poppler_form_field_mapping_free)
1984
* poppler_form_field_mapping_new:
1986
* Creates a new #PopplerFormFieldMapping
1988
* Returns: a new #PopplerFormFieldMapping, use poppler_form_field_mapping_free() to free it
1990
PopplerFormFieldMapping *
1991
poppler_form_field_mapping_new (void)
1993
return g_slice_new0 (PopplerFormFieldMapping);
1997
* poppler_form_field_mapping_copy:
1998
* @mapping: a #PopplerFormFieldMapping to copy
2000
* Creates a copy of @mapping
2002
* Returns: a new allocated copy of @mapping
2004
PopplerFormFieldMapping *
2005
poppler_form_field_mapping_copy (PopplerFormFieldMapping *mapping)
2007
PopplerFormFieldMapping *new_mapping;
2009
new_mapping = g_slice_dup (PopplerFormFieldMapping, mapping);
2012
new_mapping->field = (PopplerFormField *)g_object_ref (mapping->field);
2018
* poppler_form_field_mapping_free:
2019
* @mapping: a #PopplerFormFieldMapping
2021
* Frees the given #PopplerFormFieldMapping
2024
poppler_form_field_mapping_free (PopplerFormFieldMapping *mapping)
2026
if (G_UNLIKELY (!mapping))
2030
g_object_unref (mapping->field);
2032
g_slice_free (PopplerFormFieldMapping, mapping);
2035
/* PopplerAnnot Mapping Type */
2036
POPPLER_DEFINE_BOXED_TYPE (PopplerAnnotMapping, poppler_annot_mapping,
2037
poppler_annot_mapping_copy,
2038
poppler_annot_mapping_free)
2041
* poppler_annot_mapping_new:
2043
* Creates a new #PopplerAnnotMapping
2045
* Returns: a new #PopplerAnnotMapping, use poppler_annot_mapping_free() to free it
2047
PopplerAnnotMapping *
2048
poppler_annot_mapping_new (void)
2050
return g_slice_new0 (PopplerAnnotMapping);
2054
* poppler_annot_mapping_copy:
2055
* @mapping: a #PopplerAnnotMapping to copy
2057
* Creates a copy of @mapping
2059
* Returns: a new allocated copy of @mapping
2061
PopplerAnnotMapping *
2062
poppler_annot_mapping_copy (PopplerAnnotMapping *mapping)
2064
PopplerAnnotMapping *new_mapping;
2066
new_mapping = g_slice_dup (PopplerAnnotMapping, mapping);
2069
new_mapping->annot = (PopplerAnnot *) g_object_ref (mapping->annot);
2075
* poppler_annot_mapping_free:
2076
* @mapping: a #PopplerAnnotMapping
2078
* Frees the given #PopplerAnnotMapping
2081
poppler_annot_mapping_free (PopplerAnnotMapping *mapping)
2083
if (G_UNLIKELY (!mapping))
2087
g_object_unref (mapping->annot);
2089
g_slice_free (PopplerAnnotMapping, mapping);
2093
* poppler_page_get_crop_box:
2094
* @page: a #PopplerPage
2095
* @rect: (out): a #PopplerRectangle to fill
2097
* Retrurns the crop box of @page
2100
poppler_page_get_crop_box (PopplerPage *page, PopplerRectangle *rect)
2102
PDFRectangle* cropBox = page->page->getCropBox ();
2104
rect->x1 = cropBox->x1;
2105
rect->x2 = cropBox->x2;
2106
rect->y1 = cropBox->y1;
2107
rect->y2 = cropBox->y2;
2111
* poppler_page_get_text_layout:
2112
* @page: A #PopplerPage
2113
* @rectangles: (out) (array length=n_rectangles) (transfer container): return location for an array of #PopplerRectangle
2114
* @n_rectangles: (out) length of returned array
2116
* Obtains the layout of the text as a list of #PopplerRectangle
2117
* This array must be freed with g_free () when done.
2119
* The position in the array represents an offset in the text returned by
2120
* poppler_page_get_text()
2122
* Return value: %TRUE if the page contains text, %FALSE otherwise
2127
poppler_page_get_text_layout (PopplerPage *page,
2128
PopplerRectangle **rectangles,
2129
guint *n_rectangles)
2132
TextWordList *wordlist;
2133
TextWord *word, *nextword;
2134
PopplerRectangle *rect;
2135
int i, j, offset = 0;
2136
gdouble x1, y1, x2, y2;
2137
gdouble x3, y3, x4, y4;
2139
g_return_val_if_fail (POPPLER_IS_PAGE (page), FALSE);
2143
text = poppler_page_get_text_page (page);
2144
wordlist = text->makeWordList (gFalse);
2146
if (wordlist->getLength () <= 0)
2152
// Getting the array size
2153
for (i = 0; i < wordlist->getLength (); i++)
2155
word = wordlist->get (i);
2156
*n_rectangles += word->getLength () + 1;
2159
*rectangles = g_new (PopplerRectangle, *n_rectangles);
2161
// Calculating each char position
2162
for (i = 0; i < wordlist->getLength (); i++)
2164
word = wordlist->get (i);
2165
for (j = 0; j < word->getLength (); j++)
2167
rect = *rectangles + offset;
2168
word->getCharBBox (j,
2176
// adding spaces and break lines
2177
rect = *rectangles + offset;
2178
word->getBBox (&x1, &y1, &x2, &y2);
2180
nextword = word->getNext ();
2183
nextword->getBBox (&x3, &y3, &x4, &y4);
2184
// space is from one word to other and with the same height as