richmemo: refactoring in RTF loading

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3811 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
skalogryz
2014-11-28 22:09:46 +00:00
parent 9d9a2c6066
commit 2e8c900170
2 changed files with 125 additions and 46 deletions

View File

@ -14,6 +14,7 @@ procedure RegisterRTFLoader;
type type
TEncConvProc = function (const s: string): string; TEncConvProc = function (const s: string): string;
//todo: rewrite! it's not language based but fontchar-set based
procedure LangConvAdd(lang: Integer; convproc: TEncConvProc); procedure LangConvAdd(lang: Integer; convproc: TEncConvProc);
function LangConvGet(lang: Integer; var convproc: TEncConvProc): Boolean; function LangConvGet(lang: Integer; var convproc: TEncConvProc): Boolean;
@ -57,20 +58,27 @@ end;
type type
{ TRTFMemoParser } { TRTFMemoParser }
{ TRTFParams }
TRTFParams = class(TObject)
public
fnt : TFontParams;
pm : TParaMetric;
pa : TParaAlignment;
fnum : Integer; // font index in the font table
prev : TRTFParams;
constructor Create(aprev: TRTFParams);
end;
TRTFMemoParser = class(TRTFParser) TRTFMemoParser = class(TRTFParser)
private private
txtbuf : String; // keep it UTF8 encoded! txtbuf : String; // keep it UTF8 encoded!
fcolor : TColor; // Foreground color
txtlen : Integer; txtlen : Integer;
pm : TParaMetric; prm : TRTFParams;
pa : TParaAlignment; lang : Integer;
fnum: Integer; langproc : TEncConvProc;
fsz : double;
fst : TFontStyles;
lang : Integer;
langproc : TEncConvProc;
protected protected
procedure classUnk; procedure classUnk;
procedure classText; procedure classText;
@ -228,6 +236,22 @@ begin
LangConvAdd(1066, @CP1258ToUTF8); // vietnam LangConvAdd(1066, @CP1258ToUTF8); // vietnam
end; end;
{ TRTFParams }
constructor TRTFParams.Create(aprev: TRTFParams);
begin
prev:=aprev;
if Assigned(prev) then begin
fnt:=prev.fnt;
pm:=prev.pm;
pa:=prev.pa;
fnum:=prev.fnum;
end else begin
InitFontParams(fnt);
InitParaMetric(pm)
end;
end;
{ TRTFMemoParserr } { TRTFMemoParserr }
procedure TRTFMemoParser.classUnk; procedure TRTFMemoParser.classUnk;
@ -294,7 +318,22 @@ begin
end; end;
procedure TRTFMemoParser.classGroup; procedure TRTFMemoParser.classGroup;
var
t : TRTFParams;
begin begin
//todo:
Exit;
case rtfMajor of
rtfBeginGroup: begin
t:=TRTFParams.Create(prm);
prm:=t;
end;
rtfEndGroup: begin
t:=prm.prev;
prm.Free;
prm:=t;
end;
end;
//writeln('group: ', rtfMajor, ' ',rtfMinor,' ', rtfParam, ' ', GetRtfText); //writeln('group: ', rtfMajor, ' ',rtfMinor,' ', rtfParam, ' ', GetRtfText);
end; end;
@ -307,25 +346,24 @@ procedure TRTFMemoParser.doChangePara(aminor, aparam: Integer);
begin begin
case aminor of case aminor of
rtfParDef:begin rtfParDef:begin
FillChar(pm, sizeof(pm), 0); prm.pa:=paLeft;
pa:=paLeft;
end; end;
rtfQuadLeft: pa:=paLeft; rtfQuadLeft: prm.pa:=paLeft;
rtfQuadRight: pa:=paRight; rtfQuadRight: prm.pa:=paRight;
rtfQuadJust: pa:=paJustify; rtfQuadJust: prm.pa:=paJustify;
rtfQuadCenter: pa:=paCenter; rtfQuadCenter: prm.pa:=paCenter;
rtfFirstIndent: begin rtfFirstIndent: begin
pm.FirstLine:=aparam / 20; prm.pm.FirstLine:=aparam / 20;
pm.FirstLine:=pm.FirstLine+pm.HeadIndent; prm.pm.FirstLine:=prm.pm.FirstLine+prm.pm.HeadIndent;
end; end;
rtfLeftIndent: begin rtfLeftIndent: begin
pm.HeadIndent:=aparam / 20; prm.pm.HeadIndent:=aparam / 20;
pm.FirstLine:=pm.FirstLine+pm.HeadIndent; prm.pm.FirstLine:=prm.pm.FirstLine+prm.pm.HeadIndent;
end; end;
rtfRightIndent: pm.TailIndent := aparam / 20; rtfRightIndent: prm.pm.TailIndent := aparam / 20;
rtfSpaceBefore: pm.SpaceBefore := aparam / 20; rtfSpaceBefore: prm.pm.SpaceBefore := aparam / 20;
rtfSpaceAfter: pm.SpaceAfter := aparam / 20; rtfSpaceAfter: prm.pm.SpaceAfter := aparam / 20;
rtfSpaceBetween: pm.LineSpacing := aparam / 240; rtfSpaceBetween: prm.pm.LineSpacing := aparam / 240;
rtfLanguage: begin rtfLanguage: begin
lang:=rtfParam; lang:=rtfParam;
langproc:=nil; langproc:=nil;
@ -354,25 +392,48 @@ end;
procedure TRTFMemoParser.doChangeCharAttr(aminor, aparam: Integer); procedure TRTFMemoParser.doChangeCharAttr(aminor, aparam: Integer);
var var
p : PRTFColor; p : PRTFColor;
const
HColor : array [1..16] of TColor = (
clBlack
,clBlue
,clAqua // Cyan
,clLime // Green
,clFuchsia //Magenta
,clRed
,clYellow
,clGray // unused!
,clNavy // DarkBlue
,clTeal // DarkCyan
,clGreen // DarkGreen
,clPurple // clDarkMagenta
,clMaroon // clDarkRed
,clOlive // clDarkYellow
,clGray //clDarkGray
,clSilver //clLightGray
);
begin begin
if txtbuf<>'' then PushText; if txtbuf<>'' then PushText;
case aminor of case aminor of
rtfPlain: fst:=[]; rtfPlain: prm.fnt.Style:=[];
rtfBold: if aparam=0 then Exclude(fst,fsBold) else Include(fst, fsBold); rtfBold: if aparam=0 then Exclude(prm.fnt.Style,fsBold) else Include(prm.fnt.Style, fsBold);
rtfItalic: if aparam=0 then Exclude(fst,fsItalic) else Include(fst, fsItalic); rtfItalic: if aparam=0 then Exclude(prm.fnt.Style,fsItalic) else Include(prm.fnt.Style, fsItalic);
rtfStrikeThru: if aparam=0 then Exclude(fst,fsStrikeOut) else Include(fst, fsStrikeOut); rtfStrikeThru: if aparam=0 then Exclude(prm.fnt.Style,fsStrikeOut) else Include(prm.fnt.Style, fsStrikeOut);
rtfFontNum: fnum:=aparam; rtfFontNum: prm.fnum:=aparam;
rtfFontSize: fsz:=aparam/2; rtfFontSize: prm.fnt.Size:=round(aparam/2);
rtfUnderline: if aparam=0 then Exclude(fst,fsUnderline) else Include(fst, fsUnderline); rtfUnderline: if aparam=0 then Exclude(prm.fnt.Style,fsUnderline) else Include(prm.fnt.Style, fsUnderline);
rtfNoUnderline: Exclude(fst, fsUnderline); rtfNoUnderline: Exclude(prm.fnt.Style, fsUnderline);
rtfHighlight: begin
prm.fnt.HasBkClr := (aparam>0) and (aparam<=high(HColor));
if prm.fnt.HasBkClr then prm.fnt.BkColor:=HColor[aparam];
end;
rtfForeColor: begin rtfForeColor: begin
if rtfParam<>0 then p:=Colors[rtfParam] if rtfParam<>0 then p:=Colors[rtfParam]
else p:=nil; else p:=nil;
if not Assigned(p) then if not Assigned(p) then
fcolor:=DefaultTextColor prm.fnt.Color:=DefaultTextColor
else else
fcolor:=RGBToColor(p^.rtfCRed, p^.rtfCGreen, p^.rtfCBlue); prm.fnt.Color:=RGBToColor(p^.rtfCRed, p^.rtfCGreen, p^.rtfCBlue);
end; end;
end; end;
end; end;
@ -385,7 +446,6 @@ end;
procedure TRTFMemoParser.PushText; procedure TRTFMemoParser.PushText;
var var
len : Integer; len : Integer;
font : TFontParams;
pf : PRTFFONT; pf : PRTFFONT;
selst : Integer; selst : Integer;
begin begin
@ -404,17 +464,21 @@ begin
Memo.SelLength:=0; Memo.SelLength:=0;
Memo.SelText:=txtbuf; Memo.SelText:=txtbuf;
Memo.SetParaMetric(selst, 1, pm); if Assigned(prm) then begin
Memo.SetParaAlignment(selst, 1, pa); Memo.SetParaMetric(selst, 1, prm.pm );
Memo.SetParaAlignment(selst, 1, prm.pa );
end;
Memo.GetTextAttributes(selst, font); // Memo.GetTextAttributes(selst, font);
pf:=Fonts[fnum]; pf:=Fonts[prm.fnum];
if Assigned(pf) then if Assigned(pf) then
font.Name:=pf^.rtfFName; prm.fnt.Name:=pf^.rtfFName;
font.Size:=round(fsz); //prm.fnt.Size:=round(fsz);
font.Style:=fst; //prm.fnt.Style:=fst;
font.Color:=ColorToRGB(fColor); //prm.fnt.Color:=ColorToRGB(fColor);
Memo.SetTextAttributes(selst, len, font); //prm.fnt.HasBkClr:=hasbk;
//prm.fnt.BkColor:=bcolor;
Memo.SetTextAttributes(selst, len, prm.fnt);
txtbuf:=''; txtbuf:='';
end; end;
@ -430,14 +494,26 @@ begin
end; end;
procedure TRTFMemoParser.StartReading; procedure TRTFMemoParser.StartReading;
var
t : TRTFParams;
begin begin
Memo.Lines.BeginUpdate; Memo.Lines.BeginUpdate;
try try
fsz:=12;//\fsN Font size in half-points (the default is 24).
fnum:=0; prm:=TRTFParams.Create(nil);
prm.fnt.Size:=12; //\fsN Font size in half-points (the default is 24).
prm.fnum:=0;
inherited StartReading; inherited StartReading;
PushText; PushText;
// clear the stack, if overflow
while Assigned(prm) do begin
t:=prm.prev;
prm.Free;
prm:=t;
end;
Memo.SelStart:=0; Memo.SelStart:=0;
Memo.SelLength:=0; Memo.SelLength:=0;
finally finally
@ -471,6 +547,7 @@ function SaveStream(ARich: TcustomRichMemo; Dst: TStream): Boolean;
var var
p : TSaveParams; p : TSaveParams;
begin begin
writeln('saving stream!');
FillChar(p, sizeof(p), 0); FillChar(p, sizeof(p), 0);
p.start:=-1; p.start:=-1;
p.len:=-1; p.len:=-1;

