private static int a( SpannableStringBuilder paramSpannableStringBuilder, int paramInt1, int paramInt2) { int i; if ((paramInt1 + 1 < paramInt2) && (paramSpannableStringBuilder.charAt(paramInt1 + 1) == '\'')) { paramSpannableStringBuilder.delete(paramInt1, paramInt1 + 1); i = 1; } while (true) { return i; i = 0; paramSpannableStringBuilder.delete(paramInt1, paramInt1 + 1); int j = paramInt2 - 1; while (paramInt1 < j) if (paramSpannableStringBuilder.charAt(paramInt1) == '\'') { if ((paramInt1 + 1 < j) && (paramSpannableStringBuilder.charAt(paramInt1 + 1) == '\'')) { paramSpannableStringBuilder.delete(paramInt1, paramInt1 + 1); j--; i++; paramInt1++; } else { paramSpannableStringBuilder.delete(paramInt1, paramInt1 + 1); return i; } } else { paramInt1++; i++; } } }
public final void run() { if ((this.a.F) || (!this.a.i())) { return; } Spanned localSpanned = Html.fromHtml(this.a.az); if ((localSpanned instanceof SpannableStringBuilder)) {} int i; int j; for (SpannableStringBuilder localSpannableStringBuilder = (SpannableStringBuilder) localSpanned; ; localSpannableStringBuilder = new SpannableStringBuilder(localSpanned)) { i = localSpannableStringBuilder.length(); for (j = 0; (j != i) && (Character.isWhitespace(localSpannableStringBuilder.charAt(j))); j++) {} } if (j != 0) { localSpannableStringBuilder.delete(0, j); i = localSpannableStringBuilder.length(); } for (int k = i - 1; (k >= 0) && (Character.isWhitespace(localSpannableStringBuilder.charAt(k))); k--) {} if (k != i - 1) { localSpannableStringBuilder.delete(k + 1, i); } this.a.ax.setText(localSpannableStringBuilder); Linkify.addLinks(this.a.ax, 1); this.a.ax.setVisibility(0); this.a.ax.setMovementMethod(LinkMovementMethod.getInstance()); this.a.ay.setVisibility(0); }
/** * Sets the styling for string with code segments. * * <p>The general process is to search for <code>[[<[</code> and <code>]>]]</code> tokens to * find the code fragments within the escaped text. A <code>Spannable</code> is created which * which breaks up the origin sequence into non-code and code fragments, and applies a monospace * font to the code fragments. * * @param sequence the Spannable generated from Html.fromHtml * @return the message with monospace font applied to code fragments */ private CharSequence setCodeFont(SpannableStringBuilder sequence) { int start = 0; int end = 0; for (int i = 0; i < sequence.length(); i++) { if (sequence.charAt(i) == '[' && i < sequence.length() - 3) { if (sequence.charAt(i + 1) == '[' && sequence.charAt(i + 2) == '<' && sequence.charAt(i + 3) == '[') { start = i; } } else if (sequence.charAt(i) == ']' && i < sequence.length() - 3) { if (sequence.charAt(i + 1) == '>' && sequence.charAt(i + 2) == ']' && sequence.charAt(i + 3) == ']') { end = i; } } if (end > start) { sequence.delete(end, end + 4); sequence.delete(start, start + 4); sequence.setSpan( new TypefaceSpan("monospace"), start, end - 4, Spannable.SPAN_INCLUSIVE_INCLUSIVE); start = 0; end = 0; i = i - 4; // move back to compensate for removal of [[<[ } } return sequence; }
private static int appendQuotedText(SpannableStringBuilder s, int i, int len) { if (i + 1 < len && s.charAt(i + 1) == QUOTE) { s.delete(i, i + 1); return 1; } int count = 0; // delete leading quote s.delete(i, i + 1); len--; while (i < len) { char c = s.charAt(i); if (c == QUOTE) { // QUOTEQUOTE -> QUOTE if (i + 1 < len && s.charAt(i + 1) == QUOTE) { s.delete(i, i + 1); len--; count++; i++; } else { // Closing QUOTE ends quoted text copying s.delete(i, i + 1); break; } } else { i++; count++; } } return count; }
/** * Set the necessary spans for each spoiler. * * <p>The algorithm works in the same way as <code>setCodeFont</code>. * * @param sequence * @return */ private CharSequence setSpoilerStyle(SpannableStringBuilder sequence) { int start = 0; int end = 0; for (int i = 0; i < sequence.length(); i++) { if (sequence.charAt(i) == '[' && i < sequence.length() - 3) { if (sequence.charAt(i + 1) == '[' && sequence.charAt(i + 2) == 's' && sequence.charAt(i + 3) == '[') { start = i; } } else if (sequence.charAt(i) == ']' && i < sequence.length() - 3) { if (sequence.charAt(i + 1) == 's' && sequence.charAt(i + 2) == ']' && sequence.charAt(i + 3) == ']') { end = i; } } if (end > start) { sequence.delete(end, end + 4); sequence.delete(start, start + 4); BackgroundColorSpan backgroundColorSpan = new BackgroundColorSpan(Color.BLACK); ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(Color.BLACK); URLSpan urlSpan = sequence.getSpans(start, start, URLSpan.class)[0]; sequence.setSpan( urlSpan, sequence.getSpanStart(urlSpan), start - 1, Spanned.SPAN_INCLUSIVE_INCLUSIVE); // spoiler text has a space at the front sequence.setSpan( backgroundColorSpan, start + 1, end - 4, Spannable.SPAN_INCLUSIVE_INCLUSIVE); sequence.setSpan(foregroundColorSpan, start, end - 4, Spannable.SPAN_INCLUSIVE_INCLUSIVE); storedSpoilerSpans.add(foregroundColorSpan); storedSpoilerSpans.add(backgroundColorSpan); // Shift 1 to account for remove of beginning "<" storedSpoilerStarts.add(start - 1); storedSpoilerStarts.add(start - 1); storedSpoilerEnds.add(end - 5); storedSpoilerEnds.add(end - 5); sequence.delete(start - 2, start - 1); // remove the trailing < start = 0; end = 0; i = i - 5; // move back to compensate for removal of [[s[ } } return sequence; }
public static CharSequence a(CharSequence paramCharSequence, Time paramTime) { SpannableStringBuilder localSpannableStringBuilder = new SpannableStringBuilder(paramCharSequence); int i = paramCharSequence.length(); int j = 0; int k; int m; int i2; int i1; if (j < i) { k = 1; m = localSpannableStringBuilder.charAt(j); if (m == 39) { i2 = a(localSpannableStringBuilder, j, i); i1 = localSpannableStringBuilder.length(); } } while (true) { j = i2 + j; i = i1; break; while ((j + k < i) && (localSpannableStringBuilder.charAt(j + k) == m)) k++; Object localObject; switch (m) { default: localObject = null; case 97: case 65: case 100: case 69: case 104: case 107: case 109: case 76: case 77: case 115: case 122: case 121: } while (true) if (localObject != null) { localSpannableStringBuilder.replace(j, j + k, (CharSequence) localObject); i2 = ((String) localObject).length(); i1 = localSpannableStringBuilder.length(); break; if (paramTime.hour < 12) ; for (int i10 = 0; ; i10 = 1) { localObject = DateUtils.getAMPMString(i10); break; } if (paramTime.hour < 12) ; for (int i9 = 0; ; i9 = 1) { localObject = DateUtils.getAMPMString(i9); break; } localObject = aN(paramTime.monthDay, k); continue; int i7 = 1 + paramTime.weekDay; if (k < 4) ; for (int i8 = 20; ; i8 = 10) { localObject = DateUtils.getDayOfWeekString(i7, i8); break; } int i6 = paramTime.hour; if (i6 == 0) i6 = 12; if (i6 > 12) i6 -= 12; localObject = aN(i6, k); continue; localObject = aN(paramTime.hour, k); continue; localObject = aN(paramTime.minute, k); continue; int i5 = paramTime.month; if (k >= 4) { localObject = DateUtils.getMonthString(i5, 10); } else if (k == 3) { localObject = DateUtils.getMonthString(i5, 20); } else { localObject = aN(i5 + 1, k); continue; localObject = aN(paramTime.second, k); continue; TimeZone localTimeZone = TimeZone.getDefault(); localTimeZone.inDaylightTime(new Date(paramTime.toMillis(false))); if (k < 2) { long l = (localTimeZone.getRawOffset() + paramTime.gmtoff) / 1000L; StringBuilder localStringBuilder = new StringBuilder(); if (l < 0L) { localStringBuilder.insert(0, "-"); l = -l; } while (true) { int i3 = (int) (l / 3600L); int i4 = (int) (l % 3600L / 60L); localStringBuilder.append(aN(i3, 2)); localStringBuilder.append(aN(i4, 2)); localObject = localStringBuilder.toString(); break; localStringBuilder.insert(0, "+"); } } if (paramTime.isDst != 0) ; for (boolean bool = true; ; bool = false) { localObject = localTimeZone.getDisplayName(bool, 0); break; } int n = paramTime.year; if (k <= 2) { localObject = aN(n % 100, 2); } else { Locale localLocale = Locale.getDefault(); Object[] arrayOfObject = new Object[1]; arrayOfObject[0] = Integer.valueOf(n); localObject = String.format(localLocale, "%d", arrayOfObject); continue; if ((paramCharSequence instanceof Spanned)) return new SpannedString(localSpannableStringBuilder); return localSpannableStringBuilder.toString(); } } } i1 = i; i2 = k; } }
/** * Given a format string and a {@link java.util.Calendar} object, returns a CharSequence * containing the requested date. * * @param inFormat the format string, as described in {@link android.text.format.DateFormat} * @param inDate the date to format * @return a {@link CharSequence} containing the requested text */ public static CharSequence format(CharSequence inFormat, Calendar inDate) { SpannableStringBuilder s = new SpannableStringBuilder(inFormat); int count; LocaleData localeData = LocaleData.get(Locale.getDefault()); int len = inFormat.length(); for (int i = 0; i < len; i += count) { count = 1; int c = s.charAt(i); if (c == QUOTE) { count = appendQuotedText(s, i, len); len = s.length(); continue; } while ((i + count < len) && (s.charAt(i + count) == c)) { count++; } String replacement; switch (c) { case 'A': case 'a': replacement = localeData.amPm[inDate.get(Calendar.AM_PM) - Calendar.AM]; break; case 'd': replacement = zeroPad(inDate.get(Calendar.DATE), count); break; case 'c': case 'E': replacement = getDayOfWeekString(localeData, inDate.get(Calendar.DAY_OF_WEEK), count, c); break; case 'K': // hour in am/pm (0-11) case 'h': // hour in am/pm (1-12) { int hour = inDate.get(Calendar.HOUR); if (c == 'h' && hour == 0) { hour = 12; } replacement = zeroPad(hour, count); } break; case 'H': // hour in day (0-23) case 'k': // hour in day (1-24) [but see note below] { int hour = inDate.get(Calendar.HOUR_OF_DAY); // Historically on Android 'k' was interpreted as 'H', which wasn't // implemented, so pretty much all callers that want to format 24-hour // times are abusing 'k'. http://b/8359981. if (false && c == 'k' && hour == 0) { hour = 24; } replacement = zeroPad(hour, count); } break; case 'L': case 'M': replacement = getMonthString(localeData, inDate.get(Calendar.MONTH), count, c); break; case 'm': replacement = zeroPad(inDate.get(Calendar.MINUTE), count); break; case 's': replacement = zeroPad(inDate.get(Calendar.SECOND), count); break; case 'y': replacement = getYearString(inDate.get(Calendar.YEAR), count); break; case 'z': replacement = getTimeZoneString(inDate, count); break; default: replacement = null; break; } if (replacement != null) { s.replace(i, i + count, replacement); count = replacement.length(); // CARE: count is used in the for loop above len = s.length(); } } if (inFormat instanceof Spanned) { return new SpannedString(s); } else { return s.toString(); } }
@Override public void applySpan(HtmlSpanner spanner, SpannableStringBuilder builder) { if (useStyle.getFontFamily() != null || useStyle.getFontStyle() != null || useStyle.getFontWeight() != null) { FontFamilySpan originalSpan = getFontFamilySpan(builder, start, end); FontFamilySpan newSpan; if (useStyle.getFontFamily() == null && originalSpan == null) { newSpan = new FontFamilySpan(this.defaultFont); } else if (useStyle.getFontFamily() != null) { newSpan = new FontFamilySpan(useStyle.getFontFamily()); } else { newSpan = new FontFamilySpan(originalSpan.getFontFamily()); } if (useStyle.getFontWeight() != null) { newSpan.setBold(useStyle.getFontWeight() == Style.FontWeight.BOLD); } else if (originalSpan != null) { newSpan.setBold(originalSpan.isBold()); } if (useStyle.getFontStyle() != null) { newSpan.setItalic(useStyle.getFontStyle() == Style.FontStyle.ITALIC); } else if (originalSpan != null) { newSpan.setItalic(originalSpan.isItalic()); } // Log.d("StyleCallback", "Applying FontFamilySpan from " + start + " to " + end + " on text " // + builder.subSequence(start, end)); // Log.d("StyleCallback", "FontFamilySpan: " + newSpan ); builder.setSpan(newSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } // If there's no border, we use a BackgroundColorSpan to draw colour behind the text if (spanner.isUseColoursFromStyle() && useStyle.getBackgroundColor() != null && useStyle.getBorderStyle() == null) { // Log.d("StyleCallback", "Applying BackgroundColorSpan with color " + // useStyle.getBackgroundColor() + " from " + start + " to " + end + " on text " + // builder.subSequence(start, end)); builder.setSpan( new BackgroundColorSpan(useStyle.getBackgroundColor()), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } // If there is a border, the BorderSpan will also draw the background colour if needed. if (useStyle.getBorderStyle() != null) { builder.setSpan( new BorderSpan(useStyle, start, end, spanner.isUseColoursFromStyle()), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } if (useStyle.getFontSize() != null) { StyleValue styleValue = useStyle.getFontSize(); if (styleValue.getUnit() == StyleValue.Unit.PS) { if (styleValue.getFloatValue() > 0) { // Log.d("StyleCallback", "Applying AbsoluteFloatSizeSpan with size " + // useStyle.getAbsoluteFontSize() + " from " + start + " to " + end + " on text " + // builder.subSequence(start, end)); builder.setSpan( new AbsoluteFloatSizeSpan(styleValue.getFloatValue()), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } else if (styleValue.getUnit() == StyleValue.Unit.PX) { if (styleValue.getIntValue() > 0) { // Log.d("StyleCallback", "Applying AbsoluteSizeSpan with size " + // useStyle.getAbsoluteFontSize() + " from " + start + " to " + end + " on text " + // builder.subSequence(start, end)); builder.setSpan( new AbsoluteSizeSpan(styleValue.getIntValue()), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } else { if (styleValue.getFloatValue() > 0f) { // Log.d("StyleCallback", "Applying RelativeSizeSpan with size " + // useStyle.getRelativeFontSize() + " from " + start + " to " + end + " on text " + // builder.subSequence(start, end)); builder.setSpan( new RelativeSizeSpan(styleValue.getFloatValue()), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } } if (spanner.isUseColoursFromStyle() && useStyle.getColor() != null) { // Log.d("StyleCallback", "Applying ForegroundColorSpan from " + start + " to " + end + " on // text " + builder.subSequence(start, end) ); builder.setSpan( new ForegroundColorSpan(useStyle.getColor()), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } if (useStyle.getTextAlignment() != null) { AlignmentSpan alignSpan = null; switch (useStyle.getTextAlignment()) { case LEFT: alignSpan = new AlignNormalSpan(); break; case CENTER: alignSpan = new CenterSpan(); break; case RIGHT: alignSpan = new AlignOppositeSpan(); break; } // Log.d("StyleCallback", "Applying AlignmentSpan from " + start + " to " + end + " on text " // + builder.subSequence(start, end) ); builder.setSpan(alignSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } if (useStyle.getTextIndent() != null) { StyleValue styleValue = useStyle.getTextIndent(); int marginStart = start; while (marginStart < end && builder.charAt(marginStart) == '\n') { marginStart++; } int marginEnd = min(end, marginStart + 1); Log.d( "StyleCallback", "Applying LeadingMarginSpan from " + marginStart + " to " + marginEnd + " on text " + builder.subSequence(marginStart, marginEnd)); if (styleValue.getUnit() == StyleValue.Unit.PX) { if (styleValue.getIntValue() > 0) { builder.setSpan( new LeadingMarginSpan.Standard(styleValue.getIntValue(), 0), marginStart, marginEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } else { if (styleValue.getFloatValue() > 0f) { builder.setSpan( new LeadingMarginSpan.Standard( (int) (HtmlSpanner.HORIZONTAL_EM_WIDTH * styleValue.getFloatValue()), 0), marginStart, marginEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } } /* We ignore negative horizontal margins, since that would cause the text to be rendered off-screen */ if (useStyle.getMarginLeft() != null) { StyleValue styleValue = useStyle.getMarginLeft(); if (styleValue.getUnit() == StyleValue.Unit.PX) { if (styleValue.getIntValue() > 0) { builder.setSpan( new LeadingMarginSpan.Standard(styleValue.getIntValue()), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } else if (styleValue.getFloatValue() > 0f) { builder.setSpan( new LeadingMarginSpan.Standard( (int) (HtmlSpanner.HORIZONTAL_EM_WIDTH * styleValue.getFloatValue())), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } } }