之前一直很想好好的研究一下coreText,現在正好有這個機會,特此記錄一下
<喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+CkNURnJhbWUg1/fOqtK7uPbV+8zltcS7rbK8KENhbnZhcymjrMbk1tDTydDQKENUTGluZSnX6bPJo6y2+MO/0NC/ydLUt9bOqtK7uPa78rbguPbQobe9v+mjqENUUnVuo6mhozwvcD4KPHA+Ctei0uKjusTjsrvQ6NKq19S8urS0vahDVFJ1bqOsQ29yZSBUZXh0vau4+b7dTlNBdHRyaWJ1dGVkU3RyaW5ntcTK9NDUwLTX1LavtLS9qENUUnVuoaPDv7j2Q1RSdW621M/zttTTprK7zay1xMr00NSjrNX90vK0y6OsxOO/ydLU19TTybXEv9jWxtfWzOWhotHVyauhotfWvOS+4LXItcjQxc+ioaM8L3A+Cjxicj4KCjxwPjwvcD4KPHA+Cs2os6O0psDtsr2+26O6PC9wPgo8cD4KMS7G5Mq1wfezzMrH1eLR+bXEo7oKIDGhosn6s8nSqrvm1sa1xE5TQXR0cmlidXRlZFN0cmluZ7bUz/OhoyAyoaLJ+rPJ0ru49kNURnJhbWVzZXR0ZXJSZWa21M/zo6zIu7rztLS9qNK7uPZDR1BhdGi21M/zo6zV4rj2UGF0aLbUz/PTw9Pase3Kvr/Ju+bWxsf40/LX+LHqJiMyMDU0MDuhorOkv+2hoyAzoaLKudPDyc/D5sn6s8m1xHNldHRlcrrNcGF0aMn6s8nSu7j2Q1RGcmFtZVJlZrbUz/OjrNXiuPa21M/zsPy6rMHL1eLBvbj2ttTP87XE0MXPoqOo19bM5dDFz6Khotf4serQxc+io6mjrMv8vs2/ydLUyrnTw0NURnJhbWVEcmF3t723qLvm1sbBy6GjPGJyPgrG5NbQv8nS1Lj8z+rPuLXEyejWw7u70NC3vcq9o6y21Mbrt73KvaOsu+bWxsf40/K1xLTz0KG1yKGjPGJyPgo8YnI+CjwvcD4KPHA+CjIuu+bWxta7ysfP1Mq+o6y147v3ysK8/r7N0OjSqtK7uPbF0LbPwcuhozxicj4KQ1RGcmFtZSCw/Lqswcu24Lj2Q1RMaW5lLLKix9K/ydLUtcO1vbj3uPZsaW5ltcTG5Mq1zrvWw9PrtPPQoaGjxdC2z7Xju/e0ptTasrvU2sSzuPZsaW5lyc+ho0NUTGluZSDT1r/J0tTF0LbP1eK49rXjKM/gttTT2mN0bGluZbXE1/ix6im0prXEzsTX1re2zqeho8i7uvOx6cD61eK49nN0cmluZ7XEy/nT0E5TVGV4dENoZWNraW5nUmVzdWx0o6y4+b7dcmVzdWx0tcRyYW5nxdC2z7Xju/e0ptTasrvU2tXiuPZyYW5nyc+jrLTTtvi1w7W9teO797XEwbS909PrzrvWw6GjPC9wPgo8cD4KPGJyPgo8L3A+CjxwPs/Cw+bKx9K70KnP4LnYtcS7+bG+1qrKtjwvcD4KPHA+PC9wPgo8cD4K19bM5bXEu/mxvtaqyrajujwvcD4KPHA+CjwvcD4KPHA+CtfWzOUoRm9udCk6ysfSu8+1wdDX1rrFoaLR+cq9us2w9SYjMjA1NDA7z+DNrLXE19a3+yjA/cjnOjEwsPW62szlUGFsYXRpbm8poaPP1rbgsbvK086q19bR+bXEzazS5bTKPC9wPgo8cD4K19bD5ihGYWNlKTrKx8v509DX1rrFtcSw9SYjMjA1NDA7us0mIzI2Njg0O8q9tcTX27rPPC9wPgo8cD4K19bM5byvKEZvbnQgZmFtaWx5KTrKx9K71+nP4LnY19bM5SjA/cjnOkZyYW5rbGluIGZhbWlsebD8wKhGcmFua2xpbiBHb3RoaWOhokZyYW4ta2xpbkhlYXZ5us1GcmFua2xpbiBDb21wcmVzc2VkKTwvcD4KPHA+CrD1JiMyMDU0MDsoV2VpZ2h0KTrTw9Paw+jK9tfWzOW01rbIoaO15NDNtcSw9SYjMjA1NDA7LLTT1+601rW91+7PuCzT0Lyrz7ihos+4oaJib29roaLW0LXIoaKw67TWoaK01qGivc+01qGivKu01jwvcD4KPHA+CtH5yr0oU3R5bGUpOtfW0M7T0Mj91tbQzsq9OlJvbWFuIHR5cGXKx9axzOU7b2JsaXF1ZSB0eXBlysfQsczlO3V0YWt1YyB0eXBlysfQsczlvObH+s/fKLHIUm9tYW4gdHlwZbj8z/HK6beozOUpoaM8L3A+CjxwPgp4uN+2yChYIGhlaWdodCk61rjQodC019bEuLXExr2++bjftsgo0tR4zqq7+de8KaGjsPUmIzIwNTQwO8/gzay1xMG919bEuCx4uN+2yNS9tPO1xNfWxLi/tMbwwLSxyHi437bI0KG1xNfWxLjSqrTzPC9wPgo8cD4KQ2FwuN+2yChDYXAgaGVpZ2h0KTrT63i437bIz+AmIzIwMjg0O6Gj1ri089C019bEuLXExr2++bjftsgo0tRDzqq7+de8KTwvcD4KPHA+Cs/C0NDX1sS4KERlc2NlbmRlcik6wP3I59Ta19bEuHHW0Cy7+c/f0tTPwrXE19bEuLK/t9a90M/Cyeyyv7fWPC9wPgo8cD4Kyc/Q0NfWxLgoQXNjZW5kZXIpOni437bI0tTJz7XEsr+31iixyMjn19bEuGIpvdDX9snPyeyyv7fWPC9wPgo8cD4Ku/nP3yhCYXNlbGluZSk6zaizo9TaeKGidqGiYqGibc/CtcTEx8z1z988L3A+CjxwPgrD6LHfKFN0cm9rZSk61+mzydfWt/u1xM/fu/LH+s/foaO/ydLUvNO01rvyuMSx5NfWt/vQzte0PC9wPgo8cD4Ks8TP3yhTZXJpZik608PAtMq519a3+7j8v8nK07XE0rvM9cuuxr3P36GjyOfX1sS41/PJz73Hus3PwrK/tcTLrsa9z9+hozwvcD4KPHA+Cs7es8TP3yhTYW5zIFNlcmlmKTq/ydLUyMPFxdfW1LGyu8q508OzxM/f17DKzqGjPC9wPgo8cD4Kt73QztfWKEJsb2NrKTrV4tbW19bM5bXEscq7rcq519a3+7+0xvDAtLHIzt6zxM/f19a4/M/UJiMzMDUyNDsstau7ubK7tb2zo7z7tcSzxM/f19a1xLPMtsiho8D9yOdMdWJhbGluIEdyYXBovs3Kx7e90M7X1izV4tbW19a/tMbwwLS6w8/xysfEvs23v+m/zLXE0rvR+TwvcD4KPHA+CsrW0LTM5b3Fsb4oQ2FsbGlncmFwaGljIHNjcmlwdCk6ysfSu9bWt8LQp8rW0LTM5bXE19bM5aGjwP3I5011cnJheSBIaWxsu/LV30ZyYWt0dXLX1szlPC9wPgo8cD4K0tXK9dfWKERlY29yYXRpdmUpOs/xu+a7rbDjtcTX1szlPC9wPgo8cD4KUGm3+7rFKFBpc3ltYm9sKTq3x7Hq17y1xNfWxLjK/dfW19a3+7XEzNjK4rf7usWho8D9yOdXaW5nZGluZ3O6zU1hdGhlbWF0aWNhbCBQaTwvcD4KPHA+CsGs0LQoTGlnYXR1cmUpOsrH0rvPtcHQwazQtNfWxLjI52ZpoaJmbKGiZmZpu/JmZmyho9PJ09rX1tCp19bEuNDO17S1xNSt0vK+rbOjsbvBrNC0LLnKxcXX1tSx0tHPsLnfvavL/MPHwazQtKGjPC9wPgo8aW1nIHNyYz0="http://www.bkjia.com/uploadfile/Collfiles/20140106/2014010609171164.gif" alt="\">
字元屬性名稱:
const CFStringRef kCTCharacterShapeAttributeName; //字型形狀屬性 必須是CFNumberRef對象預設為0,非0則對應相應的字元形狀定義,如1表示傳統字元形狀const CFStringRef kCTFontAttributeName; //字型屬性 必須是CTFont對象const CFStringRef kCTKernAttributeName; //字元間隔屬性 必須是CFNumberRef對象const CFStringRef kCTLigatureAttributeName; //設定是否使用連字屬性,設定為0,表示不使用連字屬性。標準的英文連字有FI,FL.預設值為1,既是使用標準連字。也就是當搜尋到f時候,會把fl當成一個文字。必須是CFNumberRef 預設為1,可取0,1,2const CFStringRef kCTForegroundColorAttributeName; //字型顏色屬性 必須是CGColor對象,預設為blackconst CFStringRef kCTForegroundColorFromContextAttributeName; //內容相關的字型顏色屬性 必須為CFBooleanRef 預設為False,const CFStringRef kCTParagraphStyleAttributeName; //段落樣式屬性 必須是CTParagraphStyle對象 預設為NILconst CFStringRef kCTStrokeWidthAttributeName; //筆畫線條寬度 必須是CFNumberRef對象,默為0.0f,標準為3.0fconst CFStringRef kCTStrokeColorAttributeName; //筆畫的顏色屬性 必須是CGColorRef 對象,預設為前景色彩const CFStringRef kCTSuperscriptAttributeName; //設定字型的上下標屬性 必須是CFNumberRef對象 預設為0,可為-1為下標,1為上標,需要字型支援才行。如排列組合的樣式Cn1const CFStringRef kCTUnderlineColorAttributeName; //字型底線顏色屬性 必須是CGColorRef對象,預設為前景色彩const CFStringRef kCTUnderlineStyleAttributeName; //字型底線樣式屬性 必須是CFNumberRef對象,默為kCTUnderlineStyleNone 可以通過CTUnderlineStypleModifiers 進行修改底線風格const CFStringRef kCTVerticalFormsAttributeName;//文字的字形方向屬性 必須是CFBooleanRef 預設為false,false表示水平方向,true表示豎直方向const CFStringRef kCTGlyphInfoAttributeName;//字型資訊屬性 必須是CTGlyphInfo對象const CFStringRef kCTRunDelegateAttributeName//CTRun 委託屬性 必須是CTRunDelegate對象
關於CTM
CTM,Context Translate Matrix。 它是把要繪製的上下文以一個叫做Matrix的東西來表示,可以簡單地想作,繪製的內容相關的每一個點都映射在Matrix上,你在Matrix上的操作都會使得上下文上的點產生相應的變動。如放大、旋轉、移動。
在一般的教程裡面,為了達到旋轉或放大縮小的目的,一般都會先改變這個上下文,如:
CGContextTranslateCTM(context, 0, self.bounds.size.height);CGContextScaleCTM(context, 1.0f, -1.0f);
然後進行繪圖操作。那麼這個繪圖操作是怎麼做的呢?這個對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則是倒過來的。如:
那麼怎麼辦呢?想想,仔細看上面這張圖,貌似像是正常方向的倒影,但是水平線卻在最上面。嗯,挪下來,然後再反過來,看一下效果。如:
效果:
IOS CoreText.framework --- 基本用法