Смекни!
smekni.com

Основы графического вывода (стр. 1 из 26)

Основы графического вывода

В предыдущих разделах мы вскользь касались темы, связанной с графическим выводом. При рассмотрении самого первого приложения (пример 1), были коротко отмечены основные правила работы с графическими устройствами, введено понятие контекст устройства (device context, DC), обсуждены некоторые основные правила работы с контекстом. При первом знакомстве мы ограничились только применением контекста устройства при обработке сообщения WM_PAINT.

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

Контекст устройства

Повторим вкратце основные положения, сформулированные при первом знакомстве:

Все средства вывода в Windows относятся к графическому интерфейсу устройств (GDI). GDI представляет собой библиотеку функций для выполнения графического вывода на различных устройствах, не только на дисплее.

Все функции GDI взаимодействуют с контекстом устройства (devicecontext, DC). Так что для осуществления вывода на устройство необходимо выполнить три основных шага:

получить хендл контекста этого устройства

осуществить собственно вывод на это устройство (рисование, вывод текста и пр.)

обязательно освободить контекст устройства.

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

Контекст устройства описывает так называемые атрибуты контекста и непосредственно характеристики устройства.

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

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

Рисунок 1. Вывод изображений с использованием контекста устройства в Windows

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

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

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

с разным разрешением — от 640x400, 640x480 и до часто встречающихся 1024x768, 1280x1024. Было бы очень желательно, что бы даже в режиме 640x400 все диалоги и окна помещались на экране.

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

с разными настройками системной палитры; включая контрастные и энергосберегающие режимы (иногда применяются для переносных компьютеров)

если приложение способно выводить на принтер, то надо иметь в виду, что вместо принтера может оказаться плоттер, который хорошо рисует линии, но совершенно не может выводить растровых изображений, либо АЦПУ, которое способно только печатать текст.

Получение информации об устройстве

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

Для того, что бы получить информацию об устройстве в GDI предусмотрена функция int GetDeviceCaps (hDC, nIndex);

Эта функция возвращает целое число, являющееся значением указанного аргументом nIndex параметра устройства. В windows.h определено значительное количество символических имен, определяющих возвращаемые функцией GetDeviceCaps данные. Возвращаемое число может представлять собой как непосредственное значение запрашиваемого параметра (например, ширину устройства в миллиметрах), либо битовой последовательностью, в которой отдельные биты являются флагами (см., например, параметр RASTERCAPS). Полный список всех возможных характеристик устройства весьма обширен, поэтому приводить его здесь не будем; при необходимости можно обратиться к формальному описанию функции GetDeviceCaps в документации. Некоторые из них:

DRIVERVERSION Версия драйвера. 0x0100 обозначает версию 1.0
HORZSIZE, VERTSIZE размер устройства вывода в миллиметрах
HORZRES, VERTRES размер устройства вывода в единицах устройства вывода (пикселях)
LOGPIXELSX,LOGPIXELSY число единиц устройства (пикселей), приходящееся на один логический дюйм[1]
BITSPERPIXEL число бит на 1 пиксель
PLANES число битовых планов
TECHNOLOGY тип устройства, может принимать следующие значения:DT_PLOTTER векторный плоттерDT_RASDISPLAY растровый дисплейDT_RASPRINTER растровый принтерDT_RASCAMERA растровая камераDT_CHARSTREAM поток символовDT_METAFILE метафайлDT_DISPFILE дисплейный файл
NUMBRUSHES Число встроенных кистей
NUMPENS Число встроенных перьев
ASPECTX Относительная ширина пикселя
ASPECTY Относительная высота пикселя
ASPECTXY Относительная диагональ пикселя
RASTERCAPS Битовая маска, указывающая возможности устройства при работе с растровыми операциямиRC_BANDING поддерживает пополосный выводRC_BITBLT может передавать битмапыRC_BITMAP64 битмапы могут быть больше 64КRC_DI_BITMAP поддерживает независимые от устройства битмапыRC_DIBTODEV поддерживает функцию SetDIBitsToDeviceRC_FLOODFILL может выполнять заливку замкнутых контуровRC_GDI20_OUTPUT поддерживает расширения версии 2.0 GDIRC_PALETTE устройство использует палитруRC_SCALING устройство может масштабироватьRC_STRETCHBLT устройство поддерживает функцию StretchBltRC_STRETCHDIB устройство поддерживает функцию StretchDIBits...
... ...

