Add cluster count API

This is a preparation of the inter character justification

Bug: 283193133
Test: CtsTextTestCases
Test: minikin_tests

Change-Id: Ia3a69a83cc1a3cde56d8a66a7cab1c85c7109050
diff --git a/libs/hwui/hwui/MinikinUtils.cpp b/libs/hwui/hwui/MinikinUtils.cpp
index 7552b56d..833069f 100644
--- a/libs/hwui/hwui/MinikinUtils.cpp
+++ b/libs/hwui/hwui/MinikinUtils.cpp
@@ -96,7 +96,7 @@
 float MinikinUtils::measureText(const Paint* paint, minikin::Bidi bidiFlags,
                                 const Typeface* typeface, const uint16_t* buf, size_t start,
                                 size_t count, size_t bufSize, float* advances,
-                                minikin::MinikinRect* bounds) {
+                                minikin::MinikinRect* bounds, uint32_t* clusterCount) {
     minikin::MinikinPaint minikinPaint = prepareMinikinPaint(paint, typeface);
     const minikin::U16StringPiece textBuf(buf, bufSize);
     const minikin::Range range(start, start + count);
@@ -104,7 +104,7 @@
     const minikin::EndHyphenEdit endHyphen = paint->getEndHyphenEdit();
 
     return minikin::Layout::measureText(textBuf, range, bidiFlags, minikinPaint, startHyphen,
-                                        endHyphen, advances, bounds);
+                                        endHyphen, advances, bounds, clusterCount);
 }
 
 minikin::MinikinExtent MinikinUtils::getFontExtent(const Paint* paint, minikin::Bidi bidiFlags,
diff --git a/libs/hwui/hwui/MinikinUtils.h b/libs/hwui/hwui/MinikinUtils.h
index 61bc881..f8574ee 100644
--- a/libs/hwui/hwui/MinikinUtils.h
+++ b/libs/hwui/hwui/MinikinUtils.h
@@ -53,7 +53,7 @@
 
     static float measureText(const Paint* paint, minikin::Bidi bidiFlags, const Typeface* typeface,
                              const uint16_t* buf, size_t start, size_t count, size_t bufSize,
-                             float* advances, minikin::MinikinRect* bounds);
+                             float* advances, minikin::MinikinRect* bounds, uint32_t* clusterCount);
 
     static minikin::MinikinExtent getFontExtent(const Paint* paint, minikin::Bidi bidiFlags,
                                                 const Typeface* typeface, const uint16_t* buf,
diff --git a/libs/hwui/jni/Graphics.cpp b/libs/hwui/jni/Graphics.cpp
index 7cc4866..8315c4c 100644
--- a/libs/hwui/jni/Graphics.cpp
+++ b/libs/hwui/jni/Graphics.cpp
@@ -247,6 +247,9 @@
 static jfieldID gFontMetricsInt_bottom;
 static jfieldID gFontMetricsInt_leading;
 
+static jclass gRunInfo_class;
+static jfieldID gRunInfo_clusterCount;
+
 ///////////////////////////////////////////////////////////////////////////////
 
 void GraphicsJNI::get_jrect(JNIEnv* env, jobject obj, int* L, int* T, int* R, int* B)
@@ -511,6 +514,10 @@
     return descent - ascent + leading;
 }
 
+void GraphicsJNI::set_cluster_count_to_run_info(JNIEnv* env, jobject runInfo, jint clusterCount) {
+    env->SetIntField(runInfo, gRunInfo_clusterCount, clusterCount);
+}
+
 ///////////////////////////////////////////////////////////////////////////////////////////
 
 jobject GraphicsJNI::createBitmapRegionDecoder(JNIEnv* env, BitmapRegionDecoderWrapper* bitmap) {
@@ -834,5 +841,10 @@
     gFontMetricsInt_bottom = GetFieldIDOrDie(env, gFontMetricsInt_class, "bottom", "I");
     gFontMetricsInt_leading = GetFieldIDOrDie(env, gFontMetricsInt_class, "leading", "I");
 
+    gRunInfo_class = FindClassOrDie(env, "android/graphics/Paint$RunInfo");
+    gRunInfo_class = MakeGlobalRefOrDie(env, gRunInfo_class);
+
+    gRunInfo_clusterCount = GetFieldIDOrDie(env, gRunInfo_class, "mClusterCount", "I");
+
     return 0;
 }
