1. 程式人生 > >[iOS]CoreText 學習筆記(1)

[iOS]CoreText 學習筆記(1)

感謝唐巧大神的文章,總結一下學習筆記.

完善的排版引擎,所有的程式碼(顏色、frame等)按照不同的功能分成不同的類。


按照以上原則,將CTDisplayView中的部分內容拆開,由 4 個類構成:

  1. CTFrameParserConfig類,用於配置繪製的引數,例如:文字顏色,大小,行間距等。
  2. CTFrameParser類,用於生成最後繪製介面需要的CTFrameRef例項。
  3. CoreTextData類,用於儲存由CTFrameParser類生成的CTFrameRef例項以及CTFrameRef實際繪製需要的高度。
  4. CTDisplayView
    類,持有CoreTextData類的例項,負責將CTFrameRef繪製到介面上。
  1. CTFrameParser通過CTFrameParserConfig例項來生成CoreTextData例項。
  2. CTDisplayView通過持有CoreTextData例項來獲得繪製所需要的所有資訊。
  3. ViewController類通過配置CTFrameParserConfig例項,進而獲得生成的CoreTextData例項,最後將其賦值給他的CTDisplayView成員,達到將指定內容顯示在介面上的效果。

圖:UML 示意圖

API介面文件。

https://developer.apple.com/library/mac/#documentation/Carbon/Reference/CoreText_Framework_Ref/_index.html

CoreText 框架中最常用的幾個類:

  1. CTFont
  2. CTFontCollection
  3. CTFontDescriptor
  4. CTFrame
  5. CTFramesetter
  6. CTGlyphInfo
  7. CTLine
  8. CTParagraphStyle
  9. CTRun
  10. CTTextTab
  11. CTTypesetter

先來了解一下該框架的整體視窗組合圖:

CTFrame 作為一個整體的畫布(Canvas),其中由行(CTLine)組成,而每行可以分為一個或多個小方塊(CTRun)。

注意: 你不需要自己建立CTRun,Core Text將根據NSAttributedString的屬性來自動建立CTRun。每個CTRun物件對應不同的屬性,正因此,你可以自由的控制字型、顏色、字間距等等資訊。

通常處理步聚:

1.使用core text就是先有一個要顯示的string,然後定義這個string每個部分的樣式->attributedString -> 生成 CTFramesetter -> 得到CTFrame -> 繪製(CTFrameDraw) 
其中可以更詳細的設定換行方式,對齊方式,繪製區域的大小等。 
2.繪製只是顯示,點選事件就需要一個判斷了。 
CTFrame 包含了多個CTLine,並且可以得到各個line的其實位置與大小。判斷點選處在不在某個line上。CTLine 又可以判斷這個點(相對於ctline的座標)處的文字範圍。然後遍歷這個string的所有NSTextCheckingResult,根據result的rang判斷點選處在不在這個rang上,從而得到點選的連結與位置。

字型的基本知識:

字型(Font):是一系列字號、樣式和磅值相同的字元(例如:10磅黑體Palatino)。現多被視為字樣的同義詞

字面(Face):是所有字號的磅值和格式的綜合

字型集(Font family):是一組相關字型(例如:Franklin family包括Franklin Gothic、Fran-klinHeavy和Franklin Compressed)

磅值(Weight):用於描述字型粗度。典型的磅值,從最粗到最細,有極細、細、book、中等、半粗、粗、較粗、極粗

樣式(Style):字形有三種形式:Roman type是直體;oblique type是斜體;utakuc type是斜體兼曲線(比Roman type更像書法體)。

x高度(X height):指小寫字母的平均高度(以x為基準)。磅值相同的兩字母,x高度越大的字母看起來比x高度小的字母要大

Cap高度(Cap height):與x高度相似。指大寫字母的平均高度(以C為基準)

下行字母(Descender):例如在字母q中,基線以下的字母部分叫下伸部分

上行字母(Ascender):x高度以上的部分(比如字母b)叫做上伸部分

基線(Baseline):通常在x、v、b、m下的那條線

描邊(Stroke):組成字元的線或曲線。可以加粗或改變字元形狀

襯線(Serif):用來使字元更可視的一條水平線。如字母左上角和下部的水平線。

無襯線(Sans Serif):可以讓排字員不使用襯線裝飾。

方形字(Block):這種字型的筆畫使字元看起來比無襯線字更顯眼,但還不到常見的襯線字的程度。例如Lubalin Graph就是方形字,這種字看起來好像是木頭塊刻的一樣

手寫體指令碼(Calligraphic script):是一種仿效手寫體的字型。例如Murray Hill或者Fraktur字型

藝術字(Decorative):像繪畫般的字型

Pi符號(Pisymbol):非標準的字母數字字元的特殊符號。例如Wingdings和Mathematical Pi

連寫(Ligature):是一系列連寫字母如fi、fl、ffi或ffl。由於字些字母形狀的原因經常被連寫,故排字員已習慣將它們連寫。

字元屬性名稱:

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,2
const CFStringRef kCTForegroundColorAttributeName;             
//字型顏色屬性  必須是CGColor物件,預設為black
const CFStringRef kCTForegroundColorFromContextAttributeName; 
//上下文的字型顏色屬性 必須為CFBooleanRef 預設為False,
const CFStringRef kCTParagraphStyleAttributeName;              
//段落樣式屬性 必須是CTParagraphStyle物件 預設為NIL
const CFStringRef kCTStrokeWidthAttributeName;              
//筆畫線條寬度 必須是CFNumberRef物件,默為0.0f,標準為3.0f
const CFStringRef kCTStrokeColorAttributeName;              
//筆畫的顏色屬性 必須是CGColorRef 物件,預設為前景色
const CFStringRef kCTSuperscriptAttributeName;              
//設定字型的上下標屬性 必須是CFNumberRef物件 預設為0,可為-1為下標,1為上標,需要字型支援才行。如排列組合的樣式Cn1
const CFStringRef kCTUnderlineColorAttributeName;           
//字型下劃線顏色屬性 必須是CGColorRef物件,預設為前景色
const CFStringRef kCTUnderlineStyleAttributeName;           
//字型下劃線樣式屬性 必須是CFNumberRef物件,默為kCTUnderlineStyleNone 可以通過CTUnderlineStypleModifiers 進行修改下劃線風格
const CFStringRef kCTVerticalFormsAttributeName;
//文字的字形方向屬性 必須是CFBooleanRef 預設為falsefalse表示水平方向,true表示豎直方向
const CFStringRef kCTGlyphInfoAttributeName;
//字型資訊屬性 必須是CTGlyphInfo物件
const CFStringRef kCTRunDelegateAttributeName
//CTRun 委託屬性 必須是CTRunDelegate物件

舉例說明:

[cpp]   view plain copy

  1. NSMutableAttributedString *mabstring = [[NSMutableAttributedString alloc]initWithString:@ "This is a test of characterAttribute. 中文字元" ];  


[cpp]   view plain copy

  1. //設定字型屬性   
  2.   CTFontRef font = CTFontCreateWithName(CFSTR( "Georgia" ), 40, NULL);  
  3.   [mabstring addAttribute:(id)kCTFontAttributeName value:(id)font range:NSMakeRange(0, 4)];   

[cpp]   view plain copy

  1. //設定斜體字   
  2.     CTFontRef font = CTFontCreateWithName((CFStringRef)[UIFont italicSystemFontOfSize:20].fontName, 14, NULL);  
  3.     [mabstring addAttribute:(id)kCTFontAttributeName value:(id)font range:NSMakeRange(0, 4)];  

[cpp]   view plain copy

  1. //下劃線   
  2.     [mabstring addAttribute:(id)kCTUnderlineStyleAttributeName value:(id)[NSNumber numberWithInt:kCTUnderlineStyleDouble] range:NSMakeRange(0, 4)];   

[cpp]   view plain copy

  1. //下劃線顏色   
  2.     [mabstring addAttribute:(id)kCTUnderlineColorAttributeName value:(id)[UIColor redColor].CGColor range:NSMakeRange(0, 4)];  

[cpp]   view plain copy

  1. //設定字型簡隔 eg:test    
  2.      long  number = 10;  
  3.     CFNumberRef num = CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt8Type,&number);  
  4.     [mabstring addAttribute:(id)kCTKernAttributeName value:(id)num range:NSMakeRange(10, 4)];  

[cpp]   view plain copy

  1. //設定連字   
  2. long  number = 1;  
  3.     CFNumberRef num = CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt8Type,&number);  
  4.     [mabstring addAttribute:(id)kCTLigatureAttributeName value:(id)num range:NSMakeRange(0, [str length])];  

連字還不會使用,未看到效果。

[cpp]   view plain copy

  1. //設定字型顏色   
  2.     [mabstring addAttribute:(id)kCTForegroundColorAttributeName value:(id)[UIColor redColor].CGColor range:NSMakeRange(0, 9)];  

[cpp]   view plain copy

  1. //設定字型顏色為前影色   
  2.     CFBooleanRef flag = kCFBooleanTrue;  
  3.     [mabstring addAttribute:(id)kCTForegroundColorFromContextAttributeName value:(id)flag range:NSMakeRange(5, 10)];  

無明顯效果。

[cpp]   view plain copy

  1. //設定空心字   
  2.      long  number = 2;  
  3.     CFNumberRef num = CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt8Type,&number);  
  4.     [mabstring addAttribute:(id)kCTStrokeWidthAttributeName value:(id)num range:NSMakeRange(0, [str length])];  

[cpp]   view plain copy

  1. //設定空心字   
  2.      long  number = 2;  
  3.     CFNumberRef num = CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt8Type,&number);  
  4.     [mabstring addAttribute:(id)kCTStrokeWidthAttributeName value:(id)num range:NSMakeRange(0, [str length])];  
  5.        
  6.      //設定空心字顏色   
  7.     [mabstring addAttribute:(id)kCTStrokeColorAttributeName value:(id)[UIColor greenColor].CGColor range:NSMakeRange(0, [str length])];  


在設定空心字顏色時,必須先將字型高為空心,否則設定顏色是沒有效果的。 

[cpp]   view plain copy

  1. //對同一段字型進行多屬性設定       
  2.      //紅色   
  3.     NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithObject:(id)[UIColor redColor].CGColor forKey:(id)kCTForegroundColorAttributeName];  
  4.      //斜體   
  5.     CTFontRef font = CTFontCreateWithName((CFStringRef)[UIFont italicSystemFontOfSize:20].fontName, 40, NULL);  
  6.     [attributes setObject:(id)font forKey:(id)kCTFontAttributeName];  
  7.      //下劃線   
  8.     [attributes setObject:(id)[NSNumber numberWithInt:kCTUnderlineStyleDouble] forKey:(id)kCTUnderlineStyleAttributeName];  
  9.       
  10.     [mabstring addAttributes:attributes range:NSMakeRange(0, 4)];  

最後是draw了。

[cpp]   view plain copy

  1. -( void )characterAttribute  
  2. {  
  3.     NSString *str = @ "This is a test of characterAttribute. 中文字元" ;  
  4.     NSMutableAttributedString *mabstring = [[NSMutableAttributedString alloc]initWithString:str];  
  5.       
  6.     [mabstring beginEditing];  
  7.      /*  
  8.     long number = 1;  
  9.     */   
  10.      /*  
  11.     //設定字型屬性  
  12.  
  13.     */   
  14.      /*  
  15.     //設定字型簡隔 eg:test   
  16.     long number = 10;  
  17.     */   
  18.   
  19.      /*  
  20.     long number = 1;  
  21.      */   
  22.      /*  
  23.     //設定字型顏色  
  24.      */   
  25.      /*  
  26.     //設定字型顏色為前影色  
  27.     CFBooleanRef flag = kCFBooleanTrue;  
  28.      */   
  29.       
  30.      /*  
  31.     //設定空心字  
  32.     long number = 2;  
  33.        
  34.     //設定空心字顏色  
  35.      */   
  36.       
  37.      /*  
  38.     long number = 1;  
  39.     */   
  40.       
  41.      /*  
  42.     //設定斜體字  
  43.     */    
  44.       
  45.      /*  
  46.     //下劃線  
  47.     //下劃線顏色  
  48.      */   
  49.       
  50.       
  51.       
  52.      //對同一段字型進行多屬性設定       
  53.      //紅色   
  54.     NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithObject:(id)[UIColor redColor].CGColor forKey:(id)kCTForegroundColorAttributeName];  
  55.      //斜體   
  56.     CTFontRef font = CTFontCreateWithName((CFStringRef)[UIFont italicSystemFontOfSize:20].fontName, 40, NULL);  
  57.     [attributes setObject:(id)font forKey:(id)kCTFontAttributeName];  
  58.      //下劃線   
  59.     [attributes setObject:(id)[NSNumber numberWithInt:kCTUnderlineStyleDouble] forKey:(id)kCTUnderlineStyleAttributeName];  
  60.       
  61.     [mabstring addAttributes:attributes range:NSMakeRange(0, 4)];  
  62.        
  63.   
  64.       
  65.     NSRange kk = NSMakeRange(0, 4);  
  66.       
  67.     NSDictionary * dc = [mabstring attributesAtIndex:0 effectiveRange:&kk];  
  68.       
  69.     [mabstring endEditing];  
  70.       
  71.     NSLog(@ "value = %@" ,dc);  
  72.       
  73.   
  74.       
  75.     CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)mabstring);  
  76.       
  77.     CGMutablePathRef Path = CGPathCreateMutable();  
  78.       
  79.     CGPathAddRect(Path, NULL ,CGRectMake(10 , 0 ,self.bounds.size.width-10 , self.bounds.size.height-10));  
  80.