Significant cleanup in api, and more importantly in sementics, of SkFontHost
- FindTypeface is now CreateTypeface, and what it returns is always considered
    a new instance, even if it is from a cache (in which case it will have been
    ref()'d. The caller must always balance its ownership by calling unref() on
    the result when they are done.
- CloseStream is gone, since the caller can/must call stream->unref() when they
    are done using it.
- ResolveTypeface is now ValidFontID, and just returns a bool.



git-svn-id: http://skia.googlecode.com/svn/trunk@109 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkTypeface.cpp b/src/core/SkTypeface.cpp
index bb91776..38d0e01 100644
--- a/src/core/SkTypeface.cpp
+++ b/src/core/SkTypeface.cpp
@@ -1,40 +1,42 @@
 #include "SkTypeface.h"
 #include "SkFontHost.h"
 
-static const SkTypeface* resolve_null_typeface(const SkTypeface* face) {
-    if (NULL == face) {
-        face = SkFontHost::FindTypeface(NULL, NULL, SkTypeface::kNormal);
-        SkASSERT(face);
-    }
-    return face;
-}
-
 uint32_t SkTypeface::UniqueID(const SkTypeface* face) {
-    return resolve_null_typeface(face)->uniqueID();
+    if (face) {
+        return face->uniqueID();
+    }
+
+    // We cache the default fontID, assuming it will not change during a boot
+    // The initial value of 0 is fine, since a typeface's uniqueID should not
+    // be zero.
+    static uint32_t gDefaultFontID;
+    
+    if (0 == gDefaultFontID) {
+        SkTypeface* defaultFace = SkFontHost::CreateTypeface(NULL, NULL,
+                                                    SkTypeface::kNormal);
+        SkASSERT(defaultFace);
+        gDefaultFontID = defaultFace->uniqueID();
+        defaultFace->unref();
+    }
+    return gDefaultFontID;
 }
 
 bool SkTypeface::Equal(const SkTypeface* facea, const SkTypeface* faceb) {
-    return resolve_null_typeface(facea)->uniqueID() ==
-           resolve_null_typeface(faceb)->uniqueID();
+    return SkTypeface::UniqueID(facea) == SkTypeface::UniqueID(faceb);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 SkTypeface* SkTypeface::CreateFromName(const char name[], Style style) {
-    SkTypeface* face = SkFontHost::FindTypeface(NULL, name, style);
-    face->ref();
-    return face;
+    return SkFontHost::CreateTypeface(NULL, name, style);
 }
 
 SkTypeface* SkTypeface::CreateFromTypeface(const SkTypeface* family, Style s) {
-    family = resolve_null_typeface(family);
-    SkTypeface* face = SkFontHost::FindTypeface(family, NULL, s);
-    face->ref();
-    return face;
+    return SkFontHost::CreateTypeface(family, NULL, s);
 }
 
 SkTypeface* SkTypeface::CreateFromStream(SkStream* stream) {
-    return SkFontHost::CreateTypeface(stream);
+    return SkFontHost::CreateTypefaceFromStream(stream);
 }
 
 SkTypeface* SkTypeface::CreateFromFile(const char path[]) {
diff --git a/src/ports/SkFontHost_FONTPATH.cpp b/src/ports/SkFontHost_FONTPATH.cpp
index 84ff664..ceab395 100644
--- a/src/ports/SkFontHost_FONTPATH.cpp
+++ b/src/ports/SkFontHost_FONTPATH.cpp
@@ -239,9 +239,9 @@
     return (uint32_t)((char*)p - (char*)0);
 }
 
-SkTypeface* SkFontHost::FindTypeface(const SkTypeface* familyFace,
-                                     const char familyName[],
-                                     SkTypeface::Style style)
+SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
+                                       const char familyName[],
+                                       SkTypeface::Style style)
 {
     const FontFamilyRec* family;
     
@@ -268,7 +268,7 @@
     return SkNEW_ARGS(FontFaceRec_Typeface, (face));
 }
 
-SkTypeface* SkFontHost::CreateTypeface(SkStream* stream) {
+SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
     sk_throw();  // not implemented
     return NULL;
 }
@@ -278,10 +278,8 @@
     return NULL;
 }
 
