aboutsummaryrefslogtreecommitdiffstats
path: root/src/ports
diff options
context:
space:
mode:
authorRussell Brenner <russellbrenner@google.com>2011-07-11 09:49:03 -0700
committerRussell Brenner <russellbrenner@google.com>2011-07-11 11:29:57 -0700
commiteb4843787eb5afdc08871f38de631736d8f3a9f3 (patch)
treef485953a7d2951b18b944b49a11e749d05c41e26 /src/ports
parent8af39c6fd2e903d2b0a2b1b91b295b847a3ec772 (diff)
downloadexternal_skia-eb4843787eb5afdc08871f38de631736d8f3a9f3.zip
external_skia-eb4843787eb5afdc08871f38de631736d8f3a9f3.tar.gz
external_skia-eb4843787eb5afdc08871f38de631736d8f3a9f3.tar.bz2
Revert "Allow multiple styles for fallback fonts"
The change being reverted somehow alters the reference counting of SkTypeface instances, resulting in prematurely freed font data, which is the underlying issue with the disappearing clock on the lockscreen (http://b/5004404). This reverts commit 792a256ab723bbc4b55ba00194fe2a9195cae8c0. Bug: 5004404 Change-Id: I5c3b225f860ce2dcfc0751bded2d842b43a2d3c4
Diffstat (limited to 'src/ports')
-rw-r--r--src/ports/SkFontHost_android.cpp121
1 files changed, 52 insertions, 69 deletions
diff --git a/src/ports/SkFontHost_android.cpp b/src/ports/SkFontHost_android.cpp
index 2b3d976..bccd869 100644
--- a/src/ports/SkFontHost_android.cpp
+++ b/src/ports/SkFontHost_android.cpp
@@ -73,29 +73,17 @@ static FamilyRec* gFamilyHead;
static SkTDArray<NameFamilyPair> gNameList;
struct FamilyRec {
- FamilyRec* fPrev;
FamilyRec* fNext;
SkTypeface* fFaces[4];
FamilyRec()
{
- static FamilyRec* tail = 0;
- if (!gFamilyHead) {
- gFamilyHead = this;
- }
- fPrev = tail;
- fNext = 0;
+ fNext = gFamilyHead;
memset(fFaces, 0, sizeof(fFaces));
- if (tail) {
- tail->fNext = this;
- }
- tail = this;
-// SkDebugf("FamilyRec::FamilyRec(%p) fPrev=%p fNext=%p fFaces=[%p,%p,%p,%p]",
-// this, fPrev, fNext, fFaces[0], fFaces[1], fFaces[2], fFaces[3]);
+ gFamilyHead = this;
}
};
-// Styles are spread across a family. Fallback fonts, as a whole, are treated as one family
static SkTypeface* find_best_face(const FamilyRec* family,
SkTypeface::Style style) {
SkTypeface* const* faces = family->fFaces;
@@ -173,20 +161,26 @@ static FamilyRec* remove_from_family(const SkTypeface* face) {
return family; // return the empty family
}
+// maybe we should make FamilyRec be doubly-linked
static void detach_and_delete_family(FamilyRec* family) {
- FamilyRec* prev = family->fPrev;
- FamilyRec* next = family->fNext;
+ FamilyRec* curr = gFamilyHead;
+ FamilyRec* prev = NULL;
- if (family == gFamilyHead) {
- gFamilyHead = next;
- }
- if (prev) {
- prev->fNext = next;
- }
- if (next) {
- next->fPrev = prev;
+ while (curr != NULL) {
+ FamilyRec* next = curr->fNext;
+ if (curr == family) {
+ if (prev == NULL) {
+ gFamilyHead = next;
+ } else {
+ prev->fNext = next;
+ }
+ SkDELETE(family);
+ return;
+ }
+ prev = curr;
+ curr = next;
}
- SkDELETE(family);
+ SkASSERT(!"Yikes, couldn't find family in our list to remove/delete");
}
static SkTypeface* find_typeface(const char name[], SkTypeface::Style style) {
@@ -371,7 +365,8 @@ private:
///////////////////////////////////////////////////////////////////////////////
static bool get_name_and_style(const char path[], SkString* name,
- SkTypeface::Style* style, bool* isFixedWidth) {
+ SkTypeface::Style* style,
+ bool* isFixedWidth, bool isExpected) {
SkString fullpath;
GetFullPathForSysFonts(&fullpath, path);
@@ -387,7 +382,10 @@ static bool get_name_and_style(const char path[], SkString* name,
return true;
}
}
- SkDebugf("get_name_and_style() failed to open <%s> as a font\n", fullpath.c_str());
+
+ if (isExpected) {
+ SkDebugf("---- failed to open <%s> as a font\n", fullpath.c_str());
+ }
return false;
}
@@ -430,14 +428,11 @@ static const FontInitRec gSystemFonts[] = {
them in the order we want them to be accessed by NextLogicalFont().
*/
{ "DroidSansArabic.ttf", gFBNames },
- { "DroidSansHebrew-Regular.ttf",gFBNames },
- { "DroidSansHebrew-Bold.ttf", NULL },
+ { "DroidSansHebrew.ttf", gFBNames },
{ "DroidSansThai.ttf", gFBNames },
{ "MTLmr3m.ttf", gFBNames }, // Motoya Japanese Font
{ "MTLc3m.ttf", gFBNames }, // Motoya Japanese Font
{ "DroidSansJapanese.ttf", gFBNames },
- { "DroidSansEthiopic-Regular.ttf",gFBNames },
- { "DroidSansEthiopic-Bold.ttf", NULL },
{ "DroidSansFallback.ttf", gFBNames }
};
@@ -447,10 +442,14 @@ static const FontInitRec gSystemFonts[] = {
static FamilyRec* gDefaultFamily;
static SkTypeface* gDefaultNormal;
-/* Fallback fonts are a segment of the linked list that starts at gFamilyHead,
- configured by load_system_fonts().
+/* This is sized conservatively, assuming that it will never be a size issue.
+ It will be initialized in load_system_fonts(), and will be filled with the
+ fontIDs that can be used for fallback consideration, in sorted order (sorted
+ meaning element[0] should be used first, then element[1], etc. When we hit
+ a fontID==0 in the array, the list is done, hence our allocation size is
+ +1 the total number of possible system fonts. Also see NextLogicalFont().
*/
-static FamilyRec* gFallbackHead;
+static uint32_t gFallbackFonts[SK_ARRAY_COUNT(gSystemFonts)+1];
/* Called once (ensured by the sentinel check at the beginning of our body).
Initializes all the globals, and register the system fonts.
@@ -463,6 +462,7 @@ static void load_system_fonts() {
const FontInitRec* rec = gSystemFonts;
SkTypeface* firstInFamily = NULL;
+ int fallbackCount = 0;
for (size_t i = 0; i < SK_ARRAY_COUNT(gSystemFonts); i++) {
// if we're the first in a new family, clear firstInFamily
@@ -475,8 +475,9 @@ static void load_system_fonts() {
SkTypeface::Style style;
// we expect all the fonts, except the "fallback" fonts
- // after one fallback is received, all the rest are fallbacks, too
- if (!get_name_and_style(rec[i].fFileName, &name, &style, &isFixedWidth)) {
+ bool isExpected = (rec[i].fNames != gFBNames);
+ if (!get_name_and_style(rec[i].fFileName, &name, &style,
+ &isFixedWidth, isExpected)) {
continue;
}
@@ -488,10 +489,14 @@ static void load_system_fonts() {
isFixedWidth) // filename
);
-// SkDebugf("load_system_fonts() %s, %d, %d, %d\n",
-// rec[i].fFileName, style, firstInFamily, tf->uniqueID());
-
if (rec[i].fNames != NULL) {
+ // see if this is one of our fallback fonts
+ if (rec[i].fNames == gFBNames) {
+ // SkDebugf("---- adding %s as fallback[%d] fontID %d\n",
+ // rec[i].fFileName, fallbackCount, tf->uniqueID());
+ gFallbackFonts[fallbackCount++] = tf->uniqueID();
+ }
+
firstInFamily = tf;
FamilyRec* family = find_family(tf);
const char* const* names = rec[i].fNames;
@@ -505,20 +510,14 @@ static void load_system_fonts() {
add_name(*names, family);
names += 1;
}
- // see if this is one of our fallback fonts
- if (rec[i].fNames == gFBNames) {
- if (!gFallbackHead) {
- // record the first of the fallback families
- gFallbackHead = family;
- }
- }
-
}
}
// do this after all fonts are loaded. This is our default font, and it
// acts as a sentinel so we only execute load_system_fonts() once
gDefaultNormal = find_best_face(gDefaultFamily, SkTypeface::kNormal);
+ // now terminate our fallback list with the sentinel value
+ gFallbackFonts[fallbackCount] = 0;
}
///////////////////////////////////////////////////////////////////////////////
@@ -583,15 +582,13 @@ SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
if (NULL != familyFace) {
tf = find_typeface(familyFace, style);
-// SkDebugf("SkFontHost::CreateTypeface find_typeface for familyFace returns %p", tf);
} else if (NULL != familyName) {
+// SkDebugf("======= familyName <%s>\n", familyName);
tf = find_typeface(familyName, style);
-// SkDebugf("SkFontHost::CreateTypeface find_typeface for familyName returns %p", tf);
}
if (NULL == tf) {
tf = find_best_face(gDefaultFamily, style);
-// SkDebugf("SkFontHost::CreateTypeface find_best_face for gDefaultFamily returns %p", tf);
}
// we ref(), since the symantic is to return a new instance
@@ -647,27 +644,13 @@ SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
in our list. Note: list is zero-terminated, and returning zero means
we have no more fonts to use for fallbacks.
*/
-
- SkTypeface* origTypeface = find_from_uniqueID(origFontID);
- SkTypeface::Style origStyle = origTypeface ? origTypeface->style() : SkTypeface::kNormal;
-
- FamilyRec* family = gFallbackHead;
- while (family) {
- SkTypeface* typeface = find_best_face(family, origStyle);
- family = family->fNext;
- if (typeface && typeface->uniqueID() == currFontID) {
- if (family) {
- return find_best_face(family, origStyle)->uniqueID();
- } else {
- return 0;
- }
+ const uint32_t* list = gFallbackFonts;
+ for (int i = 0; list[i] != 0; i++) {
+ if (list[i] == currFontID) {
+ return list[i+1];
}
}
-
- if (gFallbackHead) {
- return find_best_face(gFallbackHead, origStyle)->uniqueID();
- }
- return 0;
+ return list[0];
}
///////////////////////////////////////////////////////////////////////////////