• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.Paint;
23 import android.os.Parcel;
24 import android.text.ParcelableSpan;
25 import android.text.TextPaint;
26 import android.text.TextUtils;
27 
28 import com.android.internal.util.Preconditions;
29 
30 /**
31  * The classes that affect the line height of paragraph should implement this interface.
32  */
33 @android.ravenwood.annotation.RavenwoodKeepWholeClass
34 public interface LineHeightSpan extends ParagraphStyle, WrapTogetherSpan {
35     /**
36      * Classes that implement this should define how the height is being calculated.
37      *
38      * @param text       the text
39      * @param start      the start of the line
40      * @param end        the end of the line
41      * @param spanstartv the start of the span
42      * @param lineHeight the line height
43      * @param fm         font metrics of the paint, in integers
44      */
chooseHeight(CharSequence text, int start, int end, int spanstartv, int lineHeight, Paint.FontMetricsInt fm)45     public void chooseHeight(CharSequence text, int start, int end,
46             int spanstartv, int lineHeight,
47             Paint.FontMetricsInt fm);
48 
49     /**
50      * The classes that affect the line height of paragraph with respect to density,
51      * should implement this interface.
52      */
53     public interface WithDensity extends LineHeightSpan {
54 
55         /**
56          * Classes that implement this should define how the height is being calculated.
57          *
58          * @param text       the text
59          * @param start      the start of the line
60          * @param end        the end of the line
61          * @param spanstartv the start of the span
62          * @param lineHeight the line height
63          * @param paint      the paint
64          */
chooseHeight(CharSequence text, int start, int end, int spanstartv, int lineHeight, Paint.FontMetricsInt fm, TextPaint paint)65         public void chooseHeight(CharSequence text, int start, int end,
66                 int spanstartv, int lineHeight,
67                 Paint.FontMetricsInt fm, TextPaint paint);
68     }
69 
70     /**
71      * Default implementation of the {@link LineHeightSpan}, which changes the line height of the
72      * attached paragraph.
73      * <p>
74      * For example, a paragraph with its line height equal to 100px can be set like this:
75      * <pre>
76      * SpannableString string = new SpannableString("This is a multiline paragraph. This is a multiline paragraph.");
77      * string.setSpan(new LineHeightSpan.Standard(100), 0, string.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
78      * </pre>
79      * <img src="{@docRoot}reference/android/images/text/style/lineheightspan.png" />
80      * <figcaption>Text with line height set to 100 pixels.</figcaption>
81      * <p>
82      * Notice that LineHeightSpan will change the line height of the entire paragraph, even though it
83      * covers only part of the paragraph.
84      * </p>
85      */
86     class Standard implements LineHeightSpan, ParcelableSpan {
87 
88         private final @Px int mHeight;
89         /**
90          * Set the line height of the paragraph to <code>height</code> physical pixels.
91          */
Standard(@x @ntRangefrom = 1) int height)92         public Standard(@Px @IntRange(from = 1) int height) {
93             Preconditions.checkArgument(height > 0, "Height: %d must be positive", height);
94             mHeight = height;
95         }
96 
97         /**
98          * Constructor called from {@link TextUtils} to restore the span from a parcel
99          */
Standard(@onNull Parcel src)100         public Standard(@NonNull Parcel src) {
101             mHeight = src.readInt();
102         }
103 
104         /**
105          * Returns the line height specified by this span.
106          */
107         @Px
getHeight()108         public int getHeight() {
109             return mHeight;
110         }
111 
112         @Override
getSpanTypeId()113         public int getSpanTypeId() {
114             return getSpanTypeIdInternal();
115         }
116 
117         /** @hide */
118         @Override
getSpanTypeIdInternal()119         public int getSpanTypeIdInternal() {
120             return TextUtils.LINE_HEIGHT_SPAN;
121         }
122 
123         @Override
describeContents()124         public int describeContents() {
125             return 0;
126         }
127 
128         @Override
writeToParcel(Parcel dest, int flags)129         public void writeToParcel(Parcel dest, int flags) {
130             writeToParcelInternal(dest, flags);
131         }
132 
133         /** @hide */
134         @Override
writeToParcelInternal(@onNull Parcel dest, int flags)135         public void writeToParcelInternal(@NonNull Parcel dest, int flags) {
136             dest.writeInt(mHeight);
137         }
138 
139         @Override
chooseHeight(@onNull CharSequence text, int start, int end, int spanstartv, int lineHeight, @NonNull Paint.FontMetricsInt fm)140         public void chooseHeight(@NonNull CharSequence text, int start, int end,
141                 int spanstartv, int lineHeight,
142                 @NonNull Paint.FontMetricsInt fm) {
143             final int originHeight = fm.descent - fm.ascent;
144             // If original height is not positive, do nothing.
145             if (originHeight <= 0) {
146                 return;
147             }
148             final float ratio = mHeight * 1.0f / originHeight;
149             fm.descent = Math.round(fm.descent * ratio);
150             fm.ascent = fm.descent - mHeight;
151         }
152     }
153 }
154