2

I have implemented text editor control for my MVVM application using System.Windows.Media.TextFormatting classes as text formatting engine. The model defines text pretty much like you would have in HTML or XAML, there are paragraphs that contain spans and runs, spans contain more spans etc. The view model exposes linear list of text state changes and is exposed through adapter that implements TextFormatting.TextSource. The TextFormatter will then produce collection of TextLine objects that are rendered by custom FrameWorkElement in view.

So far so good. I can do multiple fonts, sizes, underline, strikeout, foreground and background colors. For implementing superscript, I can reduce the font size and then draw the individual text block at some vertical offset. Underline is just the matter of drawing a line under a text run.

Where I got stuck however, is the letter spacing and horizontal text scaling. Letter spacing means that some amount of extra width is added to every character in text run.

Text effects can be specified for scaling or moving part of text but effects apply only during rendering and do not affect line wrapping. Scaled text block will simply overlap neighbouring text and its size change is not used for calculating line length.

I could add custom tabs after each character, but that would mess with the bookkeeping of indices of model and view. I would be adding characters that are in view but do not exist in the model. Adding code points to content would also mess with the Unicode text layout - code point may not be the same as grapheme so it is probably no that easy.

There is no way for me to publish whole project, but I created limited test application that tries to establish crude MVVM and replicates some parts from original project. There is no model, I just fill the page viewmodel with hardcoded elements.

I have seen the proposed solution to letter spacing in XAML, however in my case there is no XAML. I have formatted text as part of proprietary document format.

Documentation of the TextFormatting is rather laconic. Digging into the Avalon text editor code helped, but I have not really seen anyone else using this part of .NET.

I quite accept that the question is far from clear and it does not make much sense until someone has either investigated the example app or has prior experience with .net text formatting API.

If nothing else, perhaps someone will find the code example useful even without letter spacing ;)

  • Did you ever figure out word and character spacing with TextLine? I'm looking for the same thing. – Todd Main Oct 28 '19 at 17:50
  • Not really. I have functional text editor now but the text model in the application is still rather simple and this approach covers what I need. However, when the letter spacing and horizontal scaling will be needed, then I'll be back at the drawing board. Only small opening I can see is modifyig the typeface. I have C++ code for writing fonts, so the last resort would be editing the actual font to create a temporary typeface on the fly. I hope we will not need it though (either go bust or find resources for rewriting the editor) – Congenital Optimist Oct 29 '19 at 18:39
  • Thanks for the response. I was going to look at overriding the IndexedGlyphRun as I know that GlyphRun allows for letter spacing and kerning. However, I haven't really worked with the TextFormatter object much, so I'm not entirely sure if it's possible. If I figure it out, I'll let you know. – Todd Main Oct 30 '19 at 04:21
  • Above was wrong for `IndexedGlyphRun`. But `TextShapeableCharacters` may have what we're looking for. Investigating... – Todd Main Nov 13 '19 at 19:04

0 Answers0