Loading core/jni/android/graphics/Canvas.cpp +38 −25 Original line number Diff line number Diff line Loading @@ -821,32 +821,45 @@ public: } #ifdef USE_MINIKIN static void drawGlyphsToSkia(SkCanvas* canvas, SkPaint* paint, Layout* layout, float x, float y) { size_t nGlyphs = layout->nGlyphs(); class DrawTextFunctor { public: DrawTextFunctor(const Layout& layout, SkCanvas* canvas, jfloat x, jfloat y, SkPaint* paint, uint16_t* glyphs, SkPoint* pos) : layout(layout), canvas(canvas), x(x), y(y), paint(paint), glyphs(glyphs), pos(pos) { } void operator()(SkTypeface* t, size_t start, size_t end) { for (size_t i = start; i < end; i++) { glyphs[i] = layout.getGlyphId(i); pos[i].fX = x + layout.getX(i); pos[i].fY = y + layout.getY(i); } paint->setTypeface(t); canvas->drawPosText(glyphs + start, (end - start) << 1, pos + start, *paint); } private: const Layout& layout; SkCanvas* canvas; jfloat x; jfloat y; SkPaint* paint; uint16_t* glyphs; SkPoint* pos; }; static void drawGlyphsToSkia(SkCanvas* canvas, SkPaint* paint, const Layout& layout, float x, float y) { size_t nGlyphs = layout.nGlyphs(); uint16_t* glyphs = new uint16_t[nGlyphs]; SkPoint* pos = new SkPoint[nGlyphs]; SkTypeface *lastFace = NULL; SkTypeface *skFace = NULL; size_t start = 0; x += MinikinUtils::xOffsetForTextAlign(paint, layout); SkPaint::Align align = paint->getTextAlign(); paint->setTextAlign(SkPaint::kLeft_Align); paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding); for (size_t i = 0; i < nGlyphs; i++) { MinikinFontSkia *mfs = static_cast<MinikinFontSkia *>(layout->getFont(i)); skFace = mfs->GetSkTypeface(); glyphs[i] = layout->getGlyphId(i); pos[i].fX = x + layout->getX(i); pos[i].fY = y + layout->getY(i); if (i > 0 && skFace != lastFace) { paint->setTypeface(lastFace); canvas->drawPosText(glyphs + start, (i - start) << 1, pos + start, *paint); start = i; } lastFace = skFace; } if (skFace != NULL) { paint->setTypeface(skFace); canvas->drawPosText(glyphs + start, (nGlyphs - start) << 1, pos + start, *paint); } DrawTextFunctor f(layout, canvas, x, y, paint, glyphs, pos); MinikinUtils::forFontRun(layout, f); doDrawTextDecorations(canvas, x, y, layout.getAdvance(), paint); paint->setTextAlign(align); delete[] glyphs; delete[] pos; } Loading @@ -868,7 +881,7 @@ public: Layout layout; MinikinUtils::SetLayoutProperties(&layout, paint, flags, typeface); layout.doLayout(textArray + start, count); drawGlyphsToSkia(canvas, paint, &layout, x, y); drawGlyphsToSkia(canvas, paint, layout, x, y); #else sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint, textArray, start, count, contextCount, flags); Loading core/jni/android/graphics/MinikinUtils.cpp +16 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include "SkPaint.h" #include "minikin/Layout.h" #include "TypefaceImpl.h" #include "MinikinSkia.h" #include "MinikinUtils.h" Loading @@ -42,4 +43,18 @@ void MinikinUtils::SetLayoutProperties(Layout* layout, SkPaint* paint, int flags layout->setProperties(css); } float MinikinUtils::xOffsetForTextAlign(SkPaint* paint, const Layout& layout) { switch (paint->getTextAlign()) { case SkPaint::kCenter_Align: return layout.getAdvance() * -0.5f; break; case SkPaint::kRight_Align: return -layout.getAdvance(); break; default: break; } return 0; } } core/jni/android/graphics/MinikinUtils.h +21 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,27 @@ class MinikinUtils { public: static void SetLayoutProperties(Layout* layout, SkPaint* paint, int flags, TypefaceImpl* face); static float xOffsetForTextAlign(SkPaint* paint, const Layout& layout); // f is a functor of type void f(SkTypeface *, size_t start, size_t end); template <typename F> static void forFontRun(const Layout& layout, F& f) { SkTypeface* lastFace = NULL; size_t start = 0; size_t nGlyphs = layout.nGlyphs(); for (size_t i = 0; i < nGlyphs; i++) { MinikinFontSkia* mfs = static_cast<MinikinFontSkia*>(layout.getFont(i)); SkTypeface* skFace = mfs->GetSkTypeface(); if (i > 0 && skFace != lastFace) { f(lastFace, start, i); start = i; } lastFace = skFace; } if (nGlyphs > start) { f(lastFace, start, nGlyphs); } } }; } // namespace android Loading core/jni/android/graphics/Paint.cpp +65 −8 Original line number Diff line number Diff line Loading @@ -822,26 +822,83 @@ public: return result; } static void getTextPath(JNIEnv* env, SkPaint* paint, const jchar* text, jint count, jint bidiFlags, jfloat x, jfloat y, SkPath *path) { #ifdef USE_MINIKIN class GetTextFunctor { public: GetTextFunctor(const Layout& layout, SkPath* path, jfloat x, jfloat y, SkPaint* paint, uint16_t* glyphs, SkPoint* pos) : layout(layout), path(path), x(x), y(y), paint(paint), glyphs(glyphs), pos(pos) { } void operator()(SkTypeface* t, size_t start, size_t end) { for (size_t i = start; i < end; i++) { glyphs[i] = layout.getGlyphId(i); pos[i].fX = x + layout.getX(i); pos[i].fY = y + layout.getY(i); } paint->setTypeface(t); if (start == 0) { paint->getPosTextPath(glyphs + start, (end - start) << 1, pos + start, path); } else { paint->getPosTextPath(glyphs + start, (end - start) << 1, pos + start, &tmpPath); path->addPath(tmpPath); } } private: const Layout& layout; SkPath* path; jfloat x; jfloat y; SkPaint* paint; uint16_t* glyphs; SkPoint* pos; SkPath tmpPath; }; #endif static void getTextPath(JNIEnv* env, SkPaint* paint, TypefaceImpl* typeface, const jchar* text, jint count, jint bidiFlags, jfloat x, jfloat y, SkPath* path) { #ifdef USE_MINIKIN Layout layout; MinikinUtils::SetLayoutProperties(&layout, paint, bidiFlags, typeface); layout.doLayout(text, count); size_t nGlyphs = layout.nGlyphs(); uint16_t* glyphs = new uint16_t[nGlyphs]; SkPoint* pos = new SkPoint[nGlyphs]; x += MinikinUtils::xOffsetForTextAlign(paint, layout); SkPaint::Align align = paint->getTextAlign(); paint->setTextAlign(SkPaint::kLeft_Align); paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding); GetTextFunctor f(layout, path, x, y, paint, glyphs, pos); MinikinUtils::forFontRun(layout, f); paint->setTextAlign(align); delete[] glyphs; delete[] pos; #else TextLayout::getTextPath(paint, text, count, bidiFlags, x, y, path); #endif } static void getTextPath___C(JNIEnv* env, jobject clazz, jlong paintHandle, jint bidiFlags, static void getTextPath___C(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jint bidiFlags, jcharArray text, jint index, jint count, jfloat x, jfloat y, jlong pathHandle) { SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); SkPath* path = reinterpret_cast<SkPath*>(pathHandle); const jchar* textArray = env->GetCharArrayElements(text, NULL); getTextPath(env, paint, textArray + index, count, bidiFlags, x, y, path); getTextPath(env, paint, typeface, textArray + index, count, bidiFlags, x, y, path); env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT); } static void getTextPath__String(JNIEnv* env, jobject clazz, jlong paintHandle, jint bidiFlags, static void getTextPath__String(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jint bidiFlags, jstring text, jint start, jint end, jfloat x, jfloat y, jlong pathHandle) { SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); SkPath* path = reinterpret_cast<SkPath*>(pathHandle); const jchar* textArray = env->GetStringChars(text, NULL); getTextPath(env, paint, textArray + start, end - start, bidiFlags, x, y, path); getTextPath(env, paint, typeface, textArray + start, end - start, bidiFlags, x, y, path); env->ReleaseStringChars(text, textArray); } Loading Loading @@ -1035,8 +1092,8 @@ static JNINativeMethod methods[] = { {"native_getTextRunCursor", "(J[CIIIII)I", (void*) SkPaintGlue::getTextRunCursor___C}, {"native_getTextRunCursor", "(JLjava/lang/String;IIIII)I", (void*) SkPaintGlue::getTextRunCursor__String}, {"native_getTextPath","(JI[CIIFFJ)V", (void*) SkPaintGlue::getTextPath___C}, {"native_getTextPath","(JILjava/lang/String;IIFFJ)V", (void*) SkPaintGlue::getTextPath__String}, {"native_getTextPath","(JJI[CIIFFJ)V", (void*) SkPaintGlue::getTextPath___C}, {"native_getTextPath","(JJILjava/lang/String;IIFFJ)V", (void*) SkPaintGlue::getTextPath__String}, {"nativeGetStringBounds", "(JLjava/lang/String;IIILandroid/graphics/Rect;)V", (void*) SkPaintGlue::getStringBounds }, {"nativeGetCharArrayBounds", "(J[CIIILandroid/graphics/Rect;)V", Loading core/jni/android/graphics/TextLayoutCache.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #define LOG_TAG "TextLayoutCache" #include <utils/JenkinsHash.h> #include <utils/CallStack.h> #include "TextLayoutCache.h" #include "TextLayout.h" Loading Loading @@ -89,6 +90,11 @@ void TextLayoutCache::purgeCaches() { sp<TextLayoutValue> TextLayoutCache::getValue(const SkPaint* paint, const jchar* text, jint start, jint count, jint contextCount, jint dirFlags) { AutoMutex _l(mLock); #ifdef USE_MINIKIN // We want to get rid of all legacy calls in the Minikin case, so log ALOGW("TextLayoutCache being invoked!"); CallStack _cs(LOG_TAG); #endif nsecs_t startTime = 0; if (mDebugEnabled) { startTime = systemTime(SYSTEM_TIME_MONOTONIC); Loading Loading
core/jni/android/graphics/Canvas.cpp +38 −25 Original line number Diff line number Diff line Loading @@ -821,32 +821,45 @@ public: } #ifdef USE_MINIKIN static void drawGlyphsToSkia(SkCanvas* canvas, SkPaint* paint, Layout* layout, float x, float y) { size_t nGlyphs = layout->nGlyphs(); class DrawTextFunctor { public: DrawTextFunctor(const Layout& layout, SkCanvas* canvas, jfloat x, jfloat y, SkPaint* paint, uint16_t* glyphs, SkPoint* pos) : layout(layout), canvas(canvas), x(x), y(y), paint(paint), glyphs(glyphs), pos(pos) { } void operator()(SkTypeface* t, size_t start, size_t end) { for (size_t i = start; i < end; i++) { glyphs[i] = layout.getGlyphId(i); pos[i].fX = x + layout.getX(i); pos[i].fY = y + layout.getY(i); } paint->setTypeface(t); canvas->drawPosText(glyphs + start, (end - start) << 1, pos + start, *paint); } private: const Layout& layout; SkCanvas* canvas; jfloat x; jfloat y; SkPaint* paint; uint16_t* glyphs; SkPoint* pos; }; static void drawGlyphsToSkia(SkCanvas* canvas, SkPaint* paint, const Layout& layout, float x, float y) { size_t nGlyphs = layout.nGlyphs(); uint16_t* glyphs = new uint16_t[nGlyphs]; SkPoint* pos = new SkPoint[nGlyphs]; SkTypeface *lastFace = NULL; SkTypeface *skFace = NULL; size_t start = 0; x += MinikinUtils::xOffsetForTextAlign(paint, layout); SkPaint::Align align = paint->getTextAlign(); paint->setTextAlign(SkPaint::kLeft_Align); paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding); for (size_t i = 0; i < nGlyphs; i++) { MinikinFontSkia *mfs = static_cast<MinikinFontSkia *>(layout->getFont(i)); skFace = mfs->GetSkTypeface(); glyphs[i] = layout->getGlyphId(i); pos[i].fX = x + layout->getX(i); pos[i].fY = y + layout->getY(i); if (i > 0 && skFace != lastFace) { paint->setTypeface(lastFace); canvas->drawPosText(glyphs + start, (i - start) << 1, pos + start, *paint); start = i; } lastFace = skFace; } if (skFace != NULL) { paint->setTypeface(skFace); canvas->drawPosText(glyphs + start, (nGlyphs - start) << 1, pos + start, *paint); } DrawTextFunctor f(layout, canvas, x, y, paint, glyphs, pos); MinikinUtils::forFontRun(layout, f); doDrawTextDecorations(canvas, x, y, layout.getAdvance(), paint); paint->setTextAlign(align); delete[] glyphs; delete[] pos; } Loading @@ -868,7 +881,7 @@ public: Layout layout; MinikinUtils::SetLayoutProperties(&layout, paint, flags, typeface); layout.doLayout(textArray + start, count); drawGlyphsToSkia(canvas, paint, &layout, x, y); drawGlyphsToSkia(canvas, paint, layout, x, y); #else sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint, textArray, start, count, contextCount, flags); Loading
core/jni/android/graphics/MinikinUtils.cpp +16 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #include "SkPaint.h" #include "minikin/Layout.h" #include "TypefaceImpl.h" #include "MinikinSkia.h" #include "MinikinUtils.h" Loading @@ -42,4 +43,18 @@ void MinikinUtils::SetLayoutProperties(Layout* layout, SkPaint* paint, int flags layout->setProperties(css); } float MinikinUtils::xOffsetForTextAlign(SkPaint* paint, const Layout& layout) { switch (paint->getTextAlign()) { case SkPaint::kCenter_Align: return layout.getAdvance() * -0.5f; break; case SkPaint::kRight_Align: return -layout.getAdvance(); break; default: break; } return 0; } }
core/jni/android/graphics/MinikinUtils.h +21 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,27 @@ class MinikinUtils { public: static void SetLayoutProperties(Layout* layout, SkPaint* paint, int flags, TypefaceImpl* face); static float xOffsetForTextAlign(SkPaint* paint, const Layout& layout); // f is a functor of type void f(SkTypeface *, size_t start, size_t end); template <typename F> static void forFontRun(const Layout& layout, F& f) { SkTypeface* lastFace = NULL; size_t start = 0; size_t nGlyphs = layout.nGlyphs(); for (size_t i = 0; i < nGlyphs; i++) { MinikinFontSkia* mfs = static_cast<MinikinFontSkia*>(layout.getFont(i)); SkTypeface* skFace = mfs->GetSkTypeface(); if (i > 0 && skFace != lastFace) { f(lastFace, start, i); start = i; } lastFace = skFace; } if (nGlyphs > start) { f(lastFace, start, nGlyphs); } } }; } // namespace android Loading
core/jni/android/graphics/Paint.cpp +65 −8 Original line number Diff line number Diff line Loading @@ -822,26 +822,83 @@ public: return result; } static void getTextPath(JNIEnv* env, SkPaint* paint, const jchar* text, jint count, jint bidiFlags, jfloat x, jfloat y, SkPath *path) { #ifdef USE_MINIKIN class GetTextFunctor { public: GetTextFunctor(const Layout& layout, SkPath* path, jfloat x, jfloat y, SkPaint* paint, uint16_t* glyphs, SkPoint* pos) : layout(layout), path(path), x(x), y(y), paint(paint), glyphs(glyphs), pos(pos) { } void operator()(SkTypeface* t, size_t start, size_t end) { for (size_t i = start; i < end; i++) { glyphs[i] = layout.getGlyphId(i); pos[i].fX = x + layout.getX(i); pos[i].fY = y + layout.getY(i); } paint->setTypeface(t); if (start == 0) { paint->getPosTextPath(glyphs + start, (end - start) << 1, pos + start, path); } else { paint->getPosTextPath(glyphs + start, (end - start) << 1, pos + start, &tmpPath); path->addPath(tmpPath); } } private: const Layout& layout; SkPath* path; jfloat x; jfloat y; SkPaint* paint; uint16_t* glyphs; SkPoint* pos; SkPath tmpPath; }; #endif static void getTextPath(JNIEnv* env, SkPaint* paint, TypefaceImpl* typeface, const jchar* text, jint count, jint bidiFlags, jfloat x, jfloat y, SkPath* path) { #ifdef USE_MINIKIN Layout layout; MinikinUtils::SetLayoutProperties(&layout, paint, bidiFlags, typeface); layout.doLayout(text, count); size_t nGlyphs = layout.nGlyphs(); uint16_t* glyphs = new uint16_t[nGlyphs]; SkPoint* pos = new SkPoint[nGlyphs]; x += MinikinUtils::xOffsetForTextAlign(paint, layout); SkPaint::Align align = paint->getTextAlign(); paint->setTextAlign(SkPaint::kLeft_Align); paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding); GetTextFunctor f(layout, path, x, y, paint, glyphs, pos); MinikinUtils::forFontRun(layout, f); paint->setTextAlign(align); delete[] glyphs; delete[] pos; #else TextLayout::getTextPath(paint, text, count, bidiFlags, x, y, path); #endif } static void getTextPath___C(JNIEnv* env, jobject clazz, jlong paintHandle, jint bidiFlags, static void getTextPath___C(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jint bidiFlags, jcharArray text, jint index, jint count, jfloat x, jfloat y, jlong pathHandle) { SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); SkPath* path = reinterpret_cast<SkPath*>(pathHandle); const jchar* textArray = env->GetCharArrayElements(text, NULL); getTextPath(env, paint, textArray + index, count, bidiFlags, x, y, path); getTextPath(env, paint, typeface, textArray + index, count, bidiFlags, x, y, path); env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT); } static void getTextPath__String(JNIEnv* env, jobject clazz, jlong paintHandle, jint bidiFlags, static void getTextPath__String(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jint bidiFlags, jstring text, jint start, jint end, jfloat x, jfloat y, jlong pathHandle) { SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); SkPath* path = reinterpret_cast<SkPath*>(pathHandle); const jchar* textArray = env->GetStringChars(text, NULL); getTextPath(env, paint, textArray + start, end - start, bidiFlags, x, y, path); getTextPath(env, paint, typeface, textArray + start, end - start, bidiFlags, x, y, path); env->ReleaseStringChars(text, textArray); } Loading Loading @@ -1035,8 +1092,8 @@ static JNINativeMethod methods[] = { {"native_getTextRunCursor", "(J[CIIIII)I", (void*) SkPaintGlue::getTextRunCursor___C}, {"native_getTextRunCursor", "(JLjava/lang/String;IIIII)I", (void*) SkPaintGlue::getTextRunCursor__String}, {"native_getTextPath","(JI[CIIFFJ)V", (void*) SkPaintGlue::getTextPath___C}, {"native_getTextPath","(JILjava/lang/String;IIFFJ)V", (void*) SkPaintGlue::getTextPath__String}, {"native_getTextPath","(JJI[CIIFFJ)V", (void*) SkPaintGlue::getTextPath___C}, {"native_getTextPath","(JJILjava/lang/String;IIFFJ)V", (void*) SkPaintGlue::getTextPath__String}, {"nativeGetStringBounds", "(JLjava/lang/String;IIILandroid/graphics/Rect;)V", (void*) SkPaintGlue::getStringBounds }, {"nativeGetCharArrayBounds", "(J[CIIILandroid/graphics/Rect;)V", Loading
core/jni/android/graphics/TextLayoutCache.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #define LOG_TAG "TextLayoutCache" #include <utils/JenkinsHash.h> #include <utils/CallStack.h> #include "TextLayoutCache.h" #include "TextLayout.h" Loading Loading @@ -89,6 +90,11 @@ void TextLayoutCache::purgeCaches() { sp<TextLayoutValue> TextLayoutCache::getValue(const SkPaint* paint, const jchar* text, jint start, jint count, jint contextCount, jint dirFlags) { AutoMutex _l(mLock); #ifdef USE_MINIKIN // We want to get rid of all legacy calls in the Minikin case, so log ALOGW("TextLayoutCache being invoked!"); CallStack _cs(LOG_TAG); #endif nsecs_t startTime = 0; if (mDebugEnabled) { startTime = systemTime(SYSTEM_TIME_MONOTONIC); Loading