Unit printdialog;

{$mode objfpc}{$H+}

Interface

Uses
  Classes, SysUtils, FileUtil, LResources, Printers, PrintersDlgs, Forms, Controls, Graphics, Dialogs,
  ExtCtrls, Spin, Buttons, StdCtrls, CADEngine, tpg, Dispatcher;

Type

  { TPrintDialogForm }

  TPrintDialogForm = Class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    WhitePaperCheckBox: TCheckBox;
    Panel1: TPanel;
    OrientationRadioGroup: TRadioGroup;
    PrintDialog: TPrintDialog;
    PrinterSetupDialog: TPrinterSetupDialog;
    PrintLineSpinEdit: TSpinEdit;
    PrintSpeedButton: TSpeedButton;
    WSpinEdit: TSpinEdit;
    HSpinEdit: TSpinEdit;
    Procedure FormClose(Sender: TObject; Var CloseAction: TCloseAction);
    Procedure PrintSpeedButtonClick(Sender: TObject);
    Procedure WSpinEditChange(Sender: TObject);
  Private
    { private declarations }
  Public
    { public declarations }
  End;

Var
  PrintDialogForm: TPrintDialogForm;

Implementation
Uses Unit1;

{ TPrintDialogForm }

Procedure TPrintDialogForm.PrintSpeedButtonClick(Sender: TObject);
Var PrintDrawer:TDrawer;
    I,J:Longint;
    K:Extended; //Screen pixel to printer pixel ratio
    XC1,YC1,Xc,Yc:Longint;
    x1,x2,y1,y2:Longint;
    wx1,wx2,wy1,wy2:Extended;
    WXc,WYc:Extended;
    BGColor:String;
begin
//  PrintDialog.Options.
  Case OrientationRadioGroup.ItemIndex Of
  0: Printer.Orientation:=poLandscape;
  1: Printer.Orientation:=poPortrait;
  End;

//If Not PrinterSetupDialog.Execute Then Exit;
  If Not PrintDialog.Execute Then Exit;
  PrintDrawer:=TDrawer.Create(Printer.Canvas);
  LogMessage(5,IntToStr(Printer.PageWidth));
  LogMessage(5,IntToStr(Printer.XDPI));

  K:=Printer.PageHeight*HSpinEdit.Value/Drawer.Wy;

{  // landscape 2 landscape - short Dst edge/short Src edge
  If (Drawer.Wx/Drawer.Wy>1) And (Printer.PageWidth/Printer.PageHeight>1) Then Begin
    R:=Printer.PageHeight/Drawer.Wy;
    Drawer.
    Scene.Drawer.ExecCommand('SetColor clRed',ZeroAcc);
    Scene.Drawer.ExecCommand('Rect ',ZeroAcc);
  End;
  // landscape 2 portrait - long Dst edge/short Src edge
  If (Drawer.Wx/Drawer.Wy>1) And (Printer.PageWidth/Printer.PageHeight<1) Then R:=Printer.PageHeight/Drawer.Wy;
  // portrait 2 landscape - long Dst edge/short Src edge
  If (Drawer.Wx/Drawer.Wy<1) And (Printer.PageWidth/Printer.PageHeight>1) Then R:=Printer.PageWidth/Drawer.Wx;
  // portrait 2 portrait - short Dst edge/short Src edge
  If (Drawer.Wx/Drawer.Wy<1) And (Printer.PageWidth/Printer.PageHeight<1) Then R:=Printer.PageWidth/Drawer.Wx;
 }
  //Xc Yc - координаты в пространстве пикселов экрана которые пересчитываются в мировые, чтобы быть подставленными в drawer принтера
  XC1:=Round((Drawer.Wx-WSpinEdit.Value*Printer.PageWidth/K)/2+Printer.PageWidth/2/K);
  YC1:=Round(Drawer.Wy/(2*HSpinEdit.Value));
  BGColor:=Scene.BGColor;
  If WhitePaperCheckBox.Checked Then Scene.BGColor:='clWhite';
  For I:=0 To WSpinEdit.Value-1 Do
    For J:=0 To HSpinEdit.Value-1 Do Begin
      Xc:=Round(Xc1+I*Printer.PageWidth/K);
      Yc:=Round(Yc1+J*Printer.PageHeight/K);
      Drawer.StoW(Xc,Yc,Wxc,Wyc);

      X1:=Round(Xc-Printer.PageWidth/K/2);
      X2:=Round(Xc+Printer.PageWidth/K/2);
      Y1:=Round(Yc-Printer.PageHeight/K/2);
      Y2:=Round(Yc+Printer.PageHeight/K/2);

      Drawer.StoW(X1,Y1,Wx1,Wy1);
      Drawer.StoW(X2,Y2,Wx2,Wy2);

      PrintDrawer.ViewX:=Wxc;
      PrintDrawer.ViewY:=Wyc;
      PrintDrawer.ViewScale:=Form1.ViewScaleEdit.Value/K;
      PrintDrawer.ViewAngle:=Form1.ViewAngleEdit.Value/180*pi;
      PrintDrawer.Wx:=Printer.PageWidth;
      PrintDrawer.Wy:=Printer.PageHeight;
      PrintDrawer.RecalcMatrix;
      Scene.Drawer:=PrintDrawer;
      Scene.UpdateScreenShell(PrintDrawer);
      Scene.UpdateVisibility;
      PrintDrawer.PrintMultiplier:=PrintLineSpinEdit.Value;
      Printer.BeginDoc;
      Scene.DrawScene(False);
      Printer.EndDoc;
    End;
  PrintDrawer.Free;
  Scene.BGColor:=BGColor;
  Scene.Drawer:=Drawer;
  Scene.UpdateScreenShell(Drawer);
  Scene.UpdateVisibility;