View File

@ -334,6 +334,7 @@ const
rtfForeColor = 20; rtfForeColor = 20;
rtfBackColor = 21; rtfBackColor = 21;
rtfGray = 22; rtfGray = 22;
rtfHighlight = 23;
rtfPictAttr = 13; rtfPictAttr = 13;
rtfMacQD = 0; rtfMacQD = 0;
@ -468,7 +469,7 @@ type
---------------------------------------------------------------------} ---------------------------------------------------------------------}
const const
rtfKey : Array [0..283] of TRTFKey = rtfKey : Array [0..284] of TRTFKey =
( (
( rtfKMajor: RTFSPECIALCHAR; rtfKMinor : rtfCURHEADPICT; rtfKStr : 'chpict'; rtfKhash : 0), ( rtfKMajor: RTFSPECIALCHAR; rtfKMinor : rtfCURHEADPICT; rtfKStr : 'chpict'; rtfKhash : 0),
( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfCurHeadDate; rtfKstr : 'chdate'; rtfkHash : 0), ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfCurHeadDate; rtfKstr : 'chdate'; rtfkHash : 0),
@ -532,6 +533,7 @@ const
( rtfKMajor: rtfCharAttr; rtfKMinor: rtfForeColor; rtfKstr : 'cf'; rtfkHash : 0), ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfForeColor; rtfKstr : 'cf'; rtfkHash : 0),
( rtfKMajor: rtfCharAttr; rtfKMinor: rtfBackColor; rtfKstr : 'cb'; rtfkHash : 0), ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfBackColor; rtfKstr : 'cb'; rtfkHash : 0),
( rtfKMajor: rtfCharAttr; rtfKMinor: rtfGray; rtfKstr : 'gray'; rtfkHash : 0), ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfGray; rtfKstr : 'gray'; rtfkHash : 0),
( rtfKMajor: rtfCharAttr; rtfKMinor: rtfHighlight; rtfKstr : 'highlight'; rtfkHash : 0),
( rtfKMajor: rtfParAttr; rtfKMinor: rtfParDef; rtfKstr : 'pard'; rtfkHash : 0), ( rtfKMajor: rtfParAttr; rtfKMinor: rtfParDef; rtfKstr : 'pard'; rtfkHash : 0),
( rtfKMajor: rtfParAttr; rtfKMinor: rtfStyleNum; rtfKstr : 's'; rtfkHash : 0), ( rtfKMajor: rtfParAttr; rtfKMinor: rtfStyleNum; rtfKstr : 's'; rtfkHash : 0),