views:

457

answers:

1

I want to create wavy underlines using TextDecoration (in a control similar to RichTextBox).

I did the following thing:

private static Pen CreateErrorPen() {
    var geometry = new StreamGeometry();
    using (var context = geometry.Open()) {
        context.BeginFigure(new Point(0.0, 0.0), false, false);
        context.PolyLineTo(new[] {
            new Point(0.75, 0.75),
            new Point(1.5, 0.0),
            new Point(2.25, 0.75),
            new Point(3.0, 0.0)
        }, true, true);
    }

    var brushPattern = new GeometryDrawing {
        Pen = new Pen(Brushes.Red, 0.2),
        Geometry = geometry
    };

    var brush = new DrawingBrush(brushPattern) {
        TileMode = TileMode.Tile,
        Viewport = new Rect(0.0, 1.5, 9.0, 3.0),
        ViewportUnits = BrushMappingMode.Absolute
    };

    var pen = new Pen(brush, 3.0);
    pen.Freeze();

    return pen;
}

This almost works, but depending on the underlined word position in text, underlines often show up as a pattern of several superimposed waves. Also the underlines are a bit blurry even when they are correct (wpf problem with drawing between pixels, I suppose).

My solution was kind of a trial-and-error, so I might have gone a wrong way, especially with Viewport/ViewportUnits.

What am I doing wrong and is there a way to get crisp underlines?

Thanks in advance.

+1  A: 

bstoney had a solution to this problem here. The key seems to be setting the Viewbox as well as the Viewport such that the waves are seperated vertically, so you only get 1 in the underline.

There are some breaks in the wave that can be eliminated by extending it to the right and changing the Viewbox from so it starts from X=1 instead of 0:

<VisualBrush x:Key="WavyBrush" TileMode="Tile" Viewbox="1,0,3,3" ViewboxUnits="Absolute" Viewport="0,-1,6,4" ViewportUnits="Absolute">
    <VisualBrush.Visual>
        <Path Data="M 0,1 C 1,0 2,2 3,1 4,0 5,2 6,1" Stroke="Red" StrokeThickness="0.2"/>
    </VisualBrush.Visual>
</VisualBrush>
Robert Macnee
I have tried setting both, but I still get very weird effects (the waves do not intersect, but are vertically sliced in half in some cases -- it seems the pattern is not fixed in relation to the final line position within the document).
Andrey Shchekin
Ooh, I see what you mean now. It's very noticable as you change the text size.I think what we really want is for the Viewport units to be absolute horizontally, but relative vertically. I'll mess with this some more.
Robert Macnee