Я написал простое приложение Cocoa для Mac OS X (10.7), используя Xcode 4.2. Все, что делает приложение, — это создает окно с прокручиваемым массивом вложенных представлений, каждое из которых представляет страницу для рисования на очень низком уровне. Метод isFlipped вложенного представления возвращает YES, поэтому источником каждого вложенного представления является верхний левый угол. Используя различные подпрограммы Core Graphics, я могу успешно рисовать линии и заполнять контуры, а также все эти забавные вещи PostScript.
Меня смущает рисование глифов из заданного шрифта.
Вот полный код, вырезанный и вставленный из программы, для метода -drawRect: sub-View -
- (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);
}
Что заставило меня рвать на себе волосы, так это то, что первые два вызова рисования глифов с использованием CGContextShowGlyphsAtPoint() работают нормально, как и ожидалось, но третья попытка с использованием CGContextShowGlyphsAtPositions() никогда ничего не рисует. Таким образом, на странице только два символа @, а не три. Эта разница в поведении не зависит от того, использовал ли я ранее CGContextSetFont() или CGContextSelectFont().
Должно быть какое-то скрытое изменение в состоянии, или что-то совершенно другое под капотом с этими двумя почти идентичными процедурами рисования глифов Core Graphics, но все мои эксперименты до сих пор не продемонстрировали, что это может быть.
Вздох. Я просто хочу эффективно рисовать массив глифов в соответствующем массиве позиций в представлении.
Есть идеи, что я ошибаюсь?