Code

Encapsulating use of gcc hash_map extension.
authorJon A. Cruz <jon@joncruz.org>
Sun, 27 Dec 2009 03:35:08 +0000 (19:35 -0800)
committerJon A. Cruz <jon@joncruz.org>
Sun, 27 Dec 2009 03:35:08 +0000 (19:35 -0800)
src/libnrtype/FontFactory.cpp
src/libnrtype/FontFactory.h
src/libnrtype/FontInstance.cpp
src/libnrtype/font-instance.h

index fec9316b98a7aa3e3493e0fd9ca77133aa5c02cd..1f85ee5ca7c39e2cac79ade09a814c66b2c541f6 100644 (file)
 /* Freetype2 */
 # include <pango/pangoft2.h>
 
+#include <ext/hash_map>
+
+
+typedef __gnu_cxx::hash_map<PangoFontDescription*, font_instance*, font_descr_hash, font_descr_equal> FaceMapType;
 
 // need to avoid using the size field
 size_t font_descr_hash::operator()( PangoFontDescription *const &x) const {
@@ -299,20 +303,25 @@ font_factory *font_factory::Default(void)
     return lUsine;
 }
 
-font_factory::font_factory(void)
-{
-    fontSize = 512;
-    nbEnt = 0;
-    maxEnt = 32;
-    ents = (font_entry*)g_malloc(maxEnt*sizeof(font_entry));
+font_factory::font_factory(void) :
+    nbEnt(0),
+    maxEnt(32),
+    ents(static_cast<font_entry*>(g_malloc(maxEnt*sizeof(font_entry)))),
 
 #ifdef USE_PANGO_WIN32
-    hScreenDC = pango_win32_get_dc();
-    fontServer = pango_win32_font_map_for_display();
-    fontContext = pango_win32_get_context();
-    pangoFontCache = pango_win32_font_map_get_font_cache(fontServer);
+    fontServer(pango_win32_font_map_for_display()),
+    fontContext(pango_win32_get_context()),
+    pangoFontCache(pango_win32_font_map_get_font_cache(fontServer)),
+    hScreenDC(pango_win32_get_dc()),
+#else
+    fontServer(pango_ft2_font_map_new()),
+    fontContext(0),
+#endif
+    fontSize(512),
+    loadedPtr(new FaceMapType())
+{
+#ifdef USE_PANGO_WIN32
 #else
-    fontServer = pango_ft2_font_map_new();
     pango_ft2_font_map_set_resolution((PangoFT2FontMap*)fontServer, 72, 72);
     fontContext = pango_ft2_font_map_create_context((PangoFT2FontMap*)fontServer);
     pango_ft2_font_map_set_default_substitute((PangoFT2FontMap*)fontServer,FactorySubstituteFunc,this,NULL);
@@ -321,6 +330,11 @@ font_factory::font_factory(void)
 
 font_factory::~font_factory(void)
 {
+    if (loadedPtr) {
+        FaceMapType* tmp = static_cast<FaceMapType*>(loadedPtr);
+        loadedPtr = 0;
+    }
+
     for (int i = 0;i < nbEnt;i++) ents[i].f->Unref();
     if ( ents ) g_free(ents);
 
@@ -793,6 +807,7 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail)
 
     font_instance *res = NULL;
 
+    FaceMapType& loadedFaces = *static_cast<FaceMapType*>(loadedPtr);
     if ( loadedFaces.find(descr) == loadedFaces.end() ) {
         // not yet loaded
         PangoFont *nFace = NULL;
@@ -849,8 +864,9 @@ font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail)
         res->Ref();
         AddInCache(res);
     }
-    if(res)
-       res->InitTheFace();
+    if (res) {
+        res->InitTheFace();
+    }
     return res;
 }
 
