File: IconMarginSpan.java

package info (click to toggle)
android-platform-frameworks-base 1%3A10.0.0%2Br36-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 321,788 kB
  • sloc: java: 962,234; cpp: 274,314; xml: 242,770; python: 5,060; sh: 1,432; ansic: 494; makefile: 47; sed: 19
file content (113 lines) | stat: -rw-r--r-- 3,684 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.text.style;

import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Px;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.text.Layout;
import android.text.Spanned;

/**
 * Paragraph affecting span, that draws a bitmap at the beginning of a text. The span also allows
 * setting a padding between the bitmap and the text. The default value of the padding is 0px. The
 * span should be attached from the first character of the text.
 * <p>
 * For example, an <code>IconMarginSpan</code> with a bitmap and a padding of 30px can be set
 * like this:
 * <pre>
 * SpannableString string = new SpannableString("Text with icon and padding");
 * string.setSpan(new IconMarginSpan(bitmap, 30), 0, string.length(),
 * Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
 * </pre>
 * <img src="{@docRoot}reference/android/images/text/style/iconmarginspan.png" />
 * <figcaption>Text with <code>IconMarginSpan</code></figcaption>
 * <p>
 *
 * @see DrawableMarginSpan for working with a {@link android.graphics.drawable.Drawable} instead of
 * a {@link Bitmap}.
 */
public class IconMarginSpan implements LeadingMarginSpan, LineHeightSpan {

    @NonNull
    private final Bitmap mBitmap;
    @Px
    private final int mPad;

    /**
     * Creates an {@link IconMarginSpan} from a {@link Bitmap}.
     *
     * @param bitmap bitmap to be rendered at the beginning of the text
     */
    public IconMarginSpan(@NonNull Bitmap bitmap) {
        this(bitmap, 0);
    }

    /**
     * Creates an {@link IconMarginSpan} from a {@link Bitmap}.
     *
     * @param bitmap bitmap to be rendered at the beginning of the text
     * @param pad    padding width, in pixels, between the bitmap and the text
     */
    public IconMarginSpan(@NonNull Bitmap bitmap, @IntRange(from = 0) int pad) {
        mBitmap = bitmap;
        mPad = pad;
    }

    @Override
    public int getLeadingMargin(boolean first) {
        return mBitmap.getWidth() + mPad;
    }

    @Override
    public void drawLeadingMargin(Canvas c, Paint p, int x, int dir,
            int top, int baseline, int bottom,
            CharSequence text, int start, int end,
            boolean first, Layout layout) {
        int st = ((Spanned) text).getSpanStart(this);
        int itop = layout.getLineTop(layout.getLineForOffset(st));

        if (dir < 0) {
            x -= mBitmap.getWidth();
        }

        c.drawBitmap(mBitmap, x, itop, p);
    }

    @Override
    public void chooseHeight(CharSequence text, int start, int end,
            int istartv, int v,
            Paint.FontMetricsInt fm) {
        if (end == ((Spanned) text).getSpanEnd(this)) {
            int ht = mBitmap.getHeight();

            int need = ht - (v + fm.descent - fm.ascent - istartv);
            if (need > 0) {
                fm.descent += need;
            }

            need = ht - (v + fm.bottom - fm.top - istartv);
            if (need > 0) {
                fm.bottom += need;
            }
        }
    }

}