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