Loading apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java +11 −0 Original line number Diff line number Diff line Loading @@ -88,4 +88,15 @@ public class StaticLayoutPerfTest { .build(); } } @Test public void testCreateRandom_breakBalanced() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { final CharSequence text = generateRandomParagraph(9); StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH) .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED) .build(); } } } core/java/android/text/StaticLayout.java +2 −4 Original line number Diff line number Diff line Loading @@ -780,9 +780,7 @@ public class StaticLayout extends Layout { firstWidth, firstWidthLineCount, restWidth, variableTabStops, TAB_INCREMENT, b.mBreakStrategy, b.mHyphenationFrequency, // TODO: Support more justification mode, e.g. letter spacing, stretching. b.mJustificationMode != Layout.JUSTIFICATION_MODE_NONE, (indents != null && indents.length > mLineCount) ? indents : null, mLineCount); b.mJustificationMode != Layout.JUSTIFICATION_MODE_NONE, indents, mLineCount); // measurement has to be done before performing line breaking // but we don't want to recompute fontmetrics or span ranges the Loading Loading @@ -1506,7 +1504,7 @@ public class StaticLayout extends Layout { @FloatRange(from = 0.0f) float restWidth, @Nullable int[] variableTabStops, int defaultTabStop, @BreakStrategy int breakStrategy, @HyphenationFrequency int hyphenationFrequency, boolean isJustified, @Nullable int[] indents, @IntRange(from = 0) int intentsOffset); @Nullable int[] indents, @IntRange(from = 0) int indentsOffset); private static native float nAddStyleRun(long nativePtr, long nativePaint, int start, int end, boolean isRtl); Loading core/jni/android_text_StaticLayout.cpp +35 −9 Original line number Diff line number Diff line Loading @@ -52,17 +52,46 @@ struct JLineBreaksID { static jclass gLineBreaks_class; static JLineBreaksID gLineBreaks_fieldID; class JNILineBreakerLineWidth : public minikin::LineBreaker::LineWidthDelegate { public: JNILineBreakerLineWidth(float firstWidth, int32_t firstLineCount, float restWidth, std::vector<float>&& indents, int32_t indentsOffset) : mFirstWidth(firstWidth), mFirstLineCount(firstLineCount), mRestWidth(restWidth), mIndents(std::move(indents)), mIndentsOffset(indentsOffset) {} float getLineWidth(size_t lineNo) override { const float width = ((ssize_t)lineNo < (ssize_t)mFirstLineCount) ? mFirstWidth : mRestWidth; if (mIndents.empty()) { return width; } const size_t indentIndex = lineNo + mIndentsOffset; if (indentIndex < mIndents.size()) { return width - mIndents[indentIndex]; } else { return width - mIndents.back(); } } private: const float mFirstWidth; const int32_t mFirstLineCount; const float mRestWidth; const std::vector<float> mIndents; const int32_t mIndentsOffset; }; // set text and set a number of parameters for creating a layout (width, tabstops, strategy, // hyphenFrequency) static void nSetupParagraph(JNIEnv* env, jclass, jlong nativePtr, jcharArray text, jint length, jfloat firstWidth, jint firstWidthLineLimit, jfloat restWidth, jintArray variableTabStops, jint defaultTabStop, jint strategy, jint hyphenFrequency, jboolean isJustified, jintArray indents, jint insetsOffset) { jboolean isJustified, jintArray indents, jint indentsOffset) { minikin::LineBreaker* b = reinterpret_cast<minikin::LineBreaker*>(nativePtr); b->resize(length); env->GetCharArrayRegion(text, 0, length, b->buffer()); b->setText(); b->setLineWidths(firstWidth, firstWidthLineLimit, restWidth); if (variableTabStops == nullptr) { b->setTabStops(nullptr, 0, defaultTabStop); } else { Loading @@ -73,17 +102,14 @@ static void nSetupParagraph(JNIEnv* env, jclass, jlong nativePtr, jcharArray tex b->setHyphenationFrequency(static_cast<minikin::HyphenationFrequency>(hyphenFrequency)); b->setJustified(isJustified); std::vector<float> indentVec; // TODO: copy indents only once when LineBreaker is started to be used. if (indents != nullptr) { // If indents is not null, it is guaranteed that lineOffset is less than the size of array. ScopedIntArrayRO indentArr(env, indents); std::vector<float> indentVec( indentArr.get() + insetsOffset, indentArr.get() + indentArr.size()); b->setIndents(indentVec); } else { b->setIndents(std::vector<float>()); indentVec.assign(indentArr.get(), indentArr.get() + indentArr.size()); } b->setLineWidthDelegate(std::make_unique<JNILineBreakerLineWidth>( firstWidth, firstWidthLineLimit, restWidth, std::move(indentVec), indentsOffset)); } static void recycleCopy(JNIEnv* env, jobject recycle, jintArray recycleBreaks, Loading Loading
apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java +11 −0 Original line number Diff line number Diff line Loading @@ -88,4 +88,15 @@ public class StaticLayoutPerfTest { .build(); } } @Test public void testCreateRandom_breakBalanced() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { final CharSequence text = generateRandomParagraph(9); StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH) .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED) .build(); } } }
core/java/android/text/StaticLayout.java +2 −4 Original line number Diff line number Diff line Loading @@ -780,9 +780,7 @@ public class StaticLayout extends Layout { firstWidth, firstWidthLineCount, restWidth, variableTabStops, TAB_INCREMENT, b.mBreakStrategy, b.mHyphenationFrequency, // TODO: Support more justification mode, e.g. letter spacing, stretching. b.mJustificationMode != Layout.JUSTIFICATION_MODE_NONE, (indents != null && indents.length > mLineCount) ? indents : null, mLineCount); b.mJustificationMode != Layout.JUSTIFICATION_MODE_NONE, indents, mLineCount); // measurement has to be done before performing line breaking // but we don't want to recompute fontmetrics or span ranges the Loading Loading @@ -1506,7 +1504,7 @@ public class StaticLayout extends Layout { @FloatRange(from = 0.0f) float restWidth, @Nullable int[] variableTabStops, int defaultTabStop, @BreakStrategy int breakStrategy, @HyphenationFrequency int hyphenationFrequency, boolean isJustified, @Nullable int[] indents, @IntRange(from = 0) int intentsOffset); @Nullable int[] indents, @IntRange(from = 0) int indentsOffset); private static native float nAddStyleRun(long nativePtr, long nativePaint, int start, int end, boolean isRtl); Loading
core/jni/android_text_StaticLayout.cpp +35 −9 Original line number Diff line number Diff line Loading @@ -52,17 +52,46 @@ struct JLineBreaksID { static jclass gLineBreaks_class; static JLineBreaksID gLineBreaks_fieldID; class JNILineBreakerLineWidth : public minikin::LineBreaker::LineWidthDelegate { public: JNILineBreakerLineWidth(float firstWidth, int32_t firstLineCount, float restWidth, std::vector<float>&& indents, int32_t indentsOffset) : mFirstWidth(firstWidth), mFirstLineCount(firstLineCount), mRestWidth(restWidth), mIndents(std::move(indents)), mIndentsOffset(indentsOffset) {} float getLineWidth(size_t lineNo) override { const float width = ((ssize_t)lineNo < (ssize_t)mFirstLineCount) ? mFirstWidth : mRestWidth; if (mIndents.empty()) { return width; } const size_t indentIndex = lineNo + mIndentsOffset; if (indentIndex < mIndents.size()) { return width - mIndents[indentIndex]; } else { return width - mIndents.back(); } } private: const float mFirstWidth; const int32_t mFirstLineCount; const float mRestWidth; const std::vector<float> mIndents; const int32_t mIndentsOffset; }; // set text and set a number of parameters for creating a layout (width, tabstops, strategy, // hyphenFrequency) static void nSetupParagraph(JNIEnv* env, jclass, jlong nativePtr, jcharArray text, jint length, jfloat firstWidth, jint firstWidthLineLimit, jfloat restWidth, jintArray variableTabStops, jint defaultTabStop, jint strategy, jint hyphenFrequency, jboolean isJustified, jintArray indents, jint insetsOffset) { jboolean isJustified, jintArray indents, jint indentsOffset) { minikin::LineBreaker* b = reinterpret_cast<minikin::LineBreaker*>(nativePtr); b->resize(length); env->GetCharArrayRegion(text, 0, length, b->buffer()); b->setText(); b->setLineWidths(firstWidth, firstWidthLineLimit, restWidth); if (variableTabStops == nullptr) { b->setTabStops(nullptr, 0, defaultTabStop); } else { Loading @@ -73,17 +102,14 @@ static void nSetupParagraph(JNIEnv* env, jclass, jlong nativePtr, jcharArray tex b->setHyphenationFrequency(static_cast<minikin::HyphenationFrequency>(hyphenFrequency)); b->setJustified(isJustified); std::vector<float> indentVec; // TODO: copy indents only once when LineBreaker is started to be used. if (indents != nullptr) { // If indents is not null, it is guaranteed that lineOffset is less than the size of array. ScopedIntArrayRO indentArr(env, indents); std::vector<float> indentVec( indentArr.get() + insetsOffset, indentArr.get() + indentArr.size()); b->setIndents(indentVec); } else { b->setIndents(std::vector<float>()); indentVec.assign(indentArr.get(), indentArr.get() + indentArr.size()); } b->setLineWidthDelegate(std::make_unique<JNILineBreakerLineWidth>( firstWidth, firstWidthLineLimit, restWidth, std::move(indentVec), indentsOffset)); } static void recycleCopy(JNIEnv* env, jobject recycle, jintArray recycleBreaks, Loading