You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
5.7 KiB

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);
}
}
}