• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.text.style;
18 
19 import android.annotation.IntRange;
20 import android.annotation.NonNull;
21 import android.annotation.Px;
22 import android.graphics.Bitmap;
23 import android.graphics.Canvas;
24 import android.graphics.Paint;
25 import android.text.Layout;
26 import android.text.Spanned;
27 
28 /**
29  * Paragraph affecting span, that draws a bitmap at the beginning of a text. The span also allows
30  * setting a padding between the bitmap and the text. The default value of the padding is 0px. The
31  * span should be attached from the first character of the text.
32  * <p>
33  * For example, an <code>IconMarginSpan</code> with a bitmap and a padding of 30px can be set
34  * like this:
35  * <pre>
36  * SpannableString string = new SpannableString("Text with icon and padding");
37  * string.setSpan(new IconMarginSpan(bitmap, 30), 0, string.length(),
38  * Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
39  * </pre>
40  * <img src="{@docRoot}reference/android/images/text/style/iconmarginspan.png" />
41  * <figcaption>Text with <code>IconMarginSpan</code></figcaption>
42  * <p>
43  *
44  * @see DrawableMarginSpan for working with a {@link android.graphics.drawable.Drawable} instead of
45  * a {@link Bitmap}.
46  */
47 @android.ravenwood.annotation.RavenwoodKeepWholeClass
48 public class IconMarginSpan implements LeadingMarginSpan, LineHeightSpan {
49 
50     @NonNull
51     private final Bitmap mBitmap;
52     @Px
53     private final int mPad;
54 
55     /**
56      * Creates an {@link IconMarginSpan} from a {@link Bitmap}.
57      *
58      * @param bitmap bitmap to be rendered at the beginning of the text
59      */
IconMarginSpan(@onNull Bitmap bitmap)60     public IconMarginSpan(@NonNull Bitmap bitmap) {
61         this(bitmap, 0);
62     }
63 
64     /**
65      * Creates an {@link IconMarginSpan} from a {@link Bitmap}.
66      *
67      * @param bitmap bitmap to be rendered at the beginning of the text
68      * @param pad    padding width, in pixels, between the bitmap and the text
69      */
IconMarginSpan(@onNull Bitmap bitmap, @IntRange(from = 0) int pad)70     public IconMarginSpan(@NonNull Bitmap bitmap, @IntRange(from = 0) int pad) {
71         mBitmap = bitmap;
72         mPad = pad;
73     }
74 
75     @Override
getLeadingMargin(boolean first)76     public int getLeadingMargin(boolean first) {
77         return mBitmap.getWidth() + mPad;
78     }
79 
80     @Override
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)81     public void drawLeadingMargin(Canvas c, Paint p, int x, int dir,
82             int top, int baseline, int bottom,
83             CharSequence text, int start, int end,
84             boolean first, Layout layout) {
85         int st = ((Spanned) text).getSpanStart(this);
86         int itop = layout.getLineTop(layout.getLineForOffset(st));
87 
88         if (dir < 0) {
89             x -= mBitmap.getWidth();
90         }
91 
92         c.drawBitmap(mBitmap, x, itop, p);
93     }
94 
95     @Override
chooseHeight(CharSequence text, int start, int end, int istartv, int v, Paint.FontMetricsInt fm)96     public void chooseHeight(CharSequence text, int start, int end,
97             int istartv, int v,
98             Paint.FontMetricsInt fm) {
99         if (end == ((Spanned) text).getSpanEnd(this)) {
100             int ht = mBitmap.getHeight();
101 
102             int need = ht - (v + fm.descent - fm.ascent - istartv);
103             if (need > 0) {
104                 fm.descent += need;
105             }
106 
107             need = ht - (v + fm.bottom - fm.top - istartv);
108             if (need > 0) {
109                 fm.bottom += need;
110             }
111         }
112     }
113 
114     @Override
toString()115     public String toString() {
116         return "IconMarginSpan{bitmap=" + getBitmap() + ", padding=" + getPadding() + '}';
117     }
118 
119     /**
120      * Returns the bitmap to be used at the beginning of the text
121      * @return a bitmap
122      */
getBitmap()123     @NonNull public Bitmap getBitmap() {
124         return mBitmap;
125     }
126 
127     /**
128      * Returns the padding width between the bitmap and the text.
129      * @return a padding width in pixels
130      */
getPadding()131     @Px public int getPadding() {
132         return mPad;
133     }
134 }
135