Поделиться через


Практическое руководство. Вывод текста по контуру

В большинстве случаев при добавлении орнаментации в текстовые строки в приложении Windows Presentation Foundation (WPF) используется текст с точки зрения коллекции дискретных символов, или глифов. Например, можно создать линейную градиентную кисть и применить ее к свойству Foreground объекта TextBox. При отображении или изменении текстового поля линейная градиентная кисть автоматически применяется к текущему набору символов в текстовой строке.

Text displayed with a linear gradient brush

Однако можно также преобразовать текст в объекты Geometry, что позволяет создавать другие типы форматированного текста. Например, можно создать объект Geometry, основанный на контуре строки текста.

Text outline using a linear gradient brush

Если текст преобразуется в объект Geometry, он больше не представляет собой коллекцию символов: изменить символы в текстовой строке невозможно. Тем не менее можно повлиять на внешний вид преобразованного текст, изменив его свойства штриха и заливки. Штрих — это контур преобразованного текста; заливка — это область внутри контура преобразованного текста.

В следующих примерах показаны несколько способов создания визуальных эффектов посредством изменения штриха и заливки преобразованного текста.

Text with different colors for fill and stroke

Text with image brush applied to stroke

Кроме того, можно изменить прямоугольник ограничивающего прямоугольника или выделение преобразованного текста. В следующем примере показан способ создания визуальных эффектов посредством изменения штриха и выделения преобразованного текста.

Text with image brush applied to stroke and highlight

Пример

Ключом к преобразованию текста в объект Geometry является использование объекта FormattedText. После создания этого объекта можно использовать методы BuildGeometry и BuildHighlightGeometry для преобразования текста в объекты Geometry. Первый метод возвращает геометрию форматированного текста; второй метод возвращает геометрию ограничивающего прямоугольника форматированного текста. В следующем примере кода показано, как создать объект FormattedText и получить геометрические объекты форматированного текста и его ограничивающего прямоугольника.

/// <summary>
/// Create the outline geometry based on the formatted text.
/// </summary>
public void CreateText()
{
    System.Windows.FontStyle fontStyle = FontStyles.Normal;
    FontWeight fontWeight = FontWeights.Medium;

    if (Bold == true) fontWeight = FontWeights.Bold;
    if (Italic == true) fontStyle = FontStyles.Italic;

    // Create the formatted text based on the properties set.
    FormattedText formattedText = new FormattedText(
        Text,
        CultureInfo.GetCultureInfo("en-us"),
        FlowDirection.LeftToRight,
        new Typeface(
            Font,
            fontStyle,
            fontWeight,
            FontStretches.Normal),
        FontSize,
        System.Windows.Media.Brushes.Black // This brush does not matter since we use the geometry of the text.
        );

    // Build the geometry object that represents the text.
    _textGeometry = formattedText.BuildGeometry(new System.Windows.Point(0, 0));

    // Build the geometry object that represents the text highlight.
    if (Highlight == true)
    {
        _textHighLightGeometry = formattedText.BuildHighlightGeometry(new System.Windows.Point(0, 0));
    }
}
''' <summary>
''' Create the outline geometry based on the formatted text.
''' </summary>
Public Sub CreateText()
    Dim fontStyle As FontStyle = FontStyles.Normal
    Dim fontWeight As FontWeight = FontWeights.Medium

    If Bold = True Then
        fontWeight = FontWeights.Bold
    End If
    If Italic = True Then
        fontStyle = FontStyles.Italic
    End If

    ' Create the formatted text based on the properties set.
    Dim formattedText As New FormattedText(Text, CultureInfo.GetCultureInfo("en-us"), FlowDirection.LeftToRight, New Typeface(Font, fontStyle, fontWeight, FontStretches.Normal), FontSize, Brushes.Black) ' This brush does not matter since we use the geometry of the text.

    ' Build the geometry object that represents the text.
    _textGeometry = formattedText.BuildGeometry(New Point(0, 0))

    ' Build the geometry object that represents the text highlight.
    If Highlight = True Then
        _textHighLightGeometry = formattedText.BuildHighlightGeometry(New Point(0, 0))
    End If
End Sub

Чтобы отобразить полученные объекты Geometry, необходимо получить доступ к объекту DrawingContext, отображающему преобразованный текст. В этих примерах кода такой доступ достигается путем создания объекта пользовательского элемента управления, производного от класса, который поддерживает определяемую пользователем отрисовку.

Чтобы отобразить объекты Geometry в пользовательском элементе управления, предоставьте переопределение для метода OnRender. Переопределенный метод должен использовать метод DrawGeometry для рисования объектов Geometry.

/// <summary>
/// OnRender override draws the geometry of the text and optional highlight.
/// </summary>
/// <param name="drawingContext">Drawing context of the OutlineText control.</param>
protected override void OnRender(DrawingContext drawingContext)
{
    // Draw the outline based on the properties that are set.
    drawingContext.DrawGeometry(Fill, new System.Windows.Media.Pen(Stroke, StrokeThickness), _textGeometry);

    // Draw the text highlight based on the properties that are set.
    if (Highlight == true)
    {
        drawingContext.DrawGeometry(null, new System.Windows.Media.Pen(Stroke, StrokeThickness), _textHighLightGeometry);
    }
}
''' <summary>
''' OnRender override draws the geometry of the text and optional highlight.
''' </summary>
''' <param name="drawingContext">Drawing context of the OutlineText control.</param>
Protected Overrides Sub OnRender(ByVal drawingContext As DrawingContext)
    ' Draw the outline based on the properties that are set.
    drawingContext.DrawGeometry(Fill, New Pen(Stroke, StrokeThickness), _textGeometry)

    ' Draw the text highlight based on the properties that are set.
    If Highlight = True Then
        drawingContext.DrawGeometry(Nothing, New Pen(Stroke, StrokeThickness), _textHighLightGeometry)
    End If
End Sub

Источник примера объекта пользовательского элемента управления см. на страницах OutlineTextControl.cs для C# и OutlineTextControl.vb для Visual Basic.

См. также