• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef MINIKIN_HYPHENATOR_MAP_H
18 #define MINIKIN_HYPHENATOR_MAP_H
19 
20 #include <map>
21 #include <mutex>
22 
23 #include "minikin/Hyphenator.h"
24 #include "minikin/Macros.h"
25 
26 #include "Locale.h"
27 
28 namespace minikin {
29 
30 class HyphenatorMap {
31 public:
32     // This map doesn't take ownership of the hyphenator but we don't need to care about the
33     // ownership. In Android, the Hyphenator is allocated in Zygote and never gets released.
add(const std::string & localeStr,const Hyphenator * hyphenator)34     static void add(const std::string& localeStr, const Hyphenator* hyphenator) {
35         getInstance().addInternal(localeStr, hyphenator);
36     }
37 
addAlias(const std::string & fromLocaleStr,const std::string & toLocaleStr)38     static void addAlias(const std::string& fromLocaleStr, const std::string& toLocaleStr) {
39         getInstance().addAliasInternal(fromLocaleStr, toLocaleStr);
40     }
41 
42     // Remove all hyphenators from the map. This is test only method.
clear()43     static void clear() { getInstance().clearInternal(); }
44 
45     // The returned pointer is never a dangling pointer. If nothing found for a given locale,
46     // returns a hyphenator which only processes soft hyphens.
47     //
48     // The Hyphenator lookup works with the following rules:
49     // 1. Search for the Hyphenator with the given locale.
50     // 2. If not found, try again with language + script + region + variant.
51     // 3. If not found, try again with language + region + variant.
52     // 4. If not found, try again with language + variant.
53     // 5. If not found, try again with language.
54     // 6. If not found, try again with script.
lookup(const Locale & locale)55     static const Hyphenator* lookup(const Locale& locale) {
56         return getInstance().lookupInternal(locale);
57     }
58 
59 protected:
60     // The following five methods are protected for testing purposes.
61     HyphenatorMap();  // Use getInstance() instead.
62     void addInternal(const std::string& localeStr, const Hyphenator* hyphenator);
63     void addAliasInternal(const std::string& fromLocaleStr, const std::string& toLocaleStr);
64     const Hyphenator* lookupInternal(const Locale& locale);
65 
66 private:
getInstance()67     static HyphenatorMap& getInstance() {  // Singleton.
68         static HyphenatorMap map;
69         return map;
70     }
71 
72     void clearInternal();
73 
74     const Hyphenator* lookupByIdentifier(uint64_t id) const EXCLUSIVE_LOCKS_REQUIRED(mMutex);
75     const Hyphenator* lookupBySubtag(const Locale& locale, SubtagBits bits) const
76             EXCLUSIVE_LOCKS_REQUIRED(mMutex);
77 
78     const Hyphenator* mSoftHyphenOnlyHyphenator;
79     std::map<uint64_t, const Hyphenator*> mMap GUARDED_BY(mMutex);
80 
81     std::mutex mMutex;
82 };
83 
84 }  // namespace minikin
85 
86 #endif  // MINIKIN_HYPHENATOR_MAP_H
87