Loading... # 一、问题描述 最近打开一个CAD文件显示问号,用看图王发现是钢筋字体,像往常一样替换tssdeng.shx字体。 <div class='album_block'> [album type="photos"] ![CAD缺字体](https://www4.iceyer.cn:444/usr/uploads/2024/05/997006794.png) ![看图王字体正常](https://www4.iceyer.cn:444/usr/uploads/2024/05/3436151317.png) [/album] </div> # 二、初步测试 1. 在CAD中通过`PR`命令查看对应的字体样式,之后输入`ST`命令找到对应样式,替换`tssdeng.shx`,操作后发现依旧显示问号,emmmm。 ![CAD](https://www4.iceyer.cn:444/usr/uploads/2024/05/113265818.png) 2. 回到看图王中,确认就是钢筋符号。我们知道在CAD中,`单行文字`可以通过`%%数字`的形式来输入CAD钢筋符号,所以这里我们测试在这段文本后面输入`%%132`,可以发现钢筋字体确实被转换了。 ![%%132](https://www4.iceyer.cn:444/usr/uploads/2024/05/3008281615.png) PS:CAD支持直接输入Unicode编码,比如`%%132`也可以用`\u+0084`! # 三、深入分析 1. 既然肉眼看不出问题,那就复制到文本文档中,用`WinHex`一探究竟吧。 ![WinHex](https://www4.iceyer.cn:444/usr/uploads/2024/05/1026490265.png) 2. 这里发现我们正常显示的Ⅲ级钢筋字体是`C2 84`,而显示异常的是`EE 94 B2`,这里我们就需要查看`tssdeng.shx`字体了,看看是不是缺少某些字库导致的。 3. 在CAD中的SHX是矢量字库字体,平常字体编辑器无法预览,这里可以用`ShxViewer`、`SHX2SHP`两款软件进行查看。 ![ShxViewer](https://www4.iceyer.cn:444/usr/uploads/2024/05/1114174378.png) 4. 细心的会发现,我们在CAD输入的`%%132`中的`132`转换十六进制就等于`84`,所以我们在这两款软件中找到`84`的位置都可以看到钢筋符号,同理我们也知道了相邻位置的钢筋符号: | 16进制 | 10进制 | 解释 | | ------- | ------ | -------- | | \u+0082 | %%130 | Ⅰ级钢筋 | | \u+0083 | %%131 | Ⅱ级钢筋 | | \u+0084 | %%132 | Ⅲ级钢筋 | | \u+0085 | %%133 | Ⅳ级钢筋 | | ... | | | 5. 但是我们在`WinHex`中,显示`C2 84`,而不是`84`,为什么会多一个`C2`呢?`EE 94 B2`又如何计算它在字体中所对应的位置呢? 6. 带着这些疑问我们首先需要了解**UTF-8 编码规则**: ``` U+0000 到 U+007F(1字节): 这个范围的字符只需要一个字节,直接与 ASCII 码相同,从 `0x00` 到 `0x7F`。 U+0080 到 U+07FF(2字节): 这个范围的字符需要两个字节来编码。 第一个字节从 `110xxxxx` 开始,第二个字节从 `10xxxxxx` 开始。 这里的 `x` 代表原始Unicode代码点的比特。 U+0800 到 U+FFFF(3字节): 这个范围的字符需要三个字节来编码。 第一个字节从 `1110xxxx` 开始,随后两个字节都从 `10xxxxxx` 开始。 U+10000 到 U+10FFFF(4字节): 这个范围的字符需要四个字节来编码。 第一个字节从 `11110xxx` 开始,随后三个字节都从 `10xxxxxx` 开始。 ``` 7. 这里说一下我的理解,有误请指出,首先是**正向思维**: ``` `U+0084`属于`U+0080 到 U+07FF`区间,所以最后应该得到两个字节; `84`转换二进制得到`1000 0100`; 根据字节高低位,我们可以先算第二个字节,第二个字节从 `10xxxxxx` 开始,取`1000 0100`后六位`00 0100`与 `10xxxxxx` 拼接得到`1000 0100`,转换十六进制得到`84`; 第一个字节从 `110xxxxx` 开始,因为刚刚`1000 0100`用掉了6位,我们还剩下2位,即`10`,拼接得到`110xxx10`,但是这里我们需要5位,所以补零占位,得到`1100 0010`,转换十六进制得到`C2`; 将两个字节拼接得到`C2 84`两个字节。 ``` 8. 接下来是**逆向思维**: ``` `C2 84`是两个字节,遵循UTF-8 编码规则,即第一个字节从 `110xxxxx` 开始,第二个字节从 `10xxxxxx` 开始; `C2`转换二进制`1100 0010`取后5位得到`0 0010`; `84`转换二进制`1000 0100`取后6位得到`00 0100`; 将两个二进制拼接得到`0 0010 00 0100`,去掉前面多余的0整理后`1000 0100`,转换十六进制得到`84`。 ``` 9. 最后让我们计算**EE 94 B2**: ``` `EE 94 B2`是三个字节,遵循UTF-8 编码规则,即第一个字节从 `1110xxxx` 开始,随后两个字节都从 `10xxxxxx` 开始; `EE`转换二进制`1110 1110`取后4位得到`1110`; `94`转换二进制`1001 0100`取后6位得到`01 0100`; `B2`转换二进制`1011 0010`取后6位得到`11 0010`; 将三个二进制拼接得到`1110 01 0100 11 0010`整理后`1110 0101 0011 0010`,转换十六进制得到`E532`。 ``` 10. 使用上述两款软件也验证了`E532`位置不存在对应的字形。既然没有,那咱就手动添加一个试试。 ![E532](https://www4.iceyer.cn:444/usr/uploads/2024/05/3297915876.png) 11. 因SHX文件不能直接修改,需要反编译成SHP文件才能修改,碰巧这两款软件都支持反编译SHP。 ![反编译SHP](https://www4.iceyer.cn:444/usr/uploads/2024/05/3395590227.png) 12. 将得到的SHP文件用记事本打开,我们可以搜索找到`*132`(84)开头到下一个`*`开头中间内容就是`*132`的字形内容,我们把它复制到文件末尾,修改开头为`*58674`(E532),然后保存。 <div class='album_block'> [album type="photos"] ![*132](https://www4.iceyer.cn:444/usr/uploads/2024/05/727520627.png) ![*58674](https://www4.iceyer.cn:444/usr/uploads/2024/05/1589468761.png) [/album] </div> 13. 回到CAD中输入`COMPILE`命令,找到更改后的`tssdeng.shp`文件,选择`打开`,将自动编译成`tssdeng.shx`文件。关闭CAD,将新的`tssdeng.shx`文件替换到CAD的fonts文件夹中,再次启动CAD,问题得到解决。其他钢筋符号或者生僻字同理。 <div class='album_block'> [album type="photos"] ![COMPILE](https://www4.iceyer.cn:444/usr/uploads/2024/05/1469972246.png) ![Fonts](https://www4.iceyer.cn:444/usr/uploads/2024/05/2908621125.png) ![CAD](https://www4.iceyer.cn:444/usr/uploads/2024/05/369028373.png) [/album] </div> 14. 当然,新的`tssdeng.shx`字体文件我们放在`SHX2SHP`中也能找到`E532`位置的字形了。 ![SHX2SHP](https://www4.iceyer.cn:444/usr/uploads/2024/05/3548051404.png) # 四、后记 1. 在使用`SHX2SHP`时,如果字形存在引用的情况下,比如`2,`开头是字形,`7,*xx`开头是引用`*xx`字形。在使用`Code view`显示的不是引用的字形; 2. 在使用`ShxViewer`时,反编译shp文件头部会加入编译信息会导致`COMPILE`命令报错,需要删除;同时`*`引用的位置有时显示10进制有的显示16进制,貌似超过ff就会显示16进制?而且软件显示的数量貌似也有限制,但在`SHX2SHP`根据位置可以单独查看。 3. 所以上面两个软件配合着来吧。 4. 其实研究到中途时,偶然发现网络上有新一版的`tssdeng.shx`文件,内部已经包含了本次`E532`的字形,所以这里留一下研究思路吧,方便后面手动添加字形,也可以解决生僻字的问题,比如这篇文章:[制作一个含生僻字的矢量字体文件-CSDN博客](https://blog.csdn.net/issating/article/details/125392388) # 五、下载 <button class=" btn m-b-xs btn-primary " onclick="window.open('https://www.iceyer.cn/usr/uploads/2024/05/527779931.zip','_blank')">相关测试文件及工具</button> Last modification:May 30, 2024 © Allow specification reprint Support Appreciate the author AliPayWeChat Like 10 喜欢我的文章吗? 别忘了点赞或赞赏,让我知道创作的路上有你陪伴。