diff --git a/libs/hwui/jni/GraphicsJNI.h b/libs/hwui/jni/GraphicsJNI.h
index b9fff36..b0a1074 100644
--- a/libs/hwui/jni/GraphicsJNI.h
+++ b/libs/hwui/jni/GraphicsJNI.h
@@ -77,6 +77,8 @@
     static SkRect* jrect_to_rect(JNIEnv*, jobject jrect, SkRect*);
     static void rect_to_jrectf(const SkRect&, JNIEnv*, jobject jrectf);
 
+    static void set_cluster_count_to_run_info(JNIEnv* env, jobject runInfo, jint clusterCount);
+
     static void set_jpoint(JNIEnv*, jobject jrect, int x, int y);
 
     static SkIPoint* jpoint_to_ipoint(JNIEnv*, jobject jpoint, SkIPoint* point);
diff --git a/libs/hwui/jni/Paint.cpp b/libs/hwui/jni/Paint.cpp
index d84b73d..286f06a 100644
--- a/libs/hwui/jni/Paint.cpp
+++ b/libs/hwui/jni/Paint.cpp
@@ -114,7 +114,7 @@
 
         std::unique_ptr<float[]> advancesArray(new float[count]);
         MinikinUtils::measureText(&paint, static_cast<minikin::Bidi>(bidiFlags), typeface, text, 0,
-                                  count, count, advancesArray.get(), nullptr);
+                                  count, count, advancesArray.get(), nullptr, nullptr);
 
         for (int i = 0; i < count; i++) {
             // traverse in the given direction
@@ -206,7 +206,7 @@
         }
         const float advance = MinikinUtils::measureText(
                 paint, static_cast<minikin::Bidi>(bidiFlags), typeface, text, start, count,
-                contextCount, advancesArray.get(), nullptr);
+                contextCount, advancesArray.get(), nullptr, nullptr);
         if (advances) {
             env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray.get());
         }
@@ -244,7 +244,7 @@
         minikin::Bidi bidiFlags = dir == 1 ? minikin::Bidi::FORCE_RTL : minikin::Bidi::FORCE_LTR;
         std::unique_ptr<float[]> advancesArray(new float[count]);
         MinikinUtils::measureText(paint, bidiFlags, typeface, text, start, count, start + count,
-                                  advancesArray.get(), nullptr);
+                                  advancesArray.get(), nullptr, nullptr);
         size_t result = minikin::GraphemeBreak::getTextRunCursor(advancesArray.get(), text,
                 start, count, offset, moveOpt);
         return static_cast<jint>(result);
