Пути

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

Следующие разделы фокусируются прежде всего на использовании NSBezierPath класс, обеспечивающий основной интерфейс для создания и управления путями. Какао также обеспечивает ряд функций, предлагающих подобное поведение для создания и рисования путей, но не требующих издержек создания объекта. Те функции упоминаются, где это необходимо, но для получения дополнительной информации, видят Ссылку Платформы Ссылки и AppKit Платформы Основы.

Соедините стандартные блоки каналом

Какао определяет несколько основополагающих типов данных для управления геометрическими данными в среде получения. Эти типы данных включают NSPoint, NSRect, и NSSize. Вы используете эти типы данных для указания строк, прямоугольников и информации о ширине и высоте для форм, которые Вы хотите нарисовать. Все от строк и прямоугольников к кругам, дугам и Кривым Безье может быть указано с помощью один или больше этих структур данных.

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

NSPoint, NSRect, и NSSize типы данных имеют эквиваленты в Кварцевой среде: CGPoint, CGRect, и CGSize. Поскольку расположение типов Какао и Кварца идентично, можно преобразовать между двумя типами путем кастинга от одного типа до его дубликата.

Класс NSBezierPath

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

Элементы пути

NSBezierPath возразите элементам пути использования для создания пути. Элемент пути состоит из примитивной команды и одной или более точек. Команда говорит объект контуров, как интерпретировать связанные точки. Когда собрано, ряд элементов пути создает ряд линейных сегментов, формирующих желаемую форму.

NSBezierPath класс обрабатывает большую часть работы создания и организации элементов пути первоначально. Знание, как управлять элементами пути, становится важным, однако, если Вы хотите внести изменения в существующий путь. При создании сложного контура на основе ввода данных пользователем Вы могли бы хотеть дать пользователю опцию изменения того пути позже. Несмотря на то, что Вы могли создать новый объект контуров с изменениями, намного более просто изменить существующие элементы пути. (Для получения информации о том, как изменить элементы пути, посмотрите Элементы Отдельного тракта Управления.)

NSBezierPath класс определяет только четыре основных команды элемента пути, перечисленные в Таблице 8-1. Этих команд достаточно для определения всех возможных форм контура. Каждая команда имеет одну или более точек, содержащих информацию, должен был расположить элемент пути. Большинство элементов пути использует текущую точку получения в качестве начальной точки для рисования.

Табличные 8-1  команды элемента Пути

Команда

Число очков

Описание

NSMoveToBezierPathElement

1

Перемещает текущую точку получения объекта контуров к указанной точке. Этот элемент пути не приводит ни к какому получению. Используя эту команду посреди пути приводит к разъединенному линейному сегменту.

NSLineToBezierPathElement

1

Создает прямую линию от текущей точки получения до указанной точки. Строки и прямоугольники указаны с помощью этого элемента пути.

NSCurveToBezierPathElement

3

Создает изогнутый сегмент линии от текущей точки до указанной конечной точки с помощью двух контрольных точек для определения кривой. Точки сохранены в следующем порядке: controlPoint1, controlPoint2, endPoint. Овалы, дуги и Кривые Безье все элементы кривой использования для указания их геометрии.

NSClosePathBezierPathElement

1

