Create Font sets from native fonts
Bug: 173752727 Test: atest SystemFontsTest (with enabling LAZY flag) Change-Id: Ic4e405a68e355919ee6493e51528fd44d79cd48e
This commit is contained in:
@@ -123,6 +123,19 @@ public final class Font {
|
||||
mLocaleList = localeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a builder with a byte buffer and file path.
|
||||
*
|
||||
* This method is intended to be called only from SystemFonts.
|
||||
* @param path font file path
|
||||
* @param localeList comma concatenated BCP47 compliant language tag.
|
||||
* @hide
|
||||
*/
|
||||
public Builder(@NonNull File path, @NonNull String localeList) {
|
||||
this(path);
|
||||
mLocaleList = localeList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a builder with a file path.
|
||||
*
|
||||
@@ -809,29 +822,13 @@ public final class Font {
|
||||
|
||||
// If not found, create Font object from native object for Java API users.
|
||||
ByteBuffer buffer = NativeFontBufferHelper.refByteBuffer(ptr);
|
||||
long packed = nGetFontInfo(ptr);
|
||||
int weight = (int) (packed & 0x0000_0000_0000_FFFFL);
|
||||
boolean italic = (packed & 0x0000_0000_0001_0000L) != 0;
|
||||
int ttcIndex = (int) ((packed & 0x0000_FFFF_0000_0000L) >> 32);
|
||||
int axisCount = (int) ((packed & 0xFFFF_0000_0000_0000L) >> 48);
|
||||
FontVariationAxis[] axes = new FontVariationAxis[axisCount];
|
||||
char[] charBuffer = new char[4];
|
||||
for (int i = 0; i < axisCount; ++i) {
|
||||
long packedAxis = nGetAxisInfo(ptr, i);
|
||||
float value = Float.intBitsToFloat((int) (packedAxis & 0x0000_0000_FFFF_FFFFL));
|
||||
charBuffer[0] = (char) ((packedAxis & 0xFF00_0000_0000_0000L) >> 56);
|
||||
charBuffer[1] = (char) ((packedAxis & 0x00FF_0000_0000_0000L) >> 48);
|
||||
charBuffer[2] = (char) ((packedAxis & 0x0000_FF00_0000_0000L) >> 40);
|
||||
charBuffer[3] = (char) ((packedAxis & 0x0000_00FF_0000_0000L) >> 32);
|
||||
axes[i] = new FontVariationAxis(new String(charBuffer), value);
|
||||
}
|
||||
String path = nGetFontPath(ptr);
|
||||
File file = (path == null) ? null : new File(path);
|
||||
Font.Builder builder = new Font.Builder(buffer, file, "")
|
||||
.setWeight(weight)
|
||||
.setSlant(italic ? FontStyle.FONT_SLANT_ITALIC : FontStyle.FONT_SLANT_UPRIGHT)
|
||||
.setTtcIndex(ttcIndex)
|
||||
.setFontVariationSettings(axes);
|
||||
NativeFont.Font font = NativeFont.readNativeFont(ptr);
|
||||
|
||||
Font.Builder builder = new Font.Builder(buffer, font.getFile(), "")
|
||||
.setWeight(font.getStyle().getWeight())
|
||||
.setSlant(font.getStyle().getSlant())
|
||||
.setTtcIndex(font.getIndex())
|
||||
.setFontVariationSettings(font.getAxes());
|
||||
|
||||
Font newFont = null;
|
||||
try {
|
||||
@@ -845,15 +842,6 @@ public final class Font {
|
||||
}
|
||||
}
|
||||
|
||||
@CriticalNative
|
||||
private static native long nGetFontInfo(long ptr);
|
||||
|
||||
@CriticalNative
|
||||
private static native long nGetAxisInfo(long ptr, int i);
|
||||
|
||||
@FastNative
|
||||
private static native String nGetFontPath(long ptr);
|
||||
|
||||
@FastNative
|
||||
private static native float nGetGlyphBounds(long font, int glyphId, long paint, RectF rect);
|
||||
|
||||
|
||||
205
graphics/java/android/graphics/fonts/NativeFont.java
Normal file
205
graphics/java/android/graphics/fonts/NativeFont.java
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.graphics.fonts;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
|
||||
import dalvik.annotation.optimization.CriticalNative;
|
||||
import dalvik.annotation.optimization.FastNative;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Read native font objects.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class NativeFont {
|
||||
|
||||
/**
|
||||
* Represents native font object.
|
||||
*/
|
||||
public static final class Font {
|
||||
private final File mFile;
|
||||
private final int mIndex;
|
||||
private final FontVariationAxis[] mAxes;
|
||||
private final FontStyle mStyle;
|
||||
|
||||
public Font(File file, int index, FontVariationAxis[] axes, FontStyle style) {
|
||||
mFile = file;
|
||||
mIndex = index;
|
||||
mAxes = axes;
|
||||
mStyle = style;
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return mFile;
|
||||
}
|
||||
|
||||
public FontVariationAxis[] getAxes() {
|
||||
return mAxes;
|
||||
}
|
||||
|
||||
public FontStyle getStyle() {
|
||||
return mStyle;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return mIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Font font = (Font) o;
|
||||
return mIndex == font.mIndex && mFile.equals(font.mFile)
|
||||
&& Arrays.equals(mAxes, font.mAxes) && mStyle.equals(font.mStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = Objects.hash(mFile, mIndex, mStyle);
|
||||
result = 31 * result + Arrays.hashCode(mAxes);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents native font family object.
|
||||
*/
|
||||
public static final class Family {
|
||||
private final List<Font> mFonts;
|
||||
private final String mLocale;
|
||||
|
||||
public Family(List<Font> fonts, String locale) {
|
||||
mFonts = fonts;
|
||||
mLocale = locale;
|
||||
}
|
||||
|
||||
public List<Font> getFonts() {
|
||||
return mFonts;
|
||||
}
|
||||
|
||||
public String getLocale() {
|
||||
return mLocale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
Family family = (Family) o;
|
||||
return mFonts.equals(family.mFonts) && mLocale.equals(family.mLocale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mFonts, mLocale);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get underlying font families from Typeface
|
||||
*
|
||||
* @param typeface a typeface
|
||||
* @return list of family
|
||||
*/
|
||||
public static List<Family> readTypeface(Typeface typeface) {
|
||||
int familyCount = nGetFamilyCount(typeface.native_instance);
|
||||
List<Family> result = new ArrayList<>(familyCount);
|
||||
for (int i = 0; i < familyCount; ++i) {
|
||||
result.add(readNativeFamily(nGetFamily(typeface.native_instance, i)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read family object from native pointer
|
||||
*
|
||||
* @param familyPtr a font family pointer
|
||||
* @return a family
|
||||
*/
|
||||
public static Family readNativeFamily(long familyPtr) {
|
||||
int fontCount = nGetFontCount(familyPtr);
|
||||
List<Font> result = new ArrayList<>(fontCount);
|
||||
for (int i = 0; i < fontCount; ++i) {
|
||||
result.add(readNativeFont(nGetFont(familyPtr, i)));
|
||||
}
|
||||
String localeList = nGetLocaleList(familyPtr);
|
||||
return new Family(result, localeList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read font object from native pointer.
|
||||
*
|
||||
* @param ptr a font pointer
|
||||
* @return a font
|
||||
*/
|
||||
public static Font readNativeFont(long ptr) {
|
||||
long packed = nGetFontInfo(ptr);
|
||||
int weight = (int) (packed & 0x0000_0000_0000_FFFFL);
|
||||
boolean italic = (packed & 0x0000_0000_0001_0000L) != 0;
|
||||
int ttcIndex = (int) ((packed & 0x0000_FFFF_0000_0000L) >> 32);
|
||||
int axisCount = (int) ((packed & 0xFFFF_0000_0000_0000L) >> 48);
|
||||
FontVariationAxis[] axes = new FontVariationAxis[axisCount];
|
||||
char[] charBuffer = new char[4];
|
||||
for (int i = 0; i < axisCount; ++i) {
|
||||
long packedAxis = nGetAxisInfo(ptr, i);
|
||||
float value = Float.intBitsToFloat((int) (packedAxis & 0x0000_0000_FFFF_FFFFL));
|
||||
charBuffer[0] = (char) ((packedAxis & 0xFF00_0000_0000_0000L) >> 56);
|
||||
charBuffer[1] = (char) ((packedAxis & 0x00FF_0000_0000_0000L) >> 48);
|
||||
charBuffer[2] = (char) ((packedAxis & 0x0000_FF00_0000_0000L) >> 40);
|
||||
charBuffer[3] = (char) ((packedAxis & 0x0000_00FF_0000_0000L) >> 32);
|
||||
axes[i] = new FontVariationAxis(new String(charBuffer), value);
|
||||
}
|
||||
String path = nGetFontPath(ptr);
|
||||
File file = (path == null) ? null : new File(path);
|
||||
FontStyle style = new FontStyle(weight,
|
||||
italic ? FontStyle.FONT_SLANT_ITALIC : FontStyle.FONT_SLANT_UPRIGHT);
|
||||
|
||||
return new Font(file, ttcIndex, axes, style);
|
||||
}
|
||||
|
||||
@CriticalNative
|
||||
private static native int nGetFamilyCount(long ptr);
|
||||
|
||||
@CriticalNative
|
||||
private static native long nGetFamily(long ptr, int index);
|
||||
|
||||
@FastNative
|
||||
private static native String nGetLocaleList(long familyPtr);
|
||||
|
||||
@CriticalNative
|
||||
private static native long nGetFont(long familyPtr, int fontIndex);
|
||||
|
||||
@CriticalNative
|
||||
private static native int nGetFontCount(long familyPtr);
|
||||
|
||||
@CriticalNative
|
||||
private static native long nGetFontInfo(long fontPtr);
|
||||
|
||||
@CriticalNative
|
||||
private static native long nGetAxisInfo(long fontPtr, int i);
|
||||
|
||||
@FastNative
|
||||
private static native String nGetFontPath(long fontPtr);
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package android.graphics.fonts;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.graphics.FontListParser;
|
||||
import android.graphics.Typeface;
|
||||
import android.text.FontConfig;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
@@ -68,19 +69,50 @@ public final class SystemFonts {
|
||||
return sAvailableFonts;
|
||||
}
|
||||
|
||||
Set<Font> set = new HashSet<>();
|
||||
if (Typeface.ENABLE_LAZY_TYPEFACE_INITIALIZATION) {
|
||||
sAvailableFonts = collectAllFonts();
|
||||
} else {
|
||||
Set<Font> set = new HashSet<>();
|
||||
for (FontFamily[] items : sFamilyMap.values()) {
|
||||
for (FontFamily family : items) {
|
||||
for (int i = 0; i < family.getSize(); ++i) {
|
||||
set.add(family.getFont(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (FontFamily[] items : sFamilyMap.values()) {
|
||||
for (FontFamily family : items) {
|
||||
for (int i = 0; i < family.getSize(); ++i) {
|
||||
set.add(family.getFont(i));
|
||||
sAvailableFonts = Collections.unmodifiableSet(set);
|
||||
}
|
||||
return sAvailableFonts;
|
||||
}
|
||||
}
|
||||
|
||||
private static @NonNull Set<Font> collectAllFonts() {
|
||||
Map<String, Typeface> map = Typeface.getSystemFontMap();
|
||||
HashSet<NativeFont.Font> seenFonts = new HashSet<>();
|
||||
HashSet<Font> result = new HashSet<>();
|
||||
for (Typeface typeface : map.values()) {
|
||||
List<NativeFont.Family> families = NativeFont.readTypeface(typeface);
|
||||
for (NativeFont.Family family : families) {
|
||||
for (NativeFont.Font font : family.getFonts()) {
|
||||
if (seenFonts.contains(font)) {
|
||||
continue;
|
||||
}
|
||||
seenFonts.add(font);
|
||||
try {
|
||||
result.add(new Font.Builder(font.getFile(), family.getLocale())
|
||||
.setFontVariationSettings(font.getAxes())
|
||||
.setTtcIndex(font.getIndex())
|
||||
.setWeight(font.getStyle().getWeight())
|
||||
.setSlant(font.getStyle().getSlant())
|
||||
.build());
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Failed to load " + font.getFile(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sAvailableFonts = Collections.unmodifiableSet(set);
|
||||
return sAvailableFonts;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static @Nullable ByteBuffer mmap(@NonNull String fullPath) {
|
||||
|
||||
@@ -333,6 +333,7 @@ cc_defaults {
|
||||
"jni/YuvToJpegEncoder.cpp",
|
||||
"jni/fonts/Font.cpp",
|
||||
"jni/fonts/FontFamily.cpp",
|
||||
"jni/fonts/NativeFont.cpp",
|
||||
"jni/text/LineBreaker.cpp",
|
||||
"jni/text/MeasuredText.cpp",
|
||||
"jni/text/TextShaper.cpp",
|
||||
|
||||
@@ -69,6 +69,7 @@ extern int register_android_graphics_drawable_AnimatedVectorDrawable(JNIEnv* env
|
||||
extern int register_android_graphics_drawable_VectorDrawable(JNIEnv* env);
|
||||
extern int register_android_graphics_fonts_Font(JNIEnv* env);
|
||||
extern int register_android_graphics_fonts_FontFamily(JNIEnv* env);
|
||||
extern int register_android_graphics_fonts_NativeFont(JNIEnv* env);
|
||||
extern int register_android_graphics_pdf_PdfDocument(JNIEnv* env);
|
||||
extern int register_android_graphics_pdf_PdfEditor(JNIEnv* env);
|
||||
extern int register_android_graphics_pdf_PdfRenderer(JNIEnv* env);
|
||||
@@ -135,6 +136,7 @@ static const RegJNIRec gRegJNI[] = {
|
||||
REG_JNI(register_android_graphics_drawable_VectorDrawable),
|
||||
REG_JNI(register_android_graphics_fonts_Font),
|
||||
REG_JNI(register_android_graphics_fonts_FontFamily),
|
||||
REG_JNI(register_android_graphics_fonts_NativeFont),
|
||||
REG_JNI(register_android_graphics_pdf_PdfDocument),
|
||||
REG_JNI(register_android_graphics_pdf_PdfEditor),
|
||||
REG_JNI(register_android_graphics_pdf_PdfRenderer),
|
||||
|
||||
@@ -186,38 +186,6 @@ static jfloat Font_getFontMetrics(JNIEnv* env, jobject, jlong fontHandle, jlong
|
||||
return spacing;
|
||||
}
|
||||
|
||||
// Critical Native
|
||||
static jlong Font_getFontInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle) {
|
||||
const minikin::Font* font = reinterpret_cast<minikin::Font*>(fontHandle);
|
||||
MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->typeface().get());
|
||||
|
||||
uint64_t result = font->style().weight();
|
||||
result |= font->style().slant() == minikin::FontStyle::Slant::ITALIC ? 0x10000 : 0x00000;
|
||||
result |= ((static_cast<uint64_t>(minikinSkia->GetFontIndex())) << 32);
|
||||
result |= ((static_cast<uint64_t>(minikinSkia->GetAxes().size())) << 48);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Critical Native
|
||||
static jlong Font_getAxisInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle, jint index) {
|
||||
const minikin::Font* font = reinterpret_cast<minikin::Font*>(fontHandle);
|
||||
MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->typeface().get());
|
||||
const minikin::FontVariation& var = minikinSkia->GetAxes().at(index);
|
||||
uint32_t floatBinary = *reinterpret_cast<const uint32_t*>(&var.value);
|
||||
return (static_cast<uint64_t>(var.axisTag) << 32) | static_cast<uint64_t>(floatBinary);
|
||||
}
|
||||
|
||||
// FastNative
|
||||
static jstring Font_getFontPath(JNIEnv* env, jobject, jlong fontHandle) {
|
||||
const minikin::Font* font = reinterpret_cast<minikin::Font*>(fontHandle);
|
||||
MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->typeface().get());
|
||||
const std::string& filePath = minikinSkia->getFilePath();
|
||||
if (filePath.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
return env->NewStringUTF(filePath.c_str());
|
||||
}
|
||||
|
||||
// Critical Native
|
||||
static jlong Font_getNativeFontPtr(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle) {
|
||||
FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle);
|
||||
@@ -276,9 +244,6 @@ static const JNINativeMethod gFontBuilderMethods[] = {
|
||||
static const JNINativeMethod gFontMethods[] = {
|
||||
{ "nGetGlyphBounds", "(JIJLandroid/graphics/RectF;)F", (void*) Font_getGlyphBounds },
|
||||
{ "nGetFontMetrics", "(JJLandroid/graphics/Paint$FontMetrics;)F", (void*) Font_getFontMetrics },
|
||||
{ "nGetFontInfo", "(J)J", (void*) Font_getFontInfo },
|
||||
{ "nGetAxisInfo", "(JI)J", (void*) Font_getAxisInfo },
|
||||
{ "nGetFontPath", "(J)Ljava/lang/String;", (void*) Font_getFontPath },
|
||||
{ "nGetNativeFontPtr", "(J)J", (void*) Font_getNativeFontPtr },
|
||||
{ "nGetFontBufferAddress", "(J)J", (void*) Font_GetBufferAddress },
|
||||
};
|
||||
|
||||
125
libs/hwui/jni/fonts/NativeFont.cpp
Normal file
125
libs/hwui/jni/fonts/NativeFont.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#undef LOG_TAG
|
||||
#define LOG_TAG "Minikin"
|
||||
|
||||
#include "Font.h"
|
||||
#include "SkData.h"
|
||||
#include "SkFont.h"
|
||||
#include "SkFontMetrics.h"
|
||||
#include "SkFontMgr.h"
|
||||
#include "SkRefCnt.h"
|
||||
#include "SkTypeface.h"
|
||||
#include "GraphicsJNI.h"
|
||||
#include <nativehelper/ScopedUtfChars.h>
|
||||
#include "Utils.h"
|
||||
#include "FontUtils.h"
|
||||
|
||||
#include <hwui/MinikinSkia.h>
|
||||
#include <hwui/Paint.h>
|
||||
#include <hwui/Typeface.h>
|
||||
#include <minikin/FontFamily.h>
|
||||
#include <minikin/LocaleList.h>
|
||||
#include <ui/FatVector.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace android {
|
||||
|
||||
// Critical Native
|
||||
static jint NativeFont_getFamilyCount(CRITICAL_JNI_PARAMS_COMMA jlong typefaceHandle) {
|
||||
Typeface* tf = reinterpret_cast<Typeface*>(typefaceHandle);
|
||||
return tf->fFontCollection->getFamilies().size();
|
||||
}
|
||||
|
||||
// Critical Native
|
||||
static jlong NativeFont_getFamily(CRITICAL_JNI_PARAMS_COMMA jlong typefaceHandle, jint index) {
|
||||
Typeface* tf = reinterpret_cast<Typeface*>(typefaceHandle);
|
||||
return reinterpret_cast<jlong>(tf->fFontCollection->getFamilies()[index].get());
|
||||
|
||||
}
|
||||
|
||||
// Fast Native
|
||||
static jstring NativeFont_getLocaleList(JNIEnv* env, jobject, jlong familyHandle) {
|
||||
minikin::FontFamily* family = reinterpret_cast<minikin::FontFamily*>(familyHandle);
|
||||
uint32_t localeListId = family->localeListId();
|
||||
return env->NewStringUTF(minikin::getLocaleString(localeListId).c_str());
|
||||
}
|
||||
|
||||
// Critical Native
|
||||
static jint NativeFont_getFontCount(CRITICAL_JNI_PARAMS_COMMA jlong familyHandle) {
|
||||
minikin::FontFamily* family = reinterpret_cast<minikin::FontFamily*>(familyHandle);
|
||||
return family->getNumFonts();
|
||||
}
|
||||
|
||||
// Critical Native
|
||||
static jlong NativeFont_getFont(CRITICAL_JNI_PARAMS_COMMA jlong familyHandle, jint index) {
|
||||
minikin::FontFamily* family = reinterpret_cast<minikin::FontFamily*>(familyHandle);
|
||||
return reinterpret_cast<jlong>(family->getFont(index));
|
||||
}
|
||||
|
||||
// Critical Native
|
||||
static jlong NativeFont_getFontInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle) {
|
||||
const minikin::Font* font = reinterpret_cast<minikin::Font*>(fontHandle);
|
||||
MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->typeface().get());
|
||||
|
||||
uint64_t result = font->style().weight();
|
||||
result |= font->style().slant() == minikin::FontStyle::Slant::ITALIC ? 0x10000 : 0x00000;
|
||||
result |= ((static_cast<uint64_t>(minikinSkia->GetFontIndex())) << 32);
|
||||
result |= ((static_cast<uint64_t>(minikinSkia->GetAxes().size())) << 48);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Critical Native
|
||||
static jlong NativeFont_getAxisInfo(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle, jint index) {
|
||||
const minikin::Font* font = reinterpret_cast<minikin::Font*>(fontHandle);
|
||||
MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->typeface().get());
|
||||
const minikin::FontVariation& var = minikinSkia->GetAxes().at(index);
|
||||
uint32_t floatBinary = *reinterpret_cast<const uint32_t*>(&var.value);
|
||||
return (static_cast<uint64_t>(var.axisTag) << 32) | static_cast<uint64_t>(floatBinary);
|
||||
}
|
||||
|
||||
// FastNative
|
||||
static jstring NativeFont_getFontPath(JNIEnv* env, jobject, jlong fontHandle) {
|
||||
const minikin::Font* font = reinterpret_cast<minikin::Font*>(fontHandle);
|
||||
MinikinFontSkia* minikinSkia = static_cast<MinikinFontSkia*>(font->typeface().get());
|
||||
const std::string& filePath = minikinSkia->getFilePath();
|
||||
if (filePath.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
return env->NewStringUTF(filePath.c_str());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const JNINativeMethod gNativeFontMethods[] = {
|
||||
{ "nGetFamilyCount", "(J)I", (void*) NativeFont_getFamilyCount },
|
||||
{ "nGetFamily", "(JI)J", (void*) NativeFont_getFamily },
|
||||
{ "nGetLocaleList", "(J)Ljava/lang/String;", (void*) NativeFont_getLocaleList },
|
||||
{ "nGetFontCount", "(J)I", (void*) NativeFont_getFontCount },
|
||||
{ "nGetFont", "(JI)J", (void*) NativeFont_getFont },
|
||||
{ "nGetFontInfo", "(J)J", (void*) NativeFont_getFontInfo },
|
||||
{ "nGetAxisInfo", "(JI)J", (void*) NativeFont_getAxisInfo },
|
||||
{ "nGetFontPath", "(J)Ljava/lang/String;", (void*) NativeFont_getFontPath },
|
||||
};
|
||||
|
||||
int register_android_graphics_fonts_NativeFont(JNIEnv* env) {
|
||||
return RegisterMethodsOrDie(env, "android/graphics/fonts/NativeFont", gNativeFontMethods,
|
||||
NELEM(gNativeFontMethods));
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
Reference in New Issue
Block a user