Введение

QuickDraw — это библиотека 2D-графики и связанный интерфейс программирования приложений (API), являющийся ключевым компонентом классической Mac OS. Изначально она была разработана Биллом Аткинсоном и Энди Герцфельдом. QuickDraw по-прежнему присутствовала в библиотеках macOS, но в значительной степени уступила место более современной графической системе Quartz. В Mac OS X Tiger QuickDraw была официально признана устаревшей. В Mac OS X Leopard приложения, использующие QuickDraw, не могли воспользоваться добавленной 64-битной поддержкой. В OS X Mountain Lion поддержка заголовочных файлов QuickDraw была удалена из операционной системы. Приложения, использующие QuickDraw, продолжали работать в OS X Mountain Lion до macOS High Sierra, однако текущие версии Xcode и SDK macOS не содержат заголовочных файлов, необходимых для их компиляции.

Принципы QuickDraw

QuickDraw был основан на LisaGraf системы Apple Lisa начала 1980-х годов и разрабатывался с учетом совместимости с интерфейсами и средами разработки ранних систем Apple, основанных на Pascal. Кроме того, QuickDraw являлась растровой графической системой, определяющей пиксель как базовую единицу графической информации. Это отличалось от векторных графических систем, в которых графические примитивы определяются математически и растрируются по мере необходимости в соответствии с разрешением дисплея. Растровая система требовала значительно меньше вычислительной мощности и являлась преобладающей парадигмой во время разработки QuickDraw. QuickDraw определил ключевую структуру данных – графический порт, или GrafPort. Это была логическая область рисования, в которой можно было создавать графику. Наиболее очевидным объектом на экране, соответствующим GrafPort, было окно, но весь рабочий стол мог выступать в качестве GrafPort, а также могли существовать порты, не отображаемые на экране. GrafPort определял систему координат. В QuickDraw она имела разрешение 16 бит, обеспечивая 65 536 уникальных вертикальных и горизонтальных позиций. Эти позиции нумеровались от -32 767 в крайнем левом (или верхнем) углу до +32 767 в крайнем правом (или нижнем) углу. Обычно окно настраивалось таким образом, чтобы верхний левый угол его области содержимого находился в точке 0,0 в соответствующем GrafPort. Область содержимого окна не включала в себя рамку окна, тень или строку заголовка (если они присутствовали). Координаты QuickDraw относились к бесконечно тонким линиям между позициями пикселей. Фактический пиксель отрисовывался в пространстве непосредственно справа и ниже указанной координаты. Это упрощало задачу программистов и помогало избежать графических артефактов, вызванных ошибками на единицу. На Macintosh пиксели были квадратными, а GrafPort имел разрешение по умолчанию 72 пикселя на дюйм, выбранное для соответствия стандартам полиграфической индустрии, где использовалось 72 пункта на дюйм. QuickDraw также содержал ряд функций масштабирования и преобразования. QuickDraw поддерживал ряд глобальных переменных для каждого процесса, важнейшей из которых был текущий порт. Изначально это упрощало API, поскольку все операции относились к "текущему порту", но по мере развития операционной системы использование глобального состояния также затрудняло интеграцию QuickDraw с современными подходами к проектированию, такими как многопоточность и вытесняющая многозадачность. Для решения этих проблем Carbon API (мост между Mac OS 9 и Mac OS X) добавил дополнительные параметры к некоторым процедурам, позволяя хранить (непрозрачную) информацию о потоках и использовать новую (неопрашиваемую) структуру событий.

Операции более высокого уровня

Любая последовательность графических вызовов QuickDraw может быть записана в структуру, называемую Picture. Эту структуру затем можно сохранить в памяти и "воспроизвести" в любое время, воссоздавая графическую последовательность. При воспроизведении изображение можно разместить в новых координатах или масштабировать без потери разрешения, что обычно происходит при масштабировании растровых изображений. Picture можно сохранить на диск, в этом виде он определяет формат Apple PICT. Целое растровое изображение (или PixMap, когда речь идет о цветных изображениях) может быть скопировано из одного GrafPort в другой, с масштабированием и обрезкой. Эта операция, известная как blitting или CopyBits (по названию функции), является основой для большинства анимационных и спрайтовых эффектов на Mac. QuickDraw предоставляет аналогичную функцию blitting, предназначенную для реализации прокрутки внутри GrafPort – изображение в порту можно сдвинуть в новое положение без масштабирования (но с обрезкой, если необходимо). Каждая примитивная графическая операция выполняется через StdProcs – серию указателей на функции, хранящихся в GrafPort. Этот ограниченный полиморфизм позволяет переопределять или заменять отдельные операции пользовательскими функциями, что позволяет драйверам принтеров перехватывать графические команды и преобразовывать их в соответствующие операции принтера. Таким образом, QuickDraw может быть визуализирован с использованием PostScript, что позволило Macintosh фактически изобрести настольную публикацию. Подобно подклассу, структура данных Window начинается с ассоциированного GrafPort, что делает окна в основном взаимозаменяемыми с любым GrafPort. Хотя это и удобно, это упрощало написание ошибочного кода, который передавал графический порт, не предназначенный для отображения на экране, в API, ожидающий полноценное окно.

История

