[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