Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cec02064 authored by Seigo Nonaka's avatar Seigo Nonaka Committed by Android (Google) Code Review
Browse files

Merge "Calculate set of available fonts in native" into sc-dev

parents f6d97cfa d5ecabab
Loading
Loading
Loading
Loading
+18 −0
Original line number Original line Diff line number Diff line
@@ -46,7 +46,10 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel;
import java.util.Arrays;
import java.util.Arrays;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Objects;
import java.util.Objects;
import java.util.Set;


/**
/**
 * A font class can be used for creating FontFamily.
 * 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
    @CriticalNative
    private static native long nGetMinikinFontPtr(long font);
    private static native long nGetMinikinFontPtr(long font);


@@ -900,4 +915,7 @@ public final class Font {


    @CriticalNative
    @CriticalNative
    private static native long nGetAxisInfo(long fontPtr, int i);
    private static native long nGetAxisInfo(long fontPtr, int i);

    @FastNative
    private static native long[] nGetAvailableFontSet();
}
}
+1 −51
Original line number Original line Diff line number Diff line
@@ -22,7 +22,6 @@ import android.graphics.FontListParser;
import android.graphics.Typeface;
import android.graphics.Typeface;
import android.text.FontConfig;
import android.text.FontConfig;
import android.util.ArrayMap;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.util.Log;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
@@ -39,7 +38,6 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.Collections;
import java.util.List;
import java.util.List;
import java.util.Map;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.Set;


/**
/**
@@ -60,36 +58,6 @@ public final class SystemFonts {
    private static final Object LOCK = new Object();
    private static final Object LOCK = new Object();
    private static @GuardedBy("sLock") Set<Font> sAvailableFonts;
    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.
     * Returns all available font files in the system.
     *
     *
@@ -98,25 +66,7 @@ public final class SystemFonts {
    public static @NonNull Set<Font> getAvailableFonts() {
    public static @NonNull Set<Font> getAvailableFonts() {
        synchronized (LOCK) {
        synchronized (LOCK) {
            if (sAvailableFonts == null) {
            if (sAvailableFonts == null) {
                Set<SystemFontHashWrapper> set = new ArraySet<>();
                sAvailableFonts = Font.getAvailableFonts();
                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);
            }
            }
            return sAvailableFonts;
            return sAvailableFonts;
        }
        }
+20 −0
Original line number Original line Diff line number Diff line
@@ -35,6 +35,7 @@
#include <minikin/FontFamily.h>
#include <minikin/FontFamily.h>
#include <minikin/FontFileParser.h>
#include <minikin/FontFileParser.h>
#include <minikin/LocaleList.h>
#include <minikin/LocaleList.h>
#include <minikin/SystemFonts.h>
#include <ui/FatVector.h>
#include <ui/FatVector.h>


#include <memory>
#include <memory>
@@ -282,6 +283,22 @@ static jint Font_getSourceId(CRITICAL_JNI_PARAMS_COMMA jlong fontPtr) {
    return font->font->typeface()->GetSourceId();
    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
// Fast Native
static jlong FontFileUtil_getFontRevision(JNIEnv* env, jobject, jobject buffer, jint index) {
static jlong FontFileUtil_getFontRevision(JNIEnv* env, jobject, jobject buffer, jint index) {
    NPE_CHECK_RETURN_ZERO(env, buffer);
    NPE_CHECK_RETURN_ZERO(env, buffer);
@@ -373,6 +390,9 @@ static const JNINativeMethod gFontMethods[] = {
        {"nGetAxisCount", "(J)I", (void*)Font_getAxisCount},
        {"nGetAxisCount", "(J)I", (void*)Font_getAxisCount},
        {"nGetAxisInfo", "(JI)J", (void*)Font_getAxisInfo},
        {"nGetAxisInfo", "(JI)J", (void*)Font_getAxisInfo},
        {"nGetSourceId", "(J)I", (void*)Font_getSourceId},
        {"nGetSourceId", "(J)I", (void*)Font_getSourceId},

        // System font accessors
        {"nGetAvailableFontSet", "()[J", (void*)Font_getAvailableFontSet},
};
};


static const JNINativeMethod gFontFileUtilMethods[] = {
static const JNINativeMethod gFontFileUtilMethods[] = {