[Lazarus] [ISSUE] FCL-Web and LazReport

Leonardo M. Ramé l.rame at griensu.com
Thu Jan 17 12:18:07 CET 2013


On 2013-01-17 09:07:09 -0200, silvioprog wrote:
>    2013/1/17 Leonardo M. Ramé <[1]l.rame at griensu.com>
> 
>      On 2013-01-17 08:52:11 +0100, Michael Van Canneyt wrote:
>      >
>      > On Wed, 16 Jan 2013, silvioprog wrote:
>      >
>      > >Hello,
>      > >Please see in:
>      > >
>      > >[2]http://bugs.freepascal.org/view.php?id=23664
>      >
>      > This cannot be fixed. Lazreport is not suitable for use in
>      webapplications.
>      >
>      > Some time ago, I started a new reporting engine exactly for this
>      reason.
>      >
>      > A well-designed reporting engine is independent of any widget set.
>      > (see e.g. jasperreports in Java)
>      >
>      > Michael.
>      >
> 
>      I had a similar issue some time ago with, TAChart. It needed TCanvas to
>      draw charts, but that was fixed by Alexander, if I remember correctly.
> 
>      That's why I stopped looking for a report generator for my cgi apps. Now
>      I rely on libHaru ([3]http://libharu.org/), which is a C shared library
>      with Pascal bindings that allows creation of PDF files.
> 
>      The problem with libHaru is you don't create reports out of markup, but
>      by code. In my case that's not a problem, because I'm the only one in
>      charge of creating reports, a different story will be when the final
>      user wants to create their own reports.
>      --
>      Leonardo M. Ramé
>      [4]http://leonardorame.blogspot.com
> 
>    Very nice.
>    You could send a small example with this library to take a look? Thank
>    you.
>    --

Yes, te attached file generates a report based on a TCollection
containing the data for each page, it has a header, body (with many
lines) and a footer. I also attached a small jpg showing the final
report.

-- 
Leonardo M. Ramé
http://leonardorame.blogspot.com
-------------- next part --------------
unit resumen_cuenta;
{$mode delphi}{$H+}

interface

uses
  SysUtils, hpdf, hpdf_types, hpdf_consts,
  Math, Classes,
  datos_resumen;

type
  
  { TResumenCta }

  TResumenCta = class(TCollectionItem)
  private
    FDatosResumen: TDatosResumen;
    page: HPDF_Page;
    pageWidth: Double;
    pageHeight: Double;
    leftMargin: Double;
    rightMargin: Double;
    topMargin: Double;
    x: double;
    y: double;
    angle1: double;
    rad1: double;
    image: HPDF_Image;
    iw: double;
    ih: double;
    pdf: HPDF_Doc;
    FFont: HPDF_Font;
    FBold: HPDF_Font;
    FBolditalic: HPDF_Font;
    FLogoGS: HPDF_Image;
    FLogoBW: HPDF_Image;
    procedure WriteText(page: HPDF_Page; x,y: double; Text: string; font: HPDF_Font);
    procedure WriteCenteredText(page: HPDF_Page; x,w,y: double; Text: string; font: HPDF_Font);
    procedure WriteRightAlignedText(page: HPDF_Page; x,w,y: double; Text: string; font: HPDF_Font);
    procedure DrawCoupon(page: HPDF_Page; x, y: double; font, bold: HPDF_Font; pdf: HPDF_Doc);
    procedure ImprimirDetalle(font, bold: HPDF_Font);
  public
    constructor Create(ACollection: TCollection); override;
    procedure Draw;
    property bold: HPDF_Font read FBold write FBold;
    property font: HPDF_Font read FFont write FFont;
    property boldItalic: HPDF_Font read FBoldItalic write FBoldItalic;
    property DatosResumen: TDatosResumen read FDatosResumen write FDatosResumen;
    property LogoGS: HPDF_Image read FLogoGS write FLogoGS;
    property LogoBW: HPDF_Image read FLogoBW write FLogoBW;
  end;

  { TResumenesCta }

  TResumenesCta = class(TCollection)
  private
    FDatosResumenes: TDatosResumenes;
    FPdf: HPDF_Doc;
    font: HPDF_Font;
    bold: HPDF_Font;
    bolditalic: HPDF_Font;
    FLogoGS: HPDF_Image;
    FLogoBW: HPDF_Image;
    function GetItem(AIndex: Integer): TResumenCta;
  public
    constructor Create(ADatosResumenes: TDatosResumenes);
    destructor Destroy; override;
    function Add: TResumenCta;
    procedure Save;
    procedure SaveToStream(AStream: TStream);
    procedure Draw;
    property Items[AIndex: Integer]: TResumenCta read GetItem; default;
    property pdf: HPDF_Doc read FPdf;
    property DatosResumenes: TDatosResumenes read FDatosResumenes;
  end;

implementation

const
  cLineHeight = 12;
  fname: string = 'Test.pdf';
  DASH_MODE1: array[0..0] of HPDF_UINT16 = (5);

procedure error_handler (error_no: HPDF_STATUS; detail_no: HPDF_STATUS;
              user_data: Pointer); stdcall;
var
  message: string;
begin
  message := 'ERROR: ' + IntToStr(error_no) + '-' + IntToStr(detail_no);
  raise Exception.Create(message);
end;

{ TResumenesCta }

constructor TResumenesCta.Create(ADatosResumenes: TDatosResumenes);
begin
  inherited Create(TResumenCta);
  Fpdf := HPDF_New(@error_handler, nil);
  HPDF_SetCompressionMode(Fpdf, HPDF_COMP_ALL);

  {* create default-font *}
  bold := HPDF_GetFont(Fpdf, 'Courier-Bold', 'WinAnsiEncoding');
  font := HPDF_GetFont(Fpdf, 'Courier', 'WinAnsiEncoding');
  bolditalic := HPDF_GetFont(Fpdf, 'Courier-BoldOblique', 'WinAnsiEncoding');

  FDatosResumenes := ADatosResumenes;

  if not fileExists('logo-gs.png') then
    raise Exception.Create('file logo-gs.png does not exists.');

  FLogoGS := HPDF_LoadPngImageFromFile (pdf, 'logo-gs.png');

  if not fileExists('logo-bw.png') then
    raise Exception.Create('file logo-bw.png does not exists.');

  FLogoBW := HPDF_LoadPngImageFromFile (pdf, 'logo-bw.png');
end;

destructor TResumenesCta.Destroy;
begin
  HPDF_Free (pdf);
end;

function TResumenesCta.Add: TResumenCta;
begin
  Result := TResumenCta(inherited Add);
  Result.pdf := FPdf;
  Result.font := font;
  Result.bold := bold;
  Result.boldItalic:= bolditalic;
end;

procedure TResumenesCta.Save;
begin
  (* save the document to a file *)
  HPDF_SaveToFile (Fpdf, PChar(fname));
end;

procedure TResumenesCta.SaveToStream(AStream: TStream);
var
  lSize: HPDF_UINT32;
  buf: array[0..4096] of HPDF_BYTE;

begin
  HPDF_SaveToStream(pdf);
  HPDF_ResetStream(pdf);
  while true do
  begin
    lSize := 4096;
    HPDF_ReadFromStream(pdf, buf, @lSize);
    if(lSize = 0) then
      break;
    AStream.Write(buf, lSize);
  end;
  AStream.Position := 0;
end;

procedure TResumenesCta.Draw;
var
  I: Integer;
  lResumenCta: TResumenCta;
begin
  Clear;
  for I := 0 to FDatosResumenes.Count - 1 do
  begin
    lResumenCta := Add;
    lResumenCta.LogoBW:= FLogoBW;
    lResumenCta.LogoGS:= FLogoGS;
    lResumenCta.DatosResumen := FDatosResumenes[I];
    lResumenCta.Draw;
  end;
end;
 
function TResumenesCta.GetItem(AIndex: Integer): TResumenCta;
begin
  Result := TResumenCta(inherited GetItem(AIndex));
end;

{ TResumenCta }

constructor TResumenCta.Create(ACollection: TCollection);
begin
  page := HPDF_AddPage((ACollection as TResumenesCta).pdf);

  (* tamaño de página *)
  pageWidth := HPDF_Page_GetWidth(page);
  pageHeight := HPDF_Page_GetHeight(page);
  leftMargin := 10;
  rightMargin := pageWidth - leftMargin;
  topMargin := pageHeight - 10;
  x := leftMargin + 4;
  y := topMargin;
end;

procedure TResumenCta.WriteText(page: HPDF_Page; x,y: double; Text: string; font: HPDF_Font);
begin
  HPDF_Page_BeginText(page);
  HPDF_Page_MoveTextPos(page, x, y);
  HPDF_Page_SetFontAndSize(page, font, 10);
  HPDF_Page_ShowText(page, PAnsiChar(UTF8ToAnsi(Text)));
  HPDF_Page_EndText(page);
end;

procedure TResumenCta.WriteCenteredText(page: HPDF_Page; x,w,y: double; Text: string; font: HPDF_Font);
var
  lText: PAnsiChar;
begin
  lText := PAnsiChar(UTF8ToAnsi(Text));
  HPDF_Page_BeginText(page);
  HPDF_Page_MoveTextPos(page, x, y);
  HPDF_Page_SetFontAndSize(page, font, 10);
  HPDF_Page_TextRect(page, x, y, x + w, y, lText, HPDF_TALIGN_CENTER, nil);
  HPDF_Page_EndText(page);
end;

procedure TResumenCta.WriteRightAlignedText(page: HPDF_Page; x,w,y: double; Text: string; font: HPDF_Font);
var
  lText: PAnsiChar;
begin
  lText := PAnsiChar(UTF8ToAnsi(Text));
  HPDF_Page_BeginText(page);
  HPDF_Page_MoveTextPos(page, x, y);
  HPDF_Page_SetFontAndSize(page, font, 10);
  HPDF_Page_TextRect(page, x, y, x + w, y, lText, HPDF_TALIGN_RIGHT, nil);
  HPDF_Page_EndText(page);
end;

procedure TResumenCta.DrawCoupon(page: HPDF_Page; x, y: double; font, bold: HPDF_Font; pdf: HPDF_Doc);
var
  image: HPDF_Image;
  iw: double;
  ih: double;

begin
  iw := HPDF_Image_GetWidth(FLogoBW) / 6;
  ih := HPDF_Image_GetHeight(FLogoBW) / 6;
  HPDF_Page_DrawImage(page, FLogoBW, x + 43, y, iw, ih);


  y := y - (cLineHeight * 0.5);
  WriteCenteredText(page, x, 210, y, 'Vencimiento', font);
  y := y - cLineHeight;
  WriteCenteredText(page, x, 210, y,  FormatDateTime('DD/MM/YYYY', FDatosResumen.Vto), font);
  y := y - (cLineHeight * 1.5);
  WriteCenteredText(page, x, 210, y, FDatosResumen.Cliente, bold);
  y := y - cLineHeight;
  WriteCenteredText(page, x, 210, y, 'Cta. Nº ' + FDatosResumen.TarjetaNro, bold);
  y := y - (cLineHeight * 1.5);
  WriteCenteredText(page, x, 210, y, 'Importe: $ ' + Format('%.2f', [FDatosResumen.Importe]), font);
  y := y - cLineHeight;
  WriteCenteredText(page, x, 210, y, Format('Nº Resumen: %d', [FDatosResumen.ResumenNro]), font);
end;

function compare(Item1, Item2: TCollectionItem): Integer;
var
  lItem1: TItemDetalle;
  lItem2: TItemDetalle;
begin
  lItem1 := Item1 as TItemDetalle;
  lItem2 := Item2 as TItemDetalle;
  if lItem1.Tipo < lItem2.Tipo then
    Result := -1
  else if lItem1.Tipo > lItem2.Tipo then
    Result := 1
  else
    Result := 0;
end;

procedure TResumenCta.ImprimirDetalle(font, bold: HPDF_Font);
var
  I: Integer;
  y: Integer;
  lDetalle: TItemDetalle;
  lFont: HPDF_Font;
  lTipo: Integer;
begin
  y := 694;
  x := leftMargin + 5;
  lTipo := 1; // el tipo 1 no se muestra, para mostrarlo comenzar con tipo -1.
  //FDatosResumen.Detalle.Sort(compare);
  for I := 0 to FDatosResumen.Detalle.Count - 1 do
  begin
    lDetalle := FDatosResumen.Detalle[I];
    if lDetalle.Tipo <> lTipo then
    begin
      lTipo := lDetalle.Tipo;
      lFont := bold;
      lDetalle := FDatosResumen.Detalle[I];
      case lTipo of
        2: WriteText(page, x + 120, y, 'CONSUMO DEL MES', lFont);
        3: WriteText(page, x + 120, y, 'CONSUMO DE LOS ADICIONALES', lFont);
        4: WriteText(page, x + 120, y, 'CARGOS FIJOS', lFont);
        5: WriteText(page, x + 120, y, 'OTROS CARGOS (5)', lFont);
        7: WriteText(page, x + 120, y, 'OTROS CARGOS', lFont);
      else
        WriteText(page, x + 120, y, Format('Tipo: %d', [lTipo]), lFont);
      end;

      y := y - cLineHeight;
    end;
    lFont := font;
    WriteText(page, x, y, FormatDateTime('DD/MM/YYYY', lDetalle.Fecha), lFont);
    WriteRightAlignedText(page, x + 60, 50, (y - 4) + cLineHeight, lDetalle.Cupon, lFont);
    WriteText(page, x + 120, y, lDetalle.Concepto, lFont);
    WriteRightAlignedText(page, x + 495, 70, (y - 4) + cLineHeight, Format('$ %.2f', [lDetalle.Importe]), lFont);
    y := y - cLineHeight;
  end;
end;

procedure TResumenCta.Draw;
begin
  {* encabezado *}
  HPDF_Page_SetGrayFill (page, 0.8);
  HPDF_Page_Rectangle(page, leftMargin, topMargin, rightMargin - leftMargin, -54);
  HPDF_Page_Fill(page);

  HPDF_Page_SetGrayFill (page, 0);
  HPDF_Page_SetFontAndSize(page, bold, 10);

  y := y - cLineHeight;
  WriteText(page, x, y, 'Señores', bold);

  y := y - cLineHeight;
  WriteText(page, x, y, FDatosResumen.Cliente, bold);

  y := y - cLineHeight;
  WriteText(page, x, y, FDatosResumen.GetDomicilio, bold);

  y := y - cLineHeight;

  WriteText(page, x, y, FDatosResumen.GetBarrio, bold);

  HPDF_Page_SetLineWidth (page, 0.5);
  HPDF_Page_SetGrayFill (page, 1);
  HPDF_Page_SetGrayStroke(page, 0);
  HPDF_Page_Rectangle(page, 360, topMargin - 2, 110, -50);
  HPDF_Page_Rectangle(page, 473, topMargin - 2, 110, -50);
  HPDF_Page_FillStroke(page);

  DefaultFormatSettings.DateSeparator := '/';

  HPDF_Page_SetGrayFill (page, 0);
  y := topMargin - 4;
  x := 360;
  WriteCenteredText(page, x, 110, y, 'Período desde', bold);
  y := y - cLineHeight;
  WriteCenteredText(page, x, 110, y, FormatDateTime('DD/MM/YYYY', FDatosResumen.Desde), font);
  y := y - cLineHeight;
  WriteCenteredText(page, x, 110, y, 'Período hasta', bold);
  y := y - cLineHeight;
  WriteCenteredText(page, x, 110, y, FormatDateTime('DD/MM/YYYY', FDatosResumen.Hasta), font);

  y := topMargin - 4;
  x := 473;
  WriteCenteredText(page, x, 110, y, 'Fecha emisión', bold);
  y := y - cLineHeight;
  WriteCenteredText(page, x, 110, y, FormatDateTime('DD/MM/YYYY', FDatosResumen.Emision), font);
  y := y - cLineHeight;
  WriteCenteredText(page, x, 110, y, 'Fecha vto.', bold);
  y := y - cLineHeight;
  WriteCenteredText(page, x, 110, y, FormatDateTime('DD/MM/YYYY', FDatosResumen.Vto), font);

  x := leftMargin;
  
  y := (y + 4) - (cLineHeight * 2.5);
  WriteText(page, x, y, 'CUIL / CUIT: ' + FDatosResumen.CUIL + ' ' + FDatosResumen.CondIVA + ' PESOS (Arg.)', bold);
  y := y - cLineHeight;
  WriteText(page, x, y, 'Tarjeta Nro.: ' + FDatosResumen.TarjetaNro + ' - Alta/Renovación: ' + FormatDateTime('DD/MM/YYYY', FDatosResumen.Renovacion), bold);

  y := y - cLineHeight;

  (* Tabla *)
  // borde general
  HPDF_Page_SetLineWidth (page, 0.5);
  HPDF_Page_SetGrayFill (page, 1);
  HPDF_Page_SetGrayStroke(page, 0);
  HPDF_Page_Rectangle(page, leftMargin, y, pageWidth - (leftMargin * 2), -550);
  HPDF_Page_FillStroke(page);

  // primera linea
  HPDF_Page_SetLineWidth (page, 0.5);
  HPDF_Page_SetGrayFill (page, 0.75);
  HPDF_Page_SetGrayStroke(page, 0);
  HPDF_Page_Rectangle(page, leftMargin, y, pageWidth - (leftMargin * 2), -(cLineHeight + 5));
  HPDF_Page_FillStroke(page);

  HPDF_Page_SetGrayFill (page, 0);
  WriteCenteredText(page, x, pageWidth, y - 3, 'DETALLE RESUMEN DE CUENTA', bold);

  // segunda linea
  y := y - (cLineHeight + 5);
  HPDF_Page_SetLineWidth (page, 0.5);
  HPDF_Page_SetGrayFill (page, 1);
  HPDF_Page_SetGrayStroke(page, 0);
  HPDF_Page_Rectangle(page, leftMargin, y, pageWidth - (leftMargin * 2), -(cLineHeight + 5));
  HPDF_Page_FillStroke(page);

  HPDF_Page_SetGrayFill (page, 0);
  y := y - 3;
  WriteCenteredText(page, x, 70, y, 'FECHA', font);
  WriteCenteredText(page, x + 70, 50, y, 'CUPON', font);
  WriteCenteredText(page, x + 130, 380, y, 'CONCEPTO', font);
  WriteCenteredText(page, x + 498, 80, y, 'IMPORTE', font);

  // divisores de columna linea continua 
  y := y - cLineHeight;
  HPDF_Page_SetLineWidth (page, 0.5);
  HPDF_Page_SetGrayFill (page, 1);
  HPDF_Page_SetGrayStroke(page, 0);
  x := 80;
  HPDF_Page_MoveTo(page, x, 724);
  HPDF_Page_LineTo(page, x, 707);

  x := 130;
  HPDF_Page_MoveTo(page, x, 724);
  HPDF_Page_LineTo(page, x, 707);

  x := 510;
  HPDF_Page_MoveTo(page, x, 724);
  HPDF_Page_LineTo(page, x, 707);
  HPDF_Page_FillStroke(page);

  (* Se incluye filigrama *)
  iw := HPDF_Image_GetWidth(FLogoGS) / 2.5;
  ih := HPDF_Image_GetHeight(FLogoGS) / 2.5;
  x := (pageWidth / 2) - (iw / 2);
  y := (pageHeight / 2);
  HPDF_Page_DrawImage(page, FLogoGS, x, y, iw, ih);

  // divisores de columna linea discontinua 
  y := y - cLineHeight;
  HPDF_Page_SetLineWidth (page, 0.5);
  HPDF_Page_SetGrayFill (page, 1);
  HPDF_Page_SetGrayStroke(page, 0.75);
  HPDF_Page_SetDash(page, @DASH_MODE1, 1, 1);
  x := 80;
  HPDF_Page_MoveTo(page, x, 704);
  HPDF_Page_LineTo(page, x, 200);

  x := 130;
  HPDF_Page_MoveTo(page, x, 704);
  HPDF_Page_LineTo(page, x, 200);

  x := 510;
  HPDF_Page_MoveTo(page, x, 704);
  HPDF_Page_LineTo(page, x, 200);
  HPDF_Page_FillStroke(page);

  // pie de la tabla 
  y := 200;
  HPDF_Page_SetLineWidth (page, 0.5);
  HPDF_Page_SetGrayFill (page, 1);
  HPDF_Page_SetGrayStroke(page, 0);
  HPDF_Page_SetDash(page, nil, 0, 0);
  HPDF_Page_Rectangle(page, leftMargin, y, pageWidth - (leftMargin * 2), -(cLineHeight + 5));
  HPDF_Page_FillStroke(page);

  x := 510;
  HPDF_Page_SetLineWidth (page, 0.5);
  HPDF_Page_SetGrayFill (page, 0.75);
  HPDF_Page_SetGrayStroke(page, 0);
  HPDF_Page_SetDash(page, nil, 0, 0);
  HPDF_Page_Rectangle(page, x, y, 75, -(cLineHeight + 5));
  HPDF_Page_FillStroke(page);

  x := 350;
  HPDF_Page_SetGrayFill (page, 0);
  y := y - 3;
  WriteRightAlignedText(page, x, 150, y, 'Saldo al ' + FormatDateTime('DD/MM/YYYY', FDatosResumen.Desde), FBold);

  HPDF_Page_SetGrayFill (page, 0);
  x := 510;
  WriteRightAlignedText(page, x, 70, y, '$ ' + Format('%.2f', [FDatosResumen.Importe]), FBold);

  (* Recuadro lugares de pago *) 
  y := y - 28;
  HPDF_Page_SetLineWidth (page, 0.5);
  HPDF_Page_SetGrayFill (page, 0);
  HPDF_Page_SetGrayStroke(page, 0);
  HPDF_Page_Rectangle(page, leftMargin + 8, y, pageWidth - ((leftMargin + 5) * 2), -(cLineHeight + 5));
  HPDF_Page_FillStroke(page);

  y := y + 3;
  HPDF_Page_SetLineWidth (page, 0.5);
  HPDF_Page_SetGrayFill (page, 1);
  HPDF_Page_SetGrayStroke(page, 0);
  HPDF_Page_Rectangle(page, leftMargin + 5, y, pageWidth - ((leftMargin + 5) * 2), -(cLineHeight + 5));
  HPDF_Page_FillStroke(page);

  HPDF_Page_SetGrayFill (page, 0);
  x := leftMargin + 5;
  y := y - 2;
  WriteCenteredText(page, x, pageWidth - ((leftMargin + 5) * 2), y - 1, 'Este resumen podrá ser abonado en Farmacias Del Milagro y Del Norte, o por Débito Automático', FBolditalic);

  (* linea discontinua horizontal*)
  y := y - 30;
  HPDF_Page_SetLineWidth (page, 0.5);
  HPDF_Page_SetGrayFill (page, 1);
  HPDF_Page_SetGrayStroke(page, 0.75);
  HPDF_Page_SetDash(page, @DASH_MODE1, 1, 1);
  x := leftMargin;
  HPDF_Page_MoveTo(page, x, y);
  HPDF_Page_LineTo(page, x + (pageWidth - (leftMargin * 2)), y);

  (* 1ra linea discontinua vertical *)
  x := (leftMargin + (pageWidth - (leftMargin * 2))) / 3;
  HPDF_Page_MoveTo(page, x, y);
  HPDF_Page_LineTo(page, x, y - 140);

  (* 2da linea discontinua vertical *)
  x := x + ((leftMargin + (pageWidth - (leftMargin * 2))) / 3);
  HPDF_Page_MoveTo(page, x, y);
  HPDF_Page_LineTo(page, x, y - 140);
  HPDF_Page_FillStroke(page);

  (* Pié *)
  angle1 := 90;                 
  HPDF_Page_SetFontAndSize(page, font, 10);
  rad1 := DegToRad(angle1); 
  HPDF_Page_SetGrayFill (page, 0);

  HPDF_Page_BeginText (page);
  HPDF_Page_SetTextMatrix (page, 
    cos(rad1), 
    sin(rad1), 
    -sin(rad1), 
    cos(rad1),
    leftMargin + 5, 
    y - 94);
  HPDF_Page_ShowText (page, 'Para el cliente');

  x := (leftMargin + (pageWidth - (leftMargin * 2))) / 3;
  HPDF_Page_SetTextMatrix (page, 
    cos(rad1), 
    sin(rad1), 
    -sin(rad1), 
    cos(rad1),
    x + 10,
    y - 82);
  HPDF_Page_ShowText (page, 'Para el banco');

  x := x + (leftMargin + (pageWidth - (leftMargin * 2))) / 3;
  HPDF_Page_SetTextMatrix (page, 
    cos(rad1), 
    sin(rad1), 
    -sin(rad1), 
    cos(rad1),
    x + 10, 
    y - 112);
  HPDF_Page_ShowText (page, 'Para Tarjeta Salud');

  HPDF_Page_EndText (page);

  HPDF_Page_SetGrayFill (page, 0);
  x := leftMargin;
  y := y - (cLineHeight * 3);
  DrawCoupon(page, x,  y, font, bold, pdf);

  x := (leftMargin + (pageWidth - (leftMargin * 2))) / 3;
  DrawCoupon(page, x,  y, font, bold, pdf);

  x := x + (leftMargin + (pageWidth - (leftMargin * 2))) / 3;
  DrawCoupon(page, x,  y, font, bold, pdf);

  (* Detalle *)
  HPDF_Page_SetGrayFill (page, 0);
  ImprimirDetalle(font, bold);
end;

end.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: report.jpg
Type: image/jpeg
Size: 30006 bytes
Desc: not available
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20130117/d0d98709/attachment-0003.jpg>


More information about the Lazarus mailing list