How to find the height of an EXACT pixel displayed on Windows using DrawText

I want to find the exact height of the text displayed on Windows. I tried both GetTextExtentPoint32 and calling DrawText with the DT_CALCRECT flag, and both give the same result.

The returned height seems to be based on the full height of the cell, regardless of the actual text to be drawn.

The code below is the WM_PAINT handler for the standard Win32 Visual Studio 2013 Win32 project. He creates a (large) font and draws a sample text. The highest part of the text is 98 pixels, but the value returned by GetTextExtentPoint32 is 131.

I understand that some applications may require the full height of the cell, but also some applications (like mine) just want the actual height to be used by the text.

Does anyone know how to find this information?

Yes, I can display DC and scan down, looking for the first non-phonic color pixel, but it will be very slow.

thanks

case WM_PAINT: { hdc = BeginPaint (hWnd, &ps); HFONT hfont = CreateFont (-99, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, VARIABLE_PITCH, L"Segoe UI Semibold"); auto old_hfont = SelectObject (hdc, hfont); wchar_t sample_text[] = L"123 Testing 123"; size_t sample_text_length = wcslen (sample_text); SIZE s; GetTextExtentPoint32 (hdc, sample_text, sample_text_length, &s); RECT r = {10, 10, 10 + s.cx, 10 + s.cy}; SetBkColor (hdc, RGB (80, 120, 160)); SetTextColor (hdc, RGB (220, 220, 220)); DrawText (hdc, sample_text, sample_text_length, &r, DT_SINGLELINE | DT_NOPREFIX | DT_LEFT | DT_TOP); SelectObject (hdc, old_hfont); DeleteObject (hfont); EndPaint (hWnd, &ps); break; } 
+8
c ++ windows gdi
source share
4 answers

See GetGlyphOutline(GGO_METRICS) returned GLYPHMETRICS structure should contain all the data needed to calculate the degree.

+7
source share

Your text is not drawn directly; first it becomes a path that describes the contours of your geometries / glyphs. A path consists of movements, lines, and curves (and a close flag to the previous). In addition to curves, other path segments are the extreme points of the final fill. Converting curves to lines and iterating over all segments of the path to find the minimum and maximum in horizontal and vertical sizes by points leads to the fact that the nearest rectangle fits your text.

You can convert your text to a path by invoking it with a call to BeginPath before and EndPath after. FlattenPath converts the curve-> line line. GetPath provides access to waypoints in context. AbortPath permanently removes the path from the context.

If you don’t have to set a transparent background , the path may be the background around your text, and the first segments of the path are the background / extents of the rectangular lines - not what you want.

To simplify this method, you can eliminate duplicate characters and wildcards 1) below the baseline 2) above the midline 3) rest. All of this together is very fast compared to your "look pixels".

Other useful sources about font metric text sizes ( GetTextMetrics ) and character widths ( GetCharABCWidths )

+4
source share

If your sample text contains only ASCII letters, you can manually estimate the height of the ascending letter, for example, b , a descending letter of type g and a median letter of type x . You would do it ahead of time, perhaps even offline, so any inefficient method is great.

Then (depending on the font with a small margin of error) calculating the total height is a simple check for ascending ( bdfhijklt and AZ ) and descenders ( gjpqy ) in your line.

+3
source share

If it is a TrueType font, you can find the size of the wrt glyph layout for the “previous” letter and line in the fmtx table, as described here . There is also similar information available for OpenType fonts, but it looks more cumbersome to get something meaningful.

This does not give you the actual pixel size of the glyph, but it gives you a more accurate idea when the true type font path for a particular glyph is drawn relative to the "baseline", and the units are scaled with the point size and font width.

In your case, I would take a look at FreeType, a third-party library that works fast and supports bitmap fonts, TrueType and OpenType fonts. It is widely used and very well documented and maintained and can provide accurate metrics.

+2
source share

All Articles