Чертеж NSBezierPath

Я хочу сделать округленный прямоугольник на NSImage, и я решил, что использование NSBezierPath будет лучшим способом. Тем не менее, я столкнулся с проблемой: вместо рисования красивой кривой я получаю следующее:

enter image description here

По причинам, которые я не могу понять, NSBezierPath рисует округлую часть с более темным цветом, чем остальные.

Здесь код, который я использую (внутри drawRect: вызов пользовательского представления):

NSBezierPath* bp = [NSBezierPath bezierPathWithRoundedRect: self.bounds xRadius: 5 yRadius: 5];
[[[NSColor blackColor] colorWithAlphaComponent: 0.5] setStroke];
[bp stroke];

Любые идеи?

Изменить:

Если я вставлю путь на 0.5, все будет отлично. Но почему я получаю это, когда я компенсирую путь на 10 пикселей (например)?

enter image description here

Если я правильно понимаю, он должен также нарисовать тонкую линию...

Ответы

Ответ 1

Многие системы рендеринга получены из модели рисования PostScript. Core Graphics - одна из этих производных систем. (Вот некоторые другие: PDF, SVG, HTML Canvas 2D Контекст, Cairo.)

Все эти системы имеют идею поглаживания пути с линией некоторой фиксированной ширины. Когда вы перемещаете путь, линия пересекает путь: половина ширины линии находится на одной стороне пути, а половина ширины линии находится на другой стороне. Вот диаграмма, которая может сделать это яснее:

path stroke

Теперь, что происходит, когда вы поглаживаете путь, который лежит вдоль границы вашего взгляда? Половина хода выйдет за пределы вашего обзора и будет отсечена - не нарисована. Вы увидите только половину хода, попадающего в рамки обзора.

Когда вы используете закругленный угол, этот угол отходит от границы вида, к его центру, так что больше штриха вокруг угла попадает внутрь границы вида. Таким образом, кажется, что инсульт становится толще вокруг закругленного угла, например:

path stroke clipped

Чтобы исправить это, вам нужно вставить свой путь на половину ширины линии, чтобы весь штрих попал в пределы вашего обзора по всему пути. Ширина линии по умолчанию равна 1.0, поэтому:

NSBezierPath* bp = [NSBezierPath bezierPathWithRoundedRect:
    NSRectInset(self.bounds, 0.5, 0.5) xRadius:5 yRadius:5];