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

Commit a4649d95 authored by Anish Athalye's avatar Anish Athalye Committed by Android (Google) Code Review
Browse files

Merge "Implement Paint.breakText() using Minikin"

parents 31f8d22e a7aa1b0a
Loading
Loading
Loading
Loading
+47 −17
Original line number Diff line number Diff line
@@ -936,32 +936,62 @@ public:
        return paint->getLooper() && paint->getLooper()->asABlurShadow(NULL);
    }

    static int breakText(JNIEnv* env, SkPaint& paint, const jchar text[],
    static int breakText(JNIEnv* env, const SkPaint& paint, TypefaceImpl* typeface, const jchar text[],
                         int count, float maxWidth, jint bidiFlags, jfloatArray jmeasured,
                         SkPaint::TextBufferDirection tbd) {
                         SkPaint::TextBufferDirection textBufferDirection) {
        size_t measuredCount = 0;
        float measured = 0;

#ifdef USE_MINIKIN
        Layout layout;
        std::string css = MinikinUtils::setLayoutProperties(&layout, &paint, bidiFlags, typeface);
        layout.doLayout(text, 0, count, count, css);
        float* advances = new float[count];
        layout.getAdvances(advances);
        const bool forwardScan = (textBufferDirection == SkPaint::kForward_TextBufferDirection);
        for (int i = 0; i < count; i++) {
            // traverse in the given direction
            int index = forwardScan ? i : (count - i - 1);
            float width = advances[index];
            if (measured + width > maxWidth) {
                break;
            }
            // properly handle clusters when scanning backwards
            if (forwardScan || width != 0.0f) {
                measuredCount = i + 1;
            }
            measured += width;
        }
        delete[] advances;
#else
        sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(&paint,
                text, 0, count, count, bidiFlags);
        if (value == NULL) {
            return 0;
        }
        SkScalar     measured;
        SkScalar m;
        size_t bytes = paint.breakText(value->getGlyphs(), value->getGlyphsCount() << 1,
                maxWidth, &measured, tbd);
                maxWidth, &m, textBufferDirection);
        SkASSERT((bytes & 1) == 0);
        measuredCount = bytes >> 1;
        measured = SkScalarToFloat(m);
#endif

        if (jmeasured && env->GetArrayLength(jmeasured) > 0) {
            AutoJavaFloatArray autoMeasured(env, jmeasured, 1);
            jfloat* array = autoMeasured.ptr();
            array[0] = SkScalarToFloat(measured);
            array[0] = measured;
        }
        return bytes >> 1;
        return measuredCount;
    }

    static jint breakTextC(JNIEnv* env, jobject jpaint, jcharArray jtext,
    static jint breakTextC(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jcharArray jtext,
            jint index, jint count, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) {
        NPE_CHECK_RETURN_ZERO(env, jpaint);
        NPE_CHECK_RETURN_ZERO(env, jtext);

        SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);

        SkPaint::TextBufferDirection tbd;
        if (count < 0) {
            tbd = SkPaint::kBackward_TextBufferDirection;
@@ -976,28 +1006,28 @@ public:
            return 0;
        }

        SkPaint*     paint = GraphicsJNI::getNativePaint(env, jpaint);
        const jchar* text = env->GetCharArrayElements(jtext, NULL);
        count = breakText(env, *paint, text + index, count, maxWidth,
        count = breakText(env, *paint, typeface, text + index, count, maxWidth,
                          bidiFlags, jmeasuredWidth, tbd);
        env->ReleaseCharArrayElements(jtext, const_cast<jchar*>(text),
                                      JNI_ABORT);
        return count;
    }

    static jint breakTextS(JNIEnv* env, jobject jpaint, jstring jtext,
    static jint breakTextS(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jstring jtext,
                jboolean forwards, jfloat maxWidth, jint bidiFlags, jfloatArray jmeasuredWidth) {
        NPE_CHECK_RETURN_ZERO(env, jpaint);
        NPE_CHECK_RETURN_ZERO(env, jtext);

        SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
        TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);

        SkPaint::TextBufferDirection tbd = forwards ?
                                        SkPaint::kForward_TextBufferDirection :
                                        SkPaint::kBackward_TextBufferDirection;

        SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
        int count = env->GetStringLength(jtext);
        const jchar* text = env->GetStringChars(jtext, NULL);
        count = breakText(env, *paint, text, count, maxWidth, bidiFlags, jmeasuredWidth, tbd);
        count = breakText(env, *paint, typeface, text, count, maxWidth, bidiFlags, jmeasuredWidth, tbd);
        env->ReleaseStringChars(jtext, text);
        return count;
    }
@@ -1108,8 +1138,8 @@ static JNINativeMethod methods[] = {
    {"native_measureText","([CIII)F", (void*) SkPaintGlue::measureText_CIII},
    {"native_measureText","(Ljava/lang/String;I)F", (void*) SkPaintGlue::measureText_StringI},
    {"native_measureText","(Ljava/lang/String;III)F", (void*) SkPaintGlue::measureText_StringIII},
    {"native_breakText","([CIIFI[F)I", (void*) SkPaintGlue::breakTextC},
    {"native_breakText","(Ljava/lang/String;ZFI[F)I", (void*) SkPaintGlue::breakTextS},
    {"native_breakText","(JJ[CIIFI[F)I", (void*) SkPaintGlue::breakTextC},
    {"native_breakText","(JJLjava/lang/String;ZFI[F)I", (void*) SkPaintGlue::breakTextS},
    {"native_getTextWidths","(JJ[CIII[F)I", (void*) SkPaintGlue::getTextWidths___CIII_F},
    {"native_getTextWidths","(JJLjava/lang/String;III[F)I", (void*) SkPaintGlue::getTextWidths__StringIII_F},
    {"native_getTextRunAdvances","(JJ[CIIIIZ[FI)F",
+14 −10
Original line number Diff line number Diff line
@@ -1532,19 +1532,21 @@ public class Paint {
            return 0;
        }
        if (!mHasCompatScaling) {
            return native_breakText(text, index, count, maxWidth, mBidiFlags, measuredWidth);
            return native_breakText(mNativePaint, mNativeTypeface, text, index, count, maxWidth,
                    mBidiFlags, measuredWidth);
        }

        final float oldSize = getTextSize();
        setTextSize(oldSize * mCompatScaling);
        int res = native_breakText(text, index, count, maxWidth*mCompatScaling, mBidiFlags,
                measuredWidth);
        int res = native_breakText(mNativePaint, mNativeTypeface, text, index, count,
                maxWidth * mCompatScaling, mBidiFlags, measuredWidth);
        setTextSize(oldSize);
        if (measuredWidth != null) measuredWidth[0] *= mInvCompatScaling;
        return res;
    }

    private native int native_breakText(char[] text, int index, int count,
    private static native int native_breakText(long native_object, long native_typeface,
                                               char[] text, int index, int count,
                                               float maxWidth, int bidiFlags, float[] measuredWidth);

    /**
@@ -1622,19 +1624,21 @@ public class Paint {
            return 0;
        }
        if (!mHasCompatScaling) {
            return native_breakText(text, measureForwards, maxWidth, mBidiFlags, measuredWidth);
            return native_breakText(mNativePaint, mNativeTypeface, text, measureForwards,
                    maxWidth, mBidiFlags, measuredWidth);
        }

        final float oldSize = getTextSize();
        setTextSize(oldSize*mCompatScaling);
        int res = native_breakText(text, measureForwards, maxWidth*mCompatScaling, mBidiFlags,
                measuredWidth);
        int res = native_breakText(mNativePaint, mNativeTypeface, text, measureForwards,
                maxWidth*mCompatScaling, mBidiFlags, measuredWidth);
        setTextSize(oldSize);
        if (measuredWidth != null) measuredWidth[0] *= mInvCompatScaling;
        return res;
    }

    private native int native_breakText(String text, boolean measureForwards,
    private static native int native_breakText(long native_object, long native_typeface,
                                        String text, boolean measureForwards,
                                        float maxWidth, int bidiFlags, float[] measuredWidth);

    /**