本文主要是介绍Aexi(4)-字体,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
已经好久都没有更新博客了,确实最近本大二狗学校里面的事情比较多,终于处理完了,下面更新博客的速度也会加快的.而且这个项目确实拖了比较长的时间了,我也给自己设置一个DeadLine吧.下月10号将PC平台上的Aexi完成,下月20号之前将其移植到Android平台上,并抽象出主要部分,封装成一个库发到Github上面.
下面就开始这次博客的内容,这次博客的主要想写一个开发过程中的小问题—字体.下面先简单介绍一下目前的项目主要类结构.
UML简图一张(本人没有系统的学过UML,各位看官不要深究细节哈).
可以看到,每个继承自GlyphImpl的对象都有一个frame属性,frame属性(命名来自iOS),记录了该Glyph的位置以及宽高信息.这个frame的值由compositor对象中的compose方法中进行赋值.然后在compose方法执行完毕排版结束之后,调用每个Glyph的drawme()方法绘制自身.其中,drawMe()方法中就会使用赋值过的frame中存储的信息进行绘制.
主要的过程都介绍完了,在实际开发过程中,我们遇到了一个非常令人费解的现象.请看图:
可以清楚的看到,我们的Caret对象跑到了文字的下面.
为什么会出现这种问题呢?是我们的参数传递的有问题吗?为了验证,我又新建了一个项目,绘制了几个图形,请看图.
在Y值传入的参数相同的情况下,drawString方法绘制的文字和其他图形绘制方法绘制的图形的位置就是不一样.
根据图上显示的位置,其实很容易就认为其实文字绘制的起始点坐标在文字的左下角,因为图上很明显,传入相同的Y 值,而文字绘制在上,图形绘制在下面.但是实际上这样想很接近了,但是还是不对.我们将图片放大了看,请看图:
放大了看,其实还是有几个像素伸下来的,所以并不是整个文字的左下角.
那么这到底是怎么回事呢?
遇到这样的问题,我们就要去查找万能的API文档了.首先我们想到的是Font类.在搜索遍了font类后,笔者找到了关键所在,那就是fontMetrics类.
实际上,Graphics的DrawString()方法中给出的x参数和Y参数就是字体文件的baseLine的左顶点的坐标.
看不清楚baseLine看上面这张图就可以了.
那么在代码中如何获取到asent和desent的数据呢?废话不多说上代码.
.
通过sun.font.FontDesignMetrics这个类的getMetrics方法,可以获取到一个现成的font类的fontmetrics对象,这个对象就封装了该font的这些信息.调用相应的方法就可以获取到了
最后一个问题,我们在排版时,显然不希望对frame赋值时需要计算相应的数值而对character区别对待,并且每个文字的大小显然不能由外部来决定,而应该由该character的字体的大小来决定.为了能对外提供统一访问的对待,我们仍然把frame的x,y当成该字体的左上角来对待,而在字符的绘制方法时,将其转换为基线坐标.代码如下.
这样我们就可以实现文字和图形的统一排版了
这篇关于Aexi(4)-字体的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!