GDI (Graphics Device Interface, Graphical Device Interface) — один из трёх основных компонентов или «подсистем», вместе с ядром и Windows API, составляющих пользовательский интерфейс (оконный менеджер GDI) Microsoft Windows.

GDI — это интерфейс Windows для представления графических объектов и передачи их на устройства отображения, такие, как мониторы и принтеры.

GDI отвечает за отрисовку линий и кривых, отображение шрифтов и обработку палитры. Он не отвечает за отрисовку окон, меню и т. п., эта задача закреплена за пользовательской подсистемой, располагающейся в user32.dll и основывающейся на GDI. GDI выполняет те же функции, что и QuickDraw в Mac OS.

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

Простые игры, которые не требуют быстрой графики, могут использовать GDI. Однако GDI не обеспечивает качественной анимации, поскольку в нём нет возможности синхронизации с кадровым буфером. Также в GDI нет растеризации для отрисовки 3D-графики. Современные игры используют DirectX или OpenGL, что даёт программистам доступ к большему количеству аппаратных возможностей.

Краткое описание

[править | править код]

Для определения атрибутов текста и изображения, которые выводятся на экран или принтер, используется программный объект под названием «контекст устройства» (Device Context, DC). DC, как и большинство объектов GDI, инкапсулирует подробности реализации и данные в себе и к ним нельзя получить прямой доступ.

Для любого рисования нужен объект HDC (Handle DC). При выводе на принтер HDC получается вызовом CreateDC, и на нём вызываются специальные функции для перехода на новую страницу печатаемого документа. При выводе на экран также можно использовать CreateDC, но это приведёт к рисованию поверх всех окон вне их границ, потому обычно для рисования на экране используются вызовы GetDC и BeginPaint, принадлежащие уже не GDI, а USER, и возвращающие контекст, ссылающийся на регион отсечения окна.

Функциональность:

Реализация

[править | править код]

В Windows 9x и более ранних реализована в 16-битной GDI.DLL, которая, в свою очередь, подгружает выполненный в виде DLL драйвер видеокарты. Драйвер видеокарты первоначально и был обязан реализовать вообще всё рисование, в том числе рисование через битмапы в памяти в формате экрана. Позже появилась DIBENG.DLL, в которой было реализовано рисование на битмапах типичных форматов, драйвер был обязан пропускать в неё все вызовы, кроме тех, для которых он задействовал аппаратный ускоритель видеокарты.

Драйвер принтера подгружался таким же образом и имел тот же интерфейс «сверху», но «снизу» он вместо рисования в памяти/на аппаратуре генерировал последовательности команд принтера и отсылал их в объект Job. Эти команды, как правило, были либо двоичные и не читаемые человеком, либо PostScript.

В Windows NT GDI была полностью переписана с нуля заново, причём на C++ (по слухам, у Microsoft тогда не было компилятора этого языка и они использовали cfront). API для приложений не изменился (кроме добавления кривых Безье), для драйверов — обёртки на языке Си вокруг реализованных на C++ внутренностей (вроде BRUSHOBJ_pvGetRbrush).

Сама GDI была размещена сначала в WINSRV.DLL в процессе CSRSS.EXE, начиная с NT4 — в win32k.sys. Драйверы загружались туда же. DIBENG.DLL была переписана заново и перенесена туда же, как совокупность вызовов EngXxx — EngTextOut и другие. Логика взаимодействия драйвера-GDI-DIBENG осталась примерно та же.

GDI32.DLL в режиме пользователя реализована как набор специальных системных вызовов, ведущих в win32k.sys (до NT4 — как обёртки вокруг вызова CsrClientCallServer, посылавшего сообщение в CSRSS.EXE).

В Windows Vista появилась модель драйверов WDDM, в которой была отменена возможность использования аппаратуры двухмерной графики. При использовании WDDM все GDI-приложения (то есть все обычные системные части Windows UI — заголовки и рамки окон, рабочий стол, панель задач и другое) используют GDI-драйвер cdd.dll (Canonical Display Driver)[1], который рисует на некоторых битмапах в памяти, своих для каждого окна (содержимое окна стало запоминаться в памяти, до того Windows никогда так не делала и всегда перерисовывала окна заново, кроме неких специальных окон с флагом CS_SAVEBITS). Изображения из cdd.dll извлекаются процессом dwm.exe (Desktop Window Manager), который является Direct3D-приложением и отрисовывает «картинки окон» на физическом экране через Direct3D.

Сам же WDDM-драйвер поддерживает только DirectDraw и Direct3D и не имеет отношения ни к GDI, ни к win32k.sys, сопрягаясь с модулем dxgkrnl.sys в ядре.