QuickDraw начал свою жизнь как Lisa Graf в рамках разработки Apple Lisa. Для Macintosh он был первоначально упрощен, но затем расширен. Первоначально QuickDraw GrafPorts поддерживал только бит-глубину 1, то есть один бит на пиксель, или черно-белый. Это соответствовало встроенному экрану раннего Macintosh с фиксированным размером 512×342 пикселей. Ограниченная поддержка цвета использовала примитивную плоскостную модель, позволяя QuickDraw управлять некоторыми типами точечно-матричных принтеров, использующих многоцветные ленты, но лишь немногие приложения поддерживали эту функцию. В 1987 году был разработан и выпущен Macintosh II, выполненный в виде более традиционной трехблочной конструкции – компьютер, монитор и клавиатура были отдельными устройствами. Поскольку монитор был отдельным и больше, чем у оригинального Mac, видеоархитектура неизбежно должна была измениться. Кроме того, Mac II перевел Macintosh от черно-белого изображения к полноцветному. Apple также решила в это время обеспечить поддержку бесшовного рабочего стола, охватывающего несколько мониторов, что было первым в отрасли. Таким образом, был создан Color QuickDraw – значительное расширение оригинального QuickDraw. Оригинальная архитектура не предусматривала большой возможности расширения, но, используя ряд обходных решений, разработчикам Apple удалось сделать добавление цвета и новой видеоархитектуры практически незаметным как для разработчиков, так и для конечных пользователей. Color QuickDraw представил новые структуры данных, включая GDevices для представления каждой подключенной видеокарты/монитора и новую структуру GrafPort для работы с цветом (CGrafPort), а также PixMaps вместо BitMaps для изображений с несколькими битами на пиксель. Одним из приемов обеспечения совместимости было то, что новая структура имела точно такой же размер, как и старая, с большинством членов данных на тех же местах, но с добавлением дескрипторов и указателей на цветовые структуры вместо полей BitMap. Верхние два бита поля rowBytes использовались в качестве флагов для различения GrafPort и CGrafPort (они всегда были равны нулю в GrafPorts старого типа, поскольку BitMap никогда не могла быть настолько широкой, чтобы эти биты могли быть установлены). Использование этих двух старших битов впоследствии дало о себе знать, поскольку оно ограничивало максимальную ширину строки до 4095 для 32-битных PixMaps, что стало проблемой при работе с графикой высокого разрешения. Более поздняя разработка (Carbon) устранила это ограничение, но не обеспечивала полной обратной совместимости. В Color QuickDraw также был добавлен менеджер палитр, который управлял распределением цветов на индексированных видеоустройствах. Большинство операций с графическими примитивами остались неизменными (но работали в цвете), либо были добавлены новые цветовые версии черно-белых API. Первоначально Color QuickDraw мог работать только с 1-, 2-, 4- и 8-битными видеокартами, которые были доступны в то время. Вскоре после этого появились 24-битные видеокарты (так называемые true color), и QuickDraw был снова обновлен для поддержки до 32 бит на пиксель (фактически 24 бита, с 8 неиспользуемыми) цветовых данных ("32 Bit QuickDraw"). Однако архитектура всегда позволяла это, поэтому новые API не требовались. Сами цветовые структуры данных позволяли получить глубину цвета 1, 2, 4, 8, 15 и 24 бита, что давало соответственно 2, 4, 16, 256, 32 768 и 16 777 216 цветов или 4, 16 и 256 оттенков серого. QuickDraw заботился об управлении передискретизацией цветов до доступной цветовой глубины фактического видеооборудования или о передаче между буферами изображений вне экрана, включая опциональное дитерирование изображений до более низкой глубины для повышения качества изображения. Также был добавлен набор утилит для выборки цветов, чтобы программисты могли генерировать оптимальные цветовые палитры для использования с индексированными видеоустройствами. Архитектура QuickDraw всегда позволяла создавать GrafPorts и связанные с ними BitMaps или PixMaps "вне экрана", где графику можно было компоновать в памяти, не отображая ее немедленно на экране. Пиксели можно было передавать между этими внеэкранными портами и экраном с помощью функции копирования QuickDraw CopyBits. Такая внеэкранная композиция является основой для игр и графических приложений, требующих больших ресурсов. Однако до появления 32 Bit QuickDraw такие внеэкранные миры приходилось создавать и настраивать вручную программистами в своих приложениях. Это могло быть подвержено ошибкам, поскольку включало в себя три или более отдельных и довольно сложных структур данных (CGrafPort, PixMap и GDevice, а для индексированных устройств – таблицу поиска цветов и ее обратную). С 32 Bit QuickDraw была добавлена поддержка ОС для обработки этого, в виде "Offscreen Graphics World" или GWorld. Буфер видео (PixMap) GWorld мог храниться в основной памяти или, при наличии, в неиспользуемых частях видеопамяти, где копирование на экран могло быть оптимизировано за счет устранения необходимости передачи большого объема данных пикселей по шине основной памяти. С появлением QuickTime QuickDraw получил возможность работать с сжатыми растровыми данными, такими как JPEG. Менеджер сжатия изображений QuickTime тесно интегрировался с QuickDraw: в частности, вызовы декомпрессии изображений были полноценными вызовами рисования QuickDraw, и если изображение записывалось, сжатые данные сохранялись как часть изображения для отображения при последующем рисовании. Менеджер сжатия изображений также добавил интеграцию с ColorSync для сопоставления цветов. После этого, за исключением изменений в серверной части для оптимизации новых архитектур процессоров (PowerPC), QuickDraw оставался в основном неизменным на протяжении всего оставшегося срока службы классической Mac OS. QuickDraw GX и QuickDraw 3D использовали имя QuickDraw и могли взаимодействовать со структурами данных PixMap и изображений QuickDraw, но в остальном были полностью отдельными по функциональности. С Mac OS X QuickDraw стал частью API Carbon. В 2005 году, с выпуском Mac OS X 10.4, QuickDraw был официально объявлен устаревшим. В 2010 году, с выпуском исходного кода MacPaint 1.3 через Музей истории компьютеров, историческая версия исходного кода QuickDraw также стала доступной.