Remove requestedStyle from SkTypefaceCache.

The typeface cache contains typefaces which can be compared against to
determine if an already known typeface will work instead of creating a
new typeface id. This is primarily for sharing scaler contexts. How that
typeface was requested is not relevant to this comparison, so don't cache
it. Request caching must be handled separately.

GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1879423002

Review URL: https://codereview.chromium.org/1879423002
diff --git a/src/core/SkTypefaceCache.cpp b/src/core/SkTypefaceCache.cpp
index faf3978..05a7a8e 100644
--- a/src/core/SkTypefaceCache.cpp
+++ b/src/core/SkTypefaceCache.cpp
@@ -15,46 +15,29 @@
 
 SkTypefaceCache::SkTypefaceCache() {}
 
-SkTypefaceCache::~SkTypefaceCache() {
-    const Rec* curr = fArray.begin();
-    const Rec* stop = fArray.end();
-    while (curr < stop) {
-        curr->fFace->unref();
-        curr += 1;
-    }
-}
-
-void SkTypefaceCache::add(SkTypeface* face, const SkFontStyle& requestedStyle) {
-    if (fArray.count() >= TYPEFACE_CACHE_LIMIT) {
+void SkTypefaceCache::add(SkTypeface* face) {
+    if (fTypefaces.count() >= TYPEFACE_CACHE_LIMIT) {
         this->purge(TYPEFACE_CACHE_LIMIT >> 2);
     }
 
-    Rec* rec = fArray.append();
-    rec->fFace = SkRef(face);
-    rec->fRequestedStyle = requestedStyle;
+    fTypefaces.emplace_back(SkRef(face));
 }
 
 SkTypeface* SkTypefaceCache::findByProcAndRef(FindProc proc, void* ctx) const {
-    const Rec* curr = fArray.begin();
-    const Rec* stop = fArray.end();
-    while (curr < stop) {
-        SkTypeface* currFace = curr->fFace;
-        if (proc(currFace, curr->fRequestedStyle, ctx)) {
-            return SkRef(currFace);
+    for (const sk_sp<SkTypeface>& typeface : fTypefaces) {
+        if (proc(typeface.get(), ctx)) {
+            return SkRef(typeface.get());
         }
-        curr += 1;
     }
     return nullptr;
 }
 
 void SkTypefaceCache::purge(int numToPurge) {
-    int count = fArray.count();
+    int count = fTypefaces.count();
     int i = 0;
     while (i < count) {
-        SkTypeface* face = fArray[i].fFace;
-        if (face->unique()) {
-            face->unref();
-            fArray.remove(i);
+        if (fTypefaces[i]->unique()) {
+            fTypefaces.removeShuffle(i);
             --count;
             if (--numToPurge == 0) {
                 return;
@@ -66,7 +49,7 @@
 }
 
 void SkTypefaceCache::purgeAll() {
-    this->purge(fArray.count());
+    this->purge(fTypefaces.count());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -83,15 +66,14 @@
 
 SK_DECLARE_STATIC_MUTEX(gMutex);
 
-void SkTypefaceCache::Add(SkTypeface* face, const SkFontStyle& requestedStyle) {
+void SkTypefaceCache::Add(SkTypeface* face) {
     SkAutoMutexAcquire ama(gMutex);
-    Get().add(face, requestedStyle);
+    Get().add(face);
 }
 
 SkTypeface* SkTypefaceCache::FindByProcAndRef(FindProc proc, void* ctx) {
     SkAutoMutexAcquire ama(gMutex);
-    SkTypeface* typeface = Get().findByProcAndRef(proc, ctx);
-    return typeface;
+    return Get().findByProcAndRef(proc, ctx);
 }
 
 void SkTypefaceCache::PurgeAll() {
@@ -102,16 +84,19 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 #ifdef SK_DEBUG
-static bool DumpProc(SkTypeface* face, const SkFontStyle& s, void* ctx) {
-    SkDebugf("SkTypefaceCache: face %p fontID %d weight %d width %d style %d refcnt %d\n",
-             face, face->uniqueID(), s.weight(), s.width(), s.slant(), face->getRefCnt());
+static bool DumpProc(SkTypeface* face, void* ctx) {
+    SkString n;
+    face->getFamilyName(&n);
+    SkFontStyle s = face->fontStyle();
+    SkFontID id = face->uniqueID();
+    SkDebugf("SkTypefaceCache: face %p fontID %d weight %d width %d style %d refcnt %d name %s\n",
+             face, id, s.weight(), s.width(), s.slant(), face->getRefCnt(), n.c_str());
     return false;
 }
 #endif
 
 void SkTypefaceCache::Dump() {
 #ifdef SK_DEBUG
-    SkAutoMutexAcquire ama(gMutex);
     (void)Get().findByProcAndRef(DumpProc, nullptr);
 #endif
 }
diff --git a/src/core/SkTypefaceCache.h b/src/core/SkTypefaceCache.h
index bb2cb85..bf90dae 100644
--- a/src/core/SkTypefaceCache.h
+++ b/src/core/SkTypefaceCache.h
@@ -10,27 +10,20 @@
 #ifndef SkTypefaceCache_DEFINED
 #define SkTypefaceCache_DEFINED
 
+#include "SkRefCnt.h"
 #include "SkTypeface.h"
-#include "SkTDArray.h"
-
-/*  TODO
- *  Provide std way to cache name+requestedStyle aliases to the same typeface.
- *
- *  The current mechanism ends up create a diff typeface for each one, even if
- *  they map to the same internal obj (e.g. CTFontRef on the mac)
- */
+#include "SkTArray.h"
 
 class SkTypefaceCache {
 public:
     SkTypefaceCache();
-    ~SkTypefaceCache();
 
     /**
      * Callback for FindByProc. Returns true if the given typeface is a match
      * for the given context. The passed typeface is owned by the cache and is
      * not additionally ref()ed. The typeface may be in the disposed state.
      */
-    typedef bool(*FindProc)(SkTypeface*, const SkFontStyle&, void* context);
+    typedef bool(*FindProc)(SkTypeface*, void* context);
 
     /**
      *  Add a typeface to the cache. This ref()s the typeface, so that the
@@ -38,7 +31,7 @@
      *  whose refcnt is 1 (meaning only the cache is an owner) will be
      *  unref()ed.
      */
-    void add(SkTypeface*, const SkFontStyle& requested);
+    void add(SkTypeface*);
 
     /**
      *  Iterate through the cache, calling proc(typeface, ctx) with each
@@ -63,7 +56,7 @@
 
     // These are static wrappers around a global instance of a cache.
 
-    static void Add(SkTypeface*, const SkFontStyle& requested);
+    static void Add(SkTypeface*);
     static SkTypeface* FindByProcAndRef(FindProc proc, void* ctx);
     static void PurgeAll();
 
@@ -77,11 +70,7 @@
 
     void purge(int count);
 
-    struct Rec {
-        SkTypeface* fFace;
-        SkFontStyle fRequestedStyle;
-    };
-    SkTDArray<Rec> fArray;
+    SkTArray<sk_sp<SkTypeface>> fTypefaces;
 };
 
 #endif
diff --git a/src/ports/SkFontHost_fontconfig.cpp b/src/ports/SkFontHost_fontconfig.cpp
index 0ed8d8f..1394efd 100644
--- a/src/ports/SkFontHost_fontconfig.cpp
+++ b/src/ports/SkFontHost_fontconfig.cpp
@@ -58,7 +58,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-static bool find_by_FontIdentity(SkTypeface* cachedTypeface, const SkFontStyle&, void* ctx) {
+static bool find_by_FontIdentity(SkTypeface* cachedTypeface, void* ctx) {
     typedef SkFontConfigInterface::FontIdentity FontIdentity;
     FontConfigTypeface* cachedFCTypeface = static_cast<FontConfigTypeface*>(cachedTypeface);
     FontIdentity* identity = static_cast<FontIdentity*>(ctx);
@@ -196,7 +196,7 @@
     if (!face) {
         face = FontConfigTypeface::Create(outStyle, identity, outFamilyName);
         // Add this FontIdentity to the FontIdentity cache.
-        SkTypefaceCache::Add(face, outStyle);
+        SkTypefaceCache::Add(face);
     }
     // Add this request to the request cache.
     SkFontHostRequestCache::Add(face, request.release());
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index 049d08b..02c5464 100644
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -486,7 +486,7 @@
     return new SkTypeface_Mac(fontRef, resourceRef, style, isFixedPitch, isLocalStream);
 }
 
-static bool find_by_CTFontRef(SkTypeface* cached, const SkFontStyle&, void* context) {
+static bool find_by_CTFontRef(SkTypeface* cached, void* context) {
     CTFontRef self = (CTFontRef)context;
     CTFontRef other = ((SkTypeface_Mac*)cached)->fFontRef;
 
@@ -546,7 +546,7 @@
         return face;
     }
     face = NewFromFontRef(ctFont.release(), nullptr, false);
-    SkTypefaceCache::Add(face, face->fontStyle());
+    SkTypefaceCache::Add(face);
     return face;
 }
 
@@ -583,7 +583,7 @@
         CFRetain(resourceRef);
     }
     face = NewFromFontRef(fontRef, resourceRef, false);
-    SkTypefaceCache::Add(face, face->fontStyle());
+    SkTypefaceCache::Add(face);
     return face;
 }
 
@@ -2166,7 +2166,7 @@
     }
 
     face = NewFromFontRef(ctFont.release(), nullptr, false);
-    SkTypefaceCache::Add(face, face->fontStyle());
+    SkTypefaceCache::Add(face);
     return face;
 }
 
diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp
index c9781ba..5ded39c 100644
--- a/src/ports/SkFontHost_win.cpp
+++ b/src/ports/SkFontHost_win.cpp
@@ -308,13 +308,11 @@
     return gDefaultFont;
 }
 
-static bool FindByLogFont(SkTypeface* face, const SkFontStyle& requestedStyle, void* ctx) {
+static bool FindByLogFont(SkTypeface* face, void* ctx) {
     LogFontTypeface* lface = static_cast<LogFontTypeface*>(face);
     const LOGFONT* lf = reinterpret_cast<const LOGFONT*>(ctx);
 
-    return lface &&
-           get_style(lface->fLogFont) == requestedStyle &&
-           !memcmp(&lface->fLogFont, lf, sizeof(LOGFONT));
+    return !memcmp(&lface->fLogFont, lf, sizeof(LOGFONT));
 }
 
 /**
@@ -327,7 +325,7 @@
     SkTypeface* face = SkTypefaceCache::FindByProcAndRef(FindByLogFont, &lf);
     if (nullptr == face) {
         face = LogFontTypeface::Create(lf);
-        SkTypefaceCache::Add(face, get_style(lf));
+        SkTypefaceCache::Add(face);
     }
     return face;
 }
diff --git a/src/ports/SkFontMgr_fontconfig.cpp b/src/ports/SkFontMgr_fontconfig.cpp
index b672f43..4b26f41 100644
--- a/src/ports/SkFontMgr_fontconfig.cpp
+++ b/src/ports/SkFontMgr_fontconfig.cpp
@@ -605,7 +605,7 @@
                                           sizes.begin(), names.count());
     }
 
-    static bool FindByFcPattern(SkTypeface* cached, const SkFontStyle&, void* ctx) {
+    static bool FindByFcPattern(SkTypeface* cached, void* ctx) {
         SkTypeface_fontconfig* cshFace = static_cast<SkTypeface_fontconfig*>(cached);
         FcPattern* ctxPattern = static_cast<FcPattern*>(ctx);
         return FcTrue == FcPatternEqual(cshFace->fPattern, ctxPattern);
@@ -624,7 +624,7 @@
             FcPatternReference(pattern);
             face = SkTypeface_fontconfig::Create(pattern);
             if (face) {
-                fTFCache.add(face, SkFontStyle());
+                fTFCache.add(face);
             }
         }
         return face;
diff --git a/src/ports/SkFontMgr_win_dw.cpp b/src/ports/SkFontMgr_win_dw.cpp
index a03fcf8..e178598 100644
--- a/src/ports/SkFontMgr_win_dw.cpp
+++ b/src/ports/SkFontMgr_win_dw.cpp
@@ -353,7 +353,7 @@
     IDWriteFontFamily* fDWriteFontFamily;
 };
 
-static bool FindByDWriteFont(SkTypeface* cached, const SkFontStyle&, void* ctx) {
+static bool FindByDWriteFont(SkTypeface* cached, void* ctx) {
     DWriteFontTypeface* cshFace = reinterpret_cast<DWriteFontTypeface*>(cached);
     ProtoDWriteTypeface* ctxFace = reinterpret_cast<ProtoDWriteTypeface*>(ctx);
     bool same;
@@ -457,7 +457,7 @@
     if (nullptr == face) {
         face = DWriteFontTypeface::Create(fFactory.get(), fontFace, font, fontFamily);
         if (face) {
-            fTFCache.add(face, get_style(font));
+            fTFCache.add(face);
         }
     }
     return face;
diff --git a/tests/TypefaceTest.cpp b/tests/TypefaceTest.cpp
index b3bc157..130cabf 100644
--- a/tests/TypefaceTest.cpp
+++ b/tests/TypefaceTest.cpp
@@ -5,7 +5,9 @@
  * found in the LICENSE file.
  */
 
+#include "SkRefCnt.h"
 #include "SkTypeface.h"
+#include "SkTypefaceCache.h"
 #include "Test.h"
 
 DEF_TEST(Typeface, reporter) {
@@ -24,3 +26,68 @@
     REPORTER_ASSERT(reporter, nullptr == t3.get());
 #endif
 }
+
+class SkEmptyTypeface : public SkTypeface {
+public:
+    static sk_sp<SkTypeface> Create(SkFontID id) { return sk_sp<SkTypeface>(new SkEmptyTypeface(id)); }
+protected:
+    SkEmptyTypeface(SkFontID id) : SkTypeface(SkFontStyle(), id, true) { }
+
+    SkStreamAsset* onOpenStream(int* ttcIndex) const override { return nullptr; }
+    SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
+                                           const SkDescriptor*) const override {
+        return nullptr;
+    }
+    void onFilterRec(SkScalerContextRec*) const override { }
+    virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
+                                PerGlyphInfo,
+                                const uint32_t*, uint32_t) const override { return nullptr; }
+    void onGetFontDescriptor(SkFontDescriptor*, bool*) const override { }
+    virtual int onCharsToGlyphs(const void* chars, Encoding encoding,
+                                uint16_t glyphs[], int glyphCount) const override {
+        SK_ABORT("unimplemented");
+        return 0;
+    }
+    int onCountGlyphs() const override { return 0; };
+    int onGetUPEM() const override { return 0; };
+    void onGetFamilyName(SkString* familyName) const override { familyName->reset(); }
+    SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override {
+        SK_ABORT("unimplemented");
+        return nullptr;
+    };
+    int onGetTableTags(SkFontTableTag tags[]) const override { return 0; }
+    size_t onGetTableData(SkFontTableTag, size_t, size_t, void*) const override { return 0; }
+};
+
+static bool count_proc(SkTypeface* face, void* ctx) {
+    int* count = static_cast<int*>(ctx);
+    *count = *count + 1;
+    return false;
+}
+static int count(skiatest::Reporter* reporter, const SkTypefaceCache& cache) {
+    int count = 0;
+    SkTypeface* none = cache.findByProcAndRef(count_proc, &count);
+    REPORTER_ASSERT(reporter, none == nullptr);
+    return count;
+}
+
+DEF_TEST(TypefaceCache, reporter) {
+    sk_sp<SkTypeface> t1(SkEmptyTypeface::Create(1));
+    {
+        SkTypefaceCache cache;
+        REPORTER_ASSERT(reporter, count(reporter, cache) == 0);
+        {
+            sk_sp<SkTypeface> t0(SkEmptyTypeface::Create(0));
+            cache.add(t0.get());
+            REPORTER_ASSERT(reporter, count(reporter, cache) == 1);
+            cache.add(t1.get());
+            REPORTER_ASSERT(reporter, count(reporter, cache) == 2);
+            cache.purgeAll();
+            REPORTER_ASSERT(reporter, count(reporter, cache) == 2);
+        }
+        REPORTER_ASSERT(reporter, count(reporter, cache) == 2);
+        cache.purgeAll();
+        REPORTER_ASSERT(reporter, count(reporter, cache) == 1);
+    }
+    REPORTER_ASSERT(reporter, t1->unique());
+}