StaticLayout_Delegate.java revision 6b06ef9725495cf071deec3bad76aff32c59b39e
1ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Guptapackage android.text; 2ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Gupta 3e8685f6153d281f24d1d2cbfa5942f40a5b461b1Diego Perezimport com.android.layoutlib.bridge.impl.DelegateManager; 4ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Guptaimport com.android.tools.layoutlib.annotations.LayoutlibDelegate; 5ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Gupta 6442aee6bc1abfb143dcfa1ba60d696e576d066c4Deepanshu Guptaimport android.annotation.NonNull; 7345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillardimport android.annotation.Nullable; 8f3284cbd38989279a116e0082b7ab5b987c13388Diego Perezimport android.graphics.BidiRenderer; 9f3284cbd38989279a116e0082b7ab5b987c13388Diego Perezimport android.graphics.Paint; 10f3284cbd38989279a116e0082b7ab5b987c13388Diego Perezimport android.graphics.Paint_Delegate; 11f3284cbd38989279a116e0082b7ab5b987c13388Diego Perezimport android.graphics.RectF; 129fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Guptaimport android.icu.text.BreakIterator; 13345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillardimport android.text.Layout.BreakStrategy; 14345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillardimport android.text.Layout.HyphenationFrequency; 154ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Guptaimport android.text.Primitive.PrimitiveType; 169fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Guptaimport android.text.StaticLayout.LineBreaks; 174ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta 186b06ef9725495cf071deec3bad76aff32c59b39eVictor Changimport java.text.CharacterIterator; 194ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Guptaimport java.util.ArrayList; 20f3284cbd38989279a116e0082b7ab5b987c13388Diego Perezimport java.util.Arrays; 214ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Guptaimport java.util.List; 22ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Gupta 23ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Guptaimport javax.swing.text.Segment; 24ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Gupta 25ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Gupta/** 26ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Gupta * Delegate that provides implementation for native methods in {@link android.text.StaticLayout} 274ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta * <p/> 288a16d5d203a48e7b13761f329333b3dcb8f8210bDeepanshu Gupta * Through the layoutlib_create tool, selected methods of StaticLayout have been replaced 29ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Gupta * by calls to methods of the same name in this delegate class. 30ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Gupta * 31ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Gupta */ 32ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Guptapublic class StaticLayout_Delegate { 33ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Gupta 344ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta private static final char CHAR_SPACE = 0x20; 354ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta private static final char CHAR_TAB = 0x09; 364ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta private static final char CHAR_NEWLINE = 0x0A; 374ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta private static final char CHAR_ZWSP = 0x200B; // Zero width space. 384ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta 39e8685f6153d281f24d1d2cbfa5942f40a5b461b1Diego Perez // ---- Builder delegate manager ---- 40e8685f6153d281f24d1d2cbfa5942f40a5b461b1Diego Perez private static final DelegateManager<Builder> sBuilderManager = 41e8685f6153d281f24d1d2cbfa5942f40a5b461b1Diego Perez new DelegateManager<Builder>(Builder.class); 42e8685f6153d281f24d1d2cbfa5942f40a5b461b1Diego Perez 43ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Gupta @LayoutlibDelegate 44345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard /*package*/ static long nInit( 45345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard @BreakStrategy int breakStrategy, 46345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard @HyphenationFrequency int hyphenationFrequency, 47345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard boolean isJustified, 48345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard @Nullable int[] indents, 49345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard @Nullable int[] leftPaddings, 50345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard @Nullable int[] rightPaddings) { 51345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard Builder builder = new Builder(); 52345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard builder.mBreakStrategy = breakStrategy; 53345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard return sBuilderManager.addNewDelegate(builder); 549fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta } 559fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta 569fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta @LayoutlibDelegate 57345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard /*package*/ static void nFinish(long nativePtr) { 58345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard sBuilderManager.removeJavaReferenceFor(nativePtr); 599fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta } 609fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta 619fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta @LayoutlibDelegate 621d98a835ecb5d85ab9045fe9bee4af8fe5a5cca7Jerome Gaillard /*package*/ static void nAddStyleRun(long nativeBuilder, long nativePaint, int start, 63009184dd1182a3bcd25a18302ad34a07c3e6be42Jerome Gaillard int end, boolean isRtl) { 649fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta Builder builder = sBuilderManager.getDelegate(nativeBuilder); 654e51324759676e6f66edd7e34a2c0ec7c997d8eeJerome Gaillard if (builder == null) { 661d98a835ecb5d85ab9045fe9bee4af8fe5a5cca7Jerome Gaillard return; 674e51324759676e6f66edd7e34a2c0ec7c997d8eeJerome Gaillard } 68345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard builder.mRuns.add(new StyleRun(nativePaint, start, end, isRtl)); 699fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta } 709fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta 719fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta @LayoutlibDelegate 72009184dd1182a3bcd25a18302ad34a07c3e6be42Jerome Gaillard /*package*/ static void nAddReplacementRun(long nativeBuilder, long nativePaint, int start, 73009184dd1182a3bcd25a18302ad34a07c3e6be42Jerome Gaillard int end, float width) { 749fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta Builder builder = sBuilderManager.getDelegate(nativeBuilder); 759fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta if (builder == null) { 769fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta return; 779fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta } 78345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard builder.mRuns.add(new ReplacementRun(start, end, width)); 799fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta } 809fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta 819fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta @LayoutlibDelegate 82345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard /*package*/ static int nComputeLineBreaks( 83345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard /* non zero */ long nativePtr, 849fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta 85345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard // Inputs 86345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard @NonNull char[] text, 87345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard int length, 88345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard float firstWidth, 89345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard int firstWidthLineCount, 90345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard float restWidth, 91345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard @Nullable int[] variableTabStops, 92345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard int defaultTabStop, 93345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard int indentsOffset, 94345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard 95345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard // Outputs 96345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard @NonNull LineBreaks recycle, 97345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard int recycleLength, 98345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard @NonNull int[] recycleBreaks, 99345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard @NonNull float[] recycleWidths, 100345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard @NonNull float[] recycleAscents, 101345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard @NonNull float[] recycleDescents, 102345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard @NonNull int[] recycleFlags, 103345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard @NonNull float[] charWidths) { 104345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard Builder builder = sBuilderManager.getDelegate(nativePtr); 1059fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta if (builder == null) { 1069fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta return 0; 1079fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta } 1087169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta 109345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard builder.mText = text; 110345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard builder.mWidths = new float[length]; 111345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard builder.mLineWidth = new LineWidth(firstWidth, firstWidthLineCount, restWidth); 112345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard builder.mTabStopCalculator = new TabStops(variableTabStops, defaultTabStop); 113345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard 114345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard for (Run run: builder.mRuns) { 115345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard run.addTo(builder); 116345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard } 117345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard 1187169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta // compute all possible breakpoints. 119009184dd1182a3bcd25a18302ad34a07c3e6be42Jerome Gaillard BreakIterator it = BreakIterator.getLineInstance(); 1206b06ef9725495cf071deec3bad76aff32c59b39eVictor Chang it.setText((CharacterIterator) new Segment(builder.mText, 0, length)); 1217169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta 1227169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta // average word length in english is 5. So, initialize the possible breaks with a guess. 1237169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta List<Integer> breaks = new ArrayList<Integer>((int) Math.ceil(length / 5d)); 1247169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta int loc; 1257169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta it.first(); 1267169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta while ((loc = it.next()) != BreakIterator.DONE) { 1277169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta breaks.add(loc); 1287169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta } 1297169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta 1307169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta List<Primitive> primitives = 1317169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta computePrimitives(builder.mText, builder.mWidths, length, breaks); 1327169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta switch (builder.mBreakStrategy) { 1337169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta case Layout.BREAK_STRATEGY_SIMPLE: 1347169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta builder.mLineBreaker = new GreedyLineBreaker(primitives, builder.mLineWidth, 1357169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta builder.mTabStopCalculator); 1367169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta break; 1377169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta case Layout.BREAK_STRATEGY_HIGH_QUALITY: 1387169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta // TODO 1397169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta// break; 1407169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta case Layout.BREAK_STRATEGY_BALANCED: 1417169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta builder.mLineBreaker = new OptimizingLineBreaker(primitives, builder.mLineWidth, 1427169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta builder.mTabStopCalculator); 1437169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta break; 1447169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta default: 1450609785e6f839bfd27e33fa2630e6a1c12be9a20Diego Perez assert false : "Unknown break strategy: " + builder.mBreakStrategy; 1460609785e6f839bfd27e33fa2630e6a1c12be9a20Diego Perez builder.mLineBreaker = new GreedyLineBreaker(primitives, builder.mLineWidth, 1470609785e6f839bfd27e33fa2630e6a1c12be9a20Diego Perez builder.mTabStopCalculator); 1487169c14107fc4291342b6211fff01723996fd351Deepanshu Gupta } 1499fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta builder.mLineBreaker.computeBreaks(recycle); 150b28e813fd8bd9a9e330ea1803f5b153b6fc7d4e0Jerome Gaillard System.arraycopy(builder.mWidths, 0, charWidths, 0, builder.mWidths.length); 1514ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta return recycle.breaks.length; 152ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Gupta } 153ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Gupta 1544ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta /** 1554ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta * Compute metadata each character - things which help in deciding if it's possible to break 1564ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta * at a point or not. 1574ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta */ 1584ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta @NonNull 1594ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta private static List<Primitive> computePrimitives(@NonNull char[] text, @NonNull float[] widths, 1604ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta int length, @NonNull List<Integer> breaks) { 1614ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta // Initialize the list with a guess of the number of primitives: 1624ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta // 2 Primitives per non-whitespace char and approx 5 chars per word (i.e. 83% chars) 1634ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta List<Primitive> primitives = new ArrayList<Primitive>(((int) Math.ceil(length * 1.833))); 1644ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta int breaksSize = breaks.size(); 1654ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta int breakIndex = 0; 1664ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta for (int i = 0; i < length; i++) { 1674ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta char c = text[i]; 1684ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta if (c == CHAR_SPACE || c == CHAR_ZWSP) { 1694ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta primitives.add(PrimitiveType.GLUE.getNewPrimitive(i, widths[i])); 1704ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta } else if (c == CHAR_TAB) { 1714ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta primitives.add(PrimitiveType.VARIABLE.getNewPrimitive(i)); 1724ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta } else if (c != CHAR_NEWLINE) { 1734ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta while (breakIndex < breaksSize && breaks.get(breakIndex) < i) { 1744ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta breakIndex++; 1754ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta } 1764ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta Primitive p; 1774ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta if (widths[i] != 0) { 1784ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta if (breakIndex < breaksSize && breaks.get(breakIndex) == i) { 1794ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta p = PrimitiveType.PENALTY.getNewPrimitive(i, 0, 0); 1804ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta } else { 1814ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta p = PrimitiveType.WORD_BREAK.getNewPrimitive(i, 0); 1824ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta } 1834ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta primitives.add(p); 1844ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta } 1854ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta 1864ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta primitives.add(PrimitiveType.BOX.getNewPrimitive(i, widths[i])); 1874ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta } 1884ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta } 1894ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta // final break at end of everything 1904ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta primitives.add( 1914ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta PrimitiveType.PENALTY.getNewPrimitive(length, 0, -PrimitiveType.PENALTY_INFINITY)); 1924ef9b507c2c1b73805533a86d935d637493d5903Deepanshu Gupta return primitives; 193ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Gupta } 194e8685f6153d281f24d1d2cbfa5942f40a5b461b1Diego Perez 195f3284cbd38989279a116e0082b7ab5b987c13388Diego Perez private static float measureText(long nativePaint, char []text, int index, int count, 196f3284cbd38989279a116e0082b7ab5b987c13388Diego Perez float[] widths, int bidiFlags) { 197f3284cbd38989279a116e0082b7ab5b987c13388Diego Perez Paint_Delegate paint = Paint_Delegate.getDelegate(nativePaint); 198f3284cbd38989279a116e0082b7ab5b987c13388Diego Perez RectF bounds = new BidiRenderer(null, paint, text) 199f3284cbd38989279a116e0082b7ab5b987c13388Diego Perez .renderText(index, index + count, bidiFlags, widths, 0, false); 200f3284cbd38989279a116e0082b7ab5b987c13388Diego Perez return bounds.right - bounds.left; 201f3284cbd38989279a116e0082b7ab5b987c13388Diego Perez } 202f3284cbd38989279a116e0082b7ab5b987c13388Diego Perez 2039fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta // TODO: Rename to LineBreakerRef and move everything other than LineBreaker to LineBreaker. 204e8685f6153d281f24d1d2cbfa5942f40a5b461b1Diego Perez /** 205f3284cbd38989279a116e0082b7ab5b987c13388Diego Perez * Java representation of the native Builder class. 206e8685f6153d281f24d1d2cbfa5942f40a5b461b1Diego Perez */ 2079fe7fca9bcdceade9c654c6a8dcf0c48be16d78dDeepanshu Gupta private static class Builder { 208f3284cbd38989279a116e0082b7ab5b987c13388Diego Perez char[] mText; 209f3284cbd38989279a116e0082b7ab5b987c13388Diego Perez float[] mWidths; 210345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard private LineBreaker mLineBreaker; 211345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard private int mBreakStrategy; 212345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard private LineWidth mLineWidth; 213345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard private TabStops mTabStopCalculator; 214345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard private ArrayList<Run> mRuns = new ArrayList<>(); 215345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard } 216345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard 217345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard private abstract static class Run { 218345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard int mStart; 219345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard int mEnd; 220345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard 221345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard Run(int start, int end) { 222345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard mStart = start; 223345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard mEnd = end; 224345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard } 225345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard 226345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard abstract void addTo(Builder builder); 227345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard } 228345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard 229345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard private static class StyleRun extends Run { 230345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard private long mNativePaint; 231345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard private boolean mIsRtl; 232345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard 233345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard private StyleRun(long nativePaint, int start, int end, boolean isRtl) { 234345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard super(start, end); 235345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard mNativePaint = nativePaint; 236345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard mIsRtl = isRtl; 237345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard } 238345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard 239345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard @Override 240345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard void addTo(Builder builder) { 241345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard int bidiFlags = mIsRtl ? Paint.BIDI_FORCE_RTL : Paint.BIDI_FORCE_LTR; 242345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard measureText(mNativePaint, builder.mText, mStart, mEnd - mStart, builder.mWidths, 243345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard bidiFlags); 244345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard } 245345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard } 246345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard 247345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard private static class ReplacementRun extends Run { 248345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard private final float mWidth; 249345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard 250345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard private ReplacementRun(int start, int end, float width) { 251345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard super(start, end); 252345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard mWidth = width; 253345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard } 254345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard 255345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard @Override 256345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard void addTo(Builder builder) { 257345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard builder.mWidths[mStart] = mWidth; 258345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard Arrays.fill(builder.mWidths, mStart + 1, mEnd, 0.0f); 259345d3cef8e40f59abeaba5402f51d3068b229bbcJerome Gaillard } 260e8685f6153d281f24d1d2cbfa5942f40a5b461b1Diego Perez } 261ae0b1a2ebde9984c2e75650b7dcfa7449d1a8833Deepanshu Gupta} 262