硬汉嵌入式论坛

 找回密码
 立即注册
查看: 5118|回复: 22
收起左侧

[有问必答] 第22期TrueType矢量字体例程不能显示中文

[复制链接]

1

主题

9

回帖

1

积分

新手上路

积分
1
发表于 2016-7-11 16:23:27 | 显示全部楼层 |阅读模式
求中文矢量字体的显示示例,第22期好像只能显示应为和数字。谢谢
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117564
QQ
发表于 2016-7-11 16:26:30 | 显示全部楼层
F407板子做不到,汉字矢量字体库太大了,外部SRAM加载不进去。最近在弄F429板子的emWin教程,后面做个。
回复

使用道具 举报

1

主题

9

回帖

1

积分

新手上路

积分
1
 楼主| 发表于 2016-7-11 16:32:10 | 显示全部楼层
大概需要多少内存呢,一直没弄明白,这个内存是指整个字库需要的内存吗?是否可以只加载需要的字库呢,比如说我只需要显示“明天”这两个字,只加载这一点字库不行吗
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117564
QQ
发表于 2016-7-12 08:57:06 | 显示全部楼层

回 waming2102 的帖子

waming2102:大概需要多少内存呢,一直没弄明白,这个内存是指整个字库需要的内存吗?是否可以只加载需要的字库呢,比如说我只需要显示“明天”这两个字,只加载这一点字库不行吗
(2016-07-11 16:32)
矢量字体要全部都加载后使用,不支持几个字的情况。矢量函数一般都是10几MB
回复

使用道具 举报

1

主题

9

回帖

1

积分

新手上路

积分
1
 楼主| 发表于 2016-7-12 10:01:46 | 显示全部楼层
谢谢,明白啦,我自己在捣鼓,可不可以提供一下编程思路呢,都不知道汉字显示要用到哪些函数,具体有哪些流程,汉字显示跟英文和数字显示不一样吧,网上的资料很少
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117564
QQ
发表于 2016-7-12 10:34:32 | 显示全部楼层

回 waming2102 的帖子

waming2102:谢谢,明白啦,我自己在捣鼓,可不可以提供一下编程思路呢,都不知道汉字显示要用到哪些函数,具体有哪些流程,汉字显示跟英文和数字显示不一样吧,网上的资料很少 (2016-07-12 10:01) 
跟英文的显示一样,没区别。
回复

使用道具 举报

1

主题

9

回帖

1

积分

新手上路

积分
1
 楼主| 发表于 2016-7-12 11:32:25 | 显示全部楼层
谢谢,跟英文显示方式一样,我能正确显示汉字了。

字库需要的内存大,就是因为要去读ttf文件,将ttf文件的所有内容读到RAM中,能不能换个方式,像写flash一样,直接将矢量字库烧写在SD卡中(不用文件的形式)或者flash中,需要显示某个字时,根据其编码,读对应的数据就行,这样就不需要用太大的内存,不知道这样做能否实现,以前做点阵的字库是可以将文件直接烧写到flash中的,但是是bin文件,不知道ttf文件可不可以。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117564
QQ
发表于 2016-7-13 00:21:02 | 显示全部楼层

回 waming2102 的帖子

waming2102:谢谢,跟英文显示方式一样,我能正确显示汉字了。

字库需要的内存大,就是因为要去读ttf文件,将ttf文件的所有内容读到RAM中,能不能换个方式,像写flash一样,直接将矢量字库烧写在SD卡中(不用文件的形式)或者flash中,需要显示某个字时,根据其编码,读对应的数据就行,这样 .. (2016-07-12 11:32) 
不支持,emWin的矢量字体显示只能是总线地址的形式去访问。
回复

使用道具 举报

6

主题

231

回帖

249

积分

高级会员

积分
249
发表于 2016-7-13 10:38:02 | 显示全部楼层
其实很少RAM就可以使用矢量字体,我用过freetype,他需要你配置几个读取函数,你那几个函数可以从RAM读,也可以从闪存读,也可以从文件系统读。反正他要求你读矢量字库那个部分你就按要求读取就行了,不需要整个矢量字库装入内存的。实际上几十K字节的内存就可以支持矢量字体的显示,当然了内存越大越好,如果能够把整个矢量字库装入内存就更好。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117564
QQ
发表于 2016-7-13 10:47:49 | 显示全部楼层

回 novice 的帖子

novice:其实很少RAM就可以使用矢量字体,我用过freetype,他需要你配置几个读取函数,你那几个函数可以从RAM读,也可以从闪存读,也可以从文件系统读。反正他要求你读矢量字库那个部分你就按要求读取就行了,不需要整个矢量字库装入内存的。实际上几十K字节的内存就可以支持矢量字体的显 .. (2016-07-13 10:38) 
emWin的API函数已经限制只能全部加载。除非修改底层。
回复

使用道具 举报

6

