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

Commit 3a4217fb authored by Seigo Nonaka's avatar Seigo Nonaka
Browse files

Pass full context to Minikin

Bug: 72461923
Test: atest CtsWidgetTestCases:EditTextTest
    CtsWidgetTestCases:TextViewFadingEdgeTest
    FrameworksCoreTests:TextViewFallbackLineSpacingTest
    FrameworksCoreTests:TextViewTest FrameworksCoreTests:TypefaceTest
    CtsGraphicsTestCases:TypefaceTest CtsWidgetTestCases:TextViewTest
    CtsTextTestCases FrameworksCoreTests:android.text
    CtsWidgetTestCases:TextViewPrecomputedTextTest
Test: minikin_tests
Test: hwui_unit_tests

Change-Id: Ic0827a85dbf1ab2b38d44514e400f524686748d2
parent 21f2c00d
Loading
Loading
Loading
Loading
+18 −5
Original line number Diff line number Diff line
@@ -308,7 +308,10 @@ namespace PaintGlue {
    static void getTextPath(JNIEnv* env, Paint* paint, const Typeface* typeface, const jchar* text,
            jint count, jint bidiFlags, jfloat x, jfloat y, SkPath* path) {
        minikin::Layout layout = MinikinUtils::doLayout(
                paint, static_cast<minikin::Bidi>(bidiFlags), typeface, text, 0, count, count,
                paint, static_cast<minikin::Bidi>(bidiFlags), typeface,
                text, count,  // text buffer
                0, count,  // draw range
                0, count,  // context range
                nullptr);
        size_t nGlyphs = layout.nGlyphs();
        uint16_t* glyphs = new uint16_t[nGlyphs];
@@ -351,7 +354,11 @@ namespace PaintGlue {
        SkIRect ir;

        minikin::Layout layout = MinikinUtils::doLayout(&paint,
                static_cast<minikin::Bidi>(bidiFlags), typeface, text, 0, count, count, nullptr);
                static_cast<minikin::Bidi>(bidiFlags), typeface,
                text, count,  // text buffer
                0, count,  // draw range
                0, count,  // context range
                nullptr);
        minikin::MinikinRect rect;
        layout.getBounds(&rect);
        r.fLeft = rect.mLeft;
@@ -466,8 +473,11 @@ namespace PaintGlue {
            prevCp = cp;
        }
        minikin::Layout layout = MinikinUtils::doLayout(paint,
                static_cast<minikin::Bidi>(bidiFlags), typeface, str.get(), 0, str.size(),
                str.size(), nullptr);
                static_cast<minikin::Bidi>(bidiFlags), typeface,
                str.get(), str.size(),  // text buffer
                0, str.size(),  // draw range
                0, str.size(),  // context range
                nullptr);
        size_t nGlyphs = countNonSpaceGlyphs(layout);
        if (nGlyphs != 1 && nChars > 1) {
            // multiple-character input, and was not a ligature
@@ -487,7 +497,10 @@ namespace PaintGlue {
            // 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(paint,
                    static_cast<minikin::Bidi>(bidiFlags), typeface, ZZ_FLAG_STR, 0, 4, 4,
                    static_cast<minikin::Bidi>(bidiFlags), typeface,
                    ZZ_FLAG_STR, 4,  // text buffer
                    0, 4,  // draw range
                    0, 4,  // context range
                    nullptr);
            if (zzLayout.nGlyphs() != 1 || layoutContainsNotdef(zzLayout)) {
                // The font collection doesn't have a glyph for unknown flag. Just return true.
+43 −31
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@
#include <hwui/Paint.h>
#include <hwui/Typeface.h>
#include <minikin/Layout.h>
#include <nativehelper/ScopedPrimitiveArray.h>
#include <nativehelper/ScopedStringChars.h>

#include "Bitmap.h"
#include "SkDrawFilter.h"
@@ -487,56 +489,66 @@ static void drawBitmapMesh(JNIEnv* env, jobject, jlong canvasHandle, jobject jbi
                                             colorA.ptr() + colorIndex, paint);
}

static void drawTextChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text,
static void drawTextChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray charArray,
                          jint index, jint count, jfloat x, jfloat y, jint bidiFlags,
                          jlong paintHandle) {
    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
    const Typeface* typeface = paint->getAndroidTypeface();
    jchar* jchars = env->GetCharArrayElements(text, NULL);
    get_canvas(canvasHandle)->drawText(jchars + index, 0, count, count, x, y,
            static_cast<minikin::Bidi>(bidiFlags), *paint, typeface, nullptr);
    env->ReleaseCharArrayElements(text, jchars, JNI_ABORT);
    ScopedCharArrayRO text(env, charArray);
    get_canvas(canvasHandle)->drawText(
            text.get(), text.size(),  // text buffer
            index, count,  // draw range
            0, text.size(),  // context range
            x, y,  // draw position
            static_cast<minikin::Bidi>(bidiFlags), *paint, typeface, nullptr /* measured text */);
}

static void drawTextString(JNIEnv* env, jobject, jlong canvasHandle, jstring text,
static void drawTextString(JNIEnv* env, jobject, jlong canvasHandle, jstring strObj,
                           jint start, jint end, jfloat x, jfloat y, jint bidiFlags,
                           jlong paintHandle) {
    ScopedStringChars text(env, strObj);
    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
    const Typeface* typeface = paint->getAndroidTypeface();
    const int count = end - start;
    const jchar* jchars = env->GetStringChars(text, NULL);
    get_canvas(canvasHandle)->drawText(jchars + start, 0, count, count, x, y,
            static_cast<minikin::Bidi>(bidiFlags), *paint, typeface, nullptr);
    env->ReleaseStringChars(text, jchars);
}
    get_canvas(canvasHandle)->drawText(
            text.get(), text.size(),  // text buffer
            start, end - start,  // draw range
            0, text.size(),  // context range
            x, y,  // draw position
            static_cast<minikin::Bidi>(bidiFlags), *paint, typeface, nullptr /* measured text */);
}

static void drawTextRunChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray charArray,
                             jint index, jint count, jint contextIndex, jint contextCount,
                             jfloat x, jfloat y, jboolean isRtl, jlong paintHandle,
                             jlong mtHandle) {
    minikin::MeasuredText* mt = reinterpret_cast<minikin::MeasuredText*>(mtHandle);
    const minikin::Bidi bidiFlags = isRtl ? minikin::Bidi::FORCE_RTL : minikin::Bidi::FORCE_LTR;

static void drawTextRunChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text, jint index,
                             jint count, jint contextIndex, jint contextCount, jfloat x, jfloat y,
                             jboolean isRtl, jlong paintHandle, jlong mtHandle) {
    ScopedCharArrayRO text(env, charArray);
    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
    minikin::MeasuredText* mt = reinterpret_cast<minikin::MeasuredText*>(mtHandle);
    const Typeface* typeface = paint->getAndroidTypeface();

    const minikin::Bidi bidiFlags = isRtl ? minikin::Bidi::FORCE_RTL : minikin::Bidi::FORCE_LTR;
    jchar* jchars = env->GetCharArrayElements(text, NULL);
    get_canvas(canvasHandle)->drawText(jchars + contextIndex, index - contextIndex, count,
                                       contextCount, x, y, bidiFlags, *paint, typeface, mt);
    env->ReleaseCharArrayElements(text, jchars, JNI_ABORT);
    get_canvas(canvasHandle)->drawText(
            text.get(), text.size(),  // text buffer
            index, count,  // draw range
            contextIndex, contextCount,  // context range,
            x, y,  // draw position
            bidiFlags, *paint, typeface, mt);
}

