MeasureCharacterRanges不符合角色?

时间:2013-05-10 13:35:09

标签: c++ text fonts gdi+

我尝试使用以下代码测量包含字符串中每个字符的区域:

void Draw(HDC dc)
{
    using namespace Gdiplus;
    Graphics graphics(dc);
    wstring chars;
    for(int i=32; i<127; ++i)
    {
        chars += i;
        chars += 32;
    }

    Font font(L"Times New Roman", 30, FontStyleRegular, UnitPoint);
    TextRenderingHint hint = TextRenderingHintAntiAlias    ;
    const StringFormat* pStringFormat = StringFormat::GenericTypographic();
    StringFormat MeasureFormat(pStringFormat);
    const float Offset = 60.f;
    RectF   layout(Offset, Offset, m_ScreenWidth - Offset*2, m_ScreenHeight - Offset*2);
    std::vector<RectF> charSize;
    for(size_t i=0; i<chars.size(); ++i)
    {
        if(i%2 == 0)
        {
            CharacterRange range(i, 1);
            MeasureFormat.SetMeasurableCharacterRanges(1, &range);
            Region region;

            graphics.MeasureCharacterRanges(chars.c_str(), -1, &font, layout, &MeasureFormat, 1, &region);
            RectF rec;
            region.GetBounds(&rec, &graphics);   
            charSize.push_back(rec);
        }
    }

    graphics.SetTextRenderingHint(hint);

    for(size_t i=0 ; i<charSize.size(); ++i)
    {
        graphics.FillRectangle(&SolidBrush(0xaa998844), charSize[i]);
    }

    graphics.DrawString(chars.c_str(), -1, &font, layout, pStringFormat, &SolidBrush(0xff0000ff));
}

这就是结果:

screen shot

正如您所看到的,字母“f”和“g”的区域并未完美地包含这些字符。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:3)

这是因为这些字符设计为与相邻字符悬垂。您突出显示的宽度是下一个角色应该开始的距离,这不一定是角色的边界框。

我不是GDI +的专家,但您可能需要更改格式化标志,告诉它您不希望字符悬在边界框上。特别是,StringFormatFlagsNoFitBlackBox看起来很有用。

如果您正在使用直接GDI,您可能需要致电GetCharABCWidths以确定角色是否以及多少可以悬挂在测量的边界框上并手动调整它。