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);