tsdima, есть предложение снабдить Printer верхней точкой, для чтения и печати различных контекстов, вот тогда можно будет графику в полный рост печатать, хоть с экрана, хоть с bitmap'а
Непонятки возникли у меня только с матрицей пикселей в Img_Point, которая выпадает из общей закономерности, если послать пиксель на принтер я смогу, то вот что читать -- понтия не имею
Этот топик читают: Гость
Разработчик
Ответов: 26163
Рейтинг: 2127
|
|||
карма: 22 |
|
Ответов: 2125
Рейтинг: 159
|
|||
nesco писал(а): есть предложение снабдить Printer верхней точкой, для чтения и печати различных контекстовКонтекст - это просто контекст, он не задаёт ни области для рисования, ни других параметров. Я полагал, что вывод графики будет через Img_Bmp, который будет брать контекст для отрисовки так же, как и другие Img_... Собственно, Img_Bmp для этого и предназначен - рисовать картинку. |
|||
карма: 1 |
|
Разработчик
Ответов: 26163
Рейтинг: 2127
|
|||
tsdima, тут проблема возникла (об ней и в инэте пишут) -- API-функция BitBlt (StretchBlt) не поддерживает контекст принтера, а вот SetPixel, работает, но метод очень медленный.
------------ Дoбавленo: Только что проверил, действительно функция GetDeviceCaps(Printer.Handle, RC_BITBLT) возвращает 0 И чего теперь |
|||
карма: 22 |
|
Ответов: 2125
Рейтинг: 159
|
|||
Попробуй GetDeviceCaps(Printer.Handle, RASTERCAPS) и StretchBlt
А ещё не надо забывать пересчитывать координаты для принтера в логические пиксели. Оно может и рисуется, но в невидимой области страницы. Кроме того, возможно для графики придётся делать SetMapMode(Printer.Handle, MM_TEXT) |
|||
карма: 1 |
|
Разработчик
Ответов: 26163
Рейтинг: 2127
|
|||
tsdima писал(а): А ещё не надо забывать пересчитывать координаты для принтера в логические пиксели |
|||
карма: 22 |
|
Ответов: 2125
Рейтинг: 159
|
|||
Я тоже попробовал печать картинки. Вполне так себе быстро. Однако StretchBlt не работает, т.е. растягивать картинку приходится вручную.
Я взял иконку 32х32, растянул до 1000х1000, на бумаге она примерно 4.2х4.2 см, т.е. примерно 600dpi, что соответствует истине. SetMapMode делать не надо! |
|||
карма: 1 |
|
Разработчик
Ответов: 26163
Рейтинг: 2127
|
|||
tsdima, ты кодом вывода поделись, через чего выводишь-то на принтер. BitBlt у меня не работает однозначно, а значит, у кого-то может тоже не работать.
tsdima писал(а): Я взял иконку 32х32, растянул до 1000х1000Давай, я выложу компоненты с базовым классом, а ты посмотришь, что с ними можно сделать на предмет быстрой печати. Текст, кстати, тоже на контекст принтера выводиться не хочет ------------ Дoбавленo: Вот, приклеил, посмотри. Там все, что я успел перевести. Правда, принтеру на выход onPrint вывел его контекст (по аналогии с MainForm) P.S. Может еще кто поюзает для тестирования багов, да и скорость печати проверит. |
|||
карма: 22 |
| ||
файлы: 1 | img_draw.zip [13.9KB] [197] |
Ответов: 2125
Рейтинг: 159
|
|||
nesco писал(а): tsdima, ты кодом вывода поделисьДык я ничего особенного не делал. Поменял Img_Bmp абсолютно аналогично, как и в предыдущем эксперименте (добавил процедуру Context, скопировав Handle, убрал запрос dc у окна и присвоил напрямую из потока). Закомментировал свой же SetMapMode в hiPrinter.pas. Схема тоже аналогичная, с использованием компонента Resize. nesco писал(а): доступ к принтеру по сети, через серверДык и у меня также. nesco писал(а): Вот, приклеил, посмотриЯ полагал, что _prop_DrawSource будет делать только две функции: 1. выдать контекст 2. освободить его _prop_DrawSource: procedure(var _Data:TData; var dc:HDC; nFunc:word) of object; А мясо надо оставить в самом компоненте. ------------ Дoбавленo: После того, как ты растянул картинку в памяти при помощи StretchBlt можно было выводить на принтер при помощи BitBlt. Твоя ошибка, наверное, была в том, что ты использовал SetMapMode(pdc, MM_HIMETRIC), а то, что координата Y растёт в другом направлении - не учёл. Фактически, в этом случае, либо координату Y надо задавать отрицательную, либо использовать SetViewportOrgEx(pdc, 0, -PageHeight, nil) |
|||
карма: 1 |
|
Разработчик
Ответов: 26163
Рейтинг: 2127
|
|||
tsdima писал(а): Твоя ошибка, наверное, была в том, что ты использовал SetMapMode(pdc, MM_HIMETRIC), а то, что координата Y растёт в другом направлении - не учёлtsdima писал(а): А мясо надо оставить в самом компонентеПомимо отрицательного у, добивает еще зеркальное изображение при определенном выводе tsdima писал(а): либо использовать SetViewportOrgEx(pdc, 0, -PageHeight, nil) |
|||
карма: 22 |
| ||
Голосовали: | Валерий |
Ответов: 2125
Рейтинг: 159
|
|||
nesco писал(а): А на кой черт оно там нужноНу да, а при появлении нового компонента, унаследованного от того же базового класса - опять менять базовый класс? Плохой стиль ООП. |
|||
карма: 1 |
|
Разработчик
Ответов: 26163
Рейтинг: 2127
|
|||
tsdima писал(а): опять менять базовый классtsdima писал(а): Ну да, а при появлении нового компонентаtsdima писал(а): _prop_DrawSource: procedure(var _Data:TData; var dc:HDC; nFunc:word) of object;
А мясо надо оставить в самом компоненте |
|||
карма: 22 |
|
Ответов: 2125
Рейтинг: 159
|
|||
nesco писал(а): функция отображения и печати у всех разнаяА должна бы быть одинаковой... nesco писал(а): и на кой тогда вообще вызов DrawSource -- предподготовка к выводу, что ли Типа того. Чтобы "мясо" не было зависимым от DrawSource. |
|||
карма: 1 |
|
Разработчик
Ответов: 26163
Рейтинг: 2127
|
|||
tsdima, это получается, что мы должны вынести doDraw в наследников (как это я сейчас сделал), подготовить контекст к отрисовке и вызвать DrawSource родителя, правильно я понял. Тут получится, что мы будем делать несколько ненужных операций по созданию промежуточного контекста отрисовки с уже готовым изображением. И еще, если контекст канвы и принтера очищать не надо, то контекст окна -- обязательно, а значит его надо делать в родителе.
------------ Дoбавленo: Мдяяя уж... Сейчас проверил -- точно нужен промежуточный контекст для принтера с уже готовым, увеличенным рисунком, тогда BitBlt начинает работат, но работает сравнительно быстро (320x240 передавало около 20 сек по сетке) |
|||
карма: 22 |
|
Ответов: 2125
Рейтинг: 159
|
|||
nesco писал(а): вынести doDraw в наследников Мне это кажется более логичным. nesco писал(а): подготовить контекст к отрисовке и вызвать DrawSource родителя, правильно я понялНе совсем. DrawSource это и есть подготовка и выдача контекста перед отрисовкой (задача номер 1), а также очистка и удаление при необходимости после отрисовки (задача номер 2). Получается, что doDraw выглядит примерно так:
Кстати, DrawSource могла бы выполнять и другие задачи, например трансляцию координат (тех, которые хранятся в базовом классе, либо передаваемых как параметр, который в этом случае нужно сделать безтиповым) причём с учётом установленного MapMode, который может быть различным для разных контекстов. В данном случае я имею ввиду принтер. ------------ Дoбавленo: Можно было бы даже освободить разработчика от необходимости указывать DrawSource, если передавать этот тип как тип данных вместе с hWnd/hBitmap/hDC. |
|||
карма: 1 |
|
Разработчик
Ответов: 26163
Рейтинг: 2127
|
|||
tsdima, зачем у тебя указано два вызова DrawSource
Что означает константа nFunc Что мы передаем в _Data, если мы его отдаем, значит обработчик данных должен быть в базе Что подразумевается под ... рисуем на контексте dc ... -- основные функции отрисовки конкретного компонента, так что ли tsdima писал(а): Можно было бы даже освободить разработчика от необходимости указывать DrawSource, если передавать этот тип как тип данных вместе с hWnd/hBitmap/hDCtsdima писал(а): тех, которые хранятся в базовом классе, либо передаваемых как параметр, который в этом случае нужно сделать безтиповым) причём с учётом установленного MapModeТы уж извини, но концепция какя-то мутноватая отрисовывается, для меня, по крайней мере. Самый главный вопрос, который меня беспокоит -- это где применять конкретные методы графической отрисовки , в компоненте или в базе Если не трудно, то напиши по пунктам, что делать с кратким описанием основных методов, что откуда читаем, и что куда передаем, и где чего отрисовываем. |
|||
карма: 22 |
|