2013-06-13 2 views
3

Xcode 4.2를 사용하여 Mac OS X (10.7) 용 간단한 코코아 응용 프로그램을 작성했습니다. 모든 응용 프로그램은 스크롤 가능한 하위 뷰 배열을 포함하는 창을 작성합니다. 각 하위 뷰는 매우 낮은 수준의 항목을 그리는 페이지를 나타냅니다. 하위 뷰의 isFlipped 메소드는 YES를 전달하므로 모든 하위 뷰의 원점이 왼쪽 위 모서리입니다. 다양한 Core Graphics 루틴을 사용하여 필자는 선을 그려 경로를 채우고 PostScripty를 즐겁게 할 수있었습니다.CGContextShowGlyphsAtPoint()가 작동 할 때 왜 CGContextShowGlyphsAtPositions()가 작동하지 않습니까?

내가 혼란스러워하는 주어진 글꼴에서 글리프 그리기입니다.

여기에 전체 코드가 있어요, 컷 - 앤 - 붙여 넣기 하위보기의 -drawRect를 들어, 프로그램에서 : 방법 -

- (void)drawRect:(NSRect)dirtyRect 
{ 
    // Start with background color for any part of this view 
    [[NSColor whiteColor] set]; 
    NSRectFill(dirtyRect); 

    // Drop down to Core Graphics world, ensuring there's no side-effects 
    context = (CGContextRef) [[NSGraphicsContext currentContext] graphicsPort]; 
    CGContextSaveGState(context); 
    { 
    //CGFontRef theFont = CGFontCreateWithFontName(CFSTR("American Typewriter")); 
    //CGContextSetFont(context, theFont); 
    CGContextSelectFont(context, "American Typewriter", 200, kCGEncodingMacRoman); 
    CGContextSetFontSize(context, 200); 

    // Adjust the text transform so the text doesn't draw upside down 
    CGContextSetTextMatrix(context, CGAffineTransformScale(CGAffineTransformIdentity, 1, -1)); 

    CGContextSetTextDrawingMode(context, kCGTextFillStroke); 
    CGContextSetRGBFillColor(context, 0.0, .3, 0.8, 1.0); 

    // Find the center of view's (not dirtyRect's) bounds 
    // View is 612 x 792 (nominally 8.5" by 11") 

    CGPoint centerPoint; 
    CGRect bds = [self bounds]; 
    centerPoint.x = bds.origin.x + bds.size.width/2; 
    centerPoint.y = bds.origin.y + bds.size.height/2; 

    // Create arrays to hold glyph IDs and the positions at which to draw them. 
    #define glyphCount 1      // For now, just one glyph 
    CGGlyph glyphs[glyphCount]; 
    CGPoint positions[glyphCount]; 

    glyphs[0] = 40;        // Glyph ID for '@' character in above font 
    positions[0] = centerPoint; 

    // Draw above center. This works. 
    CGContextShowGlyphsAtPoint(context, centerPoint.x, centerPoint.y - 200.0, glyphs, glyphCount); 

    // Draw at center. This works. 
    CGContextShowGlyphsAtPoint(context, positions[0].x, positions[0].y, glyphs, glyphCount); 

    // Draw below center. This fails (draws nothing). Why? 
    positions[0].y += 200.0; 
    CGContextShowGlyphsAtPositions(context, glyphs, positions, glyphCount); 
    } 
    CGContextRestoreGState(context); 
} 

무엇 내 머리를 잡아 당겨 가지고하는 것은 처음 두 glyph- 그 CGContextShowGlyphsAtPoint()를 사용하여 그리기 호출이 예상대로 잘 작동하지만 CGContextShowGlyphsAtPositions()를 사용하는 세 번째 시도는 아무 것도 그리지 않습니다. 따라서 페이지에는 @ 기호가 두 개뿐입니다. 이 동작의 차이는 이전에 CGContextSetFont() 또는 CGContextSelectFont()를 사용했는지 여부에 달려 있지 않습니다.

두 가지 거의 완전히 다른 핵심 그래픽 글리프 그리기 루틴이있는 상태에서 약간의 숨겨진 변경이 있거나 후드 아래에서 매우 다른 것이 있어야하지만 지금까지의 모든 실험은 있다.

한숨. 난 그냥보기에서 해당 위치 배열에있는 글리프 배열을 효율적으로 그릴 싶습니다.

어떤 아이디어가 잘못 되었습니까?

답변

1

Peter Hosey의 답변에 의해 머리가 위아래로 구부러져서 가능한 많은 실험이 끝난 후 (일부는 꽤 옳지는 않지만, 많은 감사합니다!), 여기에 내 혼란의 원인과 설명이 있습니다. 올바른 (음, 코드는 내가 기대하는 것을 어쨌든하고있다).

