Merge changes I46744e51,I1f566cce
* changes:
Solidify and optimize Paint text related APIs
Add more optimizations for Text measuring / breaking / getting advances
diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java
index c114c37..3e5f32e 100644
--- a/core/java/android/text/TextLine.java
+++ b/core/java/android/text/TextLine.java
@@ -828,7 +828,10 @@
if (start == measureLimit) {
TextPaint wp = mWorkPaint;
wp.set(mPaint);
- return handleText(wp, 0, 0, 0, 0, runIsRtl, c, x, top, y, bottom, fmi, needWidth);
+ if (fmi != null) {
+ expandMetricsFromPaint(fmi, wp);
+ }
+ return 0f;
}
// Shaping needs to take into account context up to metric boundaries,
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 64749e9..98d7fce 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -325,11 +325,13 @@
NPE_CHECK_RETURN_ZERO(env, text);
size_t textLength = env->GetArrayLength(text);
-
if ((index | count) < 0 || (size_t)(index + count) > textLength) {
doThrowAIOOBE(env);
return 0;
}
+ if (count == 0) {
+ return 0;
+ }
SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
const jchar* textArray = env->GetCharArrayElements(text, NULL);
@@ -350,15 +352,22 @@
NPE_CHECK_RETURN_ZERO(env, jpaint);
NPE_CHECK_RETURN_ZERO(env, text);
- SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
- const jchar* textArray = env->GetStringChars(text, NULL);
-
int count = end - start;
- size_t textLength = env->GetStringLength(text);
- if ((start | count) < 0 || (size_t)count > textLength) {
+ if ((start | count) < 0) {
doThrowAIOOBE(env);
return 0;
}
+ if (count == 0) {
+ return 0;
+ }
+ size_t textLength = env->GetStringLength(text);
+ if ((size_t)count > textLength) {
+ doThrowAIOOBE(env);
+ return 0;
+ }
+
+ const jchar* textArray = env->GetStringChars(text, NULL);
+ SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
jfloat width = 0;
#if RTL_USE_HARFBUZZ
@@ -376,10 +385,15 @@
NPE_CHECK_RETURN_ZERO(env, jpaint);
NPE_CHECK_RETURN_ZERO(env, text);
- SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
- const jchar* textArray = env->GetStringChars(text, NULL);
size_t textLength = env->GetStringLength(text);
+ if (textLength == 0) {
+ return 0;
+ }
+
+ const jchar* textArray = env->GetStringChars(text, NULL);
+ SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
jfloat width = 0;
+
#if RTL_USE_HARFBUZZ
TextLayout::getTextRunAdvances(paint, textArray, 0, textLength, textLength,
paint->getFlags(), NULL /* dont need all advances */, width);
@@ -391,8 +405,25 @@
}
static int dotextwidths(JNIEnv* env, SkPaint* paint, const jchar text[], int count, jfloatArray widths) {
+ NPE_CHECK_RETURN_ZERO(env, paint);
+ NPE_CHECK_RETURN_ZERO(env, text);
+
+ if (count < 0 || !widths) {
+ doThrowAIOOBE(env);
+ return 0;
+ }
+ if (count == 0) {
+ return 0;
+ }
+ size_t widthsLength = env->GetArrayLength(widths);
+ if ((size_t)count > widthsLength) {
+ doThrowAIOOBE(env);
+ return 0;
+ }
+
AutoJavaFloatArray autoWidths(env, widths, count);
jfloat* widthsArray = autoWidths.ptr();
+
#if RTL_USE_HARFBUZZ
jfloat totalAdvance;
@@ -427,6 +458,22 @@
static int doTextGlyphs(JNIEnv* env, SkPaint* paint, const jchar* text, jint start, jint count,
jint contextCount, jint flags, jcharArray glyphs) {
+ NPE_CHECK_RETURN_ZERO(env, paint);
+ NPE_CHECK_RETURN_ZERO(env, text);
+
+ if ((start | count | contextCount) < 0 || contextCount < count || !glyphs) {
+ doThrowAIOOBE(env);
+ return 0;
+ }
+ if (count == 0) {
+ return 0;
+ }
+ size_t glypthsLength = env->GetArrayLength(glyphs);
+ if ((size_t)count > glypthsLength) {
+ doThrowAIOOBE(env);
+ return 0;
+ }
+
jchar* glyphsArray = env->GetCharArrayElements(glyphs, NULL);
HB_ShaperItem shaperItem;
HB_FontRec font;
@@ -455,8 +502,25 @@
static jfloat doTextRunAdvances(JNIEnv *env, SkPaint *paint, const jchar *text,
jint start, jint count, jint contextCount, jint flags,
jfloatArray advances, jint advancesIndex) {
+ NPE_CHECK_RETURN_ZERO(env, paint);
+ NPE_CHECK_RETURN_ZERO(env, text);
+
+ if ((start | count | contextCount | advancesIndex) < 0 || contextCount < count) {
+ doThrowAIOOBE(env);
+ return 0;
+ }
+ if (count == 0) {
+ return 0;
+ }
+ if (advances) {
+ size_t advancesLength = env->GetArrayLength(advances);
+ if ((size_t)count > advancesLength) {
+ doThrowAIOOBE(env);
+ return 0;
+ }
+ }
jfloat advancesArray[count];
- jfloat totalAdvance;
+ jfloat totalAdvance = 0;
TextLayout::getTextRunAdvances(paint, text, start, count, contextCount, flags,
advancesArray, totalAdvance);
@@ -470,8 +534,26 @@
static jfloat doTextRunAdvancesICU(JNIEnv *env, SkPaint *paint, const jchar *text,
jint start, jint count, jint contextCount, jint flags,
jfloatArray advances, jint advancesIndex) {
+ NPE_CHECK_RETURN_ZERO(env, paint);
+ NPE_CHECK_RETURN_ZERO(env, text);
+
+ if ((start | count | contextCount | advancesIndex) < 0 || contextCount < count) {
+ doThrowAIOOBE(env);
+ return 0;
+ }
+ if (count == 0) {
+ return 0;
+ }
+ if (advances) {
+ size_t advancesLength = env->GetArrayLength(advances);
+ if ((size_t)count > advancesLength) {
+ doThrowAIOOBE(env);
+ return 0;
+ }
+ }
+
jfloat advancesArray[count];
- jfloat totalAdvance;
+ jfloat totalAdvance = 0;
TextLayout::getTextRunAdvancesICU(paint, text, start, count, contextCount, flags,
advancesArray, totalAdvance);
@@ -512,7 +594,7 @@
jint count, jint flags, jint offset, jint opt) {
#if RTL_USE_HARFBUZZ
jfloat scalarArray[count];
- jfloat totalAdvance;
+ jfloat totalAdvance = 0;
TextLayout::getTextRunAdvances(paint, text, start, count, count, flags,
scalarArray, totalAdvance);
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index 1df8143..e509ee0 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1185,6 +1185,9 @@
* @return The width of the text
*/
public float measureText(char[] text, int index, int count) {
+ if (text == null || text.length == 0 || count == 0) {
+ return 0f;
+ }
if (!mHasCompatScaling) return native_measureText(text, index, count);
final float oldSize = getTextSize();
setTextSize(oldSize*mCompatScaling);
@@ -1204,6 +1207,9 @@
* @return The width of the text
*/
public float measureText(String text, int start, int end) {
+ if (text == null || text.length() == 0 || start == end) {
+ return 0f;
+ }
if (!mHasCompatScaling) return native_measureText(text, start, end);
final float oldSize = getTextSize();
setTextSize(oldSize*mCompatScaling);
@@ -1221,6 +1227,9 @@
* @return The width of the text
*/
public float measureText(String text) {
+ if (text == null || text.length() == 0) {
+ return 0f;
+ }
if (!mHasCompatScaling) return native_measureText(text);
final float oldSize = getTextSize();
setTextSize(oldSize*mCompatScaling);
@@ -1240,6 +1249,9 @@
* @return The width of the text
*/
public float measureText(CharSequence text, int start, int end) {
+ if (text == null || text.length() == 0 || start == end) {
+ return 0f;
+ }
if (text instanceof String) {
return measureText((String)text, start, end);
}
@@ -1275,6 +1287,9 @@
*/
public int breakText(char[] text, int index, int count,
float maxWidth, float[] measuredWidth) {
+ if (text == null || text.length == 0 || count == 0) {
+ return 0;
+ }
if (!mHasCompatScaling) {
return native_breakText(text, index, count, maxWidth, measuredWidth);
}
@@ -1309,6 +1324,9 @@
public int breakText(CharSequence text, int start, int end,
boolean measureForwards,
float maxWidth, float[] measuredWidth) {
+ if (text == null || text.length() == 0 || start == end) {
+ return 0;
+ }
if (start == 0 && text instanceof String && end == text.length()) {
return breakText((String) text, measureForwards, maxWidth,
measuredWidth);
@@ -1347,6 +1365,9 @@
*/
public int breakText(String text, boolean measureForwards,
float maxWidth, float[] measuredWidth) {
+ if (text == null || text.length() == 0) {
+ return 0;
+ }
if (!mHasCompatScaling) {
return native_breakText(text, measureForwards, maxWidth, measuredWidth);
}
@@ -1374,6 +1395,9 @@
*/
public int getTextWidths(char[] text, int index, int count,
float[] widths) {
+ if (text == null || text.length == 0 || count == 0) {
+ return 0;
+ }
if ((index | count) < 0 || index + count > text.length
|| count > widths.length) {
throw new ArrayIndexOutOfBoundsException();
@@ -1404,6 +1428,9 @@
*/
public int getTextWidths(CharSequence text, int start, int end,
float[] widths) {
+ if (text == null || text.length() == 0 || start == end) {
+ return 0;
+ }
if (text instanceof String) {
return getTextWidths((String) text, start, end, widths);
}
@@ -1434,6 +1461,9 @@
* @return the number of unichars in the specified text.
*/
public int getTextWidths(String text, int start, int end, float[] widths) {
+ if (text == null || text.length() == 0 || start == end) {
+ return 0;
+ }
if ((start | end | (end - start) | (text.length() - end)) < 0) {
throw new IndexOutOfBoundsException();
}
@@ -1528,6 +1558,9 @@
int contextIndex, int contextCount, int flags, float[] advances,
int advancesIndex, int reserved) {
+ if (chars == null || chars.length == 0){
+ return 0f;
+ }
if ((index | count | contextIndex | contextCount | advancesIndex
| (index - contextIndex)
| ((contextIndex + contextCount) - (index + count))
@@ -1584,6 +1617,9 @@
int contextStart, int contextEnd, int flags, float[] advances,
int advancesIndex, int reserved) {
+ if (text == null || text.length() == 0) {
+ return 0f;
+ }
if (text instanceof String) {
return getTextRunAdvances((String) text, start, end,
contextStart, contextEnd, flags, advances, advancesIndex, reserved);
@@ -1702,6 +1738,9 @@
public float getTextRunAdvances(String text, int start, int end, int contextStart,
int contextEnd, int flags, float[] advances, int advancesIndex, int reserved) {
+ if (text == null || text.length() == 0 || start == end || contextStart == contextEnd) {
+ return 0f;
+ }
if ((start | end | contextStart | contextEnd | advancesIndex | (end - start)
| (start - contextStart) | (contextEnd - end)
| (text.length() - contextEnd)