RVRTFProps.pas
上传用户:daoqigc
上传日期:2021-04-20
资源大小:2795k
文件大小:109k
源码类别:

RichEdit

开发平台:

Delphi

  1. {*******************************************************}
  2. {                                                       }
  3. {       RichView                                        }
  4. {       TRVRTFReaderProperties:                         }
  5. {       - property of TRichView                         }
  6. {         (RichView.RTFReadProperties)                  }
  7. {       - intermediate class between RichView and       }
  8. {         RTF parser (TRVRTFReader)                     }
  9. {                                                       }
  10. {       Copyright (c) Sergey Tkachenko                  }
  11. {       svt@trichview.com                               }
  12. {       http://www.trichview.com                        }
  13. {                                                       }
  14. {*******************************************************}
  15. unit RVRTFProps;
  16. interface
  17. {$I RV_Defs.inc}
  18. uses SysUtils, Windows, Classes, Forms, Math,
  19.      {$IFNDEF RVDONOTUSERTFIMPORT}
  20.      RVRTF,
  21.      {$ENDIF}
  22.      {$IFNDEF RVDONOTUSELISTS}
  23.      RVMarker,
  24.      {$ENDIF}
  25.      {$IFNDEF RVDONOTUSEOLECONTAINER}
  26.      (*
  27.      OleCtnrs, ActiveX, ComObj,
  28.      *)
  29.      {$ENDIF}
  30.      RVScroll, CRVData, CRVFData, RVStyle, Graphics, RVRTFErr, RVUni, RVItem,
  31.      RVMapWht, RVFuncs,
  32.      RVClasses;
  33. {$IFNDEF RICHVIEWCBDEF3}
  34. {$DEFINE RVDONOTUSEUNICODE}
  35. {$ENDIF}
  36. {$IFDEF RVDONOTUSERVF}
  37. {$DEFINE RVDONOTUSETABLES}
  38. {$ENDIF}
  39. const
  40.   RV_TableGridEps: Integer = 1;
  41. type
  42.   TRVAllowUseStyleEvent = procedure (StyleNo: Integer; TextStyle: Boolean;
  43.                                      var Allow: Boolean) of object;
  44.   {$IFNDEF RVDONOTUSERTFIMPORT}
  45.   TRVCustomImageItemEvent = procedure (RVData: TCustomRVData;
  46.     Graphic: TGraphic; Hypertext: Boolean; var item: TCustomRVItemInfo;
  47.     var FreeGraphic: Boolean; RTFPicture: TRVRTFPicture;
  48.     var  Name: String) of object;
  49.   {$ENDIF}
  50.   TRVRTFReaderProperties = class (TPersistent)
  51.     private
  52.       FUnicodeMode: TRVReaderUnicode;
  53.       FTextStyleMode: TRVReaderStyleMode;
  54.       FParaStyleMode: TRVReaderStyleMode;
  55.       FIgnorePictures, FIgnoreTables: Boolean;
  56.       FUseHypertextStyles: Boolean;
  57.       FParaNo: Integer;
  58.       FStyleNo: Integer;
  59.       //FAdjustVisibleBorders: Boolean;
  60.       FExplicitTableWidth: Boolean;
  61.       FSkipHiddenText: Boolean;
  62.       FHideTableGridLines: Boolean;
  63.       FLineBreaksAsParagraphs: Boolean;
  64.       {$IFNDEF RVDONOTUSERTFIMPORT}
  65.       FEmptyPara: Integer;
  66.       RVData, CurrentRVData: TCustomRVData;
  67.       RVStyle: TRVStyle;
  68.       PageBreak: Boolean;
  69.       PageBreakRVData: TCustomRVData;
  70.       PixelsPerTwip: Double;
  71.       Reader: TRVRTFReader;
  72.       FirstTime: Boolean;
  73.       InsertPoint, CurrentRow, CurrentCol: Integer;
  74.       Tables: TRVList;
  75.       FHeaderRVData, FFooterRVData: TCustomRVData;
  76.       FHeaderYMM, FFooterYMM: Integer;
  77.       FConvertHighlight: TRVRTFHighlight;
  78.       HFType: TRVRTFHeaderFooterType;
  79.       FBasePath: String;
  80.       FExtractMetafileBitmaps: Boolean;
  81.       {$IFNDEF RVDONOTUSELISTS}
  82.       IgnoreLists: Boolean;
  83.       LastMarkerIndex: Integer;
  84.       IsLastMarkerWord97: Boolean;
  85.       LevelToListNo: TRVIntegerList;
  86.       ListTableMap97: TRVIntegerList;
  87.       ListStylesCountBefore: Integer;
  88.       {$ENDIF}
  89.       FStoreImagesFileNames: Boolean;
  90.       procedure InitReader;
  91.       procedure DoneReader;
  92.       function ReturnParaNo(Position: TRVRTFPosition): Integer;
  93.       function CreateTextItem(const Text: String;
  94.         {$IFDEF RICHVIEWCBDEF3}const WideText: WideString;{$ENDIF}
  95.         StyleNo, ParaNo: Integer; UseUnicode: Boolean;
  96.         var ResText: String): TRVTextItemInfo;
  97.       {$IFNDEF RVDONOTUSELISTS}
  98.       function GetMarkerIndex(RTFMarker: TRVRTFMarkerProperties): Integer;
  99.       function InsertMarker(ParaNo: Integer): Boolean;
  100.       procedure InsertMarker97(ParaNo: Integer);
  101.       procedure ReaderUpdateMarker(Sender: TObject);
  102.       procedure MergeListTable97;
  103.       function AreListStylesEqual97(RVList: TRVListInfo;
  104.         RTFList: TRVRTFList97): Boolean;
  105.       function FindListStyle97(RTFList: TRVRTFList97;
  106.         ForbiddenStyles: TRVIntegerList): Integer;
  107.       {$ENDIF}
  108.       procedure InsertItem(var Text: String; item: TCustomRVItemInfo;
  109.         Position: TRVRTFPosition);
  110.       procedure CurrentBorder(var RVBorderStyle: TRVBorderStyle;
  111.         var RVBorderWidth, RVBorderIntWidth: Integer; var RVBorderColor: TColor;
  112.         var RVBorderOffs: TRVRect);
  113.       function FindParaNo(RVBorderStyle: TRVBorderStyle;
  114.         RVBorderWidth, RVBorderIntWidth: Integer; RVBorderColor: TColor;
  115.         RVBorderOffs: TRVRect): Integer;
  116.       {$IFNDEF RVDONOTUSETABLES}
  117.       function GetEmptyParaNo(Alignment: TRVAlignment): Integer;
  118.       function GetEmptyStyleNo: Integer;
  119.       {$ENDIF}
  120.       function FindBestParaNo: Integer;
  121.       function FindStyleNo(AUnicode, AHypertext: Boolean): Integer;
  122.       function FindBestStyleNo(AUnicode, AHypertext: Boolean): Integer;
  123.       procedure AddPara(RVBorderStyle: TRVBorderStyle;
  124.         RVBorderWidth, RVBorderIntWidth: Integer; RVBorderColor: TColor;
  125.         RVBorderOffs: TRVRect);
  126.       procedure AddStyle(AUnicode, AHypertext: Boolean);
  127.       function ReturnParaNo_: Integer;
  128.       function ReturnStyleNo(AUnicode: Boolean): Integer;
  129.       function IsHypertext_: Boolean;
  130.       function IsHypertext(var Target, Hint, Extras: String): Boolean;
  131.       function AllowUseStyle(StyleNo: Integer; TextStyle: Boolean): Boolean;
  132.       {$ENDIF}
  133.       procedure SetParaNo(const Value: Integer);
  134.       procedure SetStyleNo(const Value: Integer);
  135.     protected
  136.       {$IFNDEF RVDONOTUSERTFIMPORT}
  137.       procedure ReaderProgress(Sender: TRVRTFReader; Stage: TRVRTFProgressStage;
  138.         PercentDone: Byte);
  139.       procedure NewReaderText(Sender: TRVRTFReader; const Text: String;
  140.         Position: TRVRTFPosition);
  141.       procedure ReaderEndParsing(Sender: TObject);
  142.       {$IFDEF RICHVIEWCBDEF3}
  143.       procedure NewReaderUnicodeText(Sender: TRVRTFReader;
  144.         const Text: WideString; Position: TRVRTFPosition);
  145.       {$ENDIF}
  146.       procedure NewReaderPicture(Sender: TRVRTFReader; RTFPicture: TRVRTFPicture;
  147.         Graphic: TGraphic; Position: TRVRTFPosition; const FileName: String;
  148.         var Inserted: Boolean);
  149.       procedure ReaderImportPicture(Sender: TRVRTFReader; const Location: String;
  150.         var Graphic: TGraphic; var Invalid: Boolean);
  151.       {$IFNDEF RVDONOTUSEOLECONTAINER}
  152.       (*
  153.       procedure NewReaderObject(Sender: TRVRTFReader; RTFObject: TRVRTFObject;
  154.         Position: TRVRTFPosition; var Inserted: Boolean);
  155.       *)
  156.       {$ENDIF}
  157.       {$IFNDEF RVDONOTUSETABLES}
  158.       procedure AssignRowProperties;
  159.       procedure ReaderTable(Sender: TRVRTFReader; WhatHappens: TRVRTFTableEventKind);
  160.       {$ENDIF}
  161.       procedure ReaderPageBreak(Sender: TObject);
  162.       procedure ReaderHeaderFooter(Sender: TRVRTFReader; HFType: TRVRTFHeaderFooterType;
  163.         Starting: Boolean; var Supported: Boolean);
  164.       {$ENDIF}
  165.     public
  166.       EditFlag: Boolean;
  167.       ErrorCode: TRVRTFErrorCode;
  168.       FailedBecauseOfProtect, FullReformat: Boolean;
  169.       NonFirstItemsAdded: Integer;
  170.       AllowNewPara: Boolean;
  171.       OnAllowUseStyle:   TRVAllowUseStyleEvent;
  172.       {$IFNDEF RVDONOTUSERTFIMPORT}
  173.       OnCustomImageItem: TRVCustomImageItemEvent;
  174.       {$ENDIF}
  175.       Index: Integer;
  176.       constructor Create;
  177.       procedure Assign(Source: TPersistent); override;
  178.       function ReadFromFile(const AFileName: String; ARVData: TCustomRVData): TRVRTFErrorCode;
  179.       {$IFDEF RVUSEWORDDOC}
  180.       function ReadFromWordDocFile(const AFileName: String; ARVData: TCustomRVData): TRVRTFErrorCode;
  181.       {$ENDIF}
  182.       function ReadFromStream(AStream: TStream; ARVData: TCustomRVData): TRVRTFErrorCode;
  183.       function InsertFromStreamEd(AStream: TStream; ARVData: TCustomRVData; var AIndex: Integer): TRVRTFErrorCode;
  184.       //property AdjustVisibleBorders: Boolean read FAdjustVisibleBorders write FAdjustVisibleBorders;
  185.       property ExplicitTableWidth: Boolean read FExplicitTableWidth write FExplicitTableWidth default False;
  186.       {$IFNDEF RVDONOTUSERTFIMPORT}
  187.       procedure SetHeader(RVData: TCustomRVData);
  188.       procedure SetFooter(RVData: TCustomRVData);
  189.       property HeaderYMM: Integer read FHeaderYMM;
  190.       property FooterYMM: Integer read FFooterYMM;
  191.       property BasePath: String read FBasePath write FBasePath;
  192.       {$ENDIF}
  193.     published
  194.       property UnicodeMode: TRVReaderUnicode read FUnicodeMode write FUnicodeMode default rvruNoUnicode;
  195.       property TextStyleMode: TRVReaderStyleMode read FTextStyleMode write FTextStyleMode default rvrsUseClosest;
  196.       property ParaStyleMode: TRVReaderStyleMode read FParaStyleMode write FParaStyleMode default rvrsUseClosest;
  197.       property IgnorePictures: Boolean read FIgnorePictures write FIgnorePictures default False;
  198.       property IgnoreTables: Boolean read FIgnoreTables write FIgnoreTables default False;      
  199.       property UseHypertextStyles: Boolean read FUseHypertextStyles write FUseHypertextStyles default False;
  200.       property TextStyleNo: Integer read FStyleNo write SetStyleNo default 0;
  201.       property ParaStyleNo: Integer read FParaNo write SetParaNo default 0;
  202.       property SkipHiddenText: Boolean read FSkipHiddenText write FSkipHiddenText default True;
  203.       property AutoHideTableGridLines: Boolean read FHideTableGridLines write FHideTableGridLines default False;
  204.       property LineBreaksAsParagraphs: Boolean read FLineBreaksAsParagraphs write FLineBreaksAsParagraphs default False;
  205.       {$IFNDEF RVDONOTUSERTFIMPORT}
  206.       property ExtractMetafileBitmaps: Boolean read FExtractMetafileBitmaps write FExtractMetafileBitmaps default True;
  207.       property ConvertHighlight: TRVRTFHighlight read FConvertHighlight write FConvertHighlight default rtfhlColorTable;
  208.       property StoreImagesFileNames: Boolean read FStoreImagesFileNames write FStoreImagesFileNames default False;      
  209.       {$ENDIF}
  210.   end;
  211. implementation
  212. uses RVStr
  213.   {$IFNDEF RVDONOTUSETABLES}
  214.   , RVTable
  215.   {$ENDIF}
  216.   ;
  217. {$IFNDEF RVDONOTUSERTFIMPORT}
  218. {$IFNDEF RVDONOTUSETABLES}
  219. {=============================== TTableInfo ===================================}
  220. type
  221.   TTableInfo = class
  222.     public
  223.       HRules: TRVIntegerList;
  224.       ParentRow, ParentCol, PrevColCount: Integer;
  225.       table, lastrow: TRVTableItemInfo;
  226.       VSpacingTw, VBorderSpacing1Tw,VBorderSpacing2Tw: Integer;
  227.       HSpacingTw, CellPaddingTw, CellPaddingCount, BestWidth: Integer;
  228.       BorderWidthTw, CellBorderWidthTw, CellCount, BorderCount, CellBorderCount: Integer;
  229.       UseHSpacing, UseVSpacing, Word2000, CellFlatBorder, RichViewSpecial: Boolean;
  230.       RowFinished: Boolean;
  231.       constructor Create;
  232.       destructor Destroy; override;
  233.       procedure Finalize(PixelsPerTwip: Double; {AdjustVisibleBorders: Boolean; }
  234.         DefStyleNo, DefParaNo: Integer; ExplicitTableWidth, AutoHideGridLines: Boolean);
  235.   end;
  236. {------------------------------------------------------------------------------}
  237. constructor TTableInfo.Create;
  238. begin
  239.   inherited Create;
  240.   HRules := TRVIntegerList.Create;
  241.   CellFlatBorder := True;
  242. end;
  243. {------------------------------------------------------------------------------}
  244. destructor TTableInfo.Destroy;
  245. begin
  246.   lastrow.Free;
  247.   HRules.Free;
  248.   inherited Destroy;
  249. end;
  250. {------------------------------------------------------------------------------}
  251. procedure TTableInfo.Finalize(PixelsPerTwip: Double; {AdjustVisibleBorders: Boolean; }
  252.   DefStyleNo, DefParaNo: Integer; ExplicitTableWidth, AutoHideGridLines: Boolean);
  253. var r,c: Integer;
  254.     //r2,c2: Integer;
  255.     Cell1: TRVTableCellData;
  256.     //Cell2: TRVTableCellData;
  257. begin
  258.   if CellFlatBorder then
  259.     table.CellBorderStyle := rvtbColor;
  260.   if table.BorderColor=table.BorderLightColor then
  261.     table.BorderStyle := rvtbColor;
  262.   if CellPaddingCount>0 then
  263.     table.CellPadding := Round(PixelsPerTwip*CellPaddingTw / CellPaddingCount)
  264.   else
  265.     table.CellPadding := 0;
  266.   for r := 0 to table.Rows.Count-1 do
  267.     for c := 0 to table.Rows[r].Count-1 do begin
  268.       Cell1 := table.Cells[r,c];
  269.       if (Cell1<>nil) then begin
  270.         if not RichViewSpecial and (Cell1.BestWidth>table.CellPadding*2) then
  271.           Cell1.BestWidth := Cell1.BestWidth-table.CellPadding*2;
  272.         if (Cell1.Items.Count=0) then
  273.          Cell1.AddNL('', DefStyleNo, DefParaNo);
  274.       end;
  275.     end;
  276.   {
  277.   if (not UseVSpacing or not UseHSpacing) and AdjustVisibleBorders then
  278.     for r := 0 to table.Rows.Count-1 do
  279.       for c := 0 to table.Rows[r].Count-1 do begin
  280.         Cell1 := table.Cells[r,c];
  281.         if (Cell1<>nil) and Cell1.VisibleBorders.Left and not UseHSpacing and (c>0) then begin
  282.           Cell2 := table.Rows.GetMainCell(r,c-1,r2,c2);
  283.           if Cell2.VisibleBorders.Right then
  284.             Cell1.VisibleBorders.Left := False;
  285.         end;
  286.         if (Cell1<>nil) and Cell1.VisibleBorders.Top and not UseVSpacing and (r>0) then begin
  287.           Cell2 := table.Rows.GetMainCell(r-1,c,r2,c2);
  288.           if Cell2.VisibleBorders.Bottom then
  289.             Cell1.VisibleBorders.Top := False;
  290.         end;
  291.       end;
  292.   }
  293.   if UseVSpacing then begin
  294.     if table.Rows.Count>1 then
  295.       table.CellVSpacing := Round(PixelsPerTwip*VSpacingTw / (table.Rows.Count-1));
  296.       table.BorderVSpacing := Round(PixelsPerTwip*(VBorderSpacing1Tw+VBorderSpacing2Tw));
  297.     end
  298.   else begin
  299.     table.CellVSpacing := -1;
  300.     table.BorderVSpacing := -1;
  301.   end;
  302.   if UseHSpacing then
  303.     table.CellHSpacing := Round(PixelsPerTwip*HSpacingTw / table.Rows.Count)
  304.   else begin
  305.     table.CellHSpacing := -1;
  306.   end;
  307.   table.BorderHSpacing := table.CellHSpacing;
  308.   if RichViewSpecial then
  309.     table.BestWidth := BestWidth
  310.   else
  311.     if BestWidth>0 then begin
  312.       if BorderCount>0 then
  313.         table.BestWidth := Round(PixelsPerTwip*(BestWidth-BorderWidthTw/BorderCount))
  314.       else
  315.         table.BestWidth := Round(PixelsPerTwip*BestWidth);
  316.       end
  317.     else if BestWidth<0 then
  318.       table.BestWidth := BestWidth div 50
  319.     else if ExplicitTableWidth then
  320.       table.BestWidth := Round((HRules[HRules.Count-1]-HRules[0])*PixelsPerTwip);
  321.   if CellBorderCount>0 then begin
  322.     table.CellBorderWidth :=  Round(PixelsPerTwip*CellBorderWidthTw/CellBorderCount);
  323.     if (table.CellBorderWidth=0) and (Round(CellBorderWidthTw/CellBorderCount)>=5) then
  324.       table.CellBorderWidth := 1;
  325.   end;
  326.   if BorderCount>0 then begin
  327.     table.BorderWidth :=  Round(PixelsPerTwip*BorderWidthTw/BorderCount);
  328.     if (table.BorderWidth=0) and (Round(BorderWidthTw/BorderCount)>=5) then
  329.       table.BorderWidth := 1;
  330.   end;
  331.   if not UseVSpacing and not UseHSpacing and (table.BorderWidth=table.CellBorderWidth) then begin
  332.     table.BorderWidth := 0;
  333.     table.BorderHSpacing := 0;
  334.     table.BorderVSpacing := 0;
  335.   end;
  336.   if AutoHideGridLines then
  337.     table.Options := table.Options + [rvtoHideGridLines];
  338. end;
  339. {$ENDIF}
  340. {==============================================================================}
  341. procedure BorderRTF2RV(StyleRTF:TRVRTFBorderType; WidthRTF: Integer;
  342.   var StyleRV: TRVBorderStyle; var WidthRV, IntWidthRV: Integer;
  343.   PixelPerTwips: Double; InvertSides: Boolean);
  344. begin
  345.   IntWidthRV := 0;
  346.   case StyleRTF of
  347.     rtf_brdr_None:
  348.       begin
  349.         StyleRV := rvbNone;
  350.         WidthRV := 0;
  351.       end;
  352.     rtf_brdr_SingleThickness,
  353.     rtf_brdr_Inset, rtf_brdr_Outset, rtf_brdr_Shadow,
  354.     rtf_brdr_Dot, rtf_brdr_Dash, rtf_brdr_DashSmall,
  355.     rtf_brdr_DotDash, rtf_brdr_DotDotDash,
  356.     rtf_brdr_Wavy, rtf_brdr_Striped,
  357.     rtf_brdr_Emboss, rtf_brdr_Engrave:
  358.       begin
  359.        // WidthRTF = width of line
  360.         StyleRV := rvbSingle;
  361.         WidthRV    := Round(WidthRTF*PixelPerTwips);
  362.       end;
  363.     rtf_brdr_DoubleThickness:
  364.       begin
  365.         // WidthRTF = width of line / 2
  366.         StyleRV := rvbSingle;
  367.         WidthRV    := Round(WidthRTF*PixelPerTwips*2);
  368.       end;
  369.     rtf_brdr_Double, rtf_brdr_DoubleWavy:
  370.       begin
  371.         // WidthRTF = width of line = width of space
  372.         StyleRV := rvbDouble;
  373.         WidthRV    := Round(WidthRTF*PixelPerTwips);
  374.         IntWidthRV := WidthRV*2-1;
  375.       end;
  376.     rtf_brdr_Triple:
  377.       begin
  378.         // WidthRTF = width of line = width of space
  379.         StyleRV := rvbTriple;
  380.         WidthRV    := Round(WidthRTF*PixelPerTwips);
  381.         IntWidthRV := WidthRV*2-1;
  382.       end;
  383.     rtf_brdr_Hairline:
  384.       begin
  385.         StyleRV := rvbSingle;
  386.         WidthRV := 1;
  387.       end;
  388.     rtf_brdr_ThickThinSmall:
  389.       begin
  390.         // original: one-pixel thin line, one-pixel space, WidthRTF thick line
  391.         if InvertSides then
  392.           StyleRV := rvbThickInside
  393.         else
  394.           StyleRV    := rvbThickOutside;
  395.         WidthRV    := Round(WidthRTF*PixelPerTwips/2);
  396.         IntWidthRV := WidthRV+(WidthRV+1) div 2;
  397.       end;
  398.     rtf_brdr_ThickThinMed:
  399.       begin
  400.         // original: WidthRTF thick line, thin line - half (?), space = thin line,
  401.         if InvertSides then
  402.           StyleRV := rvbThickInside
  403.         else
  404.           StyleRV    := rvbThickOutside;
  405.         WidthRV    := Round(WidthRTF*PixelPerTwips/2);
  406.         IntWidthRV := WidthRV*2+(WidthRV+1) div 2;
  407.       end;
  408.     rtf_brdr_ThickThinLarge:
  409.       begin
  410.         // original: one-pixel thin line, two-pixel thick line (?), WidthRTF space
  411.         if InvertSides then
  412.           StyleRV := rvbThickInside
  413.         else
  414.           StyleRV    := rvbThickOutside;
  415.         WidthRV    := 1;
  416.         IntWidthRV := Round(WidthRTF*PixelPerTwips)+1;
  417.       end;
  418.     rtf_brdr_ThinThickSmall:
  419.       begin
  420.         if not InvertSides then
  421.           StyleRV := rvbThickInside
  422.         else
  423.           StyleRV    := rvbThickOutside;
  424.         IntWidthRV := 1+Round(WidthRTF*PixelPerTwips*3/8);
  425.         IntWidthRV := WidthRV+(WidthRV+1) div 2;
  426.       end;
  427.     rtf_brdr_ThinThickMed:
  428.       begin
  429.         if not InvertSides then
  430.           StyleRV := rvbThickInside
  431.         else
  432.           StyleRV    := rvbThickOutside;
  433.         WidthRV    := Round(WidthRTF*PixelPerTwips/2);
  434.         IntWidthRV := WidthRV*2+(WidthRV+1) div 2;
  435.       end;
  436.     rtf_brdr_ThinThickLarge:
  437.       begin
  438.         if not InvertSides then
  439.           StyleRV := rvbThickInside
  440.         else
  441.           StyleRV    := rvbThickOutside;
  442.         WidthRV    := 1;
  443.         IntWidthRV := Round(WidthRTF*PixelPerTwips)+1;
  444.       end;
  445.     rtf_brdr_ThinThickThinSmall:
  446.       begin
  447.         StyleRV    := rvbTriple;
  448.         WidthRV    := Round(WidthRTF*PixelPerTwips/3);
  449.         IntWidthRV := WidthRV*2-1;;
  450.       end;
  451.     rtf_brdr_ThinThickThinMed:
  452.       begin
  453.         StyleRV    := rvbTriple;
  454.         WidthRV    := Round(WidthRTF*PixelPerTwips/2);
  455.         IntWidthRV := WidthRV*3-1;
  456.       end;
  457.     rtf_brdr_ThinThickThinLarge:
  458.       begin
  459.         StyleRV    := rvbTriple;
  460.         WidthRV    := 1;
  461.         IntWidthRV := Round(WidthRTF*PixelPerTwips);
  462.       end;
  463.   end;
  464. end;
  465. {------------------------------------------------------------------------------}
  466. function GetStyleSSType(VShift: Integer): TRVRTFSScriptType;
  467. begin
  468.   if VShift=0 then
  469.     Result := rtf_ss_Normal
  470.   else if VShift<0 then
  471.     Result := rtf_ss_Subscript
  472.   else
  473.     Result := rtf_ss_Superscript;
  474. end;
  475. {$ENDIF}
  476. {=========================== TRVRTFReaderProperties ===========================}
  477. constructor TRVRTFReaderProperties.Create;
  478. begin
  479.   inherited Create;
  480.   FUnicodeMode   := rvruNoUnicode;
  481.   FTextStyleMode := rvrsUseClosest;
  482.   FParaStyleMode := rvrsUseClosest;
  483.   FSkipHiddenText  := True;
  484.   //AdjustVisibleBorders := True;
  485.   FHideTableGridLines := False;
  486.   AllowNewPara   := True;
  487.   {$IFNDEF RVDONOTUSERTFIMPORT}
  488.   FConvertHighlight := rtfhlColorTable;
  489.   FExtractMetafileBitmaps := True;
  490.   {$ENDIF}
  491. end;
  492. {------------------------------------------------------------------------------}
  493. procedure TRVRTFReaderProperties.Assign(Source: TPersistent);
  494. begin
  495.   if Source is TRVRTFReaderProperties then begin
  496.     FUnicodeMode   := TRVRTFReaderProperties(Source).FUnicodeMode;
  497.     FTextStyleMode := TRVRTFReaderProperties(Source).FTextStyleMode;
  498.     FParaStyleMode := TRVRTFReaderProperties(Source).FParaStyleMode;
  499.     FIgnorePictures  := TRVRTFReaderProperties(Source).FIgnorePictures;
  500.     FIgnoreTables  := TRVRTFReaderProperties(Source).FIgnoreTables;
  501.     FSkipHiddenText := TRVRTFReaderProperties(Source).FSkipHiddenText;
  502.     FParaNo        := TRVRTFReaderProperties(Source).FParaNo;
  503.     FStyleNo        := TRVRTFReaderProperties(Source).FStyleNo;
  504.     FUseHypertextStyles := TRVRTFReaderProperties(Source).FUseHypertextStyles;
  505.     FLineBreaksAsParagraphs := TRVRTFReaderProperties(Source).FLineBreaksAsParagraphs;
  506.     {$IFNDEF RVDONOTUSERTFIMPORT}
  507.     FExtractMetafileBitmaps := TRVRTFReaderProperties(Source).FExtractMetafileBitmaps;
  508.     FConvertHighlight := TRVRTFReaderProperties(Source).FConvertHighlight;
  509.     {$ENDIF}
  510.     end
  511.   else
  512.     inherited Assign(Source);
  513. end;
  514. {------------------------------------------------------------------------------}
  515. function TRVRTFReaderProperties.ReadFromFile(const AFileName: String;
  516.   ARVData: TCustomRVData): TRVRTFErrorCode;
  517. begin
  518. {$IFNDEF RVDONOTUSERTFIMPORT}
  519.   try
  520.     RVData := ARVData;
  521.     EditFlag := False;
  522.     InsertPoint := RVData.Items.Count;
  523.     Index := -1;
  524.     Reader := TRVRTFReader.Create(nil);
  525.     try
  526.       InitReader;
  527.       Result := Reader.ReadFromFile(AFileName);
  528.       ErrorCode := Result;
  529.     finally
  530.       DoneReader;
  531.       Reader.Free;
  532.     end;
  533.   except
  534.     Result := rtf_ec_Exception;
  535.   end;
  536. {$ELSE}
  537.   Result := rtf_ec_OK;
  538. {$ENDIF}
  539. end;
  540. {------------------------------------------------------------------------------}
  541. {$IFDEF RVUSEWORDDOC}
  542. function TRVRTFReaderProperties.ReadFromWordDocFile(const AFileName: String; ARVData: TCustomRVData): TRVRTFErrorCode;
  543. begin
  544. {$IFNDEF RVDONOTUSERTFIMPORT}
  545.   try
  546.     RVData := ARVData;
  547.     EditFlag := False;
  548.     InsertPoint := RVData.Items.Count;
  549.     Index := -1;
  550.     Reader := TRVRTFReader.Create(nil);
  551.     try
  552.       InitReader;
  553.       Result := Reader.ReadFromWordDocFile(AFileName);
  554.       ErrorCode := Result;
  555.     finally
  556.       DoneReader;
  557.       Reader.Free;
  558.     end;
  559.   except
  560.     Result := rtf_ec_Exception;
  561.   end;
  562. {$ELSE}
  563.   Result := rtf_ec_OK;
  564. {$ENDIF}
  565. end;
  566. {$ENDIF}
  567. {------------------------------------------------------------------------------}
  568. function TRVRTFReaderProperties.ReadFromStream(AStream: TStream;
  569.   ARVData: TCustomRVData): TRVRTFErrorCode;
  570. begin
  571. {$IFNDEF RVDONOTUSERTFIMPORT}
  572.   try
  573.     RVData := ARVData;
  574.     Reader := TRVRTFReader.Create(nil);
  575.     EditFlag := False;
  576.     InsertPoint := RVData.Items.Count;
  577.     Index := -1;
  578.     try
  579.       InitReader;
  580.       Result := Reader.ReadFromStream(AStream);
  581.       ErrorCode := Result;
  582.     finally
  583.       DoneReader;
  584.       Reader.Free;
  585.     end;
  586.   except
  587.     Result := rtf_ec_Exception;
  588.   end;
  589. {$ELSE}
  590.   Result := rtf_ec_OK;
  591. {$ENDIF}
  592. end;
  593. {------------------------------------------------------------------------------}
  594. function TRVRTFReaderProperties.InsertFromStreamEd(AStream: TStream;
  595.   ARVData: TCustomRVData; var AIndex: Integer): TRVRTFErrorCode;
  596. begin
  597. {$IFNDEF RVDONOTUSERTFIMPORT}
  598.   RVData := ARVData;
  599.   Reader := TRVRTFReader.Create(nil);
  600.   EditFlag := True;
  601.   InsertPoint := AIndex;
  602.   Index := -1;
  603.   try
  604.     InitReader;
  605.     Result := Reader.ReadFromStream(AStream);
  606.     ErrorCode := Result;
  607.   finally
  608.     Reader.Free;
  609.     DoneReader;
  610.     AIndex := Index;
  611.   end;
  612. {$ELSE}
  613.   Result := rtf_ec_OK;
  614. {$ENDIF}
  615. end;
  616. {------------------------------------------------------------------------------}
  617. procedure TRVRTFReaderProperties.SetParaNo(const Value: Integer);
  618. begin
  619.   if Value<0 then
  620.     raise Exception.Create(errRVNegative);
  621.   FParaNo := Value;
  622. end;
  623. {------------------------------------------------------------------------------}
  624. procedure TRVRTFReaderProperties.SetStyleNo(const Value: Integer);
  625. begin
  626.   if Value<0 then
  627.     raise Exception.Create(errRVNegative);
  628.   FStyleNo := Value;
  629. end;
  630. {------------------------------------------------------------------------------}
  631. {$IFNDEF RVDONOTUSERTFIMPORT}
  632. procedure TRVRTFReaderProperties.SetFooter(RVData: TCustomRVData);
  633. begin
  634.   FFooterRVData := RVData;
  635. end;
  636. {------------------------------------------------------------------------------}
  637. procedure TRVRTFReaderProperties.SetHeader(RVData: TCustomRVData);
  638. begin
  639.   FHeaderRVData := RVData;
  640. end;
  641. {------------------------------------------------------------------------------}
  642. procedure TRVRTFReaderProperties.NewReaderPicture(Sender: TRVRTFReader;
  643.   RTFPicture: TRVRTFPicture; Graphic: TGraphic; Position: TRVRTFPosition;
  644.   const FileName: String; var Inserted: Boolean);
  645. var item: TCustomRVItemInfo;
  646.     Target, Hint, Extras: String;
  647.     StyleNo, ItemTag,v: Integer;
  648.     ItemName: String;
  649.     Hyp, FreeGraphic: Boolean;
  650. begin
  651.   Inserted := False;
  652.   ItemName := '';
  653.   Hint := '';
  654.   if Assigned(OnCustomImageItem) then begin
  655.     Hyp := IsHypertext(Target, Hint, Extras);
  656.     item := nil;
  657.     FreeGraphic := False;
  658.     OnCustomImageItem(CurrentRVData, Graphic, Hyp, item, FreeGraphic, RTFPicture,
  659.       ItemName);
  660.     if FreeGraphic then
  661.       Graphic.Free;
  662.     if item<>nil then
  663.       RVData.ReadHyperlink(Target, Extras, rvlfRTF, item.StyleNo, item.Tag, ItemName);
  664.     end
  665.   else begin
  666.     if Graphic=nil then begin
  667.       if RTFPicture.ShpPict then
  668.         exit;
  669.       Graphic := RV_CreateGraphics(TGraphicClass(RVStyle.InvalidPicture.Graphic.ClassType));
  670.       Graphic.Assign(RVStyle.InvalidPicture.Graphic);
  671.     end;
  672.     StyleNo  := rvsPicture;
  673.     ItemTag  := 0;
  674.     if IsHypertext(Target, Hint, Extras) then begin
  675.       RVData.ReadHyperlink(Target, Extras, rvlfRTF, StyleNo, ItemTag, ItemName);
  676.       item := CreateRichViewItem(StyleNo,RVData) as TRVGraphicItemInfo;
  677.       TRVGraphicItemInfo(item).Image := Graphic;
  678.       TRVGraphicItemInfo(item).Tag := ItemTag;
  679.       end
  680.     else
  681.       item := TRVGraphicItemInfo.CreateEx(CurrentRVData, Graphic, rvvaBaseline);
  682.   end;
  683.   if item<>nil then begin
  684.     if (item is TRVGraphicItemInfo) and (RTFPicture<>nil) then begin
  685.       if (TRVGraphicItemInfo(item).Image is TMetafile) or (RTFPicture.PicScaleX<>100) then begin
  686.         if RTFPicture.SuggestedWidth>0 then
  687.           v := RTFPicture.SuggestedWidth
  688.         else
  689.           v := TRVGraphicItemInfo(item).Image.Width;
  690.         TRVGraphicItemInfo(item).ImageWidth := Round(v/100*RTFPicture.PicScaleX);
  691.       end;
  692.       if (TRVGraphicItemInfo(item).Image is TMetafile) or (RTFPicture.PicScaleY<>100) then begin
  693.         if RTFPicture.SuggestedHeight>0 then
  694.           v := RTFPicture.SuggestedHeight
  695.         else
  696.           v := TRVGraphicItemInfo(item).Image.Height;
  697.         TRVGraphicItemInfo(item).ImageHeight := Round(v/100*RTFPicture.PicScaleY);
  698.       end;
  699.     end;
  700.     item.ParaNo := ReturnParaNo(Position);
  701.     {$IFNDEF RVDONOTUSEITEMHINTS}
  702.     item.Hint := Hint;
  703.     {$ENDIF}
  704.     if StoreImagesFileNames then
  705.       item.SetExtraStrProperty(rvespImageFileName, FileName);
  706.     item.BeforeLoading(rvlfRTF);
  707.     InsertItem(ItemName, item, Position);
  708.     Inserted := True;
  709.   end;
  710. end;
  711. {------------------------------------------------------------------------------}
  712. procedure TRVRTFReaderProperties.ReaderImportPicture(Sender: TRVRTFReader;
  713.   const Location: String; var Graphic: TGraphic; var Invalid: Boolean);
  714. begin
  715.   Graphic := CurrentRVData.ImportPicture(Location, 0, 0, Invalid);
  716. end;
  717. {------------------------------------------------------------------------------}
  718. {$IFNDEF RVDONOTUSEOLECONTAINER}
  719. (*
  720. type
  721.   TStreamHeader = record
  722.     case Integer of
  723.       0: ( { New }
  724.         Signature: Integer;
  725.         DrawAspect: Integer;
  726.         DataSize: Integer);
  727.       1: ( { Old }
  728.         PartRect: TSmallRect);
  729.   end;
  730.   TRTFObjectHeader = record
  731.     Signature: Integer;
  732.     DrawAspect: Integer;
  733.     ProgIdSize: Integer;
  734.   end;
  735. const
  736.   StreamSignature = $434F4442; {'BDOC'}
  737. procedure TRVRTFReaderProperties.NewReaderObject(Sender: TRVRTFReader;
  738.   RTFObject: TRVRTFObject; Position: TRVRTFPosition; var Inserted: Boolean);
  739. var ole: TOLEContainer;
  740.     item: TRVControlItemInfo;
  741.     s: String;
  742.     Size: Integer;
  743.     Stream: TStream;
  744.     header: TStreamHeader;
  745.     rtfheader: TRTFObjectHeader;
  746.     StreamAdapter: TStreamAdapter;
  747.     OleObject: IOleObject;
  748.     TempLockBytes: ILockBytes;
  749.     TempStorage: IStorage;
  750.     DataHandle: HGlobal;
  751.     Buffer: Pointer;
  752. begin
  753.   case RTFObject.ObjType of
  754.     rtf_obj_Emb:
  755.       begin
  756.         ole := TOLEContainer.Create(nil);
  757.         try
  758.           ole.Visible := False;
  759.           ole.Parent := RVData.GetParentControl;
  760.           ole.Width := Round(RTFObject.WidthTw*PixelsPerTwip);
  761.           ole.Height := Round(RTFObject.HeightTw*PixelsPerTwip);
  762.           RTFObject.Data.ReadBuffer(rtfheader, sizeof(rtfheader));
  763.           RTFObject.Data.Seek(rtfheader.ProgIdSize+12, soFromCurrent);
  764.           header.Signature := StreamSignature;
  765.           header.DrawAspect := 1;//rtfheader.DrawAspect;
  766.           Header.DataSize := RTFObject.Data.Size-RTFObject.Data.Position;
  767.           Stream := TMemoryStream.Create;
  768.           Stream.WriteBuffer(header, sizeof(header));
  769.           Stream.CopyFrom(RTFObject.Data, Header.DataSize);
  770.           Stream.Position := 0;
  771.           ole.LoadFromStream(Stream);
  772.           Stream.Free;
  773.           item := TRVControlItemInfo.CreateEx(CurrentRVData, ole, rvvaBaseline);
  774.           s := '';
  775.           InsertItem(s, item, Position);
  776.           Inserted := True;
  777.         except
  778.           ole.Free;
  779.         end;
  780.       end;
  781.   end;
  782. end;
  783. *)
  784. {$ENDIF}
  785. {------------------------------------------------------------------------------}
  786. function GetIndex(List: TRVIntegerList; Value: Integer): Integer;
  787. var i: Integer;
  788. begin
  789.   for i := 0 to List.Count-1 do
  790.     if List[i]>=Value then begin
  791.       Result := i;
  792.       exit;
  793.     end;
  794.   Result := List.Count;
  795. end;
  796. {$IFNDEF RVDONOTUSETABLES}
  797. {------------------------------------------------------------------------------}
  798. procedure MergeCol(table: TRVTableItemInfo; c: Integer);
  799. var r: Integer;
  800. begin
  801.   if c>=table.Rows[0].Count-2 then
  802.     exit;
  803.   for r := 0 to table.Rows.Count-2 do
  804.     if table.Cells[r,c]<>nil then
  805.       table.Cells[r,c].Clear;
  806.   for r := 0 to table.Rows.Count-2 do
  807.     if (table.Cells[r,c]<>nil) and (table.Cells[r,c+1]<>nil) then begin
  808.       table.Cells[r,c].AssignAttributesFrom(table.Cells[r,c+1], True,1,1);
  809.       table.Rows.MergeCells(r,c, table.Cells[r,c+1].ColSpan+1,table.Cells[r,c+1].RowSpan,True,False);
  810.     end;
  811. end;
  812. {------------------------------------------------------------------------------}
  813. procedure GetBorderColors(Border: TRVRTFParaBorder; var c1, c2: TColor);
  814. begin
  815.   c1 := clNone;
  816.   c2 := clNone;
  817.   if Border.Sides[rtf_side_Left].BorderType<>rtf_brdr_None then
  818.     c1 := Border.Sides[rtf_side_Left].Color
  819.   else if Border.Sides[rtf_side_Top].BorderType<>rtf_brdr_None then
  820.     c1 := Border.Sides[rtf_side_Top].Color;
  821.   if Border.Sides[rtf_side_Right].BorderType<>rtf_brdr_None then
  822.     c2 := Border.Sides[rtf_side_Right].Color
  823.   else if Border.Sides[rtf_side_Bottom].BorderType<>rtf_brdr_None then
  824.     c2 := Border.Sides[rtf_side_Bottom].Color;
  825. end;
  826. {------------------------------------------------------------------------------}
  827. procedure TRVRTFReaderProperties.AssignRowProperties;
  828. var info: TTableInfo;
  829.     i,span,r,c,idx,val,strt: Integer;
  830.     RowProps: TRVRTFRowProperties;
  831.     side: TRVRTFSide;
  832.     c1,c2: TColor;
  833.     {............................................................}
  834.     procedure AssignCellProperties(Cell: TRVTableCellData; Props: TRVRTFCellProperties; RuleIndex1,RuleIndex2: Integer);
  835.     var side: TRVRTFSide;
  836.         w: Integer;
  837.         c1, c2: TColor;
  838.     begin
  839.        inc(info.CellCount);
  840.        Cell.Color := Props.Color;
  841.        if RowProps.RichViewSpecial then
  842.          Cell.BestHeight := Props.BestHeight
  843.        else if RowProps.HeightTw>0 then
  844.          Cell.BestHeight := Round(RowProps.HeightTw*PixelsPerTwip);
  845.        for side := Low(TRVRTFSide) to High(TRVRTFSide) do begin
  846.          if Props.Border.Sides[side].BorderType<>rtf_brdr_None then begin
  847.            inc(info.CellBorderCount);
  848.            inc(info.CellBorderWidthTw, Props.Border.Sides[side].WidthTw);
  849.          end;
  850.        end;
  851.        Cell.VisibleBorders.Left := Props.Border.Sides[rtf_side_Left].BorderType<>rtf_brdr_None;
  852.        Cell.VisibleBorders.Top := Props.Border.Sides[rtf_side_Top].BorderType<>rtf_brdr_None;
  853.        Cell.VisibleBorders.Right := Props.Border.Sides[rtf_side_Right].BorderType<>rtf_brdr_None;
  854.        Cell.VisibleBorders.Bottom := Props.Border.Sides[rtf_side_Bottom].BorderType<>rtf_brdr_None;
  855.        GetBorderColors(Props.Border,c1,c2);
  856.        Cell.BorderColor := c1;
  857.        Cell.BorderLightColor := c2;
  858.        info.CellFlatBorder := info.CellFlatBorder and ((c1=c2) or (c1=clNone) or (c2=clNone));
  859.        if RowProps.RichViewSpecial then
  860.          Cell.BestWidth := Props.BestWidth
  861.        else begin
  862.          info.Word2000 := info.Word2000 or (Props.BestWidth<>0);
  863.          if not info.Word2000 then begin
  864.            w := info.HRules[RuleIndex2]-info.HRules[RuleIndex1];
  865.            Cell.BestWidth := Round(w*PixelsPerTwip)
  866.            end
  867.          else
  868.            if Props.BestWidth>0 then begin
  869.              w := Props.BestWidth;
  870.              Cell.BestWidth := Round(w*PixelsPerTwip)
  871.              end
  872.            else
  873.              Cell.BestWidth := Props.BestWidth div 50;
  874.        end;
  875.        case Props.VAlign of
  876.          rtf_val_Top:
  877.            Cell.VAlign := rvcTop;
  878.          rtf_val_Bottom:
  879.            Cell.VAlign := rvcBottom;
  880.          rtf_val_Center:
  881.            Cell.VAlign := rvcMiddle;
  882.        end;
  883.     end;
  884.     {............................................................}
  885.     procedure HideBorders(Row,Col: Integer);
  886.     var Cell: TRVTableCellData;
  887.     begin
  888.       Cell := info.table.Cells[Row,Col];
  889.       if Cell<>nil then begin
  890.         Cell.VisibleBorders.SetAll(False);
  891.         Cell.Clear;
  892.         Cell.AddNL('',GetEmptyStyleNo,GetEmptyParaNo(rvaLeft));
  893.       end;
  894.     end;
  895.     {............................................................}
  896. begin
  897.   info := TTableInfo(Tables[Tables.Count-1]);
  898.   info.table.InsertRows(info.table.Rows.Count,1,-1);
  899.   if info.table.Rows[0].Count<info.lastrow.Rows[0].Count then begin
  900.     c := info.table.Rows[0].Count;
  901.     span := info.lastrow.Rows[0].Count-info.table.Rows[0].Count+1;
  902.     info.table.InsertCols(c,span,-1);
  903.     if CurrentRow>1 then begin
  904.       info.table.MergeCells(0,c,span,info.table.Rows.Count,True);
  905.       HideBorders(0,c);
  906.     end;
  907.   end;
  908.   RowProps := Reader.RTFState.RowProps;
  909.   if RowProps.Heading then
  910.     info.table.HeadingRowCount := info.table.Rows.Count;
  911.   //assigning table attributes
  912.   if RowProps.UseSpacing[rtf_side_Top] then
  913.     if CurrentRow=0 then begin
  914.       info.VBorderSpacing1Tw := RowProps.SpacingTw[rtf_side_Top];
  915.       info.table.VisibleBorders.Top :=
  916.         (RowProps.Border.Sides[rtf_side_Top].BorderType<>rtf_brdr_None);
  917.       info.table.VisibleBorders.Left :=
  918.         (RowProps.Border.Sides[rtf_side_Left].BorderType<>rtf_brdr_None);
  919.       info.table.VisibleBorders.Right :=
  920.         (RowProps.Border.Sides[rtf_side_Right].BorderType<>rtf_brdr_None);
  921.       end
  922.     else
  923.       inc(info.VSpacingTw, RowProps.SpacingTw[rtf_side_Top]);
  924.   info.table.VisibleBorders.Bottom :=
  925.     (RowProps.Border.Sides[rtf_side_Bottom].BorderType<>rtf_brdr_None);
  926.   inc(info.VSpacingTw, info.VBorderSpacing2Tw);
  927.   info.UseHSpacing := info.UseHSpacing or
  928.     (RowProps.UseSpacing[rtf_side_Left] and (RowProps.SpacingTw[rtf_side_Left]>0)) or
  929.     (RowProps.UseSpacing[rtf_side_Right] and (RowProps.SpacingTw[rtf_side_Right]>0));
  930.   info.UseVSpacing := info.UseVSpacing or
  931.     (RowProps.UseSpacing[rtf_side_Top] and (RowProps.SpacingTw[rtf_side_Top]>0)) or
  932.     (RowProps.UseSpacing[rtf_side_Bottom] and (RowProps.SpacingTw[rtf_side_Bottom]>0));
  933.   for side := Low(TRVRTFSide) to High(TRVRTFSide) do
  934.     if RowProps.SpacingTw[side]<0 then
  935.       RowProps.FUseSpacing[side] := False;
  936.   if RowProps.UseSpacing[rtf_side_Bottom] then
  937.     info.VBorderSpacing2Tw := RowProps.SpacingTw[rtf_side_Bottom];
  938.   if RowProps.UseSpacing[rtf_side_Left] then
  939.     inc(info.HSpacingTw, RowProps.SpacingTw[rtf_side_Left])
  940.   else begin
  941.     inc(info.HSpacingTw, RowProps.GapHTw);
  942.     if RowProps.UsePadding[rtf_side_Left] then
  943.       dec(info.HSpacingTw, RowProps.PaddingTw[rtf_side_Left]);
  944.   end;
  945.   if RowProps.UseSpacing[rtf_side_Right] then
  946.     inc(info.HSpacingTw, RowProps.SpacingTw[rtf_side_Right])
  947.   else begin
  948.     inc(info.HSpacingTw, RowProps.GapHTw);
  949.     if RowProps.UsePadding[rtf_side_Right] then
  950.       dec(info.HSpacingTw, RowProps.PaddingTw[rtf_side_Right]);
  951.   end;
  952.   for side := Low(TRVRTFSide) to High(TRVRTFSide) do begin
  953.     if RowProps.Border.Sides[side].BorderType<>rtf_brdr_None then begin
  954.       inc(info.BorderWidthTw, RowProps.Border.Sides[side].WidthTw);
  955.       inc(info.BorderCount);
  956.     end;
  957.     if RowProps.UsePadding[side] then
  958.       inc(info.CellPaddingTw, RowProps.PaddingTw[side]);
  959.     inc(info.CellPaddingCount);
  960.   end;
  961.   if RowProps.RichViewSpecial then begin
  962.     info.BestWidth := RowProps.BestWidth;
  963.     info.RichViewSpecial := True;
  964.     end
  965.   else
  966.     if ((info.BestWidth<=0)  and (RowProps.BestWidth<info.BestWidth)) or
  967.        ((info.BestWidth>=0) and (RowProps.BestWidth>info.BestWidth)) then
  968.       info.BestWidth := RowProps.BestWidth;
  969.   GetBorderColors(RowProps.Border,c1,c2);
  970.   if c1<>clNone then
  971.     info.table.BorderLightColor := c1;
  972.   if c2<>clNone then
  973.     info.table.BorderColor := c2;
  974.   // assigning cells
  975.   if CurrentRow=0 then begin
  976.     info.HRules.Add(RowProps.LeftTw);
  977.     for i := 0 to RowProps.CellProps.Count-1 do
  978.       info.HRules.Add(RowProps.CellProps[i].RightBoundaryTw);
  979.   end;
  980.   strt := 0;
  981.   if CurrentRow>0 then begin
  982.     val := RowProps.LeftTw;
  983.     idx := GetIndex(info.HRules, val);
  984.     if idx=0 then begin
  985.       if abs(info.HRules[idx]-val)>RV_TableGridEps then begin
  986.         info.HRules.Insert(0, val);
  987.         info.table.InsertCols(0,1,-1);
  988.         info.table.Cells[CurrentRow,0].Clear;
  989.         info.table.Cells[CurrentRow,0].AssignAttributesFrom(info.table.Cells[CurrentRow,1],True,1,1);
  990.         info.table.Rows.MergeCells(0,0,1,CurrentRow,True,False);
  991.         HideBorders(0,0);
  992.         strt := 0;
  993.       end;
  994.      end
  995.     else if idx=info.HRules.Count then begin
  996.       info.HRules.Add(val);
  997.       info.table.InsertCols(idx-1,2,-1);
  998.       info.table.Rows.MergeCells(0,idx,1,CurrentRow,True,False);
  999.       HideBorders(0,idx);
  1000.       MergeCol(info.table,idx-1);
  1001.       info.table.Rows.MergeCells(CurrentRow,0,idx,1,True,False);
  1002.       HideBorders(CurrentRow,0);
  1003.       if info.table.Cells[CurrentRow,0]<>nil then
  1004.         info.table.Cells[CurrentRow,0].BestWidth := Round((info.HRules[idx]-info.HRules[0]-RowProps.GapHTw*2)*PixelsPerTwip);
  1005.       strt := idx;
  1006.       end
  1007.     else begin
  1008.       if abs(info.HRules[idx]-val)>RV_TableGridEps then begin
  1009.         info.HRules.Insert(idx, val);
  1010.         info.HRules.Sort;
  1011.         info.table.InsertCols(idx-1,1,-1);
  1012.         HideBorders(CurrentRow,idx-1);
  1013.         MergeCol(info.table,idx-1);
  1014.       end;
  1015.       info.table.Rows.MergeCells(CurrentRow,0,idx,1,True,False);
  1016.       if idx>0 then
  1017.         HideBorders(CurrentRow,0);
  1018.       strt := idx;
  1019.     end;
  1020.     for i := 0 to RowProps.CellProps.Count-1 do begin
  1021.       val := RowProps.CellProps[i].RightBoundaryTw;
  1022.       if RowProps.CellProps[i].HMerge=rtf_cm_First then
  1023.         if strt<info.HRules.Count-1 then begin
  1024.           val := info.HRules[strt+1];
  1025.           if val>RowProps.CellProps[i+1].RightBoundaryTw then
  1026.             val := RowProps.CellProps[i+1].RightBoundaryTw;
  1027.           end
  1028.         else
  1029.           val := RowProps.CellProps[i+1].RightBoundaryTw;
  1030.       idx := GetIndex(info.HRules, val);
  1031.       if (idx=info.HRules.Count) then begin
  1032.         //if strt<info.HRules.Count-1 then begin
  1033.           info.table.InsertCols(idx-1,1,-1);
  1034.         //end;
  1035.         info.HRules.Add(val);
  1036.         info.table.Rows.MergeCells(0,idx-1,1,CurrentRow,True,False);
  1037.         HideBorders(0,idx-1);
  1038.         end
  1039.       else if abs(info.HRules[idx]-val)>RV_TableGridEps then begin
  1040.         info.HRules.Insert(idx, val);
  1041.         info.HRules.Sort;
  1042.         info.table.InsertCols(idx-1,1,-1);
  1043.         MergeCol(info.table,idx-1);
  1044.       end;
  1045.       info.table.Rows.MergeCells(CurrentRow,strt,idx-strt,1,True,False);
  1046.       if (strt>0) and (RowProps.CellProps[i].HMerge=rtf_cm_Merged) then begin
  1047.         info.table.Rows.GetMainCell(CurrentRow,strt-1,r,c);
  1048.         info.table.Rows.MergeCells(r,c,idx-c,CurrentRow-r+1,True,False);
  1049.       end;
  1050.       if RowProps.CellProps[i].VMerge=rtf_cm_Merged then begin
  1051.         info.table.Rows.GetMainCell(CurrentRow-1,strt,r,c);
  1052.         span := idx-c;
  1053.         if info.table.Cells[r,c].ColSpan>span then
  1054.           span := info.table.Cells[r,c].ColSpan;
  1055.         info.table.Rows.MergeCells(r,c,span,CurrentRow-r+1,True,False);
  1056.       end;
  1057.       if info.table.Cells[CurrentRow,strt]<>nil then begin
  1058.         AssignCellProperties(info.table.Cells[CurrentRow,strt],RowProps.CellProps[i],strt,idx);
  1059.         info.table.Cells[CurrentRow,strt].Clear;
  1060.         info.table.Cells[CurrentRow,strt].DrainFrom(info.lastrow.Cells[0,i]);
  1061.       end;
  1062.       strt := idx;
  1063.       //if strt>=info.table.Rows.Count then
  1064.       //  dec(strt);
  1065.     end;
  1066.     for i := strt to info.table.Rows[CurrentRow].Count-1 do
  1067.       HideBorders(CurrentRow,i);
  1068.     end
  1069.   else // CurrentRow=0
  1070.     for i := 0 to RowProps.CellProps.Count-1 do begin
  1071.       if RowProps.CellProps[i].HMerge=rtf_cm_Merged then begin
  1072.         info.table.Rows.GetMainCell(CurrentRow,i-1,r,c);
  1073.         info.table.Rows.MergeCells(r,c,i-c+1,1,True,False);
  1074.       end;
  1075.       if info.table.Cells[CurrentRow,i]<>nil then begin
  1076.         AssignCellProperties(info.table.Cells[CurrentRow,i], RowProps.CellProps[i],i,i+1);
  1077.         info.table.Cells[CurrentRow,i].Clear;
  1078.         info.table.Cells[CurrentRow,i].DrainFrom(info.lastrow.Cells[0,i]);
  1079.       end;
  1080.     end;
  1081.   info.PrevColCount := info.table.Rows[0].Count-1;
  1082. end;
  1083. {------------------------------------------------------------------------------}
  1084. procedure TRVRTFReaderProperties.ReaderTable(Sender: TRVRTFReader;
  1085.   WhatHappens: TRVRTFTableEventKind);
  1086. var info: TTableInfo;
  1087.     i: Integer;
  1088.     PrevRVData:TCustomRVData;
  1089.     s: String;
  1090.     APageBreak: Boolean;
  1091.     APageBreakRVData: TCustomRVData;
  1092.     Alignment: TRVAlignment;
  1093. begin
  1094.   case WhatHappens of
  1095.     rvf_tbl_TableStart:
  1096.       begin
  1097.         if Tables=nil then
  1098.           Tables := TRVList.Create;
  1099.         info := TTableInfo.Create;
  1100.         info.table := TRVTableItemInfo.CreateEx(0,0,CurrentRVData);
  1101.         if PageBreak and (PageBreakRVData=CurrentRVData) then begin
  1102.           info.table.PageBreakBefore := True;
  1103.           PageBreak := False;
  1104.           PageBreakRVData := nil;
  1105.         end;        
  1106.         info.table.BeforeLoading(rvlfRTF);
  1107.         info.table.Color := clNone;
  1108.         info.table.BorderStyle := rvtbRaisedColor;
  1109.         info.table.CellBorderStyle := rvtbLoweredColor;
  1110.         info.table.CellBorderColor := clWindowText;
  1111.         info.table.BorderColor := clWindowText;
  1112.         info.table.BorderLightColor := clWindowText;
  1113.         info.table.CellBorderLightColor := clWindowText;
  1114.         info.lastrow := TRVTableItemInfo.CreateEx(1,1,CurrentRVData);
  1115.         info.lastrow.BeforeLoading(rvlfRTF);
  1116.         info.ParentRow := CurrentRow;
  1117.         info.ParentCol := CurrentCol;
  1118.         CurrentRow := 0;
  1119.         CurrentCol := 0;
  1120.         CurrentRVData := info.lastrow.Cells[0,0];
  1121.         CurrentRVData.Clear;
  1122.         Tables.Add(info);
  1123.       end;
  1124.     rvf_tbl_TableEnd:
  1125.       begin
  1126.         info := TTableInfo(Tables[Tables.Count-1]);
  1127.         if Tables.Count=1 then
  1128.           case HFType of
  1129.             rtf_hf_Header:
  1130.               PrevRVData := FHeaderRVData;
  1131.             rtf_hf_Footer:
  1132.               PrevRVData := FFooterRVData;
  1133.             else
  1134.               PrevRVData := RVData;
  1135.           end
  1136.         else
  1137.           PrevRVData := TTableInfo(Tables[Tables.Count-2]).lastrow.Cells[0,info.ParentCol];
  1138.         info.Finalize(PixelsPerTwip, {AdjustVisibleBorders, }
  1139.           GetEmptyStyleNo, GetEmptyParaNo(rvaLeft), ExplicitTableWidth,
  1140.           AutoHideTableGridLines);
  1141.         if PageBreak and (PageBreakRVData=CurrentRVData) then
  1142.           PageBreakRVData := PrevRVData;
  1143.         APageBreak := PageBreak;
  1144.         APageBreakRVData := PageBreakRVData;
  1145.         PageBreak := False;
  1146.         PageBreakRVData := nil;
  1147.         CurrentRVData := PrevRVData;
  1148.         CurrentRow := info.ParentRow;
  1149.         CurrentCol := info.ParentCol;
  1150.         info.table.DeleteCols(info.HRules.Count-1,info.table.Rows[0].Count-info.HRules.Count+1,False);
  1151.         if Reader.FTableAlignmentDefined then
  1152.           Alignment := TRVAlignment(ord(Reader.FTableAlignment))
  1153.         else
  1154.           Alignment := rvaLeft; //TRVAlignment(ord(Reader.RTFState.ParaProps.Alignment));        
  1155.         info.table.ParaNo := GetEmptyParaNo(Alignment);
  1156.         s := '';
  1157.         if (info.table.Rows.Count=0) or (info.table.Rows[0].Count=0) then begin
  1158.           info.table.Free;
  1159.           info.table := nil
  1160.           end
  1161.         else begin
  1162.           info.table.DeleteEmptyRows;
  1163.           InsertItem(s, info.table, rtf_ts_NewPara);
  1164.         end;
  1165.         if not info.RowFinished then begin
  1166.           {$IFNDEF RVDONOTUSELISTS}
  1167.           IgnoreLists := True;
  1168.           {$ENDIF}
  1169.           try
  1170.             for i := 0 to info.lastrow.Cells[0,0].Items.Count-1 do begin
  1171.               s := info.lastrow.Cells[0,0].Items[i];
  1172.               InsertItem(s, info.lastrow.Cells[0,0].GetItem(i), rtf_ts_NewPara);
  1173.               info.lastrow.Cells[0,0].Items.Objects[i] := nil;
  1174.             end;
  1175.           finally
  1176.             {$IFNDEF RVDONOTUSELISTS}
  1177.             IgnoreLists := False;
  1178.             LastMarkerIndex := -1;
  1179.             {$ENDIF}
  1180.           end;
  1181.         end;
  1182.         Tables.Delete(Tables.Count-1);
  1183.         PageBreak := APageBreak;
  1184.         PageBreakRVData := APageBreakRVData;
  1185.       end;
  1186.     rvf_tbl_CellEnd:
  1187.       begin
  1188.         info := TTableInfo(Tables[Tables.Count-1]);
  1189.         if info.lastrow.Cells[0,CurrentCol].Items.Count=0 then begin
  1190.            NewReaderText(Sender,'',rtf_ts_NewPara);
  1191.            {$IFNDEF RVDONOTUSELISTS}
  1192.            ReaderUpdateMarker(Sender);
  1193.            {$ENDIF}
  1194.         end;
  1195.         inc(CurrentCol);
  1196.         if CurrentCol=info.lastrow.Rows[0].Count then
  1197.           info.lastrow.InsertCols(CurrentCol,1,-1);
  1198.         CurrentRVData := info.lastrow.Cells[0,CurrentCol];
  1199.         CurrentRVData.Clear;
  1200.       end;
  1201.     rvf_tbl_RowEnd:
  1202.       begin
  1203.         AssignRowProperties;
  1204.         info := TTableInfo(Tables[Tables.Count-1]);
  1205.         info.RowFinished := True;
  1206.         inc(CurrentRow);
  1207.         CurrentCol := 0;
  1208.         info.lastrow.Rows.Reset(1,1);;
  1209.         CurrentRVData := info.lastrow.Cells[0,CurrentCol];
  1210.         CurrentRVData.Clear;
  1211.       end;
  1212.   end;
  1213. end;
  1214. {$ENDIF}
  1215. {------------------------------------------------------------------------------}
  1216. function TRVRTFReaderProperties.CreateTextItem(const Text: String;
  1217.                                                {$IFDEF RICHVIEWCBDEF3}
  1218.                                                const WideText: WideString;
  1219.                                                {$ENDIF}
  1220.                                                StyleNo, ParaNo: Integer;
  1221.                                                UseUnicode: Boolean;
  1222.                                                var ResText: String): TRVTextItemInfo;
  1223. var
  1224.   Target, Hint, Extras: String;
  1225.   AStyleNo,ItemTag: Integer;
  1226. begin
  1227.   Hint := '';
  1228.   Result := RichViewTextItemClass.Create(CurrentRVData);
  1229.   Result.BeforeLoading(rvlfRTF);
  1230.   {$IFNDEF RVDONOTUSEUNICODE}
  1231.   if RVStyle.TextStyles[StyleNo].Unicode then
  1232.     Include(Result.ItemOptions, rvioUnicode);
  1233.   if not UseUnicode then
  1234.     if RVStyle.TextStyles[StyleNo].Unicode then
  1235.       ResText := RVU_AnsiToUnicode(
  1236.         RVU_Charset2CodePage(
  1237.           Reader.FontTable[Reader.RTFState.CharProps.FontIndex].Charset), Text)
  1238.     else
  1239.       ResText := Text
  1240.   else
  1241.     if RVStyle.TextStyles[StyleNo].Unicode then begin
  1242.       SetLength(ResText, Length(WideText)*2);
  1243.       Move(Pointer(WideText)^, PChar(ResText)^, Length(ResText));
  1244.       end
  1245.     else
  1246.       ResText := Reader.UnicodeToAnsi(WideText);
  1247.   {$ELSE}
  1248.   ResText := Text;
  1249.   {$ENDIF}
  1250.   ResText := CurrentRVData.ReplaceTabs(ResText, StyleNo, False);
  1251.   ItemTag := 0;
  1252.   if IsHypertext(Target, Hint, Extras) then begin
  1253.     AStyleNo := StyleNo;
  1254.     CurrentRVData.ReadHyperlink(Target, Extras, rvlfRTF, AStyleNo, ItemTag, ResText);
  1255.     if AStyleNo>=0 then
  1256.       StyleNo := AStyleNo;
  1257.   end;
  1258.   Result.StyleNo := StyleNo;
  1259.   Result.ParaNo  := ParaNo;
  1260.   Result.Tag     := ItemTag;
  1261.   {$IFNDEF RVDONOTUSEITEMHINTS}
  1262.   Result.Hint    := Hint;
  1263.   {$ENDIF}
  1264. end;
  1265. {------------------------------------------------------------------------------}
  1266. procedure TRVRTFReaderProperties.InsertItem(var Text: String;
  1267.   item: TCustomRVItemInfo; Position: TRVRTFPosition);
  1268. var Dummy: Integer;
  1269. begin
  1270.   case Position of
  1271.      rtf_ts_ContinuePara:
  1272.          item.SameAsPrev := True;
  1273.      rtf_ts_NewLine,
  1274.      rtf_ts_NewPara:
  1275.        begin
  1276.          if (Position = rtf_ts_NewLine) and not LineBreaksAsParagraphs then
  1277.            item.BR := True
  1278.          else begin
  1279.            if not AllowNewPara then
  1280.              item.BR := True
  1281.            else begin
  1282.              {$IFNDEF RVDONOTUSELISTS}
  1283.              if (item.StyleNo<>rvsListMarker) and not IgnoreLists {$IFNDEF RVDONOTUSETABLES} and (item.StyleNo<>rvsTable){$ENDIF} then
  1284.                if InsertMarker(item.ParaNo) then
  1285.                  item.SameAsPrev := True;
  1286.              {$ENDIF}
  1287.            end;
  1288.          end;
  1289.        end;
  1290.   end;
  1291.   if PageBreak and (PageBreakRVData=CurrentRVData) then begin
  1292.     item.PageBreakBefore := True;
  1293.     PageBreak := False;
  1294.     PageBreakRVData := nil;
  1295.   end;
  1296.   if RVData=CurrentRVData then begin
  1297.     if FirstTime then begin
  1298.       FirstTime := False;
  1299.       if not EditFlag and ((InsertPoint=0) or
  1300.        (CurrentRVData.GetItem(InsertPoint-1).GetBoolValue(rvbpFullWidth))) then
  1301.         item.SameAsPrev := False;
  1302.       if not RVData.InsertFirstRVFItem(InsertPoint, Text, Item, EditFlag, FullReformat, Dummy) then begin
  1303.         FailedBecauseOfProtect := True;
  1304.         abort;
  1305.       end;
  1306.       if item<>nil then begin
  1307.         Item.AfterLoading(rvlfRTF);
  1308.         inc(InsertPoint);
  1309.         Index := InsertPoint-1;
  1310.         end
  1311.       else
  1312.         FirstTime := True;
  1313.       {$IFNDEF RVDONOTUSELISTS}
  1314.       if (item<>nil) and (item.StyleNo=rvsListMarker) then
  1315.         LastMarkerIndex := Index;
  1316.       {$ENDIF}
  1317.       end
  1318.     else begin
  1319.       if (InsertPoint=0) or
  1320.        (CurrentRVData.GetItem(InsertPoint-1).GetBoolValue(rvbpFullWidth)) then
  1321.         item.SameAsPrev := False;
  1322.       Item.Inserting(RVData, Text, False);
  1323.       RVData.Items.InsertObject(InsertPoint, Text, Item);
  1324.       Item.Inserted(RVData, InsertPoint);
  1325.       Item.AfterLoading(rvlfRTF);
  1326.       {$IFNDEF RVDONOTUSELISTS}
  1327.       RVData.AddMarkerInList(InsertPoint);
  1328.       if item.StyleNo=rvsListMarker then
  1329.         LastMarkerIndex := InsertPoint;
  1330.       {$ENDIF}
  1331.       inc(InsertPoint);
  1332.       inc(NonFirstItemsAdded);
  1333.     end;
  1334.     end
  1335.   else begin
  1336.     if (CurrentRVData.Items.Count=0) or
  1337.        (CurrentRVData.GetItem(CurrentRVData.Items.Count-1).GetBoolValue(rvbpFullWidth)) then
  1338.       item.SameAsPrev := False;
  1339.     Item.Inserting(CurrentRVData, Text, False);
  1340.     CurrentRVData.Items.AddObject(Text, Item);
  1341.     Item.Inserted(CurrentRVData, CurrentRVData.Items.Count-1);
  1342.     if (CurrentRVData=FHeaderRVData) or (CurrentRVData=FFooterRVData) then
  1343.       Item.AfterLoading(rvlfRTF);
  1344.     {$IFNDEF RVDONOTUSELISTS}
  1345.     CurrentRVData.AddMarkerInList(CurrentRVData.Items.Count-1);
  1346.     if item.StyleNo=rvsListMarker then
  1347.       LastMarkerIndex := CurrentRVData.Items.Count-1;
  1348.     {$ENDIF}
  1349.     {$IFNDEF RVDONOTUSETABLES}
  1350.     if (CurrentRVData<>FHeaderRVData) and (CurrentRVData<>FFooterRVData) then
  1351.       TTableInfo(Tables[Tables.Count-1]).RowFinished := False;
  1352.     {$ENDIF}
  1353.   end;
  1354. end;
  1355. {------------------------------------------------------------------------------}
  1356. {$IFNDEF RVDONOTUSELISTS}
  1357. procedure ConvMarker(RTFMarker: TRVRTFMarkerProperties;
  1358.                      var RVType: TRVListType;
  1359.                      var FormatStr1,FormatStr2: String);
  1360. begin
  1361.   if (RTFMarker.Level=11) or
  1362.      ((RTFMarker.Level=10) and (RTFMarker.ListType=rtf_pn_Default)) then begin
  1363.     RVType := rvlstBullet;
  1364.     FormatStr1 := RTFMarker.TextBefore;
  1365.     FormatStr2 := RTFMarker.TextBefore;
  1366.     end
  1367.   else begin
  1368.     case RTFMarker.ListType of
  1369.       rtf_pn_Default, rtf_pn_Decimal:
  1370.         RVType := rvlstDecimal;
  1371.       rtf_pn_LowerLetter:
  1372.         RVType := rvlstLowerAlpha;
  1373.       rtf_pn_UpperLetter:
  1374.         RVType := rvlstUpperAlpha;
  1375.       rtf_pn_LowerRoman:
  1376.         RVType := rvlstLowerRoman;
  1377.       rtf_pn_UpperRoman:
  1378.         RVType := rvlstUpperRoman;
  1379.     end;
  1380.     FormatStr1 := RTFMarker.TextBefore+'%s'+RTFMarker.TextAfter;
  1381.     FormatStr2 := RTFMarker.TextBefore+'%0:s'+RTFMarker.TextAfter;
  1382.   end;
  1383. end;
  1384. {------------------------------------------------------------------------------}
  1385. function GetMarkerFontName(Reader: TRVRTFReader;
  1386.   RTFMarker: TRVRTFCustomMarkerProperties): String;
  1387. begin
  1388.   if RTFMarker.FontIndex<0 then
  1389.     Result := Reader.FontTable[0].Name//RVFONT_SYMBOL
  1390.   else
  1391.     Result := Reader.FontTable[RTFMarker.FontIndex].Name;
  1392. end;
  1393. {------------------------------------------------------------------------------}
  1394. {$IFDEF RICHVIEWCBDEF3}
  1395. function GetMarkerCharset(Reader: TRVRTFReader;
  1396.   RTFMarker: TRVRTFCustomMarkerProperties): TFontCharset;
  1397. begin
  1398.   if RTFMarker.FontIndex<0 then
  1399.     Result := Reader.FontTable[0].Charset// SYMBOL_CHARSET
  1400.   else
  1401.     Result := Reader.FontTable[RTFMarker.FontIndex].Charset;
  1402. end;
  1403. {$ENDIF}
  1404. {------------------------------------------------------------------------------}
  1405. {$IFNDEF RICHVIEWCBDEF4}
  1406. function max(a,b:Integer): Integer;
  1407. begin
  1408.   if a>b then
  1409.     Result := a
  1410.   else
  1411.     Result := b;
  1412. end;
  1413. {$ENDIF}
  1414. function TRVRTFReaderProperties.GetMarkerIndex(RTFMarker: TRVRTFMarkerProperties): Integer;
  1415. var i: Integer;
  1416.     Level : TRVListLevel;
  1417.     FormatStr1,FormatStr2, FontName: String;
  1418.     ListType: TRVListType;
  1419.     FirstIndent, LeftIndent, PNIndent, PNSpace: Integer;
  1420.     MarkerAlign: TRVRTFAlignment;
  1421.     {..............................................}
  1422.     function IsEqualIndents(Level : TRVListLevel): Boolean;
  1423.     begin
  1424.       if RTFMarker.Hanging then
  1425.         Result :=
  1426.           (Level.LeftIndent=LeftIndent) and
  1427.           (Level.FirstIndent=max(PNSpace, FirstIndent+PNIndent))
  1428.       else
  1429.         Result :=
  1430.           (Level.LeftIndent=LeftIndent) and
  1431.           (Level.FirstIndent= max(0, FirstIndent+max(PNIndent,PNSpace)));
  1432.       if not Result then
  1433.         exit;
  1434.       case MarkerAlign of
  1435.         rtf_al_Left:
  1436.           Result := Level.MarkerIndent=LeftIndent+FirstIndent;
  1437.         rtf_al_Right:
  1438.           Result := Level.MarkerIndent=Level.FirstIndent+Level.LeftIndent;
  1439.         rtf_al_Center:
  1440.           Result := Level.MarkerIndent=(LeftIndent+FirstIndent+Level.FirstIndent+Level.LeftIndent) div 2;
  1441.       end;
  1442.     end;
  1443.     {..............................................}
  1444. begin
  1445.   Result := -1;
  1446.   if ParaStyleMode<>rvrsAddIfNeeded then
  1447.     exit;  
  1448.   if (RTFMarker=nil) or (RTFMarker.FontIndex>=Reader.FontTable.Count) or (RTFMarker.Level<=0) then
  1449.     exit;
  1450.   if LevelToListNo.Count=0 then
  1451.     LevelToListNo.InitWith(-1, 11);
  1452.   if (RTFMarker.Level<11) and (LevelToListNo[RTFMarker.Level-1]>=0) then begin
  1453.     Result := LevelToListNo[RTFMarker.Level-1];
  1454.     exit;
  1455.   end;
  1456.   FontName := GetMarkerFontName(Reader, RTFMarker);
  1457.   ConvMarker(RTFMarker, ListType, FormatStr1,FormatStr2);
  1458.   MarkerAlign := RTFMarker.Alignment;
  1459.   if RTFMarker.Level=11 then
  1460.     MarkerAlign := rtf_al_Left;
  1461.   LeftIndent := Round(Reader.RTFState.ParaProps.LeftIndentTw*PixelsPerTwip);
  1462.   FirstIndent := Round(Reader.RTFState.ParaProps.FirstIndentTw*PixelsPerTwip);
  1463.   PNIndent := Round(RTFMarker.IndentTw*PixelsPerTwip);
  1464.   PNSpace  := Round(RTFMarker.SpaceTw*PixelsPerTwip);
  1465.   for i := 0 to RVStyle.ListStyles.Count-1 do begin
  1466.     if RVStyle.ListStyles[i].Levels.Count=0 then
  1467.       continue;
  1468.     Level := RVStyle.ListStyles[i].Levels[0];
  1469.     if (Level.ListType=ListType) and
  1470.        (Level.MarkerAlignment=TRVMarkerAlignment(MarkerAlign)) and
  1471.        IsEqualIndents(Level) and
  1472.        (Level.Font.Size=RTFMarker.FontSize) and
  1473.        (Level.Font.Style=RTFMarker.FontStyle) and
  1474.        (Level.Font.Color=RTFMarker.Color) and
  1475.        (AnsiCompareText(Level.Font.Name,FontName)=0) and
  1476.        ((Level.FormatString=FormatStr1) or (Level.FormatString=FormatStr2)) then begin
  1477.       Result := i;
  1478.       LevelToListNo[RTFMarker.Level-1] := Result;
  1479.       exit;
  1480.     end;
  1481.   end;
  1482.   Result := RVStyle.ListStyles.Count;
  1483.   Level := RVStyle.ListStyles.Add.Levels.Add;
  1484.   RVStyle.ListStyles[RVStyle.ListStyles.Count-1].Standard := False;
  1485.   Level.ListType   := ListType;
  1486.   Level.LeftIndent := LeftIndent;
  1487.   Level.MarkerIndent := LeftIndent+FirstIndent;
  1488.   if RTFMarker.Hanging then
  1489.     Level.FirstIndent := max(PNSpace, FirstIndent+PNIndent)
  1490.   else
  1491.     Level.FirstIndent := max(0, FirstIndent+max(PNIndent,PNSpace));
  1492.   Level.MarkerAlignment := TRVMarkerAlignment(MarkerAlign);
  1493.   case MarkerAlign of
  1494.     rtf_al_Right:
  1495.       begin
  1496.         Level.MarkerIndent := Level.FirstIndent+Level.LeftIndent;
  1497.       end;
  1498.     rtf_al_Center:
  1499.       begin
  1500.         Level.MarkerIndent := (Level.FirstIndent+Level.LeftIndent+Level.MarkerIndent) div 2;
  1501.       end;
  1502.   end;
  1503.   Level.Font.Size  := RTFMarker.FontSize;
  1504.   Level.Font.Style := RTFMarker.FontStyle;
  1505.   Level.Font.Color := RTFMarker.Color;
  1506.   Level.Font.Name  := FontName;
  1507.   Level.FormatString := FormatStr1;
  1508.   LevelToListNo[RTFMarker.Level-1] := Result;
  1509. end;
  1510. {------------------------------------------------------------------------------}
  1511. // Old-style numbering has higher priority
  1512. function TRVRTFReaderProperties.InsertMarker(ParaNo: Integer): Boolean;
  1513. var marker: TRVMarkerItemInfo;
  1514.     s: String;
  1515. begin
  1516.   if ParaStyleMode<>rvrsAddIfNeeded then begin
  1517.     Result := False;
  1518.     exit;
  1519.   end;
  1520.   if not Reader.RTFState.ParaProps.HasMarker then
  1521.     LevelToListNo.Clear;
  1522.   Result := Reader.RTFState.ParaProps.HasMarker and
  1523.     (Reader.RTFState.ParaProps.MarkerProps.Level>0);
  1524.   if not Result then begin
  1525.     if Reader.RTFState.ParaProps.ListOverrideIndex>=0 then begin
  1526.       MergeListTable97;
  1527.       InsertMarker97(ParaNo);
  1528.       Result := True;
  1529.     end;
  1530.     exit;
  1531.   end;
  1532.   if LevelToListNo.Count=0 then
  1533.     LevelToListNo.InitWith(-1, 11);
  1534.   marker := TRVMarkerItemInfo.CreateEx(CurrentRVData,
  1535.     -1, -1, Reader.RTFState.ParaProps.MarkerProps.Start,
  1536.     LevelToListNo[Reader.RTFState.ParaProps.MarkerProps.Level-1]<0);
  1537.   marker.ParaNo := ParaNo;
  1538.   marker.BeforeLoading(rvlfRTF);
  1539.   s := '';
  1540.   InsertItem(s, marker, rtf_ts_NewPara);
  1541.   IsLastMarkerWord97 := False;
  1542. end;
  1543. {------------------------------------------------------------------------------}
  1544. procedure TRVRTFReaderProperties.InsertMarker97(ParaNo: Integer);
  1545. var marker: TRVMarkerItemInfo;
  1546.     s: String;
  1547.     ListLevel, ListNo, ListMappedNo: Integer;
  1548.     ListOverride: TRVRTFListOverride97;
  1549.     Start: Integer;
  1550.     UseStart: Boolean;
  1551. begin
  1552.   if ParaStyleMode<>rvrsAddIfNeeded then
  1553.     exit;
  1554.   ListLevel := Reader.RTFState.ParaProps.ListLevel;
  1555.   ListOverride := Reader.ListOverrideTable[Reader.RTFState.ParaProps.ListOverrideIndex];
  1556.   if ListLevel<ListOverride.Count then begin
  1557.     Start := ListOverride[ListLevel].Start;
  1558.     UseStart := ListOverride[ListLevel].UseStart;
  1559.     end
  1560.   else begin
  1561.     Start := 1;
  1562.     UseStart := False;
  1563.   end;
  1564.   ListNo := ListOverride.ListIndex;
  1565.   ListMappedNo := ListTableMap97[ListNo];
  1566.   marker := TRVMarkerItemInfo.CreateEx(CurrentRVData,
  1567.     ListMappedNo, Reader.RTFState.ParaProps.ListLevel, Start, UseStart);
  1568.   marker.ParaNo := ParaNo;
  1569.   marker.BeforeLoading(rvlfRTF);
  1570.   s := '';
  1571.   InsertItem(s, marker, rtf_ts_NewPara);
  1572.   IsLastMarkerWord97 := True;
  1573. end;
  1574. {------------------------------------------------------------------------------}
  1575. procedure TRVRTFReaderProperties.ReaderUpdateMarker(Sender: TObject);
  1576. var Marker: TRVMarkerItemInfo;
  1577.     ListLevel, ListNo, FIDif: Integer;
  1578.     ListOverride: TRVRTFListOverride97;
  1579.     Level: TRVListLevel;
  1580. begin
  1581.   if ParaStyleMode<>rvrsAddIfNeeded then
  1582.     exit;
  1583.   if LastMarkerIndex>=0 then begin
  1584.     if not IsLastMarkerWord97 then begin
  1585.       Marker := CurrentRVData.GetItem(LastMarkerIndex) as TRVMarkerItemInfo;
  1586.       Marker.ListNo := GetMarkerIndex(Reader.RTFState.ParaProps.MarkerProps);
  1587.       if Marker.ListNo>=0 then begin
  1588.         Marker.Level := 0;
  1589.         CurrentRVData.RecalcMarker(LastMarkerIndex, True);
  1590.       end;
  1591.       end
  1592.     else begin
  1593.       ListLevel := Reader.RTFState.ParaProps.ListLevel;
  1594.       if Reader.RTFState.ParaProps.ListOverrideIndex>=0 then begin
  1595.         ListOverride := Reader.ListOverrideTable[Reader.RTFState.ParaProps.ListOverrideIndex];
  1596.         ListNo := ListOverride.ListIndex;
  1597.         if not Reader.ListTable[ListNo].Items[ListLevel].FIndentsUpdated then begin
  1598.           Marker := CurrentRVData.GetItem(LastMarkerIndex) as TRVMarkerItemInfo;
  1599.           Level := RVStyle.ListStyles[Marker.ListNo].Levels[Marker.Level];
  1600.           if (Marker.ListNo>=ListStylesCountBefore) then begin
  1601.             FIDif := Level.LeftIndent+Level.FirstIndent-Level.MarkerIndent;
  1602.             Level.MarkerIndent := Round(
  1603.               (Reader.RTFState.ParaProps.LeftIndentTw+Reader.RTFState.ParaProps.FirstIndentTw)*PixelsPerTwip);
  1604.             Level.LeftIndent :=
  1605.               Round(Reader.RTFState.ParaProps.LeftIndentTw*PixelsPerTwip);
  1606.             Level.FirstIndent := Level.MarkerIndent-Level.LeftIndent+FIDif;
  1607.           end;
  1608.           Reader.ListTable[ListNo].Items[ListLevel].FIndentsUpdated := True;
  1609.         end;
  1610.         if not Reader.ListTable[ListNo].Items[ListLevel].FFontSizeDefined then begin
  1611.           Marker := CurrentRVData.GetItem(LastMarkerIndex) as TRVMarkerItemInfo;
  1612.           if (Marker.ListNo>=ListStylesCountBefore) then begin
  1613.             RVStyle.ListStyles[Marker.ListNo].Levels[Marker.Level].Font.Size :=
  1614.               Reader.RTFState.CharProps.Size;
  1615.             Reader.ListTable[ListNo].Items[ListLevel].FFontSize :=
  1616.               Reader.RTFState.CharProps.Size;
  1617.             Reader.ListTable[ListNo].Items[ListLevel].FFontSizeDefined :=
  1618.               True;
  1619.           end;
  1620.         end;
  1621.       end;
  1622.     end;
  1623.     LastMarkerIndex := -1;
  1624.   end;
  1625. end;
  1626. {------------------------------------------------------------------------------}
  1627. procedure ConvMarker97(Reader: TRVRTFReader;
  1628.                      RTFMarker: TRVRTFListLevel97;
  1629.                      var RVType: TRVListType;
  1630.                      var FormatStr1,FormatStr2: String;
  1631.                      var FormatStrW:
  1632.                      {$IFDEF RICHVIEWCBDEF3}WideString{$ELSE}String{$ENDIF}
  1633.                      );
  1634. var i: Integer;
  1635.     s1,s2: String;
  1636. {$IFNDEF RVDONOTUSEUNICODE}
  1637.     FontName: String;
  1638. {$ENDIF}
  1639. begin
  1640.   case RTFMarker.ListType of
  1641.     rtf_pn_Decimal, rtf_pn_Default:
  1642.       RVType := rvlstDecimal;
  1643.     rtf_pn_LowerLetter:
  1644.       RVType := rvlstLowerAlpha;
  1645.     rtf_pn_UpperLetter:
  1646.       RVType := rvlstUpperAlpha;
  1647.     rtf_pn_LowerRoman:
  1648.       RVType := rvlstLowerRoman;
  1649.     rtf_pn_UpperRoman:
  1650.       RVType := rvlstUpperRoman;
  1651.     rtf_pn_Bullet:
  1652.       RVType := rvlstBullet;
  1653.   end;
  1654.   FormatStr1 := Copy(RTFMarker.Text, 2, Length(RTFMarker.Text)-1);
  1655.   FormatStr2 := FormatStr1;
  1656.   for i := Length(FormatStr1) downto 1 do
  1657.     if FormatStr1[i] in [#0..#9] then begin
  1658.       s2 := '%'+IntToStr(ord(FormatStr1[i]))+':s';
  1659.       if FormatStr1[i]=#0 then
  1660.         s1 := '%s'
  1661.       else
  1662.         s1 := s2;
  1663.       Delete(FormatStr1,i,1);
  1664.       Insert(s1, FormatStr1, i);
  1665.       Delete(FormatStr2,i,1);
  1666.       Insert(s2, FormatStr2, i);
  1667.     end;
  1668.   FormatStrW := '';
  1669.   {$IFNDEF RVDONOTUSEUNICODE}
  1670.   if (RTFMarker.TextW<>'') and (RTFMarker.ListType=rtf_pn_Bullet) then begin
  1671.     RVType := rvlstUnicodeBullet;
  1672.     FormatStrW := Copy(RTFMarker.TextW, 2, Length(RTFMarker.TextW)-1);
  1673.     if (Length(FormatStrW)=1) then begin
  1674.       FontName := GetMarkerFontName(Reader, RTFMarker);
  1675.       if (Word(FormatStrW[1])>=61601) and (Word(FormatStrW[1])<=61694) and
  1676.          (CompareText(FontName, RVFONT_SYMBOL)=0) then begin
  1677.         FormatStr1 := chr(Word(FormatStrW[1])-61601+161);
  1678.         FormatStr2 := FormatStr1;
  1679.         RVType := rvlstBullet;
  1680.       end;
  1681.       if (Word(FormatStrW[1])>=61473) and (Word(FormatStrW[1])<=61695) and
  1682.          (CompareText(FontName, RVFONT_WINGDINGS)=0) then begin
  1683.         FormatStr1 := chr(Word(FormatStrW[1])-61473+33);
  1684.         FormatStr2 := FormatStr1;
  1685.         RVType := rvlstBullet;
  1686.       end;
  1687.     end;
  1688.   end;
  1689.   {$ENDIF}
  1690. end;
  1691. {------------------------------------------------------------------------------}
  1692. function AreLevelsEqual97(RVLevel: TRVListLevel; RTFLevel: TRVRTFListLevel97;
  1693.                      RVType: TRVListType;
  1694.                      const FontName, FormatStr1, FormatStr2: String;
  1695.                      const FormatStrW: {$IFDEF RICHVIEWCBDEF3}WideString{$ELSE}String{$ENDIF};
  1696.                      PixelsPerTwip: Double): Boolean;
  1697. begin
  1698.   Result :=  (RVLevel.ListType = RVType) and
  1699.             (RVLevel.StartFrom = RTFLevel.Start) and
  1700.             (RVLevel.MarkerAlignment = TRVMarkerAlignment(RTFLevel.Alignment)) and
  1701.             (RVLevel.LeftIndent = Round(RTFLevel.LeftIndentTw*PixelsPerTwip)) and
  1702.             (RVLevel.MarkerIndent = Round(RTFLevel.FirstIndentTw*PixelsPerTwip)+RVLevel.LeftIndent) and
  1703.             (RVLevel.FirstIndent = Round(RTFLevel.TabPosTw*PixelsPerTwip)-RVLevel.LeftIndent) and
  1704.             (RTFLevel.NoRestart = not (rvloLevelReset in RVLevel.Options)) and
  1705.             (RTFLevel.Legal = (rvloLegalStyleNumbering in RVLevel.Options)) and
  1706.             (RVLevel.Font.Style = RTFLevel.FontStyle) and
  1707.             (RVLevel.Font.Color = RTFLevel.Color) and
  1708.             (RVLevel.Font.Size  = RTFLevel.FontSize) and
  1709.             (CompareText(RVLevel.Font.Name, FontName) = 0);
  1710.   if not Result then
  1711.     exit;
  1712.   case RVType of
  1713.     rvlstDecimal,rvlstLowerAlpha,
  1714.     rvlstUpperAlpha,rvlstLowerRoman,
  1715.     rvlstUpperRoman,rvlstBullet:
  1716.       Result := (RVLevel.FormatString=FormatStr1) or
  1717.                 (RVLevel.FormatString=FormatStr2);
  1718.     {$IFNDEF RVDONOTUSEUNICODE}
  1719.     rvlstUnicodeBullet:
  1720.       Result := (RVLevel.FormatStringW=FormatStrW);
  1721.     {$ENDIF}
  1722.   end;
  1723. end;
  1724. {------------------------------------------------------------------------------}
  1725. function TRVRTFReaderProperties.AreListStylesEqual97(RVList: TRVListInfo; RTFList: TRVRTFList97): Boolean;
  1726. var
  1727.   RVType: TRVListType;
  1728.   FontName, FormatStr1, FormatStr2: String;
  1729.   FormatStrW: {$IFDEF RICHVIEWCBDEF3}WideString{$ELSE}String{$ENDIF};
  1730.   RTFLevel: TRVRTFListLevel97;
  1731.   i: Integer;
  1732. begin
  1733.   Result := RVList.Levels.Count>=RTFList.Count;
  1734.   if not Result then
  1735.     exit;
  1736.   for i := 0 to RTFList.Count-1 do begin
  1737.      RTFLevel := RTFList.Items[i];
  1738.       ConvMarker97(Reader, RTFLevel, RVType, FormatStr1, FormatStr2, FormatStrW);
  1739.       FontName := GetMarkerFontName(Reader, RTFLevel);
  1740.       Result := AreLevelsEqual97(RVList.Levels[i], RTFLevel, RVType,
  1741.         FontName,FormatStr1,FormatStr2,FormatStrW,PixelsPerTwip);
  1742.       if not Result then
  1743.         exit;
  1744.   end;
  1745. end;
  1746. {------------------------------------------------------------------------------}
  1747. function TRVRTFReaderProperties.FindListStyle97(RTFList: TRVRTFList97;
  1748.   ForbiddenStyles: TRVIntegerList): Integer;
  1749. var i: Integer;
  1750. begin
  1751.   if ParaStyleMode=rvrsAddIfNeeded then
  1752.     for i := 0 to RVStyle.ListStyles.Count-1 do
  1753.       if (ForbiddenStyles.IndexOf(Pointer(i))<0) and
  1754.          AreListStylesEqual97(RVStyle.ListStyles[i], RTFList) then begin
  1755.         Result := i;
  1756.         exit;
  1757.       end;
  1758.   Result := -1;
  1759. end;
  1760. {------------------------------------------------------------------------------}
  1761. procedure TRVRTFReaderProperties.MergeListTable97;
  1762. var i,j: Integer;
  1763.     RVLevel : TRVListLevel;
  1764.     RTFLevel: TRVRTFListLevel97;
  1765.     FormatStr1,FormatStr2,FontName: String;
  1766.     FormatStrW: {$IFDEF RICHVIEWCBDEF3}WideString{$ELSE}String{$ENDIF};
  1767.     {$IFDEF RICHVIEWCBDEF3}
  1768.     Charset: TFontCharset;
  1769.     {$ENDIF}
  1770.     RVType: TRVListType;
  1771.     ListNo: Integer;
  1772.     ForbiddenStyles: TRVIntegerList;
  1773. begin
  1774.   if ParaStyleMode<>rvrsAddIfNeeded then
  1775.     exit;
  1776.   if ListTableMap97<>nil then
  1777.     exit;
  1778.   ListStylesCountBefore := RVStyle.ListStyles.Count;
  1779.   ForbiddenStyles := TRVIntegerList.Create;
  1780.   try
  1781.     ListTableMap97 := TRVIntegerList.Create;
  1782.     for i := 0 to Reader.ListTable.Count-1 do begin
  1783.       ListNo := FindListStyle97(Reader.ListTable[i], ForbiddenStyles);
  1784.       if ListNo>=0 then begin
  1785.         ListTableMap97.Add(ListNo);
  1786.         ForbiddenStyles.Add(ListNo);
  1787.         end
  1788.       else begin
  1789.         RVStyle.ListStyles.Add;
  1790.         RVStyle.ListStyles[RVStyle.ListStyles.Count-1].Standard := False;
  1791.         ListTableMap97.Add(RVStyle.ListStyles.Count-1);
  1792.         ForbiddenStyles.Add(RVStyle.ListStyles.Count-1);
  1793.         for j := 0 to Reader.ListTable[i].Count-1 do begin
  1794.           RTFLevel := Reader.ListTable[i].Items[j];
  1795.           ConvMarker97(Reader, RTFLevel, RVType, FormatStr1, FormatStr2, FormatStrW);
  1796.           FontName := GetMarkerFontName(Reader, RTFLevel);
  1797.           {$IFDEF RICHVIEWCBDEF3}
  1798.           Charset  := GetMarkerCharset(Reader, RTFLevel);
  1799.           {$ENDIF}
  1800.           RVLevel := RVStyle.ListStyles[RVStyle.ListStyles.Count-1].Levels.Add;
  1801.           RVLevel.ListType := RVType;
  1802.           RVLevel.FormatString := FormatStr1;
  1803.           {$IFNDEF RVDONOTUSEUNICODE}
  1804.           RVLevel.FormatStringW := FormatStrW;
  1805.           {$ENDIF}
  1806.           RVLevel.MarkerAlignment := TRVMarkerAlignment(RTFLevel.Alignment);
  1807.           RVLevel.Font.Name := FontName;
  1808.           {$IFDEF RICHVIEWCBDEF3}
  1809.           RVLevel.Font.Charset  := Charset;
  1810.           {$ENDIF}
  1811.           RVLevel.Font.Style := RTFLevel.FontStyle;
  1812.           RVLevel.Font.Color := RTFLevel.Color;
  1813.           RVLevel.Font.Size  := RTFLevel.FontSize;
  1814.           RVLevel.LeftIndent := Round(RTFLevel.LeftIndentTw*PixelsPerTwip);
  1815.           RVLevel.MarkerIndent := Round(RTFLevel.FirstIndentTw*PixelsPerTwip)+RVLevel.LeftIndent;
  1816.           RVLevel.FirstIndent := Round(RTFLevel.TabPosTw*PixelsPerTwip)-RVLevel.LeftIndent;
  1817.           RVLevel.StartFrom   := RTFLevel.Start;
  1818.           if RTFLevel.NoRestart then
  1819.             RVLevel.Options := RVLevel.Options - [rvloLevelReset];
  1820.           if RTFLevel.Legal then
  1821.             RVLevel.Options := RVLevel.Options + [rvloLegalStyleNumbering];
  1822.         end;
  1823.       end;
  1824.     end;
  1825.   finally
  1826.     ForbiddenStyles.Free;
  1827.   end;
  1828. end;
  1829. {$ENDIF}
  1830. {------------------------------------------------------------------------------}
  1831. procedure TRVRTFReaderProperties.ReaderProgress(Sender: TRVRTFReader;
  1832.   Stage: TRVRTFProgressStage; PercentDone: Byte);
  1833. begin
  1834.   RVData.DoProgress(rvloLoading, TRVProgressStage(Stage), PercentDone);
  1835. end;
  1836. {------------------------------------------------------------------------------}
  1837. procedure TRVRTFReaderProperties.NewReaderText(Sender: TRVRTFReader;
  1838.   const Text: String; Position: TRVRTFPosition);
  1839. var StyleNo : Integer;
  1840.     item    : TCustomRVItemInfo;
  1841.     s: String;
  1842. begin
  1843.   if FSkipHiddenText and Reader.RTFState.CharProps.Hidden then
  1844.     exit;
  1845.   if LineBreaksAsParagraphs and (Position=rtf_ts_NewLine) then
  1846.     Position := rtf_ts_NewPara;
  1847.   StyleNo := ReturnStyleNo(UnicodeMode=rvruOnlyUnicode);
  1848.   {$IFNDEF RVDONOTUSETABS}
  1849.   if (RVStyle.SpacesInTab=0) and (Text=#09) then begin
  1850.     item := TRVTabItemInfo.Create(CurrentRVData);
  1851.     item.StyleNo := rvsTab;
  1852.     TRVTabItemInfo(item).TextStyleNo := StyleNo;
  1853.     TRVTabItemInfo(item).ParaNo := ReturnParaNo(Position);
  1854.     s := '';
  1855.     end
  1856.   else
  1857.   {$ENDIF}
  1858.     item := CreateTextItem(Text, {$IFDEF RICHVIEWCBDEF3} '',{$ENDIF}
  1859.       StyleNo, ReturnParaNo(Position), False, s);
  1860.   InsertItem(s, item, Position);
  1861. end;
  1862. {------------------------------------------------------------------------------}
  1863. procedure TRVRTFReaderProperties.ReaderEndParsing(Sender: TObject);
  1864. begin
  1865.   {$IFDEF RICHVIEW_DPMARGINS}
  1866.   if not EditFlag then begin
  1867.     if Reader.RTFState.DocProps.LeftMarginTw>0 then
  1868.       RVData.GetAbsoluteRootData.GetDocProperties.Values['LeftMarginMM'] :=
  1869.         IntToStr(Round(Reader.RTFState.DocProps.LeftMarginTw*127/(1440*5)));
  1870.     if Reader.RTFState.DocProps.TopMarginTw>0 then
  1871.       RVData.GetAbsoluteRootData.GetDocProperties.Values['TopMarginMM'] :=
  1872.         IntToStr(Round(Reader.RTFState.DocProps.TopMarginTw*127/(1440*5)));
  1873.     if Reader.RTFState.DocProps.RightMarginTw>0 then
  1874.       RVData.GetAbsoluteRootData.GetDocProperties.Values['RightMarginMM'] :=
  1875.         IntToStr(Round(Reader.RTFState.DocProps.RightMarginTw*127/(1440*5)));
  1876.     if Reader.RTFState.DocProps.BottomMarginTw>0 then
  1877.       RVData.GetAbsoluteRootData.GetDocProperties.Values['BottomMarginMM'] :=
  1878.         IntToStr(Round(Reader.RTFState.DocProps.BottomMarginTw*127/(1440*5)));
  1879.   end;
  1880.   {$ENDIF}
  1881. end;
  1882. {------------------------------------------------------------------------------}
  1883. {$IFDEF RICHVIEWCBDEF3}
  1884. procedure TRVRTFReaderProperties.NewReaderUnicodeText(Sender: TRVRTFReader;
  1885.   const Text: WideString; Position: TRVRTFPosition);
  1886. var StyleNo : Integer;
  1887.     item    : TCustomRVItemInfo;
  1888.     s,s2: String;
  1889.     CodePage: TRVCodePage;
  1890.     Unicode: Boolean;
  1891.     FontIndex: Integer;
  1892. begin
  1893.   if FSkipHiddenText and Reader.RTFState.CharProps.Hidden then
  1894.     exit;
  1895.   if LineBreaksAsParagraphs and (Position=rtf_ts_NewLine) then
  1896.     Position := rtf_ts_NewPara;    
  1897.   s2 := '';
  1898.   Unicode := UnicodeMode in [rvruOnlyUnicode, rvruMixed];
  1899.   if UnicodeMode = rvruMixed then begin
  1900.     FontIndex := Reader.RTFState.CharProps.FontIndex;
  1901.     if (FontIndex>=0) and (FontIndex<Reader.FontTable.Count) then begin
  1902.       CodePage := RVU_Charset2CodePage(Reader.FontTable[FontIndex].Charset);
  1903.       if CodePage=CP_ACP then
  1904.         CodePage := Reader.CodePage;
  1905.       s2 := RVU_GetRawUnicode(Text);
  1906.       if (CodePage<>CP_ACP) and RVU_CanBeConvertedToAnsi(CodePage, s2) then begin
  1907.         s2 := RVU_UnicodeToAnsi(CodePage, s2);
  1908.         Unicode := False;
  1909.       end;
  1910.     end;
  1911.   end;
  1912.   StyleNo := ReturnStyleNo(Unicode);
  1913.   {$IFNDEF RVDONOTUSETABS}
  1914.   if (RVStyle.SpacesInTab=0) and (Text=#09) then begin
  1915.     item := TRVTabItemInfo.Create(CurrentRVData);
  1916.     item.StyleNo := rvsTab;
  1917.     TRVTabItemInfo(item).TextStyleNo := StyleNo;
  1918.     TRVTabItemInfo(item).ParaNo := ReturnParaNo(Position);
  1919.     s := '';
  1920.     end
  1921.   else
  1922.   {$ENDIF}
  1923.   begin
  1924.     if Unicode then
  1925.       item := CreateTextItem('', Text, StyleNo, ReturnParaNo(Position), True, s)
  1926.     else
  1927.       item := CreateTextItem(s2, '', StyleNo, ReturnParaNo(Position), False, s)
  1928.   end;
  1929.   InsertItem(s, item, Position);
  1930. end;
  1931. {$ENDIF}
  1932. {------------------------------------------------------------------------------}
  1933. procedure TRVRTFReaderProperties.ReaderHeaderFooter(Sender: TRVRTFReader;
  1934.   HFType: TRVRTFHeaderFooterType; Starting: Boolean;
  1935.   var Supported: Boolean);
  1936. begin
  1937.   // 1 twip = 20 points = 1/1440 inch
  1938.   Supported := False;
  1939.   if Starting then begin
  1940.     case HFType of
  1941.       rtf_hf_Header:
  1942.         if FHeaderRVData<>nil then begin
  1943.           CurrentRVData := FHeaderRVData;
  1944.           CurrentRVData.Clear;
  1945.           FHeaderYMM := Round(Reader.RTFState.SectProps.HeaderYTw*127/(1440*5));
  1946.           Supported := True;
  1947.           Self.HFType := HFType;
  1948.         end;
  1949.       rtf_hf_Footer:
  1950.         if FFooterRVData<>nil then begin
  1951.           CurrentRVData := FFooterRVData;
  1952.           CurrentRVData.Clear;
  1953.           FFooterYMM := Round(Reader.RTFState.SectProps.FooterYTw*127/(1440*5));
  1954.           Supported := True;
  1955.           Self.HFType := HFType;
  1956.         end;
  1957.     end;
  1958.     end
  1959.   else begin
  1960.     CurrentRVData := RVData;
  1961.     Self.HFType := rtf_hf_MainText;
  1962.   end;
  1963.   RVStyle := CurrentRVData.GetRVStyle;
  1964. end;
  1965. {------------------------------------------------------------------------------}
  1966. procedure TRVRTFReaderProperties.ReaderPageBreak(Sender: TObject);
  1967. begin
  1968.   PageBreakRVData := CurrentRVData;
  1969.   PageBreak := True;
  1970. end;
  1971. {------------------------------------------------------------------------------}
  1972. procedure TRVRTFReaderProperties.InitReader;
  1973. begin
  1974.   PixelsPerTwip := RV_GetPixelsPerInch / (72*20);
  1975.   RVStyle := RVData.GetRVStyle;  
  1976.   Reader.PixelsPerInch := RV_GetPixelsPerInch;
  1977.   Reader.ConvertHighlight := TRVRTFHighlightConvert(ConvertHighlight);
  1978.   Reader.BasePath := BasePath;
  1979.   Reader.ExtractMetafileBitmaps := ExtractMetafileBitmaps;
  1980.   HFType := rtf_hf_MainText;
  1981.   {$IFNDEF RVDONOTUSELISTS}
  1982.   Reader.OnUpdateMarker := ReaderUpdateMarker;
  1983.   LastMarkerIndex := -1;
  1984.   LevelToListNo := TRVIntegerList.Create;
  1985.   {$ENDIF}
  1986.   Reader.OnNewText := NewReaderText;
  1987.   {$IFNDEF RVDONOTUSEUNICODE}
  1988.   if UnicodeMode in [rvruMixed, rvruOnlyUnicode] then
  1989.     Reader.OnNewUnicodeText := NewReaderUnicodeText;
  1990.   {$ENDIF}
  1991.   if not IgnorePictures then begin
  1992.     Reader.OnNewPicture := NewReaderPicture;
  1993.     Reader.OnImportPicture := ReaderImportPicture;
  1994.   end;
  1995.   if RVData.IsAssignedOnProgress then
  1996.     Reader.OnProgress := ReaderProgress
  1997.   else
  1998.     Reader.OnProgress := nil; 
  1999.   {$IFNDEF RVDONOTUSEOLECONTAINER}
  2000.   (*
  2001.   Reader.OnNewObject := NewReaderObject;
  2002.   *)
  2003.   {$ENDIF}
  2004.   Reader.DefCodePage := RVData.GetDefaultCodePage;
  2005.   Reader.OnRequiredPageBreak := ReaderPageBreak;
  2006.   Reader.TabAsSeparateChar := RVStyle.SpacesInTab=0;
  2007.   Reader.OnEndParsing := ReaderEndParsing;
  2008.   {$IFNDEF RVDONOTUSETABLES}
  2009.   if not FIgnoreTables then
  2010.     Reader.OnTable     := ReaderTable;
  2011.   {$ENDIF}
  2012.   PageBreak := False;
  2013.   PageBreakRVData := nil;
  2014.   NonFirstItemsAdded := 0;
  2015.   FirstTime := True;
  2016.   FailedBecauseOfProtect := False;
  2017.   FullReformat := False;
  2018.   Tables    := nil;
  2019.   CurrentRVData := RVData;
  2020.   CurrentRow := -1;
  2021.   CurrentCol := -1;
  2022.   FEmptyPara := -1;
  2023.   FHeaderYMM := -1;
  2024.   FFooterYMM := -1;
  2025.   if (FHeaderRVData<>nil) or (FFooterRVData<>nil) then
  2026.     Reader.OnHeaderFooter := ReaderHeaderFooter;
  2027.   if (FHeaderRVData<>nil) then
  2028.     FHeaderRVData.Clear;
  2029.   if (FFooterRVData<>nil) then
  2030.     FFooterRVData.Clear;
  2031.   {$IFNDEF RVDONOTUSELISTS}
  2032.   ListStylesCountBefore := 0;
  2033.   {$ENDIF}
  2034. end;
  2035. {------------------------------------------------------------------------------}
  2036. procedure TRVRTFReaderProperties.DoneReader;
  2037. begin
  2038.   {$IFNDEF RVDONOTUSELISTS}
  2039.   ReaderUpdateMarker(nil);
  2040.   {$ENDIF}
  2041.   Tables.Free;
  2042.   Tables := nil;
  2043.   {$IFNDEF RVDONOTUSELISTS}
  2044.   LevelToListNo.Free;
  2045.   LevelToListNo := nil;
  2046.   ListTableMap97.Free;
  2047.   ListTableMap97 := nil;
  2048.   {$ENDIF}
  2049. end;
  2050. {------------------------------------------------------------------------------}
  2051. procedure TRVRTFReaderProperties.CurrentBorder(
  2052.   var RVBorderStyle: TRVBorderStyle; var RVBorderWidth,
  2053.   RVBorderIntWidth: Integer; var RVBorderColor: TColor;
  2054.   var RVBorderOffs: TRVRect);
  2055. var side: TRVRTFSide;
  2056. begin
  2057.   with Reader.RTFState.ParaProps do begin
  2058.     if HasBorder then
  2059.       with Border do begin
  2060.         RVBorderOffs := TRVRect.Create;
  2061.         RVBorderOffs.Left   := Round(Sides[rtf_side_Left  ].SpaceTw*PixelsPerTwip);
  2062.         RVBorderOffs.Top    := Round(Sides[rtf_side_Top   ].SpaceTw*PixelsPerTwip);
  2063.         RVBorderOffs.Right  := Round(Sides[rtf_side_Right ].SpaceTw*PixelsPerTwip);
  2064.         RVBorderOffs.Bottom := Round(Sides[rtf_side_Bottom].SpaceTw*PixelsPerTwip);
  2065.         if Sides[rtf_side_Top].BorderType<>rtf_brdr_None then
  2066.           side := rtf_side_Top
  2067.         else if Sides[rtf_side_Left].BorderType<>rtf_brdr_None then
  2068.           side := rtf_side_Left
  2069.         else   if Sides[rtf_side_Bottom].BorderType<>rtf_brdr_None then
  2070.           side := rtf_side_Bottom
  2071.         else
  2072.           side := rtf_side_Right;
  2073.         RVBorderColor := Sides[side].Color;
  2074.         BorderRTF2RV(Sides[side].BorderType, Sides[side].WidthTw,
  2075.           RVBorderStyle, RVBorderWidth, RVBorderIntWidth,
  2076.           PixelsPerTwip, side in [rtf_side_Bottom, rtf_side_Right]);
  2077.       end
  2078.     else begin
  2079.       RVBorderStyle := rvbNone;
  2080.       RVBorderWidth := 0;
  2081.       RVBorderIntWidth := 0;
  2082.       RVBorderColor   := clNone;
  2083.       RVBorderOffs := nil;
  2084.     end;
  2085.   end;
  2086. end;
  2087. {------------------------------------------------------------------------------}
  2088. {$IFNDEF RVDONOTUSETABS}
  2089. function GetTabLeaderChar(RTFLeader: TRVRTFTabLeader): String;
  2090. begin
  2091.   case RTFLeader of
  2092.     rtf_tl_Dot:       Result := '.';
  2093.     rtf_tl_MiddleDot: Result := #$B7;
  2094.     rtf_tl_Hyphen:    Result := '-';
  2095.     rtf_tl_Underline: Result := '_';
  2096.     rtf_tl_EqualSign: Result := '=';
  2097.     else              Result := '';
  2098.   end;
  2099. end;
  2100. {------------------------------------------------------------------------------}
  2101. function GetRVTabAlign(Align: TRVRTFTabAlign): TRVTabAlign;
  2102. begin
  2103.   case Align of
  2104.     rtf_tab_Right, rtf_tab_Decimal: Result := rvtaRight;
  2105.     rtf_tab_Center: Result := rvtaCenter;
  2106.     else            Result := rvtaLeft;
  2107.   end;
  2108. end;
  2109. {$ENDIF}
  2110. {------------------------------------------------------------------------------}
  2111. function TRVRTFReaderProperties.FindBestParaNo: Integer;
  2112. var i: Integer;
  2113.     Para: TParaInfo;
  2114.     LeftIndent, RightIndent, FirstIndent, SpaceBefore, SpaceAfter: Integer;
  2115.     w, bw, maxw,LS: Integer;
  2116.     RVBorderStyle: TRVBorderStyle; RVBorderWidth, RVBorderIntWidth: Integer;
  2117.     RVBorderOffs: TRVRect;
  2118.     {..........................................................}
  2119.     function CompareBorderSide( RVBorder:TRVBorder;
  2120.       RVBorderStyle: TRVBorderStyle; RVBorderWidth,RVBorderIntWidth: Integer;
  2121.       RVBorderColor: TColor; SideVisible: Boolean): Integer;
  2122.     begin
  2123.       Result := 0;
  2124.       with Reader.RTFState.ParaProps do
  2125.         if HasBorder and (RVBorderStyle<>rvbNone) then begin
  2126.           if (RVBorder.Style=rvbNone) or not SideVisible then
  2127.             exit;
  2128.           inc(Result, RVSMW_BORDERSIDE);
  2129.           inc(Result, RV_CompareInts(RVBorderWidth, RVBorder.Width, RVSMW_WIDTH));
  2130.           inc(Result, RV_CompareInts(RVBorderIntWidth, RVBorder.InternalWidth, RVSMW_WIDTH));
  2131.           inc(Result, RV_CompareColors(RVBorder.Color, RVBorderColor, RVSMW_EACHRGBCOLOR, RVSMW_COLORSET));
  2132.           if RVBorderStyle=RVBorder.Style then
  2133.             inc(Result, RVSMW_BORDERSTYLE);
  2134.           end
  2135.         else
  2136.           if (RVBorder.Style=rvbNone) or not SideVisible then
  2137.             inc(Result, RVSMW_BORDERNOSIDE);
  2138.     end;
  2139.     {..........................................................}
  2140.     function CompareLS: Integer;
  2141.     var v: Integer;
  2142.     begin
  2143.       Result := 0;
  2144.       if not Reader.RTFState.ParaProps.LineSpacingMulti then
  2145.         exit;
  2146.       if Para.LineSpacingType=rvlsSpaceBetween then begin
  2147.         if Para.LineSpacing>1 then
  2148.           Result := - 4*RVSMW_LINESPACING
  2149.         else if (LS<=100) then
  2150.           Result := RVSMW_LINESPACING;
  2151.         exit;
  2152.       end;
  2153.       v := Para.LineSpacing;
  2154.       if v<100 then
  2155.         v := 100;
  2156.       Result := RV_CompareInts(LS, v, RVSMW_LINESPACING);
  2157.     end;
  2158.     {..........................................................}
  2159.     {$IFNDEF RVDONOTUSETABS}
  2160.     function CompareTabs(RVTabs: TRVTabInfos; RTFTabs: TRVRTFTabList): Integer;
  2161.     var i: Integer;
  2162.         RVTab: TRVTabInfo;
  2163.         RTFTab: TRVRTFTab;
  2164.         MinCount: Integer;
  2165.     begin
  2166.       Result := 0;
  2167.       if RVStyle.SpacesInTab>0 then
  2168.         exit;      
  2169.       if RVTabs.Count<RTFTabs.Count then
  2170.         MinCount := RVTabs.Count
  2171.       else
  2172.         MinCount := RTFTabs.Count;
  2173.       for i := 0 to MinCount-1 do begin
  2174.         RVTab := RVTabs[i];
  2175.         RTFTab := RTFTabs[i];
  2176.         inc(Result, RV_CompareInts(Round(RTFTab.PositionTW*PixelsPerTwip), RVTab.Position,  RVSMW_TABPOS));
  2177.         if GetRVTabAlign(RTFTab.Align) = RVTab.Align then
  2178.           inc(Result, RVSMW_TABALIGN);
  2179.         if GetTabLeaderChar(RTFTab.Leader) = RVTab.Leader then
  2180.           inc(Result, RVSMW_LEADER);
  2181.       end;
  2182.       dec(Result, (RVTabs.Count-MinCount)*RVSMW_NOTAB);
  2183.       dec(Result, (RTFTabs.Count-MinCount)*RVSMW_NOTAB);
  2184.     end;
  2185.     {$ENDIF}
  2186.     {..........................................................}
  2187. begin
  2188.   Result := 0;
  2189.   maxw   := 0;
  2190.   with Reader.RTFState.ParaProps do begin
  2191.     LeftIndent   := Round(LeftIndentTw *PixelsPerTwip);
  2192.     RightIndent  := Round(RightIndentTw*PixelsPerTwip);
  2193.     FirstIndent  := Round(FirstIndentTw*PixelsPerTwip);
  2194.     SpaceBefore  := Round(SpaceBeforeTw*PixelsPerTwip);
  2195.     SpaceAfter   := Round(SpaceAfterTw *PixelsPerTwip);
  2196.     LS           := abs(LineSpacing) * 100 div 240;
  2197.     if LS<100 then
  2198.       LS := 100;
  2199.     if HasBorder then begin
  2200.         RVBorderOffs := TRVRect.Create;
  2201.         RVBorderOffs.Left   := Round(Border.Sides[rtf_side_Left  ].SpaceTw*PixelsPerTwip);
  2202.         RVBorderOffs.Top    := Round(Border.Sides[rtf_side_Top   ].SpaceTw*PixelsPerTwip);
  2203.         RVBorderOffs.Right  := Round(Border.Sides[rtf_side_Right ].SpaceTw*PixelsPerTwip);
  2204.         RVBorderOffs.Bottom := Round(Border.Sides[rtf_side_Bottom].SpaceTw*PixelsPerTwip);
  2205.       end
  2206.     else
  2207.       RVBorderOffs := nil;
  2208.     for i := 0 to RVStyle.ParaStyles.Count-1 do begin
  2209.       if not AllowUseStyle(i, False) then
  2210.         continue;
  2211.       Para := RVStyle.ParaStyles[i];
  2212.       bw := Para.Border.GetTotalWidth;
  2213.       w := 0;
  2214.       if ord(Para.Alignment)=ord(Alignment) then
  2215.         inc(w, RVSMW_ALIGNMENT);
  2216.       inc(w, RV_CompareInts(LeftIndent+bw,  Para.LeftIndent,  RVSMW_INDENT));
  2217.       inc(w, RV_CompareInts(RightIndent+bw, Para.RightIndent, RVSMW_INDENT));
  2218.       inc(w, RV_CompareInts(FirstIndent, Para.FirstIndent, RVSMW_INDENT));
  2219.       inc(w, RV_CompareInts(SpaceBefore+bw, Para.SpaceBefore, RVSMW_INDENT));
  2220.       inc(w, RV_CompareInts(SpaceAfter+bw,  Para.SpaceAfter,  RVSMW_INDENT));
  2221.       inc(w, RV_CompareColors(Para.Background.Color, Color, RVSMW_EACHRGBBCOLOR, RVSMW_BCOLORSET));
  2222.       if (rvpaoKeepLinesTogether in Para.Options) = KeepLinesTogether then
  2223.         inc(w, RVSMW_KEEPLINESTOGETHER);
  2224.       if (rvpaoKeepWithNext in Para.Options) = KeepWithNext then
  2225.         inc(w, RVSMW_KEEPWITHNEXT);
  2226.       inc(w, CompareLS);
  2227.       if HasBorder then begin
  2228.         inc(w, RV_CompareInts(RVBorderOffs.Left,   Para.Border.BorderOffsets.Left,   RVSMW_INDENT));
  2229.         inc(w, RV_CompareInts(RVBorderOffs.Top,    Para.Border.BorderOffsets.Top,    RVSMW_INDENT));
  2230.         inc(w, RV_CompareInts(RVBorderOffs.Right,  Para.Border.BorderOffsets.Right,  RVSMW_INDENT));
  2231.         inc(w, RV_CompareInts(RVBorderOffs.Bottom, Para.Border.BorderOffsets.Bottom, RVSMW_INDENT));
  2232.         BorderRTF2RV(Border.Sides[rtf_side_Left].BorderType, Border.Sides[rtf_side_Left].WidthTw,
  2233.                      RVBorderStyle, RVBorderWidth, RVBorderIntWidth,
  2234.                      PixelsPerTwip, False);
  2235.         inc(w, CompareBorderSide(Para.Border, RVBorderStyle, RVBorderWidth,
  2236.                                  RVBorderIntWidth,
  2237.                                  Border.Sides[rtf_side_Left].Color,
  2238.                                  Para.Border.VisibleBorders.Left));
  2239.         BorderRTF2RV(Border.Sides[rtf_side_Top].BorderType, Border.Sides[rtf_side_Top].WidthTw,
  2240.                      RVBorderStyle, RVBorderWidth, RVBorderIntWidth,
  2241.                      PixelsPerTwip, False);
  2242.         inc(w, CompareBorderSide(Para.Border, RVBorderStyle, RVBorderWidth,
  2243.                                  RVBorderIntWidth,
  2244.                                  Border.Sides[rtf_side_Top].Color,
  2245.                                  Para.Border.VisibleBorders.Top));
  2246.         BorderRTF2RV(Border.Sides[rtf_side_Right].BorderType, Border.Sides[rtf_side_Right].WidthTw,
  2247.                      RVBorderStyle, RVBorderWidth, RVBorderIntWidth,
  2248.                      PixelsPerTwip, True);
  2249.         inc(w, CompareBorderSide(Para.Border, RVBorderStyle, RVBorderWidth,
  2250.                                  RVBorderIntWidth,
  2251.                                  Border.Sides[rtf_side_Right].Color,
  2252.                                  Para.Border.VisibleBorders.Right));
  2253.         BorderRTF2RV(Border.Sides[rtf_side_Bottom].BorderType, Border.Sides[rtf_side_Bottom].WidthTw,
  2254.                      RVBorderStyle, RVBorderWidth, RVBorderIntWidth,
  2255.                      PixelsPerTwip, True);
  2256.         inc(w, CompareBorderSide(Para.Border, RVBorderStyle, RVBorderWidth,
  2257.                                  RVBorderIntWidth,
  2258.                                  Border.Sides[rtf_side_Bottom].Color,
  2259.                                  Para.Border.VisibleBorders.Bottom));
  2260.         {$IFNDEF RVDONOTUSETABS}
  2261.         inc(w, CompareTabs(Para.Tabs, Tabs));
  2262.         {$ENDIF}
  2263.         end
  2264.       else
  2265.         if Para.Border.Style=rvbNone then
  2266.           inc(w, RVSMW_BORDERNOSIDE);
  2267.       if w>maxw then begin
  2268.         Result := i;
  2269.         maxw := w;
  2270.       end;
  2271.     end;
  2272.     RVBorderOffs.Free;
  2273.   end;
  2274. end;
  2275. {------------------------------------------------------------------------------}
  2276. function GetRVBorderTotalWidth(RVBorderStyle: TRVBorderStyle;
  2277.   RVBorderWidth, RVBorderIntWidth: Integer): Integer;
  2278. begin
  2279.   case RVBorderStyle of
  2280.     rvbSingle:
  2281.       Result := RVBorderWidth;
  2282.     rvbDouble:
  2283.       Result := 2*RVBorderWidth+RVBorderIntWidth;
  2284.     rvbTriple:
  2285.       Result := 3*RVBorderWidth+2*RVBorderIntWidth;
  2286.     rvbThickInside, rvbThickOutside:
  2287.       Result := 3*RVBorderWidth+RVBorderIntWidth;
  2288.     else
  2289.       Result := 0;
  2290.   end;
  2291. end;
  2292. {------------------------------------------------------------------------------}
  2293. procedure AdjustIndents(RVBorderStyle: TRVBorderStyle;
  2294.   RVBorderWidth, RVBorderIntWidth: Integer; RVBorderOffs: TRVRect;
  2295.    var LeftIndent, RightIndent, SpaceBefore, SpaceAfter: Integer);
  2296. var w: Integer;
  2297. begin
  2298.  if RVBorderOffs<>nil then begin
  2299.    w := GetRVBorderTotalWidth(RVBorderStyle, RVBorderWidth, RVBorderIntWidth)-1;
  2300.    if LeftIndent<RVBorderOffs.Left+w then
  2301.      LeftIndent := RVBorderOffs.Left+w;
  2302.    if SpaceBefore<RVBorderOffs.Top+w then
  2303.      SpaceBefore := RVBorderOffs.Top+w;
  2304.    if RightIndent<RVBorderOffs.Right+w then
  2305.      RightIndent := RVBorderOffs.Right+w;
  2306.    if SpaceAfter<RVBorderOffs.Bottom+w then
  2307.      SpaceAfter := RVBorderOffs.Bottom+w;
  2308.   end;
  2309. end;
  2310. {------------------------------------------------------------------------------}
  2311. function TRVRTFReaderProperties.FindParaNo(RVBorderStyle: TRVBorderStyle;
  2312.   RVBorderWidth, RVBorderIntWidth: Integer; RVBorderColor: TColor;
  2313.   RVBorderOffs: TRVRect): Integer;
  2314.     {..........................................................}
  2315.     function EqualBorders(RVBorder:TRVBorder; RVBorderStyle: TRVBorderStyle;
  2316.       RVBorderWidth,RVBorderIntWidth: Integer; RVBorderColor: TColor;
  2317.       RVBorderOffs: TRVRect):Boolean;
  2318.     begin
  2319.       with Reader.RTFState.ParaProps do
  2320.         if HasBorder then
  2321.         Result := (RVBorder.Style=RVBorderStyle) and
  2322.                   (RVBorder.Width=RVBorderWidth) and
  2323.                   ((RVBorder.InternalWidth=RVBorderIntWidth) or (RVBorderStyle=rvbSingle)) and
  2324.                   (RVBorder.Color=RVBorderColor) and
  2325.                   (RVBorder.VisibleBorders.Left   = (Border.Sides[rtf_side_Left].BorderType<>rtf_brdr_None))  and
  2326.                   (RVBorder.VisibleBorders.Top    = (Border.Sides[rtf_side_Top].BorderType<>rtf_brdr_None))   and
  2327.                   (RVBorder.VisibleBorders.Right  = (Border.Sides[rtf_side_Right].BorderType<>rtf_brdr_None)) and
  2328.                   (RVBorder.VisibleBorders.Bottom = (Border.Sides[rtf_side_Bottom].BorderType<>rtf_brdr_None)) and
  2329.                   (RVBorderOffs<>nil) and RVBorder.BorderOffsets.IsEqual(RVBorderOffs)
  2330.       else
  2331.         Result := RVBorder.Style=rvbNone;
  2332.     end;
  2333.     {..........................................................}
  2334.     function EqualLS(Para: TParaInfo; LS: Integer): Boolean;
  2335.     begin
  2336.       if not Reader.RTFState.ParaProps.LineSpacingMulti then begin
  2337.         Result := True;
  2338.         exit;
  2339.       end;
  2340.       if (Para.LineSpacingType=rvlsSpaceBetween) then begin
  2341.          if (Para.LineSpacing>1) then begin
  2342.            Result := False;
  2343.            exit;
  2344.          end;
  2345.          Result := LS<=100;
  2346.          exit;
  2347.       end;
  2348.       Result := (LS = Para.LineSpacing) or
  2349.                 ((LS<100) and (Para.LineSpacing<100));
  2350.     end;
  2351.     {..........................................................}
  2352.     {$IFNDEF RVDONOTUSETABS}
  2353.     function EqualTabs(RVTabs: TRVTabInfos; RTFTabs: TRVRTFTabList): Boolean;
  2354.     var i: Integer;
  2355.         RVTab: TRVTabInfo;
  2356.         RTFTab: TRVRTFTab;
  2357.     begin
  2358.       if RVStyle.SpacesInTab>0 then begin
  2359.         Result := True;
  2360.         exit;
  2361.       end;
  2362.       Result := RVTabs.Count=RTFTabs.Count;
  2363.       if not Result then
  2364.         exit;
  2365.       for i := 0 to RTFTabs.Count-1 do begin
  2366.         RVTab := RVTabs[i];
  2367.         RTFTab := RTFTabs[i];
  2368.         Result :=
  2369.           (Round(RTFTab.PositionTW*PixelsPerTwip) = RVTab.Position) and
  2370.           (GetRVTabAlign(RTFTab.Align)            = RVTab.Align) and
  2371.           (GetTabLeaderChar(RTFTab.Leader)        = RVTab.Leader);
  2372.         if not Result then
  2373.           exit;
  2374.       end;
  2375.     end;
  2376.     {$ENDIF}
  2377.     {..........................................................}
  2378. var i: Integer;
  2379.     Para: TParaInfo;
  2380.     LeftIndent, RightIndent, FirstIndent, SpaceBefore, SpaceAfter, LS: Integer;
  2381. begin
  2382.   Result := -1;
  2383.   with Reader.RTFState.ParaProps do begin
  2384.    LeftIndent   := Round(LeftIndentTw *PixelsPerTwip);
  2385.    RightIndent  := Round(RightIndentTw*PixelsPerTwip);
  2386.    FirstIndent  := Round(FirstIndentTw*PixelsPerTwip);
  2387.    SpaceBefore  := Round(SpaceBeforeTw*PixelsPerTwip);
  2388.    SpaceAfter   := Round(SpaceAfterTw *PixelsPerTwip);
  2389.    AdjustIndents(RVBorderStyle, RVBorderWidth, RVBorderIntWidth, RVBorderOffs,
  2390.      LeftIndent, RightIndent, SpaceBefore, SpaceAfter);
  2391.    LS           := abs(LineSpacing) * 100 div 240;
  2392.    for i := 0 to RVStyle.ParaStyles.Count-1 do begin
  2393.      Para := RVStyle.ParaStyles[i];
  2394.      if (ord(Para.Alignment)=ord(Alignment)) and
  2395.         (Para.LeftIndent = LeftIndent) and
  2396.         (Para.RightIndent = RightIndent) and
  2397.         (Para.FirstIndent = FirstIndent) and
  2398.         (Para.SpaceBefore = SpaceBefore) and
  2399.         (Para.SpaceAfter  = SpaceAfter) and
  2400.         (Para.Background.Color = Color) and
  2401.         ((rvpaoKeepLinesTogether in Para.Options) = KeepLinesTogether) and
  2402.         ((rvpaoKeepWithNext in Para.Options) = KeepWithNext) and
  2403.         EqualLS(Para,LS) and
  2404.         {$IFNDEF RVDONOTUSETABS}
  2405.         EqualTabs(Para.Tabs, Tabs) and
  2406.         {$ENDIF}
  2407.         EqualBorders(Para.Border, RVBorderStyle, RVBorderWidth,
  2408.           RVBorderIntWidth, RVBorderColor, RVBorderOffs)
  2409.        then begin
  2410.          Result := i;
  2411.          break;
  2412.        end;
  2413.      end;
  2414.   end;
  2415. end;
  2416. {------------------------------------------------------------------------------}
  2417. {$IFNDEF RVDONOTUSETABLES}
  2418. function TRVRTFReaderProperties.GetEmptyStyleNo: Integer;
  2419. begin
  2420.   case TextStyleMode of
  2421.     rvrsUseSpecified:
  2422.       Result := TextStyleNo;
  2423.     else
  2424.       Result := 0;
  2425.   end;
  2426. end;
  2427. {------------------------------------------------------------------------------}
  2428. function TRVRTFReaderProperties.GetEmptyParaNo(Alignment: TRVAlignment): Integer;
  2429. var pi: TParaInfo;
  2430. begin
  2431.   if (Alignment=rvaLeft) and  (FEmptyPara>=0) then begin
  2432.     Result := FEmptyPara;
  2433.     exit;
  2434.   end;
  2435.   case ParaStyleMode of
  2436.     rvrsUseSpecified:
  2437.       Result := ParaStyleNo;
  2438.     rvrsUseClosest:
  2439.       Result := 0;
  2440.     else
  2441.       begin
  2442.         pi := RVStyle.ParaStyles[0];
  2443.         if (pi.LeftIndent=0) and
  2444.            (pi.RightIndent=0) and
  2445.            (pi.FirstIndent=0) and
  2446.            (pi.Alignment=Alignment) then
  2447.           Result := 0
  2448.         else begin
  2449.           pi := TParaInfo.Create(nil);
  2450.           try
  2451.             pi.Assign(RVStyle.ParaStyles[0]);
  2452.             pi.LeftIndent  := 0;
  2453.             pi.RightIndent := 0;
  2454.             pi.FirstIndent := 0;
  2455.             pi.Alignment   := Alignment;
  2456.             Result := RVStyle.ParaStyles.FindSuchStyle(0,pi,RVAllParaInfoProperties);
  2457.             if Result=-1 then begin
  2458.               RVStyle.ParaStyles.Add.Assign(pi);
  2459.               Result := RVStyle.ParaStyles.Count-1;
  2460.               RVStyle.ParaStyles[Result].Standard := False;
  2461.             end;
  2462.           finally
  2463.             pi.Free;
  2464.           end;
  2465.         end;
  2466.       end;
  2467.   end;
  2468.   if (Alignment=rvaLeft) then
  2469.     FEmptyPara := Result;
  2470. end;
  2471. {$ENDIF}
  2472. {------------------------------------------------------------------------------}
  2473. procedure TRVRTFReaderProperties.AddPara(RVBorderStyle: TRVBorderStyle;
  2474.   RVBorderWidth, RVBorderIntWidth: Integer; RVBorderColor: TColor;
  2475.   RVBorderOffs: TRVRect);
  2476. var Para: TParaInfo;
  2477.     LeftIndent, RightIndent, SpaceBefore, SpaceAfter: Integer;
  2478.     {$IFNDEF RVDONOTUSETABS}
  2479.     i: Integer;    
  2480.     RVTab: TRVTabInfo;
  2481.     {$ENDIF}
  2482. begin
  2483.   Para := TParaInfo(RVStyle.ParaStyles.Add);
  2484.   Para.Standard := False;
  2485.   with Reader.RTFState.ParaProps do begin
  2486.     Para.Alignment   := TRVAlignment(Alignment);
  2487.     Para.FirstIndent := Round(FirstIndentTw*PixelsPerTwip);
  2488.     LeftIndent  := Round(LeftIndentTw *PixelsPerTwip);
  2489.     RightIndent := Round(RightIndentTw*PixelsPerTwip);
  2490.     SpaceBefore := Round(SpaceBeforeTw*PixelsPerTwip);
  2491.     SpaceAfter  := Round(SpaceAfterTw *PixelsPerTwip);
  2492.     AdjustIndents(RVBorderStyle, RVBorderWidth, RVBorderIntWidth, RVBorderOffs,
  2493.       LeftIndent, RightIndent, SpaceBefore, SpaceAfter);
  2494.     Para.LeftIndent := LeftIndent;
  2495.     Para.RightIndent := RightIndent;
  2496.     Para.SpaceBefore := SpaceBefore;
  2497.     Para.SpaceAfter := SpaceAfter;
  2498.     if LineSpacingMulti then begin
  2499.       Para.LineSpacing := LineSpacing*100 div 240;
  2500.     end;
  2501.     Para.Background.Color := Color;
  2502.     if KeepLinesTogether then
  2503.       Para.Options := Para.Options + [rvpaoKeepLinesTogether];
  2504.     if KeepWithNext then
  2505.       Para.Options := Para.Options + [rvpaoKeepWithNext];
  2506.     {$IFNDEF RVDONOTUSETABS}
  2507.     if HasTabs then
  2508.       for i := 0 to Tabs.Count-1 do begin
  2509.         RVTab := Para.Tabs.Add;
  2510.         RVTab.Position := Round(Tabs[i].PositionTW*PixelsPerTwip);
  2511.         RVTab.Leader   := GetTabLeaderChar(Tabs[i].Leader);
  2512.         RVTab.Align    := GetRVTabAlign(Tabs[i].Align);
  2513.       end;
  2514.     {$ENDIF}
  2515.     if HasBorder then begin
  2516.       Para.Border.Style         := RVBorderStyle;
  2517.       Para.Border.Width         := RVBorderWidth;
  2518.       Para.Border.InternalWidth := RVBorderIntWidth;
  2519.       with Border do begin
  2520.         Para.Border.Color         := RVBorderColor;
  2521.         Para.Border.VisibleBorders.Left   := Sides[rtf_side_Left].BorderType  <>rtf_brdr_None;
  2522.         Para.Border.VisibleBorders.Top    := Sides[rtf_side_Top].BorderType   <>rtf_brdr_None;
  2523.         Para.Border.VisibleBorders.Right  := Sides[rtf_side_Right].BorderType <>rtf_brdr_None;
  2524.         Para.Border.VisibleBorders.Bottom := Sides[rtf_side_Bottom].BorderType<>rtf_brdr_None;
  2525.       end;
  2526.       if RVBorderOffs<>nil then
  2527.         Para.Border.BorderOffsets.Assign(RVBorderOffs);
  2528.     end;
  2529.   end;
  2530. end;
  2531. {------------------------------------------------------------------------------}
  2532. function TRVRTFReaderProperties.ReturnParaNo_: Integer;
  2533. var RVBorderStyle: TRVBorderStyle;
  2534.     RVBorderWidth, RVBorderIntWidth: Integer;
  2535.     RVBorderColor: TColor;
  2536.     RVBorderOffs: TRVRect;
  2537. begin
  2538.   case ParaStyleMode of
  2539.     rvrsUseSpecified:
  2540.       Result := ParaStyleNo;
  2541.     rvrsUseClosest:
  2542.       Result := FindBestParaNo;
  2543.     else
  2544.       begin
  2545.         CurrentBorder(RVBorderStyle, RVBorderWidth, RVBorderIntWidth, RVBorderColor,
  2546.           RVBorderOffs);
  2547.         Result := FindParaNo(RVBorderStyle, RVBorderWidth, RVBorderIntWidth,
  2548.           RVBorderColor, RVBorderOffs);
  2549.         if Result<0 then begin
  2550.           AddPara(RVBorderStyle, RVBorderWidth, RVBorderIntWidth, RVBorderColor,
  2551.             RVBorderOffs);
  2552.           Result := RVStyle.ParaStyles.Count-1;
  2553.         end;
  2554.         RVBorderOffs.Free;
  2555.       end;
  2556.   end;
  2557. end;
  2558. {------------------------------------------------------------------------------}
  2559. function TRVRTFReaderProperties.ReturnParaNo(Position: TRVRTFPosition): Integer;
  2560. begin
  2561.   case Position of
  2562.   rtf_ts_NewPara:
  2563.     begin
  2564.       Result := ReturnParaNo_;
  2565.     end;
  2566.   else
  2567.     begin
  2568.       if CurrentRVData=RVData then begin
  2569.         if (InsertPoint-1<RVData.Items.Count) and (InsertPoint>0) then begin
  2570.           Result := RVData.GetItemPara(InsertPoint-1);
  2571.           end
  2572.         else
  2573.           Result := 0;
  2574.         end
  2575.       else begin
  2576.         if CurrentRVData.Items.Count=0 then
  2577.           Result := 0
  2578.         else
  2579.           Result := CurrentRVData.GetItemPara(CurrentRVData.Items.Count-1);
  2580.       end;
  2581.     end;
  2582.   end;
  2583. end;
  2584. {------------------------------------------------------------------------------}
  2585. function TRVRTFReaderProperties.FindBestStyleNo(AUnicode, AHypertext: Boolean): Integer;
  2586. var i: Integer;
  2587.     FontStyle: TFontInfo;
  2588.     FN: String;
  2589.     {$IFDEF RICHVIEWCBDEF3}
  2590.     Charset: TFontCharset;
  2591.     {$ENDIF}
  2592.     w, maxw, FontSize: Integer;
  2593.     fs: TFontStyle;
  2594.     CharSpacing: Integer;
  2595. begin
  2596.   Result := 0;
  2597.   maxw   := 0;
  2598.   with Reader.RTFState.CharProps do begin
  2599.     if FontName='' then
  2600.       FN := AnsiLowerCase(Reader.FontTable[FontIndex].Name)
  2601.     else
  2602.       FN := AnsiLowerCase(FontName);
  2603.     {$IFDEF RICHVIEWCBDEF3}
  2604.     Charset := Reader.FontTable[FontIndex].Charset;
  2605.     if (FontName=RVFONT_SYMBOL) or (FontName=RVFONT_WINGDINGS) then
  2606.       Charset := SYMBOL_CHARSET;
  2607.     {$ENDIF}
  2608.     CharSpacing  := Round(CharSpacingTw*PixelsPerTwip);
  2609.     if SScriptType = rtf_ss_Normal then
  2610.       FontSize := Size
  2611.     else
  2612.       FontSize := Round(Size/2);
  2613.     for i := 0 to RVStyle.TextStyles.Count-1 do begin
  2614.       if not AllowUseStyle(i, True) then
  2615.         continue;
  2616.       FontStyle := RVStyle.TextStyles[i];
  2617.       w := 0;
  2618.       if {$IFNDEF RVDONOTUSEUNICODE}
  2619.         (FontStyle.Unicode = AUnicode) and
  2620.         {$ENDIF}
  2621.         ((AHypertext and FontStyle.Jump) or
  2622.          (not AHypertext and (UseHypertextStyles or not FontStyle.Jump))) then begin
  2623.         if (AnsiLowerCase(FontStyle.FontName)=FN) then
  2624.           inc(w,RVSMW_FONTNAME);
  2625.         {$IFDEF RICHVIEWCBDEF3}
  2626.         if Charset=FontStyle.Charset then
  2627.           inc(w, RVSMW_FONTCHARSET)
  2628.         else
  2629.           if (Charset=DEFAULT_CHARSET) or
  2630.              (FontStyle.Charset=DEFAULT_CHARSET) then
  2631.             inc(w, RVSMW_FONTCHARSET div 4);
  2632.         {$ENDIF}
  2633.         {$IFDEF RVLANGUAGEPROPERTY}
  2634.         if Language = FontStyle.Language then
  2635.           inc(w, RVSMW_LANGUAGE);
  2636.         {$ENDIF}
  2637.         inc(w, RV_CompareInts(FontSize, FontStyle.Size, RVSMW_FONTSIZE));
  2638.         inc(w, RV_CompareColors(FontStyle.Color, Color, RVSMW_EACHRGBCOLOR, RVSMW_COLORSET));
  2639.         inc(w, RV_CompareColors(FontStyle.BackColor, BackColor, RVSMW_EACHRGBBCOLOR, RVSMW_BCOLORSET));
  2640.         if (rvfsAllCaps in FontStyle.StyleEx) = (rtf_fs_AllCaps in StyleEx) then
  2641.           inc(w, RVSMW_ALLCAPS);
  2642.         for fs := Low(TFontStyle) to High(TFontStyle) do
  2643.           if (fs in FontStyle.Style) = (fs in Style) then
  2644.             inc(w, RVSMW_FONTEACHSTYLE);
  2645.         if (FontStyle.Style=[])=(Style=[]) then
  2646.           inc(w, RVSMW_FONTSTYLESET);
  2647.         inc(w, Round((1 - abs(FontStyle.CharScale-CharScaleX) / 100)*RVSMW_CHARSCALE));
  2648.         inc(w, RV_CompareInts(CharSpacing, FontStyle.CharSpacing, RVSMW_FONTSIZE));
  2649.         if GetStyleSSType(FontStyle.VShift)=SScriptType then
  2650.           inc(w, RVSMW_VSHIFT);
  2651.         if FontStyle.StyleEx<>[] then
  2652.           w := w div 4;
  2653.         if w>maxw then begin
  2654.           maxw := w;
  2655.           Result := i;
  2656.         end;
  2657.       end;
  2658.     end;
  2659.   end;
  2660. end;
  2661. {------------------------------------------------------------------------------}
  2662. function TRVRTFReaderProperties.FindStyleNo(AUnicode, AHypertext: Boolean): Integer;
  2663. var i: Integer;
  2664.     FontStyle: TFontInfo;
  2665.     FontSize: Integer;
  2666.     FN: String;
  2667.     CharSpacing: Integer;
  2668.     {$IFDEF RICHVIEWCBDEF3}
  2669.     Charset: TFontCharset;
  2670.     {$ENDIF}
  2671. begin
  2672.   Result := -1;
  2673.   {$IFDEF RVTEXTFOOTNOTES}
  2674.   if Reader.RTFState.CharProps.FootNote<>'' then
  2675.     exit;
  2676.   {$ENDIF}
  2677.   with Reader.RTFState.CharProps do begin
  2678.     if Reader.FontTable.Count=0 then begin
  2679.       Result := 0;
  2680.       exit;
  2681.     end;
  2682.     if FontName='' then
  2683.       FN := AnsiLowerCase(Reader.FontTable[FontIndex].Name)
  2684.     else
  2685.       FN := AnsiLowerCase(FontName);
  2686.     {$IFDEF RICHVIEWCBDEF3}
  2687.     Charset := Reader.FontTable[FontIndex].Charset;
  2688.     if (FontName=RVFONT_SYMBOL) or (FontName=RVFONT_WINGDINGS) then
  2689.       Charset := SYMBOL_CHARSET;
  2690.     {$ENDIF}
  2691.     CharSpacing  := Round(CharSpacingTw*PixelsPerTwip);
  2692.     if SScriptType = rtf_ss_Normal then
  2693.       FontSize := Size
  2694.     else
  2695.       FontSize := Round(Size/2);    
  2696.     for i := 0 to RVStyle.TextStyles.Count-1 do begin
  2697.       FontStyle := RVStyle.TextStyles[i];
  2698.       if (AnsiLowerCase(FontStyle.FontName)=FN) and
  2699.          (FontStyle.Size=FontSize) and
  2700.          (FontStyle.Color=Color) and
  2701.          (FontStyle.BackColor=BackColor) and
  2702.          (FontStyle.Style=Style) and
  2703.          {$IFDEF RVLANGUAGEPROPERTY}
  2704.          (FontStyle.Language = Language) and
  2705.          {$ENDIF}
  2706.          {$IFDEF RICHVIEWCBDEF3}
  2707.          ((FontStyle.Charset=Charset)
  2708.           or (FontStyle.Charset=DEFAULT_CHARSET)) // <-- not very good solution
  2709.           and
  2710.          {$ENDIF}
  2711.          (FontStyle.CharScale=CharScaleX) and
  2712.          (FontStyle.CharSpacing=CharSpacing) and
  2713.          ((rvfsAllCaps in FontStyle.StyleEx)=(rtf_fs_AllCaps in StyleEx)) and
  2714.          (GetStyleSSType(FontStyle.VShift)=SScriptType) and
  2715.          {$IFNDEF RVDONOTUSEUNICODE}
  2716.          (FontStyle.Unicode=AUnicode) and
  2717.          {$ENDIF}
  2718.          (FontStyle.StyleEx = []) and
  2719.          ((AHypertext and FontStyle.Jump) or
  2720.           (not AHypertext and (UseHypertextStyles or not FontStyle.Jump))) then begin
  2721.         Result := i;
  2722.         break;
  2723.       end;
  2724.     end;
  2725.   end;
  2726. end;
  2727. {------------------------------------------------------------------------------}
  2728. procedure TRVRTFReaderProperties.AddStyle(AUnicode, AHypertext: Boolean);
  2729. var FontStyle: TFontInfo;
  2730. begin
  2731.   FontStyle := TFontInfo(RVStyle.TextStyles.Add);
  2732.   FontStyle.Standard := False;
  2733.   with Reader.RTFState.CharProps do begin
  2734.     FontStyle.Jump      := AHypertext;
  2735.     {$IFNDEF RVDONOTUSEUNICODE}
  2736.     FontStyle.Unicode   := AUnicode;
  2737.     {$ENDIF}
  2738.     FontStyle.Style     := Style;
  2739.     if SScriptType = rtf_ss_Normal then
  2740.       FontStyle.Size := Size
  2741.     else
  2742.       FontStyle.Size := Round(Size/2);
  2743.     FontStyle.Color     := Color;
  2744.     FontStyle.BackColor := BackColor;
  2745.     if FontName='' then
  2746.       FontStyle.FontName  := Reader.FontTable[FontIndex].Name
  2747.     else begin
  2748.       FontStyle.FontName  := FontName;
  2749.       // FontStyle.Protection := FontStyle.Protection+[rvprStyleProtect,rvprDoNotAutoSwitch];
  2750.     end;
  2751.     {$IFDEF RICHVIEWCBDEF3}
  2752.     FontStyle.Charset   := Reader.FontTable[FontIndex].Charset;
  2753.     if (FontName=RVFONT_SYMBOL) or (FontName=RVFONT_WINGDINGS) then
  2754.       FontStyle.Charset := SYMBOL_CHARSET;
  2755.     {$ENDIF}
  2756.     FontStyle.CharScale := CharScaleX;
  2757.     FontStyle.CharSpacing := Round(CharSpacingTw*PixelsPerTwip);
  2758.     case SScriptType of
  2759.       rtf_ss_Normal:
  2760.         FontStyle.VShift := 0;
  2761.       rtf_ss_Superscript:
  2762.         FontStyle.VShift := 45;
  2763.       rtf_ss_Subscript:
  2764.         FontStyle.VShift := -25;
  2765.     end;
  2766.     if rtf_fs_AllCaps in StyleEx then
  2767.       FontStyle.StyleEx := FontStyle.StyleEx+[rvfsAllCaps];
  2768.     {$IFDEF RVLANGUAGEPROPERTY}
  2769.     FontStyle.Language := Language;
  2770.     {$ENDIF}
  2771.     {$IFDEF RVTEXTFOOTNOTES}
  2772.     if rtf_fs_FootNote in StyleEX then begin
  2773.       FontStyle.StyleEx := FontStyle.StyleEx+[rvfsFootNotes];
  2774.       FontStyle.FootNote := FootNote;
  2775.     end;    
  2776.     {$ENDIF}
  2777.   end;
  2778. end;
  2779. {------------------------------------------------------------------------------}
  2780. function TRVRTFReaderProperties.ReturnStyleNo(AUnicode: Boolean): Integer;
  2781. var ht: Boolean;
  2782. begin
  2783.   case TextStyleMode of
  2784.     rvrsUseSpecified:
  2785.       Result := TextStyleNo;
  2786.     rvrsUseClosest:
  2787.       Result := FindBestStyleNo(AUnicode, IsHypertext_);
  2788.     else
  2789.       begin
  2790.         ht := IsHypertext_;
  2791.         Result := FindStyleNo(AUnicode, ht);
  2792.         if Result<0 then begin
  2793.           AddStyle(AUnicode, ht);
  2794.           Result := RVStyle.TextStyles.Count-1;
  2795.         end;
  2796.       end;
  2797.   end;
  2798. end;
  2799. const HYPERLINK = 'HYPERLINK';
  2800. {------------------------------------------------------------------------------}
  2801. function TRVRTFReaderProperties.IsHypertext(var Target, Hint,
  2802.   Extras: String): Boolean;
  2803. var p: Integer;
  2804.     s: String;
  2805.     removed, quoted: Boolean;
  2806.     i, state: Integer;
  2807. begin
  2808.   if Reader.RTFState.FieldCode='' then begin
  2809.     Result := False;
  2810.     exit;
  2811.   end;
  2812.   s := Trim(Reader.RTFState.FieldCode);
  2813.   if s[1]='' then
  2814.     s := Copy(s, 2, Length(s));
  2815.   p := Pos(HYPERLINK, UpperCase(s));
  2816.   Result := p=1;
  2817.   if not Result then
  2818.     exit;
  2819.   Target := Reader.GetFieldCommandValueEx(s, p);
  2820.   if p<=Length(s) then
  2821.     Extras := Copy(s, p, Length(s)-p+1)
  2822.   else
  2823.     Extras := '';
  2824.   removed := False;
  2825.   for p := Length(Target) downto 2 do begin
  2826.     removed := not removed and (Target[p]='') and (Target[p-1]='');
  2827.     if removed then
  2828.       Delete(Target, p, 1);
  2829.   end;
  2830.   quoted := False;
  2831.   state := 0;
  2832.   Hint := '';
  2833.   for i := 1 to Length(Extras) do
  2834.     case state of
  2835.     0:
  2836.       begin
  2837.         if not quoted then begin
  2838.           if Extras[i]='' then
  2839.            state := 1
  2840.           else if Extras[i]='"' then
  2841.             quoted := True;
  2842.           end
  2843.         else if Extras[i]='"' then
  2844.           quoted := False;
  2845.       end;
  2846.     1:
  2847.       if Extras[i]='o' then
  2848.         state := 2
  2849.       else
  2850.         state := 0;
  2851.     2:
  2852.       if Extras[i]=' ' then
  2853.         state := 3
  2854.       else
  2855.         state := 0;
  2856.     3:
  2857.       begin
  2858.         if Extras[i]='"' then
  2859.           quoted := True
  2860.         else
  2861.           Hint := Hint+Extras[i];
  2862.         state := 4;
  2863.       end;
  2864.     4:
  2865.       begin
  2866.         if (quoted and (Extras[i]='"')) or
  2867.            (not quoted and (Extras[i]=' ')) then
  2868.           break;
  2869.         Hint := Hint+Extras[i];
  2870.       end;
  2871.     end;
  2872.   Target := RV_DecodeURL(Target);
  2873.   if (BasePath<>'') and (Pos(':', Target)=0) then
  2874.     Target := BasePath+Target;
  2875. end;
  2876. {------------------------------------------------------------------------------}
  2877. function TRVRTFReaderProperties.IsHypertext_: Boolean;
  2878. begin
  2879.   if Reader.RTFState.FieldCode='' then
  2880.     Result := False
  2881.   else
  2882.     Result := Pos(HYPERLINK, Reader.RTFState.FieldCode)>0;
  2883. end;
  2884. {------------------------------------------------------------------------------}
  2885. function TRVRTFReaderProperties.AllowUseStyle(StyleNo: Integer; TextStyle: Boolean): Boolean;
  2886. begin
  2887.   Result := True;
  2888.   if Assigned(OnAllowUseStyle) then
  2889.     OnAllowUseStyle(StyleNo, TextStyle, Result);
  2890. end;
  2891. {$ENDIF}
  2892. end.