Canvas.TextExtent for italic fonts returns wrong results

Canvas.TextExtent for italic fonts returns wrong results

Post by Dani Epstei » Fri, 10 Nov 2000 04:00:00



Hi,

The caption says it all. Canvas.TextExtents (and therefore
Canvas.TextWidth, Canvas.TextHeight) gives the wrong results when using
italic fonts (very noticeable on very large font heights > 200). The
issue is that I need to know for a string of text the width and height
of each letter, and to get the outline of each letter as a series of
TPoints.

To trace the letter I paint each letter on a canvas and then trace the
edges. In order to make the canvas large enough for the letter the
following is done:
        Canvas.Width := Canvas.TextWidth(SomeLetter);
        Canvas.Height := Canvas.TextHeight(SomeLetter);
which clips italic fonts, i.e. the italic letter is in fact wider than
TextWidth says it is.

Any solutions?
--
Dani Epstein
CTO TFcom Ltd.

 
 
 

Canvas.TextExtent for italic fonts returns wrong results

Post by Carl Caulket » Fri, 10 Nov 2000 04:00:00



Quote:>    Canvas.Width := Canvas.TextWidth(SomeLetter);
>    Canvas.Height := Canvas.TextHeight(SomeLetter);
> which clips italic fonts, i.e. the italic letter is in fact wider than
> TextWidth says it is.

> Any solutions?

Hi Dani,

I think you have to delve into the Windows API. Have a look at the
GetOutlineTextMetrics function. If you want some decent Delphi oriented
information about this function you could try ITKnowledge which has an
online copy of the book, "The Tomes of Delphi 3: Win32 Graphical API".
ITKnowledge costs about $20 per month and I believe there is a 30 day
free trial period. The direct URL to the page is:

http://www.itknowledge.com/reference/dir.10.10.41.html

Cheers,
Carl

 
 
 

Canvas.TextExtent for italic fonts returns wrong results

Post by Dani Epstei » Fri, 10 Nov 2000 04:00:00


Hey, hi Carl!


> Hi Dani,

> I think you have to delve into the Windows API.

Did! GetOutlineTextMetrics will give you info on the whole font, but not
the individual letter. It'll also give wrong info on italics, believe it
or not. The closest thing to what I want is GetGlyphOutline which,
amazingly, is buggy according to Microsoft when retrieving bitmaps,
which I tried and discovered for myself.

GetTextExtentPoint32 suffers from a clipping problem too, on italics.

Quote:>Have a look at the
> GetOutlineTextMetrics function. If you want some decent Delphi oriented
> information about this function you could try ITKnowledge which has an
> online copy of the book, "The Tomes of Delphi 3: Win32 Graphical API".
> ITKnowledge costs about $20 per month and I believe there is a 30 day
> free trial period.

Thanks for that. I think they've gotten a lot smarter, as they request
credit card details up front. Ah well.

Cheers,
--
Dani Epstein
CTO TFcom Ltd.

 
 
 

Canvas.TextExtent for italic fonts returns wrong results

Post by Joris Van Damm » Sat, 11 Nov 2000 10:37:38


Hey there!

It's been a very long time, but I remember having the same problem once.

The problem here, especially with italic fonts, is that there is no such
thing as a single defineable character width. Suppose you draw two
capital I's in italic. It is very possible that the most bottom left
point of the second I is actually more left than the most upper right
point of the first I. So what would you define as the TextWidth of the
first I? The amount of pixels you have to add to its position to get the
position of the second I? Or the amount of pixels you need as width of a
bitmap to draw the I completely on? See, these are two different things.

Take a look at GetCharABCWidths in the win32 help. I quote:

Quote:>> The TrueType rasterizer provides ABC character spacing after a specific point size has been selected. "A" spacing is the distance added to the current position before placing the glyph. "B" spacing is the width of the black part of the glyph. "C" spacing is the distance added to the current position to provide white space to the right of the glyph. The total advanced width is given by A+B+C.

When the GetCharABCWidths function retrieves negative "A" or "C" widths
for a character, that character includes underhangs or overhangs. <<

I haven't tested it, but I think in the case of the I's, the C width
will be negative and the B width will be the width you are after if you
want an encapsulating rectangle's dimensions. It should be possible, if
you need an encapsulating rectangle for a piece of text, to use the
TextWidth function, and add -(A width) of the first character if it is
negative and -(C width) of the last character if that is negative.
Haven't tested it, but it seems logical.

Joris

 
 
 

Canvas.TextExtent for italic fonts returns wrong results

Post by Dani Epstei » Tue, 14 Nov 2000 04:00:00



> Take a look at GetCharABCWidths
> Joris

Works a charm. Thanks a million!
--
Dani Epstein
CTO TFcom Ltd.