blob: f17129c8d953bf83ddb5afe939a802f7b33482cb [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"
Kevin Lubick1175dc02022-02-28 12:41:27 -050025#include "SkRect.h"
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070026#include "SkRefCnt.h"
Kevin Lubick1175dc02022-02-28 12:41:27 -050027#include "SkScalar.h"
28#include "SkStream.h"
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070029#include "SkTypeface.h"
30#include "GraphicsJNI.h"
31#include <nativehelper/ScopedUtfChars.h>
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070032#include "Utils.h"
33#include "FontUtils.h"
34
35#include <hwui/MinikinSkia.h>
Seigo Nonaka1ed4f642020-09-10 17:19:34 -070036#include <hwui/Paint.h>
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070037#include <hwui/Typeface.h>
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070038#include <minikin/FontFamily.h>
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -080039#include <minikin/FontFileParser.h>
Seigo Nonaka1dd39f32021-02-05 19:15:29 -080040#include <minikin/LocaleList.h>
Seigo Nonakad5ecaba2021-05-27 15:49:37 -070041#include <minikin/SystemFonts.h>
Jagadeesh Pakaravoorb624af32020-05-01 00:01:40 +000042#include <ui/FatVector.h>
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070043
44#include <memory>
45
46namespace android {
47
48struct NativeFontBuilder {
49 std::vector<minikin::FontVariation> axes;
50};
51
52static inline NativeFontBuilder* toBuilder(jlong ptr) {
53 return reinterpret_cast<NativeFontBuilder*>(ptr);
54}
55
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070056static void releaseFont(jlong font) {
57 delete reinterpret_cast<FontWrapper*>(font);
58}
59
60static void release_global_ref(const void* /*data*/, void* context) {
Derek Sollenbergerc5882c42019-10-25 11:11:32 -040061 JNIEnv* env = GraphicsJNI::getJNIEnv();
62 bool needToAttach = (env == nullptr);
63 if (needToAttach) {
64 env = GraphicsJNI::attachJNIEnv("release_font_data");
65 if (env == nullptr) {
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070066 ALOGE("failed to attach to thread to release global ref.");
67 return;
68 }
69 }
70
71 jobject obj = reinterpret_cast<jobject>(context);
72 env->DeleteGlobalRef(obj);
73}
74
75// Regular JNI
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070076static jlong Font_Builder_initBuilder(JNIEnv*, jobject) {
77 return reinterpret_cast<jlong>(new NativeFontBuilder());
78}
79
80// Critical Native
Jerome Gaillard21e7e2d2019-05-14 14:34:46 +010081static void Font_Builder_addAxis(CRITICAL_JNI_PARAMS_COMMA jlong builderPtr, jint tag, jfloat value) {
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070082 toBuilder(builderPtr)->axes.emplace_back(static_cast<minikin::AxisTag>(tag), value);
83}
84
85// Regular JNI
86static jlong Font_Builder_build(JNIEnv* env, jobject clazz, jlong builderPtr, jobject buffer,
Seigo Nonaka99c07562021-02-03 21:37:57 -080087 jstring filePath, jstring langTags, jint weight, jboolean italic,
88 jint ttcIndex) {
Seigo Nonakaa1c21c02018-07-20 15:57:39 -070089 NPE_CHECK_RETURN_ZERO(env, buffer);
90 std::unique_ptr<NativeFontBuilder> builder(toBuilder(builderPtr));
91 const void* fontPtr = env->GetDirectBufferAddress(buffer);
92 if (fontPtr == nullptr) {
93 jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer");
94 return 0;
95 }
96 jlong fontSize = env->GetDirectBufferCapacity(buffer);
97 if (fontSize <= 0) {
98 jniThrowException(env, "java/lang/IllegalArgumentException",
99 "buffer size must not be zero or negative");
100 return 0;
101 }
Seigo Nonaka54c6a272018-10-25 15:44:32 -0700102 ScopedUtfChars fontPath(env, filePath);
Seigo Nonaka99c07562021-02-03 21:37:57 -0800103 ScopedUtfChars langTagStr(env, langTags);
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700104 jobject fontRef = MakeGlobalRefOrDie(env, buffer);
105 sk_sp<SkData> data(SkData::MakeWithProc(fontPtr, fontSize,
106 release_global_ref, reinterpret_cast<void*>(fontRef)));
Kohsuke Yatoh1ca390e2020-11-06 16:21:30 -0800107 std::shared_ptr<minikin::MinikinFont> minikinFont = fonts::createMinikinFontSkia(
108 std::move(data), std::string_view(fontPath.c_str(), fontPath.size()),
109 fontPtr, fontSize, ttcIndex, builder->axes);
110 if (minikinFont == nullptr) {
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700111 jniThrowException(env, "java/lang/IllegalArgumentException",
112 "Failed to create internal object. maybe invalid font data.");
113 return 0;
114 }
Seigo Nonaka99c07562021-02-03 21:37:57 -0800115 uint32_t localeListId = minikin::registerLocaleList(langTagStr.c_str());
116 std::shared_ptr<minikin::Font> font =
117 minikin::Font::Builder(minikinFont)
118 .setWeight(weight)
119 .setSlant(static_cast<minikin::FontStyle::Slant>(italic))
120 .setLocaleListId(localeListId)
121 .build();
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700122 return reinterpret_cast<jlong>(new FontWrapper(std::move(font)));
123}
124
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700125// Fast Native
126static jlong Font_Builder_clone(JNIEnv* env, jobject clazz, jlong fontPtr, jlong builderPtr,
127 jint weight, jboolean italic, jint ttcIndex) {
128 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
Seigo Nonaka760d3512020-10-01 12:29:03 -0700129 MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->typeface().get());
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700130 std::unique_ptr<NativeFontBuilder> builder(toBuilder(builderPtr));
131
132 // Reconstruct SkTypeface with different arguments from existing SkTypeface.
133 FatVector<SkFontArguments::VariationPosition::Coordinate, 2> skVariation;
134 for (const auto& axis : builder->axes) {
135 skVariation.push_back({axis.axisTag, axis.value});
136 }
137 SkFontArguments args;
138 args.setCollectionIndex(ttcIndex);
139 args.setVariationDesignPosition({skVariation.data(), static_cast<int>(skVariation.size())});
140
141 sk_sp<SkTypeface> newTypeface = minikinSkia->GetSkTypeface()->makeClone(args);
142
143 std::shared_ptr<minikin::MinikinFont> newMinikinFont = std::make_shared<MinikinFontSkia>(
Seigo Nonaka5dd6dd52021-02-11 20:02:27 -0800144 std::move(newTypeface), minikinSkia->GetSourceId(), minikinSkia->GetFontData(),
145 minikinSkia->GetFontSize(), minikinSkia->getFilePath(), minikinSkia->GetFontIndex(),
146 builder->axes);
Seigo Nonaka760d3512020-10-01 12:29:03 -0700147 std::shared_ptr<minikin::Font> newFont = minikin::Font::Builder(newMinikinFont)
148 .setWeight(weight)
149 .setSlant(static_cast<minikin::FontStyle::Slant>(italic))
150 .build();
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700151 return reinterpret_cast<jlong>(new FontWrapper(std::move(newFont)));
152}
153
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700154///////////////////////////////////////////////////////////////////////////////
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800155// Font JNI functions
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700156
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700157// Fast Native
158static jfloat Font_getGlyphBounds(JNIEnv* env, jobject, jlong fontHandle, jint glyphId,
159 jlong paintHandle, jobject rect) {
160 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle);
Seigo Nonaka760d3512020-10-01 12:29:03 -0700161 MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->typeface().get());
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700162 Paint* paint = reinterpret_cast<Paint*>(paintHandle);
163
164 SkFont* skFont = &paint->getSkFont();
165 // We don't use populateSkFont since it is designed to be used for layout result with addressing
166 // auto fake-bolding.
167 skFont->setTypeface(minikinSkia->RefSkTypeface());
168
169 uint16_t glyph16 = glyphId;
170 SkRect skBounds;
171 SkScalar skWidth;
172 skFont->getWidthsBounds(&glyph16, 1, &skWidth, &skBounds, nullptr);
173 GraphicsJNI::rect_to_jrectf(skBounds, env, rect);
174 return SkScalarToFloat(skWidth);
175}
176
177// Fast Native
178static jfloat Font_getFontMetrics(JNIEnv* env, jobject, jlong fontHandle, jlong paintHandle,
179 jobject metricsObj) {
180 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle);
Seigo Nonaka760d3512020-10-01 12:29:03 -0700181 MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->font->typeface().get());
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700182 Paint* paint = reinterpret_cast<Paint*>(paintHandle);
183
184 SkFont* skFont = &paint->getSkFont();
185 // We don't use populateSkFont since it is designed to be used for layout result with addressing
186 // auto fake-bolding.
187 skFont->setTypeface(minikinSkia->RefSkTypeface());
188
189 SkFontMetrics metrics;
190 SkScalar spacing = skFont->getMetrics(&metrics);
191 GraphicsJNI::set_metrics(env, metricsObj, metrics);
192 return spacing;
193}
194
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700195// Critical Native
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800196static jlong Font_getMinikinFontPtr(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
197 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
Kohsuke Yatoha3f5f222021-06-09 20:09:49 +0000198 return reinterpret_cast<jlong>(font->font.get());
Seigo Nonaka760d3512020-10-01 12:29:03 -0700199}
200
Seigo Nonaka31bf8602020-10-14 15:04:01 -0700201// Critical Native
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800202static jlong Font_cloneFont(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
203 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
204 std::shared_ptr<minikin::Font> ref = font->font;
205 return reinterpret_cast<jlong>(new FontWrapper(std::move(ref)));
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700206}
207
208// Fast Native
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800209static jobject Font_newByteBuffer(JNIEnv* env, jobject, jlong fontPtr) {
210 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
211 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
212 return env->NewDirectByteBuffer(const_cast<void*>(minikinFont->GetFontData()),
213 minikinFont->GetFontSize());
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700214}
215
216// Critical Native
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800217static jlong Font_getBufferAddress(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
218 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
219 return reinterpret_cast<jlong>(font->font->typeface()->GetFontData());
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700220}
221
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800222// Critical Native
Jerome Gaillardb71861c2021-02-09 13:10:49 +0000223static jlong Font_getReleaseNativeFontFunc(CRITICAL_JNI_PARAMS) {
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800224 return reinterpret_cast<jlong>(releaseFont);
225}
226
227// Fast Native
228static jstring Font_getFontPath(JNIEnv* env, jobject, jlong fontPtr) {
229 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
Kohsuke Yatoha3f5f222021-06-09 20:09:49 +0000230 minikin::BufferReader reader = font->font->typefaceMetadataReader();
Kohsuke Yatoh711a1202022-07-29 00:46:39 +0000231 if (reader.current() != nullptr) {
Kohsuke Yatoha3f5f222021-06-09 20:09:49 +0000232 std::string path = std::string(reader.readString());
233 if (path.empty()) {
234 return nullptr;
235 }
236 return env->NewStringUTF(path.c_str());
237 } else {
238 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
239 const std::string& path = minikinFont->GetFontPath();
240 if (path.empty()) {
241 return nullptr;
242 }
243 return env->NewStringUTF(path.c_str());
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800244 }
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800245}
246
247// Fast Native
248static jstring Font_getLocaleList(JNIEnv* env, jobject, jlong fontPtr) {
249 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
250 uint32_t localeListId = font->font->getLocaleListId();
251 if (localeListId == 0) {
252 return nullptr;
253 }
254 std::string langTags = minikin::getLocaleString(localeListId);
255 if (langTags.empty()) {
256 return nullptr;
257 }
258 return env->NewStringUTF(langTags.c_str());
259}
260
261// Critical Native
262static jint Font_getPackedStyle(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
263 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
264 uint32_t weight = font->font->style().weight();
265 uint32_t isItalic = font->font->style().slant() == minikin::FontStyle::Slant::ITALIC ? 1 : 0;
266 return (isItalic << 16) | weight;
267}
268
269// Critical Native
270static jint Font_getIndex(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
271 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
Kohsuke Yatoha3f5f222021-06-09 20:09:49 +0000272 minikin::BufferReader reader = font->font->typefaceMetadataReader();
Kohsuke Yatoh711a1202022-07-29 00:46:39 +0000273 if (reader.current() != nullptr) {
Kohsuke Yatoha3f5f222021-06-09 20:09:49 +0000274 reader.skipString(); // fontPath
275 return reader.read<int>();
276 } else {
277 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
278 return minikinFont->GetFontIndex();
279 }
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800280}
281
282// Critical Native
283static jint Font_getAxisCount(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
284 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
Kohsuke Yatoha3f5f222021-06-09 20:09:49 +0000285 minikin::BufferReader reader = font->font->typefaceMetadataReader();
Kohsuke Yatoh711a1202022-07-29 00:46:39 +0000286 if (reader.current() != nullptr) {
Kohsuke Yatoha3f5f222021-06-09 20:09:49 +0000287 reader.skipString(); // fontPath
288 reader.skip<int>(); // fontIndex
289 return reader.readArray<minikin::FontVariation>().second;
290 } else {
291 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
292 return minikinFont->GetAxes().size();
293 }
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800294}
295
296// Critical Native
297static jlong Font_getAxisInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr, jint index) {
298 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
Kohsuke Yatoha3f5f222021-06-09 20:09:49 +0000299 minikin::BufferReader reader = font->font->typefaceMetadataReader();
300 minikin::FontVariation var;
Kohsuke Yatoh711a1202022-07-29 00:46:39 +0000301 if (reader.current() != nullptr) {
Kohsuke Yatoha3f5f222021-06-09 20:09:49 +0000302 reader.skipString(); // fontPath
303 reader.skip<int>(); // fontIndex
304 var = reader.readArray<minikin::FontVariation>().first[index];
305 } else {
306 const std::shared_ptr<minikin::MinikinFont>& minikinFont = font->font->typeface();
307 var = minikinFont->GetAxes().at(index);
308 }
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800309 uint32_t floatBinary = *reinterpret_cast<const uint32_t*>(&var.value);
310 return (static_cast<uint64_t>(var.axisTag) << 32) | static_cast<uint64_t>(floatBinary);
311}
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700312
Seigo Nonaka5dd6dd52021-02-11 20:02:27 -0800313// Critical Native
314static jint Font_getSourceId(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
315 FontWrapper* font = reinterpret_cast<FontWrapper*>(fontPtr);
316 return font->font->typeface()->GetSourceId();
317}
318
Seigo Nonakad5ecaba2021-05-27 15:49:37 -0700319static jlongArray Font_getAvailableFontSet(JNIEnv* env, jobject) {
320 std::vector<jlong> refArray;
321 minikin::SystemFonts::getFontSet(
322 [&refArray](const std::vector<std::shared_ptr<minikin::Font>>& fontSet) {
323 refArray.reserve(fontSet.size());
324 for (const auto& font : fontSet) {
325 std::shared_ptr<minikin::Font> fontRef = font;
326 refArray.push_back(
327 reinterpret_cast<jlong>(new FontWrapper(std::move(fontRef))));
328 }
329 });
330 jlongArray r = env->NewLongArray(refArray.size());
331 env->SetLongArrayRegion(r, 0, refArray.size(), refArray.data());
332 return r;
333}
334
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800335// Fast Native
336static jlong FontFileUtil_getFontRevision(JNIEnv* env, jobject, jobject buffer, jint index) {
337 NPE_CHECK_RETURN_ZERO(env, buffer);
338 const void* fontPtr = env->GetDirectBufferAddress(buffer);
339 if (fontPtr == nullptr) {
340 jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer");
341 return 0;
342 }
343 jlong fontSize = env->GetDirectBufferCapacity(buffer);
344 if (fontSize <= 0) {
345 jniThrowException(env, "java/lang/IllegalArgumentException",
346 "buffer size must not be zero or negative");
347 return 0;
348 }
349 minikin::FontFileParser parser(fontPtr, fontSize, index);
350 std::optional<uint32_t> revision = parser.getFontRevision();
351 if (!revision.has_value()) {
352 return -1L;
353 }
354 return revision.value();
355}
356
357static jstring FontFileUtil_getFontPostScriptName(JNIEnv* env, jobject, jobject buffer,
358 jint index) {
359 NPE_CHECK_RETURN_ZERO(env, buffer);
360 const void* fontPtr = env->GetDirectBufferAddress(buffer);
361 if (fontPtr == nullptr) {
362 jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer");
363 return nullptr;
364 }
365 jlong fontSize = env->GetDirectBufferCapacity(buffer);
366 if (fontSize <= 0) {
367 jniThrowException(env, "java/lang/IllegalArgumentException",
368 "buffer size must not be zero or negative");
369 return nullptr;
370 }
371 minikin::FontFileParser parser(fontPtr, fontSize, index);
372 std::optional<std::string> psName = parser.getPostScriptName();
373 if (!psName.has_value()) {
374 return nullptr; // null
375 }
376 return env->NewStringUTF(psName->c_str());
377}
Seigo Nonaka9d5ab7e2021-01-20 22:50:09 -0800378
379static jint FontFileUtil_isPostScriptType1Font(JNIEnv* env, jobject, jobject buffer, jint index) {
380 NPE_CHECK_RETURN_ZERO(env, buffer);
381 const void* fontPtr = env->GetDirectBufferAddress(buffer);
382 if (fontPtr == nullptr) {
383 jniThrowException(env, "java/lang/IllegalArgumentException", "Not a direct buffer");
384 return -1;
385 }
386 jlong fontSize = env->GetDirectBufferCapacity(buffer);
387 if (fontSize <= 0) {
388 jniThrowException(env, "java/lang/IllegalArgumentException",
389 "buffer size must not be zero or negative");
390 return -1;
391 }
392 minikin::FontFileParser parser(fontPtr, fontSize, index);
393 std::optional<bool> isType1 = parser.isPostScriptType1Font();
394 if (!isType1.has_value()) {
395 return -1; // not an OpenType font. HarfBuzz failed to parse it.
396 }
397 return isType1.value();
398}
399
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800400///////////////////////////////////////////////////////////////////////////////
401
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700402static const JNINativeMethod gFontBuilderMethods[] = {
Seigo Nonaka99c07562021-02-03 21:37:57 -0800403 {"nInitBuilder", "()J", (void*)Font_Builder_initBuilder},
404 {"nAddAxis", "(JIF)V", (void*)Font_Builder_addAxis},
405 {"nBuild", "(JLjava/nio/ByteBuffer;Ljava/lang/String;Ljava/lang/String;IZI)J",
406 (void*)Font_Builder_build},
407 {"nClone", "(JJIZI)J", (void*)Font_Builder_clone},
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700408};
409
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700410static const JNINativeMethod gFontMethods[] = {
Seigo Nonaka1dd39f32021-02-05 19:15:29 -0800411 {"nGetMinikinFontPtr", "(J)J", (void*)Font_getMinikinFontPtr},
412 {"nCloneFont", "(J)J", (void*)Font_cloneFont},
413 {"nNewByteBuffer", "(J)Ljava/nio/ByteBuffer;", (void*)Font_newByteBuffer},
414 {"nGetBufferAddress", "(J)J", (void*)Font_getBufferAddress},
415 {"nGetReleaseNativeFont", "()J", (void*)Font_getReleaseNativeFontFunc},
416 {"nGetGlyphBounds", "(JIJLandroid/graphics/RectF;)F", (void*)Font_getGlyphBounds},
417 {"nGetFontMetrics", "(JJLandroid/graphics/Paint$FontMetrics;)F",
418 (void*)Font_getFontMetrics},
419 {"nGetFontPath", "(J)Ljava/lang/String;", (void*)Font_getFontPath},
420 {"nGetLocaleList", "(J)Ljava/lang/String;", (void*)Font_getLocaleList},
421 {"nGetPackedStyle", "(J)I", (void*)Font_getPackedStyle},
422 {"nGetIndex", "(J)I", (void*)Font_getIndex},
423 {"nGetAxisCount", "(J)I", (void*)Font_getAxisCount},
424 {"nGetAxisInfo", "(JI)J", (void*)Font_getAxisInfo},
Seigo Nonaka5dd6dd52021-02-11 20:02:27 -0800425 {"nGetSourceId", "(J)I", (void*)Font_getSourceId},
Seigo Nonakad5ecaba2021-05-27 15:49:37 -0700426
427 // System font accessors
428 {"nGetAvailableFontSet", "()[J", (void*)Font_getAvailableFontSet},
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700429};
430
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800431static const JNINativeMethod gFontFileUtilMethods[] = {
432 { "nGetFontRevision", "(Ljava/nio/ByteBuffer;I)J", (void*) FontFileUtil_getFontRevision },
433 { "nGetFontPostScriptName", "(Ljava/nio/ByteBuffer;I)Ljava/lang/String;",
434 (void*) FontFileUtil_getFontPostScriptName },
Seigo Nonaka9d5ab7e2021-01-20 22:50:09 -0800435 { "nIsPostScriptType1Font", "(Ljava/nio/ByteBuffer;I)I",
436 (void*) FontFileUtil_isPostScriptType1Font },
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800437};
438
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700439int register_android_graphics_fonts_Font(JNIEnv* env) {
440 return RegisterMethodsOrDie(env, "android/graphics/fonts/Font$Builder", gFontBuilderMethods,
Seigo Nonaka1ed4f642020-09-10 17:19:34 -0700441 NELEM(gFontBuilderMethods)) +
442 RegisterMethodsOrDie(env, "android/graphics/fonts/Font", gFontMethods,
Seigo Nonakaf3a19152020-09-14 15:29:42 -0700443 NELEM(gFontMethods)) +
Seigo Nonaka47b6c1b2021-01-13 15:02:47 -0800444 RegisterMethodsOrDie(env, "android/graphics/fonts/FontFileUtil", gFontFileUtilMethods,
445 NELEM(gFontFileUtilMethods));
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700446}
447
Kohsuke Yatoh1ca390e2020-11-06 16:21:30 -0800448namespace fonts {
449
450std::shared_ptr<minikin::MinikinFont> createMinikinFontSkia(
451 sk_sp<SkData>&& data, std::string_view fontPath, const void *fontPtr, size_t fontSize,
452 int ttcIndex, const std::vector<minikin::FontVariation>& axes) {
453 FatVector<SkFontArguments::VariationPosition::Coordinate, 2> skVariation;
454 for (const auto& axis : axes) {
455 skVariation.push_back({axis.axisTag, axis.value});
456 }
457
458 std::unique_ptr<SkStreamAsset> fontData(new SkMemoryStream(std::move(data)));
459
460 SkFontArguments args;
461 args.setCollectionIndex(ttcIndex);
462 args.setVariationDesignPosition({skVariation.data(), static_cast<int>(skVariation.size())});
463
464 sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault());
465 sk_sp<SkTypeface> face(fm->makeFromStream(std::move(fontData), args));
466 if (face == nullptr) {
467 return nullptr;
468 }
Seigo Nonaka5dd6dd52021-02-11 20:02:27 -0800469 return std::make_shared<MinikinFontSkia>(std::move(face), getNewSourceId(), fontPtr, fontSize,
Kohsuke Yatoh1ca390e2020-11-06 16:21:30 -0800470 fontPath, ttcIndex, axes);
Seigo Nonakaa1c21c02018-07-20 15:57:39 -0700471}
Kohsuke Yatoh1ca390e2020-11-06 16:21:30 -0800472
Seigo Nonaka5dd6dd52021-02-11 20:02:27 -0800473int getNewSourceId() {
474 static std::atomic<int> sSourceId = {0};
475 return sSourceId++;
476}
477
Kohsuke Yatoh1ca390e2020-11-06 16:21:30 -0800478} // namespace fonts
479
480} // namespace android