Problem with rotated fonts ...

Hi all,

I'm developing a CAD-like application and need to implement drawing of text objects. With these I have following problem:

When drawing a text with TextOut() the text is displayed with an offset if the font's rotation is not orthogonal (not 0, 90, 180 or 270 degrees). The amount of this offset depends on the font's height and moves the text from the insertion point toward the baseline of the text.

Is there anybody out there who knows how to avoid this offset or at least to calculate this offset exactly?

If this description of my problem is unclear please tell me, I can post a sample drawing function which illustrates it ...

BTW, I'm using MFC(VC++6.0, NT4Sp5), but I don't think it's a MFC problem but a general Windows problem.

ZOPPO
LVL 31
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Author Commented:
Edited text of question.
0
Commented:
If you are drawing the text so that it moves up it moves to the right (the text is in the 1st quadrant) at a 45 degre angle, say.  In What directection does the text move?  by how much?  what are the font's metrics?  height, leading, etc.
0
Author Commented:
The text moves vertically to the baseline, so it moves down for both 1 and -1 degree ...

For unrotated text I get following TEXTMETRIC:
tmAscent = 31.
tmDescent = 8.
tmAveCharWidth = 14.
tmMaxCharWidth = 40.
tmHeight = 39.
tmWeight = 400.
tmItalic = 0.
tmUnderlined = 0.
tmStruckOut = 0.
tmFirstChar = 30.
tmLastChar = 255.
tmDefaultChar = 31.
tmBreakChar = 32.
tmPitchAndFamily = 23.
tmCharSet = 0.
tmOverhang = 0.
tmDigitizedAspectX = 96.
tmDigitizedAspectY = 96.

For rotated (1 degree) I get following:
tmAscent = 35.
tmDescent = 11.
tmAveCharWidth = 14.
tmMaxCharWidth = 40.
tmHeight = 46.
tmWeight = 400.
tmItalic = 0.
tmUnderlined = 0.
tmStruckOut = 0.
tmFirstChar = 30.
tmLastChar = 255.
tmDefaultChar = 31.
tmBreakChar = 32.
tmPitchAndFamily = 23.
tmCharSet = 0.
tmOverhang = 0.
tmDigitizedAspectX = 96.
tmDigitizedAspectY = 96.

Used font is:
LOGFONT lf = {
-34,
0,
0,
0,
FW_NORMAL,
0,
0,
0,
DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY|NONANTIALIASED_QUALITY,
DEFAULT_PITCH|FF_DONTCARE,
"Times New Roman"
};

>> by how much
depends on the font size; with font create from this LOGFONT lf it's about 4 or 5 pixels

thanks for prompt response :)

ZOPPO
0
Commented:
the problem is, that the coordinate you pass to textout defaults to the upper left corner of the boundary box used by the text. the rotation will be applied afterwards.

you can use SetTextAlign (dc, TA_BASELINE) to let the y-coordinate start point to the baseline of the text. This way the text will rotate around the lower left baseline of your font which is much more predictable.

(to explain more.. the baseline is the y-coordinate where all "normal" characters start.. exceptions are chars like g and q which actually go below the baseline...)

Nils
0

Experts Exchange Solution brought to you by

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Author Commented:
Yes, nils pipenbrinck, you're right, the text look better now.

But, please stay patient for a while before I accept your answer, because all objects in my application have their insertion points in the top left and it would be a quite large amount of work to modify this for text objects. If someone can offer me a solution without changing the text align to something other than top left I would prefer it.

If you agree I'll let this question open until monday, ok?

>the rotation will be applied afterwards.
Even I do not understand why a rotation about 1 degree can result in a vertical offset of about 5 pixels ...

BTW, it's not easy to view your EE profile because of the ' '...

ZOPPO
0
Commented:
jep.. I know.. when I first registered to ee I wasn't able to login because of the space in my name..

anyways.. they fixed it some years ago..

and you can watch my profile by clicking on my name :)

ok.. go ahead and look for better solutions.. I don't have any problems with that..

btw. I wonder if you use the SetMapMode and SetViewportEx stuff to do the printing.. if you do so be warned: they suck.. text will be scaled, but it's not precise.. (I once had a problem where I printed text on the screen and used SetMapMode to scale it to a printer dc.. the problem was, that the printed text was larger than my minified version on the screen.. There is no way to work around that (even if ms word can do it we cannot.. I guess they somewhat hack themself into the rasterizer to fix that...)).

Nils

0
Commented:
it would take a little triginometry.  But I'm not sure of the exact formula because I'm not sure how things are moving.
0
Commented:
>> SetMapMode to scale it to a printer dc..
>> the problem was, that the printed text was
>> larger than my minified version on the screen..
I've never seen a problem with mapping modes or heard of one here.  I strongly expect you were making a mistake.
0
Commented:

nietod: no, I didn't made an error. you can do a simple check:

write a text string (ttf!), count the number of pixels and draw a line under the text (same length)... then set the mapping mode so it zooms the image and send it to a printer dc..

you should expect the line have the same length as the text.. but that's not true.. the text modifies it's width nonlinear to the zoom-mode... sometimes it gets longer, sometimes smaller (depends on the font used).

funny, isn't it?

the font-mapper generates a new font when you zoom it.. however, it's not nessesary, that the new font has the same height/width ratio because of kerning and hinting. that's the problem I run into..

GetTextExtend still works, but that won't help you if you code a vector drawing program and you can't make every line you draw relative to a textextend. in my case I ended up drawing the ttf's myself (which was a heap of work but solved the problem).

nils

0
Commented:
This has nothing to do with mapping modes.  True-type fonts do not scale linearly.  This is intentional.  The fonts contain "hints" that control how they are to scale.  So if you double the size of a font, only the height doubles, the width of the strokes might not double, the width of the characters might not double.  You should notice this fact in a single mapping mode.  Double the height of a font and the length of the text does not double.
0
Commented:
nietod: yoU're right..

anyways.. it's a nice pitfall to step into :)

happy coding,
nils
0
Author Commented:
ok, seems here doesn't happen any more, so I'll have to byte into the soure apple and modify my implementation :(

thanks nil and nietod,

have a nice day,

ZOPPO
0
Author Commented:
Of course 'bite' instead of 'byte' ...

I could say this was a typical 'Freudscher' typo if I would know how to translate it to English...    :o)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.