[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