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 uint32_t runOffset; 44 uint32_t runCount; 45 Range range; 46 bool isRtl; 47 }; 48 49 BidiText(const U16StringPiece& textBuf, const Range& range, Bidi bidiFlags); 50 51 RunInfo getRunInfoAt(uint32_t runOffset) const; 52 53 class iterator { 54 public: 55 inline bool operator==(const iterator& o) const { 56 return mRunOffset == o.mRunOffset && mParent == o.mParent; 57 } 58 59 inline bool operator!=(const iterator& o) const { return !(*this == o); } 60 61 inline RunInfo operator*() const { return mParent->getRunInfoAt(mRunOffset); } 62 63 inline iterator& operator++() { 64 mRunOffset++; 65 return *this; 66 } 67 68 private: 69 friend class BidiText; 70 iterator(const BidiText * parent,uint32_t runOffset)71 iterator(const BidiText* parent, uint32_t runOffset) 72 : mParent(parent), mRunOffset(runOffset) {} 73 74 const BidiText* mParent; 75 uint32_t mRunOffset; 76 }; 77 begin()78 inline iterator begin() const { return iterator(this, 0); } end()79 inline iterator end() const { return iterator(this, mRunCount); } 80 getRunCount()81 inline uint32_t getRunCount() const { return mRunCount; } 82 83 private: 84 UBiDiUniquePtr mBidi; // Maybe null for single run. 85 const Range mRange; // The range in the original buffer. Used for range check. 86 bool mIsRtl; // The paragraph direction. 87 uint32_t mRunCount; // The number of the bidi run in this text. 88 89 MINIKIN_PREVENT_COPY_AND_ASSIGN(BidiText); 90 }; 91 92 } // namespace minikin 93 94 #endif // MINIKIN_BIDI_UTILS_H 95