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

RichEdit

开发平台:

Delphi

  1.         Result := '</div>';
  2.     end;
  3.     {...........................................................}
  4.     procedure SaveMiddle(Stream: TStream;
  5.                          const Path: String);
  6.     var
  7.       i: Integer;
  8.       item: TCustomRVItemInfo;
  9.       CloseDIV: Boolean;
  10.       s2, s3, ATag, HintTag: String;
  11.       cpno: Integer;
  12.       CreateBulletList: Boolean;
  13.       RVStyle: TRVStyle;
  14.       TextStyleNo: Integer;
  15.       {$IFNDEF RVDONOTUSELISTS}
  16.       marker: TRVMarkerItemInfo;
  17.       {$ENDIF}
  18.     begin
  19.       cpno := 0;
  20.       {$IFNDEF RVDONOTUSELISTS}
  21.       marker := nil;
  22.       {$ENDIF}
  23.       RVStyle := GetRVStyle;
  24.       CreateBulletList := Bullets=nil;
  25.       if CreateBulletList then
  26.         Bullets := TRVList.Create;
  27.       try
  28.         if not (rvsoDefault0Style in Options) then begin
  29.           s3 := RV_HTMLOpenFontTag(RVStyle.TextStyles[0],
  30.             RVStyle.TextStyles[0], False, Options);
  31.           if rvsoUTF8 in Options then
  32.             s3 := RVU_AnsiToUTF8(CP_ACP, s3);
  33.           RVWriteLn(Stream, s3);
  34.         end;
  35.         CloseDIV := False;
  36.         for i:=0 to Items.Count-1 do begin
  37.           item := GetItem(i);
  38.           if not item.SameAsPrev then begin
  39.             if item.BR then
  40.               RVWriteLn(Stream, Format('<br%s>', [RV_HTMLGetEndingSlash(Options)]))
  41.             else begin
  42.               {$IFNDEF RVDONOTUSELISTS}
  43.               if marker<>nil then begin
  44.                 RVWriteLn(Stream,'</li>');
  45.                 RVWrite(Stream, GetParaHTMLCode(Self, i, False, False));
  46.               end;
  47.               {$ENDIF}
  48.               if CloseDIV then begin
  49.                 RVWriteLn(Stream,GetCloseDIVTag);
  50.                 RVWrite(Stream, GetParaHTMLCode(Self, i, False, False));
  51.                 CloseDIV := False;
  52.               end;
  53.             end;
  54.             if not item.BR then
  55.               case item.StyleNo of
  56.                 rvsBreak: ;
  57.                 {$IFNDEF RVDONOTUSELISTS}
  58.                 rvsListMarker:
  59.                   begin
  60.                     if (rvsoMarkersAsText in Options) or
  61.                        (TRVMarkerItemInfo(item).GetLevelInfo(RVStyle)=nil) then begin
  62.                       RVWrite(Stream, GetParaHTMLCode(Self, i, True, False));
  63.                       RVWrite(Stream, GetOpenDIVTag(RVStyle.ParaStyles[item.ParaNo].Alignment, item));
  64.                       CloseDIV := True;
  65.                       end
  66.                     else begin
  67.                       TRVMarkerItemInfo(item).SaveHTMLSpecial(Stream, marker, RVStyle, False);
  68.                       RVWrite(Stream, GetParaHTMLCode(Self, i, True, False));
  69.                       marker := TRVMarkerItemInfo(item);
  70.                       if marker.GetLevelInfo(RVStyle).HasNumbering then
  71.                         RVWrite(Stream,Format('<li value=%s%s>',
  72.                           [RV_HTMLGetIntAttrVal(marker.Counter, Options), GetPageBreakCSS(marker)]))
  73.                       else
  74.                         RVWrite(Stream,Format('<li%s>',[GetPageBreakCSS(marker)]));
  75.                     end;
  76.                   end;
  77.                 {$ENDIF}
  78.                 else
  79.                   begin
  80.                     {$IFNDEF RVDONOTUSELISTS}
  81.                     if marker<>nil then begin
  82.                       marker.HTMLOpenOrCloseTags(Stream, marker.Level, -1, RVStyle, False);
  83.                       marker := nil;
  84.                     end;
  85.                     {$ENDIF}
  86.                     RVWrite(Stream, GetParaHTMLCode(Self, i, True, False));
  87.                     RVWrite(Stream, GetOpenDIVTag(RVStyle.ParaStyles[item.ParaNo].Alignment, item));
  88.                     CloseDIV := True;
  89.                   end;
  90.               end;
  91.           end;
  92.           SaveHTMLCheckpoint(Stream, item.Checkpoint, cpno, RVDEFAULTCHECKPOINTPREFIX, True, Options);
  93.           ATag := '';
  94.           HintTag := '';
  95.           if item.GetBoolValueEx(rvbpJump, RVStyle) then
  96.             ATag := GetHTMLATag(i, '', rvsoUTF8 in Options);
  97.           if ATag<>'' then
  98.             RVWrite(Stream, ATag)
  99.           else begin
  100.             item.GetExtraStrProperty(rvespHint, HintTag);
  101.             if HintTag<>'' then
  102.               HintTag := RV_GetHintStr(rvsfHTML, HintTag);
  103.           end;
  104.           if (item.StyleNo<0) and (item.AssociatedTextStyleNo<0) then begin // non-text
  105.             s2 := '';
  106.             if SaveItemToFile(Path, Self, i, rvsfHTML, False, s2) then
  107.               RVWrite(Stream, s2)
  108.             else begin
  109.               item.SaveToHTML(Stream, Self, i, Items[i], Path, ImagesPrefix,
  110.                 imgSaveNo, Color, Options, False, Bullets);
  111.               if item.StyleNo=rvsBreak then
  112.                 RVWriteLn(Stream,'');
  113.             end;
  114.             end
  115.           else begin
  116.             if item.StyleNo<0 then
  117.               TextStyleNo := item.AssociatedTextStyleNo
  118.             else
  119.               TextStyleNo := GetActualStyle(item);
  120.             if ShouldSaveTextToHTML(TextStyleNo) then begin // text or tab
  121.               if HintTag<>'' then
  122.                 RVWrite(Stream, '<span '+HintTag+'>');
  123.               if TextStyleNo<>0 then begin
  124.                 s3 := RV_HTMLOpenFontTag(RVStyle.TextStyles[TextStyleNo],
  125.                   RVStyle.TextStyles[0], True, Options);
  126.                 if rvsoUTF8 in Options then
  127.                   s3 := RVU_AnsiToUTF8(CP_ACP, s3);
  128.                 RVWrite(Stream, s3);
  129.               end;
  130.               if item.StyleNo>=0 then begin
  131.                 s2 := GetTextForHTML(Path, i, False, Options);
  132.                 RVWrite(Stream, s2);
  133.                 end
  134.               else begin
  135.                 s2 := '';
  136.                 if SaveItemToFile(Path, Self, i, rvsfHTML, False, s2) then
  137.                   RVWrite(Stream, s2)
  138.                  else
  139.                    item.SaveToHTML(Stream, Self, i, Items[i], Path, ImagesPrefix,
  140.                      imgSaveNo, Color, Options, False, Bullets);
  141.               end;
  142.               if TextStyleNo<>0 then
  143.                 RVWrite(Stream,
  144.                   RV_HTMLCloseFontTag(RVStyle.TextStyles[TextStyleNo],
  145.                     RVStyle.TextStyles[0], True));
  146.               if HintTag<>'' then
  147.                 RVWrite(Stream, '</span>');
  148.             end;
  149.           end;
  150.           if ATag<>'' then
  151.             RVWrite(Stream,'</a>');
  152.         end;
  153.         {$IFNDEF RVDONOTUSELISTS}
  154.         if marker<>nil then begin
  155.           RVWriteLn(Stream,'</li>');
  156.           RVWrite(Stream, GetParaHTMLCode(Self, ItemCount, False, False));
  157.           marker.HTMLOpenOrCloseTags(Stream, marker.Level, -1, RVStyle, False);
  158.         end;
  159.         {$ENDIF}
  160.         if CloseDIV then begin
  161.           RVWriteLn(Stream,GetCloseDIVTag);
  162.           RVWrite(Stream, GetParaHTMLCode(Self, ItemCount, False, False));
  163.         end;
  164.         if not (rvsoDefault0Style in Options) then
  165.           RVWriteLn(Stream,
  166.                   RV_HTMLCloseFontTag(RVStyle.TextStyles[0], RVStyle.TextStyles[0], False));
  167.         SaveHTMLCheckpoint(Stream, NotAddedCP, cpno, RVDEFAULTCHECKPOINTPREFIX, False, Options);
  168.       finally
  169.         if CreateBulletList then begin
  170.           Bullets.Free;
  171.         end;
  172.       end;
  173.     end;
  174.     {...........................................................}
  175. begin
  176.   Result := False;
  177.   if GetRVStyle = nil then exit;
  178.   Result := True;
  179.   try
  180.     if not (rvsoMiddleOnly in Options) and
  181.        not (rvsoLastOnly in Options) then
  182.        SaveFirst(Stream, Path, Title);
  183.     if not (rvsoFirstOnly in Options) and
  184.        not (rvsoLastOnly in Options) then
  185.        SaveMiddle(Stream, Path);
  186.     if not (rvsoFirstOnly in Options) and
  187.        not (rvsoMiddleOnly in Options) then
  188.        SaveLast(Stream);
  189.   except
  190.     Result := False;
  191.   end;
  192. end;
  193. {------------------------------------------------------------------------------}
  194. function TCustomRVData.SaveBackgroundToHTML(bmp: TBitmap; Color: TColor;
  195.   const Path, ImagesPrefix: String; var imgSaveNo: Integer;
  196.   SaveOptions: TRVSaveOptions): String;
  197. var DoDefault: Boolean;
  198. begin
  199.   Result := '';
  200.   HTMLSaveImage(Self, -1, Path, Color, Result, DoDefault);
  201.   if DoDefault then
  202.     Result := RV_GetHTMLPath(DoSavePicture(rvsfHTML, ImagesPrefix, Path,
  203.       imgSaveNo, rvsoOverrideImages in SaveOptions, Color, bmp), SaveOptions,
  204.       GetRVStyle.DefCodePage);
  205. end;
  206. {------------------------------------------------------------------------------}
  207. function TCustomRVData.SaveHTMLToStreamEx(Stream: TStream; const Path,
  208.   Title, ImagesPrefix, ExtraStyles, ExternalCSS, CPPrefix: String;
  209.   Options: TRVSaveOptions; Color: TColor; var CurrentFileColor: TColor;
  210.   var imgSaveNo: Integer; LeftMargin, TopMargin, RightMargin, BottomMargin: Integer;
  211.   Background: TRVBackground; Bullets: TRVList): Boolean;
  212.     {......................................................}
  213.     procedure WriteExtraHTMLCode(Area: TRVHTMLSaveArea; AddSpace: Boolean);
  214.     var s: String;
  215.     begin
  216.       s := GetExtraHTMLCode(Area, True);
  217.       if s<>'' then
  218.         if AddSpace then
  219.           RVWrite(Stream,' '+s)
  220.         else
  221.           RVWrite(Stream, s);
  222.     end;
  223.     {......................................................}
  224.     function GetBackgroundVPos(BStyle: TBackgroundStyle): String;
  225.     begin
  226.       case BStyle of
  227.         bsTopLeft, bsTopRight:
  228.           Result := 'top';
  229.         bsBottomLeft, bsBottomRight:
  230.           Result := 'bottom';
  231.         else
  232.           Result := 'center';
  233.       end;
  234.     end;
  235.     {......................................................}
  236.     function GetBackgroundHPos(BStyle: TBackgroundStyle): String;
  237.     begin
  238.       case BStyle of
  239.         bsTopLeft, bsBottomLeft:
  240.           Result := 'left';
  241.         bsTopRight, bsBottomRight:
  242.           Result := 'right';
  243.         else
  244.           Result := 'center';
  245.       end;
  246.     end;
  247.     {......................................................}
  248.     procedure SaveFirst(Stream: TStream;
  249.       const Path,Title,ExtraStyles,ExternalCSS: String);
  250.     var s: String;
  251.         CSSOptions: TRVSaveCSSOptions;
  252.     begin
  253.       if rvsoXHTML in Options then begin
  254.         RVWrite(Stream, '<?xml version="1.0"');
  255.         {$IFDEF RICHVIEWCBDEF3}
  256.         if rvsoUTF8 in Options then
  257.           s := 'UTF-8'
  258.         else
  259.           s := RV_CharSet2HTMLLang(GetRVStyle.TextStyles[0].CharSet);
  260.         if s<>'' then
  261.           RVWrite(Stream,SysUtils.Format(' encoding="%s"',[s]));
  262.         {$ENDIF}
  263.         RVWriteLn(Stream, '?>');
  264.         RVWriteLn(Stream, '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">');
  265.         RVWriteLn(Stream, '<html xmlns="http://www.w3.org/1999/xhtml">');
  266.         end
  267.       else begin
  268.         RVWriteLn(Stream,'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">');
  269.         RVWrite(Stream, '<html>');
  270.       end;
  271.       s := Title;
  272.       if rvsoUTF8 in Options then
  273.         s := RVU_AnsiToUTF8(GetRVStyle.DefCodePage, Title);
  274.       RVWriteLn(Stream,'<head><title>'+s+'</title>');
  275.       {$IFDEF RICHVIEWCBDEF3}
  276.       if rvsoUTF8 in Options then
  277.         s := 'UTF-8'
  278.       else
  279.         s := RV_CharSet2HTMLLang(GetRVStyle.TextStyles[0].CharSet);
  280.       if s<>'' then
  281.         RVWriteLn(Stream,SysUtils.Format('<meta http-equiv="Content-Type" content="text/html; charset=%s"%s>',
  282.           [s, RV_HTMLGetEndingSlash(Options)]));
  283.       {$ENDIF}
  284.       RVWrite(Stream,'<style type="text/css">');
  285.       if rvsoXHTML in Options then
  286.         RVWriteLn(Stream,'')
  287.       else
  288.         RVWriteLn(Stream,'<!--');
  289.       s := RV_GetHTMLRGBStr(Color, False);
  290.       RVWriteLn(Stream, 'body {');
  291.       RVWriteLn(Stream, SysUtils.Format('  margin: %dpx %dpx %dpx %dpx;',
  292.                 [TopMargin, RightMargin, BottomMargin, LeftMargin]));
  293.       if s<>'' then
  294.         RVWriteLn(Stream, '  background-color: '+s+';');
  295.       if (Background.Style<>bsNoBitmap) and
  296.          (not Background.Bitmap.Empty) then begin
  297.          s := SaveBackgroundToHTML(Background.Bitmap, Color, Path, ImagesPrefix,
  298.            imgSaveNo, Options);
  299.          if s<>'' then begin
  300.            RVWriteLn(Stream, SysUtils.Format('  background-image: url("%s");', [s]));
  301.            RVWriteLn(Stream, '  background-repeat: '+rv_cssBkRepeat[Background.Style]+';');
  302.            RVWriteLn(Stream, '  background-attachment: '+rv_cssBkAttachment[Background.Style]+';');
  303.            if Background.Style in [bsStretched, bsCentered, bsTopLeft, bsTopRight,
  304.              bsBottomLeft, bsBottomRight] then
  305.                RVWriteLn(Stream, '  background-position: '+GetBackgroundVPos(Background.Style)+
  306.                 ' '+GetBackgroundHPos(Background.Style)+';');
  307.          end;
  308.       end;
  309.       RVWriteLn(Stream, '}');
  310.       if (ExternalCSS='') and not (rvsoInlineCSS in Options) then begin
  311.         CSSOptions := [];
  312.         if (rvsoNoDefCSSStyle in Options) then
  313.           Include(CSSOptions, rvcssNoDefCSSStyle);
  314.         if (rvsoUTF8 in Options) then
  315.           Include(CSSOptions, rvcssUTF8);
  316.         GetRVStyle.SaveCSSToStream(Stream, CSSOptions);
  317.       end;
  318.       if ExtraStyles<>'' then begin
  319.         s := ExtraStyles;
  320.         if (rvsoUTF8 in Options) then
  321.           s := RVU_AnsiToUTF8(GetRVStyle.DefCodePage, s);
  322.         RVWriteLn(Stream, s);
  323.       end;
  324.       if not (rvsoXHTML in Options) then
  325.         RVWrite(Stream,'-->');
  326.       RVWriteLn(Stream,'</style>');
  327.       if (ExternalCSS<>'') and not (rvsoInlineCSS in Options) then begin
  328.         s := ExternalCSS;
  329.         if (rvsoUTF8 in Options) then
  330.           s := RVU_AnsiToUTF8(GetRVStyle.DefCodePage, s);
  331.         RVWriteLn(Stream, '<link type="text/css" href="'+s+'" rel="stylesheet">');
  332.       end;
  333.       WriteExtraHTMLCode(rv_thms_Head, False);
  334.       RVWriteLn(Stream,'</head>');
  335.       RVWrite(Stream,'<body');
  336.       WriteExtraHTMLCode(rv_thms_BodyAttribute, True);
  337.       RVWriteLn(Stream,'>');
  338.       WriteExtraHTMLCode(rv_thms_Body, False);
  339.     end;
  340.     {......................................................}
  341.     procedure SaveLast(Stream: TStream);
  342.     begin
  343.       RVWriteLn(Stream,'');
  344.       WriteExtraHTMLCode(rv_thms_End, False);
  345.       RVWriteLn(Stream,'</body></html>');
  346.     end;
  347.     {......................................................}
  348.     function GetTextCSS(TextStyleNo: Integer; RVStyle: TRVStyle): String;
  349.     var MemoryStream: TStream;
  350.     begin
  351.       if (rvsoInlineCSS in Options) then begin
  352.         MemoryStream := TMemoryStream.Create;
  353.         try
  354.           RVStyle.TextStyles[TextStyleNo].SaveCSSToStream(MemoryStream,
  355.             nil, False, rvsoUTF8 in Options);
  356.           SetLength(Result, MemoryStream.Size);
  357.           MemoryStream.Position := 0;
  358.           MemoryStream.ReadBuffer(PChar(Result)^, Length(Result));
  359.         finally
  360.           MemoryStream.Free;
  361.         end;
  362.         Result := 'style="'+Result+'"';
  363.         end
  364.       else
  365.         Result := 'class='+RV_HTMLGetStrAttrVal('rvts'+IntToStr(TextStyleNo), Options);
  366.     end;
  367.     {......................................................}
  368.     function GetPageBreakCSS(item: TCustomRVItemInfo; OnlyValue, SpaceBefore: Boolean): String;
  369.     begin
  370.       if item.PageBreakBefore then begin
  371.         Result := 'page-break-before: always;';
  372.         if not OnlyValue then
  373.           Result := 'style="'+Result+'"';
  374.         end
  375.       else
  376.         Result := '';
  377.       if (Result<>'') and SpaceBefore then
  378.         Result := ' '+Result;
  379.     end;
  380.     {......................................................}
  381.     function GetParaCSSValue(item: TCustomRVItemInfo; RVStyle: TRVStyle;
  382.       IgnoreLeftIndents: Boolean): String;
  383.     var MemoryStream: TStream;
  384.     begin
  385.       if (rvsoInlineCSS in Options) then begin
  386.         MemoryStream := TMemoryStream.Create;
  387.         try
  388.           RVStyle.ParaStyles[item.ParaNo].SaveCSSToStream(MemoryStream, nil,
  389.             False, False, IgnoreLeftIndents);
  390.           SetLength(Result, MemoryStream.Size);
  391.           MemoryStream.Position := 0;
  392.           MemoryStream.ReadBuffer(PChar(Result)^, Length(Result));
  393.         finally
  394.           MemoryStream.Free;
  395.         end;
  396.         end
  397.       else
  398.         Result := '';
  399.       Result := Result+GetPageBreakCSS(item, True, Result<>'')
  400.     end;
  401.     {......................................................}
  402.     function GetParaCSS(item: TCustomRVItemInfo; RVStyle: TRVStyle;
  403.       IgnoreLeftIndents: Boolean): String;
  404.     begin
  405.       if (rvsoInlineCSS in Options) then
  406.         Result := 'style="'+GetParaCSSValue(item, RVStyle, IgnoreLeftIndents)+'"'
  407.       else if (Item.ParaNo>0) or (rvsoNoDefCSSStyle in Options) then
  408.         Result := 'class='+RV_HTMLGetStrAttrVal('rvps'+IntToStr(item.ParaNo), Options)+
  409.          GetPageBreakCSS(item, False, True)
  410.       else
  411.         Result := GetPageBreakCSS(item, False, False);
  412.     end;
  413.     {......................................................}
  414.     function GetItemTextStyleNo(ItemNo: Integer): Integer;
  415.     var item: TCustomRVItemInfo;
  416.     begin
  417.       item := GetItem(ItemNo);
  418.       if item.StyleNo>=0 then
  419.         Result := GetActualStyle(item)
  420.       else begin
  421.         Result := item.AssociatedTextStyleNo;
  422.         if Result<0 then
  423.           Result := item.StyleNo;
  424.       end;
  425.     end;
  426.     {......................................................}
  427.     procedure SaveMiddle(Stream: TStream; const Path: String; CPPrefix: String);
  428.     var i: Integer;
  429.         item: TCustomRVItemInfo;
  430.         s, s2, ATag, HintAttr: String;
  431.         cpno, CurFont, OpenedPara, TextStyleNo: Integer;
  432.         CreateBulletList, Use0StyleAsDef, DIVOpened: Boolean;
  433.         RVStyle: TRVStyle;
  434.         {$IFNDEF RVDONOTUSELISTS}
  435.         marker: TRVMarkerItemInfo;
  436.         {$ENDIF}
  437.     begin
  438.       if CPPrefix='' then
  439.         CPPrefix := RVDEFAULTCHECKPOINTPREFIX;
  440.       RVStyle := GetRVStyle;
  441.       cpno    := 0;
  442.       CurFont := -1;
  443.       OpenedPara := -1;
  444.       DIVOpened := False;
  445.       {$IFNDEF RVDONOTUSELISTS}
  446.       marker := nil;
  447.       {$ENDIF}
  448.       CreateBulletList := Bullets=nil;
  449.       if CreateBulletList then
  450.         Bullets := TRVList.Create;
  451.       try
  452.         Use0StyleAsDef := (RVStyle.TextStyles.Count>=1) and
  453.           not RVStyle.TextStyles[0].Jump and
  454.           (RVStyle.TextStyles[0].BackColor=clNone) and
  455.           not (rvsoNoDefCSSStyle in Options);
  456.         for i:=0 to Items.Count-1 do begin
  457.           item := GetItem(i);
  458.           if (not item.SameAsPrev) then begin
  459.             if ((OpenedPara<0) {$IFNDEF RVDONOTUSELISTS}and (marker=nil){$ENDIF}) or
  460.                item.BR then
  461.               RVWriteLn(Stream,'');
  462.             if item.BR then 
  463.               RVWrite(Stream, Format('<br%s>', [RV_HTMLGetEndingSlash(Options)]))
  464.             else begin
  465.               {$IFNDEF RVDONOTUSELISTS}
  466.               if marker<>nil then begin
  467.                 RVWriteLn(Stream,'</li>');
  468.                 RVWrite(Stream, GetParaHTMLCode(Self, i, False, True));
  469.                 end
  470.               else if (OpenedPara>=0) then
  471.               {$ENDIF}
  472.               begin
  473.                 if DIVOpened then
  474.                   RVWriteLn(Stream,'</div>')
  475.                 else
  476.                   RVWriteLn(Stream,'</p>');
  477.                 DIVOpened := False;
  478.                 RVWrite(Stream, GetParaHTMLCode(Self, i, False, True));
  479.               end;
  480.               CurrentFileColor := RVStyle.ParaStyles[item.ParaNo].Background.Color;
  481.               if CurrentFileColor=clNone then
  482.                 CurrentFileColor := Color;
  483.               case item.StyleNo of
  484.                 rvsBreak:
  485.                   OpenedPara := -1;
  486.                 {$IFNDEF RVDONOTUSELISTS}
  487.                 rvsListMarker:
  488.                   begin
  489.                     if TRVMarkerItemInfo(item).GetLevelInfo(RVStyle)<>nil then begin
  490.                       if rvsoMarkersAsText in Options then begin
  491.                         RVWrite(Stream, GetParaHTMLCode(Self, i, True, True));
  492.                         if ((item.ParaNo=0) and not (rvsoNoDefCSSStyle in Options)) or
  493.                            (rvsoInlineCSS in Options) then
  494.                           RVWrite(Stream, Format('<p style="%s %s">',
  495.                             [GetParaCSSValue(item, RVStyle, True),
  496.                              TRVMarkerItemInfo(item).GetLevelInfo(RVStyle).GetIndentCSSForTextVersion]))
  497.                         else
  498.                           RVWrite(Stream, Format('<p %s style="%s">',
  499.                             [GetParaCSS(item, RVStyle, True),
  500.                              TRVMarkerItemInfo(item).GetLevelInfo(RVStyle).GetIndentCSSForTextVersion]));
  501.                         OpenedPara := item.ParaNo;
  502.                         end
  503.                       else begin
  504.                         TRVMarkerItemInfo(item).SaveHTMLSpecial(Stream, marker, RVStyle, True);
  505.                         RVWrite(Stream, GetParaHTMLCode(Self, i, True, True));
  506.                         marker := TRVMarkerItemInfo(item);
  507.                         if marker.GetLevelInfo(RVStyle).HasNumbering then
  508.                           RVWrite(Stream,Format('<li value=%s',[RV_HTMLGetIntAttrVal(marker.Counter, Options)]))
  509.                         else
  510.                           RVWrite(Stream,'<li');
  511.                         s := GetParaCSS(item, RVStyle, True);
  512.                         if s<>'' then
  513.                           RVWrite(Stream, ' '+s);
  514.                         RVWrite(Stream, marker.GetLICSS(Self, i, Path,
  515.                           ImagesPrefix, imgSaveNo, CurrentFileColor, Options,
  516.                           Bullets));
  517.                         RVWrite(Stream,'>');
  518.                         OpenedPara := -1;
  519.                       end
  520.                       end
  521.                     else begin
  522.                       {$IFNDEF RVDONOTUSELISTS}
  523.                       if marker<>nil then begin
  524.                         marker.HTMLOpenOrCloseTags(Stream, marker.Level, -1, RVStyle, True);
  525.                         marker := nil;
  526.                       end;
  527.                       {$ENDIF}
  528.                       RVWrite(Stream, GetParaHTMLCode(Self, i, True, True));
  529.                       s := GetParaCSS(item, RVStyle, False);
  530.                       if item.GetBoolValue(rvbpNoHTML_P) then
  531.                       if s='' then
  532.                         RVWrite(Stream, '<p>')
  533.                       else
  534.                         RVWrite(Stream, Format('<p %s>',[s]));
  535.                       OpenedPara := item.ParaNo;
  536.                     end;
  537.                   end;
  538.                 {$ENDIF}
  539.                 else
  540.                   begin
  541.                     {$IFNDEF RVDONOTUSELISTS}
  542.                     if marker<>nil then begin
  543.                       marker.HTMLOpenOrCloseTags(Stream, marker.Level, -1, RVStyle, True);
  544.                       marker := nil;
  545.                     end;
  546.                     {$ENDIF}
  547.                     RVWrite(Stream, GetParaHTMLCode(Self, i, True, True));
  548.                     s := GetParaCSS(item, RVStyle, False);
  549.                     if item.GetBoolValue(rvbpNoHTML_P) then begin
  550.                       DIVOpened := True;
  551.                       if s='' then
  552.                         RVWrite(Stream, '<div>')
  553.                       else
  554.                         RVWrite(Stream, Format('<div %s>',[s]))
  555.                       end
  556.                     else
  557.                       if s='' then
  558.                         RVWrite(Stream, '<p>')
  559.                       else
  560.                         RVWrite(Stream, Format('<p %s>',[s]));
  561.                     OpenedPara := item.ParaNo;
  562.                   end;
  563.               end
  564.             end;
  565.           end;
  566.           SaveHTMLCheckpoint(Stream, item.Checkpoint, cpno, CPPrefix, False, Options);
  567.           if (item.StyleNo<0) and (item.AssociatedTextStyleNo<0) then begin
  568.             ATag := '';
  569.             if item.GetBoolValueEx(rvbpJump, RVStyle) then begin
  570.               ATag := GetHTMLATag(i, '', rvsoUTF8 in Options);
  571.               if ATag<>'' then
  572.                 RVWrite(Stream, ATag);
  573.             end;
  574.             s2 := '';
  575.             if SaveItemToFile(Path, Self, i, rvsfHTML, False, s2) then
  576.               RVWrite(Stream, s2)
  577.             else
  578.               item.SaveToHTML(Stream, Self, i, Items[i], Path, ImagesPrefix,
  579.                 imgSaveNo, CurrentFileColor, Options, True, Bullets);
  580.             if item.GetBoolValueEx(rvbpJump, RVStyle) then begin
  581.               if ATag<>'' then
  582.                 RVWrite(Stream, '</a>');
  583.             end;
  584.             end
  585.           else begin
  586.             TextStyleNo := GetItemTextStyleNo(i);
  587.             if ShouldSaveTextToHTML(TextStyleNo) then begin
  588.               ATag := '';
  589.               if item.GetBoolValueEx(rvbpJump, RVStyle) then
  590.                 ATag := GetHTMLATag(i, GetTextCSS(TextStyleNo, RVStyle), rvsoUTF8 in Options);
  591.               if ATag<>'' then
  592.                 RVWrite(Stream, ATag)
  593.               else begin
  594.                 if CurFont<>TextStyleNo then begin
  595.                   if (TextStyleNo=0) and Use0StyleAsDef and
  596.                      not (rvsoInlineCSS in Options) then
  597.                     CurFont := -1
  598.                   else begin
  599.                     CurFont := TextStyleNo;
  600.                     RVWrite(Stream, SysUtils.Format('<span %s>',
  601.                       [GetTextCSS(TextStyleNo, RVStyle)]));
  602.                   end;
  603.                 end;
  604.               end;
  605.               HintAttr := '';
  606.               if ATag='' then begin
  607.                 item.GetExtraStrProperty(rvespHint, HintAttr);
  608.                 HintAttr := RV_GetHintStr(rvsfHTML, HintAttr);
  609.                 if HintAttr<>'' then
  610.                   RVWrite(Stream, SysUtils.Format('<span %s>', [HintAttr]));
  611.               end;
  612.               if item.StyleNo>=0 then begin
  613.                 s2 := GetTextForHTML(Path, i, True, Options);
  614.                 RVWrite(Stream, s2);
  615.                 end
  616.               else begin
  617.                 s2 := '';
  618.                 if SaveItemToFile(Path, Self, i, rvsfHTML, False, s2) then
  619.                   RVWrite(Stream, s2)
  620.                 else
  621.                   item.SaveToHTML(Stream, Self, i, Items[i], Path, ImagesPrefix,
  622.                     imgSaveNo, CurrentFileColor, Options, True, Bullets);
  623.               end;
  624.               if HintAttr<>'' then
  625.                 RVWrite(Stream,'</span>');
  626.               if ATag<>'' then
  627.                 RVWrite(Stream,'</a>')
  628.               else
  629.                 if (CurFont<>-1) and
  630.                    ((i=Items.Count-1) or (GetItemTextStyleNo(i+1)<>TextStyleNo) or
  631.                    RVStyle.TextStyles[GetItemTextStyleNo(i)].Jump or
  632.                    (not GetItem(i+1).SameAsPrev)) then begin
  633.                   RVWrite(Stream, '</span>');
  634.                   CurFont := -1;
  635.                 end;
  636.             end;
  637.           end;
  638.         end;
  639.         {$IFNDEF RVDONOTUSELISTS}
  640.         if marker<>nil then begin
  641.           RVWriteLn(Stream,'</li>');
  642.           RVWrite(Stream, GetParaHTMLCode(Self, ItemCount, False, True));
  643.           marker.HTMLOpenOrCloseTags(Stream, marker.Level, -1, RVStyle, True);
  644.         end;
  645.         {$ENDIF}
  646.         if (OpenedPara<>-1) then begin
  647.           if DIVOpened then
  648.             RVWriteLn(Stream,'</div>')
  649.           else
  650.             RVWriteLn(Stream,'</p>');
  651.           RVWrite(Stream, GetParaHTMLCode(Self, ItemCount, False, True));
  652.         end;
  653.         SaveHTMLCheckpoint(Stream, NotAddedCP, cpno, CPPrefix, False, Options);
  654.       finally
  655.         if CreateBulletList then begin
  656.           Bullets.Free;
  657.         end;
  658.       end;
  659.     end;
  660.     {......................................................}
  661. begin
  662.   Result := False;
  663.   if GetRVStyle = nil then exit;
  664.   Result := True;
  665.   CurrentFileColor := Color;
  666.   try
  667.     if not (rvsoMiddleOnly in Options) and
  668.        not (rvsoLastOnly in Options) then
  669.        SaveFirst(Stream, Path, Title, ExtraStyles, ExternalCSS);
  670.     if not (rvsoFirstOnly in Options) and
  671.        not (rvsoLastOnly in Options) then
  672.        SaveMiddle(Stream, Path, CPPrefix);
  673.     if not (rvsoFirstOnly in Options) and
  674.        not (rvsoMiddleOnly in Options) then
  675.        SaveLast(Stream);
  676.   except
  677.     Result := False;
  678.   end;
  679. end;
  680. {$ENDIF}
  681. {------------------------------------------------------------------------------}
  682. procedure TCustomRVData.CheckItemClass(ItemNo: Integer; RequiredClass: TCustomRVItemInfoClass);
  683. begin
  684.   if not (Items.Objects[ItemNo] is RequiredClass) then
  685.     raise ERichViewError.Create(errRVTypesMismatch);
  686. end;
  687. {------------------------------------------------------------------------------}
  688. function TCustomRVData.FindControlItemNo(actrl: TControl): Integer;
  689. var i: Integer;
  690. begin
  691.   for i := 0 to Items.Count-1 do
  692.     if TCustomRVItemInfo(Items.Objects[i]).OwnsControl(actrl) then begin
  693.       Result := i;
  694.       exit;
  695.     end;
  696.   Result := -1;
  697. end;
  698. {------------------------------------------------------------------------------}
  699. function TCustomRVData.RemoveCheckpoint(ItemNo: Integer): Boolean;
  700. var OldCP: TRVCPInfo;
  701. begin
  702.   with TCustomRVItemInfo(Items.Objects[ItemNo]) do begin
  703.     OldCP := Checkpoint;
  704.     FreeCheckpoint(Checkpoint, True, True);
  705.   end;
  706.   Result := OldCP<>nil;
  707. end;
  708. {------------------------------------------------------------------------------}
  709. procedure TCustomRVData.SetGrouped(ItemNo: Integer; Grouped: Boolean);
  710. begin
  711.   with GetItem(ItemNo) do
  712.   if Grouped then
  713.     Include(ItemOptions, rvioGroupWithNext)
  714.   else
  715.     Exclude(ItemOptions, rvioGroupWithNext)
  716. end;
  717. {------------------------------------------------------------------------------}
  718. procedure TCustomRVData.SetBreakInfo(ItemNo: Integer; AWidth: Byte;
  719.   AStyle: TRVBreakStyle; AColor: TColor; ATag: Integer);
  720. begin
  721.   CheckItemClass(ItemNo, TRVBreakItemInfo);
  722.   with TRVBreakItemInfo(Items.Objects[ItemNo]) do begin
  723.     Color     := AColor;
  724.     LineWidth := AWidth;
  725.     Style     := AStyle;
  726.   end;
  727.   SetItemTag(ItemNo, ATag);
  728. end;
  729. {------------------------------------------------------------------------------}
  730. procedure TCustomRVData.SetBulletInfo(ItemNo: Integer; const AName: String;
  731.   AImageIndex: Integer; AImageList: TCustomImageList; ATag: Integer);
  732. begin
  733.   CheckItemClass(ItemNo, TRVBulletItemInfo);
  734.   with TRVBulletItemInfo(Items.Objects[ItemNo]) do
  735.     ImageIndex := AImageIndex;
  736.   SetItemTag(ItemNo, ATag);
  737.   Items[ItemNo] := AName;
  738. end;
  739. {------------------------------------------------------------------------------}
  740. function TCustomRVData.SetControlInfo(ItemNo: Integer; const AName: String;
  741.   AVAlign: TRVVAlign; ATag: Integer): Boolean;
  742. begin
  743.   CheckItemClass(ItemNo, TRVControlItemInfo);
  744.   with TRVControlItemInfo(Items.Objects[ItemNo])  do begin
  745.     Result := (VAlign<>AVAlign);
  746.     VAlign := AVAlign;
  747.   end;
  748.   SetItemTag(ItemNo, ATag);
  749.   Items[ItemNo] := AName;
  750. end;
  751. {------------------------------------------------------------------------------}
  752. procedure TCustomRVData.SetHotspotInfo(ItemNo: Integer;
  753.                              const AName: String; AImageIndex, AHotImageIndex: Integer;
  754.                              AImageList: TCustomImageList; ATag: Integer);
  755. begin
  756.   CheckItemClass(ItemNo, TRVHotspotItemInfo);
  757.   with TRVHotspotItemInfo(Items.Objects[ItemNo]) do begin
  758.     ImageIndex    := AImageIndex;
  759.     HotImageIndex := AHotImageIndex;
  760.   end;
  761.   SetItemTag(ItemNo, ATag);
  762.   Items[ItemNo] := AName;
  763. end;
  764. {------------------------------------------------------------------------------}
  765. procedure TCustomRVData.SetCheckpointInfo(ItemNo, ATag: Integer;
  766.                              const AName: String; ARaiseEvent: Boolean);
  767. begin
  768.   with TCustomRVItemInfo(Items.Objects[ItemNo]) do begin
  769.     if Checkpoint=nil then
  770.       InsertCheckpoint(ItemNo, ATag, AName, ARaiseEvent)
  771.     else begin
  772.       if rvoTagsArePChars in Options then
  773.         StrDispose(PChar(Checkpoint.Tag));
  774.       Checkpoint.Tag        := ATag;
  775.       Checkpoint.Name       := AName;
  776.       Checkpoint.RaiseEvent := ARaiseEvent;
  777.     end;
  778.   end;
  779. end;
  780. {------------------------------------------------------------------------------}
  781. procedure TCustomRVData.SetItemTag(ItemNo, ATag: Integer);
  782. begin
  783.   with GetItem(ItemNo) do begin
  784.     if Tag=ATag then exit;
  785.     if rvoTagsArePChars in Options then
  786.       StrDispose(PChar(Tag));
  787.     Tag := ATag;
  788.   end;
  789. end;
  790. {------------------------------------------------------------------------------}
  791. { Sets item's property of integer type.
  792.   ItemNo - index of item. Prop identifies the property. Value - new property
  793.   value.
  794.   Returns true is this item type has this property                             }
  795. function TCustomRVData.SetItemExtraIntProperty(ItemNo: Integer;
  796.   Prop: TRVExtraItemProperty; Value: Integer): Boolean;
  797. begin
  798.   Result := GetItem(ItemNo).SetExtraIntProperty(Prop, Value);
  799.   {$IFNDEF RVDONOTUSEANIMATION}
  800.   if Result and (Prop in [rvepAnimationInterval, rvepImageWidth, rvepImageHeight]) then
  801.     GetItem(ItemNo).UpdateAnimator(Self);
  802.   {$ENDIF}
  803. end;
  804. {------------------------------------------------------------------------------}
  805. { Gets item's property of integer type.
  806.   ItemNo - index of item. Prop identifies the property. Value receives a
  807.   property value.
  808.   Returns true is this item type has this property                             }
  809. function TCustomRVData.GetItemExtraIntProperty(ItemNo: Integer;
  810.   Prop: TRVExtraItemProperty; var Value: Integer): Boolean;
  811. begin
  812.   Result := GetItem(ItemNo).GetExtraIntProperty(Prop, Value);
  813. end;
  814. {------------------------------------------------------------------------------}
  815. { Sets item's property of string type.
  816.   ItemNo - index of item. Prop identifies the property. Value - new property
  817.   value.
  818.   Returns true is this item type has this property                             }
  819. function TCustomRVData.SetItemExtraStrProperty(ItemNo: Integer;
  820.   Prop: TRVExtraItemStrProperty; const Value: String): Boolean;
  821. begin
  822.   Result := GetItem(ItemNo).SetExtraStrProperty(Prop, Value);
  823. end;
  824. {------------------------------------------------------------------------------}
  825. { Gets item's property of string type.
  826.   ItemNo - index of item. Prop identifies the property. Value receives a
  827.   property value.
  828.   Returns true is this item type has this property                             }
  829. function TCustomRVData.GetItemExtraStrProperty(ItemNo: Integer;
  830.   Prop: TRVExtraItemStrProperty; var Value: String): Boolean;
  831. begin
  832.   Result := GetItem(ItemNo).GetExtraStrProperty(Prop, Value);
  833. end;
  834. {------------------------------------------------------------------------------}
  835. function TCustomRVData.SetPictureInfo(ItemNo: Integer; const AName: String;
  836.   Agr: TGraphic; AVAlign: TRVVAlign; ATag: Integer): Boolean;
  837. begin
  838.   CheckItemClass(ItemNo, TRVGraphicItemInfo);
  839.   with TRVGraphicItemInfo(Items.Objects[ItemNo]) do begin
  840.     Result := (Agr.Width<>Image.Width) or
  841.               (Agr.Height<>Image.Height) or
  842.               (VAlign<>AVAlign);
  843.     if Agr<>Image then begin
  844.       Image.Free;
  845.       Image := Agr;
  846.       {$IFNDEF RVDONOTUSEANIMATION}
  847.       UpdateAnimator(Self);
  848.       {$ENDIF}
  849.     end;
  850.     VAlign := AVAlign;
  851.   end;
  852.   SetItemTag(ItemNo, ATag);
  853.   Items[ItemNo] := AName;
  854.   GetItem(ItemNo).UpdatePaletteInfo(GetDoInPaletteMode, True, GetRVPalette,
  855.     GetRVLogPalette);
  856. end;
  857. {------------------------------------------------------------------------------}
  858. function TCustomRVData.GetItemStyle(ItemNo: Integer): Integer;
  859. begin
  860.   Result := GetActualStyle(GetItem(ItemNo));
  861. end;
  862. {------------------------------------------------------------------------------}
  863. function TCustomRVData.GetActualStyle(Item: TCustomRVItemInfo): Integer;
  864. begin
  865.   Result := Item.StyleNo;
  866.   if Result=rvsDefStyle then begin
  867.     if GetRVStyle.ParaStyles[Item.ParaNo].DefStyleNo>=0 then
  868.       Result := GetRVStyle.ParaStyles[Item.ParaNo].DefStyleNo
  869.     else
  870.       Result := 0;
  871.   end;
  872. end;
  873. {------------------------------------------------------------------------------}
  874. function TCustomRVData.GetActualStyle2(StyleNo, ParaNo: Integer): Integer;
  875. begin
  876.   Result := StyleNo;
  877.   if Result=rvsDefStyle then begin
  878.     if GetRVStyle.ParaStyles[ParaNo].DefStyleNo>=0 then
  879.       Result := GetRVStyle.ParaStyles[ParaNo].DefStyleNo
  880.     else
  881.       Result := 0;
  882.   end;
  883. end;
  884. {------------------------------------------------------------------------------}
  885. procedure TCustomRVData.GetBreakInfo(ItemNo: Integer; var AWidth: Byte;
  886.   var AStyle: TRVBreakStyle; var AColor: TColor; var ATag: Integer);
  887. begin
  888.   CheckItemClass(ItemNo, TRVBreakItemInfo);
  889.   with TRVBreakItemInfo(Items.Objects[ItemNo]) do begin
  890.     AWidth := LineWidth;
  891.     AStyle := Style;
  892.     AColor := Color;
  893.     ATag := Tag;
  894.   end;
  895. end;
  896. {------------------------------------------------------------------------------}
  897. procedure TCustomRVData.GetBulletInfo(ItemNo: Integer; var AName: String;
  898.   var AImageIndex: Integer; var AImageList: TCustomImageList; var ATag: Integer);
  899. begin
  900.   CheckItemClass(ItemNo, TRVBulletItemInfo);
  901.   with Items.Objects[ItemNo] as TRVBulletItemInfo do begin
  902.     AImageIndex := ImageIndex;
  903.     AImageList := ImageList;
  904.     ATag := Tag;
  905.   end;
  906.   AName := Items[ItemNo];
  907. end;
  908. {------------------------------------------------------------------------------}
  909. procedure TCustomRVData.GetControlInfo(ItemNo: Integer; var AName: String;
  910.   var Actrl: TControl; var AVAlign: TRVVAlign; var ATag: Integer);
  911. begin
  912.   CheckItemClass(ItemNo, TRVControlItemInfo);
  913.   with TRVControlItemInfo(Items.Objects[ItemNo]) do begin
  914.     Actrl := Control;
  915.     ATag := Tag;
  916.     AVAlign := VAlign;
  917.   end;
  918.   AName := Items[ItemNo];
  919. end;
  920. {------------------------------------------------------------------------------}
  921. procedure TCustomRVData.GetHotspotInfo(ItemNo: Integer; var AName: String;
  922.   var AImageIndex, AHotImageIndex: Integer; var AImageList: TCustomImageList;
  923.   var ATag: Integer);
  924. begin
  925.   CheckItemClass(ItemNo, TRVHotspotItemInfo);
  926.   with TRVHotspotItemInfo(Items.Objects[ItemNo]) do begin
  927.     AImageIndex := ImageIndex;
  928.     AHotImageIndex := HotImageIndex;
  929.     AImageList := ImageList;
  930.     ATag := Tag;
  931.   end;
  932.   AName := Items[ItemNo];
  933. end;
  934. {------------------------------------------------------------------------------}
  935. function TCustomRVData.GetItemTag(ItemNo: Integer): Integer;
  936. begin
  937.   Result := GetItem(ItemNo).Tag;
  938. end;
  939. {------------------------------------------------------------------------------}
  940. procedure TCustomRVData.GetPictureInfo(ItemNo: Integer; var AName: String;
  941.   var Agr: TGraphic; var AVAlign: TRVVAlign; var ATag: Integer);
  942. begin
  943.   CheckItemClass(ItemNo, TRVGraphicItemInfo);
  944.   with Items.Objects[ItemNo] as TRVGraphicItemInfo do begin
  945.     Agr := Image;
  946.     ATag := Tag;
  947.     AVAlign := VAlign;
  948.   end;
  949.   AName := Items[ItemNo];
  950. end;
  951. {------------------------------------------------------------------------------}
  952. procedure TCustomRVData.GetTextInfo(ItemNo: Integer; var AText: String;
  953.   var ATag: Integer);
  954. begin
  955.   if (GetItemStyle(ItemNo)<0) then
  956.     raise ERichViewError.Create(errRVTypesMismatch);
  957.   ATag  := GetItem(ItemNo).Tag;
  958.   AText := Items[ItemNo];
  959. end;
  960. {------------------------------------------------------------------------------}
  961. function TCustomRVData.IsFromNewLine(ItemNo: Integer): Boolean;
  962. begin
  963.   Result := not GetItem(ItemNo).SameAsPrev;
  964. end;
  965. {------------------------------------------------------------------------------}
  966. function TCustomRVData.GetItemPara(ItemNo: Integer): Integer;
  967. begin
  968.   Result := GetItem(ItemNo).ParaNo;
  969. end;
  970. {------------------------------------------------------------------------------}
  971. function TCustomRVData.IsParaStart(ItemNo: Integer): Boolean;
  972. begin
  973.   Result := not GetItem(ItemNo).SameAsPrev and
  974.             not GetItem(ItemNo).BR;
  975. end;
  976. {------------------------------------------------------------------------------}
  977. function TCustomRVData.GetPageBreaksBeforeItems(Index: Integer): Boolean;
  978. begin
  979.   if (Index<0) or (Index>=Items.Count) then
  980.     raise ERichViewError.Create(errRVItemRangeError);
  981.   {$IFNDEF RVDONOTUSELISTS}
  982.   if (Index>0) and (GetItemStyle(Index-1)=rvsListMarker) then
  983.     dec(Index);
  984.   {$ENDIF}
  985.   Result := GetItem(Index).PageBreakBefore;
  986. end;
  987. {------------------------------------------------------------------------------}
  988. procedure TCustomRVData.SetPageBreaksBeforeItems(Index: Integer;
  989.   Value: Boolean);
  990. begin
  991.   if (Index<0) or (Index>=Items.Count) then
  992.     raise ERichViewError.Create(errRVItemRangeError);
  993.   TCustomRVItemInfo(Items.Objects[Index]).PageBreakBefore := Value;
  994. end;
  995. {------------------------------------------------------------------------------}
  996. function TCustomRVData.FindCheckpointByName(
  997.   const Name: String): TCheckpointData;
  998. var cp: TRVCPInfo;
  999. begin
  1000.   Result := nil;
  1001.   cp := FirstCP;
  1002.   while cp<>nil do begin
  1003.     if cp.Name=Name then begin
  1004.       Result := cp;
  1005.       exit;
  1006.     end;
  1007.     cp := cp.Next;
  1008.   end;
  1009.   if (NotAddedCP<>nil) and (NotAddedCP.Name=Name) then
  1010.     Result := NotAddedCP;
  1011. end;
  1012. {------------------------------------------------------------------------------}
  1013. function TCustomRVData.FindCheckpointByTag(Tag: Integer): TCheckpointData;
  1014. var cp: TRVCPInfo;
  1015. begin
  1016.   Result := nil;
  1017.   cp := FirstCP;
  1018.   while cp<>nil do begin
  1019.     if RV_CompareTags(cp.Tag,Tag, rvoTagsArePChars in Options) then begin
  1020.       Result := cp;
  1021.       exit;
  1022.     end;
  1023.     cp := cp.Next;
  1024.   end;
  1025.   if (NotAddedCP<>nil) and RV_CompareTags(NotAddedCP.Tag,Tag,rvoTagsArePChars in Options) then
  1026.     Result := NotAddedCP;
  1027. end;
  1028. {------------------------------------------------------------------------------}
  1029. function TCustomRVData.GetCheckpointByNo(No: Integer): TCheckpointData;
  1030. var i: Integer;
  1031.     cp: TRVCPInfo;
  1032. begin
  1033.   if (no<0) or (no>=CPCount) then begin
  1034.     raise ERichViewError.Create(SysUtils.Format(errRVNoSuchCP,[no]));
  1035.     exit;
  1036.   end;
  1037.   if (no=CPCount-1) and (NotAddedCP<>nil) then
  1038.     Result := NotAddedCP
  1039.   else begin
  1040.     cp := FirstCP;
  1041.     for i := 1 to no do begin
  1042.       if cp = nil then break;
  1043.       cp := cp.Next;
  1044.     end;
  1045.     //Assert(cp<>nil, 'Can''t find checkpoint');
  1046.     Result := cp;
  1047.   end;
  1048. end;
  1049. {------------------------------------------------------------------------------}
  1050. function TCustomRVData.GetFirstCheckpoint: TCheckpointData;
  1051. begin
  1052.   Result := FirstCP;
  1053.   if Result = nil then
  1054.     Result := NotAddedCP;
  1055. end;
  1056. {------------------------------------------------------------------------------}
  1057. function TCustomRVData.GetLastCheckpoint: TCheckpointData;
  1058. begin
  1059.   Result := NotAddedCP;
  1060.   if Result = nil then
  1061.     Result := LastCP;
  1062. end;
  1063. {------------------------------------------------------------------------------}
  1064. function TCustomRVData.GetNextCheckpoint(CheckpointData: TCheckpointData): TCheckpointData;
  1065. begin
  1066.   Result := nil;
  1067.   if CheckpointData=nil then
  1068.     raise ERichViewError.Create(errRVNil);
  1069.   if CheckpointData=NotAddedCP then exit;
  1070.   Result := TRVCPInfo(CheckpointData).Next;
  1071.   if Result = nil then
  1072.     Result := NotAddedCP;
  1073. end;
  1074. {------------------------------------------------------------------------------}
  1075. function TCustomRVData.GetPrevCheckpoint(CheckpointData: TCheckpointData): TCheckpointData;
  1076. begin
  1077.   if CheckpointData=nil then
  1078.     raise ERichViewError.Create(errRVNil);
  1079.   if CheckpointData=NotAddedCP then begin
  1080.     Result := LastCP;
  1081.     exit;
  1082.   end;
  1083.   Result := TRVCPInfo(CheckpointData).Prev;
  1084. end;
  1085. {------------------------------------------------------------------------------}
  1086. function TCustomRVData.GetItemCheckpoint(ItemNo: Integer): TCheckpointData;
  1087. begin
  1088.   Result := TCustomRVItemInfo(Items.Objects[ItemNo]).Checkpoint;
  1089. end;
  1090. {------------------------------------------------------------------------------}
  1091. function TCustomRVData.GetCheckpointItemNo(CheckpointData: TCheckpointData): Integer;
  1092. begin
  1093.   if CheckpointData = nil then
  1094.     raise ERichViewError.Create(errRVNil);
  1095.   if CheckpointData=NotAddedCP then
  1096.     Result := -1
  1097.   else begin
  1098.     Result := Items.IndexOfObject(TRVCPInfo(CheckpointData).ItemInfo);
  1099.     if Result=-1 then
  1100.       raise ERichViewError.Create(errRVNoSuchCP2);
  1101.   end;
  1102. end;
  1103. {------------------------------------------------------------------------------}
  1104. function TCustomRVData.GetCheckpointNo(CheckpointData: TCheckpointData): Integer;
  1105. var cp: TRVCPInfo;
  1106. begin
  1107.   if CheckpointData = nil then
  1108.     raise ERichViewError.Create(errRVNil);
  1109.   cp := FirstCP;
  1110.   Result := 0;
  1111.   while cp<>nil do begin
  1112.     if cp=CheckpointData then exit;
  1113.     cp := cp.Next;
  1114.     inc(Result);
  1115.   end;
  1116.   if CheckpointData=NotAddedCP then exit;
  1117.   if CheckpointData = nil then
  1118.     raise ERichViewError.Create(errRVNoSuchCP2);
  1119. end;
  1120. {------------------------------------------------------------------------------}
  1121. procedure TCustomRVData.GetCheckpointInfo(CheckpointData: TCheckpointData;
  1122.   var Tag: Integer; var Name: String; var RaiseEvent: Boolean);
  1123. begin
  1124.   if CheckpointData = nil then
  1125.     raise ERichViewError.Create(errRVNil);
  1126.   Name       := TRVCPInfo(CheckpointData).Name;
  1127.   Tag        := TRVCPInfo(CheckpointData).Tag;
  1128.   RaiseEvent := TRVCPInfo(CheckpointData).RaiseEvent;
  1129. end;
  1130. {------------------------------------------------------------------------------}
  1131. procedure TCustomRVData.NormalizeParas(StartItemNo: Integer);
  1132. var i,ParaNo: Integer;
  1133. begin
  1134.   if Items.Count=0 then exit;
  1135.   i := StartItemNo;
  1136.   if i>=Items.Count then
  1137.     i := Items.Count-1;
  1138.   while (i>0) and not TCustomRVItemInfo(Items.Objects[i]).CanBeBorderStart do
  1139.     dec(i);
  1140.   ParaNo := TCustomRVItemInfo(Items.Objects[i]).ParaNo;
  1141.   inc(i);
  1142.   while (i<Items.Count) and not TCustomRVItemInfo(Items.Objects[i]).CanBeBorderStart do begin
  1143.     TCustomRVItemInfo(Items.Objects[i]).ParaNo := ParaNo;
  1144.     inc(i);
  1145.   end;
  1146. end;
  1147. {------------------------------------------------------------------------------}
  1148. function TCustomRVData.FindCPBeforeItem(ItemNo: Integer): TRVCPInfo;
  1149. begin
  1150.   UpdateCPItemNo;
  1151.   if (FirstCP=nil) or
  1152.      (FirstCP.ItemNo>=ItemNo) then begin
  1153.     Result := nil; // no CP before
  1154.     exit;
  1155.   end;
  1156.   Result := FirstCP;
  1157.   while Result.Next<>nil do begin
  1158.     if Result.Next.ItemNo>=ItemNo then exit;
  1159.     Result := Result.Next;
  1160.   end;
  1161. end;
  1162. {------------------------------------------------------------------------------}
  1163. procedure TCustomRVData.RVFGetLimits(SaveScope: TRVFSaveScope; var StartItem,
  1164.   EndItem, StartOffs, EndOffs: Integer; var StartPart, EndPart: TRVMultiDrawItemPart);
  1165. begin
  1166.   StartItem := 0;
  1167.   EndItem   := Items.Count-1;
  1168.   if StartItem<Items.Count then begin
  1169.     StartOffs := GetOffsBeforeItem(StartItem);
  1170.     if EndItem>=0 then
  1171.       EndOffs   := GetOffsAfterItem(EndItem);
  1172.   end;
  1173.   StartPart := nil;
  1174.   EndPart   := nil;
  1175. end;
  1176. {------------------------------------------------------------------------------}
  1177. function TCustomRVData.GetRVFOptions: TRVFOptions;
  1178. begin
  1179.   Result := GetRootData.GetRVFOptions;
  1180. end;
  1181. {------------------------------------------------------------------------------}
  1182. function TCustomRVData.GetExtraRTFCode(Area: TRVRTFSaveArea; Obj: TObject; Index1, Index2: Integer; InStyleSheet: Boolean): String;
  1183. begin
  1184.   Result := GetAbsoluteRootData.GetExtraRTFCode(Area, Obj, Index1, Index2, InStyleSheet);
  1185. end;
  1186. {------------------------------------------------------------------------------}
  1187. function TCustomRVData.GetExtraHTMLCode(Area: TRVHTMLSaveArea; CSSVersion: Boolean): String;
  1188. begin
  1189.   Result := GetAbsoluteRootData.GetExtraHTMLCode(Area, CSSVersion);
  1190. end;
  1191. {------------------------------------------------------------------------------}
  1192. function TCustomRVData.IsAssignedOnProgress: Boolean;
  1193. begin
  1194.  Result := GetAbsoluteRootData.IsAssignedOnProgress;
  1195. end;
  1196. {------------------------------------------------------------------------------}
  1197. procedure TCustomRVData.DoProgress(Operation: TRVLongOperation;
  1198.   Stage: TRVProgressStage; PercentDone: Byte);
  1199. begin
  1200.   GetAbsoluteRootData.DoProgress(Operation, Stage, PercentDone);
  1201. end;  
  1202. {------------------------------------------------------------------------------}
  1203. function TCustomRVData.GetParaHTMLCode(RVData: TCustomRVData; ItemNo: Integer;
  1204.   ParaStart, CSSVersion: Boolean): String;
  1205. begin
  1206.   Result := GetAbsoluteRootData.GetParaHTMLCode(RVData, ItemNo, ParaStart,
  1207.     CSSVersion);
  1208. end;
  1209. {------------------------------------------------------------------------------}
  1210. procedure TCustomRVData.SetRVFOptions(const Value: TRVFOptions);
  1211. begin
  1212.   GetRootData.SetRVFOptions(Value);
  1213. end;
  1214. {------------------------------------------------------------------------------}
  1215. function TCustomRVData.GetRVFWarnings: TRVFWarnings;
  1216. begin
  1217.   Result := GetRootData.GetRVFWarnings;
  1218. end;
  1219. {------------------------------------------------------------------------------}
  1220. procedure TCustomRVData.SetRVFWarnings(const Value: TRVFWarnings);
  1221. begin
  1222.   GetRootData.SetRVFWarnings(Value);
  1223. end;
  1224. {------------------------------------------------------------------------------}
  1225. function TCustomRVData.GetRVFSaveScope(SelectionOnly: Boolean):TRVFSaveScope;
  1226. begin
  1227.   if SelectionOnly then
  1228.     Result := rvfss_Selection
  1229.   else
  1230.     Result := rvfss_Full;
  1231. end;
  1232. {------------------------------------------------------------------------------}
  1233. {$IFNDEF RVDONOTUSERVF}
  1234. {------------------------------------------------------------------------------}
  1235. type
  1236.   TRVFHeader = record
  1237.     StyleNo,ParaNo, ReadType, ExtraValue: Integer;
  1238.     DataCount, DataRead: Integer;
  1239.     Item: TCustomRVItemInfo;
  1240.     ClassName: String;
  1241.     Name: String;
  1242.     Version, SubVersion: Integer;
  1243.     RaiseEvent: Integer;
  1244.     PersistentCheckpoint: Integer;
  1245.     CheckPointTag: Integer;
  1246.   end;
  1247.   {------------------------------------------------------------------------------}
  1248. procedure TCustomRVData.DataReader(Stream: TStream);
  1249. var Size: Integer;
  1250.     MemStream: TMemoryStream;
  1251.     Color: TColor;
  1252.     Back: TRVBackground;
  1253. begin
  1254.   MemStream := TMemoryStream.Create;
  1255.   Include(State, rvstLoadingAsPartOfItem);
  1256.   try
  1257.     Stream.ReadBuffer(Size, SizeOf(Size));
  1258.     MemStream.SetSize(Size);
  1259.     Stream.ReadBuffer(MemStream.Memory^, Size);
  1260.     Back := nil;
  1261.     LoadRVFFromStream(MemStream, Color, Back, nil);
  1262.   finally
  1263.     MemStream.Free;
  1264.     Exclude(State, rvstLoadingAsPartOfItem);
  1265.   end;
  1266. end;
  1267. {------------------------------------------------------------------------------}
  1268. procedure TCustomRVData.DataWriter(Stream: TStream);
  1269. var StartPos,Size: Integer;
  1270.     sb: Boolean;
  1271. begin
  1272.   Size := 0;
  1273.   StartPos := Stream.Position;
  1274.   Stream.WriteBuffer(Size, SizeOf(Size));
  1275.   sb := rvfoSaveBack in RVFOptions;
  1276.   RVFOptions := RVFOptions - [rvfoSaveBack];
  1277.   GetRVData.SaveRVFToStream(Stream, False, clNone, nil, nil);
  1278.   if sb then
  1279.     RVFOptions := RVFOptions + [rvfoSaveBack];
  1280.   Size := Stream.Position-SizeOf(Size)-StartPos;
  1281.   Stream.Position := StartPos;
  1282.   Stream.WriteBuffer(Size, SizeOf(Size));
  1283.   Stream.Position := StartPos+SizeOf(Size)+Size;
  1284. end;
  1285. {------------------------------------------------------------------------------}
  1286. function InsertRVFHeaderData(RVData: TCustomRVData; const Caption: String;
  1287.   var Header: TRVFHeader; var PrevCP, CurCP: TRVCPInfo;
  1288.   var Index, InsertPoint: Integer; var FirstTime: Boolean; AParaNo: Integer;
  1289.   AppendMode, EditFlag: Boolean; var NonFirstItemsAdded: Integer;
  1290.   var FullReformat: Boolean; TextStylesMapping,
  1291.   ListStylesMapping: TRVIntegerList): Boolean;
  1292. var item: TCustomRVItemInfo;
  1293.     CP: TRVCPInfo;
  1294.     Caption2: String;
  1295.     NewListNo: Integer;
  1296.     {$IFNDEF RVDONOTUSELISTS}
  1297.     OldListNo: Integer;
  1298.     {$ENDIF}
  1299. begin
  1300.   Result := True;
  1301.   {$IFNDEF RVDONOTUSELISTS}
  1302.   OldListNo := -1;
  1303.   {$ENDIF}
  1304.   if (Header.StyleNo=rvsBack) or
  1305.      (Header.StyleNo=rvsVersionInfo) then exit;
  1306.   if Header.Item<>nil then begin
  1307.     if Header.StyleNo>=0 then begin
  1308.       if EditFlag and
  1309.          (rvprRVFInsertProtect in RVData.GetRVStyle.TextStyles[RVData.GetActualStyle(Header.Item)].Protection) then
  1310.         exit;
  1311.       item := RichViewTextItemClass.Create(RVData);
  1312.       item.BeforeLoading(rvlfRVF);
  1313.       item.Assign(Header.Item);
  1314.       item.Tag := RV_CopyTag(Header.Item.Tag, rvoTagsArePChars in RVData.Options);
  1315.       end
  1316.     else begin
  1317.       item := Header.Item;
  1318.       Header.Item := nil;
  1319.       if (item.AssociatedTextStyleNo>=0) and not RichViewDoNotCheckRVFStyleRefs then begin
  1320.         if TextStylesMapping<>nil then begin
  1321.           if item.AssociatedTextStyleNo>=TextStylesMapping.Count then begin
  1322.             RVData.RVFWarnings := RVData.RVFWarnings + [rvfwConvUnknownStyles];
  1323.             if rvfoConvUnknownStylesToZero in RVData.RVFOptions then
  1324.               item.AssociatedTextStyleNo := 0
  1325.             else begin
  1326.               item.Free;
  1327.               exit;
  1328.             end;
  1329.           end;
  1330.           item.AssociatedTextStyleNo := TextStylesMapping[item.AssociatedTextStyleNo];
  1331.         end;
  1332.         if item.AssociatedTextStyleNo>=RVData.GetRVStyle.TextStyles.Count then begin
  1333.           RVData.RVFWarnings := RVData.RVFWarnings + [rvfwConvUnknownStyles];
  1334.           if rvfoConvUnknownStylesToZero in RVData.RVFOptions then
  1335.             Header.Item.StyleNo := 0
  1336.           else begin
  1337.             item.Free;
  1338.             exit;
  1339.           end;
  1340.         end;
  1341.       end;
  1342.       if not item.GetBoolValue(rvbpValid) then begin
  1343.         item.Free;
  1344.         exit;
  1345.       end;
  1346.     end;
  1347.     if (Header.ParaNo=-1) and (RVData.Items.Count<>0) and (InsertPoint>0) and
  1348.        not RVData.GetItem(InsertPoint-1).GetBoolValue(rvbpFullWidth) then begin
  1349.       item.SameAsPrev := True;
  1350.       item.ParaNo := RVData.GetItem(InsertPoint-1).ParaNo;
  1351.       end
  1352.     else begin
  1353.       item.SameAsPrev := False;
  1354.       if (Header.ParaNo<>-1) then
  1355.         item.ParaNo := Header.ParaNo
  1356.       else
  1357.         item.ParaNo := 0;
  1358.     end;
  1359.     item.UpdatePaletteInfo(RVData.GetDoInPaletteMode, False,
  1360.       RVData.GetRVPalette, RVData.GetRVLogPalette);
  1361.     if CurCP<> nil then begin
  1362.       if CurCP=RVData.NotAddedCP then begin
  1363.         dec(RVData.CPCount);
  1364.         RVData.NotAddedCP := nil;
  1365.       end;
  1366.       CP := CurCP;
  1367.       if not EditFlag then begin
  1368.         inc(RVData.CPCount);
  1369.         RVData.SetCP(item, PrevCP, CurCP)
  1370.         end
  1371.       else begin
  1372.         item.Checkpoint := CurCP;
  1373.         CurCP.ItemInfo := item;
  1374.         CurCP := nil;
  1375.       end;
  1376.       PrevCP := CP;
  1377.     end;
  1378.     Caption2 := Caption;
  1379.     {$IFNDEF RVDONOTUSEUNICODE}
  1380.     if (rvioUnicode in item.ItemOptions) and (item.StyleNo>=0) and
  1381.        (Header.ReadType=3) then
  1382.       Caption2 := RVDecodeString(Caption);    
  1383.     if (rvioUnicode in item.ItemOptions) and
  1384.        (item.StyleNo>=0) and
  1385.        (RVData.GetRVStyle<>nil) and
  1386.        not RVData.GetRVStyle.TextStyles[RVData.GetActualStyle(item)].Unicode then begin
  1387.       Caption2 := RVU_UnicodeToAnsi(RVData.GetStyleCodePage(RVData.GetActualStyle(item)), Caption);
  1388.       Exclude(item.ItemOptions, rvioUnicode);
  1389.       RVData.RVFWarnings := RVData.RVFWarnings + [rvfwConvFromUnicode];
  1390.     end;
  1391.     if not (rvioUnicode in item.ItemOptions) and
  1392.        (item.StyleNo>=0) and
  1393.        (RVData.GetRVStyle<>nil) and
  1394.        RVData.GetRVStyle.TextStyles[RVData.GetActualStyle(item)].Unicode then begin
  1395.       Caption2 := RVU_AnsiToUnicode(RVData.GetStyleCodePage(RVData.GetActualStyle(item)), Caption);
  1396.       Include(item.ItemOptions, rvioUnicode);
  1397.       RVData.RVFWarnings := RVData.RVFWarnings + [rvfwConvToUnicode];
  1398.     end;
  1399.     {$ENDIF}
  1400.     {$IFNDEF RVDONOTUSELISTS}
  1401.     if (item.StyleNo=rvsListMarker) and not RichViewDoNotCheckRVFStyleRefs then begin
  1402.       if (ListStylesMapping<>nil) and (TRVMarkerItemInfo(item).ListNo>=0) then begin
  1403.         if TRVMarkerItemInfo(item).ListNo>=ListStylesMapping.Count then begin
  1404.           RVData.RVFWarnings := RVData.RVFWarnings + [rvfwConvUnknownStyles];
  1405.           TRVMarkerItemInfo(item).ListNo := 0;
  1406.           end
  1407.         else begin
  1408.           OldListNo := TRVMarkerItemInfo(item).ListNo;
  1409.           TRVMarkerItemInfo(item).ListNo := ListStylesMapping[OldListNo];
  1410.         end;
  1411.       end;
  1412.       if TRVMarkerItemInfo(item).ListNo>=RVData.GetRVStyle.ListStyles.Count then begin
  1413.         RVData.RVFWarnings := RVData.RVFWarnings + [rvfwConvUnknownStyles];
  1414.         TRVMarkerItemInfo(item).ListNo := 0;
  1415.         if TRVMarkerItemInfo(item).ListNo>=RVData.GetRVStyle.ListStyles.Count then
  1416.           TRVMarkerItemInfo(item).ListNo := -1;
  1417.       end;
  1418.     end;
  1419.     {$ENDIF}
  1420.     if FirstTime then begin
  1421.       if AppendMode then begin
  1422.         if AParaNo=-1 then begin
  1423.           item.SameAsPrev := (InsertPoint>0) and
  1424.             not RVData.GetItem(InsertPoint-1).GetBoolValue(rvbpFullWidth);
  1425.           if item.SameAsPrev then
  1426.             item.ParaNo := RVData.GetItem(InsertPoint-1).ParaNo
  1427.           else
  1428.             item.ParaNo := 0;
  1429.           end
  1430.         else begin
  1431.           item.SameAsPrev := False;
  1432.           item.ParaNo := AParaNo;
  1433.         end;
  1434.       end;
  1435.       if not RVData.InsertFirstRVFItem(InsertPoint, Caption2, item, EditFlag,
  1436.         FullReformat, NewListNo) then begin
  1437.         Result := False;
  1438.         exit;
  1439.       end;
  1440.       if item<>nil then begin
  1441.         inc(InsertPoint);
  1442.         Index := InsertPoint-1;
  1443.         FirstTime := False;
  1444.       end;
  1445.       {$IFNDEF RVDONOTUSELISTS}
  1446.       if (OldListNo>=0) and (NewListNo>=0) then
  1447.         ListStylesMapping[OldListNo] := NewListNo;
  1448.       {$ENDIF}
  1449.       end
  1450.     else begin
  1451.       item.Inserting(RVData, Caption2, False);
  1452.       RVData.Items.InsertObject(InsertPoint, Caption2, item);
  1453.       item.Inserted(RVData, InsertPoint);
  1454.       {$IFNDEF RVDONOTUSELISTS}
  1455.       RVData.AddMarkerInList(InsertPoint);
  1456.       {$ENDIF}
  1457.       inc(InsertPoint);
  1458.       inc(NonFirstItemsAdded);
  1459.     end;
  1460.     if item<>nil then begin
  1461.       RVData.ControlAction(rvcaAfterRVFLoad, InsertPoint-1, item);
  1462.       if not (rvstLoadingAsPartOfItem in RVData.State) then
  1463.         item.AfterLoading(rvlfRVF);
  1464.       end
  1465.     else
  1466.       RVData.FreeCheckpoint(CurCP, False, False);
  1467.     end
  1468.   else begin
  1469.     // unknown item type
  1470.     if CurCP<> nil then begin
  1471.        if not EditFlag then begin
  1472.          inc(RVData.CPCount);
  1473.          item := RichViewTextItemClass.Create(RVData);
  1474.          RVData.SetCP(item, PrevCP, CurCP);
  1475.          RVData.InternalFreeItem(item,False);
  1476.          end
  1477.        else begin
  1478.          RVData.FreeCheckpoint(CurCP, False, False);
  1479.        end;
  1480.     end;
  1481.   end;
  1482. end;
  1483. {------------------------------------------------------------------------------}
  1484. function RVFReadHeader(RVData: TCustomRVData; const CurrentLine: String;
  1485.   var Header: TRVFHeader; AParaNo: Integer; var Color: TColor;
  1486.   Background: TRVBackground;
  1487.   TextStylesMapping, ParaStylesMapping: TRVIntegerList): Boolean;
  1488. var P: PChar;
  1489.     ItemOptions: Integer;
  1490.     ABackgroundStyle, AColor, Tag: Integer;
  1491. begin
  1492.   P := PChar(CurrentLine);
  1493.   Result := False;
  1494.   Header.DataRead := 0;
  1495.   if not RVFReadTextStyle(RVData.GetRVStyle,P,Header.StyleNo) then
  1496.     exit; {error}
  1497.   if Header.StyleNo = rvsVersionInfo then begin
  1498.     Header.DataCount := 0;
  1499.     Result := (RVFReadInteger(P,Header.Version) and
  1500.                RVFReadInteger(P,Header.SubVersion));
  1501.     exit;
  1502.   end;
  1503.   if not (RVFReadInteger(P,Header.DataCount) and
  1504.           RVFReadParaStyle(RVData.GetRVStyle,P,Header.ParaNo)) then
  1505.     exit; {error}
  1506.   if (Header.StyleNo<>rvsBack) and (Header.StyleNo<>rvsCheckpoint) and
  1507.      (Header.StyleNo<>rvsDocProperty) then
  1508.     Header.Item := CreateRichViewItem(Header.StyleNo, RVData);
  1509.   if Header.Item<>nil then
  1510.     Header.Item.BeforeLoading(rvlfRVF);
  1511.   if (Header.Version>=1)and(Header.SubVersion>=2) then begin
  1512.     if not RVFReadInteger(P,ItemOptions) then
  1513.       exit; {error}
  1514.     if Header.Item<>nil then
  1515.       Header.Item.ItemOptions := TRVItemOptions(Byte(ItemOptions));
  1516.   end;
  1517.   if not (RVFReadInteger(P,Header.ReadType) and
  1518.      RVFReadTag(P, rvoTagsArePChars in RVData.Options,
  1519.      (Header.Version>1) or (Header.SubVersion>2), Tag)) then
  1520.     exit; {error}
  1521.   if Header.StyleNo = rvsDocProperty then begin
  1522.     if not RVFReadInteger(P,Header.ExtraValue) then
  1523.       exit; {error}
  1524.   end;
  1525.   if Header.StyleNo=rvsCheckpoint then
  1526.     Header.CheckpointTag := Tag
  1527.   else if Header.Item<>nil then
  1528.     Header.Item.Tag := Tag;
  1529.   if (Header.Item<>nil) and (Header.StyleNo>=0) and
  1530.      not RichViewDoNotCheckRVFStyleRefs then begin
  1531.     if (TextStylesMapping<>nil) and (Header.StyleNo<>rvsDefStyle) then begin
  1532.       if Header.StyleNo>=TextStylesMapping.Count then begin
  1533.         RVData.RVFWarnings := RVData.RVFWarnings + [rvfwConvUnknownStyles];
  1534.         if rvfoConvUnknownStylesToZero in RVData.RVFOptions then
  1535.           Header.StyleNo := 0
  1536.         else
  1537.           exit;
  1538.         end
  1539.       else
  1540.         Header.StyleNo := TextStylesMapping[Header.StyleNo];
  1541.     end;
  1542.     Header.Item.StyleNo := Header.StyleNo;
  1543.     if (Header.StyleNo<>rvsDefStyle) and
  1544.        (Header.StyleNo>=RVData.GetRVStyle.TextStyles.Count) then begin
  1545.       RVData.RVFWarnings := RVData.RVFWarnings + [rvfwConvUnknownStyles];
  1546.       if rvfoConvUnknownStylesToZero in RVData.RVFOptions then
  1547.         Header.Item.StyleNo := 0
  1548.       else
  1549.         exit;
  1550.     end;
  1551.   end;
  1552.   if (Header.Item<>nil) and (Header.ParaNo>=0) and
  1553.       not RichViewDoNotCheckRVFStyleRefs then begin
  1554.     if ParaStylesMapping<>nil then begin
  1555.       if Header.ParaNo>=ParaStylesMapping.Count then begin
  1556.         RVData.RVFWarnings := RVData.RVFWarnings + [rvfwConvUnknownStyles];
  1557.         exit;
  1558.       end;
  1559.       Header.ParaNo := ParaStylesMapping[Header.ParaNo];
  1560.     end;
  1561.     if Header.ParaNo>=RVData.GetRVStyle.ParaStyles.Count then begin
  1562.       RVData.RVFWarnings := RVData.RVFWarnings + [rvfwConvUnknownStyles];
  1563.       if rvfoConvUnknownStylesToZero in RVData.RVFOptions then
  1564.         Header.ParaNo := 0
  1565.       else
  1566.         exit;
  1567.     end;
  1568.   end;
  1569.   case Header.StyleNo of
  1570.   {*}rvsCheckpoint:
  1571.     begin
  1572.       if not (P^ in [#0, #10, #13]) then begin
  1573.         if not RVFReadInteger(P,Header.RaiseEvent) then
  1574.           exit;
  1575.         end
  1576.       else
  1577.         Header.RaiseEvent := 0;
  1578.       if not (P^ in [#0, #10, #13]) then begin
  1579.         if not RVFReadInteger(P,Header.PersistentCheckpoint) then
  1580.           exit;
  1581.         end
  1582.       else
  1583.         Header.PersistentCheckpoint := 0;
  1584.     end;
  1585.   {*}rvsBack:
  1586.     begin
  1587.       if not (RVFReadInteger(P, ABackgroundStyle) and
  1588.          RVFReadInteger(P, AColor)) then
  1589.         exit;
  1590.       if rvfoLoadBack in RVData.RVFOptions then begin
  1591.         Color := AColor;
  1592.         if Background<>nil then begin
  1593.           Background.Style := TBackgroundStyle(ABackgroundStyle);
  1594.           Background.Bitmap.Handle := 0;
  1595.         end;
  1596.       end;
  1597.     end;
  1598.   {*}else
  1599.     begin
  1600.       if Header.Item = nil then begin
  1601.         Result := True;
  1602.         exit;
  1603.       end;
  1604.       if not Header.Item.ReadRVFHeader(P, RVData) then
  1605.         exit;
  1606.     end;
  1607.   end;
  1608.   Result := True;
  1609. end;
  1610. {------------------------------------------------------------------------------}
  1611. procedure TCustomRVData.DoOnStyleReaderError(Reader: TReader;
  1612.   const Message: string; var Handled: Boolean);
  1613. begin
  1614.   RVFWarnings := RVFWarnings + [rvfwUnknownStyleProperties];
  1615.   Handled := True;
  1616. end;
  1617. {------------------------------------------------------------------------------}
  1618. function TCustomRVData.InsertRVFFromStream_(Stream: TStream; var Index: Integer;
  1619.   AParaNo: Integer; AllowReplaceStyles, AppendMode, EditFlag: Boolean;
  1620.   var Color: TColor; Background: TRVBackground; Layout: TRVLayoutInfo;
  1621.   var NonFirstItemsAdded: Integer; var Protect, FullReformat: Boolean):Boolean;
  1622. var BufferString, CurrentLine: String;
  1623.     Size: Integer;
  1624.     P, EndP: PChar;
  1625.     ReadState:TRVFReadState;
  1626.     ReadMode: TRVFReadMode;
  1627.     Header: TRVFHeader;
  1628.     FirstInsert: Boolean;
  1629.     PrevCP, CurCP: TRVCPInfo;
  1630.     PTextStylesMapping: PRVIntegerList;
  1631.     PParaStylesMapping: PRVIntegerList;
  1632.     PListStylesMapping: PRVIntegerList;    
  1633.     InsertPoint: Integer;
  1634.   {.......................................................}
  1635.    procedure FreeCheckpointTag; // in-out: Header
  1636.    begin
  1637.      if rvoTagsArePChars in Options then StrDispose(PChar(Header.CheckpointTag));
  1638.      Header.CheckpointTag := 0;
  1639.    end;
  1640.   {.......................................................}
  1641.   {$IFDEF RICHVIEWCBDEF3}
  1642.   procedure ReadStyles(Styles: TCustomRVInfos; StylesReadMode: TRVFReaderStyleMode);
  1643.   var Reader: TReader;
  1644.       TmpStream: TMemoryStream;
  1645.       Val: TValueType;
  1646.   begin
  1647.     TmpStream := TMemoryStream.Create;
  1648.     try
  1649.       case Header.ReadType of
  1650.         0: // text
  1651.           RVFTextString2Stream(CurrentLine, TmpStream);
  1652.         2: // binary
  1653.           TmpStream.WriteBuffer(PChar(CurrentLine)^, Length(CurrentLine));
  1654.       end;
  1655.       if (TmpStream.Size>0) and (StylesReadMode<>rvf_sIgnore) then begin
  1656.         TmpStream.Position := 0;
  1657.         TmpStream.ReadBuffer(Val, sizeof(Val));
  1658.         if Val<>vaCollection then
  1659.           abort;
  1660.         Reader := TReader.Create(TmpStream, 4096);
  1661.         try
  1662.           Reader.OnError := DoOnStyleReaderError;
  1663.           if Styles is TRVListInfos then
  1664.             TRVListInfos(Styles).FRVData := Self;
  1665.           try
  1666.             Reader.ReadCollection(Styles);
  1667.           finally
  1668.             if Styles is TRVListInfos then
  1669.               TRVListInfos(Styles).FRVData := nil;
  1670.           end;
  1671.         finally
  1672.           Reader.Free;
  1673.         end;
  1674.       end;
  1675.     finally
  1676.       TmpStream.Free;
  1677.     end;
  1678.   end;
  1679.   {.......................................................}
  1680.   procedure MergeStyles(Base, Loaded: TCustomRVInfos;
  1681.                         var Mapping: TRVIntegerList;
  1682.                         StylesReadMode: TRVFReaderStyleMode);
  1683.   begin
  1684.     if (Loaded.Count=0) or (StylesReadMode = rvf_sIgnore) or (Mapping<>nil) then
  1685.       exit;
  1686.     if AllowReplaceStyles then begin
  1687.       Base.Assign(Loaded);
  1688.       exit;
  1689.     end;
  1690.     Mapping := TRVIntegerList.Create;
  1691.     case StylesReadMode of
  1692.       rvf_sInsertMap:
  1693.         Base.MergeWith(Loaded, rvs_merge_Map, Mapping, PTextStylesMapping^);
  1694.       rvf_sInsertMerge:
  1695.         Base.MergeWith(Loaded, rvs_merge_SmartMerge, Mapping, PTextStylesMapping^);
  1696.     end;
  1697.   end;
  1698.   {.......................................................}
  1699.    procedure ReadDocProperty;
  1700.    var Styles, BaseStyles: TCustomRVInfos;
  1701.        StylesReadMode: TRVFReaderStyleMode;
  1702.        PMapping: PRVIntegerList;
  1703.        {$IFNDEF RVDONOTUSELISTS}
  1704.        i, ListNo: Integer;
  1705.        {$ENDIF}
  1706.    begin
  1707.      case Header.DataRead of
  1708.        0:
  1709.          begin
  1710.            if (Header.ExtraValue=RVF_DOCPROP_DOCPROPLIST) and AllowReplaceStyles and
  1711.               (rvfoLoadDocProperties in RVFOptions) and (GetDocProperties<>nil) then
  1712.              GetDocProperties.Add(RVFDecodeLineBreaks(CurrentLine));
  1713.            // Header.ExtraValue<>RVF_DOCPROP_DOCPROPLIST then ignoring this line (should be name of TRVStyle)
  1714.            if Header.ReadType=2 then ReadMode := rmBeforeBinary;
  1715.          end;
  1716.        1:
  1717.          begin
  1718.            case Header.ExtraValue of
  1719.              RVF_DOCPROP_TEXTSTYLES:
  1720.                begin
  1721.                  Styles := TFontInfos.Create(GetRVStyle.GetTextStyleClass, GetRVStyle);
  1722.                  StylesReadMode := GetRVFTextStylesReadMode;
  1723.                  BaseStyles := GetRVStyle.TextStyles;
  1724.                  PMapping := PTextStylesMapping;
  1725.                end;
  1726.              RVF_DOCPROP_PARASTYLES:
  1727.                begin
  1728.                  Styles := TParaInfos.Create(GetRVStyle.GetParaStyleClass, GetRVStyle);
  1729.                  StylesReadMode := GetRVFParaStylesReadMode;
  1730.                  BaseStyles := GetRVStyle.ParaStyles;
  1731.                  PMapping := PParaStylesMapping;
  1732.                end;
  1733.              RVF_DOCPROP_LISTSTYLES:
  1734.                begin
  1735.                  Styles := TRVListInfos.Create(GetRVStyle.GetListStyleClass, GetRVStyle);
  1736.                  StylesReadMode := GetRVFParaStylesReadMode;
  1737.                  BaseStyles := GetRVStyle.ListStyles;
  1738.                  PMapping := PListStylesMapping;
  1739.                end;
  1740.              RVF_DOCPROP_LAYOUT:
  1741.                begin
  1742.                  if (Layout=nil) or (not AllowReplaceStyles) or
  1743.                     not (rvfoLoadLayout in RVFOptions) then
  1744.                    exit;
  1745.                  case Header.ReadType of
  1746.                    0: // text
  1747.                       Layout.LoadText(CurrentLine);
  1748.                    2: // binary
  1749.                       Layout.LoadBinary(CurrentLine);
  1750.                  end;
  1751.                  if (Layout.FirstParaAborted<>0) and (Layout.FirstMarkerListNo>=0) and
  1752.                     (PListStylesMapping^<>nil) then
  1753.                    Layout.FirstMarkerListNo := PListStylesMapping^[Layout.FirstMarkerListNo];
  1754.                  exit;
  1755.                end;
  1756.              RVF_DOCPROP_PREVMARKERS:
  1757.                begin
  1758.                  {$IFNDEF RVDONOTUSELISTS}
  1759.                  if (GetPrevMarkers=nil) or (not AllowReplaceStyles) or
  1760.                    not (rvfoLoadLayout in RVFOptions) then
  1761.                    exit;
  1762.                  case Header.ReadType of
  1763.                    0: // text
  1764.                       GetPrevMarkers.LoadText(CurrentLine, Self);
  1765.                    2: // binary
  1766.                       GetPrevMarkers.LoadBinary(CurrentLine, Self);
  1767.                  end;
  1768.                  if (PListStylesMapping^<>nil) then
  1769.                    for i := 0 to GetPrevMarkers.Count-1 do begin
  1770.                      ListNo := TRVMarkerItemInfo(GetPrevMarkers.Items[i]).ListNo;
  1771.                      if ListNo>=0 then
  1772.                      TRVMarkerItemInfo(GetPrevMarkers.Items[i]).ListNo :=
  1773.                        PListStylesMapping^[ListNo];
  1774.                    end;
  1775.                  {$ENDIF}
  1776.                  exit;
  1777.                end;
  1778.              RVF_DOCPROP_DOCPROPLIST:
  1779.                begin
  1780.                  if AllowReplaceStyles and (rvfoLoadDocProperties in RVFOptions) and
  1781.                    (GetDocProperties<>nil) then
  1782.                    GetDocProperties.Add(RVFDecodeLineBreaks(CurrentLine));
  1783.                  exit;
  1784.                end;
  1785.              else
  1786.                exit;
  1787.            end;
  1788.            try
  1789.              ReadStyles(Styles, StylesReadMode);
  1790.              MergeStyles(BaseStyles, Styles, PMapping^, StylesReadMode);
  1791.            finally
  1792.              Styles.Free;
  1793.            end;
  1794.          end;
  1795.        else
  1796.          if (Header.ExtraValue=RVF_DOCPROP_DOCPROPLIST) and AllowReplaceStyles and
  1797.             (rvfoLoadDocProperties in RVFOptions) and (GetDocProperties<>nil) then
  1798.            GetDocProperties.Add(RVFDecodeLineBreaks(CurrentLine));
  1799.      end;
  1800.    end;
  1801.   {$ENDIF}
  1802.   {.......................................................}
  1803.                              // in    : CurrentLine
  1804.    procedure ReadBackground; // in-out: Header
  1805.                              // out   : ReadMode, ReadState
  1806.    var bmp : TBitmap;
  1807.    begin
  1808.      case Header.DataRead of
  1809.        0:
  1810.          begin
  1811.            // ignoring this line (should be TBitmap)
  1812.            if Header.ReadType=2 then ReadMode := rmBeforeBinary;
  1813.          end;
  1814.        1:
  1815.          begin
  1816.            if rvfoLoadBack in RVFOptions then begin
  1817.              if Background<>nil then begin
  1818.                if Header.ReadType=2 then
  1819.                  RVFLoadPictureBinary(CurrentLine, Background.Bitmap)
  1820.                else
  1821.                  if not RVFLoadPicture(CurrentLine, Background.Bitmap) then abort; {error}
  1822.                end
  1823.              else begin
  1824.                bmp := TBitmap.Create;
  1825.                if Header.ReadType=2 then
  1826.                  RVFLoadPictureBinary(CurrentLine, bmp)
  1827.                else
  1828.                  if not RVFLoadPicture(CurrentLine, bmp) then abort; {error}
  1829.                bmp.Free;
  1830.              end;
  1831.            end;
  1832.            ReadState := rstSkip;
  1833.          end;
  1834.      end;
  1835.    end;
  1836.   {.......................................................}
  1837.                                // in: ReadMode
  1838.                                // in-out: P
  1839.     procedure ReadCurrentLine; // out: CurrentLine
  1840.     var Start: PChar;
  1841.         Size: Integer;
  1842.     begin
  1843.       Start := P;
  1844.       case ReadMode of
  1845.         rmBinary:
  1846.           begin
  1847.             Move(P^,Size, SizeOf(Size));
  1848.             inc(Start, SizeOf(Size));
  1849.             inc(P,     SizeOf(Size)+Size);
  1850.           end;
  1851.         rmUnicode:
  1852.           begin
  1853.             while (PWord(P)^<>UNI_ParagraphSeparator) and
  1854.                   (PWord(P)^<>0) and
  1855.                   (P<EndP) do Inc(P,2);
  1856.           end;
  1857.         else
  1858.           begin
  1859.             while not (P^ in [#0, #10, #13]) do Inc(P);
  1860.           end;
  1861.       end;
  1862.       SetString(CurrentLine, Start, P - Start);
  1863.     end;
  1864.   {.......................................................}
  1865.    procedure SkipCurrentLineTail; // in-out: P, ReadMode
  1866.    begin
  1867.      case ReadMode of
  1868.        rmText:
  1869.          begin
  1870.            if P^ = #13 then Inc(P);
  1871.            if P^ = #10 then Inc(P);
  1872.          end;
  1873.        rmBeforeUnicode:
  1874.          begin
  1875.            if P^ = #13 then Inc(P) else abort; {error}
  1876.            if P^ = #10 then Inc(P) else abort; {error}
  1877.            ReadMode := rmUnicode;
  1878.          end;
  1879.        rmUnicode:
  1880.          begin
  1881.            if PWord(P)^=UNI_ParagraphSeparator then
  1882.              Inc(P, 2);
  1883.          end;
  1884.        rmAfterUnicode:
  1885.          begin
  1886.            if PWord(P)^=UNI_ParagraphSeparator then
  1887.              Inc(P, 2);
  1888.            ReadMode := rmText;
  1889.          end;
  1890.        rmBeforeBinary:
  1891.          begin
  1892.            if P^ = #13 then Inc(P) else abort; {error}
  1893.            if P^ = #10 then Inc(P) else abort; {error}
  1894.            ReadMode := rmBinary;
  1895.          end;
  1896.        rmBinary:
  1897.          begin
  1898.            ReadMode := rmText;
  1899.          end;
  1900.      end;
  1901.    end;
  1902.   {.......................................................}
  1903.   var StartIndex: Integer;
  1904. begin
  1905.   NonFirstItemsAdded := 0;
  1906.   Result           := True;
  1907.   Protect          := True;
  1908.   FirstInsert      := True;
  1909.   StartIndex       := Index;
  1910.   InsertPoint      := Index;
  1911.   if Index>Items.Count then
  1912.     Index := Items.Count;
  1913.   if Index=Items.Count then begin
  1914.     PrevCP := LastCP;
  1915.     if EditFlag then
  1916.       CurCP := nil
  1917.     else
  1918.       CurCP  := NotAddedCP;
  1919.     end
  1920.   else begin
  1921.     PrevCP := FindCPBeforeItem(Index);
  1922.     CurCP := nil;
  1923.   end;
  1924.   RVFWarnings := [];
  1925.   if AllowReplaceStyles and (GetDocProperties<>nil) then
  1926.     GetDocProperties.Clear;
  1927.   FillChar(Header,sizeof(Header),0);
  1928.   Header.Version := 1;
  1929.   Header.SubVersion := 0;
  1930.   InitStyleMappings(PTextStylesMapping, PParaStylesMapping, PListStylesMapping);
  1931.   try
  1932.     Size := Stream.Size - Stream.Position;
  1933.     SetString(BufferString, nil, Size);
  1934.     Stream.Read(Pointer(BufferString)^, Size);
  1935.     P := Pointer(BufferString);
  1936.     EndP := PChar(BufferString)+Size;
  1937.     ReadState := rstHeader;
  1938.     ReadMode := rmText;
  1939.     if P <> nil then
  1940.       while P < EndP do begin
  1941.         ReadCurrentLine;
  1942.         case ReadState of
  1943.           rstHeader:
  1944.             begin
  1945.               if not RVFReadHeader(Self, CurrentLine, Header, AParaNo,
  1946.                 Color, Background, PTextStylesMapping^, PParaStylesMapping^) then
  1947.                 abort; {error}
  1948.               if (Header.DataCount=0) then begin
  1949.                 if not InsertRVFHeaderData(Self, '', Header, PrevCP, CurCP,
  1950.                   Index, InsertPoint, FirstInsert, AParaNo, AppendMode, EditFlag,
  1951.                   NonFirstItemsAdded, FullReformat, PTextStylesMapping^,
  1952.                   PListStylesMapping^) then
  1953.                   exit;
  1954.                 ReadState := rstHeader;
  1955.                 end
  1956.               else
  1957.                 if ((Header.Item=nil) and (Header.StyleNo<>rvsCheckpoint) and
  1958.                     (Header.StyleNo<>rvsBack)
  1959.                     {$IFDEF RICHVIEWCBDEF3}
  1960.                     and (Header.StyleNo<>rvsDocProperty)
  1961.                     {$ENDIF}
  1962.                     ) or
  1963.                    ((Header.Item<>nil) and
  1964.                     not Header.Item.GetBoolValue(rvbpRequiresRVFLines)) then
  1965.                   ReadState := rstSkip
  1966.                 else begin
  1967.                   ReadState := rstData;
  1968.                   {$IFNDEF RVDONOTUSEUNICODE}
  1969.                   if (Header.Item<>nil) and
  1970.                      (rvioUnicode in Header.Item.ItemOptions) and
  1971.                      (Header.ReadType<>3) then
  1972.                     ReadMode := rmBeforeUnicode;
  1973.                   {$ENDIF}
  1974.                 end;
  1975.             end;
  1976.           rstData:
  1977.             begin
  1978.               if Header.StyleNo<0 then begin
  1979.                 case Header.StyleNo of
  1980.                 {*} rvsBack:
  1981.                    ReadBackground;
  1982.                 {$IFDEF RICHVIEWCBDEF3}
  1983.                 {*} rvsDocProperty:
  1984.                    ReadDocProperty;
  1985.                 {$ENDIF}
  1986.                 {*} rvsCheckpoint:
  1987.                   begin
  1988.                     if CurCP = nil then begin
  1989.                       CurCP := TRVCPInfo.Create;
  1990.                       CurCP.Name := CurrentLine;
  1991.                       CurCP.Tag  := Header.CheckpointTag;
  1992.                       CurCP.RaiseEvent := Boolean(Header.RaiseEvent);
  1993.                       CurCP.Persistent := Boolean(Header.PersistentCheckpoint);
  1994.                       Header.CheckpointTag := 0;
  1995.                     end;
  1996.                   end;
  1997.                 {*} else
  1998.                   begin
  1999.                     if Header.Item<>nil then
  2000.                       if not Header.Item.ReadRVFLine(CurrentLine, Self,
  2001.                          Header.ReadType, Header.DataRead, Header.DataCount,
  2002.                          Header.Name, ReadMode, ReadState) then
  2003.                         abort;
  2004.                     if Header.DataRead=Header.DataCount-1 then
  2005.                       if not InsertRVFHeaderData(Self, Header.Name, Header,
  2006.                          PrevCP, CurCP, Index, InsertPoint, FirstInsert, AParaNo,
  2007.                          AppendMode, EditFlag, NonFirstItemsAdded, FullReformat,
  2008.                          PTextStylesMapping^, PListStylesMapping^) then
  2009.                         exit;
  2010.                   end
  2011.                 end
  2012.                 end
  2013.               else begin
  2014.                 if not InsertRVFHeaderData(Self, CurrentLine, Header, PrevCP, CurCP,
  2015.                    Index, InsertPoint, FirstInsert, AParaNo, AppendMode, EditFlag,
  2016.                    NonFirstItemsAdded, FullReformat, PTextStylesMapping^,
  2017.                    PListStylesMapping^) then
  2018.                   exit;
  2019.                 if Header.DataRead=Header.DataCount-1 then begin
  2020.                   if rvoTagsArePChars in Options then
  2021.                     StrDispose(PChar(Header.Item.Tag));
  2022.                   Header.Item.Free;
  2023.                   Header.Item := nil;
  2024.                 end;
  2025.               end;
  2026.               inc(Header.DataRead);
  2027.               if Header.DataRead=Header.DataCount then begin
  2028.                 ReadState := rstHeader;
  2029.                 if ReadMode=rmUnicode then
  2030.                   ReadMode := rmAfterUnicode;
  2031.               end;
  2032.             end;
  2033.           rstSkip:
  2034.             begin
  2035.               inc(Header.DataRead);
  2036.               if (Header.DataRead=Header.DataCount-1) and (Header.ReadType=2) then
  2037.                 ReadMode := rmBeforeBinary
  2038.               else if Header.DataRead=Header.DataCount then begin
  2039.                 if not InsertRVFHeaderData(Self, Header.Name, Header, PrevCP, CurCP,
  2040.                    Index, InsertPoint, FirstInsert, AParaNo, AppendMode, EditFlag,
  2041.                    NonFirstItemsAdded, FullReformat, PTextStylesMapping^,
  2042.                    PListStylesMapping^) then
  2043.                   exit;
  2044.                 ReadState := rstHeader;
  2045.               end;
  2046.             end;
  2047.         end;
  2048.         SkipCurrentLineTail;
  2049.       end; // of while
  2050.     Result := (ReadState = rstHeader);
  2051.     {$IFNDEF RVDONOTUSELISTS}
  2052.     if (InsertPoint-1>=0) and (InsertPoint-1<ItemCount) and
  2053.        (GetItemStyle(InsertPoint-1)=rvsListMarker) and
  2054.        ((InsertPoint=ItemCount) or IsParaStart(InsertPoint)) then begin
  2055.       Header.StyleNo := 0;
  2056.       Header.ParaNo := -1;
  2057.       Header.Item := RichViewTextItemClass.Create(Self);
  2058.       InsertRVFHeaderData(Self, '', Header, PrevCP, CurCP, Index, InsertPoint,
  2059.         FirstInsert, AParaNo, AppendMode, EditFlag,
  2060.         NonFirstItemsAdded, FullReformat, PTextStylesMapping^, PListStylesMapping^);
  2061.       Header.Item.Free;
  2062.       Header.Item := nil;
  2063.     end;
  2064.     {$ENDIF}
  2065.     if not EditFlag then
  2066.       NormalizeParas(StartIndex);
  2067.     Protect := False;
  2068.   except
  2069.     Result := False;
  2070.   end;
  2071.   DoneStyleMappings(PTextStylesMapping,PParaStylesMapping,PListStylesMapping);
  2072.   FreeCheckpointTag;
  2073.   if Result and (InsertPoint=Items.Count) and (NotAddedCP=nil) then begin
  2074.     if CurCP<> nil then inc(CPCount);
  2075.     NotAddedCP := CurCP
  2076.     end
  2077.   else
  2078.     if NotAddedCP<>CurCP then
  2079.       FreeCheckpoint(CurCP, False, False); // ignore cp from stream
  2080. end;
  2081. {------------------------------------------------------------------------------}
  2082. function TCustomRVData.AppendRVFFromStream(Stream: TStream; ParaNo: Integer;
  2083.                              var Color: TColor;
  2084.                              Background: TRVBackground):Boolean;
  2085. var Dummy: Integer;
  2086.     Dummy2, Dummy3: Boolean;
  2087.     Index: Integer;
  2088. begin
  2089.   Index := Items.Count;
  2090.   Result := InsertRVFFromStream_(Stream, Index, ParaNo, False, True, False,
  2091.     Color, Background, nil, Dummy, Dummy2, Dummy3);
  2092. end;
  2093. {------------------------------------------------------------------------------}
  2094. function TCustomRVData.InsertRVFFromStream(Stream: TStream; Index: Integer;
  2095.   var Color: TColor; Background: TRVBackground; Layout: TRVLayoutInfo;
  2096.   AllowReplaceStyles: Boolean):Boolean;
  2097. var Dummy: Integer;
  2098.     Dummy2,Dummy3: Boolean;
  2099. begin
  2100.   // AParaNo is used only if AppendMode=True
  2101.   Result := InsertRVFFromStream_(Stream, Index, -1, AllowReplaceStyles, False, False,
  2102.                              Color, Background, Layout, Dummy, Dummy2,Dummy3);
  2103. end;
  2104. {------------------------------------------------------------------------------}
  2105. function TCustomRVData.LoadRVF(const FileName: String; var Color: TColor;
  2106.   Background: TRVBackground; Layout: TRVLayoutInfo):Boolean;
  2107. var Stream: TFileStream;
  2108. begin
  2109.   try
  2110.     Stream := TFileStream.Create(FileName,fmOpenRead);
  2111.     try
  2112.       Result := LoadRVFFromStream(Stream, Color, Background, Layout);
  2113.     finally
  2114.       Stream.Free;
  2115.     end;
  2116.   except
  2117.     Result := False;
  2118.   end;
  2119. end;
  2120. {------------------------------------------------------------------------------}
  2121. function TCustomRVData.LoadRVFFromStream(Stream: TStream; var Color: TColor;
  2122.   Background: TRVBackground; Layout: TRVLayoutInfo):Boolean;
  2123. begin
  2124.   Clear;
  2125.   Result := InsertRVFFromStream(Stream,0, Color, Background, Layout, True);
  2126. end;
  2127. {------------------------------------------------------------------------------}
  2128. procedure RVFWriteCheckpoint(Stream: TStream; TagsArePChars: Boolean;
  2129.                              cp: TRVCPInfo);
  2130. begin
  2131.   if cp=nil then
  2132.     exit;
  2133.   RVFWriteLine(Stream, Format('%d %d %d %d %d %s %d %d',
  2134.     [rvsCheckpoint, 1, 0, 0, 0, RVFSaveTag(TagsArePChars,cp.Tag),
  2135.      Integer(cp.RaiseEvent), Integer(cp.Persistent)]));
  2136.   RVFWriteLine(Stream, cp.Name);
  2137. end;
  2138. {------------------------------------------------------------------------------}
  2139. function TCustomRVData.SaveRVF(const FileName: String; SelectionOnly: Boolean;
  2140.   Color: TColor; Background: TRVBackground; Layout: TRVLayoutInfo):Boolean;
  2141. var Stream: TFileStream;
  2142. begin
  2143.   try
  2144.     Stream := TFileStream.Create(FileName,fmCreate);
  2145.     try
  2146.       Result := SaveRVFToStream(Stream, SelectionOnly, Color, Background, Layout);
  2147.     finally
  2148.       Stream.Free;
  2149.     end;
  2150.   except
  2151.     Result := False;
  2152.   end;
  2153. end;
  2154. {------------------------------------------------------------------------------}
  2155. function TCustomRVData.SaveRVFToStream(Stream: TStream; SelectionOnly: Boolean;
  2156.   Color: TColor; Background: TRVBackground; Layout: TRVLayoutInfo):Boolean;
  2157. begin
  2158.   Result := SaveRVFToStreamEx(Stream, GetRVFSaveScope(SelectionOnly), Color,
  2159.     Background, Layout);
  2160. end;
  2161. {------------------------------------------------------------------------------}
  2162. function TCustomRVData.SaveRVFToStreamEx(Stream: TStream; SaveScope: TRVFSaveScope;
  2163.   Color: TColor; Background: TRVBackground; Layout: TRVLayoutInfo):Boolean;
  2164. var i: Integer;
  2165.     Header: TRVFHeader;
  2166.     SectionBackOffs: Integer;
  2167.     StartItem, EndItem, StartOffs, EndOffs: Integer;
  2168.     StartPart, EndPart: TRVMultiDrawItemPart;
  2169.     MarkerItemNo: Integer;
  2170.    {.......................................................}
  2171.      procedure RVFSaveVersionInfo;
  2172.      begin
  2173.        RVFWriteLine(Stream, SysUtils.Format('%d %d %d',
  2174.          [rvsVersionInfo, RVFVersion, RVFSubVersion]));
  2175.      end;
  2176.    {.......................................................}
  2177.    {$IFDEF RICHVIEWCBDEF3}
  2178.      procedure RVFSaveStyles(Id: Integer; Styles: TCollection);
  2179.      var SaveType: Integer;
  2180.          Writer: TWriter;
  2181.          TmpStream: TMemoryStream;
  2182.          Pos,Pos2: Integer;
  2183.      begin
  2184.        if rvfoSaveBinary in RVFOptions then
  2185.          SaveType := 2 // save binary
  2186.        else
  2187.          SaveType := 0; // save hex dump
  2188.        RVFWriteLine(Stream, Format('%d %d %d %d %d %d %d',
  2189.           [rvsDocProperty, 2, 0, 0, SaveType, 0, Id]));
  2190.        RVFWriteLine(Stream, GetRVStyle.Name);
  2191.        if rvfoSaveBinary in RVFOptions then begin
  2192.          Pos := Stream.Position;
  2193.          Stream.WriteBuffer(Pos, sizeof(Pos));
  2194.          Writer := TWriter.Create(Stream, 4096);
  2195.          if Styles is TRVListInfos then
  2196.            TRVListInfos(Styles).FRVData := Self;
  2197.          try
  2198.            Writer.WriteCollection(Styles)
  2199.          finally
  2200.            Writer.Free;
  2201.            if Styles is TRVListInfos then
  2202.              TRVListInfos(Styles).FRVData := nil;
  2203.          end;
  2204.          Pos2 := Stream.Position;
  2205.          Stream.Position := Pos;
  2206.          Pos := Pos2-Pos-sizeof(Pos);
  2207.          Stream.WriteBuffer(Pos, sizeof(Pos));
  2208.          Stream.Position := Pos2;
  2209.          end
  2210.        else begin
  2211.          TmpStream := TMemoryStream.Create;
  2212.          try
  2213.            Writer := TWriter.Create(TmpStream, 4096);
  2214.            if Styles is TRVListInfos then
  2215.              TRVListInfos(Styles).FRVData := Self;
  2216.            try
  2217.              Writer.WriteCollection(Styles);
  2218.            finally
  2219.              Writer.Free;
  2220.              if Styles is TRVListInfos then
  2221.                TRVListInfos(Styles).FRVData := nil;
  2222.            end;
  2223.            TmpStream.Position := 0;
  2224.            RVFWriteLine(Stream, RVFStream2TextString(TmpStream));
  2225.          finally
  2226.            TmpStream.Free;
  2227.          end;
  2228.        end;
  2229.      end;
  2230.    {$ENDIF}
  2231.    {.......................................................}
  2232.      procedure RVFSaveLayout;
  2233.      var SaveType : Integer;
  2234.      begin
  2235.        if rvfoSaveBinary in RVFOptions then
  2236.          SaveType := 2 // save binary
  2237.        else
  2238.          SaveType := 0; // save hex dump
  2239.        RVFWriteLine(Stream, Format('%d %d %d %d %d %d %d',
  2240.           [rvsDocProperty, 2, 0, 0, SaveType, 0, RVF_DOCPROP_LAYOUT]));
  2241.        RVFWriteLine(Stream, '');
  2242.        case SaveType of
  2243.          2:
  2244.            Layout.SaveToStream(Stream,True);
  2245.          0:
  2246.            Layout.SaveTextToStream(Stream);
  2247.        end;
  2248.      end;
  2249.    {.......................................................}
  2250.    {$IFNDEF RVDONOTUSELISTS}
  2251.      procedure RVFSavePrevMarkers(StartItemNo: Integer);
  2252.      var SaveType, MarkerIndex : Integer;
  2253.          Marker: TRVMarkerItemInfo;
  2254.      begin
  2255.        if StartItemNo=0 then
  2256.          exit;
  2257.        Marker := FindPreviousMarker(StartItemNo-1);
  2258.        if Marker=nil then
  2259.          exit;
  2260.        MarkerIndex := Marker.GetIndexInList(GetMarkers(False));
  2261.        if MarkerIndex<0 then
  2262.          exit;
  2263.        if rvfoSaveBinary in RVFOptions then
  2264.          SaveType := 2 // save binary
  2265.        else
  2266.          SaveType := 0; // save hex dump
  2267.        RVFWriteLine(Stream, Format('%d %d %d %d %d %d %d',
  2268.           [rvsDocProperty, 2, 0, 0, SaveType, 0, RVF_DOCPROP_PREVMARKERS]));
  2269.        RVFWriteLine(Stream, '');
  2270.        case SaveType of
  2271.          2:
  2272.            GetMarkers(False).SaveToStream(Stream, MarkerIndex+1, True);
  2273.          0:
  2274.            GetMarkers(False).SaveTextToStream(Stream, MarkerIndex+1);
  2275.        end;
  2276.      end;
  2277.    {$ENDIF}
  2278.    {.......................................................}
  2279.      procedure RVFSaveDocPropertiesStringList;
  2280.      var i: Integer;
  2281.          dp: TStringList;
  2282.      begin
  2283.        dp := GetAbsoluteRootData.GetDocProperties;
  2284.        if (dp=nil) or (dp.Count=0) then
  2285.          exit;
  2286.        RVFWriteLine(Stream, Format('%d %d %d %d %d %d %d',
  2287.           [rvsDocProperty, dp.Count, 0, 0, 0, 0, RVF_DOCPROP_DOCPROPLIST]));
  2288.        for i := 0 to dp.Count-1 do
  2289.          RVFWriteLine(Stream, RVFEncodeLineBreaks(dp.Strings[i]));
  2290.      end;
  2291.    {.......................................................}
  2292.      procedure RVFSaveBackground;
  2293.      var SaveType, LineCount: Integer;
  2294.      begin
  2295.        if Background=nil then exit;
  2296.        if Background.Bitmap.Empty or (Background.Style=bsNoBitmap) then
  2297.          RVFWriteLine(Stream, Format('%d %d %d %d %d %d %d %d',
  2298.                             [rvsBack, 0, -1, 0, 0, 0, ord(Background.Style), Color]))
  2299.        else begin
  2300.          LineCount := 2;
  2301.          if rvfoSaveBinary in RVFOptions then
  2302.            SaveType := 2 // save binary
  2303.          else
  2304.            SaveType := 0 // save hex dump
  2305.          ;
  2306.          RVFWriteLine(Stream, Format('%d %d %d %d %d %d %d %d',
  2307.             [rvsBack, LineCount, 0, 0, SaveType, 0, ord(Background.Style), Color]));
  2308.          if SaveType<>1 then begin
  2309.            RVFWriteLine(Stream, Background.Bitmap.ClassName);
  2310.            if rvfoSaveBinary in RVFOptions then
  2311.              RVFSavePictureBinary(Stream, Background.Bitmap)
  2312.            else
  2313.              RVFWriteLine(Stream, RVFSavePicture(Background.Bitmap));
  2314.          end;
  2315.        end;
  2316.      end;
  2317.    {.......................................................}
  2318.    { Saves text of the ItemNo-th item in range from StartOffs to EndOffs characters.
  2319.      If the ItemNo-th item is not a text item, saves an empty text line of style
  2320.      GetItem(ItemNo).AssociatedTextStyleNo (it's assumed that it's >=0).
  2321.      If StartOffs=GetOffsetBeforeItem(ItemNo) and the item has a checkpoint,
  2322.      it's saved too.
  2323.      If ForceSavingPara, item's paragraph index is saved, even if it does not
  2324.      start a new paragraph. }
  2325.     procedure WritePartialTextLine(ItemNo, StartOffs, EndOffs: Integer;
  2326.       ForceSavingPara: Boolean); // in: Stream
  2327.     var AFromStart: Boolean;
  2328.         AParaNo, TextStyleNo: Integer;
  2329.         SaveMode: Integer;
  2330.         Tail, Text: String;
  2331.         item: TCustomRVItemInfo;
  2332.         {$IFNDEF RVDONOTUSEUNICODE}
  2333.         Unicode: Boolean;
  2334.         {$ENDIF}
  2335.         ItemOptions: TRVItemOptions;
  2336.     begin
  2337.       AFromStart := (StartOffs <= GetOffsBeforeItem(ItemNo));
  2338.       item := GetItem(ItemNo);
  2339.       TextStyleNo := item.StyleNo;
  2340.       if TextStyleNo<0 then
  2341.         TextStyleNo := item.AssociatedTextStyleNo;
  2342.       {$IFNDEF RVDONOTUSEUNICODE}
  2343.       Unicode := GetRVStyle.TextStyles[TextStyleNo].Unicode;
  2344.       {$ENDIF}
  2345.       {$IFDEF RICHVIEWCBDEF3}
  2346.       {$IFNDEF RVDONOTUSEUNICODE}
  2347.       if Unicode and not (rvfoSaveBinary in RVFOptions) then
  2348.         SaveMode := 3
  2349.       else
  2350.       {$ENDIF}
  2351.         SaveMode := 0;
  2352.      {$ELSE}
  2353.      SaveMode := 0;
  2354.      {$ENDIF}
  2355.      if (AFromStart and not item.SameAsPrev) or ForceSavingPara then
  2356.        AParaNo := item.ParaNo
  2357.      else
  2358.        AParaNo   := -1;
  2359.      if AFromStart then
  2360.        RVFWriteCheckpoint(Stream, rvoTagsArePChars in Options, item.Checkpoint);
  2361.      Tail := '';
  2362.      {$IFNDEF RVDONOTUSEITEMHINTS}
  2363.      {$IFDEF RICHVIEWCBDEF3}
  2364.      if item.Hint<>'' then
  2365.        Tail := ' '+AnsiQuotedStr(item.Hint, '"');
  2366.      {$ENDIF}
  2367.      {$ENDIF}
  2368.      ItemOptions := GetItemOptions(ItemNo);
  2369.      {$IFNDEF RVDONOTUSEUNICODE}
  2370.      if Unicode then
  2371.        Include(ItemOptions, rvioUnicode);
  2372.      {$ENDIF}
  2373.      RVFWriteLine(Stream, SysUtils.Format('%s %d %s %d %d %s%s',
  2374.        [RVFSaveText(GetRVStyle, rvfoUseStyleNames in RVFOptions, TextStyleNo), 1,
  2375.        RVFSavePara(GetRVStyle, rvfoUseStyleNames in RVFOptions, AParaNo),
  2376.        Byte(ItemOptions) and RVItemOptionsMask,
  2377.        SaveMode, RVFSaveTag(rvoTagsArePChars in Options, item.Tag),
  2378.        Tail]));
  2379.      if item.StyleNo>=0 then
  2380.        Text := RVU_Copy(Items[ItemNo], StartOffs, EndOffs-StartOffs, GetItemOptions(ItemNo))
  2381.      else
  2382.        Text := '';
  2383.      RVFWriteLineX(Stream, Text,
  2384.        {$IFNDEF RVDONOTUSEUNICODE}Unicode{$ELSE}False{$ENDIF}, SaveMode=3);
  2385.      MarkerItemNo := -1;
  2386.     end;
  2387.    {.......................................................}
  2388.     function IsTheSameStyleText: Boolean; // in: i, Header
  2389.     begin
  2390.       with GetItem(i) do
  2391.         Result := (not SameAsPrev) and (StyleNo>=0) and (StyleNo=Header.StyleNo) and
  2392.           (ParaNo=Header.ParaNo) and
  2393.           ((Byte(ItemOptions) and RVItemOptionsMask) = (Byte(Header.Item.ItemOptions)and RVItemOptionsMask)) and
  2394.           RV_CompareTags(Tag, Header.Item.Tag, rvoTagsArePChars in Options) and
  2395.           {$IFNDEF RVDONOTUSEITEMHINTS}
  2396.           (Hint=Header.Item.Hint) and
  2397.           {$ENDIF}
  2398.           (Checkpoint=nil);
  2399.     end;
  2400.   {.......................................................}
  2401.    procedure RVFWritePrevStrings(i: Integer); // in: Header, SectionBackOffs
  2402.    var j: Integer;
  2403.        ItemOptions: TRVItemOptions;
  2404.        SaveMode: Integer;
  2405.        Tail: String;
  2406.    begin
  2407.      {$IFDEF RICHVIEWCBDEF3}