DELPHI AREA
MESSAGE BOARD
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

TPrintPreview: Supply the page EMF files directly?

 
   Reply to topic    DELPHI AREA Forum Index -> DELPHI AREA's Products
View previous topic :: View next topic  
Author Message
sbussinger
Member


Joined: 02 Jul 2004
Posts: 8

PostPosted: 02/08/04 17:15    Post subject: TPrintPreview: Supply the page EMF files directly? Reply with quote

In my application I'm displaying a few special pages first, then I have 6 EMF files that represent replacement manual pages to be printed (they're print images of printouts from Word captured as EMF files). The 6 EMF files total about 500 KB. Currently I am simply using PaintGraphicEx() to paint the existing EMF files onto the canvas for each page. This works but is rather slow (about 2 seconds per page) and has HUGE memory requirements (the temp file created is over 100 MB and the process memory is almost as big).

I'm wondering if it's possible to somehow stuff the existing EMF files into TPrintPreview without reprocessing them? Since I know how big the EMF files need to be I assume its the act of painting them onto the canvas that converts them to simple bitmaps and consuming all the memory.

In a quick look at the code, it appears that if I expose the TPrintPreview.FPages as a property that I could then use the .Add() method to add metafiles directly. Is there a better way to do this that doesn't require changing the source? Are there any problems I'll encounter by doing this?

Thanks for any suggestions!
Back to top
View user's profile
sbussinger
Member


Joined: 02 Jul 2004
Posts: 8

PostPosted: 02/08/04 17:25    Post subject: Reply with quote

I decided to give what I described a try and it appears to work on the screen, but printing the added pages just results in a blank sheet.
Back to top
View user's profile
Kambiz
Administrator


Joined: 07 Mar 2003
Posts: 412
Location: Tehran, Iran

PostPosted: 02/08/04 19:06    Post subject: Reply with quote

You should draw the images, because they need to be scaled to the printer's resolution.
Back to top
View user's profile Send e-mail Visit poster's website
sbussinger
Member


Joined: 02 Jul 2004
Posts: 8

PostPosted: 02/08/04 19:34    Post subject: Reply with quote

But the EMF files I'm using are already a scalable vector image that's resolution independent, right? That's why you use them yourself. All I'm trying to do is eliminate the step of converting an EMF to a bitmap to draw it into a EMF so that TPrintPreview can convert it to a bitmap again for printing.

Like I mentioned, this process is both slow and is very resource intensive. I'm going from less than half a megabyte of source files to over 100 megabytes of temp file and on older systems, it really has an effect.

My simple changes work fine on the screen, it's just printing that's failing. I'll play with it a bit and see if I can figure out why they don't print.
Back to top
View user's profile
sbussinger
Member


Joined: 02 Jul 2004
Posts: 8

PostPosted: 02/08/04 22:51    Post subject: Reply with quote

I just noticed this comment in the change log for TPrintPreview:

Quote:
Version 4.34 (December 8, 2003) Now, a page on the preview can be altered by assigning a metafile to it.


This is precisely what I needed and I didn't need any other changes to TPrintPreview. I just created empty pages and then assigned my EMF file with something like MyTPrintPreview[x].Assign(MyTMetafile).

The only problem is that it doesn't really work right. The metafile isn't StretchDrawn correctly onto the page. Are there some particular requirements for the Metafile that is assigned?

If it's in FastPrint mode, the output looks OK, but it's not stretched to the printer printable area (i.e. if the MMHeight and MMWidth are larger than the printable area on the current printer, then the output is cropped rather than shrunk to fit). If it's not in FastPrint mode, the output page is blank. I think this is because the X,Y coordinates are not in the same units as the EMF file but I'm still playing with this a bit as I have time.
Back to top
View user's profile
sbussinger
Member


Joined: 02 Jul 2004
Posts: 8

PostPosted: 03/08/04 00:35    Post subject: Reply with quote

OK, I found the problems I was having. The first was that I got no printout if FastPrint was false. The problem is in BltBitmapAsDIB():
Code:
procedure BltBitmapAsDIB(DestDc : hdc;   {Handle of where to blt}
                          x : word;       {Bit at x}
                          y : word;       {Blt at y}
                          Width : word;   {Width to stretch}
                          Height : word;  {Height to stretch}
                          bm : TBitmap);  {the TBitmap to Blt}

