diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp index c090a754ed577..49024b6a0b5fc 100644 --- a/core/jni/android/graphics/FontFamily.cpp +++ b/core/jni/android/graphics/FontFamily.cpp @@ -63,27 +63,27 @@ static jlong FontFamily_create(jlong builderPtr) { return 0; } NativeFamilyBuilder* builder = reinterpret_cast(builderPtr); - minikin::FontFamily* family = new minikin::FontFamily( - builder->langId, builder->variant, std::move(builder->fonts)); + FontFamilyWrapper* family = new FontFamilyWrapper( + std::make_shared( + builder->langId, builder->variant, std::move(builder->fonts))); delete builder; return reinterpret_cast(family); } static void FontFamily_abort(jlong builderPtr) { NativeFamilyBuilder* builder = reinterpret_cast(builderPtr); - minikin::Font::clearElementsWithLock(&builder->fonts); delete builder; } static void FontFamily_unref(jlong familyPtr) { - minikin::FontFamily* fontFamily = reinterpret_cast(familyPtr); - fontFamily->Unref(); + FontFamilyWrapper* family = reinterpret_cast(familyPtr); + delete family; } static void addSkTypeface(jlong builderPtr, sk_sp face, const void* fontData, size_t fontSize, int ttcIndex, jint givenWeight, jboolean givenItalic) { - minikin::MinikinFont* minikinFont = - new MinikinFontSkia(std::move(face), fontData, fontSize, ttcIndex, + std::shared_ptr minikinFont = + std::make_shared(std::move(face), fontData, fontSize, ttcIndex, std::vector()); NativeFamilyBuilder* builder = reinterpret_cast(builderPtr); int weight = givenWeight / 100; @@ -96,8 +96,8 @@ static void addSkTypeface(jlong builderPtr, sk_sp face, const void* } } - builder->fonts.push_back(minikin::Font(minikinFont, minikin::FontStyle(weight, italic))); - minikinFont->Unref(); + builder->fonts.push_back(minikin::Font( + std::move(minikinFont), minikin::FontStyle(weight, italic))); } static void release_global_ref(const void* /*data*/, void* context) { @@ -208,13 +208,12 @@ static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong ALOGE("addFont failed to create font, invalid request"); return false; } - minikin::MinikinFont* minikinFont = - new MinikinFontSkia(std::move(face), fontPtr, fontSize, ttcIndex, + std::shared_ptr minikinFont = + std::make_shared(std::move(face), fontPtr, fontSize, ttcIndex, std::vector()); NativeFamilyBuilder* builder = reinterpret_cast(builderPtr); - builder->fonts.push_back(minikin::Font(minikinFont, + builder->fonts.push_back(minikin::Font(std::move(minikinFont), minikin::FontStyle(weight / 100, isItalic))); - minikinFont->Unref(); return true; } diff --git a/core/jni/android/graphics/FontUtils.h b/core/jni/android/graphics/FontUtils.h index 8f44b1e82de8b..9eaaa4964b66d 100644 --- a/core/jni/android/graphics/FontUtils.h +++ b/core/jni/android/graphics/FontUtils.h @@ -18,9 +18,19 @@ #define _ANDROID_GRAPHICS_FONT_UTILS_H_ #include +#include + +namespace minikin { +class FontFamily; +} // namespace minikin namespace android { +struct FontFamilyWrapper { + FontFamilyWrapper(std::shared_ptr&& family) : family(family) {} + std::shared_ptr family; +}; + // Utility wrapper for java.util.List class ListHelper { public: diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index bdf79d30aa099..18462376cd20d 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -300,8 +300,8 @@ namespace PaintGlue { static void getTextPath(JNIEnv* env, Paint* paint, Typeface* typeface, const jchar* text, jint count, jint bidiFlags, jfloat x, jfloat y, SkPath* path) { - minikin::Layout layout; - MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, text, 0, count, count); + minikin::Layout layout = MinikinUtils::doLayout( + paint, bidiFlags, typeface, text, 0, count, count); size_t nGlyphs = layout.nGlyphs(); uint16_t* glyphs = new uint16_t[nGlyphs]; SkPoint* pos = new SkPoint[nGlyphs]; @@ -344,8 +344,8 @@ namespace PaintGlue { SkRect r; SkIRect ir; - minikin::Layout layout; - MinikinUtils::doLayout(&layout, &paint, bidiFlags, typeface, text, 0, count, count); + minikin::Layout layout = MinikinUtils::doLayout( + &paint, bidiFlags, typeface, text, 0, count, count); minikin::MinikinRect rect; layout.getBounds(&rect); r.fLeft = rect.mLeft; @@ -459,9 +459,8 @@ namespace PaintGlue { nChars++; prevCp = cp; } - minikin::Layout layout; - MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, str.get(), 0, str.size(), - str.size()); + minikin::Layout layout = MinikinUtils::doLayout( + paint, bidiFlags, typeface, str.get(), 0, str.size(), str.size()); size_t nGlyphs = countNonSpaceGlyphs(layout); if (nGlyphs != 1 && nChars > 1) { // multiple-character input, and was not a ligature @@ -480,8 +479,8 @@ namespace PaintGlue { // since ZZ is reserved for unknown or invalid territory. // U+1F1FF (REGIONAL INDICATOR SYMBOL LETTER Z) is \uD83C\uDDFF in UTF16. static const jchar ZZ_FLAG_STR[] = { 0xD83C, 0xDDFF, 0xD83C, 0xDDFF }; - minikin::Layout zzLayout; - MinikinUtils::doLayout(&zzLayout, paint, bidiFlags, typeface, ZZ_FLAG_STR, 0, 4, 4); + minikin::Layout zzLayout = MinikinUtils::doLayout( + paint, bidiFlags, typeface, ZZ_FLAG_STR, 0, 4, 4); if (zzLayout.nGlyphs() != 1 || layoutContainsNotdef(zzLayout)) { // The font collection doesn't have a glyph for unknown flag. Just return true. return true; diff --git a/core/jni/android/graphics/Typeface.cpp b/core/jni/android/graphics/Typeface.cpp index 0a0fce3ecfabf..0cdc74fa92d84 100644 --- a/core/jni/android/graphics/Typeface.cpp +++ b/core/jni/android/graphics/Typeface.cpp @@ -67,9 +67,7 @@ static jlong Typeface_createWeightAlias(JNIEnv* env, jobject, jlong familyHandle static void Typeface_unref(JNIEnv* env, jobject obj, jlong faceHandle) { Typeface* face = reinterpret_cast(faceHandle); - if (face != NULL) { - face->unref(); - } + delete face; } static jint Typeface_getStyle(JNIEnv* env, jobject obj, jlong faceHandle) { @@ -79,12 +77,13 @@ static jint Typeface_getStyle(JNIEnv* env, jobject obj, jlong faceHandle) { static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArray) { ScopedLongArrayRO families(env, familyArray); - std::vector familyVec; + std::vector> familyVec; + familyVec.reserve(families.size()); for (size_t i = 0; i < families.size(); i++) { - minikin::FontFamily* family = reinterpret_cast(families[i]); - familyVec.push_back(family); + FontFamilyWrapper* family = reinterpret_cast(families[i]); + familyVec.emplace_back(family->family); } - return reinterpret_cast(Typeface::createFromFamilies(familyVec)); + return reinterpret_cast(Typeface::createFromFamilies(std::move(familyVec))); } static void Typeface_setDefault(JNIEnv *env, jobject, jlong faceHandle) { diff --git a/core/jni/android_text_StaticLayout.cpp b/core/jni/android_text_StaticLayout.cpp index c05ef26fd5ac2..90ed6eb5e60e0 100644 --- a/core/jni/android_text_StaticLayout.cpp +++ b/core/jni/android_text_StaticLayout.cpp @@ -159,11 +159,12 @@ static jfloat nAddStyleRun(JNIEnv* env, jclass, jlong nativePtr, minikin::LineBreaker* b = reinterpret_cast(nativePtr); Paint* paint = reinterpret_cast(nativePaint); Typeface* typeface = reinterpret_cast(nativeTypeface); - minikin::FontCollection *font; minikin::MinikinPaint minikinPaint; - minikin::FontStyle style = MinikinUtils::prepareMinikinPaint(&minikinPaint, &font, paint, + Typeface* resolvedTypeface = Typeface::resolveDefault(typeface); + minikin::FontStyle style = MinikinUtils::prepareMinikinPaint(&minikinPaint, paint, typeface); - return b->addStyleRun(&minikinPaint, font, style, start, end, isRtl); + return b->addStyleRun(&minikinPaint, resolvedTypeface->fFontCollection, style, start, end, + isRtl); } // Accept width measurements for the run, passed in from Java diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp index c365b5d8e6043..c64a89de7296d 100644 --- a/libs/hwui/hwui/Canvas.cpp +++ b/libs/hwui/hwui/Canvas.cpp @@ -153,8 +153,8 @@ void Canvas::drawText(const uint16_t* text, int start, int count, int contextCou // minikin may modify the original paint Paint paint(origPaint); - minikin::Layout layout; - MinikinUtils::doLayout(&layout, &paint, bidiFlags, typeface, text, start, count, contextCount); + minikin::Layout layout = MinikinUtils::doLayout( + &paint, bidiFlags, typeface, text, start, count, contextCount); size_t nGlyphs = layout.nGlyphs(); std::unique_ptr glyphs(new uint16_t[nGlyphs]); @@ -205,8 +205,8 @@ private: void Canvas::drawTextOnPath(const uint16_t* text, int count, int bidiFlags, const SkPath& path, float hOffset, float vOffset, const Paint& paint, Typeface* typeface) { Paint paintCopy(paint); - minikin::Layout layout; - MinikinUtils::doLayout(&layout, &paintCopy, bidiFlags, typeface, text, 0, count, count); + minikin::Layout layout = MinikinUtils::doLayout( + &paintCopy, bidiFlags, typeface, text, 0, count, count); hOffset += MinikinUtils::hOffsetForTextAlign(&paintCopy, layout, path); // Set align to left for drawing, as we don't want individual diff --git a/libs/hwui/hwui/MinikinSkia.cpp b/libs/hwui/hwui/MinikinSkia.cpp index cbae0a0dbf4ac..ba4e3a4df578a 100644 --- a/libs/hwui/hwui/MinikinSkia.cpp +++ b/libs/hwui/hwui/MinikinSkia.cpp @@ -91,7 +91,7 @@ const std::vector& MinikinFontSkia::GetAxes() const { return mAxes; } -minikin::MinikinFont* MinikinFontSkia::createFontWithVariation( +std::shared_ptr MinikinFontSkia::createFontWithVariation( const std::vector& variations) const { SkFontMgr::FontParameters params; @@ -110,7 +110,8 @@ minikin::MinikinFont* MinikinFontSkia::createFontWithVariation( sk_sp fm(SkFontMgr::RefDefault()); sk_sp face(fm->createFromStream(stream, params)); - return new MinikinFontSkia(std::move(face), mFontData, mFontSize, ttcIndex, variations); + return std::make_shared(std::move(face), mFontData, mFontSize, ttcIndex, + variations); } uint32_t MinikinFontSkia::packPaintFlags(const SkPaint* paint) { diff --git a/libs/hwui/hwui/MinikinSkia.h b/libs/hwui/hwui/MinikinSkia.h index db59fe520068e..6c12485845fd0 100644 --- a/libs/hwui/hwui/MinikinSkia.h +++ b/libs/hwui/hwui/MinikinSkia.h @@ -45,7 +45,7 @@ public: size_t GetFontSize() const; int GetFontIndex() const; const std::vector& GetAxes() const; - minikin::MinikinFont* createFontWithVariation( + std::shared_ptr createFontWithVariation( const std::vector&) const; static uint32_t packPaintFlags(const SkPaint* paint); diff --git a/libs/hwui/hwui/MinikinUtils.cpp b/libs/hwui/hwui/MinikinUtils.cpp index 713e5099da265..d1871ffaf92be 100644 --- a/libs/hwui/hwui/MinikinUtils.cpp +++ b/libs/hwui/hwui/MinikinUtils.cpp @@ -27,9 +27,8 @@ namespace android { minikin::FontStyle MinikinUtils::prepareMinikinPaint(minikin::MinikinPaint* minikinPaint, - minikin::FontCollection** pFont, const Paint* paint, Typeface* typeface) { + const Paint* paint, Typeface* typeface) { const Typeface* resolvedFace = Typeface::resolveDefault(typeface); - *pFont = resolvedFace->fFontCollection; minikin::FontStyle resolved = resolvedFace->fStyle; /* Prepare minikin FontStyle */ @@ -54,23 +53,23 @@ minikin::FontStyle MinikinUtils::prepareMinikinPaint(minikin::MinikinPaint* mini return minikinStyle; } -void MinikinUtils::doLayout(minikin::Layout* layout, const Paint* paint, int bidiFlags, +minikin::Layout MinikinUtils::doLayout(const Paint* paint, int bidiFlags, Typeface* typeface, const uint16_t* buf, size_t start, size_t count, size_t bufSize) { - minikin::FontCollection *font; minikin::MinikinPaint minikinPaint; - minikin::FontStyle minikinStyle = prepareMinikinPaint(&minikinPaint, &font, paint, typeface); - layout->setFontCollection(font); - layout->doLayout(buf, start, count, bufSize, bidiFlags, minikinStyle, minikinPaint); + minikin::FontStyle minikinStyle = prepareMinikinPaint(&minikinPaint, paint, typeface); + minikin::Layout layout(Typeface::resolveDefault(typeface)->fFontCollection); + layout.doLayout(buf, start, count, bufSize, bidiFlags, minikinStyle, minikinPaint); + return layout; } float MinikinUtils::measureText(const Paint* paint, int bidiFlags, Typeface* typeface, const uint16_t* buf, size_t start, size_t count, size_t bufSize, float *advances) { - minikin::FontCollection *font; minikin::MinikinPaint minikinPaint; - minikin::FontStyle minikinStyle = prepareMinikinPaint(&minikinPaint, &font, paint, typeface); + minikin::FontStyle minikinStyle = prepareMinikinPaint(&minikinPaint, paint, typeface); + Typeface* resolvedTypeface = Typeface::resolveDefault(typeface); return minikin::Layout::measureText(buf, start, count, bufSize, bidiFlags, minikinStyle, - minikinPaint, font, advances); + minikinPaint, resolvedTypeface->fFontCollection, advances); } bool MinikinUtils::hasVariationSelector(Typeface* typeface, uint32_t codepoint, uint32_t vs) { diff --git a/libs/hwui/hwui/MinikinUtils.h b/libs/hwui/hwui/MinikinUtils.h index d6f64d2418d50..0f22adc5d42bc 100644 --- a/libs/hwui/hwui/MinikinUtils.h +++ b/libs/hwui/hwui/MinikinUtils.h @@ -35,9 +35,9 @@ namespace android { class MinikinUtils { public: ANDROID_API static minikin::FontStyle prepareMinikinPaint(minikin::MinikinPaint* minikinPaint, - minikin::FontCollection** pFont, const Paint* paint, Typeface* typeface); + const Paint* paint, Typeface* typeface); - ANDROID_API static void doLayout(minikin::Layout* layout, const Paint* paint, int bidiFlags, + ANDROID_API static minikin::Layout doLayout(const Paint* paint, int bidiFlags, Typeface* typeface, const uint16_t* buf, size_t start, size_t count, size_t bufSize); @@ -56,11 +56,11 @@ public: ANDROID_API static void forFontRun(const minikin::Layout& layout, Paint* paint, F& f) { float saveSkewX = paint->getTextSkewX(); bool savefakeBold = paint->isFakeBoldText(); - minikin::MinikinFont* curFont = NULL; + const minikin::MinikinFont* curFont = nullptr; size_t start = 0; size_t nGlyphs = layout.nGlyphs(); for (size_t i = 0; i < nGlyphs; i++) { - minikin::MinikinFont* nextFont = layout.getFont(i); + const minikin::MinikinFont* nextFont = layout.getFont(i); if (i > 0 && nextFont != curFont) { MinikinFontSkia::populateSkPaint(paint, curFont, layout.getFakery(start)); f(start, i); diff --git a/libs/hwui/hwui/Typeface.cpp b/libs/hwui/hwui/Typeface.cpp index 9f9fac61fecc9..4b8575adb32b8 100644 --- a/libs/hwui/hwui/Typeface.cpp +++ b/libs/hwui/hwui/Typeface.cpp @@ -64,7 +64,6 @@ Typeface* Typeface::createFromTypeface(Typeface* src, SkTypeface::Style style) { Typeface* result = new Typeface; if (result != nullptr) { result->fFontCollection = resolvedFace->fFontCollection; - result->fFontCollection->Ref(); result->fSkiaStyle = style; result->fBaseWeight = resolvedFace->fBaseWeight; resolveStyle(result); @@ -83,7 +82,6 @@ Typeface* Typeface::createFromTypefaceWithVariation(Typeface* src, // None of passed axes are supported by this collection. // So we will reuse the same collection with incrementing reference count. result->fFontCollection = resolvedFace->fFontCollection; - result->fFontCollection->Ref(); } result->fSkiaStyle = resolvedFace->fSkiaStyle; result->fBaseWeight = resolvedFace->fBaseWeight; @@ -97,7 +95,6 @@ Typeface* Typeface::createWeightAlias(Typeface* src, int weight) { Typeface* result = new Typeface; if (result != nullptr) { result->fFontCollection = resolvedFace->fFontCollection; - result->fFontCollection->Ref(); result->fSkiaStyle = resolvedFace->fSkiaStyle; result->fBaseWeight = weight; resolveStyle(result); @@ -105,18 +102,19 @@ Typeface* Typeface::createWeightAlias(Typeface* src, int weight) { return result; } -Typeface* Typeface::createFromFamilies(const std::vector& families) { +Typeface* Typeface::createFromFamilies( + std::vector>&& families) { Typeface* result = new Typeface; - result->fFontCollection = new minikin::FontCollection(families); + result->fFontCollection.reset(new minikin::FontCollection(families)); if (families.empty()) { ALOGW("createFromFamilies creating empty collection"); result->fSkiaStyle = SkTypeface::kNormal; } else { const minikin::FontStyle defaultStyle; - minikin::FontFamily* firstFamily = reinterpret_cast(families[0]); - minikin::MinikinFont* mf = firstFamily->getClosestMatch(defaultStyle).font; - if (mf != NULL) { - SkTypeface* skTypeface = reinterpret_cast(mf)->GetSkTypeface(); + const std::shared_ptr& firstFamily = families[0]; + const minikin::MinikinFont* mf = firstFamily->getClosestMatch(defaultStyle).font; + if (mf != nullptr) { + SkTypeface* skTypeface = reinterpret_cast(mf)->GetSkTypeface(); // TODO: probably better to query more precise style from family, will be important // when we open up API to access 100..900 weights result->fSkiaStyle = skTypeface->style(); @@ -129,11 +127,6 @@ Typeface* Typeface::createFromFamilies(const std::vector& return result; } -void Typeface::unref() { - fFontCollection->Unref(); - delete this; -} - void Typeface::setDefault(Typeface* face) { gDefaultTypeface = face; } @@ -150,15 +143,12 @@ void Typeface::setRobotoTypefaceForTest() { sk_sp typeface = SkTypeface::MakeFromStream(fontData.release()); LOG_ALWAYS_FATAL_IF(typeface == nullptr, "Failed to make typeface from %s", kRobotoFont); - minikin::MinikinFont* font = new MinikinFontSkia(std::move(typeface), data, st.st_size, 0, - std::vector()); - minikin::FontFamily* family = new minikin::FontFamily( - std::vector({ minikin::Font(font, minikin::FontStyle()) })); - font->Unref(); - - std::vector typefaces = { family }; - minikin::FontCollection *collection = new minikin::FontCollection(typefaces); - family->Unref(); + std::shared_ptr font = std::make_shared( + std::move(typeface), data, st.st_size, 0, std::vector()); + std::shared_ptr family = std::make_shared( + std::vector({ minikin::Font(std::move(font), minikin::FontStyle()) })); + std::shared_ptr collection = + std::make_shared(std::move(family)); Typeface* hwTypeface = new Typeface(); hwTypeface->fFontCollection = collection; diff --git a/libs/hwui/hwui/Typeface.h b/libs/hwui/hwui/Typeface.h index 4392ebc36badf..19a4f6c5acd5a 100644 --- a/libs/hwui/hwui/Typeface.h +++ b/libs/hwui/hwui/Typeface.h @@ -23,11 +23,12 @@ #include #include #include +#include namespace android { struct ANDROID_API Typeface { - minikin::FontCollection *fFontCollection; + std::shared_ptr fFontCollection; // style used for constructing and querying Typeface objects SkTypeface::Style fSkiaStyle; @@ -37,8 +38,6 @@ struct ANDROID_API Typeface { // resolved style actually used for rendering minikin::FontStyle fStyle; - void unref(); - static Typeface* resolveDefault(Typeface* src); static Typeface* createFromTypeface(Typeface* src, SkTypeface::Style style); @@ -48,7 +47,8 @@ struct ANDROID_API Typeface { static Typeface* createWeightAlias(Typeface* src, int baseweight); - static Typeface* createFromFamilies(const std::vector& families); + static Typeface* createFromFamilies( + std::vector>&& families); static void setDefault(Typeface* face);