方法: 中抜きの文字列を作成する

ほとんどの場合、Windows Presentation Foundation (WPF) アプリケーションでテキスト文字列に装飾を追加するときは、不連続の文字またはグリフのコレクションという観点でテキストを使用します。 たとえば、線状グラデーション ブラシを作成し、TextBox オブジェクトの Foreground プロパティにそれを適用します。 テキスト ボックスを表示または編集すると、テキスト文字列内の現在の文字セットに線状グラデーション ブラシが自動的に適用されます。

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 オブジェクトに変換できます。 最初のメソッドでは、書式設定されたテキストのジオメトリが返されます。2 番目のメソッドでは、書式設定されたテキストの境界ボックスのジオメトリが返されます。 次のコード例では、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

カスタム ユーザー コントロール オブジェクトの例のソースについては、C# の場合は OutlineTextControl.cs を、Visual Basic の場合は OutlineTextControl.vb を参照してください。

関連項目