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
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 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 @@
     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;
+    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;
     }
-    if (prev) {
-        prev->fNext = next;
-    }
-    if (next) {
-        next->fPrev = prev;
-    }
-    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 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 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 @@
             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 @@
         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 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 @@
 
     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 @@
         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 @@
                                      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 @@
                 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 @@
 
     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 @@
         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];
 }
 
 ///////////////////////////////////////////////////////////////////////////////