主题

231

回帖

249

积分

高级会员

积分
249
发表于 2016-7-13 11:38:44 | 显示全部楼层

回 eric2013 的帖子

eric2013:emWin的API函数已经限制只能全部加载。除非修改底层。 (2016-07-13 10:47)
这个反映出emWin的设计人员经验不足,就像当年很多西方程序员写的程序不支持中文一样。
因为TRUETYPE矢量字体技术是Adobe/Microsoft/Apple三家公司的专利,freetype矢量字体引擎是绕过了TRUETYPE专利的一种实现,所以我猜想emWin和其他第三方库也是用freetype改的。
freetype原本就对嵌入式支持得很好,我用STM32F103也跑过freetype,当然效果不算好。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117564
QQ
发表于 2016-7-13 11:51:37 | 显示全部楼层

回 novice 的帖子

novice:这个反映出emWin的设计人员经验不足,就像当年很多西方程序员写的程序不支持中文一样。
因为TRUETYPE矢量字体技术是Adobe/Microsoft/Apple三家公司的专利,freetype矢量字体引擎是绕过了TRUETYPE专利的一种实现,所以我猜想emWin和其他第三方库也是用freetype改的。
freetype原本 .. (2016-07-13 11:38)
就是freetype,矢量字体库是以源码的形式添加的,用户可以修改底层接口的。还有个PNG的库也是以源码的形式添加的。

emWin已经很成熟了,距今都20年了,97发布第一个版本,矢量字体的显示全部加载才能反映出优势,总线式数据读取,要不跟点阵显示没有区别。这种STM32类的单片机系统上面使用矢量字体,只有总线方式的读取方案才能发挥出矢量字体的优势,在F429上面显示,效果杠杠的。

https://forum.anfulai.cn/forum.php?mod=viewthread&tid=18389

像emWin里面的SIF点阵字体也是全部加载的方式,总线式访问,极大加快读取速度。作为区分的另一种XBF点阵字体是支持各种操作的。
回复

使用道具 举报

1

主题

9

回帖

1

积分

新手上路

积分
1
 楼主| 发表于 2016-7-13 14:35:42 | 显示全部楼层
谢谢大家的回复,让我学到了很多,也就是说由于RAM的限制,要想用矢量字库,必须得修改底层,但是需要修改哪些函数呢,有没有谁做过这样的修改可以指导一下我呢,谢谢
回复

使用道具 举报

1

主题

9

回帖

1

积分

新手上路

积分
1
 楼主| 发表于 2016-7-13 16:47:51 | 显示全部楼层
从SD卡中读取ttf文件,如何使用FT_New_Face函数或者FT_Open_Face函数呢
回复

使用道具 举报

6

主题

231

回帖

249

积分

高级会员

积分
249
发表于 2016-7-13 16:58:57 | 显示全部楼层

回 waming2102 的帖子

waming2102:谢谢大家的回复,让我学到了很多,也就是说由于RAM的限制,要想用矢量字库,必须得修改底层,但是需要修改哪些函数呢,有没有谁做过这样的修改可以指导一下我呢,谢谢 (2016-07-13 14:35)
f_open
f_close
fread
fseek
ftell
等几个文件IO函数,你根据自己的实际情况重写这几个函数,显示读内存、读闪存等重定向。
还有一个问题就是矢量字体的图元索引是用UNICODE编码的,这个需要你将GBK码转换成UNICODE码。
回复

使用道具 举报

1

主题

9

回帖

1

积分

新手上路

积分
1
 楼主| 发表于 2016-7-14 09:23:24 | 显示全部楼层

回 novice 的帖子

novice:f_open
f_close
fread
fseek
....... (2016-07-13 16:58) 
谢谢,比如想显示“明天”这两个字,当我获得他们的矢量数据后,如何将这些数据转换为像素点数据呢,另外,如何实现字体的放大缩小操作并转换为像素点数据呢
回复

使用道具 举报

6

主题

231

回帖

249

积分

高级会员

积分
249
发表于 2016-7-15 09:57:18 | 显示全部楼层
不是三言两语可以说明白的,给你一点示范代码,这是在VC++上的演示代码。

截图

截图

ft_demo.rar (5 KB, 下载次数: 139)
回复

使用道具 举报

1

主题

9

回帖

1

积分

新手上路

积分
1
 楼主| 发表于 2016-7-15 11:04:54 | 显示全部楼层

回 novice 的帖子

novice:不是三言两语可以说明白的,给你一点示范代码,这是在VC++上的演示代码。


 (2016-07-15 09:57) 
谢谢,我看了你的代码,FT_Initialize中用到的FT_New_Face函数,由于我开发板上用的是stm32外接的SD卡,此函数中的文件路径如何填写呢,另外,ft_oem_read函数中调用的memcpy函数是内存到内存的拷贝,是不是意味着整个字库已经加载到内存中了呢,这样占用的内存依然很大,我用FATFS可以读文件中指定位置指定长度的数据,但是读好后的数据就不知道该如何链接到FreeType的接口函数中了,如何将读到的矢量数据跟FreeType的接口函数相连接呢。

