[poppler] poppler/CairoFontEngine.cc poppler/CairoFontEngine.h poppler/CairoOutputDev.cc
Jeff Muizelaar
jrmuizel at kemper.freedesktop.org
Sat Nov 10 11:13:59 PST 2007
poppler/CairoFontEngine.cc | 56 ++++++++++++++++++++++++++++++++++++++++++---
poppler/CairoFontEngine.h | 7 ++++-
poppler/CairoOutputDev.cc | 8 ++++--
3 files changed, 65 insertions(+), 6 deletions(-)
New commits:
commit 5797f50a99d1494767edc5928f9c3e9d927b946d
Author: Jeff Muizelaar <jeff at infidigm.net>
Date: Sat Nov 10 01:52:00 2007 -0500
Scale text to match 'm' size
This adds back the hack that was removed when fontconfig support was added long
ago. It's not a great solution but lets us be at least as good as xpdf. Fixes
#12304 with the cairo backend. The problem persists with the splash backend.
diff --git a/poppler/CairoFontEngine.cc b/poppler/CairoFontEngine.cc
old mode 100644
new mode 100755
index 8baca95..67034f0
--- a/poppler/CairoFontEngine.cc
+++ b/poppler/CairoFontEngine.cc
@@ -62,6 +62,8 @@ CairoFont *CairoFont::create(GfxFont *gfxFont, XRef *xref, FT_Library lib, GBool
codeToGID = NULL;
codeToGIDLen = 0;
cairo_font_face = NULL;
+
+ GBool substitute = gFalse;
ref = *gfxFont->getID();
fontType = gfxFont->getType();
@@ -114,6 +116,7 @@ CairoFont *CairoFont::create(GfxFont *gfxFont, XRef *xref, FT_Library lib, GBool
fontType = gfxFont->isCIDFont() ? fontCIDType2 : fontTrueType;
break;
}
+ substitute = gTrue;
}
switch (fontType) {
@@ -226,7 +229,7 @@ CairoFont *CairoFont::create(GfxFont *gfxFont, XRef *xref, FT_Library lib, GBool
goto err2; /* this doesn't do anything, but it looks like we're
* handling the error */
} {
- CairoFont *ret = new CairoFont(ref, cairo_font_face, face, codeToGID, codeToGIDLen);
+ CairoFont *ret = new CairoFont(ref, cairo_font_face, face, codeToGID, codeToGIDLen, substitute);
cairo_font_face_set_user_data (cairo_font_face,
&cairo_font_face_key,
ret,
@@ -241,9 +244,9 @@ CairoFont *CairoFont::create(GfxFont *gfxFont, XRef *xref, FT_Library lib, GBool
}
CairoFont::CairoFont(Ref ref, cairo_font_face_t *cairo_font_face, FT_Face face,
- Gushort *codeToGID, int codeToGIDLen) : ref(ref), cairo_font_face(cairo_font_face),
+ Gushort *codeToGID, int codeToGIDLen, GBool substitute) : ref(ref), cairo_font_face(cairo_font_face),
face(face), codeToGID(codeToGID),
- codeToGIDLen(codeToGIDLen) { }
+ codeToGIDLen(codeToGIDLen), substitute(substitute) { }
CairoFont::~CairoFont() {
FT_Done_Face (face);
@@ -273,6 +276,53 @@ CairoFont::getGlyph(CharCode code,
return gid;
}
+double
+CairoFont::getSubstitutionCorrection(GfxFont *gfxFont)
+{
+ double w1, w2,w3;
+ CharCode code;
+ char *name;
+
+ // for substituted fonts: adjust the font matrix -- compare the
+ // width of 'm' in the original font and the substituted font
+ if (isSubstitute() && !gfxFont->isCIDFont()) {
+ for (code = 0; code < 256; ++code) {
+ if ((name = ((Gfx8BitFont *)gfxFont)->getCharName(code)) &&
+ name[0] == 'm' && name[1] == '\0') {
+ break;
+ }
+ }
+ if (code < 256) {
+ w1 = ((Gfx8BitFont *)gfxFont)->getWidth(code);
+ {
+ 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_metrics(options, CAIRO_HINT_METRICS_OFF);
+ cairo_scaled_font_t *scaled_font = cairo_scaled_font_create(cairo_font_face, &m, &m, options);
+
+ cairo_text_extents_t extents;
+ cairo_scaled_font_text_extents(scaled_font, "m", &extents);
+
+ cairo_scaled_font_destroy(scaled_font);
+ cairo_font_options_destroy(options);
+ w3 = extents.width;
+ w2 = extents.x_advance;
+ }
+ if (!gfxFont->isSymbolic()) {
+ // if real font is substantially narrower than substituted
+ // font, reduce the font size accordingly
+ if (w1 > 0.01 && w1 < 0.9 * w2) {
+ w1 /= w2;
+ return w1;
+ }
+ }
+ }
+ }
+ return 1.0;
+}
+
//------------------------------------------------------------------------
// CairoFontEngine
//------------------------------------------------------------------------
diff --git a/poppler/CairoFontEngine.h b/poppler/CairoFontEngine.h
index f32b6a9..b8af716 100644
--- a/poppler/CairoFontEngine.h
+++ b/poppler/CairoFontEngine.h
@@ -24,15 +24,20 @@ public:
GBool matches(Ref &other);
cairo_font_face_t *getFontFace(void);
unsigned long getGlyph(CharCode code, Unicode *u, int uLen);
+ double getSubstitutionCorrection(GfxFont *gfxFont);
+
+ GBool isSubstitute() { return substitute; }
private:
CairoFont(Ref ref, cairo_font_face_t *cairo_font_face, FT_Face face,
- Gushort *codeToGID, int codeToGIDLen);
+ Gushort *codeToGID, int codeToGIDLen, GBool substitute);
Ref ref;
cairo_font_face_t *cairo_font_face;
FT_Face face;
Gushort *codeToGID;
int codeToGIDLen;
+
+ GBool substitute;
};
//------------------------------------------------------------------------
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
old mode 100644
new mode 100755
index fd2742a..68258d2
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -336,8 +336,12 @@ void CairoOutputDev::updateFont(GfxState *state) {
double fontSize = state->getFontSize();
double *m = state->getTextMat();
- matrix.xx = m[0] * fontSize * state->getHorizScaling();
- matrix.yx = m[1] * fontSize * state->getHorizScaling();
+ /* NOTE: adjusting by a constant is hack. The correct solution
+ * is probably to use user-fonts and compute the scale on a per
+ * glyph basis instead of for the entire font */
+ double w = currentFont->getSubstitutionCorrection(state->getFont());
+ matrix.xx = m[0] * fontSize * state->getHorizScaling() * w;
+ matrix.yx = m[1] * fontSize * state->getHorizScaling() * w;
matrix.xy = -m[2] * fontSize;
matrix.yy = -m[3] * fontSize;
matrix.x0 = 0;
More information about the poppler
mailing list