Search code examples
wpfxamltextboxkerning

How can I specify letter spacing or kerning, in a WPF TextBox?


I'd like to modify the spacing between characters in a WPF TextBox.
Something like the letter-spacing: 5px thing that is available in CSS.
I think it is possible in XAML; what's the simplest way?

I found the "Introduction to the GlyphRun Object and Glyphs Element" document, and found it to be exceedingly unhelpful.

This is a code example from that page:

<!-- "Hello World!" with explicit character widths for proportional font -->
<Glyphs 
   FontUri             = "C:\WINDOWS\Fonts\ARIAL.TTF"
   FontRenderingEmSize = "36"
   UnicodeString       = "Hello World!"
   Indices             = ",80;,80;,80;,80;,80;,80;,80;,80;,80;,80;,80"
   Fill                = "Maroon"
   OriginX             = "50"
   OriginY             = "225"
/>

The same documentation page gives this "explanation" for what the Indices property does:

enter image description here

I have no idea what any of that means. I'm also not sure that Indices is the right thing - the comment in the code speaks of "character widths" which I don't care about. I want to adjust the width between characters.

Also, there is no example for how to apply a Glyphs element to a TextBox. When I tried it, my WPF test app just crashed.


What I want to do is slightly increase the empty space that appears between drawn characters within a WPF TextBox. The text will vary in length and content. Do I have to modify the Indicies property every time there is a new character? Is there a way to say "make it 20% more space than usual, for every character".

Can anybody help me?


Solution

  • I tried Glyphs and FontStretch and couldn't easily get the result I was looking for. I was able to come up with an approach that works for my purposes. Maybe it will work for others, as well.

    <ItemsControl ItemsSource="{Binding SomeString}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding}" 
                           Margin="0,0,5,0"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
    

    I can bind to any string and don't need to do any character width detection to set the spacing properly. The right margin is the space between the letters.

    Example:

    Kerning