Критика

[править | править код]

Крайне сильно критикуется подсистема печати Windows, особенно в случае сравнения её с CUPS.

Причины: бинарный формат потока задания печати (в CUPS это PostScript) и реализация обработки этого потока в виде нескольких DLL внутри одного процесса SPOOLSV.EXE (CUPS вместо этого использует обычный конвейер из нескольких процессов вроде pstoraster | rastertoepson | parallel, который можно при желании запустить из обычного UNIX shell). Таким образом, CUPS поддерживает разработку фильтров заданий печати (например, для платных принтеров в отелях) даже на скриптовых языках вроде Perl.

Однако тут речь скорее о компонентах, лежащих ниже GDI.

Однако CUPS имеет серьёзные проблемы с поддержкой WinPrinterов вроде всех дешёвых лазерных принтеров Hewlett-Packard. Так как они не поддерживают распространённый формат PCL, для них надо ставить огромные, сложные в настройках и построении пакеты, такие, как HP OfficeJet (порт «hpoj» во FreeBSD). При этом CUPS прекрасно поддерживает струйные принтеры, дорогие модели лазерных принтеров Hewlett-Packard и принтеры PostScript.

Примерные аналоги

[править | править код]

Нижние уровни технологии X11, используемой в UNIX-подобных ОС, таких, как Linux.

При этом X11 беднее возможностями, чем GDI (например, есть проблемы с реализацией независимых от устройства цветов), и для получения полного аналога GDI необходимо добавить ещё ряд библиотек, таких, как SDL.

GDI+

[править | править код]
компонент Windows
Microsoft Windows GDI+
Тип компонента программное обеспечение, Microsoft Windows component[вд] и интерфейс программирования приложений
Включён в Windows XP
Windows Server 2003
Windows Vista Starter
Заменил Microsoft Windows GDI
Был заменён Диспетчер окон рабочего стола

С выходом Windows XP появился потомок подсистемы, GDI+, основанной на C++[2]. Подсистема GDI+ доступна как «плоский» набор из 600 функций, реализованных в gdiplus.dll. Эти функции «обёрнуты» в 40 классов C++. Microsoft не планирует оказывать поддержку для кода, который обращается к плоскому набору напрямую, а не через классы и методы C++. .NET Framework предлагает набор альтернативных C++ обёрточных классов, входящих в пространство имён System.Drawing..

GDI+ является улучшенной средой для 2D-графики, в которую добавлены такие возможности, как сглаживание линий (antialiasing), использование координат с плавающей точкой, градиентная заливка, возможность работы изнутри с такими графическими форматами, как JPEG и PNG, куда лучшая реализация регионов отсечения с возможностью использовать в них координаты с плавающей точкой (а не 16-битные целые) и применения к ним World Transform, преобразования двумерных матриц и т. п. GDI+ использует ARGB-цвета. Эти возможности используются в пользовательском интерфейсе Windows XP, а их присутствие в базовом графическом слое облегчает использование систем векторной графики, таких, как Flash или SVG.

Динамические библиотеки GDI+ могут распространяться вместе с приложениями для использования в предыдущих версиях Windows.

GDI+ схож с подсистемой Quartz 2D у Apple и библиотеками с открытым кодом libart и Cairo.

GDI+ есть не более чем набор обёрток над обычной GDI. В Windows 7 появился новый API Direct2D, который есть примерно то же, но реализован «сверху донизу» вплоть до драйвера видеокарты (точнее, использует некие возможности Direct3D в этом драйвере), и может использовать аппаратное ускорение — то есть видеопроцессор трёхмерной графики для рисования некоторых двухмерных объектов (antialiasing и т. д.)

Уязвимости

[править | править код]

14 сентября 2004 года была обнаружена уязвимость в GDI+ и других графических API, связанная с ошибкой в коде библиотеки JPEG. Эта ошибка позволяла выполнить произвольный код на любой системе Windows. Патч для исправления уязвимости был выпущен 12 октября 2004 года[3].

Примечания

[править | править код]
  1. Comparing Direct2D and GDI — DirectX Developer Blog — Site Home — MSDN Blogs. Дата обращения: 24 марта 2014. Архивировано из оригинала 8 апреля 2014 года.
  2. GDI+ Flat API (англ.). MSDN Library. Microsoft. Дата обращения: 31 октября 2009. Архивировано из оригинала 3 марта 2012 года.
  3. MS04-028: Buffer overrun in JPEG processing (GDI+) could allow code execution (англ.). Microsoft Support. Microsoft. Дата обращения: 6 февраля 2005. Архивировано из оригинала 6 февраля 2005 года.

Ссылки

[править | править код]