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