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 Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.text;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Canvas;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Paint;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Path;
2286fcef87b802ee58147127dc5cca940239a30404Eric Fischerimport android.text.style.ParagraphStyle;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A BoringLayout is a very simple Layout implementation for text that
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * fits on a single line and is all left-to-right characters.
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You will probably never want to make one of these yourself;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if you do, be sure to call {@link #isBoring} first to make sure
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the text meets the criteria.
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>This class is used by widgets to control text layout. You should not need
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to use this class directly unless you are implementing your own widget
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * or custom display object, in which case
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you are encouraged to use a Layout instead of calling
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.graphics.Canvas#drawText(java.lang.CharSequence, int, int, float, float, android.graphics.Paint)
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *  Canvas.drawText()} directly.</p>
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class BoringLayout extends Layout implements TextUtils.EllipsizeCallback {
3808fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir
3908fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir    /**
4008fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * Utility function to construct a BoringLayout instance.
4108fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *
4208fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param source the text to render
4308fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param paint the default paint for the layout
4408fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param outerWidth the wrapping width for the text
4508fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param align whether to left, right, or center the text
4608fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param spacingMult this value is no longer used by BoringLayout
4708fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param spacingAdd this value is no longer used by BoringLayout
4808fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param metrics {@code #Metrics} instance that contains information about FontMetrics and
4908fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                line width
5008fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param includePad set whether to include extra space beyond font ascent and descent which is
5108fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                   needed to avoid clipping in some scripts
5208fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     */
5308fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir    public static BoringLayout make(CharSequence source, TextPaint paint, int outerWidth,
5408fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir            Alignment align, float spacingMult, float spacingAdd, BoringLayout.Metrics metrics,
5508fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir            boolean includePad) {
5608fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir        return new BoringLayout(source, paint, outerWidth, align, spacingMult, spacingAdd, metrics,
5708fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir                includePad);
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6008fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir    /**
6108fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * Utility function to construct a BoringLayout instance.
6208fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *
6308fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param source the text to render
6408fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param paint the default paint for the layout
6508fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param outerWidth the wrapping width for the text
6608fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param align whether to left, right, or center the text
6708fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param spacingmult this value is no longer used by BoringLayout
6808fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param spacingadd this value is no longer used by BoringLayout
6908fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param metrics {@code #Metrics} instance that contains information about FontMetrics and
7008fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                line width
7108fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param includePad set whether to include extra space beyond font ascent and descent which is
7208fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                   needed to avoid clipping in some scripts
7308fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param ellipsize whether to ellipsize the text if width of the text is longer than the
7408fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                  requested width
7508fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param ellipsizedWidth the width to which this Layout is ellipsizing. If {@code ellipsize} is
7608fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                        {@code null}, or is {@link TextUtils.TruncateAt#MARQUEE} this value is
7708fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                        not used, {@code outerWidth} is used instead
7808fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     */
7908fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir    public static BoringLayout make(CharSequence source, TextPaint paint, int outerWidth,
8008fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir            Alignment align, float spacingmult, float spacingadd, BoringLayout.Metrics metrics,
8108fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir            boolean includePad, TextUtils.TruncateAt ellipsize, int ellipsizedWidth) {
8208fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir        return new BoringLayout(source, paint, outerWidth, align, spacingmult, spacingadd, metrics,
8308fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir                includePad, ellipsize, ellipsizedWidth);
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a BoringLayout for the specified text, potentially reusing
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this one if it is already suitable.  The caller must make sure that
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * no one is still using this Layout.
9008fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *
9108fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param source the text to render
9208fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param paint the default paint for the layout
9308fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param outerwidth the wrapping width for the text
9408fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param align whether to left, right, or center the text
9508fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param spacingMult this value is no longer used by BoringLayout
9608fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param spacingAdd this value is no longer used by BoringLayout
9708fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param metrics {@code #Metrics} instance that contains information about FontMetrics and
9808fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                line width
9908fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param includePad set whether to include extra space beyond font ascent and descent which is
10008fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                   needed to avoid clipping in some scripts
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10208fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir    public BoringLayout replaceOrMake(CharSequence source, TextPaint paint, int outerwidth,
10308fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir            Alignment align, float spacingMult, float spacingAdd, BoringLayout.Metrics metrics,
10408fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir            boolean includePad) {
10508fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir        replaceWith(source, paint, outerwidth, align, spacingMult, spacingAdd);
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mEllipsizedWidth = outerwidth;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mEllipsizedStart = 0;
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mEllipsizedCount = 0;
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11108fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir        init(source, paint, align, metrics, includePad, true);
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns a BoringLayout for the specified text, potentially reusing
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this one if it is already suitable.  The caller must make sure that
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * no one is still using this Layout.
11908fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *
12008fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param source the text to render
12108fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param paint the default paint for the layout
12208fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param outerWidth the wrapping width for the text
12308fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param align whether to left, right, or center the text
12408fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param spacingMult this value is no longer used by BoringLayout
12508fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param spacingAdd this value is no longer used by BoringLayout
12608fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param metrics {@code #Metrics} instance that contains information about FontMetrics and
12708fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                line width
12808fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param includePad set whether to include extra space beyond font ascent and descent which is
12908fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                   needed to avoid clipping in some scripts
13008fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param ellipsize whether to ellipsize the text if width of the text is longer than the
13108fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                  requested width
13208fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param ellipsizedWidth the width to which this Layout is ellipsizing. If {@code ellipsize} is
13308fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                        {@code null}, or is {@link TextUtils.TruncateAt#MARQUEE} this value is
13408fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                        not used, {@code outerwidth} is used instead
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13608fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir    public BoringLayout replaceOrMake(CharSequence source, TextPaint paint, int outerWidth,
13708fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir            Alignment align, float spacingMult, float spacingAdd, BoringLayout.Metrics metrics,
13808fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir            boolean includePad, TextUtils.TruncateAt ellipsize, int ellipsizedWidth) {
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean trust;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ellipsize == null || ellipsize == TextUtils.TruncateAt.MARQUEE) {
14208fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir            replaceWith(source, paint, outerWidth, align, spacingMult, spacingAdd);
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14408fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir            mEllipsizedWidth = outerWidth;
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mEllipsizedStart = 0;
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mEllipsizedCount = 0;
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            trust = true;
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
14908fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir            replaceWith(TextUtils.ellipsize(source, paint, ellipsizedWidth, ellipsize, true, this),
15008fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir                    paint, outerWidth, align, spacingMult, spacingAdd);
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mEllipsizedWidth = ellipsizedWidth;
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            trust = false;
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15608fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir        init(getText(), paint, align, metrics, includePad, trust);
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16008fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir    /**
16108fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param source the text to render
16208fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param paint the default paint for the layout
16308fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param outerwidth the wrapping width for the text
16408fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param align whether to left, right, or center the text
16508fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param spacingMult this value is no longer used by BoringLayout
16608fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param spacingAdd this value is no longer used by BoringLayout
16708fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param metrics {@code #Metrics} instance that contains information about FontMetrics and
16808fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                line width
16908fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param includePad set whether to include extra space beyond font ascent and descent which is
17008fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                   needed to avoid clipping in some scripts
17108fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     */
17208fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir    public BoringLayout(CharSequence source, TextPaint paint, int outerwidth, Alignment align,
17308fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir            float spacingMult, float spacingAdd, BoringLayout.Metrics metrics, boolean includePad) {
17408fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir        super(source, paint, outerwidth, align, spacingMult, spacingAdd);
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mEllipsizedWidth = outerwidth;
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mEllipsizedStart = 0;
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mEllipsizedCount = 0;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18008fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir        init(source, paint, align, metrics, includePad, true);
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18308fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir    /**
18408fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *
18508fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param source the text to render
18608fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param paint the default paint for the layout
18708fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param outerWidth the wrapping width for the text
18808fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param align whether to left, right, or center the text
18908fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param spacingMult this value is no longer used by BoringLayout
19008fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param spacingAdd this value is no longer used by BoringLayout
19108fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param metrics {@code #Metrics} instance that contains information about FontMetrics and
19208fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                line width
19308fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param includePad set whether to include extra space beyond font ascent and descent which is
19408fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                   needed to avoid clipping in some scripts
19508fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param ellipsize whether to ellipsize the text if width of the text is longer than the
19608fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                  requested {@code outerwidth}
19708fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     * @param ellipsizedWidth the width to which this Layout is ellipsizing. If {@code ellipsize} is
19808fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                        {@code null}, or is {@link TextUtils.TruncateAt#MARQUEE} this value is
19908fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     *                        not used, {@code outerwidth} is used instead
20008fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir     */
20108fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir    public BoringLayout(CharSequence source, TextPaint paint, int outerWidth, Alignment align,
20208fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir            float spacingMult, float spacingAdd, BoringLayout.Metrics metrics, boolean includePad,
20308fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir            TextUtils.TruncateAt ellipsize, int ellipsizedWidth) {
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /*
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * It is silly to have to call super() and then replaceWith(),
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * but we can't use "this" for the callback until the call to
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * super() finishes.
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
20908fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir        super(source, paint, outerWidth, align, spacingMult, spacingAdd);
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean trust;
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ellipsize == null || ellipsize == TextUtils.TruncateAt.MARQUEE) {
21408fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir            mEllipsizedWidth = outerWidth;
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mEllipsizedStart = 0;
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mEllipsizedCount = 0;
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            trust = true;
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
21908fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir            replaceWith(TextUtils.ellipsize(source, paint, ellipsizedWidth, ellipsize, true, this),
22008fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir                        paint, outerWidth, align, spacingMult, spacingAdd);
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mEllipsizedWidth = ellipsizedWidth;
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            trust = false;
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22608fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir        init(getText(), paint, align, metrics, includePad, trust);
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22908fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir    /* package */ void init(CharSequence source, TextPaint paint, Alignment align,
23008fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir            BoringLayout.Metrics metrics, boolean includePad, boolean trustWidth) {
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int spacing;
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (source instanceof String && align == Layout.Alignment.ALIGN_NORMAL) {
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDirect = source.toString();
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mDirect = null;
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mPaint = paint;
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
24108fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir        if (includePad) {
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            spacing = metrics.bottom - metrics.top;
24307e6c237d3f19b98bbec237892a785fd3895368aRaph Levien            mDesc = metrics.bottom;
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            spacing = metrics.descent - metrics.ascent;
24607e6c237d3f19b98bbec237892a785fd3895368aRaph Levien            mDesc = metrics.descent;
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mBottom = spacing;
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (trustWidth) {
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMax = metrics.width;
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /*
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             * If we have ellipsized, we have to actually calculate the
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             * width because the width that was passed in was for the
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             * full text, not the ellipsized form.
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             */
259e8e45f2c05cb3b6d23f30c8f96d8e0b3699cea7aDoug Felt            TextLine line = TextLine.obtain();
260e8e45f2c05cb3b6d23f30c8f96d8e0b3699cea7aDoug Felt            line.set(paint, source, 0, source.length(), Layout.DIR_LEFT_TO_RIGHT,
261e8e45f2c05cb3b6d23f30c8f96d8e0b3699cea7aDoug Felt                    Layout.DIRS_ALL_LEFT_TO_RIGHT, false, null);
26233253a4baa6279f81a73425b49dfb6abe5f5416eNeil Fuller            mMax = (int) Math.ceil(line.metrics(null));
263e8e45f2c05cb3b6d23f30c8f96d8e0b3699cea7aDoug Felt            TextLine.recycle(line);
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
26608fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir        if (includePad) {
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mTopPadding = metrics.top - metrics.ascent;
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mBottomPadding = metrics.bottom - metrics.descent;
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns null if not boring; the width, ascent, and descent if boring.
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
27508fac62bc9b73ab5e7ff9e96d0f3f6ec27928354Siyamed Sinir    public static Metrics isBoring(CharSequence text, TextPaint paint) {
276cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        return isBoring(text, paint, TextDirectionHeuristics.FIRSTSTRONG_LTR, null);
277cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    }
278cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
279cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    /**
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns null if not boring; the width, ascent, and descent in the
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * provided Metrics object (or a new one if the provided one was null)
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if boring.
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
284f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    public static Metrics isBoring(CharSequence text, TextPaint paint, Metrics metrics) {
285cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        return isBoring(text, paint, TextDirectionHeuristics.FIRSTSTRONG_LTR, metrics);
286cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    }
287cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
288cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    /**
2895536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader     * Returns true if the text contains any RTL characters, bidi format characters, or surrogate
2905536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader     * code units.
2915536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader     */
2925536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader    private static boolean hasAnyInterestingChars(CharSequence text, int textLength) {
2935536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader        final int MAX_BUF_LEN = 500;
2945536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader        final char[] buffer = TextUtils.obtain(MAX_BUF_LEN);
2955536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader        try {
2965536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader            for (int start = 0; start < textLength; start += MAX_BUF_LEN) {
2975536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader                final int end = Math.min(start + MAX_BUF_LEN, textLength);
2985536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader
2995536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader                // No need to worry about getting half codepoints, since we consider surrogate code
3005536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader                // units "interesting" as soon we see one.
3015536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader                TextUtils.getChars(text, start, end, buffer, 0);
3025536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader
3035536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader                final int len = end - start;
3045536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader                for (int i = 0; i < len; i++) {
3055536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader                    final char c = buffer[i];
3068823c85f0a98988a21bddedf1e1c3fb725258ba1Roozbeh Pournader                    if (c == '\n' || c == '\t' || TextUtils.couldAffectRtl(c)) {
3075536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader                        return true;
3085536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader                    }
3095536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader                }
3105536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader            }
3115536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader            return false;
3125536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader        } finally {
3135536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader            TextUtils.recycle(buffer);
3145536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader        }
3155536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader    }
3165536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader
3175536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader    /**
318cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * Returns null if not boring; the width, ascent, and descent in the
319cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * provided Metrics object (or a new one if the provided one was null)
320cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * if boring.
321cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * @hide
322cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     */
323cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    public static Metrics isBoring(CharSequence text, TextPaint paint,
324cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            TextDirectionHeuristic textDir, Metrics metrics) {
3253cf8208a62eb493cbd83d7b9d1f155eb174fcee0Roozbeh Pournader        final int textLength = text.length();
3265536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader        if (hasAnyInterestingChars(text, textLength)) {
3275536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader           return null;  // There are some interesting characters. Not boring.
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3295536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader        if (textDir != null && textDir.isRtl(text, 0, textLength)) {
3305536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader           return null;  // The heuristic considers the whole text RTL. Not boring.
3315536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader        }
3325536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader        if (text instanceof Spanned) {
33386fcef87b802ee58147127dc5cca940239a30404Eric Fischer            Spanned sp = (Spanned) text;
3343cf8208a62eb493cbd83d7b9d1f155eb174fcee0Roozbeh Pournader            Object[] styles = sp.getSpans(0, textLength, ParagraphStyle.class);
33586fcef87b802ee58147127dc5cca940239a30404Eric Fischer            if (styles.length > 0) {
3365536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader                return null;  // There are some PargraphStyle spans. Not boring.
33786fcef87b802ee58147127dc5cca940239a30404Eric Fischer            }
33886fcef87b802ee58147127dc5cca940239a30404Eric Fischer        }
33986fcef87b802ee58147127dc5cca940239a30404Eric Fischer
3405536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader        Metrics fm = metrics;
3415536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader        if (fm == null) {
3425536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader            fm = new Metrics();
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
3445536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader            fm.reset();
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3465536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader
3474e90fa262d57c1c1ee72166e2ddfce391696ca24Seigo Nonaka        TextLine line = TextLine.obtain();
3484e90fa262d57c1c1ee72166e2ddfce391696ca24Seigo Nonaka        line.set(paint, text, 0, textLength, Layout.DIR_LEFT_TO_RIGHT,
3494e90fa262d57c1c1ee72166e2ddfce391696ca24Seigo Nonaka                Layout.DIRS_ALL_LEFT_TO_RIGHT, false, null);
35053145635e4fd724208e01db1ef6187a2212d6090Seigo Nonaka        fm.width = (int) Math.ceil(line.metrics(fm));
3514e90fa262d57c1c1ee72166e2ddfce391696ca24Seigo Nonaka        TextLine.recycle(line);
3525536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader
3535536c4fdee8684ebbb2d17af72ce94757a5e1a80Roozbeh Pournader        return fm;
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
356f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    @Override
357f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    public int getHeight() {
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mBottom;
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
361f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    @Override
362f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    public int getLineCount() {
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 1;
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
366f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    @Override
367f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    public int getLineTop(int line) {
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (line == 0)
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mBottom;
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
374f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    @Override
375f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    public int getLineDescent(int line) {
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mDesc;
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    @Override
380f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    public int getLineStart(int line) {
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (line == 0)
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return 0;
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return getText().length();
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
387f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    @Override
388f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    public int getParagraphDirection(int line) {
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DIR_LEFT_TO_RIGHT;
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
392f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    @Override
393f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    public boolean getLineContainsTab(int line) {
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
397f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    @Override
398f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    public float getLineMax(int line) {
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mMax;
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
402f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    @Override
40344e8d60f53ebeb9734395b041f20cd67dbcf287fJohn Reck    public float getLineWidth(int line) {
40444e8d60f53ebeb9734395b041f20cd67dbcf287fJohn Reck        return (line == 0 ? mMax : 0);
40544e8d60f53ebeb9734395b041f20cd67dbcf287fJohn Reck    }
40644e8d60f53ebeb9734395b041f20cd67dbcf287fJohn Reck
40744e8d60f53ebeb9734395b041f20cd67dbcf287fJohn Reck    @Override
408f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    public final Directions getLineDirections(int line) {
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return Layout.DIRS_ALL_LEFT_TO_RIGHT;
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
412f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    @Override
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getTopPadding() {
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mTopPadding;
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
417f483e514d4ed3b93cc5ba22beb9c85efcda75535Gilles Debunne    @Override
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getBottomPadding() {
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mBottomPadding;
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getEllipsisCount(int line) {
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mEllipsizedCount;
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getEllipsisStart(int line) {
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mEllipsizedStart;
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getEllipsizedWidth() {
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mEllipsizedWidth;
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // Override draw so it will be faster.
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void draw(Canvas c, Path highlight, Paint highlightpaint,
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     int cursorOffset) {
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mDirect != null && highlight == null) {
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            c.drawText(mDirect, 0, mBottom - mDesc, mPaint);
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super.draw(c, highlight, highlightpaint, cursorOffset);
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Callback for the ellipsizer to report what region it ellipsized.
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void ellipsized(int start, int end) {
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mEllipsizedStart = start;
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mEllipsizedCount = end - start;
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private String mDirect;
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private Paint mPaint;
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* package */ int mBottom, mDesc;   // for Direct
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mTopPadding, mBottomPadding;
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private float mMax;
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int mEllipsizedWidth, mEllipsizedStart, mEllipsizedCount;
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static class Metrics extends Paint.FontMetricsInt {
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int width;
466e8e45f2c05cb3b6d23f30c8f96d8e0b3699cea7aDoug Felt
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override public String toString() {
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return super.toString() + " width=" + width;
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
47070f660f2d6220b10ddb5e32d665c38e30f0ab35cSiyamed Sinir
47170f660f2d6220b10ddb5e32d665c38e30f0ab35cSiyamed Sinir        private void reset() {
47270f660f2d6220b10ddb5e32d665c38e30f0ab35cSiyamed Sinir            top = 0;
47370f660f2d6220b10ddb5e32d665c38e30f0ab35cSiyamed Sinir            bottom = 0;
47470f660f2d6220b10ddb5e32d665c38e30f0ab35cSiyamed Sinir            ascent = 0;
47570f660f2d6220b10ddb5e32d665c38e30f0ab35cSiyamed Sinir            descent = 0;
47670f660f2d6220b10ddb5e32d665c38e30f0ab35cSiyamed Sinir            width = 0;
47770f660f2d6220b10ddb5e32d665c38e30f0ab35cSiyamed Sinir            leading = 0;
47870f660f2d6220b10ddb5e32d665c38e30f0ab35cSiyamed Sinir        }
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
481