2012-04-13 3 views
2

UIFont와 CTFont는 서로 다른 점을 알고 있지만 제대로 작동 할 수있었습니다.iPhone iOS UIFont에서 CTFontRef로 변환하면 크기가 잘못 정렬됩니다.

PDF를 생성하고 UIView를 템플릿으로 사용하려고하지만 편집 가능한 PDF를 그리기 위해 CTFontRef를 특정 프레임에서 렌더링해야합니다. 아래는 PDF 컨텍스트에서 UILabel을 그리는 제 방법입니다. 이 메서드는 UILabel을 글꼴 이름, 글꼴 크기 및 위치에 대한 템플릿으로 사용하고 CTFontRef는 문자를 PDF로 렌더링합니다.

이 방법은 효과가 있지만 버릇이 있습니다.

아래 코드는 UIFont로 작성된 텍스트에 맞게 충분히 큰 프레임에서 렌더링하지 못할 수도 있습니다. 예를 들어 특정 글꼴에 맞는 80x21 UILabel이 있습니다. 이 글꼴을 CTFontRef로 렌더링하려고하면 80x30이라고 말하기 위해 레이블 높이를 높이 지 않는 한 빈 공간이 생깁니다. 간단히 말해, CTFontRef는 프레임을 수평 또는 수직으로 클립하지 않는 텍스트를 렌더링하지 않습니다.

또한 일부 글꼴의 너비가 다르기 때문에 UIFont의 20 자에 맞는 80x21 레이블은 CTFontRef의 15 자처럼 적합 할 수 있습니다. 내 추측은 CTFontRef가 텍스트를 자르지 않고 단순히 프레임의 어느 방향으로 튀어 나오는 단어도 렌더링하지 않기 때문입니다.

몇 가지 질문 : 내 글꼴 크기가 잘못 정렬 될 수있는 원인은 무엇입니까? 다른 부동산을 복사해야합니까? CTFontRef에게 레이블 끝에 긴 단어를 잘라내도록 요청하는 방법이 있습니까?

//xOriginOffset, yOriginOffset is the X of the origin of the container view that holds the label. 

+(void)drawTextLabel:(UILabel*)label WithXOriginOffset:(int)xOriginOffset YOffset:(int)yOriginOffset 
{ 

    NSString* textToDraw = label.text; 
    CFStringRef stringRef = (__bridge CFStringRef)textToDraw; 

    UIFont* uiFont = label.font; 


    // Prepare font 

    CTFontRef font = CTFontCreateWithName((__bridge CFStringRef)uiFont.fontName, uiFont.pointSize, NULL); 

    // Create an attributed string 
    CFStringRef keys[] = { kCTFontAttributeName,kCTForegroundColorAttributeName }; 
    CFTypeRef values[] = { font,[[UIColor redColor]CGColor] }; 
    CFDictionaryRef attr = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 
               sizeof(keys)/sizeof(keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 

    // Prepare the text using a Core Text Framesetter 
    CFAttributedStringRef currentText = CFAttributedStringCreate(NULL, stringRef, attr); 

    NSAssert(currentText!=nil,@"current text is nil!"); 
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText); 

    //account for the view's superview 
    CGRect frameRect = CGRectMake(xOriginOffset+label.frame.origin.x, 
            yOriginOffset+label.frame.origin.y, 
            label.frame.size.width, 
            label.frame.size.height); 


    CGMutablePathRef framePath = CGPathCreateMutable(); 
    CGPathAddRect(framePath, NULL, frameRect); 

    // Get the frame that will do the rendering. 
    CFRange currentRange = CFRangeMake(0, 0); 
    CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, currentRange, framePath, NULL); 
    CGPathRelease(framePath); 

    // Get the graphics context. 
    CGContextRef currentContext = UIGraphicsGetCurrentContext(); 

    NSAssert(currentContext!=nil,@"currentContext is nil!"); 


    // Draw the frame. 
    CTFrameDraw(frameRef, currentContext); 

    CFRelease(frameRef); 
    CFRelease(stringRef); 
    CFRelease(framesetter); 
} 

업데이트 :

나는 코드를 리팩토링 및 완전한 기능을 갖춘 PDF 텍스트를 생산하는 지금이 방법을 사용하고 있습니다.

+(void)drawTextLabel:(UILabel*)label WithXOriginOffset:(int)xOriginOffset YOffset:(int)yOriginOffset 
{ 

    NSString* textToDraw = label.text; 

    UIFont* uiFont = label.font; 
     // Prepare font 
    CGRect frameRect = CGRectMake(xOriginOffset+label.frame.origin.x, 
            yOriginOffset+label.frame.origin.y, 
            label.frame.size.width, 
            label.frame.size.height); 

    [textToDraw drawInRect:frameRect withFont:uiFont lineBreakMode:UILineBreakModeTailTruncation]; 
    } 

답변

3

1) 당신은 CoreText에 의해 그려진 텍스트로 UIKit에 의해 그려진 텍스트를 혼합 할 수 없습니다. 이것은 Apple 문서 (Text, Web and Editing Programming for iOS in the section "Core Text and the UIKit Framework" 참조)에 언급되어 있습니다. UIKit은 반올림을 수행하고 성능을 높이기 위해 몇 가지 단축키가 필요하며 기본적으로 커닝을하지 않습니다.

2) 아니요, 일부 속성이 누락되지 않았습니다.

3) CoreText는 텍스트를 자르는 간단한 방법을 제공하지 않으므로 텍스트를 직접 작성해야합니다.

+0

감사합니다. 귀하의 답변을 통해 두 가지 문제를 모두 해결할 수있었습니다. –