unit Drukowanie;

interface

uses Classes,Graphics,Dialogs,SysUtils,Windows,Printers;

type TMarginesy = record
  Lewy,Prawy,Gorny,Dolny :Integer;
end;

function Drukuj(tekst :TStrings;czcionka :TFont;domyslnaDrukarka :Boolean;marginesy :TMarginesy) :Integer; overload;
procedure Drukuj(obraz :TGraphic;zachowajProporcje,domyslnaDrukarka :Boolean;marginesy :TMarginesy); overload;

implementation

function Drukuj(tekst :TStrings;czcionka :TFont;domyslnaDrukarka :Boolean;marginesy :TMarginesy) :Integer;
var
  i,linia :Integer;
  wysokoscCzcionki,wysokoscLinii,szerokoscStrony :Integer;
  PrintDialog :TPrintDialog;
begin
Result:=0;

if not domyslnaDrukarka then
  begin
  PrintDialog:=TPrintDialog.Create(nil);
  if not PrintDialog.Execute then Exit;
  PrintDialog.Free;
  end;

//Ustawianie wielkosci czcionki
Printer.Canvas.Font:=czcionka;

//ustalanie koloru tekstu
Printer.Canvas.Pen.Color:=czcionka.Color;

//Ustalanie wysokosci wiersza na wydruku na podstawie wielkosci czcionki
wysokoscCzcionki:=Printer.Canvas.TextHeight('A');
for i:=0 to tekst.Count-1 do
  if Printer.Canvas.TextHeight(tekst.Strings[i])>wysokoscCzcionki then
    wysokoscCzcionki:=Printer.Canvas.TextHeight(tekst.Strings[i]);

//Wysokosc linii to poltora wysokosci najwyzszej czcionki
wysokoscLinii:=(3*wysokoscCzcionki) div 2;

//lamanie dlugich linii
szerokoscStrony:=Printer.PageWidth-marginesy.Lewy-marginesy.Prawy;
for i:=0 to tekst.Count-1 do
  if Printer.Canvas.TextWidth(tekst.Strings[i])>szerokoscStrony then
    ShowMessage('Linia '+IntToStr(i)+' jest dłuższa niż szerokość strony');

Printer.BeginDoc;
linia:=0;
Result:=1;
for i:=0 to tekst.Count-1 do
  begin
  Printer.Canvas.TextOut(marginesy.Lewy,marginesy.Gorny+linia*wysokoscLinii,tekst.Strings[i]);
  Inc(linia);
  if (marginesy.Gorny+linia*wysokoscLinii)>=(Printer.PageHeight-marginesy.Dolny) then
    begin
    linia:=0;
    Printer.NewPage;
    Inc(Result);
    end;
  end;
Printer.EndDoc;
end;

procedure Drukuj(obraz :TGraphic;zachowajProporcje,domyslnaDrukarka :Boolean;marginesy :TMarginesy);
var
  PrintDialog :TPrintDialog;
  obszar :TRect;
  proporcjeObrazu,proporcjeObszaru :Real;
begin
if not domyslnaDrukarka then
  begin
  PrintDialog:=TPrintDialog.Create(nil);
  if not PrintDialog.Execute then Exit;
  PrintDialog.Free;
  end;

proporcjeObrazu:=obraz.Width/obraz.Height;

//portret/pejzaz
if proporcjeObrazu<1
  then Printer.Orientation:=poPortrait
  else Printer.Orientation:=poLandscape;

//wstepny obszar to cala strona poza marginesami
obszar.Left:=marginesy.Lewy;
obszar.Right:=Printer.PageWidth-marginesy.Prawy;
obszar.Top:=marginesy.Gorny;
obszar.Bottom:=Printer.PageHeight-marginesy.Dolny;
proporcjeObszaru:=(obszar.Right-obszar.Left)/(obszar.Bottom-obszar.Top);

//skalowanie
if zachowajProporcje then
  begin
  if proporcjeObrazu>proporcjeObszaru
    then obszar.Bottom:=obszar.Top+Round((obszar.Right-obszar.Left)/proporcjeObrazu)
    else obszar.Right:=obszar.Left+Round((obszar.Bottom-obszar.Top)*proporcjeObrazu);
  end;

//drukowanie
Printer.BeginDoc;
Printer.Canvas.TextOut(0,0,''); //wymuszenie przygotowania plotna
Printer.Canvas.StretchDraw(obszar,obraz);
Printer.EndDoc;
end;

end.
