[poppler] glib/poppler-page.cc

Carlos Garcia Campos carlosgc at kemper.freedesktop.org
Mon Apr 12 10:35:20 PDT 2010


 glib/poppler-page.cc |  227 ++++++++++++++++++++-------------------------------
 1 file changed, 93 insertions(+), 134 deletions(-)

New commits:
commit 55c76069c52f9f51c6b8c60fe1aa8de499012ea8
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date:   Mon Apr 12 19:32:46 2010 +0200

    [glib] Use existing cairo api when rendering to a pixbuf
    
    I should fix bug #5589 for the GDK api too.

diff --git a/glib/poppler-page.cc b/glib/poppler-page.cc
index 747ee0c..39645bd 100644
--- a/glib/poppler-page.cc
+++ b/glib/poppler-page.cc
@@ -256,59 +256,8 @@ poppler_page_get_text_page (PopplerPage *page)
 }
 
 #ifdef POPPLER_WITH_GDK
-typedef struct {
-  unsigned char *cairo_data;
-  cairo_surface_t *surface;
-  cairo_t *cairo;
-} OutputDevData;
-
-static void
-poppler_page_prepare_output_dev (PopplerPage *page,
-				 double scale,
-				 int rotation,
-				 gboolean transparent,
-				 OutputDevData *output_dev_data)
-{
-  CairoOutputDev *output_dev;
-  cairo_surface_t *surface;
-  double width, height;
-  int cairo_width, cairo_height, cairo_rowstride, rotate;
-  unsigned char *cairo_data;
-
-  rotate = rotation + page->page->getRotate ();
-  if (rotate == 90 || rotate == 270) {
-    height = page->page->getCropWidth ();
-    width = page->page->getCropHeight ();
-  } else {
-    width = page->page->getCropWidth ();
-    height = page->page->getCropHeight ();
-  }
-
-  cairo_width = (int) ceil(width * scale);
-  cairo_height = (int) ceil(height * scale);
-
-  output_dev = page->document->output_dev;
-  cairo_rowstride = cairo_width * 4;
-  cairo_data = (guchar *) gmallocn (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_data->cairo = cairo_create (surface);
-  output_dev->setCairo (output_dev_data->cairo);
-}
-
 static void
 copy_cairo_surface_to_pixbuf (cairo_surface_t *surface,
-			      unsigned char   *data,
 			      GdkPixbuf       *pixbuf)
 {
   int cairo_width, cairo_height, cairo_rowstride;
@@ -319,8 +268,8 @@ copy_cairo_surface_to_pixbuf (cairo_surface_t *surface,
 
   cairo_width = cairo_image_surface_get_width (surface);
   cairo_height = cairo_image_surface_get_height (surface);
-  cairo_rowstride = cairo_width * 4;
-  cairo_data = data;
+  cairo_rowstride = cairo_image_surface_get_stride (surface);
+  cairo_data = cairo_image_surface_get_data (surface);
 
   pixbuf_data = gdk_pixbuf_get_pixels (pixbuf);
   pixbuf_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
@@ -346,31 +295,6 @@ copy_cairo_surface_to_pixbuf (cairo_surface_t *surface,
 	}
     }
 }	
-
-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);
-  gfree (output_dev_data->cairo_data);
-}
-
-static void
-poppler_page_set_selection_alpha (PopplerPage           *page,
-				  double                 scale,
-				  GdkPixbuf             *pixbuf,
-				  PopplerSelectionStyle  style,
-				  PopplerRectangle      *selection)
-{
-  /* Cairo doesn't need this, since cairo generates an alpha channel. */ 
-}
 #endif /* POPPLER_WITH_GDK */
 
 static GBool
