nsComplexBreaker.cpp (1991B)
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 #include "nsComplexBreaker.h" 7 8 #include "LineBreakCache.h" 9 #include "MainThreadUtils.h" 10 #include "mozilla/Assertions.h" 11 #include "mozilla/Services.h" 12 #include "mozilla/StaticPtr.h" 13 #include "nsTHashMap.h" 14 #include "nsIObserver.h" 15 #include "nsIObserverService.h" 16 #include "nsString.h" 17 #include "nsTArray.h" 18 #include "nsThreadUtils.h" 19 20 using namespace mozilla; 21 using namespace mozilla::intl; 22 23 void ComplexBreaker::GetBreaks(const char16_t* aText, uint32_t aLength, 24 uint8_t* aBreakBefore) { 25 // It is believed that this is only called on the main thread, so we don't 26 // need to lock the caching structures. A diagnostic assert is used in case 27 // our tests don't exercise all code paths. 28 MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread()); 29 30 MOZ_ASSERT(aText, "aText shouldn't be null"); 31 MOZ_ASSERT(aLength, "aLength shouldn't be zero"); 32 MOZ_ASSERT(aBreakBefore, "aBreakBefore shouldn't be null"); 33 34 // Check the cache. 35 LineBreakCache::KeyType key{aText, aLength}; 36 auto entry = LineBreakCache::Cache()->Lookup(key); 37 if (entry) { 38 auto& breakBefore = entry.Data().mBreaks; 39 LineBreakCache::CopyAndFill(breakBefore, aBreakBefore, 40 aBreakBefore + aLength); 41 return; 42 } 43 44 NS_GetComplexLineBreaks(aText, aLength, aBreakBefore); 45 46 // As a very simple memory saving measure we trim off trailing elements that 47 // are false before caching. 48 auto* afterLastTrue = aBreakBefore + aLength; 49 while (!*(afterLastTrue - 1)) { 50 if (--afterLastTrue == aBreakBefore) { 51 break; 52 } 53 } 54 55 entry.Set(LineBreakCache::EntryType{ 56 nsString(aText, aLength), 57 nsTArray<uint8_t>(aBreakBefore, afterLastTrue - aBreakBefore)}); 58 }