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.graphics.Canvas; 20 import android.graphics.Paint; 21 import android.graphics.Path; 22 import android.graphics.Path.Direction; 23 import android.os.Parcel; 24 import android.text.Layout; 25 import android.text.ParcelableSpan; 26 import android.text.Spanned; 27 import android.text.TextUtils; 28 29 public class BulletSpan implements LeadingMarginSpan, ParcelableSpan { 30 private final int mGapWidth; 31 private final boolean mWantColor; 32 private final int mColor; 33 34 private static final int BULLET_RADIUS = 3; 35 private static Path sBulletPath = null; 36 public static final int STANDARD_GAP_WIDTH = 2; 37 38 public BulletSpan() { 39 mGapWidth = STANDARD_GAP_WIDTH; 40 mWantColor = false; 41 mColor = 0; 42 } 43 44 public BulletSpan(int gapWidth) { 45 mGapWidth = gapWidth; 46 mWantColor = false; 47 mColor = 0; 48 } 49 50 public BulletSpan(int gapWidth, int color) { 51 mGapWidth = gapWidth; 52 mWantColor = true; 53 mColor = color; 54 } 55 56 public BulletSpan(Parcel src) { 57 mGapWidth = src.readInt(); 58 mWantColor = src.readInt() != 0; 59 mColor = src.readInt(); 60 } 61 62 public int getSpanTypeId() { 63 return TextUtils.BULLET_SPAN; 64 } 65 66 public int describeContents() { 67 return 0; 68 } 69 70 public void writeToParcel(Parcel dest, int flags) { 71 dest.writeInt(mGapWidth); 72 dest.writeInt(mWantColor ? 1 : 0); 73 dest.writeInt(mColor); 74 } 75 76 public int getLeadingMargin(boolean first) { 77 return 2 * BULLET_RADIUS + mGapWidth; 78 } 79 80 public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, 81 int top, int baseline, int bottom, 82 CharSequence text, int start, int end, 83 boolean first, Layout l) { 84 if (((Spanned) text).getSpanStart(this) == start) { 85 Paint.Style style = p.getStyle(); 86 int oldcolor = 0; 87 88 if (mWantColor) { 89 oldcolor = p.getColor(); 90 p.setColor(mColor); 91 } 92 93 p.setStyle(Paint.Style.FILL); 94 95 if (c.isHardwareAccelerated()) { 96 if (sBulletPath == null) { 97 sBulletPath = new Path(); 98 // Bullet is slightly better to avoid aliasing artifacts on mdpi devices. 99 sBulletPath.addCircle(0.0f, 0.0f, 1.2f * BULLET_RADIUS, Direction.CW); 100 } 101 102 c.save(); 103 c.translate(x + dir * BULLET_RADIUS, (top + bottom) / 2.0f); 104 c.drawPath(sBulletPath, p); 105 c.restore(); 106 } else { 107 c.drawCircle(x + dir * BULLET_RADIUS, (top + bottom) / 2.0f, BULLET_RADIUS, p); 108 } 109 110 if (mWantColor) { 111 p.setColor(oldcolor); 112 } 113 114 p.setStyle(style); 115 } 116 } 117 } 118