明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 8583|回复: 50

[基础教程] 浅谈如何制作矢量字体文件

    [复制链接]
发表于 2024-1-1 12:21:19 | 显示全部楼层 |阅读模式
本帖最后由 原地踏步 于 2024-1-3 21:20 编辑

本人原本对矢量字体文件一无所知,后来在明经看到wharan及szhorse等网友的贴子,颇受启发,于是试着自己研究了一下。中间也经历了一些曲折,最后总算有点收获,不敢藏私,在这里与各位朋友分享。若有错误,欢迎大家批评指正。
szhorse的帖子:http://bbs.mjtd.com/thread-186226-1-1.html

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

评分

参与人数 9明经币 +11 收起 理由
USER2128 + 1 很给力!
Wu_Enwu + 1
pzweng + 3 很给力!
spp_wall + 1 赞一个!
bssurvey + 1 赞一个!
szhorse + 1 非常优秀,收藏学习
自贡黄明儒 + 1 太优秀了,做一个记号
cghdy + 1
llsheng_73 + 1 赞一个!

查看全部评分

本帖被以下淘专辑推荐:

 楼主| 发表于 2024-1-1 13:11:29 | 显示全部楼层
制作文字
1)准备
先将编译后的形文件,如HZTXT.SHX,反编译成形定义文件HZTXT.SHP。反编译可采用SHX2SHP等软件,网上有,搜一下就可以。
再开一张新图,绘制一个网格。网格间距为1mm,尺寸大小根据需要确定。尺寸越大,字体精度越高,但字节数可能会增加。
由于形定义文件X、Y的位移取值范围为-128~+127,因此建议网格不要超过127×127。这样只要线段均在网格内,就不必担心超出范围的问题了。
将网格制成图块,块名为“GRID”(后面的程序要用到),原点为网格左下角。
现在,就可以开始写字了。
2)制作
写字的方式很多,高手可以直接绘制,一般人可以先找几个与待写字符有相同偏旁的文字,用CAD的ET自带程序TXTEXP炸开,再来拼凑组合,也可以找一个喜欢的TrueType或其它字体来描(推荐)。若采用描字法,可将底字设置适当的透明度,以避免遮住光标。
有效的图元为 LINE、LWPOLYLINE、POLYLINE、ARC、CIRCLE。
将写好的字置于网格内,运行程序LINSHP,即可生成该字符的代码。
程序会删除网格中的原线段,按数据内容重新绘制在网格内,并生成代码及字节数。如果拾取了文字,还会生成它的GBK或UNICODE码。
由于形文件所要求的矢量均为整数,程序又仅使用代码12和13来绘制圆弧(整圆采用代码10绘制),因此所有的点均会落在网格上(使用代码11绘制时,终点不一定落在网格上)。但写字时不可能这么精确,这会造成一些意料之外的结果,因此可能还需要做一些微调,特别是涉及到弧的情况下。调整可就在网格内进行,待满意后可再次运行LINSHP。
程序可将生成的数据直接写入形定义文件中,但不知什么原因有时候会出错,建议选择不写入,而将打印在屏幕上的代码手动复制至形定义文件中。
形定义文件的最后应有至少一个空行。
程序默认字体格式为BIGFONT,字宽固定,也可选择UNIFONT,或字宽不固定。
当选择固定字宽时,BIGFONT字体采用十进制编码,数据始终以 “7,1” 开头,以 “7,2” 结束;UNIFONT字体采用十六进制编码,始终以 “7,00001” 开头,以 “7,00002” 结束。当选择可变字宽时,不使用代码7,用户需自己输入字宽。通常BIGFONT字体均为全角字符,采用固定字宽即可,但UNIFONT字体可能包含有半角的英文字母、数字及符号,此时就会用到可变字宽。
程序可支持所有平面的UNICODE字符编码,但位于平面0以外的字符编码,目前的CAD(我用的是2014及2021)无法通过编译。
程序不进行坐标转换,不检查图块是否正确(只读取图块名及插入点),也不检查图层是否锁定。
最后,使用CAD的命令COMPILE编译字形定义文件,即可得到字形文件。
若字符大小为127×127,则绘制的文字会与字高为127,宽度因子为1的写出来的文字完全吻合。