Отмечает конец текущего подпути в указанной точке. (Обратите внимание на то, что точка, указанная для элемента Замкнутого контура, является по существу тем же как текущей точкой.

Когда Вы добавляете новую форму к пути, NSBezierPath разламывает ту форму на один или несколько элементов пути компонента в целях хранения. Например, вызов moveToPoint: или lineToPoint: создает Перемещение К элементу или Строку К элементу соответственно. В случае более сложных форм, как прямоугольники и овалы, могут быть созданы несколько строк или элементов кривой. Рисунок 8-1 показывает две формы и получающиеся элементы пути. Для изогнутого сегмента данные также показывают контрольные точки, определяющие кривую.

  Элементы Пути рисунка 8-1 для сложного контура
Path elements for a complex path

Перечисление 8-1 показывает код, создающий путь, показанный на рисунке 8-1.

Перечисление 8-1  , Создающее сложный контур

NSBezierPath* aPath = [NSBezierPath bezierPath];
 
[aPath moveToPoint:NSMakePoint(0.0, 0.0)];
[aPath lineToPoint:NSMakePoint(10.0, 10.0)];
[aPath curveToPoint:NSMakePoint(18.0, 21.0)
        controlPoint1:NSMakePoint(6.0, 2.0)
        controlPoint2:NSMakePoint(28.0, 10.0)];
 
[aPath appendBezierPathWithRect:NSMakeRect(2.0, 16.0, 8.0, 5.0)];

Подпути

Подпуть является серией связанной строки и сегментов кривой в NSBezierPath объект. Единственный объект контуров может содержать многократные подпути с каждым подпутем, очерченным Перемещением К или элементом Замкнутого контура. Когда Вы устанавливаете начальную точку получения (обычно использующий moveToPoint: метод), Вы устанавливаете начальную точку первого подпути. Как Вы рисуете, Вы создаете содержание подпути до Вас любое завершение путь (использующий closePath метод), или добавляют другое Перемещение К элементу. В той точке подпуть считают закрытым, и любые новые элементы добавляются к новому подпути.

Некоторые методы NSBezierPath автоматически создайте новый подпуть для Вас. Например, создавая прямоугольник или овальные результаты в добавлении Перемещения К элементу, нескольким элементам получения, и Замкнутому контуру и Перемещению К элементу (см. рисунок 8-1 для примера). Перемещение К элементу в конце списка элементов гарантирует, что текущую точку получения оставляют в известном расположении, которое в этом случае является в точке источника прямоугольника.

Подпути существуют, чтобы помочь Вам отличить различные части объекта контуров. Например, подпути влияют на способ, которым путь заполнен; см. Вьющиеся Правила. Подразделение пути в подпути также влияет на методы такой как bezierPathByReversingPath, который инвертирует подпути по одному. В других случаях, тем не менее, подсоединяет каналом в NSBezierPath возразите совместно используют те же атрибуты получения.

Атрибуты пути

NSBezierPath объект поддерживает все атрибуты, должен был определить форму его пути. Эти атрибуты включают ширину строки, плоскость кривой, стиль окончания линии, стиль соединения строки и предельный угол стыка пути. Вы устанавливаете эти значения с помощью методов NSBezierPath.

Атрибуты пути не вступают в силу, пока Вы не заполняете или перечеркиваете путь, поэтому при изменении атрибута несколько раз прежде, чем нарисовать путь только последнее значение используется. NSBezierPath класс поддерживает и пользовательскую и версию по умолчанию каждого атрибута. Объекты контуров используют значения пользовательского атрибута, если они установлены. Если никакое значение пользовательского атрибута не установлено для данного объекта контуров, значение по умолчанию используется. NSBezierPath класс не использует Кварцевые функции использования набора значений атрибута пути.

Следующие разделы описывают атрибуты, которые можно установить для объекта контуров и как те атрибуты влияют представленные пути.

Ширина строки

Атрибут ширины строки управляет шириной всего пути. Ширина строки измерена в точках и указана как значение с плавающей точкой. Ширина по умолчанию для всех строк равняется 1. Изменить ширину строки по умолчанию для всех NSBezierPath объекты, Вы используете setDefaultLineWidth: метод. Для установки ширины строки для текущего объекта контуров Вы используете setLineWidth: метод того объекта контуров. Установить ширину строки по умолчанию для форм, представленных без NSBezierPath объект, необходимо использовать CGContextSetLineWidth функция в Кварце.

Дробные ширины строки представляются максимально близко к указанной ширине согласно ограничениям устройства назначения, позиции строки и текущей настройке сглаживания. Например, предположите, что Вы хотите чертить линию, чья ширина является 0,2 точками. Умножение этой ширины точками 1/72 на дюйм приводит к строке, которая 0,0027778 дюйма шириной. На экране на 90 точек на дюйм самая маленькая строка была бы 1 пиксель шириной или 0,0111 дюйма. Гарантировать Вашу строку не скрыто на экране, Какао номинально рисует его в большей минимальной ширине экрана (0,0111 дюйма). В действительности, если строка одновременно покупает и продает границу пикселей, или сглаживание включено, строка могла бы влиять на дополнительные пиксели по обе стороны от пути. Если бы устройство вывода было принтером на 600 точек на дюйм то вместо этого, Кварц был бы в состоянии представить строку ближе к ее истинной ширине 0,0027778 дюймов.

Перечисление 8-2 рисует несколько путей с помощью различных методов. NSFrameRect функционируйте использует ширину строки по умолчанию для рисования прямоугольника, так, чтобы значение было установлено до вызывания функции. Объекты контуров используют значение по умолчанию, только если не было установлено пользовательское значение. Можно даже изменить ширину строки объекта контуров и нарисовать снова для достижения различной ширины пути, несмотря на то, что необходимо было бы также переместить путь для наблюдения различия.

Перечисление 8-2  , Устанавливающее ширину строки пути

// Draw a rectangle using the default line width: 2.0.
[NSBezierPath setDefaultLineWidth:2.0];
NSFrameRect(NSMakeRect(20.0, 20.0, 10.0, 10.0));
 
// Set the line width for a single NSBezierPath object.
NSBezierPath* thePath = [NSBezierPath bezierPath];
[thePath setLineWidth:1.0]; // Has no effect.
[thePath moveToPoint:NSMakePoint(0.0, 0.0)];
[thePath lineToPoint:NSMakePoint(10.0, 0.0)];
[thePath setLineWidth:3.0];
[thePath lineToPoint:NSMakePoint(10.0, 10.0)];
 
// Because the last value set is 3.0, all lines are drawn with
// a width of 3.0, not just the second line.
[thePath stroke];
 
// Changing the width and stroking again draws the same path
// using the new line width.
[thePath setLineWidth:4.0];
[thePath stroke];
 
// Changing the default line width has no effect because a custom
// value already exists. The path is rendered with a width of 4.0.
[thePath setDefaultLineWidth:5.0];
[thePath stroke];

Стили окончания линии

Текущий стиль окончания линии определяет появление открытых точек сегмента контура. Какао поддерживает стили окончания линии, показанные на рисунке 8-2.

  Стили Окончания линии рисунка 8-2
Line cap styles

Установить стиль окончания линии для a NSBezierPath объект, используйте setLineCapStyle: метод. Стиль окончания линии по умолчанию установлен в NSButtLineCapStyle. Для изменения стиля окончания линии по умолчанию используйте setDefaultLineCapStyle: метод. Перечисление 8-3 демонстрирует оба из этих методов:

Перечисление 8-3  , Устанавливающее стиль окончания линии пути

[// Set the default line cap style
[NSBezierPath setDefaultLineCapStyle:NSButtLineCapStyle];
 
// Customize the line cap style for the new object.
NSBezierPath* aPath = [NSBezierPath bezierPath];
[aPath moveToPoint:NSMakePoint(0.0, 0.0)];
[aPath lineToPoint:NSMakePoint(10.0, 10.0)];
[aPath setLineCapStyle:NSSquareLineCapStyle];
[aPath stroke];

Стили соединения строки

Текущий стиль соединения строки определяет, как к связанным строкам по пути присоединяются в вершинах. Какао поддерживает стили соединения строки, показанные на рисунке 8-3.

  Стили соединения Строки рисунка 8-3
Line join styles

Установить стиль соединения строки для NSBezierPath объект, используйте setLineJoinStyle: метод. Стиль соединения строки по умолчанию установлен в NSMiterLineJoinStyle. Для изменения стиля соединения строки по умолчанию используйте setDefaultLineJoinStyle: метод. Перечисление 8-4 демонстрирует оба из этих методов:

Перечисление 8-4  , Устанавливающее стиль соединения строки пути

[// Set the default line join style
[NSBezierPath setDefaultLineJoinStyle:NSMiterLineJoinStyle];
 
// Customize the line join style for a new path.
NSBezierPath* aPath = [NSBezierPath bezierPath];
[aPath moveToPoint:NSMakePoint(0.0, 0.0)];
[aPath lineToPoint:NSMakePoint(10.0, 10.0)];
[aPath lineToPoint:NSMakePoint(10.0, 0.0)];
[aPath setLineJoinStyle:NSRoundLineJoinStyle];
[aPath stroke];

Стиль тире строки

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

Рисунок 8-4 показывает, что некоторые демонстрационные пунктирные узоры строки, вместе со значениями раньше создавали каждый образец.

  Пунктирные узоры Строки рисунка 8-4
Line dash patterns

NSBezierPath класс не поддерживает понятие стиля тире строки по умолчанию. Если Вы хотите стиль тире строки, необходимо применить его к пути явно с помощью setLineDash:count:phase: метод как показано в Перечислении 8-5, представляющем последний образец от предыдущей фигуры.

Перечисление 8-5  , Добавляющее тире, разрабатывает к пути

void AddDashStyleToPath(NSBezierPath* thePath)
{
    // Set the line dash pattern.
    float lineDash[6];
 
    lineDash[0] = 40.0;
    lineDash[1] = 12.0;
    lineDash[2] = 8.0;
    lineDash[3] = 12.0;
    lineDash[4] = 8.0;
    lineDash[5] = 12.0;
 
   [thePath setLineDash:lineDash count:6 phase:0.0];
}

Плоскость строки

Атрибут плоскости строки определяет точность рендеринга для изогнутых сегментов. Значение плоскости измеряет допуск максимальной погрешности (в пикселях) для использования во время рендеринга. Меньшие значения приводят к более гладким кривым, но требуют большего количества времени вычисления. Большие значения приводят к более зубчатым кривым, но представляются намного быстрее.

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

Рисунок 8-5 показывает, как изменение плоскости по умолчанию влияет на кривые поверхности. Данные слева показывают группу кривых поверхностей, представленных с набором значений плоскости к 0.6 (его значение по умолчанию). Данные справа показывают те же кривые поверхности, представленные с набором значений плоскости к 20. Искривление каждой поверхности потеряно и теперь, кажется, ряд связанных линейных сегментов.

  Эффекты Плоскости рисунка 8-5 на кривые
Flatness effects on curves

Установить плоскость для определенного NSBezierPath объект, используйте setFlatness: метод. Для установки значения плоскости по умолчанию использовать setDefaultFlatness:, как показано в Перечислении 8-6:

Перечисление 8-6  , Устанавливающее плоскость пути

[- (void) drawRect:(NSRect)rect
{
    if ([self inLiveResize])
    {
        // Adjust the default flatness upward to reduce
        // the number of required computations.
        [NSBezierPath setDefaultFlatness:10.0];
 
        // Draw live resize content.
    }
    // ...
 
}

Предельные углы стыка

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

Рисунок 8-6 показывает пример того, как различные предельные углы стыка влияют на тот же путь. Этот путь состоит из нескольких широких строк с 10 точками, соединенных соединениями среза. В числе слева, предельный угол стыка установлен в 5. Поскольку длины среза превышают предельный угол стыка, соединения строки изменяются для скашивания соединений. Путем увеличения предельного угла стыка до 16, как показано в числе справа, соединения среза восстанавливаются, но расширяются далеко вне точки, где встречаются эти две строки.

  Эффекты Предельного угла стыка рисунка 8-6
Miter limit effects

Установить предельные углы стыка для определенного NSBezierPath объект, используйте setMiterLimit: метод. Установить предельный угол стыка по умолчанию для недавно создаваемого NSBezierPath объекты, использовать setDefaultMiterLimit:. Перечисление 8-7 демонстрирует оба из этих методов:

Перечисление 8-7  , Устанавливающее предельный угол стыка для пути

// Increase the default limit
[NSBezierPath setDefaultMiterLimit:20.0];
 
// Customize the limit for a specific path with sharp angles.
NSBezierPath* aPath = [NSBezierPath bezierPath];
[aPath moveToPoint:NSMakePoint(0.0, 0.0)];
[aPath lineToPoint:NSMakePoint(8.0, 100.0)];
[aPath lineToPoint:NSMakePoint(16.0, 0.0)];
[aPath setLineWidth:5.0];
[aPath setMiterLimit:5.0];
[aPath stroke];

Проветривание правил

Когда Вы заполняете область, охваченную путем, NSBezierPath применяет правило токовой обмотки определить который области экрана заполниться. Вьющееся правило является просто алгоритмом, отслеживающим информацию о каждой непрерывной области, составляющей полную закрашенную область пути. Луч нарисован из точки в данной области к любой точке вне границ пути. Общее количество пересеченных строк пути (включая неявные строки) и направление каждой строки пути тогда интерпретируется с помощью правил в Таблице 8-2, определяющих, должна ли область быть заполнена.

Табличные 8-2  правила Проветривания

Проветривание правила

Описание

NSNonZeroWindingRule

Рассчитайте каждый слева направо соединяет каналом как +1, и каждый справа налево соединяет каналом как-1. Если сумма всех пересечений 0, точка вне пути. Если сумма является ненулевой, точка в пути, и область, содержащая его, заполнена. Это - правило проветривания значения по умолчанию.

NSEvenOddWindingRule

Считайте общее количество пересечений пути. Если число пересечений даже, точка вне пути. Если число пересечений нечетно, точка в пути, и область, содержащая его, должна быть заполнена.

Операции заполнения подходят для использования и с открытыми и с закрытыми подпутями. Закрытый подпуть является последовательностью рисования вызовов, который заканчивается элементом пути Замкнутого контура. Открытый подпуть заканчивается Перемещением Для соединения каналом элемента. Когда Вы заполняете частичный подпуть, NSBezierPath завершения это для Вас автоматически путем создания неявной (непредставленной) строки сначала к последней точке подпути.

Рисунок 8-7 показывает, как вьющиеся правила применяются к определенному пути. Подчисло a показывает, что путь представил использование ненулевого правила и подчисла b показывает, что это представило использование ровно-нечетного правила. Подчисла c и d добавьте метки направления и скрытую строку пути, закрывающую число, чтобы помочь Вам видеть, как правила применяются к двум из областей пути.

Рисунок 8-7  , Применяющий вьющиеся правила к пути
Applying winding rules to a path

Устанавливать вьющееся правило для NSBezierPath объект, используйте setWindingRule: метод. Правило проветривания значения по умолчанию NSNonZeroWindingRule. Изменить правило проветривания значения по умолчанию для всех NSBezierPath объекты, используйте setDefaultWindingRule: метод.

Управление геометрическими типами

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

Таблица 8-3 перечисляет некоторые более обычно используемые функции и их способы поведения. Синтаксис функций предоставлен в краткой нотации с типами параметра, опущенными для демонстрации соглашения о вызовах. Для полного списка доступных функций и их полного синтаксиса, посмотрите раздел Functions в Ссылке Платформы Основы.

Таблица 8-3  Обычно использовала функции геометрии

Работа

Функция

Описание

Создание

NSPoint NSMakePoint(x, y)

Возвращается должным образом отформатированный NSPoint структура данных с указанными значениями x и y.

NSSize NSMakeSize(w, h)

Возвращается должным образом отформатированный NSSize структура данных с указанной шириной и высотой.

NSRect NSMakeRect(x, y, w, h)

Возвращается должным образом отформатированный NSRect структура данных с указанным источником (x, y) и размер (ширина, высота).

Равенство

BOOL NSEqualPoints(p1, p2)

Возвраты YES если две точки являются тем же.

BOOL NSEqualSizes(s1, s2)

Возвраты YES если два типа размера имеют идентичные ширины и высоты.

BOOL NSEqualRects(r1, r2)

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

Прямоугольные манипуляции

BOOL NSContainsRect(r1, r2)

Возвраты YES если прямоугольник 1 полностью включает прямоугольник 2.

NSRect NSInsetRect(r, dX, dY)

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

NSRect NSIntersectionRect(r1, r2)

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

NSRect NSUnionRect(r1, r2)

Возвращает объединение этих двух прямоугольников.

BOOL NSMouseInRect(p, r, flipped)

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

BOOL NSPointInRect(p, r)

Тесты, находится ли точка в указанном прямоугольнике. Это - основное математическое сравнение.

Рисование фундаментальных форм

Поскольку много типов довольных, находящегося на пути получения имеют несколько преимуществ перед основанным на изображении получением:

Следующие разделы предоставляют информацию о примитивных формах, можно нарисовать пути использования. Можно объединиться один или больше этих форм, чтобы создать более сложный контур и затем перечеркнуть или заполнить путь, как описано в Рисовании Форм по Пути. Для некоторых форм может быть больше чем один способ добавить форму к пути, или могут быть альтернативные способы сразу нарисовать форму. Везде, где возможно, преимущества и недостатки каждого метода перечислены, чтобы помочь Вам решить, какой метод является самым надлежащим в особых ситуациях.

Добавление точек

NSPoint структура отдельно представляет расположение на экране; это не имеет никакого веса и не может быть нарисовано как таковое. Для рисования эквивалента точки на экране необходимо было бы создать маленький прямоугольник в желаемом расположении, как показано в Перечислении 8-8.

Перечисление 8-8  , Получающее точку

void DrawPoint(NSPoint aPoint)
{
    NSRect aRect = NSMakeRect(aPoint.x, aPoint.y, 1.0, 1.0);
 
    NSRectFill(aRect);
}

Конечно, больше общего использования для точек должно указать позицию других форм. Много форм требуют, чтобы Вы указали текущую точку прежде фактически создать форму. Вы устанавливаете текущую точку с помощью moveToPoint: или relativeMoveToPoint: методы. Некоторые формы, как прямоугольники и овалы, уже содержат информацию о расположении и не требуют отдельного вызова к moveToPoint:.

Добавление строк и многоугольников

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

  • Создайте единственные горизонтальные и вертикальные строки путем заполнения прямоугольного использования NSRectFill. Этот метод менее точен, но часто немного быстрее, чем создание NSBezierPath объект. Для создания диагональных строк с помощью этого метода необходимо применяться, вращение преобразовывают перед получением. Этот метод не является подходящим для создания связанных линейных сегментов.

  • Используйте lineToPoint:, relativeLineToPoint:, или strokeLineFromPoint:toPoint: методы NSBezierPath создать отдельные или связанные линейные сегменты. Этот метод быстр и является самой точной опцией для создания строк и сложных многоугольников.

  • Используйте appendBezierPathWithPoints:count: метод для создания серии связанных строк быстро. Этот метод быстрее, чем добавление отдельных строк.

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

Перечисление 8-9 показывает код для рисования использования параллелограма NSBezierPath. Метод в этом примере наносит параллелограм в указанном прямоугольнике. withShift параметр указывает, что горизонтальный сдвиг применился к верхнему левому и правым нижним углам прямоугольной области.

Перечисление 8-9  Используя строки для рисования многоугольника

void DrawParallelogramInRect(NSRect rect, float withShift)
{
    NSBezierPath* thePath = [NSBezierPath bezierPath];
 
    [thePath moveToPoint:rect.origin];
    [thePath lineToPoint:NSMakePoint(rect.origin.x + withShift,  NSMaxY(rect))];
    [thePath lineToPoint:NSMakePoint(NSMaxX(rect), NSMaxY(rect))];
    [thePath lineToPoint:NSMakePoint(NSMaxX(rect) - withShift,  rect.origin.y)];
    [thePath closePath];
 
    [thePath stroke];
}

Добавление прямоугольников

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

  • Используйте методы NSBezierPath создать Ваш прямоугольник. Следующие методы довольно быстры и предлагают лучшую точность:

  • Создайте прямоугольники с помощью функций Какао, описанных в Рисовании Прямоугольников. Эти функции рисуют прямоугольники быстрее, чем, но с меньшей точностью, чем, методы NSBezierPath.

  • Создайте прямоугольник с помощью отдельных строк, как описано в Добавляющих Строках и Многоугольниках. Вы могли использовать этот метод для создания по диагонали ориентированных прямоугольников — т.е. прямоугольники, стороны которых не параллельны осям x и y — не используя вращение, преобразовывают.

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

Перечисление 8-10  , Получающее прямоугольник

void DrawRectangle(NSRect aRect)
{
    NSRectFill(aRect);
    [NSBezierPath strokeRect:aRect];
}

Добавление скругленных прямоугольников

В OS X v10.5 и позже, NSBezierPath класс включает следующие методы для создания скругленных прямоугольников:

Эти методы создают прямоугольники, углы которых изогнуты согласно указанным значениям радиуса. Радиусы описывают ширину и высоту овала для использования в каждом углу прямоугольника. Рисунок 8-8 показывает, как этот нанесенный овал используется для определения пути угловых сегментов прямоугольника.

Рисунок 8-8  , Наносящий угол скругленного прямоугольника
Inscribing the corner of a rounded rectangle

Перечисление 8-11 показывает фрагмент кода, создающий и рисующий путь со скругленным прямоугольником.

Перечисление 8-11  , Получающее скругленный прямоугольник

void DrawRoundedRect(NSRect rect, CGFloat x, CGFloat y)
{
    NSBezierPath* thePath = [NSBezierPath bezierPath];
 
    [thePath appendBezierPathWithRoundedRect:rect xRadius:x yRadius:y];
    [thePath stroke];
}

Добавление овалов и кругов

Для рисования овалов и кругов используйте следующие методы NSBezierPath:

Оба метода наносят овальную внутреннюю часть прямоугольник, который Вы указываете. Необходимо тогда заполнить или перечеркнуть объект контуров для рисования овала в текущем контексте. Следующий пример создает овал из указанного прямоугольника и перечеркивает его путь.

void DrawOvalInRect(NSRect ovalRect)
{
    NSBezierPath* thePath = [NSBezierPath bezierPath];
 
    [thePath appendBezierPathWithOvalInRect:ovalRect];
    [thePath stroke];
}

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

Добавление дуг

Для рисования дуг используйте следующие методы NSBezierPath:

appendBezierPathWithArcFromPoint:toPoint:radius: метод создает дуги путем нанесения их в углу, сформированном текущей точкой, и две точки передали методу. Нанесение круга этим способом может привести к дуге, не пересекающейся, любая из точек раньше указывала его. Это может также привести к созданию нежелательной строки от текущей точки до начальной точки дуги.

Рисунок 8-9 показывает три различных дуги, и контрольные точки раньше создавали их. Поскольку две дуги создали использование appendBezierPathWithArcFromPoint:toPoint:radius:, текущая точка должна быть установлена прежде, чем вызвать метод. В обоих примерах точка установлена в (30, 30). Поскольку радиус второй дуги короче, и начальная точка дуги не является тем же как текущей точкой, линия проведена от текущей точки до начальной точки.

  Дуги Создания рисунка 8-9
Creating arcs

Перечисление 8-12 показывает фрагменты кода, которые Вы использовали бы для создания каждой из дуг от рисунка 8-9. (Несмотря на то, что данные показывают, что дуги индивидуально, выполняя следующий код представили бы дуги друг на друге.)

Перечисление 8-12  , Создающее три дуги

NSBezierPath*   arcPath1 = [NSBezierPath bezierPath];
NSBezierPath*   arcPath2 = [NSBezierPath bezierPath];
 
[[NSColor blackColor] setStroke];
 
// Create the first arc
[arcPath1 moveToPoint:NSMakePoint(30,30)];
[arcPath1 appendBezierPathWithArcFromPoint:NSMakePoint(0,30)  toPoint:NSMakePoint(0,60) radius:30];
[arcPath1 stroke];
 
// Create the second arc.
[arcPath2 moveToPoint:NSMakePoint(30,30)];
[arcPath2 appendBezierPathWithArcFromPoint:NSMakePoint(30,40)  toPoint:NSMakePoint(70,30) radius:20];
[arcPath2 stroke];
 
// Clear the old arc and do not set an initial point, which prevents a
// line being drawn from the current point to the start of the arc.
[arcPath2 removeAllPoints];
[arcPath2 appendBezierPathWithArcWithCenter:NSMakePoint(30,30) radius:30  startAngle:45 endAngle:135];
[arcPath2 stroke];

Добавление кривых Безье

Для рисования Кривых Безье необходимо использовать curveToPoint:controlPoint1:controlPoint2: метод NSBezierPath. Этот метод поддерживает создание кубической кривой от текущей точки до пункта назначения, который Вы указываете при вызове метода. controlPoint1 параметр определяет искривление, запускающееся с текущей точки, и controlPoint2 определяет искривление пункта назначения, как показано на рисунке 8-1.

  Кубическая кривая Безье рисунка 8-10
Cubic Bezier curve

Добавление текста

Поскольку NSBezierPath только поддерживает находящееся на пути содержание, Вы не можете добавить текстовые символы непосредственно к пути; вместо этого, необходимо добавить глифы. Глиф является визуальным представлением символа (или неполный символ) в определенном шрифте. Для глифов в контурном шрифте это визуальное представление сохранено как ряд математических путей, которые могут быть добавлены к NSBezierPath объект.

Для получения ряда глифов можно использовать текстовую систему Какао или NSFont класс. Получение глифов от текстовой системы Какао обычно проще, потому что можно получить глифы для произвольной строки символов, тогда как использование NSFont требует, чтобы Вы знали имена отдельных глифов. Для получения глифов от текстовой системы Какао необходимо сделать следующее:

  1. Создайте текстовые системные объекты, должен был управлять текстовым расположением.

  2. Используйте glyphAtIndex: или getGlyphs:range: метод NSLayoutManager получать желаемые глифы.

  3. Добавьте глифы к Вашему NSBezierPath объект с помощью одного из следующих методов:

Когда добавлено к Вашему NSBezierPath объект, глифы преобразовываются в серию элементов пути. Эти элементы пути просто указывают строки и кривые и не сохраняют информации о самих символах. Можно управлять путями, содержащими глифы точно так же, как Вы были бы любой другой путь путем изменения точек элемента пути или путем изменения атрибутов пути.

Рисование форм по пути

Существует две опции для рисования содержания пути: можно перечеркнуть путь или заполнить его. Перечеркивание пути представляет схему формы пути с помощью текущего цвета обводки и атрибутов пути. Заполнение пути представляет область, охваченную путем с помощью текущего цвета заливки и проветривая правило.

Рисунок 8-11 показывает тот же путь от рисунка 8-1, но с заполненным содержанием и различная штриховая примененная ширина.

  Перечеркивание рисунка 8-11 и заполнение пути.
Stroking and filling a path.

Рисование прямоугольников

Какао обеспечивает несколько функций для рисования прямоугольников к текущему контексту сразу с помощью атрибутов по умолчанию. Эти функции используют Кварцевые примитивы для рисования одного или более прямоугольников быстро, но в пути, который может быть менее точным, чем если бы необходимо было использовать NSBezierPath. Например, эти подпрограммы не применяют текущий стиль соединения к углам обрамленного прямоугольника.

Таблица 8-4 перечисляет некоторые более обычно используемые функции для рисования прямоугольников вместе с их способами поведения. Можно использовать эти функции в местах, где скорость более важна, чем точность. Синтаксис для каждой функции предоставлен в краткой нотации с типами параметра, опущенными для демонстрации соглашений о вызовах. Для полного списка доступных функций и их полного синтаксиса, посмотрите Ссылку Функций AppKit.

Табличный 8-4  Прямоугольный фрейм и функции заливки

Функция

Описание

void NSEraseRect(aRect)

Заполняет указанный прямоугольник белым.

void NSFrameRect(aRect)

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

void NSFrameRectWithWidth(aRect, width)

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

void NSFrameRectWithWidthUsingOperation(aRect, width, op)

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

void NSRectFill(aRect)

Заполняет прямоугольник с помощью текущего цвета заливки и NSCompositeCopy составление композита работы.

void NSRectFillUsingOperation(aRect, op)

Заполняет прямоугольник с помощью текущего цвета заливки и указанной составляющей композит работы.

void NSRectFillList(rectList, count)

Заполняет массив C-стиля прямоугольников с помощью текущего цвета заливки и NSCompositeCopy составление композита работы.

void NSRectFillListWithColors(rects, colors, count)

Заполняет массив C-стиля прямоугольников с помощью соответствующего списка цветов. Каждый список должен иметь то же число записей.

void NSRectFillListUsingOperation(rects, count, op)

Заполняет массив C-стиля прямоугольников с помощью текущего цвета заливки и указанной работы составления композита.

void NSRectFillListWithColorsUsingOperation(rects, colors, count, op)

Заполняет массив C-стиля прямоугольников с помощью соответствующего списка цветов и указанной работы составления композита. Список прямоугольников и список цветов должны содержать то же число элементов.

Работа с путями

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

Создание путей

Создание пути включает создание NSBezierPath возразите и добавляющий элементы пути к нему. Все пути должны начать с Перемещения К элементу отмечать первую точку пути. В некоторых случаях этот элемент добавляется для Вас, но в других необходимо добавить его сами. Например, методы, создающие замкнутый путь (такой как овал или прямоугольник) вставляют элемент MoveTo для Вас.

Сингл NSBezierPath объект может иметь многократные подпути. Каждый подпуть является самостоятельно полным путем, означая, что подпуть может не казаться связанным ни с какими другими подпутями, когда нарисовано. Заполненные подпути могут все еще взаимодействовать друг с другом, как бы то ни было. Наложение подпутей может отменить эффект заливки друг друга, приводящий к дырам в закрашенной области.

Все подпути в NSBezierPath возразите совместно используют те же атрибуты получения. Единственный способ присвоить различные атрибуты различным путям состоит в том, чтобы создать отличающийся NSBezierPath объекты для каждого.

Улучшение производительности рендеринга

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

Снова используйте свои объекты контуров

Если Вы неоднократно рисуете то же содержание, полагаете, что кэширование объектов раньше рисовало то содержание. Обычно более эффективно сохранить существующее NSBezierPath объект, чем воссоздать его во время каждого цикла получения. Для содержания, которое могло бы измениться динамично, Вы могли бы также рассмотреть поддержание пула допускающих повторное использование объектов.

Правильность по сравнению с эффективностью

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

  • Используйте доступные прямоугольники обновления для рисования только, что изменилось. Используйте отличающийся NSBezierPath объекты для каждой части экрана, а не одного большого объекта, покрывающего все. Для получения дополнительной информации посмотрите, Сокращают Сложность Пути.

  • Во время прокрутки живое изменение размеров или другие строго ограниченные во времени операции, рассматривает следующие опции:

    • Если Ваш экран содержит анимированный контент, приостановите анимацию, пока работа не завершена.

    • Попытка, временно увеличивающая стоимость плоскости для изогнутых контуров. Значение плоскости по умолчанию установлено в 0,6, который приводит к хорошим плавным кривым. Увеличивание этой стоимости выше 1.0 может заставить Ваши кривые выглядеть более зубчатыми, но должно улучшить производительность. Можно хотеть попробовать несколько различных значений для определения хорошего компромисса между появлением и скоростью.

    • Отключите сглаживание. Для получения дополнительной информации посмотрите Установку параметров сглаживания.

  • При рисовании прямоугольников использовать NSFrameRect и NSRectFill для операций, где не требуется высшее качество. Эти функции предлагают близкие приближения тому, с чем Вы добрались бы NSBezierPath но часто немного быстрее.

Сократите сложность пути

При рисовании большой суммы содержания необходимо приложить все усилия для сокращения сложности данных пути, которые Вы храните на сингле NSBezierPath объект. Объекты контуров с сотнями элементов пути требуют большего количества вычислений, чем те с 10 или 20 элементами. Каждый линейный сегмент или сегмент кривой, который Вы добавляете, увеличивают число вычислений, требуемых сгладить путь или определить, является ли точка в нем. Многочисленные пересечения пути также увеличивают число требуемых вычислений при заполнении пути.

Если точность представленных путей не крайне важна, попытайтесь использовать многократный NSBezierPath объекты нарисовать то же содержание. Существует очень мало визуального различия между использованием одного объекта контуров или объектов разнообразного пути. Если Ваш путь уже сгруппирован в многократные подпути, то становится просто вставить некоторые из тех подпутей другой NSBezierPath объекты. Используя разнообразный путь объекты сокращают количество вычислений для каждого подпути и также позволяют Вам ограничивать рендеринг только теми путями, которые находятся в текущем прямоугольнике обновления.

Управление элементами отдельного тракта

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

elementCount метод NSBezierPath возвращает общее количество элементов пути для всех подпутей объекта. Для обнаружения типа данного элемента пути используйте elementAtIndex: или elementAtIndex:associatedPoints: метод. Эти методы возвращают одно из значений, перечисленных в Таблице 8-1. Используйте elementAtIndex:associatedPoints: метод, если Вы также хотите получить точки, связанные с элементом. Если Вы уже не знаете тип элемента пути, необходимо передать этот метод массив, способный к содержанию по крайней мере трех NSPoint типы данных.

Для изменения точек, связанных с элементом пути, используйте setAssociatedPoints:atIndex: метод. Вы не можете изменить тип элемента пути, только точки, связанные с ним. При изменении точек, NSBezierPath берет только столько точек от Вашего массива точки, сколько необходимы. Например, при указании трех точек для Строки Для соединения каналом элемента, только первая точка используется.

Перечисление 8-13 показывает метод, обновляющий контрольную точку, связанную с элементом пути кривой на конце текущего пути. Точки, определяющие кривую, сохранены в порядке controlPoint1, controlPoint2, endPoint. Этот метод заменяет точку controlPoint2, который влияет на часть конца кривой.

Перечисление 8-13  , Изменяющее контрольную точку кривой, соединяет элемент каналом

- (void)replaceLastControlPointWithPoint:(NSPoint)newControl
            inPath:(NSBezierPath*)thePath
{
    int elemCount = [thePath elementCount];
    NSBezierPathElement elemType =
                [thePath elementAtIndex:(elemCount - 1)];
 
    if (elemType != NSCurveToBezierPathElement)
        return;
 
    // Get the current points for the curve.
    NSPoint points[3];
    [thePath elementAtIndex:(elemCount - 1) associatedPoints:points];
 
    // Replace the old control point.
    points[1] = newControl;
 
    // Update the points.
    [thePath setAssociatedPoints:points atIndex:(elemCount - 1)];
}

Преобразование пути

Система координат NSBezierPath возразите всегда соответствует систему координат представления, в котором она нарисована. Таким образом, учитывая путь, первая точка которого в (0, 0) в Вашем NSBezierPath объект, таща путь в Ваших местах представления, указывающих на (0, 0) в текущей системе координат представления. Для рисования того пути в различном расположении необходимо применить преобразование одним из двух способов:

  • Примените преобразование к системе координат представления и затем нарисуйте путь. Для получения информации о том, как применяться, преобразовывает к представлению, посмотрите Создание и Применение Преобразования.

  • Примените преобразование к NSBezierPath сам объект с помощью transformUsingAffineTransform: метод и затем рисует его в неизмененном представлении.

Оба метода заставляют путь быть нарисованным в том же расположении в представлении; однако, второй метод также имеет побочный эффект постоянного изменения NSBezierPath объект. В зависимости от Вашего содержания это может или может не быть надлежащим. Например, в программе иллюстрации, Вы могли бы хотеть, чтобы пользователь был в состоянии перетащить формы вокруг представления; поэтому, Вы хотели бы изменить NSBezierPath объект сохранить новую позицию пути.

Создание CGPathRef от объекта NSBezierPath

Могут быть времена, когда необходимо преобразовать NSBezierPath возразите против a CGPathRef тип данных так, чтобы можно было выполнить находящиеся на пути операции с помощью Кварца. Например, Вы могли бы хотеть нарисовать свой путь к Кварцевому слою прозрачности или использовать его, чтобы сделать усовершенствованное обнаружение хита. Несмотря на то, что Вы не можете использовать a NSBezierPath возразите непосредственно от Кварца, можно использовать его элементы пути для создания a CGPathRef объект.

Перечисление 8-14 показывает Вам, как создать a CGPathRef тип данных от NSBezierPath объект. Пример расширяет поведение NSBezierPath класс с помощью категории. quartzPath метод использует элементы пути NSBezierPath объект вызвать надлежащие Кварцевые функции создания тракта. Несмотря на то, что метод создает непостоянное CGPathRef объект, это возвращает неизменную копию для рисования. Гарантировать, что возвращенные возвраты пути корректные результаты во время обнаружения хита, этот метод неявно закрывает последний подпуть, если Ваш код не делает так явно. Кварц требует, чтобы пути были закрыты, чтобы сделать обнаружение хита на закрашенной области пути.

Перечисление 8-14  , создающее CGPathRef из NSBezierPath

@implementation NSBezierPath (BezierPathQuartzUtilities)
// This method works only in OS X v10.2 and later.
- (CGPathRef)quartzPath
{
    int i, numElements;
 
    // Need to begin a path here.
    CGPathRef           immutablePath = NULL;
 
    // Then draw the path elements.
    numElements = [self elementCount];
    if (numElements > 0)
    {
        CGMutablePathRef    path = CGPathCreateMutable();
        NSPoint             points[3];
        BOOL                didClosePath = YES;
 
        for (i = 0; i < numElements; i++)
        {
            switch ([self elementAtIndex:i associatedPoints:points])
            {
                case NSMoveToBezierPathElement:
                    CGPathMoveToPoint(path, NULL, points[0].x, points[0].y);
                    break;
 
                case NSLineToBezierPathElement:
                    CGPathAddLineToPoint(path, NULL, points[0].x, points[0].y);
                    didClosePath = NO;
                    break;
 
                case NSCurveToBezierPathElement:
                    CGPathAddCurveToPoint(path, NULL, points[0].x, points[0].y,
                                        points[1].x, points[1].y,
                                        points[2].x, points[2].y);
                    didClosePath = NO;
                    break;
 
                case NSClosePathBezierPathElement:
                    CGPathCloseSubpath(path);
                    didClosePath = YES;
                    break;
            }
        }
 
        // Be sure the path is closed or Quartz may not do valid hit detection.
        if (!didClosePath)
            CGPathCloseSubpath(path);
 
        immutablePath = CGPathCreateCopy(path);
        CGPathRelease(path);
    }
 
    return immutablePath;
}
@end

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

Обнаружение хитов мыши на пути

Если необходимо определить, произошло ли событие от нажатия мыши на пути или его закрашенной области, можно использовать containsPoint: метод NSBezierPath. Этот метод тестирует точку против всех закрытых и открытых подпутей в объекте контуров. Если точка находится на или в каком-либо из подпутей, возвратов метода YES. При определении, является ли точка в подпути, метод использует ненулевое вьющееся правило.

Если Ваше программное обеспечение работает в OS X v10.4 и позже, можно выполнить более усовершенствованное обнаружение хита с помощью CGContextPathContainsPoint и CGPathContainsPoint функции в Кварце. Используя эти функции можно определить, находится ли точка на самом пути или если точка в пути с помощью или ненулевого или ровно-нечетного вьющегося правила. Несмотря на то, что Вы не можете использовать эти функции на NSBezierPath возразите непосредственно, можно преобразовать объект контуров в a CGPathRef тип данных и затем использует их. Для получения информации о том, как преобразовать объект контуров в a CGPathRef тип данных, посмотрите Создание CGPathRef От Объекта NSBezierPath.

Перечисление 8-15 показывает пример того, как Вы могли бы выполнить усовершенствованное обнаружение хита на NSBezierPath объект. Этот пример добавляет метод к NSBezierPath класс с помощью категории. Реализация метода добавляет a CGPathRef версия текущего пути к текущему контексту и вызовам CGContextPathContainsPoint функция. Эта функция использует указанный режим для анализа расположения указанной точки относительно текущего пути и возвращает надлежащее значение. Режимы могут включать kCGPathFill, kCGPathEOFill, kCGPathStroke, kCGPathFillStroke, или kCGPathEOFillStroke.

Перечисление 8-15  , Обнаруживающее хиты на пути

@implementation NSBezierPath (BezierPathQuartzUtilities)
// Note, this method works only in OS X v10.4 and later.
- (BOOL)pathContainsPoint:(NSPoint)point forMode:(CGPathDrawingMode)mode
{
    CGPathRef       path = [self quartzPath]; // Custom method to create a CGPath
    CGContextRef    cgContext = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
    CGPoint         cgPoint;
    BOOL            containsPoint = NO;
 
    cgPoint.x = point.x;
    cgPoint.y = point.y;
 
    // Save the graphics state before doing the hit detection.
    CGContextSaveGState(cgContext);
 
    CGContextAddPath(cgContext, path);
    containsPoint = CGContextPathContainsPoint(cgContext, cgPoint, mode);
 
    CGContextRestoreGState(cgContext);
 
    return containsPoint;
}
@end