Quartz2D 之 绘制文本
1. 基础概念
1.1. 字体(Font)
同一大小、同一样式的字形的集合。
1.2. 字符(Character)
字符表示信息本身,一般指某种编码,如Unicode编码。
1.3. 字形(Glyphs)
字符+字体就会有个对应的图片,这个图片就是字形。
1.3. 字形描述集(Glyphs Metris)
字形的各个参数:

- 边框(Bounding Box):一个假想的边框,尽可能地容纳整个字形。
- 基线(Baseline):一条假想的参照线,以此为基础进行字形的渲染。一般来说是一条横线。
- 基础原点(Origin):基线上最左侧的点。
- 行间距(Leading):行与行之间的间距。
- 字间距(Kerning):字与字之间的距离,为了排版的美观,并不是所有的字形之间的距离都是一致的,但是这个基本步影响到我们的文字排版。
- 上行高度(Ascent)和下行高度(Decent):一个字形最高点和最低点到基线的距离,前者为正数,而后者为负数。当同一行内有不同字体的文字时,就取最大值作为相应的值。
lineHeight = Ascent + |Decent| + Leading
2. Core Text
原来 CGContextDrawText 被废弃掉了,现在使用 Core Text 绘制文本和图片。
参考:http://www.cocoachina.com/industry/20140521/8504.html
参考:http://blog.csdn.net/fengsh998/article/details/8691823
2.1. 基础概念

绘图接口有:CTFrameDraw 和 CTLineDraw。
2.1.1. NSAttributedString
从字面上就可以理解:包含了属性的NSString。具有的属性:粗/斜体、下划线、颜色、背景灯。每个属性都可以设置到一个字符区域范围上。
2.1.2. CTFrameSetter

