Hi there,

These patches add support for the Cairo backend to the Qt4 wrapper.  This 
makes it possible to use subpixel-rendered fonts in Okular (with some further 
minor font-rendering patches to the Cairo backend).  Obviously the long-term 
solution is to complete the Arthur backend, but in the meantime, many Qt4 
users will have Cairo installed anyway.

What should I do to get these patches merged?

Paul
From f06a22e114d88c85441ce33d3cd0647f48dfb9c9 Mon Sep 17 00:00:00 2001
From: Paul Gideon Dann <pdgid...@gmail.com>
Date: Wed, 20 May 2009 11:42:28 +0100
Subject: [PATCH 1/5] Basic Cairo backend work completed

---
 qt4/src/CMakeLists.txt      |   13 ++++++++++
 qt4/src/poppler-document.cc |    1 +
 qt4/src/poppler-page.cc     |   55 +++++++++++++++++++++++++++++++++++++++++++
 qt4/src/poppler-private.h   |   12 +++++++++
 qt4/src/poppler-qt4.h       |    3 +-
 5 files changed, 83 insertions(+), 1 deletions(-)

diff --git a/qt4/src/CMakeLists.txt b/qt4/src/CMakeLists.txt
index b18c491..15d9cbf 100644
--- a/qt4/src/CMakeLists.txt
+++ b/qt4/src/CMakeLists.txt
@@ -5,6 +5,10 @@ include_directories(
   ${QT4_INCLUDE_DIR}
   ${CMAKE_CURRENT_BINARY_DIR}
 )
+if (HAVE_CAIRO)
+  include_directories(${CAIRO_INCLUDES})
+  add_definitions(${CAIRO_CFLAGS})
+endif (HAVE_CAIRO)
 
 set(poppler_qt4_SRCS
   poppler-annotation.cc
@@ -31,10 +35,19 @@ if (ENABLE_SPLASH)
     ${CMAKE_SOURCE_DIR}/poppler/ArthurOutputDev.cc
   )
 endif (ENABLE_SPLASH)
+if (HAVE_CAIRO)
+  set(poppler_qt4_SRCS ${poppler_qt4_SRCS}
+    ${CMAKE_SOURCE_DIR}/poppler/CairoOutputDev.cc
+    ${CMAKE_SOURCE_DIR}/poppler/CairoFontEngine.cc
+  )
+endif(HAVE_CAIRO)
 qt4_automoc(${poppler_qt4_SRCS})
 add_library(poppler-qt4 SHARED ${poppler_qt4_SRCS})
 set_target_properties(poppler-qt4 PROPERTIES VERSION 3.1.0 SOVERSION 3)
 target_link_libraries(poppler-qt4 poppler ${QT4_QTCORE_LIBRARY} ${QT4_QTGUI_LIBRARY} ${QT4_QTXML_LIBRARY})
+if (HAVE_CAIRO)
+  target_link_libraries(poppler-qt4 ${CAIRO_LIBRARIES})
+endif (HAVE_CAIRO)
 if(MSVC)
 target_link_libraries(poppler-qt4 poppler ${poppler_LIBS})
 endif(MSVC)
diff --git a/qt4/src/poppler-document.cc b/qt4/src/poppler-document.cc
index 877db52..0de0fce 100644
--- a/qt4/src/poppler-document.cc
+++ b/qt4/src/poppler-document.cc
@@ -449,6 +449,7 @@ namespace Poppler {
 #if defined(HAVE_SPLASH)
         ret << Document::SplashBackend;
         ret << Document::ArthurBackend;
+        ret << Document::CairoBackend;
 #endif
         return ret;
     }
diff --git a/qt4/src/poppler-page.cc b/qt4/src/poppler-page.cc
index f3edfe6..fdbd8db 100644
--- a/qt4/src/poppler-page.cc
+++ b/qt4/src/poppler-page.cc
@@ -31,6 +31,7 @@
 #include <QtGui/QPainter>
 
 #include <config.h>
+#include <math.h>
 #include <PDFDoc.h>
 #include <Catalog.h>
 #include <Form.h>
@@ -273,6 +274,60 @@ QImage Page::renderToImage(double xres, double yres, int x, int y, int w, int h,
 #endif
       break;
     }
