1.3.4.2. "Резиновая" линия и растровые операции
1.3.4.2. "Резиновая" линия и растровые операции
Теперь нужно дать пользователю возможность рисовать линии. Для этого мы используем стандартную "резиновую" линию: пользователь нажимает левую кнопку мыши и, удерживая ее, передвигает мышь. До тех пор, пока кнопка удерживается, за курсором тянется линия. Как только пользователь отпускает кнопку, линия "впечатывается" в рисунок.
Сама по себе реализация "резиновой" линии очень проста: при наступлении события OnMouseDown запоминаются координаты начала линии и взводится флаг, показывающий, что включен режим рисования "резиновой" линии. Также запоминаются координаты конца отрезка, который на данный момент совпадает с началом. В обработчике OnMouseMove, если включен режим рисования "резиновой" линии, стирается линия со старыми координатами конца и рисуется с новыми. При наступлении OnMouseUp программа выходит из режима рисования "резиновой" линии, рисуя окончательный ее вариант с текущими координатами конца.
Самое сложное в этой последовательности действий — стереть нарисованную ранее линию. Если бы у нас был однородный фон, можно было бы просто нарисовать старую линию еще раз цветом фона — это выглядело бы как ее стирание. Но поскольку фон не однородный, а составлен из нарисованных ранее линий, этот способ мы применить не можем.
Для решения этой задачи мы здесь рассмотрим самый простой метод — инверсное рисование (более сложный метод будет рассмотрен чуть позже). При этом каждая точка, принадлежащая линии, закрашивается не каким-либо фиксированным цветом, а инвертируется (т. е. к текущему цвету точки применяется операция not). Для стирания линии просто рисуем ее еще раз: двойная инверсия восстанавливает предыдущий цвет точек (not not X = X для любого X).
При рисовании пером и кистью GDI позволяет использовать различные растровые операции, которые определяют результирующий цвет каждого пиксела в зависимости от цвета фона и пера или кисти. По умолчанию применяется операция R2_COPYPEN, в которой цвет фона игнорируется, а результирующий цвет пиксела совпадает с цветом пера или кисти. Изменить растровую операцию можно с помощью функции SetROP2 (двойка в названии функции показывает, что устанавливаемая растровая операция имеет два аргумента — цвет рисования и цвет фона: при выводе растровых рисунков могут применяться растровые операции с тремя аргументами — см. функцию BitBlt). Нас будет интересовать операция R2_NOT, которая инвертирует фоновый цвет, игнорируя цвет пера или кисти.
Примечание
Растровая операция влияет на все, что рисуется с помощью пера и кисти, т. е. на рисование границ фигур и их заливку. Кроме того, растровая операция влияет также на результат работы функции SetPixel (и, соответственно, изменение цвета с помощью Canvas.Pixels[X, Y]), т. к. эта операция выполняется с мощью кистей.
Код, рисующий "резиновую" линию, приведен в листинге 1.59.
Листинг 1.59. Рисование "резиновой" линии инверсным методом
procedure TLinesForm.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then begin
OldX:= X;
OldY:= Y;
BegX:= X;
BegY:= Y;
LineDrawing:= True;
end;
end;
procedure TLinesForm.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
if LineDrawing and ((X <> OldX) or (Y <> OldY)) then
with Canvas do
begin
SetROP2(Handle, R2_NOT);
Line(BegX, BegY, OldX, OldY); // Стираем старую линию.
Line(BegX, BegY, X, Y); // Рисуем новую.
OldX:= X;
OldY:= Y;
end;
end;
procedure TLinesFom.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if (Button = mbLeft) and LineDrawing then
begin
case RGroupLine.ItemIndex of
2: Canvas.Pen.Color:= clBlue;
3: begin
Canvas.Brush.Color:= clRed;
Canvas.Pen.Color:= clRed;
end;
4: Canvas.Pen.Color:= clGreen;
end;
Line(BegX, BegY, X, Y);
LineDrawing:= False;
end;
end;
Обратите внимание, что резиновая линия следует за мышью даже тогда, когда мышь выходит за пределы формы, т. е. форма получает сообщения мыши, когда курсор находится за ее пределами. Это становится возможным благодаря захвату мыши окном. Любое окно в Windows может захватить мышь для монопольного использования, и тогда все сообщения от мыши будет получать это окно, независимо от того, где находится курсор. В VCL любой визуальный компонент, у которого установлен стиль csCaptureMouse (а у формы он по умолчанию установлен) автоматически захватывает мышь при нажатии левой кнопки и освобождает при ее отпускании, поэтому мы получаем требуемый нам эффект автоматически.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
«Резиновая» верстка
«Резиновая» верстка Все созданные нами шаблоны имели фиксированную ширину: то есть ширина юнитов, колонок, областей и т. д. остается постоянной при изменении размеров окна браузера. Большинство коммерчески успешных сайтов используют этот принцип с момента появления
Линия жизни объекта
Линия жизни объекта Линия жизни объекта (object lifeline) изображается пунктирной вертикальной линией, ассоциированной с единственным объектом на диаграмме последовательности. Линия жизни служит для обозначения периода времени, в течение которого объект существует в системе
Терминальная линия (TTY)
Терминальная линия (TTY) Терминал или псевдотерминал, ассоциированный с процессом, если такой существует. Процессы-демоны не имеют ассоциированного
Выделенная линия
Выделенная линия В двух словах: дорого и круто. Главное отличие выделенной линии от коммутируемого доступа заключается в том, что ваш компьютер подключен к Интернету постоянно. Это значит, что для того, чтобы посмотреть электронную почту или посетить какой-либо сайт, вам
Растровые редакторы
Растровые редакторы Первый растровый редактор, доступный в Linux, с которым вы сейчас познакомитесь, – это
Fence (Линия выбора)
Fence (Линия выбора) Режим Fence (Линия выбора) напоминает режим Crossing Polygon (Пересечение с многоугольником), но в отличие от него последнее звено ломаной линии, замыкающей границу многоугольника, отсутствует. В этом режиме выделяются только те объекты, которые пересекаются
6.1. Растровые изображения и объекты векторной графики
6.1. Растровые изображения и объекты векторной графики Возможности работы с графикой, которые предоставляет Microsoft Word, достаточно велики. Наличие графических объектов в текстовых документах часто желательно, а в некоторых случаях просто необходимо. Иллюстрации могут
4.3. Операции сравнения и логические операции
4.3. Операции сравнения и логические операции Символ операции Значение Использование ! Логическое НЕ !expr меньше exprexpr = Меньше либо равно expr=expr больше exprexpr = больше либо равно expr=expr == равно expr==expr != не равно expr!=expr логическое
Режим Линия времени
Режим Линия времени В режиме Линия времени доступно гораздо больше возможностей, нежели в рассмотренном ранее режиме Сценарий. В этом вы можете убедиться, взглянув на рис. 4.4. Рис. 4.4. Окно Фильм в режиме Линия времениНа рис. 4.4 видно, что сцены, из которых состоит фильм,
2. Линия строк
2. Линия строк Признаки слева направо (рис. 182): Рис. 182• линия строки прямая;• линия строки поднимающаяся;• линия строки опускающаяся;• линия строки волнообразная;• линия строки выгнутая (аркообразная);• линия строки вогнутая;• линия строки беспорядочная,
6.4.1. Выделенная линия
6.4.1. Выделенная линия Выделенную линию организовать не всегда возможно, да и для домашнего пользователя это довольно дорогое удовольствие (организация выделенной линии и ее поддержка). Поэтому данный способ сразу отпадает. А учитывая, что DSL-соединения доступны всем, то в
Голубятня: Линия мысли Сергей Голубицкий
Голубятня: Линия мысли Сергей Голубицкий Опубликовано 23 декабря 2012 года В пятницу решили торжественно отужинать в честь несостоявшегося конца света. По этому поводу заказали вечером в ресторане еды в количестве слегка превосходящем обычные
Генеральная линия: От Fortan до C#
Генеральная линия: От Fortan до C# Автор: Виктор ШепелевКак уже было сказано, подавляющее большинство языков программирования из «настоящего мэйнстрима» ведут свою идеологическую родословную напрямую из машинного языка/ассемблера. Конечно, по этому пути они успели зайти