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