• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2023 Huawei Device Co., Ltd. All rights reserved
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "SkTypeface_ohos.h"
6 
7 #include "securec.h"
8 
9 #include "SkFontDescriptor.h"
10 #include "SkFontHost_FreeType_common.h"
11 #include "SkTArray.h"
12 
13 /*! Constructor
14  * \param familyName the specified family name for the typeface
15  * \param info the font information for the typeface
16  */
SkTypeface_OHOS(const SkString & familyName,FontInfo & info)17 SkTypeface_OHOS::SkTypeface_OHOS(const SkString& familyName, FontInfo& info)
18     : SkTypeface_FreeType(info.style, info.isFixedWidth),
19       specifiedName(familyName)
20 {
21     fontInfo = std::make_unique<FontInfo>(std::move(info));
22 }
23 
24 /*! Constructor
25  * \param info the font information for the typeface
26  */
SkTypeface_OHOS(FontInfo & info)27 SkTypeface_OHOS::SkTypeface_OHOS(FontInfo& info)
28     : SkTypeface_FreeType(info.style, info.isFixedWidth)
29 {
30     specifiedName.reset();
31     fontInfo = std::make_unique<FontInfo>(std::move(info));
32 }
33 
readStreamFromFile(const std::unique_ptr<FontInfo> & fontInfo) const34 void SkTypeface_OHOS::readStreamFromFile(const std::unique_ptr<FontInfo>& fontInfo) const
35 {
36     if (fontInfo->stream != nullptr) {
37         return;
38     }
39     std::lock_guard<std::mutex> lock(mutex_);
40     if (fontInfo->stream == nullptr) {
41         fontInfo->stream = SkStream::MakeFromFile(fontInfo->fname.c_str());
42     }
43 }
44 
45 /*! To get stream of the typeface
46  * \param[out] ttcIndex the index of the typeface in a ttc file returned to the caller
47  * \return The stream object of the typeface
48  */
onOpenStream(int * ttcIndex) const49 std::unique_ptr<SkStreamAsset> SkTypeface_OHOS::onOpenStream(int* ttcIndex) const
50 {
51     if (fontInfo) {
52         if (ttcIndex) {
53             *ttcIndex = fontInfo->index;
54         }
55         readStreamFromFile(fontInfo);
56         if (fontInfo->stream) {
57             return fontInfo->stream->duplicate();
58         }
59     }
60     return nullptr;
61 }
62 
63 /*! To make font data from the typeface
64  * \return The object of SkFontData
65  */
onMakeFontData() const66 std::unique_ptr<SkFontData> SkTypeface_OHOS::onMakeFontData() const
67 {
68     if (fontInfo == nullptr) {
69         return nullptr;
70     }
71     readStreamFromFile(fontInfo);
72     if (fontInfo->stream == nullptr) {
73         return nullptr;
74     }
75     return std::make_unique<SkFontData>(fontInfo->stream->duplicate(), fontInfo->index,
76                fontInfo->axisSet.axis.data(), fontInfo->axisSet.axis.size());
77 }
78 
79 /*! To get the font descriptor of the typeface
80  * \param[out] descriptor the font descriptor returned to the caller
81  * \param[out] isLocal the false to the caller
82  */
onGetFontDescriptor(SkFontDescriptor * descriptor,bool * isLocal) const83 void SkTypeface_OHOS::onGetFontDescriptor(SkFontDescriptor* descriptor, bool* isLocal) const
84 {
85     if (isLocal) {
86         *isLocal = false;
87     }
88     if (descriptor) {
89         SkString familyName;
90         onGetFamilyName(&familyName);
91         descriptor->setFamilyName(familyName.c_str());
92         descriptor->setStyle(this->fontStyle());
93         descriptor->setVariationCoordinates(fontInfo->axisSet.axis.size());
94         for (int i = 0; i < fontInfo->axisSet.axis.size(); i++) {
95             descriptor->getVariation()[i].axis = fontInfo->axisSet.range[i].fTag;
96             // The axis actual value need to dealt by SkFixedToFloat because the real-time value was
97             // changed in SkTypeface_FreeType::Scanner::computeAxisValues
98             descriptor->getVariation()[i].value = SkFixedToFloat(fontInfo->axisSet.axis[i]);
99         }
100     }
101 }
102 
103 /*! To get the family name of the typeface
104  * \param[out] familyName the family name returned to the caller
105  */
onGetFamilyName(SkString * familyName) const106 void SkTypeface_OHOS::onGetFamilyName(SkString* familyName) const
107 {
108     if (familyName == nullptr) {
109         return;
110     }
111     if (specifiedName.size() > 0) {
112         *familyName = specifiedName;
113     } else {
114         if (fontInfo) {
115             *familyName = fontInfo->familyName;
116         }
117     }
118 }
119 
120 #ifdef OHOS_SUPPORT
onGetFontPath(SkString * path) const121 void SkTypeface_OHOS::onGetFontPath(SkString* path) const
122 {
123     if (path == nullptr) {
124         return;
125     }
126     if (fontInfo != nullptr) {
127         *path = fontInfo->fname;
128     }
129 }
130 #endif
131 
132 /*! To clone a typeface from this typeface
133  * \param args the specified font arguments from which the new typeface is created
134  * \return The object of a new typeface
135  * \note The caller must call unref() on the returned object
136  */
onMakeClone(const SkFontArguments & args) const137 sk_sp<SkTypeface> SkTypeface_OHOS::onMakeClone(const SkFontArguments& args) const
138 {
139     int ttcIndex = args.getCollectionIndex();
140     auto stream = openStream(&ttcIndex);
141 
142     FontInfo info(*(fontInfo.get()));
143     unsigned int axisCount = args.getVariationDesignPosition().coordinateCount;
144     if (axisCount > 0) {
145         SkTypeface_FreeType::Scanner fontScanner;
146         SkTypeface_FreeType::Scanner::AxisDefinitions axisDefs;
147         if (!fontScanner.scanFont(stream.get(), ttcIndex, &info.familyName, &info.style,
148             &info.isFixedWidth, &axisDefs)) {
149             return nullptr;
150         }
151         if (axisDefs.count() > 0) {
152             SkFixed axis[axisDefs.count()];
153             fontScanner.computeAxisValues(axisDefs, args.getVariationDesignPosition(),
154                 axis, info.familyName);
155             info.setAxisSet(axisCount, axis, axisDefs.data());
156             info.style = info.computeFontStyle();
157             return sk_make_sp<SkTypeface_OHOS>(specifiedName, info);
158         }
159     }
160 
161     return sk_ref_sp(this);
162 }
163 
164 /*! To get the font information of the typeface
165  * \return The object of FontInfo
166  */
getFontInfo() const167 const FontInfo* SkTypeface_OHOS::getFontInfo() const
168 {
169     return fontInfo.get();
170 }
171