Obtaining kerning information

c++, gdi, gdi+, kerning

Solution

The problem lies in the fact that you are passing in a `Gdiplus::Font` and not a HFONT for `SelectObject`. You need to convert `Font* myFont` into a `HFONT`, then pass that `HFONT` into SelectObject.

First, to convert a `Gdiplus::Font` into a `HFONT`, you need to get the LOGFONT from the `Gdiplus::Font`. Once you do this, the rest is simple. The working solution to get number of kerning pairs is

Font* gdiFont = new Font(L"Times New Roman", 12);

Bitmap* bitmap = new Bitmap(256, 256, PixelFormat32bppARGB);
Graphics* g = new Graphics(bitmap);

LOGFONT logFont;
gdiFont->GetLogFontA(g, &logFont);
HFONT hfont = CreateFontIndirect(&logFont);

HDC hdc = GetDC(NULL);
SelectObject(hdc, hfont);
DWORD numberOfKerningPairs = GetKerningPairs(hdc, INT_MAX, NULL );

As you can tell, the only functional change I gave was to creating a `FONT`.

Problem

How can I obtain kerning information for GDI to then use in GetKerningPairs? The documentation states that The number of pairs in the lpkrnpair array. If the font has more than nNumPairs kerning pairs, the function returns an error. However, I do not know how many pairs to pass in, and I don't see a way to query for it. EDIT #2 Here is my fill application that I have also tried, this is always producing 0 for any font for the number of pairs. GetLastError will always return 0 also. ``` #include <windows.h> #include <Gdiplus.h> #include <iostream> using namespace std; using namespace Gdiplus; int main(void) { GdiplusStartupInput gdiplusStartupInput; ULONG_PTR gdiplusToken; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); Font* myFont = new Font(L"Times New Roman", 12); Bitmap* bitmap = new Bitmap(256, 256, PixelFormat32bppARGB); Graphics* g = new Graphics(bitmap); //HDC hdc = g->GetHDC(); HDC hdc = GetDC(NULL); SelectObject(hdc, myFont->Clone()); DWORD numberOfKerningPairs = GetKerningPairs(hdc, INT_MAX, NULL ); cout << GetLastError() << endl; cout << numberOfKerningPairs << endl; GdiplusShutdown(gdiplusToken); return 0; } ``` EDIT I tried to do the following, however, it still gave me 0. ``` Font* myFont = new Font(L"Times New Roman", 10); Bitmap* bitmap = new Bitmap(256, 256, PixelFormat32bppARGB); Graphics* g = new Graphics(bitmap); SelectObject(g->GetHDC(), myFont); //DWORD numberOfKerningPairs = GetKerningPairs( g->GetHDC(), -1, NULL ); DWORD numberOfKerningPairs = GetKerningPairs( g->GetHDC(), INT_MAX, NULL ); ```

Original source