Merge "Implement LineBreaker callback and fix indent repeating."

This commit is contained in:
TreeHugger Robot
2017-08-31 01:41:01 +00:00
committed by Android (Google) Code Review
3 changed files with 48 additions and 13 deletions

View File

@@ -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();
}
}
}

View File

@@ -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
@@ -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);

View File

@@ -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 {
@@ -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,