Цвет фона и режим заполнения фона



 

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

функциями для рисования линий — для заполнения промежутков между штрихами прерывистой линии

функциями вывода текста — для заполнения пространства под символами текста.

функциями, применяющими кисть — для заполнения фона между линиями штрихованных кистей.

 

Рисунок 5. Рисование прерывистых линий в разных режимах заполнения фона.

 

Для задания цвета фона и для выяснения текущего цвета вы можете воспользоваться функциями

COLORREF SetBkColor (hDC, crColor);

COLORREF GetBkColor (hDC);

Функции возвращают используемый ранее цвет фона. Аналогично перу, GDI будет использовать ближайший чистый цвет в качестве цвета фона.

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

int SetBkMode (hDC, nBkMode);

int GetBkMode (hDC);

GDI поддерживает два разных режима заполнения фона; один из них называется OPAQUE — это режим по умолчанию. В режиме OPAQUE промежутки заполняются текущим цветом фона, а в другом режиме, называемом TRANSPARENT, фон в промежутках не изменяется.

 

Режим рисования

 

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

Атрибут режим рисования задает правила, по которым GDI переносит информацию из одной битовой последовательности на другую. Так, помимо самого очевидного копирования возможны операции инверсии как уже имеющегося изображения, так и рисуемого, объединение с помощью различных битовых операций И (and), ИЛИ (or), ИСКЛЮЧАЮЩЕЕ ИЛИ (xor).

При рассмотрении процесса переноса изображения мы будем исходить из предположения монохромного устройства вывода, так как анализ процесса рисования на цветном устройстве выглядит громоздко. Говоря о монохромном устройстве мы будем обозначать светлую точку будем битом со значением 1, а для темную точку — 0.

При рисовании мы можем условно рассматривать три разные битовые последовательности:

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

контекст устройства, содержащий нарисованный ранее образ (хотя бы просто закрашенный фон), в документации называется destination;

результат — то изображение, которое будет находиться на контексте устройства после рисования;

Применительно к этим трем битовым последовательностям говорят о двоичной растровой операции (binary raster operation, ROP2), так как в формировании результата участвуют две исходных битовых последовательности.

Режим рисования задает операцию над битами обеих последовательностей, выполняемую в процессе переноса изображения. Всего возможно 16 различных режимов рисования:

 

Перо (Pen) P 1 1 0 0 Выполняемая Режим рисования
Имеющееся изображение (Destination) D 1 0 1 0 операция  
  0 0 0 0 0 0 R2_BLACK
  0 0 0 1 ~ (P|D) 1 R2_NOTMERGEPEN
  0 0 1 0  (~P)&D 2 R2_MASKNOTPEN
  0 0 1 1 ~P 3 R2_NOTCOPYPEN
  0 1 0 0 P& (~D) 4 R2_MASKPENNOT
  0 1 0 1 ~D 5 R2_NOT
Повторное рисование восстанавливает фон 0 1 1 0 P^D 6 R2_XORPEN
  0 1 1 1 ~ (P&D) 7 R2_NOTMASKPEN
  1 0 0 0 P&D 8 R2_MASKPEN
  1 0 0 1 ~ (P^D) 9 R2_NOTXORPEN
Прежнее изображение не меняется 1 0 1 0 D 10 R2_NOP
  1 0 1 1  (~P)|D 11 R2_MERGENOTPEN
Режим рисования по умолчанию 1 1 0 0 P 12 R2_COPYPEN
  1 1 0 1 P| (~D) 13 R2_MERGEPENNOT
  1 1 1 0 P|D 14 R2_MERGEPEN
  1 1 1 1 1 15 R2_WHITE

 

Так, например, по умолчанию используется операция копирования исходного изображения на контекст устройства (называемая R2_COPYPEN), довольно часто применяется операция исключающее или (R2_XORPEN) между пером и существующим изображением на контексте.

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

оба изображения, переносимое (pen) и имеющееся (destination), содержат светлые точки

переносимое изображение (pen) содержит светлую точку, а имеющееся (destination) — темную

переносимое изображение (pen) содержит темную точку, а имеющееся (destination) — светлую

оба изображения, переносимое (pen) и имеющееся (destination), содержат темные точки

Говоря в терминах битов может понадобиться комбинировать 1 с 1, 1 с 0, 0 с 1 и 0 с 0. Эти четыре варианта перечислены во втором столбце таблицы в заголовке. В строчках ниже дается ожидаемый результат во всех четырех случаях.

Например, если в результате комбинирования светлой со светлой должна получиться светлая точка (1 и 1 дает 1), а в остальных случаях — темная (1 и 0, 0 и 1, а также 0 и 0 дают 0), то в таблице эта операция будет обозначена как 1 0 0 0 — R2_MASKPEN.

Вы можете установить желаемый режим рисования, или узнать текущий с помощью функций

int SetROP2 (hDC, nIndex);

int GetROP2 (hDC);

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

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

 

Рисунок 6. Получение номера растровой операции.


Направление рисования дуг

 

Для задания дуги, которую вы хотите нарисовать необходимо определить эллипс, дугу которого вы собираетесь нарисовать, а также начальную и конечную точки дуги. Но вот проблема — от начальной до конечной точки можно провести дугу в двух разных направлениях, так что приходится дополнительно определять, в каком именно направлении дуга будет нарисована. Обычно принято, что дуга рисуется против хода часовой стрелки.

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

int GetArcDirection (hDC);

int SetArcDirection (hDC, nIndex);

Допустимыми являются AD_COUNTERCLOCKWISE — рисование против хода часовой стрелки (принято по умолчанию) и AD_CLOCKWISE — по ходу часовой стрелки.

Внимание! Эти две функции не работают в случае расширенного режима задания координат (см. функцию SetGraphicsMode 1, GM_ADVANCED) — в этом случае дуги всегда рисуются против хода часовой стрелки.

 


Дата добавления: 2019-02-12; просмотров: 238; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!