Paul Gideon Dann
Thu, 11 Jun 2009 03:14:12 -0700
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