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