Loading graphics/java/android/graphics/text/PositionedGlyphs.java +29 −10 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } Loading Loading @@ -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) { Loading @@ -260,6 +272,7 @@ public final class PositionedGlyphs { } mFonts.add(prevFont); } } NoImagePreloadHolder.REGISTRY.registerNativeAllocation(this, layoutPtr); } Loading Loading @@ -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) { Loading libs/hwui/jni/text/TextShaper.cpp +85 −12 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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 ); Loading Loading @@ -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) { Loading @@ -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(); } Loading @@ -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(); } Loading @@ -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); Loading Loading @@ -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) { Loading Loading
graphics/java/android/graphics/text/PositionedGlyphs.java +29 −10 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } Loading Loading @@ -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) { Loading @@ -260,6 +272,7 @@ public final class PositionedGlyphs { } mFonts.add(prevFont); } } NoImagePreloadHolder.REGISTRY.registerNativeAllocation(this, layoutPtr); } Loading Loading @@ -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) { Loading
libs/hwui/jni/text/TextShaper.cpp +85 −12 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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 ); Loading Loading @@ -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) { Loading @@ -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(); } Loading @@ -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(); } Loading @@ -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); Loading Loading @@ -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) { Loading