/* * 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.Paint; import android.os.Parcel; import android.text.ParcelableSpan; import android.text.TextPaint; import android.text.TextUtils; import com.android.internal.util.Preconditions; /** * The classes that affect the line height of paragraph 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 lineHeight, Paint.FontMetricsInt fm); /** * The classes that affect the line height of paragraph 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 lineHeight, Paint.FontMetricsInt fm, TextPaint paint); } /** * Default implementation of the {@link LineHeightSpan}, which changes the line height of the * attached paragraph. *

* For example, a paragraph with its line height equal to 100px can be set like this: *

     * SpannableString string = new SpannableString("This is a multiline paragraph. This is a multiline paragraph.");
     * string.setSpan(new LineHeightSpan.Standard(100), 0, string.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
     * 
* *
Text with line height set to 100 pixels.
*

* Notice that LineHeightSpan will change the line height of the entire paragraph, even though it * covers only part of the paragraph. *

*/ class Standard implements LineHeightSpan, ParcelableSpan { private final @Px int mHeight; /** * Set the line height of the paragraph to height physical pixels. */ public Standard(@Px @IntRange(from = 1) int height) { Preconditions.checkArgument(height > 0, "Height: %d must be positive", height); mHeight = height; } /** * Constructor called from {@link TextUtils} to restore the span from a parcel */ public Standard(@NonNull Parcel src) { mHeight = src.readInt(); } /** * Returns the line height specified by this span. */ @Px public int getHeight() { return mHeight; } @Override public int getSpanTypeId() { return getSpanTypeIdInternal(); } /** @hide */ @Override public int getSpanTypeIdInternal() { return TextUtils.LINE_HEIGHT_SPAN; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { writeToParcelInternal(dest, flags); } /** @hide */ @Override public void writeToParcelInternal(@NonNull Parcel dest, int flags) { dest.writeInt(mHeight); } @Override public void chooseHeight(@NonNull CharSequence text, int start, int end, int spanstartv, int lineHeight, @NonNull Paint.FontMetricsInt fm) { final int originHeight = fm.descent - fm.ascent; // If original height is not positive, do nothing. if (originHeight <= 0) { return; } final float ratio = mHeight * 1.0f / originHeight; fm.descent = Math.round(fm.descent * ratio); fm.ascent = fm.descent - mHeight; } } }