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

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

Merge "Add necessary APIs for supporting glyph level drawing"

parents 491a89f3 1ed4f644
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -16389,7 +16389,9 @@ package android.graphics.fonts {
    method @Nullable public android.graphics.fonts.FontVariationAxis[] getAxes();
    method @NonNull public java.nio.ByteBuffer getBuffer();
    method @Nullable public java.io.File getFile();
    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 @NonNull public android.graphics.fonts.FontStyle getStyle();
    method @IntRange(from=0) public int getTtcIndex();
  }
@@ -16401,6 +16403,7 @@ package android.graphics.fonts {
    ctor public Font.Builder(@NonNull android.os.ParcelFileDescriptor, @IntRange(from=0) long, @IntRange(from=0xffffffff) long);
    ctor public Font.Builder(@NonNull android.content.res.AssetManager, @NonNull String);
    ctor public Font.Builder(@NonNull android.content.res.Resources, int);
    ctor public Font.Builder(@NonNull android.graphics.fonts.Font);
    method @NonNull public android.graphics.fonts.Font build() throws java.io.IOException;
    method @NonNull public android.graphics.fonts.Font.Builder setFontVariationSettings(@Nullable String);
    method @NonNull public android.graphics.fonts.Font.Builder setFontVariationSettings(@Nullable android.graphics.fonts.FontVariationAxis[]);
+71 −2
Original line number Diff line number Diff line
@@ -22,6 +22,8 @@ import android.annotation.Nullable;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.LocaleList;
import android.os.ParcelFileDescriptor;
import android.util.TypedValue;
@@ -29,6 +31,7 @@ import android.util.TypedValue;
import com.android.internal.util.Preconditions;

import dalvik.annotation.optimization.CriticalNative;
import dalvik.annotation.optimization.FastNative;

import libcore.util.NativeAllocationRegistry;

@@ -63,6 +66,7 @@ public final class Font {

        private @Nullable ByteBuffer mBuffer;
        private @Nullable File mFile;
        private @Nullable Font mFont;
        private @NonNull String mLocaleList = "";
        private @IntRange(from = -1, to = 1000) int mWeight = NOT_SPECIFIED;
        private @IntRange(from = -1, to = 1) int mItalic = NOT_SPECIFIED;
@@ -203,6 +207,22 @@ public final class Font {
            }
        }

        /**
         * Constructs a builder from existing Font instance.
         *
         * @param font the font instance.
         */
        public Builder(@NonNull Font font) {
            mFont = font;
            // Copies all parameters as a default value.
            mBuffer = font.getBuffer();
            mWeight = font.getStyle().getWeight();
            mItalic = font.getStyle().getSlant();
            mAxes = font.getAxes();
            mFile = font.getFile();
            mTtcIndex = font.getTtcIndex();
        }

        /**
         * Creates a buffer containing font data using the assetManager and other
         * provided inputs.
@@ -430,8 +450,13 @@ public final class Font {
            }
            final ByteBuffer readonlyBuffer = mBuffer.asReadOnlyBuffer();
            final String filePath = mFile == null ? "" : mFile.getAbsolutePath();
            final long ptr = nBuild(builderPtr, readonlyBuffer, filePath, mWeight, italic,
                    mTtcIndex);

            long ptr;
            if (mFont == null) {
                ptr = nBuild(builderPtr, readonlyBuffer, filePath, mWeight, italic, mTtcIndex);
            } else {
                ptr = nClone(mFont.getNativePtr(), builderPtr, mWeight, italic, mTtcIndex);
            }
            final Font font = new Font(ptr, readonlyBuffer, mFile,
                    new FontStyle(mWeight, slant), mTtcIndex, mAxes, mLocaleList);
            sFontRegistry.registerNativeAllocation(font, ptr);
@@ -449,6 +474,10 @@ public final class Font {
                boolean italic, int ttcIndex);
        @CriticalNative
        private static native long nGetReleaseNativeFont();

        @FastNative
        private static native long nClone(long fontPtr, long builderPtr, int weight,
                boolean italic, int ttcIndex);
    }

    private final long mNativePtr;  // address of the shared ptr of minikin::Font
@@ -538,6 +567,40 @@ public final class Font {
        return LocaleList.forLanguageTags(mLocaleList);
    }

    /**
     * Retrieve the glyph horizontal advance and bounding box.
     *
     * Note that {@link android.graphics.Typeface} in {@link android.graphics.Paint} is ignored.
     *
     * @param glyphId a glyph ID
     * @param paint a paint object used for resolving glyph style
     * @param rect a nullable destination object. If null is passed, this function just return the
     *             horizontal advance. If non-null is passed, this function fills bounding box
     *             information to this object.
     * @return the amount of horizontal advance in pixels
     */
    public float getGlyphBounds(@IntRange(from = 0) int glyphId, @NonNull Paint paint,
            @Nullable RectF rect) {
        return nGetGlyphBounds(mNativePtr, glyphId, paint.getNativeInstance(), rect);
    }

    /**
     * Retrieve the font metrics information.
     *
     * Note that {@link android.graphics.Typeface} in {@link android.graphics.Paint} is ignored.
     *
     * @param paint a paint object used for retrieving font metrics.
     * @param metrics a nullable destination object. If null is passed, this function only retrieve
     *                recommended interline spacing. If non-null is passed, this function fills to
     *                font metrics to it.
     *
     * @see Paint#getFontMetrics()
     * @see Paint#getFontMetricsInt()
     */
    public void getMetrics(@NonNull Paint paint, @Nullable Paint.FontMetrics metrics) {
        nGetFontMetrics(mNativePtr, paint.getNativeInstance(), metrics);
    }

    /** @hide */
    public long getNativePtr() {
        return mNativePtr;
@@ -573,4 +636,10 @@ public final class Font {
            + ", buffer=" + mBuffer
            + "}";
    }

    @FastNative
    private static native float nGetGlyphBounds(long font, int glyphId, long paint, RectF rect);

    @FastNative
    private static native float nGetFontMetrics(long font, long paint, Paint.FontMetrics metrics);
}
+59 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include "GraphicsJNI.h"

#include "SkCanvas.h"
#include "SkFontMetrics.h"
#include "SkMath.h"
#include "SkRegion.h"
#include <cutils/ashmem.h>
@@ -228,6 +229,20 @@ static jfieldID gColorSpace_Named_LinearExtendedSRGBFieldID;
static jclass gTransferParameters_class;
static jmethodID gTransferParameters_constructorMethodID;

static jclass   gFontMetrics_class;
static jfieldID gFontMetrics_top;
static jfieldID gFontMetrics_ascent;
static jfieldID gFontMetrics_descent;
static jfieldID gFontMetrics_bottom;
static jfieldID gFontMetrics_leading;

static jclass   gFontMetricsInt_class;
static jfieldID gFontMetricsInt_top;
static jfieldID gFontMetricsInt_ascent;
static jfieldID gFontMetricsInt_descent;
static jfieldID gFontMetricsInt_bottom;
static jfieldID gFontMetricsInt_leading;

///////////////////////////////////////////////////////////////////////////////

void GraphicsJNI::get_jrect(JNIEnv* env, jobject obj, int* L, int* T, int* R, int* B)
@@ -468,6 +483,32 @@ SkRegion* GraphicsJNI::getNativeRegion(JNIEnv* env, jobject region)
    return r;
}

