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

Commit 18dfafee authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Introduce getSourceIdentifier instead of isSameSource."

parents 06b00738 bb684034
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -16424,9 +16424,9 @@ package android.graphics.fonts {
    method public float getGlyphBounds(@IntRange(from=0) int, @NonNull android.graphics.Paint, @Nullable android.graphics.RectF);
    method @NonNull public android.os.LocaleList getLocaleList();
    method public void getMetrics(@NonNull android.graphics.Paint, @Nullable android.graphics.Paint.FontMetrics);
    method public int getSourceIdentifier();
    method @NonNull public android.graphics.fonts.FontStyle getStyle();
    method @IntRange(from=0) public int getTtcIndex();
    method public boolean isSameSource(@NonNull android.graphics.fonts.Font);
  }
  public static final class Font.Builder {
+1 −1
Original line number Diff line number Diff line
@@ -16406,9 +16406,9 @@ package android.graphics.fonts {
    method public float getGlyphBounds(@IntRange(from=0) int, @NonNull android.graphics.Paint, @Nullable android.graphics.RectF);
    method @NonNull public android.os.LocaleList getLocaleList();
    method public void getMetrics(@NonNull android.graphics.Paint, @Nullable android.graphics.Paint.FontMetrics);
    method public int getSourceIdentifier();
    method @NonNull public android.graphics.fonts.FontStyle getStyle();
    method @IntRange(from=0) public int getTtcIndex();
    method public boolean isSameSource(@NonNull android.graphics.fonts.Font);
  }
  public static final class Font.Builder {
+81 −5
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.os.LocaleList;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.LongSparseLongArray;
import android.util.TypedValue;

import com.android.internal.annotations.GuardedBy;
@@ -69,6 +70,11 @@ public final class Font {
    private static final LongSparseArray<WeakReference<Font>> FONT_PTR_MAP =
            new LongSparseArray<>();

    private static final Object SOURCE_ID_LOCK = new Object();
    @GuardedBy("SOURCE_ID_LOCK")
    private static final LongSparseLongArray FONT_SOURCE_ID_MAP =
            new LongSparseLongArray(300);  // System font has 200 fonts, so 300 should be enough.

    /**
     * A builder class for creating new Font.
     */
@@ -465,13 +471,24 @@ public final class Font {
            final String filePath = mFile == null ? "" : mFile.getAbsolutePath();

            long ptr;
            int fontIdentifier;
            if (mFont == null) {
                ptr = nBuild(builderPtr, readonlyBuffer, filePath, mWeight, italic, mTtcIndex);
                long fontBufferPtr = nGetFontBufferAddress(ptr);
                synchronized (SOURCE_ID_LOCK) {
                    long id = FONT_SOURCE_ID_MAP.get(fontBufferPtr, -1);
                    if (id == -1) {
                        id = FONT_SOURCE_ID_MAP.size();
                        FONT_SOURCE_ID_MAP.put(fontBufferPtr, id);
                    }
                    fontIdentifier = (int) id;
                }
            } else {
                ptr = nClone(mFont.getNativePtr(), builderPtr, mWeight, italic, mTtcIndex);
                fontIdentifier = mFont.mSourceIdentifier;
            }
            final Font font = new Font(ptr, readonlyBuffer, mFile,
                    new FontStyle(mWeight, slant), mTtcIndex, mAxes, mLocaleList);
                    new FontStyle(mWeight, slant), mTtcIndex, mAxes, mLocaleList, fontIdentifier);
            sFontRegistry.registerNativeAllocation(font, ptr);
            return font;
        }
@@ -500,13 +517,15 @@ public final class Font {
    private final @IntRange(from = 0) int mTtcIndex;
    private final @Nullable FontVariationAxis[] mAxes;
    private final @NonNull String mLocaleList;
    private final int mSourceIdentifier;  // An identifier of font source data.

    /**
     * Use Builder instead
     */
    private Font(long nativePtr, @NonNull ByteBuffer buffer, @Nullable File file,
            @NonNull FontStyle fontStyle, @IntRange(from = 0) int ttcIndex,
            @Nullable FontVariationAxis[] axes, @NonNull String localeList) {
            @Nullable FontVariationAxis[] axes, @NonNull String localeList,
            int sourceIdentifier) {
        mBuffer = buffer;
        mFile = file;
        mFontStyle = fontStyle;
@@ -514,6 +533,7 @@ public final class Font {
        mTtcIndex = ttcIndex;
        mAxes = axes;
        mLocaleList = localeList;
        mSourceIdentifier = sourceIdentifier;

        synchronized (MAP_LOCK) {
            FONT_PTR_MAP.append(nGetNativeFontPtr(mNativePtr), new WeakReference<>(this));
@@ -626,6 +646,62 @@ public final class Font {
        return mNativePtr;
    }

    /**
     * Returns the unique ID of the source font data.
     *
     * You can use this identifier as a key of the cache or checking if two fonts can be
     * interpolated with font variation settings.
     * <pre>
     * <code>
     *   // Following three Fonts, fontA, fontB, fontC have the same identifier.
     *   Font fontA = new Font.Builder("/path/to/font").build();
     *   Font fontB = new Font.Builder(fontA).setTtcIndex(1).build();
     *   Font fontC = new Font.Builder(fontB).setFontVariationSettings("'wght' 700).build();
     *
     *   // Following fontD has the different identifier from above three.
     *   Font fontD = new Font.Builder("/path/to/another/font").build();
     *
     *   // Following fontE has different identifier from above four even the font path is the same.
     *   // To get the same identifier, please create new Font instance from existing fonts.
     *   Font fontE = new Font.Builder("/path/to/font").build();
     * </code>
     * </pre>
     *
     * Here is an example of caching font object that has
     * <pre>
     * <code>
     *   private LongSparseArray<SparseArray<Font>> mCache = new LongSparseArray<>();
     *
     *   private Font getFontWeightVariation(Font font, int weight) {
     *       // Different collection index is treated as different font.
     *       long key = ((long) font.getSourceIdentifier()) << 32 | (long) font.getTtcIndex();
     *
     *       SparseArray<Font> weightCache = mCache.get(key);
     *       if (weightCache == null) {
     *          weightCache = new SparseArray<>();
     *          mCache.put(key, weightCache);
     *       }
     *
     *       Font cachedFont = weightCache.get(weight);
     *       if (cachedFont != null) {
     *         return cachedFont;
     *       }
     *
     *       Font newFont = new Font.Builder(cachedFont)
     *           .setFontVariationSettings("'wght' " + weight);
     *           .build();
     *
     *       weightCache.put(weight, newFont);
     *       return newFont;
     *   }
     * </code>
     * </pre>
     * @return an unique identifier for the font source data.
     */
    public int getSourceIdentifier() {
        return mSourceIdentifier;
    }

    /**
     * Returns true if the given font is created from the same source data from this font.
     *
@@ -643,7 +719,7 @@ public final class Font {
     * @param other a font object to be compared.
     * @return true if given font is created from the same source from this font. Otherwise false.
     */
    public boolean isSameSource(@NonNull Font other) {
    private boolean isSameSource(@NonNull Font other) {
        Objects.requireNonNull(other);

        // Shortcut for the same instance.
@@ -660,7 +736,7 @@ public final class Font {
        // underlying native font object holds buffer address, check if this buffer points exactly
        // the same address as a shortcut of equality. For being compatible with of API30 or before,
        // check buffer position even if the buffer points the same address.
        if (nIsSameBufferAddress(mNativePtr, other.mNativePtr)
        if (mSourceIdentifier == other.mSourceIdentifier
                && mBuffer.position() == other.mBuffer.position()) {
            return true;
        }
@@ -788,5 +864,5 @@ public final class Font {
    private static native long nGetNativeFontPtr(long ptr);

    @CriticalNative
    private static native boolean nIsSameBufferAddress(long lFontPtr, long rFontPtr);
    private static native long nGetFontBufferAddress(long font);
}
+5 −8
Original line number Diff line number Diff line
@@ -239,13 +239,10 @@ static jlong Font_getNativeFontPtr(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle) {
}

// Critical Native
static jboolean Font_isSameBufferAddress(CRITICAL_JNI_PARAMS_COMMA jlong lFontHandle,
                                         jlong rFontHandle) {
    FontWrapper* lFont = reinterpret_cast<FontWrapper*>(lFontHandle);
    FontWrapper* rFont = reinterpret_cast<FontWrapper*>(rFontHandle);
    const void* lBufferPtr = lFont->font->typeface()->GetFontData();
    const void* rBufferPtr = rFont->font->typeface()->GetFontData();
    return lBufferPtr == rBufferPtr;
static jlong Font_GetBufferAddress(CRITICAL_JNI_PARAMS_COMMA jlong fontHandle) {
    FontWrapper* font = reinterpret_cast<FontWrapper*>(fontHandle);
    const void* bufferPtr = font->font->typeface()->GetFontData();
    return reinterpret_cast<jlong>(bufferPtr);
}

///////////////////////////////////////////////////////////////////////////////
@@ -297,7 +294,7 @@ static const JNINativeMethod gFontMethods[] = {
    { "nGetAxisInfo", "(JI)J", (void*) Font_getAxisInfo },
    { "nGetFontPath", "(J)Ljava/lang/String;", (void*) Font_getFontPath },
    { "nGetNativeFontPtr", "(J)J", (void*) Font_getNativeFontPtr },
    { "nIsSameBufferAddress", "(JJ)Z", (void*) Font_isSameBufferAddress },
    { "nGetFontBufferAddress", "(J)J", (void*) Font_GetBufferAddress },
};

static const JNINativeMethod gFontBufferHelperMethods[] = {