Componentes.Terceros.FastRe.../official/4.2/Source/ExportPack/frxExportRTF.pas

1106 lines
36 KiB
ObjectPascal

{******************************************}
{ }
{ FastReport v4.0 }
{ RTF export filter }
{ }
{ Copyright (c) 1998-2007 }
{ by Alexander Fediachov, }
{ Fast Reports Inc. }
{ }
{******************************************}
unit frxExportRTF;
interface
{$I frx.inc}
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, extctrls, ComObj, Printers, frxClass, JPEG, ShellAPI, frxExportMatrix
{$IFDEF Delphi6}, Variants {$ENDIF}, frxProgress, ComCtrls, frxGraphicUtils;
type
TfrxHeaderFooterMode = (hfText, hfPrint, hfNone);
TfrxRTFExportDialog = class(TForm)
OkB: TButton;
CancelB: TButton;
GroupPageRange: TGroupBox;
DescrL: TLabel;
AllRB: TRadioButton;
CurPageRB: TRadioButton;
PageNumbersRB: TRadioButton;
PageNumbersE: TEdit;
GroupQuality: TGroupBox;
WCB: TCheckBox;
PageBreaksCB: TCheckBox;
PicturesCB: TCheckBox;
OpenCB: TCheckBox;
SaveDialog1: TSaveDialog;
ContinuousCB: TCheckBox;
HeadFootL: TLabel;
PColontitulCB: TComboBox;
procedure FormCreate(Sender: TObject);
procedure PageNumbersEChange(Sender: TObject);
procedure PageNumbersEKeyPress(Sender: TObject; var Key: Char);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
end;
TfrxRTFExport = class(TfrxCustomExportFilter)
private
FColorTable: TStringList;
FCurrentPage: Integer;
FDataList: TList;
FExportPageBreaks: Boolean;
FExportPictures: Boolean;
FFirstPage: Boolean;
FFontTable: TStringList;
FCharsetTable: TStringList;
FMatrix: TfrxIEMatrix;
FOpenAfterExport: Boolean;
FProgress: TfrxProgress;
FWysiwyg: Boolean;
FCreator: String;
FHeaderFooterMode: TfrxHeaderFooterMode;
function TruncReturns(const Str: WideString): WideString;
function GetRTFBorders(const Style: TfrxIEMStyle): string;
function GetRTFColor(const c: DWORD): string;
function GetRTFFontStyle(const f: TFontStyles): String;
function GetRTFFontColor(const f: String): String;
function GetRTFFontName(const f: String; const charset: Integer): String;
function GetRTFHAlignment(const HAlign: TfrxHAlign) : String;
function GetRTFVAlignment(const VAlign: TfrxVAlign) : String;
function StrToRTFSlash(const Value: WideString): WideString;
function StrToRTFUnicodeEx(const Value: WideString): String;
function StrToRTFUnicode(const Value: WideString): String;
procedure ExportPage(const Stream: TStream);
procedure PrepareExport;
public
constructor Create(AOwner: TComponent); override;
class function GetDescription: String; override;
function ShowModal: TModalResult; override;
function Start: boolean; override;
procedure Finish; override;
procedure FinishPage(Page: TfrxReportPage; Index: Integer); override;
procedure StartPage(Page: TfrxReportPage; Index: Integer); override;
procedure ExportObject(Obj: TfrxComponent); override;
published
property ExportPageBreaks: Boolean read FExportPageBreaks write FExportPageBreaks default True;
property ExportPictures: Boolean read FExportPictures write FExportPictures default True;
property OpenAfterExport: Boolean read FOpenAfterExport
write FOpenAfterExport default False;
property Wysiwyg: Boolean read FWysiwyg write FWysiwyg;
property Creator: String read FCreator write FCreator;
property SuppressPageHeadersFooters;
property HeaderFooterMode: TfrxHeaderFooterMode read FHeaderFooterMode write FHeaderFooterMode;
end;
implementation
uses frxUtils, frxFileUtils, frxRes, frxrcExports;
{$R *.dfm}
const
Xdivider = 15.05;
Ydivider = 13;
PageDivider = 15.02;
MargDivider = 56.48;
FONT_DIVIDER = 15;
IMAGE_DIVIDER = 25.3;
{ TfrxRTFExport }
constructor TfrxRTFExport.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ShowDialog := True;
FExportPageBreaks := True;
FExportPictures := True;
FWysiwyg := True;
FHeaderFooterMode := hfText;
FCreator := 'FastReport http://www.fast-report.com';
FilterDesc := frxGet(8504);
DefaultExt := frxGet(8505);
end;
class function TfrxRTFExport.GetDescription: String;
begin
Result := frxResources.Get('RTFexport');
end;
function TfrxRTFExport.TruncReturns(const Str: WideString): WideString;
begin
Result := Str;
if Copy(Result, Length(Result) - 1, 2) = #13#10 then
Delete(Result, Length(Result) - 1, 2);
end;
function TfrxRTFExport.StrToRTFSlash(const Value: WideString): WideString;
var
i: integer;
begin
result := '';
for i := 1 to Length(Value) do
begin
if Value[i] = '\' then
result := result + '\\'
else if Value[i] = '{' then
result := result + '\{'
else if Value[i] = '}' then
result := result + '\}'
else if (Value[i] = #13) and (i < (Length(Value) - 1)) and (Value[i + 1] = #10) then
result := result + '\line'#13
else
result := result + Value[i];
end;
end;
function TfrxRTFExport.StrToRTFUnicodeEx(const Value: WideString): String;
var
s: WideString;
begin
s := StrToRTFSlash(Value);
Result := StrToRTFUnicode(s);
end;
function TfrxRTFExport.StrToRTFUnicode(const Value: WideString): String;
var
i: integer;
pwc: ^Word;
begin
result := '';
for i := 1 to Length(Value) do
begin
pwc := @Value[i];
if pwc^ > 127 then
result := result + '\u' + IntToStr(pwc^) + '\''3f'
else
result := result + Chr(pwc^);
end;
end;
function TfrxRTFExport.GetRTFBorders(const Style: TfrxIEMStyle): string;
var
brdrw: String;
brdrc: String;
brdrs: String;
begin
Result := '';
brdrw := '\brdrs\brdrw' + IntToStr(Round(Style.FrameWidth * 20));
brdrc := '\brdrcf' + GetRTFFontColor(GetRTFColor(Style.FrameColor));
if Style.FrameStyle = fsDouble then
brdrs := '\brdrdb'
else if Style.FrameStyle <> fsSolid then
brdrs := '\brdrdashsm'
else brdrs := '';
if ftTop in Style.FrameTyp then
Result := Result + '\clbrdrt' + brdrw + brdrc + brdrs;
if ftLeft in Style.FrameTyp then
Result := Result + '\clbrdrl' + brdrw + brdrc + brdrs;
if ftBottom in Style.FrameTyp then
Result := Result + '\clbrdrb' + brdrw + brdrc + brdrs;
if ftRight in Style.FrameTyp then
Result := Result + '\clbrdrr' + brdrw + brdrc + brdrs;
end;
function TfrxRTFExport.GetRTFColor(const c: DWORD): string;
var
cn: DWORD;
begin
cn := ColorToRGB(c);
Result := '\red' + IntToStr(GetRValue(cn)) +
'\green' + IntToStr(GetGValue(cn)) +
'\blue' + IntToStr(GetBValue(cn)) + ';'
end;
function TfrxRTFExport.GetRTFFontStyle(const f: TFontStyles): String;
begin
Result := '';
if fsItalic in f then Result := '\i';
if fsBold in f then Result := Result + '\b';
if fsUnderline in f then Result := Result + '\ul';
end;
function TfrxRTFExport.GetRTFFontColor(const f: String): String;
var
i: Integer;
begin
i := FColorTable.IndexOf(f);
if i <> -1 then
Result := IntToStr(i + 1)
else
begin
FColorTable.Add(f);
Result := IntToStr(FColorTable.Count);
end;
end;
function TfrxRTFExport.GetRTFFontName(const f: String; const Charset: Integer): String;
var
i: Integer;
begin
i := FFontTable.IndexOf(f);
if i <> -1 then
Result := IntToStr(i)
else
begin
FFontTable.Add(f);
FCharsetTable.Add(IntToStr(charset));
Result := IntToStr(FFontTable.Count - 1);
end;
end;
function TfrxRTFExport.GetRTFHAlignment(const HAlign: TfrxHAlign) : String;
begin
if (HAlign = haLeft) then Result := '\ql'
else if (HAlign = haRight) then Result := '\qr'
else if (HAlign = haCenter) then Result := '\qc'
// else if (HAlign = haBlock) then Result := '\qj'
else Result := '\ql';
end;
function TfrxRTFExport.GetRTFVAlignment(const VAlign: TfrxVAlign) : String;
begin
if (VAlign = vaTop) then Result := '\clvertalt'
else if (VAlign = vaCenter) then Result := '\clvertalc'
else if (VAlign = vaBottom) then Result := '\clvertalb'
else Result := '\clvertalt';
end;
procedure TfrxRTFExport.PrepareExport;
var
i, j, x, y, n, n1, fx: Integer;
s, s0, s1, s2: String;
Obj: TfrxIEMObject;
RepPos: TStringList;
function PosEx(const SubStr, S: string; Offset: Cardinal = 1): Integer;
var
I,X: Integer;
Len, LenSubStr: Integer;
begin
if Offset = 1 then
Result := Pos(SubStr, S)
else
begin
I := Offset;
LenSubStr := Length(SubStr);
Len := Length(S) - LenSubStr + 1;
while I <= Len do
begin
if S[I] = SubStr[1] then
begin
X := 1;
while (X < LenSubStr) and (S[I + X] = SubStr[X + 1]) do
Inc(X);
if (X = LenSubStr) then
begin
Result := I;
exit;
end;
end;
Inc(I);
end;
Result := 0;
end;
end;
begin
for y := 0 to FMatrix.Height - 1 do
for x := 0 to FMatrix.Width - 1 do
begin
i := FMatrix.GetCell(x, y);
if (i <> -1) then
begin
Obj := FMatrix.GetObjectById(i);
if Obj.Counter <> -1 then
begin
Obj.Counter := -1;
GetRTFFontColor(GetRTFColor(Obj.Style.Color));
GetRTFFontColor(GetRTFColor(Obj.Style.FrameColor));
if Obj.IsRichText then
begin
RepPos := TStringList.Create;
s := Obj.Memo.Text;
fx := Pos('{\fonttbl', s);
Delete(s, 1, fx + 8);
i := 1;
RepPos.Clear;
while (i < Length(s)) and (s[i] <> '}') do
begin
while (i < Length(s)) and (s[i] <> '{') and (s[i] <> '}') do
Inc(i);
j := i;
while (j < Length(s)) and (s[j] <> '}') do
Inc(j);
Inc(j);
s1 := Copy(s, i , j - i - 2);
i := j;
j := Pos(' ', s1);
s2 := Copy(s1, j + 1, Length(s1) - j + 1);
s0 := '\f' + GetRTFFontName(s2, 1);
j := Pos('\f', s1);
n := j + 1;
while (n < Length(s1)) and (s1[n] <> '\') and (s1[n] <> ' ') do
Inc(n);
s2 := Copy(s1, j, n - j);
j := Pos('}}', s);
s1 := Copy(s, j + 2, Length(s) - j - 1);
j := j + 2;
n := 1;
while n > 0 do
begin
n := Pos(s2, s1);
if n > 0 then
begin
if RepPos.IndexOf(IntToStr(n + j - 1)) = -1 then
begin
RepPos.Add(IntToStr(n + j - 1));
Delete(s, n + j - 1, Length(s2));
Insert(s0, s, n + j - 1);
end;
j := j + n + Length(s2) - 1;
s1 := Copy(s, j, Length(s) - j + 1);
end;
end;
end;
fx := Pos('}}', s);
if fx > 0 then
Delete(s, 1, fx + 1);
fx := Pos('{\colortbl', s);
if fx > 0 then
begin
Delete(s, 1, fx + 11);
i := 1;
n1 := 1;
RepPos.Clear;
while (i < Length(s)) and (s[i] <> '}') do
begin
while (i < Length(s)) and (s[i] <> '\') do
Inc(i);
j := i;
while (j < Length(s)) and (s[j] <> ';') do
Inc(j);
Inc(j);
s1 := Copy(s, i , j - i);
i := j;
s0 := '\cf' + GetRTFFontColor(s1);
s2 := '\cf' + IntToStr(n1);
j := Pos(';}', s);
s1 := Copy(s, j + 2, Length(s) - j - 1);
j := j + 2;
n := 1;
while n > 0 do
begin
n := Pos(s2, s1);
if n > 0 then
begin
if RepPos.IndexOf(IntToStr(n + j - 1)) = -1 then
begin
RepPos.Add(IntToStr(n + j - 1));
Delete(s, n + j - 1, Length(s2));
Insert(s0, s, n + j - 1);
end;
j := j + n + Length(s2) - 1;
s1 := Copy(s, j, Length(s) - j + 1);
end;
end;
Inc(n1);
end;
fx := Pos(';}', s);
if fx > 0 then
Delete(s, 1, fx + 1);
end;
fx := Pos('{\stylesheet', s);
if fx > 0 then
begin
Delete(s, 1, fx + 12);
fx := Pos('}}', s);
if fx > 0 then
Delete(s, 1, fx + 1);
end;
s := StringReplace(s, '\pard', '', [rfReplaceAll]);
Delete(s, Length(s) - 3, 3);
fx := 1;
while fx > 0 do
begin
fx := Pos('\lang', s);
if fx > 0 then
begin
Delete(s, fx , 5);
n := PosEx('\', s, fx);
Delete(s, fx, n - fx);
end;
end;
fx := 1;
while fx > 0 do
begin
fx := Pos('\sa', s);
if fx > 0 then
begin
Delete(s, fx , 3);
n := PosEx('\', s, fx);
Delete(s, fx, n - fx);
end;
end;
fx := 1;
while fx > 0 do
begin
fx := Pos('\sb', s);
if fx > 0 then
begin
Delete(s, fx , 3);
n := PosEx('\', s, fx);
Delete(s, fx, n - fx);
end;
end;
fx := 1;
while fx > 0 do
begin
fx := Pos('\cbpat', s);
if fx > 0 then
begin
Delete(s, fx , 5);
n := PosEx('\', s, fx);
Delete(s, fx, n - fx);
end;
end;
fx := 1;
while fx > 0 do
begin
fx := Pos('\cfpat', s);
if fx > 0 then
begin
Delete(s, fx , 5);
n := PosEx('\', s, fx);
Delete(s, fx, n - fx);
end;
end;
Obj.Memo.Text := s;
RepPos.Free;
end else if Obj.IsText then
begin
GetRTFFontColor(GetRTFColor(Obj.Style.Font.Color));
GetRTFFontName(Obj.Style.Font.Name, Obj.Style.Charset);
end;
end;
end;
end;
end;
procedure TfrxRTFExport.ExportPage(const Stream: TStream);
var
i, j, x, y, fx, fy, dx, dy, n, n1, pbk: Integer;
dcol, drow, xoffs: Integer;
buff, s, s0, s1, s2: String;
st, st1: WideString;
CellsLine: String;
Obj: TfrxIEMObject;
Graphic: TGraphic;
Str, CellsStream: TStream;
bArr: array[0..1023] of Byte;
FMode: Integer; // 3 - header, 2 - footer, 1 - body, 0 - stop
FHTMLTags: TfrxHTMLTagsList;
Tag: TfrxHTMLTag;
TagFColor: TColor;
TagFStyleB, TagFStyleU, TagFStyleI: Integer;
procedure WriteExpLn(const str: string);
begin
if Length(str) > 0 then
begin
Stream.Write(str[1], Length(str));
Stream.Write(#13#10, 2);
end;
end;
procedure SetPageProp(Page: Integer);
begin
WriteExpLn('\pgwsxn' + IntToStr(Round(FMatrix.GetPageWidth(Page) * PageDivider)) +
'\pghsxn' + IntToStr(Round(FMatrix.GetPageHeight(Page) * PageDivider)) +
'\marglsxn' + IntToStr(Round(FMatrix.GetPageLMargin(Page) * MargDivider)) +
'\margrsxn' + IntToStr(Round(FMatrix.GetPageRMargin(Page) * MargDivider)) +
'\margtsxn' + IntToStr(Round(FMatrix.GetPageTMargin(Page) * MargDivider)) +
'\margbsxn' + IntToStr(Round(FMatrix.GetPageBMargin(Page) * MargDivider)));
if FMatrix.GetPageOrientation(Page) = poLandscape then
WriteExpLn('\lndscpsxn');
end;
begin
PrepareExport;
WriteExpLn('{\rtf1\ansi');
s := '{\fonttbl';
for i := 0 to FFontTable.Count - 1 do
begin
s1 := '{\f' + IntToStr(i) + '\fcharset' + FCharsetTable[i] + ' ' + FFontTable[i] + '}';
if Length(s + s1) < 255 then
s := s + s1
else
begin
WriteExpLn(s);
s := s1;
end;
end;
s := s + '}';
WriteExpLn(s);
s := '{\colortbl;';
for i := 0 to FColorTable.Count - 1 do
begin
s1 := FColorTable[i];
if Length(s + s1) < 255 then
s := s + s1
else
begin
WriteExpLn(s);
s := s1;
end;
end;
s := s + '}';
WriteExpLn(s);
WriteExpLn('{\info{\title ' + StrToRTFUnicodeEx(Report.ReportOptions.Name) +
'}{\author ' + StrToRTFUnicodeEx(FCreator) +
'}{\creatim\yr' + FormatDateTime('yyyy', Now) +
'\mo' + FormatDateTime('mm', Now) + '\dy' + FormatDateTime('dd', Now) +
'\hr' + FormatDateTime('hh', Now) + '\min' + FormatDateTime('nn', Now) + '}}');
if ShowProgress then
FProgress.Execute(FMatrix.Height - 1, frxResources.Get('ProgressWait'), True, True);
pbk := 0;
SetPageProp(pbk);
if FHeaderFooterMode = hfPrint then
FMode := 3
else
FMode := 1;
///
while FMode > 0 do
begin
if FMode = 3 then
WriteExpLn('{\header ')
else if FMode = 2 then
WriteExpLn('{\footer ');
for y := 0 to FMatrix.Height - 2 do
begin
if ShowProgress then
begin
FProgress.Tick;
if FProgress.Terminated then
break;
end;
if FExportPageBreaks and (FMode = 1) then
if FMatrix.PagesCount > pbk then
if FMatrix.GetPageBreak(pbk) <= FMatrix.GetYPosById(y) then
begin
WriteExpLn('\pard\sect');
Inc(pbk);
if pbk < FMatrix.PagesCount then
SetPageProp(pbk);
continue;
end;
drow := Round((FMatrix.GetYPosById(y + 1) - FMatrix.GetYPosById(y)) * Ydivider);
buff := '\trrh' + IntToStr(drow)+ '\trgaph15';
CellsStream := TMemoryStream.Create;
try
xoffs := Round(FMatrix.GetXPosById(1));
for x := 1 to FMatrix.Width - 2 do
begin
i := FMatrix.GetCell(x, y);
if (i <> -1) then
begin
Obj := FMatrix.GetObjectById(i);
if (FMode = 3) and (not Obj.Header) then
Continue;
if (FMode = 2) and (not Obj.Footer) then
Continue;
if (FMode = 1) and (Obj.Header or Obj.Footer) and
((FHeaderFooterMode = hfPrint) or
(FHeaderFooterMode = hfNone)) then
Continue;
FMatrix.GetObjectPos(i, fx, fy, dx, dy);
if Obj.Counter = -1 then
begin
if dy > 1 then
buff := buff + '\clvmgf';
if (obj.Style.Color mod 16777216) <> clWhite then
buff := buff + '\clcbpat' + GetRTFFontColor(GetRTFColor(Obj.Style.Color));
buff := buff + GetRTFVAlignment(Obj.Style.VAlign) + GetRTFBorders(Obj.Style) + '\cltxlrtb';
dcol := Round((Obj.Left + Obj.Width - xoffs) * Xdivider);
buff := buff + '\cellx' + IntToStr(dcol);
if Obj.IsText then
begin
s := '\f' + GetRTFFontName(Obj.Style.Font.Name, Obj.Style.Charset);
if Length(Obj.Memo.Text) > 0 then
s := s + '\fs' + IntToStr(Obj.Style.Font.Size * 2)
else
begin
j := drow div FONT_DIVIDER;
if j > 20 then j := 20;
s := s + '\fs' + IntToStr(j);
end;
s := s + GetRTFFontStyle(Obj.Style.Font.Style);
s := s + '\cf' + GetRTFFontColor(GetRTFColor(Obj.Style.Font.Color));
if (Obj.IsRichText) then
s1 := Obj.Memo.Text
else
begin
if Obj.HTMLTags then
begin
FHTMLTags := TfrxHTMLTagsList.Create;
try
FHTMLTags.SetDefaults(Obj.Style.Font.Color, Obj.Style.Font.Size, Obj.Style.Font.Style);
FHTMLTags.AllowTags := True;
st := StrToRTFSlash(TruncReturns(Obj.Memo.Text));
st1 := st;
s1 := '';
TagFColor := Obj.Style.Color;
TagFStyleB := 0;
TagFStyleU := 0;
TagFStyleI := 0;
FHTMLTags.ExpandHTMLTags(st);
for i := 0 to FHTMLTags.Count - 1 do
for j := 0 to FHTMLTags[i].Count - 1 do
begin
Tag := FHTMLTags[i].Items[j];
// bold tags
if (fsBold in Tag.Style) and (TagFStyleB = 0) then
begin
Inc(TagFStyleB);
s1 := s1 + '\b ';
end;
if (TagFStyleB > 0) and (not (fsBold in Tag.Style)) then
begin
Dec(TagFStyleB);
s1 := s1 + '\b0 ';
end;
// italic tags
if (fsItalic in Tag.Style) and (TagFStyleI = 0) then
begin
Inc(TagFStyleI);
s1 := s1 + '\i ';
end;
if (TagFStyleI > 0) and (not (fsItalic in Tag.Style)) then
begin
Dec(TagFStyleI);
s1 := s1 + '\i0 ';
end;
// underline tags
if (fsUnderline in Tag.Style) and (TagFStyleU = 0) then
begin
Inc(TagFStyleU);
s1 := s1 + '\ul ';
end;
if (TagFStyleU > 0) and (not (fsUnderline in Tag.Style)) then
begin
Dec(TagFStyleU);
s1 := s1 + '\ul0 ';
end;
// color tags
if (Tag.Color <> Obj.Style.Font.Color) and (Tag.Color <> TagFColor) then
begin
TagFColor := Tag.Color;
s1 := s1 + '\cf' + GetRTFFontColor(GetRTFColor(TagFColor)) + ' ';
end;
if (Tag.Color <> TagFColor) then
begin
TagFColor := Tag.Color;
s1 := s1 + '\cf' + GetRTFFontColor(GetRTFColor(TagFColor)) + ' ';
end;
s1 := s1 + StrToRTFUnicode(st1[Tag.Position]);
end;
s1 := s1 + '\plain';
finally
FHTMLTags.Free;
end;
end
else
s1 := StrToRTFUnicodeEx(TruncReturns(Obj.Memo.Text));
end;
if Trim(s1) <> '' then
begin
j := Round(Obj.Style.CharSpacing * FONT_DIVIDER);
s2 := '\sb' + IntToStr(Round(Obj.Style.GapY * Ydivider)) +
'\li' + IntToStr(Round((Obj.Style.GapX / 2) * Xdivider)) +
'\fi' + IntToStr(Round((Obj.Style.ParagraphGap) * Xdivider)) +
'\expnd' + IntToStr(j div 5) + '\expndtw' + IntToStr(j) +
'\sl' + IntToStr(Round((Obj.Style.Font.Size + Obj.Style.LineSpacing - 2) * Ydivider)) +
'\slmult0';
if Obj.Style.WordBreak then
s2 := s2 + '\hyphauto1\hyphcaps1';
end else
s2 := '';
CellsLine := GetRTFHAlignment(Obj.Style.HAlign) +
'{' + s + s2 + ' ' + s1 + '\cell}';
s := '\par'#13#10'\cell';
while Pos(s, CellsLine) > 0 do
CellsLine := StringReplace(CellsLine, s, '\cell', []);
CellsStream.Write(CellsLine[1], Length(CellsLine));
end
else if FExportPictures then
begin
Graphic := Obj.Image;
if not ((Graphic = nil) or Graphic.Empty) then
begin
Str := TMemoryStream.Create;
try
dx := Round(Obj.Width);
dy := Round(Obj.Height);
fx := Graphic.Width;
fy := Graphic.Height;
Graphic.SaveToStream(Str);
Str.Position := 0;
CellsLine := '{\sb0\li0\sl0\slmult0 {\pict\wmetafile8\picw' + FloatToStr(Round(dx * IMAGE_DIVIDER)) +
'\pich' + FloatToStr(Round(dy * IMAGE_DIVIDER)) + '\picbmp\picbpp4' + #13#10;
CellsStream.Write(CellsLine[1], Length(CellsLine));
Str.Read(n, 2);
Str.Read(n, 4);
n := n div 2 + 7;
s0 := IntToHex(n + $24, 8);
s := '010009000003' + Copy(s0, 7, 2) + Copy(s0, 5, 2) +
Copy(s0, 3, 2) + Copy(s0, 1, 2) + '0000';
s0 := IntToHex(n, 8);
s1 := Copy(s0, 7, 2) + Copy(s0, 5, 2) + Copy(s0, 3, 2) + Copy(s0, 1, 2);
s := s + s1 + '0000050000000b0200000000050000000c02';
s0 := IntToHex(fy, 4);
s := s + Copy(s0, 3, 2) + Copy(s0, 1, 2);
s0 := IntToHex(fx, 4);
s := s + Copy(s0, 3, 2) + Copy(s0, 1, 2) +
'05000000090200000000050000000102ffffff000400000007010300' + s1 +
'430f2000cc000000';
s0 := IntToHex(fy, 4);
s := s + Copy(s0, 3, 2) + Copy(s0, 1, 2);
s0 := IntToHex(fx, 4);
s := s + Copy(s0, 3, 2) + Copy(s0, 1, 2) + '00000000';
s0 := IntToHex(fy, 4);
s := s + Copy(s0, 3, 2) + Copy(s0, 1, 2);
s0 := IntToHex(fx, 4);
s := s + Copy(s0, 3, 2) + Copy(s0, 1, 2) + '00000000';
CellsLine := s + #13#10;
CellsStream.Write(CellsLine[1], Length(CellsLine));
Str.Read(bArr[0], 8);
n1 := 0; s := '';
repeat
n := Str.Read(bArr[0], 1024);
for j := 0 to n - 1 do
begin
s := s + IntToHex(bArr[j], 2);
Inc(n1);
if n1 > 63 then
begin
n1 := 0;
CellsLine := s + #13#10;
CellsStream.Write(CellsLine[1], Length(CellsLine));
s := '';
end;
end;
until n < 1024;
finally
Str.Free;
end;
if n1 <> 0 then
begin
CellsLine := s + #13#10;
CellsStream.Write(CellsLine[1], Length(CellsLine));
end;
s := '030000000000}';
CellsLine := s + '\cell}' + #13#10;
CellsStream.Write(CellsLine[1], Length(CellsLine));
end;
end;
Obj.Counter := y + 1;
end
else
begin
if (dy > 1) and (Obj.Counter <> (y + 1))then
begin
buff := buff + '\clvmrg';
buff := buff + GetRTFBorders(Obj.Style) + '\cltxlrtb';
dcol := Round((Obj.Left + Obj.Width - xoffs) * Xdivider);
buff := buff + '\cellx' + IntToStr(dcol);
j := drow div FONT_DIVIDER;
if j > 20 then
j := 20;
CellsLine := '{\fs' + IntToStr(j) + '\cell}';
CellsStream.Write(CellsLine[1], Length(CellsLine));
Obj.Counter := y + 1;
end;
end
end
end;
if CellsStream.Size > 0 then
begin
s := '\trowd' + buff + '\pard\intbl';
WriteExpLn(s);
Stream.CopyFrom(CellsStream, 0);
WriteExpLn('\pard\intbl{\trowd' + buff + '\row}');
end;
finally
CellsStream.Free;
end;
end;
if FMode in [2, 3] then
WriteExpLn('}');
Dec(FMode);
end;
WriteExpLn('}');
end;
function TfrxRTFExport.ShowModal: TModalResult;
begin
if not Assigned(Stream) then
begin
with TfrxRTFExportDialog.Create(nil) do
begin
SendMessage(GetWindow(PColontitulCB.Handle,GW_CHILD), EM_SETREADONLY, 1, 0);
OpenCB.Visible := not SlaveExport;
if SlaveExport then
FOpenAfterExport := False;
if (FileName = '') and (not SlaveExport) then
SaveDialog1.FileName := ChangeFileExt(ExtractFileName(frxUnixPath2WinPath(Report.FileName)), SaveDialog1.DefaultExt)
else
SaveDialog1.FileName := FileName;
ContinuousCB.Checked := SuppressPageHeadersFooters;
PicturesCB.Checked := FExportPictures;
PageBreaksCB.Checked := FExportPageBreaks;
WCB.Checked := FWysiwyg;
OpenCB.Checked := FOpenAfterExport;
if PageNumbers <> '' then
begin
PageNumbersE.Text := PageNumbers;
PageNumbersRB.Checked := True;
end;
if FHeaderFooterMode = hfText then
PColontitulCB.ItemIndex := 0
else if FHeaderFooterMode = hfPrint then
PColontitulCB.ItemIndex := 1
else
PColontitulCB.ItemIndex := 2;
Result := ShowModal;
if Result = mrOk then
begin
if PColontitulCB.ItemIndex = 0 then
FHeaderFooterMode := hfText
else if PColontitulCB.ItemIndex = 1 then
FHeaderFooterMode := hfPrint
else
FHeaderFooterMode := hfNone;
PageNumbers := '';
CurPage := False;
if CurPageRB.Checked then
CurPage := True
else if PageNumbersRB.Checked then
PageNumbers := PageNumbersE.Text;
SuppressPageHeadersFooters := ContinuousCB.Checked;
if FHeaderFooterMode = hfPrint then
SuppressPageHeadersFooters := True;
FExportPictures := PicturesCB.Checked;
FExportPageBreaks := PageBreaksCB.Checked;
FWysiwyg := WCB.Checked;
FOpenAfterExport := OpenCB.Checked;
if not SlaveExport then
begin
if DefaultPath <> '' then
SaveDialog1.InitialDir := DefaultPath;
if SaveDialog1.Execute then
FileName := SaveDialog1.FileName
else
Result := mrCancel;
end
else
FileName := ChangeFileExt(GetTempFile, SaveDialog1.DefaultExt);
end;
Free;
end;
end else
Result := mrOk;
end;
function TfrxRTFExport.Start: Boolean;
begin
if (FileName <> '') or Assigned(Stream) then
begin
if (ExtractFilePath(FileName) = '') and (DefaultPath <> '') then
FileName := DefaultPath + '\' + FileName;
FFirstPage := True;
FCurrentPage := 0;
FMatrix := TfrxIEMatrix.Create(UseFileCache, Report.EngineOptions.TempDir);
FMatrix.ShowProgress := ShowProgress;
if FWysiwyg then
FMatrix.Inaccuracy := 0.5
else
FMatrix.Inaccuracy := 10;
FMatrix.RotatedAsImage := True;
FMatrix.RichText := True;
FMatrix.PlainRich := False;
FMatrix.AreaFill := True;
FMatrix.CropAreaFill := True;
// FMatrix.DeleteHTMLTags := True;
FMatrix.DeleteHTMLTags := False;
FMatrix.BackgroundImage := False;
FMatrix.Background := False;
FMatrix.Printable := ExportNotPrintable;
FFontTable := TStringList.Create;
FCharsetTable := TStringList.Create;
FColorTable := TStringList.Create;
FDataList := TList.Create;
Result := True
end
else
Result := False;
end;
procedure TfrxRTFExport.StartPage(Page: TfrxReportPage; Index: Integer);
begin
Inc(FCurrentPage);
if FFirstPage then
FFirstPage := False;
end;
procedure TfrxRTFExport.ExportObject(Obj: TfrxComponent);
begin
if (Obj is TfrxPageHeader) and (ExportNotPrintable or TfrxView(Obj).Printable) then
FMatrix.SetPageHeader(TfrxBand(Obj))
else if (Obj is TfrxPageFooter) and (ExportNotPrintable or TfrxView(Obj).Printable) then
FMatrix.SetPageFooter(TfrxBand(Obj))
else if (Obj is TfrxView) and (ExportNotPrintable or TfrxView(Obj).Printable) then
begin
if (Obj is TfrxCustomMemoView) or
(FExportPictures and (not (Obj is TfrxCustomMemoView))) then
FMatrix.AddObject(TfrxView(Obj))
end;
end;
procedure TfrxRTFExport.FinishPage(Page: TfrxReportPage; Index: Integer);
begin
FMatrix.AddPage(Page.Orientation, Page.Width, Page.Height, Page.LeftMargin,
Page.TopMargin, Page.RightMargin, Page.BottomMargin);
end;
procedure TfrxRTFExport.Finish;
var
Exp: TStream;
begin
FMatrix.Prepare;
if ShowProgress then
FProgress := TfrxProgress.Create(nil);
try
if Assigned(Stream) then
Exp := Stream
else
Exp := TFileStream.Create(FileName, fmCreate);
try
ExportPage(Exp);
finally
if not Assigned(Stream) then
Exp.Free;
end;
if FOpenAfterExport and (not Assigned(Stream)) then
ShellExecute(GetDesktopWindow, 'open', PChar(FileName), nil, nil, SW_SHOW);
except
on e: Exception do
case Report.EngineOptions.NewSilentMode of
simSilent: Report.Errors.Add(e.Message);
simMessageBoxes: frxErrorMsg(e.Message);
simReThrow: raise;
end;
end;
FMatrix.Clear;
FMatrix.Free;
FFontTable.Free;
FCharsetTable.Free;
FColorTable.Free;
FDataList.Free;
if ShowProgress then
FProgress.Free;
end;
{ TfrxRTFExportDialog }
procedure TfrxRTFExportDialog.FormCreate(Sender: TObject);
begin
Caption := frxGet(8500);
OkB.Caption := frxGet(1);
CancelB.Caption := frxGet(2);
GroupPageRange.Caption := frxGet(7);
AllRB.Caption := frxGet(3);
CurPageRB.Caption := frxGet(4);
PageNumbersRB.Caption := frxGet(5);
DescrL.Caption := frxGet(9);
GroupQuality.Caption := frxGet(8);
ContinuousCB.Caption := frxGet(8950);
PicturesCB.Caption := frxGet(8501);
PageBreaksCB.Caption := frxGet(6);
WCB.Caption := frxGet(8502);
OpenCB.Caption := frxGet(8503);
SaveDialog1.Filter := frxGet(8504);
SaveDialog1.DefaultExt := frxGet(8505);
HeadFootL.Caption := frxGet(8951);
PColontitulCB.Items[0] := frxGet(8952);
PColontitulCB.Items[1] := frxGet(8953);
PColontitulCB.Items[2] := frxGet(8954);
if UseRightToLeftAlignment then
FlipChildren(True);
end;
procedure TfrxRTFExportDialog.PageNumbersEChange(Sender: TObject);
begin
PageNumbersRB.Checked := True;
end;
procedure TfrxRTFExportDialog.PageNumbersEKeyPress(Sender: TObject;
var Key: Char);
begin
case key of
'0'..'9':;
#8, '-', ',':;
else
key := #0;
end;
end;
procedure TfrxRTFExportDialog.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = VK_F1 then
frxResources.Help(Self);
end;
end.