Obtaining kerning information

瘦欲@ 提交于 2019-12-22 08:17:33

问题


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 );

回答1:


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.




回答2:


You first call it with the third parameter set to NULL, in which case it returns the number of kerning pairs for the font. You then allocate memory, and call it again passing that buffer:

int num_pairs = GetKerningPairs(your_dc, -1, NULL);

KERNINGPAIR *pairs = malloc(sizeof(*pairs) * num_pairs);

GetKernningPairs(your_dc, num_pairs, pairs);

Edit: I did a quick test (using MFC by not GDI+) and got what seemed like reasonable results. The code I used was:

CFont font;
font.CreatePointFont(120, "Times New Roman", pDC);
pDC->SelectObject(&font);

int pairs = pDC->GetKerningPairs(1000, NULL);

CString result;
result.Format("%d", pairs);
pDC->TextOut(10, 10, result);

This printed out 116 as the result.



来源:https://stackoverflow.com/questions/10082825/obtaining-kerning-information

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!