tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

LineBreakCache.h (3097B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #ifndef mozilla_intl_LineBreakCache_h__
      7 #define mozilla_intl_LineBreakCache_h__
      8 
      9 #include "nsIObserver.h"
     10 #include "nsString.h"
     11 #include "nsTArray.h"
     12 #include "nsThreadUtils.h"
     13 #include "mozilla/MruCache.h"
     14 #include "mozilla/StaticPtr.h"
     15 #include "mozilla/intl/Segmenter.h"
     16 
     17 namespace mozilla {
     18 namespace intl {
     19 
     20 namespace detail {
     21 struct LBCacheKey {
     22  const char16_t* mText;
     23  uint32_t mLength;
     24  // ICU4X segmenter results depend on these flags, so they need to be part
     25  // of the cache key. (Legacy ComplexBreaker just leaves them as default.)
     26  WordBreakRule mWordBreak = WordBreakRule::Normal;
     27  LineBreakRule mLineBreak = LineBreakRule::Auto;
     28  bool mIsChineseOrJapanese = false;
     29 };
     30 
     31 struct LBCacheEntry {
     32  nsString mText;
     33  nsTArray<uint8_t> mBreaks;
     34  WordBreakRule mWordBreak = WordBreakRule::Normal;
     35  LineBreakRule mLineBreak = LineBreakRule::Auto;
     36  bool mIsChineseOrJapanese = false;
     37 };
     38 }  // namespace detail
     39 
     40 // Most-recently-used cache for line-break results, because finding line-
     41 // breaks may be slow for complex writing systems (e.g. Thai, Khmer).
     42 // The MruCache size should be a prime number that is slightly less than a
     43 // power of two.
     44 class LineBreakCache : public MruCache<detail::LBCacheKey, detail::LBCacheEntry,
     45                                       LineBreakCache, 4093> {
     46 public:
     47  static void Initialize();
     48  static void Shutdown();
     49 
     50  using KeyType = detail::LBCacheKey;
     51  using EntryType = detail::LBCacheEntry;
     52 
     53  static LineBreakCache* Cache() {
     54    if (!sBreakCache) {
     55      sBreakCache = new LineBreakCache();
     56    }
     57    return sBreakCache;
     58  }
     59 
     60  static HashNumber Hash(const KeyType& aKey) {
     61    HashNumber h = HashString(aKey.mText, aKey.mLength);
     62    h = AddToHash(h, aKey.mWordBreak);
     63    h = AddToHash(h, aKey.mLineBreak);
     64    h = AddToHash(h, aKey.mIsChineseOrJapanese);
     65    return h;
     66  }
     67 
     68  static bool Match(const KeyType& aKey, const EntryType& aEntry) {
     69    return nsDependentSubstring(aKey.mText, aKey.mLength)
     70               .Equals(aEntry.mText) &&
     71           aKey.mWordBreak == aEntry.mWordBreak &&
     72           aKey.mLineBreak == aEntry.mLineBreak &&
     73           aKey.mIsChineseOrJapanese == aEntry.mIsChineseOrJapanese;
     74  }
     75 
     76  static void CopyAndFill(const nsTArray<uint8_t>& aCachedBreakBefore,
     77                          uint8_t* aBreakBefore, uint8_t* aEndBreakBefore) {
     78    auto* startFill = std::copy(aCachedBreakBefore.begin(),
     79                                aCachedBreakBefore.end(), aBreakBefore);
     80    std::fill(startFill, aEndBreakBefore, false);
     81  }
     82 
     83  class Observer final : public nsIObserver {
     84    ~Observer() = default;
     85 
     86   public:
     87    NS_DECL_ISUPPORTS
     88    NS_DECL_NSIOBSERVER
     89  };
     90 
     91 private:
     92  static StaticAutoPtr<LineBreakCache> sBreakCache;
     93 };
     94 
     95 }  // namespace intl
     96 }  // namespace mozilla
     97 
     98 #endif /* mozilla_intl_LineBreakCache_h__ */