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 public class QuoteSpan implements LeadingMarginSpan, ParcelableSpan { 61 /** 62 * Default stripe width in pixels. 63 */ 64 public static final int STANDARD_STRIPE_WIDTH_PX = 2; 65 66 /** 67 * Default gap width in pixels. 68 */ 69 public static final int STANDARD_GAP_WIDTH_PX = 2; 70 71 /** 72 * Default color for the quote stripe. 73 */ 74 @ColorInt 75 public static final int STANDARD_COLOR = 0xff0000ff; 76 77 @ColorInt 78 private final int mColor; 79 @Px 80 private final int mStripeWidth; 81 @Px 82 private final int mGapWidth; 83 84 /** 85 * Creates a {@link QuoteSpan} with the default values. 86 */ QuoteSpan()87 public QuoteSpan() { 88 this(STANDARD_COLOR, STANDARD_STRIPE_WIDTH_PX, STANDARD_GAP_WIDTH_PX); 89 } 90 91 /** 92 * Creates a {@link QuoteSpan} based on a color. 93 * 94 * @param color the color of the quote stripe. 95 */ QuoteSpan(@olorInt int color)96 public QuoteSpan(@ColorInt int color) { 97 this(color, STANDARD_STRIPE_WIDTH_PX, STANDARD_GAP_WIDTH_PX); 98 } 99 100 /** 101 * Creates a {@link QuoteSpan} based on a color, a stripe width and the width of the gap 102 * between the stripe and the text. 103 * 104 * @param color the color of the quote stripe. 105 * @param stripeWidth the width of the stripe. 106 * @param gapWidth the width of the gap between the stripe and the text. 107 */ QuoteSpan(@olorInt int color, @IntRange(from = 0) int stripeWidth, @IntRange(from = 0) int gapWidth)108 public QuoteSpan(@ColorInt int color, @IntRange(from = 0) int stripeWidth, 109 @IntRange(from = 0) int gapWidth) { 110 mColor = color; 111 mStripeWidth = stripeWidth; 112 mGapWidth = gapWidth; 113 } 114 115 /** 116 * Create a {@link QuoteSpan} from a parcel. 117 */ QuoteSpan(@onNull Parcel src)118 public QuoteSpan(@NonNull Parcel src) { 119 mColor = src.readInt(); 120 mStripeWidth = src.readInt(); 121 mGapWidth = src.readInt(); 122 } 123 124 @Override getSpanTypeId()125 public int getSpanTypeId() { 126 return getSpanTypeIdInternal(); 127 } 128 129 /** 130 * @hide 131 */ 132 @Override getSpanTypeIdInternal()133 public int getSpanTypeIdInternal() { 134 return TextUtils.QUOTE_SPAN; 135 } 136 137 @Override describeContents()138 public int describeContents() { 139 return 0; 140 } 141 142 @Override writeToParcel(Parcel dest, int flags)143 public void writeToParcel(Parcel dest, int flags) { 144 writeToParcelInternal(dest, flags); 145 } 146 147 /** 148 * @hide 149 */ 150 @Override writeToParcelInternal(Parcel dest, int flags)151 public void writeToParcelInternal(Parcel dest, int flags) { 152 dest.writeInt(mColor); 153 dest.writeInt(mStripeWidth); 154 dest.writeInt(mGapWidth); 155 } 156 157 /** 158 * Get the color of the quote stripe. 159 * 160 * @return the color of the quote stripe. 161 */ 162 @ColorInt getColor()163 public int getColor() { 164 return mColor; 165 } 166 167 /** 168 * Get the width of the quote stripe. 169 * 170 * @return the width of the quote stripe. 171 */ getStripeWidth()172 public int getStripeWidth() { 173 return mStripeWidth; 174 } 175 176 /** 177 * Get the width of the gap between the stripe and the text. 178 * 179 * @return the width of the gap between the stripe and the text. 180 */ getGapWidth()181 public int getGapWidth() { 182 return mGapWidth; 183 } 184 185 @Override getLeadingMargin(boolean first)186 public int getLeadingMargin(boolean first) { 187 return mStripeWidth + mGapWidth; 188 } 189 190 @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)191 public void drawLeadingMargin(@NonNull Canvas c, @NonNull Paint p, int x, int dir, 192 int top, int baseline, int bottom, 193 @NonNull CharSequence text, int start, int end, 194 boolean first, @NonNull Layout layout) { 195 Paint.Style style = p.getStyle(); 196 int color = p.getColor(); 197 198 p.setStyle(Paint.Style.FILL); 199 p.setColor(mColor); 200 201 c.drawRect(x, top, x + dir * mStripeWidth, bottom, p); 202 203 p.setStyle(style); 204 p.setColor(color); 205 } 206 207 @Override toString()208 public String toString() { 209 return "QuoteSpan{" 210 + "color=" + String.format("#%08X", getColor()) 211 + ", stripeWidth=" + getStripeWidth() 212 + ", gapWidth=" + getGapWidth() 213 + '}'; 214 } 215 } 216