Форум: "Основная";
Текущий архив: 2006.07.23;
Скачать: [xml.tar.bz2];
Внизпринтер - точное позиционирование Найти похожие ветки
← →
Urvin (2006-06-08 16:54) [0]Необходимо совершить точное позиционирование рисованных объектов на принтере, т.е., например, вывести прямоугольник размером сантиметр на сантиметр на расстоянии по два сантиметра с верохнего и левого края листа.
нашел следующий код, но он позволяет только добиться правильных размеров прямоугольника.printer.BeginDoc;
SetMapMode(printer.Canvas.Handle, MM_LOMETRIC);
printer.Canvas.rectangle(200,-200,300,-300);
printer.EndDoc;
как добиться правильного размещения этого прямоугольника на листе?
← →
Amoeba © (2006-06-08 17:21) [1]Чтобы этого добиться, надо при расчете координат вводить поправку на размер полей на листе, которые недоступны принтеру для печати (координаты отсчитываются относительно области листа, на которую принтер можнт что-либо печатать).
← →
Urvin (2006-06-08 17:27) [2]Amoeba, дык в том и вопрос! не пользователю же с линейкой ползать по листу и вбивать значения полей!
← →
Virgo_Style © (2006-06-08 18:29) [3]см. в эту сторону (кусок из старой программы... могу что-то забыть или напутать)
//dpi:
dpiX :=GetDeviceCaps(Printer.Handle, LogPixelsX);
dpiY :=GetDeviceCaps(Printer.Handle, LogPixelsY);
//размеры логические:
logX :=GetDeviceCaps(Printer.Handle, HORZRES);
logY :=GetDeviceCaps(Printer.Handle, VERTRES);
//мертвая зона в... в чем? afair, пиксели
offX :=GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX);
offY :=GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY);
//физические размеры... вроде тоже пикселиphsX :=GetDeviceCaps(Printer.Handle, PHYSICALWIDTH);
phsY :=GetDeviceCaps(Printer.Handle, PHYSICALHEIGHT);
// итого мертвая зона (поля т.е.) в пикселях:
DZLeft:=offX ;
DZTop:= offY;
DZRight:= phsX-logX-offX;
DZBottom:=phsY-logY-offY;
еще раз предупреждаю - проверь... но общее направление вроде такое. И вроде даже получалось %-)
← →
Sergey Masloff (2006-06-08 20:23) [4]Да без разницы зоны. Принтеры разные все равно если в точные бланки надо впечатывать автоматом не получится. Все равно придется в настройках пользователя дельту хранить - смещения левого верхнего угла по x и y
← →
Джо © (2006-06-08 20:27) [5]> [4] Sergey Masloff (08.06.06 20:23)
Отчего же? Определяешь с помощью GetDeviceCaps PHYSICALOFFSET"ы и их уже можешь вычитать из координат для печати.
← →
Urvin (2006-06-08 20:38) [6]Sergey Masloff тот же ворд работает без запросов пользователя на вбивание смещений!
всем спасибо! иду прововать!
← →
Sergey Masloff (2006-06-08 21:35) [7]Urvin (08.06.06 20:38) [6]
>тот же ворд работает без запросов пользователя на вбивание смещений
Извини, но это можешь бабушке своей рассказывать
Джо © (08.06.06 20:27) [5]
>Отчего же? Определяешь с помощью GetDeviceCaps PHYSICALOFFSET"ы
Да это все хорошо. Относительно того что драйвер тебе рассказал ты отпозиционируешься. А что у принтера лоток кривой и смещен тоже он сообщит?
К сожалению как показывает мой опыт (печать пары миллионов полисов страхования туристов и почти столько же автострахования на типографских бланках в тысячах точек извините за попытку мерянья) - не хватает программных настроек. Всегда нужно пользователю давать возможность подкорректировать.
← →
Джо © (2006-06-08 21:52) [8]> [7] Sergey Masloff (08.06.06 21:35)
> Да это все хорошо. Относительно того что драйвер тебе рассказал
> ты отпозиционируешься. А что у принтера лоток кривой и смещен
> тоже он сообщит?
> К сожалению как показывает мой опыт (печать пары миллионов
> полисов страхования туристов и почти столько же автострахования
> на типографских бланках в тысячах точек извините за попытку
> мерянья) - не хватает программных настроек. Всегда нужно
> пользователю давать возможность подкорректировать.
Тут я, конечно, согласен. В моей собственной программе при печати на бланках тоже это было предусмотрено, ибо даже не столько лоток иногда по-разному подает в разных экземплярах принтеров одной марки, но, как я заметил, в бланках разных серий обрез бумаги тоже по-разному проходит. С этим всем согласен, как и с необходимостью такую настройку пользователю предоставить. Просто неверно понял, сорри.
← →
Джо © (2006-06-08 21:55) [9]Кстати, когда-то видел довольно серьезную программу (под Windows), которую перед использованием возможности печати необходимо было откалибровать. То есть, она печатала шаблон, ты его аккуратно мерял линеечкой или измерителем и вводил свои значения, в т.ч, отступы от краев и т.п. :)
← →
Urvin (2006-06-09 09:11) [10]Реализация в коде получилась следующая:
procedure TForm1.Button1Click(Sender: TObject);
var
logX, logY,offX,offY,phsX,phsY,dpiX,dpiY: integer;
DZLeft,DZTop,DZRight, DZBottom: integer;
const
mmpi: single = 25.4; //Константа количества миллиметров в дюйме
begin
printer.Title:="Printer test page";
printer.BeginDoc;
//Устанавливаем логическую единицу размера
//Одна единица - 0.1 миллиметра
//Координаты отсчитываются с верхнего левого края
//вправо и вверх (!)
SetMapMode(printer.Canvas.Handle, MM_LOMETRIC);
//Вычисление количества пикселей на дюйм
dpiX :=GetDeviceCaps(Printer.Handle, LogPixelsX);
dpiY :=GetDeviceCaps(Printer.Handle, LogPixelsY);
//Логические размеры печатаемой области
logX :=GetDeviceCaps(Printer.Handle, HORZRES);
logY :=GetDeviceCaps(Printer.Handle, VERTRES);
//мертвая зона левого и верхнего краев листа
offX :=GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX);
offY :=GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY);
//физические размеры листа в пикселях
phsX :=GetDeviceCaps(Printer.Handle, PHYSICALWIDTH);
phsY :=GetDeviceCaps(Printer.Handle, PHYSICALHEIGHT);
//вычисленная в логических единицах мертвая зона
DZLeft:= round(10 * mmpi * offX / dpiX);
DZTop:= round(10 * mmpi * offY / dpiY);
DZRight:= round(10 * mmpi * (phsX-logX-offX) / dpiX);
DZBottom:=round(10 * mmpi * (phsY-logY-offY) / dpiY);
with printer.Canvas do
begin
//Выводим четыре квадрата по краям листа с поправкой на мертвую зону
rectangle(0 -DZLeft, 0 +DZTop, 200-DZLeft, -200+DZTop);
rectangle(1900-DZLeft ,0 +DZTop ,2100-DZLeft,-200 +DZTop);
rectangle(0 -DZLeft ,-2770+DZTop ,200 -DZLeft,-2970+DZTop);
rectangle(1900-DZLeft ,-2770+DZTop ,2100-DZLeft,-2970+DZTop);
//И проведем через их середины линии
MoveTo(100-DZLeft,-100+DZTop); LineTo(2000-DZLeft,-100+DZTop);
MoveTo(100-DZLeft,-100+DZTop); LineTo(100-DZLeft,-2870+DZTop);
MoveTo(2000-DZLeft,-100+DZTop); LineTo(2000-DZLeft,-2870+DZTop);
MoveTo(100-DZLeft,-2870+DZTop); LineTo(2000-DZLeft,-2870+DZTop);
//Установим шрифт высотой 5 миллиметров
Font.Height := 50;
Font.Name := "Verdana";
//Выведем текст позиционируя без поправки на мертвую зону
TextOut(250, - 110, "Printer test page " + printer.Printers[printer.PrinterIndex]);
TextOut(250, - 180, "Death zone: Upper(" + FloatToStr(DZLeft/10) + ", " + FloatToStr(DZTop/10) + ") "
+ "Lower(" + FloatToStr(DZRight/10) + ", " + FloatToStr(DZBottom/10) + ")" );
//Нарисуем линию длиной в 7.5 сантиметров без поправки на мертвую зону
MoveTo(250, - 240);
LineTo(1000, - 240);
end;
printer.EndDoc;
end;
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2006.07.23;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.013 c