引言

学习CoreText,最初的想法是写一个杂志类的应用,因为对网易和zarca应用一些技术的疑问,所以,自己有了很强的兴趣欲和钻研欲,开始这段有点不顺的学习过程。

难题

1、对CGContextRef的CTM不理解,观念导致很多东西没有正确的理解。
2、对NS的了解不多,一些文字绘制方面的座标系问题让自己很迷惑。
3、对CoreText麻烦的API严重不适应。

关于CTM

CTM,Context Translate Matrix。 它是把要绘制的上下文以一个叫做Matrix的东西来表示,可以简单地想作,绘制的上下文的每一个点都映射在Matrix上,你在Matrix上的操作都会使得上下文上的点产生相应的变动。如放大、旋转、移动。

在一般的教程里面,为了达到旋转或放大缩小的目的,一般都会先改变这个上下文,如:

1
2
3
4
5
CGContextTranslateCTM(context, 0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0f, -1.0f); // some draw code
// ....

然后进行绘图操作。那么这个绘图操作是怎么做的呢?这个对Matrix的操作,为什么是放在前面而不是放在后面,为什么放在后面又没有效果呢?不是说改变Matrix就会改变上面的映射的所有点呢?这些常规的逻辑思维使得问题越发无法理解和解决。那么我们先从context来了解。

一般情况也,我们总是认为context就是画布,所有的matrix旋转都是针对画布的旋转,虽然这样的理解是错误的,但是得到的结果却是正确的,但是如果在一些稍复杂的坐标系转换时,或者更改matrix时在之前或之后的理解时,这样理解就会得到难得理解的结果。

其实context说的是绘画人所处的角度上下文。如下图,默认的情况下,绘画人的角度是正对着画布的:

画布是白色的,而我则是在左上角用一个黄色的三角形来标识它的左上角,使用left top来标识context的左上角,而绘画人是黄色的圆形。

要记着!!画布无论怎么样都是正对着屏幕的,它不会旋转,或者放大缩小,或者移动。

那么为什么又看起来我放大了或者移动了呢?其实移动的是你的context,也就是你所处的context视角,我举个例子,比方说我要旋转180度在左上角写一个“abcdefg”。

首先,我要先旋转180度:

然后,我在左上角写上“abcdefg”:

然后重置context:

可以看到,我们改变context只是改变了自己面对画布的角度,而画布仍然是正对着屏幕的,自己始终以context的左上角为自己角度的左上角,而不是以画布的左上角为左上角,也就是说,这时绘画时的座标(0,0)是你旋转后context的left top,而不是画布 的左上角,记着这一点很重要。

所以,在绘画的时候,其实是倒着画在了画布的右下角上。而重置context,则是把自己正对着画布而已。这也就说清了为什么是在使用matrix更改context之后进行绘图有效(把自己面对画布的角度先调整了),而不是在画了之后再调整(因为你都画完了,再调整自己的角度还有什么用?)。

正确理解使用matrix更改context的方式很重要,因为这涉及到坐标系的问题,之后的CoreText相当讨论会讲到一个例子。

关于NS座标系

NS坐标系是以左下角为(0,0),与iOS的坐标系在Y上是相反的,所以,在iOS进行CoreText进行绘图或文字的时候,X方向是一致的,但是Y则是倒过来的。如下图:

那么怎么办呢?想想,仔细看上面这张图,貌似像是正常方向的倒影,但是水平线却在最上面。嗯,挪下来,然后再反过来,看一下效果。如下图:

效果:

效果果然如图所示,好!!

可是是不是就这样完了呢?不是,还有一个更为重要的问题,这个时候,进行了两次的转换matrix,context的left top在哪里呢?

根据之前的理论,那得让自己先把自己向下移,然后把头倒过来,OK,这下明白了,这下画布的左下角变成了context的左上角,别的都没变。这时,当你在(20, 20)画一个长方形,其实就是画布的(20, canvas.height - 20 + rect.size.height)的位置上画了个长方形,而且是倒过来的。

仔细想想这个,有趣的事情还有很多,因为按照自己看过本文之前的理论,可能会非常惊讶为什么得到的结果和自己想的不一样,一直以为是在(20, 20)处画一个长方形,结果却刚好相反,这就是没有理解context及matrix的正确含义所致。

