将CTFrame分解为CTLines

时间:2012-05-13 04:52:58

标签: objective-c core-text

我有以下代码在rect中绘制属性字符串:

CGContextRef context = UIGraphicsGetCurrentContext();
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)string);

    // left column form
    CGMutablePathRef leftColumnPath = CGPathCreateMutable();
    CGPathAddRect(leftColumnPath, NULL, CGRectMake(rect.origin.x, -rect.origin.y,rect.size.width, self.bounds.size.height));

    // left column frame
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);
    CGContextTranslateCTM(context, 0, self.bounds.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);   
    CTFrameRef leftFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), leftColumnPath, NULL);
    CTFrameDraw(leftFrame, context);

这里一切正常,但我需要更好地控制每一行。因此,我想分别绘制每一行,而不是绘制框架。所以我正在尝试使用它来代替使用CTFrameDraw:

CFArrayRef linesArray =  CTFrameGetLines(leftFrame);
    for (CFIndex i = 0; i < CFArrayGetCount(linesArray); i++){
        CTLineRef line = CFArrayGetValueAtIndex(linesArray, i);
        CTLineDraw(line, context);
}

但是,这与绘制框架的结果不同。我是Core Text的新手,那么我应该做更多的事情来画线吗?当前此循环执行多次,但屏幕底部只绘制一条线(而不是CTFrameDraw顶部)

2 个答案:

答案 0 :(得分:2)

CGContextSetTextPosition(context, x, y)之前插入CTLineDraw并更改x&amp;根据需要(不要忘记y被撤销)

答案 1 :(得分:1)

示例代码提取自: https://github.com/BigZaphod/Chameleon/blob/master/UIKit/Classes/UIStringDrawing.m

 if (lines)
 {
     CFIndex numberOfLines = CFArrayGetCount(lines);

    numberOfLines = 3;

    const CGFloat fontLineHeight = font.lineHeight;
    CGFloat textOffset = 0;

    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSaveGState(ctx);
    CGContextTranslateCTM(ctx, rect.origin.x, rect.origin.y+font.ascender);
    CGContextSetTextMatrix(ctx, CGAffineTransformMakeScale(1,-1));

    for (CFIndex lineNumber=0; lineNumber<numberOfLines; lineNumber++) {
        CTLineRef line = CFArrayGetValueAtIndex(lines, lineNumber);
        float flush = 0.5;

        switch (alignment) {
            case UITextAlignmentCenter: flush = 0.5;    break;
            case UITextAlignmentRight:  flush = 1;      break;
            case UITextAlignmentLeft:
            default:                    flush = 0;      break;
        }

        CGFloat penOffset = CTLineGetPenOffsetForFlush(line, flush, rect.size.width);
        CGContextSetTextPosition(ctx, penOffset, textOffset);
        CTLineDraw(line, ctx);
        textOffset += fontLineHeight;
    }

    CGContextRestoreGState(ctx);

    CFRelease(lines);
}