Соответственно, чтобы сделать такую надпись, нужно создать регион, совпадающий по форме с этой надписью. В GDI есть целый ряд функций для создания регионов различной формы, но вот для создания региона в форме букв функции нет. Зато GDI поддерживает другие объекты — траектории. Строго говоря, это не совсем объекты, траектория не имеет дескриптора (по крайней мере, API не предоставляет этот дескриптор программам), и в каждом контексте устройства может быть только одна траектория. Создание траектории начинается с вызова функции BeginPath
EndPath
. Графические функции, вызванные между BeginPath
и EndPath
, не выводят ничего в контекст устройства, а то, что должно быть выведено, вместо этого запоминается в траектории (которая представляет собой совокупность замкнутых кривых). С траекторией можно выполнить много полезных операций (см., например,BeginPath
и EndPath
мы вызываем DrawText
. формируя таким образом траекторию, состоящую из контуров букв. Затем с помощью функции PathToRegion
мы создаем регион, границы которого совпадают с контурами траектории, т. е., в данном случае, регион, совпадающий по форме с надписью.На самом деле не все графические функции, вызванные между BeginPath
EndPath
, добавляют контуры к траектории. Это зависит от версии операционной системы. Подробнее этот вопрос обсуждается вВ ходе работы программы регион не меняется, так что нет нужды создавать его каждый раз при обработке события OnPaint
FRgn
формы для дальнейшего использования.Все, что осталось сделать, — это установить регион отсечения с помощью функции SelectClipRgn
Теперь рассмотрим, как рисуются звезды в правом верхнем углу окна (листинг 1.35).
var
I: Integer;
Star: array[0..4] of TPoint;
…
// Следующая группа команд рисует две звезды справа от
// надписи. Эти звезды демонстрируют использование двух
// режимов заливки: WINDING и ALTERNATE. Для простых
// фигур эти режимы дают одинаковые результаты, разница
// возникает только при закрашивании сложных фигур,
// имеющих самопересечения.
Canvas.Pen.Style:= psSolid;
Canvas.Pen.Width:= 1;
Canvas.Pen.Color:= clRed;
Canvas.Brush.Style:= bsSolid;
Canvas.Brush.Color:= clRed;
// Вычисляем координаты вершин звезды. Они помещаются
// в массив Star в следующем порядке (если первой
// считать верхнюю вершину и нумеровать остальные по
// часовой стрелке от нее): 1-3-5-2-4
for I:= 0 to 4 do
begin
Star[I].X:= Round(380 + 90 * Sin(0.8 * I * Pi));
Star[I].Y:= Round(100 — 90 * Cos(0.8 * I * Pi));
end;
// Устанавливаем режим заливки WINDING. При
// использовании этого режима закрашивается все
// содержимое многоугольника независимо от того,
// как именно он нарисован.
SetPolyFillMode(Canvas.Handle, WINDING);
Canvas.Polygon(Star);
// Сдвигаем координаты звезды, чтобы нарисовать ее
// правее с другим режимом заливки.
for I:= 0 to 4 do Inc(Star([I].X, 200);
// Устанавливаем режим заливки ALTERNATE. При
// использовании этого режима заполняются горизонтальные
// линии, лежащие между нечетной и четной сторонами
// многоугольника. В результате пятиугольник в центре
// звезды оказывается незаполненным.