RichEdit SetCharFormat Character Size and Spacing

I have hundreds of reports that have been manually formatted using <SPACES> to make characters align.  The text is either 10CPI or 17.xx CPI as in the old dot matrix printers.

I'm trying to import them to a CRichEditDoc/View type of arrangement.  I've tried fixed pitch fonts such as Courier New and  Lucida Console, and though each will change size, they seem to do so in some sort of secret increment, and are sometimes almost unreadable on the screen.

Within the documents, if a line is compressed, then the entire line is compressed.  I'm NOT trying to line up decimals using different fonts, etc.  It is simply that on an 8 1/2 x 11 sheet of paper, it would be nice if the compressed lines began and ended at approximately the same place as the non-compressed ones.

How can I SetCharFormat so that I end up with 80 characters per line, and 132 characters per line, or you could think of it as 10 CPI and 16.5 CPI?

Thanks in advance, rick
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

DanRollinsConnect With a Mentor Commented:
First, you can know if a font is a TrueType by using the
    GetTextMetric API
Look in TEXTMETRIC.tmPitchAndFamily

That works for a font that has been selected into a DC, but I'm thinking that all you have is a font name.  It appears that the best way to do this would be to call

It requires a callback function, but if you pass in a font face name, it will return a TEXTMETRIC structure that includes the desired info.

Next, why are you seeing the "quantum jumps" as you increase the font-size in small increments?

As mysterious as it seems, it's actually surprizingly simple:  
The fonts have to be created with equal character width.  An on-screen character width is an exact whole number of pixels.  Say each 7-pt character is 10 pixels wide.  Then your line of 80 characters will be 800 pixels wide. Now you ask for one that is just 1/20th of a point larger.  When the font is created, it can't be 10.1 pixel cells wide, it can only be 10.0 or 11.0 so the Font Manager selects the closest one.

One way to show this is to print out a page, rather than view it on screen.  Your laser printer has much higher resolution than your screen (24,000 pixels wide vs., say 800 or 1200), so as you edge up the size in twips, you may still see some "quantum jumps," but they will be a lot smoother.  :-)

-- Dan
The important thing to do is to choose a fixed-pitch font that is a TrueType font (I usually go with "Courier New").  If you pick one of the older font faces,  such as "Courier" then it only exists in certain sizes and the font manamgent system picks one that it thinks will work.

>> How can I SetCharFormat so that I end up with 80 characters per line, and 132 characters per line, or you could think of it as 10 CPI and 16.5 CPI?

A 10 CPI  font is a 12-pt font
A 16.5 CPI font is about a 7-pt font (actually, about 7.2)

In the CHARFORMAT structure that you pass to the SetCharFormat function, you must set yHeight in twips -- twentieths of a point.  So, code like the attached should work for you.

>> it would be nice if the compressed lines began and ended at approximately the same place as the non-compressed ones.

I don't understand this part of your question.  Obviously, lines of different size characters will end at different places...
cf.cbSize= sizeof( CHARFORMAT );
cf.dwMask= CFM_FACE | CFM_SIZE;
cf.yHeight= 240; // 12pt (or 144 = 7.2pt = 16.5 cpi)
strcpy( cf.szFaceName, "Courier New" );
m_ctlRE.SetCharFormat( cf );

Open in new window

rickatseasoftAuthor Commented:
Dan thanks for taking the time to answer, and you've gotten me a lot closer to solving my problem.  Thanks again.  

First to answer your question.  The reports in question are written in code that was designed for the unix environment on dot matrix printers, and specifically had two type sizes, 10 CPI and 16.5(or so) CPI---or 80 char per line and 132 char per line.  To make the reports visually pleasing, those lines that had 80 chars or less were printed in 10CPI and were padded to have about 80 characters, and those that had more than 80 characters were printed in 16.5CPI and were padded to have about 132 characters.  Ergo, regardless of the type size, the lines were about 8" long, and ended at the same place.  In other words, the pages were symmetrical left and right.

Just a couple of quick follow-up questions if you don't mind.  

My font selection routine requires that if the font isn't a TRUETYPE_FONTTYPE font, then it is not used.  In other words, the name "Courier New" isn't even in contention unless it is TRUETYPE.  However, at the point of font selection as in strcpy(cf.szFaceName,"Courier New") can I be guaranteed that the font selected is, in fact, a TRUETYPE?  Can there EVER be a situation where there exists a Courier New that is TRUE_TYPE, and another that is not?  My next question might illustrate why I'm asking this one.

I did as you suggested, and my report, in fact, displayed on the screen with an 80 character line (yHeight=240) that ended at almost exactly the same place as 128 character line(yHeight=144), so you have solved my problem.  Thank you.  What I inferred from your TRUE_TYPE comment that I should see a continuous change in type size as changes are made to yHeight.  I did a little experment, and incremented the cf.yHeight by one for each iteration.  I observed absolutely no difference between the length of the lines with cf.yHeight at 144 right up through cf.yHeight=157.  When cf.yHeight is set to 158, the line then becomes about an inch longer than it was at 144 through 157.  Soooo, it took a 14 twip increment to have any discernible effect.  BTW, my computer has three fixed pitch TRUE_TYPE fonts: Courier New, Lucida Console, and Lucidea Sans Typewriter, and all exhibit the same behavior.  Can you please explain this?

Thanks again, Rick
rickatseasoftAuthor Commented:

Thanks for all the help
rickatseasoftAuthor Commented:
Thanks again
All Courses

From novice to tech pro — start learning today.