public Stream GetFilledCircleWithCenteredText(int imgSize, string rgbCircleColor, string txt, string rgbTextColor, string fontFamilyName, int fontSize) { Stream result = null; using (UIImage image = new UIImage()) { UIGraphics.BeginImageContext(new SizeF(imgSize, imgSize)); CGRect rect = new CGRect(0, 0, imgSize, imgSize); image.Draw(rect); using (CGContext g = UIGraphics.GetCurrentContext()) { float x = (float)(rect.X + (rect.Width / 2)); float y = (float)(rect.Y + (rect.Height / 2)); // Draws the circle UIColor background = FromHexString(rgbCircleColor); g.SetLineWidth(1); g.SetFillColor(background.CGColor); g.SetStrokeColor(background.CGColor); CGPath path = new CGPath(); path.AddArc(x, y, NMath.Min(rect.Width, rect.Height) / 2 - 1f, 0, 2.0f * (float)Math.PI, true); g.AddPath(path); g.DrawPath((CGPathDrawingMode.FillStroke)); // Draws the text g.SetFillColor(FromHexString(rgbTextColor).CGColor); var attributedString = new NSAttributedString(txt, new CoreText.CTStringAttributes { ForegroundColorFromContext = true, Font = new CoreText.CTFont(fontFamilyName, fontSize * 2) }); using (var textLine = new CoreText.CTLine(attributedString)) { g.TranslateCTM(x - (textLine.GetBounds(CoreText.CTLineBoundsOptions.UseGlyphPathBounds).Width / 2), y + (textLine.GetBounds(CoreText.CTLineBoundsOptions.UseGlyphPathBounds).Height / 2)); g.ScaleCTM(1, -1); textLine.Draw(g); } } var resultImage = UIGraphics.GetImageFromCurrentImageContext(); UIGraphics.EndImageContext(); NSData data = resultImage.AsPNG(); result = data.AsStream(); } return(result); }
// using the attributes of SKPaint paint parameter: //Typeface, //TextSize, //TextAlign(Center|Left), //Style(Fill|Stroke), //Color, //StrokeWidth(if Style=Stroke) public static CGSize DrawTextS(CGContext canvas, string text, SKPoint point, SKPaint paint) { // BASIC TEXT DRAWING IN CGContext: //canvas.SetTextDrawingMode(toCGTextDrawingMode(paint.Style)); //canvas.SetFillColor(CGUtil.toCGColor(paint.Color)); //canvas.SetStrokeColor(CGUtil.toCGColor(paint.Color)); //canvas.SetLineWidth(paint.StrokeWidth); //canvas.SelectFont("Helvetica", paint.TextSize, CGTextEncoding.MacRoman); //// upsidedown text: https://stackoverflow.com/questions/44122778/ios-swift-core-graphics-string-is-upside-down //canvas.SaveState(); //canvas.TranslateCTM(center.X, center.Y); // text should be centered, but isn't //canvas.ScaleCTM(1, -1); //canvas.ShowTextAtPoint(0, 0, text); //canvas.RestoreState(); // TEXT DRAWING IN CoreText to compute text size: // https://docs.microsoft.com/en-us/dotnet/api/foundation.nsattributedstring?view=xamarin-ios-sdk-12 var typeface = (paint.Typeface == null) ? "Helvetica" : paint.Typeface.FamilyName; var attributedString = new Foundation.NSAttributedString(text, new CoreText.CTStringAttributes() { ForegroundColor = Color(paint.Color), // ForegroundColor is used (only?) if paint.Style = Fill, and overrides paint.Color Font = new CoreText.CTFont(typeface, paint.TextSize) }); var textLine = new CoreText.CTLine(attributedString); CGSize textSize = attributedString.Size; // maybe we can extract the true baseline origin and return a Rect instead of a Size? bool centered = paint.TextAlign == SKTextAlign.Center; CGPoint textStart = (centered) ? new CGPoint(point.X - textSize.Width / 2.0f, point.Y) : Point(point); canvas.SetTextDrawingMode(CG.TextDrawingMode(paint.Style)); canvas.SetStrokeColor(CG.Color(paint.Color)); // paint.Color is used (only?) if paint.Style = Stroke canvas.SetLineWidth(paint.StrokeWidth); // upsidedown text: https://stackoverflow.com/questions/44122778/ios-swift-core-graphics-string-is-upside-down canvas.SaveState(); canvas.TranslateCTM(textStart.X, textStart.Y); canvas.ScaleCTM(1, -1); canvas.TextPosition = new CGPoint(0, 0); // because of the translation textLine.Draw(canvas); canvas.RestoreState(); return(textSize); }