diff --git a/components/richmemo/richmemo.pas b/components/richmemo/richmemo.pas
index a937621ac..b7e85a39d 100644
--- a/components/richmemo/richmemo.pas
+++ b/components/richmemo/richmemo.pas
@@ -136,6 +136,10 @@ function GetFontParams(color: TColor; styles: TFontStyles): TFontParams; overloa
function GetFontParams(const Name: String; color: TColor; styles: TFontStyles): TFontParams; overload;
function GetFontParams(const Name: String; Size: Integer; color: TColor; styles: TFontStyles): TFontParams; overload;
+var
+ RTFLoadStream : function (AMemo: TCustomRichMemo; Source: TStream): Boolean = nil;
+ RTFSaveStream : function (AMemo: TCustomRichMemo; Dest: TStream): Boolean = nil;
+
implementation
function GetFontParams(styles: TFontStyles): TFontParams; overload;
@@ -307,17 +311,25 @@ end;
function TCustomRichMemo.LoadRichText(Source: TStream): Boolean;
begin
- if Assigned(Source) and HandleAllocated then
- Result := TWSCustomRichMemoClass(WidgetSetClass).LoadRichText(Self, Source)
- else
+ if Assigned(Source) and HandleAllocated then begin
+ Result := TWSCustomRichMemoClass(WidgetSetClass).LoadRichText(Self, Source);
+ if not Result and Assigned(RTFLoadStream) then begin
+ Self.Lines.BeginUpdate;
+ Self.Lines.Clear;
+ Result:=RTFLoadStream(Self, Source);
+ Self.Lines.EndUpdate;
+ end;
+ end else
Result := false;
end;
function TCustomRichMemo.SaveRichText(Dest: TStream): Boolean;
begin
- if Assigned(Dest) and HandleAllocated then
- Result := TWSCustomRichMemoClass(WidgetSetClass).SaveRichText(Self, Dest)
- else
+ if Assigned(Dest) and HandleAllocated then begin
+ Result := TWSCustomRichMemoClass(WidgetSetClass).SaveRichText(Self, Dest);
+ if not Result and Assigned(RTFSaveStream) then
+ Result:=RTFSaveStream(Self, Dest);
+ end else
Result := false;
end;
diff --git a/components/richmemo/richmemofactory.pas b/components/richmemo/richmemofactory.pas
index 7da4e4167..4b965c1a4 100644
--- a/components/richmemo/richmemofactory.pas
+++ b/components/richmemo/richmemofactory.pas
@@ -18,16 +18,20 @@ function RegisterCustomRichMemo: Boolean;
implementation
+{$define NoRichMemo}
+{$ifdef LCLWin32}{$undef NoRichMemo}{$endif}
+{$ifdef LCLCarbon}{$undef NoRichMemo}{$endif}
+{$ifdef LCLGtk2}{$undef NoRichMemo}{$endif}
+
function RegisterCustomRichMemo: Boolean; alias : 'WSRegisterCustomRichMemo';
var
cls : TWSLCLComponentClass;
begin
Result := True;
- {$ifdef LCLWin32}RegisterWSComponent(TCustomRichMemo, TWin32WSCustomRichMemo);
- {$elif LCLCarbon}RegisterWSComponent(TCustomRichMemo, TCarbonWSCustomRichMemo);
- {$elif LCLGtk2}RegisterWSComponent(TCustomRichMemo, TGtk2WSCustomRichMemo);
- {$else}RegisterWSComponent(TCustomRichMemo, TWSCustomRichMemo);
- {$endif}
+ {$ifdef LCLWin32}RegisterWSComponent(TCustomRichMemo, TWin32WSCustomRichMemo);{$endif}
+ {$ifdef LCLCarbon}RegisterWSComponent(TCustomRichMemo, TCarbonWSCustomRichMemo);{$endif}
+ {$ifdef LCLGtk2}RegisterWSComponent(TCustomRichMemo, TGtk2WSCustomRichMemo);{$endif}
+ {$ifdef NoRichMemo}RegisterWSComponent(TCustomRichMemo, TWSCustomRichMemo);{$endif}
cls:=FindWSComponentClass(TCustomRichMemo);
if not Assigned(cls) then RegisterWSComponent(TCustomRichMemo, TWSCustomRichMemo);
end;
diff --git a/components/richmemo/richmemopackage.lpk b/components/richmemo/richmemopackage.lpk
index 26d847079..2f8e61bc3 100644
--- a/components/richmemo/richmemopackage.lpk
+++ b/components/richmemo/richmemopackage.lpk
@@ -22,7 +22,7 @@
"/>
-
+
@@ -66,6 +66,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/richmemo/richmemortf.pas b/components/richmemo/richmemortf.pas
new file mode 100644
index 000000000..92c18dbb8
--- /dev/null
+++ b/components/richmemo/richmemortf.pas
@@ -0,0 +1,94 @@
+unit RichMemoRTF;
+
+interface
+
+uses
+ Classes, SysUtils, LCLProc, LCLIntf,
+ RichMemo, RTFParsPre211;
+
+//todo: formatting support!
+
+function MVCParserLoadStream(ARich: TCustomRichMemo; Source: TStream): Boolean;
+
+implementation
+
+type
+ { TRTFMemoParser }
+
+ TRTFMemoParser = class(TRTFParser)
+ protected
+ procedure classText;
+ procedure classControl;
+
+ procedure doSpecialChar;
+ public
+ txt : String;
+ Memo : TCustomRichMemo;
+ constructor Create(AMemo: TCustomRichMemo; AStream: TStream);
+ end;
+
+
+{ TRTFMemoParserr }
+procedure TRTFMemoParser.classText;
+begin
+ //writeln('txt: ', rtfMajor, ' ',rtfMinor,' ', rtfParam);
+ case rtfMinor of
+ rtfOptDest:;
+ else
+ txt:=txt+Self.GetRtfText;
+ end;
+end;
+
+procedure TRTFMemoParser.classControl;
+begin
+ //writeln('ctrl: ', rtfClass,' ', rtfMajor, ' ', Self.GetRtfText, ' ',rtfMinor,' ', rtfParam);
+ case rtfMajor of
+ rtfSpecialChar: doSpecialChar;
+ end;
+end;
+
+procedure TRTFMemoParser.doSpecialChar;
+const
+ CharPara = #10;
+ CharTab = #9;
+ CharLine = #13;
+begin
+ case rtfMinor of
+ rtfLine: txt:=txt+CharLine;
+ rtfPar: txt:=txt+CharPara;
+ rtfTab: txt:=txt+CharTab;
+ end;
+end;
+
+constructor TRTFMemoParser.Create(AMemo:TCustomRichMemo;AStream:TStream);
+begin
+ inherited Create(AStream);
+ Memo:=AMemo;
+ ClassCallBacks[rtfText]:=@classText;
+ ClassCallBacks[rtfControl]:=@classControl;
+end;
+
+function MVCParserLoadStream(ARich: TCustomRichMemo; Source: TStream): Boolean;
+var
+ p : TRTFMemoParser;
+begin
+ Result:=Assigned(ARich) and Assigned(Source);
+ if not Result then Exit;
+
+ p:=TRTFMemoParser.Create(ARich, Source);
+ try
+ p.StartReading;
+ ARich.SelStart:=0;
+ ARich.SelLength:=0;
+ ARich.Text:=p.txt;
+ finally
+ p.Free;
+ end;
+ Result:=True;
+end;
+
+initialization
+ RTFLoadStream:=@MVCParserLoadStream;
+
+
+end.
diff --git a/components/richmemo/rtfdata.inc b/components/richmemo/rtfdata.inc
new file mode 100644
index 000000000..1c58932bb
--- /dev/null
+++ b/components/richmemo/rtfdata.inc
@@ -0,0 +1,768 @@
+{
+ This file is part of the Free Pascal run time library.
+ Copyright (c) 1999-2000 by Michael Van Canneyt, member of the
+ Free Pascal development team
+
+ All major and minor RTF class definitions.
+
+ See the file COPYING.FPC, included in this distribution,
+ for details about the copyright.
+
+ 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.
+
+ **********************************************************************}
+
+{ ---------------------------------------------------------------------
+ Twentieths of a point (twips) per inch (Many RTF measurements
+ are in twips per inch (tpi) units). Assumes 72 points/inch.
+ ---------------------------------------------------------------------}
+
+const
+ rtfTpi = 1440;
+ rtfBufSiz = 255; { buffer size}
+
+{ ---------------------------------------------------------------------
+ Tokens are associated with up to three classification numbers:
+
+ Class number: Broadest (least detailed) breakdown. For programs
+ that only care about gross token distinctions.
+ Major/minor numbers: Within their class, tokens have a major
+ number, and may also have a minor number to further
+ distinquish tokens with the same major number.
+
+ *** Class, major and minor token numbers are all >= 0 ***
+
+ Tokens that can't be classified are put in the "unknown" class.
+ For such, the major and minor numbers are meaningless, although
+ rtfTextBuf may be of interest then.
+
+ Text tokens are a single character, and the major number indicates
+ the character value (note: can be non-ascii, i.e., greater than 127).
+ There is no minor number.
+
+ Control symbols may have a parameter value, which will be found in
+ rtfParam. If no parameter was given, rtfParam = rtfNoParam.
+
+ RTFGetToken() return value is the class number, but it sets all the
+ global token vars.
+
+ rtfEOF is a fake token used by the reader; the writer never sees
+ it (except in the token reader hook, if it installs one).
+
+ Information pertaining to last token read by RTFToken. The
+ text is exactly as it occurs in the input file, e.g.,
+ will be found in rtfTextBuf as, even though it means .
+
+ These variables are also set when styles are reprocessed.
+ ----------------------------------------------------------------------}
+ rtfNoParam = (-1000000);
+
+ { Token classes (zero-based and sequential) }
+ rtfUnknown = 0;
+ rtfGroup = 1;
+ rtfText = 2;
+ rtfControl = 3;
+ rtfEOF = 4;
+ rtfMaxClass = 5 { highest class + 1 };
+
+ { Group class major numbers }
+ rtfBeginGroup = 0;
+ rtfEndGroup = 1;
+
+ { Control class major and minor numbers.}
+ rtfVersion = 0;
+ rtfDefFont = 1;
+ rtfCharSet = 2;
+ rtfAnsiCharSet = 0;
+ rtfMacCharSet = 1;
+ rtfPcCharSet = 2;
+ rtfPcaCharSet = 3;
+
+ { Destination minor numbers should be zero-based, sequential }
+ rtfDestination = 3;
+ rtfPict = 0;
+ rtfNeXTGraphic = 1;
+ rtfFootnote = 2;
+ rtfHeader = 3;
+ rtfHeaderLeft = 4;
+ rtfHeaderRight = 5;
+ rtfHeaderFirst = 6;
+ rtfFooter = 7;
+ rtfFooterLeft = 8;
+ rtfFooterRight = 9;
+ rtfFooterFirst = 10;
+ rtfFNSep = 11;
+ rtfFNContSep = 12;
+ rtfFNContNotice = 13;
+ rtfInfo = 14;
+ rtfStyleSheet = 15;
+ rtfFontTbl = 16;
+ rtfColorTbl = 17;
+ rtfField = 18;
+ rtfFieldInst = 19;
+ rtfFieldResult = 20;
+ rtfIndex = 21;
+ rtfIndexBold = 22;
+ rtfIndexItalic = 23;
+ rtfIndexText = 24;
+ rtfIndexRange = 25;
+ rtfTOC = 26;
+ rtfBookmarkStart = 27;
+ rtfBookmarkEnd = 28;
+ rtfITitle = 29;
+ rtfISubject = 30;
+ rtfIAuthor = 31;
+ rtfIOperator = 32;
+ rtfIKeywords = 33;
+ rtfIComment = 34;
+ rtfIVersion = 35;
+ rtfIDoccomm = 36;
+ rtfMaxDestination = 37 { highest dest + 1 };
+
+ rtfFontFamily = 4;
+ rtfFFNil = 0;
+ rtfFFRoman = 1;
+ rtfFFSwiss = 2;
+ rtfFFModern = 3;
+ rtfFFScript = 4;
+ rtfFFDecor = 5;
+ rtfFFTech = 6;
+
+ rtfColorName = 5;
+ rtfRed = 0;
+ rtfGreen = 1;
+ rtfBlue = 2;
+
+ rtfSpecialChar = 6;
+ rtfCurHeadPage = 0;
+ rtfCurFNote = 1;
+ rtfCurHeadPict = 2 { valid? };
+ rtfCurHeadDate = 3;
+ rtfCurHeadTime = 4;
+ rtfFormula = 5;
+ rtfNoBrkSpace = 6;
+ rtfNoReqHyphen = 7;
+ rtfNoBrkHyphen = 8;
+ rtfPage = 9;
+ rtfLine = 10;
+ rtfPar = 11;
+ rtfSect = 12;
+ rtfTab = 13;
+ rtfCell = 14;
+ rtfRow = 15;
+ rtfCurAnnot = 16;
+ rtfAnnotation = 17;
+ rtfAnnotID = 18;
+ rtfCurAnnotRef = 19;
+ rtfFNoteSep = 20;
+ rtfFNoteCont = 21;
+ rtfColumn = 22;
+ rtfOptDest = 23;
+ rtfIIntVersion = 24;
+ rtfICreateTime = 25;
+ rtfIRevisionTime = 26;
+ rtfIPrintTime = 27;
+ rtfIBackupTime = 28;
+ rtfIEditTime = 29;
+ rtfIYear = 30;
+ rtfIMonth = 31;
+ rtfIDay = 32;
+ rtfIHour = 33;
+ rtfIMinute = 34;
+ rtfINPages = 35;
+ rtfINWords = 36;
+ rtfINChars = 37;
+ rtfIIntID = 38;
+
+ rtfStyleAttr = 7;
+ rtfBasedOn = 0;
+ rtfNext = 1;
+
+ rtfDocAttr = 8;
+ rtfPaperWidth = 0;
+ rtfPaperHeight = 1;
+ rtfLeftMargin = 2;
+ rtfRightMargin = 3;
+ rtfTopMargin = 4;
+ rtfBottomMargin = 5;
+ rtfFacingPage = 6;
+ rtfGutterWid = 7;
+ rtfDefTab = 8;
+ rtfWidowCtrl = 9;
+ rtfHyphHotZone = 10;
+ rtfFNoteEndSect = 11;
+ rtfFNoteEndDoc = 12;
+ rtfFNoteText = 13;
+ rtfFNoteBottom = 14;
+ rtfFNoteStart = 15;
+ rtfFNoteRestart = 16;
+ rtfPageStart = 17;
+ rtfLineStart = 18;
+ rtfLandscape = 19;
+ rtfFracWidth = 20;
+ rtfNextFile = 21;
+ rtfTemplate = 22;
+ rtfMakeBackup = 23;
+ rtfRTFDefault = 24;
+ rtfRevisions = 25;
+ rtfMirrorMargin = 26;
+ rtfRevDisplay = 27;
+ rtfRevBar = 28;
+
+ rtfSectAttr = 9;
+ rtfSectDef = 0;
+ rtfNoBreak = 1;
+ rtfColBreak = 2;
+ rtfPageBreak = 3;
+ rtfEvenBreak = 4;
+ rtfOddBreak = 5;
+ rtfPageStarts = 6;
+ rtfPageCont = 7;
+ rtfPageRestart = 8;
+ rtfPageDecimal = 9;
+ rtfPageURoman = 10;
+ rtfPageLRoman = 11;
+ rtfPageULetter = 12;
+ rtfPageLLetter = 13;
+ rtfPageNumLeft = 14;
+ rtfPageNumTop = 15;
+ rtfHeaderY = 16;
+ rtfFooterY = 17;
+ rtfLineModulus = 18;
+ rtfLineDist = 19;
+ rtfLineStarts = 20;
+ rtfLineRestart = 21;
+ rtfLineRestartPg = 22;
+ rtfLineCont = 23;
+ rtfTopVAlign = 24;
+ rtfBottomVAlign = 25;
+ rtfCenterVAlign = 26;
+ rtfJustVAlign = 27;
+ rtfColumns = 28;
+ rtfColumnSpace = 29;
+ rtfColumnLine = 30;
+ rtfENoteHere = 31;
+ rtfTitleSpecial = 32;
+
+ rtfTblAttr = 10;
+ rtfCellBordBottom = 0;
+ rtfCellBordTop = 1;
+ rtfCellBordLeft = 2;
+ rtfCellBordRight = 3;
+ rtfRowDef = 4;
+ rtfRowLeft = 5;
+ rtfRowRight = 6;
+ rtfRowCenter = 7;
+ rtfRowGapH = 8;
+ rtfRowHt = 9;
+ rtfRowLeftEdge = 10;
+ rtfCellPos = 11;
+ rtfMergeRngFirst = 12;
+ rtfMergePrevious = 13;
+
+ rtfParAttr = 11;
+ rtfParDef = 0;
+ rtfStyleNum = 1;
+ rtfQuadLeft = 2;
+ rtfQuadRight = 3;
+ rtfQuadJust = 4;
+ rtfQuadCenter = 5;
+ rtfFirstIndent = 6;
+ rtfLeftIndent = 7;
+ rtfRightIndent = 8;
+ rtfSpaceBefore = 9;
+ rtfSpaceAfter = 10;
+ rtfSpaceBetween = 11;
+ rtfInTable = 12;
+ rtfKeep = 13;
+ rtfKeepNext = 14;
+ rtfSideBySide = 15;
+ rtfPBBefore = 16;
+ rtfNoLineNum = 17;
+ rtfTabPos = 18;
+ rtfTabRight = 19;
+ rtfTabCenter = 20;
+ rtfTabDecimal = 21;
+ rtfTabBar = 22;
+ rtfBorderTop = 23;
+ rtfBorderBottom = 24;
+ rtfBorderLeft = 25;
+ rtfBorderRight = 26;
+ rtfBorderBox = 27;
+ rtfBorderBar = 28;
+ rtfBorderBetween = 29;
+ rtfBorderSingle = 30;
+ rtfBorderThick = 31;
+ rtfBorderShadow = 32;
+ rtfBorderDouble = 33;
+ rtfBorderDot = 34;
+ rtfBorderHair = 35;
+ rtfBorderSpace = 36;
+ rtfLeaderDot = 37;
+ rtfLeaderHyphen = 38;
+ rtfLeaderUnder = 39;
+ rtfLeaderThick = 40;
+
+ rtfCharAttr = 12;
+ rtfPlain = 0;
+ rtfBold = 1;
+ rtfItalic = 2;
+ rtfStrikeThru = 3;
+ rtfOutline = 4;
+ rtfShadow = 5;
+ rtfSmallCaps = 6;
+ rtfAllCaps = 7;
+ rtfInvisible = 8;
+ rtfFontNum = 9;
+ rtfFontSize = 10;
+ rtfExpand = 11;
+ rtfUnderline = 12;
+ rtfWUnderline = 13;
+ rtfDUnderline = 14;
+ rtfDbUnderline = 15;
+ rtfNoUnderline = 16;
+ rtfSuperScript = 17;
+ rtfSubScript = 18;
+ rtfRevised = 19;
+ rtfForeColor = 20;
+ rtfBackColor = 21;
+ rtfGray = 22;
+
+ rtfPictAttr = 13;
+ rtfMacQD = 0;
+ rtfWinMetafile = 1;
+ rtfWinBitmap = 2;
+ rtfPicWid = 3;
+ rtfPicHt = 4;
+ rtfPicGoalWid = 5;
+ rtfPicGoalHt = 6;
+ rtfPicScaleX = 7;
+ rtfPicScaleY = 8;
+ rtfPicScaled = 9;
+ rtfPicCropTop = 10;
+ rtfPicCropBottom = 11;
+ rtfPicCropLeft = 12;
+ rtfPicCropRight = 13;
+ rtfPixelBits = 14;
+ rtfBitmapPlanes = 15;
+ rtfBitmapWid = 16;
+ rtfPicBinary = 17;
+
+ rtfNeXTGrAttr = 14;
+ rtfNeXTGWidth = 0;
+ rtfNeXTGHeight = 1;
+
+ rtfFieldAttr = 15;
+ rtfFieldDirty = 0;
+ rtfFieldEdited = 1;
+ rtfFieldLocked = 2;
+ rtfFieldPrivate = 3;
+
+ rtfTOCAttr = 16;
+ rtfTOCType = 0;
+ rtfTOCLevel = 1;
+
+ rtfPosAttr = 17;
+ rtfPosX = 0;
+ rtfPosXCenter = 1;
+ rtfPosXInside = 2;
+ rtfPosXLeft = 3;
+ rtfPosXOutSide = 4;
+ rtfPosXRight = 5;
+ rtfPosY = 6;
+ rtfPosYInline = 7;
+ rtfPosYTop = 8;
+ rtfPosYCenter = 9;
+ rtfPosYBottom = 10;
+ rtfAbsWid = 11;
+ rtfTextDist = 12;
+ rtfRPosMargV = 13;
+ rtfRPosPageV = 14;
+ rtfRPosMargH = 15;
+ rtfRPosPageH = 16;
+ rtfRPosColH = 17;
+
+ rtfBasedOnNone = 222; { "no based-on style" }
+
+
+type
+
+{ ---------------------------------------------------------------------
+ Callback Types
+ ---------------------------------------------------------------------}
+
+ TRTFFunc = Procedure of object;
+ TRTFFuncPtr = procedure of object;
+
+{ ---------------------------------------------------------------------
+ RTF font, color and style structures. Used for font table,
+ color table, and stylesheet processing.
+ ---------------------------------------------------------------------}
+
+ PRTFFONT = ^TRTFFONT;
+ TRTFFont = Record
+ rtfFName : string; { font name }
+ rtfFNum : integer; { font number }
+ rtfFFamily : integer; { font family }
+ rtfNextFont : PRTFFONT; { next font in list }
+ end;
+
+
+{ ----------------------------------------------------------------------
+ Color values are -1 if the default color for the the color
+ number should be used. The default color is writer-dependent.
+ ----------------------------------------------------------------------}
+
+ PRTFColor = ^TRTFColor;
+ TRTFColor = Record
+ rtfCNum : integer; { color number }
+ rtfCRed : INteger; { red value }
+ rtfCGreen : INteger; { green value }
+ rtfCBlue : integer; { blue value }
+ rtfNextColor : PRTFColor; { next color in list }
+ end;
+
+ PRTFStyleElt = ^TRTFStyleElt;
+ TRTFStyleElt = record
+ rtfSEClass, { token class }
+ rtfSEMajor, { token major number }
+ rtfSEMinor, { token minor number }
+ rtfSEParam : Integer; { control symbol parameter }
+ rtfSEText : String; { text of symbol }
+ rtfNextSE : PRTFStyleElt; { next element in style }
+ end;
+
+ PRTFSTyle = ^TRTFStyle;
+ TRTFStyle = record
+ rtfSName : string; { style name }
+ rtfSNum, { style number }
+ rtfSBasedOn, { style this one's based on }
+ rtfSNextPar : integer; { style next paragraph style }
+ rtfSSEList : PRTFStyleElt; { list of style words }
+ rtfExpanding : Integer; { non-zero = being expanded }
+ rtfNextStyle : PRTFStyle; { next style in style list }
+ end;
+
+{ ---------------------------------------------------------------------
+ Control symbol lookup routines
+ ---------------------------------------------------------------------}
+
+type
+ TRTFKey = record
+ rtfKMajor : Integer; { major number }
+ rtfKMinor : Integer; { minor number }
+ rtfKStr : string[20]; { symbol name }
+ rtfKHash : Integer; { symbol name hash value }
+ end;
+
+{ ---------------------------------------------------------------------
+ A minor number of -1 means the token has no minor number
+ (all valid minor numbers are >= 0).
+ ---------------------------------------------------------------------}
+
+const
+ rtfKey : Array [0..281] of TRTFKey =
+ (
+ ( rtfKMajor: RTFSPECIALCHAR; rtfKMinor : rtfCURHEADPICT; rtfKStr : 'chpict'; rtfKhash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfCurHeadDate; rtfKstr : 'chdate'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfCurHeadTime; rtfKstr : 'chtime'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfCurHeadPage; rtfKstr : 'chpgn'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfCurFNote; rtfKstr : 'chftn'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfCurAnnotRef; rtfKstr : 'chatn'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfFNoteSep; rtfKstr : 'chftnsep'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfFNoteCont; rtfKstr : 'chftnsepc'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfFormula; rtfKstr : '|'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfNoBrkSpace; rtfKstr : '~'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfNoReqHyphen; rtfKstr : '-'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfNoBrkHyphen; rtfKstr : '_'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfCell; rtfKstr : 'cell'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfRow; rtfKstr : 'row'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfPar; rtfKstr : 'par'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfPar; rtfKstr : #10; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfPar; rtfKstr : #13; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfSect; rtfKstr : 'sect'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfPage; rtfKstr : 'page'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfColumn; rtfKstr : 'column'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfLine; rtfKstr : 'line'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfTab; rtfKstr : 'tab'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfOptDest; rtfKstr : '*'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfIIntVersion; rtfKstr : 'vern'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfICreateTime; rtfKstr : 'creatim'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfIRevisionTime; rtfKstr : 'revtim'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfIPrintTime; rtfKstr : 'printim'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfIBackupTime; rtfKstr : 'buptim'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfIEditTime; rtfKstr : 'edmins'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfIYear; rtfKstr : 'yr'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfIMonth; rtfKstr : 'mo'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfIDay; rtfKstr : 'dy'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfIHour; rtfKstr : 'hr'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfIMinute; rtfKstr : 'min'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfINPages; rtfKstr : 'nofpages'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfINWords; rtfKstr : 'nofwords'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfINChars; rtfKstr : 'nofchars'; rtfkHash : 0),
+ ( rtfKMajor: rtfSpecialChar; rtfKMinor: rtfIIntID; rtfKstr : 'id'; rtfkHash : 0),
+
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfPlain; rtfKstr : 'plain'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfBold; rtfKstr : 'b'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfItalic; rtfKstr : 'i'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfStrikeThru; rtfKstr : 'strike'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfOutline; rtfKstr : 'outl'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfShadow; rtfKstr : 'shad'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfSmallCaps; rtfKstr : 'scaps'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfAllCaps; rtfKstr : 'caps'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfInvisible; rtfKstr : 'v'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfFontNum; rtfKstr : 'f'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfFontSize; rtfKstr : 'fs'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfExpand; rtfKstr : 'expnd'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfUnderline; rtfKstr : 'ul'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfWUnderline; rtfKstr : 'ulw'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfDUnderline; rtfKstr : 'uld'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfDbUnderline; rtfKstr : 'uldb'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfNoUnderline; rtfKstr : 'ulnone'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfSuperScript; rtfKstr : 'up'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfSubScript; rtfKstr : 'dn'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfRevised; rtfKstr : 'revised'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfForeColor; rtfKstr : 'cf'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfBackColor; rtfKstr : 'cb'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharAttr; rtfKMinor: rtfGray; rtfKstr : 'gray'; rtfkHash : 0),
+
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfParDef; rtfKstr : 'pard'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfStyleNum; rtfKstr : 's'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfQuadLeft; rtfKstr : 'ql'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfQuadRight; rtfKstr : 'qr'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfQuadJust; rtfKstr : 'qj'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfQuadCenter; rtfKstr : 'qc'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfFirstIndent; rtfKstr : 'fi'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfLeftIndent; rtfKstr : 'li'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfRightIndent; rtfKstr : 'ri'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfSpaceBefore; rtfKstr : 'sb'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfSpaceAfter; rtfKstr : 'sa'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfSpaceBetween; rtfKstr : 'sl'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfInTable; rtfKstr : 'intbl'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfKeep; rtfKstr : 'keep'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfKeepNext; rtfKstr : 'keepn'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfSideBySide; rtfKstr : 'sbys'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfPBBefore; rtfKstr : 'pagebb'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfNoLineNum; rtfKstr : 'noline'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfTabPos; rtfKstr : 'tx'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfTabRight; rtfKstr : 'tqr'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfTabCenter; rtfKstr : 'tqc'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfTabDecimal; rtfKstr : 'tqdec'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfTabBar; rtfKstr : 'tb'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfBorderTop; rtfKstr : 'brdrt'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfBorderBottom; rtfKstr : 'brdrb'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfBorderLeft; rtfKstr : 'brdrl'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfBorderRight; rtfKstr : 'brdrr'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfBorderBar; rtfKstr : 'bar'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfBorderBox; rtfKstr : 'box'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfBorderBetween; rtfKstr : 'brdrbtw'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfBorderSingle; rtfKstr : 'brdrs'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfBorderThick; rtfKstr : 'brdrth'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfBorderShadow; rtfKstr : 'brdrsh'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfBorderDouble; rtfKstr : 'brdrdb'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfBorderDot; rtfKstr : 'brdrdot'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfBorderHair; rtfKstr : 'brdrhair'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfLeaderDot; rtfKstr : 'tldot'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfLeaderHyphen; rtfKstr : 'tlhyph'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfLeaderUnder; rtfKstr : 'tlul'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfLeaderThick; rtfKstr : 'tlth'; rtfkHash : 0),
+ ( rtfKMajor: rtfParAttr; rtfKMinor: rtfBorderSpace; rtfKstr : 'brsp'; rtfkHash : 0),
+
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfSectDef; rtfKstr : 'sectd'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfNoBreak; rtfKstr : 'sbknone'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfColBreak; rtfKstr : 'sbkcol'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfPageBreak; rtfKstr : 'sbkpage'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfEvenBreak; rtfKstr : 'sbkeven'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfOddBreak; rtfKstr : 'sbkodd'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfPageCont; rtfKstr : 'pgncont'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfPageStarts; rtfKstr : 'pgnstarts'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfPageRestart; rtfKstr : 'pgnrestart'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfPageDecimal; rtfKstr : 'pgndec'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfPageURoman; rtfKstr : 'pgnucrm'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfPageLRoman; rtfKstr : 'pgnlcrm'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfPageULetter; rtfKstr : 'pgnucltr'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfPageLLetter; rtfKstr : 'pgnlcltr'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfPageNumLeft; rtfKstr : 'pgnx'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfPageNumTop; rtfKstr : 'pgny'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfHeaderY; rtfKstr : 'headery'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfFooterY; rtfKstr : 'footery'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfLineModulus; rtfKstr : 'linemod'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfLineDist; rtfKstr : 'linex'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfLineStarts; rtfKstr : 'linestarts'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfLineRestart; rtfKstr : 'linerestart'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfLineRestartPg; rtfKstr : 'lineppage'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfLineCont; rtfKstr : 'linecont'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfTopVAlign; rtfKstr : 'vertalt'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfBottomVAlign; rtfKstr : 'vertal'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfCenterVAlign; rtfKstr : 'vertalc'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfJustVAlign; rtfKstr : 'vertalj'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfColumns; rtfKstr : 'cols'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfColumnSpace; rtfKstr : 'colsx'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfColumnLine; rtfKstr : 'linebetcol'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfENoteHere; rtfKstr : 'endnhere'; rtfkHash : 0),
+ ( rtfKMajor: rtfSectAttr; rtfKMinor: rtfTitleSpecial; rtfKstr : 'titlepg'; rtfkHash : 0),
+
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfPaperWidth; rtfKstr : 'paperw'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfPaperHeight; rtfKstr : 'paperh'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfLeftMargin; rtfKstr : 'margl'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfRightMargin; rtfKstr : 'margr'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfTopMargin; rtfKstr : 'margt'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfBottomMargin; rtfKstr : 'margb'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfFacingPage; rtfKstr : 'facingp'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfGutterWid; rtfKstr : 'gutter'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfDefTab; rtfKstr : 'deftab'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfWidowCtrl; rtfKstr : 'widowctrl'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfHyphHotZone; rtfKstr : 'hyphhotz'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfFNoteEndSect; rtfKstr : 'endnotes'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfFNoteEndDoc; rtfKstr : 'enddoc'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfFNoteBottom; rtfKstr : 'ftnbj'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfFNoteText; rtfKstr : 'ftntj'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfFNoteStart; rtfKstr : 'ftnstart'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfFNoteRestart; rtfKstr : 'ftnrestart'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfPageStart; rtfKstr : 'pgnstart'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfLineStart; rtfKstr : 'linestart'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfLandscape; rtfKstr : 'landscape'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfFracWidth; rtfKstr : 'fracwidth'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfNextFile; rtfKstr : 'nextfile'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfTemplate; rtfKstr : 'template'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfMakeBackup; rtfKstr : 'makeback'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfRTFDefault; rtfKstr : 'defformat'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfRevisions; rtfKstr : 'revisions'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfMirrorMargin; rtfKstr : 'margmirror'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfRevDisplay; rtfKstr : 'revprop'; rtfkHash : 0),
+ ( rtfKMajor: rtfDocAttr; rtfKMinor: rtfRevBar; rtfKstr : 'revbar'; rtfkHash : 0),
+
+ ( rtfKMajor: rtfStyleAttr; rtfKMinor: rtfBasedOn; rtfKstr : 'sbasedon'; rtfkHash : 0),
+ ( rtfKMajor: rtfStyleAttr; rtfKMinor: rtfNext; rtfKstr : 'snext'; rtfkHash : 0),
+
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfMacQD; rtfKstr : 'macpict'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfWinMetafile; rtfKstr : 'wmetafile'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfWinBitmap; rtfKstr : 'wbitmap'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfPicWid; rtfKstr : 'picw'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfPicHt; rtfKstr : 'pich'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfPicGoalWid; rtfKstr : 'picwgoal'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfPicGoalWid; rtfKstr : 'picwGoal'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfPicGoalHt; rtfKstr : 'pichgoal'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfPicGoalHt; rtfKstr : 'pichGoal'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfPicScaleX; rtfKstr : 'picscalex'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfPicScaleY; rtfKstr : 'picscaley'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfPicScaled; rtfKstr : 'picscaled'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfPicCropTop; rtfKstr : 'piccropt'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfPicCropBottom; rtfKstr : 'piccropb'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfPicCropLeft; rtfKstr : 'piccropl'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfPicCropRight; rtfKstr : 'piccropr'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfPixelBits; rtfKstr : 'wbmbitspixel'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfBitmapPlanes; rtfKstr : 'wbmplanes'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfBitmapWid; rtfKstr : 'wbmwidthbytes'; rtfkHash : 0),
+ ( rtfKMajor: rtfPictAttr; rtfKMinor: rtfPicBinary; rtfKstr : 'bin'; rtfkHash : 0),
+
+ ( rtfKMajor: rtfNeXTGrAttr; rtfKMinor: rtfNeXTGWidth; rtfKstr : 'width'; rtfkHash : 0),
+ ( rtfKMajor: rtfNeXTGrAttr; rtfKMinor: rtfNeXTGHeight; rtfKstr : 'height'; rtfkHash : 0),
+
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfPict; rtfKstr : 'pict'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfNeXTGraphic; rtfKstr : 'NeXTGraphic'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfFootnote; rtfKstr : 'footnote'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfHeader; rtfKstr : 'header'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfHeaderLeft; rtfKstr : 'headerl'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfHeaderRight; rtfKstr : 'headerr'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfHeaderFirst; rtfKstr : 'headerf'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfFooter; rtfKstr : 'footer'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfFooterLeft; rtfKstr : 'footerl'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfFooterRight; rtfKstr : 'footerr'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfFooterFirst; rtfKstr : 'footerf'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfFNSep; rtfKstr : 'ftnsep'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfFNContSep; rtfKstr : 'ftnsepc'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfFNContNotice; rtfKstr : 'ftncn'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfInfo; rtfKstr : 'info'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfStyleSheet; rtfKstr : 'stylesheet'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfFontTbl; rtfKstr : 'fonttbl'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfColorTbl; rtfKstr : 'colortbl'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfAnnotation; rtfKstr : 'annotation'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfAnnotID; rtfKstr : 'atnid'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfField; rtfKstr : 'field'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfFieldInst; rtfKstr : 'fldinst'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfFieldResult; rtfKstr : 'fldrslt'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfIndex; rtfKstr : 'xe'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfIndexBold; rtfKstr : 'bxe'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfIndexItalic; rtfKstr : 'ixe'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfIndexText; rtfKstr : 'txe'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfIndexRange; rtfKstr : 'rxe'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfTOC; rtfKstr : 'tc'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfBookmarkStart; rtfKstr : 'bkmkstart'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfBookmarkEnd; rtfKstr : 'bkmkend'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfITitle; rtfKstr : 'title'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfISubject; rtfKstr : 'subject'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfIAuthor; rtfKstr : 'author'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfIOperator; rtfKstr : 'operator'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfIKeywords; rtfKstr : 'keywords'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfIComment; rtfKstr : 'comment'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfIVersion; rtfKstr : 'version'; rtfkHash : 0),
+ ( rtfKMajor: rtfDestination; rtfKMinor: rtfIDoccomm; rtfKstr : 'doccomm'; rtfkHash : 0),
+
+ ( rtfKMajor: rtfTOCAttr; rtfKMinor: rtfTOCType; rtfKstr : 'tcf'; rtfkHash : 0),
+ ( rtfKMajor: rtfTOCAttr; rtfKMinor: rtfTOCLevel; rtfKstr : 'tcl'; rtfkHash : 0),
+
+ ( rtfKMajor: rtfFontFamily; rtfKMinor: rtfFFNil; rtfKstr : 'fnil'; rtfkHash : 0),
+ ( rtfKMajor: rtfFontFamily; rtfKMinor: rtfFFRoman; rtfKstr : 'froman'; rtfkHash : 0),
+ ( rtfKMajor: rtfFontFamily; rtfKMinor: rtfFFSwiss; rtfKstr : 'fswiss'; rtfkHash : 0),
+ ( rtfKMajor: rtfFontFamily; rtfKMinor: rtfFFModern; rtfKstr : 'fmodern'; rtfkHash : 0),
+ ( rtfKMajor: rtfFontFamily; rtfKMinor: rtfFFScript; rtfKstr : 'fscript'; rtfkHash : 0),
+ ( rtfKMajor: rtfFontFamily; rtfKMinor: rtfFFDecor; rtfKstr : 'fdecor'; rtfkHash : 0),
+ ( rtfKMajor: rtfFontFamily; rtfKMinor: rtfFFTech; rtfKstr : 'ftech'; rtfkHash : 0),
+
+ ( rtfKMajor: rtfColorName; rtfKMinor: rtfRed; rtfKstr : 'red'; rtfkHash : 0),
+ ( rtfKMajor: rtfColorName; rtfKMinor: rtfGreen; rtfKstr : 'green'; rtfkHash : 0),
+ ( rtfKMajor: rtfColorName; rtfKMinor: rtfBlue; rtfKstr : 'blue'; rtfkHash : 0),
+
+ ( rtfKMajor: rtfCharSet; rtfKMinor: rtfMacCharSet; rtfKstr : 'mac'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharSet; rtfKMinor: rtfAnsiCharSet; rtfKstr : 'ansi'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharSet; rtfKMinor: rtfPcCharSet; rtfKstr : 'pc'; rtfkHash : 0),
+ ( rtfKMajor: rtfCharSet; rtfKMinor: rtfPcaCharSet; rtfKstr : 'pca'; rtfkHash : 0),
+
+ ( rtfKMajor: rtfTblAttr; rtfKMinor: rtfCellBordBottom; rtfKstr : 'clbrdrb'; rtfkHash : 0),
+ ( rtfKMajor: rtfTblAttr; rtfKMinor: rtfCellBordTop; rtfKstr : 'clbrdrt'; rtfkHash : 0),
+ ( rtfKMajor: rtfTblAttr; rtfKMinor: rtfCellBordLeft; rtfKstr : 'clbrdrl'; rtfkHash : 0),
+ ( rtfKMajor: rtfTblAttr; rtfKMinor: rtfCellBordRight; rtfKstr : 'clbrdrr'; rtfkHash : 0),
+ ( rtfKMajor: rtfTblAttr; rtfKMinor: rtfRowDef; rtfKstr : 'trowd'; rtfkHash : 0),
+ ( rtfKMajor: rtfTblAttr; rtfKMinor: rtfRowLeft; rtfKstr : 'trql'; rtfkHash : 0),
+ ( rtfKMajor: rtfTblAttr; rtfKMinor: rtfRowRight; rtfKstr : 'trqr'; rtfkHash : 0),
+ ( rtfKMajor: rtfTblAttr; rtfKMinor: rtfRowCenter; rtfKstr : 'trqc'; rtfkHash : 0),
+ ( rtfKMajor: rtfTblAttr; rtfKMinor: rtfRowGapH; rtfKstr : 'trgaph'; rtfkHash : 0),
+ ( rtfKMajor: rtfTblAttr; rtfKMinor: rtfRowHt; rtfKstr : 'trrh'; rtfkHash : 0),
+ ( rtfKMajor: rtfTblAttr; rtfKMinor: rtfRowLeftEdge; rtfKstr : 'trleft'; rtfkHash : 0),
+ ( rtfKMajor: rtfTblAttr; rtfKMinor: rtfCellPos; rtfKstr : 'cellx'; rtfkHash : 0),
+ ( rtfKMajor: rtfTblAttr; rtfKMinor: rtfMergeRngFirst; rtfKstr : 'clmgf'; rtfkHash : 0),
+ ( rtfKMajor: rtfTblAttr; rtfKMinor: rtfMergePrevious; rtfKstr : 'clmrg'; rtfkHash : 0),
+
+ ( rtfKMajor: rtfFieldAttr; rtfKMinor: rtfFieldDirty; rtfKstr : 'flddirty'; rtfkHash : 0),
+ ( rtfKMajor: rtfFieldAttr; rtfKMinor: rtfFieldEdited; rtfKstr : 'fldedit'; rtfkHash : 0),
+ ( rtfKMajor: rtfFieldAttr; rtfKMinor: rtfFieldLocked; rtfKstr : 'fldlock'; rtfkHash : 0),
+ ( rtfKMajor: rtfFieldAttr; rtfKMinor: rtfFieldPrivate; rtfKstr : 'fldpriv'; rtfkHash : 0),
+
+ ( rtfKMajor: rtfPosAttr; rtfKMinor: rtfPosX; rtfKstr : 'posx'; rtfkHash : 0),
+ ( rtfKMajor: rtfPosAttr; rtfKMinor: rtfPosXCenter; rtfKstr : 'posxc'; rtfkHash : 0),
+ ( rtfKMajor: rtfPosAttr; rtfKMinor: rtfPosXInside; rtfKstr : 'posxi'; rtfkHash : 0),
+ ( rtfKMajor: rtfPosAttr; rtfKMinor: rtfPosXLeft; rtfKstr : 'posxl'; rtfkHash : 0),
+ ( rtfKMajor: rtfPosAttr; rtfKMinor: rtfPosXOutSide; rtfKstr : 'posxo'; rtfkHash : 0),
+ ( rtfKMajor: rtfPosAttr; rtfKMinor: rtfPosXRight; rtfKstr : 'posxr'; rtfkHash : 0),
+ ( rtfKMajor: rtfPosAttr; rtfKMinor: rtfPosY; rtfKstr : 'posy'; rtfkHash : 0),
+ ( rtfKMajor: rtfPosAttr; rtfKMinor: rtfPosYInline; rtfKstr : 'posyil'; rtfkHash : 0),
+ ( rtfKMajor: rtfPosAttr; rtfKMinor: rtfPosYTop; rtfKstr : 'posyt'; rtfkHash : 0),
+ ( rtfKMajor: rtfPosAttr; rtfKMinor: rtfPosYCenter; rtfKstr : 'posyc'; rtfkHash : 0),
+ ( rtfKMajor: rtfPosAttr; rtfKMinor: rtfPosYBottom; rtfKstr : 'posyb'; rtfkHash : 0),
+ ( rtfKMajor: rtfPosAttr; rtfKMinor: rtfAbsWid; rtfKstr : 'absw'; rtfkHash : 0),
+ ( rtfKMajor: rtfPosAttr; rtfKMinor: rtfTextDist; rtfKstr : 'dxfrtext'; rtfkHash : 0),
+ ( rtfKMajor: rtfPosAttr; rtfKMinor: rtfRPosMargV; rtfKstr : 'pvmrg'; rtfkHash : 0),
+ ( rtfKMajor: rtfPosAttr; rtfKMinor: rtfRPosPageV; rtfKstr : 'pvpg'; rtfkHash : 0),
+ ( rtfKMajor: rtfPosAttr; rtfKMinor: rtfRPosMargH; rtfKstr : 'phmrg'; rtfkHash : 0),
+ ( rtfKMajor: rtfPosAttr; rtfKMinor: rtfRPosPageH; rtfKstr : 'phpg'; rtfkHash : 0),
+ ( rtfKMajor: rtfPosAttr; rtfKMinor: rtfRPosColH; rtfKstr : 'phcol'; rtfkHash : 0),
+
+ ( rtfKMajor: rtfVersion; rtfKMinor: -1; rtfKstr : 'rtf'; rtfkHash : 0),
+ ( rtfKMajor: rtfDefFont; rtfKMinor: -1; rtfKstr : 'deff'; rtfkHash : 0),
+
+ ( rtfKMajor: 0; rtfKMinor: -1; rtfKstr : ''; rtfkHash : 0)
+ );
+
diff --git a/components/richmemo/rtfparspre211.pp b/components/richmemo/rtfparspre211.pp
new file mode 100644
index 000000000..8749c5681
--- /dev/null
+++ b/components/richmemo/rtfparspre211.pp
@@ -0,0 +1,971 @@
+Unit RTFParsPre211;
+{
+ This file is part of the Free Pascal run time library.
+ Copyright (c) 1999-2000 by Michael Van Canneyt, Member of the
+ Free Pascal development team
+
+ This unit implements a RTF Parser.
+
+ See the file COPYING.FPC, included in this distribution,
+ for details about the copyright.
+
+ 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.
+
+ **********************************************************************}
+
+// modified: by Dmitry Boyarintsev 20-may-2010, fixing identation and code-style
+
+{$mode objfpc}
+
+interface
+
+uses
+ Classes, SysUtils;
+
+{$i rtfdata.inc}
+
+type
+ TRTFErrorHandler = Procedure (s : string) of object;
+
+ { TRTFParser }
+
+ TRTFParser = class(TObject)
+ private
+ FOnRTFError : TRTFerrorHandler;
+ FfontList : PRTFFont;
+ FcolorList : PRTFColor;
+ FstyleList : PRTFStyle;
+ FrtfClass : Integer;
+ FrtfMajor : Integer;
+ FrtfMinor : Integer;
+ FrtfParam : Integer;
+ rtfTextBuf : string [rtfBufSiz];
+ rtfTextLen : Integer;
+ pushedChar : Integer; { pushback char if read too far }
+ pushedClass : Integer; { pushed token info for RTFUngetToken() }
+ pushedMajor : Integer;
+ pushedMinor : Integer;
+ pushedParam : Integer;
+ pushedTextBuf : String[rtfBufSiz];
+ FStream : TStream;
+ ccb : array [0..rtfMaxClass] of TRTFFuncPtr; { class callbacks }
+ dcb : array [0..rtfMaxDestination] of TRTFFuncPtr; { destination callbacks }
+ readHook : TRTFFUNCPTR;
+ FTokenClass: Integer;
+ procedure Error (msg : String);
+ procedure LookupInit ;
+ procedure ReadFontTbl ;
+ procedure ReadColorTbl;
+ procedure ReadStyleSheet ;
+ procedure ReadInfoGroup ;
+ procedure ReadPictGroup ;
+ function CheckCM (Aclass, major: Integer) : Boolean;
+ function CheckCMM (Aclass, major, minor : Integer) : Boolean;
+ function CheckMM (major, minor : Integer) : Boolean;
+ procedure Real_RTFGetToken;
+ function GetChar : Integer;
+ procedure Lookup (S : String);
+ function GetFont (num : Integer) : PRTFFont;
+ function GetColor (num : Integer) : PRTFColor;
+ function GetStyle (num : Integer) : PRTFStyle;
+ procedure setClassCallback (Aclass : Integer; Acallback : TRTFFuncPtr);
+ function GetClassCallback (Aclass : Integer) : TRTFFuncPtr;
+ procedure SetDestinationCallback (ADestination : Integer; Acallback : TRTFFuncPtr);
+ function GetDestinationCallback (Adestination : Integer) : TRTFFuncPtr ;
+ procedure SetStream (Astream : TStream);
+ public
+ constructor Create (AStream : TStream);
+ destructor Destroy; override;
+ procedure GetReadHook (Var q : TRTFFuncPtr);
+ function GetToken : Integer;
+ function PeekToken : Integer;
+ procedure ResetParser;
+ procedure RouteToken;
+ procedure SkipGroup;
+ procedure StartReading;
+ procedure SetReadHook (Hook : TRTFFuncPtr);
+ procedure UngetToken;
+ procedure SetToken (Aclass, major, minor, param : Integer; text : string);
+ procedure ExpandStyle (n : Integer);
+ function GetRtfText: string;
+ { Properties }
+ property Colors [Index : Integer]: PRTFColor Read GetColor;
+ property ClassCallBacks [AClass : Integer]: TRTFFuncptr
+ read GetClassCallBack write SetClassCallback;
+ property DestinationCallBacks [Adestination : Integer]: TRTFFuncptr
+ read GetdestinationCallBack write SetdestinationCallback;
+ property Fonts [Index : Integer]: PRTFFont Read GetFont;
+ property OnRTFError : TRTFerrorHandler Read FOnRTFError Write FOnRTFError;
+ property rtfClass : Integer Read FrtfClass;
+ property rtfMajor : Integer Read FrtfMajor;
+ property rtfMinor : Integer Read FrtfMinor;
+ property rtfParam : Integer Read FrtfParam;
+ property Stream : TStream Read FStream Write SetStream;
+ property Styles [index : Integer] : PRTFStyle Read GetStyle;
+ end;
+
+Implementation
+
+const
+ EOF = -255;
+
+{ ---------------------------------------------------------------------
+ Utility functions
+ ---------------------------------------------------------------------}
+
+function Hash (s : String) : Integer;
+var
+ val,i : integer;
+begin
+ val:=0;
+ for i:=1 to length(s) do
+ val:=val+ord(s[i]);
+ Hash:=val;
+end;
+
+function isalpha (s : integer) : Boolean;
+begin
+ Result:= ( (s>=ord('A')) and (s<=ord('Z')))
+ or (((s>=ord('a')) and ((s<=ord('z')) )));
+end;
+
+function isdigit (s : integer) : Boolean;
+begin
+ Result:= ( (s>=ord('0')) and (s<=ord('9')) )
+end;
+
+function HexVal (c : Integer) : Integer;
+begin
+ if (c>=ord('A')) and (C<=ord('Z')) then inc (c,32);
+ if cnil do begin
+ fp := FfontList^.rtfNextFont;
+ dispose (FfontList);
+ FfontList := fp;
+ end;
+
+ while FcolorList<>nil do begin
+ cp := FcolorList^.rtfNextColor;
+ dispose (FcolorList);
+ FcolorList := cp;
+ end;
+
+ while FstyleList<>nil do begin
+ sp := FstyleList^.rtfNextStyle;
+ eltList := FstyleList^.rtfSSEList;
+ while eltList<>nil do begin
+ ep:=eltList^.rtfNextSE;
+ dispose(eltList);
+ eltList:= ep;
+ end;
+ Dispose (FstyleList);
+ FstyleList := sp;
+ end;
+ FrtfClass := -1;
+ pushedClass := -1;
+ pushedChar := EOF;
+
+ { Reset the stream if it is assigned }
+ if assigned (FStream) then
+ FStream.seek(0,soFromBeginning);
+End;
+
+
+Destructor TRTFParser.Destroy;
+var
+ cp : PRTFColor;
+ fp : PRTFFont;
+ sp : PRTFStyle;
+ ep,eltlist : PRTFStyleElt;
+begin
+ { Dump the lists. }
+ while FfontList<>nil do begin
+ fp := FfontList^.rtfNextFont;
+ dispose (FfontList);
+ FfontList := fp;
+ end;
+
+ while FcolorList<>nil do begin
+ cp := FcolorList^.rtfNextColor;
+ dispose (FcolorList);
+ FcolorList := cp;
+ end;
+
+ while FstyleList<>nil do begin
+ sp := FstyleList^.rtfNextStyle;
+ eltList := FstyleList^.rtfSSEList;
+ while eltList<>nil do begin
+ ep:=eltList^.rtfNextSE;
+ dispose(eltList);
+ eltList:= ep;
+ end;
+ Dispose (FstyleList);
+ FstyleList := sp;
+ end;
+
+ { Dump rest }
+ inherited destroy;
+end;
+
+
+{ ---------------------------------------------------------------------
+ Callback table manipulation routines
+ ---------------------------------------------------------------------}
+
+Procedure TRTFParser.SetClassCallback (Aclass : Integer; Acallback : TRTFFuncPtr);
+begin
+ if (aclass>=0) and (Aclass=0) and (Aclass=0) and (Adestination=0) and (ADestinationrtfEOF) do
+ RouteToken;
+end;
+
+
+{ Route a token. If it's a destination for which a reader is
+ installed, process the destination internally, otherwise
+ pass the token to the writer's class callback. }
+procedure TRTFParser.RouteToken;
+var
+ p : TRTFFuncPtr;
+begin
+ if (rtfClass < 0) or (rtfClass>=rtfMaxClass) then
+ Error ('No such class : '+rtfTextBuf)
+ else begin
+ if (CheckCM (rtfControl, rtfDestination)) then begin
+ { invoke destination-specific callback if there is one }
+ p:=GetDestinationCallback (rtfMinor);
+ if assigned(p) then begin
+ p();
+ exit
+ end;
+ end;
+ { invoke class callback if there is one }
+ p:= GetClassCallback (rtfClass);
+ if assigned(p) then p();
+ end;
+end;
+
+
+{ Skip to the end of the current group. When this returns,
+ writers that maintain a state stack may want to call their
+ state unstacker; global vars will still be set to the group's
+ closing brace. }
+Procedure TRTFParser.SkipGroup;
+Var
+ level : Integer;
+Begin
+ level:= 1;
+ while (GetToken<>rtfEOF) do
+ if (rtfClass=rtfGroup) then begin
+ if (rtfMajor=rtfBeginGroup) then
+ inc(level)
+ else if (rtfMajor=rtfEndGroup) then begin
+ dec(level);
+ if (level < 1) then Exit; { end of initial group }
+ end;
+ end;
+End;
+
+{ Read one token. Call the read hook if there is one. The
+ token class is the return value. Returns rtfEOF when there
+ are no more tokens. }
+function TRTFParser.GetToken : Integer;
+var
+ p : TRTFFuncPTR;
+begin
+ GetReadHook (p);
+ while true do begin
+ Real_RTFGetToken;
+ if (assigned(p)) then p(); { give read hook a look at token }
+ { Silently discard newlines and carriage returns. }
+ if not ((rtfClass=rtfText) and ((rtfMajor=13) or (rtfmajor=10))) then
+ Break;
+ end;
+ Result:=rtfClass;
+end;
+
+{ ---------------------------------------------------------------------
+ Install or return a token reader hook.
+ ---------------------------------------------------------------------}
+procedure TRTFParser.SetReadHook(Hook : TRTFFuncPtr);
+begin
+ readHook := Hook;
+end;
+
+procedure TRTFParser.GetReadHook(Var q : TRTFFuncPtr);
+begin
+ Q:=readHook;
+end;
+
+procedure TRTFParser.UngetToken;
+begin
+ if (pushedClass >= 0) then { there's already an ungotten token }
+ Error ('cannot unget two tokens');
+ if (rtfClass < 0) then
+ Error ('no token to unget');
+ pushedClass := rtfClass;
+ pushedMajor := rtfMajor;
+ pushedMinor := rtfMinor;
+ pushedParam := rtfParam;
+ rtfTextBuf := pushedTextBuf;
+end;
+
+function TRTFParser.PeekToken : Integer;
+begin
+ Real_RTFGetToken;
+ UngetToken;
+ Result:=rtfClass;
+end;
+
+Procedure TRTFParser.Real_RTFGetToken;
+var
+ sign,c,c2 : Integer;
+begin
+ { check for pushed token from RTFUngetToken() }
+ if (pushedClass >= 0) then begin
+ FrtfClass := pushedClass;
+ FrtfMajor := pushedMajor;
+ FrtfMinor := pushedMinor;
+ FrtfParam := pushedParam;
+ rtfTextBuf := pushedTextBuf;
+ rtfTextLen := length (rtfTextBuf);
+ pushedClass := -1;
+ Exit;
+ end;
+
+ { initialize token vars }
+ FrtfClass := rtfUnknown;
+ FrtfParam := rtfNoParam;
+ rtfTextBuf := '';
+ rtfTextLen := 0;
+ FTokenClass := rtfUnknown;
+
+ { get first character, which may be a pushback from previous token }
+
+ if (pushedChar <> EOF) then begin
+ c := pushedChar;
+ rtfTextBuf:=rtfTextBuf+chr(c);
+ inc(rtftextlen);
+ pushedChar := EOF;
+ end else begin
+ c:=GetChar;
+ if C=EOF then begin
+ FrtfClass := rtfEOF;
+ Exit;
+ end;
+ end;
+
+ if c=ord('{') then begin
+ FrtfClass := rtfGroup;
+ FrtfMajor := rtfBeginGroup;
+ exit;
+ end;
+
+ if c=ord('}') then begin
+ FrtfClass := RTFGROUP;
+ FrtfMajor := rtfEndGroup;
+ exit;
+ end;
+
+ if c<>ord('\') then begin
+ { Two possibilities here:
+ 1) ASCII 9, effectively like \tab control symbol
+ 2) literal text char }
+ if c=ord(#8) then begin { ASCII 9 }
+ FrtfClass := rtfControl;
+ FrtfMajor := rtfSpecialChar;
+ FrtfMinor := rtfTab;
+ end else begin
+ FrtfClass := rtfText;
+ FrtfMajor := c;
+ end;
+ Exit;
+ end;
+
+ c:=getchar;
+ if (c=EOF) then { early eof, whoops (class is rtfUnknown) }
+ Exit;
+
+ if ( not isalpha (c)) then begin
+ { Three possibilities here:
+ 1) hex encoded text char, e.g., \'d5, \'d3
+ 2) special escaped text char, e.g., \, \;
+ 3) control symbol, e.g., \_, \-, \|, \<10> }
+ if c=ord('''') then begin{ hex char }
+ c:=getchar;
+ if (c<>EOF) then begin
+ c2:=getchar;
+ if (c2<>EOF) then begin
+ { should do isxdigit check! }
+ FrtfClass := rtfText;
+ FrtfMajor := HexVal (c) * 16 + HexVal (c2);
+ Exit;
+ end;
+ end;
+ { early eof, whoops (class is rtfUnknown) }
+ Exit;
+ end;
+ if pos (chr(c),':{};\')<>0 then begin{ escaped char }
+ FrtfClass := rtfText;
+ FrtfMajor := c;
+ exit;
+ end;
+
+ { control symbol }
+ Lookup (rtfTextBuf); { sets class, major, minor }
+ FTokenClass:=rtfControl;
+ exit;
+ end;
+
+ { control word }
+ while (isalpha (c)) do begin
+ c:=GetChar;
+ if (c=EOF) then Break;
+ end;
+
+ { At this point, the control word is all collected, so the
+ major/minor numbers are determined before the parameter
+ (if any) is scanned. There will be one too many characters
+ in the buffer, though, so fix up before and restore after
+ looking up. }
+ if (c<>EOF) then Delete(rtfTextBuf,length(rtfTextbuf),1);
+ Lookup (rtfTextBuf); { sets class, major, minor }
+ FTokenClass:=rtfControl;
+ if (c <>EOF) then
+ rtfTextBuf:=rtfTextBuf+chr(c);
+
+ { Should be looking at first digit of parameter if there
+ is one, unless it's negative. In that case, next char
+ is '-', so need to gobble next char, and remember sign. }
+ sign := 1;
+ if c = ord('-') then begin
+ sign := -1;
+ c := GetChar;
+ end;
+
+ if (c<>EOF) then
+ if isdigit (c) then begin
+ FrtfParam := 0;
+ while (isdigit (c)) do begin { gobble parameter }
+ FrtfParam := FrtfParam * 10 + c - ord('0');
+ c:=GetChar;
+ if (c=EOF) then Break;
+ end;
+ FrtfParam:= sign*FrtfParam;
+ end;
+
+ { If control symbol delimiter was a blank, gobble it.
+ Otherwise the character is first char of next token, so
+ push it back for next call. In either case, delete the
+ delimiter from the token buffer. }
+ if (c<>EOF) then begin
+ if c<>ord (' ') then pushedChar := c;
+ Delete (rtfTextBuf,rtfTextLen,1);
+ Dec (rtfTextLen);
+ end;
+end;
+
+function TRTFParser.GetChar : Integer;
+var
+ c : byte;
+begin
+ if FStream.read(c,1)<>0 then begin
+ if (c and 128)=128 then c:=ord('?');
+ Result:=c;
+ rtfTextBuf:=rtfTextBuf+chr(c);
+ inc(rtfTextLen);
+ end else
+ Result:=EOF;
+end;
+
+{ Synthesize a token by setting the global variables to the
+ values supplied. Typically this is followed with a call
+ to RTFRouteToken().
+ If param is non-negative, it becomes part of the token text. }
+Procedure TRTFParser.SetToken (Aclass, major, minor, param : Integer; text : string);
+Begin
+ FrtfClass := Aclass;
+ FrtfMajor := major;
+ FrtfMinor := minor;
+ FrtfParam := param;
+ if (param=rtfNoParam) then
+ rtfTextBuf:=text
+ else
+ rtfTextBuf:=text+IntTostr(param);
+ rtfTextLen:=length(rtfTextBuf);
+end;
+
+{ ---------------------------------------------------------------------
+ Special destination readers. They gobble the destination so the
+ writer doesn't have to deal with them. That's wrong for any
+ translator that wants to process any of these itself. In that
+ case, these readers should be overridden by installing a different
+ destination callback.
+
+ NOTE: The last token read by each of these reader will be the
+ destination's terminating '', which will then be the current token.
+ That 'End;' token is passed to RTFRouteToken() - the writer has already
+ seen the 'Begin' that began the destination group, and may have pushed a
+ state; it also needs to know at the end of the group that a state
+ should be popped.
+
+ It's important that rtfdata.inc and the control token lookup table list
+ as many symbols as possible, because these readers unfortunately
+ make strict assumptions about the input they expect, and a token
+ of class rtfUnknown will throw them off easily.
+ ----------------------------------------------------------------------}
+
+
+{ Read Begin \fonttbl ... End; destination. Old font tables don't have
+ braces around each table entry; try to adjust for that.}
+procedure TRTFParser.ReadFontTbl;
+var
+ fp : PRTFFont;
+ bp : string[rtfbufsiz];
+ old : Integer;
+begin
+ old := -1;
+
+ while true do begin
+ GetToken;
+ if CheckCM (rtfGroup, rtfEndGroup) then break;
+ if (old < 0) then begin { first entry - determine tbl type }
+ if CheckCMM (rtfControl, rtfCharAttr, rtfFontNum) then
+ old:=1 { no brace }
+ else if CheckCM (rtfGroup, rtfBeginGroup) then
+ old:= 0 { brace }
+ else { can't tell! }
+ Error ('FTErr - Cannot determine format')
+ end;
+ if (old=0) then begin { need to find "Begin" here }
+ if not CheckCM (rtfGroup, rtfBeginGroup) then
+ Error ('FTErr - missing {');
+ GetToken; { yes, skip to next token }
+ end;
+
+ new(fp);
+ if (fp=nil) then
+ Error ('FTErr - cannot allocate font entry');
+ fp^.rtfNextFont:= FfontList;
+ FfontList:=fp;
+ if not CheckCMM (rtfControl, rtfCharAttr, rtfFontNum) then
+ Error ('FTErr - missing font number');
+ fp^.rtfFNum := rtfParam;
+
+ { Read optionalcommands. Recognize only fontfamily}
+ GetToken;
+ if not CheckCM (rtfControl, rtfFontFamily) then
+ error ('FTErr - missing font family ');
+ fp^.rtfFFamily := rtfMinor;
+
+ { Read optional commands/groups. Recognize none at this point..}
+ GetToken;
+ while (rtfclass=rtfcontrol) or ((rtfclass=rtfgroup) or (rtfclass=rtfunknown)) do begin
+ if rtfclass=rtfgroup then SkipGroup;
+ GetToken
+ end;
+
+ { Read font name }
+ bp:='';
+ while (rtfclass=rtfText) do begin
+ if rtfMajor=ord(';') then Break;
+ bp:=bp+chr(rtfMajor);
+ GetToken
+ end;
+
+ if bp='' then Error ('FTErr - missing font name');
+ fp^.rtffname:=bp;
+
+ { Read alternate font}
+ if (old=0) then begin { need to see "End;" here }
+ GetToken;
+ if not CheckCM (rtfGroup, rtfEndGroup) then
+ Error ('FTErr - missing }');
+ end;
+ end;
+
+ RouteToken; { feed "End;" back to router }
+end;
+
+
+{ The color table entries have color values of -1 if
+ the default color should be used for the entry (only
+ a semi-colon is given in the definition, no color values).
+ There will be a problem if a partial entry (1 or 2 but
+ not 3 color values) is given. The possibility is ignored
+ here. }
+Procedure TRTFParser.ReadColorTbl;
+var
+ cp : PRTFColor;
+ cnum : Integer;
+Begin
+ cnum:=0;
+ while true do begin
+ GetToken;
+ if CheckCM (rtfGroup, rtfEndGroup) then Break;
+ new(cp);
+ if (cp=nil) then
+ Error ('CTErr - cannot allocate color entry');
+ cp^.rtfCNum :=cnum;
+ cp^.rtfCRed :=-1;
+ cp^.rtfCGreen:=-1;
+ cp^.rtfCBlue :=-1;
+ cp^.rtfNextColor := FColorList;
+ inc(cnum);
+ FcolorList:=cp;
+ while true do begin
+ if not CheckCM (rtfControl, rtfColorName) then Break;
+ case rtfMinor of
+ rtfRed: cp^.rtfCRed :=rtfParam;
+ rtfGreen: cp^.rtfCGreen :=rtfParam;
+ rtfBlue: cp^.rtfCBlue :=rtfParam;
+ end;
+ GetToken;
+ end;
+ if not CheckCM (rtfText, ord(';')) then
+ Error ('CTErr - malformed entry');
+ end;
+ RouteToken; { feed "End;" back to router }
+end;
+
+
+{ The "Normal" style definition doesn't contain any style number
+ (why?), all others do. Normal style is given style 0. }
+
+Procedure TRTFParser.ReadStyleSheet;
+var
+ sp : PRTFStyle;
+ sep,sepLast : PRTFStyleElt;
+ bp : string[rtfBufSiz];
+begin
+ while true do begin
+ GetToken;
+ if CheckCM (rtfGroup, rtfEndGroup) then Break;
+ new (sp);
+ if sp=nil then Error ('SSErr - cannot allocate stylesheet entry');
+ sp^.rtfSNum := -1;
+ sp^.rtfSBasedOn := rtfBasedOnNone;
+ sp^.rtfSNextPar := -1;
+ sp^.rtfSSEList := nil;
+ sepLast:=nil;
+ sp^.rtfNextStyle := FstyleList;
+ sp^.rtfExpanding := 0;
+ FstyleList := sp;
+ if not CheckCM (rtfGroup, rtfBeginGroup) then Error ('SSErr - missing {');
+ while (GetToken=rtfControl) or (FTokenClass=rtfControl) do begin
+ if rtfClass=rtfUnknown then Continue;
+ if (CheckMM (rtfParAttr, rtfStyleNum)) then begin
+ sp^.rtfSNum:=rtfParam;
+ continue;
+ end;
+ if (CheckMM (rtfStyleAttr, rtfBasedOn)) then begin
+ sp^.rtfSBasedOn:=rtfParam;
+ continue;
+ end;
+ if (CheckMM (rtfStyleAttr, rtfNext)) then begin
+ sp^.rtfSNextPar:=rtfParam;
+ Continue;
+ end;
+ new(sep);
+ if sep=nil then
+ Error ('SSErr - cannot allocate style element');
+ sep^.rtfSEClass:=rtfClass;
+ sep^.rtfSEMajor:=rtfMajor;
+ sep^.rtfSEMinor:=rtfMinor;
+ sep^.rtfSEParam:=rtfParam;
+ sep^.rtfSEText:=rtfTextBuf;
+ if sepLast=nil then
+ sp^.rtfSSEList:=sep { first element }
+ else { add to end }
+ sepLast^.rtfNextSE:=sep;
+ sep^.rtfNextSE:=nil;
+ sepLast:=sep;
+ end;
+ if sp^.rtfSNextPar=-1 then { \snext not given }
+ sp^.rtfSNextPar:=sp^.rtfSNum; { next is itself }
+ if rtfClass<>rtfText then
+ Error ('SSErr - missing style name');
+ Bp:='';
+ while rtfClass=rtfText do begin
+ if rtfMajor=ord(';') then begin
+ GetToken;
+ Break;
+ end;
+ bp:=bp+chr(rtfMajor);
+ GetToken;
+ end;
+ if (sp^.rtfSNum < 0) then begin { no style number was specified, (only legal for Normal style) }
+ if bp<>'Normal' then
+ Error ('SSErr - missing style number');
+ sp^.rtfSNum:=0;
+ end;
+ sp^.rtfSName:=bp;
+ if not CheckCM (rtfGroup, rtfEndGroup) then
+ Error ('SSErr - missing }');
+ end;
+ RouteToken; { feed "End;" back to router }
+end;
+
+
+Procedure TRTFParser.ReadInfoGroup;
+Begin
+ SkipGroup;
+ RouteToken; { feed "End;" back to router }
+end;
+
+Procedure TRTFParser.ReadPictGroup;
+Begin
+ SkipGroup;
+ RouteToken; { feed "End;" back to router }
+end;
+
+
+{ ----------------------------------------------------------------------
+ Routines to return pieces of stylesheet, or font or color tables
+ ----------------------------------------------------------------------}
+function TRTFParser.GetStyle (num : Integer) : PRTFStyle;
+var
+ s : PRTFSTyle;
+begin
+ s:=Fstylelist;
+ if num<>1 then
+ while s<>nil do begin
+ if (s^.rtfSNum=num) then break;
+ s:=s^.rtfNextStyle;
+ end;
+ Result:=s; { NULL if not found }
+end;
+
+function TRTFParser.GetFont (num : Integer) : PRTFFont;
+var
+ f :PRTFFont;
+begin
+ f:=FfontList;
+ if num<>-1 then
+ while f<>nil do begin
+ if f^.rtfFNum=num then break;
+ f:=f^.rtfNextFont;
+ end;
+ Result:=f; { NULL if not found }
+end;
+
+function TRTFParser.GetColor (num : Integer) : PRTFColor;
+var
+ c : PRTFColor;
+begin
+ c:=Fcolorlist;
+ if (num<>-1) then
+ while c<>nil do begin
+ if c^.rtfCNum=num then break;
+ c:=c^.rtfNextColor;
+ end;
+ Result:=c; { NULL if not found }
+End;
+
+{ ---------------------------------------------------------------------
+ Expand style n, if there is such a style.
+ ---------------------------------------------------------------------}
+
+procedure TRTFParser.ExpandStyle (n : Integer);
+var
+ s : PRTFStyle;
+ se : PRTFStyleElt;
+begin
+ if n=-1 then Exit;
+ s:=GetStyle (n);
+ if s=nil then Exit;
+
+ if (s^.rtfExpanding<>0) then
+ Error ('Style expansion loop, style '+inttostr(n));
+ s^.rtfExpanding:=1; { set expansion flag for loop detection }
+{
+ Expand "based-on" style. This is done by synthesizing
+ the token that the writer needs to see in order to trigger
+ another style expansion, and feeding to token back through
+ the router so the writer sees it.
+}
+ SetToken (rtfControl, rtfParAttr, rtfStyleNum, s^.rtfSBasedOn, '\s');
+ RouteToken;
+
+{
+ Now route the tokens unique to this style. RTFSetToken()
+ isn't used because it would add the param value to the end
+ of the token text, which already has it in.
+}
+ se:=s^.rtfSSEList;
+ while se<>nil do begin
+ FrtfClass:=se^.rtfSEClass;
+ FrtfMajor:=se^.rtfSEMajor;
+ FrtfMinor:=se^.rtfSEMinor;
+ FrtfParam:=se^.rtfSEParam;
+ rtfTextBuf:=se^.rtfSEText;
+ rtfTextLen:=length (rtfTextBuf);
+ RouteToken;
+ se:=se^.rtfNextSE
+ end;
+ s^.rtfExpanding:=0; { done - clear expansion flag }
+End;
+
+function TRTFParser.GetRtfText: string;
+begin
+ SetString(Result, @rtfTextBuf[1], rtfTextLen);
+end;
+
+{ ---------------------------------------------------------------------
+ Initialize lookup table hash values.
+ Only need to do this the first time it's called.
+ ---------------------------------------------------------------------}
+
+Procedure TRTFParser.LookupInit;
+var
+ count : Integer;
+begin
+ count:=0;
+ while rtfkey[count].rtfKStr<>'' do begin
+ rtfkey[count].rtfKHash:=Hash (rtfkey[count].rtfKStr);
+ inc(count)
+ end;
+end;
+
+{ ---------------------------------------------------------------------
+ Determine major and minor number of control token. If it's
+ not found, the class turns into rtfUnknown.
+ ---------------------------------------------------------------------}
+procedure TRTFParser.Lookup (S : String);
+var
+ thehash,rp : Integer;
+begin
+ delete(s,1,1); { skip over the leading \ character }
+ thehash:=Hash (s);
+ rp:=0;
+ while rtfkey[rp].rtfKstr<>'' do begin
+ if (thehash=rtfkey[rp].rtfKHash) and (s=rtfkey[rp].rtfKStr) then begin
+ FrtfClass:=rtfControl;
+ FrtfMajor:=rtfkey[rp].rtfKMajor;
+ FrtfMinor:=rtfkey[rp].rtfKMinor;
+ exit;
+ end;
+ inc(rp);
+ end;
+ FrtfClass:=rtfUnknown;
+End;
+
+procedure TRTFParser.Error (msg : String);
+{ Call errorhandler }
+begin
+ if assigned(onrtferror) then onrtferror(msg);
+end;
+{ ---------------------------------------------------------------------
+ Token comparison routines
+ ---------------------------------------------------------------------}
+
+function TRTFParser.CheckCM (Aclass, major: Integer) : Boolean;
+begin
+ Result:=(rtfClass=Aclass) and (rtfMajor=major);
+end;
+
+function TRTFParser.CheckCMM (Aclass, major, minor : Integer) : Boolean;
+begin
+ Result:=(rtfClass=Aclass) and ((rtfMajor=major) and (rtfMinor=minor));
+end;
+
+function TRTFParser.CheckMM (major, minor : Integer) : Boolean;
+begin
+ Result:=(rtfMajor=major) and (rtfMinor=minor);
+end;
+
+procedure TRTFParser.SetStream (Astream : TStream);
+begin
+ FStream:=Astream;
+end;
+
+end.