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

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

Merge "Update TextRunShaper to be backward compatible" into main

parents 66680ae9 8fb95361
Loading
Loading
Loading
Loading
+29 −10
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.graphics.Typeface;
import android.graphics.fonts.Font;

import com.android.internal.util.Preconditions;
import com.android.text.flags.Flags;

import dalvik.annotation.optimization.CriticalNative;

@@ -132,6 +133,9 @@ public final class PositionedGlyphs {
    @NonNull
    public Font getFont(@IntRange(from = 0) int index) {
        Preconditions.checkArgumentInRange(index, 0, glyphCount() - 1, "index");
        if (Flags.typefaceRedesign()) {
            return mFonts.get(nGetFontId(mLayoutPtr, index));
        }
        return mFonts.get(index);
    }

@@ -245,11 +249,19 @@ public final class PositionedGlyphs {
     */
    public PositionedGlyphs(long layoutPtr, float xOffset, float yOffset) {
        mLayoutPtr = layoutPtr;
        int glyphCount = nGetGlyphCount(layoutPtr);
        mFonts = new ArrayList<>(glyphCount);
        mXOffset = xOffset;
        mYOffset = yOffset;

        if (Flags.typefaceRedesign()) {
            int fontCount = nGetFontCount(layoutPtr);
            mFonts = new ArrayList<>(fontCount);
            for (int i = 0; i < fontCount; ++i) {
                mFonts.add(new Font(nGetFontRef(layoutPtr, i)));
            }
        } else {
            int glyphCount = nGetGlyphCount(layoutPtr);
            mFonts = new ArrayList<>(glyphCount);

            long prevPtr = 0;
            Font prevFont = null;
            for (int i = 0; i < glyphCount; ++i) {
@@ -260,6 +272,7 @@ public final class PositionedGlyphs {
                }
                mFonts.add(prevFont);
            }
        }

        NoImagePreloadHolder.REGISTRY.registerNativeAllocation(this, layoutPtr);
    }
@@ -290,6 +303,12 @@ public final class PositionedGlyphs {
    private static native float nGetWeightOverride(long minikinLayout, int i);
    @CriticalNative
    private static native float nGetItalicOverride(long minikinLayout, int i);
    @CriticalNative
    private static native int nGetFontCount(long minikinLayout);
    @CriticalNative
    private static native long nGetFontRef(long minikinLayout, int fontId);
    @CriticalNative
    private static native int nGetFontId(long minikinLayout, int glyphIndex);

    @Override
    public boolean equals(Object o) {
+85 −12
Original line number Diff line number Diff line
@@ -31,12 +31,34 @@

namespace android {

struct FakedFontKey {
    uint32_t operator()(const minikin::FakedFont& fakedFont) const {
        return minikin::Hasher()
                .update(reinterpret_cast<uintptr_t>(fakedFont.font.get()))
                .update(fakedFont.fakery.bits())
                .update(fakedFont.fakery.variationSettings())
                .hash();
    }
};

struct LayoutWrapper {
    LayoutWrapper(minikin::Layout&& layout, float ascent, float descent)
        : layout(std::move(layout)), ascent(ascent), descent(descent)  {}

    LayoutWrapper(minikin::Layout&& layout, float ascent, float descent, std::vector<jlong>&& fonts,
                  std::vector<uint32_t>&& fontIds)
            : layout(std::move(layout))
            , ascent(ascent)
            , descent(descent)
            , fonts(std::move(fonts))
            , fontIds(std::move(fontIds)) {}

    minikin::Layout layout;
    float ascent;
    float descent;

    std::vector<jlong> fonts;
    std::vector<uint32_t> fontIds;  // per glyph
};

static void releaseLayout(jlong ptr) {
@@ -64,6 +86,43 @@ static jlong shapeTextRun(const uint16_t* text, int textSize, int start, int cou
        overallDescent = std::max(overallDescent, extent.descent);
    }

    if (text_feature::typeface_redesign()) {
        uint32_t runCount = layout.getFontRunCount();

        std::unordered_map<minikin::FakedFont, uint32_t, FakedFontKey> fakedToFontIds;
        std::vector<jlong> fonts;
        std::vector<uint32_t> fontIds;

        fontIds.resize(layout.nGlyphs());
        for (uint32_t ri = 0; ri < runCount; ++ri) {
            const minikin::FakedFont& fakedFont = layout.getFontRunFont(ri);

            auto it = fakedToFontIds.find(fakedFont);
            uint32_t fontId;
            if (it != fakedToFontIds.end()) {
                fontId = it->second;  // We've seen it.
            } else {
                fontId = fonts.size();  // This is new to us. Create new one.
                std::shared_ptr<minikin::Font> font = std::make_shared<minikin::Font>(
                        fakedFont.font, fakedFont.fakery.variationSettings());
                fonts.push_back(reinterpret_cast<jlong>(new FontWrapper(std::move(font))));
                fakedToFontIds.insert(std::make_pair(fakedFont, fontId));
            }

            const uint32_t runStart = layout.getFontRunStart(ri);
            const uint32_t runEnd = layout.getFontRunEnd(ri);
            for (uint32_t i = runStart; i < runEnd; ++i) {
                fontIds[i] = fontId;
            }
        }

        std::unique_ptr<LayoutWrapper> ptr =
                std::make_unique<LayoutWrapper>(std::move(layout), overallAscent, overallDescent,
                                                std::move(fonts), std::move(fontIds));

        return reinterpret_cast<jlong>(ptr.release());
    }

    std::unique_ptr<LayoutWrapper> ptr = std::make_unique<LayoutWrapper>(
        std::move(layout), overallAscent, overallDescent
    );
@@ -156,6 +215,8 @@ static jboolean TextShaper_Result_getFakeItalic(CRITICAL_JNI_PARAMS_COMMA jlong
    return layout->layout.getFakery(i).isFakeItalic();
}

constexpr float NO_OVERRIDE = -1;

float findValueFromVariationSettings(const minikin::FontFakery& fakery, minikin::AxisTag tag) {
    for (const minikin::FontVariation& fv : fakery.variationSettings()) {
        if (fv.axisTag == tag) {
@@ -171,12 +232,7 @@ static jfloat TextShaper_Result_getWeightOverride(CRITICAL_JNI_PARAMS_COMMA jlon
    if (text_feature::typeface_redesign()) {
        float value =
                findValueFromVariationSettings(layout->layout.getFakery(i), minikin::TAG_wght);
        if (!std::isnan(value)) {
            return value;
        } else {
            const std::shared_ptr<minikin::Font>& font = layout->layout.getFontRef(i);
            return font->style().weight();
        }
        return std::isnan(value) ? NO_OVERRIDE : value;
    } else {
        return layout->layout.getFakery(i).wghtAdjustment();
    }
@@ -188,12 +244,7 @@ static jfloat TextShaper_Result_getItalicOverride(CRITICAL_JNI_PARAMS_COMMA jlon
    if (text_feature::typeface_redesign()) {
        float value =
                findValueFromVariationSettings(layout->layout.getFakery(i), minikin::TAG_ital);
        if (!std::isnan(value)) {
            return value;
        } else {
            const std::shared_ptr<minikin::Font>& font = layout->layout.getFontRef(i);
            return font->style().isItalic();
        }
        return std::isnan(value) ? NO_OVERRIDE : value;
    } else {
        return layout->layout.getFakery(i).italAdjustment();
    }
@@ -206,6 +257,24 @@ static jlong TextShaper_Result_getFont(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint
    return reinterpret_cast<jlong>(new FontWrapper(std::move(fontRef)));
}

// CriticalNative
static jint TextShaper_Result_getFontCount(CRITICAL_JNI_PARAMS_COMMA jlong ptr) {
    const LayoutWrapper* layout = reinterpret_cast<LayoutWrapper*>(ptr);
    return layout->fonts.size();
}

// CriticalNative
static jlong TextShaper_Result_getFontRef(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint fontId) {
    const LayoutWrapper* layout = reinterpret_cast<LayoutWrapper*>(ptr);
    return layout->fonts[fontId];
}

// CriticalNative
static jint TextShaper_Result_getFontId(CRITICAL_JNI_PARAMS_COMMA jlong ptr, jint glyphIdx) {
    const LayoutWrapper* layout = reinterpret_cast<LayoutWrapper*>(ptr);
    return layout->fontIds[glyphIdx];
}

// CriticalNative
static jlong TextShaper_Result_nReleaseFunc(CRITICAL_JNI_PARAMS) {
    return reinterpret_cast<jlong>(releaseLayout);
@@ -250,6 +319,10 @@ static const JNINativeMethod gResultMethods[] = {
        {"nGetWeightOverride", "(JI)F", (void*)TextShaper_Result_getWeightOverride},
        {"nGetItalicOverride", "(JI)F", (void*)TextShaper_Result_getItalicOverride},
        {"nReleaseFunc", "()J", (void*)TextShaper_Result_nReleaseFunc},

        {"nGetFontCount", "(J)I", (void*)TextShaper_Result_getFontCount},
        {"nGetFontRef", "(JI)J", (void*)TextShaper_Result_getFontRef},
        {"nGetFontId", "(JI)I", (void*)TextShaper_Result_getFontId},
};

int register_android_graphics_text_TextShaper(JNIEnv* env) {