Julia Lavrova | a3552c5 | 2019-05-30 16:12:56 -0400 | [diff] [blame] | 1 | // Copyright 2019 Google LLC. |
| 2 | #ifndef ParagraphCache_DEFINED |
| 3 | #define ParagraphCache_DEFINED |
| 4 | |
| 5 | namespace skia { |
| 6 | namespace textlayout { |
| 7 | |
| 8 | // Just the flutter input for now |
| 9 | class ParagraphCacheKey { |
| 10 | public: |
| 11 | ParagraphCacheKey(SkParagraphStyle paraStyle, |
| 12 | SkTHashMap<const char*, std::pair<SkFont, SkScalar>> mapping, |
| 13 | SkSpan<const char> utf8) |
| 14 | : fHash(0) { |
| 15 | fHash = mix(fHash, paraStyle.computeHash()); |
| 16 | fHash = mix(fHash, computeHash(mapping)); |
| 17 | fHash = mix(fHash, computeHash(utf8)); |
| 18 | } |
| 19 | |
| 20 | uint32_t hash() const { return fHash; } |
| 21 | |
| 22 | private: |
| 23 | uint32 computeHash(SkTHashMap<const char*, std::pair<SkFont, SkScalar>> mapping) { |
| 24 | uint32 hash = 0; |
| 25 | mapping.forEach([&hash](const char* ch, std::pair<SkFont, SkScalar> font) { |
| 26 | hash = mix(hash, t.computeHash()); |
| 27 | }); |
| 28 | for (auto& t : array) { |
| 29 | hash = mix(hash, ch); |
| 30 | hash = mix(hash, SkGoodHash(font.first)); |
| 31 | hash = mix(hash, SkGoodHash(font.second)); |
| 32 | } |
| 33 | return hash; |
| 34 | } |
| 35 | |
| 36 | uint32 computeHash(SkSpan<const char> text) {} |
| 37 | |
| 38 | uint32 computeHash(SkSpan<const char> text) { |
| 39 | uint32 hash = mix(0, text.size()); |
| 40 | for (uint32 i = 0; i < text.size(); i += 2) { |
| 41 | uint32 data = text[i] | text[i + 1] << 16; |
| 42 | hash = mix(hash, data); |
| 43 | } |
| 44 | if (text.size() & 1) { |
| 45 | uint32 data = text.back(); |
| 46 | hash = mix(hash, data); |
| 47 | } |
| 48 | return hash; |
| 49 | } |
| 50 | |
| 51 | uint32 mix(uint32 hash, uint32 data) { |
| 52 | hash += data; |
| 53 | hash += (hash << 10); |
| 54 | hash ^= (hash >> 6); |
| 55 | return hash; |
| 56 | } |
| 57 | |
| 58 | uint32 fHash; |
| 59 | }; |
| 60 | |
| 61 | class ParagraphCacheValue { |
| 62 | public: |
| 63 | ParagraphCacheValue(std::shared<SkParagraph> paragraph, |
| 64 | SkTHashMap<const char*, |
| 65 | std::pair<SkFont, SkScalar>> mapping) |
| 66 | : fKey(ParagraphCacheKey(paragraph.getParagraphStyle(), mapping, paragraph.getText())) |
| 67 | , fFontCollection(collection) |
| 68 | , fParagraphStyle(paraStyle) |
| 69 | , fTextStyles(textStyles) |
| 70 | , fUtf8(utf8) {} |
| 71 | |
| 72 | static const ParagraphCacheKey& GetKey(const ParagraphCacheValue& value) { return fKey; } |
| 73 | static uint32_t Hash(const ParagraphCacheKey& key) { return fKey.hash(); } |
| 74 | |
| 75 | private: |
| 76 | ParagraphCacheKey fKey; |
| 77 | |
| 78 | std::shared<SkParagraph> fParagraph; |
| 79 | std::pair<SkFont, SkScalar>>fMapping; |
| 80 | }; |
| 81 | |
| 82 | class ParagraphCache : public SkTDynamicHash<ParagraphCacheValue, ParagraphCacheKey> { |
| 83 | public: |
| 84 | Hash() : INHERITED() {} |
| 85 | |
| 86 | // Promote protected methods to public for this test. |
| 87 | int capacity() const { return this->INHERITED::capacity(); } |
| 88 | int countCollisions(const int& key) const { return this->INHERITED::countCollisions(key); } |
| 89 | |
| 90 | private: |
| 91 | typedef SkTDynamicHash<ParagraphCacheValue, ParagraphCacheKey> INHERITED; |
| 92 | }; |
| 93 | } // namespace textlayout |
| 94 | } // namespace skia |
| 95 | |
| 96 | #endif // ParagraphCache_DEFINED |