On Wednesday 20 May 2009 23:25:01 Albert Astals Cid wrote: > Can i have that pdf for local comparison?
Sorry, I'm afraid it's proprietary material. (Probably shouldn't have used it for comparison; oh well!) It's my copy of "Agile Web Development with Rails". I was reading it when I decided I had to get subpixel rendering working :) However, you should be able to see the results in any PDF. I've done further work on my patchset since my last e-mail. After some hunting, I discovered how to enable FreeType's default LCD filter (FIR5) in the Cairo backend. (By default Cairo uses the legacy version, hence the colour fringing.) This function (in patch 4) relies on the LCD filtering patch for Cairo (http://aur.archlinux.org/packages/cairo-lcd/cairo-lcd/lcd- filter.patch). I've also added a further patch that enables slight hinting in the Cairo backend. This has been suggested elsewhere, and does seem to sharpen text up a little. Comparison of FIR5-filtered text with no hinting vs slight hinting: No hinting: http://snurl.com/ihakt Slight hinting: http://snurl.com/ihalk Apologies for re-attaching the whole patchset -- I figured it would be cleaner than trying to track changes I made in each patch. Most of this patchset is of course a quick hack to achieve the desired effect, but I do hope that the Cairo backend for Qt4 (patches 1+2) and the slight hinting (patch 5) will be considered for merging. The rest will hopefully be helpful to anyone else wanting beautiful fonts in Okular right now. Paul
From de4279b0a174a7c1b5e2a6974488d45aa5953842 Mon Sep 17 00:00:00 2001 From: Paul Gideon Dann <[email protected]> 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 03085a5..4018982 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,9 +48,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.1
From 899e96825df616511a8937f6012e112c7cebb379 Mon Sep 17 00:00:00 2001 From: Paul Gideon Dann <[email protected]> Date: Thu, 21 May 2009 10:55:49 +0100 Subject: [PATCH 5/5] Enabling slight hinting in Cairo Backend Originally suggested at: http://bugs.freedesktop.org/show_bug.cgi?id=3307#c20 --- poppler/CairoFontEngine.cc | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/poppler/CairoFontEngine.cc b/poppler/CairoFontEngine.cc index a4edd12..8bf7581 100644 --- a/poppler/CairoFontEngine.cc +++ b/poppler/CairoFontEngine.cc @@ -123,7 +123,7 @@ CairoFont::getSubstitutionCorrection(GfxFont *gfxFont) cairo_matrix_t m; cairo_matrix_init_identity(&m); cairo_font_options_t *options = cairo_font_options_create(); - cairo_font_options_set_hint_style(options, CAIRO_HINT_STYLE_NONE); + cairo_font_options_set_hint_style(options, CAIRO_HINT_STYLE_SLIGHT); cairo_font_options_set_hint_metrics(options, CAIRO_HINT_METRICS_OFF); cairo_scaled_font_t *scaled_font = cairo_scaled_font_create(cairo_font_face, &m, &m, options); @@ -178,7 +178,7 @@ _ft_new_face_uncached (FT_Library lib, return gFalse; font_face = cairo_ft_font_face_create_for_ft_face (face, - FT_LOAD_NO_HINTING | + FT_LOAD_TARGET_LIGHT | FT_LOAD_NO_BITMAP); if (cairo_font_face_set_user_data (font_face, &_ft_cairo_key, @@ -325,7 +325,7 @@ _ft_new_face (FT_Library lib, _ft_open_faces = l; l->font_face = cairo_ft_font_face_create_for_ft_face (tmpl.face, - FT_LOAD_NO_HINTING | + FT_LOAD_TARGET_LIGHT | FT_LOAD_NO_BITMAP); if (cairo_font_face_set_user_data (l->font_face, &_ft_cairo_key, -- 1.6.3.1
From 23ef6b1d1e130a5ef74335f5d1a10f99459e3051 Mon Sep 17 00:00:00 2001 From: Paul Gideon Dann <[email protected]> Date: Wed, 20 May 2009 13:17:29 +0100 Subject: [PATCH 3/5] Setting default QT4 backend to Cairo --- qt4/src/poppler-private.h | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/qt4/src/poppler-private.h b/qt4/src/poppler-private.h index bd89008..545935d 100644 --- a/qt4/src/poppler-private.h +++ b/qt4/src/poppler-private.h @@ -95,7 +95,7 @@ namespace Poppler { void init(GooString *ownerPassword, GooString *userPassword) { m_fontInfoIterator = 0; - m_backend = Document::SplashBackend; + m_backend = Document::CairoBackend; m_outputDev = 0; paperColor = Qt::white; m_hints = 0; -- 1.6.3.1
From c04f338133005f6b52e53e797034ddbe59091d6a Mon Sep 17 00:00:00 2001 From: Paul Gideon Dann <[email protected]> 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 9a27538..069dad9 100644 --- a/qt4/src/poppler-page.cc +++ b/qt4/src/poppler-page.cc @@ -30,6 +30,7 @@ #include <QtGui/QPainter> #include <config.h> +#include <math.h> #include <PDFDoc.h> #include <Catalog.h> #include <Form.h> @@ -272,6 +273,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 05c4c0d..b6646b8 100644 --- a/qt4/src/poppler-qt4.h +++ b/qt4/src/poppler-qt4.h @@ -637,7 +637,8 @@ while (it->hasNext()) { */ enum RenderBackend { SplashBackend, ///< Splash backend - ArthurBackend ///< Arthur (Qt4) backend + ArthurBackend, ///< Arthur (Qt4) backend + CairoBackend ///< Cairo backend }; /** -- 1.6.3.1
From 6e858f2133cae7ccbfc0686d6c55c247ad124200 Mon Sep 17 00:00:00 2001 From: Paul Gideon Dann <[email protected]> Date: Wed, 20 May 2009 13:06:48 +0100 Subject: [PATCH 4/5] Forcing subpixel rendering in Cairo backend --- poppler/CairoOutputDev.cc | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 5d4cb82..99e3838 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -176,6 +176,16 @@ void CairoOutputDev::setCairo(cairo_t *cairo) } if (cairo != NULL) { this->cairo = cairo_reference (cairo); + { + cairo_font_options_t *options = cairo_font_options_create (); + cairo_get_font_options (cairo, options); + cairo_font_options_set_antialias (options, CAIRO_ANTIALIAS_SUBPIXEL); + cairo_font_options_set_subpixel_order (options, CAIRO_SUBPIXEL_ORDER_RGB); + cairo_font_options_set_lcd_filter (options, CAIRO_LCD_FILTER_FIR5); + cairo_font_options_set_hint_style (options, CAIRO_HINT_STYLE_SLIGHT); + cairo_set_font_options (cairo, options); + cairo_font_options_destroy (options); + } /* save the initial matrix so that we can use it for type3 fonts. */ //XXX: is this sufficient? could we miss changes to the matrix somehow? cairo_get_matrix(cairo, &orig_matrix); -- 1.6.3.1
_______________________________________________ poppler mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/poppler