CoreText中坐标转换的一些理解的更多相关文章

  1. SQL SERVER 2005/2008 中关于架构的理解(二)

    本文上接SQL SERVER 2005/2008 中关于架构的理解(一)      架构的作用与示例 用户与架构(schema)分开,让数据库内各对象不再绑在某个用户账号上,可以解决SQL SERVE ...

  2. SQL SERVER 2005/2008 中关于架构的理解(一)

    SQL SERVER 2005/2008 中关于架构的理解(一) 在一次的实际工作中碰到以下情况,在 SQL SERVER 2008中,新建了一个新用户去访问几张由其他用户创建的表,但是无法进行查询, ...

  3. C++中 类的构造函数理解(一)

    C++中 类的构造函数理解(一) 写在前面 这段时间完成三个方面的事情: 1.继续巩固基础知识(主要是C++ 方面的知识) 2.尝试实现一个iOS的app,通过完成app,学习iOS开发中要用到的知识 ...

  4. ECshop中的session机制理解

    ECshop中的session机制理解     在网上找了发现都是来之一人之手,也没有用自己的话去解释,这里我就抛砖引玉,发表一下自己的意见,还希望能得到各界人士的指导批评! 此session机制不需 ...

  5. [开发技巧]·Numpy中对axis的理解与应用

    [开发技巧]·Numpy中对axis的理解与应用 1.问题描述 在使用Numpy时我们经常要对Array进行操作,如果需要针对Array的某一个纬度进行操作时,就会用到axis参数. 一般的教程都是针 ...

  6. 【C++】类中this指针的理解

    转自 苦涩的茶https://www.cnblogs.com/liushui-sky/p/5802981.html C++类中this指针的理解 先要理解class的意思.class应该理解为一种类型 ...

  7. Java中线程同步的理解 - 其实应该叫做Java线程排队

    Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可 ...

  8. OpenGL中的像素包装理解

    OpenGL中的像素包装理解 像素包装 位图和像素图很少会被紧密包装到内存中.在许多硬件平台上,考虑到性能的原因位图和像素图的每一行的数据会从特殊的字节对齐地址开始.绝大多数编译 器会自动把变量和缓冲 ...

  9. tomcat的配置文件server.conf中的元素的理解

    tomcat的配置文件server.conf中的元素的理解 tomcat作为一个servlet服务器本身的配置文件是tomcat_home/conf/server.conf,这个配置文件中有很多元素, ...

随机推荐

  1. 小学生之Log4j使用教程

    以前都是把所有日志都输出到一个文件下面,今天有个同事问想把某个包下的日志输出到 指定的地方,于是就在网上查了一些资料,总结一下,以免以后用到. 一.log4j是什么?  Log4j是一个开源的日志记录 ...

  2. Ajax (jquery)实现智能提示搜索框(in Django)

    搜索框输入搜索名字,从数据库中筛选名字, 如果有包含输入的字母的名字则以json格式返回并且显示在搜索框下:          html文件: <!DOCTYPE html> <ht ...

  3. oracle数据库实验讲义-读书笔记(一)

    1.激活锁定的用户alter user scott account unlock identified by tiger;2.使用内含脚本建立scott用户@%oracle_home%\rdbms\a ...

  4. MVC校验特性

    1.前端引入3个脚本       ①jq脚本   ②jQuery.Validate.js  ③jquery.validate.unobtrusive.js(异步验证) 2.后端加特性 在表对应的Mod ...

  5. Android再学习-20141111-Android应用的七大件

    Android应用的七大件 应用程序的四大组件: Android的四大组件,使用时需要在程序中注册. Activity: Activity是应用程序的一个界面,可以通过这个界面查看联系人.打电话或者玩 ...

  6. Java学习笔记--Java8 Lambda表达式

    Java Lambda表达式入门:http://blog.csdn.net/renfufei/article/details/24600507 lambda内容的介绍:http://swiftlet. ...

  7. WPF学习拾遗(二)TextBlock换行

    原文:WPF学习拾遗(二)TextBlock换行 下午在帮组里的同事解决一个小问题,为了以后方便,把就把它收集一下吧. 新建一个TextBlock作为最基础的一个控件,他所携带的功能相对于其他的控件要 ...

  8. PowerShell正则表达式(一) 定义模式

    PowerShell正则表达式(一) 定义模式 7 29 9月, 2013  在 Powershell tagged 正则表达式 by Mooser Lee 本文索引 [隐藏] 1限定符 2识别IP地 ...

  9. Cmake,source_group

    Cmake的source_group命令相当于VS里面给编译需要的文件归类,把一些相同性质的文件放一个类里面,这些“类”,可以在VS 图形界面下左边(一般情况下),看到header文件夹下面的H文件, ...

  10. win8开机密码忘了怎么办

    原文地址:http://zhidao.baidu.com/question/582486883100064325.html windows8系统虽然让众用户用着不习惯,但是还是拥有大批追随者.今天,绿 ...