1 /*
2  * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef GRAPHIC_LITE_LINE_BREAK_H
17 #define GRAPHIC_LITE_LINE_BREAK_H
18 
19 #include "graphic_config.h"
20 #if ENABLE_ICU
21 #include <cstdint>
22 #include <string>
23 
24 #include "common/text.h"
25 #include "font/ui_font_header.h"
26 #include "gfx_utils/file.h"
27 #include "gfx_utils/heap_base.h"
28 #include "gfx_utils/mem_api.h"
29 
30 namespace OHOS {
31 class UILineBreakProxy;
32 /**
33  * @brief Using ICU as the core of lineBreakEngine.
34  *
35  */
36 class UILineBreakEngine : public HeapBase {
37 public:
38     /**
39      * @brief Get UILineBreakEngine instannce.
40      *
41      * @return UILineBreakEngine&
42      */
43     static UILineBreakEngine& GetInstance();
44 
45     /**
46      * @brief Init the line break engine and load the line break rules.
47      *
48      */
Init()49     void Init()
50     {
51         LoadRule();
52     }
53 
54     /**
55      * @brief Get the next line break position.
56      *
57      * @param record UILineBreakProxy instance.
58      * @return uint16_t Next line break position.
59      */
60     uint16_t GetNextBreakPos(UILineBreakProxy& record);
61 
62     /**
63      * @brief Set the rule file path.
64      *
65      * @param fp File descriptor.
66      * @param offset The offset of rule.
67      * @param size File size.
68      * @return int32_t Result.
69      */
SetRuleBinInfo(int32_t fp,int32_t offset,uint32_t size)70     int32_t SetRuleBinInfo(int32_t fp, int32_t offset, uint32_t size)
71     {
72         fp_ = fp;
73         offset_ = offset;
74         int32_t fRet = lseek(fp_, offset, SEEK_SET);
75         if (fRet != offset) {
76             return fRet;
77         }
78         size_ = size;
79         return 0;
80     }
81 
82     /**
83      * @brief Set the rule file load addr object.
84      *
85      * @param addr The rule file load addr.
86      */
SetRuleFileLoadAddr(char * addr)87     void SetRuleFileLoadAddr(char* addr)
88     {
89         addr_ = addr;
90     }
91 
92     /**
93      * @brief Get the rule file load addr.
94      *
95      * @return char* The rule file load addr.
96      */
GetRuleFileLoadAddr()97     char* GetRuleFileLoadAddr() const
98     {
99         return addr_;
100     }
101 
102     /**
103      * @brief Get the size of rule file.
104      *
105      * @return int32_t The size of rule file.
106      */
GetRuleFileSize()107     int32_t GetRuleFileSize() const
108     {
109         return size_;
110     }
111 
112     // 0xFFFF: unlimit the length until the end null.
113     uint32_t GetNextLineAndWidth(const char* text,
114                                  uint16_t fontId,
115                                  uint8_t fontSize,
116                                  int16_t space,
117                                  bool allBreak,
118                                  int16_t& maxWidth,
119                                  int16_t& maxHeight,
120                                  uint16_t& letterIndex,
121                                  SpannableString* spannableString,
122                                  uint16_t len = 0xFFFF,
123                                  bool eliminateTrailingSpaces = false);
124     bool IsBreakPos(uint32_t unicode, uint16_t fontId, uint8_t fontSize, int32_t& state);
125 
126 private:
UILineBreakEngine()127     UILineBreakEngine()
128         : initSuccess_(false), addr_(nullptr), size_(0), fp_(0), offset_(0), lineBreakTrie_(nullptr), stateTbl_(nullptr)
129     {
130     }
~UILineBreakEngine()131     ~UILineBreakEngine() {}
132 
133     void LoadRule();
134     int16_t GetLetterWidth(uint32_t unicode, uint16_t& letterIndex, int16_t& maxHeight,
135                            uint16_t fontId, uint8_t fontSize, SpannableString* spannableString);
136     static constexpr const int32_t LINE_BREAK_STATE_START = 1;
137     static constexpr const int32_t LINE_BREAK_STATE_STOP = 0;
138     bool initSuccess_;
139     char* addr_;
140     int32_t size_;
141     int32_t fp_;
142     int32_t offset_;
143     void* lineBreakTrie_;
144     const void* stateTbl_;
145 };
146 
147 /**
148  * @brief Line break proxy.
149  *
150  */
151 class UILineBreakProxy : public HeapBase {
152 public:
153     UILineBreakProxy() = delete;
154 
155     /**
156      * @brief Construct a new UILineBreakProxy object.
157      *
158      * @param str Input string.
159      * @param len The length of string.
160      */
UILineBreakProxy(uint32_t * str,uint16_t len)161     UILineBreakProxy(uint32_t* str, uint16_t len) : str_(str), len_(len), prePos_(0) {}
162 
~UILineBreakProxy()163     ~UILineBreakProxy()
164     {
165         str_ = nullptr;
166         len_ = 0;
167         prePos_ = 0;
168     }
169 
170     /**
171      * @brief Get next line break position.
172      *
173      * @return uint16_t Next line break position.
174      */
GetNextBreakPos()175     uint16_t GetNextBreakPos()
176     {
177         uint16_t offsetFromPrePos = UILineBreakEngine::GetInstance().GetNextBreakPos(*this);
178         prePos_ += offsetFromPrePos;
179         return prePos_;
180     }
181 
182     /**
183      * @brief Get the length of string.
184      *
185      * @return uint16_t The length of string.
186      */
GetStrLen()187     uint16_t GetStrLen() const
188     {
189         if (prePos_ < len_) {
190             return len_ - prePos_;
191         }
192         return 0;
193     }
194 
195     /**
196      * @brief Get the string.
197      *
198      * @return uint16_t* The str setted.
199      */
GetStr()200     const uint32_t* GetStr() const
201     {
202         if (prePos_ < len_) {
203             return &(str_[prePos_]);
204         }
205         return nullptr;
206     }
207 
208 private:
209     uint32_t* str_;
210     uint16_t len_;
211     uint16_t prePos_;
212 };
213 } // namespace OHOS
214 #endif // ENABLE_ICU
215 #endif // GRAPHIC_LITE_LINE_BREAK_H
216