На этом шаге мы рассмотрим возможные режимы сопоставления экранных и общепринятых координат.
В графических устройствах вывода применяется двумерная система координат. При выводе на экран используется пиксельная сетка, на принтеры - двумерный массив точек печатной страницы. Аналогичная система применяется в Windows-приложениях графическими функциями. GDI работает с абстрактными единицами измерения, которые называются логическими единицами (logical units).
В качестве примера ниже приведена строка из функции OnDraw(), которая инициализирует объект шрифта для текста, выводимого в контекст устройства. Высота создаваемого шрифта составляет 16 логических единиц.
aFont.CreateFont(16,0,0,0,0,0,0,0,0,0,0,0,FF_ROMAN,0);
В следующем фрагменте кода сначала текущая позиция в графическом представлении переносится в точку с координатами (100,200), а затем рисуется горизонтальная линия длиной 200 логических единиц до точки с координатами (300,200).
pDC->MoveTo(100, 200); pDC->LineTo(300, 200);
Логические единицы не имеют физического смысла. Чтобы придать им физический смысл, Вам нужно приравнять их к единицам измерения устройства. Это делается посредством реализованной в GDI системы сопоставления координат (coordinate mapping system), обеспечивающей стандартный интерфейс к различным типам дисплеев, принтеров и прочих устройств вывода. Задавая режим сопоставления (mapping mode), Вы определяете способ перевода логических единиц, в которых измеряется область рисования приложения, в единицы устройства (device units), выполняющего аппаратный вывод изображения. GDI гарантирует адекватное отображение на любом устройстве вывода.
В GDI есть восемь режимов сопоставления, устанавливающих соотношение между логическими координатами и координатами устройства. В режиме сопоставления ММ_ТЕХТ, принятом по умолчанию, логическая единица приравнивается к пикселю устройства независимо от разрешения устройства. В этом случае обычно возникают затруднения с выводом изображения на принтер.
Обратите внимание, какое крохотное изображение появляется при печати. Причина уменьшения изображения в различном разрешении экрана и принтера. Графические функции масштабируют вывод в единицах разрешения устройства вывода. Поэтому символ высотой в 16 пикселей имеет на мониторе с разрешением 800 на 600 высоту около 5 мм, а на принтере с разрешением 600 на 600 точек на дюйм его высота составит примерно 0,7 мм.
ММ_ТЕХТ - один из шести фиксированных режимов сопоставления, в котором устанавливается прямое соотношения между логическими единицами и единицами устройства. В остальных фиксированных режимах логические единицы преобразуются в единицы длины. Например в режиме MM_LOENGLISH логическая единица соответствует 0,01 дюйму на устройстве вывода. Перечень фиксированных режимов сопоставления координат приведен в таблице 1.
Режим сопоставления координат | Единице вывода соответствует |
---|---|
ММ_ТЕХТ | Один пиксель устройства |
MM_LOENGLISH | 0,01 дюйма |
MM_HIENGLISH | 0,001 дюйма |
MM_LOMETRIC | 0,1 мм |
MM_HIMETRIC | 0,01 мм |
MM_TWIPS | 1/1440 дюйма |
Кроме фиксированных режимов Вы можете использовать и нефиксированные режимы сопоставления MM_ISOTROPIC и ММ_ANISOTROPIC. В них нет жестких соотношений между логическими и физическими единицами, поэтому их надо задавать самостоятельно. Когда установлен режим MM_ISOTROPIC, GDI непрерывно регулирует соотношения координат таким образом, чтобы одна логическая единица имела одинаковый физический размер в обоих (х и у) направлениях. В режиме MM_ANISOTROPIC соотношение между координатами х и у может быть произвольным.
Чтобы задать соотношение между логическими и физическими единицами, нужно описать два прямоугольника. Первый определяет относительные размеры логической области, которая называется окном (window), второй - области устройства, которая называется областью просмотра (viewport). Размеры окна задаются в логических единицах с помощью функции CDC::SetWindowExt(). Область просмотра измеряется в единицах устройства и устанавливается функцией CDC::SetViewportExt(). Информацию о текущих размерностях устройства получают вызовом функции CDC::GetDeviceCaps().
Следующий код устанавливает режим сопоставления координат, аналогичный MM_LOENGLISH:
pDC->SetMapMode(MM_ANISOTROPIC); pDC->SetViewPortExt(pDC->GetDeviceCaps(LOGPIXELSX), pDC->GetDeviceCaps(LOGPIXELSY)); pDC->SetWindowExt(100, -100);
Параметры LOGPIXELSX и LOGPIXELSY передают функции GetDeviceCaps() число пикселей в логическом дюйме дисплея по ширине и высоте соответственно. В показанном выше фрагменте задано, что изображаемый на устройстве квадрат со стороной 1 дюйм соответствует квадрату в графической области приложения со стороной 100 логических единиц. Другими словами, одна логическая единица эквивалентна 0,01 дюйма на устройстве вывода.
Обратите внимание, что параметр у функции SetWindowExt() имеет отрицательное значение. По умолчанию начало координат устройств в соответствии с соглашениями Windows находится в верхнем левом углу окна, и значения у увеличиваются сверху вниз. Задав отрицательное соотношение между координатами у окна и области просмотра, Вы можете выполнять графические функции в общепринятой математической системе координат, в которой значения у увеличиваются снизу вверх. Только учтите, что начало экранной системы координат (точка с координатами (0,0)) находится по умолчанию в верхнем левом углу окна, и если координаты у увеличиваются снизу вверх, то выводимые изображения не будут видны. Если Вы не хотите, чтобы рисование выходило в область, лежащую выше верхней границы окна, либо измените знак координаты у, либо сместите началj координатной системы окна в точку, соответствующую левому ниж нему углу логического окна.
Фиксированные режимы сопоставления координат следуют математическому соглашению, в соответствии с которым значения координаты х увеличиваются слева направо, координаты у - снизу вверх. Режим ММ_ТЕХТ следует Windows-соглашению, по которому значения координаты у увеличиваются сверху вниз.
Установив наиболее удобный режим сопоставления координат, Вы сможете воспроизводить изображения средствами графических GDI-функций, используя логические координаты. Преобразования между логическими и физическими координатами обрабатываются автоматически. Однако иногда требуется дополнительное преобразование координат, поскольку некоторые данные поступают только в координатах устройства. Например, позиция щелчка мышью передается функции-обработчику CView::OnLButtonDown() в виде параметра, состоящего из пары физических координат. Чтобы узнать, попадает ли этот щелчок в определенную зону логической области окна, нужно выполнить преобразование координат. Эта возможность реализуется CDC-методами LPtoDP() и DPtoLP().
На следующем шаге мы рассмотрим реализацию прокрутки.