Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 85d8a993 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Updating more spans"

parents 8a1b786d 139e1b5c
Loading
Loading
Loading
Loading
+62 −22
Original line number Diff line number Diff line
@@ -16,32 +16,72 @@

package android.text.style;

import android.annotation.NonNull;
import android.annotation.Px;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.Spanned;

public class DrawableMarginSpan
implements LeadingMarginSpan, LineHeightSpan
{
    public DrawableMarginSpan(Drawable b) {
        mDrawable = b;
/**
 * A span which adds a drawable and a padding to the paragraph it's attached to.
 * <p>
 * If the height of the drawable is bigger than the height of the line it's attached to then the
 * line height is increased to fit the drawable. <code>DrawableMarginSpan</code> allows setting a
 * padding between the drawable and the text. The default value is 0. The span must be set from the
 * beginning of the text, otherwise either the span won't be rendered or it will be rendered
 * incorrectly.
 * <p>
 * For example, a drawable and a padding of 20px can be added like this:
 * <pre>{@code SpannableString string = new SpannableString("Text with a drawable.");
 * string.setSpan(new DrawableMarginSpan(drawable, 20), 0, string.length(),
 * Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}</pre>
 * <img src="{@docRoot}reference/android/images/text/style/drawablemarginspan.png" />
 * <figcaption>Text with a drawable and a padding.</figcaption>
 * <p>
 *
 * @see IconMarginSpan for working with a {@link android.graphics.Bitmap} instead of
 * a {@link Drawable}.
 */
public class DrawableMarginSpan implements LeadingMarginSpan, LineHeightSpan {
    private static final int STANDARD_PAD_WIDTH = 0;

    @NonNull
    private final Drawable mDrawable;
    @Px
    private final int mPad;

    /**
     * Creates a {@link DrawableMarginSpan} from a {@link Drawable}. The pad width will be 0.
     *
     * @param drawable the drawable to be added
     */
    public DrawableMarginSpan(@NonNull Drawable drawable) {
        this(drawable, STANDARD_PAD_WIDTH);
    }

    public DrawableMarginSpan(Drawable b, int pad) {
        mDrawable = b;
    /**
     * Creates a {@link DrawableMarginSpan} from a {@link Drawable} and a padding, in pixels.
     *
     * @param drawable the drawable to be added
     * @param pad      the distance between the drawable and the text
     */
    public DrawableMarginSpan(@NonNull Drawable drawable, int pad) {
        mDrawable = drawable;
        mPad = pad;
    }

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

    public void drawLeadingMargin(Canvas c, Paint p, int x, int dir,
    @Override
    public void drawLeadingMargin(@NonNull Canvas c, @NonNull Paint p, int x, int dir,
            int top, int baseline, int bottom,
                                  CharSequence text, int start, int end,
                                  boolean first, Layout layout) {
            @NonNull CharSequence text, int start, int end,
            boolean first, @NonNull Layout layout) {
        int st = ((Spanned) text).getSpanStart(this);
        int ix = (int) x;
        int itop = (int) layout.getLineTop(layout.getLineForOffset(st));
@@ -54,22 +94,22 @@ implements LeadingMarginSpan, LineHeightSpan
        mDrawable.draw(c);
    }

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

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

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

    private Drawable mDrawable;
    private int mPad;
    }
}
+60 −19
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package android.text.style;

import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
@@ -24,10 +27,41 @@ import android.graphics.drawable.Drawable;
import java.lang.ref.WeakReference;

/**
 * Span that replaces the text it's attached to with a {@link Drawable} that can be aligned with
 * the bottom or with the baseline of the surrounding text.
 * <p>
 * For an implementation that constructs the drawable from various sources (<code>Bitmap</code>,
 * <code>Drawable</code>, resource id or <code>Uri</code>) use {@link ImageSpan}.
 * <p>
 * A simple implementation of <code>DynamicDrawableSpan</code> that uses drawables from resources
 * looks like this:
 * <pre>
 * class MyDynamicDrawableSpan extends DynamicDrawableSpan {
 *
 * private final Context mContext;
 * private final int mResourceId;
 *
 * public MyDynamicDrawableSpan(Context context, @DrawableRes int resourceId) {
 *     mContext = context;
 *     mResourceId = resourceId;
 * }
 *
 * {@literal @}Override
 * public Drawable getDrawable() {
 *      Drawable drawable = mContext.getDrawable(mResourceId);
 *      drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
 *      return drawable;
 * }
 * }</pre>
 * The class can be used like this:
 * <pre>
 * SpannableString string = new SpannableString("Text with a drawable span");
 * string.setSpan(new MyDynamicDrawableSpan(context, R.mipmap.ic_launcher), 12, 20, Spanned
 * .SPAN_EXCLUSIVE_EXCLUSIVE);</pre>
 * <img src="{@docRoot}reference/android/images/text/style/dynamicdrawablespan.png" />
 * <figcaption>Replacing text with a drawable.</figcaption>
 */
public abstract class DynamicDrawableSpan extends ReplacementSpan {
    private static final String TAG = "DynamicDrawableSpan";

    /**
     * A constant indicating that the bottom of this span should be aligned
@@ -44,12 +78,20 @@ public abstract class DynamicDrawableSpan extends ReplacementSpan {

    protected final int mVerticalAlignment;

    private WeakReference<Drawable> mDrawableRef;

    /**
     * Creates a {@link DynamicDrawableSpan}. The default vertical alignment is
     * {@link #ALIGN_BOTTOM}
     */
    public DynamicDrawableSpan() {
        mVerticalAlignment = ALIGN_BOTTOM;
    }

    /**
     * @param verticalAlignment one of {@link #ALIGN_BOTTOM} or {@link #ALIGN_BASELINE}.
     * Creates a {@link DynamicDrawableSpan} based on a vertical alignment.\
     *
     * @param verticalAlignment one of {@link #ALIGN_BOTTOM} or {@link #ALIGN_BASELINE}
     */
    protected DynamicDrawableSpan(int verticalAlignment) {
        mVerticalAlignment = verticalAlignment;
@@ -71,9 +113,9 @@ public abstract class DynamicDrawableSpan extends ReplacementSpan {
    public abstract Drawable getDrawable();

    @Override
    public int getSize(Paint paint, CharSequence text,
                         int start, int end,
                         Paint.FontMetricsInt fm) {
    public int getSize(@NonNull Paint paint, CharSequence text,
            @IntRange(from = 0) int start, @IntRange(from = 0) int end,
            @Nullable Paint.FontMetricsInt fm) {
        Drawable d = getCachedDrawable();
        Rect rect = d.getBounds();

@@ -89,9 +131,9 @@ public abstract class DynamicDrawableSpan extends ReplacementSpan {
    }

    @Override
    public void draw(Canvas canvas, CharSequence text,
                     int start, int end, float x, 
                     int top, int y, int bottom, Paint paint) {
    public void draw(@NonNull Canvas canvas, CharSequence text,
            @IntRange(from = 0) int start, @IntRange(from = 0) int end, float x,
            int top, int y, int bottom, @NonNull Paint paint) {
        Drawable b = getCachedDrawable();
        canvas.save();

@@ -109,8 +151,9 @@ public abstract class DynamicDrawableSpan extends ReplacementSpan {
        WeakReference<Drawable> wr = mDrawableRef;
        Drawable d = null;

        if (wr != null)
        if (wr != null) {
            d = wr.get();
        }

        if (d == null) {
            d = getDrawable();
@@ -119,7 +162,5 @@ public abstract class DynamicDrawableSpan extends ReplacementSpan {

        return d;
    }

    private WeakReference<Drawable> mDrawableRef;
}
+58 −17
Original line number Diff line number Diff line
@@ -16,28 +16,67 @@

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;

public class IconMarginSpan
implements LeadingMarginSpan, LineHeightSpan
{
    public IconMarginSpan(Bitmap b) {
        mBitmap = b;
/**
 * 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);
    }

    public IconMarginSpan(Bitmap b, int pad) {
        mBitmap = b;
    /**
     * 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,
@@ -45,12 +84,14 @@ implements LeadingMarginSpan, LineHeightSpan
        int st = ((Spanned) text).getSpanStart(this);
        int itop = layout.getLineTop(layout.getLineForOffset(st));

        if (dir < 0)
        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) {
@@ -58,15 +99,15 @@ implements LeadingMarginSpan, LineHeightSpan
            int ht = mBitmap.getHeight();

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

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

    private Bitmap mBitmap;
    private int mPad;
}
+130 −31
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package android.text.style;

import android.annotation.DrawableRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
@@ -27,18 +29,49 @@ import android.util.Log;

import java.io.InputStream;

/**
 * Span that replaces the text it's attached to with a {@link Drawable} that can be aligned with
 * the bottom or with the baseline of the surrounding text. The drawable can be constructed from
 * varied sources:
 * <ul>
 * <li>{@link Bitmap} - see {@link #ImageSpan(Context, Bitmap)} and
 * {@link #ImageSpan(Context, Bitmap, int)}
 * </li>
 * <li>{@link Drawable} - see {@link #ImageSpan(Drawable, int)}</li>
 * <li>resource id - see {@link #ImageSpan(Context, int, int)}</li>
 * <li>{@link Uri} - see {@link #ImageSpan(Context, Uri, int)}</li>
 * </ul>
 * The default value for the vertical alignment is {@link DynamicDrawableSpan#ALIGN_BOTTOM}
 * <p>
 * For example, an <code>ImagedSpan</code> can be used like this:
 * <pre>
 * SpannableString string = SpannableString("Bottom: span.\nBaseline: span.");
 * // using the default alignment: ALIGN_BOTTOM
 * string.setSpan(ImageSpan(this, R.mipmap.ic_launcher), 7, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
 * string.setSpan(ImageSpan(this, R.mipmap.ic_launcher, DynamicDrawableSpan.ALIGN_BASELINE),
 * 22, 23, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
 * </pre>
 * <img src="{@docRoot}reference/android/images/text/style/imagespan.png" />
 * <figcaption>Text with <code>ImageSpan</code>s aligned bottom and baseline.</figcaption>
 */
public class ImageSpan extends DynamicDrawableSpan {

    @Nullable
    private Drawable mDrawable;
    @Nullable
    private Uri mContentUri;
    @DrawableRes
    private int mResourceId;
    @Nullable
    private Context mContext;
    @Nullable
    private String mSource;

    /**
     * @deprecated Use {@link #ImageSpan(Context, Bitmap)} instead.
     */
    @Deprecated
    public ImageSpan(Bitmap b) {
    public ImageSpan(@NonNull Bitmap b) {
        this(null, b, ALIGN_BOTTOM);
    }

@@ -46,80 +79,143 @@ public class ImageSpan extends DynamicDrawableSpan {
     * @deprecated Use {@link #ImageSpan(Context, Bitmap, int)} instead.
     */
    @Deprecated
    public ImageSpan(Bitmap b, int verticalAlignment) {
    public ImageSpan(@NonNull Bitmap b, int verticalAlignment) {
        this(null, b, verticalAlignment);
    }

    public ImageSpan(Context context, Bitmap b) {
        this(context, b, ALIGN_BOTTOM);
    /**
     * Constructs an {@link ImageSpan} from a {@link Context} and a {@link Bitmap} with the default
     * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}
     *
     * @param context context used to create a drawable from {@param bitmap} based on the display
     *                metrics of the resources
     * @param bitmap  bitmap to be rendered
     */
    public ImageSpan(@NonNull Context context, @NonNull Bitmap bitmap) {
        this(context, bitmap, ALIGN_BOTTOM);
    }

    /**
     * Constructs an {@link ImageSpan} from a {@link Context}, a {@link Bitmap} and a vertical
     * alignment.
     *
     * @param context           context used to create a drawable from {@param bitmap} based on
     *                          the display metrics of the resources
     * @param bitmap            bitmap to be rendered
     * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
     * {@link DynamicDrawableSpan#ALIGN_BASELINE}.
     *                          {@link DynamicDrawableSpan#ALIGN_BASELINE}
     */
    public ImageSpan(Context context, Bitmap b, int verticalAlignment) {
    public ImageSpan(@NonNull Context context, @NonNull Bitmap bitmap, int verticalAlignment) {
        super(verticalAlignment);
        mContext = context;
        mDrawable = context != null
                ? new BitmapDrawable(context.getResources(), b)
                : new BitmapDrawable(b);
                ? new BitmapDrawable(context.getResources(), bitmap)
                : new BitmapDrawable(bitmap);
        int width = mDrawable.getIntrinsicWidth();
        int height = mDrawable.getIntrinsicHeight();
        mDrawable.setBounds(0, 0, width > 0 ? width : 0, height > 0 ? height : 0);
    }

    public ImageSpan(Drawable d) {
        this(d, ALIGN_BOTTOM);
    /**
     * Constructs an {@link ImageSpan} from a drawable with the default
     * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}.
     *
     * @param drawable drawable to be rendered
     */
    public ImageSpan(@NonNull Drawable drawable) {
        this(drawable, ALIGN_BOTTOM);
    }

    /**
     * Constructs an {@link ImageSpan} from a drawable and a vertical alignment.
     *
     * @param drawable          drawable to be rendered
     * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
     * {@link DynamicDrawableSpan#ALIGN_BASELINE}.
     *                          {@link DynamicDrawableSpan#ALIGN_BASELINE}
     */
    public ImageSpan(Drawable d, int verticalAlignment) {
    public ImageSpan(@NonNull Drawable drawable, int verticalAlignment) {
        super(verticalAlignment);
        mDrawable = d;
        mDrawable = drawable;
    }

    public ImageSpan(Drawable d, String source) {
        this(d, source, ALIGN_BOTTOM);
    /**
     * Constructs an {@link ImageSpan} from a drawable and a source with the default
     * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}
     *
     * @param drawable drawable to be rendered
     * @param source   drawable's Uri source
     */
    public ImageSpan(@NonNull Drawable drawable, @NonNull String source) {
        this(drawable, source, ALIGN_BOTTOM);
    }

    /**
     * Constructs an {@link ImageSpan} from a drawable, a source and a vertical alignment.
     *
     * @param drawable          drawable to be rendered
     * @param source            drawable's uri source
     * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
     * {@link DynamicDrawableSpan#ALIGN_BASELINE}.
     *                          {@link DynamicDrawableSpan#ALIGN_BASELINE}
     */
    public ImageSpan(Drawable d, String source, int verticalAlignment) {
    public ImageSpan(@NonNull Drawable drawable, @NonNull String source, int verticalAlignment) {
        super(verticalAlignment);
        mDrawable = d;
        mDrawable = drawable;
        mSource = source;
    }

    public ImageSpan(Context context, Uri uri) {
    /**
     * Constructs an {@link ImageSpan} from a {@link Context} and a {@link Uri} with the default
     * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}. The Uri source can be retrieved via
     * {@link #getSource()}
     *
     * @param context context used to create a drawable from {@param bitmap} based on the display
     *                metrics of the resources
     * @param uri     {@link Uri} used to construct the drawable that will be rendered
     */
    public ImageSpan(@NonNull Context context, @NonNull Uri uri) {
        this(context, uri, ALIGN_BOTTOM);
    }

    /**
     * Constructs an {@link ImageSpan} from a {@link Context}, a {@link Uri} and a vertical
     * alignment. The Uri source can be retrieved via {@link #getSource()}
     *
     * @param context           context used to create a drawable from {@param bitmap} based on
     *                          the display
     *                          metrics of the resources
     * @param uri               {@link Uri} used to construct the drawable that will be rendered.
     * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
     * {@link DynamicDrawableSpan#ALIGN_BASELINE}.
     *                          {@link DynamicDrawableSpan#ALIGN_BASELINE}
     */
    public ImageSpan(Context context, Uri uri, int verticalAlignment) {
    public ImageSpan(@NonNull Context context, @NonNull Uri uri, int verticalAlignment) {
        super(verticalAlignment);
        mContext = context;
        mContentUri = uri;
        mSource = uri.toString();
    }

    public ImageSpan(Context context, @DrawableRes int resourceId) {
    /**
     * Constructs an {@link ImageSpan} from a {@link Context} and a resource id with the default
     * alignment {@link DynamicDrawableSpan#ALIGN_BOTTOM}
     *
     * @param context    context used to retrieve the drawable from resources
     * @param resourceId drawable resource id based on which the drawable is retrieved
     */
    public ImageSpan(@NonNull Context context, @DrawableRes int resourceId) {
        this(context, resourceId, ALIGN_BOTTOM);
    }

    /**
     * Constructs an {@link ImageSpan} from a {@link Context}, a resource id and a vertical
     * alignment.
     *
     * @param context           context used to retrieve the drawable from resources
     * @param resourceId        drawable resource id based on which the drawable is retrieved.
     * @param verticalAlignment one of {@link DynamicDrawableSpan#ALIGN_BOTTOM} or
     * {@link DynamicDrawableSpan#ALIGN_BASELINE}.
     *                          {@link DynamicDrawableSpan#ALIGN_BASELINE}
     */
    public ImageSpan(Context context, @DrawableRes int resourceId, int verticalAlignment) {
    public ImageSpan(@NonNull Context context, @DrawableRes int resourceId,
            int verticalAlignment) {
        super(verticalAlignment);
        mContext = context;
        mResourceId = resourceId;
@@ -142,7 +238,7 @@ public class ImageSpan extends DynamicDrawableSpan {
                        drawable.getIntrinsicHeight());
                is.close();
            } catch (Exception e) {
                Log.e("sms", "Failed to loaded content " + mContentUri, e);
                Log.e("ImageSpan", "Failed to loaded content " + mContentUri, e);
            }
        } else {
            try {
@@ -150,7 +246,7 @@ public class ImageSpan extends DynamicDrawableSpan {
                drawable.setBounds(0, 0, drawable.getIntrinsicWidth(),
                        drawable.getIntrinsicHeight());
            } catch (Exception e) {
                Log.e("sms", "Unable to find resource: " + mResourceId);
                Log.e("ImageSpan", "Unable to find resource: " + mResourceId);
            }
        }

@@ -159,9 +255,12 @@ public class ImageSpan extends DynamicDrawableSpan {

    /**
     * Returns the source string that was saved during construction.
     *
     * @return the source string that was saved during construction
     * @see #ImageSpan(Drawable, String) and this{@link #ImageSpan(Context, Uri)}
     */
    @Nullable
    public String getSource() {
        return mSource;
    }

}
+33 −7
Original line number Diff line number Diff line
@@ -19,16 +19,42 @@ package android.text.style;
import android.graphics.Paint;
import android.text.TextPaint;

public interface LineHeightSpan
extends ParagraphStyle, WrapTogetherSpan
{
/**
 * The classes that affect the height of the line should implement this interface.
 */
public interface LineHeightSpan extends ParagraphStyle, WrapTogetherSpan {
    /**
     * Classes that implement this should define how the height is being calculated.
     *
     * @param text       the text
     * @param start      the start of the line
     * @param end        the end of the line
     * @param spanstartv the start of the span
     * @param lineHeight the line height
     * @param fm         font metrics of the paint, in integers
     */
    public void chooseHeight(CharSequence text, int start, int end,
                             int spanstartv, int v,
            int spanstartv, int lineHeight,
            Paint.FontMetricsInt fm);

    /**
     * The classes that affect the height of the line with respect to density, should implement this
     * interface.
     */
    public interface WithDensity extends LineHeightSpan {

        /**
         * Classes that implement this should define how the height is being calculated.
         *
         * @param text       the text
         * @param start      the start of the line
         * @param end        the end of the line
         * @param spanstartv the start of the span
         * @param lineHeight the line height
         * @param paint      the paint
         */
        public void chooseHeight(CharSequence text, int start, int end,
                                 int spanstartv, int v,
                int spanstartv, int lineHeight,
                Paint.FontMetricsInt fm, TextPaint paint);
    }
}
Loading