Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.07.23;
Скачать: CL | DM;

Вниз

принтер - точное позиционирование   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.06 c
3-1147858011
BorisMor
2006-05-17 13:26
2006.07.23
Процедуры в InterBase


1-1149756373
D@Nger
2006-06-08 12:46
2006.07.23
Сравнение дат


3-1147876311
S@shka
2006-05-17 18:31
2006.07.23
Сбросить данные из таблицы в файл.


2-1151952980
HF-Trade
2006-07-03 22:56
2006.07.23
Взять данные со странички....


15-1150941036
Perwomai
2006-06-22 05:50
2006.07.23
Футбол и национализм