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 public class IconMarginSpan implements LeadingMarginSpan, LineHeightSpan { 48 49 @NonNull 50 private final Bitmap mBitmap; 51 @Px 52 private final int mPad; 53 54 /** 55 * Creates an {@link IconMarginSpan} from a {@link Bitmap}. 56 * 57 * @param bitmap bitmap to be rendered at the beginning of the text 58 */ IconMarginSpan(@onNull Bitmap bitmap)59 public IconMarginSpan(@NonNull Bitmap bitmap) { 60 this(bitmap, 0); 61 } 62 63 /** 64 * Creates an {@link IconMarginSpan} from a {@link Bitmap}. 65 * 66 * @param bitmap bitmap to be rendered at the beginning of the text 67 * @param pad padding width, in pixels, between the bitmap and the text 68 */ IconMarginSpan(@onNull Bitmap bitmap, @IntRange(from = 0) int pad)69 public IconMarginSpan(@NonNull Bitmap bitmap, @IntRange(from = 0) int pad) { 70 mBitmap = bitmap; 71 mPad = pad; 72 } 73 74 @Override getLeadingMargin(boolean first)75 public int getLeadingMargin(boolean first) { 76 return mBitmap.getWidth() + mPad; 77 } 78 79 @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)80 public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, 81 int top, int baseline, int bottom, 82 CharSequence text, int start, int end, 83 boolean first, Layout layout) { 84 int st = ((Spanned) text).getSpanStart(this); 85 int itop = layout.getLineTop(layout.getLineForOffset(st)); 86 87 if (dir < 0) { 88 x -= mBitmap.getWidth(); 89 } 90 91 c.drawBitmap(mBitmap, x, itop, p); 92 } 93 94 @Override chooseHeight(CharSequence text, int start, int end, int istartv, int v, Paint.FontMetricsInt fm)95 public void chooseHeight(CharSequence text, int start, int end, 96 int istartv, int v, 97 Paint.FontMetricsInt fm) { 98 if (end == ((Spanned) text).getSpanEnd(this)) { 99 int ht = mBitmap.getHeight(); 100 101 int need = ht - (v + fm.descent - fm.ascent - istartv); 102 if (need > 0) { 103 fm.descent += need; 104 } 105 106 need = ht - (v + fm.bottom - fm.top - istartv); 107 if (need > 0) { 108 fm.bottom += need; 109 } 110 } 111 } 112 113 @Override toString()114 public String toString() { 115 return "IconMarginSpan{bitmap=" + getBitmap() + ", padding=" + getPadding() + '}'; 116 } 117 118 /** 119 * Returns the bitmap to be used at the beginning of the text 120 * @return a bitmap 121 */ getBitmap()122 @NonNull public Bitmap getBitmap() { 123 return mBitmap; 124 } 125 126 /** 127 * Returns the padding width between the bitmap and the text. 128 * @return a padding width in pixels 129 */ getPadding()130 @Px public int getPadding() { 131 return mPad; 132 } 133 } 134