Retaining font size when loading/saving RTF in WPF
Asked Answered
C

1

7

Consider the following RTF document

{\rtf1\ansi\ansicpg1252\deff0\deflang1031{\fonttbl{\f0\fswiss\fprq2\fcharset0 Segoe UI;}{\f1\fswiss\fcharset0 Arial;}}
{\*\generator Msftedit 5.41.15.1507;}\viewkind4\uc1\pard\f0\fs22 Sample Text\f1\fs20\par
}

It contains "Sample Text" in font Segoe UI 11 pt. Now when I load and then save the document using WPF's FlowDocument and TextRange.Load() and .Save(), respectively, the font size is reduced to 10.5pt. Is there any way to retain the original font size when using RTF as input/output?

Captor answered 21/7, 2009 at 14:27 Comment(1)
Well, one thing I considered as a possibility was this: 1. Get XAML from the RichTextBox; 2. Modify it by adding 0.001 to each font size; 3. Use code (easily found) to convert XAML to RTF with the built-in classes. That way you're tweaking the input so your output is what you want.Cambium
C
8

All of WPF's measurement is in pixels (although not exactly screen pixels). Even when you specify the FontSize of a TextRange.

Internally, when you specify something like FontSize="14pt" in XAML, WPF uses LengthConverter and changes that qualified double based on a factor associated with the unit of measurement you give. So 11 gets multiplied by 1.3333333, approximately. So if you feed a plain double value to a FontSize property, the unit is pixels.

However, if you use FontSize="14.0001pt", or multiply the points by 1.3333334, or maybe even just add 0.0001 to the pixel measurement, it offsets things just enough that you actually get \fs22 or \fs28 (rather than \fs21 or \fs27, respectively). This is for when you're setting a size in WPF.

The reason you have \fs22, Load(), Save(), and then have \fs21 has to do with the same thing. A parser takes the RTF and converts it into WPF objects. So 22 half-points become something like 14.666666666667 pixels. When you Save() again, those pixels get converted back to a different unit, but not very correctly. 14.666666666667 pixels become 21 half points, but 14.6666674 pixels become 22 half points, which is what you wanted.

Maybe this information will give you an idea how to get RTF differently. Maybe you can get XAML out instead and convert it. Maybe there's a nice free third-part XAML-to-RTF converter that doesn't have annoying rounding errors.

Cambium answered 19/8, 2009 at 19:36 Comment(1)
Good explanation of the problem. In the meantime, I was looking around for such a third-party component. Alas, not with much success.Radke

© 2022 - 2024 — McMap. All rights reserved.