| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/text/Hyphenation.h" | 5 #include "platform/text/hyphenation/HyphenationMinikin.h" |
| 6 | 6 |
| 7 #include "base/files/file.h" | 7 #include "base/files/file.h" |
| 8 #include "base/files/memory_mapped_file.h" | 8 #include "base/files/memory_mapped_file.h" |
| 9 #include "base/metrics/histogram_macros.h" | 9 #include "base/metrics/histogram_macros.h" |
| 10 #include "base/timer/elapsed_timer.h" | 10 #include "base/timer/elapsed_timer.h" |
| 11 #include "platform/LayoutLocale.h" | 11 #include "platform/LayoutLocale.h" |
| 12 #include "platform/text/hyphenation/HyphenatorAOSP.h" | 12 #include "platform/text/hyphenation/HyphenatorAOSP.h" |
| 13 #include "public/platform/InterfaceProvider.h" | 13 #include "public/platform/InterfaceProvider.h" |
| 14 #include "public/platform/Platform.h" | 14 #include "public/platform/Platform.h" |
| 15 #include "public/platform/modules/hyphenation/hyphenation.mojom-blink.h" | 15 #include "public/platform/modules/hyphenation/hyphenation.mojom-blink.h" |
| 16 | 16 |
| 17 namespace blink { | 17 namespace blink { |
| 18 | 18 |
| 19 using Hyphenator = android::Hyphenator; | 19 using Hyphenator = android::Hyphenator; |
| 20 | 20 |
| 21 class HyphenationMinikin : public Hyphenation { | |
| 22 public: | |
| 23 bool openDictionary(const AtomicString& locale); | |
| 24 | |
| 25 size_t lastHyphenLocation(const StringView& text, | |
| 26 size_t beforeIndex) const override; | |
| 27 Vector<size_t, 8> hyphenLocations(const StringView&) const override; | |
| 28 | |
| 29 private: | |
| 30 static base::File openDictionaryFile(const AtomicString& locale); | |
| 31 | |
| 32 std::vector<uint8_t> hyphenate(const StringView&) const; | |
| 33 | |
| 34 base::MemoryMappedFile m_file; | |
| 35 std::unique_ptr<Hyphenator> m_hyphenator; | |
| 36 }; | |
| 37 | |
| 38 static mojom::blink::HyphenationPtr connectToRemoteService() { | 21 static mojom::blink::HyphenationPtr connectToRemoteService() { |
| 39 mojom::blink::HyphenationPtr service; | 22 mojom::blink::HyphenationPtr service; |
| 40 Platform::current()->interfaceProvider()->getInterface( | 23 Platform::current()->interfaceProvider()->getInterface( |
| 41 mojo::MakeRequest(&service)); | 24 mojo::MakeRequest(&service)); |
| 42 return service; | 25 return service; |
| 43 } | 26 } |
| 44 | 27 |
| 45 static const mojom::blink::HyphenationPtr& getService() { | 28 static const mojom::blink::HyphenationPtr& getService() { |
| 46 DEFINE_STATIC_LOCAL(mojom::blink::HyphenationPtr, service, | 29 DEFINE_STATIC_LOCAL(mojom::blink::HyphenationPtr, service, |
| 47 (connectToRemoteService())); | 30 (connectToRemoteService())); |
| 48 return service; | 31 return service; |
| 49 } | 32 } |
| 50 | 33 |
| 51 base::File HyphenationMinikin::openDictionaryFile(const AtomicString& locale) { | 34 bool HyphenationMinikin::openDictionary(const AtomicString& locale) { |
| 52 const mojom::blink::HyphenationPtr& service = getService(); | 35 const mojom::blink::HyphenationPtr& service = getService(); |
| 53 base::File file; | 36 base::File file; |
| 54 base::ElapsedTimer timer; | 37 base::ElapsedTimer timer; |
| 55 service->OpenDictionary(locale, &file); | 38 service->OpenDictionary(locale, &file); |
| 56 UMA_HISTOGRAM_TIMES("Hyphenation.Open", timer.Elapsed()); | 39 UMA_HISTOGRAM_TIMES("Hyphenation.Open", timer.Elapsed()); |
| 57 return file; | 40 |
| 41 return openDictionary(std::move(file)); |
| 58 } | 42 } |
| 59 | 43 |
| 60 bool HyphenationMinikin::openDictionary(const AtomicString& locale) { | 44 bool HyphenationMinikin::openDictionary(base::File file) { |
| 61 base::File file = openDictionaryFile(locale); | |
| 62 if (!file.IsValid()) | 45 if (!file.IsValid()) |
| 63 return false; | 46 return false; |
| 64 if (!m_file.Initialize(std::move(file))) { | 47 if (!m_file.Initialize(std::move(file))) { |
| 65 DLOG(ERROR) << "mmap failed"; | 48 DLOG(ERROR) << "mmap failed"; |
| 66 return false; | 49 return false; |
| 67 } | 50 } |
| 68 | 51 |
| 69 m_hyphenator = WTF::wrapUnique(Hyphenator::loadBinary(m_file.data())); | 52 m_hyphenator = WTF::wrapUnique(Hyphenator::loadBinary(m_file.data())); |
| 70 | 53 |
| 71 return true; | 54 return true; |
| 72 } | 55 } |
| 73 | 56 |
| 74 std::vector<uint8_t> HyphenationMinikin::hyphenate( | 57 std::vector<uint8_t> HyphenationMinikin::hyphenate( |
| 75 const StringView& text) const { | 58 const StringView& text) const { |
| 76 std::vector<uint8_t> result; | 59 std::vector<uint8_t> result; |
| 77 if (text.is8Bit()) { | 60 if (text.is8Bit()) { |
| 78 String text16Bit = text.toString(); | 61 String text16Bit = text.toString(); |
| 79 text16Bit.ensure16Bit(); | 62 text16Bit.ensure16Bit(); |
| 80 m_hyphenator->hyphenate(&result, text16Bit.characters16(), | 63 m_hyphenator->hyphenate(&result, text16Bit.characters16(), |
| 81 text16Bit.length()); | 64 text16Bit.length()); |
| 82 } else { | 65 } else { |
| 83 m_hyphenator->hyphenate(&result, text.characters16(), text.length()); | 66 m_hyphenator->hyphenate(&result, text.characters16(), text.length()); |
| 84 } | 67 } |
| 85 return result; | 68 return result; |
| 86 } | 69 } |
| 87 | 70 |
| 88 size_t HyphenationMinikin::lastHyphenLocation(const StringView& text, | 71 size_t HyphenationMinikin::lastHyphenLocation(const StringView& text, |
| 89 size_t beforeIndex) const { | 72 size_t beforeIndex) const { |
| 90 if (text.length() < minimumPrefixLength + minimumSuffixLength) | 73 if (text.length() < minimumPrefixLength + minimumSuffixLength || |
| 74 beforeIndex <= minimumPrefixLength) |
| 91 return 0; | 75 return 0; |
| 92 | 76 |
| 93 std::vector<uint8_t> result = hyphenate(text); | 77 std::vector<uint8_t> result = hyphenate(text); |
| 94 static_assert(minimumPrefixLength >= 1, | 78 beforeIndex = |
| 95 "Change the 'if' above if this fails"); | 79 std::min<size_t>(beforeIndex, text.length() - minimumSuffixLength); |
| 96 for (size_t i = text.length() - minimumSuffixLength - 1; | 80 CHECK_LE(beforeIndex, result.size()); |
| 97 i >= minimumPrefixLength; i--) { | 81 CHECK_GE(beforeIndex, 1u); |
| 82 static_assert(minimumPrefixLength >= 1, "|beforeIndex - 1| can underflow"); |
| 83 for (size_t i = beforeIndex - 1; i >= minimumPrefixLength; i--) { |
| 98 if (result[i]) | 84 if (result[i]) |
| 99 return i; | 85 return i; |
| 100 } | 86 } |
| 101 return 0; | 87 return 0; |
| 102 } | 88 } |
| 103 | 89 |
| 104 Vector<size_t, 8> HyphenationMinikin::hyphenLocations( | 90 Vector<size_t, 8> HyphenationMinikin::hyphenLocations( |
| 105 const StringView& text) const { | 91 const StringView& text) const { |
| 106 Vector<size_t, 8> hyphenLocations; | 92 Vector<size_t, 8> hyphenLocations; |
| 107 if (text.length() < minimumPrefixLength + minimumSuffixLength) | 93 if (text.length() < minimumPrefixLength + minimumSuffixLength) |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 hyphenation.clear(); | 149 hyphenation.clear(); |
| 164 | 150 |
| 165 DEFINE_STATIC_LOCAL(LocaleMap, localeFallback, (createLocaleFallbackMap())); | 151 DEFINE_STATIC_LOCAL(LocaleMap, localeFallback, (createLocaleFallbackMap())); |
| 166 const auto& it = localeFallback.find(locale); | 152 const auto& it = localeFallback.find(locale); |
| 167 if (it != localeFallback.end()) | 153 if (it != localeFallback.end()) |
| 168 return LayoutLocale::get(it->value)->getHyphenation(); | 154 return LayoutLocale::get(it->value)->getHyphenation(); |
| 169 | 155 |
| 170 return nullptr; | 156 return nullptr; |
| 171 } | 157 } |
| 172 | 158 |
| 159 PassRefPtr<HyphenationMinikin> HyphenationMinikin::fromFileForTesting( |
| 160 base::File file) { |
| 161 RefPtr<HyphenationMinikin> hyphenation(adoptRef(new HyphenationMinikin)); |
| 162 if (hyphenation->openDictionary(std::move(file))) |
| 163 return hyphenation.release(); |
| 164 return nullptr; |
| 165 } |
| 166 |
| 173 } // namespace blink | 167 } // namespace blink |
| OLD | NEW |