@@ -611,23 +535,47 @@ _poppler_page_render_to_pixbuf (PopplerPage *page,
 				GBool printing,
 				GdkPixbuf *pixbuf)
 {
-  OutputDevData data;
-  
-  poppler_page_prepare_output_dev (page, scale, rotation, FALSE, &data);
+  cairo_t *cr;
+  cairo_surface_t *surface;
 
-  page->page->displaySlice(page->document->output_dev,
-			   72.0 * scale, 72.0 * scale,
-			   rotation,
-			   gFalse, /* useMediaBox */
-			   gTrue, /* Crop */
-			   src_x, src_y,
-			   src_width, src_height,
-			   printing,
-			   page->document->doc->getCatalog (),
-			   NULL, NULL,
-			   printing ? poppler_print_annot_cb : NULL, NULL);
-  
-  poppler_page_copy_to_pixbuf (page, pixbuf, &data);
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+					src_width, src_height);
+  cr = cairo_create (surface);
+  cairo_save (cr);
+  switch (rotation) {
+  case 90:
+	  cairo_translate (cr, src_x + src_width, -src_y);
+	  break;
+  case 180:
+	  cairo_translate (cr, src_x + src_width, src_y + src_height);
+	  break;
+  case 270:
+	  cairo_translate (cr, -src_x, src_y + src_height);
+	  break;
+  default:
+	  cairo_translate (cr, -src_x, -src_y);
+  }
+
+  if (scale != 1.0)
+	  cairo_scale (cr, scale, scale);
+
+  if (rotation != 0)
+	  cairo_rotate (cr, rotation * G_PI / 180.0);
+
+  if (printing)
+	  poppler_page_render_for_printing (page, cr);
+  else
+	  poppler_page_render (page, cr);
+  cairo_restore (cr);
+
+  cairo_set_operator (cr, CAIRO_OPERATOR_DEST_OVER);
+  cairo_set_source_rgb (cr, 1., 1., 1.);
+  cairo_paint (cr);
+
+  cairo_destroy (cr);
+
+  copy_cairo_surface_to_pixbuf (surface, pixbuf);
+  cairo_surface_destroy (surface);
 }
 
 /**
@@ -761,53 +709,64 @@ poppler_page_render_selection_to_pixbuf (PopplerPage           *page,
                                          GdkColor              *glyph_color,
                                          GdkColor              *background_color)
 {
-  OutputDev *output_dev;
-  OutputDevData data;
-  TextPage *text;
-  SelectionStyle selection_style = selectionStyleGlyph;
-  PDFRectangle pdf_selection(selection->x1, selection->y1,
-			     selection->x2, selection->y2);
+  cairo_t *cr;
+  cairo_surface_t *surface;
+  double width, height;
+  int cairo_width, cairo_height, rotate;
+  PopplerColor poppler_background_color;
+  PopplerColor poppler_glyph_color;
 
-  GfxColor gfx_background_color = { 
-      {
-	  background_color->red,
-	  background_color->green,
-	  background_color->blue
-      }
-  };
-  GfxColor gfx_glyph_color = {
-      {
-	  glyph_color->red,
-	  glyph_color->green,
-	  glyph_color->blue
-      }
-  };
+  poppler_background_color.red = background_color->red;
+  poppler_background_color.green = background_color->green;
+  poppler_background_color.blue = background_color->blue;
+  poppler_glyph_color.red = glyph_color->red;
+  poppler_glyph_color.green = glyph_color->green;
+  poppler_glyph_color.blue = glyph_color->blue;
 
-  switch (style)
-    {
-      case POPPLER_SELECTION_GLYPH:
-        selection_style = selectionStyleGlyph;
-	break;
-      case POPPLER_SELECTION_WORD:
-        selection_style = selectionStyleWord;
-	break;
-      case POPPLER_SELECTION_LINE:
-        selection_style = selectionStyleLine;
-	break;
-    }
+  rotate = rotation + page->page->getRotate ();
+  if (rotate == 90 || rotate == 270) {
+    height = page->page->getCropWidth ();
+    width = page->page->getCropHeight ();
+  } else {
+    width = page->page->getCropWidth ();
+    height = page->page->getCropHeight ();
+  }
 
-  output_dev = page->document->output_dev;
+  cairo_width = (int) ceil(width * scale);
+  cairo_height = (int) ceil(height * scale);
 
-  poppler_page_prepare_output_dev (page, scale, rotation, TRUE, &data);
+  surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+					cairo_width, cairo_height);
+  cr = cairo_create (surface);
+  cairo_set_source_rgba (cr, 0, 0, 0, 0);
+  cairo_paint (cr);
 
-  text = poppler_page_get_text_page (page);
-  text->drawSelection (output_dev, scale, rotation,
-			   &pdf_selection, selection_style,
-			   &gfx_glyph_color, &gfx_background_color);
+  switch (rotate) {
+  case 90:
+	  cairo_translate (cr, cairo_width, 0);
+	  break;
+  case 180:
+	  cairo_translate (cr, cairo_width, cairo_height);
+	  break;
+  case 270:
+	  cairo_translate (cr, 0, cairo_height);
+	  break;
+  default:
+	  cairo_translate (cr, 0, 0);
+  }
+  if (scale != 1.0)
+	  cairo_scale (cr, scale, scale);
+
+  if (rotate != 0)
+	  cairo_rotate (cr, rotation * G_PI / 180.0);
+
+  poppler_page_render_selection (page, cr, selection, old_selection, style,
+				 &poppler_glyph_color, &poppler_background_color);
 
-  poppler_page_copy_to_pixbuf (page, pixbuf, &data);
+  cairo_destroy (cr);
 
-  poppler_page_set_selection_alpha (page, scale, pixbuf, style, selection);
+  copy_cairo_surface_to_pixbuf (surface, pixbuf);
+  cairo_surface_destroy (surface);
 }
 
 #endif /* POPPLER_WITH_GDK */


More information about the poppler mailing list