Home General
New Blog Posts: Merging Reports - Part 1 and Part 2

Oddity With TppImage

edited September 2002 in General
RB7, Delphi 5 with patch.

I have a bitmap image that is 1200 pixels by 900 pixels. I assign it
to a TppImage in the report detail before print as in

procedure TForm1.RptDetailBeforePrint(Sender: TObject);
begin
MapImg.Picture.Bitmap.Assign(FixedImg.Picture.Bitmap);
end;

This results in a tppImage size of 12.5 inches x 9.375 inches which is
too big for a standard piece of paper. Thus, in the tppImage before
print event I add the code below. Note that the only bands defined
for the report are header, detail, and footer. The only component in
the detail band is the tppImage.

procedure TForm1.MapImgPrint(Sender: TObject);
var
Width, Height : double;
begin
Width := Rpt.PrinterSetup.PaperWidth -
(Rpt.PrinterSetup.MarginLeft + Rpt.PrinterSetup.MarginRight);
Height := Rpt.PrinterSetup.PaperHeight -
(Rpt.PrinterSetup.MarginTop + Rpt.PrinterSetup.MarginBottom
+ RptHeader.Height + RptFooter.Height);
if MapImg.Width > Width then
MapImg.Width := Width;
if MapImg.Height > Height then
MapImg.Height := Height; // - 0.5; <<<<<<<< FUDGE FACTOR
end;

THE PROBLEM: If I do not include the "fudge factor", the image does
not show on the page.

The report has AutoStop = true, and the DBPipeline = nil.
The detail band is set for phDynamic and having a bottom offset of 0
or > 0 makes no difference.
The image has AutoSize = true, Center = true, MaintainAspect = true,
Stretch = true.

I can live with a fudge factor, but I would like to know what is
missing in my height measurements that prevents the image from
showing.

Last PS: Moving the image resize code to the detail band before print
makes no difference.

Comments

  • edited September 2002
    You need to find out what the printer's unprintable area is. Reference the
    printer driver specifications from the printer manufacturer to find this
    out. If this unprintable area is just a little larger than you margins, then
    that might be a problem. You'll have to increase the margins to account for
    the printer's unprintable area. Try using a TppShape in a one page report.
    Make the shape static height in a test report in order to see how large of
    an object can be successfully printed on the page. This way you can adjust
    the margins incrementally.


    Cheers,

    Jim Bennett
    Digital Metaphors

  • edited September 2002
    Ahhh yes... the famous gutter. I did it a bit differently. I've added a
    snippet of code here to permit a program to get the unprintable area for the
    selected printer... it is down and dirty and applies only to inches since that
    is what I use. Hmm... maybe in the next version this data could be made
    available in the PrinterSetup stuff... since the gutter info is necessary to get
    an image to print at maximum size.

    type
    TGutterInfo = record
    Left : double; // unprintable width each side in inches
    Right : double;
    Top : double;
    Bottom : double;
    end;

    function GetGutterInfo(Printer : TPrinter) : TGutterInfo;
    var
    PaperSize : TPoint; // physical size in pixels
    PrintSize : TPoint; // printable size in pixels
    Gutter : TRect; // unprintable margin
    DPI : TPoint; // pix per inch
    dc : HDC;
    begin
    dc := Printer.Handle;
    Gutter.Left := GetDeviceCaps(dc,PHYSICALOFFSETX);
    Gutter.Top := GetDeviceCaps(dc,PHYSICALOFFSETY);
    PaperSize.x := GetDeviceCaps(dc,PHYSICALWIDTH);
    PaperSize.y := GetDeviceCaps(dc,PHYSICALHEIGHT);
    PrintSize.x := GetDeviceCaps(dc,HORZRES);
    PrintSize.y := GetDeviceCaps(dc,VERTRES);
    if (PaperSize.x = 0) then
    PaperSize.x := PrintSize.x;
    if (PaperSize.y = 0) then
    PaperSize.y := PrintSize.y;
    Gutter.Right := PaperSize.x - (PrintSize.x + Gutter.Left);
    Gutter.Bottom := PaperSize.y - (PrintSize.y + Gutter.Top);
    DPI.x := GetDeviceCaps(dc,LOGPIXELSX);
    DPI.y := GetDeviceCaps(dc,LOGPIXELSY);
    if DPI.x <> 0 then begin
    Result.Left := Gutter.Left / DPI.x;
    Result.Right := Gutter.Right / DPI.x;
    end
    else begin
    Result.Left := -1.0;
    Result.Right := -1.0;
    end;
    if DPI.y <> 0 then begin
    Result.Top := Gutter.Top / DPI.y;
    Result.Bottom := Gutter.Bottom / DPI.y;
    end
    else begin
    Result.Top := -1.0;
    Result.Bottom := -1.0;
    end;
    end;


  • edited September 2002
    OK... two more questions for you RB gurus, please.

    a) In the example below, the PrinterSetup.Margin(s) are all set at 1/4 inch, which
    is exactly representable in float, FWIW. Using the routine below, the printer tells
    me that its gutter area is 75 pixels on each side, and its DPI is 300. Thus, the
    gutter for the printer is also 1/4 inch. Thus, in theory, the margins ought to
    account for the gutter but this is not the case. Is the printer driver lying to me
    about real gutter sizes?

    b) I used Printer.Handle in the routine since Printer.Canvas.Handle results in an
    error unless Printer.BeginDoc is called. I am assuming that Printer.Handle does
    point to the currently selected printer and that the DeviceCaps call is returning
    valid information. Is this a valid assumption?

    TIA.

This discussion has been closed.