Хотя могут быть и другие способы, один из способов сделать это состоит в том, чтобы сначала нарисовать строку только штрихом, а затем нарисовать строку только с заливкой, прямо поверх того, что было нарисовано ранее. (Adobe InDesign на самом деле имеет эту встроенную функцию, в которой, как представляется, применяется только штрих к внешней стороне буквы, что помогает с удобочитаемостью).
Это просто примерное представление, показывающее, как этого добиться (вдохновлено http://developer.apple.com/library/mac/#qa/qa2008/qa1531.html):
Сначала настройте атрибуты:
@implementation MDInDesignTextView
static NSMutableDictionary *regularAttributes = nil;
static NSMutableDictionary *indesignBackgroundAttributes = nil;
static NSMutableDictionary *indesignForegroundAttributes = nil;
- (void)drawRect:(NSRect)frame {
NSString *string = @"Got stroke?";
if (regularAttributes == nil) {
regularAttributes = [[NSMutableDictionary
dictionaryWithObjectsAndKeys:
[NSFont systemFontOfSize:64.0],NSFontAttributeName,
[NSColor whiteColor],NSForegroundColorAttributeName,
[NSNumber numberWithFloat:-5.0],NSStrokeWidthAttributeName,
[NSColor blackColor],NSStrokeColorAttributeName, nil] retain];
}
if (indesignBackgroundAttributes == nil) {
indesignBackgroundAttributes = [[NSMutableDictionary
dictionaryWithObjectsAndKeys:
[NSFont systemFontOfSize:64.0],NSFontAttributeName,
[NSNumber numberWithFloat:-5.0],NSStrokeWidthAttributeName,
[NSColor blackColor],NSStrokeColorAttributeName, nil] retain];
}
if (indesignForegroundAttributes == nil) {
indesignForegroundAttributes = [[NSMutableDictionary
dictionaryWithObjectsAndKeys:
[NSFont systemFontOfSize:64.0],NSFontAttributeName,
[NSColor whiteColor],NSForegroundColorAttributeName, nil] retain];
}
[[NSColor grayColor] set];
[NSBezierPath fillRect:frame];
// draw top string
[string drawAtPoint:
NSMakePoint(frame.origin.x + 200.0, frame.origin.y + 200.0)
withAttributes:regularAttributes];
// draw bottom string in two passes
[string drawAtPoint:
NSMakePoint(frame.origin.x + 200.0, frame.origin.y + 140.0)
withAttributes:indesignBackgroundAttributes];
[string drawAtPoint:
NSMakePoint(frame.origin.x + 200.0, frame.origin.y + 140.0)
withAttributes:indesignForegroundAttributes];
}
@end
Это дает следующий вывод:
Теперь, это не идеально, поскольку глифы иногда попадают на дробные границы, но, безусловно, выглядит лучше, чем по умолчанию.
Если производительность является проблемой, вы всегда можете посмотреть на более низкий уровень, такой как CoreGraphics или CoreText.