@@ -924,15 +940,18 @@ font_instance *font_factory::Face(char const *family, NRTypePosDef apos)
 
 void font_factory::UnrefFace(font_instance *who)
 {
-    if ( who == NULL ) return;
-    if ( loadedFaces.find(who->descr) == loadedFaces.end() ) {
-        // not found
-        char *tc = pango_font_description_to_string(who->descr);
-        g_warning("unrefFace %p=%s: failed\n",who,tc);
-        g_free(tc);
-    } else {
-        loadedFaces.erase(loadedFaces.find(who->descr));
-        //                     printf("unrefFace %p: success\n",who);
+    if ( who ) {
+        FaceMapType& loadedFaces = *static_cast<FaceMapType*>(loadedPtr);
+
+        if ( loadedFaces.find(who->descr) == loadedFaces.end() ) {
+            // not found
+            char *tc = pango_font_description_to_string(who->descr);
+            g_warning("unrefFace %p=%s: failed\n",who,tc);
+            g_free(tc);
+        } else {
+            loadedFaces.erase(loadedFaces.find(who->descr));
+            //                 printf("unrefFace %p: success\n",who);
+        }
     }
 }
 
index 9f4b31a2e5c776f967d85ef1e7ccec5412a24f4a..8d85bcf3e88e3127181c604ef0b9b6edb2717aba 100644 (file)
@@ -11,7 +11,6 @@
 
 #include <functional>
 #include <algorithm>
-#include <ext/hash_map>
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
@@ -84,31 +83,29 @@ public:
     double fontSize; /**< The huge fontsize used as workaround for hinting.
                       *   Different between freetype and win32. */
 
-    __gnu_cxx::hash_map<PangoFontDescription*, font_instance*, font_descr_hash, font_descr_equal> loadedFaces;
-
     font_factory();
     virtual ~font_factory();
 
     /// Returns the default font_factory.
     static font_factory*  Default();
-    
+
     /// Constructs a pango string for use with the fontStringMap (see below)
     Glib::ustring         ConstructFontSpecification(PangoFontDescription *font);
     Glib::ustring         ConstructFontSpecification(font_instance *font);
-    
+
     /// Returns strings to be used in the UI for family and face (or "style" as the column is labeled)
     Glib::ustring         GetUIFamilyString(PangoFontDescription const *fontDescr);
     Glib::ustring         GetUIStyleString(PangoFontDescription const *fontDescr);
-    
+
     /// Modifiers for the font specification (returns new font specification)
     Glib::ustring         ReplaceFontSpecificationFamily(const Glib::ustring & fontSpec, const Glib::ustring & newFamily);
     Glib::ustring         FontSpecificationSetItalic(const Glib::ustring & fontSpec, bool turnOn);
     Glib::ustring         FontSpecificationSetBold(const Glib::ustring & fontSpec, bool turnOn);
-    
+
     // Gathers all strings needed for UI while storing pango information in
     // fontInstanceMap and fontStringMap
     void                  GetUIFamiliesAndStyles(FamilyToStylesMap *map);
-    
+
     /// Retrieve a font_instance from a style object, first trying to use the font-specification, the CSS information
     font_instance*        FaceFromStyle(SPStyle const *style);
 
@@ -129,17 +126,19 @@ public:
 
     // internal
     void                  AddInCache(font_instance *who);
-    
+
 private:
+    void*                 loadedPtr;
+
     // These two maps are used for translating between what's in the UI and a pango
     // font description.  This is necessary because Pango cannot always
     // reproduce these structures from the names it gave us in the first place.
-    
+
     // Key: A string produced by font_factory::ConstructFontSpecification
     // Value: The associated PangoFontDescription
     typedef std::map<Glib::ustring, PangoFontDescription *> PangoStringToDescrMap;
     PangoStringToDescrMap fontInstanceMap;
-    
+
     // Key: Family name in UI + Style name in UI
     // Value: The associated string that should be produced with font_factory::ConstructFontSpecification
     typedef std::map<Glib::ustring, Glib::ustring> UIStringToPangoStringMap;
index e1413b46e788a87f9f90832c551aeec169d4e614..f34a230c1f05ac09b2d984ed1cb0660431649b67 100644 (file)
 # include FT_TRUETYPE_TABLES_H
 # include <pango/pangoft2.h>
 
+#include <ext/hash_map>
+
+
+// the various raster_font in use at a given time are held in a hash_map whose indices are the
+// styles, hence the 2 following 'classes'
+struct font_style_hash : public std::unary_function<font_style, size_t> {
+    size_t operator()(font_style const &x) const;
+};
+
+struct font_style_equal : public std::binary_function<font_style, font_style, bool> {
+    bool operator()(font_style const &a, font_style const &b);
+};
+
+
+typedef __gnu_cxx::hash_map<font_style, raster_font*, font_style_hash, font_style_equal> StyleMap;
+
 
 
 size_t  font_style_hash::operator()(const font_style &x) const {
@@ -155,36 +171,61 @@ static int ft2_cubic_to(FREETYPE_VECTOR *control1, FREETYPE_VECTOR *control2, FR
  *
  */
 
-font_instance::font_instance(void)
+font_instance::font_instance(void) :
+    pFont(0),
+    descr(0),
+    refCount(0),
+    daddy(0),
+    nbGlyph(0),
+    maxGlyph(0),
+    glyphs(0),
+    loadedPtr(new StyleMap()),
+    theFace(0)
 {
-       //printf("font instance born\n");
-       descr=NULL;
-       pFont=NULL;
-       refCount=0;
-       daddy=NULL;
-       nbGlyph=maxGlyph=0;
-       glyphs=NULL;
-       theFace=NULL;
+    //printf("font instance born\n");
 }
 
 font_instance::~font_instance(void)
 {
-       if ( daddy ) daddy->UnrefFace(this);
-       //printf("font instance death\n");
-       if ( pFont ) g_object_unref(pFont);
-       pFont=NULL;
-       if ( descr ) pango_font_description_free(descr);
-       descr=NULL;
-       //      if ( theFace ) FT_Done_Face(theFace); // owned by pFont. don't touch
-       theFace=NULL;
-
-       for (int i=0;i<nbGlyph;i++) {
-               if ( glyphs[i].outline ) delete glyphs[i].outline;
-        if ( glyphs[i].pathvector ) delete glyphs[i].pathvector;
-       }
-       if ( glyphs ) free(glyphs);
-       nbGlyph=maxGlyph=0;
-       glyphs=NULL;
+    if ( loadedPtr ) {
+        StyleMap* tmp = static_cast<StyleMap*>(loadedPtr);
+        delete tmp;
+        loadedPtr = 0;
+    }
+
+    if ( daddy ) {
+        daddy->UnrefFace(this);
+        daddy = 0;
+    }
+
+    //printf("font instance death\n");
+    if ( pFont ) {
+        g_object_unref(pFont);
+        pFont = 0;
+    }
+
+    if ( descr ) {
+        pango_font_description_free(descr);
+        descr = 0;
+    }
+
+    // if ( theFace ) FT_Done_Face(theFace); // owned by pFont. don't touch
+    theFace = 0;
+
+    for (int i=0;i<nbGlyph;i++) {
+        if ( glyphs[i].outline ) {
+            delete glyphs[i].outline;
+        }
+        if ( glyphs[i].pathvector ) {
+            delete glyphs[i].pathvector;
+        }
+    }
+    if ( glyphs ) {
+        free(glyphs);
+        glyphs = 0;
+    }
+    nbGlyph = 0;
+    maxGlyph = 0;
 }
 
 void font_instance::Ref(void)
@@ -728,7 +769,8 @@ raster_font* font_instance::RasterFont(const font_style &inStyle)
                nStyle.dashes=(double*)malloc(nStyle.nbDash*sizeof(double));
                memcpy(nStyle.dashes,savDashes,nStyle.nbDash*sizeof(double));
        }
-       if ( loadedStyles.find(nStyle) == loadedStyles.end() ) {
+        StyleMap& loadedStyles = *static_cast<StyleMap*>(loadedPtr);
+        if ( loadedStyles.find(nStyle) == loadedStyles.end() ) {
                 raster_font *nR = new raster_font(nStyle);
                nR->Ref();
                nR->daddy=this;
@@ -746,15 +788,17 @@ raster_font* font_instance::RasterFont(const font_style &inStyle)
 
 void font_instance::RemoveRasterFont(raster_font* who)
 {
-       if ( who == NULL ) return;
-       if ( loadedStyles.find(who->style) == loadedStyles.end() ) {
-               //g_print("RemoveRasterFont failed \n");
-               // not found
-       } else {
-               loadedStyles.erase(loadedStyles.find(who->style));
-               //g_print("RemoveRasterFont\n");
-               Unref();
-       }
+    if ( who ) {
+        StyleMap& loadedStyles = *static_cast<StyleMap*>(loadedPtr);
+        if ( loadedStyles.find(who->style) == loadedStyles.end() ) {
+            //g_print("RemoveRasterFont failed \n");
+            // not found
+        } else {
+            loadedStyles.erase(loadedStyles.find(who->style));
+            //g_print("RemoveRasterFont\n");
+            Unref();
+        }
+    }
 }
 
 
index 4209a20af68c723c41daabd6867857cb0b62ee8b..521c9a42428db3f94884c7cee1352b4d095404de 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef SEEN_LIBNRTYPE_FONT_INSTANCE_H
 #define SEEN_LIBNRTYPE_FONT_INSTANCE_H
 
-#include <ext/hash_map>
 #include <map>
 #include <pango/pango-types.h>
 #include <pango/pango-font.h>
 #include <2geom/d2.h>
 
 // the font_instance are the template of several raster_font; they provide metrics and outlines
-// that are drawn by the raster_font, so the raster_font needs info relative to the way the 
+// that are drawn by the raster_font, so the raster_font needs info relative to the way the
 // font need to be drawn. note that fontsize is a scale factor in the transform matrix
 // of the style
-// the various raster_font in use at a given time are held in a hash_map whose indices are the
-// styles, hence the 2 following 'classes'
-struct font_style_hash : public std::unary_function<font_style, size_t> {
-    size_t operator()(font_style const &x) const;
-};
-
-struct font_style_equal : public std::binary_function<font_style, font_style, bool> {
-    bool operator()(font_style const &a, font_style const &b);
-};
-
 class font_instance {
 public:
-       // hashmap to get the raster_font for a given style
-    __gnu_cxx::hash_map<font_style, raster_font*, font_style_hash, font_style_equal>     loadedStyles;
-       // the real source of the font
+    // the real source of the font
     PangoFont*            pFont;
-               // depending on the rendering backend, different temporary data
+    // depending on the rendering backend, different temporary data
 
-               // that's the font's fingerprint; this particular PangoFontDescription gives the entry at which this font_instance
-               // resides in the font_factory loadedFaces hash_map
+    // that's the font's fingerprint; this particular PangoFontDescription gives the entry at which this font_instance
+    // resides in the font_factory loadedFaces hash_map
     PangoFontDescription* descr;
-               // refcount
+    // refcount
     int                   refCount;
-               // font_factory owning this font_instance
+    // font_factory owning this font_instance
     font_factory*         daddy;
 
     // common glyph definitions for all the rasterfonts
@@ -58,38 +45,38 @@ public:
 
     bool                 IsOutlineFont(void); // utility
     void                 InstallFace(PangoFont* iFace); // utility; should reset the pFont field if loading failed
-                                       // in case the PangoFont is a bitmap font, for example. that way, the calling function 
-                                       // will be able to check the validity of the font before installing it in loadedFaces
+    // in case the PangoFont is a bitmap font, for example. that way, the calling function
+    // will be able to check the validity of the font before installing it in loadedFaces
     void                 InitTheFace();
 
     int                  MapUnicodeChar(gunichar c); // calls the relevant unicode->glyph index function
     void                 LoadGlyph(int glyph_id);    // the main backend-dependent function
-                                       // loads the given glyph's info
-               
-               // nota: all coordinates returned by these functions are on a [0..1] scale; you need to multiply 
-               // by the fontsize to get the real sizes
+    // loads the given glyph's info
+
+    // nota: all coordinates returned by these functions are on a [0..1] scale; you need to multiply
+    // by the fontsize to get the real sizes
     Path*                Outline(int glyph_id, Path *copyInto=NULL);
-                                       // queries the outline of the glyph (in livarot Path form), and copies it into copyInto instead
-                                       // of allocating a new Path if copyInto != NULL
+    // queries the outline of the glyph (in livarot Path form), and copies it into copyInto instead
+    // of allocating a new Path if copyInto != NULL
     Geom::PathVector*    PathVector(int glyph_id);
                          // returns the 2geom-type pathvector for this glyph. no refcounting needed, it's deallocated when the font_instance dies
     double               Advance(int glyph_id, bool vertical);
-                                       // nominal advance of the font.
+    // nominal advance of the font.
     bool                 FontMetrics(double &ascent, double &descent, double &leading);
     bool                 FontSlope(double &run, double &rise);
                                 // for generating slanted cursors for oblique fonts
     Geom::OptRect             BBox(int glyph_id);
 
-               // creates a rasterfont for the given style
+    // creates a rasterfont for the given style
     raster_font*         RasterFont(Geom::Matrix const &trs, double stroke_width,
                                     bool vertical = false, JoinType stroke_join = join_straight,
                                     ButtType stroke_cap = butt_straight, float miter_limit = 4.0);
-               // the dashes array in iStyle is copied
+    // the dashes array in iStyle is copied
     raster_font*         RasterFont(font_style const &iStyle);
-               // private use: tells the font_instance that the raster_font 'who' has died
+    // private use: tells the font_instance that the raster_font 'who' has died
     void                 RemoveRasterFont(raster_font *who);
 
-               // attribute queries
+    // attribute queries
     unsigned             Name(gchar *str, unsigned size);
     unsigned             PSName(gchar *str, unsigned size);
     unsigned             Family(gchar *str, unsigned size);
@@ -98,10 +85,13 @@ public:
 private:
     void                 FreeTheFace();
 
+    // hashmap to get the raster_font for a given style
+    void*                loadedPtr; // Pointer to a hash_map. Moved into .cpp to not expose use of __gnu_cxx extension.
+
 #ifdef USE_PANGO_WIN32
     HFONT                 theFace;
 #else
-    FT_Face               theFace; 
+    FT_Face               theFace;
                 // it's a pointer in fact; no worries to ref/unref it, pango does its magic
                 // as long as pFont is valid, theFace is too
 #endif