use SkDataTable to return familyNames for fontmgr



git-svn-id: http://skia.googlecode.com/svn/trunk@8781 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/include/ports/SkFontConfigInterface.h b/include/ports/SkFontConfigInterface.h
index e9d3f6c..786c346 100644
--- a/include/ports/SkFontConfigInterface.h
+++ b/include/ports/SkFontConfigInterface.h
@@ -8,8 +8,10 @@
 #ifndef SkFontConfigInterface_DEFINED
 #define SkFontConfigInterface_DEFINED
 
+#include "SkDataTable.h"
 #include "SkFontStyle.h"
 #include "SkRefCnt.h"
+#include "SkTArray.h"
 #include "SkTypeface.h"
 
 /**
@@ -86,14 +88,11 @@
 
     // New APIS, which have default impls for now (which do nothing)
 
-    virtual int countFamilies() { return 0; };
-    virtual int getFamilySet(int index, SkString* outFamilyName,
-                             FontIdentity outIdentities[], int maxCount) {
-        return 0;
-    }
-    virtual int matchFamilySet(const char familyName[], SkString* outFamilyName,
-                               FontIdentity outIdentities[], int maxCount) {
-        return 0;
+    virtual SkDataTable* getFamilyNames() { return SkDataTable::NewEmpty(); }
+    virtual bool matchFamilySet(const char inFamilyName[],
+                                SkString* outFamilyName,
+                                SkTArray<FontIdentity>*) {
+        return false;
     }
 };
 
diff --git a/src/ports/SkFontConfigInterface_direct.cpp b/src/ports/SkFontConfigInterface_direct.cpp
index fcb309e..b0a2e46 100644
--- a/src/ports/SkFontConfigInterface_direct.cpp
+++ b/src/ports/SkFontConfigInterface_direct.cpp
@@ -28,6 +28,12 @@
                                  SkTypeface::Style* outStyle) SK_OVERRIDE;
     virtual SkStream* openStream(const FontIdentity&) SK_OVERRIDE;
 
+    // new APIs
+    virtual SkDataTable* getFamilyNames() SK_OVERRIDE;
+    virtual bool matchFamilySet(const char inFamilyName[],
+                                SkString* outFamilyName,
+                                SkTArray<FontIdentity>*) SK_OVERRIDE;
+
 private:
     SkMutex mutex_;
 };
@@ -448,3 +454,61 @@
 SkStream* SkFontConfigInterfaceDirect::openStream(const FontIdentity& identity) {
     return SkStream::NewFromFile(identity.fString.c_str());
 }
+
+///////////////////////////////////////////////////////////////////////////////
+
+static const char* get_name(FcPattern* pattern, const char field[]) {
+    const char* name;
+    if (FcPatternGetString(pattern, field, 0, (FcChar8**)&name) != FcResultMatch) {
+        name = "";
+    }
+    return name;
+}
+
+static bool find_name(const SkTDArray<const char*>& list, const char* str) {
+    int count = list.count();
+    for (int i = 0; i < count; ++i) {
+        if (!strcmp(list[i], str)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+SkDataTable* SkFontConfigInterfaceDirect::getFamilyNames() {
+    FcPattern* pat = FcPatternCreate();
+    FcObjectSet* os = FcObjectSetBuild (FC_FAMILY, (char *) 0);
+    if (NULL == os) {
+        return false;
+    }
+    FcFontSet* fs = FcFontList(NULL, pat, os);
+    if (NULL == fs) {
+        FcObjectSetDestroy(os);
+        return false;
+    }
+
+    SkTDArray<const char*> names;
+    SkTDArray<size_t> sizes;
+    for (int i = 0; i < fs->nfont; ++i) {
+        FcPattern* match = fs->fonts[i];
+        const char* famName = get_name(match, FC_FAMILY);
+        if (!find_name(names, famName)) {
+            *names.append() = famName;
+            *sizes.append() = strlen(famName) + 1;
+        }
+    }
+
+    FcFontSetDestroy(fs);
+    FcObjectSetDestroy(os);
+    FcPatternDestroy(pat);
+
+    return SkDataTable::NewCopyArrays((const void*const*)names.begin(),
+                                      sizes.begin(), names.count());
+}
+
+bool SkFontConfigInterfaceDirect::matchFamilySet(const char inFamilyName[],
+                                                 SkString* outFamilyName,
+                                                 SkTArray<FontIdentity>* ids) {
+    return false;
+}
+
diff --git a/src/ports/SkFontHost_fontconfig.cpp b/src/ports/SkFontHost_fontconfig.cpp
index e9fe185..55ac904 100644
--- a/src/ports/SkFontHost_fontconfig.cpp
+++ b/src/ports/SkFontHost_fontconfig.cpp
@@ -353,8 +353,6 @@
         fRecs[i].fStyleName.set(get_name(matches[i], FC_STYLE));
         fRecs[i].fFileName.set(get_name(matches[i], FC_FILE));
         fRecs[i].fStyle = make_fontconfig_style(matches[i]);
-        
-//        SkDebugf("%s [%d %d %d]\n", fRecs[i].fFileName.c_str(), fRecs[i].fStyle.weight(), fRecs[i].fStyle.width(), fRecs[i].fStyle.isItalic());
     }
 }
 
@@ -381,74 +379,39 @@
     return NULL;
 }
 
-static bool find_name(const SkTDArray<const char*>& array, const char* name) {
-    for (int i = 0; i < array.count(); ++i) {
-        if (0 == strcmp(array[i], name)) {
-            return true;
-        }
-    }
-    return false;
-}
-
 class SkFontMgr_fontconfig : public SkFontMgr {
     SkAutoTUnref<SkFontConfigInterface> fFCI;
-
-    int fFamilyCount;
-    SkString* fFamilyNames;
+    SkDataTable* fFamilyNames;
 
     void init() {
-        if (fFamilyCount >= 0) {
-            return;
+        if (!fFamilyNames) {
+            fFamilyNames = fFCI->getFamilyNames();
         }
-
-        FcPattern* pat = FcPatternCreate();
-        FcObjectSet* os = FcObjectSetBuild (FC_FAMILY, (char *) 0);
-        FcFontSet* fs = FcFontList(NULL, pat, os);
-
-        SkTDArray<const char*> familyNames;
-        familyNames.setReserve(fs->nfont);
-        for (int i=0; fs && i < fs->nfont; ++i) {
-            FcPattern* match = fs->fonts[i];
-            const char* famName = get_name(match, FC_FAMILY);
-            if (!find_name(familyNames, famName)) {
-                *familyNames.append() = famName;
-            }
-//            SkDebugf("[%d %d] %s %s %x\n", i, fs->nfont, get_name(match, FC_FILE),
-//                     get_name(match, FC_FAMILY), get_name(match, FC_FAMILY));
-        }
-        
-        fFamilyCount = familyNames.count();
-        fFamilyNames = SkNEW_ARRAY(SkString, fFamilyCount);
-        for (int i = 0; i < fFamilyCount; ++i) {
-            fFamilyNames[i].set(familyNames[i]);
-        }
-
-        if (fs) FcFontSetDestroy(fs);
-        FcPatternDestroy(pat);
     }
 
 public:
-    SkFontMgr_fontconfig(SkFontConfigInterface* fci) : fFCI(fci) {
-        fFamilyCount = -1;
-    }
+    SkFontMgr_fontconfig(SkFontConfigInterface* fci)
+        : fFCI(fci)
+        , fFamilyNames(NULL) {}
     
     virtual ~SkFontMgr_fontconfig() {
-        SkDELETE_ARRAY(fFamilyNames);
+        SkSafeUnref(fFamilyNames);
     }
 
 protected:
-    virtual int onCountFamilies() { this->init(); return fFamilyCount; }
+    virtual int onCountFamilies() {
+        this->init();
+        return fFamilyNames->count();
+    }
 
     virtual void onGetFamilyName(int index, SkString* familyName) {
         this->init();
-        SkASSERT((unsigned)index < (unsigned)fFamilyCount);
-        *familyName = fFamilyNames[index];
+        familyName->set(fFamilyNames->atStr(index));
     }
 
     virtual SkFontStyleSet* onCreateStyleSet(int index) {
         this->init();
-        SkASSERT((unsigned)index < (unsigned)fFamilyCount);
-        return this->onMatchFamily(fFamilyNames[index].c_str());
+        return this->onMatchFamily(fFamilyNames->atStr(index));
     }
 
     virtual SkFontStyleSet* onMatchFamily(const char familyName[]) {
@@ -488,12 +451,6 @@
             if (!is_lower(*justName)) {
                 *trimmedMatches.append() = match[i];
             }
-            #if 0
-            printf("[%d:%d] %s %s [%d %d %d]\n", i, count,
-                   get_name(match[i], FC_STYLE), get_name(match[i], FC_FILE),
-                   get_int(match[i], FC_WEIGHT), get_int(match[i], FC_WIDTH),
-                   get_int(match[i], FC_SLANT));
-            #endif
         }
 
         SkFontStyleSet_FC* sset = SkNEW_ARGS(SkFontStyleSet_FC,