Вверх ↑
Этот топик читают: Гость
Разработчик
Ответов: 26163
Рейтинг: 2127
#31: 2008-03-04 19:25:36 ЛС | профиль | цитата
tsdima, есть предложение снабдить Printer верхней точкой, для чтения и печати различных контекстов, вот тогда можно будет графику в полный рост печатать, хоть с экрана, хоть с bitmap'а

Непонятки возникли у меня только с матрицей пикселей в Img_Point, которая выпадает из общей закономерности, если послать пиксель на принтер я смогу, то вот что читать -- понтия не имею
карма: 22

0
Ответов: 2125
Рейтинг: 159
#32: 2008-03-05 10:53:35 ЛС | профиль | цитата
nesco писал(а):
есть предложение снабдить Printer верхней точкой, для чтения и печати различных контекстов

Контекст - это просто контекст, он не задаёт ни области для рисования, ни других параметров. Я полагал, что вывод графики будет через Img_Bmp, который будет брать контекст для отрисовки так же, как и другие Img_... Собственно, Img_Bmp для этого и предназначен - рисовать картинку.
карма: 1

0
Разработчик
Ответов: 26163
Рейтинг: 2127
#33: 2008-03-05 12:44:22 ЛС | профиль | цитата
tsdima, тут проблема возникла (об ней и в инэте пишут) -- API-функция BitBlt (StretchBlt) не поддерживает контекст принтера, а вот SetPixel, работает, но метод очень медленный.
------------ Дoбавленo:

Только что проверил, действительно функция GetDeviceCaps(Printer.Handle, RC_BITBLT) возвращает 0
И чего теперь
карма: 22

0
Ответов: 2125
Рейтинг: 159
#34: 2008-03-05 13:33:52 ЛС | профиль | цитата
Попробуй GetDeviceCaps(Printer.Handle, RASTERCAPS) и StretchBlt

А ещё не надо забывать пересчитывать координаты для принтера в логические пиксели. Оно может и рисуется, но в невидимой области страницы.

Кроме того, возможно для графики придётся делать SetMapMode(Printer.Handle, MM_TEXT)

карма: 1

0
Разработчик
Ответов: 26163
Рейтинг: 2127
#35: 2008-03-05 13:56:29 ЛС | профиль | цитата
tsdima писал(а):
А ещё не надо забывать пересчитывать координаты для принтера в логические пиксели
Все печатает нормально, но не на физическом устройстве, а на эмуляторе принтера в Office. А вот устройство -- хоть ты сдохни, я уже 7 минут жду вывода рисунка 640х480, 32x32 выводился с полминуты
карма: 22

0
Ответов: 2125
Рейтинг: 159
#36: 2008-03-05 15:38:37 ЛС | профиль | цитата
Я тоже попробовал печать картинки. Вполне так себе быстро. Однако StretchBlt не работает, т.е. растягивать картинку приходится вручную.
Я взял иконку 32х32, растянул до 1000х1000, на бумаге она примерно 4.2х4.2 см, т.е. примерно 600dpi, что соответствует истине.
SetMapMode делать не надо!
карма: 1

0
Разработчик
Ответов: 26163
Рейтинг: 2127
#37: 2008-03-05 17:26:53 ЛС | профиль | цитата
tsdima, ты кодом вывода поделись, через чего выводишь-то на принтер. BitBlt у меня не работает однозначно, а значит, у кого-то может тоже не работать.

tsdima писал(а):
Я взял иконку 32х32, растянул до 1000х1000
Это через промежуточный контекст памяти, ну я так тоже делал. У меня такая иконка долго висит с полминуты (доступ к принтеру по сети, через сервер).

Давай, я выложу компоненты с базовым классом, а ты посмотришь, что с ними можно сделать на предмет быстрой печати. Текст, кстати, тоже на контекст принтера выводиться не хочет

------------ Дoбавленo:


Вот, приклеил, посмотри. Там все, что я успел перевести. Правда, принтеру на выход onPrint вывел его контекст (по аналогии с MainForm)

P.S. Может еще кто поюзает для тестирования багов, да и скорость печати проверит.
карма: 22

0
файлы: 1img_draw.zip [13.9KB] [197]
Ответов: 2125
Рейтинг: 159
#38: 2008-03-05 18:40:41 ЛС | профиль | цитата
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

0
Разработчик
Ответов: 26163
Рейтинг: 2127
#39: 2008-03-05 19:22:30 ЛС | профиль | цитата
tsdima писал(а):
Твоя ошибка, наверное, была в том, что ты использовал SetMapMode(pdc, MM_HIMETRIC), а то, что координата Y растёт в другом направлении - не учёл
Учел, координата y1, к примеру -- y1 := not y1 * 2540 div LOGPIXELSY_; для всех операций контекста.
tsdima писал(а):
А мясо надо оставить в самом компоненте
А на кой черт оно там нужно, когда все, кроме принтера (и то не с прямой отрисовкой, а с контекстами), работает прекрасно, зато код сократился в разы.
Помимо отрицательного у, добивает еще зеркальное изображение при определенном выводе
tsdima писал(а):
либо использовать SetViewportOrgEx(pdc, 0, -PageHeight, nil)
Над этим надо подумать, может это -- к лучшему.
карма: 22

