Commit fcdd5c51 authored by Carlos Garcia Campos's avatar Carlos Garcia Campos

Do not render images when getting the image mapping, it can be done later on demand.

parent 37ae4657
......@@ -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);
}
......
......@@ -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;
......
......@@ -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);
}
}
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment