Fixing the cache

Change-Id: Ief6ce50095c73498307748d30608100c10790746
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/264399
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Julia Lavrova <jlavrova@google.com>
diff --git a/modules/skparagraph/src/ParagraphCache.cpp b/modules/skparagraph/src/ParagraphCache.cpp
index 05d951c..af35d5d 100644
--- a/modules/skparagraph/src/ParagraphCache.cpp
+++ b/modules/skparagraph/src/ParagraphCache.cpp
@@ -9,12 +9,12 @@
 public:
     ParagraphCacheKey(const ParagraphImpl* paragraph)
         : fText(paragraph->fText.c_str(), paragraph->fText.size())
-        , fResolvedFonts(paragraph->resolvedFonts())
+        , fPlaceholders(paragraph->fPlaceholders)
         , fTextStyles(paragraph->fTextStyles)
         , fParagraphStyle(paragraph->paragraphStyle()) { }
 
     SkString fText;
-    SkTArray<ResolvedFontDescriptor> fResolvedFonts;
+    SkTArray<Placeholder, true> fPlaceholders;
     SkTArray<Block, true> fTextStyles;
     ParagraphStyle fParagraphStyle;
 };
@@ -47,25 +47,29 @@
 }
 uint32_t ParagraphCache::KeyHash::operator()(const ParagraphCacheKey& key) const {
     uint32_t hash = 0;
-    for (auto& fd : key.fResolvedFonts) {
-        hash = mix(hash, SkGoodHash()(fd.fTextStart));
-        hash = mix(hash, SkGoodHash()(fd.fFont.getSize()));
-
-        if (fd.fFont.getTypeface() != nullptr) {
-            SkString name;
-            fd.fFont.getTypeface()->getFamilyName(&name);
-            hash = mix(hash, SkGoodHash()(name));
-            hash = mix(hash, SkGoodHash()(fd.fFont.getTypeface()->fontStyle()));
-        }
+    for (auto& ph : key.fPlaceholders) {
+        hash = mix(hash, SkGoodHash()(ph.fRange.start));
+        hash = mix(hash, SkGoodHash()(ph.fRange.end));
+        hash = mix(hash, SkGoodHash()(ph.fStyle.fBaselineOffset));
+        hash = mix(hash, SkGoodHash()(ph.fStyle.fBaseline));
+        hash = mix(hash, SkGoodHash()(ph.fStyle.fAlignment));
+        hash = mix(hash, SkGoodHash()(ph.fStyle.fHeight));
+        hash = mix(hash, SkGoodHash()(ph.fStyle.fWidth));
     }
     for (auto& ts : key.fTextStyles) {
-        if (!ts.fStyle.isPlaceholder()) {
-            hash = mix(hash, SkGoodHash()(ts.fStyle.getLetterSpacing()));
-            hash = mix(hash, SkGoodHash()(ts.fStyle.getWordSpacing()));
-            hash = mix(hash, SkGoodHash()(ts.fRange));
-        } else {
-            // TODO: cache placeholders
+        if (ts.fStyle.isPlaceholder()) {
+            continue;
         }
+        hash = mix(hash, SkGoodHash()(ts.fStyle.getLetterSpacing()));
+        hash = mix(hash, SkGoodHash()(ts.fStyle.getWordSpacing()));
+        hash = mix(hash, SkGoodHash()(ts.fRange));
+        for (auto& ff : ts.fStyle.getFontFamilies()) {
+            hash = mix(hash, SkGoodHash()(ff));
+        }
+        hash = mix(hash, SkGoodHash()(ts.fStyle.getFontStyle()));
+        hash = mix(hash, SkGoodHash()(ts.fStyle.getFontSize()));
+        hash = mix(hash, SkGoodHash()(ts.fRange.start));
+        hash = mix(hash, SkGoodHash()(ts.fRange.end));
     }
     hash = mix(hash, SkGoodHash()(key.fText));
     return hash;
@@ -75,7 +79,7 @@
     if (a.fText.size() != b.fText.size()) {
         return false;
     }
-    if (a.fResolvedFonts.count() != b.fResolvedFonts.count()) {
+    if (a.fPlaceholders.count() != b.fPlaceholders.count()) {
         return false;
     }
     if (a.fText != b.fText) {
@@ -89,39 +93,33 @@
         // This is too strong, but at least we will not lose lines
         return false;
     }
-
-    for (size_t i = 0; i < a.fResolvedFonts.size(); ++i) {
-        auto& fda = a.fResolvedFonts[i];
-        auto& fdb = b.fResolvedFonts[i];
-        if (fda.fTextStart != fdb.fTextStart) {
-            return false;
-        }
-        if (fda.fFont != fdb.fFont) {
-            return false;
-        }
-    }
-
     for (size_t i = 0; i < a.fTextStyles.size(); ++i) {
         auto& tsa = a.fTextStyles[i];
         auto& tsb = b.fTextStyles[i];
-        if (!(tsa.fStyle == tsb.fStyle)) {
+        if (tsa.fStyle.isPlaceholder()) {
+            continue;
+        }
+        if (!(tsa.fStyle.equalsByFonts(tsb.fStyle))) {
             return false;
         }
-        if (!tsa.fStyle.isPlaceholder()) {
-            if (tsa.fStyle.getLetterSpacing() != tsb.fStyle.getLetterSpacing()) {
-                return false;
-            }
-            if (tsa.fStyle.getWordSpacing() != tsb.fStyle.getWordSpacing()) {
-                return false;
-            }
-            if (tsa.fRange.width() != tsb.fRange.width()) {
-                return false;
-            }
-            if (tsa.fRange.start != tsb.fRange.start) {
-                return false;
-            }
-        } else {
-            // TODO: compare placeholders
+        if (tsa.fRange.width() != tsb.fRange.width()) {
+            return false;
+        }
+        if (tsa.fRange.start != tsb.fRange.start) {
+            return false;
+        }
+    }
+    for (size_t i = 0; i < a.fPlaceholders.size(); ++i) {
+        auto& tsa = a.fPlaceholders[i];
+        auto& tsb = b.fPlaceholders[i];
+        if (!(tsa.fStyle.equals(tsb.fStyle))) {
+            return false;
+        }
+        if (tsa.fRange.width() != tsb.fRange.width()) {
+            return false;
+        }
+        if (tsa.fRange.start != tsb.fRange.start) {
+            return false;
         }
     }