Loading apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java 0 → 100644 +91 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package android.text; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; import android.support.test.filters.LargeTest; import android.support.test.runner.AndroidJUnit4; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import java.nio.CharBuffer; import java.util.Random; @LargeTest @RunWith(AndroidJUnit4.class) public class StaticLayoutPerfTest { public StaticLayoutPerfTest() { } @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); private static final String FIXED_TEXT = "Lorem ipsum dolor sit amet, consectetur adipiscing " + "elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad " + "minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea " + "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse " + "cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " + "proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; private static final int FIXED_TEXT_LENGTH = FIXED_TEXT.length(); private static TextPaint PAINT = new TextPaint(); private static final int TEXT_WIDTH = 20 * (int) PAINT.getTextSize(); @Test public void testCreate() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { StaticLayout.Builder.obtain(FIXED_TEXT, 0, FIXED_TEXT_LENGTH, PAINT, TEXT_WIDTH) .build(); } } private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; private static final int ALPHABET_LENGTH = ALPHABET.length(); private static final int PARA_LENGTH = 500; private final char[] mBuffer = new char[PARA_LENGTH]; private final Random mRandom = new Random(31415926535L); private CharSequence generateRandomParagraph(int wordLen) { for (int i = 0; i < PARA_LENGTH; i++) { if (i % (wordLen + 1) == wordLen) { mBuffer[i] = ' '; } else { mBuffer[i] = ALPHABET.charAt(mRandom.nextInt(ALPHABET_LENGTH)); } } return CharBuffer.wrap(mBuffer); } // This tries to simulate the case where the cache hit rate is low, and most of the text is // new text. @Test public void testCreateRandom() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { final CharSequence text = generateRandomParagraph(9); StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH) .build(); } } } api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -41781,6 +41781,7 @@ package android.text { method public android.text.StaticLayout.Builder setMaxLines(int); method public android.text.StaticLayout.Builder setText(java.lang.CharSequence); method public android.text.StaticLayout.Builder setTextDirection(android.text.TextDirectionHeuristic); method public android.text.StaticLayout.Builder setUseLineSpacingFromFallbacks(boolean); } public abstract interface TextDirectionHeuristic { api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -45383,6 +45383,7 @@ package android.text { method public android.text.StaticLayout.Builder setMaxLines(int); method public android.text.StaticLayout.Builder setText(java.lang.CharSequence); method public android.text.StaticLayout.Builder setTextDirection(android.text.TextDirectionHeuristic); method public android.text.StaticLayout.Builder setUseLineSpacingFromFallbacks(boolean); } public abstract interface TextDirectionHeuristic { api/test-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -42052,6 +42052,7 @@ package android.text { method public android.text.StaticLayout.Builder setMaxLines(int); method public android.text.StaticLayout.Builder setText(java.lang.CharSequence); method public android.text.StaticLayout.Builder setTextDirection(android.text.TextDirectionHeuristic); method public android.text.StaticLayout.Builder setUseLineSpacingFromFallbacks(boolean); } public abstract interface TextDirectionHeuristic { core/java/android/text/StaticLayout.java +41 −10 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ public class StaticLayout extends Layout { b.mSpacingMult = 1.0f; b.mSpacingAdd = 0.0f; b.mIncludePad = true; b.mFallbackLineSpacing = false; b.mEllipsizedWidth = width; b.mEllipsize = null; b.mMaxLines = Integer.MAX_VALUE; Loading Loading @@ -227,6 +228,24 @@ public class StaticLayout extends Layout { return this; } /** * Set whether to respect the ascent and descent of the fallback fonts that are used in * displaying the text (which is needed to avoid text from consecutive lines running into * each other). If set, fallback fonts that end up getting used can increase the ascent * and descent of the lines that they are used on. * * <p>For backward compatibility reasons, the default is {@code false}, but setting this to * true is strongly recommended. It is required to be true if text could be in languages * like Burmese or Tibetan where text is typically much taller or deeper than Latin text. * * @param useLineSpacingFromFallbacks whether to expand linespacing based on fallback fonts * @return this builder, useful for chaining */ public Builder setUseLineSpacingFromFallbacks(boolean useLineSpacingFromFallbacks) { mFallbackLineSpacing = useLineSpacingFromFallbacks; return this; } /** * Set the width as used for ellipsizing purposes, if it differs from the * normal layout width. The default is the {@code width} Loading Loading @@ -432,6 +451,7 @@ public class StaticLayout extends Layout { float mSpacingMult; float mSpacingAdd; boolean mIncludePad; boolean mFallbackLineSpacing; int mEllipsizedWidth; TextUtils.TruncateAt mEllipsize; int mMaxLines; Loading Loading @@ -606,6 +626,7 @@ public class StaticLayout extends Layout { TextPaint paint = b.mPaint; int outerWidth = b.mWidth; TextDirectionHeuristic textDir = b.mTextDir; final boolean fallbackLineSpacing = b.mFallbackLineSpacing; float spacingmult = b.mSpacingMult; float spacingadd = b.mSpacingAdd; float ellipsizedWidth = b.mEllipsizedWidth; Loading Loading @@ -784,11 +805,14 @@ public class StaticLayout extends Layout { nGetWidths(b.mNativePtr, widths); int breakCount = nComputeLineBreaks(b.mNativePtr, lineBreaks, lineBreaks.breaks, lineBreaks.widths, lineBreaks.flags, lineBreaks.breaks.length); lineBreaks.widths, lineBreaks.ascents, lineBreaks.descents, lineBreaks.flags, lineBreaks.breaks.length); int[] breaks = lineBreaks.breaks; float[] lineWidths = lineBreaks.widths; int[] flags = lineBreaks.flags; final int[] breaks = lineBreaks.breaks; final float[] lineWidths = lineBreaks.widths; final float[] ascents = lineBreaks.ascents; final float[] descents = lineBreaks.descents; final int[] flags = lineBreaks.flags; final int remainingLineCount = mMaximumVisibleLineCount - mLineCount; final boolean ellipsisMayBeApplied = ellipsize != null Loading @@ -799,7 +823,7 @@ public class StaticLayout extends Layout { && ellipsisMayBeApplied) { // Calculate width and flag. float width = 0; int flag = 0; int flag = 0; // XXX May need to also have starting hyphen edit for (int i = remainingLineCount - 1; i < breakCount; i++) { if (i == breakCount - 1) { width += lineWidths[i]; Loading @@ -808,7 +832,7 @@ public class StaticLayout extends Layout { width += widths[j]; } } flag |= flags[i] & TAB_MASK; // XXX May need to also have starting hyphen edit flag |= flags[i] & TAB_MASK; } // Treat the last line and overflowed lines as a single line. breaks[remainingLineCount - 1] = breaks[breakCount - 1]; Loading Loading @@ -859,8 +883,14 @@ public class StaticLayout extends Layout { boolean moreChars = (endPos < bufEnd); final int ascent = fallbackLineSpacing ? Math.min(fmAscent, (int) Math.round(ascents[breakIndex])) : fmAscent; final int descent = fallbackLineSpacing ? Math.max(fmDescent, (int) Math.round(descents[breakIndex])) : fmDescent; v = out(source, here, endPos, fmAscent, fmDescent, fmTop, fmBottom, ascent, descent, fmTop, fmBottom, v, spacingmult, spacingadd, chooseHt, chooseHtv, fm, flags[breakIndex], needMultiply, chdirs, dir, easy, bufEnd, includepad, trackpad, addLastLineSpacing, chs, widths, paraStart, ellipsize, Loading Loading @@ -891,8 +921,6 @@ public class StaticLayout extends Layout { if ((bufEnd == bufStart || source.charAt(bufEnd - 1) == CHAR_NEW_LINE) && mLineCount < mMaximumVisibleLineCount) { // Log.e("text", "output last " + bufEnd); measured.setPara(source, bufEnd, bufEnd, textDir, b); paint.getFontMetricsInt(fm); Loading Loading @@ -1470,7 +1498,8 @@ public class StaticLayout extends Layout { // to reduce the number of JNI calls in the common case where the // arrays do not have to be resized private static native int nComputeLineBreaks(long nativePtr, LineBreaks recycle, int[] recycleBreaks, float[] recycleWidths, int[] recycleFlags, int recycleLength); int[] recycleBreaks, float[] recycleWidths, float[] recycleAscents, float[] recycleDescents, int[] recycleFlags, int recycleLength); private int mLineCount; private int mTopPadding, mBottomPadding; Loading Loading @@ -1529,6 +1558,8 @@ public class StaticLayout extends Layout { private static final int INITIAL_SIZE = 16; public int[] breaks = new int[INITIAL_SIZE]; public float[] widths = new float[INITIAL_SIZE]; public float[] ascents = new float[INITIAL_SIZE]; public float[] descents = new float[INITIAL_SIZE]; public int[] flags = new int[INITIAL_SIZE]; // hasTab // breaks, widths, and flags should all have the same length } Loading Loading
apct-tests/perftests/core/src/android/text/StaticLayoutPerfTest.java 0 → 100644 +91 −0 Original line number Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package android.text; import android.perftests.utils.BenchmarkState; import android.perftests.utils.PerfStatusReporter; import android.support.test.filters.LargeTest; import android.support.test.runner.AndroidJUnit4; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import java.nio.CharBuffer; import java.util.Random; @LargeTest @RunWith(AndroidJUnit4.class) public class StaticLayoutPerfTest { public StaticLayoutPerfTest() { } @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); private static final String FIXED_TEXT = "Lorem ipsum dolor sit amet, consectetur adipiscing " + "elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad " + "minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea " + "commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse " + "cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " + "proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; private static final int FIXED_TEXT_LENGTH = FIXED_TEXT.length(); private static TextPaint PAINT = new TextPaint(); private static final int TEXT_WIDTH = 20 * (int) PAINT.getTextSize(); @Test public void testCreate() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { StaticLayout.Builder.obtain(FIXED_TEXT, 0, FIXED_TEXT_LENGTH, PAINT, TEXT_WIDTH) .build(); } } private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; private static final int ALPHABET_LENGTH = ALPHABET.length(); private static final int PARA_LENGTH = 500; private final char[] mBuffer = new char[PARA_LENGTH]; private final Random mRandom = new Random(31415926535L); private CharSequence generateRandomParagraph(int wordLen) { for (int i = 0; i < PARA_LENGTH; i++) { if (i % (wordLen + 1) == wordLen) { mBuffer[i] = ' '; } else { mBuffer[i] = ALPHABET.charAt(mRandom.nextInt(ALPHABET_LENGTH)); } } return CharBuffer.wrap(mBuffer); } // This tries to simulate the case where the cache hit rate is low, and most of the text is // new text. @Test public void testCreateRandom() { final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); while (state.keepRunning()) { final CharSequence text = generateRandomParagraph(9); StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH) .build(); } } }
api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -41781,6 +41781,7 @@ package android.text { method public android.text.StaticLayout.Builder setMaxLines(int); method public android.text.StaticLayout.Builder setText(java.lang.CharSequence); method public android.text.StaticLayout.Builder setTextDirection(android.text.TextDirectionHeuristic); method public android.text.StaticLayout.Builder setUseLineSpacingFromFallbacks(boolean); } public abstract interface TextDirectionHeuristic {
api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -45383,6 +45383,7 @@ package android.text { method public android.text.StaticLayout.Builder setMaxLines(int); method public android.text.StaticLayout.Builder setText(java.lang.CharSequence); method public android.text.StaticLayout.Builder setTextDirection(android.text.TextDirectionHeuristic); method public android.text.StaticLayout.Builder setUseLineSpacingFromFallbacks(boolean); } public abstract interface TextDirectionHeuristic {
api/test-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -42052,6 +42052,7 @@ package android.text { method public android.text.StaticLayout.Builder setMaxLines(int); method public android.text.StaticLayout.Builder setText(java.lang.CharSequence); method public android.text.StaticLayout.Builder setTextDirection(android.text.TextDirectionHeuristic); method public android.text.StaticLayout.Builder setUseLineSpacingFromFallbacks(boolean); } public abstract interface TextDirectionHeuristic {
core/java/android/text/StaticLayout.java +41 −10 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ public class StaticLayout extends Layout { b.mSpacingMult = 1.0f; b.mSpacingAdd = 0.0f; b.mIncludePad = true; b.mFallbackLineSpacing = false; b.mEllipsizedWidth = width; b.mEllipsize = null; b.mMaxLines = Integer.MAX_VALUE; Loading Loading @@ -227,6 +228,24 @@ public class StaticLayout extends Layout { return this; } /** * Set whether to respect the ascent and descent of the fallback fonts that are used in * displaying the text (which is needed to avoid text from consecutive lines running into * each other). If set, fallback fonts that end up getting used can increase the ascent * and descent of the lines that they are used on. * * <p>For backward compatibility reasons, the default is {@code false}, but setting this to * true is strongly recommended. It is required to be true if text could be in languages * like Burmese or Tibetan where text is typically much taller or deeper than Latin text. * * @param useLineSpacingFromFallbacks whether to expand linespacing based on fallback fonts * @return this builder, useful for chaining */ public Builder setUseLineSpacingFromFallbacks(boolean useLineSpacingFromFallbacks) { mFallbackLineSpacing = useLineSpacingFromFallbacks; return this; } /** * Set the width as used for ellipsizing purposes, if it differs from the * normal layout width. The default is the {@code width} Loading Loading @@ -432,6 +451,7 @@ public class StaticLayout extends Layout { float mSpacingMult; float mSpacingAdd; boolean mIncludePad; boolean mFallbackLineSpacing; int mEllipsizedWidth; TextUtils.TruncateAt mEllipsize; int mMaxLines; Loading Loading @@ -606,6 +626,7 @@ public class StaticLayout extends Layout { TextPaint paint = b.mPaint; int outerWidth = b.mWidth; TextDirectionHeuristic textDir = b.mTextDir; final boolean fallbackLineSpacing = b.mFallbackLineSpacing; float spacingmult = b.mSpacingMult; float spacingadd = b.mSpacingAdd; float ellipsizedWidth = b.mEllipsizedWidth; Loading Loading @@ -784,11 +805,14 @@ public class StaticLayout extends Layout { nGetWidths(b.mNativePtr, widths); int breakCount = nComputeLineBreaks(b.mNativePtr, lineBreaks, lineBreaks.breaks, lineBreaks.widths, lineBreaks.flags, lineBreaks.breaks.length); lineBreaks.widths, lineBreaks.ascents, lineBreaks.descents, lineBreaks.flags, lineBreaks.breaks.length); int[] breaks = lineBreaks.breaks; float[] lineWidths = lineBreaks.widths; int[] flags = lineBreaks.flags; final int[] breaks = lineBreaks.breaks; final float[] lineWidths = lineBreaks.widths; final float[] ascents = lineBreaks.ascents; final float[] descents = lineBreaks.descents; final int[] flags = lineBreaks.flags; final int remainingLineCount = mMaximumVisibleLineCount - mLineCount; final boolean ellipsisMayBeApplied = ellipsize != null Loading @@ -799,7 +823,7 @@ public class StaticLayout extends Layout { && ellipsisMayBeApplied) { // Calculate width and flag. float width = 0; int flag = 0; int flag = 0; // XXX May need to also have starting hyphen edit for (int i = remainingLineCount - 1; i < breakCount; i++) { if (i == breakCount - 1) { width += lineWidths[i]; Loading @@ -808,7 +832,7 @@ public class StaticLayout extends Layout { width += widths[j]; } } flag |= flags[i] & TAB_MASK; // XXX May need to also have starting hyphen edit flag |= flags[i] & TAB_MASK; } // Treat the last line and overflowed lines as a single line. breaks[remainingLineCount - 1] = breaks[breakCount - 1]; Loading Loading @@ -859,8 +883,14 @@ public class StaticLayout extends Layout { boolean moreChars = (endPos < bufEnd); final int ascent = fallbackLineSpacing ? Math.min(fmAscent, (int) Math.round(ascents[breakIndex])) : fmAscent; final int descent = fallbackLineSpacing ? Math.max(fmDescent, (int) Math.round(descents[breakIndex])) : fmDescent; v = out(source, here, endPos, fmAscent, fmDescent, fmTop, fmBottom, ascent, descent, fmTop, fmBottom, v, spacingmult, spacingadd, chooseHt, chooseHtv, fm, flags[breakIndex], needMultiply, chdirs, dir, easy, bufEnd, includepad, trackpad, addLastLineSpacing, chs, widths, paraStart, ellipsize, Loading Loading @@ -891,8 +921,6 @@ public class StaticLayout extends Layout { if ((bufEnd == bufStart || source.charAt(bufEnd - 1) == CHAR_NEW_LINE) && mLineCount < mMaximumVisibleLineCount) { // Log.e("text", "output last " + bufEnd); measured.setPara(source, bufEnd, bufEnd, textDir, b); paint.getFontMetricsInt(fm); Loading Loading @@ -1470,7 +1498,8 @@ public class StaticLayout extends Layout { // to reduce the number of JNI calls in the common case where the // arrays do not have to be resized private static native int nComputeLineBreaks(long nativePtr, LineBreaks recycle, int[] recycleBreaks, float[] recycleWidths, int[] recycleFlags, int recycleLength); int[] recycleBreaks, float[] recycleWidths, float[] recycleAscents, float[] recycleDescents, int[] recycleFlags, int recycleLength); private int mLineCount; private int mTopPadding, mBottomPadding; Loading Loading @@ -1529,6 +1558,8 @@ public class StaticLayout extends Layout { private static final int INITIAL_SIZE = 16; public int[] breaks = new int[INITIAL_SIZE]; public float[] widths = new float[INITIAL_SIZE]; public float[] ascents = new float[INITIAL_SIZE]; public float[] descents = new float[INITIAL_SIZE]; public int[] flags = new int[INITIAL_SIZE]; // hasTab // breaks, widths, and flags should all have the same length } Loading