Merge "Calculate set of available fonts in native" into sc-dev
This commit is contained in:
@@ -46,7 +46,10 @@ import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A font class can be used for creating FontFamily.
|
||||
@@ -859,6 +862,18 @@ public final class Font {
|
||||
+ "}";
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static Set<Font> getAvailableFonts() {
|
||||
// The font uniqueness is already calculated in the native code. So use IdentityHashMap
|
||||
// for avoiding hash/equals calculation.
|
||||
IdentityHashMap<Font, Font> map = new IdentityHashMap<>();
|
||||
for (long nativePtr : nGetAvailableFontSet()) {
|
||||
Font font = new Font(nativePtr);
|
||||
map.put(font, font);
|
||||
}
|
||||
return Collections.unmodifiableSet(map.keySet());
|
||||
}
|
||||
|
||||
@CriticalNative
|
||||
private static native long nGetMinikinFontPtr(long font);
|
||||
|
||||
@@ -900,4 +915,7 @@ public final class Font {
|
||||
|
||||
@CriticalNative
|
||||
private static native long nGetAxisInfo(long fontPtr, int i);
|
||||
|
||||
@FastNative
|
||||
private static native long[] nGetAvailableFontSet();
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import android.graphics.FontListParser;
|
||||
import android.graphics.Typeface;
|
||||
import android.text.FontConfig;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
@@ -39,7 +38,6 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -60,36 +58,6 @@ public final class SystemFonts {
|
||||
private static final Object LOCK = new Object();
|
||||
private static @GuardedBy("sLock") Set<Font> sAvailableFonts;
|
||||
|
||||
/**
|
||||
* Helper wrapper class for skipping buffer equality check of Font#equals.
|
||||
*
|
||||
* Due to historical reasons, the Font#equals checks the byte-by-byte buffer equality which
|
||||
* requires heavy IO work in getAvailableFonts. Since the fonts came from system are all regular
|
||||
* file backed font instance and stored in the unique place, just comparing file path should be
|
||||
* good enough for this case.
|
||||
*/
|
||||
private static final class SystemFontHashWrapper {
|
||||
private final Font mFont;
|
||||
SystemFontHashWrapper(Font font) {
|
||||
mFont = font;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
// All system fonts are regular-file backed font instance, so no need to
|
||||
// compare buffers.
|
||||
return mFont.paramEquals(((SystemFontHashWrapper) o).mFont);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mFont);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all available font files in the system.
|
||||
*
|
||||
@@ -98,25 +66,7 @@ public final class SystemFonts {
|
||||
public static @NonNull Set<Font> getAvailableFonts() {
|
||||
synchronized (LOCK) {
|
||||
if (sAvailableFonts == null) {
|
||||
Set<SystemFontHashWrapper> set = new ArraySet<>();
|
||||
for (Typeface tf : Typeface.getSystemFontMap().values()) {
|
||||
List<FontFamily> families = tf.getFallback();
|
||||
for (int i = 0; i < families.size(); ++i) {
|
||||
FontFamily family = families.get(i);
|
||||
for (int j = 0; j < family.getSize(); ++j) {
|
||||
set.add(new SystemFontHashWrapper(family.getFont(j)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unwrapping font instance for Set<Font> interface. The ArraySet#add won't call
|
||||
// Font#equals function if none of two objects has the same hash, so following
|
||||
// unwrapping won't cause bad performance due to byte-by-byte equality check.
|
||||
ArraySet<Font> result = new ArraySet(set.size());
|
||||
for (SystemFontHashWrapper wrapper : set) {
|
||||
result.add(wrapper.mFont);
|
||||
}
|
||||
sAvailableFonts = Collections.unmodifiableSet(result);
|
||||
sAvailableFonts = Font.getAvailableFonts();
|
||||
}
|
||||
return sAvailableFonts;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <minikin/FontFamily.h>
|
||||
#include <minikin/FontFileParser.h>
|
||||
#include <minikin/LocaleList.h>
|
||||
#include <minikin/SystemFonts.h>
|
||||
#include <ui/FatVector.h>
|
||||
|
||||
#include <memory>
|
||||
@@ -282,6 +283,22 @@ static jint Font_getSourceId(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
|
||||
return font->font->typeface()->GetSourceId();
|
||||
}
|
||||
|
||||
static jlongArray Font_getAvailableFontSet(JNIEnv* env, jobject) {
|
||||
std::vector<jlong> refArray;
|
||||
minikin::SystemFonts::getFontSet(
|
||||
[&refArray](const std::vector<std::shared_ptr<minikin::Font>>& fontSet) {
|
||||
refArray.reserve(fontSet.size());
|
||||
for (const auto& font : fontSet) {
|
||||
std::shared_ptr<minikin::Font> fontRef = font;
|
||||
refArray.push_back(
|
||||
reinterpret_cast<jlong>(new FontWrapper(std::move(fontRef))));
|
||||
}
|
||||
});
|
||||
jlongArray r = env->NewLongArray(refArray.size());
|
||||
env->SetLongArrayRegion(r, 0, refArray.size(), refArray.data());
|
||||
return r;
|
||||
}
|
||||
|
||||
// Fast Native
|
||||
static jlong FontFileUtil_getFontRevision(JNIEnv* env, jobject, jobject buffer, jint index) {
|
||||
NPE_CHECK_RETURN_ZERO(env, buffer);
|
||||
@@ -373,6 +390,9 @@ static const JNINativeMethod gFontMethods[] = {
|
||||
{"nGetAxisCount", "(J)I", (void*)Font_getAxisCount},
|
||||
{"nGetAxisInfo", "(JI)J", (void*)Font_getAxisInfo},
|
||||
{"nGetSourceId", "(J)I", (void*)Font_getSourceId},
|
||||
|
||||
// System font accessors
|
||||
{"nGetAvailableFontSet", "()[J", (void*)Font_getAvailableFontSet},
|
||||
};
|
||||
|
||||
static const JNINativeMethod gFontFileUtilMethods[] = {
|
||||
|
||||
Reference in New Issue
Block a user