xref: /aosp_15_r20/frameworks/minikin/libs/minikin/ScriptUtils.h (revision 834a2baab5fdfc28e9a428ee87c7ea8f6a06a53d)
1 /*
2  * Copyright (C) 2023 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_SCRIPT_UTILS_H
18 #define MINIKIN_SCRIPT_UTILS_H
19 
20 #include <unicode/ubidi.h>
21 
22 #include <memory>
23 
24 #include "minikin/Layout.h"
25 #include "minikin/Macros.h"
26 #include "minikin/U16StringPiece.h"
27 
28 namespace minikin {
29 
30 // A helper class for iterating the bidi run transitions.
31 class ScriptText {
32 public:
33     struct RunInfo {
34         Range range;
35         hb_script_t script;
36     };
37 
ScriptText(const U16StringPiece & textBuf,uint32_t start,uint32_t end)38     ScriptText(const U16StringPiece& textBuf, uint32_t start, uint32_t end)
39             : mTextBuf(textBuf), mRange(start, end) {}
40 
ScriptText(const U16StringPiece & textBuf)41     explicit ScriptText(const U16StringPiece& textBuf)
42             : mTextBuf(textBuf), mRange(0, textBuf.size()) {}
43 
44     class iterator {
45     public:
46         inline bool operator==(const iterator& o) const {
47             return mStart == o.mStart && mParent == o.mParent;
48         }
49 
50         inline bool operator!=(const iterator& o) const { return !(*this == o); }
51 
52         inline std::pair<Range, hb_script_t> operator*() const {
53             return std::make_pair(Range(mStart, mEnd), mScript);
54         }
55 
56         inline iterator& operator++() {
57             mStart = mEnd;
58             std::tie(mEnd, mScript) = getScriptRun(mParent->mTextBuf, mParent->mRange, mStart);
59             return *this;
60         }
61 
62     private:
63         friend class ScriptText;
64 
iterator(const ScriptText * parent,uint32_t start)65         iterator(const ScriptText* parent, uint32_t start) : mParent(parent), mStart(start) {
66             std::tie(mEnd, mScript) = getScriptRun(mParent->mTextBuf, mParent->mRange, mStart);
67         }
68 
69         const ScriptText* mParent;
70         uint32_t mStart;
71         uint32_t mEnd;
72         hb_script_t mScript;
73     };
74 
begin()75     inline iterator begin() const { return iterator(this, mRange.getStart()); }
end()76     inline iterator end() const { return iterator(this, mRange.getEnd()); }
77 
78 private:
79     U16StringPiece mTextBuf;
80     Range mRange;
81 
82     static std::pair<uint32_t, hb_script_t> getScriptRun(U16StringPiece text, Range range,
83                                                          uint32_t pos);
84 
85     MINIKIN_PREVENT_COPY_AND_ASSIGN(ScriptText);
86 };
87 
88 }  // namespace minikin
89 
90 #endif  // MINIKIN_SCRIPT_UTILS_H
91