--------------------------------------------------------------------------------

When using this with the DrawText API, I make the rectangle that the text is contained in the width of the return value of GetTextExtentPoint32


I know I am using the right parameters, but sometimes the rectangle is way too big (over 15 pixels wider than the actual width of the text) and sometimes the rectangle is too small.

It seems that this API is a little.. screwed up perhaps? If I input "WWWWWWWWWWWW" for example, the rectangle containing the text is around 20 pixels too big but if I input "iiiiiiiiiiii", the rectangle is around 20 pixels too small.

I tried using SetTextCharacterExtra, but that just screwed things up even more. I'm looking for a more accurate and precise way to set the rectangle's width via the width of the text. Btw, there will never be any spaces, numbers, or symbols as the text. The width of the text will only ever contain the 26 lowercase letters and 26 uppercase letters.

Thanks for any help. :)

Dani AI

Generated

reported that measured widths from GetTextExtentPoint32 sometimes don’t match the rectangle used by DrawText (wide letters like "W" vs narrow ones like "i" behaved differently). That outcome is expected when glyph metrics, kerning, overhangs and the device-context state (selected HFONT, mapping mode, transforms, any extra character spacing) are involved — GetTextExtentPoint32 reports extents based on the selected font/DC but layout and rounding rules can differ between measurement APIs. (learn.microsoft.com)

As suggested, the most foolproof way to get the exact rectangle that DrawText will use is to call DrawText with the DT_CALCRECT flag first; DrawText runs the same formatting/layout path it uses for drawing and updates the RECT accordingly. That removes the mismatch when DrawText is the final rendering function. (learn.microsoft.com)

For programmatic, character-accurate widths, either ask GDI for per-character extents or get glyph ABC metrics and sum them. GetTextExtentExPoint fills a dx array with cumulative extents so the final entry gives the string width; GetCharABCWidths returns A/B/C values (A = pre‑spacing, B = glyph width, C = trailing space) useful for TrueType fonts — summing A+B+C over the glyphs yields the advanced width including overhangs. Example sketches follow.

int n = lstrlenA(text);
int *dx = (int*)malloc(sizeof(int)*n);
SIZE sz;
int fit = 0;
GetTextExtentExPointA(hdc, text, n, INT_MAX, &fit, dx, &sz);
// total width = (fit>0) ? dx[fit-1] : 0;
free(dx);

// TrueType per-glyph ABC (works only for TrueType):
ABC *abc = (ABC*)malloc(sizeof(ABC)*n);
for (int i=0;i<n;++i) GetCharABCWidthsA(hdc, (BYTE)text[i], (BYTE)text[i], &abc[i]);
int total = 0;
for (int i=0;i<n;++i) total += abc[i].abcA + abc[i].abcB + abc[i].abcC;
free(abc);

Use GetTextExtentExPoint or GetCharABCWidths depending on needs. (learn.microsoft.com)

Final troubleshooting checklist: measure with the same HDC state used for drawing (select the same HFONT, same mapping mode and transforms), avoid mixing measurement/DCs, and be aware that SetTextCharacterExtra influences spacing (it’s a compatibility API; ExtTextOut with explicit lpDx is recommended for precise control). Those steps eliminate the common 10–20px mismatches described. (learn.microsoft.com)

How about this little rider in the manual page?

Because some devices kern characters, the sum of the extents of the characters in a string does not always equal to the extent of the string.

> I'm looking for a more accurate and precise way to set the
> rectangle's width via the width of the text.
You call DrawText() but you use the DT_CALCRECT flag to indicate that you just want the clip to be calculated. It doesn't draw anything.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.