[poppler] glib/poppler-page.cc glib/poppler-page.h poppler/CairoOutputDev.cc poppler/CairoOutputDev.h
Carlos Garcia Campos
carlosgc at kemper.freedesktop.org
Sat Jan 19 09:10:03 PST 2008
glib/poppler-page.cc | 81 +++++++++++++++-------------
glib/poppler-page.h | 6 +-
poppler/CairoOutputDev.cc | 131 ++++++++++++++++++++++++++--------------------
poppler/CairoOutputDev.h | 12 +++-
4 files changed, 135 insertions(+), 95 deletions(-)
New commits:
commit fcdd5c51f370d040ae57aa64801c9bd4dbe88752
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date: Sat Jan 19 18:00:10 2008 +0100
Do not render images when getting the image mapping, it can be done later on demand.
diff --git a/glib/poppler-page.cc b/glib/poppler-page.cc
index 13d639a..803effe 100644
--- a/glib/poppler-page.cc
+++ b/glib/poppler-page.cc
@@ -1106,11 +1106,18 @@ poppler_page_find_text (PopplerPage *page,
#if defined (HAVE_CAIRO)
static CairoImageOutputDev *
-poppler_page_get_image_output_dev (PopplerPage *page)
+poppler_page_get_image_output_dev (PopplerPage *page,
+ GBool (*imgDrawDeviceCbk)(int img_id, void *data),
+ void *imgDrawCbkData)
{
if (page->image_dev == NULL) {
page->image_dev = new CairoImageOutputDev ();
+ if (imgDrawDeviceCbk) {
+ page->image_dev->setImageDrawDecideCbk (imgDrawDeviceCbk,
+ imgDrawCbkData);
+ }
+
if (page->gfx)
delete page->gfx;
page->gfx = page->page->createGfx(page->image_dev,
@@ -1127,33 +1134,12 @@ poppler_page_get_image_output_dev (PopplerPage *page)
return page->image_dev;
}
-static GdkPixbuf *
-poppler_page_image_pixbuf_create (PopplerPage *page,
- CairoImage *image)
-{
- GdkPixbuf *pixbuf;
- cairo_surface_t *surface;
-
- surface = image->getImage ();
-
- pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
- FALSE, 8,
- cairo_image_surface_get_width (surface),
- cairo_image_surface_get_height (surface));
-
- copy_cairo_surface_to_pixbuf (surface,
- cairo_image_surface_get_data (surface),
- pixbuf);
-
- return pixbuf;
-}
-
/**
* poppler_page_get_image_mapping:
* @page: A #PopplerPage
*
* Returns a list of #PopplerImageMapping items that map from a
- * location on @page to a #GdkPixbuf. This list must be freed
+ * location on @page to an image of the page. This list must be freed
* with poppler_page_free_image_mapping() when done.
*
* Return value: A #GList of #PopplerImageMapping
@@ -1167,7 +1153,7 @@ poppler_page_get_image_mapping (PopplerPage *page)
g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);
- out = poppler_page_get_image_output_dev (page);
+ out = poppler_page_get_image_output_dev (page, NULL, NULL);
for (i = 0; i < out->getNumImages (); i++) {
PopplerImageMapping *mapping;
@@ -1180,7 +1166,7 @@ poppler_page_get_image_mapping (PopplerPage *page)
image->getRect (&(mapping->area.x1), &(mapping->area.y1),
&(mapping->area.x2), &(mapping->area.y2));
- mapping->image = poppler_page_image_pixbuf_create (page, image);
+ mapping->image_id = i;
mapping->area.x1 -= page->page->getCropBox()->x1;
mapping->area.x2 -= page->page->getCropBox()->x1;
@@ -1193,11 +1179,39 @@ poppler_page_get_image_mapping (PopplerPage *page)
return map_list;
}
-static void
-poppler_images_mapping_free (PopplerImageMapping *mapping)
+static GBool
+image_draw_decide_cb (int image_id, void *data)
{
- g_object_unref (mapping->image);
- g_free (mapping);
+ return (image_id == GPOINTER_TO_INT (data));
+}
+
+/**
+ * poppler_page_get_image:
+ * @page: A #PopplerPage
+ * @image_id: The image identificator
+ *
+ * Returns a cairo surface for the image of the @page
+ *
+ * Return value: A cairo surface for the image
+ **/
+cairo_surface_t *
+poppler_page_get_image (PopplerPage *page,
+ gint image_id)
+{
+ CairoImageOutputDev *out;
+ cairo_surface_t *image;
+
+ g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);
+
+ out = poppler_page_get_image_output_dev (page,
+ image_draw_decide_cb,
+ GINT_TO_POINTER (image_id));
+
+ if (image_id >= out->getNumImages ())
+ return NULL;
+
+ image = out->getImage (image_id)->getImage ();
+ return image ? cairo_surface_reference (image) : NULL;
}
/**
@@ -1213,11 +1227,11 @@ poppler_page_free_image_mapping (GList *list)
if (list == NULL)
return;
- g_list_foreach (list, (GFunc) (poppler_images_mapping_free), NULL);
+ g_list_foreach (list, (GFunc)g_free, NULL);
g_list_free (list);
}
-#else
+#else /* HAVE_CAIRO */
GList *
poppler_page_get_image_mapping (PopplerPage *page)
@@ -1593,8 +1607,6 @@ poppler_image_mapping_copy (PopplerImageMapping *mapping)
new_mapping = poppler_image_mapping_new ();
*new_mapping = *mapping;
- if (new_mapping->image)
- new_mapping->image = gdk_pixbuf_copy (new_mapping->image);
return new_mapping;
}
@@ -1602,9 +1614,6 @@ poppler_image_mapping_copy (PopplerImageMapping *mapping)
void
poppler_image_mapping_free (PopplerImageMapping *mapping)
{
- if (mapping->image)
- g_object_unref (mapping->image);
-
g_free (mapping);
}
diff --git a/glib/poppler-page.h b/glib/poppler-page.h
index c2cc51d..f8de186 100644
--- a/glib/poppler-page.h
+++ b/glib/poppler-page.h
@@ -84,6 +84,10 @@ GList *poppler_page_get_link_mapping (PopplerPage *pa
void poppler_page_free_link_mapping (GList *list);
GList *poppler_page_get_image_mapping (PopplerPage *page);
void poppler_page_free_image_mapping (GList *list);
+#ifdef POPPLER_HAS_CAIRO
+cairo_surface_t *poppler_page_get_image (PopplerPage *page,
+ gint image_id);
+#endif
GList *poppler_page_get_form_field_mapping (PopplerPage *page);
void poppler_page_free_form_field_mapping (GList *list);
GdkRegion *poppler_page_get_selection_region (PopplerPage *page,
@@ -167,7 +171,7 @@ void poppler_page_transition_free (PopplerPageTransition *
struct _PopplerImageMapping
{
PopplerRectangle area;
- GdkPixbuf *image;
+ gint image_id;
};
GType poppler_image_mapping_get_type (void) G_GNUC_CONST;
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index ef6e42f..99f5c2b 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -51,9 +51,8 @@ static inline void printMatrix(cairo_matrix_t *matrix){
// CairoImage
//------------------------------------------------------------------------
-CairoImage::CairoImage (cairo_surface_t *image,
- double x1, double y1, double x2, double y2) {
- this->image = cairo_surface_reference (image);
+CairoImage::CairoImage (double x1, double y1, double x2, double y2) {
+ this->image = NULL;
this->x1 = x1;
this->y1 = y1;
this->x2 = x2;
@@ -65,6 +64,12 @@ CairoImage::~CairoImage () {
cairo_surface_destroy (image);
}
+void CairoImage::setImage (cairo_surface_t *image) {
+ if (this->image)
+ cairo_surface_destroy (this->image);
+ this->image = cairo_surface_reference (image);
+}
+
//------------------------------------------------------------------------
// CairoOutputDev
//------------------------------------------------------------------------
@@ -1624,6 +1629,8 @@ CairoImageOutputDev::CairoImageOutputDev()
images = NULL;
numImages = 0;
size = 0;
+ imgDrawCbk = NULL;
+ imgDrawCbkData = NULL;
}
CairoImageOutputDev::~CairoImageOutputDev()
@@ -1668,20 +1675,23 @@ void CairoImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *st
x2 = x1 + width;
y2 = y1 + height;
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
- cr = cairo_create (surface);
- setCairo (cr);
- cairo_translate (cr, 0, height);
- cairo_scale (cr, width, -height);
+ image = new CairoImage (x1, y1, x2, y2);
+ saveImage (image);
- CairoOutputDev::drawImageMask(state, ref, str, width, height, invert, inlineImg);
+ if (imgDrawCbk && imgDrawCbk (numImages - 1, imgDrawCbkData)) {
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ cr = cairo_create (surface);
+ setCairo (cr);
+ cairo_translate (cr, 0, height);
+ cairo_scale (cr, width, -height);
- image = new CairoImage (surface, x1, y1, x2, y2);
- saveImage (image);
-
- setCairo (NULL);
- cairo_surface_destroy (surface);
- cairo_destroy (cr);
+ CairoOutputDev::drawImageMask(state, ref, str, width, height, invert, inlineImg);
+ image->setImage (surface);
+
+ setCairo (NULL);
+ cairo_surface_destroy (surface);
+ cairo_destroy (cr);
+ }
}
void CairoImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
@@ -1708,20 +1718,23 @@ void CairoImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
x2 = x1 + width;
y2 = y1 + height;
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
- cr = cairo_create (surface);
- setCairo (cr);
- cairo_translate (cr, 0, height);
- cairo_scale (cr, width, -height);
-
- CairoOutputDev::drawImage(state, ref, str, width, height, colorMap, maskColors, inlineImg);
-
- image = new CairoImage (surface, x1, y1, x2, y2);
+ image = new CairoImage (x1, y1, x2, y2);
saveImage (image);
-
- setCairo (NULL);
- cairo_surface_destroy (surface);
- cairo_destroy (cr);
+
+ if (imgDrawCbk && imgDrawCbk (numImages - 1, imgDrawCbkData)) {
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ cr = cairo_create (surface);
+ setCairo (cr);
+ cairo_translate (cr, 0, height);
+ cairo_scale (cr, width, -height);
+
+ CairoOutputDev::drawImage(state, ref, str, width, height, colorMap, maskColors, inlineImg);
+ image->setImage (surface);
+
+ setCairo (NULL);
+ cairo_surface_destroy (surface);
+ cairo_destroy (cr);
+ }
}
void CairoImageOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
@@ -1751,21 +1764,24 @@ void CairoImageOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stre
x2 = x1 + width;
y2 = y1 + height;
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
- cr = cairo_create (surface);
- setCairo (cr);
- cairo_translate (cr, 0, height);
- cairo_scale (cr, width, -height);
-
- CairoOutputDev::drawSoftMaskedImage(state, ref, str, width, height, colorMap,
- maskStr, maskWidth, maskHeight, maskColorMap);
-
- image = new CairoImage (surface, x1, y1, x2, y2);
+ image = new CairoImage (x1, y1, x2, y2);
saveImage (image);
-
- setCairo (NULL);
- cairo_surface_destroy (surface);
- cairo_destroy (cr);
+
+ if (imgDrawCbk && imgDrawCbk (numImages - 1, imgDrawCbkData)) {
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ cr = cairo_create (surface);
+ setCairo (cr);
+ cairo_translate (cr, 0, height);
+ cairo_scale (cr, width, -height);
+
+ CairoOutputDev::drawSoftMaskedImage(state, ref, str, width, height, colorMap,
+ maskStr, maskWidth, maskHeight, maskColorMap);
+ image->setImage (surface);
+
+ setCairo (NULL);
+ cairo_surface_destroy (surface);
+ cairo_destroy (cr);
+ }
}
void CairoImageOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str,
@@ -1795,19 +1811,22 @@ void CairoImageOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *
x2 = x1 + width;
y2 = y1 + height;
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
- cr = cairo_create (surface);
- setCairo (cr);
- cairo_translate (cr, 0, height);
- cairo_scale (cr, width, -height);
-
- CairoOutputDev::drawMaskedImage(state, ref, str, width, height, colorMap,
- maskStr, maskWidth, maskHeight, maskInvert);
-
- image = new CairoImage (surface, x1, y1, x2, y2);
+ image = new CairoImage (x1, y1, x2, y2);
saveImage (image);
-
- setCairo (NULL);
- cairo_surface_destroy (surface);
- cairo_destroy (cr);
+
+ if (imgDrawCbk && imgDrawCbk (numImages - 1, imgDrawCbkData)) {
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ cr = cairo_create (surface);
+ setCairo (cr);
+ cairo_translate (cr, 0, height);
+ cairo_scale (cr, width, -height);
+
+ CairoOutputDev::drawMaskedImage(state, ref, str, width, height, colorMap,
+ maskStr, maskWidth, maskHeight, maskInvert);
+ image->setImage (surface);
+
+ setCairo (NULL);
+ cairo_surface_destroy (surface);
+ cairo_destroy (cr);
+ }
}
diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h
index ade108e..ae44532 100644
--- a/poppler/CairoOutputDev.h
+++ b/poppler/CairoOutputDev.h
@@ -34,11 +34,14 @@ class CairoFont;
class CairoImage {
public:
// Constructor.
- CairoImage (cairo_surface_t *image, double x1, double y1, double x2, double y2);
+ CairoImage (double x1, double y1, double x2, double y2);
// Destructor.
~CairoImage ();
+ // Set the image cairo surface
+ void setImage (cairo_surface_t *image);
+
// Get the image cairo surface
cairo_surface_t *getImage () const { return image; }
@@ -324,16 +327,21 @@ public:
virtual void clearSoftMask(GfxState * /*state*/) {}
//----- Image list
+ // By default images are not rendred
+ void setImageDrawDecideCbk(GBool (*cbk)(int img_id, void *data),
+ void *data) { imgDrawCbk = cbk; imgDrawCbkData = data; }
// Iterate through list of images.
int getNumImages() const { return numImages; }
CairoImage *getImage(int i) const { return images[i]; }
private:
void saveImage(CairoImage *image);
-
+
CairoImage **images;
int numImages;
int size;
+ GBool (*imgDrawCbk)(int img_id, void *data);
+ void *imgDrawCbkData;
};
#endif
More information about the poppler
mailing list