csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
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.
215 lines
8.4 KiB
215 lines
8.4 KiB
using Avalonia.Collections;
|
|
using Avalonia.Media.TextFormatting;
|
|
|
|
namespace Avalonia.Media
|
|
{
|
|
/// <summary>
|
|
/// Represents a text decoration, which is a visual ornamentation that is added to text (such as an underline).
|
|
/// </summary>
|
|
public class TextDecoration : AvaloniaObject
|
|
{
|
|
/// <summary>
|
|
/// Defines the <see cref="Location"/> property.
|
|
/// </summary>
|
|
public static readonly StyledProperty<TextDecorationLocation> LocationProperty =
|
|
AvaloniaProperty.Register<TextDecoration, TextDecorationLocation>(nameof(Location));
|
|
|
|
/// <summary>
|
|
/// Defines the <see cref="Stroke"/> property.
|
|
/// </summary>
|
|
public static readonly StyledProperty<IBrush> StrokeProperty =
|
|
AvaloniaProperty.Register<TextDecoration, IBrush>(nameof(Stroke));
|
|
|
|
/// <summary>
|
|
/// Defines the <see cref="StrokeThicknessUnit"/> property.
|
|
/// </summary>
|
|
public static readonly StyledProperty<TextDecorationUnit> StrokeThicknessUnitProperty =
|
|
AvaloniaProperty.Register<TextDecoration, TextDecorationUnit>(nameof(StrokeThicknessUnit));
|
|
|
|
/// <summary>
|
|
/// Defines the <see cref="StrokeDashArray"/> property.
|
|
/// </summary>
|
|
public static readonly StyledProperty<AvaloniaList<double>> StrokeDashArrayProperty =
|
|
AvaloniaProperty.Register<TextDecoration, AvaloniaList<double>>(nameof(StrokeDashArray));
|
|
|
|
/// <summary>
|
|
/// Defines the <see cref="StrokeDashOffset"/> property.
|
|
/// </summary>
|
|
public static readonly StyledProperty<double> StrokeDashOffsetProperty =
|
|
AvaloniaProperty.Register<TextDecoration, double>(nameof(StrokeDashOffset));
|
|
|
|
/// <summary>
|
|
/// Defines the <see cref="StrokeThickness"/> property.
|
|
/// </summary>
|
|
public static readonly StyledProperty<double> StrokeThicknessProperty =
|
|
AvaloniaProperty.Register<TextDecoration, double>(nameof(StrokeThickness), 1);
|
|
|
|
/// <summary>
|
|
/// Defines the <see cref="StrokeLineCap"/> property.
|
|
/// </summary>
|
|
public static readonly StyledProperty<PenLineCap> StrokeLineCapProperty =
|
|
AvaloniaProperty.Register<TextDecoration, PenLineCap>(nameof(StrokeLineCap));
|
|
|
|
/// <summary>
|
|
/// Defines the <see cref="StrokeOffset"/> property.
|
|
/// </summary>
|
|
public static readonly StyledProperty<double> StrokeOffsetProperty =
|
|
AvaloniaProperty.Register<TextDecoration, double>(nameof(StrokeOffset));
|
|
|
|
/// <summary>
|
|
/// Defines the <see cref="StrokeOffsetUnit"/> property.
|
|
/// </summary>
|
|
public static readonly StyledProperty<TextDecorationUnit> StrokeOffsetUnitProperty =
|
|
AvaloniaProperty.Register<TextDecoration, TextDecorationUnit>(nameof(StrokeOffsetUnit));
|
|
|
|
/// <summary>
|
|
/// Gets or sets the location.
|
|
/// </summary>
|
|
/// <value>
|
|
/// The location.
|
|
/// </value>
|
|
public TextDecorationLocation Location
|
|
{
|
|
get => GetValue(LocationProperty);
|
|
set => SetValue(LocationProperty, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the <see cref="IBrush"/> that specifies how the <see cref="TextDecoration"/> is painted.
|
|
/// </summary>
|
|
public IBrush Stroke
|
|
{
|
|
get { return GetValue(StrokeProperty); }
|
|
set { SetValue(StrokeProperty, value); }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the units in which the thickness of the <see cref="TextDecoration"/> is expressed.
|
|
/// </summary>
|
|
public TextDecorationUnit StrokeThicknessUnit
|
|
{
|
|
get => GetValue(StrokeThicknessUnitProperty);
|
|
set => SetValue(StrokeThicknessUnitProperty, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets a collection of <see cref="double"/> values that indicate the pattern of dashes and gaps
|
|
/// that is used to draw the <see cref="TextDecoration"/>.
|
|
/// </summary>
|
|
public AvaloniaList<double> StrokeDashArray
|
|
{
|
|
get { return GetValue(StrokeDashArrayProperty); }
|
|
set { SetValue(StrokeDashArrayProperty, value); }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value that specifies the distance within the dash pattern where a dash begins.
|
|
/// </summary>
|
|
public double StrokeDashOffset
|
|
{
|
|
get { return GetValue(StrokeDashOffsetProperty); }
|
|
set { SetValue(StrokeDashOffsetProperty, value); }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the thickness of the <see cref="TextDecoration"/>.
|
|
/// </summary>
|
|
public double StrokeThickness
|
|
{
|
|
get { return GetValue(StrokeThicknessProperty); }
|
|
set { SetValue(StrokeThicknessProperty, value); }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets a <see cref="PenLineCap"/> enumeration value that describes the shape at the ends of a line.
|
|
/// </summary>
|
|
public PenLineCap StrokeLineCap
|
|
{
|
|
get { return GetValue(StrokeLineCapProperty); }
|
|
set { SetValue(StrokeLineCapProperty, value); }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The stroke's offset.
|
|
/// </summary>
|
|
/// <value>
|
|
/// The pen offset.
|
|
/// </value>
|
|
public double StrokeOffset
|
|
{
|
|
get => GetValue(StrokeOffsetProperty);
|
|
set => SetValue(StrokeOffsetProperty, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the units in which the <see cref="StrokeOffset"/> value is expressed.
|
|
/// </summary>
|
|
public TextDecorationUnit StrokeOffsetUnit
|
|
{
|
|
get => GetValue(StrokeOffsetUnitProperty);
|
|
set => SetValue(StrokeOffsetUnitProperty, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Draws the <see cref="TextDecoration"/> at given origin.
|
|
/// </summary>
|
|
/// <param name="drawingContext">The drawing context.</param>
|
|
/// <param name="glyphRun">The decorated run.</param>
|
|
/// <param name="fontMetrics">The font metrics of the decorated run.</param>
|
|
/// <param name="defaultBrush">The default brush that is used to draw the decoration.</param>
|
|
internal void Draw(DrawingContext drawingContext, GlyphRun glyphRun, FontMetrics fontMetrics, IBrush defaultBrush)
|
|
{
|
|
var baselineOrigin = glyphRun.BaselineOrigin;
|
|
var thickness = StrokeThickness;
|
|
|
|
switch (StrokeThicknessUnit)
|
|
{
|
|
case TextDecorationUnit.FontRecommended:
|
|
switch (Location)
|
|
{
|
|
case TextDecorationLocation.Underline:
|
|
thickness = fontMetrics.UnderlineThickness;
|
|
break;
|
|
case TextDecorationLocation.Strikethrough:
|
|
thickness = fontMetrics.StrikethroughThickness;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
case TextDecorationUnit.FontRenderingEmSize:
|
|
thickness = fontMetrics.FontRenderingEmSize * thickness;
|
|
break;
|
|
}
|
|
|
|
var origin = new Point();
|
|
|
|
switch (Location)
|
|
{
|
|
case TextDecorationLocation.Baseline:
|
|
origin += glyphRun.BaselineOrigin;
|
|
break;
|
|
case TextDecorationLocation.Strikethrough:
|
|
origin += new Point(baselineOrigin.X, baselineOrigin.Y + fontMetrics.StrikethroughPosition);
|
|
break;
|
|
case TextDecorationLocation.Underline:
|
|
origin += new Point(baselineOrigin.X, baselineOrigin.Y + fontMetrics.UnderlinePosition);
|
|
break;
|
|
}
|
|
|
|
switch (StrokeOffsetUnit)
|
|
{
|
|
case TextDecorationUnit.FontRenderingEmSize:
|
|
origin += new Point(0, StrokeOffset * fontMetrics.FontRenderingEmSize);
|
|
break;
|
|
case TextDecorationUnit.Pixel:
|
|
origin += new Point(0, StrokeOffset);
|
|
break;
|
|
}
|
|
|
|
var pen = new Pen(Stroke ?? defaultBrush, thickness,
|
|
new DashStyle(StrokeDashArray, StrokeDashOffset), StrokeLineCap);
|
|
|
|
drawingContext.DrawLine(pen, origin, origin + new Point(glyphRun.Metrics.Width, 0));
|
|
}
|
|
}
|
|
}
|
|
|