[poppler] 7 commits - configure.ac glib/poppler-document.cc poppler/CairoFontEngine.cc poppler/CairoFontEngine.h poppler/CairoOutputDev.cc poppler/CairoOutputDev.h test/pdf-inspector.cc
Carlos Garcia Campos
carlosgc at kemper.freedesktop.org
Fri Oct 31 11:33:24 PDT 2008
configure.ac | 2
glib/poppler-document.cc | 3
poppler/CairoFontEngine.cc | 343 ++++++++++++++++++++++++++++++++++-----------
poppler/CairoFontEngine.h | 47 +++++-
poppler/CairoOutputDev.cc | 40 ++++-
poppler/CairoOutputDev.h | 16 +-
test/pdf-inspector.cc | 2
7 files changed, 353 insertions(+), 100 deletions(-)
New commits:
commit 5c051aa117477cba5d350adfc539acb4b5f2a56a
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Sat Nov 1 01:59:07 2008 +1030
Require cairo 1.8.2 for user-font support
diff --git a/configure.ac b/configure.ac
index 8b7ebe7..71794ca 100644
--- a/configure.ac
+++ b/configure.ac
@@ -200,7 +200,7 @@ if test x$enable_splash_output = xyes; then
AC_DEFINE(HAVE_SPLASH)
fi
-CAIRO_VERSION="1.4"
+CAIRO_VERSION="1.8.2"
AC_SUBST(CAIRO_VERSION)
AC_ARG_ENABLE(cairo-output,
AC_HELP_STRING([--disable-cairo-output],
commit a3edfa30680864b95a5196c5619846de42980857
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Sat Nov 1 01:57:32 2008 +1030
Implement Type 3 fonts in cairo backend using cairo user-fonts
diff --git a/poppler/CairoFontEngine.cc b/poppler/CairoFontEngine.cc
index 75340b8..dc975be 100644
--- a/poppler/CairoFontEngine.cc
+++ b/poppler/CairoFontEngine.cc
@@ -32,12 +32,16 @@
#include "config.h"
#include <string.h>
#include "CairoFontEngine.h"
+#include "CairoOutputDev.h"
#include "CharCodeToUnicode.h"
#include "GlobalParams.h"
#include <fofi/FoFiTrueType.h>
#include <fofi/FoFiType1C.h>
#include "goo/gfile.h"
#include "Error.h"
+#include "XRef.h"
+#include "Gfx.h"
+#include "Page.h"
#if HAVE_FCNTL_H && HAVE_SYS_MMAN_H && HAVE_SYS_STAT_H
#include <fcntl.h>
@@ -531,6 +535,163 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref,
return NULL;
}
+//------------------------------------------------------------------------
+// CairoType3Font
+//------------------------------------------------------------------------
+
+static const cairo_user_data_key_t type3_font_key = {0};
+
+typedef struct _type3_font_info {
+ GfxFont *font;
+ XRef *xref;
+ Catalog *catalog;
+ CairoFontEngine *fontEngine;
+} type3_font_info_t;
+
+static void
+_free_type3_font_info(void *closure)
+{
+ type3_font_info_t *info = (type3_font_info_t *) closure;
+
+ info->font->decRefCnt();
+ free (info);
+}
+
+static cairo_status_t
+_render_type3_glyph (cairo_scaled_font_t *scaled_font,
+ unsigned long glyph,
+ cairo_t *cr,
+ cairo_text_extents_t *metrics)
+{
+ Dict *charProcs;
+ Object charProc;
+ CairoOutputDev *output_dev;
+ cairo_matrix_t matrix;
+ double *mat;
+ double wx, wy;
+ PDFRectangle box;
+ type3_font_info_t *info;
+ GfxFont *font;
+ Dict *resDict;
+ Gfx *gfx;
+
+ info = (type3_font_info_t *)
+ cairo_font_face_get_user_data (cairo_scaled_font_get_font_face (scaled_font),
+ &type3_font_key);
+
+ font = info->font;
+ resDict = ((Gfx8BitFont *)font)->getResources();
+ charProcs = ((Gfx8BitFont *)(info->font))->getCharProcs();
+ if (!charProcs)
+ return CAIRO_STATUS_USER_FONT_ERROR;
+
+ if ((int)glyph >= charProcs->getLength())
+ return CAIRO_STATUS_USER_FONT_ERROR;
+
+ mat = font->getFontMatrix();
+ matrix.xx = mat[0];
+ matrix.yx = mat[1];
+ matrix.xy = mat[2];
+ matrix.yy = mat[3];
+ matrix.x0 = mat[4];
+ matrix.y0 = mat[5];
+ cairo_transform (cr, &matrix);
+ cairo_matrix_init_scale (&matrix, 1, -1);
+ cairo_transform (cr, &matrix);
+
+ output_dev = new CairoOutputDev();
+ output_dev->setCairo(cr);
+
+ box.x1 = mat[0];
+ box.y1 = mat[1];
+ box.x2 = mat[2];
+ box.y2 = mat[3];
+ gfx = new Gfx(info->xref, output_dev, resDict, info->catalog, &box, NULL);
+ output_dev->startDoc(info->xref, info->catalog, info->fontEngine);
+ output_dev->startPage (1, gfx->getState());
+ output_dev->setInType3Char(gTrue);
+ gfx->display(charProcs->getVal(glyph, &charProc));
+
+ output_dev->getType3GlyphWidth (&wx, &wy);
+ metrics->x_advance = wx;
+ metrics->y_advance = wy;
+ if (output_dev->hasType3GlyphBBox()) {
+ double *bbox = output_dev->getType3GlyphBBox();
+
+ cairo_matrix_transform_point (&matrix, &bbox[0], &bbox[1]);
+ cairo_matrix_transform_point (&matrix, &bbox[2], &bbox[3]);
+ metrics->x_bearing = bbox[0];
+ metrics->y_bearing = bbox[1];
+ metrics->width = bbox[2] - bbox[0];
+ metrics->height = bbox[3] - bbox[1];
+ }
+
+ delete gfx;
+ delete output_dev;
+ charProc.free();
+
+ return CAIRO_STATUS_SUCCESS;
+}
+
+
+CairoType3Font *CairoType3Font::create(GfxFont *gfxFont, XRef *xref,
+ Catalog *catalog, CairoFontEngine *fontEngine) {
+ Object refObj, strObj;
+ type3_font_info_t *info;
+ cairo_font_face_t *font_face;
+ Ref ref;
+ Gushort *codeToGID;
+ int codeToGIDLen;
+ int i, j;
+ char **enc;
+ Dict *charProcs;
+ char *name;
+
+ charProcs = ((Gfx8BitFont *)gfxFont)->getCharProcs();
+ info = (type3_font_info_t *) malloc(sizeof(*info));
+ ref = *gfxFont->getID();
+ font_face = cairo_user_font_face_create();
+ cairo_user_font_face_set_render_glyph_func (font_face, _render_type3_glyph);
+ gfxFont->incRefCnt();
+ info->font = gfxFont;
+ info->xref = xref;
+ info->catalog = catalog;
+ info->fontEngine = fontEngine;
+
+ cairo_font_face_set_user_data (font_face, &type3_font_key, (void *) info, _free_type3_font_info);
+
+ enc = ((Gfx8BitFont *)gfxFont)->getEncoding();
+ codeToGID = (Gushort *)gmallocn(256, sizeof(int));
+ codeToGIDLen = 256;
+ for (i = 0; i < 256; ++i) {
+ codeToGID[i] = 0;
+ if ((name = enc[i])) {
+ for (j = 0; j < charProcs->getLength(); j++) {
+ if (strcmp(name, charProcs->getKey(j)) == 0) {
+ codeToGID[i] = (Gushort) j;
+ }
+ }
+ }
+ }
+
+ return new CairoType3Font(ref, xref, catalog, font_face, codeToGID, codeToGIDLen);
+}
+
+CairoType3Font::CairoType3Font(Ref ref,
+ XRef *xref,
+ Catalog *cat,
+ cairo_font_face_t *cairo_font_face,
+ Gushort *codeToGID,
+ int codeToGIDLen) : CairoFont(ref,
+ cairo_font_face,
+ codeToGID,
+ codeToGIDLen,
+ gFalse),
+ xref(xref),
+ catalog(catalog) { }
+
+CairoType3Font::~CairoType3Font() { }
+
//------------------------------------------------------------------------
// CairoFontEngine
@@ -567,12 +728,6 @@ CairoFontEngine::getFont(GfxFont *gfxFont, XRef *xref, Catalog *catalog) {
CairoFont *font;
GfxFontType fontType;
- fontType = gfxFont->getType();
- if (fontType == fontType3) {
- /* Need to figure this out later */
- // return NULL;
- }
-
ref = *gfxFont->getID();
for (i = 0; i < cairoFontCacheSize; ++i) {
@@ -586,7 +741,12 @@ CairoFontEngine::getFont(GfxFont *gfxFont, XRef *xref, Catalog *catalog) {
}
}
- font = CairoFreeTypeFont::create (gfxFont, xref, lib, useCIDs);
+ fontType = gfxFont->getType();
+ if (fontType == fontType3)
+ font = CairoType3Font::create (gfxFont, xref, catalog, this);
+ else
+ font = CairoFreeTypeFont::create (gfxFont, xref, lib, useCIDs);
+
//XXX: if font is null should we still insert it into the cache?
if (fontCache[cairoFontCacheSize - 1]) {
delete fontCache[cairoFontCacheSize - 1];
diff --git a/poppler/CairoFontEngine.h b/poppler/CairoFontEngine.h
index 1f25026..2474dc6 100644
--- a/poppler/CairoFontEngine.h
+++ b/poppler/CairoFontEngine.h
@@ -37,6 +37,8 @@
#include "GfxFont.h"
#include "Catalog.h"
+class CairoFontEngine;
+
class CairoFont {
public:
CairoFont(Ref ref,
@@ -77,6 +79,22 @@ private:
//------------------------------------------------------------------------
+class CairoType3Font : public CairoFont {
+public:
+ static CairoType3Font *create(GfxFont *gfxFont, XRef *xref,
+ Catalog *catalog, CairoFontEngine *fontEngine);
+ virtual ~CairoType3Font();
+
+private:
+ CairoType3Font(Ref ref, XRef *xref, Catalog *catalog,
+ cairo_font_face_t *cairo_font_face,
+ Gushort *codeToGID, int codeToGIDLen);
+ XRef *xref;
+ Catalog *catalog;
+};
+
+//------------------------------------------------------------------------
+
#define cairoFontCacheSize 64
//------------------------------------------------------------------------
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index 3a9d452..70911b5 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -126,6 +126,7 @@ CairoOutputDev::CairoOutputDev() {
currentFont = NULL;
prescaleImages = gTrue;
printing = gTrue;
+ inType3Char = gFalse;
t3_glyph_has_bbox = gFalse;
groupColorSpaceStack = NULL;
@@ -415,9 +416,6 @@ void CairoOutputDev::updateFont(GfxState *state) {
needFontUpdate = gFalse;
- if (state->getFont()->getType() == fontType3)
- return;
-
currentFont = fontEngine->getFont (state->getFont(), xref, catalog);
if (!currentFont)
@@ -440,6 +438,11 @@ void CairoOutputDev::updateFont(GfxState *state) {
matrix.yy = -m[3] * fontSize;
matrix.x0 = 0;
matrix.y0 = 0;
+ if (inType3Char) {
+ cairo_matrix_t m;
+ cairo_matrix_init_scale (&m, 1, -1);
+ cairo_matrix_multiply (&matrix, &m, &matrix);
+ }
cairo_set_font_matrix (cairo, &matrix);
}
diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h
index b57f734..878d3e3 100644
--- a/poppler/CairoOutputDev.h
+++ b/poppler/CairoOutputDev.h
@@ -99,7 +99,7 @@ public:
// Does this device use beginType3Char/endType3Char? Otherwise,
// text in Type 3 fonts will be drawn with drawChar/drawString.
- virtual GBool interpretType3Chars() { return gTrue; }
+ virtual GBool interpretType3Chars() { return gFalse; }
//----- initialization and control
@@ -214,6 +214,7 @@ public:
void setCairo (cairo_t *cr);
void setPrinting (GBool printing) { this->printing = printing; }
+ void setInType3Char(GBool inType3Char) { this->inType3Char = inType3Char; }
void getType3GlyphWidth (double *wx, double *wy) { *wx = t3_glyph_wx; *wy = t3_glyph_wy; }
GBool hasType3GlyphBBox () { return t3_glyph_has_bbox; }
double *getType3GlyphBBox () { return t3_glyph_bbox; }
@@ -244,6 +245,7 @@ protected:
cairo_glyph_t *glyphs;
int glyphCount;
cairo_path_t *textClipPath;
+ GBool inType3Char; // inside a Type 3 CharProc
double t3_glyph_wx, t3_glyph_wy;
GBool t3_glyph_has_bbox;
double t3_glyph_bbox[4];
commit feab1e982a2ee39bb372d593633a06b6a499822f
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Sat Nov 1 01:21:39 2008 +1030
Add CairoOutputDev functions for getting Type 3 glyph metrics
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index eec5167..3a9d452 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -126,6 +126,7 @@ CairoOutputDev::CairoOutputDev() {
currentFont = NULL;
prescaleImages = gTrue;
printing = gTrue;
+ t3_glyph_has_bbox = gFalse;
groupColorSpaceStack = NULL;
group = NULL;
@@ -675,10 +676,19 @@ void CairoOutputDev::endType3Char(GfxState *state) {
}
void CairoOutputDev::type3D0(GfxState *state, double wx, double wy) {
+ t3_glyph_wx = wx;
+ t3_glyph_wy = wy;
}
void CairoOutputDev::type3D1(GfxState *state, double wx, double wy,
double llx, double lly, double urx, double ury) {
+ t3_glyph_wx = wx;
+ t3_glyph_wy = wy;
+ t3_glyph_bbox[0] = llx;
+ t3_glyph_bbox[1] = lly;
+ t3_glyph_bbox[2] = urx;
+ t3_glyph_bbox[3] = ury;
+ t3_glyph_has_bbox = gTrue;
}
void CairoOutputDev::endTextObject(GfxState *state) {
diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h
index d70740d..b57f734 100644
--- a/poppler/CairoOutputDev.h
+++ b/poppler/CairoOutputDev.h
@@ -214,6 +214,10 @@ public:
void setCairo (cairo_t *cr);
void setPrinting (GBool printing) { this->printing = printing; }
+ void getType3GlyphWidth (double *wx, double *wy) { *wx = t3_glyph_wx; *wy = t3_glyph_wy; }
+ GBool hasType3GlyphBBox () { return t3_glyph_has_bbox; }
+ double *getType3GlyphBBox () { return t3_glyph_bbox; }
+
protected:
void doPath(cairo_t *cairo, GfxState *state, GfxPath *path);
@@ -240,6 +244,9 @@ protected:
cairo_glyph_t *glyphs;
int glyphCount;
cairo_path_t *textClipPath;
+ double t3_glyph_wx, t3_glyph_wy;
+ GBool t3_glyph_has_bbox;
+ double t3_glyph_bbox[4];
GBool prescaleImages;
commit a75efe208d899d4a23d5e2fcef200e4225721636
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Sat Nov 1 00:26:40 2008 +1030
Make the catalog available to CairoFontEngine
diff --git a/glib/poppler-document.cc b/glib/poppler-document.cc
index 7637af4..ef5deb0 100644
--- a/glib/poppler-document.cc
+++ b/glib/poppler-document.cc
@@ -106,14 +106,15 @@ _poppler_document_new_from_pdfdoc (PDFDoc *newDoc,
#if defined (HAVE_CAIRO)
document->output_dev = new CairoOutputDev ();
+ document->output_dev->startDoc(document->doc->getXRef (), document->doc->getCatalog ());
#elif defined (HAVE_SPLASH)
SplashColor white;
white[0] = 255;
white[1] = 255;
white[2] = 255;
document->output_dev = new SplashOutputDev(splashModeRGB8, 4, gFalse, white);
-#endif
document->output_dev->startDoc(document->doc->getXRef ());
+#endif
return document;
}
diff --git a/poppler/CairoFontEngine.cc b/poppler/CairoFontEngine.cc
index 61e00a3..75340b8 100644
--- a/poppler/CairoFontEngine.cc
+++ b/poppler/CairoFontEngine.cc
@@ -561,7 +561,7 @@ CairoFontEngine::~CairoFontEngine() {
}
CairoFont *
-CairoFontEngine::getFont(GfxFont *gfxFont, XRef *xref) {
+CairoFontEngine::getFont(GfxFont *gfxFont, XRef *xref, Catalog *catalog) {
int i, j;
Ref ref;
CairoFont *font;
diff --git a/poppler/CairoFontEngine.h b/poppler/CairoFontEngine.h
index 8b7a99f..1f25026 100644
--- a/poppler/CairoFontEngine.h
+++ b/poppler/CairoFontEngine.h
@@ -35,6 +35,7 @@
#include <cairo-ft.h>
#include "GfxFont.h"
+#include "Catalog.h"
class CairoFont {
public:
@@ -89,7 +90,7 @@ public:
CairoFontEngine(FT_Library libA);
~CairoFontEngine();
- CairoFont *getFont(GfxFont *gfxFont, XRef *xref);
+ CairoFont *getFont(GfxFont *gfxFont, XRef *xref, Catalog *catalog);
private:
CairoFont *fontCache[cairoFontCacheSize];
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index 25335b7..eec5167 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -107,6 +107,7 @@ GBool CairoOutputDev::ft_lib_initialized = gFalse;
CairoOutputDev::CairoOutputDev() {
xref = NULL;
+ catalog = NULL;
if (!ft_lib_initialized) {
FT_Init_FreeType(&ft_lib);
@@ -172,8 +173,10 @@ void CairoOutputDev::setCairo(cairo_t *cairo)
}
}
-void CairoOutputDev::startDoc(XRef *xrefA, CairoFontEngine *parentFontEngine) {
+void CairoOutputDev::startDoc(XRef *xrefA, Catalog *catalogA,
+ CairoFontEngine *parentFontEngine) {
xref = xrefA;
+ catalog = catalogA;
if (parentFontEngine) {
fontEngine = parentFontEngine;
} else {
@@ -414,7 +417,7 @@ void CairoOutputDev::updateFont(GfxState *state) {
if (state->getFont()->getType() == fontType3)
return;
- currentFont = fontEngine->getFont (state->getFont(), xref);
+ currentFont = fontEngine->getFont (state->getFont(), xref, catalog);
if (!currentFont)
return;
diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h
index 27b39ed..d70740d 100644
--- a/poppler/CairoOutputDev.h
+++ b/poppler/CairoOutputDev.h
@@ -207,7 +207,7 @@ public:
//----- special access
// Called to indicate that a new PDF document has been loaded.
- void startDoc(XRef *xrefA, CairoFontEngine *fontEngine = NULL);
+ void startDoc(XRef *xrefA, Catalog *catalogA, CairoFontEngine *fontEngine = NULL);
GBool isReverseVideo() { return gFalse; }
@@ -224,6 +224,7 @@ protected:
CairoFont *currentFont;
XRef *xref; // xref table for current document
+ Catalog *catalog;
static FT_Library ft_lib;
static GBool ft_lib_initialized;
diff --git a/test/pdf-inspector.cc b/test/pdf-inspector.cc
index 3965380..3eb8650 100644
--- a/test/pdf-inspector.cc
+++ b/test/pdf-inspector.cc
@@ -292,7 +292,7 @@ PdfInspector::load(const char *file_name)
gtk_spin_button_set_range (GTK_SPIN_BUTTON (spin), 0, doc->getNumPages()-1);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), 0);
- output->startDoc (doc->getXRef());
+ output->startDoc (doc->getXRef(), doc->getCatalog());
}
else
{
commit 941d3976c496b75a3c5a9d19b80044fc2b57bd98
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Fri Oct 31 22:44:41 2008 +1030
Allow multiple instances of CairoOutputDev to be created
for the same document that shares the same CairoFontEngine.
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index 03cc059..25335b7 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -114,6 +114,7 @@ CairoOutputDev::CairoOutputDev() {
}
fontEngine = NULL;
+ fontEngine_owner = gFalse;
glyphs = NULL;
fill_pattern = NULL;
stroke_pattern = NULL;
@@ -134,7 +135,7 @@ CairoOutputDev::CairoOutputDev() {
}
CairoOutputDev::~CairoOutputDev() {
- if (fontEngine) {
+ if (fontEngine_owner && fontEngine) {
delete fontEngine;
}
@@ -171,12 +172,17 @@ void CairoOutputDev::setCairo(cairo_t *cairo)
}
}
-void CairoOutputDev::startDoc(XRef *xrefA) {
+void CairoOutputDev::startDoc(XRef *xrefA, CairoFontEngine *parentFontEngine) {
xref = xrefA;
- if (fontEngine) {
- delete fontEngine;
+ if (parentFontEngine) {
+ fontEngine = parentFontEngine;
+ } else {
+ if (fontEngine) {
+ delete fontEngine;
+ }
+ fontEngine = new CairoFontEngine(ft_lib);
+ fontEngine_owner = gTrue;
}
- fontEngine = new CairoFontEngine(ft_lib);
}
void CairoOutputDev::startPage(int pageNum, GfxState *state) {
diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h
index 9a18613..27b39ed 100644
--- a/poppler/CairoOutputDev.h
+++ b/poppler/CairoOutputDev.h
@@ -207,7 +207,7 @@ public:
//----- special access
// Called to indicate that a new PDF document has been loaded.
- void startDoc(XRef *xrefA);
+ void startDoc(XRef *xrefA, CairoFontEngine *fontEngine = NULL);
GBool isReverseVideo() { return gFalse; }
@@ -229,6 +229,8 @@ protected:
static GBool ft_lib_initialized;
CairoFontEngine *fontEngine;
+ GBool fontEngine_owner;
+
cairo_t *cairo;
cairo_matrix_t orig_matrix;
GBool needFontUpdate; // set when the font needs to be updated
commit 94cff513d8589f51b243fcb078f82cb931bb6d35
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Fri Oct 31 21:11:01 2008 +1030
Use correct return type in _ft_new_face
diff --git a/poppler/CairoFontEngine.cc b/poppler/CairoFontEngine.cc
index 587275d..61e00a3 100644
--- a/poppler/CairoFontEngine.cc
+++ b/poppler/CairoFontEngine.cc
@@ -313,7 +313,7 @@ _ft_new_face (FT_Library lib,
{
cairo_font_face_destroy (l->font_face);
_ft_done_face (l);
- return NULL;
+ return gFalse;
}
*face_out = l->face;
commit 0b5ee897a24ce1edfca19a3b843f9b7ee7026d07
Author: Adrian Johnson <ajohnson at redneon.com>
Date: Fri Oct 31 20:55:14 2008 +1030
Refactor CairoFont
Create a CairoFreeType subclass and move the FreeType specific code
into it.
diff --git a/poppler/CairoFontEngine.cc b/poppler/CairoFontEngine.cc
index 8d5ad72..587275d 100644
--- a/poppler/CairoFontEngine.cc
+++ b/poppler/CairoFontEngine.cc
@@ -50,16 +50,106 @@
#pragma implementation
#endif
-static void fileWrite(void *stream, char *data, int len) {
- fwrite(data, 1, len, (FILE *)stream);
-}
//------------------------------------------------------------------------
// CairoFont
//------------------------------------------------------------------------
+CairoFont::CairoFont(Ref ref,
+ cairo_font_face_t *cairo_font_face,
+ Gushort *codeToGID,
+ int codeToGIDLen,
+ GBool substitute) : ref(ref),
+ cairo_font_face(cairo_font_face),
+ codeToGID(codeToGID),
+ codeToGIDLen(codeToGIDLen),
+ substitute(substitute) { }
+
+CairoFont::~CairoFont() {
+ cairo_font_face_destroy (cairo_font_face);
+ gfree(codeToGID);
+}
+
+GBool
+CairoFont::matches(Ref &other) {
+ return (other.num == ref.num && other.gen == ref.gen);
+}
+
+cairo_font_face_t *
+CairoFont::getFontFace(void) {
+ return cairo_font_face;
+}
+
+unsigned long
+CairoFont::getGlyph(CharCode code,
+ Unicode *u, int uLen) {
+ FT_UInt gid;
+
+ if (codeToGID && code < codeToGIDLen) {
+ gid = (FT_UInt)codeToGID[code];
+ } else {
+ gid = (FT_UInt)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;
+}
+
+//------------------------------------------------------------------------
+// CairoFreeTypeFont
+//------------------------------------------------------------------------
+
static cairo_user_data_key_t _ft_cairo_key;
+static void fileWrite(void *stream, char *data, int len) {
+ fwrite(data, 1, len, (FILE *)stream);
+}
+
static void
_ft_done_face_uncached (void *closure)
{
@@ -234,7 +324,22 @@ _ft_new_face (FT_Library lib,
#define _ft_new_face _ft_new_face_uncached
#endif
-CairoFont *CairoFont::create(GfxFont *gfxFont, XRef *xref, FT_Library lib, GBool useCIDs) {
+CairoFreeTypeFont::CairoFreeTypeFont(Ref ref,
+ cairo_font_face_t *cairo_font_face,
+ FT_Face face,
+ Gushort *codeToGID,
+ int codeToGIDLen,
+ GBool substitute) : CairoFont(ref,
+ cairo_font_face,
+ codeToGID,
+ codeToGIDLen,
+ substitute),
+ face(face) { }
+
+CairoFreeTypeFont::~CairoFreeTypeFont() { }
+
+CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref,
+ FT_Library lib, GBool useCIDs) {
Ref embRef;
Object refObj, strObj;
GooString *tmpFileName, *fileName,*tmpFileName2;
@@ -415,7 +520,7 @@ CairoFont *CairoFont::create(GfxFont *gfxFont, XRef *xref, FT_Library lib, GBool
delete tmpFileName;
}
- return new CairoFont(ref,
+ return new CairoFreeTypeFont(ref,
font_face, face,
codeToGID, codeToGIDLen,
substitute);
@@ -426,85 +531,6 @@ CairoFont *CairoFont::create(GfxFont *gfxFont, XRef *xref, FT_Library lib, GBool
return NULL;
}
-CairoFont::CairoFont(Ref ref, cairo_font_face_t *cairo_font_face, FT_Face face,
- Gushort *codeToGID, int codeToGIDLen, GBool substitute) : ref(ref), cairo_font_face(cairo_font_face),
- face(face), codeToGID(codeToGID),
- codeToGIDLen(codeToGIDLen), substitute(substitute) { }
-
-CairoFont::~CairoFont() {
- cairo_font_face_destroy (cairo_font_face);
- gfree(codeToGID);
-}
-
-GBool
-CairoFont::matches(Ref &other) {
- return (other.num == ref.num && other.gen == ref.gen);
-}
-
-cairo_font_face_t *
-CairoFont::getFontFace(void) {
- return cairo_font_face;
-}
-
-unsigned long
-CairoFont::getGlyph(CharCode code,
- Unicode *u, int uLen) {
- FT_UInt gid;
-
- if (codeToGID && code < codeToGIDLen) {
- gid = (FT_UInt)codeToGID[code];
- } else {
- gid = (FT_UInt)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
@@ -560,7 +586,7 @@ CairoFontEngine::getFont(GfxFont *gfxFont, XRef *xref) {
}
}
- font = CairoFont::create (gfxFont, xref, lib, useCIDs);
+ font = CairoFreeTypeFont::create (gfxFont, xref, lib, useCIDs);
//XXX: if font is null should we still insert it into the cache?
if (fontCache[cairoFontCacheSize - 1]) {
delete fontCache[cairoFontCacheSize - 1];
@@ -571,4 +597,3 @@ CairoFontEngine::getFont(GfxFont *gfxFont, XRef *xref) {
fontCache[0] = font;
return font;
}
-
diff --git a/poppler/CairoFontEngine.h b/poppler/CairoFontEngine.h
index 5ecdcdf..8b7a99f 100644
--- a/poppler/CairoFontEngine.h
+++ b/poppler/CairoFontEngine.h
@@ -38,8 +38,12 @@
class CairoFont {
public:
- static CairoFont *create(GfxFont *gfxFont, XRef *xref, FT_Library lib, GBool useCIDs);
- ~CairoFont();
+ CairoFont(Ref ref,
+ cairo_font_face_t *face,
+ Gushort *codeToGID,
+ int codeToGIDLen,
+ GBool substitute);
+ virtual ~CairoFont();
GBool matches(Ref &other);
cairo_font_face_t *getFontFace(void);
@@ -47,12 +51,9 @@ public:
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, GBool substitute);
+protected:
Ref ref;
cairo_font_face_t *cairo_font_face;
- FT_Face face;
Gushort *codeToGID;
int codeToGIDLen;
@@ -62,6 +63,19 @@ private:
//------------------------------------------------------------------------
+class CairoFreeTypeFont : public CairoFont {
+public:
+ static CairoFreeTypeFont *create(GfxFont *gfxFont, XRef *xref, FT_Library lib, GBool useCIDs);
+ virtual ~CairoFreeTypeFont();
+
+private:
+ CairoFreeTypeFont(Ref ref, cairo_font_face_t *cairo_font_face, FT_Face face,
+ Gushort *codeToGID, int codeToGIDLen, GBool substitute);
+ FT_Face face;
+};
+
+//------------------------------------------------------------------------
+
#define cairoFontCacheSize 64
//------------------------------------------------------------------------
More information about the poppler
mailing list