blob: bd3b7c93466cc0daa7f949d3dbd7bfdd344a9905 [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>
Seigo Nonakad5ecaba2021-05-27 15:49:37 -070038#include <minikin/SystemFonts.h>
Jagadeesh Pakaravoorb624af32020-05-01 00:01:40 +000039#include <ui/FatVector.h>
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070040
41#include <memory>
42
43namespace android {
44
45struct NativeFontBuilder {
46 std::vector<minikin::FontVariation> axes;
47};
48
49static inline NativeFontBuilder* toBuilder(jlong ptr) {
50 return reinterpret_cast<NativeFontBuilder*>(ptr);
51}
52
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070053static void releaseFont(jlong font) {
54 delete reinterpret_cast<FontWrapper*>(font);
55}
56
57static void release_global_ref(const void* /*data*/, void* context) {
Derek Sollenbergerc5882c42019-10-25 11:11:32 -040058 JNIEnv* env = GraphicsJNI::getJNIEnv();
59 bool needToAttach = (env == nullptr);
60 if (needToAttach) {
61 env = GraphicsJNI::attachJNIEnv("release_font_data");
62 if (env == nullptr) {
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070063 ALOGE("failed to attach to thread to release global ref.");
64 return;
65 }
66 }
67
68 jobject obj = reinterpret_cast<jobject>(context);
69 env->DeleteGlobalRef(obj);
70}
71
72// Regular JNI
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070073static jlong Font_Builder_initBuilder(JNIEnv*, jobject) {
74 return reinterpret_cast<jlong>(new NativeFontBuilder());
75}
76
77// Critical Native
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +010078static void Font_Builder_addAxis(CRITICAL_JNI_PARAMS_COMMA jlong builderPtr, jint tag, jfloat value) {
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070079 toBuilder(builderPtr)->axes.emplace_back(static_cast<minikin::AxisTag>(tag), value);
80}
81
82// Regular JNI
83static jlong Font_Builder_build(JNIEnv* env, jobject clazz, jlong builderPtr, jobject buffer,
Seigo Nonaka99c07562021-02-03 21:37:57 -080084 jstring filePath, jstring langTags, jint weight, jboolean italic,
85 jint ttcIndex) {
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070086 NPE_CHECK_RETURN_ZERO(env, buffer);
87 std::unique_ptr<NativeFontBuilder> builder(toBuilder(builderPtr));
88 const void* fontPtr = env->GetDirectBufferAddress(buffer);
89 if (fontPtr == nullptr) {
90 jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer");
91 return 0;
92 }
93 jlong fontSize = env->GetDirectBufferCapacity(buffer);
94 if (fontSize <= 0) {
95 jniThrowException(env, "java/lang/IllegalArgumentException",
96 "buffer size must not be zero or negative");
97 return 0;
98 }
Seigo Nonaka54c6a272018-10-25 15:44:32 -070099 ScopedUtfChars fontPath(env, filePath);
Seigo Nonaka99c07562021-02-03 21:37:57 -0800100 ScopedUtfChars langTagStr(env, langTags);
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700101 jobject fontRef = MakeGlobalRefOrDie(env, buffer);
102 sk_sp<SkData> data(SkData::MakeWithProc(fontPtr, fontSize,
103 release_global_ref, reinterpret_cast<void*>(fontRef)));
Kohsuke Yatoh1ca390e2020-11-06 16:21:30 -0800104 std::shared_ptr<minikin::MinikinFont> minikinFont = fonts::createMinikinFontSkia(
105 std::move(data), std::string_view(fontPath.c_str(), fontPath.size()),
106 fontPtr, fontSize, ttcIndex, builder->axes);
107 if (minikinFont == nullptr) {
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700108 jniThrowException(env, "java/lang/IllegalArgumentException",
109 "Failed to create internal object. maybe invalid font data.");
110 return 0;
111 }
Seigo Nonaka99c07562021-02-03 21:37:57 -0800112 uint32_t localeListId = minikin::registerLocaleList(langTagStr.c_str());
113 std::shared_ptr<minikin::Font> font =
114 minikin::Font::Builder(minikinFont)
115 .setWeight(weight)
116 .setSlant(static_cast<minikin::FontStyle::Slant>(italic))
117 .setLocaleListId(localeListId)
118 .build();
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700119 return reinterpret_cast<jlong>(new FontWrapper(std::move(font)));
120}
121
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700122// Fast Native
123static jlong Font_Builder_clone(JNIEnv* env, jobject clazz, jlong fontPtr, jlong builderPtr,
124 jint weight, jboolean italic, jint ttcIndex) {
125 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
Seigo Nonaka760d3512020-10-01 12:29:03 -0700126 MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->typeface().get());
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700127 std::unique_ptr<NativeFontBuilder> builder(toBuilder(builderPtr));
128
129 // Reconstruct SkTypeface with different arguments from existing SkTypeface.
130 FatVector<SkFontArguments::VariationPosition::Coordinate, 2> skVariation;
131 for (const auto& axis : builder->axes) {
132 skVariation.push_back({axis.axisTag, axis.value});
133 }
134 SkFontArguments args;
135 args.setCollectionIndex(ttcIndex);
136 args.setVariationDesignPosition({skVariation.data(), static_cast<int>(skVariation.size())});
137
138 sk_sp<SkTypeface> newTypeface = minikinSkia->GetSkTypeface()->makeClone(args);
139
140 std::shared_ptr<minikin::MinikinFont> newMinikinFont = std::make_shared<MinikinFontSkia>(
Seigo Nonaka5dd6dd52021-02-11 20:02:27 -0800141 std::move(newTypeface), minikinSkia->GetSourceId(), minikinSkia->GetFontData(),
142 minikinSkia->GetFontSize(), minikinSkia->getFilePath(), minikinSkia->GetFontIndex(),
143 builder->axes);
Seigo Nonaka760d3512020-10-01 12:29:03 -0700144 std::shared_ptr<minikin::Font> newFont = minikin::Font::Builder(newMinikinFont)
145 .setWeight(weight)
146 .setSlant(static_cast<minikin::FontStyle::Slant>(italic))
147 .build();
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700148 return reinterpret_cast<jlong>(new FontWrapper(std::move(newFont)));
149}
150
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700151///////////////////////////////////////////////////////////////////////////////
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800152// Font JNI functions
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700153
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700154// Fast Native
155static jfloat Font_getGlyphBounds(JNIEnv* env, jobject, jlong fontHandle, jint glyphId,
156 jlong paintHandle, jobject rect) {
157 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle);
Seigo Nonaka760d3512020-10-01 12:29:03 -0700158 MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->typeface().get());
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700159 Paint* paint = reinterpret_cast<Paint*>(paintHandle);
160
161 SkFont* skFont = &paint->getSkFont();
162 // We don't use populateSkFont since it is designed to be used for layout result with addressing
163 // auto fake-bolding.
164 skFont->setTypeface(minikinSkia->RefSkTypeface());
165
166 uint16_t glyph16 = glyphId;
167 SkRect skBounds;
168 SkScalar skWidth;
169 skFont->getWidthsBounds(&glyph16, 1, &skWidth, &skBounds, nullptr);
170 GraphicsJNI::rect_to_jrectf(skBounds, env, rect);
171 return SkScalarToFloat(skWidth);
172}
173
174// Fast Native
175static jfloat Font_getFontMetrics(JNIEnv* env, jobject, jlong fontHandle, jlong paintHandle,
176 jobject metricsObj) {
177 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle);
Seigo Nonaka760d3512020-10-01 12:29:03 -0700178 MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->typeface().get());
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700179 Paint* paint = reinterpret_cast<Paint*>(paintHandle);
180
181 SkFont* skFont = &paint->getSkFont();
182 // We don't use populateSkFont since it is designed to be used for layout result with addressing
183 // auto fake-bolding.
184 skFont->setTypeface(minikinSkia->RefSkTypeface());
185
186 SkFontMetrics metrics;
187 SkScalar spacing = skFont->getMetrics(&metrics);
188 GraphicsJNI::set_metrics(env, metricsObj, metrics);
189 return spacing;
190}
191
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700192// Critical Native
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800193static jlong Font_getMinikinFontPtr(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
194 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
195 return reinterpret_cast<jlong>(font->font->typeface().get());
Seigo Nonaka760d3512020-10-01 12:29:03 -0700196}
197
Seigo Nonaka31bf8602020-10-14 15:04:01 -0700198// Critical Native
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800199static jlong Font_cloneFont(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
200 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
201 std::shared_ptr<minikin::Font> ref = font->font;
202 return reinterpret_cast<jlong>(new FontWrapper(std::move(ref)));
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700203}
204
205// Fast Native
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800206static jobject Font_newByteBuffer(JNIEnv* env, jobject, jlong fontPtr) {
207 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
208 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
209 return env->NewDirectByteBuffer(const_cast<void*>(minikinFont->GetFontData()),
210 minikinFont->GetFontSize());
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700211}
212
213// Critical Native
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800214static jlong Font_getBufferAddress(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
215 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
216 return reinterpret_cast<jlong>(font->font->typeface()->GetFontData());
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700217}
218
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800219// Critical Native
Jerome Gaillardb71861c2021-02-09 13:10:49 +0000220static jlong Font_getReleaseNativeFontFunc(CRITICAL_JNI_PARAMS) {
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800221 return reinterpret_cast<jlong>(releaseFont);
222}
223
224// Fast Native
225static jstring Font_getFontPath(JNIEnv* env, jobject, jlong fontPtr) {
226 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
227 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
228 const std::string& path = minikinFont->GetFontPath();
229 if (path.empty()) {
230 return nullptr;
231 }
232 return env->NewStringUTF(path.c_str());
233}
234
235// Fast Native
236static jstring Font_getLocaleList(JNIEnv* env, jobject, jlong fontPtr) {
237 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
238 uint32_t localeListId = font->font->getLocaleListId();
239 if (localeListId == 0) {
240 return nullptr;
241 }
242 std::string langTags = minikin::getLocaleString(localeListId);
243 if (langTags.empty()) {
244 return nullptr;
245 }
246 return env->NewStringUTF(langTags.c_str());
247}
248
249// Critical Native
250static jint Font_getPackedStyle(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
251 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
252 uint32_t weight = font->font->style().weight();
253 uint32_t isItalic = font->font->style().slant() == minikin::FontStyle::Slant::ITALIC ? 1 : 0;
254 return (isItalic << 16) | weight;
255}
256
257// Critical Native
258static jint Font_getIndex(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
259 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
260 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
261 return minikinFont->GetFontIndex();
262}
263
264// Critical Native
265static jint Font_getAxisCount(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
266 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
267 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
268 return minikinFont->GetAxes().size();
269}
270
271// Critical Native
272static jlong Font_getAxisInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr, jint index) {
273 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
274 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
275 minikin::FontVariation var = minikinFont->GetAxes().at(index);
276 uint32_t floatBinary = *reinterpret_cast<const uint32_t*>(&var.value);
277 return (static_cast<uint64_t>(var.axisTag) << 32) | static_cast<uint64_t>(floatBinary);
278}
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700279
Seigo Nonaka5dd6dd52021-02-11 20:02:27 -0800280// Critical Native
281static jint Font_getSourceId(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
282 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
283 return font->font->typeface()->GetSourceId();
284}
285
Seigo Nonakad5ecaba2021-05-27 15:49:37 -0700286static jlongArray Font_getAvailableFontSet(JNIEnv* env, jobject) {
287 std::vector<jlong> refArray;
288 minikin::SystemFonts::getFontSet(
289 [&refArray](const std::vector<std::shared_ptr<minikin::Font>>& fontSet) {
290 refArray.reserve(fontSet.size());
291 for (const auto& font : fontSet) {
292 std::shared_ptr<minikin::Font> fontRef = font;
293 refArray.push_back(
294 reinterpret_cast<jlong>(new FontWrapper(std::move(fontRef))));
295 }
296 });
297 jlongArray r = env->NewLongArray(refArray.size());
298 env->SetLongArrayRegion(r, 0, refArray.size(), refArray.data());
299 return r;
300}
301
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800302// Fast Native
303static jlong FontFileUtil_getFontRevision(JNIEnv* env, jobject, jobject buffer, jint index) {
304 NPE_CHECK_RETURN_ZERO(env, buffer);
305 const void* fontPtr = env->GetDirectBufferAddress(buffer);
306 if (fontPtr == nullptr) {
307 jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer");
308 return 0;
309 }
310 jlong fontSize = env->GetDirectBufferCapacity(buffer);
311 if (fontSize <= 0) {
312 jniThrowException(env, "java/lang/IllegalArgumentException",
313 "buffer size must not be zero or negative");
314 return 0;
315 }
316 minikin::FontFileParser parser(fontPtr, fontSize, index);
317 std::optional<uint32_t> revision = parser.getFontRevision();
318 if (!revision.has_value()) {
319 return -1L;
320 }
321 return revision.value();
322}
323
324static jstring FontFileUtil_getFontPostScriptName(JNIEnv* env, jobject, jobject buffer,
325 jint index) {
326 NPE_CHECK_RETURN_ZERO(env, buffer);
327 const void* fontPtr = env->GetDirectBufferAddress(buffer);
328 if (fontPtr == nullptr) {
329 jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer");
330 return nullptr;
331 }
332 jlong fontSize = env->GetDirectBufferCapacity(buffer);
333 if (fontSize <= 0) {
334 jniThrowException(env, "java/lang/IllegalArgumentException",
335 "buffer size must not be zero or negative");
336 return nullptr;
337 }
338 minikin::FontFileParser parser(fontPtr, fontSize, index);
339 std::optional<std::string> psName = parser.getPostScriptName();
340 if (!psName.has_value()) {
341 return nullptr; // null
342 }
343 return env->NewStringUTF(psName->c_str());
344}
Seigo Nonaka9d5ab7e2021-01-20 22:50:09 -0800345
346static jint FontFileUtil_isPostScriptType1Font(JNIEnv* env, jobject, jobject buffer, jint index) {
347 NPE_CHECK_RETURN_ZERO(env, buffer);
348 const void* fontPtr = env->GetDirectBufferAddress(buffer);
349 if (fontPtr == nullptr) {
350 jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer");
351 return -1;
352 }
353 jlong fontSize = env->GetDirectBufferCapacity(buffer);
354 if (fontSize <= 0) {
355 jniThrowException(env, "java/lang/IllegalArgumentException",
356 "buffer size must not be zero or negative");
357 return -1;
358 }
359 minikin::FontFileParser parser(fontPtr, fontSize, index);
360 std::optional<bool> isType1 = parser.isPostScriptType1Font();
361 if (!isType1.has_value()) {
362 return -1; // not an OpenType font. HarfBuzz failed to parse it.
363 }
364 return isType1.value();
365}
366
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800367///////////////////////////////////////////////////////////////////////////////
368
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700369static const JNINativeMethod gFontBuilderMethods[] = {
Seigo Nonaka99c07562021-02-03 21:37:57 -0800370 {"nInitBuilder", "()J", (void*)Font_Builder_initBuilder},
371 {"nAddAxis", "(JIF)V", (void*)Font_Builder_addAxis},
372 {"nBuild", "(JLjava/nio/ByteBuffer;Ljava/lang/String;Ljava/lang/String;IZI)J",
373 (void*)Font_Builder_build},
374 {"nClone", "(JJIZI)J", (void*)Font_Builder_clone},
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700375};
376
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700377static const JNINativeMethod gFontMethods[] = {
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800378 {"nGetMinikinFontPtr", "(J)J", (void*)Font_getMinikinFontPtr},
379 {"nCloneFont", "(J)J", (void*)Font_cloneFont},
380 {"nNewByteBuffer", "(J)Ljava/nio/ByteBuffer;", (void*)Font_newByteBuffer},
381 {"nGetBufferAddress", "(J)J", (void*)Font_getBufferAddress},
382 {"nGetReleaseNativeFont", "()J", (void*)Font_getReleaseNativeFontFunc},
383 {"nGetGlyphBounds", "(JIJLandroid/graphics/RectF;)F", (void*)Font_getGlyphBounds},
384 {"nGetFontMetrics", "(JJLandroid/graphics/Paint$FontMetrics;)F",
385 (void*)Font_getFontMetrics},
386 {"nGetFontPath", "(J)Ljava/lang/String;", (void*)Font_getFontPath},
387 {"nGetLocaleList", "(J)Ljava/lang/String;", (void*)Font_getLocaleList},
388 {"nGetPackedStyle", "(J)I", (void*)Font_getPackedStyle},
389 {"nGetIndex", "(J)I", (void*)Font_getIndex},
390 {"nGetAxisCount", "(J)I", (void*)Font_getAxisCount},
391 {"nGetAxisInfo", "(JI)J", (void*)Font_getAxisInfo},
Seigo Nonaka5dd6dd52021-02-11 20:02:27 -0800392 {"nGetSourceId", "(J)I", (void*)Font_getSourceId},
Seigo Nonakad5ecaba2021-05-27 15:49:37 -0700393
394 // System font accessors
395 {"nGetAvailableFontSet", "()[J", (void*)Font_getAvailableFontSet},
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700396};
397
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800398static const JNINativeMethod gFontFileUtilMethods[] = {
399 { "nGetFontRevision", "(Ljava/nio/ByteBuffer;I)J", (void*) FontFileUtil_getFontRevision },
400 { "nGetFontPostScriptName", "(Ljava/nio/ByteBuffer;I)Ljava/lang/String;",
401 (void*) FontFileUtil_getFontPostScriptName },
Seigo Nonaka9d5ab7e2021-01-20 22:50:09 -0800402 { "nIsPostScriptType1Font", "(Ljava/nio/ByteBuffer;I)I",
403 (void*) FontFileUtil_isPostScriptType1Font },
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800404};
405
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700406int register_android_graphics_fonts_Font(JNIEnv* env) {
407 return RegisterMethodsOrDie(env, "android/graphics/fonts/Font$Builder", gFontBuilderMethods,
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700408 NELEM(gFontBuilderMethods)) +
409 RegisterMethodsOrDie(env, "android/graphics/fonts/Font", gFontMethods,
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700410 NELEM(gFontMethods)) +
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800411 RegisterMethodsOrDie(env, "android/graphics/fonts/FontFileUtil", gFontFileUtilMethods,
412 NELEM(gFontFileUtilMethods));
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700413}
414
Kohsuke Yatoh1ca390e2020-11-06 16:21:30 -0800415namespace fonts {
416
417std::shared_ptr<minikin::MinikinFont> createMinikinFontSkia(
418 sk_sp<SkData>&& data, std::string_view fontPath, const void *fontPtr, size_t fontSize,
419 int ttcIndex, const std::vector<minikin::FontVariation>& axes) {
420 FatVector<SkFontArguments::VariationPosition::Coordinate, 2> skVariation;
421 for (const auto& axis : axes) {
422 skVariation.push_back({axis.axisTag, axis.value});
423 }
424
425 std::unique_ptr<SkStreamAsset> fontData(new SkMemoryStream(std::move(data)));
426
427 SkFontArguments args;
428 args.setCollectionIndex(ttcIndex);
429 args.setVariationDesignPosition({skVariation.data(), static_cast<int>(skVariation.size())});
430
431 sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
432 sk_sp<SkTypeface> face(fm->makeFromStream(std::move(fontData), args));
433 if (face == nullptr) {
434 return nullptr;
435 }
Seigo Nonaka5dd6dd52021-02-11 20:02:27 -0800436 return std::make_shared<MinikinFontSkia>(std::move(face), getNewSourceId(), fontPtr, fontSize,
Kohsuke Yatoh1ca390e2020-11-06 16:21:30 -0800437 fontPath, ttcIndex, axes);
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700438}
Kohsuke Yatoh1ca390e2020-11-06 16:21:30 -0800439
Seigo Nonaka5dd6dd52021-02-11 20:02:27 -0800440int getNewSourceId() {
441 static std::atomic<int> sSourceId = {0};
442 return sSourceId++;
443}
444
Kohsuke Yatoh1ca390e2020-11-06 16:21:30 -0800445} // namespace fonts
446
447} // namespace android