static void drawTextRunString(JNIEnv* env, jobject obj, jlong canvasHandle, jstring text,
static void drawTextRunString(JNIEnv* env, jobject obj, jlong canvasHandle, jstring strObj,
                              jint start, jint end, jint contextStart, jint contextEnd,
                              jfloat x, jfloat y, jboolean isRtl, jlong paintHandle) {
    const minikin::Bidi bidiFlags = isRtl ? minikin::Bidi::FORCE_RTL : minikin::Bidi::FORCE_LTR;

    ScopedStringChars text(env, strObj);
    Paint* paint = reinterpret_cast<Paint*>(paintHandle);
    const Typeface* typeface = paint->getAndroidTypeface();

    const minikin::Bidi bidiFlags = isRtl ? minikin::Bidi::FORCE_RTL : minikin::Bidi::FORCE_LTR;
    jint count = end - start;
    jint contextCount = contextEnd - contextStart;
    const jchar* jchars = env->GetStringChars(text, NULL);
    get_canvas(canvasHandle)->drawText(jchars + contextStart, start - contextStart, count,
                                       contextCount, x, y, bidiFlags, *paint, typeface, nullptr);
    env->ReleaseStringChars(text, jchars);
    get_canvas(canvasHandle)->drawText(
            text.get(), text.size(),  // text buffer
            start, end - start,  // draw range
            contextStart, contextEnd - contextStart,  // context range
            x, y,  // draw position
            bidiFlags, *paint, typeface, nullptr /* measured text */);
}

static void drawTextOnPathChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text,
+10 −7
Original line number Diff line number Diff line
@@ -153,15 +153,15 @@ private:
    float totalAdvance;
};