-SkTypeface* SkFontHost::ResolveTypeface(uint32_t fontID) {
-    // TODO: this should just return a bool if fontID is valid
-    // since we don't keep a global-list, this will leak at the moment
-    return new FontFaceRec_Typeface(*get_default_face());
+bool SkFontHost::ValidFontID(uint32_t fontID) {
+    return get_id(*get_default_face()) == fontID;
 }
 
 SkStream* SkFontHost::OpenStream(uint32_t fontID) {
@@ -289,10 +287,6 @@
     return NULL;
 }
 
-void SkFontHost::CloseStream(uint32_t fontID, SkStream* stream) {
-    // not implemented
-}
-
 void SkFontHost::Serialize(const SkTypeface* tface, SkWStream* stream) {
     const FontFaceRec* face = &((const FontFaceRec_Typeface*)tface)->fFace;
     stream->write(face, sizeof(face));
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp
index 742a861..a241e38 100644
--- a/src/ports/SkFontHost_FreeType.cpp
+++ b/src/ports/SkFontHost_FreeType.cpp
@@ -102,9 +102,10 @@
     uint32_t        fRefCnt;
     uint32_t        fFontID;
 
+    // assumes ownership of the stream, will call unref() when its done
     SkFaceRec(SkStream* strm, uint32_t fontID);
     ~SkFaceRec() {
-        SkFontHost::CloseStream(fFontID, fSkStream);
+        fSkStream->unref();
     }
 };
 
@@ -387,7 +388,7 @@
         killing all of the contexts when we know that a given fontID is going
         away...
      */
-    if (SkFontHost::ResolveTypeface(fRec.fFontID) == NULL) {
+    if (!SkFontHost::ValidFontID(fRec.fFontID)) {
         return (FT_Error)-1;
     }
 
diff --git a/src/ports/SkFontHost_android.cpp b/src/ports/SkFontHost_android.cpp
index 1cd2e3b..21ed0b7 100644
--- a/src/ports/SkFontHost_android.cpp
+++ b/src/ports/SkFontHost_android.cpp
@@ -127,7 +127,10 @@
     return NULL;
 }
 
-static SkTypeface* resolve_uniqueID(uint32_t uniqueID)
+/*  Returns the matching typeface, or NULL. If a typeface is found, its refcnt
+    is not modified.
+ */
+static SkTypeface* find_from_uniqueID(uint32_t uniqueID)
 {
     FamilyRec* curr = gFamilyHead;
     while (curr != NULL) {
@@ -275,7 +278,6 @@
     bool isSysFont() const { return fIsSysFont; }
     
     virtual SkStream* openStream() = 0;
-    virtual void closeStream(SkStream*) = 0;
     virtual const char* getUniqueString() const = 0;
     
 private:
@@ -292,16 +294,21 @@
                    SkStream* stream)
         : INHERITED(style, sysFont, familyMember)
     {
+        SkASSERT(stream);
+        stream->ref();
         fStream = stream;
     }
-    virtual ~StreamTypeface()
-    {
-        SkDELETE(fStream);
+    virtual ~StreamTypeface() {
+        fStream->unref();
     }
     
     // overrides
-    virtual SkStream* openStream() { return fStream; }
-    virtual void closeStream(SkStream*) {}
+    virtual SkStream* openStream() {
+        // we just ref our existing stream, since the caller will call unref()
+        // when they are through
+        fStream->ref();
+        return fStream;
+    }
     virtual const char* getUniqueString() const { return NULL; }
 
 private:
@@ -342,10 +349,6 @@
         }
         return stream;
     }
-    virtual void closeStream(SkStream* stream)
-    {
-        SkDELETE(stream);
-    }
     virtual const char* getUniqueString() const {
         const char* str = strrchr(fPath.c_str(), '/');
         if (str) {
@@ -495,7 +498,7 @@
 void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
     const char* name = ((FamilyTypeface*)face)->getUniqueString();
 
-    stream->write8((uint8_t)face->getStyle());
+    stream->write8((uint8_t)face->style());
 
     if (NULL == name || 0 == *name) {
         stream->writePackedUInt(0);
@@ -504,7 +507,7 @@
         uint32_t len = strlen(name);
         stream->writePackedUInt(len);
         stream->write(name, len);
-//      SkDebugf("--- fonthost serialize <%s> %d\n", name, face->getStyle());
+//      SkDebugf("--- fonthost serialize <%s> %d\n", name, face->style());
     }
 }
 
@@ -525,21 +528,21 @@
                 // backup until we hit the fNames
                 for (int j = i; j >= 0; --j) {
                     if (rec[j].fNames != NULL) {
-                        return SkFontHost::FindTypeface(NULL, rec[j].fNames[0],
-                                                    (SkTypeface::Style)style);
+                        return SkFontHost::CreateTypeface(NULL,
+                                    rec[j].fNames[0], (SkTypeface::Style)style);
                     }
                 }
             }
         }
     }
