Я хочу взять заполненный прямоугольник и пробить в нем отверстие, используя другую форму. Это именно то, для чего предназначен NSBezierPath
. Вы добавляете прямоугольный путь, затем добавляете подпуть, который будет «пробивать» его и, наконец, заполнить. В моем случае подпуть на самом деле текст. Нет проблем, отлично работает:
За исключением случаев, когда я использую Helvetica Neue Bold для своего шрифта. Когда я использую это, я просто получаю сплошной синий прямоугольник без какого-либо текста. Но подпуть действительно рисует - на самом деле, если я немного уменьшу залитый прямоугольник, вы действительно сможете увидеть часть текстового пути:
У меня такое же поведение с Helvetica Neue Italic. Хорошо работает Helvetica Neue Medium, Helvetica Bold, Times New Roman Bold и Arial Bold.
Я пробовал использовать как NSEvenOddWindingRule
, так и NSNonZeroWindingRule
. ( РЕДАКТИРОВАТЬ : По-видимому, я действительно не пробовал правило NSEvenOddWinding
, потому что оно в конце концов работает)
Это код, который я использую внутри метод drawRect
моего подкласса NSView
.
NSLayoutManager *layoutManger = [[[NSLayoutManager alloc] init] autorelease];
NSTextContainer *textContainer = [[[NSTextContainer alloc]
initWithContainerSize:NSMakeSize(300, 100)] autorelease];
NSFont *font = [NSFont fontWithName:@"Helvetica Neue Bold" size:100];
NSDictionary *textAttribs = [NSDictionary dictionaryWithObjectsAndKeys:
font, NSFontAttributeName, nil];
NSTextStorage *textStorage = [[[NSTextStorage alloc] initWithString:@"Hello"
attributes:textAttribs] autorelease];
[layoutManger addTextContainer:textContainer];
[layoutManger setTextStorage:textStorage];
NSRange glyphRange = [layoutManger glyphRangeForTextContainer:textContainer];
NSGlyph glyphArray[glyphRange.length];
NSUInteger glyphCount = [layoutManger getGlyphs:glyphArray range:glyphRange];
NSBezierPath *path = [NSBezierPath bezierPathWithRect:NSMakeRect(0, 0, 200, 100)];
[path appendBezierPathWithGlyphs:glyphArray count:glyphCount inFont:font];
[[NSColor blueColor] setFill];
[path fill];
Ну и что? здесь происходит? Почему некоторые шрифты ведут себя иначе, чем другие, когда дело доходит до добавления глифов к пути?
EDIT : Решение состоит в использовании NSEvenOddWindingRule
. После создания пути
добавьте следующую строку:
[path setWindingRule:NSEvenOddWindingRule];
Ответ Питера Хози дает объяснение, почему это так.