Unit uDrawWrappedText;

{$I ..\..\..\Lib\PDFlibDefines.inc}

Interface

Uses
  {$IFDEF XE2+} Winapi.Windows,
  System.Classes,
  System.SysUtils,
  System.StrUtils,
  Vcl.Controls,
  Vcl.StdCtrls,
  Vcl.Forms,
  Vcl.Dialogs,
  Vcl.Graphics,
  Vcl.ExtCtrls,
  Winapi.ShellAPI,
  {$ELSE}
  Windows,
  Classes,
  SysUtils,
  StrUtils,
  Controls,
  StdCtrls,
  Forms,
  Dialogs,
  Graphics,
  ExtCtrls,
  ShellAPI,
  {$ENDIF}
  PDFlibrary;

Type
  TForm1 = Class(TForm)
    Image1: TImage;
    Step1: TButton;
    Step2: TButton;
    Step3: TButton;
    btnPrint: TButton;
    btnBasic: TButton;
    Step4: TButton;
    Procedure Step1Click(Sender: TObject);
    Procedure Step2Click(Sender: TObject);
    Procedure Step3Click(Sender: TObject);
    Procedure btnPrintClick(Sender: TObject);
    Procedure btnBasicClick(Sender: TObject);
    procedure Step4Click(Sender: TObject);
  Private
    { Private declarations }
  Public
    { Public declarations }
  End;

Var
  Form1: TForm1;
Implementation
{$R *.dfm}

Procedure TForm1.Step1Click(Sender: TObject);
Var
  PDF: TPDFlib;
  FontID1, FontID2, FontID3: Integer;
  PStream: TMemoryStream;