void GraphicsJNI::set_metrics(JNIEnv* env, jobject metrics, const SkFontMetrics& skmetrics) {
    if (metrics == nullptr) return;
    SkASSERT(env->IsInstanceOf(metrics, gFontMetrics_class));
    env->SetFloatField(metrics, gFontMetrics_top, SkScalarToFloat(skmetrics.fTop));
    env->SetFloatField(metrics, gFontMetrics_ascent, SkScalarToFloat(skmetrics.fAscent));
    env->SetFloatField(metrics, gFontMetrics_descent, SkScalarToFloat(skmetrics.fDescent));
    env->SetFloatField(metrics, gFontMetrics_bottom, SkScalarToFloat(skmetrics.fBottom));
    env->SetFloatField(metrics, gFontMetrics_leading, SkScalarToFloat(skmetrics.fLeading));
}

int GraphicsJNI::set_metrics_int(JNIEnv* env, jobject metrics, const SkFontMetrics& skmetrics) {
    int ascent = SkScalarRoundToInt(skmetrics.fAscent);
    int descent = SkScalarRoundToInt(skmetrics.fDescent);
    int leading = SkScalarRoundToInt(skmetrics.fLeading);

    if (metrics) {
        SkASSERT(env->IsInstanceOf(metrics, gFontMetricsInt_class));
        env->SetIntField(metrics, gFontMetricsInt_top, SkScalarFloorToInt(skmetrics.fTop));
        env->SetIntField(metrics, gFontMetricsInt_ascent, ascent);
        env->SetIntField(metrics, gFontMetricsInt_descent, descent);
        env->SetIntField(metrics, gFontMetricsInt_bottom, SkScalarCeilToInt(skmetrics.fBottom));
        env->SetIntField(metrics, gFontMetricsInt_leading, leading);
    }
    return descent - ascent + leading;
}

