richmemo: optimize rtf reading for paragraph alignment, text buffer, skipping rtf destinations

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3815 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
skalogryz
2014-12-01 11:08:59 +00:00
parent 6194b41ef0
commit 3bf63e4d38

View File

@ -74,11 +74,15 @@ type
TRTFMemoParser = class(TRTFParser) TRTFMemoParser = class(TRTFParser)
private private
txtbuf : String; // keep it UTF8 encoded! txtbuf : String; // keep it UTF8 encoded!
txtlen : Integer; txtlen : Integer;
HLFromCTable : Boolean;
prm : TRTFParams; prm : TRTFParams;
lang : Integer; lang : Integer;
langproc : TEncConvProc; langproc : TEncConvProc;
procedure AddText(const atext: string);
protected protected
procedure classUnk; procedure classUnk;
procedure classText; procedure classText;
@ -254,18 +258,39 @@ end;
{ TRTFMemoParserr } { TRTFMemoParserr }
procedure TRTFMemoParser.AddText(const atext: string);
var
nl : Integer;
l : Integer;
begin
nl:=txtlen+length(atext);
if nl>length(txtbuf) then begin
l:=length(txtbuf);
while l<nl do
if l=0 then l:=256
else l:=l*2;
SetLength(txtbuf, l);
end;
Move(atext[1], txtbuf[txtlen+1], length(atext));
inc(txtlen, length(atext));
end;
procedure TRTFMemoParser.classUnk; procedure TRTFMemoParser.classUnk;
var var
txt : string; txt : string;
ws : UnicodeString; ws : UnicodeString;
begin begin
//writelN('unk: ', rtfMajor, ' ',rtfMinor,' ', rtfParam,' ', GetRtfText); if not Assigned(prm) then exit;
txt:=GetRtfText; txt:=GetRtfText;
if (txt='\object') then begin
SkipGroup;
Exit;
end;
if (length(txt)>2) and (txt[1]='\') and (txt[2]='u') and (txt[3] in ['0'..'9']) then begin if (length(txt)>2) and (txt[1]='\') and (txt[2]='u') and (txt[3] in ['0'..'9']) then begin
SetLength(Ws,1); SetLength(Ws,1);
ws[1]:=UnicodeChar(rtfParam); ws[1]:=UnicodeChar(rtfParam);
txtbuf:=txtbuf+UTF8Encode(ws); AddText( UTF8Encode(ws) );
txtlen:=length(txtbuf);
end; end;
end; end;
@ -288,27 +313,28 @@ var
txt : string; txt : string;
bt : Char; bt : Char;
begin begin
if not Assigned(prm) then exit;
txt:=Self.GetRtfText; txt:=Self.GetRtfText;
//writeln('txt: ', rtfMajor, ' ',rtfMinor,' ', rtfParam,' ',);
if (length(txt)=4) and (txt[1]='\') and (txt[2]=#39) then begin if (length(txt)=4) and (txt[1]='\') and (txt[2]=#39) then begin
if Assigned(langproc) then begin if Assigned(langproc) then begin
bt:=char(RTFCharToByte(txt)); bt:=char(RTFCharToByte(txt));
txtbuf:=txtbuf+langproc(bt);
txtlen:=length(txtbuf); AddText( langproc(bt) );
end; end;
end else end else begin
case rtfMinor of AddText(txt);
rtfOptDest: {skipping option generator};
else
txtbuf:=txtbuf+txt;
txtlen:=length(txtbuf);
end; end;
end; end;
procedure TRTFMemoParser.classControl; procedure TRTFMemoParser.classControl;
begin begin
if txtbuf<>'' then if not Assigned(prm) then exit;
if txtlen>0 then begin
PushText; PushText;
end;
//writeln('ctrl: ', rtfClass,' ', rtfMajor, ' ', Self.GetRtfText, ' ',rtfMinor,' ', rtfParam); //writeln('ctrl: ', rtfClass,' ', rtfMajor, ' ', Self.GetRtfText, ' ',rtfMinor,' ', rtfParam);
case rtfMajor of case rtfMajor of
rtfSpecialChar: doSpecialChar; rtfSpecialChar: doSpecialChar;
@ -321,6 +347,8 @@ procedure TRTFMemoParser.classGroup;
var var
t : TRTFParams; t : TRTFParams;
begin begin
if not Assigned(prm) then exit;
//todo: //todo:
Exit; Exit;
case rtfMajor of case rtfMajor of
@ -354,11 +382,9 @@ begin
rtfQuadCenter: prm.pa:=paCenter; rtfQuadCenter: prm.pa:=paCenter;
rtfFirstIndent: begin rtfFirstIndent: begin
prm.pm.FirstLine:=aparam / 20; prm.pm.FirstLine:=aparam / 20;
prm.pm.FirstLine:=prm.pm.FirstLine+prm.pm.HeadIndent;
end; end;
rtfLeftIndent: begin rtfLeftIndent: begin
prm.pm.HeadIndent:=aparam / 20; prm.pm.HeadIndent:=aparam / 20;
prm.pm.FirstLine:=prm.pm.FirstLine+prm.pm.HeadIndent;
end; end;
rtfRightIndent: prm.pm.TailIndent := aparam / 20; rtfRightIndent: prm.pm.TailIndent := aparam / 20;
rtfSpaceBefore: prm.pm.SpaceBefore := aparam / 20; rtfSpaceBefore: prm.pm.SpaceBefore := aparam / 20;
@ -385,9 +411,10 @@ const
CharLine = #13; CharLine = #13;
begin begin
case rtfMinor of case rtfMinor of
rtfLine: txtbuf:=txtbuf+CharLine; rtfOptDest: SkipGroup;
rtfPar: txtbuf:=txtbuf+CharPara; rtfLine: AddText(CharLine);
rtfTab: txtbuf:=txtbuf+CharTab; rtfPar: AddText(CharPara);
rtfTab: AddText(CharTab);
end; end;
end; end;
@ -414,8 +441,6 @@ const
,clSilver //clLightGray ,clSilver //clLightGray
); );
begin begin
if txtbuf<>'' then PushText;
case aminor of case aminor of
rtfPlain: prm.fnt.Style:=[]; rtfPlain: prm.fnt.Style:=[];
rtfBold: if aparam=0 then Exclude(prm.fnt.Style,fsBold) else Include(prm.fnt.Style, fsBold); rtfBold: if aparam=0 then Exclude(prm.fnt.Style,fsBold) else Include(prm.fnt.Style, fsBold);
@ -427,7 +452,15 @@ begin
rtfNoUnderline: Exclude(prm.fnt.Style, fsUnderline); rtfNoUnderline: Exclude(prm.fnt.Style, fsUnderline);
rtfHighlight: begin rtfHighlight: begin
prm.fnt.HasBkClr := (aparam>0) and (aparam<=high(HColor)); prm.fnt.HasBkClr := (aparam>0) and (aparam<=high(HColor));
if prm.fnt.HasBkClr then prm.fnt.BkColor:=HColor[aparam]; if prm.fnt.HasBkClr then begin
if HLFromCTable then prm.fnt.BkColor:=HColor[aparam]
else begin
p:=Colors[aparam];
if Assigned(p) then prm.fnt.BkColor:=RGBToColor(p^.rtfCRed, p^.rtfCGreen, p^.rtfCBlue)
// fallback?
else prm.fnt.BkColor:=HColor[aparam];
end;
end;
end; end;
rtfForeColor: begin rtfForeColor: begin
if rtfParam<>0 then p:=Colors[rtfParam] if rtfParam<>0 then p:=Colors[rtfParam]
@ -450,8 +483,16 @@ var
len : Integer; len : Integer;
pf : PRTFFONT; pf : PRTFFONT;
selst : Integer; selst : Integer;
b : string;
begin begin
len:=UTF8Length(txtbuf); if not Assigned(prm) then exit;
if txtlen=0 then Exit;
b:=Copy(txtbuf, 1, txtlen);
len:=UTF8Length(b);
txtlen:=0;
txtbuf:='';
if len=0 then Exit; if len=0 then Exit;
Memo.SelStart:=MaxInt; Memo.SelStart:=MaxInt;
@ -464,10 +505,13 @@ begin
Memo.SelStart:=selst; Memo.SelStart:=selst;
Memo.SelLength:=0; Memo.SelLength:=0;
Memo.SelText:=txtbuf; Memo.SelText:=b;
if Assigned(prm) then begin if Assigned(prm) then begin
prm.pm.FirstLine:=prm.pm.HeadIndent+prm.pm.FirstLine;
Memo.SetParaMetric(selst, 1, prm.pm ); Memo.SetParaMetric(selst, 1, prm.pm );
prm.pm.FirstLine:=prm.pm.FirstLine-prm.pm.HeadIndent;
Memo.SetParaAlignment(selst, 1, prm.pa ); Memo.SetParaAlignment(selst, 1, prm.pa );
end; end;
@ -481,7 +525,6 @@ begin
//prm.fnt.HasBkClr:=hasbk; //prm.fnt.HasBkClr:=hasbk;
//prm.fnt.BkColor:=bcolor; //prm.fnt.BkColor:=bcolor;
Memo.SetTextAttributes(selst, len, prm.fnt); Memo.SetTextAttributes(selst, len, prm.fnt);
txtbuf:='';
end; end;
constructor TRTFMemoParser.Create(AMemo:TCustomRichMemo;AStream:TStream); constructor TRTFMemoParser.Create(AMemo:TCustomRichMemo;AStream:TStream);