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