【问题标题】:Obtaining kerning information获取字距信息
【发布时间】:2012-04-22 09:26:55
【问题描述】:

如何获取 GDI 的字距调整信息,然后在 GetKerningPairs 中使用? documentation 声明

lpkrnpair 数组中的对数。如果字体超过 nNumPairs kerning pair,函数返回错误。

但是,我不知道要传入多少对,也没有办法查询它。

编辑#2

这是我也尝试过的填充应用程序,对于任何字体的对数,这始终为 0。 GetLastError 也将始终返回 0。

#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;
}

编辑 我尝试执行以下操作,但是它仍然给了我 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 );

【问题讨论】:

    标签: c++ gdi+ gdi kerning


    【解决方案1】:

    问题在于您传递的是Gdiplus::Font 而不是SelectObject 的HFONT。您需要将Font* myFont 转换为HFONT,然后将HFONT 传递给SelectObject。

    首先,要将Gdiplus::Font 转换为HFONT,您需要从Gdiplus::Font 中获取LOGFONT。一旦你这样做了,剩下的就很简单了。获得字距对数的工作解决方案是

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

    如您所知,我所做的唯一功能更改是创建FONT

    【讨论】:

      【解决方案2】:

      您首先调用它时将第三个参数设置为 NULL,在这种情况下,它会返回字体的紧缩对数。然后分配内存,并通过该缓冲区再次调用它:

      int num_pairs = GetKerningPairs(your_dc, -1, NULL);
      
      KERNINGPAIR *pairs = malloc(sizeof(*pairs) * num_pairs);
      
      GetKernningPairs(your_dc, num_pairs, pairs);
      

      编辑:我做了一个快速测试(使用 MFC 而不是 GDI+)并得到了似乎合理的结果。我使用的代码是:

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

      这会打印出116 作为结果。

      【讨论】:

      • 为了让它工作,我似乎需要使用我的字体 dc,我怎么能得到它?
      • @chadb:创建一个 DC,并选择字体。您通常希望使用与最终目标兼容的 DC,因此如果输出要进入屏幕,请创建与屏幕兼容的 DC。如果它要去打印机,请为打印机创建一个。
      • 嗯,我试过了,我仍然得到 0。我更新了上面的代码,因为它不适合这里。
      • @chadb:我在答案中编辑了一些测试代码。做一些测试,似乎第二个参数,当第三个为 NULL 时确实应该忽略,毕竟没有被忽略,所以你需要将它设置为一个正数才能得到结果。我尝试了 1000 和 INT_MAX,似乎都很好。
      • 我尝试了 INT_MAX,但不幸的是也没有用,GDI+ 仍然返回 0。
      猜你喜欢
      • 1970-01-01
      • 2023-02-01
      • 2010-09-20
      • 1970-01-01
      • 1970-01-01
      • 2015-12-01
      • 2014-01-18
      • 1970-01-01
      • 2010-11-03
      相关资源
      最近更新 更多