0

CoreText を使用して MAC OS X にカスタム テキスト レイアウト アルゴリズムを実装しています。カスタム NSView サブクラス オブジェクト内の別の場所にある CTRun の一部を部分的にレンダリングする必要があります。

これが私の drawRect: メソッドの実装です。

- (void)drawRect:(NSRect)dirtyRect {
// Drawing code here.
CGContextRef context =
(CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
CGContextSaveGState(context); {
    [[NSColor whiteColor] set];
    NSRectFill(dirtyRect);


    CTFontRef font = CTFontCreateWithName(CFSTR("Menlo"), 20, &CGAffineTransformIdentity);

    CFTypeRef values[] = {font};
    CFStringRef keys[] = {kCTFontAttributeName};

    CFDictionaryRef dictionary =
    CFDictionaryCreate(NULL,
                       (const void **)&keys,
                       (const void **)&values,
                       sizeof(keys) / sizeof(keys[0]),
                       &kCFTypeDictionaryKeyCallBacks,
                       &kCFTypeDictionaryValueCallBacks);

    CFAttributedStringRef longString =
    CFAttributedStringCreate(kCFAllocatorDefault, CFSTR("this_is_a_very_long_string_that_compromises_many_glyphs,we_wil_see_it:)"), dictionary);
    CTLineRef lineRef = CTLineCreateWithAttributedString(longString);

    CFArrayRef runsArray = CTLineGetGlyphRuns(lineRef);
    CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runsArray, 0);

    CGAffineTransform textTransform = CGAffineTransformIdentity;
    textTransform = CGAffineTransformScale(textTransform, 1.0, -1.0);
    CGContextSetTextMatrix(context, textTransform);

    CGAffineTransform sequenceTransform =
    CGAffineTransformIdentity;
    sequenceTransform = CGAffineTransformTranslate(sequenceTransform, 0, 23.2818);


    CGPoint firstPoint = CGPointApplyAffineTransform(CGPointMake(0, 0), sequenceTransform);
    CFRange firstRange = CFRangeMake(0, 24);
    CGContextSetTextPosition(context, firstPoint.x, firstPoint.y);
    CTRunDraw(run, context, firstRange);

    CGPoint secondPoint = CGPointApplyAffineTransform(CGPointMake(0, 26.2812), sequenceTransform);
    CFRange secondRange = CFRangeMake(24, 24);
    CGContextSetTextPosition(context, secondPoint.x, secondPoint.y);
    CTRunDraw(run, context, secondRange);

    CGPoint thirdPoint = CGPointApplyAffineTransform(CGPointMake(0, 52.5625), sequenceTransform);
    CFRange thirdRange = CFRangeMake(48, 23);
    CGContextSetTextPosition(context, thirdPoint.x, thirdPoint.y);
    CTRunDraw(run, context, thirdRange);

}
CGContextRestoreGState(context);

}

このコードの出力は次の とおりですhttps://docs.google.com/open?id=0B8df1OdxKw4FYkE5Z1d1VUZQYWs

問題は CTRunDraw() メソッドが指定された範囲以外の位置に空白を挿入することです。

私が望むのは、実行の一部を正しい位置にレンダリングすることです。これが私が望む正しい出力です(正しい出力は元の出力のフォトショップです)。 https://docs.google.com/open?id=0B8df1OdxKw4FcFRnS0p1cFBfa28

注: カスタム NSView サブクラスで反転座標系を使用しています。

- (BOOL)isFlipped {
return YES;

}

4

1 に答える 1

0

あなたはCTRunここを悪用しています。ACTRunは、レイアウトされたグリフを含む水平ボックスです。その一部を互いに下に描画しようとするのは、実際には意味がありません (確かに、そのような組版は、少し複雑な場合でも間違っています)。なんで?特定の位置に改行があると、選択されるグリフが異なる場合があるためです (これは、たとえば合字で発生する可能性があります)。また、文字とグリフの間に必ずしも 1:1 のマッピングがあるとは限らないことに注意してください。

私の推測では、おそらく独自の完全なカスタム タイプセッターは必要ないでしょう (そして、私を信じてください。書くのは複雑なので、必要がない場合は作成しないでください)。代わりに、CTTypesetterand/orCTFramesetterを使用して、必要な出力を取得してください。

于 2013-05-16T17:08:13.620 に答える