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