일반적인 상위 수준의 포스트 스크립트 경로/그리기 모델에서 문자를 그리면 현재 문자 (경로 끝)가 다음 문자가 나타날 위치로 업데이트되어 현재 사용자 공간 변환은 동일하게 유지됩니다. 그러나 텍스트 매트릭스 변환은 으로 글리프의 너비에 의해 (또는 더 정확하게는 진행 벡터에 의해) 변환되어 다음에 그려 질 문자가 새로운 텍스트 또는 새 텍스트 출처에서 시작될 수 있도록합니다. 텍스트 행렬의 축척 비율은 변환 후에도 변하지 않습니다.

그래서 문자 배열의 수직 감각을 뒤집기위한 CGContextSetTextMatrix()에 대한 초기 설정 호출이 필요합니다 (사용자 공간이 비슷하게 뒤집 으면). 그렇지 않으면 그리기 모음 그리기 루틴 모두 글리프를 위/r/t 경로 그리기, 텍스트 그리기가 시작되는 위치 또는 사용되는 그리기 루틴에 상관없이.

두 개의 글리프 컬렉션 드로잉 루틴 중 어느 것도 현재 경로에 영향을 미치지 않습니다. 그것들은 그것보다 낮은 수준입니다. 경로의 위치 나 모양에 영향을주지 않으면 서 경로 생성 호출간에 루틴을 삽입 할 수 있음을 발견했습니다. 코드의

위에 게시 CGContextShowGlyphsAtPositions()는 글리프 컬렉션을 그리는 데 사용하는 위치 데이터는 이전에 그려진 오른쪽 번역 된 현재 텍스트 행렬의 원점에 대응하는 사용자 영역 포인트에 대한 모든 상대은 '@'글리프. 큰 글꼴 크기를 사용했기 때문에 position[0]은 다음 '@'글리프가 뷰의 경계 밖으로 그려지기 때문에 보이지 않지만 그려졌습니다.

하지만 두 가지 루틴 중에는 여전히 미묘한 차이가 있습니다. CGContextShowGlyphsAtPositions()은 절대 사용자 공간 위치에 글리프를 배치하는 데 사용할 수 없습니다. 그렇다면 어디에서 시작해야할지 어떻게 말합니까? 그 대답 (또는 적어도 하나의 대답)은을 그릴 글리프가 없더라도 CGContextShowGlyphsAtPoint()은 주어진 사용자 공간 점 으로 텍스트 행렬의 원점을 업데이트한다는 것입니다. 그리고 CGContextShowGlyphsAtPoint()은 각 글리프 그리기 후에 텍스트 행렬을 변환해야합니다. 왜냐하면 서로의 상단에 전체 글리프 컬렉션을 그리는 것이 무엇 때문입니까?

글리프 수가 0 인 CGContextShowGlyphsAtPoint()을 사용하여 사용자 공간의 비 경로 점으로 "이동"한 다음 (임의의 횟수)을 각각의 위치 벡터로 호출 할 수 있습니다. CGContextShowGlyphsAtPositions()이 반환 될 때 텍스트 행렬 원점을 전혀 업데이트하지 않고 텍스트 행렬의 원점 (또는 실제로는 그에 해당하는 사용자 공간 점)을 기준으로 처리됩니다.

마지막으로 CGContextShowGlyphsAtPositions()에 제공된 위치 데이터는 사용자 공간 좌표로 나타납니다. 이러한 루틴에 대한 Apple의 헤더 파일에 언급 된 내용은 분명히 이렇게 말하고 있습니다.

0

하나의 가능성은 CGContextShowGlyphsAtPositions 문서에서,이 인 각 글리프의 위치가 텍스트 공간에 을 지정

하고, 결과적으로 사용자 공간의 텍스트 행렬을 변환 인 .

The text matrix은 그래픽 상태의 현재 변환 행렬과 다른 컨텍스트의 별도 속성입니다.

이 함수는 사용자 공간 지정된 위치 에서 글리프의 배열을 표시

그것은 하지CGContextShowGlyphsAtPoint가 있다고한다.

(강조는 모두 따옴표에 추가됩니다.) 단일 지점에서 상형 문자를 표시 할 때

이 그래서, 텍스트 행렬은 실제로 사용되지 않습니다.

그러나 배열의 위치에 글리프를 표시하면 그 위치가 사용되며 잘못된 행렬의 증상이 나타납니다. 특히, 텍스트를 다른 방향으로 뒤집으려고하는 행렬이 잘못되었습니다. 좌표계를 거꾸로 뒤집습니다. 당신은 시야 밖에서 그림을 그립니다.

(-1 대신 비율을 조정하여 설정하면 실제로 무슨 뜻인지 알 수 있습니다.)

나의 추천은 CGContextSetTextMatrix 전화를 꺼내는 것입니다.

+0

감사합니다. 무슨 일이 일어나는가를 알기 위해 텍스트 매트릭스에 대한 귀하의 제안은 내가 혼란에 빠지기 위해 필요한 것이 었습니다. CGContextSetTextMatrix에 대한 호출을 제거하라는 제안은 좋지 않습니다. 아래에서 설명하겠습니다. – jsbox

+0

그리고이 방법의 헤더 파일은 LOL에 대해 반대라고 말합니다. 고마워, 애플 : "위치는 사용자 공간에 명시되어있다" – Adam