[poppler] poppler/glib: poppler-page.cc, 1.57, 1.58 poppler-page.h, 1.24, 1.25 poppler-private.h, 1.17, 1.18 poppler.h, 1.14, 1.15 test-poppler-glib.c, 1.20, 1.21

Albert Astals Cid aacid at kemper.freedesktop.org
Mon May 21 14:35:12 PDT 2007


Update of /cvs/poppler/poppler/glib
In directory kemper:/tmp/cvs-serv6259/glib

Modified Files:
	poppler-page.cc poppler-page.h poppler-private.h poppler.h 
	test-poppler-glib.c 
Log Message:
        * glib/poppler-page.cc:
        * glib/poppler-page.h:
        * glib/poppler-private.h:
        * glib/poppler.h:
        * glib/test-poppler-glib.c:
        * poppler/CairoOutputDev.cc:
        * poppler/CairoOutputDev.h: Extend CairoOutputdev to do
        image caching when rendering


Index: poppler-page.cc
===================================================================
RCS file: /cvs/poppler/poppler/glib/poppler-page.cc,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -d -r1.57 -r1.58
--- poppler-page.cc	27 Apr 2007 22:26:09 -0000	1.57
+++ poppler-page.cc	21 May 2007 21:35:10 -0000	1.58
@@ -73,7 +73,10 @@
     delete page->gfx;
   if (page->text_dev != NULL)
     delete page->text_dev;
-
+#if defined (HAVE_CAIRO)
+  if (page->image_dev != NULL)
+    delete page->image_dev;
+#endif
   /* page->page is owned by the document */
 }
 
@@ -282,9 +285,9 @@
 }
 
 static void
-poppler_page_copy_to_pixbuf (PopplerPage *page,
-			     GdkPixbuf *pixbuf,
-			     OutputDevData *output_dev_data)
+copy_cairo_surface_to_pixbuf (cairo_surface_t *surface,
+			      unsigned char   *data,
+			      GdkPixbuf       *pixbuf)
 {
   int cairo_width, cairo_height, cairo_rowstride;
   unsigned char *pixbuf_data, *dst, *cairo_data;
@@ -292,10 +295,10 @@
   unsigned int *src;
   int x, y;
 
-  cairo_width = cairo_image_surface_get_width (output_dev_data->surface);
-  cairo_height = cairo_image_surface_get_height (output_dev_data->surface);
+  cairo_width = cairo_image_surface_get_width (surface);
+  cairo_height = cairo_image_surface_get_height (surface);
   cairo_rowstride = cairo_width * 4;
-  cairo_data = output_dev_data->cairo_data;
+  cairo_data = data;
 
   pixbuf_data = gdk_pixbuf_get_pixels (pixbuf);
   pixbuf_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
@@ -320,7 +323,17 @@
 	  src++;
 	}
     }
+}	
 
+static void
+poppler_page_copy_to_pixbuf (PopplerPage *page,
+			     GdkPixbuf *pixbuf,
+			     OutputDevData *output_dev_data)
+{
+  copy_cairo_surface_to_pixbuf (output_dev_data->surface,
+				output_dev_data->cairo_data,
+				pixbuf);
+  
   page->document->output_dev->setCairo (NULL);
   cairo_surface_destroy (output_dev_data->surface);
   cairo_destroy (output_dev_data->cairo);
@@ -468,7 +481,7 @@
 			   src_width, src_height,
 			   gFalse, /* printing */
 			   page->document->doc->getCatalog ());
-
+  
   poppler_page_copy_to_pixbuf (page, pixbuf, &data);
 }
 
@@ -478,6 +491,8 @@
   if (page->text_dev == NULL) {
     page->text_dev = new TextOutputDev (NULL, gTrue, gFalse, gFalse);
 
+    if (page->gfx)
+      delete page->gfx;
     page->gfx = page->page->createGfx(page->text_dev,
 				      72.0, 72.0, 0,
 				      gFalse, /* useMediaBox */
@@ -858,6 +873,136 @@
   return g_list_reverse (matches);
 }
 
+#if defined (HAVE_CAIRO)
+
+static CairoImageOutputDev *
+poppler_page_get_image_output_dev (PopplerPage *page)
+{
+  if (page->image_dev == NULL) {
+    page->image_dev = new CairoImageOutputDev ();
+
+    if (page->gfx)
+      delete page->gfx;
+    page->gfx = page->page->createGfx(page->image_dev,
+				      72.0, 72.0, 0,
+				      gFalse, /* useMediaBox */
+				      gTrue, /* Crop */
+				      -1, -1, -1, -1,
+				      NULL, /* links */
+				      page->document->doc->getCatalog (),
+				      NULL, NULL, NULL, NULL);
+
+    page->page->display(page->gfx);
+  }
+
+  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
+ * with poppler_page_free_image_mapping() when done.
+ *
+ * Return value: A #GList of #PopplerImageMapping
+ **/
+GList *
+poppler_page_get_image_mapping (PopplerPage *page)
+{
+  GList *map_list = NULL;
+  CairoImageOutputDev *out;
+  gint i;
+  
+  g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);
+
+  out = poppler_page_get_image_output_dev (page);
+
+  for (i = 0; i < out->getNumImages (); i++) {
+    PopplerImageMapping *mapping;
+    CairoImage *image;
+
+    image = out->getImage (i);
+
+    /* Create the mapping */
+    mapping = g_new (PopplerImageMapping, 1);
+
+    image->getRect (&(mapping->area.x1), &(mapping->area.y1),
+		    &(mapping->area.x2), &(mapping->area.y2));
+    mapping->image = poppler_page_image_pixbuf_create (page, image);
+    
+    mapping->area.x1 -= page->page->getCropBox()->x1;
+    mapping->area.x2 -= page->page->getCropBox()->x1;
+    mapping->area.y1 -= page->page->getCropBox()->y1;
+    mapping->area.y2 -= page->page->getCropBox()->y1;
+
+    map_list = g_list_prepend (map_list, mapping);
+  }
+
+  return map_list;	
+}
+
+static void
+poppler_images_mapping_free (PopplerImageMapping *mapping)
+{
+  g_object_unref (mapping->image);
+  g_free (mapping);
+}
+
+/**
+ * poppler_page_free_image_mapping:
+ * @list: A list of #PopplerImageMapping<!-- -->s
+ *
+ * Frees a list of #PopplerImageMapping<!-- -->s allocated by
+ * poppler_page_get_image_mapping().
+ **/
+void
+poppler_page_free_image_mapping (GList *list)
+{
+  if (list == NULL)
+    return;
+
+  g_list_foreach (list, (GFunc) (poppler_images_mapping_free), NULL);
+  g_list_free (list);
+}
+
+#else
+
+GList *
+poppler_page_get_image_mapping (PopplerPage *page)
+{
+  return NULL;
+}
+
+void
+poppler_page_free_image_mapping (GList *list)
+{
+}
+
+#endif /* HAVE_CAIRO */
+
 /**
  * poppler_page_render_to_ps:
  * @page: a #PopplerPage

Index: poppler-page.h
===================================================================
RCS file: /cvs/poppler/poppler/glib/poppler-page.h,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- poppler-page.h	27 Apr 2007 22:26:09 -0000	1.24
+++ poppler-page.h	21 May 2007 21:35:10 -0000	1.25
@@ -71,6 +71,8 @@
 							  PopplerRectangle   *rect);
 GList                 *poppler_page_get_link_mapping     (PopplerPage        *page);
 void                   poppler_page_free_link_mapping    (GList              *list);
+GList                 *poppler_page_get_image_mapping    (PopplerPage        *page);
+void                   poppler_page_free_image_mapping   (GList              *list);
 GdkRegion             *poppler_page_get_selection_region (PopplerPage        *page,
 							  gdouble             scale,
 							  PopplerRectangle   *selection);
@@ -137,6 +139,14 @@
 PopplerPageTransition *poppler_page_transition_copy     (PopplerPageTransition *transition);
 void                   poppler_page_transition_free     (PopplerPageTransition *transition);
 
+/* Mapping between areas on the current page and images */
+#define POPPLER_TYPE_IMAGE_MAPPING             (poppler_image_mapping_get_type ())
+struct  _PopplerImageMapping
+{
+  PopplerRectangle area;
+  GdkPixbuf *image;	
+};
+
 /* FormField */
 #define POPPLER_TYPE_FORM_FIELD                     (poppler_form_field_get_type ())
 struct _PopplerTextField

Index: poppler-private.h
===================================================================
RCS file: /cvs/poppler/poppler/glib/poppler-private.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- poppler-private.h	24 Feb 2007 23:32:22 -0000	1.17
+++ poppler-private.h	21 May 2007 21:35:10 -0000	1.18
@@ -59,6 +59,9 @@
   int index;
   TextOutputDev *text_dev;
   Gfx *gfx;
+#if defined (HAVE_CAIRO)
+  CairoImageOutputDev *image_dev;
+#endif
 };
 
 PopplerFormField *_form_field_new_from_widget (FormWidget* field);

