blob: 5a972f56ea879acf6a46fb99d53e909939488964 [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>(
Seigo Nonaka5dd6dd52021-02-11 20:02:27 -0800140 std::move(newTypeface), minikinSkia->GetSourceId(), minikinSkia->GetFontData(),
141 minikinSkia->GetFontSize(), minikinSkia->getFilePath(), minikinSkia->GetFontIndex(),
142 builder->axes);
Seigo Nonaka760d3512020-10-01 12:29:03 -0700143 std::shared_ptr<minikin::Font> newFont = minikin::Font::Builder(newMinikinFont)
144 .setWeight(weight)
145 .setSlant(static_cast<minikin::FontStyle::Slant>(italic))
146 .build();
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700147 return reinterpret_cast<jlong>(new FontWrapper(std::move(newFont)));
148}
149
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700150///////////////////////////////////////////////////////////////////////////////
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800151// Font JNI functions
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700152
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700153// Fast Native
154static jfloat Font_getGlyphBounds(JNIEnv* env, jobject, jlong fontHandle, jint glyphId,
155 jlong paintHandle, jobject rect) {
156 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle);
Seigo Nonaka760d3512020-10-01 12:29:03 -0700157 MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->typeface().get());
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700158 Paint* paint = reinterpret_cast<Paint*>(paintHandle);
159
160 SkFont* skFont = &paint->getSkFont();
161 // We don't use populateSkFont since it is designed to be used for layout result with addressing
162 // auto fake-bolding.
163 skFont->setTypeface(minikinSkia->RefSkTypeface());
164
165 uint16_t glyph16 = glyphId;
166 SkRect skBounds;
167 SkScalar skWidth;
168 skFont->getWidthsBounds(&glyph16, 1, &skWidth, &skBounds, nullptr);
169 GraphicsJNI::rect_to_jrectf(skBounds, env, rect);
170 return SkScalarToFloat(skWidth);
171}
172
173// Fast Native
174static jfloat Font_getFontMetrics(JNIEnv* env, jobject, jlong fontHandle, jlong paintHandle,
175 jobject metricsObj) {
176 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle);
Seigo Nonaka760d3512020-10-01 12:29:03 -0700177 MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->typeface().get());
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700178 Paint* paint = reinterpret_cast<Paint*>(paintHandle);
179
180 SkFont* skFont = &paint->getSkFont();
181 // We don't use populateSkFont since it is designed to be used for layout result with addressing
182 // auto fake-bolding.
183 skFont->setTypeface(minikinSkia->RefSkTypeface());
184
185 SkFontMetrics metrics;
186 SkScalar spacing = skFont->getMetrics(&metrics);
187 GraphicsJNI::set_metrics(env, metricsObj, metrics);
188 return spacing;
189}
190
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700191// Critical Native
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800192static jlong Font_getMinikinFontPtr(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
193 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
194 return reinterpret_cast<jlong>(font->font->typeface().get());
Seigo Nonaka760d3512020-10-01 12:29:03 -0700195}
196
Seigo Nonaka31bf8602020-10-14 15:04:01 -0700197// Critical Native
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800198static jlong Font_cloneFont(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
199 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
200 std::shared_ptr<minikin::Font> ref = font->font;
201 return reinterpret_cast<jlong>(new FontWrapper(std::move(ref)));
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700202}
203
204// Fast Native
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800205static jobject Font_newByteBuffer(JNIEnv* env, jobject, jlong fontPtr) {
206 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
207 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
208 return env->NewDirectByteBuffer(const_cast<void*>(minikinFont->GetFontData()),
209 minikinFont->GetFontSize());
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700210}
211
212// Critical Native
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800213static jlong Font_getBufferAddress(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
214 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
215 return reinterpret_cast<jlong>(font->font->typeface()->GetFontData());
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700216}
217
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800218// Critical Native
Jerome Gaillardb71861c2021-02-09 13:10:49 +0000219static jlong Font_getReleaseNativeFontFunc(CRITICAL_JNI_PARAMS) {
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800220 return reinterpret_cast<jlong>(releaseFont);
221}
222
223// Fast Native
224static jstring Font_getFontPath(JNIEnv* env, jobject, jlong fontPtr) {
225 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
226 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
227 const std::string& path = minikinFont->GetFontPath();
228 if (path.empty()) {
229 return nullptr;
230 }
231 return env->NewStringUTF(path.c_str());
232}
233
234// Fast Native
235static jstring Font_getLocaleList(JNIEnv* env, jobject, jlong fontPtr) {
236 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
237 uint32_t localeListId = font->font->getLocaleListId();
238 if (localeListId == 0) {
239 return nullptr;
240 }
241 std::string langTags = minikin::getLocaleString(localeListId);
242 if (langTags.empty()) {
243 return nullptr;
244 }
245 return env->NewStringUTF(langTags.c_str());
246}
247
248// Critical Native
249static jint Font_getPackedStyle(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
250 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
251 uint32_t weight = font->font->style().weight();
252 uint32_t isItalic = font->font->style().slant() == minikin::FontStyle::Slant::ITALIC ? 1 : 0;
253 return (isItalic << 16) | weight;
254}
255
256// Critical Native
257static jint Font_getIndex(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
258 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
259 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
260 return minikinFont->GetFontIndex();
261}
262
263// Critical Native
264static jint Font_getAxisCount(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
265 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
266 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
267 return minikinFont->GetAxes().size();
268}
269
270// Critical Native
271static jlong Font_getAxisInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr, jint index) {
272 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
273 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
274 minikin::FontVariation var = minikinFont->GetAxes().at(index);
275 uint32_t floatBinary = *reinterpret_cast<const uint32_t*>(&var.value);
276 return (static_cast<uint64_t>(var.axisTag) << 32) | static_cast<uint64_t>(floatBinary);
277}
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700278
Seigo Nonaka5dd6dd52021-02-11 20:02:27 -0800279// Critical Native
280static jint Font_getSourceId(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
281 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
282 return font->font->typeface()->GetSourceId();
283}
284
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800285// Fast Native
286static jlong FontFileUtil_getFontRevision(JNIEnv* env, jobject, jobject buffer, jint index) {
287 NPE_CHECK_RETURN_ZERO(env, buffer);
288 const void* fontPtr = env->GetDirectBufferAddress(buffer);
289 if (fontPtr == nullptr) {
290 jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer");
291 return 0;
292 }
293 jlong fontSize = env->GetDirectBufferCapacity(buffer);
294 if (fontSize <= 0) {
295 jniThrowException(env, "java/lang/IllegalArgumentException",
296 "buffer size must not be zero or negative");
297 return 0;
298 }
299 minikin::FontFileParser parser(fontPtr, fontSize, index);
300 std::optional<uint32_t> revision = parser.getFontRevision();
301 if (!revision.has_value()) {
302 return -1L;
303 }
304 return revision.value();
305}
306
307static jstring FontFileUtil_getFontPostScriptName(JNIEnv* env, jobject, jobject buffer,
308 jint index) {
309 NPE_CHECK_RETURN_ZERO(env, buffer);
310 const void* fontPtr = env->GetDirectBufferAddress(buffer);
311 if (fontPtr == nullptr) {
312 jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer");
313 return nullptr;
314 }
315 jlong fontSize = env->GetDirectBufferCapacity(buffer);
316 if (fontSize <= 0) {
317 jniThrowException(env, "java/lang/IllegalArgumentException",
318 "buffer size must not be zero or negative");
319 return nullptr;
320 }
321 minikin::FontFileParser parser(fontPtr, fontSize, index);
322 std::optional<std::string> psName = parser.getPostScriptName();
323 if (!psName.has_value()) {
324 return nullptr; // null
325 }
326 return env->NewStringUTF(psName->c_str());
327}
Seigo Nonaka9d5ab7e2021-01-20 22:50:09 -0800328
329static jint FontFileUtil_isPostScriptType1Font(JNIEnv* env, jobject, jobject buffer, jint index) {
330 NPE_CHECK_RETURN_ZERO(env, buffer);
331 const void* fontPtr = env->GetDirectBufferAddress(buffer);
332 if (fontPtr == nullptr) {
333 jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer");
334 return -1;
335 }
336 jlong fontSize = env->GetDirectBufferCapacity(buffer);
337 if (fontSize <= 0) {
338 jniThrowException(env, "java/lang/IllegalArgumentException",
339 "buffer size must not be zero or negative");
340 return -1;
341 }
342 minikin::FontFileParser parser(fontPtr, fontSize, index);
343 std::optional<bool> isType1 = parser.isPostScriptType1Font();
344 if (!isType1.has_value()) {
345 return -1; // not an OpenType font. HarfBuzz failed to parse it.
346 }
347 return isType1.value();
348}
349
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800350///////////////////////////////////////////////////////////////////////////////
351
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700352static const JNINativeMethod gFontBuilderMethods[] = {
Seigo Nonaka99c07562021-02-03 21:37:57 -0800353 {"nInitBuilder", "()J", (void*)Font_Builder_initBuilder},
354 {"nAddAxis", "(JIF)V", (void*)Font_Builder_addAxis},
355 {"nBuild", "(JLjava/nio/ByteBuffer;Ljava/lang/String;Ljava/lang/String;IZI)J",
356 (void*)Font_Builder_build},
357 {"nClone", "(JJIZI)J", (void*)Font_Builder_clone},
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700358};
359
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700360static const JNINativeMethod gFontMethods[] = {
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800361 {"nGetMinikinFontPtr", "(J)J", (void*)Font_getMinikinFontPtr},
362 {"nCloneFont", "(J)J", (void*)Font_cloneFont},
363 {"nNewByteBuffer", "(J)Ljava/nio/ByteBuffer;", (void*)Font_newByteBuffer},
364 {"nGetBufferAddress", "(J)J", (void*)Font_getBufferAddress},
365 {"nGetReleaseNativeFont", "()J", (void*)Font_getReleaseNativeFontFunc},
366 {"nGetGlyphBounds", "(JIJLandroid/graphics/RectF;)F", (void*)Font_getGlyphBounds},
367 {"nGetFontMetrics", "(JJLandroid/graphics/Paint$FontMetrics;)F",
368 (void*)Font_getFontMetrics},
369 {"nGetFontPath", "(J)Ljava/lang/String;", (void*)Font_getFontPath},
370 {"nGetLocaleList", "(J)Ljava/lang/String;", (void*)Font_getLocaleList},
371 {"nGetPackedStyle", "(J)I", (void*)Font_getPackedStyle},
372 {"nGetIndex", "(J)I", (void*)Font_getIndex},
373 {"nGetAxisCount", "(J)I", (void*)Font_getAxisCount},
374 {"nGetAxisInfo", "(JI)J", (void*)Font_getAxisInfo},
Seigo Nonaka5dd6dd52021-02-11 20:02:27 -0800375 {"nGetSourceId", "(J)I", (void*)Font_getSourceId},
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700376};
377
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800378static const JNINativeMethod gFontFileUtilMethods[] = {
379 { "nGetFontRevision", "(Ljava/nio/ByteBuffer;I)J", (void*) FontFileUtil_getFontRevision },
380 { "nGetFontPostScriptName", "(Ljava/nio/ByteBuffer;I)Ljava/lang/String;",
381 (void*) FontFileUtil_getFontPostScriptName },
Seigo Nonaka9d5ab7e2021-01-20 22:50:09 -0800382 { "nIsPostScriptType1Font", "(Ljava/nio/ByteBuffer;I)I",
383 (void*) FontFileUtil_isPostScriptType1Font },
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800384};
385
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700386int register_android_graphics_fonts_Font(JNIEnv* env) {
387 return RegisterMethodsOrDie(env, "android/graphics/fonts/Font$Builder", gFontBuilderMethods,
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700388 NELEM(gFontBuilderMethods)) +
389 RegisterMethodsOrDie(env, "android/graphics/fonts/Font", gFontMethods,
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700390 NELEM(gFontMethods)) +
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800391 RegisterMethodsOrDie(env, "android/graphics/fonts/FontFileUtil", gFontFileUtilMethods,
392 NELEM(gFontFileUtilMethods));
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700393}
394
Kohsuke Yatoh1ca390e2020-11-06 16:21:30 -0800395namespace fonts {
396
397std::shared_ptr<minikin::MinikinFont> createMinikinFontSkia(
398 sk_sp<SkData>&& data, std::string_view fontPath, const void *fontPtr, size_t fontSize,
399 int ttcIndex, const std::vector<minikin::FontVariation>& axes) {
400 FatVector<SkFontArguments::VariationPosition::Coordinate, 2> skVariation;
401 for (const auto& axis : axes) {
402 skVariation.push_back({axis.axisTag, axis.value});
403 }
404
405 std::unique_ptr<SkStreamAsset> fontData(new SkMemoryStream(std::move(data)));
406
407 SkFontArguments args;
408 args.setCollectionIndex(ttcIndex);
409 args.setVariationDesignPosition({skVariation.data(), static_cast<int>(skVariation.size())});
410
411 sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
412 sk_sp<SkTypeface> face(fm->makeFromStream(std::move(fontData), args));
413 if (face == nullptr) {
414 return nullptr;
415 }
Seigo Nonaka5dd6dd52021-02-11 20:02:27 -0800416 return std::make_shared<MinikinFontSkia>(std::move(face), getNewSourceId(), fontPtr, fontSize,
Kohsuke Yatoh1ca390e2020-11-06 16:21:30 -0800417 fontPath, ttcIndex, axes);
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700418}
Kohsuke Yatoh1ca390e2020-11-06 16:21:30 -0800419
Seigo Nonaka5dd6dd52021-02-11 20:02:27 -0800420int getNewSourceId() {
421 static std::atomic<int> sSourceId = {0};
422 return sSourceId++;
423}
424
Kohsuke Yatoh1ca390e2020-11-06 16:21:30 -0800425} // namespace fonts
426
427} // namespace android