1
Голосовали:Валерий
Ответов: 2125
Рейтинг: 159
#40: 2008-03-06 10:41:38 ЛС | профиль | цитата
nesco писал(а):
А на кой черт оно там нужно

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

карма: 1

0
Разработчик
Ответов: 26163
Рейтинг: 2127
#41: 2008-03-06 11:23:35 ЛС | профиль | цитата
tsdima писал(а):
опять менять базовый класс
Ну и функция отображения и печати у всех разная, что-то одно, а что-то отличается, и сильно отличается.
tsdima писал(а):
Ну да, а при появлении нового компонента
А мы еще чего-то собираемся туда добавлять, за столько-то лет не сильно-то он поменялся? Мне даже градиент пришлось сделать вне базового класса, слишком он специфичен.
tsdima писал(а):
_prop_DrawSource: procedure(var _Data:TData; var dc:HDC; nFunc:word) of object;

А мясо надо оставить в самом компоненте
Вот ты мне объясни, что в таком случае останется в качестве "мяса", чтение координат и контекстов Но ведь и отработка вывода графики разная в базе для каждого подкласса, и на кой тогда вообще вызов DrawSource -- предподготовка к выводу, что ли
карма: 22

0
Ответов: 2125
Рейтинг: 159
#42: 2008-03-06 11:31:51 ЛС | профиль | цитата
nesco писал(а):
функция отображения и печати у всех разная

А должна бы быть одинаковой...

nesco писал(а):
и на кой тогда вообще вызов DrawSource -- предподготовка к выводу, что ли

Типа того. Чтобы "мясо" не было зависимым от DrawSource.
карма: 1

0
Разработчик
Ответов: 26163
Рейтинг: 2127
#43: 2008-03-06 13:16:20 ЛС | профиль | цитата
tsdima, это получается, что мы должны вынести doDraw в наследников (как это я сейчас сделал), подготовить контекст к отрисовке и вызвать DrawSource родителя, правильно я понял. Тут получится, что мы будем делать несколько ненужных операций по созданию промежуточного контекста отрисовки с уже готовым изображением. И еще, если контекст канвы и принтера очищать не надо, то контекст окна -- обязательно, а значит его надо делать в родителе.

------------ Дoбавленo:


Мдяяя уж... Сейчас проверил -- точно нужен промежуточный контекст для принтера с уже готовым, увеличенным рисунком, тогда BitBlt начинает работат, но работает сравнительно быстро (320x240 передавало около 20 сек по сетке)
карма: 22

0
Ответов: 2125
Рейтинг: 159
#44: 2008-03-06 13:37:28 ЛС | профиль | цитата
nesco писал(а):
вынести doDraw в наследников

Мне это кажется более логичным.

nesco писал(а):
подготовить контекст к отрисовке и вызвать DrawSource родителя, правильно я понял

Не совсем. DrawSource это и есть подготовка и выдача контекста перед отрисовкой (задача номер 1), а также очистка и удаление при необходимости после отрисовки (задача номер 2).
Получается, что doDraw выглядит примерно так:

#pas
begin
_prop_DrawSource(_Data, dc, 1);
... рисуем на контексте dc ...
_prop_DrawSource(_Data, dc, 2);
end;
------------ Дoбавленo:

Кстати, DrawSource могла бы выполнять и другие задачи, например трансляцию координат (тех, которые хранятся в базовом классе, либо передаваемых как параметр, который в этом случае нужно сделать безтиповым) причём с учётом установленного MapMode, который может быть различным для разных контекстов. В данном случае я имею ввиду принтер.
------------ Дoбавленo:

Можно было бы даже освободить разработчика от необходимости указывать DrawSource, если передавать этот тип как тип данных вместе с hWnd/hBitmap/hDC.
карма: 1

0
Разработчик
Ответов: 26163
Рейтинг: 2127
#45: 2008-03-06 16:16:37 ЛС | профиль | цитата
tsdima, зачем у тебя указано два вызова DrawSource
Что означает константа nFunc
Что мы передаем в _Data, если мы его отдаем, значит обработчик данных должен быть в базе
Что подразумевается под ... рисуем на контексте dc ... -- основные функции отрисовки конкретного компонента, так что ли
tsdima писал(а):
Можно было бы даже освободить разработчика от необходимости указывать DrawSource, если передавать этот тип как тип данных вместе с hWnd/hBitmap/hDC
Ну мне непонятно, как передать и определить разницу между hWnd и hDC -- использовать разницу типов, я правильно понял Интересно, что контекст принтера передается в Real
tsdima писал(а):
тех, которые хранятся в базовом классе, либо передаваемых как параметр, который в этом случае нужно сделать безтиповым) причём с учётом установленного MapMode
Как получить MapMode у принтера, через отдельную точку, так, или "как"
Ты уж извини, но концепция какя-то мутноватая отрисовывается, для меня, по крайней мере.

Самый главный вопрос, который меня беспокоит -- это где применять конкретные методы графической отрисовки , в компоненте или в базе
Если не трудно, то напиши по пунктам, что делать с кратким описанием основных методов, что откуда читаем, и что куда передаем, и где чего отрисовываем.
карма: 22

0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)