8

CP437 で一部がビットマップ フォントをレンダリングするプログラムを書いています。

charテキストをレンダリングする関数では、次のように、エンコード変換の前に CP437 でa が使用可能かどうかを確認できるようにしたいと考えています。

public static void DrawCharacter(this Graphics g, char c)
{
    if (char_exist_in_encoding(Encoding.GetEncoding(437), c) {
        byte[] src = Encoding.Unicode.GetBytes(c.ToString());
        byte[] dest = Encoding.Convert(Encoding.Unicode, Encoding.GetEncoding(437), src);
        DrawCharacter(g, dest[0]); // Call the void(this Graphics, byte) overload
    }
}

このチェックを行わないと、CP437 以外の文字は'?'(63, 0x3F) になります。無効な文字を完全に非表示にしたい。char_exist_in_encoding 次の愚かなアプローチ以外の実装はありますか?

private static bool char_exist_in_encoding(Encoding e, char c)
{
    if (c == '?')
        return true;
    byte[] src = Encoding.Unicode.GetBytes(c.ToString());
    byte[] dest = Encoding.Convert(Encoding.Unicode, e, src);
    if (dest[0] == 0x3F)
        return false;
    return true;
}


おそらくあまり関係ありませんが、ビットマップは次のように作成されます。

Bitmap b = new Bitmap(256 * 8, 16);
Graphics g = Graphics.FromImage(b);
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit;
Font f = new Font("Whatever 8x16 bitmap font", 16, GraphicsUnit.Pixel);
for (byte i = 0; i < 255; i++)
{
    byte[] arr = Encoding.Convert(Encoding.GetEncoding(437), Encoding.Unicode, new byte[] { i });
    char c = Encoding.Unicode.GetChars(arr)[0];
    g.DrawString(c.ToString(), f, Brushes.Black, i * 8 - 3, 0); // Don't know why it needs a 3px offset
}
b.Save(@"D:\chars.png");
4

1 に答える 1

2

Vlad のおかげで、少し調査した後、MSDN で最終的に例をEncoderFallback見ました

私の作業中の(おそらく一時的な作業中の)コードは次のとおりです。

public static void DrawCharacter(this Graphics g, char c)
{
    byte[] src = Encoding.Unicode.GetBytes(c.ToString());
    byte[] dest = Encoding.Convert(Encoding.Unicode, Encoding.GetEncoding(437, new EncoderReplacementFallback(" "), new DecoderReplacementFallback(" ")), src);
    DrawCharacter(g, dest[0]);
}

無効な文字をスペースに置き換えます" "

PS私はもともと空string ""の文字を代わりに使用していましたが、最終的にはスペース文字を使用することにしました。

于 2012-06-26T15:40:40.617 に答える