2012-04-13 4 views
2

UIFontとCTFontは異なることが分かっていますが、それを動作させることができました。iPhone iOS UIFontからCTFontRefへの変換でサイズのずれが発生する

私はPDFを生成し、UIViewをテンプレートとして使用しようとしていますが、編集可能なPDFを描画するには、CTFontRefをあるフレームでレンダリングする必要があります。以下はPDFコンテキストでUILabelを描画する私の方法です。 このメソッドはフォント名、フォントサイズ、位置のテンプレートとしてUILabelを使用し、CTFontRefは文字をPDFにレンダリングします。

このメソッドは機能しますが、癖があります。

私は、以下のコードがUIFontで書かれたテキストに収まる大きさのフレームでレンダリングに失敗することがあることに気付きました。たとえば、特定のフォントに適合する80×21のUILabelがあります。そのフォントをCTFontRefでレンダリングしようとすると、ラベルの高さを80x30とすると、空白になります。簡単に言えば、CTFontRefは、フレームを水平または垂直にクリップしないテキストをレンダリングしません。

さらに、一部のフォントの幅が違うことに気付きました。そのため、UIFontの20文字に適合する80x21のラベルは、15文字のCTFontRefのようにしか収まりません。 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); 
} 

UPDATE:

私は、コードをリファクタリングし、フル機能の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

ありがとう、あなたの答えは両方の問題を解決するのに役立ちました! –