1 /*
2  * Copyright (C) 2018 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_LAYOUT_PIECES_H
18 #define MINIKIN_LAYOUT_PIECES_H
19 
20 #include <unordered_map>
21 
22 #include "minikin/Layout.h"
23 #include "minikin/LayoutCache.h"
24 
25 namespace minikin {
26 
27 struct LayoutPieces {
28     struct KeyHasher {
operatorLayoutPieces::KeyHasher29         std::size_t operator()(const LayoutCacheKey& key) const { return key.hash(); }
30     };
31 
LayoutPiecesLayoutPieces32     LayoutPieces() {}
33 
~LayoutPiecesLayoutPieces34     ~LayoutPieces() {
35         for (const auto it : offsetMap) {
36             const_cast<LayoutCacheKey*>(&it.first)->freeText();
37         }
38     }
39 
40     std::unordered_map<LayoutCacheKey, Layout, KeyHasher> offsetMap;
41 
insertLayoutPieces42     void insert(const U16StringPiece& textBuf, const Range& range, const MinikinPaint& paint,
43                 bool dir, StartHyphenEdit startEdit, EndHyphenEdit endEdit, const Layout& layout) {
44         auto result = offsetMap.emplace(
45                 std::piecewise_construct,
46                 std::forward_as_tuple(textBuf, range, paint, dir, startEdit, endEdit),
47                 std::forward_as_tuple(layout));
48         if (result.second) {
49             const_cast<LayoutCacheKey*>(&result.first->first)->copyText();
50         }
51     }
52 
53     template <typename F>
getOrCreateLayoutPieces54     void getOrCreate(const U16StringPiece& textBuf, const Range& range, const MinikinPaint& paint,
55                      bool dir, StartHyphenEdit startEdit, EndHyphenEdit endEdit, F& f) const {
56         auto it = offsetMap.find(LayoutCacheKey(textBuf, range, paint, dir, startEdit, endEdit));
57         if (it == offsetMap.end()) {
58             LayoutCache::getInstance().getOrCreate(textBuf, range, paint, dir, startEdit, endEdit,
59                                                    f);
60         } else {
61             f(it->second);
62         }
63     }
64 
getMemoryUsageLayoutPieces65     uint32_t getMemoryUsage() const {
66         uint32_t result = 0;
67         for (const auto& i : offsetMap) {
68             result += i.first.getMemoryUsage() + i.second.getMemoryUsage();
69         }
70         return result;
71     }
72 };
73 
74 }  // namespace minikin
75 
76 #endif  // MINIKIN_LAYOUT_PIECES_H
77