diff options
author | Graeme Geldenhuys <graeme@mastermaths.co.za> | 2012-08-01 16:40:12 +0100 |
---|---|---|
committer | Graeme Geldenhuys <graeme@mastermaths.co.za> | 2012-08-01 16:40:12 +0100 |
commit | a9022e83449e8b885d864279b6aa4700753d6746 (patch) | |
tree | 6bb77e920703261787ece2cc964ab7d1183ffe0b /src/reportengine | |
parent | 88d248839e06559a24c786b61d64a4d537a2cf46 (diff) | |
download | fpGUI-a9022e83449e8b885d864279b6aa4700753d6746.tar.xz |
Moves the PDF report engine & demo into the main source tree.
Diffstat (limited to 'src/reportengine')
-rw-r--r-- | src/reportengine/fpg_report.lpk | 75 | ||||
-rw-r--r-- | src/reportengine/fpg_report.pas | 14 | ||||
-rw-r--r-- | src/reportengine/u_command.pas | 855 | ||||
-rw-r--r-- | src/reportengine/u_pdf.pas | 2117 | ||||
-rw-r--r-- | src/reportengine/u_report.pas | 3078 | ||||
-rw-r--r-- | src/reportengine/u_reportimages.pas | 181 | ||||
-rw-r--r-- | src/reportengine/u_visu.pas | 538 |
7 files changed, 6858 insertions, 0 deletions
diff --git a/src/reportengine/fpg_report.lpk b/src/reportengine/fpg_report.lpk new file mode 100644 index 00000000..40483c1d --- /dev/null +++ b/src/reportengine/fpg_report.lpk @@ -0,0 +1,75 @@ +<?xml version="1.0"?> +<CONFIG> + <Package Version="4"> + <Name Value="fpg_report"/> + <Author Value="Jean-Marc Levecque <jean-marc.levecque@jmlesite.fr>"/> + <CompilerOptions> + <Version Value="11"/> + <SearchPaths> + <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/> + <LCLWidgetType Value="nogui"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <CStyleOperator Value="False"/> + <AllowLabel Value="False"/> + <CPPInline Value="False"/> + <UseAnsiStrings Value="False"/> + </SyntaxOptions> + </Parsing> + <Linking> + <Debugging> + <GenerateDebugInfo Value="False"/> + <UseLineInfoUnit Value="False"/> + </Debugging> + </Linking> + <Other> + <CompilerMessages> + <UseMsgFile Value="True"/> + </CompilerMessages> + <CompilerPath Value="$(CompPath)"/> + </Other> + </CompilerOptions> + <Description Value="PDF reporting engine"/> + <License Value="Modified LGPL with static linking exception."/> + <Version Minor="2"/> + <Files Count="5"> + <Item1> + <Filename Value="u_command.pas"/> + <UnitName Value="U_Command"/> + </Item1> + <Item2> + <Filename Value="u_report.pas"/> + <UnitName Value="U_Report"/> + </Item2> + <Item3> + <Filename Value="u_pdf.pas"/> + <UnitName Value="U_Pdf"/> + </Item3> + <Item4> + <Filename Value="u_visu.pas"/> + <UnitName Value="U_Visu"/> + </Item4> + <Item5> + <Filename Value="u_reportimages.pas"/> + <UnitName Value="U_ReportImages"/> + </Item5> + </Files> + <RequiredPkgs Count="2"> + <Item1> + <PackageName Value="fpgui_toolkit"/> + </Item1> + <Item2> + <PackageName Value="FCL"/> + <MinVersion Major="1" Valid="True"/> + </Item2> + </RequiredPkgs> + <UsageOptions> + <UnitPath Value="$(PkgOutDir)"/> + </UsageOptions> + <PublishOptions> + <Version Value="2"/> + <IgnoreBinaries Value="False"/> + </PublishOptions> + </Package> +</CONFIG> diff --git a/src/reportengine/fpg_report.pas b/src/reportengine/fpg_report.pas new file mode 100644 index 00000000..9479e685 --- /dev/null +++ b/src/reportengine/fpg_report.pas @@ -0,0 +1,14 @@ +{ This file was automatically created by Lazarus. Do not edit! + This source is only used to compile and install the package. + } + +unit fpg_report; + +interface + +uses + U_Command, U_Report, U_Pdf, U_Visu, U_ReportImages; + +implementation + +end. diff --git a/src/reportengine/u_command.pas b/src/reportengine/u_command.pas new file mode 100644 index 00000000..16f7b0e0 --- /dev/null +++ b/src/reportengine/u_command.pas @@ -0,0 +1,855 @@ +{ + << Impressions >> U_Commande.pas + + Copyright (C) 2010 - Jean-Marc Levecque <jean-marc.levecque@jmlesite.fr> + + This library is a free software coming as a add-on to fpGUI toolkit + See the copyright included in the fpGUI distribution for details about redistribution + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Description: + This unit builds the objects in memory to produce either the preview or pdf file +} + +unit U_Command; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, + fpg_base, fpg_main, //fpg_imgfmt_bmp, fpg_imgfmt_jpg, + U_Pdf; + +type + TZone = (zHeader,zFooter,zPage,zMargins); + TSectPageNum = (PageNum,SectNum,PSectNum); + TBorderFlags= set of (bfLeft,bfRight,bfTop,bfBottom); + + TDimensions= record + T: Single; + L: Single; + R: Single; + B: Single; + end; + + TPaper= record + H: Integer; + W: Integer; + Printable: TDimensions; + end; + + // document classes + + T_Section = class + private + FNumSect: Integer; + FNbPages: Integer; + FPaper: TPaper; + FMargins: TDimensions; + FBotHead: Single; + FTopFoot: Single; + FPages: TList; + FHeader: TList; + FFooter: TList; + FFrames: TList; + FDefCol: Integer; + FTitle: string; + function GetFirstPage: Integer; + function GetTotalPages: Integer; + public + constructor Create(APaper: TPaper; AMargins: TDimensions; ANum: Integer); virtual; + destructor Destroy; override; + procedure LoadPage(APageNum: Integer); + procedure LoadCmdHeader; + procedure LoadCmdPage; + procedure LoadCmdFooter; + procedure LoadCmdGroup; + procedure LoadCmdGroupToPage; + procedure LoadSpaceHeader(APosY: Single; AColumn: Integer; AHeight: Single; ABackColor: Integer); + procedure LoadSpacePage(APosY: Single; AColumn: Integer; AHeight: Single; ABackColor: Integer); + procedure LoadSpaceFooter(APosY: Single; AColumn: Integer; AHeight: Single; ABackColor: Integer); + procedure LoadSpaceGroup(AHeight: Single); + procedure LoadFrame(AStyle: Integer; AZone: TZone); + procedure LoadLine(APosXBegin,APosYBegin: Single; AColumn: Integer; APosXEnd,APosYEnd: Single; AStyle: Integer); + procedure LoadLineHorizHeader(APosXBegin,APosYBegin: Single; AColumn: Integer; APosXEnd,APosYEnd: Single; AStyle: Integer); + procedure LoadLineHorizPage(APosXBegin,APosYBegin: Single; AColumn: Integer; APosXEnd,APosYEnd: Single; AStyle: Integer); + procedure LoadLineHorizFooter(APosXBegin,APosYBegin: Single; AColumn: Integer; APosXEnd,APosYEnd: Single; AStyle: Integer); + procedure LoadLineHorizGroupe(AHeight: Single); + procedure LoadSurf(APos: T_Points; AColor: TfpgColor); + procedure LoadImgHeader(APosX,APosY: Single; AColumn,AImgNum: Integer); + procedure LoadImgPage(APosX,APosY: Single; AColumn,AImgNum: Integer); + procedure LoadImgFooter(APosX,APosY: Single; AColumn,AImgNum: Integer); + function GetCmdPage(NumPage: Integer): TList; + property CmdHeader: TList read FHeader; + property CmdFooter: TList read FFooter; + property NbPages: Integer read FNbPages; + property FirstPage: Integer read GetFirstPage; + property Pages: TList read FPages; + property TotPages: Integer read GetTotalPages; + property Paper: TPaper read FPaper; + property Margins: TDimensions read FMargins; + property CmdFrames: TList read FFrames; + property DefaultCol: Integer read FDefCol write FDefCol; + property Title: string read FTitle write FTitle; + end; + + T_Page = class + private + FNumPageTot: Integer; + FNumPageSect: Integer; + FCommands: TList; + public + constructor Create(ANumSec,ANumTot: Integer); virtual; + destructor Destroy; override; + property Commands: TList read FCommands write FCommands; + property PagesTot: Integer read FNumPageTot; + property PagesSect: Integer read FNumPageSect; + end; + + T_Group = class + private + FLineHeight: Single; + FGroupHeight: Single; + FCommands: TList; + public + constructor Create; virtual; + destructor Destroy; override; + property Commands: TList read FCommands write FCommands; + property LineHeight: Single read FLineHeight; + property GroupeHeight: Single read FGroupHeight; + end; + + T_WriteLine = class + private + FHeight: Integer; + FCommands: TList; + public + constructor Create; virtual; + destructor Destroy; override; + procedure LoadText(APosX,APosY: Single; AColumn,AText,AFont,AHeight,ABackColor,ABorder,ALineSpace: Integer; + ACurFont: Boolean; AFlags: TfpgTextFlags); + procedure LoadNumber(APosX,APosY: Single; AColumn,ATextNum,ATextTot,AFont,AHeight,ABackColor,ABorder,ALineSpace: Integer; + ACurFont: Boolean; AFlags: TfpgTextFlags; ATotal,AAlpha: Boolean; ATypeNum: TSectPageNum); + property Commands: TList read FCommands; + property LineHeight: Integer read FHeight; + end; + + // command classes + + T_Command = class + end; + + PSection = ^T_Section; + PPage = ^T_Page; + PLigne = ^T_WriteLine; + PCommande = ^T_Command; + PFont = ^TfpgFont; + + T_WriteText = class(T_Command) + private + FPosX: Single; + FPosY: Single; + FColumn: Integer; + FText: Integer; + FFont: Integer; + FBackColor: Integer; + FBorder: Integer; + FLineSpace: Integer; + FCurFont: Boolean; + FFlags: TfpgTextFlags; + public + constructor Create(APosX,APosY: Single; AColumn,AText,AFont,ABackColor,ABorder,ALineSpace: Integer; ACurFont: Boolean; AFlags: TfpgTextFlags); virtual; + procedure SetPosY(const AValue: Single); + property GetPosX: Single read FPosX; + property GetPosY: Single read FPosY; + property GetColumn: Integer read FColumn; + property GetText: Integer read FText; + property GetFont: Integer read FFont; + property GetBackColor: Integer read FBackColor; + property GetBorder: Integer read FBorder; + property GetLineSpace: Integer read FLineSpace; + property GetCurFont: Boolean read FCurFont; + property GetFlags: TfpgTextFlags read FFlags; + end; + + T_Number = class(T_Command) + private + FPosX: Single; + FPosY: Single; + FColumn: Integer; + FTextNum: Integer; + FTextTot: Integer; + FFont: Integer; + FBackColor: Integer; + FBorder: Integer; + FLineSpace: Integer; + FCurFont: Boolean; + FFlags: TfpgTextFlags; + FTotal: Boolean; + FAlpha: Boolean; + FTypeNum: TSectPageNum; + public + constructor Create(APosX,APosY: Single; AColumn,ATextNum,ATextTot,AFont,ABackColor,ABorder,ALineSpace: Integer; + ACurFont: Boolean; AFlags: TfpgTextFlags; ATotal,AAlpha: Boolean; ATypeNum: TSectPageNum); virtual; + procedure SetPosY(const AValue: Single); + property GetPosX: Single read FPosX; + property GetPosY: Single read FPosY; + property GetColumn: Integer read FColumn; + property GetTextNum: Integer read FTextNum; + property GetTextTot: Integer read FTextTot; + property GetFont: Integer read FFont; + property GetBackColor: Integer read FBackColor; + property GetBorder: Integer read FBorder; + property GetLineSpace: Integer read FLineSpace; + property GetCurFont: Boolean read FCurFont; + property GetFlags: TfpgTextFlags read FFlags; + property GetTotal: Boolean read FTotal; + property GetAlpha: Boolean read FAlpha; + property GetTypeNum: TSectPageNum read FTypeNum; + end; + + T_Line = class(T_Command) + private + FPosX: Single; + FPosY: Single; + FColumn: Integer; + FStyle: Integer; + FEndX: Single; + FEndY: Single; + public + constructor Create(APosX,APosY: Single; AColumn,AStyle: Integer; AEndX,AEndY: Single); virtual; + property GetPosX: Single read FPosX; + property GetPosY: Single read FPosY; + property GetColumn: Integer read FColumn; + property GetStyle: Integer read FStyle; + property GetEndX: Single read FEndX; + property GetEndY: Single read FEndY; + end; + + T_Column = class(T_Command) + private + FPos: Single; + FWidth: Single; + FMargin: Single; + FColor: TfpgColor; + public + constructor Create(APos,AWidth,AMargin: Single; AColor: TfpgColor); virtual; + function GetTextPos: Single; + function GetTextWidth: Single; + procedure SetColColor(AColor: TfpgColor); + property ColPos: Single read FPos write FPos; + property ColWidth: Single read FWidth write FWidth; + property ColMargin: Single read FMargin write FMargin; + property GetColor: TfpgColor read FColor; + end; + + T_Font = class(T_Command) + private + FFont: TfpgFont; + FColor: TfpgColor; + FSize: string; + public + constructor Create(AFont: string; AColor: TfpgColor); virtual; + destructor Destroy; override; + function GetHeight: Integer; + property GetFont: TfpgFont read FFont; + property GetColor: TfpgColor read FColor; + property GetSize: string read FSize; + end; + + T_LineSpace = class(T_Command) + private + FSup: Single; + FInt: Single; + FInf: Single; + public + constructor Create(ASup,AInt,AInf: Single); virtual; + property GetSup: Single read FSup; + property GetInt: Single read FInt; + property GetInf: Single read FInf; + end; + + T_Space = class(T_Command) + private + FPosY: Single; + FColumn: Integer; + FHeight: Single; + FBackColor: Integer; + public + constructor Create(APosY: Single; AColumn: Integer; AHeight: Single; ABackColor: Integer); virtual; + procedure SetPosY(const AValue: Single); + property GetPosY: Single read FPosY; + property GetColumn: Integer read FColumn; + property GetHeight: Single read FHeight; + property GetBackColor: Integer read FBackColor; + end; + + T_BackColor = class(T_Command) + private + FColor: TfpgColor; + public + constructor Create(AColor: TfpgColor); virtual; + property GetColor: TfpgColor read FColor; + end; + + T_LineStyle = class(T_Command) + private + FThick: Single; + FColor: TfpgColor; + FStyle: TfpgLineStyle; + public + constructor Create(AThick: Single; AColor: Tfpgcolor; AStyle: TfpgLineStyle); virtual; + property GetThick: Single read FThick; + property GetColor: TfpgColor read FColor; + property GetStyle: TfpgLineStyle read FStyle; + end; + + T_Border = class(T_Command) + private + FFlags: TBorderFlags; + FStyle: Integer; + public + constructor Create(AFlags: TBorderFlags; AStyle: Integer); + property GetFlags: TBorderFlags read FFlags; + property GetStyle: Integer read FStyle; + end; + + T_Frame = class(T_Command) + private + FStyle: Integer; + FZone: TZone; + public + constructor Create(AStyle: Integer; AZone: TZone); + property GetStyle: Integer read FStyle; + property GetZone: TZone read FZone; + end; + + T_Surface = class(T_Command) + private + FPoints: T_Points; + FColor: TfpgColor; + public + constructor Create(APoints: array of TRefPos; AColor: TfpgColor); + property GetPoints: T_Points read FPoints; + property GetColor: TfpgColor read FColor; + end; + + T_Image = class(T_Command) + private + FImage: Integer; + FColumn: Integer; + FPosX: Single; + FPosY: Single; + public + constructor Create(APosX,APosY: Single; AColumn,AImageNum: Integer); + property GetImage: Integer read FImage; + property GetColumn: Integer read FColumn; + property GetPosX: Single read FPosX; + property GetPosY: Single read FPosY; + end; + +var + Sections: TList; + Columns: TList; + Texts: TStringList; + ImageNames: TStringList; + Fonts: TList; + LineSpaces: TList; + BackColors: TList; + LineStyles: TList; + Borders: TList; + Images: TList; + VSection: T_Section; + VPage: T_Page; + VGroup: T_Group; + VWriteLine: T_WriteLine; + VCommand: T_Command; + VColumn: T_Column; + VBackColor: T_BackColor; + VFont: T_Font; + VLineSpace: T_LineSpace; + VLineStyle: T_LineStyle; + VBorder: T_Border; + +implementation + +// utility functions + +// extracts the font size from the fontdesc + +function ExtractFontSize(const AValue: string): string; +begin +if Pos(':',AValue)> 0 +then + Result:= Copy(AValue,Succ(Pos('-',AValue)),Pred(Pos(':',Avalue)-Pos('-',AValue))) +else + Result:= Copy(AValue,Succ(Pos('-',AValue)),Length(AValue)-Pos('-',AValue)); +end; + +// document class methods + +function T_Section.GetFirstPage: Integer; +begin +Result:= T_Page(Pages[0]).PagesTot; +end; + +function T_Section.GetTotalPages: Integer; +begin +if Pages.Count> 0 +then + Result:= T_Page(Pages[Pred(Pages.Count)]).PagesTot +else + Result:= 0; +end; + +constructor T_Section.Create(APaper: TPaper; AMargins: TDimensions; ANum: Integer); +begin +FNumSect:= ANum; +FNbPages:= 0; +FPaper:= APaper; +FMargins:= AMargins; +FBotHead:= FMargins.T; +FTopFoot:= FMargins.B; +FPages:= TList.Create; +FHeader:= TList.Create; +FFooter:= TList.Create; +FFrames:= TList.Create; +end; + +destructor T_Section.Destroy; +var + Cpt: Integer; +begin +if FPages.Count> 0 +then + for Cpt:= 0 to Pred(FPages.Count) do + T_Page(FPages[Cpt]).Free; +FPages.Free; +if FHeader.Count> 0 +then + for Cpt:= 0 to Pred(FHeader.Count) do + T_Command(FHeader[Cpt]).Free; +FHeader.Free; +if FFooter.Count> 0 +then + for Cpt:= 0 to Pred(FFooter.Count) do + T_Command(FFooter[Cpt]).Free; +FFooter.Free; +if FFrames.Count> 0 +then + for Cpt:= 0 to Pred(FFrames.Count) do + T_Command(FFrames[Cpt]).Free; +FFrames.Free; +inherited Destroy; +end; + +procedure T_Section.LoadPage(APageNum: Integer); +begin +Inc(FNbPages); +VPage:= T_Page.Create(FNbPages,APageNum); +FPages.Add(VPage); +end; + +procedure T_Section.LoadCmdHeader; +var + Cpt: Integer; +begin +for Cpt:= 0 to Pred(VWriteLine.Commands.Count) do + FHeader.Add(VWriteLine.Commands.Items[Cpt]); +VWriteLine.FHeight:= 0; +VWriteLine.Commands.Clear; +end; + +procedure T_Section.LoadCmdPage; +var + Cpt: Integer; +begin +for Cpt:= 0 to Pred(VWriteLine.Commands.Count) do + T_Page(Pages[Pred(FPages.Count)]).Commands.Add(VWriteLine.Commands.Items[Cpt]); +VWriteLine.FHeight:= 0; +VWriteLine.Commands.Clear; +end; + +procedure T_Section.LoadCmdFooter; +var + Cpt: Integer; +begin +for Cpt:= 0 to Pred(VWriteLine.Commands.Count) do + FFooter.Add(VWriteLine.Commands.Items[Cpt]); +VWriteLine.FHeight:= 0; +VWriteLine.Commands.Clear; +end; + +procedure T_Section.LoadCmdGroup; +var + Cpt: Integer; +begin +for Cpt:= 0 to Pred(VWriteLine.Commands.Count) do + VGroup.Commands.Add(VWriteLine.Commands.Items[Cpt]); +with VGroup do + begin + FLineHeight:= VWriteLine.FHeight; + FGroupHeight:= FGroupHeight+FLineHeight; + end; +VWriteLine.FHeight:= 0; +VWriteLine.Commands.Clear; +end; + +procedure T_Section.LoadCmdGroupToPage; +var + Cpt: Integer; +begin +for Cpt:= 0 to Pred(VGroup.Commands.Count) do + T_Page(Pages[Pred(FPages.Count)]).Commands.Add(VGroup.Commands.Items[Cpt]); +VGroup.FGroupHeight:= 0; +VGroup.Commands.Clear; +end; + +procedure T_Section.LoadSpaceHeader(APosY: Single; AColumn: Integer; AHeight: Single; ABackColor: Integer); +begin +VCommand:= T_Space.Create(APosY,AColumn,AHeight,ABackColor); +FHeader.Add(VCommand); +end; + +procedure T_Section.LoadSpacePage(APosY: Single; AColumn: Integer; AHeight: Single; ABackColor: Integer); +begin +VCommand:= T_Space.Create(APosY,AColumn,AHeight,ABackColor); +T_Page(Pages[Pred(FPages.Count)]).Commands.Add(VCommand); +end; + +procedure T_Section.LoadSpaceFooter(APosY: Single; AColumn: Integer; AHeight: Single; ABackColor: Integer); +begin +VCommand:= T_Space.Create(APosY,AColumn,AHeight,ABackColor); +FFooter.Add(VCommand); +end; + +procedure T_Section.LoadSpaceGroup(AHeight: Single); +begin +VGroup.FGroupHeight:= VGroup.FGroupHeight+AHeight; +end; + +procedure T_Section.LoadFrame(AStyle: Integer; AZone: TZone); +begin +VCommand:= T_Frame.Create(AStyle,AZone); +FFrames.Add(VCommand); +end; + +procedure T_Section.LoadLine(APosXBegin,APosYBegin: Single; AColumn: Integer; APosXEnd,APosYEnd: Single; AStyle: Integer); +begin +VCommand:= T_Line.Create(APosXBegin,APosYBegin,AColumn,AStyle,APosXEnd,APosYEnd); +T_Page(Pages[Pred(FPages.Count)]).Commands.Add(VCommand); +end; + +procedure T_Section.LoadLineHorizHeader(APosXBegin,APosYBegin: Single; AColumn: Integer; APosXEnd,APosYEnd: Single; + AStyle: Integer); +begin +VCommand:= T_Line.Create(APosXBegin,APosYBegin,AColumn,AStyle,APosXEnd,APosYEnd); +FHeader.Add(VCommand); +end; + +procedure T_Section.LoadLineHorizPage(APosXBegin,APosYBegin: Single; AColumn: Integer; APosXEnd,APosYEnd: Single; AStyle: Integer); +begin +VCommand:= T_Line.Create(APosXBegin,APosYBegin,AColumn,AStyle,APosXEnd,APosYEnd); +T_Page(Pages[Pred(FPages.Count)]).Commands.Add(VCommand); +end; + +procedure T_Section.LoadLineHorizFooter(APosXBegin,APosYBegin: Single; AColumn: Integer; APosXEnd,APosYEnd: Single; AStyle: Integer); +begin +VCommand:= T_Line.Create(APosXBegin,APosYBegin,AColumn,AStyle,APosXEnd,APosYEnd); +FFooter.Add(VCommand); +end; + +procedure T_Section.LoadLineHorizGroupe(AHeight: Single); +begin +VGroup.FGroupHeight:= VGroup.FGroupHeight+AHeight; +end; + +procedure T_Section.LoadSurf(APos: T_Points; AColor: TfpgColor); +begin +VCommand:= T_Surface.Create(APos,AColor); +T_Page(Pages[Pred(FPages.Count)]).Commands.Add(VCommand); +end; + +procedure T_Section.LoadImgHeader(APosX,APosY: Single; AColumn,AImgNum: Integer); +begin +VCommand:= T_Image.Create(APosX,APosY,AColumn,AImgNum); +FHeader.Add(VCommand); +end; + +procedure T_Section.LoadImgPage(APosX,APosY: Single; AColumn,AImgNum: Integer); +begin +VCommand:= T_Image.Create(APosX,APosY,AColumn,AImgNum); +T_Page(Pages[Pred(FPages.Count)]).Commands.Add(VCommand); +end; + +procedure T_Section.LoadImgFooter(APosX,APosY: Single; AColumn,AImgNum: Integer); +begin +VCommand:= T_Image.Create(APosX,APosY,AColumn,AImgNum); +FFooter.Add(VCommand); +end; + +function T_Section.GetCmdPage(NumPage: Integer): TList; +begin +Result:= T_Page(Pages[Pred(NumPage)]).Commands; +end; + +constructor T_Page.Create(ANumSec,ANumTot: Integer); +begin +FNumPageTot:= ANumTot; +FNumPageSect:= ANumSec; +FCommands:= TList.Create; +end; + +destructor T_Page.Destroy; +var + Cpt: Integer; +begin +if FCommands.Count> 0 +then + for Cpt:= 0 to Pred(FCommands.Count) do + T_Command(FCommands[Cpt]).Free; +FCommands.Free; +inherited Destroy; +end; + +constructor T_Group.Create; +begin +FLineHeight:= 0; +FGroupHeight:= 0; +FCommands:= TList.Create; +end; + +destructor T_Group.Destroy; +var + Cpt: Integer; +begin +if FCommands.Count> 0 +then + for Cpt:= 0 to Pred(FCommands.Count) do + T_Command(FCommands[Cpt]).Free; +FCommands.Free; +inherited Destroy; +end; + +constructor T_WriteLine.Create; +begin +FHeight:= 0; +FCommands:= TList.Create; +end; + +destructor T_WriteLine.Destroy; +var + Cpt: Integer; +begin +if FCommands.Count> 0 +then + for Cpt:= 0 to Pred(FCommands.Count) do + T_Command(FCommands[Cpt]).Free; +FCommands.Free; +inherited Destroy; +end; + +procedure T_WriteLine.LoadText(APosX,APosY: Single; AColumn,AText,AFont,AHeight,ABackColor,ABorder,ALineSpace: Integer; + ACurFont: Boolean; AFlags: TfpgTextFlags); +begin +if FHeight< AHeight +then + FHeight:= AHeight; +VCommand:= T_WriteText.Create(APosX,APosY,AColumn,AText,AFont,ABackColor,ABorder,ALineSpace,ACurFont,AFlags); +Commands.Add(VCommand); +end; + +procedure T_WriteLine.LoadNumber(APosX,APosY: Single; AColumn,ATextNum,ATextTot,AFont,AHeight,ABackColor,ABorder,ALineSpace: Integer; + ACurFont: Boolean; AFlags: TfpgTextFlags; ATotal,AAlpha: Boolean; ATypeNum: TSectPageNum); +begin +if FHeight< AHeight +then + FHeight:= AHeight; +VCommand:= T_Number.Create(APosX,APosY,AColumn,ATextNum,ATextTot,AFont,ABackColor,ABorder,ALineSpace,ACurFont,AFlags,ATotal,AAlpha,ATypeNum); +Commands.Add(VCommand); +end; + +// command class methods + +procedure T_WriteText.SetPosY(const AValue: Single); +begin +if FPosY<> AValue +then + FPosY:= AValue; +end; + +constructor T_WriteText.Create(APosX,APosY: Single; AColumn,AText,AFont,ABackColor,ABorder,ALineSpace: Integer; ACurFont: Boolean; AFlags: TfpgTextFlags); +begin +inherited Create; +FPosX:= APosX; +FPosY:= APosY; +FColumn:= AColumn; +FText:= AText; +FFont:= AFont; +FBackColor:= ABackColor; +FBorder:= ABorder; +FLineSpace:= ALineSpace; +FCurFont:= ACurFont; +FFlags:= AFlags; +end; + +procedure T_Number.SetPosY(const AValue: Single); +begin +if FPosY<> AValue +then + FPosY:= AValue; +end; + +constructor T_Number.Create(APosX,APosY: Single; AColumn,ATextNum,ATextTot,AFont,ABackColor,ABorder,ALineSpace: Integer; + ACurFont: Boolean; AFlags: TfpgTextFlags; ATotal,AAlpha: Boolean; ATypeNum: TSectPageNum); +begin +inherited Create; +FPosX:= APosX; +FPosY:= APosY; +FColumn:= AColumn; +FTextNum:= ATextNum; +FTextTot:= ATextTot; +FFont:= AFont; +FBackColor:= ABackColor; +FBorder:= ABorder; +FLineSpace:= ALineSpace; +FCurFont:= ACurFont; +FFlags:= AFlags; +FTotal:= ATotal; +FAlpha:= AAlpha; +FTypeNum:= ATypeNum; +end; + +constructor T_Line.Create(APosX,APosY: Single; AColumn,AStyle: Integer; AEndX,AEndY: Single); +begin +FPosX:= APosX; +FPosY:= APosY; +FColumn:= AColumn; +FStyle:= AStyle; +FEndX:= AEndX; +FEndY:= AEndY; +end; + +constructor T_Column.Create(APos,AWidth,AMargin: Single; AColor: TfpgColor); +begin +inherited Create; +FPos:= APos; +FWidth:= AWidth; +FMargin:= AMargin; +FColor:= AColor; +end; + +function T_Column.GetTextPos: Single; +begin +Result:= FPos+FMargin; +end; + +function T_Column.GetTextWidth: Single; +begin +Result:= FWidth-(FMargin*2); +end; + +procedure T_Column.SetColColor(AColor: TfpgColor); +begin +if FColor<> AColor +then + FColor:= AColor; +end; + +constructor T_Font.Create(AFont: string; AColor: TfpgColor); +begin +inherited Create; +FFont:= fpgApplication.GetFont(AFont); +FColor:= AColor; +FSize:= ExtractFontSize(AFont); +end; + +destructor T_Font.Destroy; +begin +FFont.Free; +inherited Destroy; +end; + +function T_Font.GetHeight: Integer; +begin +Result:= TfpgFont(FFont).Height; +end; + +constructor T_LineSpace.Create(ASup,AInt,AInf: Single); +begin +inherited Create; +FSup:= ASup; +FInt:= AInt; +FInf:= AInf; +end; + +constructor T_Space.Create(APosY: Single; AColumn: Integer; AHeight: Single; ABackColor: Integer); +begin +inherited Create; +FPosY:= APosY; +FColumn:= AColumn; +FHeight:= AHeight; +FBackColor:= ABackColor; +end; + +constructor T_Surface.Create(APoints: array of TRefPos; AColor: TfpgColor); +var + Cpt: Integer; +begin +inherited Create; +SetLength(FPoints,Length(APoints)); +for Cpt:= 0 to Pred(Length(FPoints)) do + FPoints[Cpt]:= APoints[Cpt]; +FColor:= AColor; +end; + +procedure T_Space.SetPosY(const AValue: Single); +begin +if FPosY<> AValue +then + FPosY:= AValue; +end; + +constructor T_BackColor.Create(AColor: TfpgColor); +begin +FColor:= AColor; +end; + +constructor T_LineStyle.Create(AThick: Single; AColor: Tfpgcolor; AStyle: TfpgLineStyle); +begin +inherited Create; +FThick:= AThick; +FColor:= AColor; +FStyle:= AStyle; +end; + +constructor T_Border.Create(AFlags: TBorderFlags; AStyle: Integer); +begin +inherited Create; +FFlags:= AFlags; +FStyle:= AStyle; +end; + +constructor T_Frame.Create(AStyle: Integer; AZone: TZone); +begin +inherited Create; +FStyle:= AStyle; +FZone:= AZone; +end; + +constructor T_Image.Create(APosX,APosY: Single; AColumn,AImageNum: Integer); +begin +inherited Create; +FImage:= AImageNum; +FColumn:= AColumn; +FPosX:= APosX; +FPosY:= APosY; +end; + +end. + diff --git a/src/reportengine/u_pdf.pas b/src/reportengine/u_pdf.pas new file mode 100644 index 00000000..48e3fa92 --- /dev/null +++ b/src/reportengine/u_pdf.pas @@ -0,0 +1,2117 @@ +{ + << Impressions >> U_Pdf.pas + + Copyright (C) 2010 - JM.Levecque - <jmarc.levecque@jmlesite.fr> + + This library is a free software coming as a add-on to fpGUI toolkit + See the copyright included in the fpGUI distribution for details about redistribution + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Description: + This unit produces the pdf file +} + +unit U_Pdf; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, StrUtils, + fpg_main, fpg_base, fpg_dialogs; + +type + TPdfObjet = class(TObject) + private + protected + public + constructor Create; virtual; + destructor Destroy; override; + end; + + TPdfBoolean = class(TPdfObjet) + private + FValue: Boolean; + protected + procedure WriteBoolean(const AFlux: TStream); + public + constructor CreateBoolean(const AValue: Boolean); + destructor Destroy; override; + end; + + TPdfInteger = class(TPdfObjet) + private + FValue: Integer; + protected + procedure WriteInteger(const AFlux: TStream); + procedure IncrementeInteger; + property Value: Integer read FValue write FValue; + public + constructor CreateInteger(const AValue: Integer); + destructor Destroy; override; + end; + + TPdfReference = class(TPdfObjet) + private + FValue: Integer; + protected + procedure WriteReference(const AFlux: TStream); + public + constructor CreateReference(const AValue: Integer); + destructor Destroy; override; + end; + + TPdfName = class(TPdfObjet) + private + FValue: string; + protected + procedure WriteName(const AFlux: TStream); + public + constructor CreateName(const AValue: string); + destructor Destroy; override; + end; + + TPdfString = class(TPdfObjet) + private + FValue: string; + protected + procedure WriteString(const AFlux: TStream); + public + constructor CreateString(const AValue: string); + destructor Destroy; override; + end; + + TPdfArray = class(TPdfObjet) + private + FArray: TList; + protected + procedure WriteArray(const AFlux: TStream); + procedure AddItem(const AValue: TPdfObjet); + public + constructor CreateArray; + destructor Destroy; override; + end; + + TPdfStream = class(TPdfObjet) + private + FStream: TList; + protected + procedure WriteStream(const AFlux: TStream); + procedure AddItem(const AValue: TPdfObjet); + public + constructor CreateStream; + destructor Destroy; override; + end; + + TPdfFonte = class(TPdfObjet) + private + FTxtFont: Integer; + FTxtSize: string; + protected + procedure WriteFonte(const AFlux: TStream); + function WriteFonteStream(const FFlux: TMemoryStream; const AFlux: TStream): Int64; + public + constructor CreateFonte(const AFont: Integer; const ASize: string); + destructor Destroy; override; + end; + + TPdfText = class(TPdfObjet) + private + FTxtPosX: Single; + FTxtPosY: Single; + FTxtText: TPdfString; + protected + procedure WriteText(const AFlux: TStream); + public + constructor CreateText(const APosX,APosY: Single; const AText: string); + destructor Destroy; override; + end; + + TPdfLigne = class(TPdfObjet) + private + FEpais: Single; + FStaX: Single; + FStaY: Single; + FEndX: Single; + FEndY: Single; + protected + procedure WriteLigne(const AFlux: TStream); + public + constructor CreateLigne(const AEpais,AStaX,AStaY,AEndX,AEndY: Single); + destructor Destroy; override; + end; + + TPdfRectangle = class(TPdfObjet) + private + FEpais: Single; + FRecX: Single; + FRecY: Single; + FRecW: Single; + FRecH: Single; + FFill: Boolean; + FStroke: Boolean; + protected + procedure WriteRectangle(const AFlux: TStream); + public + constructor CreateRectangle(const AEpais,APosX,APosY,AWidth,AHeight: Single; const AFill,AStroke: Boolean); + destructor Destroy; override; + end; + + TRefPos= record + X: Single; + Y: Single; + end; + + T_Points = array of TRefPos; + + TPdfSurface = class(TPdfObjet) + private + FPoints: T_Points; + protected + procedure WriteSurface(const AFlux: TStream); + public + constructor CreateSurface(const APoints: T_Points); + destructor Destroy; override; + end; + + TPdfImage = class(TPdfObjet) + private + FNumber: Integer; + FLeft: Single; + FBottom: Single; + FWidth: Integer; + FHeight: Integer; + protected + function WriteImageStream(const ANumber: Integer; AFlux: TStream): Int64; + procedure WriteImage(const AFlux: TStream); + public + constructor CreateImage(const ALeft,ABottom: Single; AWidth,AHeight,ANumber: Integer); + destructor Destroy; override; + end; + + TPdfLineStyle = class(TPdfObjet) + private + FDash: TfpgLineStyle; + FPhase: Integer; + protected + procedure WriteLineStyle(const AFlux: TStream); + public + constructor CreateLineStyle(ADash: TfpgLineStyle; APhase: Integer); + destructor Destroy; override; + end; + + TPdfColor = class(TPdfObjet) + private + FRed: string; + FGreen: string; + FBlue: string; + FStroke: Boolean; + protected + procedure WriteColor(const AFlux: TStream); + public + constructor CreateColor(const AStroke: Boolean; AColor: TfpgColor); + destructor Destroy; override; + end; + + TPdfDicElement = class(TObject) + private + FKey: TPdfName; + FValue: TPdfObjet; + protected + procedure WriteDicElement(const AFlux: TStream); + public + constructor CreateDicElement(const AKey: string; const AValue: TPdfObjet); + destructor Destroy; override; + end; + + TPdfDictionary = class(TPdfObjet) + private + FElement: TList; // list of TPdfDicElement + protected + procedure AddElement(const AKey: string; const AValue: TPdfObjet); + function ElementParCle(const AValue: string): Integer; + procedure WriteDictionary(const AObjet: Integer; const AFlux: TStream); + public + constructor CreateDictionary; + destructor Destroy; override; + end; + + TPdfXRef = class(TObject) + private + FOffset: Integer; + FObjet: TPdfDictionary; + FStream: TPdfStream; + protected + procedure WriteXRef(const AFlux: TStream); + public + constructor CreateXRef; + destructor Destroy; override; + property Offset: Integer read FOffset write FOffset; + end; + + TPageLayout= (lSingle,lTwo,lContinuous); + + TPdfDocument = class(TObject) + private + FPreferences: Boolean; + FPageLayout: TPageLayout; + FZoomValue: string; + FXRefObjets: TList; // list of TPdfXRef + protected + function ElementParNom(const AValue: string): Integer; + procedure WriteXRefTable(const AFlux: TStream); + procedure WriteObjet(const AObjet: Integer; const AFlux: TStream); + procedure CreateRefTable; + procedure CreateTrailer; + function CreateCatalog: Integer; + procedure CreateInfo; + procedure CreatePreferences; + function CreatePages(Parent: Integer): Integer; + function CreatePage(Parent,Haut,Larg,PageNum: Integer): Integer; + function CreateOutlines: Integer; + function CreateOutline(Parent,SectNo,PageNo: Integer; SectTitre: string): Integer; + procedure CreateStdFont(NomFonte: string; NumFonte: Integer); + function LoadFont(NomFonte: string): string; + procedure CreateTtfFont(const NumFonte: Integer); + procedure CreateTp1Font(const NumFonte: Integer); + procedure CreateFontDescriptor(const NumFonte: Integer); + procedure CreateFontWidth; + procedure CreateFontFile(const NumFonte: Integer); + procedure CreateImage(ImgWidth,ImgHeight,NumImg: Integer); + function CreateContents: Integer; + procedure CreateStream(NumeroPage,PageNum: Integer); + public + constructor CreateDocument(const ALayout: TPageLayout= lSingle; const AZoom: string= '100'; const APreferences: Boolean= True); + destructor Destroy; override; + procedure WriteDocument(const AFlux: TStream); + property PageLayout: TPageLayout read FPageLayout write FPageLayout default lSingle; + end; + + TFontDef = record + FType: string; + FName: string; + FAscent: string; + FDescent: string; + FCapHeight: string; + FFlags: string; + FFontBBox: string; + FItalicAngle: string; + FStemV: string; + FMissingWidth: string; + FEncoding: string; + FFile: string; + FOriginalSize: string; + FDiffs: widestring; + FCharWidth: widestring; + end; + +const + CRLF= #13#10; + PDF_VERSION= '%PDF-1.3'; + PDF_FILE_END= '%%EOF'; + PDF_MAX_GEN_NUM= 65535; + PDF_UNICODE_HEADER = 'FEFF001B%s001B'; + PDF_LANG_STRING = 'fr'; + +var + Document: TPdfDocument; + OldDecSeparator: Char; + Outline: Boolean; + FontDirectory: string; + +implementation + +uses + U_Report, U_Command; + +var + Trailer: TPdfDictionary; + CurrentColor: string; + CurrentWidth: string; + Catalogue: Integer; + FontDef: TFontDef; + Flux: TMemoryStream; + FontFiles: array of string; + +// utility functions + +function InsertEscape(const AValue: string): string; +var + Chaine: string; +begin +Result:= ''; +Chaine:= AValue; +if Pos('\',Chaine)> 0 +then + Chaine:= AnsiReplaceStr(Chaine,'\','\\'); +if Pos('(',Chaine)> 0 +then + Chaine:= AnsiReplaceStr(Chaine,'(','\('); +if Pos(')',Chaine)> 0 +then + Chaine:= AnsiReplaceStr(Chaine,')','\)'); +Result:= Chaine; +//while Pos('\',Chaine)> 0 do +// begin +// Result:= Result+Copy(Chaine,1,Pred(Pos('\',Chaine)))+'\\'; +// Chaine:= Copy(Chaine,Succ(Pos('\',Chaine)),Length(Chaine)-Pos('\',Chaine)); +// end; +//Chaine:= Result+Chaine; +//Result:= ''; +//while Pos('(',Chaine)> 0 do +// begin +// Result:= Result+Copy(Chaine,1,Pred(Pos('(',Chaine)))+'\('; +// Chaine:= Copy(Chaine,Succ(Pos('(',Chaine)),Length(Chaine)-Pos('(',Chaine)); +// end; +//Chaine:= Result+Chaine; +//Result:= ''; +//while Pos(')',Chaine)> 0 do +// begin +// Result:= Result+Copy(Chaine,1,Pred(Pos(')',Chaine)))+'\)'; +// Chaine:= Copy(Chaine,Succ(Pos(')',Chaine)),Length(Chaine)-Pos(')',Chaine)); +// end; +//Result:= Result+Chaine; +end; + +procedure WriteChaine(const Valeur: string; AFlux: TStream); +begin +AFlux.Write(PChar(Valeur)^,Length(Valeur)); +end; + +function IntToChaine(const Valeur: Integer; const Long: Integer): string; +var + Chaine: string; + Cpt: Integer; +begin +Result:= ''; +Chaine:= IntToStr(Valeur); +if Length(Chaine)< Long +then + for Cpt:= Succ(Length(Chaine)) to Long do + Result:= Result+'0'; +Result:= Result+Chaine; +end; + +function DateToPdfDate(const ADate: TDateTime): string; +begin +Result:= FormatDateTime('"D:"yyyymmddhhnnss',ADate); +end; + +function ExtractBaseFontName(const AValue: string): string; +var + FontName,Chaine1,Chaine2: string; +begin +FontName:= Copy(AValue,1,Pred(Pos('-',AValue))); +if Pos(':',AValue)> 0 +then + begin + Chaine1:= Copy(AValue,Succ(Pos(':',AValue)),Length(AValue)-Pos(':',AValue)); + Chaine1:= Uppercase(Chaine1[1])+Copy(Chaine1,2,Pred(Length(Chaine1))); + if Pos(':',Chaine1)> 0 + then + begin + Chaine2:= Copy(Chaine1,Succ(Pos(':',Chaine1)),Length(Chaine1)-Pos(':',Chaine1)); + Chaine2:= Uppercase(Chaine2[1])+Copy(Chaine2,2,Pred(Length(Chaine2))); + Chaine1:= Copy(Chaine1,1,Pred(Pos(':',Chaine1))); + Chaine1:= Uppercase(Chaine1[1])+Copy(Chaine1,2,Pred(Length(Chaine1))); + Chaine1:= Chaine1+Chaine2; + end; + Chaine1:= '-'+Chaine1; + end; +Result:= FontName+Chaine1; +end; + +// object methods + +constructor TPdfObjet.Create; +begin + // to be implemented by descendents +end; + +destructor TPdfObjet.Destroy; +begin +inherited; +end; + +procedure TPdfBoolean.WriteBoolean(const AFlux: TStream); +begin +if FValue +then + WriteChaine('true',AFlux) +else + WriteChaine('false',AFlux); +end; + +constructor TPdfBoolean.CreateBoolean(const AValue: Boolean); +begin +inherited Create; +FValue:= AValue; +end; + +destructor TPdfBoolean.Destroy; +begin +inherited; +end; + +procedure TPdfInteger.WriteInteger(const AFlux: TStream); +begin +WriteChaine(IntToStr(FValue), AFlux); +end; + +procedure TPdfInteger.IncrementeInteger; +begin +FValue:= FValue+1; +end; + +constructor TPdfInteger.CreateInteger(const AValue: Integer); +begin +inherited Create; +FValue:= AValue; +end; + +destructor TPdfInteger.Destroy; +begin +inherited; +end; + +procedure TPdfReference.WriteReference(const AFlux: TStream); +begin +WriteChaine(IntToStr(FValue)+' 0 R',AFlux); +end; + +constructor TPdfReference.CreateReference(const AValue: Integer); +begin +inherited Create; +FValue:= AValue; +end; + +destructor TPdfReference.Destroy; +begin +inherited; +end; + +procedure TPdfName.WriteName(const AFlux: TStream); +begin +if FValue<> '' +then + if Pos('Length1',FValue)> 0 + then + WriteChaine('/Length1',AFlux) + else + WriteChaine('/'+FValue,AFlux); +end; + +constructor TPdfName.CreateName(const AValue: string); +begin +inherited Create; +FValue:= AValue; +end; + +destructor TPdfName.Destroy; +begin +inherited; +end; + +procedure TPdfString.WriteString(const AFlux: TStream); +begin +WriteChaine('('+Utf8ToAnsi(FValue)+')',AFlux); +end; + +constructor TPdfString.CreateString(const AValue: string); +begin +inherited Create; +FValue:= AValue; +if (Pos('(',FValue)> 0) or (Pos(')',FValue)> 0) or (Pos('\',FValue)> 0) +then + FValue:= InsertEscape(FValue); +end; + +destructor TPdfString.Destroy; +begin +inherited; +end; + +procedure TPdfArray.WriteArray(const AFlux: TStream); +var + Cpt: Integer; +begin +WriteChaine('[',AFlux); +for Cpt:= 0 to Pred(FArray.Count) do + begin + if Cpt> 0 + then + WriteChaine(' ',AFlux); + if TPdfObjet(FArray[Cpt]) is TPdfInteger + then + TPdfInteger(FArray[Cpt]).WriteInteger(AFlux); + if TPdfObjet(FArray[Cpt]) is TPdfReference + then + TPdfReference(FArray[Cpt]).WriteReference(AFlux); + if TPdfObjet(FArray[Cpt]) is TPdfName + then + TPdfName(FArray[Cpt]).WriteName(AFlux); + end; +WriteChaine(']',AFlux); +end; + +procedure TPdfArray.AddItem(const AValue: TPdfObjet); +begin +FArray.Add(AValue); +end; + +constructor TPdfArray.CreateArray; +begin +inherited Create; +FArray:= TList.Create; +end; + +destructor TPdfArray.Destroy; +var + Cpt: Integer; +begin +if FArray.Count> 0 +then + for Cpt:= 0 to Pred(FArray.Count) do + if TPdfObjet(FArray[Cpt]) is TPdfInteger + then + TPdfInteger(FArray[Cpt]).Free + else + if TPdfObjet(FArray[Cpt]) is TPdfReference + then + TPdfReference(FArray[Cpt]).Free + else + if TPdfObjet(FArray[Cpt]) is TPdfName + then + TPdfName(FArray[Cpt]).Free; +FArray.Free; +inherited; +end; + +procedure TPdfStream.WriteStream(const AFlux: TStream); +var + Cpt: Integer; +begin +for Cpt:= 0 to Pred(FStream.Count) do + begin + if TPdfObjet(FStream[Cpt]) is TPdfFonte + then + TPdfFonte(FStream[Cpt]).WriteFonte(AFlux); + if TPdfObjet(FStream[Cpt]) is TPdfColor + then + TPdfColor(FStream[Cpt]).WriteColor(AFlux); + if TPdfObjet(FStream[Cpt]) is TPdfText + then + TPdfText(FStream[Cpt]).WriteText(AFlux); + if TPdfObjet(FStream[Cpt]) is TPdfRectangle + then + TPdfRectangle(FStream[Cpt]).WriteRectangle(AFlux); + if TPdfObjet(FStream[Cpt]) is TPdfLigne + then + TPdfLigne(FStream[Cpt]).WriteLigne(AFlux); + if TPdfObjet(FStream[Cpt]) is TPdfLineStyle + then + TPdfLineStyle(FStream[Cpt]).WriteLineStyle(AFlux); + if TPdfObjet(FStream[Cpt]) is TPdfSurface + then + TPdfSurface(FStream[Cpt]).WriteSurface(AFlux); + if TPdfObjet(FStream[Cpt]) is TPdfImage + then + TPdfImage(FStream[Cpt]).WriteImage(AFlux); + end; +end; + +procedure TPdfStream.AddItem(const AValue: TPdfObjet); +begin +FStream.Add(AValue); +end; + +constructor TPdfStream.CreateStream; +begin +inherited Create; +FStream:= TList.Create; +end; + +destructor TPdfStream.Destroy; +var + Cpt: Integer; +begin +if FStream.Count> 0 +then + for Cpt:= 0 to Pred(FStream.Count) do + if TPdfObjet(FStream[Cpt]) is TPdfFonte + then + TPdfFonte(FStream[Cpt]).Free + else + if TPdfObjet(FStream[Cpt]) is TPdfColor + then + TPdfColor(FStream[Cpt]).Free + else + if TPdfObjet(FStream[Cpt]) is TPdfText + then + TPdfText(FStream[Cpt]).Free + else + if TPdfObjet(FStream[Cpt]) is TPdfRectangle + then + TPdfRectangle(FStream[Cpt]).Free + else + if TPdfObjet(FStream[Cpt]) is TPdfLigne + then + TPdfLigne(FStream[Cpt]).Free + else + if TPdfObjet(FStream[Cpt]) is TPdfLineStyle + then + TPdfLineStyle(FStream[Cpt]).Free + else + if TPdfObjet(FStream[Cpt]) is TPdfSurface + then + TPdfSurface(FStream[Cpt]).Free + else + if TPdfObjet(FStream[Cpt]) is TPdfImage + then + TPdfImage(FStream[Cpt]).Free; +FStream.Free; +inherited; +end; + +procedure TPdfFonte.WriteFonte(const AFlux: TStream); +begin +WriteChaine('/F'+IntToStr(FTxtFont)+' '+FTxtSize+' Tf'+CRLF,AFlux); +end; + +function TPdfFonte.WriteFonteStream(const FFlux: TMemoryStream; const AFlux: TStream): Int64; +var + BeginFlux,EndFlux: Int64; +begin +WriteChaine(CRLF+'stream'+CRLF,AFlux); +BeginFlux:= AFlux.Position; +FFlux.SaveToStream(AFlux); +EndFlux:= AFlux.Position; +Result:= EndFlux-BeginFlux; +WriteChaine(CRLF,AFlux); +WriteChaine('endstream',AFlux); +end; + +constructor TPdfFonte.CreateFonte(const AFont: Integer; const ASize: string); +begin +inherited Create; +FTxtFont:= AFont; +FTxtSize:= ASize; +end; + +destructor TPdfFonte.Destroy; +begin +inherited; +end; + +procedure TPdfText.WriteText(const AFlux: TStream); +begin +WriteChaine('BT'+CRLF,AFlux); +WriteChaine(FormatFloat('0.##',FTxtPosX)+' '+FormatFloat('0.##',FTxtPosY)+' Td'+CRLF,AFlux); +TPdfString(FTxtText).WriteString(AFlux); +WriteChaine(' Tj'+CRLF,AFlux); +WriteChaine('ET'+CRLF,AFlux); +end; + +constructor TPdfText.CreateText(const APosX,APosY: Single; const AText: string); +begin +inherited Create; +FTxtPosX:= APosX; +FTxtPosY:= APosY; +FTxtText:= TPdfString.CreateString(AText); +end; + +destructor TPdfText.Destroy; +begin +FTxtText.Free; +inherited; +end; + +procedure TPdfLigne.WriteLigne(const AFlux: TStream); +begin +if (FormatFloat('0.##',FEpais)+' w')<> CurrentWidth +then + begin + WriteChaine('1 J'+CRLF,AFlux); + WriteChaine(FormatFloat('0.##',FEpais)+' w'+CRLF,AFlux); + CurrentWidth:= FormatFloat('0.##',FEpais)+' w'; + end; +WriteChaine(FormatFloat('0.##',FStaX)+' '+FormatFloat('0.##',FStaY)+' m'+CRLF,AFlux); +WriteChaine(FormatFloat('0.##',FEndX)+' '+FormatFloat('0.##',FEndY)+' l'+CRLF,AFlux); +WriteChaine('S'+CRLF,AFlux); +end; + +constructor TPdfLigne.CreateLigne(const AEpais,AStaX,AStaY,AEndX,AEndY: Single); +begin +inherited Create; +FEpais:= AEpais; +FStaX:= AStaX; +FStaY:= AStaY; +FEndX:= AEndX; +FEndY:= AEndY; +end; + +destructor TPdfLigne.Destroy; +begin +inherited; +end; + +procedure TPdfRectangle.WriteRectangle(const AFlux: TStream); +begin +if FStroke +then + if (FormatFloat('0.##',FEpais)+' w')<> CurrentWidth + then + begin + WriteChaine('1 J'+CRLF,AFlux); + WriteChaine(FormatFloat('0.##',FEpais)+' w'+CRLF,AFlux); + CurrentWidth:= FormatFloat('0.##',FEpais)+' w'; + end; +WriteChaine(FormatFloat('0.##',FRecX)+' '+FormatFloat('0.##',FRecY)+' '+FormatFloat('0.##',FRecW)+' '+FormatFloat('0.##',FRecH)+' re'+CRLF,AFlux); +if FStroke +then + WriteChaine('S'+CRLF,AFlux); +if FFill +then + WriteChaine('f'+CRLF,AFlux); +end; + +constructor TPdfRectangle.CreateRectangle(const AEpais,APosX,APosY,AWidth,AHeight: Single; const AFill,AStroke: Boolean); +begin +inherited Create; +FEpais:= AEpais; +FRecX:= APosX; +FRecY:= APosY; +FRecW:= AWidth; +FRecH:= AHeight; +FFill:= AFill; +FStroke:= AStroke; +end; + +destructor TPdfRectangle.Destroy; +begin +inherited; +end; + +procedure TPdfSurface.WriteSurface(const AFlux: TStream); +var + Cpt: Integer; +begin +WriteChaine(FormatFloat('0.##',FPoints[0].X)+' '+FormatFloat('0.##',FPoints[0].Y)+' m'+CRLF,AFlux); +for Cpt:= 1 to Pred(Length(FPoints)) do + WriteChaine(FormatFloat('0.##',FPoints[Cpt].X)+' '+FormatFloat('0.##',FPoints[Cpt].Y)+' l'+CRLF,AFlux); +WriteChaine('h'+CRLF,AFlux); +WriteChaine('f'+CRLF,AFlux); +end; + +constructor TPdfSurface.CreateSurface(const APoints: T_Points); +begin +inherited Create; +FPoints:= APoints; +end; + +destructor TPdfSurface.Destroy; +begin +inherited; +end; + +function TPdfImage.WriteImageStream(const ANumber: Integer; AFlux: TStream): Int64; +var + CptW,CptH: Integer; + BeginFlux,EndFlux: Int64; +begin +WriteChaine(CRLF+'stream'+CRLF,AFlux); +BeginFlux:= AFlux.Position; +for CptH:= 0 to Pred(TfpgImage(Images[ANumber]).Height) do + for CptW:= 0 to Pred(TfpgImage(Images[ANumber]).Width) do + begin + AFlux.WriteByte(fpgGetRed(TfpgImage(Images[ANumber]).Colors[CptW,CptH])); + AFlux.WriteByte(fpgGetGreen(TfpgImage(Images[ANumber]).Colors[CptW,CptH])); + AFlux.WriteByte(fpgGetBlue(TfpgImage(Images[ANumber]).Colors[CptW,CptH])); + end; +EndFlux:= AFlux.Position; +Result:= EndFlux-BeginFlux; +WriteChaine(CRLF,AFlux); +WriteChaine('endstream',AFlux); +end; + +procedure TPdfImage.WriteImage(const AFlux: TStream); +begin +WriteChaine('q'+CRLF,AFlux); +WriteChaine(IntToStr(FWidth)+' 0 0 '+IntToStr(FHeight)+' '+FormatFloat('0.##',FLeft)+' ' + +FormatFloat('0.##',FBottom)+' cm'+CRLF,AFlux); +WriteChaine('/I'+IntToStr(FNumber)+' Do '+CRLF,AFlux); +WriteChaine('Q'+CRLF,AFlux); +end; + +constructor TPdfImage.CreateImage(const ALeft,ABottom: Single; AWidth,AHeight,ANumber: Integer); +begin +inherited Create; +FNumber:= ANumber; +FLeft:= ALeft; +FBottom:= ABottom; +FWidth:= AWidth; +FHeight:= AHeight; +end; + +destructor TPdfImage.Destroy; +begin +inherited; +end; + +procedure TPdfLineStyle.WriteLineStyle(const AFlux: TStream); +begin +WriteChaine('[',AFlux); +case FDash of + lsDash: + WriteChaine('5 5',AFlux); + lsDot: + WriteChaine('2 2',AFlux); + lsDashDot: + WriteChaine('5 2 2 2',AFlux); + lsDashDotDot: + WriteChaine('5 2 2 2 2 2',AFlux); + end; +WriteChaine('] '+IntToStr(FPhase)+' d'+CRLF,AFlux); +end; + +constructor TPdfLineStyle.CreateLineStyle(ADash: TfpgLineStyle; APhase: Integer); +begin +inherited Create; +FDash:= ADash; +FPhase:= APhase; +end; + +destructor TPdfLineStyle.Destroy; +begin +inherited; +end; + +procedure TPdfColor.WriteColor(const AFlux: TStream); +begin +if FStroke +then + begin + if (FRed+' '+FGreen+' '+FBlue+' rg')<> CurrentColor + then + begin + WriteChaine(FRed+' '+FGreen+' '+FBlue+' rg'+CRLF,AFlux); + CurrentColor:= FRed+' '+FGreen+' '+FBlue+' rg'; + end; + end +else + if (FRed+' '+FGreen+' '+FBlue+' RG')<> CurrentColor + then + begin + WriteChaine(FRed+' '+FGreen+' '+FBlue+' RG'+CRLF,AFlux); + CurrentColor:= FRed+' '+FGreen+' '+FBlue+' RG'; + end; +end; + +constructor TPdfColor.CreateColor(const AStroke: Boolean; AColor: TfpgColor); +begin + inherited Create; + FBlue := FormatFloat('0.##', fpgGetBlue(AColor)/256); + FGreen := FormatFloat('0.##', fpgGetGreen(AColor)/256); + FRed := FormatFloat('0.##', fpgGetRed(AColor)/256); + FStroke := AStroke; +end; + +destructor TPdfColor.Destroy; +begin +inherited +end; + +procedure TPdfDicElement.WriteDicElement(const AFlux: TStream); +begin +FKey.WriteName(AFlux); +WriteChaine(' ',AFlux); +if FValue is TPdfBoolean +then + TPdfBoolean(FValue).WriteBoolean(AFlux); +if FValue is TPdfInteger +then + TPdfInteger(FValue).WriteInteger(AFlux); +if FValue is TPdfReference +then + TPdfReference(FValue).WriteReference(AFlux); +if FValue is TPdfName +then + TPdfName(FValue).WriteName(AFlux); +if FValue is TPdfString +then + TPdfString(FValue).WriteString(AFlux); +if FValue is TPdfArray +then + TPdfArray(FValue).WriteArray(AFlux); +if FValue is TPdfDictionary +then + TPdfDictionary(FValue).WriteDictionary(-1,AFlux); +WriteChaine(CRLF,AFlux); +end; + +constructor TPdfDicElement.CreateDicElement(const AKey: string; const AValue: TPdfObjet); +begin +inherited Create; +FKey:= TPdfName.CreateName(AKey); +FValue:= AValue; +end; + +destructor TPdfDicElement.Destroy; +begin +FKey.Free; +if FValue is TPdfBoolean +then + TPdfBoolean(FValue).Free +else + if FValue is TPdfDictionary + then + TPdfDictionary(FValue).Free + else + if FValue is TPdfInteger + then + TPdfInteger(FValue).Free + else + if FValue is TPdfName + then + TPdfName(FValue).Free + else + if FValue is TPdfReference + then + TPdfReference(FValue).Free + else + if FValue is TPdfString + then + TPdfString(FValue).Free + else + if FValue is TPdfArray + then + TPdfArray(FValue).Free; +inherited; +end; + +procedure TPdfDictionary.AddElement(const AKey: string; const AValue: TPdfObjet); +var + DicElement: TPdfDicElement; +begin +DicElement:= TPdfDicElement.CreateDicElement(AKey,AValue); +FElement.Add(DicElement); +end; + +function TPdfDictionary.ElementParCle(const AValue: string): Integer; +var + Cpt: Integer; +begin +Result:= -1; +for Cpt:= 0 to Pred(FElement.Count) do + if TPdfDicElement(FElement[Cpt]).FKey.FValue= AValue + then + begin + Result:= Cpt; + Exit; + end; +end; + +procedure TPdfDictionary.WriteDictionary(const AObjet: Integer; const AFlux: TStream); +var + Long: TPdfInteger; + Cpt,NumImg,NumFnt: Integer; + Value: string; +begin +if TPdfName(TPdfDicElement(FElement[0]).FKey).FValue= '' +then + TPdfDicElement(FElement[0]).WriteDicElement(AFlux) // write a charwidth array of a font +else + begin + WriteChaine('<<'+CRLF,AFlux); + if FElement.Count> 0 + then + for Cpt:= 0 to Pred(FElement.Count) do + TPdfDicElement(FElement[Cpt]).WriteDicElement(AFlux); + NumImg:= -1; + NumFnt:= -1; + if FElement.Count> 0 + then + for Cpt:= 0 to Pred(FElement.Count) do + if AObjet> -1 + then + begin + if (TPdfName(TPdfDicElement(FElement[Cpt]).FKey).FValue= 'Name') + then + if (TPdfObjet(TPdfDicElement(FElement[Cpt]).FValue) is TPdfName) + and (TPdfName(TPdfDicElement(FElement[Cpt]).FValue).FValue[1]= 'I') + then + begin + NumImg:= StrToInt(Copy(TPdfName(TPdfDicElement(FElement[Cpt]).FValue).FValue,2,Length(TPdfName(TPdfDicElement(FElement[Cpt]).FValue).FValue)-1)); + Flux:= TMemoryStream.Create; + Flux.Position:= 0; +// write image stream length in xobject dictionary + Long:= TPdfInteger.CreateInteger(TPdfImage(TPdfXRef(Document.FXRefObjets[AObjet]).FObjet).WriteImageStream(NumImg,Flux)); + TPdfDictionary(TPdfXRef(Document.FXRefObjets[AObjet]).FObjet).AddElement('Length',Long); + TPdfDicElement(FElement[Pred(FElement.Count)]).WriteDicElement(AFlux); + Flux.Free; + WriteChaine('>>',AFlux); +// write image stream in xobject dictionary + TPdfImage(TPdfXRef(Document.FXRefObjets[AObjet]).FObjet).WriteImageStream(NumImg,AFlux); + end; + if Pos('Length1',TPdfName(TPdfDicElement(FElement[Cpt]).FKey).FValue)> 0 + then + begin + Flux:= TMemoryStream.Create; + Value:= TPdfName(TPdfDicElement(FElement[Cpt]).FKey).FValue; + NumFnt:= StrToInt(Copy(Value,Succ(Pos(' ',Value)),Length(Value)-Pos(' ',Value))); + Flux.LoadFromFile(FontFiles[NumFnt]); +// write fontfile stream length in xobject dictionary + Long:= TPdfInteger.CreateInteger(Flux.Size); + TPdfDictionary(TPdfXRef(Document.FXRefObjets[AObjet]).FObjet).AddElement('Length',Long); + TPdfDicElement(FElement[Pred(FElement.Count)]).WriteDicElement(AFlux); + WriteChaine('>>',AFlux); +// write fontfile stream in xobject dictionary + TPdfFonte(TPdfXRef(Document.FXRefObjets[NumFnt]).FObjet).WriteFonteStream(Flux,AFlux); + Flux.Free; + end; + end; + if (NumImg= -1) and (NumFnt= -1) + then + WriteChaine('>>',AFlux); + end; +end; + +constructor TPdfDictionary.CreateDictionary; +begin +inherited Create; +FElement:= TList.Create; +end; + +destructor TPdfDictionary.Destroy; +var + Cpt: integer; +begin +if FElement.Count> 0 +then + for Cpt:= 0 to Pred(FElement.Count) do + TPdfDicElement(FElement[Cpt]).Free; +FElement.Free; +inherited; +end; + +procedure TPdfXRef.WriteXRef(const AFlux: TStream); +begin +WriteChaine(IntToChaine(FOffset,10)+' '+IntToChaine(0,5)+' n'+CRLF,AFlux); +end; + +constructor TPdfXRef.CreateXRef; +begin +inherited Create; +FOffset:= 0; +FObjet:= TpdfDictionary.CreateDictionary; +FStream:= nil; +end; + +destructor TPdfXRef.Destroy; +begin +FObjet.Free; +FStream.Free; +inherited; +end; + +function TPdfDocument.ElementParNom(const AValue: string): Integer; +var + Cpt: Integer; +begin +for Cpt:= 1 to Pred(FXRefObjets.Count) do + if TPdfName(TPdfDicElement(TPdfDictionary(TPdfXRef(FXRefObjets[Cpt]).FObjet).FElement[0]).FValue).FValue= AValue + then + Result:= Cpt; +end; + +procedure TPdfDocument.WriteXRefTable(const AFlux: TStream); +var + Cpt: Integer; +begin +if FXRefObjets.Count> 1 +then + for Cpt:= 1 to Pred(FXRefObjets.Count) do + TPdfXRef(FXRefObjets[Cpt]).WriteXRef(AFlux); +end; + +procedure TPdfDocument.WriteObjet(const AObjet: Integer; const AFlux: TStream); +var + Long: TPdfInteger; + Flux: TMemoryStream; +begin +WriteChaine(IntToStr(AObjet)+' 0 obj'+CRLF,AFlux); +if TPdfXRef(FXRefObjets[AObjet]).FStream= nil +then + TPdfDictionary(TPdfXRef(FXRefObjets[AObjet]).FObjet).WriteDictionary(AObjet,AFlux) +else + begin + Flux:= TMemoryStream.Create; + Flux.Position:= 0; + CurrentColor:= ''; + CurrentWidth:= ''; + TPdfXRef(FXRefObjets[AObjet]).FStream.WriteStream(Flux); +// write stream length element in contents dictionary + Long:= TPdfInteger.CreateInteger(Flux.Size); + TPdfDictionary(TPdfXRef(FXRefObjets[AObjet]).FObjet).AddElement('Length',Long); + Flux.Free; + TPdfXRef(FXRefObjets[AObjet]).FObjet.WriteDictionary(-1,AFlux); +// write stream in contents dictionary + CurrentColor:= ''; + CurrentWidth:= ''; + WriteChaine(CRLF+'stream'+CRLF,AFlux); + TPdfXRef(FXRefObjets[AObjet]).FStream.WriteStream(AFlux); + WriteChaine('endstream',AFlux); + end; +WriteChaine(CRLF+'endobj'+CRLF+CRLF,AFlux); +end; + +procedure TPdfDocument.CreateRefTable; +var + XRefObjet: TPdfXRef; +begin +FXRefObjets:= TList.Create; +// add first xref entry +XRefObjet:= TPdfXRef.CreateXRef; +FXRefObjets.Add(XRefObjet); +end; + +procedure TPdfDocument.CreateTrailer; +var + XRefObjets: TPdfInteger; +begin +Trailer:= TPdfDictionary.CreateDictionary; +// add size trailer element +XRefObjets:= TPdfInteger.CreateInteger(FXRefObjets.Count); +Trailer.AddElement('Size',XRefObjets); +end; + +function TPdfDocument.CreateCatalog: Integer; +var + Catalog: TPdfXRef; + XRefObjets: TPdfReference; + Nom: TPdfName; + Table: TPdfArray; +begin +// add xref entry +Catalog:= TPdfXRef.CreateXRef; +FXRefObjets.Add(Catalog); +// add root trailer element +XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); +Trailer.AddElement('Root',XRefObjets); +// add type element to catalog dictionary +Nom:= TPdfName.CreateName('Catalog'); +Catalog.FObjet.AddElement('Type',Nom); +// add pagelayout element to catalog dictionary +case FPageLayout of + lSingle: + Nom:= TPdfName.CreateName('SinglePage'); + lTwo: + Nom:= TPdfName.CreateName('TwoColumnLeft'); + lContinuous: + Nom:= TPdfName.CreateName('OneColumn'); + end; +Catalog.FObjet.AddElement('PageLayout',Nom); +// add openaction element to catalog dictionary +Table:= TPdfArray.CreateArray; +Catalog.FObjet.AddElement('OpenAction',Table); +Result:= Pred(FXRefObjets.Count); +end; + +procedure TPdfDocument.CreateInfo; +var + Info: TPdfXRef; + XRefObjets: TPdfReference; + Nom: TPdfString; +begin +// add xref entry +Info:= TPdfXRef.CreateXRef; +FXRefObjets.Add(Info); +// add info trailer element +XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); +Trailer.AddElement('Info',XRefObjets); +TPdfInteger(TPdfDicElement(Trailer.FElement[Trailer.ElementParCle('Size')]).FValue).FValue:= FXRefObjets.Count; +// add title element to info dictionary +Nom:= TPdfString.CreateString(Infos.Titre); +Info.FObjet.AddElement('Title',Nom); +// add author element to info dictionary +Nom:= TPdfString.CreateString(Infos.Auteur); +Info.FObjet.AddElement('Author',Nom); +// add creator element to info dictionary +Nom:= TPdfString.CreateString(ApplicationName); +Info.FObjet.AddElement('Creator',Nom); +// add producer element to info dictionary +Nom:= TPdfString.CreateString('fpGUI/FPC'); +Info.FObjet.AddElement('Producer',Nom); +// add creationdate element to info dictionary +Nom:= TPdfString.CreateString(DateToPdfDate(Now)); +Info.FObjet.AddElement('CreationDate',Nom); +end; + +procedure TPdfDocument.CreatePreferences; +var + Viewer: TPdfXRef; + XRefObjets: TPdfReference; + Nom: TPdfName; + Preference: TPdfBoolean; +begin +// add xref entry +Viewer:= TPdfXRef.CreateXRef; +FXRefObjets.Add(Viewer); +// add type element to preferences dictionary +Nom:= TPdfName.CreateName('ViewerPreferences'); +Viewer.FObjet.AddElement('Type',Nom); +// add preference element to preferences dictionary +Preference:= TPdfBoolean.CreateBoolean(True); +Viewer.FObjet.AddElement('FitWindow',Preference); +// add preferences reference to catalog dictionary +XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); +TPdfDictionary(TPdfXRef(FXRefObjets[ElementParNom('Catalog')]).FObjet).AddElement('ViewerPreferences',XRefObjets) +end; + +function TPdfDocument.CreatePages(Parent: Integer): Integer; +var + Pages: TPdfXRef; + XRefObjets: TPdfReference; + Nom: TPdfName; + Dictionaire: TPdfDictionary; + Table: TPdfArray; + Count: TPdfInteger; +begin +// add xref entry +Pages:= TPdfXRef.CreateXRef; +FXRefObjets.Add(Pages); +// add type element to pages dictionary +Nom:= TPdfName.CreateName('Pages'); +Pages.FObjet.AddElement('Type',Nom); +// add parent reference to pages dictionary if pages is not the root of the page tree +if Parent> 0 +then + begin + XRefObjets:= TPdfReference.CreateReference(Parent); + Pages.FObjet.AddElement('Parent',XRefObjets); + // increment count in parent pages dictionary + Dictionaire:= TPdfDictionary(TPdfXRef(FXRefObjets[Parent]).FObjet); + TPdfInteger(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('Count')]).FValue).IncrementeInteger; + // add kid reference in parent pages dictionary + XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); + TPdfArray(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('Kids')]).FValue).AddItem(XRefObjets); + end +else + begin + // add pages reference to catalog dictionary + XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); + TPdfDictionary(TPdfXRef(FXRefObjets[ElementParNom('Catalog')]).FObjet).AddElement('Pages',XRefObjets) + end; +// add kids element to pages dictionary +Table:= TPdfArray.CreateArray; +Pages.FObjet.AddElement('Kids',Table); +// add count element to pages dictionary +Count:= TPdfInteger.CreateInteger(0); +Pages.FObjet.AddElement('Count',Count); +Result:= Pred(FXRefObjets.Count); +end; + +function TPdfDocument.CreatePage(Parent,Haut,Larg,PageNum: Integer): Integer; +var + Page: TPdfXRef; + XRefObjets: TPdfReference; + Nom: TPdfName; + Dictionaire: TPdfDictionary; + Table: TPdfArray; + Coord: TPdfInteger; + Cpt: Integer; +begin +// add xref entry +Page:= TPdfXRef.CreateXRef; +FXRefObjets.Add(Page); +// add type element to page dictionary +Nom:= TPdfName.CreateName('Page'); +Page.FObjet.AddElement('Type',Nom); +// add parent reference to page dictionary +XRefObjets:= TPdfReference.CreateReference(Parent); +Page.FObjet.AddElement('Parent',XRefObjets); +// increment count in parent pages dictionary +Dictionaire:= TPdfDictionary(TPdfXRef(FXRefObjets[Parent]).FObjet); +TPdfInteger(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('Count')]).FValue).IncrementeInteger; +// add kid reference in parent pages dictionary +XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); +TPdfArray(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('Kids')]).FValue).AddItem(XRefObjets); +// add mediabox element to page dictionary +Table:= TPdfArray.CreateArray; +Page.FObjet.AddElement('MediaBox',Table); +// add coordinates in page mediabox +Dictionaire:= TPdfDictionary(TPdfXRef(Page).FObjet); +Coord:= TPdfInteger.CreateInteger(0); +TPdfArray(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('MediaBox')]).FValue).AddItem(Coord); +Coord:= TPdfInteger.CreateInteger(0); +TPdfArray(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('MediaBox')]).FValue).AddItem(Coord); +Coord:= TPdfInteger.CreateInteger(Larg); +TPdfArray(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('MediaBox')]).FValue).AddItem(Coord); +Coord:= TPdfInteger.CreateInteger(Haut); +TPdfArray(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('MediaBox')]).FValue).AddItem(Coord); +// add resources element to page dictionary +Dictionaire:= TPdfDictionary.CreateDictionary; +Page.FObjet.AddElement('Resources',Dictionaire); +// add procset element in resources element to page dictionary +Table:= TPdfArray.CreateArray; +TPdfDictionary(TPdfDicElement(Page.FObjet.FElement[Pred(Page.FObjet.FElement.Count)]).FValue).AddElement('ProcSet',Table); +// add font element in resources element to page dictionary +if Fonts.Count> 0 +then + begin + Dictionaire:= TPdfDictionary.CreateDictionary; + TPdfDictionary(TPdfDicElement(Page.FObjet.FElement[Pred(Page.FObjet.FElement.Count)]).FValue).AddElement('Font',Dictionaire); + end; +for Cpt:= 0 to Pred(PdfPage.Count) do + if TPdfElement(PdfPage[Cpt]) is TPdfImg + then + if TPdfImg(PdfPage[Cpt]).PageId= PageNum + then + begin +// add xobject element in resources element to page dictionary + Dictionaire:= TPdfDictionary.CreateDictionary; + TPdfDictionary(TPdfDicElement(Page.FObjet.FElement[Pred(Page.FObjet.FElement.Count)]).FValue).AddElement('XObject',Dictionaire); + Break; + end; +// add pdf element in procset array to page dictionary +Dictionaire:= TPdfDictionary(TPdfDicElement(Page.FObjet.FElement[Pred(Page.FObjet.FElement.Count)]).FValue); +Nom:= TPdfName.CreateName('PDF'); +TPdfArray(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('ProcSet')]).FValue).AddItem(Nom); +// add text element in procset array to page dictionary +Nom:= TPdfName.CreateName('Text'); +TPdfArray(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('ProcSet')]).FValue).AddItem(Nom); +// add image element in procset array to page dictionary +Nom:= TPdfName.CreateName('ImageC'); +TPdfArray(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('ProcSet')]).FValue).AddItem(Nom); +Result:= Pred(FXRefObjets.Count); +end; + +function TPdfDocument.CreateOutlines: Integer; +var + Outlines: TPdfXRef; + Nom: TPdfName; + Count: TPdfInteger; +begin +// add xref entry +Outlines:= TPdfXRef.CreateXRef; +FXRefObjets.Add(Outlines); +// add type element to outlines dictionary +Nom:= TPdfName.CreateName('Outlines'); +Outlines.FObjet.AddElement('Type',Nom); +// add count element to outlines dictionary +Count:= TPdfInteger.CreateInteger(0); +Outlines.FObjet.AddElement('Count',Count); +Result:= Pred(FXRefObjets.Count); +end; + +function TPdfDocument.CreateOutline(Parent,SectNo,PageNo: Integer; SectTitre: string): Integer; +var + Outline: TPdfXRef; + XRefObjets: TPdfReference; + Titre: TPdfString; + Count: TPdfInteger; + Table: TPdfArray; +begin +// add xref entry +Outline:= TPdfXRef.CreateXRef; +FXRefObjets.Add(Outline); +// add title element to outline dictionary +if PageNo> -1 +then + if SectTitre<> '' + then + Titre:= TPdfString.CreateString(SectTitre+' Page '+IntToStr(PageNo)) + else + Titre:= TPdfString.CreateString('Section '+IntToStr(SectNo)+' Page '+IntToStr(PageNo)) +else + if SectTitre<> '' + then + Titre:= TPdfString.CreateString(SectTitre) + else + Titre:= TPdfString.CreateString('Section '+IntToStr(SectNo)); +Outline.FObjet.AddElement('Title',Titre); +// add parent reference to outline dictionary +XRefObjets:= TPdfReference.CreateReference(Parent); +Outline.FObjet.AddElement('Parent',XRefObjets); +// add count element to outline dictionary +Count:= TPdfInteger.CreateInteger(0); +Outline.FObjet.AddElement('Count',Count); +// add dest element to outline dictionary +Table:= TPdfArray.CreateArray; +Outline.FObjet.AddElement('Dest',Table); +Result:= Pred(FXRefObjets.Count); +end; + +procedure TPdfDocument.CreateStdFont(NomFonte: string; NumFonte: Integer); +var + Fontes: TPdfXRef; + XRefObjets: TPdfReference; + Nom: TPdfName; + Dictionaire: TPdfDictionary; + Cpt: Integer; +begin +if Pos('Italic',NomFonte)> 0 +then + NomFonte:= Copy(NomFonte,1,Pred(Pos('Italic',NomFonte)))+'Oblique'; +// AnsiReplaceText(NomFonte,'Italic','Oblique'); +// add xref entry +Fontes:= TPdfXRef.CreateXRef; +FXRefObjets.Add(Fontes); +// add type element to font dictionary +Nom:= TPdfName.CreateName('Font'); +Fontes.FObjet.AddElement('Type',Nom); +// add subtype element to font dictionary +Nom:= TPdfName.CreateName('Type1'); +Fontes.FObjet.AddElement('Subtype',Nom); +// add encoding element to font dictionary +Nom:= TPdfName.CreateName('WinAnsiEncoding'); +Fontes.FObjet.AddElement('Encoding',Nom); +// add firstchar element to font dictionary +Nom:= TPdfName.CreateName('32'); +//Nom:= TPdfName.CreateName('0'); +Fontes.FObjet.AddElement('FirstChar',Nom); +// add lastchar element to font dictionary +Nom:= TPdfName.CreateName('255'); +Fontes.FObjet.AddElement('LastChar',Nom); +// add basefont element to font dictionary +Nom:= TPdfName.CreateName(NomFonte); +Fontes.FObjet.AddElement('BaseFont',Nom); +// add name element to font dictionary +Nom:= TPdfName.CreateName('F'+IntToStr(NumFonte)); +Fontes.FObjet.AddElement('Name',Nom); +// add font reference to all page dictionary +for Cpt:= 1 to Pred(FXRefObjets.Count) do + begin + Dictionaire:= TPdfDictionary(TPdfXRef(FXRefObjets[Cpt]).FObjet); + if Dictionaire.FElement.Count> 0 + then + if TPdfName(TPdfDicElement(Dictionaire.FElement[0]).FValue).FValue= 'Page' + then + begin + Dictionaire:= TPdfDictionary(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('Resources')]).FValue); + Dictionaire:= TPdfDictionary(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('Font')]).FValue); + XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); + Dictionaire.AddElement(TPdfName(Nom).FValue,XRefObjets); + end; + end; +SetLength(FontFiles,Succ(Length(FontFiles))); +FontFiles[NumFonte]:= ''; +end; + +function TPdfDocument.LoadFont(NomFonte: string): string; +var + FileTxt: TextFile; + Ligne: widestring; +begin +if FileExists(FontDirectory+NomFonte+'.fnt') +then + begin + AssignFile(FileTxt,FontDirectory+NomFonte+'.fnt'); + Reset(FileTxt); + while not Eof(FileTxt) do + begin + Readln(FileTxt,Ligne); + if Copy(Ligne,1,Pred(Pos('=',Ligne)))= 'FontType' + then + FontDef.FType:= Copy(Ligne,Succ(Pos('=',Ligne)),Length(Ligne)-Pos('=',Ligne)); + if Copy(Ligne,1,Pred(Pos('=',Ligne)))= 'FontName' + then + FontDef.FName:= Copy(Ligne,Succ(Pos('=',Ligne)),Length(Ligne)-Pos('=',Ligne)); + if Copy(Ligne,1,Pred(Pos('=',Ligne)))= 'Ascent' + then + FontDef.FAscent:= Copy(Ligne,Succ(Pos('=',Ligne)),Length(Ligne)-Pos('=',Ligne)); + if Copy(Ligne,1,Pred(Pos('=',Ligne)))= 'Descent' + then + FontDef.FDescent:= Copy(Ligne,Succ(Pos('=',Ligne)),Length(Ligne)-Pos('=',Ligne)); + if Copy(Ligne,1,Pred(Pos('=',Ligne)))= 'CapHeight' + then + FontDef.FCapHeight:= Copy(Ligne,Succ(Pos('=',Ligne)),Length(Ligne)-Pos('=',Ligne)); + if Copy(Ligne,1,Pred(Pos('=',Ligne)))= 'Flags' + then + FontDef.FFlags:= Copy(Ligne,Succ(Pos('=',Ligne)),Length(Ligne)-Pos('=',Ligne)); + if Copy(Ligne,1,Pred(Pos('=',Ligne)))= 'FontBBox' + then + FontDef.FFontBBox:= Copy(Ligne,Succ(Pos('=',Ligne)),Length(Ligne)-Pos('=',Ligne)); + if Copy(Ligne,1,Pred(Pos('=',Ligne)))= 'ItalicAngle' + then + FontDef.FItalicAngle:= Copy(Ligne,Succ(Pos('=',Ligne)),Length(Ligne)-Pos('=',Ligne)); + if Copy(Ligne,1,Pred(Pos('=',Ligne)))= 'StemV' + then + FontDef.FStemV:= Copy(Ligne,Succ(Pos('=',Ligne)),Length(Ligne)-Pos('=',Ligne)); + if Copy(Ligne,1,Pred(Pos('=',Ligne)))= 'MissingWidth' + then + FontDef.FMissingWidth:= Copy(Ligne,Succ(Pos('=',Ligne)),Length(Ligne)-Pos('=',Ligne)); + if Copy(Ligne,1,Pred(Pos('=',Ligne)))= 'Encoding' + then + FontDef.FEncoding:= Copy(Ligne,Succ(Pos('=',Ligne)),Length(Ligne)-Pos('=',Ligne)); + if Copy(Ligne,1,Pred(Pos('=',Ligne)))= 'FontFile' + then + FontDef.FFile:= FontDirectory+Copy(Ligne,Succ(Pos('=',Ligne)),Length(Ligne)-Pos('=',Ligne)); + if Copy(Ligne,1,Pred(Pos('=',Ligne)))= 'OriginalSize' + then + FontDef.FOriginalSize:= Copy(Ligne,Succ(Pos('=',Ligne)),Length(Ligne)-Pos('=',Ligne)); + if Copy(Ligne,1,Pred(Pos('=',Ligne)))= 'Diffs' + then + FontDef.FDiffs:= Copy(Ligne,Succ(Pos('=',Ligne)),Length(Ligne)-Pos('=',Ligne)); + if Copy(Ligne,1,Pred(Pos('=',Ligne)))= 'CharWidth' + then + FontDef.FCharWidth:= Copy(Ligne,Succ(Pos('=',Ligne)),Length(Ligne)-Pos('=',Ligne)); + end; + Result:= FontDef.FType; + end +else + ShowMessage('Font file '+NomFonte+'.fnt not found'); +end; + +procedure TPdfDocument.CreateTtfFont(const NumFonte: Integer); +var + Fontes: TPdfXRef; + XRefObjets: TPdfReference; + Nom: TPdfName; + Dictionaire: TPdfDictionary; + Value: TPdfInteger; + Cpt: Integer; +begin +// add xref entry +Fontes:= TPdfXRef.CreateXRef; +FXRefObjets.Add(Fontes); +// add type element to font dictionary +Nom:= TPdfName.CreateName('Font'); +Fontes.FObjet.AddElement('Type',Nom); +// add subtype element to font dictionary +Nom:= TPdfName.CreateName(FontDef.FType); +Fontes.FObjet.AddElement('Subtype',Nom); +// add encoding element to font dictionary +Nom:= TPdfName.CreateName('WinAnsiEncoding'); +Fontes.FObjet.AddElement('Encoding',Nom); +// add firstchar element to font dictionary +Value:= TPdfInteger.CreateInteger(32); +Fontes.FObjet.AddElement('FirstChar',Value); +// add lastchar element to font dictionary +Value:= TPdfInteger.CreateInteger(255); +Fontes.FObjet.AddElement('LastChar',Value); +// add basefont element to font dictionary +Nom:= TPdfName.CreateName(FontDef.FName); +Fontes.FObjet.AddElement('BaseFont',Nom); +// add name element to font dictionary +Nom:= TPdfName.CreateName('F'+IntToStr(NumFonte)); +Fontes.FObjet.AddElement('Name',Nom); +// add font reference to all page dictionary +for Cpt:= 1 to Pred(FXRefObjets.Count) do + begin + Dictionaire:= TPdfDictionary(TPdfXRef(FXRefObjets[Cpt]).FObjet); + if Dictionaire.FElement.Count> 0 + then + if TPdfName(TPdfDicElement(Dictionaire.FElement[0]).FValue).FValue= 'Page' + then + begin + Dictionaire:= TPdfDictionary(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('Resources')]).FValue); + Dictionaire:= TPdfDictionary(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('Font')]).FValue); + XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); + Dictionaire.AddElement(TPdfName(Nom).FValue,XRefObjets); + end; + end; +CreateFontDescriptor(NumFonte); +// add fontdescriptor reference to font dictionary +XRefObjets:= TPdfReference.CreateReference(FXRefObjets.Count-2); +Fontes.FObjet.AddElement('FontDescriptor',XRefObjets); +CreateFontWidth; +// add fontwidth reference to font dictionary +XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); +Fontes.FObjet.AddElement('Widths',XRefObjets); +SetLength(FontFiles,Succ(Length(FontFiles))); +FontFiles[NumFonte]:= FontDef.FFile; +end; + +procedure TPdfDocument.CreateTp1Font(const NumFonte: Integer); +begin + +end; + +procedure TPdfDocument.CreateFontDescriptor(const NumFonte: Integer); +var + FtDesc: TPdfXRef; + XRefObjets: TPdfReference; + Nom: TPdfName; + Value: TPdfInteger; + Table: TPdfArray; + Dictionaire: TPdfDictionary; +begin +// add xref entry +FtDesc:= TPdfXRef.CreateXRef; +FXRefObjets.Add(FtDesc); +// add type element to fontdescriptor dictionary +Nom:= TPdfName.CreateName('FontDescriptor'); +FtDesc.FObjet.AddElement('Type',Nom); +// add fontname element to fontdescriptor dictionary +Nom:= TPdfName.CreateName(FontDef.FName); +FtDesc.FObjet.AddElement('FontName',Nom); +// add ascent element to fontdescriptor dictionary +Value:= TPdfInteger.CreateInteger(StrToInt(FontDef.FAscent)); +FtDesc.FObjet.AddElement('Ascent',Value); +// add descent element to fontdescriptor dictionary +Value:= TPdfInteger.CreateInteger(StrToInt(FontDef.FDescent)); +FtDesc.FObjet.AddElement('Descent',Value); +// add capheight element to fontdescriptor dictionary +Value:= TPdfInteger.CreateInteger(StrToInt(FontDef.FCapHeight)); +FtDesc.FObjet.AddElement('CapHeight',Value); +// add flags element to fontdescriptor dictionary +Value:= TPdfInteger.CreateInteger(StrToInt(FontDef.FFlags)); +FtDesc.FObjet.AddElement('Flags',Value); +// add fontbbox element to fontdescriptor dictionary +Table:= TPdfArray.CreateArray; +FtDesc.FObjet.AddElement('FontBBox',Table); +// add coordinates in page fontbbox +while Pos(' ',FontDef.FFontBBox)> 0 do + begin + Dictionaire:= TPdfDictionary(TPdfXRef(FtDesc).FObjet); + Value:= TPdfInteger.CreateInteger(StrToInt(Copy(FontDef.FFontBBox,1,Pred(Pos(' ',FontDef.FFontBBox))))); + TPdfArray(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('FontBBox')]).FValue).AddItem(Value); + FontDef.FFontBBox:= Copy(FontDef.FFontBBox,Succ(Pos(' ',FontDef.FFontBBox)),Length(FontDef.FFontBBox)-Pos(' ',FontDef.FFontBBox));; + end; +// add italicangle element to fontdescriptor dictionary +Value:= TPdfInteger.CreateInteger(StrToInt(FontDef.FItalicAngle)); +FtDesc.FObjet.AddElement('ItalicAngle',Value); +// add stemv element to fontdescriptor dictionary +Value:= TPdfInteger.CreateInteger(StrToInt(FontDef.FStemV)); +FtDesc.FObjet.AddElement('StemV',Value); +// add missingwidth element to fontdescriptor dictionary +Value:= TPdfInteger.CreateInteger(StrToInt(FontDef.FMissingWidth)); +FtDesc.FObjet.AddElement('MissingWidth',Value); +CreateFontFile(NumFonte); +// add fontfilereference to fontdescriptor dictionary +XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); +FtDesc.FObjet.AddElement('FontFile2',XRefObjets); +end; + +procedure TPdfDocument.CreateFontWidth; +var + FtDesc: TPdfXRef; + XRefObjets: TPdfReference; + Value: TPdfInteger; + Table: TPdfArray; + Dictionaire: TPdfDictionary; +begin +// add xref entry +FtDesc:= TPdfXRef.CreateXRef; +FXRefObjets.Add(FtDesc); +// add element to fontwidth dictionary +Table:= TPdfArray.CreateArray; +FtDesc.FObjet.AddElement('',Table); +// add width values in fontwidth array +while Pos(' ',FontDef.FCharWidth)> 0 do + begin + Dictionaire:= TPdfDictionary(TPdfXRef(FtDesc).FObjet); + Value:= TPdfInteger.CreateInteger(StrToInt(Copy(FontDef.FCharWidth,1,Pred(Pos(' ',FontDef.FCharWidth))))); + TPdfArray(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('')]).FValue).AddItem(Value); + FontDef.FCharWidth:= Copy(FontDef.FCharWidth,Succ(Pos(' ',FontDef.FCharWidth)),Length(FontDef.FCharWidth)-Pos(' ',FontDef.FCharWidth));; + end; +end; + +procedure TPdfDocument.CreateFontFile(const NumFonte: Integer); +var + FtDesc: TPdfXRef; + XRefObjets: TPdfReference; + Nom: TPdfName; + Value: TPdfInteger; +begin +// add xref entry +FtDesc:= TPdfXRef.CreateXRef; +FXRefObjets.Add(FtDesc); +// add filter element to fontfile dictionary +Nom:= TPdfName.CreateName('FlateDecode'); +FtDesc.FObjet.AddElement('Filter',Nom); +// add length1 element to fontfile dictionary +Value:= TPdfInteger.CreateInteger(StrToInt(FontDef.FOriginalSize)); +FtDesc.FObjet.AddElement('Length1 '+IntToStr(NumFonte),Value); +end; + +procedure TPdfDocument.CreateImage(ImgWidth,ImgHeight,NumImg: Integer); +var + Images: TPdfXRef; + XRefObjets: TPdfReference; + Nom: TPdfName; + Dictionaire: TPdfDictionary; + Long: TPdfInteger; + Cpt: Integer; +begin +// add xref entry +Images:= TPdfXRef.CreateXRef; +FXRefObjets.Add(Images); +// add type element to image dictionary +Nom:= TPdfName.CreateName('XObject'); +Images.FObjet.AddElement('Type',Nom); +// add subtype element to image dictionary +Nom:= TPdfName.CreateName('Image'); +Images.FObjet.AddElement('Subtype',Nom); +// add width element to image dictionary +Long:= TPdfInteger.CreateInteger(ImgWidth); +Images.FObjet.AddElement('Width',Long); +// add height element to image dictionary +Long:= TPdfInteger.CreateInteger(ImgHeight); +Images.FObjet.AddElement('Height',Long); +// add color space element to image dictionary +Nom:= TPdfName.CreateName('DeviceRGB'); +Images.FObjet.AddElement('ColorSpace',Nom); +// add bits per component element to image dictionary +Long:= TPdfInteger.CreateInteger(8); +Images.FObjet.AddElement('BitsPerComponent',Long); +// add name element to image dictionary +Nom:= TPdfName.CreateName('I'+IntToStr(NumImg)); +Images.FObjet.AddElement('Name',Nom); +// add image reference to page dictionary +for Cpt:= 1 to Pred(FXRefObjets.Count) do + begin + Dictionaire:= TPdfDictionary(TPdfXRef(FXRefObjets[Cpt]).FObjet); + if Dictionaire.FElement.Count> 0 + then + if TPdfName(TPdfDicElement(Dictionaire.FElement[0]).FValue).FValue= 'Page' + then + begin + Dictionaire:= TPdfDictionary(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('Resources')]).FValue); + if Dictionaire.ElementParCle('XObject')> -1 + then + begin + Dictionaire:= TPdfDictionary(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('XObject')]).FValue); + XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); + Dictionaire.AddElement(TPdfName(Nom).FValue,XRefObjets); + end; + end; + end; +end; + +function TPdfDocument.CreateContents: Integer; +var + Contents: TPdfXRef; + XRefObjets: TPdfReference; + Stream: TPdfStream; +begin +// add xref entry +Contents:= TPdfXRef.CreateXRef; +FXRefObjets.Add(Contents); +Stream:= TPdfStream.CreateStream; +TPdfXRef(FXRefObjets[Pred(FXRefObjets.Count)]).FStream:= Stream; +// add contents reference to page dictionary +XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); +TPdfDictionary(TPdfXRef(FXRefObjets[Pred(Pred(FXRefObjets.Count))]).FObjet).AddElement('Contents',XRefObjets); +Result:= Pred(FXRefObjets.Count); +end; + +procedure TPdfDocument.CreateStream(NumeroPage,PageNum: Integer); +var + Cpt: Integer; + Txt: TPdfText; + Clr: TPdfColor; + Fnt: TPdfFonte; + Rct: TPdfRectangle; + Lin: TPdfLigne; + Srf: TPdfSurface; + Sty: TPdfLineStyle; + Img: TPdfImage; +begin +for Cpt:= 0 to Pred(PdfPage.Count) do + begin + if TPdfElement(PdfPage[Cpt]) is TPdfTexte + then + if TPdfTexte(PdfPage[Cpt]).PageId= NumeroPage + then + with TPdfTexte(PdfPage[Cpt]) do + begin + if FontName> -1 + then + begin + Fnt:= TPdfFonte.CreateFonte(FontName,FontSize); +// adjust font size to display device + Fnt.FTxtSize:= IntToStr(Round((StrToInt(FontSize)*fpgApplication.Screen_dpi_y) div 72)); + TPdfStream(TPdfXRef(FXRefObjets[PageNum]).FStream).AddItem(Fnt); + Clr:= TPdfColor.CreateColor(True,Couleur); + TPdfStream(TPdfXRef(FXRefObjets[PageNum]).FStream).AddItem(Clr); + end; + Txt:= TPdfText.CreateText(TextPosX,TextPosY,Writting); + TPdfStream(TPdfXRef(FXRefObjets[PageNum]).FStream).AddItem(Txt); + end; + if TPdfElement(PdfPage[Cpt]) is TPdfRect + then + if TPdfRect(PdfPage[Cpt]).PageId= NumeroPage + then + with TPdfRect(PdfPage[Cpt]) do + begin + Clr:= TPdfColor.CreateColor(True,RectColor); + TPdfStream(TPdfXRef(FXRefObjets[PageNum]).FStream).AddItem(Clr); + if RectStroke + then + begin + Sty:= TPdfLineStyle.CreateLineStyle(RectLineStyle,0); + TPdfStream(TPdfXRef(FXRefObjets[PageNum]).FStream).AddItem(Sty); + end; + Rct:= TPdfRectangle.CreateRectangle(RectThickness,RectLeft,RectBottom,RectWidth,RectHeight,RectFill,RectStroke); + TPdfStream(TPdfXRef(FXRefObjets[PageNum]).FStream).AddItem(Rct); + end; + if TPdfElement(PdfPage[Cpt]) is TPdfLine + then + if TPdfLine(PdfPage[Cpt]).PageId= NumeroPage + then + with TPdfLine(PdfPage[Cpt]) do + begin + Clr:= TPdfColor.CreateColor(False,LineColor); + TPdfStream(TPdfXRef(FXRefObjets[PageNum]).FStream).AddItem(Clr); + Sty:= TPdfLineStyle.CreateLineStyle(LineStyle,0); + TPdfStream(TPdfXRef(FXRefObjets[PageNum]).FStream).AddItem(Sty); + Lin:= TPdfLigne.CreateLigne(LineThikness,LineBeginX,LineBeginY,LineEndX,LineEndY); + TPdfStream(TPdfXRef(FXRefObjets[PageNum]).FStream).AddItem(Lin); + end; + if TPdfElement(PdfPage[Cpt]) is TPdfSurf + then + if TPdfSurf(PdfPage[Cpt]).PageId= NumeroPage + then + with TPdfSurf(PdfPage[Cpt]) do + begin + Clr:= TPdfColor.CreateColor(True,SurfColor); + TPdfStream(TPdfXRef(FXRefObjets[PageNum]).FStream).AddItem(Clr); + Srf:= TPdfSurface.CreateSurface(Points); + TPdfStream(TPdfXRef(FXRefObjets[PageNum]).FStream).AddItem(Srf); + end; + if TPdfElement(PdfPage[Cpt]) is TPdfImg + then + if TPdfImg(PdfPage[Cpt]).PageId= NumeroPage + then + with TPdfImg(PdfPage[Cpt]) do + begin + Img:= TPdfImage.CreateImage(ImgLeft,ImgBottom,ImgWidth,ImgHeight,ImgNumber); + TPdfStream(TPdfXRef(FXRefObjets[PageNum]).FStream).AddItem(Img); + end; + end; +end; + +constructor TPdfDocument.CreateDocument(const ALayout: TPageLayout; const AZoom: string; const APreferences: Boolean); +var + Cpt,CptSect,CptPage,NumFont,TreeRoot,ParentPage,PageNum,NumPage: Integer; + OutlineRoot,ParentOutline,PageOutline,NextOutline,NextSect,NewPage,PrevOutline,PrevSect: Integer; + Dictionaire: TPdfDictionary; + XRefObjets: TPdfReference; + Nom: TPdfName; + FontName,FtName: string; +begin +inherited Create; +FPreferences:= APreferences; +FPageLayout:= ALayout; +FZoomValue:= AZoom; +CreateRefTable; +CreateTrailer; +Catalogue:= CreateCatalog; +CreateInfo; +CreatePreferences; +ParentPage:= 0; +ParentOutline:= 0; +if Sections.Count> 1 +then + begin + if Outline + then + begin + OutlineRoot:= CreateOutlines; + // add outline reference to catalog dictionary + XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); + TPdfDictionary(TPdfXRef(FXRefObjets[Catalogue]).FObjet).AddElement('Outlines',XRefObjets); + // add useoutline element to catalog dictionary + Nom:= TPdfName.CreateName('UseOutlines'); + TPdfDictionary(TPdfXRef(FXRefObjets[Catalogue]).FObjet).AddElement('PageMode',Nom); + end; + TreeRoot:= CreatePages(ParentPage); + end; +NumPage:= 0; // page number identical to the call to PrintPage +for CptSect:= 0 to Pred(Sections.Count) do + begin + if Sections.Count> 1 + then + begin + if Outline + then + begin + ParentOutline:= CreateOutline(OutlineRoot,Succ(CptSect),-1,T_Section(Sections[CptSect]).Title); + Dictionaire:= TPdfDictionary(TPdfXRef(FXRefObjets[OutlineRoot]).FObjet); + TPdfInteger(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('Count')]).FValue).IncrementeInteger; + if CptSect= 0 + then + begin + XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); + TPdfDictionary(TPdfXRef(FXRefObjets[OutlineRoot]).FObjet).AddElement('First',XRefObjets); + NextSect:= ParentOutline; + PrevSect:= Pred(FXRefObjets.Count); + end + else + begin + XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); + TPdfDictionary(TPdfXRef(FXRefObjets[NextSect]).FObjet).AddElement('Next',XRefObjets); + XRefObjets:= TPdfReference.CreateReference(PrevSect); + TPdfDictionary(TPdfXRef(FXRefObjets[ParentOutline]).FObjet).AddElement('Prev',XRefObjets); + NextSect:= ParentOutline; + if CptSect< Pred(Sections.Count) + then + PrevSect:= Pred(FXRefObjets.Count); + end; + if CptSect= Pred(Sections.Count) + then + begin + XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); + TPdfDictionary(TPdfXRef(FXRefObjets[OutlineRoot]).FObjet).AddElement('Last',XRefObjets); + end; + end; + ParentPage:= CreatePages(TreeRoot); + end + else + ParentPage:= CreatePages(ParentPage); + for CptPage:= 0 to Pred(T_Section(Sections[CptSect]).Pages.Count) do + begin + with T_Section(Sections[CptSect]) do + NewPage:= CreatePage(ParentPage,Paper.H,Paper.W,Succ(NumPage)); + // add zoom factor to catalog dictionary + if (CptSect= 0) and (CptPage= 0) + then + begin + XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); + Dictionaire:= TPdfDictionary(TPdfXRef(FXRefObjets[ElementParNom('Catalog')]).FObjet); + TPdfArray(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('OpenAction')]).FValue).AddItem(XRefObjets); + Nom:= TPdfName.CreateName('XYZ null null '+FormatFloat('0.##',StrToInt(FZoomValue)/100)); + TPdfArray(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('OpenAction')]).FValue).AddItem(Nom); + end; + Inc(NumPage); + PageNum:= CreateContents; // pagenum = object number in the pdf file + CreateStream(NumPage,PageNum); + if (Sections.Count> 1) and Outline + then + begin + PageOutline:= CreateOutline(ParentOutline,Succ(CptSect),Succ(Cptpage),T_Section(Sections[CptSect]).Title); + Dictionaire:= TPdfDictionary(TPdfXRef(FXRefObjets[ParentOutline]).FObjet); + TPdfInteger(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('Count')]).FValue).IncrementeInteger; + // add page reference to outline destination + Dictionaire:= TPdfDictionary(TPdfXRef(FXRefObjets[PageOutline]).FObjet); + XRefObjets:= TPdfReference.CreateReference(NewPage); + TPdfArray(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('Dest')]).FValue).AddItem(XRefObjets); + // add display control name to outline destination + Nom:= TPdfName.CreateName('Fit'); + TPdfArray(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('Dest')]).FValue).AddItem(Nom); + if CptPage= 0 + then + begin + XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); + TPdfDictionary(TPdfXRef(FXRefObjets[ParentOutline]).FObjet).AddElement('First',XRefObjets); + NextOutline:= PageOutline; + PrevOutline:= Pred(FXRefObjets.Count); + // add page reference to parent outline destination + Dictionaire:= TPdfDictionary(TPdfXRef(FXRefObjets[ParentOutline]).FObjet); + XRefObjets:= TPdfReference.CreateReference(NewPage); + TPdfArray(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('Dest')]).FValue).AddItem(XRefObjets); + // add display control name to outline destination + Nom:= TPdfName.CreateName('Fit'); + TPdfArray(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('Dest')]).FValue).AddItem(Nom); + end + else + begin + XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); + TPdfDictionary(TPdfXRef(FXRefObjets[NextOutline]).FObjet).AddElement('Next',XRefObjets); + XRefObjets:= TPdfReference.CreateReference(PrevOutline); + TPdfDictionary(TPdfXRef(FXRefObjets[PageOutline]).FObjet).AddElement('Prev',XRefObjets); + NextOutline:= PageOutline; + if CptPage< Pred(T_Section(Sections[CptSect]).Pages.Count) + then + PrevOutline:= Pred(FXRefObjets.Count); + end; + if CptPage= Pred(T_Section(Sections[CptSect]).Pages.Count) + then + begin + XRefObjets:= TPdfReference.CreateReference(Pred(FXRefObjets.Count)); + TPdfDictionary(TPdfXRef(FXRefObjets[ParentOutline]).FObjet).AddElement('Last',XRefObjets); + end; + end; + end; + end; +if Sections.Count> 1 +then + begin + // update count in root parent pages dictionary + Dictionaire:= TPdfDictionary(TPdfXRef(FXRefObjets[TreeRoot]).FObjet); + TPdfInteger(TPdfDicElement(Dictionaire.FElement[Dictionaire.ElementParCle('Count')]).FValue).Value:= T_Section(Sections[CptSect]).TotPages; + end; +if FontDirectory= '' +then + FontDirectory:= ExtractFilePath(Paramstr(0)); +// select the font type +NumFont:= 0; +if Fonts.Count> 0 +then + for Cpt:= 0 to Pred(Fonts.Count) do + begin + FontName:= ExtractBaseFontName(T_Font(Fonts[Cpt]).GetFont.FontDesc); + if Pos('-',FontName)> 0 + then + FtName:= Copy(FontName,1,Pred(Pos('-',FontName))) + else + FtName:= FontName; + if (Lowercase(FtName)= 'courier') or (Lowercase(FtName)= 'helvetica') or (Lowercase(FtName)= 'times') + then + begin + FontName:= Uppercase(FontName[1])+Copy(FontName,2,Pred(Length(FontName))); + CreateStdFont(FontName,NumFont); + end + else + if LoadFont(FontName)= 'TrueType' + then + CreateTtfFont(NumFont) + else + CreateTp1Font(NumFont); // not implemented yet + Inc(NumFont); + end; +if Images.Count> 0 +then + for Cpt:= 0 to Pred(Images.Count) do + CreateImage(TfpgImage(Images[Cpt]).Width,TfpgImage(Images[Cpt]).Height,Cpt); +TPdfInteger(TPdfDicElement(Trailer.FElement[Trailer.ElementParCle('Size')]).FValue).FValue:= FXRefObjets.Count; +end; + +destructor TPdfDocument.Destroy; +var + Cpt: Integer; +begin +Trailer.Free; +if FXRefObjets.Count> 0 +then + for Cpt:= 0 to Pred(FXRefObjets.Count) do + TPdfXRef(FXRefObjets[Cpt]).Free; +FXRefObjets.Free; +inherited; +end; + +procedure TPdfDocument.WriteDocument(const AFlux: TStream); +var + Cpt,XRefPos: Integer; +begin +AFlux.Position:= 0; +WriteChaine(PDF_VERSION+CRLF,AFlux); +// write numbered indirect objects +for Cpt:= 1 to Pred(FXRefObjets.Count) do + begin + XRefPos:= AFlux.Position; + WriteObjet(Cpt,AFlux); + TPdfXRef(FXRefObjets[Cpt]).Offset:= XRefPos; + end; +XRefPos:= AFlux.Position; +// write xref table +WriteChaine('xref'+CRLF+'0 '+IntToStr(FXRefObjets.Count)+CRLF,AFlux); +with TPdfXRef(FXRefObjets[0]) do + WriteChaine(IntToChaine(Offset,10)+' '+IntToChaine(PDF_MAX_GEN_NUM,5)+' f'+CRLF,AFlux); +WriteXRefTable(AFlux); +// write trailer +WriteChaine('trailer'+CRLF,AFlux); +Trailer.WriteDictionary(-1,AFlux); +// write offset of last xref table +WriteChaine(CRLF+'startxref'+CRLF+IntToStr(XRefPos)+CRLF,AFlux); +WriteChaine(PDF_FILE_END,AFlux); +end; + +end. + diff --git a/src/reportengine/u_report.pas b/src/reportengine/u_report.pas new file mode 100644 index 00000000..70179365 --- /dev/null +++ b/src/reportengine/u_report.pas @@ -0,0 +1,3078 @@ +{ + << Impressions >> U_Report.pas + + Copyright (C) 2010 - Jean-Marc Levecque <jean-marc.levecque@jmlesite.fr> + + This library is a free software coming as a add-on to fpGUI toolkit + See the copyright included in the fpGUI distribution for details about redistribution + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Description: + This unit interfaces with the user program +} + +unit U_Report; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, StrUtils, + fpg_base, fpg_main, + fpg_panel, fpg_dialogs, fpg_imgfmt_bmp, fpg_imgfmt_jpg, + U_Command, U_Pdf; + +type + TPaperType= (A4,Letter,Legal,Executive,Comm10,Monarch,DL,C5,B5); + TOrient= (oPortrait,oLandscape); + TMeasureUnit = (msMM,msInch); + TPreparation= (ppPrepare,ppVisualize,ppPdfFile); + + T_Report = class(TObject) + private + OldSeparator: Char; + FVersion: Char; + FPaper: TPaper; + FPaperType: TPaperType; + FOrientation: TOrient; + FCurrentMargin: TDimensions; + FMeasureUnit: TMeasureUnit; + FPreparation: TPreparation; + FVisualization: Boolean; + FCanvas: TfpgCanvas; + FCurrentFont: Integer; + FCurrentLineSpace: Integer; + FCurrentColor: Integer; + FNmSection: Integer; + FNmPage: Integer; + FNmPageSect: Integer; + FPosRef: TRefPos; // absolute writting position + FHeaderHeight: Single; // end of text vertical position in the header + FPageHeight: Single; // end of text vertical position in the page + FFooterHeight: Single; // beginning of text vertical position in the footer + FGroup: Boolean; + FDefaultFile: string; + function Dim2Pixels(Value: Single): Single; + function Pixels2Dim(Value: Single): Single; + function AddLineBreaks(const Txt: TfpgString; AMaxLineWidth: integer; AFnt: TfpgFont): string; + function TxtHeight(AWid: Integer; const ATxt: TfpgString; AFnt: TfpgFont; ALSpace: Integer= 2): Integer; + function Convert2Alpha(Valeur: Integer): string; + function GetPaperHeight: Integer; + function GetPaperWidth: Integer; + procedure Bv_VisuPaint(Sender: TObject); + procedure PrepareFormat; + procedure CreateVisu; + procedure PrintPage(PageNumero: Integer); + procedure ShiftFooterLines(Shift: Single); + procedure ShiftPageLines(Shift: Single); + procedure ShiftGroup(Shift: Single); + function WriteText(PosX,PosY: Single; Column,Text,FontNum,BkColorNum,BordNum,SpLine: Integer; + TxtFlags: TfpgTextFlags; Zone: TZone): Single; + function WriteNumber(PosX,PosY: Single; Column,TextNum,TextTot,FontNum,BkColorNum,BordNum,SpLine: Integer; + TxtFlags: TfpgTextFlags; Total,Alpha: Boolean; Zone: TZone; SPNum: TSectPageNum): Single; + function InsertSpace(PosY: Single; Column: Integer; SpaceHeight: Single; BkColorNum: Integer; Zone: TZone): Single; + procedure LineEnd(Zone: TZone); + procedure DrawAFrame(StyLine: Integer; Zone: TZone); + procedure DrawALine(XBegin,YBegin,XEnd,YEnd: Single; StyLine: Integer); + procedure DrawAHorizLine(XBegin,YBegin: Single; Column: Integer; XEnd: Single; StyLine: Integer; Zone: TZone); + procedure PaintSurface(Points: T_Points; Couleur: TfpgColor); + procedure PaintImage(PosX,PosY: Single; Column,ImgNum: Integer; Zone: TZone); + function GetSectionTitle: string; + procedure SetSectionTitle(ATitle: string); + public + constructor Create; + destructor Destroy; override; + procedure BeginWrite(IniOrientation: TOrient= oPortrait; IniPaperType: TPaperType= A4; + IniMeasure: TMeasureUnit= msMM; IniVersion: Char= 'F'; IniVisu: Boolean= True); + // starts preview and printing process with initializations + // IniOrientation = paper orientation >> oPortrait or oLandscape + // IniPaperType = (A4, Letter,Legal,Executive,Comm10,Monarch,DL,C5,B5) + // IniMeasure = millimeters (msMM) or inches (msInches) + // IniVersion = version française 'F' or version English 'E', or other, to come + // IniVisu = True (Preview) or False (direct printing or PDF generation) + procedure EndWrite; + procedure WriteDocument; + procedure PagePreview; + procedure Section(MgLeft,MgRight,MgTop,MgBottom: Single; BackPos: Single= 0; + IniOrientation: TOrient= oPortrait); + // new section with initialization of margins + // BackPos = additional margin which can be necessary when frames are drawn + // IniOrientation = paper orientation >> oPortrait or oLandscape + procedure Page; + // new page in the current section + function BackColor(FdColor: TfpgColor): Integer; + // returns the number allocated to the color + // FdColor = background color + function Font(FtNom: string; FtColor: TfpgColor): Integer; + // returns the number allocated to the font + // FtNom = FontDesc of the font + // FtColor = font color + function LineStyle(StThick: Single; StColor: Tfpgcolor; StStyle: TfpgLineStyle): Integer; + // returns the number allocated to the line style + // StThick = thickness of the line in pixels + // StColor = line color + // StStyle = line style + function Border(BdFlags: TBorderFlags; BdStyle: Integer): Integer; + // returns the number allocated to the border + // BdFlags = position of the border (bdTop,bdBottom,bdLeft,bdRight) + // BdStyle = border line style: thickness, color, style + function Column(ClnPos,ClnWidth: Single; ClnMargin: Single= 0; ClnColor: TfpgColor= clWhite): Integer; + // returns the number allocated to the column + // ClnPos = left position in numeric value in the measurement unit (msMM or msInch) + // ClnWidth = width in numeric value in the measurement unit (msMM or msInch) + // ClnMargin = left and right margins in numeric value in the measurement unit (msMM or msInch) + // ClnColor = column background color + procedure WriteHeader(Horiz,Verti: Single; Text: string; ColNum: Integer= 0; FontNum: Integer= 0; + LineSpNum: Integer= 0; BkColorNum: Integer= -1; BordNum: Integer= -1); + // Horiz = horizontal position in column (cnLeft,cnCenter,cnRight) + // or numeric value in the measurement unit (msMM or msInch) + // Verti = line position in column (lnCourante,lnFin) + // or numeric value in the measurement unit (msMM or msInch) + // Text = text to be written + // ColNum = column reference, default between left and right margins + // FontNum = font reference + // LineSpNum = space between lines reference + // BkColorNum = background color reference, if > -1, replaces the column background color if any + // BordNum = border reference, if > -1 + function WritePage(Horiz,Verti: Single; Text: string; ColNum: Integer= 0; FontNum: Integer= 0; + LineSpNum: Integer= 0; BkColorNum: Integer= -1; BordNum: Integer= -1): Single; + // Horiz = horizontal position in column (cnLeft,cnCenter,cnRight) + // or numeric value in the measurement unit (msMM or msInch) + // Verti = line position in column (lnCourante,lnFin) + // or numeric value in the measurement unit (msMM or msInch) + // Text = text to be written + // ColNum = column reference, default between left and right margins + // FontNum = font reference + // LineSpNum = space between lines reference + // BkColorNum = background color reference, if > -1, replaces the column background color if any + // BordNum = border reference, if > -1 + procedure WriteFooter(Horiz,Verti: Single; Text: string; ColNum: Integer= 0; FontNum: Integer= 0; + LineSpNum: Integer= 0; BkColorNum: Integer= -1; BordNum: Integer= -1); + // Horiz = horizontal position in column (cnLeft,cnCenter,cnRight) + // or numeric value in the measurement unit (msMM or msInch) + // Verti = line position in column (lnCourante,lnFin) + // or numeric value in the measurement unit (msMM or msInch) + // Text = text to be written + // ColNum = column reference, default between left and right margins + // FontNum = font reference + // LineSpNum = space between lines reference + // BkColorNum = background color reference, if > -1, replaces the column background color if any + // BordNum = border reference, if > -1 + procedure NumSectionHeader(Horiz,Verti: Single; TexteSect: string= ''; TextTot: string= ''; + Total: Boolean= False; Alpha: Boolean= False; ColNum: Integer= 0; FontNum: Integer= 0; + LineSpNum: Integer= 0; BkColorNum: Integer= -1; BordNum: Integer= -1); + // Horiz = horizontal position in column (cnLeft,cnCenter,cnRight) + // or numeric value in the measurement unit (msMM or msInch) + // Verti = line position in column (lnCourante,lnFin) + // or numeric value in the measurement unit (msMM or msInch) + // TexteSection = text to be written before the section number + // TextTot = text to be written before the number of sections + // Total= True => displays the number of sections + // Alpha= True => displays the number of sections using letters in alphabetic order + // ColNum = column reference, default between left and right margins + // FontNum = font reference + // LineSpNum = space between lines reference + // BkColorNum = background color reference, if > -1, replaces the column background color if any + // BordNum = border reference, if > -1 + procedure NumSectionFooter(Horiz,Verti: Single; TexteSect: string= ''; TextTot: string= ''; + Total: Boolean= False; Alpha: Boolean= False; ColNum: Integer= 0; FontNum: Integer= 0; + LineSpNum: Integer= 0; BkColorNum: Integer= -1; BordNum: Integer= -1); + // Horiz = horizontal position in column (cnLeft,cnCenter,cnRight) + // or numeric value in the measurement unit (msMM or msInch) + // Verti = line position in column (lnCourante,lnFin) + // or numeric value in the measurement unit (msMM or msInch) + // TexteSection = text to be written before the section number + // TextTot = text to be written before the number of sections + // Total= True => displays the number of sections + // Alpha= True => displays the number of sections using letters in alphabetic order + // ColNum = column reference, default between left and right margins + // FontNum = font reference + // LineSpNum = space between lines reference + // BkColorNum = background color reference, if > -1, replaces the column background color if any + // BordNum = border reference, if > -1 + procedure NumPageHeader(Horiz,Verti: Single; TextePage: string= ''; TextTot: string= ''; + Total: Boolean= False; ColNum: Integer= 0; FontNum: Integer= 0; LineSpNum: Integer= 0; + BkColorNum: Integer= -1; BordNum: Integer= -1); + // Horiz = horizontal position in column (cnLeft,cnCenter,cnRight) + // or numeric value in the measurement unit (msMM or msInch) + // Verti = line position in column (lnCourante,lnFin) + // or numeric value in the measurement unit (msMM or msInch) + // TextePage = text to be written before the page number in the document + // TextTot = text to be written before the number of pages of the document + // Total= True > displays the number of pages of the document + // ColNum = column reference, default between left and right margins + // FontNum = font reference + // LineSpNum = space between lines reference + // BkColorNum = background color reference, if > -1, replaces the column background color if any + // BordNum = border reference, if > -1 + procedure NumPageFooter(Horiz,Verti: Single; TextePage: string= ''; TextTot: string= ''; + Total: Boolean= False; ColNum: Integer= 0; FontNum: Integer= 0; LineSpNum: Integer= 0; + BkColorNum: Integer= -1; BordNum: Integer= -1); + // Horiz = horizontal position in column (cnLeft,cnCenter,cnRight) + // or numeric value in the measurement unit (msMM or msInch) + // Verti = line position in column (lnCourante,lnFin) + // or numeric value in the measurement unit (msMM or msInch) + // TextePage = text to be written before the page number in the document + // TextTot = text to be written before the number of pages of the document + // Total= True > displays the number of pages of the document + // ColNum = column reference, default between left and right margins + // FontNum = font reference + // LineSpNum = space between lines reference + // BkColorNum = background color reference, if > -1, replaces the column background color if any + // BordNum = border reference, if > -1 + procedure NumPageSectionHeader(Horiz,Verti: Single; TexteSect: string= ''; TextTot: string= ''; + Total: Boolean= False; Alpha: Boolean= False; ColNum: Integer= 0; FontNum: Integer= 0; + LineSpNum: Integer= 0; BkColorNum: Integer= -1; BordNum: Integer= -1); + // Horiz = horizontal position in column (cnLeft,cnCenter,cnRight) + // or numeric value in the measurement unit (msMM or msInch) + // Verti = line position in column (lnCourante,lnFin) + // or numeric value in the measurement unit (msMM or msInch) + // TextePage = text to ba written before the page number in the section + // TextTot = text to be written before the number of pages of the section + // Total= True > displays the number of pages of the section + // ColNum = column reference, default between left and right margins + // FontNum = font reference + // LineSpNum = space between lines reference + // BkColorNum = background color reference, if > -1, replaces the column background color if any + // BordNum = border reference, if > -1 + procedure NumPageSectionFooter(Horiz,Verti: Single; TexteSect: string= ''; TextTot: string= ''; + Total: Boolean= False; Alpha: Boolean= False; ColNum: Integer= 0; FontNum: Integer= 0; + LineSpNum: Integer= 0; BkColorNum: Integer= -1; BordNum: Integer= -1); + // Horiz = horizontal position in column (cnLeft,cnCenter,cnRight) + // or numeric value in the measurement unit (msMM or msInch) + // Verti = line position in column (lnCourante,lnFin) + // or numeric value in the measurement unit (msMM or msInch) + // TextePage = text to ba written before the page number in the section + // TextTot = text to be written before the number of pages of the section + // Total= True > displays the number of pages of the section + // ColNum = column reference, default between left and right margins + // FontNum = font reference + // LineSpNum = space between lines reference + // BkColorNum = background color reference, if > -1, replaces the column background color if any + // BordNum = border reference, if > -1 + procedure HorizLineHeader(SpBefore,SpAfter: Single; ColNum: Integer= 0; StyleNum: Integer= 0); + // SpBefore = empty space before the horizontal line : numeric value in the measurement unit (msMM or msInch) + // SpAfter = empty space after the horizontal line : numeric value in the measurement unit (msMM or msInch) + // ColNum = column reference, default between left and right margins + // StyleNum = reference of the line style + procedure HorizLinePage(SpBefore,SpAfter: Single; ColNum: Integer= 0; StyleNum: Integer= 0); + // SpBefore = empty space before the horizontal line : numeric value in the measurement unit (msMM or msInch) + // SpAfter = empty space after the horizontal line : numeric value in the measurement unit (msMM or msInch) + // ColNum = column reference, default between left and right margins + // StyleNum = reference of the line style + procedure HorizLineFooter(SpBefore,SpAfter: Single; ColNum: Integer= 0; StyleNum: Integer= 0); + // SpBefore = empty space before the horizontal line : numeric value in the measurement unit (msMM or msInch) + // SpAfter = empty space after the horizontal line : numeric value in the measurement unit (msMM or msInch) + // ColNum = column reference, default between left and right margins + // StyleNum = reference of the line style + procedure SpaceHeader(Verti: Single; ColNum: Integer= 0; BkColorNum: Integer= -1); + // Verti = height of the empty space : numeric value in the measurement unit (msMM or msInch) + // ColNum = column reference, default between left and right margins + // BkColorNum = background color reference, if > -1, replaces the column background color if any + procedure SpacePage(Verti: Single; ColNum: Integer= 0; BkColorNum: Integer= -1); + // Verti = height of the empty space : numeric value in the measurement unit (msMM or msInch) + // ColNum = column reference, default between left and right margins + // BkColorNum = background color reference, if > -1, replaces the column background color if any + procedure SpaceFooter(Verti: Single; ColNum: Integer= 0; BkColorNum: Integer= -1); + // Verti = height of the empty space : numeric value in the measurement unit (msMM or msInch) + // ColNum = column reference, default between left and right margins + // BkColorNum = background color reference, if > -1, replaces the column background color if any + function LineSpace(SpSup,SpInt,SpInf: Single): Integer; + // SpSup = space between lines, top : numeric value in the measurement unit (msMM or msInch) + // SpInt = space between lines, internal if wrapping : numeric value in the measurement unit (msMM or msInch) + // SpInf = space between lines, botom : numeric value in the measurement unit (msMM or msInch) + procedure BeginGroup(PageJump: Boolean= False); + // PageJump = True >> forces new page before the group + // = False >> does not create a new page if the whole group can stand on the same page as the preceding text + procedure EndGroup(PageJump: Boolean= False); + // PageJump = True >> forces new page after the group + // = False >> lets continue on the same page after the group + procedure ColorColChange(ColNum: Integer; ColColor: TfpgColor); + // Changes the background color of a column + // ColNum = column reference + // ColColor = new background color for the column + procedure FrameMargins(AStyle: Integer); + // draw a frame at the page margins + // AStyle = reference of the line style of the frame + procedure FrameHeader(AStyle: Integer); + // draw a frame at the limits of the header + // AStyle = reference of the line style of the frame + procedure FramePage(AStyle: Integer); + // draw a frame at the page limits : left and right margins, header bottom and footer top + // AStyle = reference of the line style of the frame + procedure FrameFooter(AStyle: Integer); + // draw a frame at the limits of the footer + // AStyle = reference of the line style of the frame + procedure LinePage(XBegin,YBegin,XEnd,YEnd: Single; AStyle: Integer); + // draw a line at absolute position + // XBegin = horizontal position of starting point in numeric value in the measurement unit (msMM or msInch) + // YBegin = vertical position of starting point in numeric value in the measurement unit (msMM or msInch) + // XEnd = horizontal position of ending point in numeric value in the measurement unit (msMM or msInch) + // YEnd = vertical position of ending point in numeric value in the measurement unit (msMM or msInch) + // AStyle = reference of the line style of the line + procedure SurfPage(XLimits,YLimits: array of Single; AColor: TfpgColor); + // draw a coloured surface inside the defined limit points + // XLimits = list of horizontal positions of limit points + // YLimits = list of vertical positions of limit points + // AColor = colour to be painted within the limits + procedure ImageHeader(Horiz,Verti: Single; ImgFileName: string; ColNum: Integer= 0; Scale: Integer= 1); + // draw a bmp or jpg image at the defined position + // Horiz = horizontal position in numeric value in the measurement unit (msMM or msInch) + // Verti = vertical position in numeric value in the measurement unit (msMM or msInch) + // ImgFileName = name of the image file + // ColNum = column reference, default between left and right margins + // Scale = 1 for full size + // 2 for 1/2 size + // 3 for 1/3 size + // 4 for 1/4 size + procedure ImagePage(Horiz,Verti: Single; ImgFileName: string; ColNum: Integer= 0; Scale: Integer= 1); + // draw a bmp or jpg image at the defined position + // Horiz = horizontal position in numeric value in the measurement unit (msMM or msInch) + // Verti = vertical position in numeric value in the measurement unit (msMM or msInch) + // ImgFileName = name of the image file + // ColNum = column reference, default between left and right margins + // Scale = 1 for full size + // 2 for 1/2 size + // 3 for 1/3 size + // 4 for 1/4 size + procedure ImageFooter(Horiz,Verti: Single; ImgFileName: string; ColNum: Integer= 0; Scale: Integer= 1); + // draw a bmp or jpg image at the defined position + // Horiz = horizontal position in numeric value in the measurement unit (msMM or msInch) + // Verti = vertical position in numeric value in the measurement unit (msMM or msInch) + // ImgFileName = name of the image file + // ColNum = column reference, default between left and right margins + // Scale = 1 for full size + // 2 for 1/2 size + // 3 for 1/3 size + // 4 for 1/4 size + property Language: Char read FVersion write FVersion; + property Visualiser: Boolean read FVisualization write FVisualization; + property NumSection: Integer read FNmSection write FNmSection; + property NumPage: Integer read FNmPage write FNmPage; + property NumPageSection: Integer read FNmPageSect write FNmPageSect; + property PaperHeight: Integer read GetPaperHeight; + property PagerWidth: Integer read GetPaperWidth; + property DefaultFile: string read FDefaultFile write FDefaultFile; + property CurrentColor: Integer read FCurrentColor write FCurrentColor; + property SectionTitle: string read GetSectionTitle write SetSectionTitle; + end; + + // classes for interface with PDF generation + + TPdfElement = class + end; + + TPdfTexte= class(TPdfElement) + private + FPage: Integer; + FFont: Integer; + FSize: string; + FPosX: Single; + FPosY: Single; + FWidth: Single; + FText: string; + FColor: TfpgColor; + public + property PageId: Integer read FPage write FPage; + property FontName: Integer read FFont write FFont; + property FontSize: string read FSize write FSize; + property TextPosX: Single read FPosX write FPosX; + property TextPosY: Single read FPosY write FPosY; + property TextWidt: Single read FWidth write FWidth; + property Writting: string read FText write FText; + property Couleur: TfpgColor read FColor write FColor; + end; + + TPdfRect = class(TPdfElement) + private + FPage: Integer; + FThick: Single; + FLeft: Single; + FBottom: Single; + FHeight: Single; + FWidth: Single; + FColor: TfpgColor; + FFill: Boolean; + FStroke: Boolean; + FLineStyle: TfpgLineStyle; + protected + public + property PageId: Integer read FPage write FPage; + property RectThickness: Single read FThick write FThick; + property RectLeft: Single read FLeft write FLeft; + property RectBottom: Single read FBottom write FBottom; + property RectHeight: Single read FHeight write FHeight; + property RectWidth: Single read FWidth write FWidth; + property RectColor: TfpgColor read FColor write FColor; + property RectFill: Boolean read FFill write FFill; + property RectStroke: Boolean read FStroke write FStroke; + property RectLineStyle: TfpgLineStyle read FLineStyle write FLineStyle; + end; + + TPdfLine = class(TPdfElement) + private + FPage: Integer; + FThick: Single; + FBeginX: Single; + FBeginY: Single; + FEndX: Single; + FEndY: Single; + FColor: TfpgColor; + FStyle: TfpgLineStyle; + protected + public + property PageId: Integer read FPage write FPage; + property LineThikness: Single read FThick write FThick; + property LineBeginX: Single read FBeginX write FBeginX; + property LineBeginY: Single read FBeginY write FBeginY; + property LineEndX: Single read FEndX write FEndX; + property LineEndY: Single read FEndY write FEndY; + property LineColor: TfpgColor read FColor write FColor; + property LineStyle: TfpgLineStyle read FStyle write FStyle; + end; + + TPdfSurf = class(TPdfElement) + private + FPage: Integer; + FPoints: T_Points; + FColor: TfpgColor; + protected + public + property PageId: Integer read FPage write FPage; + property Points: T_Points read FPoints; + property SurfColor: TfpgColor read FColor write FColor; + end; + + TPdfImg = class(TPdfElement) + private + FPage: Integer; + FNumber: Integer; + FLeft: Single; + FBottom: Single; + FWidth: Integer; + FHeight: Integer; + protected + public + property PageId: Integer read FPage write FPage; + property ImgNumber: Integer read FNumber write FNumber; + property ImgLeft: Single read FLeft write FLeft; + property ImgBottom: Single read FBottom write FBottom; + property ImgWidth: Integer read FWidth write FWidth; + property ImgHeight: Integer read FHeight write FHeight; + end; + +var + Infos: record + Titre: string; + Auteur: string; + end; + + PdfPage: TList; + PdfTexte: TPdfTexte; + PdfRect: TPdfRect; + PdfLine: TPdfLine; + PdfSurf: TPdfSurf; + PdfImg: TPdfImg; + +const + PPI= 72; + FontDefaut= 0; + ColDefaut= -2; + lnCurrent= -1; + lnEnd= -2; +// cnSuite= -1; + cnLeft= -2; + cnCenter= -3; + cnRight= -4; + +implementation + +uses + U_Visu; + +const + InchToMM= 25.4; + +function T_Report.Dim2Pixels(Value: Single): Single; +begin +if FMeasureUnit= msMM +then + Result:= Value*PPI/InchToMM +else + Result:= Value*PPI; +end; + +function T_Report.Pixels2Dim(Value: Single): Single; +begin +if FMeasureUnit= msMM +then + Result:= Value*InchToMM/PPI +else + Result:= Value/PPI; +end; + +function T_Report.AddLineBreaks(const Txt: TfpgString; AMaxLineWidth: integer; AFnt: TfpgFont): string; +var + i,n,ls: integer; + sub: string; + lw,tw: integer; +begin +Result:= ''; +ls:= Length(Txt); +lw:= 0; +i:= 1; +while i<= ls do + begin + if (Txt[i] in txtWordDelims) + then // read the delimeter only + begin + sub:= Txt[i]; + Inc(i); + end + else // read the whole word + begin + n:= PosSetEx(txtWordDelims,Txt,i); + if n> 0 + then + begin + sub:= Copy(Txt,i,n-i); + i:= n; + end + else + begin + sub:= Copy(Txt,i,MaxInt); + i:= ls+1; + end; + end; + tw:= AFnt.TextWidth(sub); // wrap if needed + if (lw+tw> aMaxLineWidth) and (lw> 0) + then + begin + lw:= tw; + Result:= TrimRight(Result)+sLineBreak; + end + else + Inc(lw,tw); + Result:= Result+sub; + end; +end; + +function T_Report.TxtHeight(AWid: Integer; const ATxt: TfpgString; AFnt: TfpgFont; ALSpace: Integer= 2): Integer; +var + Cpt: Integer; + Wraplst: TStringList; +begin +Wraplst:= TStringList.Create; +Wraplst.Text := ATxt; +for Cpt:= 0 to Pred(Wraplst.Count) do + Wraplst[Cpt] := AddLineBreaks(Wraplst[Cpt],AWid,AFnt); +Wraplst.Text := Wraplst.Text; +Result:= (AFnt.Height*Wraplst.Count)+(ALSpace*Pred(Wraplst.Count)); +WrapLst.Free; +end; + +function T_Report.Convert2Alpha(Valeur: Integer): string; +var + Cpt: Byte; +begin +Result:= ''; +Cpt:= 0; +repeat + if Valeur> 26 + then + begin + Valeur:= Valeur-26; + Inc(Cpt); + Result:= Chr(Cpt+64); + end + else + begin + Result:= Chr(Valeur+64); + Valeur:= 0; + end; +until Valeur< 1; +end; + +function T_Report.GetPaperHeight: Integer; +begin +Result:= FPaper.H; +end; + +function T_Report.GetPaperWidth: Integer; +begin +Result:= FPaper.W; +end; + +procedure T_Report.Bv_VisuPaint(Sender: TObject); +begin +PrintPage(NumPage); +end; + +procedure T_Report.PrepareFormat; +var + TempH,TempW: Integer; + TempT,TempL,TempR,TempB: Single; +begin +with FPaper do + begin + case FPaperType of + A4: + begin + H:= 842; + W:= 595; + with Printable do + begin + T:= 10; + L:= 11; + R:= 586; + B:= 822; + end; + end; + Letter: + begin + H:= 792; + W:= 612; + with Printable do + begin + T:= 13; + L:= 13; + R:= 599; + B:= 780; + end; + end; + Legal: + begin + H:= 1008; + W:= 612; + with Printable do + begin + T:= 13; + L:= 13; + R:= 599; + B:= 996; + end; + end; + Executive: + begin + H:= 756; + W:= 522; + with Printable do + begin + T:= 14; + L:= 13; + R:= 508; + B:= 744; + end; + end; + Comm10: + begin + H:= 684; + W:= 297; + with Printable do + begin + T:= 13; + L:= 13; + R:= 284; + B:= 672; + end; + end; + Monarch: + begin + H:= 540; + W:= 279; + with Printable do + begin + T:= 13; + L:= 13; + R:= 266; + B:= 528; + end; + end; + DL: + begin + H:= 624; + W:= 312; + with Printable do + begin + T:= 14; + L:= 13; + R:= 297; + B:= 611; + end; + end; + C5: + begin + H:= 649; + W:= 459; + with Printable do + begin + T:= 13; + L:= 13; + R:= 446; + B:= 637; + end; + end; + B5: + begin + H:= 708; + W:= 499; + with Printable do + begin + T:= 14; + L:= 13; + R:= 485; + B:= 696; + end; + end; + end; + if FOrientation= oLandscape + then + begin + TempH:= H; + TempW:= W; + H:= TempW; + W:= TempH; + with Printable do + begin + TempT:= T; + TempL:= L; + TempR:= R; + TempB:= B; + T:= TempL; + L:= TempT; + R:= TempB; + B:= TempR; + end; + end; + end; +end; + +procedure T_Report.CreateVisu; +begin +F_Visu:= TF_Visu.Create(nil, self); +with F_Visu do + begin + Bv_Visu:= CreateBevel(F_Visu,(F_Visu.Width-FPaper.W) div 2,((F_Visu.Height+50-FPaper.H) div 2), + FPaper.W,FPaper.H,bsBox,bsRaised); + Bv_Visu.BackgroundColor:= clWhite; + Bv_Visu.OnPaint:= @Bv_VisuPaint; + end; +end; + +procedure T_Report.PrintPage(PageNumero: Integer); +var + CptSect,CptPage,CptCmd: Integer; + ThePage: T_Page; + Cmd: T_Command; +begin +CptSect:= 0; +repeat + Inc(CptSect); + CptPage:= 0; + with T_Section(Sections[Pred(CptSect)]) do + repeat + Inc(CptPage); + ThePage:= T_Page(Pages.Items[Pred(CptPage)]); + until (ThePage.PagesTot= PageNumero) or (CptPage= Pages.Count); +until (ThePage.PagesTot= PageNumero) or (CptSect= Sections.Count); +NumPage:= PageNumero; +NumSection:= CptSect; +NumPageSection:= ThePage.PagesSect; +with T_Section(Sections[Pred(NumSection)]) do + begin + if CmdHeader.Count> 0 + then + for CptCmd:= 0 to Pred(CmdHeader.Count) do + begin + Cmd:= T_Command(CmdHeader.Items[CptCmd]); + if Cmd is T_WriteText + then + with Cmd as T_WriteText do + WriteText(GetPosX,GetPosY,GetColumn,GetText,GetFont,GetBackColor,GetBorder,GetLineSpace,GetFlags,ZHeader); + if Cmd is T_Number + then + with Cmd as T_Number do + WriteNumber(GetPosX,GetPosY,GetColumn,GetTextNum,GetTextTot,GetFont,GetBackColor,GetBorder,GetLineSpace, + GetFlags,GetTotal,GetAlpha,zHeader,GetTypeNum); + if Cmd is T_Space + then + with Cmd as T_Space do + InsertSpace(GetPosY,GetColumn,GetHeight,GetBackColor,zHeader); + if Cmd is T_Line + then + with Cmd as T_Line do + DrawALine(GetPosX,GetPosY,GetEndX,GetEndY,GetStyle); + if Cmd is T_Image + then + with Cmd as T_Image do + PaintImage(GetPosX,GetPosY,GetColumn,GetImage,zHeader); + end; + if GetCmdPage(NumPageSection).Count> 0 + then + for CptCmd:= 0 to Pred(GetCmdPage(NumPageSection).Count) do + begin + Cmd:= T_Command(GetCmdPage(NumPageSection).Items[CptCmd]); + if Cmd is T_WriteText + then + with Cmd as T_WriteText do + WriteText(GetPosX,GetPosY,GetColumn,GetText,GetFont,GetBackColor,GetBorder,GetLineSpace,GetFlags,ZPage); + if Cmd is T_Space + then + with Cmd as T_Space do + InsertSpace(GetPosY,GetColumn,GetHeight,GetBackColor,zPage); + if Cmd is T_Line + then + with Cmd as T_Line do + DrawALine(GetPosX,GetPosY,GetEndX,GetEndY,GetStyle); + if Cmd is T_Surface + then + with Cmd as T_Surface do + PaintSurface(GetPoints,GetColor); + if Cmd is T_Image + then + with Cmd as T_Image do + PaintImage(GetPosX,GetPosY,GetColumn,GetImage,zPage); + end; + if CmdFooter.Count> 0 + then + for CptCmd:= 0 to Pred(CmdFooter.Count) do + begin + Cmd:= T_Command(CmdFooter.Items[CptCmd]); + if Cmd is T_WriteText + then + with Cmd as T_WriteText do + WriteText(GetPosX,GetPosY,GetColumn,GetText,GetFont,GetBackColor,GetBorder,GetLineSpace,GetFlags,ZFooter); + if Cmd is T_Number + then + with Cmd as T_Number do + WriteNumber(GetPosX,GetPosY,GetColumn,GetTextNum,GetTextTot,GetFont,GetBackColor,GetBorder,GetLineSpace, + GetFlags,GetTotal,GetAlpha,zFooter,GetTypeNum); + if Cmd is T_Space + then + with Cmd as T_Space do + InsertSpace(GetPosY,GetColumn,GetHeight,GetBackColor,zFooter); + if Cmd is T_Line + then + with Cmd as T_Line do + DrawALine(GetPosX,GetPosY,GetEndX,GetEndY,GetStyle); + if Cmd is T_Image + then + with Cmd as T_Image do + PaintImage(GetPosX,GetPosY,GetColumn,GetImage,zFooter); + end; + if CmdFrames.Count> 0 + then + for CptCmd:= 0 to Pred(CmdFrames.Count) do + begin + Cmd:= T_Command(CmdFrames.Items[CptCmd]); + if Cmd is T_Frame + then + with Cmd as T_Frame do + DrawAFrame(GetStyle,GetZone); + end; + end; +end; + +procedure T_Report.ShiftFooterLines(Shift: Single); +var + Cpt: Integer; + Cmd: T_Command; +begin +with T_Section(Sections[Pred(NumSection)]) do + if CmdFooter.Count> 0 + then + for Cpt:= 0 to Pred(CmdFooter.Count) do + begin + Cmd:= T_Command(CmdFooter.Items[Cpt]); + if Cmd is T_WriteText + then + with Cmd as T_WriteText do + SetPosY(GetPosY-Shift); + if Cmd is T_Number + then + with Cmd as T_Number do + SetPosY(GetPosY-Shift); + if Cmd is T_Space + then + with Cmd as T_Space do + SetPosY(GetPosY-Shift); + end; +end; + +procedure T_Report.ShiftPageLines(Shift: Single); +var + Cpt: Integer; + Cmd: T_Command; +begin +with VWriteLine do + for Cpt:= 0 to Pred(Commands.Count) do + begin + Cmd:= T_Command(Commands.Items[Cpt]); + if Cmd is T_WriteText + then + with Cmd as T_WriteText do + SetPosY(GetPosY-Shift); + end; +end; + +procedure T_Report.ShiftGroup(Shift: Single); +var + Cpt: Integer; + Cmd: T_Command; +begin +with VGroup do + for Cpt:= 0 to Pred(Commands.Count) do + begin + Cmd:= T_Command(Commands.Items[Cpt]); + if Cmd is T_WriteText + then + with Cmd as T_WriteText do + SetPosY(GetPosY-Shift); + end; +end; + +function T_Report.WriteText(PosX,PosY: Single; Column,Text,FontNum,BkColorNum,BordNum,SpLine: Integer; + TxtFlags: TfpgTextFlags; Zone: TZone): Single; +var + PosH,PosV,LnSpInt,LnSpSup,LnSpInf,ThickLine: Single; + HTxt,HeighTxt,Half,ColorLine,Cpt: Integer; + EndOfLine,UseCurFont: Boolean; + Fnt: TfpgFont; + StyleLine: TfpgLineStyle; + Wraplst: TStringList; +begin +with T_Section(Sections[Pred(NumSection)]) do + begin + EndOfLine:= False; + if FPreparation= ppPrepare + then + if FCurrentFont<> FontNum + then + begin + FCurrentFont:= FontNum; + UseCurFont:= False; + end + else + UseCurFont:= True; + Fnt:= T_Font(Fonts[FontNum]).GetFont; + if LineSpaces.Count= 0 + then + LineSpace(0,0,0); + if FCurrentLineSpace<> SpLine + then + FCurrentLineSpace:= SpLine; + with T_LineSpace(LineSpaces[FCurrentLineSpace]) do + begin + LnSpSup:= GetSup; + LnSpInt:= GetInt; + LnSpInf:= GetInf; + end; + if Column= -2 + then + Column:= DefaultCol; + if Column> -1 + then + HeighTxt:= TxtHeight(Round(T_Column(Columns[Column]).GetTextWidth),Texts[Text],Fnt,Round(LnSpInt))+Round(LnSpSup+LnSpInf) + else + HeighTxt:= TxtHeight(Paper.W,Texts[Text],Fnt,Round(LnSpInt))+Round(LnSpSup+LnSpInf); + if (Column> -1) and (BordNum> -1) + then + Half:= Round(T_LineStyle(LineStyles[T_Border(Borders[BordNum]).GetStyle]).GetThick) div 2 + else + Half:= 0; + case FPreparation of + ppPrepare: + begin + if NbPages= 0 + then + Page; + if Column> -1 + then + begin + HTxt:= VWriteLine.LineHeight; + if HTxt< HeighTxt + then + HTxt:= HeighTxt; + end + else + if HTxt< Fnt.Height + then + HTxt:= Fnt.Height; + case Zone of + zHeader: + FPosRef.Y:= FCurrentMargin.T+FHeaderHeight; + zPage: + FPosRef.Y:= FCurrentMargin.T+FHeaderHeight+FPageHeight; + zFooter: + begin + FPosRef.Y:= FCurrentMargin.B-HTxt; + FFooterHeight:= FFooterHeight+HTxt; + ShiftFooterLines(HTxt); + end; + end; + if PosY= lnCurrent + then + PosV:= FPosRef.Y+LnSpSup + else + begin + EndOfLine:= True; + if PosY= lnEnd + then + begin + PosV:= FPosRef.Y+LnSpSup; + case Zone of + zHeader: + FPosRef.Y:= FPosRef.Y+HTxt; + zPage: + begin + if FPosRef.Y+HTxt> FCurrentMargin.B-FFooterHeight + then + if FGroup + then + begin + if VGroup.GroupeHeight+HTxt< FCurrentMargin.B-FCurrentMargin.T-FHeaderHeight-FFooterHeight + then + begin + Page; + if VGroup.Commands.Count> 0 + then + begin + FPosRef.Y:= FCurrentMargin.T+FHeaderHeight; + ShiftGroup(T_WriteText(VGroup.Commands[0]).GetPosY-FPosRef.Y); + FPosRef.Y:= FPosRef.Y+VGroup.GroupeHeight+Succ(Half); + if VWriteLine.Commands.Count> 0 + then + ShiftPageLines(T_WriteText(VWriteLine.Commands[0]).GetPosY-FPosRef.Y); + PosV:= FPosRef.Y+LnSpSup; + FPosRef.Y:= FPosRef.Y+HTxt+Succ(Half); + end + else + begin + if VWriteLine.Commands.Count> 0 + then + ShiftPageLines(T_WriteText(VWriteLine.Commands[0]).GetPosY-FPosRef.Y); + PosV:= FPosRef.Y+LnSpSup; + FPosRef.Y:= FPosRef.Y+HTxt+Succ(Half); + end; + end + else + begin + LoadCmdGroupToPage; +// VGroup.Commands.Clear; + Page; + FPosRef.Y:= FCurrentMargin.T+FHeaderHeight; + if VWriteLine.Commands.Count> 0 + then + ShiftPageLines(T_WriteText(VWriteLine.Commands[0]).GetPosY-FPosRef.Y); + PosV:= FPosRef.Y+LnSpSup; + FPosRef.Y:= FPosRef.Y+HTxt+Succ(Half); + end; + end + else + begin + Page; + FPosRef.Y:= FCurrentMargin.T+FHeaderHeight; + if VWriteLine.Commands.Count> 0 + then + ShiftPageLines(T_WriteText(VWriteLine.Commands[0]).GetPosY-FPosRef.Y); + PosV:= FPosRef.Y+LnSpSup; + FPosRef.Y:= FPosRef.Y+HTxt+Succ(Half); + end + else + FPosRef.Y:= FPosRef.Y+HTxt; + end; + end; + if BordNum> -1 + then + with T_Border(Borders[BordNum]) do + if bfBottom in GetFlags + then + FPosRef.Y:= FPosRef.Y+1; + end + else + begin + PosV:= PosY; + FPosRef.Y:= PosV+LnSpInf; + end; + case Zone of + zHeader: + FHeaderHeight:= FPosRef.Y-FCurrentMargin.T; + zPage: + FPageHeight:= FPosRef.Y-FHeaderHeight-FCurrentMargin.T; + end; + end; + //if PosX= cnSuite + //then + //PosH:= FPosRef.X + //else + if Column= -1 + then + if PosX> 0 + then + PosH:= PosX + else + begin + PosH:= T_Column(Columns[ColDefaut]).GetTextPos; + if (txtRight in TxtFlags) + then + PosH:= PosH+T_Column(Columns[ColDefaut]).ColWidth-Fnt.TextWidth(Texts[Text])-T_Column(Columns[ColDefaut]).ColMargin; + if (txtHCenter in TxtFlags) + then + PosH:= PosH+(T_Column(Columns[ColDefaut]).ColWidth-Fnt.TextWidth(Texts[Text]))/2; + end + else + if PosX> 0 + then + begin + if (PosX< T_Column(Columns[Column]).GetTextPos) + or (PosX> (T_Column(Columns[Column]).GetTextPos+T_Column(Columns[Column]).GetTextWidth)) + then + PosH:= T_Column(Columns[Column]).GetTextPos + else + PosH:= PosX; + end + else + begin + PosH:= T_Column(Columns[Column]).GetTextPos; + if (txtRight in TxtFlags) + then + PosH:= PosH+T_Column(Columns[Column]).ColWidth-Fnt.TextWidth(Texts[Text])-T_Column(Columns[Column]).ColMargin; + if (txtHCenter in TxtFlags) + then + PosH:= PosH+(T_Column(Columns[Column]).ColWidth-Fnt.TextWidth(Texts[Text]))/2; + end; + FPosRef.X:= PosH+Fnt.TextWidth(Texts[Text]+' '); + VWriteLine.LoadText(PosH,PosV,Column,Text,FontNum,HTxt,BkColorNum,BordNum,SpLine,UseCurFont,TxtFlags); + Result:= Pixels2Dim(FPosRef.Y); + if EndOfLine + then + begin + HTxt:= 0; + LineEnd(Zone); + end; + end; + ppVisualize: + with FCanvas do + begin + Font:= T_Font(Fonts[FontNum]).GetFont; + SetTextColor(T_Font(Fonts[FontNum]).GetColor); + if Column> -1 + then + with T_Column(Columns[Column]) do + begin + if BkColorNum> -1 + then + SetColor(T_BackColor(BackColors[BkColorNum]).GetColor) + else + SetColor(GetColor); + FillRectangle(Round(ColPos),Round(PosY-LnSpSup),Round(ColWidth),HeighTxt); + if BordNum> -1 + then + with T_Border(Borders[BordNum]) do + begin + SetLineStyle(Round(T_LineStyle(LineStyles[GetStyle]).GetThick),T_LineStyle(LineStyles[GetStyle]).GetStyle); + SetColor(T_LineStyle(LineStyles[GetStyle]).GetColor); + if bfLeft in GetFlags + then + DrawLine(Round(ColPos)+Half,Round(PosY-LnSpSup),Round(ColPos)+Half,Round(PosY-LnSpSup)+HeighTxt); + if bfRight in GetFlags + then + DrawLine(Round(ColPos+ColWidth)-Succ(Half),Round(PosY-LnSpSup),Round(ColPos+ColWidth)-Succ(Half),Round(PosY-LnSpSup)+HeighTxt); + if bfTop in GetFlags + then + DrawLine(Round(ColPos),Round(PosY-LnSpSup)+Half,Round(ColPos+ColWidth),Round(PosY-LnSpSup)+Half); + if bfBottom in GetFlags + then + DrawLine(Round(ColPos),Round(PosY-LnSpSup)+HeighTxt-Half,Round(ColPos+ColWidth),Round(PosY-LnSpSup)+HeighTxt-Half); + end; + DrawText(Round(GetTextPos),Round(PosY),Round(GetTextWidth),0,Texts[Text],TxtFlags,Round(LnSpInt)); + end + else + DrawText(Round(PosX),Round(PosY)-Fnt.Ascent,Round(Paper.W-PosX),0,Texts[Text],TxtFlags); + end; + ppPdfFile: + if Column> -1 + then + with T_Column(Columns[Column]) do + begin + if (GetColor<> clWhite) or (BkColorNum> -1) + then + begin + PdfRect:= TPdfRect.Create; + with PdfRect do + begin + PageId:= NumPage; + FLeft:= ColPos; + FBottom:= Paper.H-PosY+LnSpSup-HeighTxt; + FHeight:= HeighTxt; + FWidth:= ColWidth; + if BkColorNum> -1 + then + FColor:= T_BackColor(BackColors[BkColorNum]).GetColor + else + FColor:= GetColor; + FFill:= True; + FStroke:= False; + end; + PdfPage.Add(PdfRect); + end; + if BordNum> -1 + then + with T_Border(Borders[BordNum]) do + begin + StyleLine:= T_LineStyle(LineStyles[GetStyle]).GetStyle; + ColorLine:= T_LineStyle(LineStyles[GetStyle]).GetColor; + ThickLine:= T_LineStyle(LineStyles[GetStyle]).GetThick; + if bfLeft in GetFlags + then + begin + PdfLine:= TPdfLine.Create; + with PdfLine do + begin + PageId:= NumPage; + FBeginX:= ColPos; + FBeginY:= Paper.H-PosY+LnSpSup; + FEndX:= ColPos; + FEndY:= Paper.H-PosY+LnSpSup-HeighTxt; + FStyle:= StyleLine; + FColor:= ColorLine; + FThick:= ThickLine; + end; + PdfPage.Add(PdfLine); + end; + if bfRight in GetFlags + then + begin + PdfLine:= TPdfLine.Create; + with PdfLine do + begin + PageId:= NumPage; + FBeginX:= ColPos+ColWidth; + FBeginY:= Paper.H-PosY+LnSpSup; + FEndX:= ColPos+ColWidth; + FEndY:= Paper.H-PosY+LnSpSup-HeighTxt; + FStyle:= StyleLine; + FColor:= ColorLine; + FThick:= ThickLine; + end; + PdfPage.Add(PdfLine); + end; + if bfTop in GetFlags + then + begin + PdfLine:= TPdfLine.Create; + with PdfLine do + begin + PageId:= NumPage; + FBeginX:= ColPos; + FBeginY:= Paper.H-PosY+LnSpSup; + FEndX:= ColPos+ColWidth; + FEndY:= Paper.H-PosY+LnSpSup; + FStyle:= StyleLine; + FColor:= ColorLine; + FThick:= ThickLine; + end; + PdfPage.Add(PdfLine); + end; + if bfBottom in GetFlags + then + begin + PdfLine:= TPdfLine.Create; + with PdfLine do + begin + PageId:= NumPage; + FBeginX:= ColPos; + FBeginY:= Paper.H-PosY+LnSpSup-HeighTxt; + FEndX:= ColPos+ColWidth; + FEndY:= Paper.H-PosY+LnSpSup-HeighTxt; + FStyle:= StyleLine; + FColor:= ColorLine; + FThick:= ThickLine; + end; + PdfPage.Add(PdfLine); + end; + end; + if Fnt.TextWidth(Texts[Text])< GetTextWidth + then + begin + PdfTexte:= TPdfTexte.Create; + with PdfTexte do + begin + PageId:= NumPage; + FFont:= FontNum; + FSize:= T_Font(Fonts[FontNum]).GetSize; + FColor:= T_Font(Fonts[FontNum]).GetColor; + TextPosX:= GetTextPos; + if (txtRight in TxtFlags) + then + TextPosX:= ColPos+ColWidth-ColMargin-Fnt.TextWidth(Texts[Text]); + if (txtHCenter in TxtFlags) + then + TextPosX:= GetTextPos+(ColWidth-Fnt.TextWidth(Texts[Text]))/2; + TextPosY:= Paper.H-PosY-Fnt.Ascent; + TextWidt:= ColWidth; + Writting:= Texts[Text]; + end; + PdfPage.Add(PdfTexte); + end + else + begin + Wraplst:= TStringList.Create; + Wraplst.Text:= Texts[Text]; + for Cpt:= 0 to Pred(Wraplst.Count) do + Wraplst[Cpt]:= AddLineBreaks(Wraplst[Cpt],Round(GetTextWidth),Fnt); + Wraplst.Text:= Wraplst.Text; + for Cpt:= 0 to Pred(Wraplst.Count) do + begin + PdfTexte:= TPdfTexte.Create; + with PdfTexte do + begin + PageId:= NumPage; + FFont:= FontNum; + FSize:= T_Font(Fonts[FontNum]).GetSize; + FColor:= T_Font(Fonts[FontNum]).GetColor; + TextPosX:= GetTextPos; + if (txtRight in TxtFlags) + then + TextPosX:= ColPos+ColWidth-ColMargin-Fnt.TextWidth(Wraplst[Cpt]); + if (txtHCenter in TxtFlags) + then + TextPosX:= GetTextPos+(ColWidth-Fnt.TextWidth(Wraplst[Cpt]))/2; + TextPosY:= Paper.H-PosY-Fnt.Ascent-(Fnt.Height+LnSpInt)*Cpt; + TextWidt:= ColWidth; + Writting:= Wraplst[Cpt]; + end; + PdfPage.Add(PdfTexte); + end; + WrapLst.Free; + end; + end + else + if Fnt.TextWidth(Texts[Text])< Paper.W-PosX + then + begin + PdfTexte:= TPdfTexte.Create; + with PdfTexte do + begin + PageId:= NumPage; + FFont:= FontNum; + FSize:= T_Font(Fonts[FontNum]).GetSize; + FColor:= T_Font(Fonts[FontNum]).GetColor; + FPosX:= PosX; + FPosY:= Paper.H-PosY; + FWidth:= Paper.W; + FText:= Texts[Text]; + end; + PdfPage.Add(PdfTexte); + end + else + begin + Wraplst:= TStringList.Create; + Wraplst.Text:= Texts[Text]; + for Cpt:= 0 to Pred(Wraplst.Count) do + Wraplst[Cpt]:= AddLineBreaks(Wraplst[Cpt],Round(Paper.W-PosX),Fnt); + Wraplst.Text:= Wraplst.Text; + for Cpt:= 0 to Pred(Wraplst.Count) do + begin + PdfTexte:= TPdfTexte.Create; + with PdfTexte do + begin + PageId:= NumPage; + FFont:= FontNum; + FSize:= T_Font(Fonts[FontNum]).GetSize; + FColor:= T_Font(Fonts[FontNum]).GetColor; + FPosX:= PosX; + FPosY:= Paper.H-PosY-Fnt.Ascent-(Fnt.Height+LnSpInt)*Cpt; + FWidth:= Paper.W; + FText:= Wraplst[Cpt]; + end; + PdfPage.Add(PdfTexte); + end; + WrapLst.Free; + end; + end; + end; +end; + +function T_Report.WriteNumber(PosX,PosY: Single; Column,TextNum,TextTot,FontNum,BkColorNum,BordNum,SpLine: Integer; + TxtFlags: TfpgTextFlags; Total,Alpha: Boolean; Zone: TZone; SPNum: TSectPageNum): Single; + + function BuildChaine: string; + var + NumAlpha: string; + begin + case SPNum of + PageNum: + if Total + then + Result:= Texts[TextNum]+' '+IntToStr(NumPage)+' '+Texts[TextTot]+' ' + +IntToStr(T_Section(Sections[Pred(Sections.Count)]).TotPages) + else + Result:= Texts[TextNum]+' '+IntToStr(NumPage); + SectNum: + begin + if Alpha + then + NumAlpha:= Convert2Alpha(NumSection) + else + NumAlpha:= IntToStr(NumSection); + if Total + then + Result:= Texts[TextNum]+' '+NumAlpha+' '+Texts[TextTot]+' '+IntToStr(Sections.Count) + else + Result:= Texts[TextNum]+' '+NumAlpha; + end; + PSectNum: + begin + if Alpha + then + NumAlpha:= Convert2Alpha(NumPageSection) + else + NumAlpha:= IntToStr(NumPageSection); + if Total + then + Result:= Texts[TextNum]+' '+NumAlpha+' '+Texts[TextTot]+' ' + +IntToStr(T_Section(Sections[Pred(NumSection)]).NbPages) + else + Result:= Texts[TextNum]+' '+NumAlpha; + end; + end; + end; + +var + PosH,PosV,LnSpInt,LnSpSup,LnSpInf,ThickLine: Single; + HTxt,HeighTxt,Half,ColorLine: Integer; + EndOfLine,UseCurFont: Boolean; + Fnt: TfpgFont; + StyleLine: TfpgLineStyle; + Chaine: string; +begin +with T_Section(Sections[Pred(NumSection)]) do + begin + EndOfLine:= False; + if FPreparation= ppPrepare + then + if FCurrentFont<> FontNum + then + begin + FCurrentFont:= FontNum; + UseCurFont:= False; + end + else + UseCurFont:= True; + Fnt:= T_Font(Fonts[FontNum]).GetFont; + if LineSpaces.Count= 0 + then + LineSpace(0,0,0); + if FCurrentLineSpace<> SpLine + then + FCurrentLineSpace:= SpLine; + with T_LineSpace(LineSpaces[FCurrentLineSpace]) do + begin + LnSpSup:= GetSup; + LnSpInt:= GetInt; + LnSpInf:= GetInf; + end; + if Column= -2 + then + Column:= DefaultCol; + if Column> -1 + then + HeighTxt:= TxtHeight(Round(T_Column(Columns[Column]).GetTextWidth),Texts[TextNum]+' 0 '+Texts[TextTot]+' 0',Fnt,Round(LnSpInt))+Round(LnSpSup+LnSpInf) + else + HeighTxt:= TxtHeight(Paper.W,Texts[TextNum]+' 0 '+Texts[TextTot]+' 0',Fnt,Round(LnSpInt))+Round(LnSpSup+LnSpInf); + if (Column> -1) and (BordNum> -1) + then + Half:= Round(T_LineStyle(LineStyles[T_Border(Borders[BordNum]).GetStyle]).GetThick) div 2; + case FPreparation of + ppPrepare: + begin + if NbPages= 0 + then + Page; + if Column> -1 + then + begin + HTxt:= VWriteLine.LineHeight; + if HTxt< HeighTxt + then + HTxt:= HeighTxt; + end + else + if HTxt< Fnt.Height + then + HTxt:= Fnt.Height; + case Zone of + zHeader: + FPosRef.Y:= FCurrentMargin.T+FHeaderHeight; + zFooter: + begin + FPosRef.Y:= FCurrentMargin.B-HTxt; + FFooterHeight:= FFooterHeight+HTxt; + ShiftFooterLines(HTxt); + end; + end; + if PosY= lnCurrent + then + PosV:= FPosRef.Y+LnSpSup + else + begin + EndOfLine:= True; + if PosY= lnEnd + then + begin + PosV:= FPosRef.Y+LnSpSup; + case Zone of + zHeader: + FPosRef.Y:= FPosRef.Y+HTxt; + end; + if BordNum> -1 + then + with T_Border(Borders[BordNum]) do + if bfBottom in GetFlags + then + FPosRef.Y:= FPosRef.Y+1; + end + else + begin + PosV:= PosY; + FPosRef.Y:= PosV+LnSpInf; + end; + case Zone of + zHeader: + FHeaderHeight:= FPosRef.Y-FCurrentMargin.T; + end; + end; + if Column= -1 + then + if PosX> 0 + then + PosH:= PosX + else + begin + PosH:= T_Column(Columns[ColDefaut]).GetTextPos-T_Column(Columns[0]).ColMargin; + if (txtRight in TxtFlags) + then + if Total + then + PosH:= PosH+T_Column(Columns[ColDefaut]).ColWidth-Fnt.TextWidth(Texts[TextNum]+' 0 '+Texts[TextTot]+' 0 ')-T_Column(Columns[ColDefaut]).ColMargin + else + PosH:= PosH+T_Column(Columns[ColDefaut]).ColWidth-Fnt.TextWidth(Texts[TextNum]+' 0 ')-T_Column(Columns[ColDefaut]).ColMargin; + if (txtHCenter in TxtFlags) + then + if Total + then + PosH:= PosH+(T_Column(Columns[ColDefaut]).ColWidth-Fnt.TextWidth(Texts[TextNum]+' 0 '+Texts[TextTot]+' 0 '))/2 + else + PosH:= PosH+(T_Column(Columns[ColDefaut]).ColWidth-Fnt.TextWidth(Texts[TextNum]+' 0 '))/2; + end + else + if PosX> 0 + then + if (PosX< T_Column(Columns[Column]).GetTextPos) + or (PosX> (T_Column(Columns[Column]).GetTextPos+T_Column(Columns[Column]).GetTextWidth)) + then + PosH:= T_Column(Columns[Column]).GetTextPos + else + PosH:= PosX + else + begin + PosH:= T_Column(Columns[Column]).GetTextPos-T_Column(Columns[Column]).ColMargin; + if (txtRight in TxtFlags) + then + if Total + then + PosH:= PosH+T_Column(Columns[Column]).ColWidth-Fnt.TextWidth(Texts[TextNum]+' 0 '+Texts[TextTot]+' 0 ')-T_Column(Columns[Column]).ColMargin + else + PosH:= PosH+T_Column(Columns[Column]).ColWidth-Fnt.TextWidth(Texts[TextNum]+' 0 ')-T_Column(Columns[Column]).ColMargin; + if (txtHCenter in TxtFlags) + then + if Total + then + PosH:= PosH+(T_Column(Columns[Column]).ColWidth-Fnt.TextWidth(Texts[TextNum]+' 0 '+Texts[TextTot]+' 0 '))/2 + else + PosH:= PosH+(T_Column(Columns[Column]).ColWidth-Fnt.TextWidth(Texts[TextNum]+' 0 '))/2; + end; + FPosRef.X:= PosH+Fnt.TextWidth(Texts[TextNum]+' 0 '+Texts[TextTot]+' 0 '); + VWriteLine.LoadNumber(PosH,PosV,Column,TextNum,TextTot,FontNum,HTxt,BkColorNum,BordNum,SpLine,UseCurFont,TxtFlags,Total,Alpha,SPNum); + Result:= Pixels2Dim(FPosRef.Y); + if EndOfLine + then + begin + HTxt:= 0; + LineEnd(Zone); + end; + end; + ppVisualize: + with FCanvas do + begin + Chaine:= BuildChaine; + Font:= T_Font(Fonts[FontNum]).GetFont; + SetTextColor(T_Font(Fonts[FontNum]).GetColor); + if Column> -1 + then + with T_Column(Columns[Column]) do + begin + if BkColorNum> -1 + then + SetColor(T_BackColor(BackColors[BkColorNum]).GetColor) + else + SetColor(GetColor); + FillRectangle(Round(ColPos),Round(PosY-LnSpSup),Round(ColWidth),HeighTxt); + if BordNum> -1 + then + with T_Border(Borders[BordNum]) do + begin + SetLineStyle(Round(T_LineStyle(LineStyles[GetStyle]).GetThick),T_LineStyle(LineStyles[GetStyle]).GetStyle); + SetColor(T_LineStyle(LineStyles[GetStyle]).GetColor); + if bfLeft in GetFlags + then + DrawLine(Round(ColPos)+Half,Round(PosY-LnSpSup),Round(ColPos)+Half,Round(PosY-LnSpSup)+HeighTxt); + if bfRight in GetFlags + then + DrawLine(Round(ColPos+ColWidth)-Half,Round(PosY-LnSpSup),Round(ColPos+ColWidth)-Half,Round(PosY-LnSpSup)+HeighTxt); + if bfTop in GetFlags + then + DrawLine(Round(ColPos),Round(PosY-LnSpSup)+Half,Round(ColPos+ColWidth),Round(PosY-LnSpSup)+Half); + if bfBottom in GetFlags + then + DrawLine(Round(ColPos),Round(PosY-LnSpSup)+HeighTxt-Succ(Half),Round(ColPos+ColWidth),Round(PosY-LnSpSup)+HeighTxt-Succ(Half)); + end; + DrawText(Round(GetTextPos),Round(PosY),Round(GetTextWidth),0,Chaine,TxtFlags,Round(LnSpInt)); + end + else + DrawText(Round(PosX),Round(PosY),Chaine,TxtFlags); + end; + ppPdfFile: + begin + Chaine:= BuildChaine; + if Column> -1 + then + with T_Column(Columns[Column]) do + begin + if (GetColor<> clWhite) or (BkColorNum> -1) + then + begin + PdfRect:= TPdfRect.Create; + with PdfRect do + begin + PageId:= NumPage; + FLeft:= ColPos; + FBottom:= Paper.H-PosY+LnSpSup-HeighTxt; + FHeight:= HeighTxt; + FWidth:= ColWidth; + if BkColorNum> -1 + then + FColor:= T_BackColor(BackColors[BkColorNum]).GetColor + else + FColor:= GetColor; + FFill:= True; + FStroke:= False; + end; + PdfPage.Add(PdfRect); + end; + if BordNum> -1 + then + with T_Border(Borders[BordNum]) do + begin + StyleLine:= T_LineStyle(LineStyles[GetStyle]).GetStyle; + ColorLine:= T_LineStyle(LineStyles[GetStyle]).GetColor; + ThickLine:= T_LineStyle(LineStyles[GetStyle]).GetThick; + if bfLeft in GetFlags + then + begin + PdfLine:= TPdfLine.Create; + with PdfLine do + begin + PageId:= NumPage; + FBeginX:= ColPos; + FBeginY:= Paper.H-PosY+LnSpSup; + FEndX:= ColPos; + FEndY:= Paper.H-PosY+LnSpSup-HeighTxt; + FStyle:= StyleLine; + FColor:= ColorLine; + FThick:= ThickLine; + end; + PdfPage.Add(PdfLine); + end; + if bfRight in GetFlags + then + begin + PdfLine:= TPdfLine.Create; + with PdfLine do + begin + PageId:= NumPage; + FBeginX:= ColPos+ColWidth; + FBeginY:= Paper.H-PosY+LnSpSup; + FEndX:= ColPos+ColWidth; + FEndY:= Paper.H-PosY+LnSpSup-HeighTxt; + FStyle:= StyleLine; + FColor:= ColorLine; + FThick:= ThickLine; + end; + PdfPage.Add(PdfLine); + end; + if bfTop in GetFlags + then + begin + PdfLine:= TPdfLine.Create; + with PdfLine do + begin + PageId:= NumPage; + FBeginX:= ColPos; + FBeginY:= Paper.H-PosY+LnSpSup; + FEndX:= ColPos+ColWidth; + FEndY:= Paper.H-PosY+LnSpSup; + FStyle:= StyleLine; + FColor:= ColorLine; + FThick:= ThickLine; + end; + PdfPage.Add(PdfLine); + end; + if bfBottom in GetFlags + then + begin + PdfLine:= TPdfLine.Create; + with PdfLine do + begin + PageId:= NumPage; + FBeginX:= ColPos; + FBeginY:= Paper.H-PosY+LnSpSup-HeighTxt; + FEndX:= ColPos+ColWidth; + FEndY:= Paper.H-PosY+LnSpSup-HeighTxt; + FStyle:= StyleLine; + FColor:= ColorLine; + FThick:= ThickLine; + end; + PdfPage.Add(PdfLine); + end; + end; + PdfTexte:= TPdfTexte.Create; + with PdfTexte do + begin + PageId:= NumPage; + FFont:= FontNum; + FSize:= T_Font(Fonts[FontNum]).GetSize; + FColor:= T_Font(Fonts[FontNum]).GetColor; + TextPosX:= GetTextPos; + if (txtRight in TxtFlags) + then + TextPosX:= ColPos+ColWidth-ColMargin-Fnt.TextWidth(Chaine); + if (txtHCenter in TxtFlags) + then + TextPosX:= GetTextPos+(ColWidth-Fnt.TextWidth(Chaine))/2; + TextPosY:= Paper.H-PosY-Fnt.Ascent; + TextWidt:= ColWidth; + Writting:= Chaine; + end; + PdfPage.Add(PdfTexte); + end + else + begin + PdfTexte:= TPdfTexte.Create; + with PdfTexte do + begin + PageId:= NumPage; + FFont:= FontNum; + FSize:= T_Font(Fonts[FontNum]).GetSize; + FColor:= T_Font(Fonts[FontNum]).GetColor; + FPosX:= PosX; + FPosY:= PosY-Fnt.Ascent; + FWidth:= Paper.W; + FText:= Chaine; + end; + PdfPage.Add(PdfTexte); + end; + end; + end; + end; +end; + +function T_Report.InsertSpace(PosY: Single; Column: Integer; SpaceHeight: Single; BkColorNum: Integer; Zone: TZone): Single; +var + PosV: Single; +begin +with T_Section(Sections[Pred(NumSection)]) do + begin + if PosY> -1 + then + PosV:= PosY + else + PosV:= FPosRef.Y; + if Column= -2 + then + Column:= DefaultCol; + case FPreparation of + ppPrepare: + begin + case Zone of + zHeader: + begin + FPosRef.Y:= FCurrentMargin.T+FHeaderHeight; + FPosRef.Y:= FPosRef.Y+SpaceHeight; + FHeaderHeight:= FPosRef.Y-FCurrentMargin.T; + LoadSpaceHeader(PosV,Column,SpaceHeight,BkColorNum); + end; + zPage: + begin + FPosRef.Y:= FCurrentMargin.T+FHeaderHeight+FPageHeight; + if FPosRef.Y+SpaceHeight> FCurrentMargin.B-FFooterHeight + then + begin + FPosRef.Y:= FCurrentMargin.T+FHeaderHeight; + Page; + end + else + FPosRef.Y:= FPosRef.Y+SpaceHeight; + FPageHeight:= FPosRef.Y-FHeaderHeight-FCurrentMargin.T; + LoadSpacePage(PosV,Column,SpaceHeight,BkColorNum); + end; + zFooter: + begin + FPosRef.Y:= FCurrentMargin.B-SpaceHeight; + FFooterHeight:= FFooterHeight+SpaceHeight; + PosV:= FPosRef.Y; + ShiftFooterLines(SpaceHeight); + LoadSpaceFooter(PosV,Column,SpaceHeight,BkColorNum); + end; + end; + if FGroup + then + LoadSpaceGroup(SpaceHeight); + Result:= Pixels2Dim(FPosRef.Y); + LineEnd(Zone); + end; + ppVisualize: + with FCanvas,T_Column(Columns[Column]) do + begin + if BkColorNum> -1 + then + SetColor(T_BackColor(BackColors[BkColorNum]).GetColor) + else + SetColor(GetColor); + FillRectangle(Round(ColPos),Round(PosV),Round(ColWidth),Round(SpaceHeight)); + end; + ppPdfFile: + begin + if Column> -1 + then + with T_Column(Columns[Column]) do + begin + if (GetColor<> clWhite) or (BkColorNum> -1) + then + begin + PdfRect:= TPdfRect.Create; + with PdfRect do + begin + PageId:= NumPage; + FLeft:= ColPos; + FBottom:= Paper.H-PosY-SpaceHeight; + FHeight:= SpaceHeight; + FWidth:= ColWidth; + if BkColorNum> -1 + then + FColor:= T_BackColor(BackColors[BkColorNum]).GetColor + else + FColor:= GetColor; + FFill:= True; + FStroke:= False; + end; + PdfPage.Add(PdfRect); + end; + end; + end; + end; + end; +end; + +procedure T_Report.LineEnd(Zone: TZone); +begin +with T_Section(Sections[Pred(NumSection)]) do + case Zone of + zHeader: + LoadCmdHeader; + zPage: + if FGroup + then + LoadCmdGroup + else + LoadCmdPage; + zFooter: + LoadCmdFooter; + end; +end; + +procedure T_Report.DrawAFrame(StyLine: Integer; Zone: TZone); +var + Half,MarginL,MarginR,MarginT,MarginB,HeaderH,FooterH: Integer; +begin +with T_Section(Sections[Pred(NumSection)]) do + case FPreparation of + ppPrepare: + LoadFrame(StyLine,Zone); + ppVisualize: + with FCanvas do + begin + with T_LineStyle(LineStyles[StyLine]) do + begin + SetLineStyle(Round(GetThick),GetStyle); + Half:= Round(GetThick) div 2; + SetColor(GetColor); + end; + with FCurrentMargin do + begin + MarginL:= Round(L); + MarginR:= Round(R); + MarginT:= Round(T); + MarginB:= Round(B); + HeaderH:= Round(FHeaderHeight); + FooterH:= Round(FFooterHeight); + case Zone of + zHeader: + begin + DrawLine(MarginL+Half,MarginT,MarginL+Half,MarginT+HeaderH); // left + DrawLine(MarginR-Half,MarginT,MarginR-Half,MarginT+HeaderH); // right + DrawLine(MarginL,MarginT+Half,MarginR,MarginT+Half); // top + DrawLine(MarginL,MarginT+HeaderH-Half,MarginR,MarginT+HeaderH-Half); // bottom + end; + zPage: + begin + DrawLine(MarginL+Half,MarginT+HeaderH,MarginL+Half,MarginB-FooterH); // left + DrawLine(MarginR-Half,MarginT+HeaderH,MarginR-Half,MarginB-FooterH); // right + DrawLine(MarginL,MarginT+HeaderH-Half,MarginR,MarginT+HeaderH-Half); // top + DrawLine(MarginL,MarginB-FooterH+Half,MarginR,MarginB-FooterH+Half); // bottom + end; + zFooter: + begin + DrawLine(MarginL+Half,MarginB-FooterH,MarginL+Half,MarginB); // left + DrawLine(MarginR-Half,MarginB-FooterH,MarginR-Half,MarginB); // right + DrawLine(MarginL,MarginB-FooterH+Half,MarginR,MarginB-FooterH+Half); // top + DrawLine(MarginL,MarginB-Half,MarginR,MarginB-Half); // bottom + end; + zMargins: + begin + DrawLine(MarginL+Half,MarginT,MarginL+Half,MarginB-Succ(Half)); // left + DrawLine(MarginR-Half,MarginT,MarginR-Half,MarginB-Succ(Half)); // right + DrawLine(MarginL,MarginT+Half,MarginR,MarginT+Half); // top + DrawLine(MarginL,MarginB-Half,MarginR,MarginB-Half); // bottom + end; + end; + end; + end; + ppPdfFile: + begin + PdfRect:= TPdfRect.Create; + with PdfRect do + begin + PageId:= NumPage; + with T_LineStyle(LineStyles[StyLine]) do + begin + FThick:= GetThick; + FColor:= GetColor; + FLineStyle:= GetStyle; + end; + with FCurrentMargin do + case Zone of + zHeader: + begin + FLeft:= L; + FBottom:= Paper.H-T-FHeaderHeight; + FHeight:= FHeaderHeight; + FWidth:= R-L; + end; + zPage: + begin + FLeft:= L; + FBottom:= Paper.H-B+FFooterHeight; + FHeight:= B-T-FHeaderHeight-FFooterHeight; + FWidth:= R-L; + end; + zFooter: + begin + FLeft:= L; + FBottom:= Paper.H-B; + FHeight:= FFooterHeight; + FWidth:= R-L; + end; + zMargins: + begin + FLeft:= L; + FBottom:= Paper.H-B; + FHeight:= B-T; + FWidth:= R-L; + end; + end; + FFill:= False; + FStroke:= True; + PdfPage.Add(PdfRect); + end; + end; + end; +end; + +procedure T_Report.DrawALine(XBegin,YBegin,XEnd,YEnd: Single; StyLine: Integer); +begin +with T_Section(Sections[Pred(NumSection)]) do + case FPreparation of + ppPrepare: + LoadLine(XBegin,YBegin,ColDefaut,XEnd,YEnd,StyLine); + ppVisualize: + with FCanvas do + begin + with T_LineStyle(LineStyles[StyLine]) do + begin + SetLineStyle(Round(GetThick),GetStyle); + SetColor(GetColor); + end; + DrawLine(Round(XBegin),Round(YBegin),Round(XEnd),Round(YEnd)); + end; + ppPdfFile: + begin + PdfLine:= TPdfLine.Create; + with PdfLine do + begin + PageId:= NumPage; + FBeginX:= XBegin; + FBeginY:= Paper.H-YBegin; + FEndX:= XEnd; + FEndY:= Paper.H-YEnd; + FStyle:= T_LineStyle(LineStyles[StyLine]).GetStyle;; + FColor:= T_LineStyle(LineStyles[StyLine]).GetColor; + FThick:= T_LineStyle(LineStyles[StyLine]).GetThick; + end; + PdfPage.Add(PdfLine); + end; + end; +end; + +procedure T_Report.DrawAHorizLine(XBegin,YBegin: Single; Column: Integer; XEnd: Single; StyLine: Integer; Zone: TZone); +var + PosV: Single; +begin +with T_Section(Sections[Pred(NumSection)]) do + case FPreparation of + ppPrepare: + begin + case Zone of + zHeader: + begin + FPosRef.Y:= FCurrentMargin.T+FHeaderHeight; + PosV:= FPosRef.Y+XBegin; + FPosRef.Y:= FPosRef.Y+XBegin+YBegin+T_LineStyle(LineStyles[StyLine]).GetThick; + FHeaderHeight:= FPosRef.Y-FCurrentMargin.T; + with T_Column(Columns[Column]) do + LoadLineHorizHeader(ColPos,PosV,Column,ColPos+ColWidth,PosV,StyLine); + end; + zPage: + begin + FPosRef.Y:= FCurrentMargin.T+FHeaderHeight+FPageHeight; + PosV:= FPosRef.Y+XBegin; + FPosRef.Y:= FPosRef.Y+XBegin+YBegin+T_LineStyle(LineStyles[StyLine]).GetThick; + FPageHeight:= FPosRef.Y-FHeaderHeight-FCurrentMargin.T; + with T_Column(Columns[Column]) do + LoadLineHorizPage(ColPos,PosV,Column,ColPos+ColWidth,PosV,StyLine); + end; + zFooter: + begin + FPosRef.Y:= FCurrentMargin.B-XBegin; + PosV:= FPosRef.Y; + FPosRef.Y:= FPosRef.Y-YBegin-T_LineStyle(LineStyles[StyLine]).GetThick; + FFooterHeight:= FFooterHeight+XBegin+YBegin+T_LineStyle(LineStyles[StyLine]).GetThick; + ShiftFooterLines(XBegin+YBegin+T_LineStyle(LineStyles[StyLine]).GetThick); + with T_Column(Columns[Column]) do + LoadLineHorizFooter(ColPos,PosV,Column,ColPos+ColWidth,PosV,StyLine); + end; + end; + if FGroup + then + LoadLineHorizGroupe(T_LineStyle(LineStyles[StyLine]).GetThick); + end; + ppVisualize: + with FCanvas do + begin + with T_LineStyle(LineStyles[StyLine]) do + begin + SetLineStyle(Round(GetThick),GetStyle); + SetColor(GetColor); + end; + DrawLine(Round(XBegin),Round(YBegin),Round(XEnd),Round(YBegin)); + end; + ppPdfFile: + begin + PdfLine:= TPdfLine.Create; + with PdfLine do + begin + PageId:= NumPage; + FBeginX:= XBegin; + FBeginY:= Paper.H-YBegin; + FEndX:= XEnd; + FEndY:= Paper.H-YBegin; + FStyle:= T_LineStyle(LineStyles[StyLine]).GetStyle;; + FColor:= T_LineStyle(LineStyles[StyLine]).GetColor; + FThick:= T_LineStyle(LineStyles[StyLine]).GetThick; + end; + PdfPage.Add(PdfLine); + end; + end; +end; + +procedure T_Report.PaintSurface(Points: T_Points; Couleur: TfpgColor); +var + OldColor: TfpgColor; + Cpt: Integer; + Pts: array of TPoint; +begin +with T_Section(Sections[Pred(NumSection)]) do + case FPreparation of + ppPrepare: + LoadSurf(Points,Couleur); + ppVisualize: + begin + OldColor:= FCanvas.Color; + FCanvas.SetColor(Couleur); + SetLength(Pts,Length(Points)); + for Cpt:= 0 to Pred(Length(Pts)) do + begin + Pts[Cpt].X:= Round(Points[Cpt].X); + Pts[Cpt].Y:= Round(Points[Cpt].Y); + end; + FCanvas.DrawPolygon(Pts); + FCanvas.SetColor(OldColor); + end; + ppPdfFile: + begin + PdfSurf:= TPdfSurf.Create; + SetLength(PdfSurf.FPoints,Length(Points)); + for Cpt:= 0 to Pred(Length(Points)) do + begin + PdfSurf.FPoints[Cpt].X:= Points[Cpt].X; + PdfSurf.FPoints[Cpt].Y:= Paper.H-Points[Cpt].Y; + end; + with PdfSurf do + begin + PageId:= NumPage; + //SetLength(FPoints,Length(Points)); + //for Cpt:= 0 to Pred(Length(Points)) do // weird behaviour: points gets length= 0 inside the with clause ! + // begin + // FPoints[Cpt].X:= Points[Cpt].X; + // FPoints[Cpt].Y:= Paper.H-Points[Cpt].Y; + // end; + FColor:= Couleur; + end; + PdfPage.Add(PdfSurf); + end; + end; +end; + +procedure T_Report.PaintImage(PosX,PosY: Single; Column,ImgNum: Integer; Zone: TZone); +begin +with T_Section(Sections[Pred(NumSection)]) do + case FPreparation of + ppPrepare: + begin + if Column> -1 + then + PosX:= T_Column(Columns[Column]).ColPos+PosX; + case Zone of + zHeader: + begin + PosY:= FCurrentMargin.T+PosY; + LoadImgHeader(PosX,PosY,Column,ImgNum); + end; + zPage: + begin + PosY:= FCurrentMargin.T+FHeaderHeight+PosY; + LoadImgPage(PosX,PosY,Column,ImgNum); + end; + zFooter: + begin + PosY:= FCurrentMargin.B-FFooterHeight+PosY; + LoadImgFooter(PosX,PosY,Column,ImgNum); + end; + end; + end; + ppVisualize: + FCanvas.DrawImage(Round(PosX),Round(PosY),TfpgImage(Images[ImgNum])); + ppPdfFile: + begin + PdfImg:= TPdfImg.Create; + with PdfImg do + begin + PageId:= NumPage; + ImgNumber:= ImgNum; + ImgLeft:= PosX; + ImgBottom:= Paper.H-PosY-TfpgImage(Images[ImgNum]).Height; + ImgWidth:= TfpgImage(Images[ImgNum]).Width; + ImgHeight:= TfpgImage(Images[ImgNum]).Height; + end; + PdfPage.Add(PdfImg); + end; + end; +end; + +function T_Report.GetSectionTitle: string; +begin +Result:= T_Section(Sections[Pred(Sections.Count)]).Title; +end; + +procedure T_Report.SetSectionTitle(ATitle: string); +begin +T_Section(Sections[Pred(Sections.Count)]).Title:= ATitle; +end; + +{ public methods } + +constructor T_Report.Create; +begin +inherited Create; +OldSeparator:= DecimalSeparator; +DecimalSeparator:= '.'; +Sections:= TList.Create; +Fonts:= TList.Create; +Columns:= TList.Create; +LineSpaces:= TList.Create; +BackColors:= TList.Create; +LineStyles:= TList.Create; +Borders:= TList.Create; +Images:= TList.Create; +ImageNames:= TStringList.Create; +Texts:= TStringList.Create; +VWriteLine:= T_WriteLine.Create; +PdfPage:= TList.Create; +Outline:= False; +end; + +destructor T_Report.Destroy; +var + Cpt: Integer; +begin +if Sections.Count> 0 +then + for Cpt:= 0 to Pred(Sections.Count) do + T_Section(Sections[Cpt]).Free; +Sections.Free; +if Fonts.Count> 0 +then + for Cpt:= 0 to Pred(Fonts.Count) do + T_Font(Fonts[Cpt]).Free; +Fonts.Free; +if Columns.Count> 0 +then + for Cpt:= 0 to Pred(Columns.Count) do + T_Column(Columns[Cpt]).Free; +Columns.Free; +if LineSpaces.Count> 0 +then + for Cpt:= 0 to Pred(LineSpaces.Count) do + T_LineSpace(LineSpaces[Cpt]).Free; +LineSpaces.Free; +if BackColors.Count> 0 +then + for Cpt:= 0 to Pred(BackColors.Count) do + T_BackColor(BackColors[Cpt]).Free; +BackColors.Free; +if LineStyles.Count> 0 +then + for Cpt:= 0 to Pred(LineStyles.Count) do + T_LineStyle(LineStyles[Cpt]).Free; +LineStyles.Free; +if Borders.Count> 0 +then + for Cpt:= 0 to Pred(Borders.Count) do + T_Border(Borders[Cpt]).Free; +Borders.Free; +if Images.Count> 0 +then + for Cpt:= 0 to Pred(Images.Count) do + TfpgImage(Images[Cpt]).Free; +Images.Free; +ImageNames.Free; +Texts.Free; +VWriteLine.Free; +if PdfPage.Count> 0 +then + for Cpt:= 0 to Pred(PdfPage.Count) do + if TPdfElement(PdfPage[Cpt]) is TPdfTexte + then + TPdfTexte(PdfPage[Cpt]).Free + else + if TPdfElement(PdfPage[Cpt]) is TPdfRect + then + TPdfRect(PdfPage[Cpt]).Free + else + if TPdfElement(PdfPage[Cpt]) is TPdfLine + then + TPdfLine(PdfPage[Cpt]).Free + else + if TPdfElement(PdfPage[Cpt]) is TPdfSurf + then + TPdfSurf(PdfPage[Cpt]).Free + else + if TPdfElement(PdfPage[Cpt]) is TPdfImg + then + TPdfImg(PdfPage[Cpt]).Free; +PdfPage.Free; +DecimalSeparator:= OldSeparator; +inherited; +end; + +procedure T_Report.BeginWrite(IniOrientation: TOrient= oPortrait; IniPaperType: TPaperType= A4; + IniMeasure: TMeasureUnit= msMM; IniVersion: Char= 'F'; IniVisu: Boolean= True); +begin +FVersion:= IniVersion; +FOrientation:= IniOrientation; +FPaperType:= IniPaperType; +FMeasureUnit:= IniMeasure; +FPreparation:= ppPrepare; +FVisualization:= IniVisu; +PrepareFormat; +if IniVisu +then + CreateVisu; +FCurrentFont:= -1; +FCurrentLineSpace:= -1; +FGroup:= False; +with FPaper do + VColumn:= T_Column.Create(Printable.L,Printable.R-Printable.L,0,clWhite); +Columns.Add(VColumn); +end; + +procedure T_Report.EndWrite; +var + Cpt: Integer; +begin +FPreparation:= ppPdfFile; +if Sections.Count> 0 +then + for Cpt:= 1 to Sections.Count do + begin + NumSection:= Cpt; + if T_Section(Sections[Pred(NumSection)]).TotPages> 0 + then + begin + NumPageSection:= 1; + NumPage:= 1; + end; + end +else + Exit; +for Cpt:= 1 to T_Section(Sections[Pred(NumSection)]).TotPages do + PrintPage(Cpt); +if FVisualization +then + begin + FPreparation:= ppVisualize; + try + WriteDocument; + F_Visu.ShowModal; + finally + F_Visu.Free; + end; + end; +end; + +procedure T_Report.WriteDocument; +begin +if FVisualization +then + FCanvas:= Bv_Visu.Canvas; +end; + +procedure T_Report.PagePreview; +begin +FVisualization:= not FVisualization; +if FVisualization +then + FCanvas:= Bv_Visu.Canvas; +end; + +procedure T_Report.Section(MgLeft,MgRight,MgTop,MgBottom: Single; BackPos: Single; + IniOrientation: TOrient= oPortrait); +var + CMargin: Single; +begin +case FPreparation of + ppPrepare: + begin + FOrientation:= IniOrientation; + PrepareFormat; + with FCurrentMargin,FPaper do + begin + if Dim2Pixels(MgLeft)> Printable.L + then + L:= Dim2Pixels(MgLeft) + else + L:= Printable.L; + if (W-Dim2Pixels(MgRight))< Printable.R + then + R:= W-Dim2Pixels(MgRight) + else + R:= Printable.R; + if Dim2Pixels(MgTop)> Printable.T + then + T:= Dim2Pixels(MgTop) + else + T:= Printable.T; + if (H-Dim2Pixels(MgBottom))< Printable.B + then + B:= H-Dim2Pixels(MgBottom) + else + B:= Printable.B; + end; + FPosRef.X:= FCurrentMargin.L; + FHeaderHeight:= 0; + FPageHeight:= 0; + FFooterHeight:= 0; + NumSection:= NumSection+1; + VSection:= T_Section.Create(FPaper,FCurrentMargin,NumSection); + Sections.Add(VSection); + CMargin:= Dim2Pixels(BackPos); + VColumn:= T_Column.Create(FCurrentMargin.L,FCurrentMargin.R-FCurrentMargin.L,CMargin,clWhite); + T_Section(Sections[Pred(Sections.Count)]).DefaultCol:= Columns.Add(VColumn); + end; + end; +end; + +procedure T_Report.Page; +begin +if FPreparation= ppPrepare +then + begin + NumPage:= NumPage+1; + T_Section(Sections[Pred(Sections.Count)]).LoadPage(NumPage); + FPosRef.Y:= FCurrentMargin.T+FHeaderHeight; + FPageHeight:= 0; + end; +end; + +function T_Report.BackColor(FdColor: TfpgColor): Integer; +begin +VBackColor:= T_BackColor.Create(FdColor); +Result:= BackColors.Add(VBackColor); +end; + +function T_Report.Font(FtNom: string; FtColor: TfpgColor): Integer; +begin +VFont:= T_Font.Create(FtNom,FtColor); +Result:= Fonts.Add(VFont); +end; + +function T_Report.LineStyle(StThick: Single; StColor: Tfpgcolor; StStyle: TfpgLineStyle): Integer; +begin +VLineStyle:= T_LineStyle.Create(StThick,StColor,StStyle); +Result:= LineStyles.Add(VLineStyle); +end; + +function T_Report.Border(BdFlags: TBorderFlags; BdStyle: Integer): Integer; +begin +VBorder:= T_Border.Create(BdFlags,BdStyle); +Result:= Borders.Add(VBorder); +end; + +//function T_Report.Border(BdFlags: TBorderFlags; StFlags: array of Integer): Integer; +//begin +//VBorder:= T_Border.Create(BdFlags,BdStyle); +//Result:= Borders.Add(VBorder); +//end; + +function T_Report.Column(ClnPos,ClnWidth: Single; ClnMargin: Single= 0; ClnColor: TfpgColor= clWhite): Integer; +var + CPos,CWidth,CMargin: Single; +begin +CPos:= Dim2Pixels(ClnPos); +CWidth:= Dim2Pixels(ClnWidth); +CMargin:= Dim2Pixels(ClnMargin); +VColumn:= T_Column.Create(CPos,CWidth,CMargin,ClnColor); +Result:= Columns.Add(VColumn); +end; + +procedure T_Report.WriteHeader(Horiz,Verti: Single; Text: string; ColNum: Integer= 0; FontNum: Integer= 0; + LineSpNum: Integer= 0; BkColorNum: Integer= -1; BordNum: Integer= -1); +var + RefText: Integer; + Flags: TfpgTextFlags; +begin +Flags:= [txtWrap]; +if Horiz< 0 +then + begin + if Horiz= cnLeft + then + Include(Flags,txtLeft); + if Horiz= cnCenter + then + Include(Flags,txtHCenter); + if Horiz= cnRight + then + Include(Flags,txtRight); + end +else + Horiz:= Dim2Pixels(Horiz); +if Verti> 0 +then + Verti:= Dim2Pixels(Verti); +RefText:= Texts.IndexOf(Text); +if RefText= -1 +then + RefText:= Texts.Add(Text); +WriteText(Horiz,Verti,ColNum,RefText,FontNum,BkColorNum,BordNum,LineSpNum,Flags,zHeader); +end; + +function T_Report.WritePage(Horiz,Verti: Single; Text: string; ColNum: Integer= 0; FontNum: Integer= 0; + LineSpNum: Integer= 0; BkColorNum: Integer= -1; BordNum: Integer= -1): Single; +var + RefText: Integer; + Flags: TfpgTextFlags; +begin +Flags:= [txtWrap]; +if Horiz< 0 +then + begin + if Horiz= cnLeft + then + Include(Flags,txtLeft); + if Horiz= cnCenter + then + Include(Flags,txtHCenter); + if Horiz= cnRight + then + Include(Flags,txtRight); + end +else + Horiz:= Dim2Pixels(Horiz); +if Verti> 0 +then + Verti:= Dim2Pixels(Verti); +RefText:= Texts.IndexOf(Text); +if RefText= -1 +then + RefText:= Texts.Add(Text); +Result:= WriteText(Horiz,Verti,ColNum,RefText,FontNum,BkColorNum,BordNum,LineSpNum,Flags,ZPage); +end; + +procedure T_Report.WriteFooter(Horiz,Verti: Single; Text: string; ColNum: Integer= 0; FontNum: Integer= 0; + LineSpNum: Integer= 0; BkColorNum: Integer= -1; BordNum: Integer= -1); +var + RefText: Integer; + Flags: TfpgTextFlags; +begin +Flags:= [txtWrap]; +if Horiz< 0 +then + begin + if Horiz= cnLeft + then + Include(Flags,txtLeft); + if Horiz= cnCenter + then + Include(Flags,txtHCenter); + if Horiz= cnRight + then + Include(Flags,txtRight); + end +else + Horiz:= Dim2Pixels(Horiz); +if Verti> 0 +then + Verti:= Dim2Pixels(Verti); +RefText:= Texts.IndexOf(Text); +if RefText= -1 +then + RefText:= Texts.Add(Text); +WriteText(Horiz,Verti,ColNum,RefText,FontNum,BkColorNum,BordNum,LineSpNum,Flags,zFooter); +end; + +procedure T_Report.NumSectionHeader(Horiz,Verti: Single; TexteSect: string= ''; TextTot: string= ''; + Total: Boolean= False; Alpha: Boolean= False; ColNum: Integer= 0; FontNum: Integer= 0; + LineSpNum: Integer= 0; BkColorNum: Integer= -1; BordNum: Integer= -1); +var + RefTextPage,RefTextTot: Integer; + Flags: TfpgTextFlags; +begin +Flags:= []; +if Horiz< 0 +then + begin + if Horiz= cnLeft + then + Include(Flags,txtLeft); + if Horiz= cnCenter + then + Include(Flags,txtHCenter); + if Horiz= cnRight + then + Include(Flags,txtRight); + end +else + Horiz:= Dim2Pixels(Horiz); +if Verti> 0 +then + Verti:= Dim2Pixels(Verti); +RefTextPage:= Texts.IndexOf(TexteSect); +if RefTextPage= -1 +then + RefTextPage:= Texts.Add(TexteSect); +RefTextTot:= Texts.IndexOf(TextTot); +if RefTextTot= -1 +then + RefTextTot:= Texts.Add(TextTot); +WriteNumber(Horiz,Verti,ColNum,RefTextPage,RefTextTot,FontNum,BkColorNum,BordNum,LineSpNum,Flags,Total,Alpha,zHeader,SectNum); +end; + +procedure T_Report.NumSectionFooter(Horiz,Verti: Single; TexteSect: string= ''; TextTot: string= ''; + Total: Boolean= False; Alpha: Boolean= False; ColNum: Integer= 0; FontNum: Integer= 0; + LineSpNum: Integer= 0;BkColorNum: Integer= -1; BordNum: Integer= -1); +var + RefTextPage,RefTextTot: Integer; + Flags: TfpgTextFlags; +begin +Flags:= []; +if Horiz< 0 +then + begin + if Horiz= cnLeft + then + Include(Flags,txtLeft); + if Horiz= cnCenter + then + Include(Flags,txtHCenter); + if Horiz= cnRight + then + Include(Flags,txtRight); + end +else + Horiz:= Dim2Pixels(Horiz); +if Verti> 0 +then + Verti:= Dim2Pixels(Verti); +RefTextPage:= Texts.IndexOf(TexteSect); +if RefTextPage= -1 +then + RefTextPage:= Texts.Add(TexteSect); +RefTextTot:= Texts.IndexOf(TextTot); +if RefTextTot= -1 +then + RefTextTot:= Texts.Add(TextTot); +WriteNumber(Horiz,Verti,ColNum,RefTextPage,RefTextTot,FontNum,BkColorNum,BordNum,LineSpNum,Flags,Total,Alpha,zFooter,SectNum); +end; + +procedure T_Report.NumPageHeader(Horiz,Verti: Single; TextePage: string= ''; TextTot: string= ''; + Total: Boolean= False; ColNum: Integer= 0; FontNum: Integer= 0; LineSpNum: Integer= 0; + BkColorNum: Integer= -1; BordNum: Integer= -1); +var + RefTextPage,RefTextTot: Integer; + Flags: TfpgTextFlags; +begin +Flags:= []; +if Horiz< 0 +then + begin + if Horiz= cnLeft + then + Include(Flags,txtLeft); + if Horiz= cnCenter + then + Include(Flags,txtHCenter); + if Horiz= cnRight + then + Include(Flags,txtRight); + end +else + Horiz:= Dim2Pixels(Horiz); +if Verti> 0 +then + Verti:= Dim2Pixels(Verti); +RefTextPage:= Texts.IndexOf(TextePage); +if RefTextPage= -1 +then + RefTextPage:= Texts.Add(TextePage); +RefTextTot:= Texts.IndexOf(TextTot); +if RefTextTot= -1 +then + RefTextTot:= Texts.Add(TextTot); +WriteNumber(Horiz,Verti,ColNum,RefTextPage,RefTextTot,FontNum,BkColorNum,BordNum,LineSpNum,Flags,Total,False,zHeader,PageNum); +end; + +procedure T_Report.NumPageFooter(Horiz,Verti: Single; TextePage: string= ''; TextTot: string= ''; + Total: Boolean= False; ColNum: Integer= 0; FontNum: Integer= 0; LineSpNum: Integer= 0; + BkColorNum: Integer= -1; BordNum: Integer= -1); +var + RefTextPage,RefTextTot: Integer; + Flags: TfpgTextFlags; +begin +Flags:= []; +if Horiz< 0 +then + begin + if Horiz= cnLeft + then + Include(Flags,txtLeft); + if Horiz= cnCenter + then + Include(Flags,txtHCenter); + if Horiz= cnRight + then + Include(Flags,txtRight); + end +else + Horiz:= Dim2Pixels(Horiz); +if Verti> 0 +then + Verti:= Dim2Pixels(Verti); +RefTextPage:= Texts.IndexOf(TextePage); +if RefTextPage= -1 +then + RefTextPage:= Texts.Add(TextePage); +RefTextTot:= Texts.IndexOf(TextTot); +if RefTextTot= -1 +then + RefTextTot:= Texts.Add(TextTot); +WriteNumber(Horiz,Verti,ColNum,RefTextPage,RefTextTot,FontNum,BkColorNum,BordNum,LineSpNum,Flags,Total,False,zFooter,PageNum); +end; + +procedure T_Report.NumPageSectionHeader(Horiz,Verti: Single; TexteSect: string= ''; TextTot: string= ''; + Total: Boolean= False; Alpha: Boolean= False; ColNum: Integer= 0; FontNum: Integer= 0; + LineSpNum: Integer= 0; BkColorNum: Integer= -1; BordNum: Integer= -1); +var + RefTextPage,RefTextTot: Integer; + Flags: TfpgTextFlags; +begin +Flags:= []; +if Horiz< 0 +then + begin + if Horiz= cnLeft + then + Include(Flags,txtLeft); + if Horiz= cnCenter + then + Include(Flags,txtHCenter); + if Horiz= cnRight + then + Include(Flags,txtRight); + end +else + Horiz:= Dim2Pixels(Horiz); +if Verti> 0 +then + Verti:= Dim2Pixels(Verti); +RefTextPage:= Texts.IndexOf(TexteSect); +if RefTextPage= -1 +then + RefTextPage:= Texts.Add(TexteSect); +RefTextTot:= Texts.IndexOf(TextTot); +if RefTextTot= -1 +then + RefTextTot:= Texts.Add(TextTot); +WriteNumber(Horiz,Verti,ColNum,RefTextPage,RefTextTot,FontNum,BkColorNum,BordNum,LineSpNum,Flags,Total,Alpha,zHeader,PSectNum); +end; + +procedure T_Report.NumPageSectionFooter(Horiz,Verti: Single; TexteSect: string= ''; TextTot: string= ''; + Total: Boolean= False; Alpha: Boolean= False; ColNum: Integer= 0; FontNum: Integer= 0; + LineSpNum: Integer= 0; BkColorNum: Integer= -1; BordNum: Integer= -1); +var + RefTextPage,RefTextTot: Integer; + Flags: TfpgTextFlags; +begin +Flags:= []; +if Horiz< 0 +then + begin + if Horiz= cnLeft + then + Include(Flags,txtLeft); + if Horiz= cnCenter + then + Include(Flags,txtHCenter); + if Horiz= cnRight + then + Include(Flags,txtRight); + end +else + Horiz:= Dim2Pixels(Horiz); +if Verti> 0 +then + Verti:= Dim2Pixels(Verti); +RefTextPage:= Texts.IndexOf(TexteSect); +if RefTextPage= -1 +then + RefTextPage:= Texts.Add(TexteSect); +RefTextTot:= Texts.IndexOf(TextTot); +if RefTextTot= -1 +then + RefTextTot:= Texts.Add(TextTot); +WriteNumber(Horiz,Verti,ColNum,RefTextPage,RefTextTot,FontNum,BkColorNum,BordNum,LineSpNum,Flags,Total,Alpha,zFooter,PSectNum); +end; + +procedure T_Report.HorizLineHeader(SpBefore,SpAfter: Single; ColNum: Integer= 0; StyleNum: Integer= 0); +begin +DrawAHorizLine(Dim2Pixels(SpBefore),Dim2Pixels(SpAfter),ColNum,-1,StyleNum,zHeader); +end; + +procedure T_Report.HorizLinePage(SpBefore,SpAfter: Single; ColNum: Integer= 0; StyleNum: Integer= 0); +begin +DrawAHorizLine(Dim2Pixels(SpBefore),Dim2Pixels(SpAfter),ColNum,-1,StyleNum,zPage); +end; + +procedure T_Report.HorizLineFooter(SpBefore,SpAfter: Single; ColNum: Integer= 0; StyleNum: Integer= 0); +begin +DrawAHorizLine(Dim2Pixels(SpBefore),Dim2Pixels(SpAfter),ColNum,-1,StyleNum,zFooter); +end; + +procedure T_Report.SpaceHeader(Verti: Single; ColNum: Integer= 0; BkColorNum: Integer= -1); +begin +InsertSpace(-1,ColNum,Dim2Pixels(Verti),BkColorNum,zHeader); +end; + +procedure T_Report.SpacePage(Verti: Single; ColNum: Integer= 0; BkColorNum: Integer= -1); +begin +InsertSpace(-1,ColNum,Dim2Pixels(Verti),BkColorNum,zPage); +end; + +procedure T_Report.SpaceFooter(Verti: Single; ColNum: Integer= 0; BkColorNum: Integer= -1); +begin +InsertSpace(-1,ColNum,Dim2Pixels(Verti),BkColorNum,zFooter); +end; + +function T_Report.LineSpace(SpSup,SpInt,SpInf: Single): Integer; +var + Sup,Int,Inf: Integer; +begin +if SpSup> 0 +then + Sup:= Round(Dim2Pixels(SpSup)) +else + Sup:= 0; +if SpInt> 0 +then + Int:= Round(Dim2Pixels(SpInt)) +else + Int:= 0; +if SpInf> 0 +then + Inf:= Round(Dim2Pixels(SpInf)) +else + Inf:= 0; +VLineSpace:= T_LineSpace.Create(Sup,Int,Inf); +Result:= LineSpaces.Add(VLineSpace); +end; + +procedure T_Report.BeginGroup(PageJump: Boolean= False); +begin +VGroup:= T_Group.Create; +FGroup:= True; +if PageJump +then + Page; +end; + +procedure T_Report.EndGroup(PageJump: Boolean= False); +begin +T_Section(Sections[Pred(Sections.Count)]).LoadCmdGroupToPage; +FGroup:= False; +VGroup.Free; +if PageJump +then + Page; +end; + +procedure T_Report.ColorColChange(ColNum: Integer; ColColor: TfpgColor); +begin +T_Column(Columns[ColNum]).SetColColor(ColColor); +end; + +procedure T_Report.FrameMargins(AStyle: Integer); +begin +DrawAFrame(AStyle,zMargins); +end; + +procedure T_Report.FrameHeader(AStyle: Integer); +begin +DrawAFrame(AStyle,zHeader); +end; + +procedure T_Report.FramePage(AStyle: Integer); +begin +DrawAFrame(AStyle,zPage); +end; + +procedure T_Report.FrameFooter(AStyle: Integer); +begin +DrawAFrame(AStyle,zFooter); +end; + +procedure T_Report.LinePage(XBegin,YBegin,XEnd,YEnd: Single; AStyle: Integer); +begin +DrawALine(Dim2Pixels(XBegin),Dim2Pixels(YBegin),Dim2Pixels(XEnd),Dim2Pixels(YEnd),AStyle); +end; + +procedure T_Report.SurfPage(XLimits,YLimits: array of Single; AColor: TfpgColor); +var + Size,Cpt: Integer; + Ends: array of TRefPos; +begin +if Length(XLimits)< Length(YLimits) +then + Size:= Length(XLimits) +else + if Length(XLimits)> Length(YLimits) + then + Size:= Length(YLimits) + else + Size:= Length(XLimits); +SetLength(Ends,Size); +for Cpt:= 0 to Pred(Size) do + begin + Ends[Cpt].X:= Dim2Pixels(XLimits[Cpt]); + Ends[Cpt].Y:= Dim2Pixels(YLimits[Cpt]); + end; +PaintSurface(Ends,AColor); +end; + +procedure T_Report.ImageHeader(Horiz,Verti: Single; ImgFileName: string; ColNum,Scale: Integer); +var + RefImage: Integer; + Image: TfpgImage; +begin +Horiz:= Dim2Pixels(Horiz); +Verti:= Dim2Pixels(Verti); +if FileExists(ImgFileName) +then + begin + RefImage:= ImageNames.IndexOf(IntToStr(Scale)+ImgFileName); + if RefImage= -1 + then + begin + if Copy(ImgFileName,Succ(Pos('.',ImgFileName)),3)= 'bmp' + then + begin + Image:= LoadImage_BMP(ImgFileName); + Scale:= 1; + end; + if (Copy(ImgFileName,Succ(Pos('.',ImgFileName)),3)= 'jpg') or (Copy(ImgFileName,Succ(Pos('.',ImgFileName)),4)= 'jpeg') + then + Image:= LoadImage_JPG(ImgFileName,Scale); + RefImage:= ImageNames.Add(IntToStr(Scale)+ImgFileName); + Images.Add(Image); + end; + PaintImage(Horiz,Verti,ColNum,RefImage,zHeader); + end +else + if fpgImages.GetImage(ImgFileName)<> nil + then + begin + RefImage:= ImageNames.IndexOf(IntToStr(Scale)+ImgFileName); + if RefImage= -1 + then + begin + Image:= fpgImages.GetImage(ImgFileName); + Scale:= 1; + RefImage:= ImageNames.Add(IntToStr(Scale)+ImgFileName); + Images.Add(Image); + end; + PaintImage(Horiz,Verti,ColNum,RefImage,zPage); + end + else + ShowMessage('Image '+ImgFileName+' is missing'); +end; + +procedure T_Report.ImagePage(Horiz,Verti: Single; ImgFileName: string; ColNum,Scale: Integer); +var + RefImage: Integer; + Image: TfpgImage; +begin +Horiz:= Dim2Pixels(Horiz); +Verti:= Dim2Pixels(Verti); +if FileExists(ImgFileName) +then + begin + RefImage:= ImageNames.IndexOf(IntToStr(Scale)+ImgFileName); + if RefImage= -1 + then + begin + if Copy(ImgFileName,Succ(Pos('.',ImgFileName)),3)= 'bmp' + then + begin + Image:= LoadImage_BMP(ImgFileName); + Scale:= 1; + end; + if (Copy(ImgFileName,Succ(Pos('.',ImgFileName)),3)= 'jpg') or (Copy(ImgFileName,Succ(Pos('.',ImgFileName)),4)= 'jpeg') + then + Image:= LoadImage_JPG(ImgFileName,Scale); + RefImage:= ImageNames.Add(IntToStr(Scale)+ImgFileName); + Images.Add(Image); + end; + PaintImage(Horiz,Verti,ColNum,RefImage,zPage); + end +else + if fpgImages.GetImage(ImgFileName)<> nil + then + begin + RefImage:= ImageNames.IndexOf(IntToStr(Scale)+ImgFileName); + if RefImage= -1 + then + begin + Image:= fpgImages.GetImage(ImgFileName); + Scale:= 1; + RefImage:= ImageNames.Add(IntToStr(Scale)+ImgFileName); + Images.Add(Image); + end; + PaintImage(Horiz,Verti,ColNum,RefImage,zPage); + end + else + ShowMessage('Image '+ImgFileName+' is missing'); +end; + +procedure T_Report.ImageFooter(Horiz,Verti: Single; ImgFileName: string; ColNum,Scale: Integer); +var + RefImage: Integer; + Image: TfpgImage; +begin +Horiz:= Dim2Pixels(Horiz); +Verti:= Dim2Pixels(Verti); +if FileExists(ImgFileName) +then + begin + RefImage:= ImageNames.IndexOf(IntToStr(Scale)+ImgFileName); + if RefImage= -1 + then + begin + if Copy(ImgFileName,Succ(Pos('.',ImgFileName)),3)= 'bmp' + then + begin + Image:= LoadImage_BMP(ImgFileName); + Scale:= 1; + end; + if (Copy(ImgFileName,Succ(Pos('.',ImgFileName)),3)= 'jpg') or (Copy(ImgFileName,Succ(Pos('.',ImgFileName)),4)= 'jpeg') + then + Image:= LoadImage_JPG(ImgFileName,Scale); + RefImage:= ImageNames.Add(IntToStr(Scale)+ImgFileName); + Images.Add(Image); + end; + PaintImage(Horiz,Verti,ColNum,RefImage,zFooter); + end +else + if fpgImages.GetImage(ImgFileName)<> nil + then + begin + RefImage:= ImageNames.IndexOf(IntToStr(Scale)+ImgFileName); + if RefImage= -1 + then + begin + Image:= fpgImages.GetImage(ImgFileName); + Scale:= 1; + RefImage:= ImageNames.Add(IntToStr(Scale)+ImgFileName); + Images.Add(Image); + end; + PaintImage(Horiz,Verti,ColNum,RefImage,zPage); + end + else + ShowMessage('Image '+ImgFileName+' is missing'); +end; + +end. + diff --git a/src/reportengine/u_reportimages.pas b/src/reportengine/u_reportimages.pas new file mode 100644 index 00000000..e7d69b92 --- /dev/null +++ b/src/reportengine/u_reportimages.pas @@ -0,0 +1,181 @@ +{ + << Impressions >> U_ReportImages.pas + + Copyright (C) 2010 - Jean-Marc Levecque <jean-marc.levecque@jmlesite.fr> + + This library is a free software coming as a add-on to fpGUI toolkit + See the copyright included in the fpGUI distribution for details about redistribution + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Description: + This unit contains the images used by the preview dialog +} + +unit U_ReportImages; + +{$mode objfpc} + +interface + +uses + fpg_main; + +procedure CreateReportImages; +function DeleteReportImages: Boolean; + +implementation + +const + repimg_Fin : Array[0..245] of byte = ( + 66, 77,246, 0, 0, 0, 0, 0, 0, 0,118, 0, 0, 0, 40, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 1, 0, 4, 0, 0, 0, 0, 0, + 128, 0, 0, 0, 18, 11, 0, 0, 18, 11, 0, 0, 0, 0, 0, 0, 16, + 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0,128, 0, 0, 0,128, + 128, 0,128, 0, 0, 0,128, 0,128, 0,128,128, 0, 0,192,192,192, + 0,128,128,128, 0, 0, 0,255, 0, 0,255, 0, 0, 0,255,255, 0, + 255, 0, 0, 0,255, 0,255, 0,255,255, 0, 0,255,255,255, 0,119, + 119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, + 119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,113, + 119,119,116, 71,119,119,119,113, 23,119,116, 71,119,119,119,113, 17, + 119,116, 71,119,119,119,113, 17, 23,116, 71,119,119,119,113, 17, 17, + 116, 71,119,119,119,113, 17, 23,116, 71,119,119,119,113, 17,119,116, + 71,119,119,119,113, 23,119,116, 71,119,119,119,113,119,119,116, 71, + 119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, + 119,119,119,119,119,119,119,119); + +const + repimg_Imprimante : Array[0..357] of byte = ( + 66, 77,102, 1, 0, 0, 0, 0, 0, 0,118, 0, 0, 0, 40, 0, 0, + 0, 20, 0, 0, 0, 20, 0, 0, 0, 1, 0, 4, 0, 0, 0, 0, 0, + 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0,128, 0, 0, 0,128, + 128, 0,128, 0, 0, 0,128, 0,128, 0,128,128, 0, 0,192,192,192, + 0,128,128,128, 0, 0, 0,255, 0, 0,255, 0, 0, 0,255,255, 0, + 255, 0, 0, 0,255, 0,255, 0,255,255, 0, 0,255,255,255, 0, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 0, 0, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 0, 0, 51, 0, 3, 51, 51, 51, 51, 48, 0, 51, 0, + 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 48,247,119,119, + 119,119,119,119,119, 3, 0, 0, 48,247,119,119,119,119,119,119,119, + 3, 0, 0, 48,247,119,119,119,119,119,153,119, 3, 0, 0, 48,255, + 255,255,255,255,255,255,255, 3, 0, 0, 56, 0,136,136,136,136,136, + 136, 0,131, 0, 0, 51, 48, 0, 0, 0, 0, 0, 0, 3, 51, 0, 0, + 51, 48,136,136,136,136,136,136, 3, 51, 0, 0, 51, 48, 0, 0, 0, + 0, 0, 0, 3, 51, 0, 0, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 0, 0, 51, 51, 51, 51, 51, 51, 56, 0, 8, 51, 0, 0, 51, 51, 51, + 51, 51, 51, 48,239,224, 51, 0, 0, 51, 56, 0, 0, 0, 0, 14,240, + 8, 51, 0, 0, 51, 48,224,239,239,239, 63,224, 51, 51, 0, 0, 51, + 56, 0, 0, 0, 0, 14,240, 8, 51, 0, 0, 51, 51, 51, 51, 51, 51, + 48,239,224, 51, 0, 0, 51, 51, 51, 51, 51, 51, 56, 0, 8, 51, 0, + 0); + +const + repimg_Precedent : Array[0..245] of byte = ( + 66, 77,246, 0, 0, 0, 0, 0, 0, 0,118, 0, 0, 0, 40, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 1, 0, 4, 0, 0, 0, 0, 0, + 128, 0, 0, 0, 18, 11, 0, 0, 18, 11, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0,128, 0, 0, 0,128, + 128, 0,128, 0, 0, 0,128, 0,128, 0,128,128, 0, 0,128,128,128, + 0,192,192,192, 0, 0, 0,255, 0,192,192,192, 0, 0,255,255, 0, + 255, 0, 0, 0,192,192,192, 0,255,255, 0, 0,255,255,255, 0,218, + 218,218,218,218,218,218,218,173,173,173,173,173,173,173,173,218,218, + 218,218,218,218,218,218,173,173,173,173,173,173,173,173,218,218,218, + 218,209,218,218,218,173,173,173,173, 17,173,173,173,218,218,218,209, + 17,218,218,218,173,173,173, 17, 17,173,173,173,218,218,209, 17, 17, + 218,218,218,173,173,173, 17, 17,173,173,173,218,218,218,209, 17,218, + 218,218,173,173,173,173, 17,173,173,173,218,218,218,218,209,218,218, + 218,173,173,173,173,173,173,173,173,218,218,218,218,218,218,218,218, + 173,173,173,173,173,173,173,173); + +const + repimg_Stop : Array[0..245] of byte = ( + 66, 77,246, 0, 0, 0, 0, 0, 0, 0,118, 0, 0, 0, 40, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 1, 0, 4, 0, 0, 0, 0, 0, + 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0,128, 0, 0, 0,128, + 128, 0,128, 0, 0, 0,128, 0,128, 0,128,128, 0, 0,192,192,192, + 0,128,128,128, 0, 0, 0,255, 0, 0,255, 0, 0, 0,255,255, 0, + 255, 0, 0, 0,255, 0,255, 0,255,255, 0, 0,255,255,255, 0, 51, + 35,153,153,153,153, 34, 35, 51, 41,153,153,153,153,147, 51, 50,153, + 153,153,153,153,153, 51, 41,153,153,153,153,153,153,147,153,255,153, + 249,159,153,249,153,159,153,249,249,249,249,249,153,153,153,249,249, + 249,249,249,153,153,159,153,249,249,249,255,153,153,249,153,249,249, + 249,249,249,159,153,153,249,249,249,249,249,159,153,249,249,249,249, + 249,249,153,255,159,255,159,153,255,153, 57,153,153,153,153,153,153, + 147, 51,153,153,153,153,153,153, 51, 51, 57,153,153,153,153,147, 51, + 51, 51,153,153,153,153, 51, 51); + +const + repimg_Suivant : Array[0..245] of byte = ( + 66, 77,246, 0, 0, 0, 0, 0, 0, 0,118, 0, 0, 0, 40, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 1, 0, 4, 0, 0, 0, 0, 0, + 128, 0, 0, 0, 18, 11, 0, 0, 18, 11, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0,128, 0, 0, 0,128, + 128, 0,128, 0, 0, 0,128, 0,128, 0,128,128, 0, 0,128,128,128, + 0,192,192,192, 0, 0, 0,255, 0,192,192,192, 0, 0,255,255, 0, + 255, 0, 0, 0,192,192,192, 0,255,255, 0, 0,255,255,255, 0,218, + 218,218,218,218,218,218,218,173,173,173,173,173,173,173,173,218,218, + 218,218,218,218,218,218,173,173,173,173,173,173,173,173,218,218,218, + 26,218,218,218,218,173,173,173, 17,173,173,173,173,218,218,218, 17, + 26,218,218,218,173,173,173, 17, 17,173,173,173,218,218,218, 17, 17, + 26,218,218,173,173,173, 17, 17,173,173,173,218,218,218, 17, 26,218, + 218,218,173,173,173, 17,173,173,173,173,218,218,218, 26,218,218,218, + 218,173,173,173,173,173,173,173,173,218,218,218,218,218,218,218,218, + 173,173,173,173,173,173,173,173); + +const + repimg_Debut : Array[0..245] of byte = ( + 66, 77,246, 0, 0, 0, 0, 0, 0, 0,118, 0, 0, 0, 40, 0, 0, + 0, 16, 0, 0, 0, 16, 0, 0, 0, 1, 0, 4, 0, 0, 0, 0, 0, + 128, 0, 0, 0, 18, 11, 0, 0, 18, 11, 0, 0, 0, 0, 0, 0, 16, + 0, 0, 0, 0, 0, 0, 0, 0, 0,128, 0, 0,128, 0, 0, 0,128, + 128, 0,128, 0, 0, 0,128, 0,128, 0,128,128, 0, 0,192,192,192, + 0,128,128,128, 0, 0, 0,255, 0, 0,255, 0, 0, 0,255,255, 0, + 255, 0, 0, 0,255, 0,255, 0,255,255, 0, 0,255,255,255, 0,119, + 119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, + 119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, 68, + 119,119,113,119,119,119,119, 68,119,119, 17,119,119,119,119, 68,119, + 113, 17,119,119,119,119, 68,119, 17, 17,119,119,119,119, 68,113, 17, + 17,119,119,119,119, 68,119, 17, 17,119,119,119,119, 68,119,113, 17, + 119,119,119,119, 68,119,119, 17,119,119,119,119, 68,119,119,113,119, + 119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, + 119,119,119,119,119,119,119,119); + +procedure CreateReportImages; +begin + + fpgImages.AddMaskedBMP('repimg.Last',@repimg_Fin,sizeof(repimg_Fin),0,0); + + fpgImages.AddMaskedBMP('repimg.Printer',@repimg_Imprimante,sizeof(repimg_Imprimante),0,0); + + fpgImages.AddMaskedBMP('repimg.Precedent',@repimg_Precedent,sizeof(repimg_Precedent),0,0); + + fpgImages.AddMaskedBMP('repimg.Stop',@repimg_Stop,sizeof(repimg_Stop),0,0); + + fpgImages.AddMaskedBMP('repimg.Next',@repimg_Suivant,sizeof(repimg_Suivant),0,0); + + fpgImages.AddMaskedBMP('repimg.First',@repimg_Debut,sizeof(repimg_Debut),0,0); + +end; + +function DeleteReportImages: Boolean; +begin + + fpgImages.DeleteImage('repimg.Last',True); + + fpgImages.DeleteImage('repimg.Printer',True); + + fpgImages.DeleteImage('repimg.Precedent',True); + + fpgImages.DeleteImage('repimg.Stop',True); + + fpgImages.DeleteImage('repimg.Next',True); + + fpgImages.DeleteImage('repimg.First',True); + +end; + +end. + diff --git a/src/reportengine/u_visu.pas b/src/reportengine/u_visu.pas new file mode 100644 index 00000000..80038a1a --- /dev/null +++ b/src/reportengine/u_visu.pas @@ -0,0 +1,538 @@ +{ + << Impressions >> U_Visu.pas + + Copyright (C) 2010 - Jean-Marc Levecque <jean-marc.levecque@jmlesite.fr> + + This library is a free software coming as a add-on to fpGUI toolkit + See the copyright included in the fpGUI distribution for details about redistribution + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + Description: + This unit is the preview form +} + +unit U_Visu; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, + {$ifdef win32} + shellapi, + {$endif} + fpg_base, fpg_main, + fpg_form, fpg_panel, fpg_label, fpg_button, fpg_edit, fpg_dialogs, fpg_utils, + U_Report; + +type + TF_Visu = class(TfpgForm) + private + FReport: T_Report; + Bv_Command: TfpgBevel; + Bt_Close: TfpgButton; + Bt_Print: TfpgButton; + Bt_Printer: TfpgButton; + Bt_Stop: TfpgButton; + Bt_Pdf: TfpgButton; + Bv_Pages: TfpgBevel; + L_Pages: TfpgLabel; + Bt_FirstPage: TfpgButton; + Bt_PrecPage: TfpgButton; + E_NumPage: TfpgEditInteger; + Bt_NextPage: TfpgButton; + Bt_LastPage: TfpgButton; + L_FromPage: Tfpglabel; + L_NbrPages: TfpgLabel; + Bv_Sections: TfpgBevel; + L_Sections: TfpgLabel; + Bt_PrecSect: TfpgButton; + E_NumSect: TfpgEditInteger; + Bt_NextSect: TfpgButton; + L_FromSect: Tfpglabel; + L_NbrSect: TfpgLabel; + L_PageSect: Tfpglabel; + L_NumPageSect: Tfpglabel; + L_FromPageSect: TfpgLabel; + L_NbrPageSect: TfpgLabel; + procedure FormShow(Sender: TObject); + procedure Bt_CloseClick(Sender: TObject); + procedure Bt_PrintClick(Sender: TObject); + procedure Bt_PrinterClick(Sender: TObject); + procedure Bt_StopClick(Sender: TObject); + procedure Bt_PdfClick(Sender: TObject); + procedure Bt_FirstPageClick(Sender: TObject); + procedure Bt_PrecPageClick(Sender: TObject); + procedure Bt_NextPageClick(Sender: TObject); + procedure Bt_LastPageClick(Sender: TObject); + procedure Bt_PrecSectClick(Sender: TObject); + procedure Bt_NextSectClick(Sender: TObject); + procedure E_NumPageKeyPress(Sender: TObject; var KeyCode: word; var ShiftState: TShiftState; + var Consumed: boolean); + procedure E_NumSectKeyPress(Sender: TObject; var KeyCode: word; var ShiftState: TShiftState; + var Consumed: boolean); + procedure ChangeButtons; + public + constructor Create(AOwner: TComponent; AImprime: T_Report); reintroduce; + destructor Destroy; override; + end; + +var + F_Visu: TF_Visu; + Bv_Visu: TfpgBevel; + +implementation + +uses + U_Command, U_Pdf, U_ReportImages; + +procedure TF_Visu.FormShow(Sender: TObject); +begin +L_Pages.Text:= 'Page'; +L_Sections.Text:= 'Section'; +L_PageSect.Text:= 'Page'; +L_FromPage.Text:= 'of'; +with FReport do + begin + if Sections.Count= 1 + then + E_NumSect.Focusable:= False; + if T_Section(Sections[Pred(Sections.Count)]).TotPages= 1 + then + E_NumPage.Focusable:= False; + E_NumPage.Text:= IntToStr(NumPage); + L_NbrPages.Text:= IntToStr(T_Section(Sections[Pred(Sections.Count)]).TotPages); + E_NumSect.Text:= IntToStr(NumSection); + L_NbrSect.Text:= IntToStr(Sections.Count); + L_NumPageSect.Text:= IntToStr(NumPageSection); + L_NbrPageSect.Text:= IntToStr(T_Section(Sections[Pred(NumSection)]).NbPages); + ChangeButtons; + end; +end; + +procedure TF_Visu.Bt_CloseClick(Sender: TObject); +begin +Close; +end; + +procedure TF_Visu.Bt_PrintClick(Sender: TObject); +begin +end; + +procedure TF_Visu.Bt_PrinterClick(Sender: TObject); +begin +end; + +procedure TF_Visu.Bt_StopClick(Sender: TObject); +begin +end; + +procedure TF_Visu.Bt_PdfClick(Sender: TObject); +var + Fd_SavePdf: TfpgFileDialog; + PdfFile: string; + PdfFileStream: TFileStream; +begin +Fd_SavePdf:= TfpgFileDialog.Create(nil); +Fd_SavePdf.InitialDir:= ExtractFilePath(Paramstr(0)); +Fd_SavePdf.FontDesc:= 'bitstream vera sans-9'; +Fd_SavePdf.Filter:= 'Fichiers pdf |*.pdf'; +Fd_SavePdf.FileName:= FReport.DefaultFile; +try + if Fd_SavePdf.RunSaveFile + then + begin + PdfFile:= Fd_SavePdf.FileName; + if Lowercase(Copy(PdfFile,Length(PdfFile)-3,4))<> '.pdf' + then + PdfFile:= PdfFile+'.pdf'; + Document:= TPdfDocument.CreateDocument; + with Document do + begin + PdfFileStream:= TFileStream.Create(PdfFile,fmCreate); + WriteDocument(PdfFileStream); + PdfFileStream.Free; + Free; + end; +{$ifdef linux} + fpgOpenURL(PdfFile); +{$endif} +{$ifdef win32} + ShellExecute(0,PChar('OPEN'),PChar(PdfFile),PChar(''),PChar(''),1); +{$endif} + end; +finally + Fd_SavePdf.Free; + end; +end; + +procedure TF_Visu.Bt_FirstPageClick(Sender: TObject); +begin +with FReport do + begin + NumPage:= 1; + NumSection:= 1; + NumPageSection:= 1; + E_NumPage.Text:= IntToStr(NumPage); + Bv_Visu.Visible:= False; + with T_Section(Sections[Pred(NumSection)]),F_Visu do + begin + Bv_Visu.Height:= Paper.H; + Bv_Visu.Width:= Paper.W; + Bv_Visu.Top:= 50+(F_Visu.Height-50-Paper.H) div 2; + Bv_Visu.Left:= (F_Visu.Width-Paper.W) div 2; + end; + Bv_Visu.Visible:= True; + ChangeButtons; + E_NumSect.Text:= IntToStr(NumSection); + L_NumPageSect.Text:= IntToStr(NumPageSection); + L_NbrPageSect.Text:= IntToStr(T_Section(Sections[Pred(NumSection)]).NbPages); + end; +end; + +procedure TF_Visu.Bt_PrecPageClick(Sender: TObject); +begin +with FReport do + begin + NumPage:= NumPage-1; + if NumPageSection= 1 + then + begin + NumSection:= NumSection-1; + NumPageSection:= T_Section(Sections[Pred(NumSection)]).NbPages; + Bv_Visu.Visible:= False; + with T_Section(Sections[Pred(NumSection)]),F_Visu do + begin + Bv_Visu.Height:= Paper.H; + Bv_Visu.Width:= Paper.W; + Bv_Visu.Top:= 50+(F_Visu.Height-50-Paper.H) div 2; + Bv_Visu.Left:= (F_Visu.Width-Paper.W) div 2; + end; + Bv_Visu.Visible:= True; + end + else + begin + NumPageSection:= NumPageSection-1; + Bv_Visu.Invalidate; + end; + E_NumPage.Text:= IntToStr(NumPage); + ChangeButtons; + E_NumSect.Text:= IntToStr(NumSection); + L_NumPageSect.Text:= IntToStr(NumPageSection); + L_NbrPageSect.Text:= IntToStr(T_Section(Sections[Pred(NumSection)]).NbPages); + end; +end; + +procedure TF_Visu.Bt_NextPageClick(Sender: TObject); +begin +with FReport do + begin + NumPage:= NumPage+1; + if NumPageSection= T_Section(Sections[Pred(NumSection)]).NbPages + then + begin + NumSection:= NumSection+1; + NumPageSection:= 1; + Bv_Visu.Visible:= False; + with T_Section(Sections[Pred(NumSection)]),F_Visu do + begin + Bv_Visu.Height:= Paper.H; + Bv_Visu.Width:= Paper.W; + Bv_Visu.Top:= 50+(F_Visu.Height-50-Paper.H) div 2; + Bv_Visu.Left:= (F_Visu.Width-Paper.W) div 2; + end; + Bv_Visu.Visible:= True; + end + else + begin + NumPageSection:= NumPageSection+1; + Bv_Visu.Invalidate; + end; + E_NumPage.Text:= IntToStr(NumPage); + ChangeButtons; + E_NumSect.Text:= IntToStr(NumSection); + L_NumPageSect.Text:= IntToStr(NumPageSection); + L_NbrPageSect.Text:= IntToStr(T_Section(Sections[Pred(NumSection)]).NbPages); + end; +end; + +procedure TF_Visu.Bt_LastPageClick(Sender: TObject); +begin +with FReport do + begin + NumPage:= T_Section(Sections[Pred(Sections.Count)]).TotPages; + NumSection:= Sections.Count; + NumPageSection:= T_Section(Sections[Pred(Sections.Count)]).NbPages; + E_NumPage.Text:= IntToStr(NumPage); + Bv_Visu.Visible:= False; + with T_Section(Sections[Pred(NumSection)]),F_Visu do + begin + Bv_Visu.Height:= Paper.H; + Bv_Visu.Width:= Paper.W; + Bv_Visu.Top:= 50+(F_Visu.Height-50-Paper.H) div 2; + Bv_Visu.Left:= (F_Visu.Width-Paper.W) div 2; + end; + Bv_Visu.Visible:= True; + ChangeButtons; + E_NumSect.Text:= IntToStr(NumSection); + L_NumPageSect.Text:= IntToStr(NumPageSection); + L_NbrPageSect.Text:= IntToStr(T_Section(Sections[Pred(NumSection)]).NbPages); + end; +end; + +procedure TF_Visu.Bt_PrecSectClick(Sender: TObject); +begin +with FReport do + begin + NumSection:= NumSection-1; + NumPage:= T_Section(Sections[Pred(NumSection)]).FirstPage; + NumPageSection:= 1; + E_NumPage.Text:= IntToStr(NumPage); + Bv_Visu.Visible:= False; + with T_Section(Sections[Pred(NumSection)]),F_Visu do + begin + Bv_Visu.Height:= Paper.H; + Bv_Visu.Width:= Paper.W; + Bv_Visu.Top:= 50+(F_Visu.Height-50-Paper.H) div 2; + Bv_Visu.Left:= (F_Visu.Width-Paper.W) div 2; + end; + Bv_Visu.Visible:= True; + ChangeButtons; + E_NumSect.Text:= IntToStr(NumSection); + L_NumPageSect.Text:= IntToStr(NumPageSection); + L_NbrPageSect.Text:= IntToStr(T_Section(Sections[Pred(NumSection)]).NbPages); + end; +end; + +procedure TF_Visu.Bt_NextSectClick(Sender: TObject); +begin +with FReport do + begin + NumSection:= NumSection+1; + NumPage:= T_Section(Sections[Pred(NumSection)]).FirstPage; + NumPageSection:= 1; + E_NumPage.Text:= IntToStr(NumPage); + Bv_Visu.Visible:= False; + with T_Section(Sections[Pred(NumSection)]),F_Visu do + begin + Bv_Visu.Height:= Paper.H; + Bv_Visu.Width:= Paper.W; + Bv_Visu.Top:= 50+(F_Visu.Height-50-Paper.H) div 2; + Bv_Visu.Left:= (F_Visu.Width-Paper.W) div 2; + end; + Bv_Visu.Visible:= True; + ChangeButtons; + E_NumSect.Text:= IntToStr(NumSection); + L_NumPageSect.Text:= IntToStr(NumPageSection); + L_NbrPageSect.Text:= IntToStr(T_Section(Sections[Pred(NumSection)]).NbPages); + end; +end; + +procedure TF_Visu.ChangeButtons; +begin +with FReport do + if T_Section(Sections[Pred(Sections.Count)]).TotPages> 1 + then + if NumPage= 1 + then + begin + Bt_FirstPage.Enabled:= False; + Bt_PrecPage.Enabled:= False; + Bt_NextPage.Enabled:= True; + Bt_LastPage.Enabled:= True; + Bt_PrecSect.Enabled:= False; + if Sections.Count> 1 + then + Bt_NextSect.Enabled:= True + else + Bt_NextSect.Enabled:= False; + end + else + if NumPage= T_Section(Sections[Pred(Sections.Count)]).TotPages + then + begin + Bt_FirstPage.Enabled:= True; + Bt_PrecPage.Enabled:= True; + Bt_NextPage.Enabled:= False; + Bt_LastPage.Enabled:= False; + if Sections.Count> 1 + then + Bt_PrecSect.Enabled:= True + else + Bt_PrecSect.Enabled:= False; + Bt_NextSect.Enabled:= False; + end + else + begin + Bt_FirstPage.Enabled:= True; + Bt_PrecPage.Enabled:= True; + Bt_NextPage.Enabled:= True; + Bt_LastPage.Enabled:= True; + if Sections.Count> 1 + then + if NumSection= 1 + then + begin + Bt_PrecSect.Enabled:= False; + Bt_NextSect.Enabled:= True; + end + else + if NumSection= Sections.Count + then + begin + Bt_PrecSect.Enabled:= True; + Bt_NextSect.Enabled:= False; + end + else + begin + Bt_PrecSect.Enabled:= True; + Bt_NextSect.Enabled:= True; + end + else + begin + Bt_PrecSect.Enabled:= False; + Bt_NextSect.Enabled:= False; + end; + end + else + begin + Bt_FirstPage.Enabled:= False; + Bt_PrecPage.Enabled:= False; + Bt_NextPage.Enabled:= False; + Bt_LastPage.Enabled:= False; + Bt_PrecSect.Enabled:= False; + Bt_NextSect.Enabled:= False; + end; +end; + +procedure TF_Visu.E_NumPageKeyPress(Sender: TObject; var KeyCode: word; var ShiftState: TShiftState; + var Consumed: boolean); +var + CptSect,CptPage,CptPageSect: Integer; +begin +if (KeyCode= KeyReturn) or (KeyCode= KeyPEnter) +then + with FReport do + begin + if E_NumPage.Value> T_Section(Sections[Pred(Sections.Count)]).TotPages + then + NumPage:= T_Section(Sections[Pred(Sections.Count)]).TotPages + else + if E_NumPage.Value= 0 + then + NumPage:= 1 + else + NumPage:= E_NumPage.Value; + E_NumPage.Value:= NumPage; + CptSect:= 0; + CptPage:= 0; + repeat + Inc(CptSect); + CptPageSect:= 0; + repeat + Inc(CptPage); + Inc(CptPageSect); + until (CptPage= NumPage) or (CptPage= T_Section(Sections[Pred(Cptsect)]).NbPages); + until CptPage= NumPage; + NumSection:= CptSect; + NumPageSection:= CptPagesect; + Bv_Visu.Invalidate; + ChangeButtons; + E_NumSect.Text:= IntToStr(NumSection); + L_NumPageSect.Text:= IntToStr(NumPageSection); + L_NbrPageSect.Text:= IntToStr(T_Section(Sections[Pred(NumSection)]).NbPages); + end; +end; + +procedure TF_Visu.E_NumSectKeyPress(Sender: TObject; var KeyCode: word; var ShiftState: TShiftState; + var Consumed: boolean); +begin +if (KeyCode= KeyReturn) or (KeyCode= KeyPEnter) +then + with FReport do + begin + if E_NumSect.Value> Sections.Count + then + NumSection:= Sections.Count + else + if E_NumSect.Value= 0 + then + NumSection:= 1 + else + NumSection:= E_NumSect.Value; + E_NumSect.Value:= NumSection; + NumPage:= T_Section(Sections[Pred(NumSection)]).FirstPage; + NumPageSection:= 1; + E_NumPage.Value:= NumPage; + Bv_Visu.Invalidate; + ChangeButtons; + L_NumPageSect.Text:= IntToStr(NumPageSection); + L_NbrPageSect.Text:= IntToStr(T_Section(Sections[Pred(NumSection)]).NbPages); + end; +end; + +constructor TF_Visu.Create(AOwner: TComponent; AImprime: T_Report); +begin +inherited Create(AOwner); +FReport := AImprime; +Name := 'F_Visu'; +WindowTitle:= 'Preview'; +WindowPosition:= wpUser; +SetPosition(0, 0, FpgApplication.ScreenWidth-2, FpgApplication.ScreenHeight-66); +Sizeable:= False; +BackgroundColor:= clMediumAquamarine; +CreateReportImages; +Bv_Command:= CreateBevel(Self,0,0,Width,50,bsBox,bsRaised); +Bv_Command.BackgroundColor:= clBisque; +Bt_Close:= CreateButton(Bv_Command,10,10,26,'',@Bt_CloseClick,'stdimg.exit'); +Bt_Close.BackgroundColor:= clOrangeRed; +Bt_Print:= CreateButton(Bv_Command,50,10,26,'',@Bt_PrintClick,'stdimg.print'); +Bt_Print.BackgroundColor:= clGreen; +Bt_Print.Enabled:= False; +Bt_Printer:= CreateButton(Bv_Command,90,10,26,'',@Bt_PrinterClick,'repimg.Printer'); +Bt_Printer.BackgroundColor:= clSilver; +Bt_Printer.Enabled:= False; +Bt_Stop:= CreateButton(Bv_Command,130,10,26,'',@Bt_StopClick,'repimg.Stop'); +Bt_Stop.BackgroundColor:= clRed; +Bt_Pdf:= CreateButton(Bv_Command,170,10,26,'',@Bt_PdfClick,'stdimg.Adobe_pdf'); +Bt_Pdf.BackgroundColor:= clWhite; +Bt_Pdf.ImageMargin:= 0; +Bv_Pages:= CreateBevel(Bv_Command,220,5,300,40,bsBox,bsLowered); +Bv_Pages.BackgroundColor:= clLinen; +Bt_FirstPage:= CreateButton(Bv_Pages,54,6,26,'',@Bt_FirstPageClick,'repimg.First'); +Bt_PrecPage:= CreateButton(Bv_Pages,80,6,26,'',@Bt_PrecPageClick,'repimg.Precedent'); +E_NumPage:= CreateEditInteger(Bv_Pages,110,8,60,0); +E_NumPage.OnKeyPress:= @E_NumPageKeypress; +Bt_NextPage:= CreateButton(Bv_Pages,174,6,26,'',@Bt_NextPageClick,'repimg.Next'); +Bt_LastPage:= CreateButton(Bv_Pages,200,6,26,'',@Bt_LastPageClick,'repimg.Last'); +L_Pages:= CreateLabel(Bv_Pages,5,E_NumPage.Top,'Page',0,E_NumPage.Height,taLeftJustify,tlcenter); +L_FromPage:= CreateLabel(Bv_Pages,235,E_NumPage.Top,'of',0,E_NumPage.Height,taLeftJustify,tlcenter); +L_NbrPages:= CreateLabel(Bv_Pages,265,E_NumPage.Top,' ',30,E_NumPage.Height,taCenter,tlcenter); +Bv_Sections:= CreateBevel(Bv_Command,540,5,500,40,bsBox,bsLowered); +Bv_Sections.BackgroundColor:= clLinen; +Bt_PrecSect:= CreateButton(Bv_Sections,90,6,26,'',@Bt_PrecSectClick,'repimg.Precedent'); +E_NumSect:= CreateEditInteger(Bv_Sections,120,8,60,0); +E_NumSect.OnKeyPress:= @E_NumSectKeyPress; +Bt_NextSect:= CreateButton(Bv_Sections,184,6,26,'',@Bt_NextSectClick,'repimg.Next'); +L_Sections:= CreateLabel(Bv_Sections,5,E_NumSect.Top,'Section',0,E_NumSect.Height,taLeftJustify,tlcenter); +L_FromSect:= CreateLabel(Bv_Sections,250,E_NumSect.Top,'of',0,E_NumSect.Height,taLeftJustify,tlcenter); +L_NbrSect:= CreateLabel(Bv_Sections,280,E_NumSect.Top,'-',0,E_NumSect.Height,taLeftJustify,tlcenter); +L_PageSect:= CreateLabel(Bv_Sections,320,E_NumSect.Top,'Page',0,E_NumSect.Height,taLeftJustify,tlcenter); +L_NumPageSect:= CreateLabel(Bv_Sections,365,E_NumSect.Top,'-',0,E_NumSect.Height,taLeftJustify,tlcenter); +L_FromPageSect:= CreateLabel(Bv_Sections,410,E_NumSect.Top,'of',0,E_NumSect.Height,taLeftJustify,tlcenter); +L_NbrPageSect:= CreateLabel(Bv_Sections,440,E_NumSect.Top,'-',0,E_NumSect.Height,taLeftJustify,tlcenter); +OnShow:= @FormShow; +end; + +destructor TF_Visu.Destroy; +begin +DeleteReportImages; +inherited Destroy; +end; + +end. + |