2

次のコードを使用して、文字列内の各文字を囲む領域を測定しようとします。

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

これが結果です。

スクリーンショット

ご覧のように、文字 'f' と 'g' の領域はこれらの文字を完全に囲んでいません。これを修正するにはどうすればよいですか?

4

1 に答える 1

3

これは、これらの文字が隣接する文字から張り出すように設計されているために発生します。強調表示している幅は、次の文字が開始する距離であり、必ずしも文字の境界ボックスではありません。

私は GDI+ の専門家ではありませんが、おそらく書式設定フラグを変更して、文字が境界ボックスからはみ出さないようにする必要があるでしょう。特に、StringFormatFlagsNoFitBlackBoxは役に立ちます。

ストレート GDI で作業している場合は、おそらくGetCharABCWidthsを呼び出して、測定されたバウンディング ボックスから文字がオーバーハングできるかどうか、およびその範囲を把握し、手動で調整する必要があります。

于 2013-05-10T15:56:26.327 に答える