上一讲我们介绍了如何获取文本字符,这一讲介绍文本的布局
我们之前在2019-7-29-WPF文本(1)-当显示文本时我们到底在做什么(1) - huangtengxiao介绍过,文本渲染需要经历找字符、measure、arrange、render过程。这里我们统一介绍measure和arrange过程(Layout过程)
Layout
首先我们思考下一群文本字符应该怎么对齐呢?上对齐?下对齐?
并不是,这群文字采用了一种奇妙的对齐方式,按照红线的那种不上不下的对齐,Baseline
对齐
什么是baseline呢,简单来说就是用于文本对齐的基准。毕竟不是所有的文字都和汉字一样写的方方正正的,还是有一些语言的布局为了整体的美观需要各个字符能够上下调节。所以基线能够控制字符的对齐。
有了基线还有什么呢?有的同学马上说到width和height。
有同学说这个这么简单,需要讲么?需要。
我们看看下面的图片。f的选择宽度要远小于字符的呈现宽度,而f的呈现大小“入侵”了其他字符的区域。因此简单的width和height肯定不能满足这些需求。
我们看下软件中字符的各个尺寸表示,以WPF为例。下图的black box指的是字符的显示图像的大小,或者说这个字符的Geometry.Bounds
。中间的横线就是字符的Baseline,用于字符的对齐。而Advance Width则是我们选择时看到的宽度,或者说是整个字符在文本中布局使用的宽度。而字符图形在渲染时的相对位置则是由left side bearing, Right side bearing, Upright baseline offset共同确定的。
由此,我们可以确定:
- 字符的布局宽度(advance width)=左侧偏移(left side bearing)+右侧偏移(Right side bearing)+字符图像宽度
- 字符的布局高度(advance height)=字符图像高度+竖直偏移(Upright baseline offset)
- 字符布局位置由baseline origin确定
那么这么多的数据应该放在哪里呢?当然是放在字体文件的元数据中咯,这样就可以大幅减少软件层面的计算量。
OK,花了大力气介绍单个字符的布局,那么多行,多段落就会相对简单。他们和我们普通元素布局类似,只要指定位置将字符一个个”码”上去就行了。
参考链接:
本文会经常更新,请阅读原文: https://dotnet-campus.github.io//post/WPF%E6%96%87%E6%9C%AC(2)-%E5%BD%93%E6%98%BE%E7%A4%BA%E6%96%87%E6%9C%AC%E6%97%B6%E6%88%91%E4%BB%AC%E5%88%B0%E5%BA%95%E5%9C%A8%E5%81%9A%E4%BB%80%E4%B9%88(2).html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 dotnet 职业技术学院 (包含链接: https://dotnet-campus.github.io/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 。