static ICharSequence EndTruncatedFormattedIter(F9PFormattedString baseFormattedString, TextPaint paint, int secondToLastEnd, int start, int endLow, int endHigh, float availWidth) { if (endHigh - endLow <= 1) { return(baseFormattedString.ToSpannableString(EllipsePlacement.End, secondToLastEnd, start, endLow)); } int mid = (endLow + endHigh) / 2; var formattedText = baseFormattedString.ToSpannableString(EllipsePlacement.End, 0, start, mid); var layout = new StaticLayout(formattedText, paint, int.MaxValue - 10000, Android.Text.Layout.Alignment.AlignNormal, 1.0f, 0.0f, true); if (layout.GetLineWidth(0) > availWidth) { return(EndTruncatedFormattedIter(baseFormattedString, paint, secondToLastEnd, start, endLow, mid, availWidth)); } return(EndTruncatedFormattedIter(baseFormattedString, paint, secondToLastEnd, start, mid, endHigh, availWidth)); }
static ICharSequence MidTruncatedFormattedIter(F9PFormattedString baseFormattedString, TextPaint paint, int secondToLastEnd, int startLastVisible, int midLastVisible, int startLow, int startHigh, int end, float availWidth) { if (startHigh - startLow <= 1) { return(baseFormattedString.ToSpannableString(EllipsePlacement.Mid, secondToLastEnd, startHigh, end, startLastVisible, midLastVisible)); } int mid = (startLow + startHigh) / 2; var formattedText = baseFormattedString.ToSpannableString(EllipsePlacement.Mid, 0, mid, end, startLastVisible, midLastVisible); var layout = TextExtensions.StaticLayout(formattedText, paint, int.MaxValue - 10000, Android.Text.Layout.Alignment.AlignNormal, 1.0f, 0.0f, true); if (layout.GetLineWidth(0) > availWidth) { return(MidTruncatedFormattedIter(baseFormattedString, paint, secondToLastEnd, startLastVisible, midLastVisible, mid, startHigh, end, availWidth)); } return(MidTruncatedFormattedIter(baseFormattedString, paint, secondToLastEnd, startLastVisible, midLastVisible, startLow, mid, end, availWidth)); }
static ICharSequence StartTruncatedFormattedIter(F9PFormattedString baseFormattedString, TextPaint paint, int secondToLastEnd, int startLow, int startHigh, int end, float availWidth, float lineHeightMultiplier) { if (startHigh - startLow <= 1) { return(baseFormattedString.ToSpannableString(EllipsePlacement.Start, secondToLastEnd, startHigh, end)); } int mid = (startLow + startHigh) / 2; var formattedText = baseFormattedString.ToSpannableString(EllipsePlacement.Start, 0, mid, end); using (var layout = TextExtensions.StaticLayout(formattedText, paint, int.MaxValue - 10000, Android.Text.Layout.Alignment.AlignNormal, lineHeightMultiplier, 0.0f, true)) { if (layout.GetLineWidth(0) > availWidth) { return(StartTruncatedFormattedIter(baseFormattedString, paint, secondToLastEnd, mid, startHigh, end, availWidth, lineHeightMultiplier)); } return(StartTruncatedFormattedIter(baseFormattedString, paint, secondToLastEnd, startLow, mid, end, availWidth, lineHeightMultiplier)); } }
static ICharSequence EndTruncatedFormatted(F9PFormattedString baseFormattedString, TextPaint paint, int secondToLastEnd, int start, int end, float availWidth) { return(EndTruncatedFormattedIter(baseFormattedString, paint, secondToLastEnd, start, start, end, availWidth)); }
//bool _truncating; internal static StaticLayout Truncate(string text, F9PFormattedString baseFormattedString, TextPaint paint, int availWidth, int availHeight, AutoFit fit, LineBreakMode lineBreakMode, ref int lines, ref ICharSequence textFormatted) { StaticLayout layout = null; var fontMetrics = paint.GetFontMetrics(); var fontLineHeight = fontMetrics.Descent - fontMetrics.Ascent; var fontLeading = System.Math.Abs(fontMetrics.Bottom - fontMetrics.Descent); textFormatted = ((ICharSequence)baseFormattedString?.ToSpannableString()) ?? new Java.Lang.String(text); if (lines > 0) { if (baseFormattedString != null) { layout = new StaticLayout(textFormatted, paint, availWidth, Android.Text.Layout.Alignment.AlignNormal, 1.0f, 0.0f, true); if (layout.Height > availHeight) { var visibleLines = (int)((fontLeading + availHeight) / (fontLineHeight + fontLeading)); if (visibleLines < lines) { lines = visibleLines; } } if (layout.LineCount > lines && lines > 0) { var secondToLastEnd = lines > 1 ? layout.GetLineEnd(lines - 2) : 0; var start = lines > 1 ? layout.GetLineStart(layout.LineCount - 2) : 0; switch (lineBreakMode) { case LineBreakMode.HeadTruncation: textFormatted = StartTruncatedFormatted(baseFormattedString, paint, secondToLastEnd, start, layout.GetLineEnd(layout.LineCount - 1), availWidth); break; case LineBreakMode.MiddleTruncation: textFormatted = MidTruncatedFormatted(baseFormattedString, paint, secondToLastEnd, layout.GetLineStart(lines - 1), (layout.GetLineEnd(lines - 1) + layout.GetLineStart(lines - 1)) / 2 - 1, start, layout.GetLineEnd(layout.LineCount - 1), availWidth); break; case LineBreakMode.TailTruncation: textFormatted = EndTruncatedFormatted(baseFormattedString, paint, secondToLastEnd, layout.GetLineStart(lines - 1), layout.GetLineEnd(layout.LineCount - 1), availWidth); break; default: //textFormatted = baseFormattedString.ToSpannableString(EllipsePlacement.None, 0, 0, layout.GetLineEnd(lines - 1)); textFormatted = TruncatedFormatted(baseFormattedString, paint, secondToLastEnd, layout.GetLineStart(lines - 1), layout.GetLineEnd(layout.LineCount - 1), availWidth); break; } } } else { layout = new StaticLayout(text, paint, availWidth, Android.Text.Layout.Alignment.AlignNormal, 1.0f, 0.0f, true); if (layout.Height > availHeight) { var visibleLines = (int)((fontLeading + availHeight) / (fontLineHeight + fontLeading)); if (visibleLines < lines) { lines = visibleLines; } } if (layout.LineCount > lines && lines > 0) { var secondToLastEnd = lines > 1 ? layout.GetLineEnd(lines - 2) : 0; var start = lines > 1 ? layout.GetLineStart(layout.LineCount - 2) : 0; switch (lineBreakMode) { case LineBreakMode.HeadTruncation: text = StartTruncatedLastLine(text, paint, secondToLastEnd, start, layout.GetLineEnd(layout.LineCount - 1), availWidth); break; case LineBreakMode.MiddleTruncation: text = MidTruncatedLastLine(text, paint, secondToLastEnd, layout.GetLineStart(lines - 1), (layout.GetLineEnd(lines - 1) + layout.GetLineStart(lines - 1)) / 2 - 1, start, layout.GetLineEnd(layout.LineCount - 1), availWidth); break; case LineBreakMode.TailTruncation: text = EndTruncatedLastLine(text, paint, secondToLastEnd, layout.GetLineStart(lines - 1), layout.GetLineEnd(layout.LineCount - 1), availWidth); break; default: text = text.Substring(0, layout.GetLineEnd(lines - 1)); break; } textFormatted = new Java.Lang.String(text); } } } return(new StaticLayout(textFormatted, paint, availWidth, Android.Text.Layout.Alignment.AlignNormal, 1.0f, 0.0f, true)); }
internal static NSAttributedString ToNSAttributedString(this F9PFormattedString formattedString, UIFont baseFont, UIColor baseColor) //, EllipsePlacement ellipsePlacement = EllipsePlacement.None, int secondToLastEnd = -1, int lastLineStart = 0, int lastLineEnd = -1, int startLastVisible = -1, int midLastVisible = -1, bool twice=false) { { var text = formattedString?.Text; if (string.IsNullOrEmpty(text)) { return(null); } if (formattedString is HTMLMarkupString hTMLMarkupString) { text = hTMLMarkupString.UnmarkedText; } var result = new NSMutableAttributedString(text); result.AddAttribute(UIStringAttributeKey.Font, baseFont, new NSRange(0, text.Length)); result.AddAttribute(UIStringAttributeKey.ForegroundColor, baseColor, new NSRange(0, text.Length)); #region Layout font-spans (MetaFonts) var metaFonts = new List <MetaFont>(); var baseMetaFont = new MetaFont( baseFont.FamilyName, (float)baseFont.PointSize, (baseFont.FontDescriptor.Traits.SymbolicTrait & UIFontDescriptorSymbolicTraits.Bold) > 0, (baseFont.FontDescriptor.Traits.SymbolicTrait & UIFontDescriptorSymbolicTraits.Italic) > 0); MathMetaFont = MathMetaFont ?? new MetaFont("STIXGeneral", (float)baseFont.PointSize); for (int i = 0; i < text.Length; i++) { if (i + 1 < text.Length && text[i] == '\ud835' && text[i + 1] >= '\udc00' && text[i + 1] <= '\udeff') { metaFonts.Add(new MetaFont(MathMetaFont)); metaFonts.Add(new MetaFont(MathMetaFont)); // there are two because we're using a double byte unicode character i++; } else { metaFonts.Add(new MetaFont(baseMetaFont)); } } #endregion #region Apply non-font Spans foreach (var span in formattedString._spans) { int spanStart = span.Start; int spanEnd = span.End; spanEnd++; if (spanEnd > result.Length) { spanEnd = (int)result.Length - 1; } NSDictionary attr; switch (span.Key) { #region Spans that change UIFont attributes case FontFamilySpan.SpanKey: for (int i = spanStart; i < spanEnd; i++) { metaFonts[i].Family = ((FontFamilySpan)span).FontFamilyName; } break; case FontSizeSpan.SpanKey: for (int i = spanStart; i < spanEnd; i++) { float size = ((FontSizeSpan)span).Size; metaFonts[i].Size = (size < 0 ? metaFonts[i].Size * (-size) : size); } break; case BoldSpan.SpanKey: for (int i = spanStart; i < spanEnd; i++) { metaFonts[i].Bold = true; } break; case ItalicsSpan.SpanKey: for (int i = spanStart; i < spanEnd; i++) { metaFonts[i].Italic = true; } break; case SuperscriptSpan.SpanKey: for (int i = spanStart; i < spanEnd; i++) { metaFonts[i].Baseline = FontBaseline.Superscript; } break; case SubscriptSpan.SpanKey: for (int i = spanStart; i < spanEnd; i++) { metaFonts[i].Baseline = FontBaseline.Subscript; } break; case NumeratorSpan.SpanKey: for (int i = spanStart; i < spanEnd; i++) { metaFonts[i].Baseline = FontBaseline.Numerator; } break; case DenominatorSpan.SpanKey: for (int i = spanStart; i < spanEnd; i++) { metaFonts[i].Baseline = FontBaseline.Denominator; } break; case ActionSpan.SpanKey: attr = new NSMutableDictionary(); attr[UIStringAttributeKey.ForegroundColor] = Xamarin.Forms.Color.Blue.ToUIColor(); attr[UIStringAttributeKey.UnderlineColor] = Xamarin.Forms.Color.Blue.ToUIColor(); attr[UIStringAttributeKey.StrikethroughColor] = Xamarin.Forms.Color.Blue.ToUIColor(); var uAttr = new NSDictionary(UIStringAttributeKey.UnderlineStyle, NSUnderlineStyle.Single); attr[UIStringAttributeKey.UnderlineStyle] = uAttr[UIStringAttributeKey.UnderlineStyle]; result.AddAttributes(attr, new NSRange(spanStart, spanEnd - spanStart)); break; #endregion #region Font Color case FontColorSpan.SpanKey: var fontColorSpan = span as FontColorSpan; attr = new NSMutableDictionary(); attr[UIStringAttributeKey.ForegroundColor] = fontColorSpan.Color.ToUIColor(); attr[UIStringAttributeKey.UnderlineColor] = fontColorSpan.Color.ToUIColor(); attr[UIStringAttributeKey.StrikethroughColor] = fontColorSpan.Color.ToUIColor(); result.AddAttributes(attr, new NSRange(spanStart, spanEnd - spanStart)); break; #endregion #region Background Color case BackgroundColorSpan.SpanKey: var backgroundColorSpan = span as BackgroundColorSpan; attr = new NSDictionary(UIStringAttributeKey.BackgroundColor, backgroundColorSpan.Color.ToUIColor()); result.AddAttributes(attr, new NSRange(spanStart, spanEnd - spanStart)); break; #endregion #region Underline case UnderlineSpan.SpanKey: attr = new NSDictionary(UIStringAttributeKey.UnderlineStyle, NSUnderlineStyle.Single); result.AddAttributes(attr, new NSRange(spanStart, spanEnd - spanStart)); break; #endregion #region Strikethrough case StrikethroughSpan.SpanKey: attr = new NSDictionary(UIStringAttributeKey.StrikethroughStyle, NSUnderlineStyle.Single); result.AddAttributes(attr, new NSRange(spanStart, spanEnd - spanStart)); break; #endregion } } #endregion #region Apply MetaFonts // run through MetaFonts to see if we need to set new Font attributes var lastMetaFont = baseMetaFont; int startIndex = 0; for (int i = 0; i < metaFonts.Count; i++) { var metaFont = metaFonts[i]; if (lastMetaFont != metaFont) { // we are at the start of a new span if (i > 0 && lastMetaFont != baseMetaFont) { // and we've been inside of a metaFont span var font = FontExtensions.BestFont(lastMetaFont, baseFont); var size = lastMetaFont.Size; var range = new NSRange(startIndex, i - startIndex); switch (lastMetaFont.Baseline) { case FontBaseline.Superscript: result.AddAttributes(new NSDictionary(UIStringAttributeKey.BaselineOffset, size / 2.22f, UIStringAttributeKey.Font, font), range); break; case FontBaseline.Subscript: result.AddAttributes(new NSDictionary(UIStringAttributeKey.BaselineOffset, -size / 6f, UIStringAttributeKey.Font, font), range); break; case FontBaseline.Numerator: result.AddAttributes(new NSDictionary(UIStringAttributeKey.BaselineOffset, size / 4f, UIStringAttributeKey.Font, font), range); break; //case FontBaseline.Denominator: // result.AddAttributes(new NSDictionary(UIStringAttributeKey.BaselineOffset, -size / 6f, UIStringAttributeKey.Font, font), range); // break; default: result.AddAttribute(UIStringAttributeKey.Font, font, range); break; } //System.Diagnostics.Debug.WriteLine("\tRANGE["+range.Location+","+range.Length+"]"); } lastMetaFont = metaFont; startIndex = i; } } if (lastMetaFont != baseMetaFont) { // and we've been inside of a metaFont span var font = FontExtensions.BestFont(lastMetaFont, baseFont); var size = lastMetaFont.Size; var range = new NSRange(startIndex, metaFonts.Count - startIndex); switch (lastMetaFont.Baseline) { case FontBaseline.Superscript: result.AddAttributes(new NSDictionary(UIStringAttributeKey.BaselineOffset, size / 2.22f, UIStringAttributeKey.Font, font), range); break; case FontBaseline.Subscript: result.AddAttributes(new NSDictionary(UIStringAttributeKey.BaselineOffset, -size / 6f, UIStringAttributeKey.Font, font), range); break; case FontBaseline.Numerator: result.AddAttributes(new NSDictionary(UIStringAttributeKey.BaselineOffset, size / 4f, UIStringAttributeKey.Font, font), range); break; //case FontBaseline.Denominator: // result.AddAttributes(new NSDictionary(UIStringAttributeKey.BaselineOffset, -size / 6f, UIStringAttributeKey.Font, font), range); // break; default: result.AddAttribute(UIStringAttributeKey.Font, font, range); break; } //System.Diagnostics.Debug.WriteLine("\tRANGE[" + range.Location + "," + range.Length + "]"); } #endregion return(result); }
public static SpannableStringBuilder ToSpannableString(this F9PFormattedString formattedString, EllipsePlacement ellipsePlacement = EllipsePlacement.None, int secondToLastEnd = -1, int lastLineStart = 0, int lastLineEnd = -1, int startLastVisible = -1, int midLastVisible = -1, bool noBreakSpace = false) { //BaseFormattedString formattedString = label.FormattedText; if (formattedString == null || formattedString.Text == null || formattedString.Text.Length < 1) { return(null); } var text = formattedString.Text; var hTMLMarkupString = formattedString as HTMLMarkupString; if (hTMLMarkupString != null) { text = hTMLMarkupString.UnmarkedText; } if (noBreakSpace) { text = text.Replace(' ', '\u00A0'); } SpannableStringBuilder result; int ellipsesLocation = text.Length; if (ellipsePlacement == EllipsePlacement.None) { result = new SpannableStringBuilder(text); } else { string ellipsesText; if (secondToLastEnd > 0 && Char.IsWhiteSpace(text[secondToLastEnd - 1])) { ellipsesText = text.Substring(0, secondToLastEnd - 1) + "\n"; } else { ellipsesText = text.Substring(0, secondToLastEnd); } /* * int beforeTrimLength = ellipsesText.Length; * if (beforeTrimLength > 0) * { * ellipsesText = ellipsesText.TrimEnd(); * trimmedCharacters = ellipsesText.Length - beforeTrimLength; * } */ //System.Diagnostics.Debug.WriteLine("ellipsesText=["+ellipsesText+"]"); if (ellipsePlacement == EllipsePlacement.Start) { ellipsesText += "…" + text.Substring(lastLineStart, lastLineEnd - lastLineStart); ellipsesLocation = secondToLastEnd + 1; } else if (ellipsePlacement == EllipsePlacement.Mid) { ellipsesText += text.Substring(startLastVisible, midLastVisible - startLastVisible) + "…" + text.Substring(lastLineStart, lastLineEnd - lastLineStart); ellipsesLocation = midLastVisible + 1; } else if (lastLineEnd > lastLineStart) { if (Char.IsWhiteSpace(text[lastLineEnd - 1])) { ellipsesText += text.Substring(lastLineStart, lastLineEnd - lastLineStart - 1) + (ellipsePlacement == EllipsePlacement.Char ? "" : "…"); ellipsesLocation = lastLineEnd; } else { ellipsesText += text.Substring(lastLineStart, lastLineEnd - lastLineStart) + (ellipsePlacement == EllipsePlacement.Char ? "" : "…"); ellipsesLocation = lastLineEnd + 1; } } //System.Diagnostics.Debug.WriteLine("\tellipsesText=["+ellipsesText+"]"); result = new SpannableStringBuilder(ellipsesText); } //Typeface mathFont = Typeface.CreateFromAsset(Settings.Context.Assets,"Fonts/STIXGeneral.otf"); Typeface mathFont = FontManagment.TypefaceForFontFamily("Forms9Patch.Resources.Fonts.STIXGeneral.otf"); if (mathFont == null) { throw new MissingMemberException("Failed to load STIXGeneral font."); } // process Spans foreach (var span in formattedString._spans) { //var spanEnd = span.End + 1; var spanEnd = span.End; //if (spanEnd > text.Length) // spanEnd = text.Length; var spanStart = span.Start; if (ellipsePlacement == EllipsePlacement.Mid) { // part start if between second to last line and start of last line (only really necessary if working on "last line only" width fitting) if (spanStart > secondToLastEnd && spanStart < startLastVisible) { spanStart = startLastVisible; } // part start if between ellipses text if (spanStart > midLastVisible && spanStart < lastLineStart) { spanStart = lastLineStart; } // part end if between secont to last line and start of last line if (spanEnd > secondToLastEnd && spanEnd < startLastVisible) { spanEnd = secondToLastEnd; } // part end if between ellipses text if (spanEnd > midLastVisible && spanEnd < lastLineStart) { spanEnd = midLastVisible; } if (spanEnd <= spanStart) { continue; } // shift up if past ellipses if (spanEnd >= ellipsesLocation) { spanEnd++; } if (spanStart >= ellipsesLocation) { spanStart++; } // close parts if (spanStart >= lastLineStart) { spanStart -= (lastLineStart - midLastVisible); } if (spanStart >= startLastVisible) { spanStart -= (startLastVisible - secondToLastEnd); } if (spanEnd >= lastLineStart) { spanEnd -= (lastLineStart - midLastVisible); } if (spanEnd >= startLastVisible) { spanEnd -= (startLastVisible - secondToLastEnd); } } else if (ellipsePlacement == EllipsePlacement.Start) { // part between second to last line and last line if (spanStart > secondToLastEnd && spanStart < lastLineStart) { spanStart = lastLineStart; } if (spanEnd > secondToLastEnd && spanEnd < lastLineStart) { spanEnd = secondToLastEnd; } if (spanEnd <= spanStart) { continue; } // shift up if past ellipses if (spanEnd >= ellipsesLocation) { spanEnd++; } if (spanStart >= ellipsesLocation) { spanStart++; } // close part if (spanStart >= lastLineStart) { spanStart = (spanStart - lastLineStart) + secondToLastEnd; } if (spanEnd >= lastLineStart) { spanEnd = (spanEnd - lastLineStart) + secondToLastEnd; } } else if (ellipsePlacement != EllipsePlacement.None)//(ellipsePlacement == EllipsePlacement.End) { // remove if start is beyond end if (spanStart > lastLineEnd) { continue; } // shrink if end is beyond end if (spanEnd > lastLineEnd) { spanEnd = lastLineEnd; } // part between second to last line and last line if (spanStart > secondToLastEnd && spanStart < lastLineStart) { spanStart = lastLineStart; } if (spanEnd > secondToLastEnd && spanEnd < lastLineStart) { spanEnd = secondToLastEnd; } if (spanEnd <= spanStart) { continue; } // close part if (spanStart >= lastLineStart) { spanStart = (spanStart - lastLineStart) + secondToLastEnd; } if (spanEnd >= lastLineStart) { spanEnd = (spanEnd - lastLineStart) + secondToLastEnd; } } // offset spanEnd by one because Android. spanEnd++; if (spanEnd > result.Length()) { spanEnd = result.Length(); } switch (span.Key) { case FontFamilySpan.SpanKey: Typeface spanTypeface = FontManagment.TypefaceForFontFamily(((FontFamilySpan)span).FontFamilyName); if (spanTypeface == null) { Console.WriteLine("Failed to find Typeface with FontFamilyName (" + ((FontFamilySpan)span).FontFamilyName + ") for FontFamilySpan."); Console.WriteLine("Ignoring FontFamilySpan"); continue; } result.SetSpan(new CustomTypefaceSpan(spanTypeface), spanStart, spanEnd, 0); break; case FontSizeSpan.SpanKey: var size = ((FontSizeSpan)span).Size; if (size < 0) { result.SetSpan(new RelativeSizeSpan(-size), spanStart, spanEnd, 0); } else { result.SetSpan(new AbsoluteSizeSpan((int)size), spanStart, spanEnd, 0); } break; case FontColorSpan.SpanKey: result.SetSpan(new ForegroundColorSpan(((FontColorSpan)span).Color.ToAndroid()), spanStart, spanEnd, 0); break; case BoldSpan.SpanKey: result.SetSpan(new StyleSpan(TypefaceStyle.Bold), spanStart, spanEnd, 0); break; case ItalicsSpan.SpanKey: result.SetSpan(new StyleSpan(TypefaceStyle.Italic), spanStart, spanEnd, 0); break; case SuperscriptSpan.SpanKey: result.SetSpan(new RelativeSizeSpan(0.575f), spanStart, spanEnd, 0); result.SetSpan(new BaselineSpan(1f / 1.5f), spanStart, spanEnd, 0); result.SetSpan(new StyleSpan(TypefaceStyle.Bold), spanStart, spanEnd, 0); break; case SubscriptSpan.SpanKey: result.SetSpan(new RelativeSizeSpan(0.6f), spanStart, spanEnd, 0); result.SetSpan(new BaselineSpan(-1f / 2.5f), spanStart, spanEnd, 0); result.SetSpan(new StyleSpan(TypefaceStyle.Bold), spanStart, spanEnd, 0); break; case NumeratorSpan.SpanKey: result.SetSpan(new RelativeSizeSpan(0.6f), spanStart, spanEnd, 0); result.SetSpan(new BaselineSpan(1f / 1.6f), spanStart, spanEnd, 0); result.SetSpan(new StyleSpan(TypefaceStyle.Bold), spanStart, spanEnd, 0); break; case DenominatorSpan.SpanKey: result.SetSpan(new RelativeSizeSpan(0.6f), spanStart, spanEnd, 0); result.SetSpan(new StyleSpan(TypefaceStyle.Bold), spanStart, spanEnd, 0); break; case BackgroundColorSpan.SpanKey: result.SetSpan(new Android.Text.Style.BackgroundColorSpan(((BackgroundColorSpan)span).Color.ToAndroid()), spanStart, spanEnd, 0); break; case UnderlineSpan.SpanKey: result.SetSpan(new Android.Text.Style.UnderlineSpan(), spanStart, spanEnd, 0); break; case StrikethroughSpan.SpanKey: result.SetSpan(new Android.Text.Style.StrikethroughSpan(), spanStart, spanEnd, 0); break; case ActionSpan.SpanKey: result.SetSpan(new ForegroundColorSpan(Xamarin.Forms.Color.Blue.ToAndroid()), spanStart, spanEnd, 0); result.SetSpan(new Android.Text.Style.UnderlineSpan(), spanStart, spanEnd, 0); break; } } //result.SetSpan (new StyleSpan (TypefaceStyle.Italic), 0, label.FormattedText.Text.Length, 0); // change font for Mathamatic Alphanumeric Unicode characters int mathStart = -1; int index = 0; //foreach (var c in formattedString.Text.GetUnicodeCodePoints()) { foreach (var c in result.ToString().GetUnicodeCodePoints()) { if (c.InMathAlphanumericBlock()) { if (mathStart < 0) { mathStart = index; } } else { if (mathStart > -1) { result.SetSpan(new CustomTypefaceSpan(mathFont), mathStart, index, 0); //System.Console.WriteLine ("MathAlphanum:[{0}]", formattedString.Text.Substring (mathStart, index - mathStart)); mathStart = -1; } } index += Char.ConvertFromUtf32(c).Length; } if (mathStart > -1) { result.SetSpan(new CustomTypefaceSpan(mathFont), mathStart, index - 1, 0); } return(result); }
static ICharSequence MidTruncatedFormatted(F9PFormattedString baseFormattedString, TextPaint paint, int secondToLastEnd, int startLastVisible, int midLastVisible, int start, int end, float availWidth, float lineHeightMultiplier) { return(MidTruncatedFormattedIter(baseFormattedString, paint, secondToLastEnd, startLastVisible, midLastVisible, start, end, end, availWidth, lineHeightMultiplier)); }