[poppler] poppler/glib: poppler-page.cc, 1.21, 1.22 poppler-page.h,
1.14, 1.15 poppler-private.h, 1.8, 1.9
Kristian Hogsberg
krh at freedesktop.org
Wed Jun 29 14:24:59 PDT 2005
- Previous message: [poppler] poppler: ChangeLog,1.126,1.127 configure.ac,1.27,1.28
- Next message: [poppler] poppler/poppler: CairoOutputDev.cc, 1.16,
1.17 CairoOutputDev.h, 1.6, 1.7 Page.cc, 1.4, 1.5 Page.h, 1.3,
1.4 TextOutputDev.cc, 1.1.1.1, 1.2 TextOutputDev.h, 1.2, 1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvs/poppler/poppler/glib
In directory gabe:/tmp/cvs-serv13816/glib
Modified Files:
poppler-page.cc poppler-page.h poppler-private.h
Log Message:
2005-06-29 Kristian Høgsberg <krh at redhat.com>
* configure.ac:
* glib/poppler-page.cc:
* glib/poppler-page.h:
* glib/poppler-private.h:
* poppler/CairoOutputDev.cc:
* poppler/CairoOutputDev.h:
* poppler/Page.cc:
* poppler/Page.h:
* poppler/TextOutputDev.cc:
* poppler/TextOutputDev.h: Add support for rendering real
selection (based on text flow).
Index: poppler-page.cc
===================================================================
RCS file: /cvs/poppler/poppler/glib/poppler-page.cc,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- poppler-page.cc 28 Jun 2005 03:44:12 -0000 1.21
+++ poppler-page.cc 29 Jun 2005 21:24:56 -0000 1.22
@@ -88,6 +88,13 @@
static void
poppler_page_finalize (GObject *object)
{
+ PopplerPage *page = POPPLER_PAGE (object);
+
+ if (page->gfx != NULL)
+ delete page->gfx;
+ if (page->text_dev != NULL)
+ delete page->text_dev;
+
/* page->page is owned by the document */
}
@@ -157,82 +164,100 @@
#if defined (HAVE_CAIRO)
+typedef struct {
+ unsigned char *cairo_data;
+ cairo_surface_t *surface;
+} OutputDevData;
+
static void
-cairo_render_to_pixbuf (PopplerPage *page,
- int src_x, int src_y,
- int src_width, int src_height,
- double scale,
- GdkPixbuf *pixbuf,
- int dest_x, int dest_y)
+poppler_page_prepare_output_dev (PopplerPage *page,
+ double scale,
+ gboolean transparent,
+ OutputDevData *output_dev_data)
{
CairoOutputDev *output_dev;
- int cairo_width, cairo_height, cairo_rowstride;
- int pixbuf_rowstride, pixbuf_n_channels;
- guchar *pixbuf_data, *cairo_data, *dst;
cairo_surface_t *surface;
- int x, y;
+ int cairo_width, cairo_height, cairo_rowstride;
+ unsigned char *cairo_data;
output_dev = page->document->output_dev;
-
cairo_width = MAX ((int)(page->page->getWidth() * scale + 0.5), 1);
cairo_height = MAX ((int)(page->page->getHeight() * scale + 0.5), 1);
cairo_rowstride = cairo_width * 4;
cairo_data = (guchar *) gmalloc (cairo_height * cairo_rowstride);
- memset (cairo_data, 0xff, cairo_height * cairo_rowstride);
+ if (transparent)
+ memset (cairo_data, 0x00, cairo_height * cairo_rowstride);
+ else
+ memset (cairo_data, 0xff, cairo_height * cairo_rowstride);
+
surface = cairo_image_surface_create_for_data(cairo_data,
CAIRO_FORMAT_ARGB32,
cairo_width, cairo_height,
cairo_rowstride);
+
+ output_dev_data->cairo_data = cairo_data;
+ output_dev_data->surface = surface;
output_dev->setSurface (surface);
+}
- page->page->displaySlice(output_dev, 72.0 * scale, 72.0 * scale,
- poppler_page_get_rotate (page),
- gTrue, /* Crop */
- src_x, src_y,
- src_width, src_height,
- NULL, /* links */
- page->document->doc->getCatalog ());
+void
+poppler_page_copy_to_pixbuf (PopplerPage *page,
+ GdkPixbuf *pixbuf,
+ OutputDevData *output_dev_data)
+{
+ int cairo_width, cairo_height, cairo_rowstride;
+ unsigned char *pixbuf_data, *dst, *cairo_data;
+ int pixbuf_rowstride, pixbuf_n_channels;
+ 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_rowstride = cairo_width * 4;
+ cairo_data = output_dev_data->cairo_data;
pixbuf_data = gdk_pixbuf_get_pixels (pixbuf);
pixbuf_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
pixbuf_n_channels = gdk_pixbuf_get_n_channels (pixbuf);
- if (dest_x + cairo_width > gdk_pixbuf_get_width (pixbuf))
- cairo_width = gdk_pixbuf_get_width (pixbuf) - dest_x;
- if (dest_y + cairo_height > gdk_pixbuf_get_height (pixbuf))
- cairo_height = gdk_pixbuf_get_height (pixbuf) - dest_y;
-
for (y = 0; y < cairo_height; y++)
{
- unsigned int *src;
-
src = (unsigned int *) (cairo_data + y * cairo_rowstride);
- dst = pixbuf_data + (dest_y + y) * pixbuf_rowstride +
- dest_x * pixbuf_n_channels;
+ dst = pixbuf_data + y * pixbuf_rowstride;
for (x = 0; x < cairo_width; x++)
{
dst[0] = (*src >> 16) & 0xff;
dst[1] = (*src >> 8) & 0xff;
dst[2] = (*src >> 0) & 0xff;
+ if (pixbuf_n_channels == 4)
+ dst[3] = (*src >> 24) & 0xff;
dst += pixbuf_n_channels;
src++;
}
}
- output_dev->setSurface (NULL);
- cairo_surface_destroy (surface);
- gfree (cairo_data);
+ page->document->output_dev->setSurface (NULL);
+ cairo_surface_destroy (output_dev_data->surface);
+ gfree (output_dev_data->cairo_data);
}
#elif defined (HAVE_SPLASH)
+typedef struct {
+} OutputDevData;
+
static void
-splash_render_to_pixbuf (PopplerPage *page,
- int src_x, int src_y,
- int src_width, int src_height,
- double scale,
- GdkPixbuf *pixbuf,
- int dest_x, int dest_y)
+poppler_page_prepare_output_dev (PopplerPage *page,
+ double scale,
+ gboolean transparent,
+ OutputDevData *output_dev_data)
+{
+ /* pft */
+}
+
+poppler_page_copy_to_pixbuf(PopplerPage *page,
+ GdkPixbuf *pixbuf,
+ OutputDevData *data)
{
SplashOutputDev *output_dev;
SplashBitmap *bitmap;
@@ -244,14 +269,6 @@
output_dev = page->document->output_dev;
- page->page->displaySlice(output_dev, 72.0 * scale, 72.0 * scale,
- poppler_page_get_rotate (page),
- gTrue, /* Crop */
- src_x, src_y,
- src_width, src_height,
- NULL, /* links */
- page->document->doc->getCatalog ());
-
bitmap = output_dev->getBitmap ();
color_ptr = bitmap->getDataPtr ();
@@ -314,22 +331,121 @@
GdkPixbuf *pixbuf,
int dest_x, int dest_y)
{
+ OutputDevData data;
g_return_if_fail (POPPLER_IS_PAGE (page));
g_return_if_fail (scale > 0.0);
g_return_if_fail (pixbuf != NULL);
-#if defined(HAVE_CAIRO)
- cairo_render_to_pixbuf (page, src_x, src_y, src_width, src_height,
- scale, pixbuf, dest_x, dest_y);
-#elif defined(HAVE_SPLASH)
- splash_render_to_pixbuf (page, src_x, src_y, src_width, src_height,
- scale, pixbuf, dest_x, dest_y);
-#else
-#error No rendering backend available
-#endif
+ poppler_page_prepare_output_dev (page, scale, FALSE, &data);
+
+ page->page->displaySlice(page->document->output_dev,
+ 72.0 * scale, 72.0 * scale,
+ poppler_page_get_rotate (page),
+ gTrue, /* Crop */
+ src_x, src_y,
+ src_width, src_height,
+ NULL, /* links */
+ page->document->doc->getCatalog ());
+
+ poppler_page_copy_to_pixbuf (page, pixbuf, &data);
+}
+
+static TextOutputDev *
+poppler_page_get_text_output_dev (PopplerPage *page)
+{
+ if (page->text_dev == NULL) {
+ page->text_dev = new TextOutputDev (NULL, gTrue, gFalse, gFalse);
+
+ page->gfx = page->page->createGfx(page->text_dev,
+ 72.0, 72.0,
+ poppler_page_get_rotate (page),
+ gTrue, /* Crop */
+ -1, -1, -1, -1,
+ NULL, /* links */
+ page->document->doc->getCatalog (),
+ NULL, NULL, NULL, NULL);
+
+ page->page->display(page->gfx);
+
+ page->text_dev->endPage();
+ }
+
+ return page->text_dev;
+}
+
+GdkRegion *
+poppler_page_get_selection_region (PopplerPage *page,
+ gdouble scale,
+ PopplerRectangle *selection)
+{
+ TextOutputDev *text_dev;
+ PDFRectangle poppler_selection;
+ GooList *list;
+ GdkRectangle rect;
+ GdkRegion *region;
+ int i;
+
+ poppler_selection.x1 = selection->x1;
+ poppler_selection.y1 = selection->y1;
+ poppler_selection.x2 = selection->x2;
+ poppler_selection.y2 = selection->y2;
+
+ text_dev = poppler_page_get_text_output_dev (page);
+ list = text_dev->getSelectionRegion(&poppler_selection, scale);
+
+ region = gdk_region_new();
+
+ for (i = 0; i < list->getLength(); i++) {
+ PDFRectangle *selection_rect = (PDFRectangle *) list->get(i);
+ rect.x = (gint) selection_rect->x1;
+ rect.y = (gint) selection_rect->y1;
+ rect.width = (gint) (selection_rect->x2 - selection_rect->x1);
+ rect.height = (gint) (selection_rect->y2 - selection_rect->y1);
+ gdk_region_union_with_rect (region, &rect);
+ delete selection_rect;
+ }
+
+ delete list;
+
+ return region;
+}
+
+void
+poppler_page_render_selection (PopplerPage *page,
+ gdouble scale,
+ GdkPixbuf *pixbuf,
+ PopplerRectangle *selection,
+ PopplerRectangle *old_selection)
+{
+ TextOutputDev *text_dev;
+ CairoOutputDev *output_dev;
+ cairo_surface_t *surface;
+ unsigned char *cairo_data;
+ OutputDevData data;
+ PDFRectangle pdf_selection(selection->x1, selection->y1,
+ selection->x2, selection->y2);
+
+ text_dev = poppler_page_get_text_output_dev (page);
+ output_dev = page->document->output_dev;
+
+ poppler_page_prepare_output_dev (page, scale, TRUE, &data);
+
+ text_dev->drawSelection (output_dev, scale, &pdf_selection);
+
+ poppler_page_copy_to_pixbuf (page, pixbuf, &data);
+
+ /* We'll need a function to destroy page->text_dev and page->gfx
+ * when the application wants to get rid of them.
+ *
+ * Two improvements: 1) make GfxFont refcounted and let TextPage and
+ * friends hold a reference to the GfxFonts they need so we can free
+ * up Gfx early. 2) use a TextPage directly when rendering the page
+ * so we don't have to use TextOutputDev and render a second
+ * time. */
}
+
static void
destroy_thumb_data (guchar *pixels, gpointer data)
{
Index: poppler-page.h
===================================================================
RCS file: /cvs/poppler/poppler/glib/poppler-page.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- poppler-page.h 20 Jun 2005 17:58:38 -0000 1.14
+++ poppler-page.h 29 Jun 2005 21:24:56 -0000 1.15
@@ -20,6 +20,7 @@
#define __POPPLER_PAGE_H__
#include <glib-object.h>
+#include <gdk/gdkregion.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "poppler.h"
@@ -33,34 +34,42 @@
GType poppler_page_get_type (void) G_GNUC_CONST;
-void poppler_page_render_to_pixbuf (PopplerPage *page,
- int src_x,
- int src_y,
- int src_width,
- int src_height,
- double scale,
- GdkPixbuf *pixbuf,
- int dest_x,
- int dest_y);
-void poppler_page_get_size (PopplerPage *page,
- double *width,
- double *height);
-PopplerOrientation poppler_page_get_orientation (PopplerPage *page);
-void poppler_page_set_orientation (PopplerPage *page,
- PopplerOrientation orientation);
-int poppler_page_get_index (PopplerPage *page);
-GdkPixbuf *poppler_page_get_thumbnail (PopplerPage *page);
-gboolean poppler_page_get_thumbnail_size (PopplerPage *page,
- int *width,
- int *height);
-GList *poppler_page_find_text (PopplerPage *page,
- const char *text);
-void poppler_page_render_to_ps (PopplerPage *page,
- PopplerPSFile *ps_file);
-char *poppler_page_get_text (PopplerPage *page,
- PopplerRectangle *rect);
-GList *poppler_page_get_link_mapping (PopplerPage *page);
-void poppler_page_free_link_mapping (GList *list);
+void poppler_page_render_to_pixbuf (PopplerPage *page,
+ int src_x,
+ int src_y,
+ int src_width,
+ int src_height,
+ double scale,
+ GdkPixbuf *pixbuf,
+ int dest_x,
+ int dest_y);
+void poppler_page_get_size (PopplerPage *page,
+ double *width,
+ double *height);
+PopplerOrientation poppler_page_get_orientation (PopplerPage *page);
+void poppler_page_set_orientation (PopplerPage *page,
+ PopplerOrientation orientation);
+int poppler_page_get_index (PopplerPage *page);
+GdkPixbuf *poppler_page_get_thumbnail (PopplerPage *page);
+gboolean poppler_page_get_thumbnail_size (PopplerPage *page,
+ int *width,
+ int *height);
+GList *poppler_page_find_text (PopplerPage *page,
+ const char *text);
+void poppler_page_render_to_ps (PopplerPage *page,
+ PopplerPSFile *ps_file);
+char *poppler_page_get_text (PopplerPage *page,
+ PopplerRectangle *rect);
+GList *poppler_page_get_link_mapping (PopplerPage *page);
+void poppler_page_free_link_mapping (GList *list);
+GdkRegion * poppler_page_get_selection_region (PopplerPage *page,
+ gdouble scale,
+ PopplerRectangle *selection);
+void poppler_page_render_selection (PopplerPage *page,
+ gdouble scale,
+ GdkPixbuf *pixbuf,
+ PopplerRectangle *selection,
+ PopplerRectangle *old_selection);
/* A rectangle on a page, with coordinates in PDF points. */
Index: poppler-private.h
===================================================================
RCS file: /cvs/poppler/poppler/glib/poppler-private.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- poppler-private.h 28 Jun 2005 03:44:12 -0000 1.8
+++ poppler-private.h 29 Jun 2005 21:24:56 -0000 1.9
@@ -5,6 +5,7 @@
#include <PDFDoc.h>
#include <PSOutputDev.h>
#include <Link.h>
+#include <Gfx.h>
#include <FontInfo.h>
#if defined (HAVE_CAIRO)
@@ -44,6 +45,8 @@
Page *page;
int index;
PopplerOrientation orientation;
+ TextOutputDev *text_dev;
+ Gfx *gfx;
};
PopplerPage *_poppler_page_new (PopplerDocument *document,
- Previous message: [poppler] poppler: ChangeLog,1.126,1.127 configure.ac,1.27,1.28
- Next message: [poppler] poppler/poppler: CairoOutputDev.cc, 1.16,
1.17 CairoOutputDev.h, 1.6, 1.7 Page.cc, 1.4, 1.5 Page.h, 1.3,
1.4 TextOutputDev.cc, 1.1.1.1, 1.2 TextOutputDev.h, 1.2, 1.3
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the poppler
mailing list