Jump to content
uligerhardt

Add text to existing metafile

Recommended Posts

I have an existing enhanced TMetafile in memory (technically speaking an array of them - it's a print preview) and want to add some text to it (page numbers). How can I best achieve that?

 

First I tried creating a TMetafileCanvas for the MF and added my text. But creating the TMetafileCanvas clears the existing MF, so no luck. Could I supress the clearing somehow?

 

The next idea was to clone the original MF:

    OrigMF := // my metafile in memory
    CloneMF := TMetafile.Create;
    try
      CloneMF.Assign(OrigMF);
      MFCanvas := TMetafileCanvas.Create(CloneMF, 0);
      try
        MFCanvas.Draw(0, 0, OrigMF);
        // Draw my stuff on MFCanvas
      finally
        MFCanvas.Free;
      end;
      OrigMF.Assign(CloneMF);
    finally
      CloneMF.Free;
    end;

but I didn't manage to preserve the page dimensions, font sizes etc. The reference DC used to create OrigMF is gone and the combinations of properties like Width, MMWidth and Inch that I tried didn't help.

How could I clone OrigMF retaining these informations (that must be stored inside)? 

 

PS: While writing this post I managed to dig out a reference DC that worked. But answers would be still interesting.

Share this post


Link to post

I don't know if this is covered in the documentation (I can't find it), but in TMetaFile's source code is the following comment:

Quote

      To create a metafile image from scratch, you must draw the image in
      a metafile canvas.  When the canvas is destroyed, it transfers the
      image into the metafile object provided to the canvas constructor.
      After the image is drawn on the canvas and the canvas is destroyed,
      the image is 'playable' in the metafile object.  Like this:

 

      MyMetafile := TMetafile.Create;
      MyMetafile.Width := 200;
      MyMetafile.Height := 200;
      with TMetafileCanvas.Create(MyMetafile, 0) do
      try
        Brush.Color := clRed;
        Ellipse(0,0,100,100);
        ...
      finally
        Free;
      end;
      Form1.Canvas.Draw(0,0,MyMetafile);  (* 1 red circle  *)

 

      To add to an existing metafile image, create a metafile canvas
      and play the source metafile into the metafile canvas
.  Like this:

 

      (* continued from previous example, so MyMetafile contains an image *)
      with TMetafileCanvas.Create(MyMetafile, 0) do
      try
        Draw(0,0,MyMetafile);
        Brush.Color := clBlue;
        Ellipse(100,100,200,200);
        ...
      finally
        Free;
      end;

      Form1.Canvas.Draw(0,0,MyMetafile);  (* 1 red circle and 1 blue circle *)

 

So, you just need to Draw() the existing TMetaFile onto the TMetafileCanvas before drawing anything else onto the Canvas - hmmm, but you are already doing that!

 

Looking at the docs and the source code, TMetafileCanvas should not be clearing anything in the TMetaFile at all.  Also, the ReferenceDC in the TMetaFileCanvas constructor can be 0, in which case the screen HDC will be used instead.

 

Based on the info above, you don't need a clone at all, since modifications made to the Canvas will be applied to the original TMetaFile only when the Canvas is destroyed, eg:

OrigMF := // my metafile in memory
MFCanvas := TMetafileCanvas.Create(OrigMF, 0);
try
  MFCanvas.Draw(0, 0, OrigMF);
  // Draw my stuff on MFCanvas
finally
  MFCanvas.Free;
end;

 

  • Thanks 1

Share this post


Link to post
21 hours ago, Remy Lebeau said:

I don't know if this is covered in the documentation (I can't find it), but in TMetaFile's source code is the following comment:

 

Thanks, I didn't see that comment. And indeed it mostly works without the cloning. However without passing a reference DC <> 0 resolution/size still get mixed up. But as mentioned in my postscriptum I found a compatible DC, so that's only a cosmetic problem. :-))

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×