Page 1 of 1

Images too big when writing JPGs to printer canvas

Posted: Fri Aug 29, 2008 7:54 pm
by JLuckey
I'm printing the contents of a TRichViewEdit using a technique from one of your samples/demos which puts 2 columns on each page. (see code sample)

The data contains lots of text and several embedded JPG images of varying sizes. In the TRichViewEdit, I set the sizes of these JPGs to thumbnail-size as I insert them into the TRichViewEdit and everything works well.

When they are printed on the report, they appear at their original size which is huge and messes up the report.

How do I control the size of JPGs when writing to the printer canvas?


Thanks,

Code: Select all


var ColWidth, DocHeight, DocTop, Col1Left, Col2Left,
    HeaderLeft, HeaderTop, HeaderWidth, LineY,
    PageNo, FooterTop : Integer;
    strDateTime : String;
    rtfTable :  TRVTableItemInfo;

begin

  ShowMessage('Starting 2 Col report');
  if rvh.RichView.ItemCount=0 then begin
    Application.MessageBox('Document is empty!', 'Empty', 0);
    exit;
  end;
  Printer.Title := 'ReportHelper Test';
  Printer.BeginDoc;
  try
    PageNo := 1;
    HeaderLeft := Printer.PageWidth div 30; // margins = 5%
    HeaderWidth := Printer.PageWidth - HeaderLeft*2;
    HeaderTop := Printer.PageHeight div 30; // margins = 5%
    FooterTop := Printer.PageHeight - (Printer.PageHeight div 40);

    ColWidth := (HeaderWidth-HeaderLeft) div 2;
    Col1Left := HeaderLeft;
    Col2Left := Col1Left + ColWidth + HeaderLeft div 2;
    rvh.Init(Printer.Canvas, ColWidth);

    while True do begin
      // creating & formatting header
      rvh2.RichView.Clear;

      // Build 1 row 2 col table for header
      rtfTable := TRVTableItemInfo.CreateEx(1, 2, rvh2.RichView.RVData);
      rtfTable.BorderWidth     := 1;
      rtfTable.CellBorderWidth := 1;
      rtfTable.CellBorderStyle := rvtbColor;
      rtfTable.CellBorderColor := clWhite;
      rtfTable.BorderStyle     := rvtbColor;
      rtfTable.BorderColor     := clWhite;
      rtfTable.Cells[0, 0].BestWidth := 0;     // Setting cell width to default
      rtfTable.Cells[0, 1].BestWidth := 0;     // Setting cell width to default

      // Load the newly-created rtfTable with page header text
      rtfTable.Cells[0,0].AddNL('Dictionary of Jungian Psychology', 3, 0);
      rtfTable.Cells[0,1].AddNL(SearchProto2.cbHeading.Text, 1, 2);
      rvh2.RichView.AddItem('', rtfTable);

      rvh2.Init(Printer.Canvas, HeaderWidth);
      rvh2.FormatNextPage(Printer.PageHeight);
      DocTop := HeaderTop + rvh2.EndAt + HeaderTop div 2;

      // formatting the first column of document
      DocHeight := Printer.PageHeight - DocTop - HeaderTop - (Printer.PageHeight - FooterTop);
      if not rvh.FormatNextPage(DocHeight) then
        break;

      // starting new page
      if PageNo>1 then
        Printer.NewPage;

      // drawing line between header and document
      with Printer.Canvas do begin
        Pen.Style := psInsideFrame;
        Pen.Width := 2;
        Pen.Color := clBlack;
        LineY := HeaderTop + rvh2.EndAt + HeaderTop div 4;
        MoveTo(HeaderLeft, LineY);
        LineTo(Printer.PageWidth-HeaderLeft, LineY);
      end;

      // drawing line between document and footer
      with Printer.Canvas do begin
        Pen.Style := psInsideFrame;
        Pen.Width := 2;
        Pen.Color := clBlack;
        LineY := FooterTop;
        MoveTo(HeaderLeft, LineY);
        LineTo(Printer.PageWidth-HeaderLeft, LineY);
      end;

      // creating & formatting footer
      DateTimeToString(strDateTime, 'dd-mmm-yy  hh:mm AM/PM', Now());
      rvhFooter.RichView.Clear;
      rvhFooter.RichView.Add('Copyright © 2008 Thornton Ladd' +
                             StringOfChar(' ', 55) + 'Page ' + IntToStr(PageNo) +
                             StringOfChar(' ', 70) + strDateTime , 2);
      rvhFooter.Init(Printer.Canvas, HeaderWidth);
      rvhFooter.FormatNextPage(75);  //Printer.PageHeight);

      // drawing header
      rvh2.DrawPageAt(HeaderLeft, HeaderTop, 1, Printer.Canvas, False, rvh2.EndAt);

      // Draw document - first column
      rvh.DrawPageAt(Col1Left, DocTop, PageNo*2-1, Printer.Canvas, False, DocHeight);

      // Draw document - second column (if necessary)
      if rvh.FormatNextPage(DocHeight) then
        rvh.DrawPageAt(Col2Left, DocTop, PageNo*2, Printer.Canvas, False, DocHeight);

      // Draw footer
      rvhFooter.DrawPageAt(HeaderLeft, FooterTop + 25, 1, Printer.Canvas, False, 75);

      inc(PageNo);

    end;  {While}

  finally
    Printer.EndDoc;
  end;

end;



Posted: Sat Aug 30, 2008 11:50 am
by Sergey Tkachenko
Unfortunately, not.
But you can truncate the output using clipping regions.

For example, you need to restrict painting to the rectangle R:

Code: Select all

var
  rgn: HRGN;
  rgnres: Integer;
...
  rgn := CreateRectRgn(0,0,1,1);
  rgnres := GetClipRgn(Canvas.Handle, rgn);
  with R do
    IntersectClipRect(Canvas.Handle,Left,Top,Right,Bottom);
  <drawing here ...>
  if rgnres=1 then
    SelectClipRgn(Canvas.Handle, rgn)
  else
    SelectClipRgn(Canvas.Handle, 0);
  DeleteObject(rgn);