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 #include "typeface.h"
17
18 #include <hb.h>
19
20 #include "texgine_exception.h"
21 #include "texgine/utils/exlog.h"
22 #ifdef LOGGER_ENABLE_SCOPE
23 #include "texgine/utils/trace.h"
24 #endif
25
26 namespace OHOS {
27 namespace Rosen {
28 namespace TextEngine {
29 #define DYNAMIC_FONT_WEIGHT 6
MakeFromFile(const std::string & filename)30 std::unique_ptr<Typeface> Typeface::MakeFromFile(const std::string &filename)
31 {
32 auto st = TexgineTypeface::MakeFromFile(filename.c_str());
33 if (st == nullptr || st->GetTypeface() == nullptr) {
34 throw TEXGINE_EXCEPTION(API_FAILED);
35 }
36
37 return std::make_unique<Typeface>(st);
38 }
39
Typeface(std::shared_ptr<TexgineTypeface> tf)40 Typeface::Typeface(std::shared_ptr<TexgineTypeface> tf)
41 : typeface_(tf)
42 {
43 if (typeface_ != nullptr) {
44 typeface_->GetFamilyName(&name_);
45 }
46 }
47
~Typeface()48 Typeface::~Typeface()
49 {
50 if (hblob_ != nullptr) {
51 hb_blob_destroy(hblob_);
52 }
53 }
54
GetName()55 std::string Typeface::GetName()
56 {
57 return name_.ToString();
58 }
59
ParseCmap(const std::shared_ptr<CmapParser> & parser)60 bool Typeface::ParseCmap(const std::shared_ptr<CmapParser> &parser)
61 {
62 LOGEX_FUNC_LINE_DEBUG(DEBUG) << "Parse Cmap: " << GetName();
63 #ifdef LOGGER_ENABLE_SCOPE
64 ScopedTrace scope("Typeface::InitCmap");
65 #endif
66 auto tag = HB_TAG('c', 'm', 'a', 'p');
67 if (typeface_ == nullptr || typeface_->GetTypeface() == nullptr) {
68 LOGEX_FUNC_LINE(WARN) << "typeface_ is nullptr";
69 return false;
70 }
71
72 auto size = typeface_->GetTableSize(tag);
73 if (size <= 0) {
74 LOGEX_FUNC_LINE(ERROR) << name_.ToString() << " haven't cmap";
75 throw TEXGINE_EXCEPTION(API_FAILED);
76 }
77
78 cmapData_ = std::make_unique<char[]>(size);
79 auto retv = typeface_->GetTableData(tag, 0, size, cmapData_.get());
80 if (size != retv) {
81 LOGEX_FUNC_LINE(ERROR) << "getTableData failed size: " << size << ", retv: " << retv;
82 throw TEXGINE_EXCEPTION(API_FAILED);
83 }
84
85 hblob_ = hb_blob_create(reinterpret_cast<const char *>(cmapData_.get()),
86 size, HB_MEMORY_MODE_WRITABLE, cmapData_.get(), nullptr);
87 if (hblob_ == nullptr) {
88 LOGEX_FUNC_LINE(ERROR) << "hblob_ is nullptr";
89 throw TEXGINE_EXCEPTION(API_FAILED);
90 }
91
92 #ifdef LOGGER_ENABLE_SCOPE
93 scope.Finish();
94 ScopedTrace scope2("Typeface::ParseCmap");
95 #endif
96 const char* data = hb_blob_get_data(hblob_, nullptr);
97 unsigned int length = hb_blob_get_length(hblob_);
98 auto retval = parser->Parse(data, length);
99 return retval == 0;
100 }
101
Has(uint32_t ch)102 bool Typeface::Has(uint32_t ch)
103 {
104 while (cmapParser_ == nullptr) {
105 auto name = GetName();
106 auto it = cmapCache_.find(name);
107 if (it != cmapCache_.end()) {
108 cmapParser_ = cmapCache_[name];
109 break;
110 }
111
112 auto parser = std::make_shared<CmapParser>();
113 if (ParseCmap(parser)) {
114 cmapParser_ = parser;
115 cmapCache_[name] = parser;
116 } else {
117 cmapCache_.erase(name);
118 return false;
119 }
120 }
121
122 return cmapParser_->GetGlyphId(ch) != CmapParser::INVALID_GLYPH_ID;
123 }
124
ComputeFakeryItalic(bool isItalic)125 void Typeface::ComputeFakeryItalic(bool isItalic)
126 {
127 isFakeItalic_ = isItalic;
128 }
129
DetectionItalic() const130 bool Typeface::DetectionItalic() const
131 {
132 return isFakeItalic_;
133 }
134
ComputeFakery(int wantedWeight)135 void Typeface::ComputeFakery(int wantedWeight)
136 {
137 bool isFakeBold = wantedWeight >= DYNAMIC_FONT_WEIGHT;
138 isFakeBold_ = isFakeBold;
139 }
140
DetectionFakeBold() const141 bool Typeface::DetectionFakeBold() const
142 {
143 return isFakeBold_;
144 }
145 } // namespace TextEngine
146 } // namespace Rosen
147 } // namespace OHOS
148