19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.text; 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas; 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Paint; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.style.CharacterStyle; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.style.MetricAffectingSpan; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.style.ReplacementSpan; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 2571b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * This class provides static methods for drawing and measuring styled text, 2671b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * like {@link android.text.Spanned} object with 2771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * {@link android.text.style.ReplacementSpan}. 2871b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Styled 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3371b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt /** 3471b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * Draws and/or measures a uniform run of text on a single line. No span of 3571b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * interest should start or end in the middle of this run (if not 3671b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * drawing, character spans that don't affect metrics can be ignored). 3771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * Neither should the run direction change in the middle of the run. 3871b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * 3971b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * <p>The x position is the leading edge of the text. In a right-to-left 4071b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * paragraph, this will be to the right of the text to be drawn. Paint 4171b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * should not have an Align value other than LEFT or positioning will get 4271b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * confused. 4371b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * 4471b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * <p>On return, workPaint will reflect the original paint plus any 4571b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * modifications made by character styles on the run. 4671b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * 4771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * <p>The returned width is signed and will be < 0 if the paragraph 4871b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * direction is right-to-left. 4971b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt */ 5071b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt private static float drawUniformRun(Canvas canvas, 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Spanned text, int start, int end, 5271b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt int dir, boolean runIsRtl, 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x, int top, int y, int bottom, 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Paint.FontMetricsInt fmi, 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextPaint paint, 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextPaint workPaint, 5771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt boolean needWidth) { 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5971b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt boolean haveWidth = false; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float ret = 0; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharacterStyle[] spans = text.getSpans(start, end, CharacterStyle.class); 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ReplacementSpan replacement = null; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6571b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt // XXX: This shouldn't be modifying paint, only workPaint. 6671b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt // However, the members belonging to TextPaint should have default 6771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt // values anyway. Better to ensure this in the Layout constructor. 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paint.bgColor = 0; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paint.baselineShift = 0; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project workPaint.set(paint); 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (spans.length > 0) { 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < spans.length; i++) { 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharacterStyle span = spans[i]; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (span instanceof ReplacementSpan) { 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replacement = (ReplacementSpan)span; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else { 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project span.updateDrawState(workPaint); 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (replacement == null) { 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharSequence tmp; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmpstart, tmpend; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8971b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt if (runIsRtl) { 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp = TextUtils.getReverse(text, start, end); 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmpstart = 0; 9271b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt // XXX: assumes getReverse doesn't change the length of the text 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmpend = end - start; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmp = text; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmpstart = start; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tmpend = end; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fmi != null) { 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project workPaint.getFontMetricsInt(fmi); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (canvas != null) { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (workPaint.bgColor != 0) { 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int c = workPaint.getColor(); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Paint.Style s = workPaint.getStyle(); 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project workPaint.setColor(workPaint.bgColor); 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project workPaint.setStyle(Paint.Style.FILL); 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11171b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt if (!haveWidth) { 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = workPaint.measureText(tmp, tmpstart, tmpend); 11371b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt haveWidth = true; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dir == Layout.DIR_RIGHT_TO_LEFT) 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawRect(x - ret, top, x, bottom, workPaint); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawRect(x, top, x + ret, bottom, workPaint); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project workPaint.setStyle(s); 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project workPaint.setColor(c); 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dir == Layout.DIR_RIGHT_TO_LEFT) { 12671b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt if (!haveWidth) { 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = workPaint.measureText(tmp, tmpstart, tmpend); 12871b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt haveWidth = true; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawText(tmp, tmpstart, tmpend, 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x - ret, y + workPaint.baselineShift, workPaint); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 13471b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt if (needWidth) { 13571b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt if (!haveWidth) { 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = workPaint.measureText(tmp, tmpstart, tmpend); 13771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt haveWidth = true; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawText(tmp, tmpstart, tmpend, 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x, y + workPaint.baselineShift, workPaint); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14571b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt if (needWidth && !haveWidth) { 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = workPaint.measureText(tmp, tmpstart, tmpend); 14771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt haveWidth = true; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = replacement.getSize(workPaint, text, start, end, fmi); 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (canvas != null) { 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dir == Layout.DIR_RIGHT_TO_LEFT) 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replacement.draw(canvas, text, start, end, 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x - ret, top, y, bottom, workPaint); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replacement.draw(canvas, text, start, end, 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x, top, y, bottom, workPaint); 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (dir == Layout.DIR_RIGHT_TO_LEFT) 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -ret; 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ret; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 17071b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * Returns the advance widths for a uniform left-to-right run of text with 17171b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * no style changes in the middle of the run. If any style is replacement 17271b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * text, the first character will get the width of the replacement and the 17371b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * remaining characters will get a width of 0. 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 17571b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * @param paint the paint, will not be modified 17671b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * @param workPaint a paint to modify; on return will reflect the original 17771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * paint plus the effect of all spans on the run 17871b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * @param text the text 17971b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * @param start the start of the run 18071b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * @param end the limit of the run 18171b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * @param widths array to receive the advance widths of the characters. Must 18271b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * be at least a large as (end - start). 18371b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * @param fmi FontMetrics information; can be null 18471b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * @return the actual number of widths returned 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static int getTextWidths(TextPaint paint, 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextPaint workPaint, 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Spanned text, int start, int end, 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] widths, Paint.FontMetricsInt fmi) { 19071b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt MetricAffectingSpan[] spans = 19171b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt text.getSpans(start, end, MetricAffectingSpan.class); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ReplacementSpan replacement = null; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project workPaint.set(paint); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < spans.length; i++) { 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MetricAffectingSpan span = spans[i]; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (span instanceof ReplacementSpan) { 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project replacement = (ReplacementSpan)span; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else { 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project span.updateMeasureState(workPaint); 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (replacement == null) { 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project workPaint.getFontMetricsInt(fmi); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project workPaint.getTextWidths(text, start, end, widths); 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int wid = replacement.getSize(workPaint, text, start, end, fmi); 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (end > start) { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project widths[0] = wid; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = start + 1; i < end; i++) 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project widths[i - start] = 0; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return end - start; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22171b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt /** 22271b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * Renders and/or measures a directional run of text on a single line. 22371b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * Unlike {@link #drawUniformRun}, this can render runs that cross style 22471b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * boundaries. Returns the signed advance width, if requested. 22571b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * 22671b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * <p>The x position is the leading edge of the text. In a right-to-left 22771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * paragraph, this will be to the right of the text to be drawn. Paint 22871b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * should not have an Align value other than LEFT or positioning will get 22971b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * confused. 23071b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * 23171b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * <p>This optimizes for unstyled text and so workPaint might not be 23271b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * modified by this call. 23371b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * 23471b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * <p>The returned advance width will be < 0 if the paragraph 23571b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * direction is right-to-left. 23671b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt */ 23771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt private static float drawDirectionalRun(Canvas canvas, 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharSequence text, int start, int end, 23971b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt int dir, boolean runIsRtl, 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x, int top, int y, int bottom, 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Paint.FontMetricsInt fmi, 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextPaint paint, 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextPaint workPaint, 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean needWidth) { 24571b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt 24671b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt // XXX: It looks like all calls to this API match dir and runIsRtl, so 24771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt // having both parameters is redundant and confusing. 24871b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt 24971b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt // fast path for unstyled text 25071b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt if (!(text instanceof Spanned)) { 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float ret = 0; 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25371b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt if (runIsRtl) { 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharSequence tmp = TextUtils.getReverse(text, start, end); 25571b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt // XXX: this assumes getReverse doesn't tweak the length of 25671b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt // the text 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int tmpend = end - start; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (canvas != null || needWidth) 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = paint.measureText(tmp, 0, tmpend); 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (canvas != null) 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawText(tmp, 0, tmpend, 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x - ret, y, paint); 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (needWidth) 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = paint.measureText(text, start, end); 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (canvas != null) 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project canvas.drawText(text, start, end, x, y, paint); 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fmi != null) { 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paint.getFontMetricsInt(fmi); 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt return ret * dir; // Layout.DIR_RIGHT_TO_LEFT == -1 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float ox = x; 28171b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt int minAscent = 0, maxDescent = 0, minTop = 0, maxBottom = 0; 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Spanned sp = (Spanned) text; 28471b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt Class<?> division; 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (canvas == null) 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project division = MetricAffectingSpan.class; 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project division = CharacterStyle.class; 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int next; 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = start; i < end; i = next) { 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project next = sp.nextSpanTransition(i, end, division); 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29571b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt // XXX: if dir and runIsRtl were not the same, this would draw 29671b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt // spans in the wrong order, but no one appears to call it this 29771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt // way. 29871b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt x += drawUniformRun(canvas, sp, i, next, dir, runIsRtl, 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x, top, y, bottom, fmi, paint, workPaint, 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project needWidth || next != end); 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fmi != null) { 30371b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt if (fmi.ascent < minAscent) 30471b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt minAscent = fmi.ascent; 30571b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt if (fmi.descent > maxDescent) 30671b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt maxDescent = fmi.descent; 30771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt 30871b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt if (fmi.top < minTop) 30971b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt minTop = fmi.top; 31071b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt if (fmi.bottom > maxBottom) 31171b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt maxBottom = fmi.bottom; 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fmi != null) { 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (start == end) { 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project paint.getFontMetricsInt(fmi); 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 31971b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt fmi.ascent = minAscent; 32071b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt fmi.descent = maxDescent; 32171b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt fmi.top = minTop; 32271b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt fmi.bottom = maxBottom; 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return x - ox; 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 32971b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt /** 33071b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * Draws a unidirectional run of text on a single line, and optionally 33171b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * returns the signed advance. Unlike drawDirectionalRun, the paragraph 33271b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * direction and run direction can be different. 33371b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt */ 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* package */ static float drawText(Canvas canvas, 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharSequence text, int start, int end, 33671b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt int dir, boolean runIsRtl, 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x, int top, int y, int bottom, 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextPaint paint, 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextPaint workPaint, 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean needWidth) { 34171b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt // XXX this logic is (dir == DIR_LEFT_TO_RIGHT) == runIsRtl 34271b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt if ((dir == Layout.DIR_RIGHT_TO_LEFT && !runIsRtl) || 34371b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt (runIsRtl && dir == Layout.DIR_LEFT_TO_RIGHT)) { 34471b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt // TODO: this needs the real direction 34571b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt float ch = drawDirectionalRun(null, text, start, end, 34671b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt Layout.DIR_LEFT_TO_RIGHT, false, 0, 0, 0, 0, null, paint, 34771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt workPaint, true); 34871b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt 34971b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt ch *= dir; // DIR_RIGHT_TO_LEFT == -1 35071b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt drawDirectionalRun(canvas, text, start, end, -dir, 35171b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt runIsRtl, x + ch, top, y, bottom, null, paint, 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project workPaint, true); 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ch; 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt return drawDirectionalRun(canvas, text, start, end, dir, runIsRtl, 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x, top, y, bottom, null, paint, workPaint, 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project needWidth); 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 36371b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * Draws a run of text on a single line, with its 36471b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * origin at (x,y), in the specified Paint. The origin is interpreted based 36571b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * on the Align setting in the Paint. 36671b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * 36771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * This method considers style information in the text (e.g. even when text 36871b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * is an instance of {@link android.text.Spanned}, this method correctly 36971b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * draws the text). See also 37071b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * {@link android.graphics.Canvas#drawText(CharSequence, int, int, float, 37171b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * float, Paint)} and 37271b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * {@link android.graphics.Canvas#drawRect(float, float, float, float, 37371b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * Paint)}. 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 37571b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * @param canvas The target canvas 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param text The text to be drawn 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param start The index of the first character in text to draw 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param end (end - 1) is the index of the last character in text to draw 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param direction The direction of the text. This must be 38071b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * {@link android.text.Layout#DIR_LEFT_TO_RIGHT} or 38171b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * {@link android.text.Layout#DIR_RIGHT_TO_LEFT}. 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x The x-coordinate of origin for where to draw the text 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param top The top side of the rectangle to be drawn 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y The y-coordinate of origin for where to draw the text 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param bottom The bottom side of the rectangle to be drawn 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param paint The main {@link TextPaint} object. 38771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * @param workPaint The {@link TextPaint} object used for temporal 38871b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * workspace. 38971b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * @param needWidth If true, this method returns the width of drawn text 39071b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * @return Width of the drawn text if needWidth is true 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static float drawText(Canvas canvas, 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharSequence text, int start, int end, 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int direction, 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float x, int top, int y, int bottom, 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextPaint paint, 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextPaint workPaint, 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean needWidth) { 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // For safety. 40071b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt direction = direction >= 0 ? Layout.DIR_LEFT_TO_RIGHT 40171b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt : Layout.DIR_RIGHT_TO_LEFT; 40271b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt 40371b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt // Hide runIsRtl parameter since it is meaningless for external 40471b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt // developers. 40571b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt // XXX: the runIsRtl probably ought to be the same as direction, then 40671b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt // this could draw rtl text. 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return drawText(canvas, text, start, end, direction, false, 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x, top, y, bottom, paint, workPaint, needWidth); 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 41271b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * Returns the width of a run of left-to-right text on a single line, 41371b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * considering style information in the text (e.g. even when text is an 41471b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * instance of {@link android.text.Spanned}, this method correctly measures 41571b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * the width of the text). 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 41771b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * @param paint the main {@link TextPaint} object; will not be modified 41871b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * @param workPaint the {@link TextPaint} object available for modification; 41971b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * will not necessarily be used 42071b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * @param text the text to measure 42171b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * @param start the index of the first character to start measuring 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param end 1 beyond the index of the last character to measure 42371b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * @param fmi FontMetrics information; can be null 42471b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt * @return The width of the text 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static float measureText(TextPaint paint, 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TextPaint workPaint, 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharSequence text, int start, int end, 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Paint.FontMetricsInt fmi) { 43071b8dd71e49016e057c46a257f79162d186a3c3aDoug Felt return drawDirectionalRun(null, text, start, end, 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Layout.DIR_LEFT_TO_RIGHT, false, 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0, 0, 0, 0, fmi, paint, workPaint, true); 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 435