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