@@ -508,7 +508,7 @@
     static jfloat doRunAdvance(JNIEnv* env, const Paint* paint, const Typeface* typeface,
                                const jchar buf[], jint start, jint count, jint bufSize,
                                jboolean isRtl, jint offset, jfloatArray advances,
-                               jint advancesIndex, SkRect* drawBounds) {
+                               jint advancesIndex, SkRect* drawBounds, uint32_t* clusterCount) {
         if (advances) {
             size_t advancesLength = env->GetArrayLength(advances);
             if ((size_t)(count + advancesIndex) > advancesLength) {
@@ -519,9 +519,9 @@
         minikin::Bidi bidiFlags = isRtl ? minikin::Bidi::FORCE_RTL : minikin::Bidi::FORCE_LTR;
         minikin::MinikinRect bounds;
         if (offset == start + count && advances == nullptr) {
-            float result =
-                    MinikinUtils::measureText(paint, bidiFlags, typeface, buf, start, count,
-                                              bufSize, nullptr, drawBounds ? &bounds : nullptr);
+            float result = MinikinUtils::measureText(paint, bidiFlags, typeface, buf, start, count,
+                                                     bufSize, nullptr,
+                                                     drawBounds ? &bounds : nullptr, clusterCount);
             if (drawBounds) {
                 copyMinikinRectToSkRect(bounds, drawBounds);
             }
@@ -529,7 +529,8 @@
         }
         std::unique_ptr<float[]> advancesArray(new float[count]);
         MinikinUtils::measureText(paint, bidiFlags, typeface, buf, start, count, bufSize,
-                                  advancesArray.get(), drawBounds ? &bounds : nullptr);
+                                  advancesArray.get(), drawBounds ? &bounds : nullptr,
+                                  clusterCount);
 
         if (drawBounds) {
             copyMinikinRectToSkRect(bounds, drawBounds);
@@ -549,7 +550,7 @@
         ScopedCharArrayRO textArray(env, text);
         jfloat result = doRunAdvance(env, paint, typeface, textArray.get() + contextStart,
                                      start - contextStart, end - start, contextEnd - contextStart,
-                                     isRtl, offset - contextStart, nullptr, 0, nullptr);
+                                     isRtl, offset - contextStart, nullptr, 0, nullptr, nullptr);
         return result;
     }
 
@@ -558,18 +559,22 @@
                                                         jint contextStart, jint contextEnd,
                                                         jboolean isRtl, jint offset,
                                                         jfloatArray advances, jint advancesIndex,
-                                                        jobject drawBounds) {
+                                                        jobject drawBounds, jobject runInfo) {
         const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
         const Typeface* typeface = paint->getAndroidTypeface();
         ScopedCharArrayRO textArray(env, text);
         SkRect skDrawBounds;
+        uint32_t clusterCount = 0;
         jfloat result = doRunAdvance(env, paint, typeface, textArray.get() + contextStart,
                                      start - contextStart, end - start, contextEnd - contextStart,
                                      isRtl, offset - contextStart, advances, advancesIndex,
-                                     drawBounds ? &skDrawBounds : nullptr);
+                                     drawBounds ? &skDrawBounds : nullptr, &clusterCount);
         if (drawBounds != nullptr) {
             GraphicsJNI::rect_to_jrectf(skDrawBounds, env, drawBounds);
         }
+        if (runInfo) {
+            GraphicsJNI::set_cluster_count_to_run_info(env, runInfo, clusterCount);
+        }
         return result;
     }
 
@@ -578,7 +583,7 @@
         minikin::Bidi bidiFlags = isRtl ? minikin::Bidi::FORCE_RTL : minikin::Bidi::FORCE_LTR;
         std::unique_ptr<float[]> advancesArray(new float[count]);
         MinikinUtils::measureText(paint, bidiFlags, typeface, buf, start, count, bufSize,
-                                  advancesArray.get(), nullptr);
+                                  advancesArray.get(), nullptr, nullptr);
         return minikin::getOffsetForAdvance(advancesArray.get(), buf, start, count, advance);
     }
 
@@ -1145,7 +1150,8 @@
          (void*)PaintGlue::getCharArrayBounds},
         {"nHasGlyph", "(JILjava/lang/String;)Z", (void*)PaintGlue::hasGlyph},
         {"nGetRunAdvance", "(J[CIIIIZI)F", (void*)PaintGlue::getRunAdvance___CIIIIZI_F},
-        {"nGetRunCharacterAdvance", "(J[CIIIIZI[FILandroid/graphics/RectF;)F",
+        {"nGetRunCharacterAdvance",
+         "(J[CIIIIZI[FILandroid/graphics/RectF;Landroid/graphics/Paint$RunInfo;)F",
          (void*)PaintGlue::getRunCharacterAdvance___CIIIIZI_FI_F},
         {"nGetOffsetForAdvance", "(J[CIIIIZF)I", (void*)PaintGlue::getOffsetForAdvance___CIIIIZF_I},
         {"nGetFontMetricsIntForText", "(J[CIIIIZLandroid/graphics/Paint$FontMetricsInt;)V",