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_BIDI_UTILS_H 18 #define MINIKIN_BIDI_UTILS_H 19 20 #define LOG_TAG "Minikin" 21 22 #include "minikin/Layout.h" 23 24 #include <memory> 25 26 #include <unicode/ubidi.h> 27 28 #include "minikin/Macros.h" 29 #include "minikin/U16StringPiece.h" 30 31 namespace minikin { 32 33 struct UBiDiDeleter { operatorUBiDiDeleter34 void operator()(UBiDi* v) { ubidi_close(v); } 35 }; 36 37 using UBiDiUniquePtr = std::unique_ptr<UBiDi, UBiDiDeleter>; 38 39 // A helper class for iterating the bidi run transitions. 40 class BidiText { 41 public: 42 struct RunInfo { 43 Range range; 44 bool isRtl; 45 }; 46 47 BidiText(const U16StringPiece& textBuf, const Range& range, Bidi bidiFlags); 48 49 RunInfo getRunInfoAt(uint32_t runOffset) const; 50 51 class iterator { 52 public: 53 inline bool operator==(const iterator& o) const { 54 return mRunOffset == o.mRunOffset && mParent == o.mParent; 55 } 56 57 inline bool operator!=(const iterator& o) const { return !(*this == o); } 58 59 inline RunInfo operator*() const { return mParent->getRunInfoAt(mRunOffset); } 60 61 inline iterator& operator++() { 62 mRunOffset++; 63 return *this; 64 } 65 66 private: 67 friend class BidiText; 68 iterator(const BidiText * parent,uint32_t runOffset)69 iterator(const BidiText* parent, uint32_t runOffset) 70 : mParent(parent), mRunOffset(runOffset) {} 71 72 const BidiText* mParent; 73 uint32_t mRunOffset; 74 }; 75 begin()76 inline iterator begin() const { return iterator(this, 0); } end()77 inline iterator end() const { return iterator(this, mRunCount); } 78 79 private: 80 UBiDiUniquePtr mBidi; // Maybe null for single run. 81 const Range mRange; // The range in the original buffer. Used for range check. 82 bool mIsRtl; // The paragraph direction. 83 uint32_t mRunCount; // The number of the bidi run in this text. 84 85 MINIKIN_PREVENT_COPY_AND_ASSIGN(BidiText); 86 }; 87 88 } // namespace minikin 89 90 #endif // MINIKIN_BIDI_UTILS_H 91