The X and Y parameters are defined as words and are being passed negative values. The reason is that the X and Y parameters when printing ultimately come from the GetPrinterPageBounds() routine:
Code:
  function GetPrinterPageBounds: TRect;
  begin
    Result.Left := 0;
    Result.Top := 0;
    if UsePrinterOptions then
    begin
      Result.Right := GetDeviceCaps(Printer.Handle, PHYSICALWIDTH);
      Result.Bottom := GetDeviceCaps(Printer.Handle, PHYSICALHEIGHT);
    end
    else
    begin
      Result.Right := ConvertUnits(FPageExt.X,
        GetDeviceCaps(Printer.Handle, LOGPIXELSX), FUnits, mmPixel);
      Result.Bottom := ConvertUnits(FPageExt.Y,
        GetDeviceCaps(Printer.Handle, LOGPIXELSY), FUnits, mmPixel);
    end;
    OffsetRect(Result,
       -GetDeviceCaps(Printer.Handle, PHYSICALOFFSETX),
       -GetDeviceCaps(Printer.Handle, PHYSICALOFFSETY));
  end;

Result.Left and Result.Top will always be negative coming out of this routine because of the OffsetRect() call. The values get converted to large positive values because of the WORD declarations and the bitmap gets printed way off the page. Changing the declarations to INTEGER seems to work OK.

My second problem was also related to GetPrinterPageBounds() routine. It returns values based on the physical size of the page rather than the logical size of the page. In my case that's an issue, but it may be better the way it is for everyone else. My problem arises because inkjets tend to have much larger bottom margins than laser printers and my output was getting cropped. I'd like to propose this change to GetPrinterPageBounds():
Code:
Replace

      Result.Right := GetDeviceCaps(Printer.Handle, PHYSICALWIDTH);
      Result.Bottom := GetDeviceCaps(Printer.Handle, PHYSICALHEIGHT);

with

      Result.Right := GetDeviceCaps(Printer.Handle, HORZRES);
      Result.Bottom := GetDeviceCaps(Printer.Handle, VERTRES);

This would mean that if UsePrinterOptions is true, that the page size is based on the printable area of the page rather than on the full size of the page in question. Any thoughts?

Thanks again for a great component set!
Back to top
View user's profile
Kambiz
Administrator


Joined: 07 Mar 2003
Posts: 412
Location: Tehran, Iran

PostPosted: 03/08/04 12:44    Post subject: Reply with quote

Thanks for the valuable information you provided.

Just for your information, TPrintPreview doesn't convert metafiles to bitmap, except FastPrint property is False and the metafile has at least one DDB bitmap as meta data (EMR_BITBLT and EMR_STRETCHBLT meta records).

Regarding to using HORZRES and VERTRES instead of PHYSICALWIDTH and PHYSICALHEIGHT I think could be some problems, because HORZRES and VERTRES are in pixels, however PHYSICALWIDTH and PHYSICALHEIGHT in logical units. I'll investigate it.
Back to top
View user's profile Send e-mail Visit poster's website
Kambiz
Administrator


Joined: 07 Mar 2003
Posts: 412
Location: Tehran, Iran

PostPosted: 03/08/04 13:50    Post subject: Reply with quote

Please forgive me, pixel and logical unit are identical here.
Back to top
View user's profile Send e-mail Visit poster's website
sbussinger
Member


Joined: 02 Jul 2004
Posts: 8

PostPosted: 03/08/04 17:09    Post subject: Reply with quote

Quote:
Just for your information, TPrintPreview doesn't convert metafiles to bitmap, except FastPrint property is False and the metafile has at least one DDB bitmap as meta data (EMR_BITBLT and EMR_STRETCHBLT meta records).


Actually I was referring to the process I was performing before finding out I could assign a TMetafile directly to the TPrintPreview. I did a BeginDoc, a PaintGraphicEx to put my EMF file on the page, then EndDoc sort of sequence and went from a nice tidy EMF file to a huge bitmap. It wasn't TPrintPreview's fault at all, it makes sense that it did it that way. But that's why I needed a way to just assign the EMF directly.

Quote:
Regarding to using HORZRES and VERTRES instead of PHYSICALWIDTH and PHYSICALHEIGHT I think could be some problems, because HORZRES and VERTRES are in pixels, however PHYSICALWIDTH and PHYSICALHEIGHT in logical units. I'll investigate it.


Thanks! I'm not entirely sure what affect this change will have on the normal cases. I haven't done a great deal of printing so I'm not entirely sure how this change would affect existing users.

Be seeing you.
Back to top
View user's profile
Display posts from previous:   
   Reply to topic    DELPHI AREA Forum Index -> DELPHI AREA's Products All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB 2.0.6 © 2001, 2002 phpBB Group