GB2312和GBK存在的价值在于,它们非常容易实现,而Unicode则不是那么容易实现。
引用
评论
ASCII、GB2312、GBK、GB18030、UTF-8的关系:
显示效果(方便起见,没有实现半角显示):
C#代码如下,如有错误欢迎指出。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace gbkzk
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
gbk16zm = File.ReadAllBytes("gbk16.bin");
gbk24zm = File.ReadAllBytes("gbk24.bin");
}
private byte[] gbk16zm;
private byte[] gbk24zm;
// 计算GBK偏移量
private int gbkoffset(byte blb, byte bhb) // byte == unsigned char
{
uint bl = blb;
uint bh = bhb;
uint offset = 0;
if (bh > 0x7F) bh--; // 去掉7F一条线
if (bl >= 0x81 && bl <= 190 0xa0) gbk 3: 81~a0 190*32="6080" { offset="(bl" - 0x81) * + (bh 0x40); } else if (bl>= 0xA1 && bl <= 1 94 0xa7) gbk 1: a1~a7 94*7="658" { offset="(bl" - 0xa1) * + (bh 6080; 注意此处要加1 } else if (bl>= 0xA8 && bl <= 190 6080 0xa9) gbk 1与gbk 5合并区 a8 a9 190*2="380" { offset="(bl" - 0xa8) * + (bh 0x40) 658; } else if (bl>= 0xAA && bl <= 4 96 658 6080 0xaf) gbk aa~af 96*6="576" { offset="(bl" - 0xaa) * + (bh 0x40) 380; } else if (bl>= 0xB0 && bl <= 190 380 658 6080 0xf7) gbk 4与gbk 2合并区 b0~f7 190*72="13680" { offset="(bl" - 0xb0) * + (bh 0x40) 576; } else if (bl>= 0xF8 && bl <= 1="=" 4 96 380 576 658 6080 0xfe) gbk f8~fe 96*7="672" { offset="(bl" - 0xf8) * + (bh 0x40) 13680; } return (int)offset; 取得字符的字模 private byte[] getgbkzm(byte[] gbkzm, int pt, byte bl, bh) size="pt" pt 8; 计算字模大小 size; 计算偏移量 zm="new" byte[size]; array.copy(gbkzm, offset, zm, 0, size); 取这个字的字模 zm; 扫描字模 bool scanzm(byte[] x, y) bitoff="y" x; 由坐标计算总位偏移 byteoff="bitoff" 字节偏移 bitshift="(7" % 8); 位偏移(从高位开始) ((zm[byteoff]>> bitshift) & 1); // 取所需位
}
// 绘制字模
private void drawzm(Graphics g, byte[] zm, int pt, int x, int y)
{
Bitmap bmp = new Bitmap(pt, pt); // 先在位图上绘制
for (int i = 0; i < pt; i++)
{
for (int j = 0; j < pt; j++)
{
bool val = scanzm(zm, pt, j, i); // 扫描字模
bmp.SetPixel(j, i, val ? Color.Black : Color.White); // 设置位图点的颜色
}
}
g.DrawImage(bmp, x, y); // 绘制位图
}
// 绘制字符串(只实现了全角字符)
private void drawstring(byte[] str, Graphics g, byte[] gbkzm, int pt)
{
byte bl = 0;
byte bh = 0;
for (int i = 0; i < str.Length; i++)
{
if (str[i] >= 0x81 && str[i] <= 0xfe && i < str.length) { 全角字符 bl="str[i];" bh="str[i" + 1]; 取得字模 byte[] zm="getgbkzm(gbkzm," pt, bl, bh); 计算坐标 int x="i" * pt 2; y="0;" 绘制字模 drawzm(g, zm, x, y); 跳过尾字节 i++; } else 不实现半角英文字符显示 continue; private void button1_click(object sender, eventargs e) txt="Encoding.GetEncoding(936).GetBytes(textBox1.Text);" graphics g="pictureBox1.CreateGraphics();" g.clear(color.white); drawstring(txt, g, gbk16zm, 16); button2_click(object gbk24zm, 24); code></=></=></=></=></=></=></=>
所用GBK字模: