Для установки режима отображения, непосредственно определяющего направление осей и размер логической единицы системы координат, используется функция SetMapMode :
int WINAPI SetMapMode(HDC hdc, int nMapMode);
Для контекста отображения hdc эта функция устанавливает новый режим отображения, заданный параметром nMapMode, возвращая номер режима отображения, который был установлен раньше.
Параметр nMapMode может принимать одно из следующих значений.
MM_TEXT Вправо Вниз 1 пиксел
MM_LOMETRIC Вправо Вверх 0,1 мм
MM_HIMETRIC Вправо Вверх 0,01 мм
MM_LOENGLISH Вправо Вверх 0,01 дюйм
MM_HIENGLISH Вправо Вверх 0,001 дюйм
MM_TWIPS Вправо Вверх 1/1440 дюйма
MM_ISOTROPIC Можно выбирать Можно выбирать Произвольный, одинаковый для осей X и Y
MM_ANISOTROPIC Можно выбирать Можно выбирать Произвольный, может быть разный для осей X и Y
Преобразование логических единиц
Итак, я осуществляю вывод на принтер средствами GDI. Получаю разрешение принтера из DEVMODE.dmPrintQuality, затем считаю коэффициенты масштабирования для линий DPI/25.4≈23.6 (потому что размеры у меня в мм) и для текста DPI/72≈8.3.
С линиями всё чётко, рисуется как надо. С текстом не всё так хорошо, как мне кажется, ибо я через CreateFont() выбирал 14-й размер, но выглядит он как 12-й. На это временно можно закрыть глаза, но тут я сталкиваюсь с другой проблемой — мне надо рассчитать, влезает ли текст в ширину рамки (это 200 мм: 210 мм — ширина листа формата А4, 10 мм — суммарный отступ от краёв листа до рамки, по 5 мм с каждой стороны).
Для получения ширины текста я использую GetTextExtentPoint32(). Она возвращает размеры в логических единицах (logical units). А теперь внимание — как мне из этих единиц перевести в те единицы, в которых я рисую? Здесь у меня мегазатуп, и вот почему. Например, для текста «2015» я получаю ширину 129 LU. Если разделить это значение на 23.6, получится 5.5 мм — это маловато для текста 14-м шрифтом. Если разделить на 8.3, то получится 15.5, и если брать это в миллиметрах, то это будет слишком много.
Читал вот это — не помогло, вообще не вникаю, как и что пересчитать :-/ Подскажите, пожалуйста, как мне оперировать имеющимися данными?
Может при создании контекста устройства проинициировать режим отображения?
Только проблема в том, что у меня смешанное содержимое — как текст, так и линии. В каких тогда единицах мне надо будет задавать размер шрифта в CreateFont(), чтоб он был 14-м?
P.S. Это тогда всю программу переписывать придётся, но спасибо за совет ☺
Вот, может пригодится для прикидок размеров. Шрифтами 14 Times New Roman и Courier New (моноширинный) надписи "2015" сделал в векторном редакторе. Сетка с шагом 0,5 мм.Размер шрифта определяется с учетом выступов под базовую линию и над ней. Т.е. с заглавными буквами и хвостатыми будет больше занимать места при том-же кегле. Надо иметь и это ввиду. Вот пример с теми же шрифтами, но с выступающими деталями букв:
За исследование спасибо. С таким поведением шрифтов с засечками я знаком, но суть в том, что текст 14-м шрифтом в моей программе и тем же самым шрифтом в ворде выглядят разными, вот что меня смущает.
Цитата: @pixo $oft
считал всё в логических единицах, умножая на коэффициент масштабирования
Цитата: @pixo $oft
но суть в том, что текст 14-м шрифтом в моей программе и тем же самым шрифтом в ворде выглядят разными, вот что меня смущает.
Может из-за этого коэффициента масштабирования, шрифты в вашей программе и "word'е" различаются.
Цитата: Kuzya
Может из-за этого коэффициента масштабирования, шрифты в вашей программе и "word'е" различаются.
Возможно, но… блин, я же считал этот коэффициент согласно рекомендациям от Microsoft. Так какого же?! :D
В общем, всё это крайне странно.