///////////////////////////////////////////////////////////////////////////////////////////

jobject GraphicsJNI::createBitmapRegionDecoder(JNIEnv* env, skia::BitmapRegionDecoder* bitmap)
@@ -764,5 +805,23 @@ int register_android_graphics_Graphics(JNIEnv* env)
    gTransferParameters_constructorMethodID = GetMethodIDOrDie(env, gTransferParameters_class,
            "<init>", "(DDDDDDD)V");

    gFontMetrics_class = FindClassOrDie(env, "android/graphics/Paint$FontMetrics");
    gFontMetrics_class = MakeGlobalRefOrDie(env, gFontMetrics_class);

    gFontMetrics_top = GetFieldIDOrDie(env, gFontMetrics_class, "top", "F");
    gFontMetrics_ascent = GetFieldIDOrDie(env, gFontMetrics_class, "ascent", "F");
    gFontMetrics_descent = GetFieldIDOrDie(env, gFontMetrics_class, "descent", "F");
    gFontMetrics_bottom = GetFieldIDOrDie(env, gFontMetrics_class, "bottom", "F");
    gFontMetrics_leading = GetFieldIDOrDie(env, gFontMetrics_class, "leading", "F");

    gFontMetricsInt_class = FindClassOrDie(env, "android/graphics/Paint$FontMetricsInt");
    gFontMetricsInt_class = MakeGlobalRefOrDie(env, gFontMetricsInt_class);

    gFontMetricsInt_top = GetFieldIDOrDie(env, gFontMetricsInt_class, "top", "I");
    gFontMetricsInt_ascent = GetFieldIDOrDie(env, gFontMetricsInt_class, "ascent", "I");
    gFontMetricsInt_descent = GetFieldIDOrDie(env, gFontMetricsInt_class, "descent", "I");
    gFontMetricsInt_bottom = GetFieldIDOrDie(env, gFontMetricsInt_class, "bottom", "I");
    gFontMetricsInt_leading = GetFieldIDOrDie(env, gFontMetricsInt_class, "leading", "I");

    return 0;
}
+12 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include "graphics_jni_helpers.h"

class SkCanvas;
struct SkFontMetrics;

namespace android {
namespace skia {
@@ -85,6 +86,17 @@ public:
                                     bool* isHardware);
    static SkRegion* getNativeRegion(JNIEnv*, jobject region);

    /**
     * Set SkFontMetrics to Java Paint.FontMetrics.
     * Do nothing if metrics is nullptr.
     */
    static void set_metrics(JNIEnv*, jobject metrics, const SkFontMetrics& skmetrics);
    /**
     * Set SkFontMetrics to Java Paint.FontMetricsInt and return recommended interline space.
     * Do nothing if metrics is nullptr.
     */
    static int set_metrics_int(JNIEnv*, jobject metrics, const SkFontMetrics& skmetrics);

