locked
Improper text kerning in RichText Box RRS feed

  • Question

  • This one has me awfully confused...

    I am trying to display kerned RTF text in a Visual Studio Visual Basic RichTextBox control (having so far tried under VS2010 and VS2012). Simply, I create a Windows Form project, add two RichTextBox's (RichTextBox1 and RichTextBox2) to the form, no change to default properties, and include the following VB code:

    Public Class Form1
    
        Private Sub Initialise(sender As System.Object, e As System.EventArgs) Handles Me.Load
            Dim txtRTF As String = "{\rtf1\ansi" & _
                               "{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}}" & _
                               "\f0\pard" & _
                               "\expndtw-60 a" & _
                               "\expndtw200 bc}"
    
            RichTextBox1.Rtf = txtRTF
            RichTextBox2.Paste() ' RichTextBox2 formats properly iff clipboard holds ANY valid rtf content
            RichTextBox2.Rtf = txtRTF
    
        End Sub
    
    End Class
    


    The txtRTF String contains, as best as I can tell, minimal valid RTF markup and text.

    Here's the confusing bit: output text in RichTextBox1 is not kerned, despite \expndtw (expand twips) RTF markup, BUT text displayed in RichTextBox2 is properly kerned, if and only if the clipboard holds ANY valid RTF content (e.g., any text has first been copied into the clipboard from, say, an MS Word document). Text displayed in RichTextBox2 is not properly kerned if clipboard contents is not in RTF format.

    Incorrect and undesired result of running if the clipboard does not contain RTF-formatted data (or if the RichTextBox2.Paste() code is removed or commented out):

    [[ OK, there would be a screenshot of my form here, except after attempting to submit my question, this website informs me that "Body text cannot contain images or links until we are able to verify your account" without, mind you, informing me just how I can be verified, while then refusing to allow me to proceed further with my post. Oh well, I'll just have to describe the diagram instead: Imagine, if you will, a little form with two RichTextBox's, the first containing "abc", the second containing "abc", each "abc" looking identical to the other, neither text field appearing kerned or especially formatted in any way.  This shouldn't have happened, and it is exactly this that is the point of my question. ]]


    Correct and desired result of running if immediately prior to running the program the clipboard holds any random RTF-formatted text:

    [[ Same again – there would be a screenshot of my form here, except this website prevents it. Descriptively: imagine a little form with two RichTextBox's, both containing "abc" as before. Nothing special about the first "abc" – it appears completely unformatted as in the two RichTextBox's in the previous (pseudo) diagram. However, the second RichTextBox in this diagram is exactly kerned as desired: the 'b' in the trigram is negatively kerned some 60 twips (i.e., butts up against) the 'a' to its immediate left; the following 'c' is located some 200 twips (20 pts) to the right of the 'b'. This is exactly the result that I want to see (except without having to step through the rigmarole of first loading some random RTF-formatted text into the clipboard and programmatically executing a clipboard paste.) ]]


    Questions:

    1. Why on earth should it matter that I have previously pasted RTF-format (and not non-RTF format) into the RichTextBox2 control before setting the RichTextBox2.Rtf field?
    2. More importantly, how can I (in VB) programmatically display properly kerned text in a RichTextBox control without the absurdity of first pasting random RTF format text into it? (I'm assuming that in addition to setting the RichTextBox control's .Rtf member, the RichTextBox2.Paste()has performed some other (undocumented?) side effect on the RichTextBox object – the question is, how can I replicate within my code?).




    Monday, January 13, 2014 10:21 AM

Answers

  • Thank you Acamar, that took a lot of work!  Nevertheless, problem now solved.

    It turns out that, although the RTF spec notes that \ltrch (left-to-right character run) is the default state, it seems that RichTextBox objects don't necessarily agree.  Including a \ltrch (or even, oddly, a \rtlch) control sequence in the RTF markup stream completely solves the failure-to-kern problem.  RTF text kerning via \expndtwN and \expndN now works perfectly well.  No need for silly Paste() commands to pre-configure the RichTextBox control into its proper state!

    • Marked as answer by Geoffrey Jones Tuesday, January 14, 2014 12:26 PM
    Tuesday, January 14, 2014 12:26 PM

All replies

  • The txtRTF String contains, as best as I can tell, minimal valid RTF markup and text.

    I think that your testing has demonstrated that this is not so.

    I would recommend comparing the two RTF properties to determine the difference that is caused by the existence of the clipboard data, because somewhere in that difference is the RTF code that is creating the kerning difference.  If the clipboard contents are convertible to valid RTF then the .Paste will convert the contents to that format and paste it.  That conversion will create the required header information for valid RTF, and somewhere in that header is the initialisation that causes the kerning to work properly.

    Monday, January 13, 2014 11:10 AM
  • Thank you Acamar, that took a lot of work!  Nevertheless, problem now solved.

    It turns out that, although the RTF spec notes that \ltrch (left-to-right character run) is the default state, it seems that RichTextBox objects don't necessarily agree.  Including a \ltrch (or even, oddly, a \rtlch) control sequence in the RTF markup stream completely solves the failure-to-kern problem.  RTF text kerning via \expndtwN and \expndN now works perfectly well.  No need for silly Paste() commands to pre-configure the RichTextBox control into its proper state!

    • Marked as answer by Geoffrey Jones Tuesday, January 14, 2014 12:26 PM
    Tuesday, January 14, 2014 12:26 PM