回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2024-1-1 12:54:09 | 显示全部楼层
原地踏步 发表于 2024-1-1 12:36
程序共4个
linshp == 将线段生成 shp 所需代码
shplin == 读取 shp 文件,生成线段

hztxt.shx 主要是美化了一些字,并增加了一些字。基本上一二三级字能写的都写了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2024-1-1 13:12:57 | 显示全部楼层
最后,在这里祝大家新年快乐,心想事成!
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2024-1-1 12:36:52 | 显示全部楼层
程序共4个
linshp == 将线段生成 shp 所需代码
shplin == 读取 shp 文件,生成线段
shpcom == 以上两个程序的共用子程序,不可单独执行
yb_gbkuni == GBK 码转 UNICODE 码映射表

点评

eii
搞明白了,高版本的cad不能运行,我的是2016版,在2008版可以运行  发表于 6 天前
 楼主| 发表于 2024-1-1 13:00:50 | 显示全部楼层
本帖最后由 原地踏步 于 2024-1-1 13:08 编辑

下面简单介绍一下如何制作矢量字体,结合一个例子来说明。详细内容可参考1楼的pdf文件。
例子中网格尺寸为127×127,字符的大小也为127×127。


字符“咸” 的代码为:
*53196,88,咸
7,1,8,(3,5),1,12,(14,39,16),12,(1,19,2),8,(0,38),8,(102,0),2,8,(-12,5),1,12,
(-18,16,5),2,8,(-13,3),1,13,(6,-60,3),(14,-45,8),(9,-10,19),(9,3,61),(5,23,7),
(0,0),2,8,(-12,48),1,12,(-45,-78,-24),2,8,(-29,18),1,9,(30,0),(0,32),(-30,0),(0,
-32),(0,0),2,8,(-8,53),1,8,(47,0),7,2,0
以下依次说明:
★第一行:
*53196:形编号,即字符“咸” 的十进制GBK码,以 “*” 开头。也可采用十六进制,十六进制编码前面要加0。同一个形定义文件中不能有重复的编号。
88:后续行中数据的字节数。每个逗号分隔着一个字节,数一下就知道了。每个形最多可有2000个字节。
:形名称,通常省略。
★后续行:
形定义的数据,可为一行或多行,每行最多可包含128个字符。
代码7:绘制编号由下一个字节指定的子形。
数据1:由代码7指定的子形编号,必须位于当前的形定义文件中。可能为:
*1,7
5,2,14,8,(-63,-127),0
也就是说,原数据也可写为(要去掉子形的结束符0):
5,2,14,8,(-63,-127),8,(3,5),1,12,(14,39,16),……
代码5:将当前位置入栈,即保存当前坐标,后面不跟数据。由于此前没有任何位移,故当前坐标为原点(0,0)。
代码2:取消激活绘图模式(提笔),也就是笔悬空移动,不绘制。
代码14:只有当文字是垂直的,才会处理下一个命令,水平文字会自动忽略此代码。垂直文字一般仅起点和终点与水平文字不同,其余都是一样的。代码14放在此处,与代码8结合,用于确定垂直文字的起点。当字符不可书写垂直文字时,就不要使用代码14。
代码8:由后面两个数字指定 X-Y 的位移(不是坐标,位移换算成坐标值要与前面的坐标相加)。
数据 (-63,-127):由代码8指定的位移,即向X方向位移 -63,向Y方向位移-127。这就是垂直文字中下一个字符的起点。其中的括号不是必需的,只是为了阅读方便。建议书写时均加上括号。
数据8,(3,5),:与上一组数据类似,区别是代码14已结束了,此处的代码8用于水平文字。即从坐标 (0,0) 开始(代码14的位移在水平文字中被忽略),向X方向位移3,向Y方向位移5。从上图中可以看出,字符 “咸” 的起点坐标即为(3,5)。
代码1:激活绘图模式(落笔)。
代码12:绘制一段圆弧,后面跟三个数字。前两个数字的含义与代码8类似,分别代表X-Y方向的位移,第三个数字为凸度,其取值范围为-127~127,逆时针为正。凸度的计算公式为:(2*H/D)*127,可采用小数计算,但计算后得到的值应取整数。半圆的凸度为127(或-127),凸度为0时表示直线段。     
形说明中的凸度与群码表中LWPOLYLINE的群码42代表的凸度计算方法类似,但多了一个系数,形的凸度=群码凸度×127。
数据“1,12,(14,39,16),12,(1,19,2),8,(0,38),8,(102,0),” 表示先绘制两段弧,再绘制两段直线,即“咸” 字中的 “厂”。该段数据也可写成:
“1,12,(14,39,16),1,12,(1,19,2),1,8,(0,38),1,8,(102,0),”
很显然,这种写法的字节数较多。
数据2,8,(-12,5),1,12,(-18,16,5),2,8,(-13,3):抬笔位移,落笔绘制一段弧,即“咸” 字右上角的点,再抬笔位移。
代码13:与代码12类似,但可绘制多段圆弧,以 (0,0) 结束。注意 “(0,0)” 不能省略,不要以为加了括号,电脑就会知道你在什么时候结束。前面说过,括号反而是可以省略的。
数据“1,13,(6,-60,3),(14,-45,8),(9,-10,19),(9,3,61),(5,23,7),(0,0),”的含义为:落笔,连续绘制5段圆弧,即右侧的弯钩。
前面的代码“12,(14,39,16),12,(1,19,2),” 也可写为:“13,(14,39,16),(1,19,2),(0,0),”
同样,这种写法的字节数较多。很容易知道,当连续绘制3段弧时,代码12与代码13的字节数相同;超过3段时,使用代码13在字节数上就有优势了。
数据2,8,(-12,48),1,12,(-45,-78,-24),2,8,(-29,18):抬笔位移,落笔绘制一段弧,即“咸”字右侧的撇,再抬笔位移。
代码9:与代码8类似,但可绘制多段直线,以 (0,0) 结束。
数据“1,9,(30,0),(0,32),(-30,0),(0,-32),(0,0),” 的含义为:落笔,连续绘制4段直线,即下方的 “口”。
前面的数据“8,(0,38),8,(102,0),” 也可写为:“9,(0,38),(102,0),(0,0),”,但字节数较多。
数据2,8,(-8,53),1,8,(47,0):抬笔位移,落笔绘制一段直线,即“口”上面的一横。
数据7,2:引用编号为2的子形,子形必须位于当前的形定义文件中。编号2的定义可能为:
*2,10
6,2,8,(127,0),14,8,(-127,-127),0
则原数据也可写为:……2,8,(-8,53),1,8,(47,0), 6,2,8,(127,0),14,8,(-127,-127),0
代码6:将当前位置出栈,即取出由前一个代码5储存的坐标。也就是说,无论此时坐标位于何处,均回到储存的坐标点上。代码5储存的坐标为(0,0),即当前的笔处于原点位置。
数据2,8,(127,0):抬笔向X方向位移127,为本字符的终点,也是下一个字符的起点。本字符起点与终点的距离,即为该字符的宽度。由于字符一般都不会写满,因此它的宽度也包含了空余部分。字符的最后一点通常都不是终点,每个字符的终点都需要专门定义。
数据14,8,(-127,-127):定义垂直文字的终点,不影响水平文字。
代码0:结束形定义。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x
发表于 2024-1-1 13:51:25 | 显示全部楼层
学习了谢谢分享
发表于 2024-1-1 13:59:08 | 显示全部楼层
不错新年的第一帖,硕果累累!
发表于 2024-1-1 14:11:10 来自手机 | 显示全部楼层
录个视频学习下,主要步骤如何
发表于 2024-1-2 07:12:23 | 显示全部楼层
新年的第一好帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-25 13:24 , Processed in 0.204000 second(s), 36 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表