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

Commit 38bd7b9c authored by Raph Levien's avatar Raph Levien Committed by Android (Google) Code Review
Browse files

Merge "Better Minikin integration" into lmp-preview-dev

parents 8da21391 f2114d56
Loading
Loading
Loading
Loading
+38 −25
Original line number Diff line number Diff line
@@ -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;
    }
@@ -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);
+16 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "SkPaint.h"
#include "minikin/Layout.h"
#include "TypefaceImpl.h"
#include "MinikinSkia.h"

#include "MinikinUtils.h"

@@ -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;
}

}
+21 −0
Original line number Diff line number Diff line
@@ -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
+65 −8
Original line number Diff line number Diff line
@@ -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);
    }

@@ -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",
+6 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#define LOG_TAG "TextLayoutCache"

#include <utils/JenkinsHash.h>
#include <utils/CallStack.h>

#include "TextLayoutCache.h"
#include "TextLayout.h"
@@ -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