Merge "Implement LineBreaker callback and fix indent repeating."
This commit is contained in:
committed by
Android (Google) Code Review
commit
ed82b166e7
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user