1

我正在从事 GDI 到 DirectWrite 迁移项目。我想计算每个 unicode 字符的宽度,在 GDI 上这是使用 GetCharWidth 完成的。在 msdn 博客上,我发现 GDI 的 GetCharWidth 的替代品是 GetDesignGlyphMetrics 。

谁能告诉我如何使用这个函数 GetDesignGlyphMetrics 来获取 DWRITE_GLYPH_METRICS?

如何实例化它的第一个参数 UINT16 const* glyphIndices?

4

1 回答 1

4

您可以通过IDWriteFontFace::GetGlyphIndices获取字形

我从我的项目中挑选了一些代码,这只是一个示例,向您展示如何使用此函数,如果您想在项目中使用它,您应该进行一些重构,将 XXXCreate 函数移动到代码的初始化部分。例如,您不需要每次调用此函数(GetCharWidth)时都创建 DWriteFacotry。并释放动态数组以避免内存泄漏。

IDWriteFactory*         g_pDWriteFactory    = NULL;
IDWriteFontFace*        g_pFontFace         = NULL;
IDWriteFontFile*        g_pFontFile         = NULL;
IDWriteTextFormat*      g_pTextFormat       = NULL;

VOID GetCharWidth(wchar_t c)
{
    // Create Direct2D Factory
    HRESULT hr = D2D1CreateFactory(
        D2D1_FACTORY_TYPE_SINGLE_THREADED,
        &g_pD2DFactory
        );
    if(FAILED(hr))
    {
        MessageBox(NULL, L"Create Direct2D factory failed!", L"Error", 0);
        return;
    }

    // Create font file reference
    const WCHAR* filePath = L"C:/Windows/Fonts/timesbd.ttf";
    hr = g_pDWriteFactory->CreateFontFileReference(
        filePath,
        NULL,
        &g_pFontFile
        );
    if(FAILED(hr))
    {
        MessageBox(NULL, L"Create font file reference failed!", L"Error", 0);
        return;
    }

    // Create font face
    IDWriteFontFile* fontFileArray[] = { g_pFontFile };
    g_pDWriteFactory->CreateFontFace(
        DWRITE_FONT_FACE_TYPE_TRUETYPE,
        1,
        fontFileArray,
        0,
        DWRITE_FONT_SIMULATIONS_NONE,
        &g_pFontFace
        );
    if(FAILED(hr))
    {
        MessageBox(NULL, L"Create font file face failed!", L"Error", 0);
        return;
    }

    wchar_t textString[] = {c, '\0'};

    // Get text length
    UINT32 textLength = (UINT32)wcslen(textString);

    UINT32* pCodePoints     = new UINT32[textLength];
    ZeroMemory(pCodePoints, sizeof(UINT32) * textLength);

    UINT16* pGlyphIndices   = new UINT16[textLength];
    ZeroMemory(pGlyphIndices, sizeof(UINT16) * textLength);

    for(unsigned int i = 0; i < textLength; ++i)
    {
        pCodePoints[i] = textString[i];
    }

    // Get glyph indices
    hr = g_pFontFace->GetGlyphIndices(
        pCodePoints,
        textLength,
        pGlyphIndices
        );
    if(FAILED(hr))
    {
        MessageBox(NULL, L"Get glyph indices failed!", L"Error", 0);
        return;
    }

    DWRITE_GLYPH_METRICS* glyphmetrics = new DWRITE_GLYPH_METRICS[textLength];
    g_pFontFace->GetDesignGlyphMetrics(pGlyphIndices, textLength, glyphmetrics);

    // do your calculation here

    delete []glyphmetrics;
    glyphmetrics = NULL;
}
于 2014-07-08T02:28:26.947 回答