use of android.text.TextPaint in project Jota-Text-Editor-old by jiro-aqua.
the class TextUtils method commaEllipsize.
/**
* Converts a CharSequence of the comma-separated form "Andy, Bob,
* Charles, David" that is too wide to fit into the specified width
* into one like "Andy, Bob, 2 more".
*
* @param text the text to truncate
* @param p the Paint with which to measure the text
* @param avail the horizontal width available for the text
* @param oneMore the string for "1 more" in the current locale
* @param more the string for "%d more" in the current locale
*/
public static CharSequence commaEllipsize(CharSequence text, TextPaint p, float avail, String oneMore, String more) {
int len = text.length();
char[] buf = new char[len];
TextUtils.getChars(text, 0, len, buf, 0);
int commaCount = 0;
for (int i = 0; i < len; i++) {
if (buf[i] == ',') {
commaCount++;
}
}
float[] wid;
if (text instanceof Spanned) {
Spanned sp = (Spanned) text;
TextPaint temppaint = new TextPaint();
wid = new float[len * 2];
int next;
for (int i = 0; i < len; i = next) {
next = sp.nextSpanTransition(i, len, MetricAffectingSpan.class);
Styled.getTextWidths(p, temppaint, sp, i, next, wid, null);
System.arraycopy(wid, 0, wid, len + i, next - i);
}
System.arraycopy(wid, len, wid, 0, len);
} else {
wid = new float[len];
p.getTextWidths(text, 0, len, wid);
}
int ok = 0;
int okRemaining = commaCount + 1;
String okFormat = "";
int w = 0;
int count = 0;
for (int i = 0; i < len; i++) {
w += wid[i];
if (buf[i] == ',') {
count++;
int remaining = commaCount - count + 1;
float moreWid;
String format;
if (remaining == 1) {
format = " " + oneMore;
} else {
format = " " + String.format(more, remaining);
}
moreWid = p.measureText(format);
if (w + moreWid <= avail) {
ok = i + 1;
okRemaining = remaining;
okFormat = format;
}
}
}
if (w <= avail) {
return text;
} else {
SpannableStringBuilder out = new SpannableStringBuilder(okFormat);
out.insert(0, text, 0, ok);
return out;
}
}
use of android.text.TextPaint in project Jota-Text-Editor-old by jiro-aqua.
the class TextUtils method ellipsize.
/**
* Returns the original text if it fits in the specified width
* given the properties of the specified Paint,
* or, if it does not fit, a copy with ellipsis character added
* at the specified edge or center.
* If <code>preserveLength</code> is specified, the returned copy
* will be padded with zero-width spaces to preserve the original
* length and offsets instead of truncating.
* If <code>callback</code> is non-null, it will be called to
* report the start and end of the ellipsized range.
*/
public static CharSequence ellipsize(CharSequence text, TextPaint p, float avail, TruncateAt where, boolean preserveLength, EllipsizeCallback callback) {
if (sEllipsis == null) {
Resources r = Resources.getSystem();
sEllipsis = r.getString(R.string.ellipsis);
}
int len = text.length();
if (!(text instanceof Spanned)) {
float wid = p.measureText(text, 0, len);
if (wid <= avail) {
if (callback != null) {
callback.ellipsized(0, 0);
}
return text;
}
float ellipsiswid = p.measureText(sEllipsis);
if (ellipsiswid > avail) {
if (callback != null) {
callback.ellipsized(0, len);
}
if (preserveLength) {
char[] buf = obtain(len);
for (int i = 0; i < len; i++) {
buf[i] = '';
}
String ret = new String(buf, 0, len);
recycle(buf);
return ret;
} else {
return "";
}
}
if (where == TruncateAt.START) {
int fit = p.breakText(text, 0, len, false, avail - ellipsiswid, null);
if (callback != null) {
callback.ellipsized(0, len - fit);
}
if (preserveLength) {
return blank(text, 0, len - fit);
} else {
return sEllipsis + text.toString().substring(len - fit, len);
}
} else if (where == TruncateAt.END) {
int fit = p.breakText(text, 0, len, true, avail - ellipsiswid, null);
if (callback != null) {
callback.ellipsized(fit, len);
}
if (preserveLength) {
return blank(text, fit, len);
} else {
return text.toString().substring(0, fit) + sEllipsis;
}
} else /* where == TruncateAt.MIDDLE */
{
int right = p.breakText(text, 0, len, false, (avail - ellipsiswid) / 2, null);
float used = p.measureText(text, len - right, len);
int left = p.breakText(text, 0, len - right, true, avail - ellipsiswid - used, null);
if (callback != null) {
callback.ellipsized(left, len - right);
}
if (preserveLength) {
return blank(text, left, len - right);
} else {
String s = text.toString();
return s.substring(0, left) + sEllipsis + s.substring(len - right, len);
}
}
}
// But do the Spanned cases by hand, because it's such a pain
// to iterate the span transitions backwards and getTextWidths()
// will give us the information we need.
// getTextWidths() always writes into the start of the array,
// so measure each span into the first half and then copy the
// results into the second half to use later.
float[] wid = new float[len * 2];
TextPaint temppaint = new TextPaint();
Spanned sp = (Spanned) text;
int next;
for (int i = 0; i < len; i = next) {
next = sp.nextSpanTransition(i, len, MetricAffectingSpan.class);
Styled.getTextWidths(p, temppaint, sp, i, next, wid, null);
System.arraycopy(wid, 0, wid, len + i, next - i);
}
float sum = 0;
for (int i = 0; i < len; i++) {
sum += wid[len + i];
}
if (sum <= avail) {
if (callback != null) {
callback.ellipsized(0, 0);
}
return text;
}
float ellipsiswid = p.measureText(sEllipsis);
if (ellipsiswid > avail) {
if (callback != null) {
callback.ellipsized(0, len);
}
if (preserveLength) {
char[] buf = obtain(len);
for (int i = 0; i < len; i++) {
buf[i] = '';
}
SpannableString ss = new SpannableString(new String(buf, 0, len));
recycle(buf);
copySpansFrom(sp, 0, len, Object.class, ss, 0);
return ss;
} else {
return "";
}
}
if (where == TruncateAt.START) {
sum = 0;
int i;
for (i = len; i >= 0; i--) {
float w = wid[len + i - 1];
if (w + sum + ellipsiswid > avail) {
break;
}
sum += w;
}
if (callback != null) {
callback.ellipsized(0, i);
}
if (preserveLength) {
SpannableString ss = new SpannableString(blank(text, 0, i));
copySpansFrom(sp, 0, len, Object.class, ss, 0);
return ss;
} else {
SpannableStringBuilder out = new SpannableStringBuilder(sEllipsis);
out.insert(1, text, i, len);
return out;
}
} else if (where == TruncateAt.END) {
sum = 0;
int i;
for (i = 0; i < len; i++) {
float w = wid[len + i];
if (w + sum + ellipsiswid > avail) {
break;
}
sum += w;
}
if (callback != null) {
callback.ellipsized(i, len);
}
if (preserveLength) {
SpannableString ss = new SpannableString(blank(text, i, len));
copySpansFrom(sp, 0, len, Object.class, ss, 0);
return ss;
} else {
SpannableStringBuilder out = new SpannableStringBuilder(sEllipsis);
out.insert(0, text, 0, i);
return out;
}
} else /* where = TruncateAt.MIDDLE */
{
float lsum = 0, rsum = 0;
int left = 0, right = len;
float ravail = (avail - ellipsiswid) / 2;
for (right = len; right >= 0; right--) {
float w = wid[len + right - 1];
if (w + rsum > ravail) {
break;
}
rsum += w;
}
float lavail = avail - ellipsiswid - rsum;
for (left = 0; left < right; left++) {
float w = wid[len + left];
if (w + lsum > lavail) {
break;
}
lsum += w;
}
if (callback != null) {
callback.ellipsized(left, right);
}
if (preserveLength) {
SpannableString ss = new SpannableString(blank(text, left, right));
copySpansFrom(sp, 0, len, Object.class, ss, 0);
return ss;
} else {
SpannableStringBuilder out = new SpannableStringBuilder(sEllipsis);
out.insert(0, text, 0, left);
out.insert(out.length(), text, right, len);
return out;
}
}
}
use of android.text.TextPaint in project Jota-Text-Editor-old by jiro-aqua.
the class TextAppearanceSpan method updateMeasureState.
@Override
public void updateMeasureState(TextPaint ds) {
if (mTypeface != null || mStyle != 0) {
Typeface tf = ds.getTypeface();
int style = 0;
if (tf != null) {
style = tf.getStyle();
}
style |= mStyle;
if (mTypeface != null) {
tf = Typeface.create(mTypeface, style);
} else if (tf == null) {
tf = Typeface.defaultFromStyle(style);
} else {
tf = Typeface.create(tf, style);
}
int fake = style & ~tf.getStyle();
if ((fake & Typeface.BOLD) != 0) {
ds.setFakeBoldText(true);
}
if ((fake & Typeface.ITALIC) != 0) {
ds.setTextSkewX(-0.25f);
}
ds.setTypeface(tf);
}
if (mTextSize > 0) {
ds.setTextSize(mTextSize);
}
}
use of android.text.TextPaint in project Klyph by jonathangerbaud.
the class TextViewUtil method setTextClickableForTags.
/**
* Make a clickable for the tags in parameters
* If callback is null, TextViewUtil.onTagClick is called
*/
public static void setTextClickableForTags(final Context context, TextView textView, Map<String, List<Tag>> tags, final TagCallback callback, boolean clickable) {
SpannableStringBuilder strBuilder = new SpannableStringBuilder(textView.getText());
for (final List<Tag> tagList : tags.values()) {
if (tagList.size() > 0) {
CharacterStyle span;
if (clickable) {
span = new ClickableSpan() {
@Override
public void onClick(View widget) {
if (callback != null)
callback.onTagClick(tagList);
else
onTagClick(context, tagList);
}
@Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.setFakeBoldText(true);
}
};
} else {
span = new StyleSpan(Typeface.BOLD);
}
Tag tag = tagList.get(0);
strBuilder.setSpan(span, tag.getOffset(), tag.getOffset() + tag.getLength(), 0);
}
}
textView.setText(strBuilder);
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
use of android.text.TextPaint in project KeepScore by nolanlawson.
the class AutoResizeTextView method resizeText.
/**
* Resize the text in a text view so that it fits and doesn't need to be
* ellipsized.
*
* Gets smaller, but doesn't get larger again.
*
*/
public void resizeText() {
TextPaint textPaint = getPaint();
String text = getText().toString();
textPaint.setTextSize(maxTextSize);
float oldTextSize = maxTextSize;
int widthLimit = getMeasuredWidth() - getCompoundPaddingLeft() - getCompoundPaddingRight();
if (widthLimit <= 0) {
// this happens if the view hasn't been measured yet
return;
}
float actualTextWidth = textPaint.measureText(text);
float newTextSize = oldTextSize;
log.d("before resize: widthLimit=%d, oldTextSize=%g, actualTextWidth=%g, newTextSize=%g, text=\"%s\"", widthLimit, oldTextSize, actualTextWidth, newTextSize, text);
// keep trying smaller size until we find one that fits
while (newTextSize > MIN_TEXT_SIZE && actualTextWidth > widthLimit) {
newTextSize -= 2;
textPaint.setTextSize(newTextSize);
actualTextWidth = textPaint.measureText(text);
}
log.d("after resize : widthLimit=%d, oldTextSize=%g, actualTextWidth=%g, newTextSize=%g, text=\"%s\"", widthLimit, oldTextSize, actualTextWidth, newTextSize, text);
setTextSize(TypedValue.COMPLEX_UNIT_PX, Math.round(newTextSize));
}
Aggregations