Одной из идей разработки GDI было обеспечение единого программного интерфейса со всеми устройствами, однако реализовать ее в полной мере практически невозможно. Поэтому вам иногда придется определять характеристики устройства, на котором вы осуществляете вывод. Например, если вы собираетесь отобразить на принтере какой–либо битмап, то надо проверить бит RC_BITBLT в параметре RASTERCAPS, так как плоттеры и АЦПУ не могут работать с растровыми изображениями; или вам может понадобиться узнать, какое число цветов может быть отображено на дисплее или цветном принтере и т.д.

Атрибуты контекста устройства

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

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

Название атрибута Стандартное значение Установить Получить
Mapping modeСистема координат MM_TEXT SetMapMode GetMapMode
Window originНачало отсчета в логических координатах 0,0 SetWindowOrg0SetWindowOrgExOffsetWindowOrg0OffsetWindowOrgEx GetWindowOrg0GetWindowOrgEx
Viewport originНачало отсчета в координатах устройства 0,0 SetViewportOrg0SetViewportOrgExOffsetViewportOrg0OffsetViewportOrgEx GetViewportOrg0GetViewportOrgEx
Window extentsМасштабные коэффициенты системы координат 1,1 SetWindowExt0SetWindowExtExSetMapModeScaleWindowExt0ScaleWindowExtEx GetWindowExt0GetWindowExtEx
Viewport extentsМасштабные коэффициенты системы координат 1,1 SetViewportExt0SetViewportExtExSetMapModeScaleViewportExt0ScaleViewportExtEx GetViewportExt0GetViewportExtEx
PenПеро (карандаш) BLACK_PEN SelectObjectSelectPen 2 SelectObjectSelectPen 2
Current pen positionТекущая позиция пера 0,0 MoveTo 0MoveToExLineTo GetCurrentPosition0GetCurrentPositionEx
BrushКисть WHITE_BRUSH SelectObjectSelectBrush 2 SelectObjectSelectBrush 2
Brush originНачальная точка кисти 0,0 (screen) SetBrushOrg0SetBrushOrgEx GetBrushOrg0GetBrushOrgEx
FontШрифт SYSTEM_FONT SelectObjectSelectFont 2 SelectObjectSelectFont 2
BitmapАссоциируемый битмап отсутствует SelectObjectSelectBitmap 2 SelectObjectSelectBitmap 2
Background modeРежим заполнения фона OPAQUE SetBkMode GetBkMode
Background colorЦвет фона White SetBkColor GetBkColor
Text colorЦвет текста BLACK SetTextColor GetTextColor
Drawing modeРежим рисования R2_COPYPEN SetROP2 GetROP2
Stretching modeРежим сжатия изображения BLACKONWHITE SetStretchBltMode GetStretchBltMode
Polygon filling modeРежим заполнения многоугольников ALTERNATE SetPolyFillMode GetPolyFillMode
Text AlignmentПривязка текста TA_LEFT|TA_TOP SetTextAlign GetTextAlign
Intercharacter spacingМежсимвольный промежуток 0 SetTextCharacterExtra GetTextCharacterExtra
Text JustificationВыравнивание строки 0,0 SetTextJustification SetTextJustification
Clipping regionОбласть отображения отсутствует SelectObjectSelectClipRgnIntersectClipRectOffsetClipRectExcludeClipRect SelectObjectGetClipBox
ArcdirectionНаправление рисования дуг AD_COUNTERCLOCKWISE SetArcDirection GetArcDirection
В случае платформы Win32
Miter LimitВеличина спрямления сопрягаемых линий 10.0 SetMiterLimit1 GetMiterLimit1
GraphicsModeРежим задания координат GM_COMPATIBLE SetGraphicsMode1 GetGraphicsMode1
WorldTransformationMatrixМатрица преобразования глобальных координат 1.0,0.0,0.00.0,1.0,0.0 SetWorldTransform1 GetWorldTransform1

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