[poppler] 2 commits - glib/poppler-annot.cc glib/poppler-page.cc glib/poppler-private.h
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Mon Feb 10 16:46:02 UTC 2020
glib/poppler-annot.cc | 109 +++++++++++++++++++++++++++++++++++++++----------
glib/poppler-page.cc | 65 +++++++++++++++++++++++++++--
glib/poppler-private.h | 2
3 files changed, 150 insertions(+), 26 deletions(-)
New commits:
commit d27cf873b8db1ca2b20cdc16a724c63a42d6473d
Author: Nelson Benítez León <nbenitezl at gmail.com>
Date: Tue Oct 29 19:08:30 2019 -0400
poppler-page: minor optimization
on poppler_page_get_annot_mapping().
Let's retrieve the cropbox just once,
on the outside of the _for_ loop.
diff --git a/glib/poppler-page.cc b/glib/poppler-page.cc
index f232d69e..322f2d48 100644
--- a/glib/poppler-page.cc
+++ b/glib/poppler-page.cc
@@ -1383,6 +1383,7 @@ poppler_page_get_annot_mapping (PopplerPage *page)
double width, height;
gint i;
Annots *annots;
+ const PDFRectangle *crop_box;
g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);
@@ -1391,6 +1392,7 @@ poppler_page_get_annot_mapping (PopplerPage *page)
return nullptr;
poppler_page_get_size (page, &width, &height);
+ crop_box = page->page->getCropBox ();
for (i = 0; i < annots->getNumAnnots (); i++) {
PopplerAnnotMapping *mapping;
@@ -1442,10 +1444,10 @@ poppler_page_get_annot_mapping (PopplerPage *page)
}
annot_rect = annot->getRect ();
- rect.x1 = annot_rect->x1 - page->page->getCropBox()->x1;
- rect.y1 = annot_rect->y1 - page->page->getCropBox()->y1;
- rect.x2 = annot_rect->x2 - page->page->getCropBox()->x1;
- rect.y2 = annot_rect->y2 - page->page->getCropBox()->y1;
+ rect.x1 = annot_rect->x1 - crop_box->x1;
+ rect.y1 = annot_rect->y1 - crop_box->y1;
+ rect.x2 = annot_rect->x2 - crop_box->x1;
+ rect.y2 = annot_rect->y2 - crop_box->y1;
if (! (annot->getFlags () & Annot::flagNoRotate))
rotation = page->page->getRotate ();
commit f5ff25788ef23041a498a98e0ba9718590d96db0
Author: Nelson Benítez León <nbenitezl at gmail.com>
Date: Mon Oct 28 21:51:21 2019 -0400
glib: automatic handle of page's cropbox on annots
Core poppler annot (Annot.cc) has cropbox offsets included
in the coordinates of the relevant fields (rect and
quadrilaterals fields).
This commit makes poppler-glib API _not_ include cropbox
offsets when providing annot info to clients (by substracting
cropbox offsets from the read core Annot info) and in the same
way, assumes no cropbox offsets are included in the info
received from clients to create new annots (cropbox offsets will
be automatically added to the corresponding core poppler Annot).
As a result of this, existent clients (like Evince) now automatically
work right for annotations placed in pages that have a cropbox.
Poppler issue: poppler/poppler#129
Evince issue: https://gitlab.gnome.org/GNOME/evince/issues/1280
diff --git a/glib/poppler-annot.cc b/glib/poppler-annot.cc
index 4d693869..b59926b4 100644
--- a/glib/poppler-annot.cc
+++ b/glib/poppler-annot.cc
@@ -264,30 +264,49 @@ _poppler_annot_text_markup_new (Annot *annot)
return _poppler_create_annot (POPPLER_TYPE_ANNOT_TEXT_MARKUP, annot);
}
+/* If @crop_box parameter is non null, it will add the crop_box offset
+ * to the coordinates of the returned quads */
static AnnotQuadrilaterals *
-create_annot_quads_from_poppler_quads (GArray *quads)
+create_annot_quads_from_poppler_quads (GArray *quads,
+ const PDFRectangle *crop_box)
{
+ PDFRectangle zerobox;
g_assert (quads->len > 0);
+ if (!crop_box) {
+ zerobox = PDFRectangle();
+ crop_box = &zerobox;
+ }
+
auto quads_array = std::make_unique<AnnotQuadrilaterals::AnnotQuadrilateral[]>(quads->len);
for (guint i = 0; i < quads->len; i++) {
PopplerQuadrilateral *quadrilateral = &g_array_index (quads, PopplerQuadrilateral, i);
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);
+ quadrilateral->p1.x + crop_box->x1, quadrilateral->p1.y + crop_box->y1,
+ quadrilateral->p2.x + crop_box->x1, quadrilateral->p2.y + crop_box->y1,
+ quadrilateral->p3.x + crop_box->x1, quadrilateral->p3.y + crop_box->y1,
+ quadrilateral->p4.x + crop_box->x1, quadrilateral->p4.y + crop_box->y1);
}
return new AnnotQuadrilaterals (std::move(quads_array), quads->len);
}
+/* If @crop_box parameter is non null, it will substract the crop_box offset
+ * from the coordinates of the returned #PopplerQuadrilateral array */
static GArray *
-create_poppler_quads_from_annot_quads (AnnotQuadrilaterals *quads_array)
+create_poppler_quads_from_annot_quads (AnnotQuadrilaterals *quads_array,
+ const PDFRectangle *crop_box)
{
GArray *quads;
guint quads_len;
+ PDFRectangle zerobox;
+
+ if (!crop_box) {
+ zerobox = PDFRectangle();
+ crop_box = &zerobox;
+ }
+
quads_len = quads_array->getQuadrilateralsLength();
quads = g_array_sized_new (FALSE, FALSE,
@@ -298,14 +317,14 @@ create_poppler_quads_from_annot_quads (AnnotQuadrilaterals *quads_array)
for (guint i = 0; i < quads_len; ++i) {
PopplerQuadrilateral *quadrilateral = &g_array_index (quads, PopplerQuadrilateral, i);
- quadrilateral->p1.x = quads_array->getX1(i);
- quadrilateral->p1.y = quads_array->getY1(i);
- quadrilateral->p2.x = quads_array->getX2(i);
- quadrilateral->p2.y = quads_array->getY2(i);
- quadrilateral->p3.x = quads_array->getX3(i);
- quadrilateral->p3.y = quads_array->getY3(i);
- quadrilateral->p4.x = quads_array->getX4(i);
- quadrilateral->p4.y = quads_array->getY4(i);
+ quadrilateral->p1.x = quads_array->getX1(i) - crop_box->x1;
+ quadrilateral->p1.y = quads_array->getY1(i) - crop_box->y1;
+ quadrilateral->p2.x = quads_array->getX2(i) - crop_box->x1;
+ quadrilateral->p2.y = quads_array->getY2(i) - crop_box->y1;
+ quadrilateral->p3.x = quads_array->getX3(i) - crop_box->x1;
+ quadrilateral->p3.y = quads_array->getY3(i) - crop_box->y1;
+ quadrilateral->p4.x = quads_array->getX4(i) - crop_box->x1;
+ quadrilateral->p4.y = quads_array->getY4(i) - crop_box->y1;
}
return quads;
@@ -1007,6 +1026,28 @@ poppler_annot_get_page_index (PopplerAnnot *poppler_annot)
return page_num <= 0 ? -1 : page_num - 1;
}
+/* Returns cropbox rect for the page where the passed in @poppler_annot is in,
+ * or NULL when could not retrieve the cropbox */
+const PDFRectangle *
+_poppler_annot_get_cropbox (PopplerAnnot *poppler_annot)
+{
+ int page_index;
+
+ /* A returned zero means annot is not added to any page yet */
+ page_index = poppler_annot->annot->getPageNum();
+
+ if (page_index) {
+ Page *page;
+
+ page = poppler_annot->annot->getDoc()->getPage(page_index);
+ if (page) {
+ return page->getCropBox ();
+ }
+ }
+
+ return nullptr;
+}
+
/**
* poppler_annot_get_rectangle:
* @poppler_annot: a #PopplerAnnot
@@ -1022,15 +1063,23 @@ poppler_annot_get_rectangle (PopplerAnnot *poppler_annot,
PopplerRectangle *poppler_rect)
{
PDFRectangle *annot_rect;
+ const PDFRectangle *crop_box;
+ PDFRectangle zerobox;
g_return_if_fail (POPPLER_IS_ANNOT (poppler_annot));
g_return_if_fail (poppler_rect != nullptr);
+ crop_box = _poppler_annot_get_cropbox (poppler_annot);
+ if (!crop_box) {
+ zerobox = PDFRectangle();
+ crop_box = &zerobox;
+ }
+
annot_rect = poppler_annot->annot->getRect ();
- poppler_rect->x1 = annot_rect->x1;
- poppler_rect->x2 = annot_rect->x2;
- poppler_rect->y1 = annot_rect->y1;
- poppler_rect->y2 = annot_rect->y2;
+ poppler_rect->x1 = annot_rect->x1 - crop_box->x1;
+ poppler_rect->x2 = annot_rect->x2 - crop_box->x1;
+ poppler_rect->y1 = annot_rect->y1 - crop_box->y1;
+ poppler_rect->y2 = annot_rect->y2 - crop_box->y1;
}
/**
@@ -1047,11 +1096,22 @@ void
poppler_annot_set_rectangle (PopplerAnnot *poppler_annot,
PopplerRectangle *poppler_rect)
{
+ const PDFRectangle *crop_box;
+ PDFRectangle zerobox;
+
g_return_if_fail (POPPLER_IS_ANNOT (poppler_annot));
g_return_if_fail (poppler_rect != nullptr);
- poppler_annot->annot->setRect (poppler_rect->x1, poppler_rect->y1,
- poppler_rect->x2, poppler_rect->y2);
+ crop_box = _poppler_annot_get_cropbox (poppler_annot);
+ if (!crop_box) {
+ zerobox = PDFRectangle();
+ crop_box = &zerobox;
+ }
+
+ poppler_annot->annot->setRect (poppler_rect->x1 + crop_box->x1,
+ poppler_rect->y1 + crop_box->y1,
+ poppler_rect->x2 + crop_box->x1,
+ poppler_rect->y2 + crop_box->y1 );
}
/* PopplerAnnotMarkup */
@@ -1614,12 +1674,14 @@ poppler_annot_text_markup_set_quadrilaterals (PopplerAnnotTextMarkup *poppler_an
GArray *quadrilaterals)
{
AnnotTextMarkup *annot;
+ const PDFRectangle* crop_box;
g_return_if_fail (POPPLER_IS_ANNOT_TEXT_MARKUP (poppler_annot));
g_return_if_fail (quadrilaterals != nullptr && quadrilaterals->len > 0);
annot = static_cast<AnnotTextMarkup *>(POPPLER_ANNOT (poppler_annot)->annot);
- AnnotQuadrilaterals *quads = create_annot_quads_from_poppler_quads (quadrilaterals);
+ crop_box = _poppler_annot_get_cropbox (POPPLER_ANNOT (poppler_annot));
+ AnnotQuadrilaterals *quads = create_annot_quads_from_poppler_quads (quadrilaterals, crop_box);
annot->setQuadrilaterals (quads);
delete quads;
}
@@ -1639,13 +1701,16 @@ poppler_annot_text_markup_set_quadrilaterals (PopplerAnnotTextMarkup *poppler_an
GArray *
poppler_annot_text_markup_get_quadrilaterals (PopplerAnnotTextMarkup *poppler_annot)
{
+ const PDFRectangle* crop_box;
AnnotTextMarkup *annot;
g_return_val_if_fail (POPPLER_IS_ANNOT_TEXT_MARKUP (poppler_annot), NULL);
annot = static_cast<AnnotTextMarkup *>(POPPLER_ANNOT (poppler_annot)->annot);
+ crop_box = _poppler_annot_get_cropbox (POPPLER_ANNOT (poppler_annot));
+ AnnotQuadrilaterals *quads = annot->getQuadrilaterals();
- return create_poppler_quads_from_annot_quads (annot->getQuadrilaterals());
+ return create_poppler_quads_from_annot_quads (quads, crop_box);
}
/* PopplerAnnotFreeText */
diff --git a/glib/poppler-page.cc b/glib/poppler-page.cc
index 319edc50..f232d69e 100644
--- a/glib/poppler-page.cc
+++ b/glib/poppler-page.cc
@@ -1502,6 +1502,34 @@ poppler_page_free_annot_mapping (GList *list)
g_list_free_full (list, (GDestroyNotify)poppler_annot_mapping_free);
}
+/* Adds or removes (according to @add parameter) the passed in @crop_box from the
+ * passed in @quads and returns it as a new #AnnotQuadrilaterals object */
+static AnnotQuadrilaterals *
+new_quads_from_offset_cropbox (const PDFRectangle* crop_box,
+ AnnotQuadrilaterals *quads,
+ gboolean add)
+{
+ int len = quads->getQuadrilateralsLength();
+ auto quads_array = std::make_unique<AnnotQuadrilaterals::AnnotQuadrilateral[]>(len);
+ for (int i = 0; i < len; i++) {
+ if (add) {
+ quads_array[i] = AnnotQuadrilaterals::AnnotQuadrilateral (
+ quads->getX1(i) + crop_box->x1, quads->getY1(i) + crop_box->y1,
+ quads->getX2(i) + crop_box->x1, quads->getY2(i) + crop_box->y1,
+ quads->getX3(i) + crop_box->x1, quads->getY3(i) + crop_box->y1,
+ quads->getX4(i) + crop_box->x1, quads->getY4(i) + crop_box->y1);
+ } else {
+ quads_array[i] = AnnotQuadrilaterals::AnnotQuadrilateral (
+ quads->getX1(i) - crop_box->x1, quads->getY1(i) - crop_box->y1,
+ quads->getX2(i) - crop_box->x1, quads->getY2(i) - crop_box->y1,
+ quads->getX3(i) - crop_box->x1, quads->getY3(i) - crop_box->y1,
+ quads->getX4(i) - crop_box->x1, quads->getY4(i) - crop_box->y1);
+ }
+ }
+
+ return new AnnotQuadrilaterals (std::move(quads_array), len);
+}
+
/**
* poppler_page_add_annot:
* @page: a #PopplerPage
@@ -1515,9 +1543,36 @@ void
poppler_page_add_annot (PopplerPage *page,
PopplerAnnot *annot)
{
+ double x1, y1, x2, y2;
+ const PDFRectangle *crop_box;
+ const PDFRectangle *page_crop_box;
+
g_return_if_fail (POPPLER_IS_PAGE (page));
g_return_if_fail (POPPLER_IS_ANNOT (annot));
+ /* Add the page's cropBox to the coordinates of rect field of annot */
+ page_crop_box = page->page->getCropBox ();
+ annot->annot->getRect(&x1, &y1, &x2, &y2);
+ annot->annot->setRect(x1 + page_crop_box->x1,
+ y1 + page_crop_box->y1,
+ x2 + page_crop_box->x1,
+ y2 + page_crop_box->y1);
+
+ AnnotTextMarkup *annot_markup = dynamic_cast<AnnotTextMarkup*>(annot->annot);
+ if (annot_markup) {
+ AnnotQuadrilaterals *quads;
+ crop_box = _poppler_annot_get_cropbox (annot);
+ if (crop_box) {
+ /* Handle hypothetical case of annot being added is already existing on a prior page, so
+ * first remove cropbox of the prior page before adding cropbox of the new page later */
+ quads = new_quads_from_offset_cropbox (crop_box, annot_markup->getQuadrilaterals(), FALSE);
+ annot_markup->setQuadrilaterals( quads );
+ }
+ /* Add to annot's quadrilaterals the offset for the cropbox of the new page */
+ quads = new_quads_from_offset_cropbox (page_crop_box, annot_markup->getQuadrilaterals(), TRUE);
+ annot_markup->setQuadrilaterals( quads );
+ }
+
page->page->addAnnot (annot->annot);
}
diff --git a/glib/poppler-private.h b/glib/poppler-private.h
index 86b587fd..6e7e45fe 100644
--- a/glib/poppler-private.h
+++ b/glib/poppler-private.h
@@ -140,6 +140,8 @@ PopplerAnnot *_poppler_annot_line_new (Annot *annot);
PopplerAnnot *_poppler_annot_circle_new (Annot *annot);
PopplerAnnot *_poppler_annot_square_new (Annot *annot);
+const PDFRectangle *_poppler_annot_get_cropbox (PopplerAnnot *poppler_annot);
+
char *_poppler_goo_string_to_utf8(const GooString *s);
gboolean _poppler_convert_pdf_date_to_gtime (const GooString *date,
time_t *gdate);
More information about the poppler
mailing list