Loading core/jni/android/graphics/Paint.cpp +47 −17 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; } Loading Loading @@ -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", Loading graphics/java/android/graphics/Paint.java +14 −10 Original line number Diff line number Diff line Loading @@ -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); /** Loading Loading @@ -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); /** Loading Loading
core/jni/android/graphics/Paint.cpp +47 −17 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; } Loading Loading @@ -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", Loading
graphics/java/android/graphics/Paint.java +14 −10 Original line number Diff line number Diff line Loading @@ -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); /** Loading Loading @@ -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); /** Loading