OpenCascade Chinese Text Rendering

eryar@163.com

Abstract. OpenCascade uses advanced text rendering powered by FTGL library. The FreeType provides vector text rendering, as a result the text can be rotated and zoomed without quality loss. FreeType also support unicode charset. The paper focus on the Chinese Text rendering.

Key Words. OpenCascade, FreeType, Chinese Text, 中文汉字, Unicode

1. Introduction

OpenGL中并没有提供直接的文字绘制支持,一个通用的二维文字解决方案是使用glDrawPixels()来显示位图形式的字体,前提是用户已经预先生成了一系列的位置形式的文字字库,这也是很多早期计算机游戏的通用做法。使用位图来绘制文字的主要问题是不能控制显示过程中的图像走样。因为文字图像的大小总是一定的,缩放后变形比较明显;如果图像是根据视点实时地进行缩放,则势必消耗大量的系统资源。一个较好的解决方案就是使用纹理来表达矢量类型的文字。矢量文字的优点在于:每个字型都是使用数学公式来描述的,并使用光滑的曲线实现笔画之间的连接。因此,将矢量文字用纹理来表达的话,只要预先设置的纹理分辨率满足需求,那么对纹理面进行缩放或改变用户的视点时,都不会造成明显的文字失真变形。

矢量文字的处理首推著名的开源跨平台开发库FreeType。这是一个专业的字体数据解析工具,可以解析TrueType, Type1等多种矢量字体格式,并通过统一的函数接口提供给用户程序使用。FreeType本身不包含文字排版和图形化显示的功能,因此可以直接将它解析字体文件的结果应用在OpenGL程序中。

OpenCascade的文字显示就用到了FreeType库,将文字转换成了矢量图形,所以可以对其任意缩放,都不会影响其显示质量。且还支持Unicode的文字的显示,当然也包含中文的显示。本文主要介绍在OpenCascade中显示中文的注意事项,也介绍了OpenCascade中将文字转换成TopoDS_Shape的功能。

2. Render Chinese Text

OpenCascade在Draw Test Harness中有关于显示文字的命令vdrawtext,显示文字效果如下图所示:

Figure 2.2 Text in Draw Test Harness

实现上图的Tcl命令如下图所示:

Figure 2.2 Draw Text Tcl Command

Figure 2.3 vdrawtext command

从vdrawtext命令中可以看出,最后一个参数就是关于多字节字符串的显示处理。输入如下命令来显示包含中文的字符串:

vdrawtext 你好OpenCascade 100  300 -400 000 255 255 0 0 000 1 50 1 SimSun 1

显示结果如下所示:

Figure 2.4 Render Chinese Text by vdrawtext command

由图可知,显示结果不正确。找到vdrawtext命令实现部分的源代码,实现代码在文件VeiwerTest_ObjectCommands.cxx中,修改其字符串转换算法后代码如下所示:

