Home | History | Annotate | Download | only in minikin
      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 {
     34     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 
     69         iterator(const BidiText* parent, uint32_t runOffset)
     70                 : mParent(parent), mRunOffset(runOffset) {}
     71 
     72         const BidiText* mParent;
     73         uint32_t mRunOffset;
     74     };
     75 
     76     inline iterator begin() const { return iterator(this, 0); }
     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