public static IReadOnlyList <IAttributedText> CreateParagraphs(this IAttributedText attributedText) { if (attributedText?.Text == null) { return(null); } List <IAttributedText> paragraphs = new List <IAttributedText>(); int start = 0; int attributeIndex = 0; using (var sr = new StringReader(attributedText.Text)) { string line; while ((line = sr.ReadLine()) != null) { var length = line.Length; var runs = new List <IAttributedTextRun>(); attributeIndex = attributedText.CreateParagraphRun(start, length, runs, attributeIndex); var paragraph = new AttributedText(line, runs); paragraphs.Add(paragraph); start += length + 1; } } return(paragraphs); }
public void Write( IAttributedText attributedText, TextWriter writer) { if (attributedText != null && !string.IsNullOrEmpty(attributedText.Text)) { bool encode = attributedText.Text.Contains("]]"); writer.Write($"<{XmlNames.AttributedText}>"); if (encode) { writer.Write($"<{XmlNames.Content} {XmlNames.Encoded}=\"True\"><![CDATA["); byte[] bytes = Encoding.UTF8.GetBytes(attributedText.Text); writer.Write(Convert.ToBase64String(bytes)); writer.Write($"]]></{XmlNames.Content}>"); } else { writer.Write($"<{XmlNames.Content}><![CDATA["); writer.Write(attributedText.Text); writer.Write($"]]></{XmlNames.Content}>"); } if (attributedText.Runs != null && attributedText.Runs.Count > 0) { foreach (var run in attributedText.Runs) { WriteRun(run, writer); } } writer.Write($"</{XmlNames.AttributedText}>"); } }
public static NSAttributedString AsNSAttributedString( this IAttributedText target, string contextFontName = null, float contextFontSize = 12f, string contextFontColor = null, bool coreTextCompatible = false) { if (target != null) { var defaultAttributes = GetDefaultAttributes(contextFontName, contextFontSize, contextFontColor); var attributedString = new NSMutableAttributedString(target.Text, defaultAttributes); if (target.Runs != null) { foreach (var run in target.Runs) { HandleRun(attributedString, run, contextFontName, contextFontSize, contextFontColor, coreTextCompatible); } } return(attributedString); } return(null); }
internal static List <IAttributedTextRun> OptimizeRuns(this IAttributedText attributedText) { if (attributedText?.Text == null) { return(null); } if (attributedText is AbstractAttributedText abstractAttributedText && abstractAttributedText.Optimal) { if (attributedText.Runs == null) { return(null); } if (attributedText.Runs is List <IAttributedTextRun> list) { return(list); } return(attributedText.Runs.ToList()); } var start = 0; var attributeIndex = 0; var text = attributedText.Text; var length = text.Length; var runs = new List <IAttributedTextRun>(); attributedText.CreateParagraphRun(start, length, runs, attributeIndex); return(runs); }
public static FlowDocument AsFlowDocument( this IAttributedText target) { if (target == null) { return(null); } var text = target.Text ?? ""; var paragraph = new Paragraph(new Run(text)); if (!string.IsNullOrWhiteSpace(text) && target.Runs != null) { foreach (var textRun in target.Runs) { var pointer1 = paragraph.ContentStart.GetPositionAtOffset(textRun.Start + 1); var pointer2 = paragraph.ContentStart.GetPositionAtOffset(textRun.GetEnd() + 1); if (pointer1 != null && pointer2 != null) { var span = new Span(pointer1, pointer2); ApplyFormattingToSpan(span, textRun); } } } return(new FlowDocument(paragraph)); }
public string Write(IAttributedText text) { using (var writer = new StringWriter()) { Write(text, writer); return(writer.ToString()); } }
private static void HandleRuns( IAttributedText target, ISpannable spannableString) { foreach (var run in target.Runs) { HandleFormatRun(spannableString, run); } }
public static SpannableStringBuilder AsSpannableStringBuilder(this IAttributedText target) { if (target != null) { var spannableString = new SpannableStringBuilder(target.Text); HandleRuns(target, spannableString); return(spannableString); } return(null); }
public static IList <AttributedTextBlock> CreateBlocks(this IAttributedText text) { if (text?.Text == null) { return(null); } var blocks = new List <AttributedTextBlock>(); var start = 0; var end = text.Text.Length; if (text.Runs?.Count > 0) { foreach (var run in text.Runs) { if (start < run.Start) { var noAttrLength = run.Start - start; var noAttrValue = text.Text.Substring(start, noAttrLength); blocks.Add(new AttributedTextBlock(noAttrValue, null)); start = run.Start; } var length = run.Length; if (length > 0) { var value = text.Text.Substring(start, length); blocks.Add(new AttributedTextBlock(value, run.Attributes)); start = run.GetEnd(); } #if DEBUG else { System.Diagnostics.Debug.WriteLine("Length should not be less then 0"); } #endif } } if (start < end) { var value = text.Text.Substring(start); blocks.Add(new AttributedTextBlock(value, null)); } return(blocks); }
public static IAttributedText Optimize(this IAttributedText attributedText) { if (attributedText?.Text == null) { return(null); } if (attributedText is AbstractAttributedText abstractAttributedText && abstractAttributedText.Optimal) { return(attributedText); } var start = 0; var attributeIndex = 0; var text = attributedText.Text; var length = text.Length; var runs = new List <IAttributedTextRun>(); attributedText.CreateParagraphRun(start, length, runs, attributeIndex); return(new AttributedText(text, runs, true)); }
public static int CreateParagraphRun( this IAttributedText text, int start, int length, IList <IAttributedTextRun> runs, int startIndexForSearch = 0) { // If the text doesn't have any runs, then we can simply return if (text.Runs == null || text.Runs.Count == 0) { return(0); } // If we've already reached the end of the runs, we can simply return if (!(startIndexForSearch < text.Runs.Count)) { return(startIndexForSearch); } var end = start + length; var index = startIndexForSearch; do { var run = text.Runs[index]; // If the run is after the end index, then we can go ahead and return if (end < run.Start) { return(index); } if (run.Intersects(start, length)) { if (start == run.Start) { var paragraphStart = run.Start - start; var paragraphLength = Math.Min(run.Length, length); runs.Add(new AttributedTextRun(paragraphStart, paragraphLength, run.Attributes)); // If the length of the run is the same as the paragraph, then we know // that the next run (if any) will apply to to the next paragraph. if (run.Length == length) { return(index + 1); } // If the run is longer than the line, then we know that the attributes from this run // will also apply to the next paragraph. if (run.Length > length) { return(index); } // If the run length is less than the length of the line, then the next run may apply // to this line, so continue } else if (end == run.GetEnd()) { var paragraphStart = Math.Max(run.Start - start, 0); var paragraphLength = Math.Min(run.Length, end - paragraphStart); runs.Add(new AttributedTextRun(paragraphStart, paragraphLength, run.Attributes)); // Since the run and the line have the same end, we know that the next run (if any) will // apply to to the next paragraph. return(index + 1); } else { var paragraphStart = Math.Max(run.Start - start, 0); var paragraphLength = Math.Min(run.Length, length - paragraphStart); runs.Add(new AttributedTextRun(paragraphStart, paragraphLength, run.Attributes)); } } index++; } while (index < text.Runs.Count); return(index); }
public void DrawText(IAttributedText value, float x, float y, float width, float height) { _commands.Add(canvas => canvas.DrawText(value, x, y, width, height)); }