| Index: third_party/WebKit/Source/platform/text/hyphenation/HyphenationMinikin.cpp
|
| diff --git a/third_party/WebKit/Source/platform/text/hyphenation/HyphenationMinikin.cpp b/third_party/WebKit/Source/platform/text/hyphenation/HyphenationMinikin.cpp
|
| index 01af49b0f0ab61a413226b661a21956fc7a2c75e..b40b1cbe464ed40f218d28f553fef1945f41bf09 100644
|
| --- a/third_party/WebKit/Source/platform/text/hyphenation/HyphenationMinikin.cpp
|
| +++ b/third_party/WebKit/Source/platform/text/hyphenation/HyphenationMinikin.cpp
|
| @@ -9,22 +9,29 @@
|
| #include "base/metrics/histogram.h"
|
| #include "base/timer/elapsed_timer.h"
|
| #include "mojo/public/cpp/system/platform_handle.h"
|
| +#include "platform/text/hyphenation/HyphenatorAOSP.h"
|
| #include "public/platform/Platform.h"
|
| #include "public/platform/ServiceRegistry.h"
|
| #include "public/platform/modules/hyphenation/hyphenation.mojom-blink.h"
|
|
|
| namespace blink {
|
|
|
| +using Hyphenator = android::Hyphenator;
|
| +
|
| class HyphenationMinikin : public Hyphenation {
|
| public:
|
| bool openDictionary(const AtomicString& locale);
|
|
|
| size_t lastHyphenLocation(const StringView& text, size_t beforeIndex) const override;
|
| + Vector<size_t, 8> hyphenLocations(const StringView&) const override;
|
|
|
| private:
|
| static base::PlatformFile openDictionaryFile(const AtomicString& locale);
|
|
|
| + std::vector<uint8_t> hyphenate(const StringView&) const;
|
| +
|
| base::MemoryMappedFile m_file;
|
| + std::unique_ptr<Hyphenator> m_hyphenator;
|
| };
|
|
|
| static mojom::blink::HyphenationPtr connectToRemoteService()
|
| @@ -71,23 +78,96 @@ bool HyphenationMinikin::openDictionary(const AtomicString& locale)
|
| return false;
|
| }
|
|
|
| - // TODO(kojii): Create dictionary from m_file when Minikin is ready.
|
| + m_hyphenator = wrapUnique(Hyphenator::loadBinary(m_file.data()));
|
|
|
| return true;
|
| }
|
|
|
| +std::vector<uint8_t> HyphenationMinikin::hyphenate(const StringView& text) const
|
| +{
|
| + std::vector<uint8_t> result;
|
| + if (text.is8Bit()) {
|
| + String text16Bit = text.toString();
|
| + text16Bit.ensure16Bit();
|
| + m_hyphenator->hyphenate(&result, text16Bit.characters16(), text16Bit.length());
|
| + } else {
|
| + m_hyphenator->hyphenate(&result, text.characters16(), text.length());
|
| + }
|
| + return result;
|
| +}
|
| +
|
| size_t HyphenationMinikin::lastHyphenLocation(const StringView& text, size_t beforeIndex) const
|
| {
|
| - // TODO(kojii): Call minikin using the dictionary when Minikin is ready.
|
| + if (text.length() < minimumPrefixLength + minimumSuffixLength)
|
| + return 0;
|
| +
|
| + std::vector<uint8_t> result = hyphenate(text);
|
| + static_assert(minimumPrefixLength >= 1, "Change the 'if' above if this fails");
|
| + for (size_t i = text.length() - minimumSuffixLength - 1;
|
| + i >= minimumPrefixLength; i--) {
|
| + if (result[i])
|
| + return i;
|
| + }
|
| return 0;
|
| }
|
|
|
| +Vector<size_t, 8> HyphenationMinikin::hyphenLocations(const StringView& text) const
|
| +{
|
| + Vector<size_t, 8> hyphenLocations;
|
| + if (text.length() < minimumPrefixLength + minimumSuffixLength)
|
| + return hyphenLocations;
|
| +
|
| + std::vector<uint8_t> result = hyphenate(text);
|
| + static_assert(minimumPrefixLength >= 1, "Change the 'if' above if this fails");
|
| + for (size_t i = text.length() - minimumSuffixLength - 1;
|
| + i >= minimumPrefixLength; i--) {
|
| + if (result[i])
|
| + hyphenLocations.append(i);
|
| + }
|
| + return hyphenLocations;
|
| +}
|
| +
|
| +using LocaleMap = HashMap<AtomicString, AtomicString, CaseFoldingHash>;
|
| +
|
| +static LocaleMap createLocaleFallbackMap()
|
| +{
|
| + // This data is from CLDR, compiled by AOSP.
|
| + // https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/text/Hyphenator.java
|
| + using LocaleFallback = const char*[2];
|
| + static LocaleFallback localeFallbackData[] = {
|
| + { "en-AS", "en-US" }, // English (American Samoa)
|
| + { "en-GU", "en-US" }, // English (Guam)
|
| + { "en-MH", "en-US" }, // English (Marshall Islands)
|
| + { "en-MP", "en-US" }, // English (Northern Mariana Islands)
|
| + { "en-PR", "en-US" }, // English (Puerto Rico)
|
| + { "en-UM", "en-US" }, // English (United States Minor Outlying Islands)
|
| + { "en-VI", "en-US" }, // English (Virgin Islands)
|
| + { "no", "nb" },
|
| + { "am", "und-Ethi" }, // Amharic
|
| + { "byn", "und-Ethi" }, // Blin
|
| + { "gez", "und-Ethi" }, // Geʻez
|
| + { "ti", "und-Ethi" }, // Tigrinya
|
| + { "wal", "und-Ethi" }, // Wolaytta
|
| + };
|
| + LocaleMap map;
|
| + for (const auto& it : localeFallbackData)
|
| + map.add(it[0], it[1]);
|
| + return map;
|
| +}
|
| +
|
| PassRefPtr<Hyphenation> Hyphenation::platformGetHyphenation(const AtomicString& locale)
|
| {
|
| RefPtr<HyphenationMinikin> hyphenation(adoptRef(new HyphenationMinikin));
|
| - if (!hyphenation->openDictionary(locale))
|
| - return nullptr;
|
| - return hyphenation.release();
|
| + if (hyphenation->openDictionary(locale.lowerASCII()))
|
| + return hyphenation.release();
|
| + hyphenation.clear();
|
| +
|
| + DEFINE_STATIC_LOCAL(LocaleMap, localeFallback, (createLocaleFallbackMap()));
|
| + const auto& it = localeFallback.find(locale);
|
| + if (it != localeFallback.end())
|
| + return get(it->value);
|
| +
|
| + return nullptr;
|
| }
|
|
|
| } // namespace blink
|
|
|