blob: c8471a9b8feb75e3fa917e262329d2fdde5632d2 [file] [log] [blame]
Seigo Nonakaa1c21c02018-07-20 15:57:39 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Derek Sollenberger5368eda2019-10-25 11:20:03 -040017#undef LOG_TAG
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070018#define LOG_TAG "Minikin"
19
Kohsuke Yatoh1ca390e2020-11-06 16:21:30 -080020#include "Font.h"
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070021#include "SkData.h"
Seigo Nonaka1ed4f642020-09-10 17:19:34 -070022#include "SkFont.h"
23#include "SkFontMetrics.h"
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070024#include "SkFontMgr.h"
25#include "SkRefCnt.h"
26#include "SkTypeface.h"
27#include "GraphicsJNI.h"
28#include <nativehelper/ScopedUtfChars.h>
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070029#include "Utils.h"
30#include "FontUtils.h"
31
32#include <hwui/MinikinSkia.h>
Seigo Nonaka1ed4f642020-09-10 17:19:34 -070033#include <hwui/Paint.h>
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070034#include <hwui/Typeface.h>
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070035#include <minikin/FontFamily.h>
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -080036#include <minikin/FontFileParser.h>
Seigo Nonaka1dd39f32021-02-05 19:15:29 -080037#include <minikin/LocaleList.h>
Jagadeesh Pakaravoorb624af32020-05-01 00:01:40 +000038#include <ui/FatVector.h>
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070039
40#include <memory>
41
42namespace android {
43
44struct NativeFontBuilder {
45 std::vector<minikin::FontVariation> axes;
46};
47
48static inline NativeFontBuilder* toBuilder(jlong ptr) {
49 return reinterpret_cast<NativeFontBuilder*>(ptr);
50}
51
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070052static void releaseFont(jlong font) {
53 delete reinterpret_cast<FontWrapper*>(font);
54}
55
56static void release_global_ref(const void* /*data*/, void* context) {
Derek Sollenbergerc5882c42019-10-25 11:11:32 -040057 JNIEnv* env = GraphicsJNI::getJNIEnv();
58 bool needToAttach = (env == nullptr);
59 if (needToAttach) {
60 env = GraphicsJNI::attachJNIEnv("release_font_data");
61 if (env == nullptr) {
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070062 ALOGE("failed to attach to thread to release global ref.");
63 return;
64 }
65 }
66
67 jobject obj = reinterpret_cast<jobject>(context);
68 env->DeleteGlobalRef(obj);
69}
70
71// Regular JNI
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070072static jlong Font_Builder_initBuilder(JNIEnv*, jobject) {
73 return reinterpret_cast<jlong>(new NativeFontBuilder());
74}
75
76// Critical Native
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +010077static void Font_Builder_addAxis(CRITICAL_JNI_PARAMS_COMMA jlong builderPtr, jint tag, jfloat value) {
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070078 toBuilder(builderPtr)->axes.emplace_back(static_cast<minikin::AxisTag>(tag), value);
79}
80
81// Regular JNI
82static jlong Font_Builder_build(JNIEnv* env, jobject clazz, jlong builderPtr, jobject buffer,
Seigo Nonaka99c07562021-02-03 21:37:57 -080083 jstring filePath, jstring langTags, jint weight, jboolean italic,
84 jint ttcIndex) {
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070085 NPE_CHECK_RETURN_ZERO(env, buffer);
86 std::unique_ptr<NativeFontBuilder> builder(toBuilder(builderPtr));
87 const void* fontPtr = env->GetDirectBufferAddress(buffer);
88 if (fontPtr == nullptr) {
89 jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer");
90 return 0;
91 }
92 jlong fontSize = env->GetDirectBufferCapacity(buffer);
93 if (fontSize <= 0) {
94 jniThrowException(env, "java/lang/IllegalArgumentException",
95 "buffer size must not be zero or negative");
96 return 0;
97 }
Seigo Nonaka54c6a272018-10-25 15:44:32 -070098 ScopedUtfChars fontPath(env, filePath);
Seigo Nonaka99c07562021-02-03 21:37:57 -080099 ScopedUtfChars langTagStr(env, langTags);
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700100 jobject fontRef = MakeGlobalRefOrDie(env, buffer);
101 sk_sp<SkData> data(SkData::MakeWithProc(fontPtr, fontSize,
102 release_global_ref, reinterpret_cast<void*>(fontRef)));
Kohsuke Yatoh1ca390e2020-11-06 16:21:30 -0800103 std::shared_ptr<minikin::MinikinFont> minikinFont = fonts::createMinikinFontSkia(
104 std::move(data), std::string_view(fontPath.c_str(), fontPath.size()),
105 fontPtr, fontSize, ttcIndex, builder->axes);
106 if (minikinFont == nullptr) {
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700107 jniThrowException(env, "java/lang/IllegalArgumentException",
108 "Failed to create internal object. maybe invalid font data.");
109 return 0;
110 }
Seigo Nonaka99c07562021-02-03 21:37:57 -0800111 uint32_t localeListId = minikin::registerLocaleList(langTagStr.c_str());
112 std::shared_ptr<minikin::Font> font =
113 minikin::Font::Builder(minikinFont)
114 .setWeight(weight)
115 .setSlant(static_cast<minikin::FontStyle::Slant>(italic))
116 .setLocaleListId(localeListId)
117 .build();
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700118 return reinterpret_cast<jlong>(new FontWrapper(std::move(font)));
119}
120
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700121// Fast Native
122static jlong Font_Builder_clone(JNIEnv* env, jobject clazz, jlong fontPtr, jlong builderPtr,
123 jint weight, jboolean italic, jint ttcIndex) {
124 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
Seigo Nonaka760d3512020-10-01 12:29:03 -0700125 MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->typeface().get());
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700126 std::unique_ptr<NativeFontBuilder> builder(toBuilder(builderPtr));
127
128 // Reconstruct SkTypeface with different arguments from existing SkTypeface.
129 FatVector<SkFontArguments::VariationPosition::Coordinate, 2> skVariation;
130 for (const auto& axis : builder->axes) {
131 skVariation.push_back({axis.axisTag, axis.value});
132 }
133 SkFontArguments args;
134 args.setCollectionIndex(ttcIndex);
135 args.setVariationDesignPosition({skVariation.data(), static_cast<int>(skVariation.size())});
136
137 sk_sp<SkTypeface> newTypeface = minikinSkia->GetSkTypeface()->makeClone(args);
138
139 std::shared_ptr<minikin::MinikinFont> newMinikinFont = std::make_shared<MinikinFontSkia>(
140 std::move(newTypeface),
141 minikinSkia->GetFontData(),
142 minikinSkia->GetFontSize(),
143 minikinSkia->getFilePath(),
144 minikinSkia->GetFontIndex(),
145 builder->axes);
Seigo Nonaka760d3512020-10-01 12:29:03 -0700146 std::shared_ptr<minikin::Font> newFont = minikin::Font::Builder(newMinikinFont)
147 .setWeight(weight)
148 .setSlant(static_cast<minikin::FontStyle::Slant>(italic))
149 .build();
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700150 return reinterpret_cast<jlong>(new FontWrapper(std::move(newFont)));
151}
152
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700153///////////////////////////////////////////////////////////////////////////////
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800154// Font JNI functions
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700155
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700156// Fast Native
157static jfloat Font_getGlyphBounds(JNIEnv* env, jobject, jlong fontHandle, jint glyphId,
158 jlong paintHandle, jobject rect) {
159 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle);
Seigo Nonaka760d3512020-10-01 12:29:03 -0700160 MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->typeface().get());
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700161 Paint* paint = reinterpret_cast<Paint*>(paintHandle);
162
163 SkFont* skFont = &paint->getSkFont();
164 // We don't use populateSkFont since it is designed to be used for layout result with addressing
165 // auto fake-bolding.
166 skFont->setTypeface(minikinSkia->RefSkTypeface());
167
168 uint16_t glyph16 = glyphId;
169 SkRect skBounds;
170 SkScalar skWidth;
171 skFont->getWidthsBounds(&glyph16, 1, &skWidth, &skBounds, nullptr);
172 GraphicsJNI::rect_to_jrectf(skBounds, env, rect);
173 return SkScalarToFloat(skWidth);
174}
175
176// Fast Native
177static jfloat Font_getFontMetrics(JNIEnv* env, jobject, jlong fontHandle, jlong paintHandle,
178 jobject metricsObj) {
179 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle);
Seigo Nonaka760d3512020-10-01 12:29:03 -0700180 MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->typeface().get());
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700181 Paint* paint = reinterpret_cast<Paint*>(paintHandle);
182
183 SkFont* skFont = &paint->getSkFont();
184 // We don't use populateSkFont since it is designed to be used for layout result with addressing
185 // auto fake-bolding.
186 skFont->setTypeface(minikinSkia->RefSkTypeface());
187
188 SkFontMetrics metrics;
189 SkScalar spacing = skFont->getMetrics(&metrics);
190 GraphicsJNI::set_metrics(env, metricsObj, metrics);
191 return spacing;
192}
193
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700194// Critical Native
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800195static jlong Font_getMinikinFontPtr(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
196 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
197 return reinterpret_cast<jlong>(font->font->typeface().get());
Seigo Nonaka760d3512020-10-01 12:29:03 -0700198}
199
Seigo Nonaka31bf8602020-10-14 15:04:01 -0700200// Critical Native
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800201static jlong Font_cloneFont(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
202 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
203 std::shared_ptr<minikin::Font> ref = font->font;
204 return reinterpret_cast<jlong>(new FontWrapper(std::move(ref)));
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700205}
206
207// Fast Native
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800208static jobject Font_newByteBuffer(JNIEnv* env, jobject, jlong fontPtr) {
209 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
210 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
211 return env->NewDirectByteBuffer(const_cast<void*>(minikinFont->GetFontData()),
212 minikinFont->GetFontSize());
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700213}
214
215// Critical Native
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800216static jlong Font_getBufferAddress(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
217 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
218 return reinterpret_cast<jlong>(font->font->typeface()->GetFontData());
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700219}
220
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800221// Critical Native
Jerome Gaillardb71861c2021-02-09 13:10:49 +0000222static jlong Font_getReleaseNativeFontFunc(CRITICAL_JNI_PARAMS) {
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800223 return reinterpret_cast<jlong>(releaseFont);
224}
225
226// Fast Native
227static jstring Font_getFontPath(JNIEnv* env, jobject, jlong fontPtr) {
228 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
229 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
230 const std::string& path = minikinFont->GetFontPath();
231 if (path.empty()) {
232 return nullptr;
233 }
234 return env->NewStringUTF(path.c_str());
235}
236
237// Fast Native
238static jstring Font_getLocaleList(JNIEnv* env, jobject, jlong fontPtr) {
239 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
240 uint32_t localeListId = font->font->getLocaleListId();
241 if (localeListId == 0) {
242 return nullptr;
243 }
244 std::string langTags = minikin::getLocaleString(localeListId);
245 if (langTags.empty()) {
246 return nullptr;
247 }
248 return env->NewStringUTF(langTags.c_str());
249}
250
251// Critical Native
252static jint Font_getPackedStyle(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
253 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
254 uint32_t weight = font->font->style().weight();
255 uint32_t isItalic = font->font->style().slant() == minikin::FontStyle::Slant::ITALIC ? 1 : 0;
256 return (isItalic << 16) | weight;
257}
258
259// Critical Native
260static jint Font_getIndex(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
261 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
262 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
263 return minikinFont->GetFontIndex();
264}
265
266// Critical Native
267static jint Font_getAxisCount(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
268 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
269 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
270 return minikinFont->GetAxes().size();
271}
272
273// Critical Native
274static jlong Font_getAxisInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr, jint index) {
275 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
276 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
277 minikin::FontVariation var = minikinFont->GetAxes().at(index);
278 uint32_t floatBinary = *reinterpret_cast<const uint32_t*>(&var.value);
279 return (static_cast<uint64_t>(var.axisTag) << 32) | static_cast<uint64_t>(floatBinary);
280}
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700281
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800282// Fast Native
283static jlong FontFileUtil_getFontRevision(JNIEnv* env, jobject, jobject buffer, jint index) {
284 NPE_CHECK_RETURN_ZERO(env, buffer);
285 const void* fontPtr = env->GetDirectBufferAddress(buffer);
286 if (fontPtr == nullptr) {
287 jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer");
288 return 0;
289 }
290 jlong fontSize = env->GetDirectBufferCapacity(buffer);
291 if (fontSize <= 0) {
292 jniThrowException(env, "java/lang/IllegalArgumentException",
293 "buffer size must not be zero or negative");
294 return 0;
295 }
296 minikin::FontFileParser parser(fontPtr, fontSize, index);
297 std::optional<uint32_t> revision = parser.getFontRevision();
298 if (!revision.has_value()) {
299 return -1L;
300 }
301 return revision.value();
302}
303
304static jstring FontFileUtil_getFontPostScriptName(JNIEnv* env, jobject, jobject buffer,
305 jint index) {
306 NPE_CHECK_RETURN_ZERO(env, buffer);
307 const void* fontPtr = env->GetDirectBufferAddress(buffer);
308 if (fontPtr == nullptr) {
309 jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer");
310 return nullptr;
311 }
312 jlong fontSize = env->GetDirectBufferCapacity(buffer);
313 if (fontSize <= 0) {
314 jniThrowException(env, "java/lang/IllegalArgumentException",
315 "buffer size must not be zero or negative");
316 return nullptr;
317 }
318 minikin::FontFileParser parser(fontPtr, fontSize, index);
319 std::optional<std::string> psName = parser.getPostScriptName();
320 if (!psName.has_value()) {
321 return nullptr; // null
322 }
323 return env->NewStringUTF(psName->c_str());
324}
Seigo Nonaka9d5ab7e2021-01-20 22:50:09 -0800325
326static jint FontFileUtil_isPostScriptType1Font(JNIEnv* env, jobject, jobject buffer, jint index) {
327 NPE_CHECK_RETURN_ZERO(env, buffer);
328 const void* fontPtr = env->GetDirectBufferAddress(buffer);
329 if (fontPtr == nullptr) {
330 jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer");
331 return -1;
332 }
333 jlong fontSize = env->GetDirectBufferCapacity(buffer);
334 if (fontSize <= 0) {
335 jniThrowException(env, "java/lang/IllegalArgumentException",
336 "buffer size must not be zero or negative");
337 return -1;
338 }
339 minikin::FontFileParser parser(fontPtr, fontSize, index);
340 std::optional<bool> isType1 = parser.isPostScriptType1Font();
341 if (!isType1.has_value()) {
342 return -1; // not an OpenType font. HarfBuzz failed to parse it.
343 }
344 return isType1.value();
345}
346
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800347///////////////////////////////////////////////////////////////////////////////
348
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700349static const JNINativeMethod gFontBuilderMethods[] = {
Seigo Nonaka99c07562021-02-03 21:37:57 -0800350 {"nInitBuilder", "()J", (void*)Font_Builder_initBuilder},
351 {"nAddAxis", "(JIF)V", (void*)Font_Builder_addAxis},
352 {"nBuild", "(JLjava/nio/ByteBuffer;Ljava/lang/String;Ljava/lang/String;IZI)J",
353 (void*)Font_Builder_build},
354 {"nClone", "(JJIZI)J", (void*)Font_Builder_clone},
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700355};
356
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700357static const JNINativeMethod gFontMethods[] = {
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800358 {"nGetMinikinFontPtr", "(J)J", (void*)Font_getMinikinFontPtr},
359 {"nCloneFont", "(J)J", (void*)Font_cloneFont},
360 {"nNewByteBuffer", "(J)Ljava/nio/ByteBuffer;", (void*)Font_newByteBuffer},
361 {"nGetBufferAddress", "(J)J", (void*)Font_getBufferAddress},
362 {"nGetReleaseNativeFont", "()J", (void*)Font_getReleaseNativeFontFunc},
363 {"nGetGlyphBounds", "(JIJLandroid/graphics/RectF;)F", (void*)Font_getGlyphBounds},
364 {"nGetFontMetrics", "(JJLandroid/graphics/Paint$FontMetrics;)F",
365 (void*)Font_getFontMetrics},
366 {"nGetFontPath", "(J)Ljava/lang/String;", (void*)Font_getFontPath},
367 {"nGetLocaleList", "(J)Ljava/lang/String;", (void*)Font_getLocaleList},
368 {"nGetPackedStyle", "(J)I", (void*)Font_getPackedStyle},
369 {"nGetIndex", "(J)I", (void*)Font_getIndex},
370 {"nGetAxisCount", "(J)I", (void*)Font_getAxisCount},
371 {"nGetAxisInfo", "(JI)J", (void*)Font_getAxisInfo},
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700372};
373
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800374static const JNINativeMethod gFontFileUtilMethods[] = {
375 { "nGetFontRevision", "(Ljava/nio/ByteBuffer;I)J", (void*) FontFileUtil_getFontRevision },
376 { "nGetFontPostScriptName", "(Ljava/nio/ByteBuffer;I)Ljava/lang/String;",
377 (void*) FontFileUtil_getFontPostScriptName },
Seigo Nonaka9d5ab7e2021-01-20 22:50:09 -0800378 { "nIsPostScriptType1Font", "(Ljava/nio/ByteBuffer;I)I",
379 (void*) FontFileUtil_isPostScriptType1Font },
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800380};
381
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700382int register_android_graphics_fonts_Font(JNIEnv* env) {
383 return RegisterMethodsOrDie(env, "android/graphics/fonts/Font$Builder", gFontBuilderMethods,
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700384 NELEM(gFontBuilderMethods)) +
385 RegisterMethodsOrDie(env, "android/graphics/fonts/Font", gFontMethods,
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700386 NELEM(gFontMethods)) +
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800387 RegisterMethodsOrDie(env, "android/graphics/fonts/FontFileUtil", gFontFileUtilMethods,
388 NELEM(gFontFileUtilMethods));
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700389}
390
Kohsuke Yatoh1ca390e2020-11-06 16:21:30 -0800391namespace fonts {
392
393std::shared_ptr<minikin::MinikinFont> createMinikinFontSkia(
394 sk_sp<SkData>&& data, std::string_view fontPath, const void *fontPtr, size_t fontSize,
395 int ttcIndex, const std::vector<minikin::FontVariation>& axes) {
396 FatVector<SkFontArguments::VariationPosition::Coordinate, 2> skVariation;
397 for (const auto& axis : axes) {
398 skVariation.push_back({axis.axisTag, axis.value});
399 }
400
401 std::unique_ptr<SkStreamAsset> fontData(new SkMemoryStream(std::move(data)));
402
403 SkFontArguments args;
404 args.setCollectionIndex(ttcIndex);
405 args.setVariationDesignPosition({skVariation.data(), static_cast<int>(skVariation.size())});
406
407 sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
408 sk_sp<SkTypeface> face(fm->makeFromStream(std::move(fontData), args));
409 if (face == nullptr) {
410 return nullptr;
411 }
412 return std::make_shared<MinikinFontSkia>(std::move(face), fontPtr, fontSize,
413 fontPath, ttcIndex, axes);
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700414}
Kohsuke Yatoh1ca390e2020-11-06 16:21:30 -0800415
416} // namespace fonts
417
418} // namespace android