using System.Diagnostics; using SkiaSharp; using SkiaSharp.Views.Maui; namespace ex_OutlineText.Views; public partial class LabelOutline : ContentView { public LabelOutline() { InitializeComponent(); } public static readonly BindableProperty TextProperty = BindableProperty.Create(nameof(Text), typeof(string), typeof(LabelOutline), "something", propertyChanged: (b, ov, nv) => (b as LabelOutline)?.canvasView.InvalidateSurface()); public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } } public static readonly BindableProperty FillProperty = BindableProperty.Create(nameof(Fill), typeof(Color), typeof(LabelOutline), Colors.DarkSalmon, propertyChanged: (b, ov, nv) => (b as LabelOutline)?.canvasView.InvalidateSurface()); public Color Fill { get { return (Color)GetValue(FillProperty); } set { SetValue(FillProperty, value); } } public static readonly BindableProperty StrokeProperty = BindableProperty.Create(nameof(Stroke), typeof(Color), typeof(LabelOutline), Colors.DarkSalmon, propertyChanged: (b, ov, nv) => (b as LabelOutline)?.canvasView.InvalidateSurface()); public Color Stroke { get { return (Color)GetValue(StrokeProperty); } set { SetValue(StrokeProperty, value); } } public static readonly BindableProperty StrokeWidthProperty = BindableProperty.Create(nameof(StrokeWidth), typeof(float), typeof(LabelOutline), 1.0f, propertyChanged: (b, ov, nv) => (b as LabelOutline)?.canvasView.InvalidateSurface()); public float StrokeWidth { get { return (float)GetValue(StrokeWidthProperty); } set { SetValue(StrokeWidthProperty, value); } } public static readonly BindableProperty FontFamilyProperty = BindableProperty.Create(nameof(FontFamily), typeof(string), typeof(LabelOutline), "something", propertyChanged: (b, ov, nv) => (b as LabelOutline)?.canvasView.InvalidateSurface()); public string FontFamily { get { return (string)GetValue(FontFamilyProperty); } set { SetValue(FontFamilyProperty, value); } } public static readonly BindableProperty TextSizeProperty = BindableProperty.Create(nameof(TextSize), typeof(float), typeof(LabelOutline), 24.0f, propertyChanged: (b, ov, nv) => (b as LabelOutline)?.canvasView.InvalidateSurface()); public float TextSize { get { return (float)GetValue(TextSizeProperty); } set { SetValue(TextSizeProperty, value); } } public static readonly BindableProperty AspectProperty = BindableProperty.Create(nameof(Aspect), typeof(Aspect), typeof(LabelOutline), Aspect.Center, propertyChanged: (b, ov, nv) => (b as LabelOutline)?.canvasView.InvalidateSurface()); public Aspect Aspect { get { return (Aspect)GetValue(AspectProperty); } set { SetValue(AspectProperty, value); } } public static readonly BindableProperty RatioProperty = BindableProperty.Create(nameof(Ratio), typeof(float), typeof(LabelOutline), 0.95f, propertyChanged: (b, ov, nv) => (b as LabelOutline)?.canvasView.InvalidateSurface()); public float Ratio { get { return (float)GetValue(RatioProperty); } set { SetValue(RatioProperty, value); } } private void OnPainting(object sender, SKPaintSurfaceEventArgs args) { SKImageInfo info = args.Info; SKCanvas canvas = args.Surface.Canvas; canvas.Clear(); // Create an SKPaint object to display the text SKPaint textPaint = new SKPaint { Style = SKPaintStyle.Fill, StrokeWidth = StrokeWidth, FakeBoldText = true, Typeface = SKTypeface.FromFamilyName(FontFamily), Color = Fill.ToSKColor(), TextSize = TextSize }; switch(Aspect) { case Aspect.AspectFit: float textHeight = Ratio * info.Height; float textWidth2 = textPaint.MeasureText(Text); textWidth2 = Ratio * info.Width * textPaint.TextSize / textWidth2; textPaint.TextSize = Math.Min(textHeight, textWidth2); break; case Aspect.AspectFill: case Aspect.Fill: float textWidth = textPaint.MeasureText(Text); textPaint.TextSize = Ratio * info.Width * textPaint.TextSize / textWidth; break; case Aspect.Center: default: break; } // Find the text bounds SKRect textBounds = new SKRect(); textPaint.MeasureText(Text, ref textBounds); // Calculate offsets to center the text on the screen float xText = info.Width / 2 - textBounds.MidX; float yText = info.Height / 2 - textBounds.MidY; // And draw the text canvas.DrawText(Text, xText, yText, textPaint); if(StrokeWidth > 0.0f) { textPaint.Style = SKPaintStyle.Stroke; textPaint.Color = Stroke.ToSKColor(); canvas.DrawText(Text, xText, yText, textPaint); } } }