引言

学习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. Tabs( 选项卡)

    一. 加载方式 //class 加载方式<div id="box" class="easyui-tabs" style="width:500px ...

  2. OD: Universal Shellcode

    本节讲如果开发通用的 Shellcode. Shellcode 的组织 shellcode 的组织对成功地 exploit 很重要. 送入缓冲区的数据包括: . 填充物.一般用 0x90 (NOP) ...

  3. The type or namespace name 'Script' does not exist in the namespace 'System.Web' (are you missing an assembly reference?)

    应该说是 .net4 的bug,没有所谓的 System.Web.Extensions.dll 库文件,需要将项目的 Target Framework修改为 3.5版本,才能加载System.Web. ...

  4. FalseEasting 和 FalseNorthing

    FalseEasting (东伪偏移) 和FalseNorthing(北伪偏移) FalseEasting (东伪偏移) 投影平面中为避免横轴(经度方向)坐标出现负值,而所加的偏移量.我国规定将高斯- ...

  5. 活动指示器UIActivityIndicatorView

    活动指示器UIActivityIndicatorView可以告知用户有一个操作正在进行中 1.创建    UIActivityIndicatorView *activityIndicatorView ...

  6. 【转】char *str 和 char str[]的区别

    char str[] = "abcd";定义了一个局部字符数组,返回它的地址肯定是一个已经释放了的空间的地址. 此函数返回的是内部一个局部字符数组str的地址,且函数调用完毕后 此 ...

  7. Visual Studio发布项目到远程服务器的步骤

    第一步: 需要远程服务器上安装Web Deploy ,下载地址:http://www.iis.net/downloads/microsoft/web-deploy PS.安装时选择完全安装. 第二步: ...

  8. HTML5 布局标签

    HTML5是HTML标准的下一个版本.越来越多的程序员开始HTML5来构建网站,相对HTML4,HTML5新增的带有语义化的标签可以代替div进行页面布局(与html5.js结合起来时可以放心使用 ) ...

  9. zendguard安装破解

    http://www.thefox.cn/zend-guard.shtml 到官网下载6.0版本安装后 URL: http://www.zend.com/en/products/guard/downl ...

  10. ROBOTS.TXT屏蔽笔记、代码、示例大全

    自己网站的ROBOTS.TXT屏蔽的记录,以及一些代码和示例: 屏蔽后台目录,为了安全,做双层管理后台目录/a/xxxx/,蜘蛛屏蔽/a/,既不透露后台路径,也屏蔽蜘蛛爬后台目录 缓存,阻止蜘蛛爬静态 ...