Fonts and Printing

I setup our Device contexts for the screen and the printers the following way

SetMapMode(lpHeader->hDC, MM_ANISOTROPIC);
SetWindowExtEx(lpHeader->hDC, 1440, 1440, NULL);
SetViewportExtEx(lpHeader->hDC,
      GetDeviceCaps(lpHeader->hDC, LOGPIXELSX),
      GetDeviceCaps(lpHeader->hDC, LOGPIXELSY), NULL);

This is similar to MM_TWIPS mapping mode.

On the screen we do the following when creating fonts

nFactor = 1440 / GetDeviceCaps(lpHeader->hScreenDC, LOGPIXELSX);
logfont.lfHeight = nFactor * FontSize;

The fontsize is normally a negative number. Choosefont would give you -13 for a 10point arial font.

On the screen the nFactor is 15. On the printer its 4. If I do exactly the same thing the font size is way too small. If I substitute a 15 for the 4, its ok. Obvisouly the calculation of the factor is incorrect.

Can anyone help?

LVL 1
philsmicronetAsked:
Who is Participating?
 
nietodConnect With a Mentor Commented:
>> Obvisouly the calculation of the factor is incorrect.
I missed that before.  Yes, that is incorrect.  (I was confussed because I thought it was what you wanted.)  The correct formula for size is

logfont.lfHeight = 20 * FontSize;

where FontSize is the size in points.  Note that the beauty of this is that the same height can be used on both the screen or the printer.  That is one reason why one uses a mapping mode like that
0
 
nietodCommented:
The way you set up the mapping and extents should allow you to specify dimensions such that the same values produce the same physical sizes on both the screen and the printer.  I.e a font of hieght 15 on the printer should be nearly the exact same size as a font of height 15 on the screen

Is that your intent?  (Its often a good scheme, but what confuses me is that with it you wouldn't want that nFactor type of formula.)

With the mapping mode set this way there is 1440 logical units per physcial inch (of the screen and printer).  Since a point is approximately 1/72 of an inch there is approxumately 20 logical units per point.  so the font size in logical units (which is what you specify when creating the font) should be 20 times the desired font size in points.

Does that help?
0
 
philsmicronetAuthor Commented:
When I multiply the fontsize by 20 the font turns out too large. I was using 20 on the printer side.

I then looked at the screen side and it was using this factor.

Any idea why 20 would produce a font size too large?

One point of interest. I originally tested this at home with a HP deskjet printer. It worked fine. When I got to work and tried it on our Laser printers the fonts came out too large?
0
Get 10% Off Your First Squarespace Website

Ready to showcase your work, publish content or promote your business online? With Squarespace’s award-winning templates and 24/7 customer service, getting started is simple. Head to Squarespace.com and use offer code ‘EXPERTS’ to get 10% off your first purchase.

 
philsmicronetAuthor Commented:
Maybe the other thing that confuses me is that when you use choosefont and select a 10 point font, it returns -13 in the lfHeight field of the logfont field. This is the field I have been using as the font size. Should I be using iPointSize;
0
 
philsmicronetAuthor Commented:
Maybe the other thing that confuses me is that when you use choosefont and select a 10 point font, it returns -13 in the lfHeight field of the logfont field. This is the field I have been using as the font size. Should I be using iPointSize;
0
 
philsmicronetAuthor Commented:
If I do use iPointSize should I

logfont.lfHeight = cf.iPointSize;

or

logfont.lfHeight = -cf.iPointSize;


0
 
philsmicronetAuthor Commented:
If I do use iPointSize should I

logfont.lfHeight = cf.iPointSize*20;

or

logfont.lfHeight = -cf.iPointSize*20;




0
 
philsmicronetAuthor Commented:
Last but not least. Choose font seems to default to the LogFont entry for the font size.

I set cf.iPointSize = 100
and logfont.lfHeight = -10 and called ChooseFont.

ChooseFont defaulted to 8 point Arial.
If I set logfont.lfHeight = 0, it defaulted to no height. How can I determine what logfont should be to default to the correct font?
0
 
nietodCommented:
>> When I multiply the fontsize by 20 the font turns out too large.
Too large in what sense.  You need to multiple the point size you want by 20.  So if you want a 12 point font, you should use 120.  this should yield a font that is about 1/6th of an inch high.  (Actually you probably want to use -120, not 120)

What are you using and what are you getting?

>> I originally tested this at home with a HP deskjet
>> printer. It worked fine. When I
>> got to work and tried it on our Laser printers the
>> fonts came out too large?
The same code?  the whole point is that this is hardware independant.  i.e. you get the same size results regardless of the resolution (pixels per inch) of the device.

>> you use choosefont and select a 10 point font, it
>> returns -13 in the lfHeight field of the logfont field
I don't use choosefont, so I'm not sure what is going on there, but one issue is that a negative height indicates that you are specifying the height of the entire "line",  that includes the accent, decent, and leading.  A positive height indicates you are specifying only the acent and decent height, so the font returned will be a little larger than this.  because of this you often want to use negative heights in LOGFONT.  How why is it returnin +-13 which is too small for a 10 point font?  I would have to guess that is because it is returning the height in device units, not logical units (because it doesn't know what sort of mapping mode you use.)  So it is saying the font should be 13 pixels high  (which is just about right for a 10 point font if you have a 96 pixel/per inch monitor--standard.)  So you must conver these device units to logical units before using them.  In your case you will multiply by 1440 and divide by the number of pixels per inch.

That is because the height specified is
0
 
nietodCommented:
>> If I do use iPointSize should I
>>
>> logfont.lfHeight = cf.iPointSize*20;
>>
>> or
>>
>> logfont.lfHeight = -cf.iPointSize*20;
Yes.

It depends on what you want.  Positive allows you to specify the height of the characters themselves, not the ehight of the space "they use".  i.e. if you have multiple lines they will each use up more space than what you specify, because of the space between the lines.  Negative means you are specifying the total space you want for a line, including the space seperating the lines.  

When you specify a font in most programs, like word processors, you usualy are specifying the total spacing (negative), not the space used just by the character.
0
 
nietodCommented:
>> if I set logfont.lfHeight = 0, it defaulted to no
>> height. How can I determine what logfont
>> should be to default to the correct font?
I'm guessing.  But you probably need to set lfheight to the height in device units (pixels).  So remember that a point is 1/72 of an inch.  So

PixelHeight =  PixelsPerInch*PointSize/72

You get PixelsPerInch from GetDeviceCaps() using LOGPIXELSY.

Note if PixelsPerInch is 96 (typical)  then the formula 96*10/72 yeilds 13.  Which is what you foudn above.  i.e. that a 10 point font is 13 pixels high on you monitor.

Note, sometimes I find that 96 is returned for a monitor even when the monitor has a very different resolution.  There is nothing you can do about that really.  You have to work with what the OS "knows"  Now that can be fixed--probably-by the user.  They need to insure that the display setup is specifying the right monitor and driver, if not the OS and therefore your program can't be blamed for working with the wrong figures.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.