[poppler] PATCH: support slight hinting in Splash backend

Andreas Hartmetz ahartmetz at gmail.com
Wed Jan 19 06:08:45 PST 2011


Hello all,

I've written a patch to enable slight font hinting in the Splash backend which 
is still used by KDE's Okular application, because the fonts are (without 
hinting) a bit too fuzzy for my taste, and full hinting makes them look ugly.
The Okular patch still needs to be fixed after a review from Pino who maintains 
Okular. It demonstrates that the Poppler patch works but the UI isn't finished.
The following patch has received a quick review from Albert already.

diff --git a/poppler/ArthurOutputDev.cc b/poppler/ArthurOutputDev.cc
index 71faeb5..8fdcfbd 100644
--- a/poppler/ArthurOutputDev.cc
+++ b/poppler/ArthurOutputDev.cc
@@ -86,7 +86,8 @@ private:
 //------------------------------------------------------------------------
 
 ArthurOutputDev::ArthurOutputDev(QPainter *painter):
-  m_painter(painter)
+  m_painter(painter),
+  m_fontHinting(NoHinting)
 {
   m_currentBrush = QBrush(Qt::SolidPattern);
   m_fontEngine = 0;
@@ -104,13 +105,18 @@ void ArthurOutputDev::startDoc(XRef *xrefA) {
   xref = xrefA;
 #ifdef HAVE_SPLASH
   delete m_fontEngine;
+
+  const bool isHintingEnabled = m_fontHinting != NoHinting;
+  const bool isSlightHinting = m_fontHinting == SlightHinting;
+
   m_fontEngine = new SplashFontEngine(
 #if HAVE_T1LIB_H
   globalParams->getEnableT1lib(),
 #endif
 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
   globalParams->getEnableFreeType(),
-  gFalse,
+  isHintingEnabled,
+  isSlightHinting,
 #endif
   m_painter->testRenderHint(QPainter::TextAntialiasing));
 #endif
diff --git a/poppler/ArthurOutputDev.h b/poppler/ArthurOutputDev.h
index 3fa586b..bea86b6 100644
--- a/poppler/ArthurOutputDev.h
+++ b/poppler/ArthurOutputDev.h
@@ -51,6 +51,15 @@ struct SplashGlyphBitmap;
 
 class ArthurOutputDev: public OutputDev {
 public:
+  /**
+   * Describes how fonts are distorted (aka hinted) to fit the pixel grid.
+   * More hinting means sharper edges and less adherence to the true letter 
shapes.
+   */
+  enum FontHinting {
+    NoHinting = 0, ///< Font shapes are left unchanged
+    SlightHinting, ///< Font shapes are distorted vertically only
+    FullHinting ///< Font shapes are distorted horizontally and vertically
+  };
 
   // Constructor.
   ArthurOutputDev(QPainter *painter );
@@ -58,6 +67,8 @@ public:
   // Destructor.
   virtual ~ArthurOutputDev();
 
+  void setFontHinting(FontHinting hinting) { m_fontHinting = hinting; }
+
   //----- get info about output device
 
   // Does this device use upside-down coordinates?
@@ -147,6 +158,7 @@ public:
   
 private:
   QPainter *m_painter;
+  FontHinting m_fontHinting;
   QFont m_currentFont;
   QPen m_currentPen;
   QBrush m_currentBrush;
diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc
index 0b3722a..a175029 100644
--- a/poppler/SplashOutputDev.cc
+++ b/poppler/SplashOutputDev.cc
@@ -964,6 +964,7 @@ SplashOutputDev::SplashOutputDev(SplashColorMode 
colorModeA,
 		      globalParams->getVectorAntialias() &&
 		      colorMode != splashModeMono1;
   enableFreeTypeHinting = gFalse;
+  enableSlightHinting = gFalse;
   setupScreenParams(72.0, 72.0);
   reverseVideo = reverseVideoA;
   if (paperColorA != NULL) {
@@ -1074,6 +1075,7 @@ void SplashOutputDev::startDoc(XRef *xrefA) {
 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
 				    globalParams->getEnableFreeType(),
 				    enableFreeTypeHinting,
+				    enableSlightHinting,
 #endif
 				    allowAntialias &&
 				      globalParams->getAntialias() &&
@@ -3323,6 +3325,11 @@ void SplashOutputDev::setFreeTypeHinting(GBool enable)
   enableFreeTypeHinting = enable;
 }
 
+void SplashOutputDev::setSlightHinting(GBool enable)
+{
+  enableSlightHinting = enable;
+}
+
 GBool SplashOutputDev::gouraudTriangleShadedFill(GfxState *state, 
GfxGouraudTriangleShading *shading)
 {
   GfxColorSpaceMode shadingMode = shading->getColorSpace()->getMode();
diff --git a/poppler/SplashOutputDev.h b/poppler/SplashOutputDev.h
index 570d036..f9de994 100644
--- a/poppler/SplashOutputDev.h
+++ b/poppler/SplashOutputDev.h
@@ -289,6 +289,7 @@ public:
 #endif
 
   void setFreeTypeHinting(GBool enable);
+  void setSlightHinting(GBool enable);
 
 private:
 
@@ -320,6 +321,7 @@ private:
   GBool allowAntialias;
   GBool vectorAntialias;
   GBool enableFreeTypeHinting;
+  GBool enableSlightHinting;
   GBool reverseVideo;		// reverse video mode
   SplashColor paperColor;	// paper color
   SplashScreenParams screenParams;
diff --git a/qt4/src/poppler-private.h b/qt4/src/poppler-private.h
index f148dbc..9f0c356 100644
--- a/qt4/src/poppler-private.h
+++ b/qt4/src/poppler-private.h
@@ -140,6 +140,7 @@ namespace Poppler {
 			SplashOutputDev * splashOutputDev = new 
SplashOutputDev(splashModeXBGR8, 4, gFalse, bgColor, gTrue, AA);
 			splashOutputDev->setVectorAntialias(m_hints & 
Document::Antialiasing ? gTrue : gFalse);
 			splashOutputDev->setFreeTypeHinting(m_hints & 
Document::TextHinting ? gTrue : gFalse);
+			splashOutputDev->setSlightHinting(m_hints & 
Document::TextSlightHinting ? gTrue : gFalse);
 			splashOutputDev->startDoc(doc->getXRef());
 			m_outputDev = splashOutputDev;
 #endif
diff --git a/qt4/src/poppler-qt4.h b/qt4/src/poppler-qt4.h
index 576c53e..006aaa4 100644
--- a/qt4/src/poppler-qt4.h
+++ b/qt4/src/poppler-qt4.h
@@ -800,7 +800,8 @@ delete it;
 	enum RenderHint {
 	    Antialiasing = 0x00000001,      ///< Antialiasing for graphics
 	    TextAntialiasing = 0x00000002,  ///< Antialiasing for text
-	    TextHinting = 0x00000004        ///< Hinting for text \since 0.12.1
+	    TextHinting = 0x00000004,       ///< Hinting for text \since 0.12.1
+	    TextSlightHinting = 0x00000008  ///< Lighter hinting for text when 
combined with TextHinting \since 0.18
 	};
 	Q_DECLARE_FLAGS( RenderHints, RenderHint )
 
diff --git a/splash/SplashFTFont.cc b/splash/SplashFTFont.cc
index 5e86311..32c8171 100644
--- a/splash/SplashFTFont.cc
+++ b/splash/SplashFTFont.cc
@@ -57,7 +57,8 @@ static int glyphPathCubicTo(const FT_Vector *ctrl1, const 
FT_Vector *ctrl2,
 SplashFTFont::SplashFTFont(SplashFTFontFile *fontFileA, SplashCoord *matA,
 			   SplashCoord *textMatA):
   SplashFont(fontFileA, matA, textMatA, fontFileA->engine->aa), 
-  enableFreeTypeHinting(fontFileA->engine->enableFreeTypeHinting)
+  enableFreeTypeHinting(fontFileA->engine->enableFreeTypeHinting),
+  enableSlightHinting(fontFileA->engine->enableSlightHinting)
 {
   FT_Face face;
   double div;
@@ -169,12 +170,19 @@ GBool SplashFTFont::getGlyph(int c, int xFrac, int 
yFrac,
   return SplashFont::getGlyph(c, xFrac, 0, bitmap, x0, y0, clip, clipRes);
 }
 
-static FT_Int32 getFTLoadFlags(GBool aa, GBool enableFreeTypeHinting)
+static FT_Int32 getFTLoadFlags(GBool aa, GBool enableFreeTypeHinting, GBool 
enableSlightHinting)
 {
-  if (aa && enableFreeTypeHinting) return FT_LOAD_NO_BITMAP;
-  else if (aa && !enableFreeTypeHinting) return FT_LOAD_NO_HINTING | 
FT_LOAD_NO_BITMAP;
-  else if (!aa && enableFreeTypeHinting) return FT_LOAD_DEFAULT;
-  else return FT_LOAD_NO_HINTING;
+  int ret = 0; // == FT_LOAD_DEFAULT
+  if (aa)
+    ret |= FT_LOAD_NO_BITMAP;
+  
+  if (enableFreeTypeHinting) {
+    if (enableSlightHinting)
+      ret |= FT_LOAD_TARGET_LIGHT;
+  } else {
+    ret |= FT_LOAD_NO_HINTING;
+  }
+  return ret;
 }
 
 GBool SplashFTFont::makeGlyph(int c, int xFrac, int yFrac,
@@ -201,7 +209,7 @@ GBool SplashFTFont::makeGlyph(int c, int xFrac, int yFrac,
     gid = (FT_UInt)c;
   }
 
-  if (FT_Load_Glyph(ff->face, gid, getFTLoadFlags(aa, enableFreeTypeHinting))) 
{
+  if (FT_Load_Glyph(ff->face, gid, getFTLoadFlags(aa, enableFreeTypeHinting, 
enableSlightHinting))) {
     return gFalse;
   }
 
@@ -284,7 +292,7 @@ double SplashFTFont::getGlyphAdvance(int c)
     return -1;
   }
 
-  if (FT_Load_Glyph(ff->face, gid, getFTLoadFlags(aa, enableFreeTypeHinting))) 
{
+  if (FT_Load_Glyph(ff->face, gid, getFTLoadFlags(aa, enableFreeTypeHinting, 
enableSlightHinting))) {
     return -1;
   }
 
@@ -332,7 +340,7 @@ SplashPath *SplashFTFont::getGlyphPath(int c) {
     // skip the TrueType notdef glyph
     return NULL;
   }
-  if (FT_Load_Glyph(ff->face, gid, getFTLoadFlags(aa, enableFreeTypeHinting))) 
{
+  if (FT_Load_Glyph(ff->face, gid, getFTLoadFlags(aa, enableFreeTypeHinting, 
enableSlightHinting))) {
     return NULL;
   }
   if (FT_Get_Glyph(slot, &glyph)) {
diff --git a/splash/SplashFTFont.h b/splash/SplashFTFont.h
index cf82504..d23191e 100644
--- a/splash/SplashFTFont.h
+++ b/splash/SplashFTFont.h
@@ -69,6 +69,7 @@ private:
   SplashCoord textScale;
   double size;
   GBool enableFreeTypeHinting;
+  GBool enableSlightHinting;
 };
 
 #endif // HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
diff --git a/splash/SplashFTFontEngine.cc b/splash/SplashFTFontEngine.cc
index 7cf4f06..f7040b8 100644
--- a/splash/SplashFTFontEngine.cc
+++ b/splash/SplashFTFontEngine.cc
@@ -58,11 +58,13 @@ static void fileWrite(void *stream, char *data, int len) {
 // SplashFTFontEngine
 //------------------------------------------------------------------------
 
-SplashFTFontEngine::SplashFTFontEngine(GBool aaA, GBool 
enableFreeTypeHintingA, FT_Library libA) {
+SplashFTFontEngine::SplashFTFontEngine(GBool aaA, GBool 
enableFreeTypeHintingA,
+				       GBool enableSlightHintingA, FT_Library libA) {
   FT_Int major, minor, patch;
 
   aa = aaA;
   enableFreeTypeHinting = enableFreeTypeHintingA;
+  enableSlightHinting = enableSlightHintingA;
   lib = libA;
 
   // as of FT 2.1.8, CID fonts are indexed by CID instead of GID
@@ -71,13 +73,14 @@ SplashFTFontEngine::SplashFTFontEngine(GBool aaA, GBool 
enableFreeTypeHintingA,
             (major == 2 && (minor > 1 || (minor == 1 && patch > 7)));
 }
 
-SplashFTFontEngine *SplashFTFontEngine::init(GBool aaA, GBool 
enableFreeTypeHintingA) {
+SplashFTFontEngine *SplashFTFontEngine::init(GBool aaA, GBool 
enableFreeTypeHintingA,
+					     GBool enableSlightHintingA) {
   FT_Library libA;
 
   if (FT_Init_FreeType(&libA)) {
     return NULL;
   }
-  return new SplashFTFontEngine(aaA, enableFreeTypeHintingA, libA);
+  return new SplashFTFontEngine(aaA, enableFreeTypeHintingA, 
enableSlightHintingA, libA);
 }
 
 SplashFTFontEngine::~SplashFTFontEngine() {
diff --git a/splash/SplashFTFontEngine.h b/splash/SplashFTFontEngine.h
index 5acb415..8fe953e 100644
--- a/splash/SplashFTFontEngine.h
+++ b/splash/SplashFTFontEngine.h
@@ -44,7 +44,7 @@ class SplashFontSrc;
 class SplashFTFontEngine {
 public:
 
-  static SplashFTFontEngine *init(GBool aaA, GBool enableFreeTypeHintingA);
+  static SplashFTFontEngine *init(GBool aaA, GBool enableFreeTypeHintingA, 
GBool enableSlightHinting);
 
   ~SplashFTFontEngine();
 
@@ -59,10 +59,11 @@ public:
 
 private:
 
-  SplashFTFontEngine(GBool aaA, GBool enableFreeTypeHintingA, FT_Library 
libA);
+  SplashFTFontEngine(GBool aaA, GBool enableFreeTypeHintingA, GBool 
enableSlightHintingA, FT_Library libA);
 
   GBool aa;
   GBool enableFreeTypeHinting;
+  GBool enableSlightHinting;
   FT_Library lib;
   GBool useCIDs;
 
diff --git a/splash/SplashFontEngine.cc b/splash/SplashFontEngine.cc
index 3c96bfb..cc74c03 100644
--- a/splash/SplashFontEngine.cc
+++ b/splash/SplashFontEngine.cc
@@ -69,6 +69,7 @@ SplashFontEngine::SplashFontEngine(
 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
 				   GBool enableFreeType,
 				   GBool enableFreeTypeHinting,
+				   GBool enableSlightHinting,
 #endif
 				   GBool aa) {
   int i;
@@ -86,7 +87,7 @@ SplashFontEngine::SplashFontEngine(
 #endif
 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
   if (enableFreeType) {
-    ftEngine = SplashFTFontEngine::init(aa, enableFreeTypeHinting);
+    ftEngine = SplashFTFontEngine::init(aa, enableFreeTypeHinting, 
enableSlightHinting);
   } else {
     ftEngine = NULL;
   }
diff --git a/splash/SplashFontEngine.h b/splash/SplashFontEngine.h
index a9d51f0..6a0c84c 100644
--- a/splash/SplashFontEngine.h
+++ b/splash/SplashFontEngine.h
@@ -57,6 +57,7 @@ public:
 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
 		   GBool enableFreeType,
 		   GBool enableFreeTypeHinting,
+		   GBool enableSlightHinting,
 #endif
 		   GBool aa);
 -- snip --

Cheers,
Andreas


More information about the poppler mailing list