示例#1
0
        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));
        }
示例#3
0
        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));
            }
        }
示例#4
0
 static ICharSequence EndTruncatedFormatted(F9PFormattedString baseFormattedString, TextPaint paint, int secondToLastEnd, int start, int end, float availWidth)
 {
     return(EndTruncatedFormattedIter(baseFormattedString, paint, secondToLastEnd, start, start, end, availWidth));
 }
示例#5
0
        //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);
        }
示例#7
0
        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);
        }
示例#8
0
 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));
 }