private void UpdateFormattedText() { if (Element?.FormattedText == null) { return; } var extensionType = typeof(FormattedStringExtensions); var type = extensionType.GetNestedType("FontSpan", BindingFlags.NonPublic); var ss = new SpannableString(Control.TextFormatted); var spans = ss.GetSpans(0, ss.ToString().Length, Class.FromType(type)); foreach (var span in spans) { var font = (Font)type.GetProperty("Font").GetValue(span, null); if ((font.FontFamily ?? Element.FontFamily) != null) { var start = ss.GetSpanStart(span); var end = ss.GetSpanEnd(span); var flags = ss.GetSpanFlags(span); ss.RemoveSpan(span); var newSpan = new CustomTypefaceSpan(Control, Element, font); ss.SetSpan(newSpan, start, end, flags); } } Control.TextFormatted = ss; }
private Object[] GetSpans <T>(SpannableString?spannable, TextRange textRange) { return(spannable?.GetSpans( textRange.Position, textRange.Position + textRange.Length, Java.Lang.Class.FromType(typeof(T))) ?? new Object[] { }); }
private static SpannableString AddImages(PostDataObject item, Context context, SpannableString spendable) { try { //Regex pattern that looks for embedded images of the format: [img src=imageName/] //exp. This [img src=imageName/] is an icon. Pattern refImg = Pattern.Compile("\\Q[img src=\\E([a-zA-Z0-9_]+?)\\Q/]\\E"); //bool hasChanges = false; Matcher matcher = refImg.Matcher(spendable); while (matcher.Find()) { bool set = true; foreach (var span in spendable.GetSpans(matcher.Start(), matcher.End(), Class.FromType(typeof(ImageSpan)))) { if (spendable.GetSpanStart(span) >= matcher.Start() && spendable.GetSpanEnd(span) <= matcher.End()) { spendable.RemoveSpan(span); } else { set = false; break; } } if (set) { string resName = spendable.SubSequence(matcher.Start(1), matcher.End(1))?.Trim(); int id = context.Resources.GetIdentifier(resName, "drawable", context.PackageName); var d = ContextCompat.GetDrawable(context, id); if (d != null) { d.SetBounds(0, 0, d.IntrinsicWidth, d.IntrinsicHeight); spendable.SetSpan(new ImageSpan(d, SpanAlign.Baseline), matcher.Start(), matcher.End(), SpanTypes.ExclusiveExclusive); } else { spendable.SetSpan(new ImageSpan(context, id, SpanAlign.Baseline), matcher.Start(), matcher.End(), SpanTypes.ExclusiveExclusive); } //hasChanges = true; } } var username = WoWonderTools.GetNameFinal(Publisher); SetTextStyle(spendable, username, TypefaceStyle.Bold); if (spendable.ToString() !.Contains(context.GetText(Resource.String.Lbl_ChangedProfileCover))) { SetTextColor(spendable, context.GetText(Resource.String.Lbl_ChangedProfileCover), "#888888"); } else if (spendable.ToString() !.Contains(context.GetText(Resource.String.Lbl_ChangedProfilePicture))) { SetTextColor(spendable, context.GetText(Resource.String.Lbl_ChangedProfilePicture), "#888888"); }
public static void RecalculateSpanPositions(this TextView textView, Label element, SpannableString spannableString, SizeRequest finalSize) { if (element?.FormattedText?.Spans == null || element.FormattedText.Spans.Count == 0) { return; } var labelWidth = finalSize.Request.Width; if (labelWidth <= 0 || finalSize.Request.Height <= 0) { return; } if (spannableString == null || spannableString.IsDisposed()) { return; } var layout = textView.Layout; if (layout == null) { return; } int next = 0; int count = 0; IList <int> totalLineHeights = new List <int>(); for (int i = 0; i < spannableString.Length(); i = next) { var type = Java.Lang.Class.FromType(typeof(Java.Lang.Object)); var span = element.FormattedText.Spans[count]; count++; if (string.IsNullOrEmpty(span.Text)) { continue; } // find the next span next = spannableString.NextSpanTransition(i, spannableString.Length(), type); // get all spans in the range - Android can have overlapping spans var spans = spannableString.GetSpans(i, next, type); var startSpan = spans[0]; var endSpan = spans[spans.Length - 1]; var startSpanOffset = spannableString.GetSpanStart(startSpan); var endSpanOffset = spannableString.GetSpanEnd(endSpan); var thisLine = layout.GetLineForOffset(endSpanOffset); var lineStart = layout.GetLineStart(thisLine); var lineEnd = layout.GetLineEnd(thisLine); //If this is true, endSpanOffset has the value for another line that belong to the next span and not it self. //So it should be rearranged to value not pass the lineEnd. if (endSpanOffset > (lineEnd - lineStart)) { endSpanOffset = lineEnd; } var startX = layout.GetPrimaryHorizontal(startSpanOffset); var endX = layout.GetPrimaryHorizontal(endSpanOffset); var startLine = layout.GetLineForOffset(startSpanOffset); var endLine = layout.GetLineForOffset(endSpanOffset); double[] lineHeights = new double[endLine - startLine + 1]; // calculate all the different line heights for (var lineCount = startLine; lineCount <= endLine; lineCount++) { var lineHeight = layout.GetLineBottom(lineCount) - layout.GetLineTop(lineCount); lineHeights[lineCount - startLine] = lineHeight; if (totalLineHeights.Count <= lineCount) { totalLineHeights.Add(lineHeight); } } var yaxis = 0.0; for (var line = startLine; line > 0; line--) { yaxis += totalLineHeights[line]; } ((ISpatialElement)span).Region = Region.FromLines(lineHeights, labelWidth, startX, endX, yaxis).Inflate(10); } }
private static bool AddImages(Context context, SpannableString spannable) { string pattern = "\\Q[img src=\\E([a-zA-Z0-9_]+?)\\Q/]\\E"; //MatchCollection m = Regex.Matches(spannable, pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase); //foreach (Match match in m) // Console.WriteLine("{0} (duplicates '{1}') at position {2}", match.Value, match.Groups[1].Value, match.Index); Java.Util.Regex.Pattern refImg = Java.Util.Regex.Pattern.Compile(pattern); bool hasChanges = false; Matcher matcher = refImg.Matcher(spannable); while (matcher.Find()) { bool set = true; foreach (ImageSpan span in spannable.GetSpans(matcher.Start(), matcher.End(), Java.Lang.Class.FromType(typeof(ImageSpan)))) { if (spannable.GetSpanStart(span) >= matcher.Start() && spannable.GetSpanEnd(span) <= matcher.End()) { spannable.RemoveSpan(span); } else { set = false; break; } } string resname = spannable.SubSequence(matcher.Start(1), matcher.End(1)).ToString().Trim(); //int id = context.Resources.GetIdentifier(resname, "drawable", context.PackageName); if (set) { hasChanges = true; int identifier = context.Resources.GetIdentifier("modezoneedit", "drawable", context.PackageName); bool isSvg = true; Bitmap bitmap2 = null; if (isSvg) { SvgBitmapDrawable oo = SvgFactory.GetDrawable(context.Resources, identifier); //oo.Mutate().SetColorFilter(0xffff0000, Android.Graphics.PorterDuff.Mode.Multiply); Bitmap bitmap = Bitmap.CreateBitmap(oo.Picture.Width, oo.Picture.Height, Bitmap.Config.Argb8888); Canvas canvas = new Canvas(bitmap); canvas.DrawPicture(oo.Picture); bitmap2 = Bitmap.CreateScaledBitmap(bitmap, (int)(bitmap.Width * 0.3), (int)(bitmap.Height * 0.3), false); } else { bitmap2 = BitmapFactory.DecodeResource(context.Resources, identifier); bitmap2 = Bitmap.CreateScaledBitmap(bitmap2, (int)(bitmap2.Width * 0.3), (int)(bitmap2.Height * 0.3), false); } ImageSpan span = new ImageSpan(context, bitmap2); spannable.SetSpan(span, matcher.Start(), matcher.End(), SpanTypes.ExclusiveExclusive); /*spannable.SetSpan(new ImageSpan(context, id), * matcher.Start(), * matcher.End(), * SpanTypes.ExclusiveExclusive * );*/ } //if (isLastPoint) canvas.DrawColor(Color.Green, PorterDuff.Mode.SrcAtop); //Bitmap b = BitmapFactory.DecodeResource(context.Resources, Resource.Drawable.ModeZoneEdit); } return(hasChanges); }
private static void AddImages(PostDataObject item, Context context, SpannableString spendable) { try { //Regex pattern that looks for embedded images of the format: [img src=imageName/] //exp. This [img src=imageName/] is an icon. Pattern refImg = Pattern.Compile("\\Q[img src=\\E([a-zA-Z0-9_]+?)\\Q/]\\E"); //bool hasChanges = false; Matcher matcher = refImg.Matcher(spendable); while (matcher.Find()) { bool set = true; foreach (var span in spendable.GetSpans(matcher.Start(), matcher.End(), Class.FromType(typeof(ImageSpan)))) { if (spendable.GetSpanStart(span) >= matcher.Start() && spendable.GetSpanEnd(span) <= matcher.End()) { spendable.RemoveSpan(span); } else { set = false; break; } } if (set) { string resName = spendable.SubSequence(matcher.Start(1), matcher.End(1)).Trim(); int id = context.Resources.GetIdentifier(resName, "drawable", context.PackageName); var d = ContextCompat.GetDrawable(context, id); if (d != null) { d.SetBounds(0, 0, d.IntrinsicWidth, d.IntrinsicHeight); spendable.SetSpan(new ImageSpan(d, SpanAlign.Baseline), matcher.Start(), matcher.End(), SpanTypes.ExclusiveExclusive); } else { spendable.SetSpan(new ImageSpan(context, id, SpanAlign.Baseline), matcher.Start(), matcher.End(), SpanTypes.ExclusiveExclusive); } //hasChanges = true; } } var username = WoWonderTools.GetNameFinal(Publisher); SetTextStyle(spendable, username, TypefaceStyle.Bold); if (spendable.ToString().Contains(context.GetText(Resource.String.Lbl_ChangedProfileCover))) { SetTextColor(spendable, context.GetText(Resource.String.Lbl_ChangedProfileCover), "#888888"); } else if (spendable.ToString().Contains(context.GetText(Resource.String.Lbl_ChangedProfilePicture))) { SetTextColor(spendable, context.GetText(Resource.String.Lbl_ChangedProfilePicture), "#888888"); } else if (spendable.ToString().Contains(context.GetText(Resource.String.Lbl_WasLive))) { SetTextColor(spendable, context.GetText(Resource.String.Lbl_WasLive), "#888888"); } else if (spendable.ToString().Contains(context.GetText(Resource.String.Lbl_IsListeningTo))) { SetTextColor(spendable, context.GetText(Resource.String.Lbl_IsListeningTo), "#888888"); } else if (spendable.ToString().Contains(context.GetText(Resource.String.Lbl_IsPlaying))) { SetTextColor(spendable, context.GetText(Resource.String.Lbl_IsPlaying), "#888888"); } else if (spendable.ToString().Contains(context.GetText(Resource.String.Lbl_IsTravelingTo))) { SetTextColor(spendable, context.GetText(Resource.String.Lbl_IsTravelingTo), "#888888"); } else if (spendable.ToString().Contains(context.GetText(Resource.String.Lbl_IsWatching))) { SetTextColor(spendable, context.GetText(Resource.String.Lbl_IsWatching), "#888888"); } else if (spendable.ToString().Contains(context.GetText(Resource.String.Lbl_AddedNewProductForSell))) { SetTextColor(spendable, context.GetText(Resource.String.Lbl_AddedNewProductForSell), "#888888"); } else if (spendable.ToString().Contains(context.GetText(Resource.String.Lbl_CreatedNewArticle))) { SetTextColor(spendable, context.GetText(Resource.String.Lbl_CreatedNewArticle), "#888888"); } else if (spendable.ToString().Contains(context.GetText(Resource.String.Lbl_CreatedNewEvent)) || (item.Event?.EventClass != null && item.SharedInfo.SharedInfoClass == null)) { SetTextColor(spendable, context.GetText(Resource.String.Lbl_CreatedNewEvent), "#888888"); SetTextColor(spendable, Methods.FunString.DecodeString(item.Event?.EventClass.Name), "#888888"); } else if (spendable.ToString().Contains(context.GetText(Resource.String.Lbl_addedNewPhotosTo))) { SetTextColor(spendable, context.GetText(Resource.String.Lbl_addedNewPhotosTo), "#888888"); } else if (spendable.ToString().Contains(context.GetText(Resource.String.Lbl_CreatedNewFund))) { SetTextColor(spendable, context.GetText(Resource.String.Lbl_CreatedNewFund), "#888888"); } else if (spendable.ToString().Contains(context.GetText(Resource.String.Lbl_OfferPostAdded))) { SetTextColor(spendable, context.GetText(Resource.String.Lbl_OfferPostAdded), "#888888"); } else if (spendable.ToString().Contains(context.GetText(Resource.String.Lbl_SharedPost))) { SetTextColor(spendable, context.GetText(Resource.String.Lbl_SharedPost), "#888888"); } //return hasChanges; } catch (Exception e) { Console.WriteLine(e); } }