Skip to content

Instantly share code, notes, and snippets.

@maxkatz6
Created November 10, 2021 03:57
Show Gist options
  • Save maxkatz6/24be64ceb9e0b395caa11a69c725658a to your computer and use it in GitHub Desktop.
Save maxkatz6/24be64ceb9e0b395caa11a69c725658a to your computer and use it in GitHub Desktop.
TextBlockWithShadow
using Avalonia;
using Avalonia.Controls;
using Avalonia.Layout;
using Avalonia.Media;
using Avalonia.Media.Immutable;
using Avalonia.Media.TextFormatting;
namespace MyApp
{
public class TextBlockWithShadow : TextBlock
{
private TextLayout? _shadowLayout;
public static StyledProperty<IBrush?> ShadowBrushProperty =
AvaloniaProperty.Register<TextBlockWithShadow, IBrush?>(nameof(ShadowBrush), new ImmutableSolidColorBrush(Colors.Black, 0.44));
public IBrush? ShadowBrush
{
get => GetValue(ShadowBrushProperty);
set => SetValue(ShadowBrushProperty, value);
}
public static StyledProperty<double> ShadowXOffsetProperty =
AvaloniaProperty.Register<TextBlockWithShadow, double>(nameof(ShadowXOffset));
public double ShadowXOffset
{
get => GetValue(ShadowXOffsetProperty);
set => SetValue(ShadowXOffsetProperty, value);
}
public static StyledProperty<double> ShadowYOffsetProperty =
AvaloniaProperty.Register<TextBlockWithShadow, double>(nameof(ShadowYOffset), 2);
public double ShadowYOffset
{
get => GetValue(ShadowYOffsetProperty);
set => SetValue(ShadowYOffsetProperty, value);
}
public override void Render(DrawingContext context)
{
var background = Background;
if (background != null)
{
context.FillRectangle(background, new Rect(Bounds.Size));
}
if (TextLayout is null)
{
return;
}
var textAlignment = TextAlignment;
var width = Bounds.Size.Width;
var offsetX = 0.0;
switch (textAlignment)
{
case TextAlignment.Center:
offsetX = (width - TextLayout.Size.Width) / 2;
break;
case TextAlignment.Right:
offsetX = width - TextLayout.Size.Width;
break;
}
var padding = Padding;
var top = padding.Top;
var textSize = TextLayout.Size;
if (Bounds.Height < textSize.Height)
{
switch (VerticalAlignment)
{
case VerticalAlignment.Center:
top += (Bounds.Height - textSize.Height) / 2;
break;
case VerticalAlignment.Bottom:
top += (Bounds.Height - textSize.Height);
break;
}
}
using (context.PushPostTransform(Matrix.CreateTranslation(padding.Left + offsetX + ShadowXOffset, top + ShadowYOffset)))
{
_shadowLayout?.Draw(context);
}
using (context.PushPostTransform(Matrix.CreateTranslation(padding.Left + offsetX, top)))
{
TextLayout.Draw(context);
}
}
protected override TextLayout? CreateTextLayout(Size constraint, string text)
{
var layout = base.CreateTextLayout(constraint, text);
if (layout is null)
{
_shadowLayout = null;
return null;
}
_shadowLayout = new TextLayout(
text ?? string.Empty,
new Typeface(FontFamily, FontStyle, FontWeight),
FontSize,
ShadowBrush,
TextAlignment,
TextWrapping,
TextTrimming,
TextDecorations,
constraint.Width,
constraint.Height,
maxLines: MaxLines,
lineHeight: LineHeight);
return layout;
}
}
}
<local:TextBlockWithShadow Text="HELLO WORLD"
FontSize="60"
ShadowBrush="Green"
ShadowYOffset="10"
ShadowXOffset="10" />
@maxkatz6
Copy link
Author

Screen Shot 2021-11-09 at 10 57 56 PM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment