CoreText 关键性常用函数说明

CoreText是专门进行文字绘制的函数集合

 

CoreText 将单个字符分为

· baseline(基线),一条假想的线,一行上的字形都以此线作为上下位置的参考,在这条线的左侧存在一个点叫做基线的原点,
· ascent(上行高度)从原点到字体中最高(这里的高深都是以基线为参照线的)的字形的顶部的距离,ascent是一个正值
· descent(下行高度)从原点到字体中最深的字形底部的距离,descent是一个负值(比如一个字体原点到最深的字形的底部的距离为2,那么descent就为-2)
· linegap(行距),linegap也可以称作leading(其实准确点讲应该叫做External leading),行高lineHeight则可以通过 ascent + |descent| + linegap 来计算。

 

使用CoreText绘制一段文字的步骤为:

1.获取画布 CGContextRef

 

2.设置坐标系。因为CoreText的坐标系是左下角,但是UIView的坐标系是左上角,需要进行相应翻转,才方便进行操作。

CGContextSetTextMatrix(context,CGAffineTransformIdentity);//设置字形变换矩阵,当前值表示不做任何字形变换处理

CGContextTranslateCTM(context, 0, self.frame.size.height);//将绘制原点从左下角位移到左上角

CGContextScaleCTM(context, 1, -1);//将坐标翻转180度

 

3.设置需要绘制的文本 NSMutableAttributedString

 

4.使用CTFramesetterCreateWithAttributedString 从NSMutableAttributedString中生成 CTFramesetterRef

 

5.设置CTFrameRef的绘制区域 

CGMutablePathRef path=CGPathCreateMutable();

CGPathAddRect(path, NULL, CGRectMake(20, 20, self.frame.size.width-40, self.frame.size.height-40));

 

6.从CTFramesetterRef中生成 CTFrameRef  。

CTFramesetterCreateFrame(ctframesetter, CFRangeMake(0, attrstr.length), path, NULL);

 

7.绘制CTFrameRef

CTFrameDraw(ctframe, context);

 

除了直接绘制CTFrameRef之外还可以对每一行进行单独处理,步骤为:

其他步骤跟上面前6步骤完全一样

7.获取CTFrameRef中的所有行

 CFArrayRef array=CTFrameGetLines(ctframe); //获取所有的行的数组

  NSInteger arrcount=CFArrayGetCount(array);//获取数组的长度

 

8.循环这个行数组获取行对象

CTLineRef line=CFArrayGetValueAtIndex(array, i);//获取第i行

 

9.可以使用 CTLineCreateJustifiedLine 函数对行进行处理,将所有不满一行的进行拉伸到满一行的位置

 CTLineRef justifiedLine = CTLineCreateJustifiedLine(line, 1.0f, self.frame.size.width-40);

 CFRelease(line);

 line = justifiedLine;

 

10.可以动态调整行的位置

float asent;//行的上半部分高度

float descent;//行的下半部分高度

float leading;//行间距

CTLineGetTypographicBounds(line, &asent, &descent, &leading);//获取行的一些属性

CGContextSetTextPosition(context,myline.point.x,self.frame.size.height-(asent+descent+leading)*(i+1)-20);//设置行的文字位置,行的坐标位置设置仍然以左下角为原点的

 

11.将行文字绘制在界面上

CTLineDraw(line, context);

 

  这里面有一些函数需要特殊注意,可能比较有用途

1.这个函数用来处理行宽不一致的问题,有些行的由于内部有一些标点符号,无法占满整行,导致行宽参差不齐,这个函数专门处理这个问题。

CTLineRef __nullable CTLineCreateJustifiedLine(

    CTLineRef line,

    CGFloat justificationFactor,

    double justificationWidth ) CT_AVAILABLE(10_5, 3_2);

 

2. 获取行中间某一个索引位置的字符的x坐标

其中 charIndex参数的索引是整段文字的文字位置索引

CGFloat CTLineGetOffsetForStringIndex(

    CTLineRef line,

    CFIndex charIndex,

    CGFloat * __nullable secondaryOffset ) CT_AVAILABLE(10_5, 3_2);

 

3.根据一个点的坐标位置获取在这个行中字符位置的索引

CFIndex CTLineGetStringIndexForPosition(

    CTLineRef line,

    CGPoint position ) CT_AVAILABLE(10_5, 3_2);

 

4.获取行的一些信息,其中返回值为行的整体宽度,行的高度为ascent+descent

double CTLineGetTypographicBounds(

    CTLineRef line,

    CGFloat * __nullable ascent,

    CGFloat * __nullable descent,

    CGFloat * __nullable leading ) CT_AVAILABLE(10_5, 3_2);

posted on 2015-12-10 22:37  压力无限大  阅读(919)  评论(0编辑  收藏  举报

导航