-    return SkFontHost::FindTypeface(NULL, NULL, (SkTypeface::Style)style);
+    return SkFontHost::CreateTypeface(NULL, NULL, (SkTypeface::Style)style);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkTypeface* SkFontHost::FindTypeface(const SkTypeface* familyFace,
-                                     const char familyName[],
-                                     SkTypeface::Style style)
+SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
+                                       const char familyName[],
+                                       SkTypeface::Style style)
 {
     load_system_fonts();
 
@@ -564,34 +567,25 @@
     return tf;
 }
 
-SkTypeface* SkFontHost::ResolveTypeface(uint32_t fontID)
+bool SkFontHost::ValidFontID(uint32_t fontID)
 {
     SkAutoMutexAcquire  ac(gFamilyMutex);
     
-    return resolve_uniqueID(fontID);
+    return find_from_uniqueID(fontID) != NULL;
 }
 
 SkStream* SkFontHost::OpenStream(uint32_t fontID)
 {
-    
-    FamilyTypeface* tf = (FamilyTypeface*)SkFontHost::ResolveTypeface(fontID);
+    FamilyTypeface* tf = (FamilyTypeface*)find_from_uniqueID(fontID);
     SkStream* stream = tf ? tf->openStream() : NULL;
 
-    if (NULL == stream || stream->getLength() == 0) {
-        delete stream;
+    if (stream && stream->getLength() == 0) {
+        stream->unref();
         stream = NULL;
     }
     return stream;
 }
 
-void SkFontHost::CloseStream(uint32_t fontID, SkStream* stream)
-{
-    FamilyTypeface* tf = (FamilyTypeface*)SkFontHost::ResolveTypeface(fontID);
-    if (NULL != tf) {
-        tf->closeStream(stream);
-    }
-}
-
 SkScalerContext* SkFontHost::CreateFallbackScalerContext(
                                                 const SkScalerContext::Rec& rec)
 {
@@ -612,10 +606,9 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkTypeface* SkFontHost::CreateTypeface(SkStream* stream)
+SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream)
 {
     if (NULL == stream || stream->getLength() <= 0) {
-        SkDELETE(stream);
         return NULL;
     }
     
@@ -627,7 +620,11 @@
 
 SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[])
 {
-    return SkFontHost::CreateTypeface(SkNEW_ARGS(SkMMAPStream, (path)));
+    SkStream* stream = SkNEW_ARGS(SkMMAPStream, (path));
+    SkTypeface* face = SkFontHost::CreateTypefaceFromStream(stream);
+    // since we created the stream, we let go of our ref() here
+    stream->unref();
+    return face;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/src/ports/SkFontHost_linux.cpp b/src/ports/SkFontHost_linux.cpp
index a7cda52..0c69126 100644
--- a/src/ports/SkFontHost_linux.cpp
+++ b/src/ports/SkFontHost_linux.cpp
@@ -125,18 +125,18 @@
     return NULL;
 }
 
-static SkTypeface* resolve_uniqueID(uint32_t uniqueID) {
+static bool valid_uniqueID(uint32_t uniqueID) {
     FamilyRec* curr = gFamilyHead;
     while (curr != NULL) {
         for (int i = 0; i < 4; i++) {
             SkTypeface* face = curr->fFaces[i];
             if (face != NULL && face->uniqueID() == uniqueID) {
-                return face;
+                return true;
             }
         }
         curr = curr->fNext;
     }
-    return NULL;
+    return false;
 }
 
 /*  Remove reference to this face from its family. If the resulting family
@@ -476,14 +476,14 @@
                 // backup until we hit the fNames
                 for (int j = i; j >= 0; --j) {
                     if (rec[j].fNames != NULL) {
-                        return SkFontHost::FindTypeface(NULL, rec[j].fNames[0],
-                                                        (SkTypeface::Style)style);
+                        return SkFontHost::CreateTypeface(NULL, rec[j].fNames[0],
+                                                          (SkTypeface::Style)style);
                     }
                 }
             }
         }
     }
-    return SkFontHost::FindTypeface(NULL, NULL, (SkTypeface::Style)style);
+    return SkFontHost::CreateTypeface(NULL, NULL, (SkTypeface::Style)style);
 #endif
     sk_throw();
     return NULL;
@@ -491,9 +491,9 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkTypeface* SkFontHost::FindTypeface(const SkTypeface* familyFace,
-                                     const char familyName[],
-                                     SkTypeface::Style style) {
+SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
+                                       const char familyName[],
+                                       SkTypeface::Style style) {
     load_system_fonts();
     
     SkAutoMutexAcquire  ac(gFamilyMutex);
@@ -517,10 +517,10 @@
     return tf;
 }
 
-SkTypeface* SkFontHost::ResolveTypeface(uint32_t fontID) {
+SkTypeface* SkFontHost::ValidFontID(uint32_t fontID) {
     SkAutoMutexAcquire  ac(gFamilyMutex);
     
-    return resolve_uniqueID(fontID);
+    return valid_uniqueID(fontID);
 }
 
 SkStream* SkFontHost::OpenStream(uint32_t fontID) {
@@ -560,7 +560,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-SkTypeface* SkFontHost::CreateTypeface(SkStream* stream) {
+SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
     if (NULL == stream || stream->getLength() <= 0) {
         SkDELETE(stream);
         return NULL;
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index 969808e..f0e3a93 100755
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -484,7 +484,7 @@
     return NULL;
 }
 
-SkTypeface* SkFontHost::CreateTypeface(SkStream* stream) {
+SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
     
     //Should not be used on Mac, keep linker happy
     SkASSERT(false);
@@ -517,17 +517,8 @@
     return SkFontHost::CreateScalerContext(desc);
 }
 
-
-    /** Return the closest matching typeface given either an existing family
-        (specified by a typeface in that family) or by a familyName, and a
-        requested style.
-        1) If familyFace is null, use famillyName.
-        2) If famillyName is null, use familyFace.
-        3) If both are null, return the default font that best matches style
-        This MUST not return NULL.
-    */
-
-SkTypeface* SkFontHost::FindTypeface(const SkTypeface* familyFace, const char familyName[], SkTypeface::Style style) {
+SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
+                            const char familyName[], SkTypeface::Style style) {
     
     SkAutoMutexAcquire  ac(gFTMutex);
     
diff --git a/src/ports/SkFontHost_none.cpp b/src/ports/SkFontHost_none.cpp
index 09854ae..608ee29 100644
--- a/src/ports/SkFontHost_none.cpp
+++ b/src/ports/SkFontHost_none.cpp
@@ -15,28 +15,14 @@
 
 #include "SkFontHost.h"
 
-SkTypeface* SkFontHost::FindTypeface(const SkTypeface* familyFace,
+SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
                                      const char famillyName[],
                                      SkTypeface::Style style) {
     SkASSERT(!"SkFontHost::FindTypeface unimplemented");
     return NULL;
 }
 
-SkTypeface* SkFontHost::ResolveTypeface(uint32_t uniqueID) {
-    SkASSERT(!"SkFontHost::ResolveTypeface unimplemented");
-    return NULL;
-}
-
-SkStream* SkFontHost::OpenStream(uint32_t uniqueID) {
-    SkASSERT(!"SkFontHost::OpenStream unimplemented");
-    return NULL;
-}
-
-void SkFontHost::CloseStream(uint32_t uniqueID, SkStream*) {
-    SkASSERT(!"SkFontHost::CloseStream unimplemented");
-}
-
-SkTypeface* SkFontHost::CreateTypeface(SkStream*) {
+SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream*) {
     SkASSERT(!"SkFontHost::CreateTypeface unimplemented");
     return NULL;
 }
@@ -48,6 +34,18 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
+bool SkFontHost::ValidFontID(uint32_t uniqueID) {
+    SkASSERT(!"SkFontHost::ResolveTypeface unimplemented");
+    return false;
+}
+
+SkStream* SkFontHost::OpenStream(uint32_t uniqueID) {
+    SkASSERT(!"SkFontHost::OpenStream unimplemented");
+    return NULL;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
 void SkFontHost::Serialize(const SkTypeface* face, SkWStream* stream) {
     SkASSERT(!"SkFontHost::Serialize unimplemented");
 }
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index c2ee51e..4cc04b5 100644
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -482,7 +482,7 @@
     return NULL;

 }

 

-SkTypeface* SkFontHost::CreateTypeface(SkStream* stream) {

+SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {

     

     //Should not be used on Windows, keep linker happy

     SkASSERT(false);

@@ -521,7 +521,8 @@
  This MUST not return NULL.

  */

 

-SkTypeface* SkFontHost::FindTypeface(const SkTypeface* familyFace, const char familyName[], SkTypeface::Style style) {

+SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,

+                            const char familyName[], SkTypeface::Style style) {

     

     SkAutoMutexAcquire  ac(gFTMutex);