GB2312和GBK存在的价值在于,它们非常容易实现,而Unicode则不是那么容易实现。
ASCII、GB2312、GBK、GB18030、UTF-8的关系:
显示效果(方便起见,没有实现半角显示):
C#代码如下,如有错误欢迎指出。
<code class="language-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></=></=></=></=></=></=></=></code>
所用GBK字模:
[修改于 8年6个月前 - 2016/06/07 15:33:45]
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |
200字以内,仅用于支线交流,主线讨论请采用回复功能。