Aexi(4)-字体

来源:互联网 发布:坐标数据导入全站仪 编辑:程序博客网 时间:2024/06/08 02:53

已经好久都没有更新博客了,确实最近本大二狗学校里面的事情比较多,终于处理完了,下面更新博客的速度也会加快的.而且这个项目确实拖了比较长的时间了,我也给自己设置一个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当成该字体的左上角来对待,而在字符的绘制方法时,将其转换为基线坐标.代码如下.


这样我们就可以实现文字和图形的统一排版了

 

0 0