    /*
     *  LegacyBitmapConfig is the old enum in Skia that matched the enum int values
     *  in Bitmap.Config. Skia no longer supports this config, but has replaced it
+2 −55
Original line number Diff line number Diff line
@@ -59,20 +59,6 @@ using namespace android::uirenderer;

namespace android {

struct JMetricsID {
    jfieldID    top;
    jfieldID    ascent;
    jfieldID    descent;
    jfieldID    bottom;
    jfieldID    leading;
};

static jclass   gFontMetrics_class;
static JMetricsID gFontMetrics_fieldID;

static jclass   gFontMetricsInt_class;
static JMetricsID gFontMetricsInt_fieldID;

static void getPosTextPath(const SkFont& font, const uint16_t glyphs[], int count,
                           const SkPoint pos[], SkPath* dst) {
    dst->reset();
@@ -618,35 +604,14 @@ namespace PaintGlue {
    static jfloat getFontMetrics(JNIEnv* env, jobject, jlong paintHandle, jobject metricsObj) {
        SkFontMetrics metrics;
        SkScalar spacing = getMetricsInternal(paintHandle, &metrics);

        if (metricsObj) {
            SkASSERT(env->IsInstanceOf(metricsObj, gFontMetrics_class));
            env->SetFloatField(metricsObj, gFontMetrics_fieldID.top, SkScalarToFloat(metrics.fTop));
            env->SetFloatField(metricsObj, gFontMetrics_fieldID.ascent, SkScalarToFloat(metrics.fAscent));
            env->SetFloatField(metricsObj, gFontMetrics_fieldID.descent, SkScalarToFloat(metrics.fDescent));
            env->SetFloatField(metricsObj, gFontMetrics_fieldID.bottom, SkScalarToFloat(metrics.fBottom));
            env->SetFloatField(metricsObj, gFontMetrics_fieldID.leading, SkScalarToFloat(metrics.fLeading));
        }
        GraphicsJNI::set_metrics(env, metricsObj, metrics);
        return SkScalarToFloat(spacing);
    }

    static jint getFontMetricsInt(JNIEnv* env, jobject, jlong paintHandle, jobject metricsObj) {
        SkFontMetrics metrics;

        getMetricsInternal(paintHandle, &metrics);
        int ascent = SkScalarRoundToInt(metrics.fAscent);
        int descent = SkScalarRoundToInt(metrics.fDescent);
        int leading = SkScalarRoundToInt(metrics.fLeading);

        if (metricsObj) {
            SkASSERT(env->IsInstanceOf(metricsObj, gFontMetricsInt_class));
            env->SetIntField(metricsObj, gFontMetricsInt_fieldID.top, SkScalarFloorToInt(metrics.fTop));
            env->SetIntField(metricsObj, gFontMetricsInt_fieldID.ascent, ascent);
            env->SetIntField(metricsObj, gFontMetricsInt_fieldID.descent, descent);
            env->SetIntField(metricsObj, gFontMetricsInt_fieldID.bottom, SkScalarCeilToInt(metrics.fBottom));
            env->SetIntField(metricsObj, gFontMetricsInt_fieldID.leading, leading);
        }
        return descent - ascent + leading;
        return GraphicsJNI::set_metrics_int(env, metricsObj, metrics);
    }


@@ -1137,24 +1102,6 @@ static const JNINativeMethod methods[] = {
};

int register_android_graphics_Paint(JNIEnv* env) {
    gFontMetrics_class = FindClassOrDie(env, "android/graphics/Paint$FontMetrics");
    gFontMetrics_class = MakeGlobalRefOrDie(env, gFontMetrics_class);

    gFontMetrics_fieldID.top = GetFieldIDOrDie(env, gFontMetrics_class, "top", "F");
    gFontMetrics_fieldID.ascent = GetFieldIDOrDie(env, gFontMetrics_class, "ascent", "F");
    gFontMetrics_fieldID.descent = GetFieldIDOrDie(env, gFontMetrics_class, "descent", "F");
    gFontMetrics_fieldID.bottom = GetFieldIDOrDie(env, gFontMetrics_class, "bottom", "F");
    gFontMetrics_fieldID.leading = GetFieldIDOrDie(env, gFontMetrics_class, "leading", "F");

    gFontMetricsInt_class = FindClassOrDie(env, "android/graphics/Paint$FontMetricsInt");
    gFontMetricsInt_class = MakeGlobalRefOrDie(env, gFontMetricsInt_class);

    gFontMetricsInt_fieldID.top = GetFieldIDOrDie(env, gFontMetricsInt_class, "top", "I");
    gFontMetricsInt_fieldID.ascent = GetFieldIDOrDie(env, gFontMetricsInt_class, "ascent", "I");
    gFontMetricsInt_fieldID.descent = GetFieldIDOrDie(env, gFontMetricsInt_class, "descent", "I");
    gFontMetricsInt_fieldID.bottom = GetFieldIDOrDie(env, gFontMetricsInt_class, "bottom", "I");
    gFontMetricsInt_fieldID.leading = GetFieldIDOrDie(env, gFontMetricsInt_class, "leading", "I");

    return RegisterMethodsOrDie(env, "android/graphics/Paint", methods, NELEM(methods));
}

Loading