Begin
  PDF := TPDFlib.Create;
  Try
    Begin
      PStream := TMemoryStream.Create;
      PDF.SetPageSize('A5');
      PDF.SetOrigin(1);           // Set the origin to the top-left corner
      PDF.SetMeasurementUnits(1); // Set the measurement units to millimeters

      FontID1 := PDF.AddTrueTypeFont('TimesNewRoman {1250}', 1);
      FontID2 := PDF.AddTrueTypeFont('Helvetica {1250}', 1);
      FontID3 := PDF.AddTrueTypeFont('Arial {1250}', 1);

      PDF.SelectPage(1);
      PDF.SelectFont(FontID1);
      PDF.SetTextColor(255, 0, 0);
      PDF.SetTextSize(14);
      PDF.DrawText(5, 12, 'TimesNewRoman: przyjęcie materiału');

      PDF.SelectFont(FontID2);
      PDF.SetTextColor(255, 0, 0);
      PDF.SetTextSize(14);
      PDF.DrawText(5, 22, 'Helvetica: przyjęcie materiału');

      PDF.SelectFont(FontID3);
      PDF.SetTextColor(255, 0, 0);
      PDF.SetTextSize(14);
      PDF.DrawText(5, 32, 'Arial: przyjęcie materiału');

      PDF.DrawLine(0, 37, PDF.PageWidth, 37);

      PDF.NewPage;
      PDF.SelectPage(2);
      PDF.SelectFont(FontID1);
      PDF.SetTextColor(255, 0, 0);
      PDF.SetTextSize(14);
      PDF.DrawText(5, 10, 'Text on page two');

      PDF.SaveToStream(PStream);
      PStream.SaveToFile('MemStream1.dat');
      PStream.Free;
      PDF.SaveToFile('MemStream1.pdf');
      ShowMessage('PageSize: ' + IntToStr(Trunc(PDF.PageWidth)) + ' * ' + IntToStr(Trunc(PDF.PageHeight)) +#13#10 +'Please check MemStream1.pdf')
    End
  Finally
    PDF.Free;
  End;
End;

Procedure TForm1.Step2Click(Sender: TObject);
Var
  PDF: TPDFlib;
  ImageID: Integer;
  Image: TImage;
  PStream, IStream: TMemoryStream;
Begin
  PDF := TPDFlib.Create;
  Try
    Begin
      PStream := TMemoryStream.Create;
      PStream.LoadFromFile('MemStream1.dat');

      PDF.LoadFromStream(PStream, '');
      PDF.SetOrigin(1);
      PDF.SetMeasurementUnits(1); // Set the measurement units to millimeters

      PDF.SelectPage(2);
      Image := TImage.Create(Nil);
      Image.Picture.LoadFromFile('Image1.bmp');
      IStream := TMemoryStream.Create;
      Image.Picture.Bitmap.SaveToStream(IStream);
      ImageID := PDF.AddImageFromStream(IStream, 0);
      PDF.SelectImage(ImageID);

      // PDF.DrawImage(8, 30, 180 * 0.2645833333, 160 * 0.2645833333);
      // if we use the width height value show in Windows, we need to multiply it by 0.2645833333, 1 pixel=0.2645833333 mm
      // if we use Image.Width & Image.Height, do not need to multiply it by 0.2645833333

      PDF.DrawImage(8, 26, Image.Width, Image.Height);
      PStream.Seek(0, soFromBeginning);
      PDF.SaveToStream(PStream);
      PStream.SaveToFile('MemStream2.dat');
      PStream.Free;
      PDF.SaveToFile('MemStream2.pdf');
      ShowMessage('PageSize: ' + IntToStr(Trunc(PDF.PageWidth)) + ' * ' + IntToStr(Trunc(PDF.PageHeight)) +#13#10 +'Please check MemStream2.pdf' )
    End
  Finally
    PDF.Free;
  End;
End;

Procedure TForm1.Step3Click(Sender: TObject);
Var
  PDF: TPDFlib;
  FontID, LineCount, AvailableLine: Integer;
  PStream: TMemoryStream;
  Text: String;
  TextHeight, BoundHeight, AvailabeHeight: double;
Begin
  PDF := TPDFlib.Create;
  Try
    Begin
      PStream := TMemoryStream.Create;
      PStream.LoadFromFile('MemStream2.dat');
      PDF.LoadFromStream(PStream, '');
      PDF.SetOrigin(1);                // Set the origin to the top-left corner
      PDF.SetMeasurementUnits(1);      // Set the measurement units to millimeters
      PDF.SetPageDimensions(148, 210); // A5 page size
      FontID := PDF.AddTrueTypeFont('TimesNewRoman {1250}', 1);


      Text := 'Line 1' +#13#10 + 'Line 2' +#13#10 +   'Line 3' +#13#10 + 'Line 4'  +#13#10 + 'Line 5' +#13#10 + 'Line 6' +#13#10 + 'Line 7';
      PDF.DrawMultiLineText(5, PDF.PageHeight - 120, #13#10, Text);

      PDF.SelectPage(2);
      PDF.SelectFont(FontID);
      PDF.SetTextSize(16);

      PDF.DrawText(5, 20, 'Next text on page two');
      PDF.DrawLine(0, 26, PDF.PageWidth, 26);
      Text := 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas vestibulum fermentum dui, id sagittis mi varius id. Morbi'
        + 'at eros vitae magna lobortis bibendum vitae dignissim lectus. Vestibulum ante ipsum primis in faucibus orci luctus et turpis '
        + 'congue congue. Vivamus nec risus eget ligula ultrices pulvinar eu quis urna. In porta, quam in aliquam porta, eros dui mollis '
        + 'lorem, quis ultricies lorem turpis quis ex. Duis aliquet quam nunc. Donec in dapibus nisi, a malesuada nulla. Praesent nec' +#13#10+#13#10
        + 'euismod felis, sed iaculis nunc. In luctus nulla quis semper posuere. Curabitur eget tempor odio. Phasellus porta hendrerit '
        + 'ante, eu fringilla diam efficitur sit amet. Morbi maximus aliquam vehicula. Nam pellentesque ullamcorper justo, id facilisis '
        + 'nunc viverra ut. Ut convallis porta enim id imperdiet. In urna ipsum, efficitur id consectetur id, ultricies consequat nisi. '
        + 'Nam ac tempor nunc. Nulla in lorem ut nunc cursus fermentum.';

      TextHeight := PDF.GetTextHeight;
      LineCount := PDF.GetWrappedTextLineCount(130, Text); // 130 - The width of the block to wrap the text to, the A5 page width is 148
      BoundHeight := PDF.GetTextBound(2); // Height over baseline because baseline is text start
      AvailabeHeight := 210 - (125 + BoundHeight); // We'll write text at y-coordinate 125, can be adjusted to other suitable value
      AvailableLine := Trunc(AvailabeHeight / TextHeight);

      ShowMessage('All wrapped text line is '+IntToStr(LineCount) + '; Available line is '+IntToStr(AvailableLine) +',' +#13#10+#13#10
        + 'The text is truncated, the second paragraph is not visible');

      PDF.SetTextAlign(3);
      PDF.DrawWrappedText(5, 125 + BoundHeight, 130, Text);  // Here we write text at y-coordinate 128 and wrap at x-coordinate 130
      ShowMessage(PDF.GetWrappedText(130,#13#10, Text));  // 130 - The width of the block to wrap the text to

      PStream.Seek(0, soFromBeginning);
      PDF.SaveToStream(PStream);
      PStream.SaveToFile('MemStream3.dat');
      PStream.Free;
      PDF.SaveToFile('MemStream3.pdf');
      ShowMessage('Please check MemStream3.pdf')
    End
  Finally
    PDF.Free;
  End;
End;


procedure TForm1.Step4Click(Sender: TObject);
Var
  PDF: TPDFlib;
  FontID, LineCount, AvailableLine: Integer;
  PStream: TMemoryStream;
  Text1, Text2: String;
  TextHeight, BoundHeight, AvailabeHeight: double;
Begin
  PDF := TPDFlib.Create;
  Try
    Begin
      PStream := TMemoryStream.Create;
      PStream.LoadFromFile('MemStream2.dat');
      PDF.LoadFromStream(PStream, '');

      PDF.SetOrigin(1);                // Set the origin to the top-left corner
      PDF.SetMeasurementUnits(1);      // Set the measurement units to millimeters
      PDF.SetPageDimensions(148, 210); // A5

      FontID := PDF.AddTrueTypeFont('TimesNewRoman {1250}', 1);
      PDF.SelectFont(FontID);
      PDF.SetTextSize(16);

      Text := 'Line 1' +#13#10 + 'Line 2' +#13#10 +   'Line 3' +#13#10 + 'Line 4'  +#13#10 + 'Line 5' +#13#10 + 'Line 6' +#13#10 + 'Line 7';
      PDF.DrawMultiLineText(5, PDF.PageHeight - 120, #13#10, Text);

      PDF.SelectPage(2);

      PDF.DrawText(5, 20, 'Next text on page two');
      PDF.DrawLine(0, 26, PDF.PageWidth, 26);

      Text1 := 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas vestibulum fermentum dui, id sagittis mi varius id. Morbi'
        + 'at eros vitae magna lobortis bibendum vitae dignissim lectus. Vestibulum ante ipsum primis in faucibus orci luctus et turpis '
        + 'congue congue. Vivamus nec risus eget ligula ultrices pulvinar eu quis urna. In porta, quam in aliquam porta, eros dui mollis '
        + 'lorem, quis ultricies lorem turpis quis ex. Duis aliquet quam nunc. Donec in dapibus nisi, a malesuada nulla. Praesent nec';

      Text2 := 'euismod felis, sed iaculis nunc. In luctus nulla quis semper posuere. Curabitur eget tempor odio. Phasellus porta hendrerit '
        + 'ante, eu fringilla diam efficitur sit amet. Morbi maximus aliquam vehicula. Nam pellentesque ullamcorper justo, id facilisis '
        + 'nunc viverra ut. Ut convallis porta enim id imperdiet. In urna ipsum, efficitur id consectetur id, ultricies consequat nisi. '
        + 'Nam ac tempor nunc. Nulla in lorem ut nunc cursus fermentum.';

      TextHeight := PDF.GetTextHeight;
      LineCount := PDF.GetWrappedTextLineCount(130, Text1); // 130 - The width of the block to wrap the text to, the A5 page width is 148
      BoundHeight := PDF.GetTextBound(2); // Height over baseline because baseline is text start
      AvailabeHeight := 210 - (125 + BoundHeight); // We'll write text at y-coordinate 125, can be adjusted to other suitable value
      AvailableLine := Trunc(AvailabeHeight / TextHeight);

      ShowMessage('All wrapped text line is '+IntToStr(LineCount) + '; Available line is '+IntToStr(AvailableLine)+#13#10#13#10
        +'We already know from previous test what is the last word that fits on the first page.'+#13#10#13#10
        +'So we break the long string from that word and write the reminder texts into next page.');

      PDF.SetTextAlign(3);
      PDF.DrawWrappedText(8, 125 + BoundHeight, 130, Text1); // Here we write text at y-coordinate 125 and wrap at x-coordinate 130
      ShowMessage(PDF.GetWrappedText(130,#13#10, Text1));

      PDF.NewPage;
      PDF.SetTextAlign(3);
      PDF.DrawWrappedText(8, 15 + BoundHeight, 130, Text2);  // On page 3 we write text at y-coordinate 15 and wrap at x-coordinate 130
      ShowMessage(PDF.GetWrappedText(130,#13#10, Text2));

      PStream.Seek(0, soFromBeginning);
      PDF.SaveToStream(PStream);
      PStream.SaveToFile('MemStream4.dat');
      PStream.Free;
      PDF.SaveToFile('MemStream4.pdf');
      ShellExecute(Handle, 'open', 'MemStream4.pdf', Nil, Nil, SW_SHOWNORMAL);
    End
  Finally
    PDF.Free;
  End;
End;

Procedure TForm1.btnPrintClick(Sender: TObject);
Var
  PDFlib: TPDFlib;
  CustPrinter: WideString;
  PrintOpt: Integer;
  PStream: TMemoryStream;
Begin
  PDFlib := TPDFlib.Create;
  PStream := TMemoryStream.Create;
  PStream.LoadFromFile('MemStream3.dat');
  Try
    With PDFlib Do
    Begin
      LoadFromStream(PStream, '');
      CustPrinter := NewCustomPrinter(GetDefaultPrinterName);
      // A5 paper size
      SetupPrinter(CustPrinter, 11, 1);
      ShowMessage('Print Name is:' + CustPrinter +#13#10 + 'Printing orientation is Portrait');
      // Option 11 set the printing orientation, 1 = portrait, 2 = landscape
      // Please refer to the SetupPrinter page in PDFlibReference.pdf
      If SetupPrinter(CustPrinter, 11, 1) = 1
      Then
      Begin
        PrintOpt := PrintOptions(1, 0, 'A5 Portrait Page');
        // Set PageScaling to 1, Fit to paper
        PrintDocument(CustPrinter, 1, PageCount, PrintOpt);
      End;
    End;
  Finally
    PDFlib.Free;
  End;
End;


Procedure TForm1.btnBasicClick(Sender: TObject);
Var
  PDF: TPDFlib;
  FontID, FontID2, FontID3, ImageID: Integer;
  Image: TImage;
  Bitmap: TBitmap;
  PStream, IStream: TMemoryStream;
Begin
  PDF := TPDFlib.Create;
  Try
    Begin
      PDF.SetPageSize('A5');
      PDF.SetOrigin(1);           // Set the origin to the top-left corner
      PDF.SetMeasurementUnits(1); // Set the measurement units to millimeters
      FontID := PDF.AddTrueTypeFont('TimesNewRoman {1250}', 1);
      FontID2 := PDF.AddTrueTypeFont('Helvetica {1250}', 1);
      FontID3 := PDF.AddTrueTypeFont('Arial {1250}', 1);
      PStream := TMemoryStream.Create;
      PDF.SelectPage(1);
      PDF.SelectFont(FontID);
      PDF.SetTextColor(255, 0, 0);
      PDF.SetTextSize(14);
      PDF.DrawText(5, 15, 'TimesNewRoman: I do see serif in letters C c T I');
      PDF.SelectFont(FontID2);
      PDF.SetTextColor(255, 0, 0);
      PDF.SetTextSize(14);
      PDF.DrawText(5, 25, 'Helvetica: przyjęcie materiału.');
      PDF.SelectFont(FontID3);
      PDF.SetTextColor(255, 0, 0);
      PDF.SetTextSize(14);
      PDF.DrawText(5, 35, 'Arial: Letters look ok. Letters C c T I.');
      PDF.DrawLine(0, 45, PDF.PageWidth, 45);

      Showmessage(PDF.GetInstalledFontsByCharset(16,0));

      PDF.SaveToStream(PStream);
      Image := TImage.Create(Nil);
      Image.Picture.LoadFromFile('Image1.bmp');
      IStream := TMemoryStream.Create;
      Image.Picture.Bitmap.SaveToStream(IStream);
      PDF.LoadFromStream(PStream, '');
      PDF.SetOrigin(1);
      ImageID := PDF.AddImageFromStream(IStream, 0);
      PDF.SelectImage(ImageID);
      PDF.DrawImage(8, 120, 180, 160);
      PStream.Seek(0, soFromBeginning);
      PDF.SaveToStream(PStream);
      PDF.LoadFromStream(PStream, '');
      PDF.SetOrigin(1);
      PStream.Seek(0, soFromBeginning);
      PDF.DrawText(8, 280, 'Load an image from memory stream');
      PDF.SaveToStream(PStream);
      IStream.Seek(0, soFromBeginning);
      PDF.RenderPageToStream(96, 1, 0, IStream);
      Bitmap := TBitmap.Create;
      IStream.Seek(0, soFromBeginning);
      Bitmap.LoadFromStream(IStream);
      Image1.Picture.Assign(Bitmap);
      PDF.SaveToFile('fromStream.pdf');
      ShowMessage('Please check fromStream.pdf');
      Bitmap.Free;
      PStream.Free;
      IStream.Free;
    End
  Finally
    PDF.Free;
  End;
End;

End.
