#1 2013-10-16 14:49:10

davidheffernan
Member
Registered: 2013-05-16
Posts: 22

Oddity when calling RenderMetaFile

Consider the following program:

program PdfTest;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.Classes,
  Winapi.Windows,
  Vcl.Graphics,
  SynCommons in 'Synopse\SynCommons.pas',
  SynLZ in 'Synopse\SynLZ.pas',
  SynPdf in 'Synopse\SynPdf.pas';

var
  Doc: TPdfDocument;
  Page: TPdfPage;
  Metafile: TMetafile;
  Canvas: TMetafileCanvas;
begin
  // create test metafile
  Metafile := TMetafile.Create;
  Metafile.SetSize(700, 700);
  Canvas := TMetafileCanvas.Create(Metafile, GetDC(0));
  Canvas.MoveTo(0, 0);
  Canvas.LineTo(700, 700);
  Canvas.MoveTo(0, 700);
  Canvas.LineTo(700, 0);
  Canvas.Free;

  // create page in portrait orientation, and render metafile to it
  Doc := TPdfDocument.Create;
  Doc.DefaultPaperSize := psA4;
  Page := Doc.AddPage;
  Page.PageLandscape := False;
  Doc.Canvas.RenderMetaFile(Metafile);
  Doc.SaveToFile('_portrait.pdf');

  // same again, but with landscape orientation
  Doc := TPdfDocument.Create;
  Doc.DefaultPaperSize := psA4;
  Page := Doc.AddPage;
  Page.PageLandscape := True;
  Doc.Canvas.RenderMetaFile(Metafile);
  Doc.SaveToFile('_landscape.pdf');
end.

This emits two PDF files that are meant to contain a simple cross.  The portrait orientation version comes out correctly.  The landscape orientation does not.

I tracked this down to the fact that TPdfCanvas.SetPage is called from AddPage.  And this caches the height of the the page:

procedure TPdfCanvas.SetPage(APage: TPdfPage);
begin
  FPage := APage;
  FPageFontList := FPage.GetResources('Font');
  FContents := TPdfStream(FPage.ValueByName('Contents'));
  FHeight := FPage.GetPageHeight;  <-----  UH OH!
  FFactor := 72/FDoc.FScreenLogPixels; // PDF expect 72 pixels per inch
end;

Then when we subsequently change orientation, the page height is changed, but FHeight is not updated.

I guess I can solve my problem by throwing in a call to TPdfCanvas.SetPage immediately before I call RenderMetafile.  Is that what I am supposed to do?  Is there a better way to solve my problem?  Is the library behaving as designed?  Do you mean to cache FPage.GetPageHeight and then not update it later?

Thanks!

Offline

#2 2013-10-16 16:07:24

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,238
Website

Re: Oddity when calling RenderMetaFile

No, this is a bug, not feature!
smile

We have fixed mixed portrait/landscape page rendering within a same document - including associated regression tests.
See http://synopse.info/fossil/info/be15825916

Hope it works as expected now.

Offline

#3 2013-10-16 16:50:25

davidheffernan
Member
Registered: 2013-05-16
Posts: 22

Re: Oddity when calling RenderMetaFile

Thanks!  I'll check this all out tomorrow.

Offline

#4 2013-10-17 18:59:38

davidheffernan
Member
Registered: 2013-05-16
Posts: 22

Re: Oddity when calling RenderMetaFile

Thanks Arnaud, that sorts the problem out and I can now remove my workaround.

Offline

Board footer

Powered by FluxBB