2012-08-08 2 views
0

CoreText를 사용하여 MAC OS X에서 사용자 지정 텍스트 레이아웃 알고리즘을 구현하고 있습니다. 커스텀 NSView 서브 클래스 객체 내의 다른 위치에 부분적으로 CTRun을 렌더링해야합니다. 여기 CTRunDraw()가 올바른 동작을 구현합니다.

가의 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; 

}

답변

0

현재 CTRun을 오용하고 있습니다. CTRun은 배치 된 글리프가 포함 된 가로 상자입니다. 서로의 일부분을 그려내는 것은 실제로 의미가 없습니다 (물론 이러한 조판은 다소 복잡한 경우에도 잘못 될 것입니다). 왜? 주어진 위치에 줄 바꿈이있는 경우 선택한 글립 문자가 다를 수있는 상황이 있기 때문에 (예 : 합자가 발생할 수 있습니다). 또한 문자와 글리프 사이에는 반드시 1 : 1 매핑이 필요하지 않습니다.

아마도 내 자신의 전체 사용자 정의 식자공이 필요하지 않을 것입니다. (나를 믿으십시오. 하나는 이므로 복잡하지 않습니다. 하나를 쓰지 마십시오). 대신 원하는 출력을 얻으려면 CTTypesetter 및/또는 CTFramesetter을 사용하십시오.