void Canvas::drawText(const uint16_t* text, int start, int count, int contextCount, float x,
                      float y, minikin::Bidi bidiFlags, const Paint& origPaint,
                      const Typeface* typeface, minikin::MeasuredText* mt) {
void Canvas::drawText(const uint16_t* text, int textSize, int start, int count, int contextStart,
                      int contextCount, float x, float y, minikin::Bidi bidiFlags,
                      const Paint& origPaint, const Typeface* typeface, minikin::MeasuredText* mt) {
    // minikin may modify the original paint
    Paint paint(origPaint);

    minikin::Layout layout =
            MinikinUtils::doLayout(&paint, bidiFlags, typeface, text, start, count, contextCount,
                                   mt);
            MinikinUtils::doLayout(&paint, bidiFlags, typeface, text, textSize, start, count,
                                   contextStart, contextCount, mt);

    x += MinikinUtils::xOffsetForTextAlign(&paint, layout);

@@ -208,8 +208,11 @@ void Canvas::drawTextOnPath(const uint16_t* text, int count, minikin::Bidi bidiF
                            const SkPath& path, float hOffset, float vOffset, const Paint& paint,
                            const Typeface* typeface) {
    Paint paintCopy(paint);
    minikin::Layout layout =
            MinikinUtils::doLayout(&paintCopy, bidiFlags, typeface, text, 0, count, count, nullptr);
    minikin::Layout layout = MinikinUtils::doLayout(&paintCopy, bidiFlags, typeface,
            text, count,  // text buffer
            0, count,  // draw range
            0, count,  // context range
            nullptr);
    hOffset += MinikinUtils::hOffsetForTextAlign(&paintCopy, layout, path);

    // Set align to left for drawing, as we don't want individual
+3 −3
Original line number Diff line number Diff line
@@ -268,9 +268,9 @@ public:
     * Converts utf16 text to glyphs, calculating position and boundary,
     * and delegating the final draw to virtual drawGlyphs method.
     */
    void drawText(const uint16_t* text, int start, int count, int contextCount, float x, float y,
                  minikin::Bidi bidiFlags, const Paint& origPaint, const Typeface* typeface,
                  minikin::MeasuredText* mt);
    void drawText(const uint16_t* text, int textSize, int start, int count, int contextStart,
                  int contextCount, float x, float y, minikin::Bidi bidiFlags,
                  const Paint& origPaint, const Typeface* typeface, minikin::MeasuredText* mt);

    void drawTextOnPath(const uint16_t* text, int count, minikin::Bidi bidiFlags,
                        const SkPath& path, float hOffset, float vOffset, const Paint& paint,
+9 −5
Original line number Diff line number Diff line
@@ -48,20 +48,24 @@ minikin::MinikinPaint MinikinUtils::prepareMinikinPaint(const Paint* paint,
}

minikin::Layout MinikinUtils::doLayout(const Paint* paint, minikin::Bidi bidiFlags,
                                       const Typeface* typeface, const uint16_t* buf, size_t start,
                                       size_t count, size_t bufSize, minikin::MeasuredText* mt) {
                                       const Typeface* typeface, const uint16_t* buf,
                                       size_t bufSize, size_t start, size_t count,
                                       size_t contextStart, size_t contextCount,
                                       minikin::MeasuredText* mt) {
    minikin::MinikinPaint minikinPaint = prepareMinikinPaint(paint, typeface);

    const minikin::U16StringPiece textBuf(buf, bufSize);
    const minikin::Range range(start, start + count);
    const minikin::Range contextRange(contextStart, contextStart + contextCount);
    const minikin::HyphenEdit hyphenEdit = static_cast<minikin::HyphenEdit>(paint->getHyphenEdit());
    const minikin::StartHyphenEdit startHyphen = minikin::startHyphenEdit(hyphenEdit);
    const minikin::EndHyphenEdit endHyphen = minikin::endHyphenEdit(hyphenEdit);

    if (mt == nullptr) {
        return minikin::Layout(textBuf,range, bidiFlags, minikinPaint, startHyphen, endHyphen);
        return minikin::Layout(textBuf.substr(contextRange), range - contextStart, bidiFlags,
                               minikinPaint, startHyphen, endHyphen);
    } else {
        return mt->buildLayout(textBuf, range, minikinPaint, bidiFlags, startHyphen, endHyphen);
        return mt->buildLayout(textBuf, range, contextRange, minikinPaint, startHyphen, endHyphen);
    }
}

@@ -76,7 +80,7 @@ float MinikinUtils::measureText(const Paint* paint, minikin::Bidi bidiFlags,
    const minikin::EndHyphenEdit endHyphen = minikin::endHyphenEdit(hyphenEdit);

    return minikin::Layout::measureText(textBuf, range, bidiFlags, minikinPaint, startHyphen,
                                        endHyphen, advances, nullptr /* layout pieces */);
                                        endHyphen, advances);
}

bool MinikinUtils::hasVariationSelector(const Typeface* typeface, uint32_t codepoint, uint32_t vs) {
Loading