2

UIFont と CTFont が別物であることは知っていますが、何とか動作させることができました。

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];
  }
4

1 に答える 1

3

UIKit1) によって描かれたテキストとによって描かれたテキストを混在させることはできませんCoreText。これは Apple ドキュメントに記載されています ( 「Core Text and the UIKit Framework」セクションの iOS 用のテキスト、Web、および編集プログラミングを参照してください)。(起こっているように見えるのは、UIKit がいくつかの丸めを行い、いくつかのショートカットを使用してパフォーマンスを向上させ、デフォルトではカーニングを行わないことです。)

2) いいえ、いくつかのプロパティが不足しているわけではありません。

3) CoreText は、テキストを切り捨てる単純な手段を提供していません。そのためには、独自のコードを作成する必要があります。

于 2012-04-13T21:34:44.350 に答える