Почему мои кварцевые дуги отображаются толще прямых? - PullRequest
4 голосов
/ 23 мая 2009

Я пытаюсь создать пользовательскую кнопку UIButton, которая должна выглядеть как UIButtonTypeRoundedRect. В моем drawRect: я создаю путь с первым вызовом CGContextMoveToPoint () и четырьмя вызовами CGContextAddArc (). Затем я прохожу путь. Однако в полученном изображении четыре закругленных угла явно толще, чем остальная часть пути.

Я подозревал, что это как-то связано с сглаживанием, поэтому я попытался отключить его с помощью CGContextSetShouldAntiAlias ​​(), но тогда это выглядело еще хуже. Я также пытался экспериментировать с шириной линии, но дуги всегда толще прямых. UIButtonTypeRoundedRect от Apple выглядит отлично, поэтому должно быть возможно как-то решить. У кого-нибудь есть подсказка?

Редактировать: соответствующий код:

CGContextRef context = UIGraphicsGetCurrentContext();
CGContextBeginPath(context);

CGContextMoveToPoint(context, rect.origin.x + kRoundedRectButtonRadius, rect.origin.y);
CGContextAddArc(context, rect.origin.x + rect.size.width - kRoundedRectButtonRadius, rect.origin.y + kRoundedRectButtonRadius, kRoundedRectButtonRadius, 3 * M_PI_2, 0, NO);
CGContextAddArc(context, rect.origin.x + rect.size.width - kRoundedRectButtonRadius, rect.origin.y + rect.size.height - kRoundedRectButtonRadius, kRoundedRectButtonRadius, 0, M_PI_2, NO);
CGContextAddArc(context, rect.origin.x + kRoundedRectButtonRadius, rect.origin.y + rect.size.height - kRoundedRectButtonRadius, kRoundedRectButtonRadius, M_PI_2, M_PI, NO);
CGContextAddArc(context, rect.origin.x + kRoundedRectButtonRadius, rect.origin.y + kRoundedRectButtonRadius, kRoundedRectButtonRadius, M_PI, 3 * M_PI_2, NO);

CGContextClosePath(context);
CGContextSetLineWidth(context, 1.7);
CGContextStrokePath(context);

1 Ответ

12 голосов
/ 23 мая 2009

Я сталкивался с этим раньше при рисовании пользовательских кнопок. Поведение, которое вы видите, проистекает из того факта, что процедуры рисования какао рисуют линии по центру вокруг позиций пикселей, на которых вы их просите. Позвольте мне объяснить.

Рисованные прямые линии падают на самый край прямоугольника кнопки. Когда вызывается ваша процедура рисования, Какао удобно установить область отсечения для точной границы прямоугольника кнопки, но когда вы просите Какао нарисовать линию вдоль края, ровно половина линии рисуется за пределами отсечения прямоугольник .

Вы заметили разницу в закругленных углах, потому что изогнутая часть полностью попадает в прямоугольник отсечения, поэтому ни одна из них не отсекается.

Теперь для решения:

Давайте предположим, что линии, которые вы рисуете, имеют толщину всего два пикселя. Это будет означать, что один пиксель рисуется внутри прямоугольника отсечения, а другой - снаружи (и поэтому игнорируется). Все, что вам нужно сделать, это нарисовать линии на один пиксель ближе к центру прямоугольника. В случае пользовательской процедуры рисования вы, вероятно, используете:

NSRect myBounds = [self bounds];

А затем вычислите ваши угловые точки оттуда. Insead, используйте:

NSRect myProperBounds = NSInsetRect([self bounds], 1.0, 1.0);

И тебе надо идти.

...