• 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 #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