#1 2017-06-14 09:38:40

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

Can I call RenderMetaFile multiple times on the same page

I'm trying to implement a "multiple pages per sheet" feature for my PDF output.  I'm currently rendering a single metafile to each page of the PDF document, calling TPdfCanvas.RenderMetaFile to achieve that.  It works a treat.

However, I'm not trying to call this function multiple times on the same page with no luck.  I'm seeing nothing at all in the generated PDF, or sometimes just a couple of parts of one of the metafiles.  But certainly not multiple metafile graphics around the page.

Before I carry on, is this something that I can expect to do, or do I need to find another approach?  I know that I can create my own metafile canvas, render my metafiles to that canvas, and finally render the composite metafile to the PDF document with a single call to TPdfCanvas.RenderMetaFile.  I was hoping to avoid having to use that extra metafile to prepare my pages.

If I should be able to call TPdfCanvas.RenderMetaFile multiple times per page, and you'd like to dig into this, I'll prepare a reproduction of the issue.  I've not done that yet because it would take a little while to extract it from my complex application code.  And I didn't want to spend that time if the answer was a simple, "this can never work, do it a different way".

Offline

#2 2017-06-14 10:41:58

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

Re: Can I call RenderMetaFile multiple times on the same page

Hmm, I think I'm going to have to make a small reproduction. The issue seems perhaps to be related to the inclusion of text in the metafile.  Without that, behaviour is fine.  Let me put together a reproduction.

Offline

#3 2017-06-14 12:27:28

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

Re: Can I call RenderMetaFile multiple times on the same page

Why not just play the TMetaFile on the main metafile, just like any TGraphic?
Then call RenderMetaFile once.

From my tests, it should work.

Offline

#4 2017-06-14 12:31:10

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

Re: Can I call RenderMetaFile multiple times on the same page

I'm not sure what you mean by "the main metafile".  Anyway, I'm working on a repro.  No point doing any more until I have something concrete.

Last edited by davidheffernan (2017-06-14 12:31:47)

Offline

#5 2017-06-14 12:44:18

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

Re: Can I call RenderMetaFile multiple times on the same page

OK, here's a simple reproduction:

program RenderMetafile;

{$APPTYPE CONSOLE}

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

var
  Doc: TPdfDocument;
  Page: TPdfPage;
  Metafile: TMetafile;
  Canvas: TMetafileCanvas;
  i: Integer;
begin
  Metafile := TMetafile.Create;
  Metafile.SetSize(200, 200);
  Canvas := TMetafileCanvas.Create(Metafile, GetDC(0));
  Canvas.TextOut(10, 10, 'SynPDF is the best!');
  Canvas.Free;

  Doc := TPdfDocument.Create;
  Doc.DefaultPaperSize := psA4;
  Page := Doc.AddPage;
  Page.PageLandscape := False;
  for i := 1 to 20 do begin
    Doc.Canvas.RenderMetaFile(Metafile, 1.0, 0.0, 20.0, i*20.0);
  end;
  Doc.SaveToFile('test.pdf');
  Doc.Free;
end.

There should be 20 instances of the text of the page, but there is just the first one.  If instead of the TextOut, I make a call to MoveTo/LineTo, then multiple instances of the line appear.

Offline

#6 2017-06-14 12:50:01

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

Re: Can I call RenderMetaFile multiple times on the same page

RenderMetaFile is not expected to be called more than once on a page, I guess.

But you can play your MetaFile text content several times.
The easiest way is to use TPdfDocumentGDI, not plain TPdfDocument, and draw the MetaFile text content on its VCL canvas.
As an alternative, you may create a new metafile, on which you draw the MetaFile text content several times.

Offline

#7 2017-06-14 14:37:30

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

Re: Can I call RenderMetaFile multiple times on the same page

Isn't this a bug though. Why would it be possible to use RenderMetafile multiple times, apart from when there is text? It feels like the metafile enumeration code is failing to handle text properly.

Offline

#8 2017-06-14 15:46:54

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

Re: Can I call RenderMetaFile multiple times on the same page

It may be a bug, you are right.
But we never observed it up to now - this is not how we use RenderMetaFile.
Using TPdfDocumentGDI has other advantages, like ability to have a preview, and direct use of the VCL canvas.

Did you try to debug and find out why you don't obtain what you expect?
Isn't any problem with the offset?
Did you try to let uncompressed pdf be generated and inspect the resulting postscript commands?

Offline

#9 2017-06-14 16:02:25

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

Re: Can I call RenderMetaFile multiple times on the same page

I'm actually mixing metafiles and raster images. For the former, I can, as you say, use TPdfDocumentGDI and render the metafile to the VCL canvas. That seems to have no problems with multiple metafiles.  For my raster images, I think it is better to use AddXObject and DrawXObject because that embeds the image in the document, which can be stretched appropriately by the PDF render process. A bit of a fankle, but I think I can make it work!

Offline

Board footer

Powered by FluxBB