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.

170 lines
5.5 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");
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);
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);
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);
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");
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);
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);
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);
public float Ratio
{
get { return (float)GetValue(RatioProperty); }
set { SetValue(RatioProperty, value); }
}
private void OnPainting(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
string text = Text;
// 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);
Console.WriteLine($"info.Width: {info.Width} ; info.Height: {info.Height} ; textPaint.TextSize: {textPaint.TextSize} ; textHeight: {textHeight} ; textWidth: {textWidth2}");
break;
case Aspect.AspectFill:
case Aspect.Fill:
float textWidth = textPaint.MeasureText(text);
textPaint.TextSize = Ratio * info.Width * textPaint.TextSize / textWidth;
Console.WriteLine($"info.Width: {info.Width} ; info.Height: {info.Height} ; textPaint.TextSize: {textPaint.TextSize}");
break;
case Aspect.Center:
default:
break;
}
// Adjust TextSize property so text is 95% of screen width
// float textWidth = textPaint.MeasureText(text);
// textPaint.TextSize = 0.95f * info.Width * textPaint.TextSize / textWidth;
// 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);
textPaint.Style = SKPaintStyle.Stroke;
textPaint.Color = Stroke.ToSKColor();
canvas.DrawText(text, xText, yText, textPaint);
}
}