[PATCH] Added cairo rendering support to cpp page-renderer.

Richard Uhler ruhler at csail.mit.edu
Sun Jul 10 18:01:34 PDT 2011


---
 cpp/Makefile.am               |   11 ++++++-
 cpp/poppler-page-renderer.cpp |   61 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 69 insertions(+), 3 deletions(-)

diff --git a/cpp/Makefile.am b/cpp/Makefile.am
index 6d4954b..3b496d1 100644
--- a/cpp/Makefile.am
+++ b/cpp/Makefile.am
@@ -1,7 +1,10 @@
 INCLUDES =					\
 	-I$(top_srcdir)				\
 	-I$(top_srcdir)/goo			\
-	-I$(top_srcdir)/poppler
+	-I$(top_srcdir)/poppler	\
+	$(CAIRO_CFLAGS) \
+	$(FREETYPE_CFLAGS) \
+	$(FONTCONFIG_CFLAGS)
 
 SUBDIRS = . tests
 
@@ -47,6 +50,10 @@ libpoppler_cpp_la_CXXFLAGS =			\
 
 libpoppler_cpp_la_LIBADD = 			\
 	$(top_builddir)/poppler/libpoppler.la	\
-	$(LIBICONV)
+	$(top_builddir)/poppler/libpoppler-cairo.la \
+	$(LIBICONV) \
+	$(CAIRO_LIBS) \
+    $(FREETYPE_LIBS)                \
+	$(FONTCONFIG_LIBS)
 
 libpoppler_cpp_la_LDFLAGS = -version-info 2:0:2 @create_shared_lib@ @auto_import_flags@
diff --git a/cpp/poppler-page-renderer.cpp b/cpp/poppler-page-renderer.cpp
index 5e07954..4067ed3 100644
--- a/cpp/poppler-page-renderer.cpp
+++ b/cpp/poppler-page-renderer.cpp
@@ -24,6 +24,9 @@
 #include <config.h>
 
 #include "PDFDoc.h"
+#if defined(HAVE_CAIRO)
+#include "CairoOutputDev.h"
+#endif
 #if defined(HAVE_SPLASH)
 #include "SplashOutputDev.h"
 #include "splash/SplashBitmap.h"
@@ -163,7 +166,63 @@ image page_renderer::render_page(const page *p,
         return image();
     }
 
-#if defined(HAVE_SPLASH)
+#if defined(HAVE_CAIRO)
+
+    page_private *pp = page_private::get(p);
+    PDFDoc* pdfdoc = pp->doc->doc;
+
+    // Calculate the dimensions of the image.
+    // It should just be (w-x) by (h-y). But 
+    //  if x == -1: use x = 0
+    //  if y == -1: use y = 0
+    //  if w == -1: figure out the width in pixels after rotation of the page
+    //  if h == -1: figure out the height in pixels after rotation of the page
+    //   Conversion to pixels: pixels = page * xres/72.0
+    x = (x == -1 ? 0 : x);
+    y = (y == -1 ? 0 : y);
+
+    if (w == -1 || h == -1) {
+        bool sideways;
+        sideways = (p->orientation() == poppler::page::landscape
+                || p->orientation() == poppler::page::seascape);
+        if (rotate % 2 == 1) {
+            sideways = !sideways;
+        }
+
+        if (w == -1) {
+            w = (sideways ? p->page_rect().height() : p->page_rect().width()) * xres/72.0;
+        }
+        if (h == -1) {
+            h = (sideways ? p->page_rect().width() : p->page_rect().height()) * yres/72.0;
+        }
+    }
+
+    cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
+    cairo_t* cairo = cairo_create(surface);
+
+    // Clear the background.
+    double bgr = ((d->paper_color >> 16) & 0xff)/256.0;
+    double bgb = ((d->paper_color >> 8) & 0xff)/256.0;
+    double bgg = ((d->paper_color >> 0) & 0xff)/256.0;
+    cairo_set_source_rgb(cairo, bgr, bgb, bgg);
+    cairo_paint(cairo);
+
+    // Draw the page content
+    CairoOutputDev dev;
+    dev.setCairo(cairo);
+    dev.startDoc(pdfdoc->getXRef(), pdfdoc->getCatalog());
+    pdfdoc->displayPageSlice(&dev, pp->index + 1,
+            xres, yres, int(rotate) * 90,
+            gFalse, gFalse, gFalse, x, y, w, h);
+
+    void* data_ptr = cairo_image_surface_get_data(surface);
+
+    const image img(reinterpret_cast<char *>(data_ptr), w, h, image::format_argb32);
+    cairo_surface_destroy(surface);
+    cairo_destroy(cairo);
+    return img.copy();
+
+#elif defined(HAVE_SPLASH)
     page_private *pp = page_private::get(p);
     PDFDoc *pdfdoc = pp->doc->doc;
 
-- 
1.7.3


--cWoXeonUoKmBZSoM--


More information about the poppler mailing list