• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 ROSEN_MODULES_TEXGINE_SRC_MEASURER_IMPL_H
17 #define ROSEN_MODULES_TEXGINE_SRC_MEASURER_IMPL_H
18 
19 #include <iomanip>
20 #include <list>
21 #include <queue>
22 
23 #include <hb.h>
24 #include <hb-icu.h>
25 #include <unicode/utf16.h>
26 #include <unicode/uchar.h>
27 
28 #include "measurer.h"
29 
30 namespace OHOS {
31 namespace Rosen {
32 namespace TextEngine {
33 struct MeasuringRun {
34     size_t start;
35     size_t end;
36     hb_script_t script = HB_SCRIPT_INVALID;
37     std::shared_ptr<Typeface> typeface = nullptr;
38 };
39 
40 class MeasurerImpl : public Measurer {
41 public:
42     MeasurerImpl(const std::vector<uint16_t> &text, const FontCollection &fontCollection);
43 
44     /*
45      * @brief Get word boundary of text
46      */
47     const std::vector<Boundary> &GetWordBoundary() const override;
48 
49     /*
50      * @brief Measure font
51      * @param cgs The output parameter, after measurer will generate char groups
52      * @return 0 is measurer successed
53      *         1 is measurer failed
54      */
55     int Measure(CharGroups &cgs) override;
56 
57     /*
58      * @brief Seeks typeface for text, this should be private, now is for UT testing
59      * @param runs Input and output parameter, intermediate products of measurement
60      */
61     void SeekTypeface(std::list<struct MeasuringRun> &runs);
62 
63     /*
64      * @brief Seeks script for text, this should be private, now is for UT testing
65      * @param runs Input and output parameter, intermediate products of measurement
66      */
67     void SeekScript(std::list<struct MeasuringRun> &runs);
68 
69     /*
70      * @brief Text shaping, after this, information such as the width and height of the
71      *         text will be obtain. This should be private, now is for UT testing
72      * @param cgs The output parameter, char groups of text
73      * @param runs Input and output parameter, intermediate products of measurement
74      * @param boundary The word boundarys of text
75      * @return 0 is shape successed
76      *         1 is shape failed
77      */
78     int Shape(CharGroups &cgs, std::list<struct MeasuringRun> &runs, std::vector<Boundary> boundaries);
79 
80     /*
81      * @brief Generate font features required for shaping.
82      *        This should be private, now is for UT testing.
83      * @param fontFeatures The output parameter. Will passed to harfbuzz
84      * @param ff Font features user want
85      */
86     void GenerateHBFeatures(std::vector<hb_feature_t> &fontFeatures, const FontFeatures *ff);
87 
88 private:
89     struct MeasurerCacheKey {
90         std::vector<uint16_t> text = {};
91         FontStyles style;
92         std::string locale = "";
93         bool rtl = false;
94         uint32_t size = 16.0; // default TextStyle fontSize_
95         size_t startIndex = 0;
96         size_t endIndex = 0;
97         double letterSpacing = 0;
98         double wordSpacing = 0;
99 
100         bool operator <(const struct MeasurerCacheKey &rhs) const
101         {
102             if (startIndex != rhs.startIndex) {
103                 return startIndex < rhs.startIndex;
104             }
105             if (endIndex != rhs.endIndex) {
106                 return endIndex < rhs.endIndex;
107             }
108             if (text != rhs.text) {
109                 return text < rhs.text;
110             }
111             if (rtl != rhs.rtl) {
112                 return rtl < rhs.rtl;
113             }
114             if (size != rhs.size) {
115                 return size < rhs.size;
116             }
117             if (style != rhs.style) {
118                 return style < rhs.style;
119             }
120             if (locale != rhs.locale) {
121                 return locale < rhs.locale;
122             }
123             if (letterSpacing != rhs.letterSpacing) {
124                 return letterSpacing < rhs.letterSpacing;
125             }
126             if (wordSpacing != rhs.wordSpacing) {
127                 return wordSpacing < rhs.wordSpacing;
128             }
129             return false;
130         }
131     };
132     struct MeasurerCacheVal {
133         CharGroups cgs;
134         std::vector<Boundary> boundaries = {};
135     };
136 
137     void DoSeekScript(std::list<struct MeasuringRun> &runs, hb_unicode_funcs_t *icuGetUnicodeFuncs);
138     int DoShape(CharGroups &cgs, MeasuringRun &run, size_t &index);
139     int GetGlyphs(CharGroups &cgs, MeasuringRun &run, size_t &index, hb_buffer_t *hbuffer,
140         std::shared_ptr<TextEngine::Typeface> typeface);
141     void DoCgsByCluster(std::map<uint32_t, TextEngine::CharGroup> &cgsByCluster);
142 
143     static inline std::map<struct MeasurerCacheKey, struct MeasurerCacheVal> cache_;
144     std::vector<Boundary> boundaries_ = {};
145 };
146 
147 hb_blob_t *HbFaceReferenceTableTypeface(hb_face_t *face, hb_tag_t tag, void *context);
148 } // namespace TextEngine
149 } // namespace Rosen
150 } // namespace OHOS
151 
152 #endif // ROSEN_MODULES_TEXGINE_SRC_MEASURER_IMPL_H