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
34 /*! To get stream of the typeface
35 * \param[out] ttcIndex the index of the typeface in a ttc file returned to the caller
36 * \return The stream object of the typeface
37 */
onOpenStream(int * ttcIndex) const38 std::unique_ptr<SkStreamAsset> SkTypeface_OHOS::onOpenStream(int* ttcIndex) const
39 {
40 if (fontInfo) {
41 if (ttcIndex) {
42 *ttcIndex = fontInfo->index;
43 }
44 if (fontInfo->stream == nullptr) {
45 fontInfo->stream = SkStream::MakeFromFile(fontInfo->fname.c_str());
46 }
47 if (fontInfo->stream) {
48 return fontInfo->stream->duplicate();
49 }
50 }
51 return nullptr;
52 }
53
54 /*! To make font data from the typeface
55 * \return The object of SkFontData
56 */
onMakeFontData() const57 std::unique_ptr<SkFontData> SkTypeface_OHOS::onMakeFontData() const
58 {
59 if (fontInfo == nullptr) {
60 return nullptr;
61 }
62
63 if (fontInfo->stream.get() == nullptr) {
64 fontInfo->stream = SkStream::MakeFromFile(fontInfo->fname.c_str());
65 }
66 if (fontInfo->stream.get() == nullptr) {
67 return nullptr;
68 }
69 return std::make_unique<SkFontData>(fontInfo->stream->duplicate(), fontInfo->index,
70 fontInfo->axisSet.axis.data(), fontInfo->axisSet.axis.size());
71 }
72
73 /*! To get the font descriptor of the typeface
74 * \param[out] descriptor the font descriptor returned to the caller
75 * \param[out] isLocal the false to the caller
76 */
onGetFontDescriptor(SkFontDescriptor * descriptor,bool * isLocal) const77 void SkTypeface_OHOS::onGetFontDescriptor(SkFontDescriptor* descriptor, bool* isLocal) const
78 {
79 if (isLocal) {
80 *isLocal = false;
81 }
82 if (descriptor) {
83 SkString familyName;
84 onGetFamilyName(&familyName);
85 descriptor->setFamilyName(familyName.c_str());
86 descriptor->setStyle(this->fontStyle());
87 descriptor->setVariationCoordinates(fontInfo->axisSet.axis.size());
88 for (int i = 0; i < fontInfo->axisSet.axis.size(); i++) {
89 descriptor->getVariation()[i].axis = fontInfo->axisSet.range[i].fTag;
90 // The axis actual value need to dealt by SkFixedToFloat because the real-time value was
91 // changed in SkTypeface_FreeType::Scanner::computeAxisValues
92 descriptor->getVariation()[i].value = SkFixedToFloat(fontInfo->axisSet.axis[i]);
93 }
94 }
95 }
96
97 /*! To get the family name of the typeface
98 * \param[out] familyName the family name returned to the caller
99 */
onGetFamilyName(SkString * familyName) const100 void SkTypeface_OHOS::onGetFamilyName(SkString* familyName) const
101 {
102 if (familyName == nullptr) {
103 return;
104 }
105 if (specifiedName.size() > 0) {
106 *familyName = specifiedName;
107 } else {
108 if (fontInfo) {
109 *familyName = fontInfo->familyName;
110 }
111 }
112 }
113
114 /*! To clone a typeface from this typeface
115 * \param args the specified font arguments from which the new typeface is created
116 * \return The object of a new typeface
117 * \note The caller must call unref() on the returned object
118 */
onMakeClone(const SkFontArguments & args) const119 sk_sp<SkTypeface> SkTypeface_OHOS::onMakeClone(const SkFontArguments& args) const
120 {
121 int ttcIndex = args.getCollectionIndex();
122 auto stream = openStream(&ttcIndex);
123
124 FontInfo info(*(fontInfo.get()));
125 unsigned int axisCount = args.getVariationDesignPosition().coordinateCount;
126 if (axisCount > 0) {
127 SkTypeface_FreeType::Scanner fontScanner;
128 SkTypeface_FreeType::Scanner::AxisDefinitions axisDefs;
129 if (!fontScanner.scanFont(stream.get(), ttcIndex, &info.familyName, &info.style,
130 &info.isFixedWidth, &axisDefs)) {
131 return nullptr;
132 }
133 if (axisDefs.count() > 0) {
134 SkFixed axis[axisDefs.count()];
135 fontScanner.computeAxisValues(axisDefs, args.getVariationDesignPosition(),
136 axis, info.familyName);
137 info.setAxisSet(axisCount, axis, axisDefs.data());
138 info.style = info.computeFontStyle();
139 return sk_make_sp<SkTypeface_OHOS>(specifiedName, info);
140 }
141 }
142
143 return sk_ref_sp(this);
144 }
145
146 /*! To get the font information of the typeface
147 * \return The object of FontInfo
148 */
getFontInfo() const149 const FontInfo* SkTypeface_OHOS::getFontInfo() const
150 {
151 return fontInfo.get();
152 }
153