+    case Poppler::Document::CairoBackend:
+    {
+#if defined(HAVE_CAIRO)
+      CairoOutputDev *output_dev =
+        static_cast<CairoOutputDev *>(m_page->parentDoc->getOutputDev());
+      double width, height;
+      int cairo_width, cairo_height, cairo_rowstride, rotate;
+      unsigned char *cairo_data;
+      cairo_surface_t *surface;
+      cairo_t *cairo;
+
+      rotate = rotation + m_page->page->getRotate ();
+      if (rotate == 90 || rotate == 270) {
+        height = m_page->page->getCropWidth ();
+        width = m_page->page->getCropHeight ();
+      } else {
+        width = m_page->page->getCropWidth ();
+        height = m_page->page->getCropHeight ();
+      }
+
+      const double scale = yres / 72.0;
+      cairo_width = (int) ceil(width * scale);
+      cairo_height = (int) ceil(height * scale);
+
+      cairo_rowstride = cairo_width * 4;
+      cairo_data = (Guchar *) gmallocn (cairo_height, cairo_rowstride);
+      // Never transparent
+      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);
+
+      cairo = cairo_create (surface);
+      output_dev->setCairo (cairo);
+
+      m_page->parentDoc->doc->displayPageSlice(
+        output_dev, m_page->index + 1, xres, yres, rotation, false, true,
+        false, x, y, w, h);
+
+      // construct a qimage SHARING the raw bitmap data in memory
+      QImage tmpimg(cairo_data, cairo_width, cairo_height,
+                    QImage::Format_ARGB32);
+      img = tmpimg.copy();
+
+      // Clean up
+      output_dev->setCairo(NULL);
+      cairo_surface_destroy (surface);
+      cairo_destroy (cairo);
+      gfree(cairo_data);
+#endif
+      break;
+    }
   }
 
   return img;
diff --git a/qt4/src/poppler-private.h b/qt4/src/poppler-private.h
index acf3124..bd89008 100644
--- a/qt4/src/poppler-private.h
+++ b/qt4/src/poppler-private.h
@@ -38,6 +38,9 @@
 #if defined(HAVE_SPLASH)
 #include <SplashOutputDev.h>
 #endif
+#if defined(HAVE_CAIRO)
+#include <CairoOutputDev.h>
+#endif
 
 #include "poppler-qt4.h"
 
@@ -144,6 +147,15 @@ namespace Poppler {
 #endif
 			break;
 			}
+			case Document::CairoBackend:
+			{
+#if defined(HAVE_CAIRO)
+			CairoOutputDev *cairoOutputDev = new CairoOutputDev();
+			cairoOutputDev->startDoc(doc->getXRef (), doc->getCatalog ());
+			m_outputDev = cairoOutputDev;
+#endif
+			break;
+			}
 			}
 		}
 		return m_outputDev;
diff --git a/qt4/src/poppler-qt4.h b/qt4/src/poppler-qt4.h
index fd384f5..be8cab5 100644
--- a/qt4/src/poppler-qt4.h
+++ b/qt4/src/poppler-qt4.h
@@ -650,7 +650,8 @@ while (it->hasNext()) {
 	*/
 	enum RenderBackend {
 	    SplashBackend,   ///< Splash backend
-	    ArthurBackend   ///< Arthur (Qt4) backend
+	    ArthurBackend,   ///< Arthur (Qt4) backend
+	    CairoBackend     ///< Cairo backend
 	};
 
 	/**
-- 
1.6.3.2

From 777b3165a4356a8ad206cc82258ae63837b69d4a Mon Sep 17 00:00:00 2001
From: Paul Gideon Dann <pdgid...@gmail.com>
Date: Wed, 20 May 2009 14:10:16 +0100
Subject: [PATCH 2/5] Cairo output can now be built (for Qt4) without building Glib backend

---
 CMakeLists.txt |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 194d46b..33966e2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -51,9 +51,9 @@ endif(JPEG_FOUND)
 macro_optional_find_package(Qt3)
 macro_optional_find_package(Qt4)
 macro_optional_find_package(GTK)
+macro_optional_find_package(Cairo)
+set(HAVE_CAIRO ${CAIRO_FOUND})
 if(GLIB_FOUND)
-  macro_optional_find_package(Cairo)
-  set(HAVE_CAIRO ${CAIRO_FOUND})
   set(POPPLER_WITH_GDK ${GDK_FOUND})
   if(CAIRO_FOUND)
     set(CAIRO_REQ "cairo")
-- 
1.6.3.2

_______________________________________________
poppler mailing list
poppler@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/poppler

Reply via email to