static int VDrawText (Draw_Interpretor& di, Standard_Integer argc, const char** argv)
{
// Check arguments
if (argc < )
{
di<<"Error: "<<argv[]<<" - invalid number of arguments\n";
di<<"Usage: type help "<<argv[]<<"\n";
return ; //TCL_ERROR
} Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext(); // Create 3D view if it doesn't exist
if ( aContext.IsNull() )
{
ViewerTest::ViewerInit();
aContext = ViewerTest::GetAISContext();
if( aContext.IsNull() )
{
di << "Error: Cannot create a 3D view\n";
return ; //TCL_ERROR
}
} // Text position
const Standard_Real X = Draw::Atof(argv[]);
const Standard_Real Y = Draw::Atof(argv[]);
const Standard_Real Z = Draw::Atof(argv[]);
const gp_Pnt pnt(X,Y,Z); // Text color
const Quantity_Parameter R = Draw::Atof(argv[])/.;
const Quantity_Parameter G = Draw::Atof(argv[])/.;
const Quantity_Parameter B = Draw::Atof(argv[])/.;
const Quantity_Color aColor( R, G, B, Quantity_TOC_RGB ); // Text alignment
const int hor_align = Draw::Atoi(argv[]);
const int ver_align = Draw::Atoi(argv[]); // Text angle
const Standard_Real angle = Draw::Atof(argv[]); // Text zooming
const Standard_Boolean zoom = Draw::Atoi(argv[]); // Text height
const Standard_Real height = Draw::Atof(argv[]); // Text aspect
const Font_FontAspect aspect = Font_FontAspect(Draw::Atoi(argv[])); // Text font
TCollection_AsciiString font;
if(argc < )
font.AssignCat("Courier");
else
font.AssignCat(argv[]); // Text is multibyte
const Standard_Boolean isMultibyte = (argc < )? Standard_False : (Draw::Atoi(argv[]) != ); // Read text string
TCollection_ExtendedString name;
if (isMultibyte)
{
/* eryar modified 20140817 11:11
const char *str = argv[1];
while ( *str || *(str+1)=='\x0A' || *(str+1)=='\x0B' || *(str+1)=='\x0C' || *(str+1)=='\x0D'
|| *(str+1)=='\x07' || *(str+1)=='\x08' || *(str+1)=='\x09' )
{
unsigned short c1 = *str++;
unsigned short c2 = *str++;
if (!c2) break;
name += (Standard_ExtCharacter)((c1 << 8) | c2);
}
*/
Resource_Unicode::ConvertGBToUnicode(argv[], name);
}
else
{
name += argv[];
} if (name.Length())
{
Handle(MyTextClass) myT = new MyTextClass(name,pnt,aColor,hor_align,ver_align,angle,zoom,height,aspect,font.ToCString());
aContext->Display(myT,Standard_True);
} return ;
}

主要当是多字节字符串,使用Resource_Unicode::ConvertGBToUnicode()函数来实现字符串转换,修改后仍输入前面的命令,可以显示中文字体了:

Figure 2.5 Render Chinese Text by vdrawtext command

综上所述,结合Draw中的代码可知,要在OpenCascade中显示中文,需要注意以下几点:

v 由于OpenCascade并没有提供直接显示文字的类,都需要从AIS_InteractiveObject派生一个文字显示类,并重载有关函数Compute();

v 字符串转换要使用Resource_Unicode::ConverteGBToUnicode()来将中文的字符串转换为Unicode字符串;

v 一定要选择正确的中文字体,否则也是显示不正确的。

Figure 2.6 A Chinese Quote

3. Convert Text to TopoDS_Shape

借助于TreeType库OpenCascade可以将文字转换成样条并生成TopoDS_Shape,即三维文字效果,相关的draw命令是text2brep,生成效果如下图所示:

Figure 3.1 3D Text in Draw Test Harness

生成上述效果的Tcl脚本如下所示:

text2brep text2d eryar@163.com Times-Roman 18 bold composite=0 
prism text text2d 0 0 2 
vdisplay text 
vsetdispmode 1 
vfit 

4. Conclusion

OpenCascade使用FreeType来实现了文字的高质量的显示,因为是矢量图形,所以任意缩放不影响文字的质量。

OpenCascade中显示中文时,需要注意字符串转换到Unicode时选择正确的转换函数,且要选择正确的字体格式,即中文字体,本文中仅以仿宋SimSun为例。

OpenCascade还可将文字转换为TopoDS_Shape进而可以显示三维字体。

综上所述,可知FreeType库的功能还是很强大的。

5. References

1. 王锐,钱学雷,OpenSceneGraph三维渲染引擎设计与实践,清华大学出版社

2. 在OpenCasCade的2D窗口中显示汉字的方法,

http://www.cadcaecam.com/forum.php?mod=viewthread&tid=15444

3. OpenCascade Draw Test Harness code

OpenCascade Chinese Text Rendering的更多相关文章

  1. OpenCascade Ray Tracing Rendering

    OpenCascade Ray Tracing Rendering eryar@163.com 摘要Abstract:OpenCascade6.7.0中引入了光线跟踪算法的实现.使用光线跟踪算法可实现 ...

  2. Using native GDI for text rendering in C#

    Using native GDI for text rendering in C# Aug12by Arthur To complete my previous post on text render ...

  3. ICDAR2017 Competition on Reading Chinese Text in the Wild(RCTW-17) 介绍

    阅读文章:<ICDAR2017 Competition on Reading Chinese Text in the Wild(RCTW-17)> 这篇文章是对一项中文检测和识别比赛项目( ...

  4. CSS Animation triggers text rendering change in Safari

    薄荷新首页上周五内测,花哥反馈在 MacBook Safari 浏览器下 鼠标移动到第一个商品的时候后面几个商品的文字会加粗.这是什么鬼??? 待我回到家打开笔记本,鼠标蹭蹭蹭的发现问题远不止如此: ...

  5. Python第三方库SnowNLP(Simplified Chinese Text Processing)快速入门与进阶

    简介 github地址:https://github.com/isnowfy/snownlp SnowNLP是一个python写的类库,可以方便的处理中文文本内容,是受到了TextBlob的启发而写的 ...

  6. Assignment 1:Chinese Text Data Processing.

    记录过程. Lucene分词:http://blog.csdn.net/cyxlzzs/article/details/7999212 Lucene自定义词典:http://lilongbao.blo ...

  7. FreeType in OpenCASCADE

    FreeType in OpenCASCADE eryar@163.com Abstract. FreeType is required for text display in the 3D view ...

  8. Quartz2D Text

    [Quartz2D Text] Quartz 2D provides a limited, low-level interface for drawing text encoded in the Ma ...

  9. Python框架、库以及软件资源汇总

    转自:http://developer.51cto.com/art/201507/483510.htm 很多来自世界各地的程序员不求回报的写代码为别人造轮子.贡献代码.开发框架.开放源代码使得分散在世 ...

随机推荐

  1. T-SQL Recipes之Database Backups

    The Problem 在DBA和T-SQL码奴日常工作中,比如常规检查,服务管理,数据库管理, 是其中最具挑战性的一个领域. 在相似任务中,比如索引碎片管理,统计管理,数据库备份是异常重要的,对任何 ...

  2. 双向链表、双向循环链表的JS实现

    关于链表简介.单链表.单向循环链表.JS中的使用以及扩充方法:  单链表.循环链表的JS实现 关于四种链表的完整封装: https://github.com/zhuwq585/Data-Structu ...

  3. js排序算法总结—冒泡,快速,选择,插入,希尔,归并

    相信排序是任何一个程序猿都会用到的东西,今天简单总结记录下常见的排序算法. 一.冒泡排序 说起冒泡排序,可能每个人都不会陌生,实现思路相当简单明了,就是不停的对数组进行两两比较,将较大(较小)的一项放 ...

  4. linux(debian) arm-linux-g++ v4.5.1交叉编译 embedded arm 版本的QtWebkit (browser) 使用qt 4.8.6 版本

    最近需要做一个项目 在arm 架构的linux下 没有桌面环境的情况下拉起 有界面的浏览器使用. 考虑用qt 的界面和 qtwebikt 的库去实现这一系列操作. 本文参考: Qt移植到ARM Lin ...

  5. xampp常见安装失败问题

    遇到这两个错误后不管它,继续安装.完成后下载Microsoft Visual C++ 2008 Redistributable Package (x86),可以到这里下载:Microsoft Visu ...

  6. 步骤进度条 css

    用css写一个简单的步骤进度条 html代码: <h4>南京游玩</h4> <ul class="step-list"> <li> ...

  7. STM32_RTC君

    五一假期已过,大家是否还像五一五二五三那样快乐呢??答案就交给你们自己寻找了哈..说到五一..就从五一开始的那一刻起..就开始计时着..到五一假期结束..呵呵..在这里,智商和情商比我高的人估计又猜到 ...

  8. Python yield函数理解

    Python中的yield函数的作用就相当于一个挂起,是不被写入内存的,相当于一个挂起的状态,用的时候迭代,不用的时候就是一个挂起状态,挂起状态会以生成器的状态表现

  9. Web服务器控件之button

    button有两种类型的按钮,一种是提交按钮,一种是命令按钮.只说命令按钮. 命令按钮事要使用两个属性,分别是CommandName和CommandArguement属性,当该按钮被点击时,将页面中的 ...

  10. linux时间同步ntp服务的安装与配置

    1.首先安装NTP [root@localhost /]# yum install ntp -y 2.修改NTP配置文件,添加NTP服务器的网络位置    /etc/ntp.conf # For mo ...