I did a bit of experimentation and a proof of concept.
The result isn't too bad but needs a bit of work.
When I select text the blue area isn't in exactly the right place.
This works using the approach I mentioned in comments.
The text in the textbox is transparent and the background of the control is used to show the formatted text.
My windows just has this in it:
<Grid>
<TextBox Width="200" Height="40"
VerticalAlignment="Top"
TextChanged="TextBox_TextChanged"
Foreground="Transparent"
FontSize="32"
>
<TextBox.Background>
<DrawingBrush Stretch="None"
AlignmentX="Left">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="LightBlue"
x:Name="TextGeometryDrawing"
Geometry="{x:Null}"
>
<GeometryDrawing.Pen>
<Pen Thickness="1" Brush="Red"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</TextBox.Background>
</TextBox>
</Grid>
My textchanged handler creates the geometry:
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TextBox tb = (TextBox)sender;
FormattedText formattedText = new FormattedText(tb.Text, CultureInfo.GetCultureInfo("en-us"),
FlowDirection.LeftToRight, new Typeface("Segoe UI"), 32, Brushes.Black,
VisualTreeHelper.GetDpi(this).PixelsPerDip);
Geometry geom = formattedText.BuildGeometry(new System.Windows.Point(0, 0));
TextGeometryDrawing.Geometry = geom;
}
Looks like

An alternative is the approach I use in our map and scenario editors. I create a geometry per letter a-z and then use a horizontal itemscontrol with a path per letter using those geometries.
You can then control each letter precisely. If you don't like some aspect of what you get from truetype conversion you can edit it in inkscape.
The insertion point and selection is likely to get even more offset that way though.