WPFで文字の縁取りをする

デフォルトで縁取りの設定があればいいのになぁ

こんにちは!

芸人のヒロシさんの趣味「ソロキャンプ」にすごく憧れを感じているのですが、 そもそも外に出たくないあらたまです!

今日はWPFアプリケーションにおけるテキスト縁取りのお話です。

テキストの縁取りをする

WPFでテキストの縁取り(アウトライン)をしたい場合、TextBlockの該当プロパティにTrueを入れて、ちょちょいっと

。。て思ったのですが、無いんですね、そんなプロパティ。。

で、参考にしたのが下記のMicrosoftさんのページ。

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


public void CreateText()
{
    ... 省略 ...

    // 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
        );

    // テキストからジオメトリを作成する
    _textGeometry = formattedText.BuildGeometry(new System.Windows.Point(0, 0));

    ... 省略 ...
}

protected override void OnRender(DrawingContext drawingContext)
{
    // 作成したジオメトリを描画する(第二引数が縁取りの色と太さ)
    drawingContext.DrawGeometry(Fill, new System.Windows.Media.Pen(Stroke, StrokeThickness), _textGeometry);

    ... 省略 ...
}
    

縁取りが乱れる!?

上記でひとまず縁取りを実装したのですが、フォントの種類や文字によって縁取りが崩れるんですよね。。

※「入」と「さ」の縁取りが乱れている

解決策としては、縁取りを描画するときのPenオブジェクトの LineJoinプロパティにPenLineJoin.Roundを設定するようにしました。


protected override void OnRender(DrawingContext drawingContext)
{
    Pen pen = new Pen(this.Stroke, this.StrokeThickness);
    pen.LineJoin = PenLineJoin.Round;

    // 作成したジオメトリを描画する(第二引数が縁取りの色と太さ)
    drawingContext.DrawGeometry(null, pen, _textGeometry);
    drawingContext.DrawGeometry(this.Fill, null, _textGeometry);

    ... 省略 ...
}    

これで無事、きれいに文字の縁取りができました!