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.ColorInt; 20 import android.annotation.IntRange; 21 import android.annotation.NonNull; 22 import android.annotation.Px; 23 import android.graphics.Canvas; 24 import android.graphics.Paint; 25 import android.os.Parcel; 26 import android.text.Layout; 27 import android.text.ParcelableSpan; 28 import android.text.TextUtils; 29 30 /** 31 * A span which styles paragraphs by adding a vertical stripe at the beginning of the text 32 * (respecting layout direction). 33 * <p> 34 * A <code>QuoteSpan</code> must be attached from the first character to the last character of a 35 * single paragraph, otherwise the span will not be displayed. 36 * <p> 37 * <code>QuoteSpans</code> allow configuring the following elements: 38 * <ul> 39 * <li><b>color</b> - the vertical stripe color. By default, the stripe color is 0xff0000ff</li> 40 * <li><b>gap width</b> - the distance, in pixels, between the stripe and the paragraph. 41 * Default value is 2px.</li> 42 * <li><b>stripe width</b> - the width, in pixels, of the stripe. Default value is 43 * 2px.</li> 44 * </ul> 45 * For example, a <code>QuoteSpan</code> using the default values can be constructed like this: 46 * <pre>{@code SpannableString string = new SpannableString("Text with quote span on a long line"); 47 *string.setSpan(new QuoteSpan(), 0, string.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}</pre> 48 * <img src="{@docRoot}reference/android/images/text/style/defaultquotespan.png" /> 49 * <figcaption><code>QuoteSpan</code> constructed with default values.</figcaption> 50 * <p> 51 * <p> 52 * To construct a <code>QuoteSpan</code> with a green stripe, of 20px in width and a gap width of 53 * 40px: 54 * <pre>{@code SpannableString string = new SpannableString("Text with quote span on a long line"); 55 *string.setSpan(new QuoteSpan(Color.GREEN, 20, 40), 0, string.length(), 56 *Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);}</pre> 57 * <img src="{@docRoot}reference/android/images/text/style/customquotespan.png" /> 58 * <figcaption>Customized <code>QuoteSpan</code>.</figcaption> 59 */ 60 @android.ravenwood.annotation.RavenwoodKeepWholeClass 61 public class QuoteSpan implements LeadingMarginSpan, ParcelableSpan { 62 /** 63 * Default stripe width in pixels. 64 */ 65 public static final int STANDARD_STRIPE_WIDTH_PX = 2; 66 67 /** 68 * Default gap width in pixels. 69 */ 70 public static final int STANDARD_GAP_WIDTH_PX = 2; 71 72 /** 73 * Default color for the quote stripe. 74 */ 75 @ColorInt 76 public static final int STANDARD_COLOR = 0xff0000ff; 77 78 @ColorInt 79 private final int mColor; 80 @Px 81 private final int mStripeWidth; 82 @Px 83 private final int mGapWidth; 84 85 /** 86 * Creates a {@link QuoteSpan} with the default values. 87 */ QuoteSpan()88 public QuoteSpan() { 89 this(STANDARD_COLOR, STANDARD_STRIPE_WIDTH_PX, STANDARD_GAP_WIDTH_PX); 90 } 91 92 /** 93 * Creates a {@link QuoteSpan} based on a color. 94 * 95 * @param color the color of the quote stripe. 96 */ QuoteSpan(@olorInt int color)97 public QuoteSpan(@ColorInt int color) { 98 this(color, STANDARD_STRIPE_WIDTH_PX, STANDARD_GAP_WIDTH_PX); 99 } 100 101 /** 102 * Creates a {@link QuoteSpan} based on a color, a stripe width and the width of the gap 103 * between the stripe and the text. 104 * 105 * @param color the color of the quote stripe. 106 * @param stripeWidth the width of the stripe. 107 * @param gapWidth the width of the gap between the stripe and the text. 108 */ QuoteSpan(@olorInt int color, @IntRange(from = 0) int stripeWidth, @IntRange(from = 0) int gapWidth)109 public QuoteSpan(@ColorInt int color, @IntRange(from = 0) int stripeWidth, 110 @IntRange(from = 0) int gapWidth) { 111 mColor = color; 112 mStripeWidth = stripeWidth; 113 mGapWidth = gapWidth; 114 } 115 116 /** 117 * Create a {@link QuoteSpan} from a parcel. 118 */ QuoteSpan(@onNull Parcel src)119 public QuoteSpan(@NonNull Parcel src) { 120 mColor = src.readInt(); 121 mStripeWidth = src.readInt(); 122 mGapWidth = src.readInt(); 123 } 124 125 @Override getSpanTypeId()126 public int getSpanTypeId() { 127 return getSpanTypeIdInternal(); 128 } 129 130 /** 131 * @hide 132 */ 133 @Override getSpanTypeIdInternal()134 public int getSpanTypeIdInternal() { 135 return TextUtils.QUOTE_SPAN; 136 } 137 138 @Override describeContents()139 public int describeContents() { 140 return 0; 141 } 142 143 @Override writeToParcel(Parcel dest, int flags)144 public void writeToParcel(Parcel dest, int flags) { 145 writeToParcelInternal(dest, flags); 146 } 147 148 /** 149 * @hide 150 */ 151 @Override writeToParcelInternal(Parcel dest, int flags)152 public void writeToParcelInternal(Parcel dest, int flags) { 153 dest.writeInt(mColor); 154 dest.writeInt(mStripeWidth); 155 dest.writeInt(mGapWidth); 156 } 157 158 /** 159 * Get the color of the quote stripe. 160 * 161 * @return the color of the quote stripe. 162 */ 163 @ColorInt getColor()164 public int getColor() { 165 return mColor; 166 } 167 168 /** 169 * Get the width of the quote stripe. 170 * 171 * @return the width of the quote stripe. 172 */ getStripeWidth()173 public int getStripeWidth() { 174 return mStripeWidth; 175 } 176 177 /** 178 * Get the width of the gap between the stripe and the text. 179 * 180 * @return the width of the gap between the stripe and the text. 181 */ getGapWidth()182 public int getGapWidth() { 183 return mGapWidth; 184 } 185 186 @Override getLeadingMargin(boolean first)187 public int getLeadingMargin(boolean first) { 188 return mStripeWidth + mGapWidth; 189 } 190 191 @Override drawLeadingMargin(@onNull Canvas c, @NonNull Paint p, int x, int dir, int top, int baseline, int bottom, @NonNull CharSequence text, int start, int end, boolean first, @NonNull Layout layout)192 public void drawLeadingMargin(@NonNull Canvas c, @NonNull Paint p, int x, int dir, 193 int top, int baseline, int bottom, 194 @NonNull CharSequence text, int start, int end, 195 boolean first, @NonNull Layout layout) { 196 Paint.Style style = p.getStyle(); 197 int color = p.getColor(); 198 199 p.setStyle(Paint.Style.FILL); 200 p.setColor(mColor); 201 202 c.drawRect(x, top, x + dir * mStripeWidth, bottom, p); 203 204 p.setStyle(style); 205 p.setColor(color); 206 } 207 208 @Override toString()209 public String toString() { 210 return "QuoteSpan{" 211 + "color=" + String.format("#%08X", getColor()) 212 + ", stripeWidth=" + getStripeWidth() 213 + ", gapWidth=" + getGapWidth() 214 + '}'; 215 } 216 } 217