end;

Procedure TPrintDialogForm.FormClose(Sender: TObject;
  Var CloseAction: TCloseAction);
Begin
  RubberDisplayList.Clear;
  CloseAction:=caHide;
  RepaintView;
end;

Procedure TPrintDialogForm.WSpinEditChange(Sender: TObject);
Var I,J:Longint;
    K:Extended; //Screen pixel to printer pixel ratio
    XC1,YC1,Xc,Yc:Longint;
    x1,x2,y1,y2:Longint;
    wx1,wx2,wy1,wy2:Extended;
    WXc,WYc:Extended;
Begin
  Case OrientationRadioGroup.ItemIndex Of
  0: Printer.Orientation:=poLandscape;
  1: Printer.Orientation:=poPortrait;
  End;
  K:=Printer.PageHeight*HSpinEdit.Value/Drawer.Wy;
  XC1:=Round((Drawer.Wx-WSpinEdit.Value*Printer.PageWidth/K)/2+Printer.PageWidth/2/K);
  YC1:=Round(Drawer.Wy/(2*HSpinEdit.Value));
  RubberDisplayList.Clear;
  For I:=0 To WSpinEdit.Value-1 Do
    For J:=0 To HSpinEdit.Value-1 Do Begin
      Xc:=Round(Xc1+I*Printer.PageWidth/K);
      Yc:=Round(Yc1+J*Printer.PageHeight/K);
      Drawer.StoW(Xc,Yc,Wxc,Wyc);

      X1:=Round(Xc-Printer.PageWidth/K/2);
      X2:=Round(Xc+Printer.PageWidth/K/2);
      Y1:=Round(Yc-Printer.PageHeight/K/2);
      Y2:=Round(Yc+Printer.PageHeight/K/2);

      Drawer.StoW(X1,Y1,Wx1,Wy1);
      Drawer.StoW(X2,Y2,Wx2,Wy2);

      RubberDisplayList.Add('SetColor clRed');
      RubberDisplayList.Add('SetBGColor clWhite');
      RubberDisplayList.Add('SetWidth 5');
      RubberDisplayList.Add('Rect '+FloatToStr(wx1)+','+FloatToStr(wy1)+','+FloatToStr(wx2)+','+FloatToStr(wy2));

    End;

  RepaintView;

end;

Initialization
  {$I printdialog.lrs}

End.

