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