如何使用Core Text计算一段文本绘制在屏幕上之后的高度
2012-10-17 10:09
309 查看
作者:virushuo 发表于
2010-07-17 03:07 最后更新于 2010-07-17 14:07
版权声明:按照by-nc-sa的cc协议可转载,拒绝采用“独家”
授权媒介(含网站和平面媒体)转载、引用、链接,除非获得本人许可。转载时请务必以超链接形式标明文章原始出处和作者信息及本声明。
http://blog.devep.net/virushuo/2010/07/17/cocoa-core-text-text-height.html
Core Text提供了一系列方便的函数,可以很容易的把文本绘制在屏幕上,对于一个Frame来说,一般并不需要担心文本的排列问题,这些Core Text的函数都可以直接搞定,只要给他一个大小合适的CGRect就可以。
但,在某些情况下,我们还希望知道这段文本在绘制之后,对应绘制的字体字号设置,在屏幕上实际占用了多大面积。举例来说,有文本段落a,屏幕大小rect,通常做法是以rect创建path,然后创建CTFramesetter,再然后创建CTFrame,最后用CTFrameDraw画出来,这时候,往往文本段落占用的实际面积会小于rect,这时候就有必要获得这段文本所占用的真正面积。
最理想的情况是使用
double CTLineGetTypographicBounds( CTLineRef line, CGFloat* ascent, CGFloat* descent, CGFloat* leading );
这是Core Text提供的函数,传入CTLine,就会得到这一行的ascent,descent和leading,在OSX上通常可以工作的很好,但是在iOS(iPhone/iPad)上这个函数的结果略有不同。
正常情况下,计算行高只需要ascent+descent+leading即可。在这个略有不同的情况下,leading的值会出现偏差,导致算出来的结果是错误的。如果不管行距,ascent+descent计算出来的Glyph的高度还是正确的。
这样就有了第一步
在创建用于绘图的CFAttributedStringRef时,除了设置字体,多设置一个CTParagraphStyleRef,其中特别应该确定行距kCTParagraphStyleSpecifierLineSpacing。在计算这里时,先逐行计算ascent+descent,累加起来,再加上一个行数*之前设置好的行距,这样算出来的就是这些文本的实际高度,CTLineGetTypographicBounds返回的结果是宽度,这样就可得到文本实际填充面积的Rect了。
但是这还是有问题,因为OSX上和iOS处理不同,所以事实上iOS的模拟器和真机的最终效果是不一样的,这样调试程序很麻烦。
于是还需要第二步
在最终往页面上绘制的时候,不再用CTFrameDraw来一次绘制全部,而是使用CTLineDraw逐行画,在画之前,先用CGContextSetTextPosition来设置好每行文本的位置。这样就保证了在任何平台上绘制效果一致。
问题就解决了。
CoreText在OS X和iOS上实现有很多细节区别,比如说,对CTRun的划分方式也不一样,在iOS上划分出来的Run数量比OSX上少很多,是按照字体划分的Run,按照文档出来,这是正确的,但OSX上是一个字一个Run这样划分的,和文档不符。iOS上的处理显然效率更好。
stackoverflow 上有一个类似的讨论,不过没考虑到iOS的区别
相关文章推荐
- 如何使用Core Text计算一段文本绘制在屏幕上之后的高度
- 如何使用Core Text计算一段文本绘制在屏幕上之后的高度
- 用Core Text计算一段文本绘制在屏幕上后的高度
- 如何使用CoreText计算一段文本
- UITextView使用sizeWithFont:计算自适应文本高度
- CoreText绘制文本计算高度
- ScrollView 嵌入Listview,当Listview中的Textview文本多行,高度如何重新计算
- 使用mouse_event时屏幕绝对坐标如何计算
- IOS 根据 指定的 字体类型 ,size ,计算 绘制 文本 所需要的 宽度与高度
- IOS 根据 指定的 字体类型 ,size ,计算 绘制 文本 所需要的 宽度与高度
- UILabel如何根据富文本内容计算高度
- UITextView使用 sizeWithFont:constrainedToSize:lineBreakMode:计算自适应文本高度
- 使用mouse_event时屏幕绝对坐标如何计算
- 使用java,计算一段文本中出现英语单词次数最多的单词
- 图形的绘制,如何使用自定义画笔(颜色,线宽,线形)。如何为程序中添加选项菜单和选项设置对话框,如何使用标准颜色对话框,如何使用字体对话框,在选项对话框中实现预览功能。实现选项对话框和窗口类中的数据交换。如何改变对话框和控件的背景色,如何改变控件的文本颜色,
- UITextView使用 sizeWithFont:constrainedToSize:lineBreakMode:计算自适应文本高度
- 在使用EditText进行文本输入时,若不进行特殊的设置,使用Android自带的软键盘,该软键盘会占用整个界面,那么,如何让键盘只占用屏幕的一部分呢?
- UITextView使用 sizeWithFont:constrainedToSize:lineBreakMode:计算自适应文本高度
- 如何在FastReport.Net中使用曲线绘制PDF文本
- UILable的使用,文本高度的计算boundingRectWithSize