由 CTFramesetter 根据参数 CGPath 生成 CTFrame。
2.1.3. CTFrame
CTFrame 由一行一行的 CTLine 组成,每个 CTLine 包含很多 CTRun 。CTRun是字形绘制的最小单位。
2.1.4. 简单示例
NSString *str = @"This is a test of characterAttribute. 中文字符";
NSMutableAttributedString *mabstring = [[NSMutableAttributedString alloc]initWithString:str]; [mabstring beginEditing]; //对同一段字体进行多属性设置
//红色
NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithObject:(id)[UIColor redColor].CGColor forKey:(id)kCTForegroundColorAttributeName];
//斜体
CTFontRef font = CTFontCreateWithName((CFStringRef)[UIFont italicSystemFontOfSize:].fontName, , NULL);
[attributes setObject:(id)font forKey:(id)kCTFontAttributeName];
//下划线
[attributes setObject:(id)[NSNumber numberWithInt:kCTUnderlineStyleDouble] forKey:(id)kCTUnderlineStyleAttributeName]; [mabstring addAttributes:attributes range:NSMakeRange(, )]; NSRange kk = NSMakeRange(, ); NSDictionary * dc = [mabstring attributesAtIndex: effectiveRange:&kk]; [mabstring endEditing];
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)mabstring); CGMutablePathRef Path = CGPathCreateMutable(); CGPathAddRect(Path, NULL ,CGRectMake( , ,self.bounds.size.width- , self.bounds.size.height-)); CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(, ), Path, NULL); //获取当前(View)上下文以便于之后的绘画,这个是一个离屏。
CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetTextMatrix(context , CGAffineTransformIdentity); //压栈,压入图形状态栈中.每个图形上下文维护一个图形状态栈,并不是所有的当前绘画环境的图形状态的元素都被保存。图形状态中不考虑当前路径,所以不保存
//保存现在的上下文图形状态。不管后续对context上绘制什么都不会影响真正得屏幕。
CGContextSaveGState(context); //x,y轴方向移动
CGContextTranslateCTM(context , ,self.bounds.size.height); //缩放x,y轴方向缩放,-1.0为反向1.0倍,坐标系转换,沿x轴翻转180度
CGContextScaleCTM(context, 1.0 ,-1.0); CTFrameDraw(frame,context); CGPathRelease(Path);
CFRelease(framesetter);
2.2. 图文混排的实现
CoreText 不能绘制图片,而是给图片预留位置,最终由 CoreGraphics完成绘制。
步骤;
- 设置某区域的 AttributedString 为 kCTRunDelegateAttributedString
- 根据上步设置生成CTRun
- 在CTRun的回调获取信息
- 通过CoreGraphics绘图。
2.2.1. s
Quartz2D 之 绘制文本的更多相关文章
- html5 canvas 笔记三(绘制文本和图片)
绘制文本 fillText(text, x, y [, maxWidth]) 在指定的(x,y)位置填充指定的文本,绘制的最大宽度是可选的. strokeText(text, x, y [, ma ...
- FontMetrics ----- 绘制文本,获取文本高度
Canvas 绘制文本时,使用FontMetrics对象,计算位置的坐标. public static class FontMetrics { /** * The maximum distance a ...
- 使用WebBrowser控件时在网页元素上绘制文本或其他自定义内容
原文:使用WebBrowser控件时在网页元素上绘制文本或其他自定义内容 第一次在CNBlogs上发Post是提出一个有关使用WebBrowser控件时对SELECT网页元素操作的疑惑,这个问题至今也 ...
- 使用GDI绘制文本
/// <summary> /// 定义一个绘制文本 /// </summary> public void Texts() ...
- 『备注』GDI+ 绘制文本有锯齿,透明背景文本绘制
背景: GDI+ 绘制文本 时,如果 背景是透明的 —— 则会出现 锯齿. //其实,我不用这三个 属性 好多年了 //而且,这三个属性 在关键时刻还有可能 帮倒忙 //关键是:这三个属性,鸟用都没有 ...
- Javascript高级编程学习笔记(88)—— Canvas(5)绘制文本
绘制文本 同样的,canvas也为绘制文本提供了相应的方法. 2D上下文提供的文本绘制方法主要有两个: fillText() strokeText() 这两个方法都接受四个参数 要绘制的文本字符串 绘 ...
- Win32汇编学习(5):绘制文本2
这次我们将学习有关文本的诸多属性如字体和颜色等. 理论: Windows 的颜色系统是用RGB值来表示的,R 代表红色,G 代表绿色,B 代表蓝色.如果您想指定一种颜色就必须给该颜色赋相关的 RGB ...
- Win32汇编学习(4):绘制文本
这次,我们将学习如何在窗口的客户区"绘制"字符串.我们还将学习关于"设备环境"的概念. 理论: "绘制"字符串 Windows 中的文本是一 ...
- Qt绘制文本一
QPainterPath,使用 drawText且设置字体,再使用painter.drawText方式 效果图: void WgtText::paintEvent(QPaintEvent *event ...
随机推荐
- 关于MyEclipse 半天打不开的问题(工作区间损坏)--转
删掉 {workspace}/.metadata/.plugins\**\*.snap 所有的 .snap文件 一般可以解决问题 如果上面一步解决不了问题, 那么删掉 {workspace}/.met ...
- jsp内部传参与重定向传参
1 重定向地址栏会发生改变,因为它会发送两次请求,内部转发,地址栏不会发生改变,因为它只有一个请求2 重定向不能获取上一次请求中的参数,而内部转换可以3 内部转发可以访问WEB-INF下的资源,重定向 ...
- 超级素数(sprime)
超级素数(sprime) 题目描述 超级素数是指一个素数,每去掉后面一个数字,总能保证剩下的数为质数,例如:373->37->3这是一个长为3的超级素数. 输入 输入一个整数n (10≤n ...
- Android PopupWindow的使用技巧(转)
Android PopupWindow的使用技巧 PopupWindow是Android上自定义弹出窗口,使用起来很方便. PopupWindow的构造函数为 public PopupWindow(V ...
- Tomcat Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
一眼就能看出来是jdk的环境有问题,但是用了这么久的jdk一直都配置的好好的,怎么一到Tomcat上就这么矫情了. 最后查解决方案,原来是我的jdk从官网直接下载的,虽然我修改了java_home,但 ...
- 块和内嵌总结,以及各个标签的应用。其中的ul ol dl特殊定义为auto,使得里面的内容展开
<!doctype html> <html> <head> <meta charset="UTF-8"/> <title> ...
- FZU 2147 A-B Game(数学)
我们只需要知道这个取完模最大是 a / 2 + 1就可以了,不过超时了几次,换了visual C++才过,oj还真是傲娇啊. #include<iostream> #include< ...
- codeforces 665C Simple Strings
相同的一段字母变一下就可以. #include<cstdio> #include<cstring> #include<cmath> #include<vect ...
- HDU 5521 Meeting
2015 ACM / ICPC 沈阳站现场赛 M题 最短路 设置N+M个节点,前N个节点是Block,后M个节点是Set,每一组Set中的点向该Set连边,从1和n开始分别求最短路.注意爆int. # ...
- 转 如何使用JEE6快速开发简单的webservice
转自:http://www.iteye.com/topic/1135747,作者:红尘默岩 前言:朋友们开始以下教程前,请先看第五大点的注意事项,以避免不必要的重复操作. 一.准备工作(以下为本实例使 ...