另外,我在网上看了矢量字库的结构,分为索引表和数据区,可以根据汉字的区位码计算某个汉字索引表的位置,
汉字指针在指针区的偏移由公式计算:pos=((qu-16)*94+wei-1)*6。   
                          注:qu--区号。wei--位号。
读出索引表的数据,再根据索引表的数据,读出汉字的矢量数据,好像没有提到UNICODE编码,这是为什么呢
回复

使用道具 举报

6

主题

231

回帖

249

积分

高级会员

积分
249
发表于 2016-7-15 12:24:16 | 显示全部楼层

回 waming2102 的帖子

waming2102:谢谢,我看了你的代码,FT_Initialize中用到的FT_New_Face函数,由于我开发板上用的是stm32外接的SD卡,此函数中的文件路径如何填写呢,另外,ft_oem_read函数中调用的memcpy函数是内存到内存的拷贝,是不是意味着整个字库已经加载到内存中了呢,这样占用的内存依然很大,我用FAT .. (2016-07-15 11:04)
ft_oem_read函数中调用的memcpy函数是内存到内存的拷贝,是不是意味着整个字库已经加载到内存中了呢

是的,这个是演示代码,如果你需要实时读取,重写那个函数就可以了,不过除非是闪存否则速度真的很慢,效果是很差的。

至于如何跟FATFS挂接?这个很简单,把fread/fseek/ftell等函数直接映射到FATFS的对应函数就可以了。

不要试图自己去解释TrueType字库文件的结构,那个复杂度不是一般的工作量。

最后提个醒:如果你的硬件不是F429/ARM7/ARM9等SOC,别花时间去折腾,没有太大的实用意义,除非你的应用对速度要求极低。
回复

使用道具 举报

6

主题

231

回帖

249

积分

高级会员

积分
249
发表于 2016-7-15 14:07:32 | 显示全部楼层

回 waming2102 的帖子

waming2102:谢谢,我看了你的代码,FT_Initialize中用到的FT_New_Face函数,由于我开发板上用的是stm32外接的SD卡,此函数中的文件路径如何填写呢,另外,ft_oem_read函数中调用的memcpy函数是内存到内存的拷贝,是不是意味着整个字库已经加载到内存中了呢,这样占用的内存依然很大,我用FAT .. (2016-07-15 11:04)
好像没有提到UNICODE编码,这是为什么呢

答:因为我那个是Windows程序,本来就是以UNICODE方式工作,你看到的L"中华人民共和国"就已经是UNICODE编码了,因为前面有个“L”。
回复

使用道具 举报

1

主题

9

回帖

1

积分

新手上路

积分
1
 楼主| 发表于 2016-7-15 16:25:11 | 显示全部楼层

回 novice 的帖子

novice:ft_oem_read函数中调用的memcpy函数是内存到内存的拷贝,是不是意味着整个字库已经加载到内存中了呢

是的,这个是演示代码,如果你需要实时读取,重写那个函数就可以了,不过除非是闪存否则速度真的很慢,效果是很差的。

....... (2016-07-15 12:24) 
真的非常感谢你,我调试了很长时间还是无法实现FreeType和FATFS的连接,我应用的场合就是对速度要求很低
回复

使用道具 举报

6

主题

231

回帖

249

积分

高级会员

积分
249
发表于 2016-7-16 11:52:05 | 显示全部楼层
FreeTypeTest.rar (3.1 MB, 下载次数: 116)

这个是keil5工程,已经把freetype和fatfs整合进去,我只能保证这个工程能够通过编译,不保证运行没有错误。
你需要做的是完成GetPixel和SetPixel这两个函数在屏幕上打点。
还有需要完成的是用于fatfs底层的IO函数,这个必须你自己完成,你编译的时候就会看到这个几个函数的报错。
如果不能正确用fatfs打开SD卡的simsun.ttc文件,请检查fatfs_init和fatfs_f_open这两个函数是否正确。
回复

使用道具 举报

1

主题

9

回帖

1

积分

新手上路

积分
1
 楼主| 发表于 2016-7-22 10:32:00 | 显示全部楼层

回 novice 的帖子

novice:

这个是keil5工程,已经把freetype和fatfs整合进去,我只能保证这个工程能够通过编译,不保证运行没有错误。
你需要做的是完成GetPixel和SetPixel这两个函数在屏幕上打点。
还有需要完成的是用于fatfs底层的IO函数,这个必须你自己完成,你编译的时候就会看到 .. (2016-07-16 11:52) 
非常感谢您,这几天有事没有上论坛,现在下载下来做一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-14 19:01 , Processed in 0.066843 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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