blob: ad78bd57469606fae0461de67ad1182e0b434b6e [file] [log] [blame]
/*
* 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;
}
}
}
}