Index: poppler.h
===================================================================
RCS file: /cvs/poppler/poppler/glib/poppler.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- poppler.h	27 Apr 2007 22:26:09 -0000	1.14
+++ poppler.h	21 May 2007 21:35:10 -0000	1.15
@@ -36,10 +36,10 @@
 
 typedef enum
 {
-	POPPLER_ORIENTATION_PORTRAIT,
-	POPPLER_ORIENTATION_LANDSCAPE,
-	POPPLER_ORIENTATION_UPSIDEDOWN,
-	POPPLER_ORIENTATION_SEASCAPE
+  POPPLER_ORIENTATION_PORTRAIT,
+  POPPLER_ORIENTATION_LANDSCAPE,
+  POPPLER_ORIENTATION_UPSIDEDOWN,
+  POPPLER_ORIENTATION_SEASCAPE
 } PopplerOrientation;
 
 typedef enum
@@ -85,6 +85,7 @@
 typedef struct _PopplerRectangle      PopplerRectangle;
 typedef struct _PopplerLinkMapping    PopplerLinkMapping;
 typedef struct _PopplerPageTransition PopplerPageTransition;
+typedef struct _PopplerImageMapping PopplerImageMapping;
 typedef struct _PopplerFormField      PopplerFormField;
 typedef struct _PopplerPage           PopplerPage;
 typedef struct _PopplerFontInfo       PopplerFontInfo;

Index: test-poppler-glib.c
===================================================================
RCS file: /cvs/poppler/poppler/glib/test-poppler-glib.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- test-poppler-glib.c	27 Apr 2007 22:26:09 -0000	1.20
+++ test-poppler-glib.c	21 May 2007 21:35:10 -0000	1.21
@@ -174,6 +174,7 @@
   char *text;
   double duration;
   PopplerRectangle area;
+  gint num_images;
 
   if (argc != 3)
     FAIL ("usage: test-poppler-glib file://FILE PAGE");
@@ -236,8 +237,12 @@
 
   gdk_pixbuf_save (pixbuf, "slice.png", "png", &error, NULL);
   printf ("\tslice:\t\tsaved 200x200 slice at (100, 100) as slice.png\n");
-  if (error != NULL)
+  if (error != NULL) {
     FAIL (error->message);
+    g_error_free (error);
+  }
+
+  g_object_unref (G_OBJECT (pixbuf));
 
   area.x1 = 0;
   area.y1 = 0;
@@ -266,6 +271,26 @@
       printf ("  (%f,%f)-(%f,%f)\n", rect->x1, rect->y1, rect->x2, rect->y2);
     }
 
+  list = poppler_page_get_image_mapping (page);
+  num_images = g_list_length (list);
+  printf ("\n");
+  if (num_images > 0)
+    printf ("\tFound %d images at positions:\n", num_images);
+  else
+    printf ("\tNo images found\n");
+  for (l = list; l != NULL; l = l->next)
+    {
+      PopplerImageMapping *mapping;
+      
+      mapping = (PopplerImageMapping *)l->data;
+      printf ("\t\t(%f, %f) - (%f, %f)\n",
+	      mapping->area.x1,
+	      mapping->area.y1,
+	      mapping->area.x2,
+	      mapping->area.y2);
+    }
+  poppler_page_free_image_mapping (list);
+  
   if (poppler_document_has_attachments (document))
     {
       int i = 0;



More information about the poppler mailing list