• 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 #include "texgine/utils/trace.h"
23 
24 namespace OHOS {
25 namespace Rosen {
26 namespace TextEngine {
MakeFromFile(const std::string & filename)27 std::unique_ptr<Typeface> Typeface::MakeFromFile(const std::string &filename)
28 {
29     auto st = TexgineTypeface::MakeFromFile(filename.c_str());
30     if (st == nullptr || st->GetTypeface() == nullptr) {
31         throw TEXGINE_EXCEPTION(API_FAILED);
32     }
33 
34     return std::make_unique<Typeface>(st);
35 }
36 
Typeface(std::shared_ptr<TexgineTypeface> tf)37 Typeface::Typeface(std::shared_ptr<TexgineTypeface> tf)
38     : typeface_(tf)
39 {
40     if (typeface_ != nullptr) {
41         typeface_->GetFamilyName(&name_);
42     }
43 }
44 
~Typeface()45 Typeface::~Typeface()
46 {
47     if (hblob_ != nullptr) {
48         hb_blob_destroy(hblob_);
49     }
50 }
51 
GetName()52 std::string Typeface::GetName()
53 {
54     return name_.ToString();
55 }
56 
ParseCmap(const std::shared_ptr<CmapParser> & parser)57 bool Typeface::ParseCmap(const std::shared_ptr<CmapParser> &parser)
58 {
59     LOGEX_FUNC_LINE(DEBUG) << "Parse Cmap: " << GetName();
60     ScopedTrace scope("Typeface::InitCmap");
61     auto tag = HB_TAG('c', 'm', 'a', 'p');
62     if (typeface_ == nullptr || typeface_->GetTypeface() == nullptr) {
63         LOGEX_FUNC_LINE(WARN) << "typeface_ is nullptr";
64         return false;
65     }
66 
67     auto size = typeface_->GetTableSize(tag);
68     if (size <= 0) {
69         LOGEX_FUNC_LINE(ERROR) << name_.ToString() << " haven't cmap";
70         throw TEXGINE_EXCEPTION(API_FAILED);
71     }
72 
73     cmapData_ = std::make_unique<char[]>(size);
74     auto retv = typeface_->GetTableData(tag, 0, size, cmapData_.get());
75     if (size != retv) {
76         LOGEX_FUNC_LINE(ERROR) << "getTableData failed size: " << size << ", retv: " << retv;
77         throw TEXGINE_EXCEPTION(API_FAILED);
78     }
79 
80     hblob_ = hb_blob_create(reinterpret_cast<const char *>(cmapData_.get()),
81         size, HB_MEMORY_MODE_WRITABLE, cmapData_.get(), nullptr);
82     if (hblob_ == nullptr) {
83         LOGEX_FUNC_LINE(ERROR) << "hblob_ is nullptr";
84         throw TEXGINE_EXCEPTION(API_FAILED);
85     }
86 
87     scope.Finish();
88     ScopedTrace scope2("Typeface::ParseCmap");
89     auto retval = parser->Parse(hb_blob_get_data(hblob_, nullptr), hb_blob_get_length(hblob_));
90     return retval == 0;
91 }
92 
Has(uint32_t ch)93 bool Typeface::Has(uint32_t ch)
94 {
95     while (cmapParser_ == nullptr) {
96         auto name = GetName();
97         auto it = cmapCache_.find(name);
98         if (it != cmapCache_.end()) {
99             cmapParser_ = cmapCache_[name];
100             break;
101         }
102 
103         auto parser = std::make_shared<CmapParser>();
104         if (ParseCmap(parser)) {
105             cmapParser_ = parser;
106             cmapCache_[name] = parser;
107         } else {
108             cmapCache_.erase(name);
109             return false;
110         }
111     }
112 
113     return cmapParser_->GetGlyphId(ch) != CmapParser::INVALID_GLYPH_ID;
114 }
115 } // namespace TextEngine
116 } // namespace Rosen
117 } // namespace OHOS
118