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

RichEdit

开发平台:

Delphi

  1. {*******************************************************}
  2. {                                                       }
  3. {       RichView                                        }
  4. {       TRVMarkerItemInfo: RichView item type           }
  5. {       representing paragraph markers.                 }
  6. {       TRVMarkerList: list of markers in the document  }
  7. {       and all its subdocuments.                       }
  8. {                                                       }
  9. {       Copyright (c) Sergey Tkachenko                  }
  10. {       svt@trichview.com                               }
  11. {       http://www.trichview.com                        }
  12. {                                                       }
  13. {*******************************************************}
  14. unit RVMarker;
  15. interface
  16. {$I RV_Defs.inc}
  17. uses SysUtils, Windows, Classes, Controls, Graphics, Forms,
  18.      RVFuncs, RVItem, RVStyle, DLines, RVFMisc, RVScroll, RVUni, RVClasses, RVStr;
  19. {$IFNDEF RVDONOTUSELISTS}
  20. type
  21.   TRVMarkerList = class;
  22.   TRVMarkerItemInfo = class (TRVRectItemInfo)
  23.     private
  24.       FWidth, FHeight, FDescent, FOverhang: Integer;
  25.       FCachedIndexInList: Integer;
  26.       procedure DoPaint(x,y: Integer; Canvas: TCanvas; State: TRVItemDrawStates;
  27.         Style: TRVStyle; dli: TRVDrawLineInfo; ColorMode: TRVColorMode);
  28.     protected
  29.       function SaveRVFHeaderTail(RVData: TPersistent): String; override;
  30.       procedure CalcSize(Canvas: TCanvas; RVData: TPersistent;
  31.         var Width, Height, Desc, Overhang: Integer;
  32.         sad: PRVScreenAndDevice; ForMinWidth: Boolean;
  33.         var HShift, SpaceBefore: Integer);
  34.       procedure CalcDisplayString(RVStyle: TRVStyle; List: TRVMarkerList;
  35.         Index: Integer);
  36.       function GetHeight: Integer; override;
  37.       function GetWidth: Integer; override;
  38.       function GetLevelInfoEx(RVStyle: TRVStyle; LevelNo: Integer): TRVListLevel;
  39.       function GetDescent: Integer; override;
  40.       function GetRVFExtraPropertyCount: Integer; override;
  41.       procedure SaveRVFExtraProperties(Stream: TStream); override;
  42.     public
  43.       ListNo, Level: Integer;
  44.       Counter: Integer;
  45.       Reset: Boolean;
  46.       StartFrom: Integer;
  47.       DisplayString: String;
  48.       NoHTMLImageSize: Boolean;
  49.       constructor CreateEx(RVData: TPersistent;
  50.         AListNo, ALevel, AStartFrom: Integer; AReset: Boolean);
  51.       constructor Create(RVData: TPersistent); override;
  52.       procedure Assign(Source: TCustomRVItemInfo); override;
  53.       function GetLevelInfo(RVStyle: TRVStyle): TRVListLevel;
  54.       function GetMinWidth(sad: PRVScreenAndDevice; Canvas: TCanvas;
  55.         RVData: TPersistent): Integer; override;
  56.       function GetBoolValue(Prop: TRVItemBoolProperty): Boolean; override;
  57.       function GetBoolValueEx(Prop: TRVItemBoolPropertyEx;
  58.         RVStyle: TRVStyle): Boolean; override;
  59.       procedure OnDocWidthChange(DocWidth: Integer; dli: TRVDrawLineInfo; Printing: Boolean;
  60.         Canvas: TCanvas; RVData: TPersistent; sad: PRVScreenAndDevice;
  61.         var HShift, Desc: Integer; NoCaching, Reformatting: Boolean); override;
  62.       procedure Paint(x,y: Integer; Canvas: TCanvas; State: TRVItemDrawStates;
  63.         Style: TRVStyle; dli: TRVDrawLineInfo); override;
  64.       procedure Print(Canvas: TCanvas; x,y,x2: Integer; Preview, Correction: Boolean;
  65.         const sad: TRVScreenAndDevice; RichView: TRVScroller; dli: TRVDrawLineInfo;
  66.         Part: Integer; ColorMode: TRVColorMode; RVData: TPersistent); override;
  67.       function PrintToBitmap(Bkgnd: TBitmap; Preview: Boolean; RichView: TRVScroller;
  68.           dli: TRVDrawLineInfo; Part: Integer; ColorMode: TRVColorMode):Boolean; override;
  69.       function ReadRVFHeader(var P: PChar; RVData: TPersistent): Boolean; override;
  70.       procedure SaveRVF(Stream: TStream; RVData: TPersistent;
  71.         ItemNo, ParaNo: Integer; const Name: String; Part: TRVMultiDrawItemPart;
  72.         ForceSameAsPrev: Boolean); override;
  73.       procedure MovingToUndoList(ItemNo: Integer; RVData, AContainerUndoItem: TObject); override;
  74.       procedure MovingFromUndoList(ItemNo: Integer; RVData: TObject); override;
  75.       function GetImageWidth(RVStyle: TRVStyle): Integer; override;
  76.       function GetImageHeight(RVStyle: TRVStyle): Integer; override;
  77.       function GetLeftOverhang: Integer; override;
  78.       {$IFNDEF RVDONOTUSEHTML}
  79.       procedure HTMLOpenOrCloseTags(Stream: TStream;
  80.         OldLevelNo, NewLevelNo: Integer; RVStyle: TRVStyle; UseCSS: Boolean);
  81.       procedure SaveHTMLSpecial(Stream: TStream; Prev: TRVMarkerItemInfo;
  82.         RVStyle: TRVStyle; UseCSS: Boolean);
  83.       procedure SaveToHTML(Stream: TStream; RVData: TPersistent;
  84.         ItemNo: Integer; const Text, Path: String;
  85.         const imgSavePrefix: String; var imgSaveNo: Integer;
  86.         CurrentFileColor: TColor; SaveOptions: TRVSaveOptions;
  87.         UseCSS: Boolean; Bullets: TRVList); override;
  88.       function GetLICSS(RVData: TPersistent; ItemNo: Integer; const Path,
  89.         imgSavePrefix: String; var imgSaveNo: Integer; CurrentFileColor: TColor;
  90.         SaveOptions: TRVSaveOptions; Bullets: TRVList): String;
  91.       {$ENDIF}
  92.       {$IFNDEF RVDONOTUSERTF}
  93.       procedure FillRTFTables(ColorList: TRVColorList;
  94.         ListOverrideCountList: TRVIntegerList; RVData: TPersistent); override;
  95.       procedure SaveRTF(Stream: TStream; const Path: String;
  96.         RVData: TPersistent; ItemNo: Integer;
  97.         const Name: String; TwipsPerPixel: Double; Level: Integer;
  98.         ColorList: TRVColorList; StyleToFont, ListOverrideOffsetsList1,
  99.         ListOverrideOffsetsList2: TRVIntegerList; FontTable: TRVList); override;
  100.       {$ENDIF}
  101.       procedure MarkStylesInUse(Data: TRVDeleteUnusedStylesData); override;
  102.       procedure UpdateStyles(Data: TRVDeleteUnusedStylesData); override;
  103.       function AsText(LineWidth: Integer; RVData: TPersistent;
  104.         const Text, Path: String; TextOnly,Unicode: Boolean): String; override;
  105.       function GetIndexInList(List: TList): Integer;
  106.       function SetExtraIntProperty(Prop: TRVExtraItemProperty;
  107.         Value: Integer): Boolean; override;
  108.       function GetExtraIntProperty(Prop: TRVExtraItemProperty;
  109.         var Value: Integer): Boolean; override;
  110.   end;
  111.   TRVMarkerList = class (TList)
  112.   public
  113.     PrevMarkerList: TRVMarkerList;
  114.     function InsertAfter(InsertMe, AfterMe: TRVMarkerItemInfo): Integer;
  115.     procedure RecalcCounters(StartFrom: Integer; RVStyle: TRVStyle);
  116.     function FindParentMarker(Index: Integer; Marker: TRVMarkerItemInfo;
  117.       var ParentList: TRVMarkerList; var ParentIndex: Integer): Boolean;
  118.     procedure RecalcDisplayStrings(RVStyle: TRVStyle);
  119.     procedure SaveToStream(Stream: TStream; Count: Integer; IncludeSize: Boolean);
  120.     procedure LoadFromStream(Stream: TStream; RVData: TPersistent;
  121.       IncludeSize: Boolean);
  122.     procedure SaveTextToStream(Stream: TStream; Count: Integer);
  123.     procedure LoadText(const s: String; RVData: TPersistent);
  124.     procedure LoadBinary(const s: String; RVData: TPersistent);
  125.   end;
  126.   function RVGetLevelInfo(RVStyle: TRVStyle; ListNo, Level: Integer): TRVListLevel;
  127. {$ENDIF}
  128. implementation
  129. {$IFNDEF RVDONOTUSELISTS}
  130. uses CRVData, CRVFData, RichView;
  131. {============================= TRVMarkerItemInfo ==============================}
  132. constructor TRVMarkerItemInfo.CreateEx(RVData: TPersistent; AListNo,
  133.   ALevel, AStartFrom: Integer; AReset: Boolean);
  134. begin
  135.   inherited Create(RVData);
  136.   StyleNo   := rvsListMarker;
  137.   ListNo    := AListNo;
  138.   Level     := ALevel;
  139.   StartFrom := AStartFrom;
  140.   Reset     := AReset;
  141.   SameAsPrev := False;
  142.   Counter   := 1;
  143.   FCachedIndexInList := -1;
  144. end;
  145. {------------------------------------------------------------------------------}
  146. constructor TRVMarkerItemInfo.Create(RVData: TPersistent);
  147. begin
  148.   inherited Create(RVData);
  149.   SameAsPrev := False;
  150.   Counter   := 1;
  151.   FCachedIndexInList := -1;  
  152. end;
  153. {------------------------------------------------------------------------------}
  154. procedure TRVMarkerItemInfo.Assign(Source: TCustomRVItemInfo);
  155. begin
  156.   if Source is TRVMarkerItemInfo then begin
  157.     ListNo    := TRVMarkerItemInfo(Source).ListNo;
  158.     Level     := TRVMarkerItemInfo(Source).Level;
  159.     StartFrom := TRVMarkerItemInfo(Source).StartFrom;
  160.     Reset     := TRVMarkerItemInfo(Source).Reset;
  161.     NoHTMLImageSize := TRVMarkerItemInfo(Source).NoHTMLImageSize;
  162.   end;
  163.   inherited Assign(Source);
  164. end;
  165. {------------------------------------------------------------------------------}
  166. procedure TRVMarkerItemInfo.MovingToUndoList(ItemNo: Integer; RVData,
  167.   AContainerUndoItem: TObject);
  168. begin
  169.   inherited;
  170.   TCustomRVData(RVData).DeleteMarkerFromList(TCustomRVData(RVData).GetItem(ItemNo), False);
  171. end;
  172. {------------------------------------------------------------------------------}
  173. procedure TRVMarkerItemInfo.MovingFromUndoList(ItemNo: Integer; RVData: TObject);
  174. begin
  175.   inherited;
  176.   TCustomRVData(RVData).AddMarkerInList(ItemNo);
  177. end;
  178. {------------------------------------------------------------------------------}
  179. function TRVMarkerItemInfo.ReadRVFHeader(var P: PChar;
  180.   RVData: TPersistent): Boolean;
  181. var v: Integer;
  182. begin
  183.   Result :=  RVFReadInteger(P,ListNo) and
  184.              RVFReadInteger(P,Level) and
  185.              RVFReadInteger(P,StartFrom) and
  186.              RVFReadInteger(P,v);
  187.   Reset := v<>0;
  188. end;
  189. {------------------------------------------------------------------------------}
  190. function TRVMarkerItemInfo.SaveRVFHeaderTail(RVData: TPersistent): String;
  191. begin
  192.   Result := Format('%d %d %d %d', [ListNo, Level, StartFrom, ord(Reset)]);
  193. end;
  194. {------------------------------------------------------------------------------}
  195. procedure TRVMarkerItemInfo.SaveRVF(Stream: TStream; RVData: TPersistent;
  196.   ItemNo, ParaNo: Integer; const Name: String; Part: TRVMultiDrawItemPart;
  197.   ForceSameAsPrev: Boolean);
  198. begin
  199.   RVFWriteLine(Stream, Format('%d %d %s %d %d %s %s',
  200.     [StyleNo, GetRVFExtraPropertyCount,
  201.      RVFItemSavePara(ParaNo, TCustomRVData(RVData), False),
  202.      Byte(ItemOptions) and RVItemOptionsMask,
  203.      0, RVFSaveTag(rvoTagsArePChars in TCustomRVData(RVData).Options,Tag),
  204.      SaveRVFHeaderTail(RVData)]));
  205.   SaveRVFExtraProperties(Stream);
  206. end;
  207. {------------------------------------------------------------------------------}
  208. function TRVMarkerItemInfo.GetLevelInfoEx(RVStyle: TRVStyle; LevelNo: Integer): TRVListLevel;
  209. begin
  210.   if LevelNo>=RVStyle.ListStyles[ListNo].Levels.Count then
  211.     LevelNo :=RVStyle.ListStyles[ListNo].Levels.Count-1;
  212.   Result := RVStyle.ListStyles[ListNo].Levels[LevelNo];
  213. end;
  214. {------------------------------------------------------------------------------}
  215. function RVGetLevelInfo(RVStyle: TRVStyle; ListNo, Level: Integer): TRVListLevel;
  216. var LevelNo: Integer;
  217. begin
  218.   Result := nil;
  219.   if ListNo<0 then
  220.     exit;
  221.   LevelNo := Level;
  222.   if LevelNo>=RVStyle.ListStyles[ListNo].Levels.Count then
  223.     LevelNo :=RVStyle.ListStyles[ListNo].Levels.Count-1;
  224.   if LevelNo<RVStyle.ListStyles[ListNo].Levels.Count then
  225.     Result := RVStyle.ListStyles[ListNo].Levels[LevelNo];
  226. end;
  227. {------------------------------------------------------------------------------}
  228. function TRVMarkerItemInfo.GetLevelInfo(RVStyle: TRVStyle): TRVListLevel;
  229. var LevelNo: Integer;
  230. begin
  231.   Result := nil;
  232.   if ListNo<0 then
  233.     exit;
  234.   LevelNo := Level;
  235.   if LevelNo>=RVStyle.ListStyles[ListNo].Levels.Count then
  236.     LevelNo :=RVStyle.ListStyles[ListNo].Levels.Count-1;
  237.   if LevelNo<RVStyle.ListStyles[ListNo].Levels.Count then
  238.     Result := RVStyle.ListStyles[ListNo].Levels[LevelNo];
  239. end;
  240. {------------------------------------------------------------------------------}
  241. procedure TRVMarkerItemInfo.CalcSize(Canvas: TCanvas; RVData: TPersistent;
  242.                                      var Width, Height, Desc, Overhang: Integer;
  243.                                      sad: PRVScreenAndDevice;
  244.                                      ForMinWidth: Boolean;
  245.                                      var HShift, SpaceBefore: Integer);
  246. var sz: TSize;
  247.     LevelInfo: TRVListLevel;
  248.     TextMetric: TTextMetric;
  249.     RVStyle: TRVStyle;
  250.     {.........................................................}
  251.     procedure CountLR(var LeftWidth, RightWidth: Integer);
  252.     begin
  253.       case LevelInfo.MarkerAlignment of
  254.         rvmaLeft:
  255.           begin
  256.             LeftWidth := 0;
  257.             RightWidth := Width;
  258.           end;
  259.         rvmaRight:
  260.           begin
  261.             LeftWidth := Width;
  262.             RightWidth := 0;
  263.           end;
  264.         rvmaCenter:
  265.           begin
  266.             RightWidth := Width div 2;
  267.             LeftWidth := Width - RightWidth;
  268.           end;
  269.       end;
  270.     end;
  271.     {.........................................................}
  272.     procedure CountWidth(UseSad: Boolean);
  273.     var  LeftWidth, RightWidth, w: Integer;
  274.     begin
  275.       CountLR(LeftWidth, RightWidth);
  276.       if UseSaD and (sad<>nil) then
  277.         w := MulDiv(LevelInfo.FirstIndent+LevelInfo.LeftIndent-LevelInfo.MarkerIndent, sad.ppixDevice, sad.ppixScreen)
  278.       else
  279.         w := LevelInfo.FirstIndent+LevelInfo.LeftIndent-LevelInfo.MarkerIndent;
  280.       if ForMinWidth then begin
  281.         Width := RightWidth;
  282.         if Width<w then
  283.           Width := w;
  284.         end
  285.       else begin
  286.         if RightWidth<w then
  287.           RightWidth := w;
  288.         if TCustomRVData(RVData).GetParaBiDiMode(ParaNo)=rvbdRightToLeft then begin
  289.           HShift :=  LeftWidth;
  290.           SpaceBefore := LeftWidth+RightWidth-Width;
  291.           end
  292.         else begin
  293.           HShift := - LeftWidth;
  294.           SpaceBefore := 0;
  295.         end;
  296.         Width := LeftWidth+RightWidth;
  297.         Overhang := HShift;
  298.       end;
  299.     end;
  300.     {.........................................................}
  301. begin
  302.   if (ListNo<0) or (Level<0) then begin
  303.     Width := 0;
  304.     Height := 0;
  305.     HShift := 0;
  306.     Desc := 0;
  307.     Overhang := 0;
  308.     SpaceBefore := 0;
  309.     exit;
  310.   end;
  311.   RVStyle := TCustomRVData(RVData).GetRVStyle;
  312.   LevelInfo := GetLevelInfo(RVStyle);
  313.   Desc := 0;
  314.   case LevelInfo.ListType of
  315.     rvlstPicture:
  316.       begin
  317.         if LevelInfo.HasPicture then begin
  318.           Width := LevelInfo.Picture.Graphic.Width;
  319.           Height := LevelInfo.Picture.Graphic.Height;
  320.           if sad<>nil then begin
  321.             Width := MulDiv(Width, sad.ppixDevice, sad.ppixScreen);
  322.             Height := MulDiv(Height, sad.ppiyDevice, sad.ppiyScreen);
  323.           end;
  324.           end
  325.         else begin
  326.           Width := 0;
  327.           Height := 0;
  328.         end;
  329.         CountWidth(True);
  330.       end;
  331.     rvlstImageList, rvlstImageListCounter:
  332.       begin
  333.         if LevelInfo.ImageList<>nil then begin
  334.           Width := TImageList(LevelInfo.ImageList).Width;
  335.           Height := TImageList(LevelInfo.ImageList).Height;
  336.           if sad<>nil then begin
  337.             Width := MulDiv(Width, sad.ppixDevice, sad.ppixScreen);
  338.             Height := MulDiv(Height, sad.ppiyDevice, sad.ppiyScreen);
  339.           end;
  340.           end
  341.         else begin
  342.           Width := 0;
  343.           Height := 0;
  344.         end;
  345.         CountWidth(True);
  346.       end;
  347.     {$IFNDEF RVDONOTUSEUNICODE}
  348.     {$IFDEF RICHVIEWCBDEF3}
  349.     rvlstUnicodeBullet:
  350.       begin
  351.         Canvas.Font := LevelInfo.Font;
  352.         if (RVStyle.TextStyles.PixelsPerInch<>0) and (LevelInfo.Font.Size>0) then
  353.           Canvas.Font.Height := - MulDiv(LevelInfo.Font.Size, RVStyle.TextStyles.PixelsPerInch, 72);
  354.         {$IFNDEF RVDONOTUSECHARSPACING}
  355.         SetTextCharacterExtra(Canvas.Handle, 0);
  356.         {$ENDIF}
  357.         SetTextAlign(Canvas.Handle, TA_LEFT);
  358.         GetTextExtentPoint32W(Canvas.Handle, Pointer(LevelInfo.FormatStringW),
  359.            Length(LevelInfo.FormatStringW), sz);
  360.         GetTextMetrics(Canvas.Handle, TextMetric);
  361.         Desc := TextMetric.tmDescent;
  362.         Width := sz.cx;
  363.         Height := sz.cy;
  364.         CountWidth(True);
  365.       end;
  366.     {$ENDIF}
  367.     {$ENDIF}
  368.     else
  369.       begin
  370.         Canvas.Font := LevelInfo.Font;
  371.         if (RVStyle.TextStyles.PixelsPerInch<>0) and (LevelInfo.Font.Size>0) then
  372.           Canvas.Font.Height := - MulDiv(LevelInfo.Font.Size, RVStyle.TextStyles.PixelsPerInch, 72);
  373.         {$IFNDEF RVDONOTUSECHARSPACING}
  374.         SetTextCharacterExtra(Canvas.Handle, 0);
  375.         {$ENDIF}
  376.         SetTextAlign(Canvas.Handle, TA_LEFT);
  377.         GetTextExtentPoint32(Canvas.Handle, PChar(DisplayString),
  378.            Length(DisplayString), sz);
  379.         GetTextMetrics(Canvas.Handle, TextMetric);
  380.         Desc := TextMetric.tmDescent;
  381.         Width := sz.cx;
  382.         Height := sz.cy;
  383.         CountWidth(True);
  384.       end;
  385.   end;
  386. end;
  387. {------------------------------------------------------------------------------}
  388. function TRVMarkerItemInfo.GetBoolValue(Prop: TRVItemBoolProperty): Boolean;
  389. begin
  390.   case Prop of
  391.     rvbpDrawingChangesFont, rvbpCanSaveUnicode {, rvbpAlwaysInText}:
  392.       Result := True;
  393.     else
  394.       Result := inherited GetBoolValue(Prop);
  395.   end;
  396. end;
  397. {------------------------------------------------------------------------------}
  398. function TRVMarkerItemInfo.GetBoolValueEx(Prop: TRVItemBoolPropertyEx; RVStyle: TRVStyle): Boolean;
  399. var LevelInfo: TRVListLevel;
  400. begin
  401.   case Prop of
  402.     rvbpActualPrintSize:
  403.       begin
  404.         (*
  405.         LevelInfo := GetLevelInfo(RVStyle);
  406.         if LevelInfo<>nil then
  407.           Result := LevelInfo.ListType in [rvlstDecimal, rvlstLowerAlpha, rvlstUpperAlpha,
  408.             rvlstBullet,
  409.             rvlstLowerRoman, rvlstUpperRoman {$IFNDEF RVDONOTUSEUNICODE}, rvlstUnicodeBullet{$ENDIF}]
  410.         else
  411.         *)
  412.           Result := True;
  413.       end;
  414.     rvbpPrintToBMP:
  415.       begin
  416.         LevelInfo := GetLevelInfo(RVStyle);
  417.         if LevelInfo<>nil then
  418.           Result := (LevelInfo.ListType in [rvlstImageList, rvlstImageListCounter]) or
  419.                   ((LevelInfo.ListType=rvlstPicture) and LevelInfo.HasPicture and
  420.                     not (LevelInfo.Picture.Graphic is TMetafile))
  421.         else
  422.           Result := False;
  423.       end;
  424.     else
  425.       Result := inherited GetBoolValueEx(Prop,RVStyle);
  426.   end;
  427. end;
  428. {------------------------------------------------------------------------------}
  429. function TRVMarkerItemInfo.GetHeight: Integer;
  430. begin
  431.   Result := FHeight;
  432. end;
  433. {------------------------------------------------------------------------------}
  434. function TRVMarkerItemInfo.GetWidth: Integer;
  435. begin
  436.   Result := FWidth;
  437. end;
  438. {------------------------------------------------------------------------------}
  439. function TRVMarkerItemInfo.GetLeftOverhang: Integer;
  440. begin
  441.   Result := FOverhang;
  442. end;
  443. {------------------------------------------------------------------------------}
  444. function TRVMarkerItemInfo.GetDescent: Integer;
  445. begin
  446.   Result := FDescent;
  447. end;
  448. {------------------------------------------------------------------------------}
  449. function TRVMarkerItemInfo.GetMinWidth(sad: PRVScreenAndDevice;
  450.   Canvas: TCanvas; RVData: TPersistent): Integer;
  451. var h,d,s,o,sb: Integer;
  452. begin
  453.   CalcSize(Canvas, RVData, Result, h, d, o, sad, True, s, sb);
  454.   if not GetBoolValueEx(rvbpActualPrintSize, TCustomRVData(RVData).GetRVStyle) and
  455.      (sad<>nil) then
  456.     Result := MulDiv(Result, sad.ppixDevice, sad.ppixScreen);
  457. end;
  458. {------------------------------------------------------------------------------}
  459. procedure TRVMarkerItemInfo.OnDocWidthChange(DocWidth: Integer;
  460.   dli: TRVDrawLineInfo; Printing: Boolean; Canvas: TCanvas;
  461.   RVData: TPersistent; sad: PRVScreenAndDevice;
  462.   var HShift, Desc: Integer; NoCaching, Reformatting: Boolean);
  463. var Oh: Integer;
  464. begin
  465.   CalcSize(Canvas, RVData, dli.Width, dli.Height, Desc, Oh, sad, False, HShift, dli.SpaceBefore);
  466.   if not Printing then begin
  467.     FWidth := dli.Width;
  468.     FHeight := dli.Height;
  469.     FDescent  := Desc;
  470.     FOverhang := Oh;
  471.   end;
  472. end;
  473. {------------------------------------------------------------------------------}
  474. procedure TRVMarkerItemInfo.CalcDisplayString(RVStyle: TRVStyle;
  475.    List: TRVMarkerList; Index: Integer);
  476. var LevelInfo: TRVListLevel;
  477.   {.......................................................}
  478.   function IntToRoman(Value: Integer): String;
  479.   const
  480.     Arabics: Array[0..12] of Integer =
  481.     (1,4,5,9,10,40,50,90,100,400,500,900,1000);
  482.     Romans:  Array[0..12] of String =
  483.     ('I','IV','V','IX','X','XL','L','XC','C','CD','D','CM','M');
  484.   var i: Integer;
  485.   begin
  486.     if Value<1 then begin
  487.       Result := '?';
  488.       exit;
  489.     end;
  490.     Result := '';
  491.     for i := 12 downto 0 do
  492.       while (Value >= Arabics[i]) do begin
  493.         Value := Value - Arabics[i];
  494.         Result := Result + Romans[i];
  495.       end;
  496.   end;
  497.   {.......................................................}
  498.   function Number2Str(Value: Integer; ListType: TRVListType): String;
  499.   const CharCount = ord('z')-ord('a')+1;
  500.   var FirstCharCode: Integer;
  501.   begin
  502.     case ListType of
  503.       rvlstDecimal, rvlstImageListCounter:
  504.         Result := IntToStr(Value);
  505.       rvlstLowerAlpha, rvlstUpperAlpha:
  506.         begin
  507.            Result := '';
  508.            if ListType=rvlstLowerAlpha then
  509.              FirstCharCode := ord('a')
  510.            else
  511.              FirstCharCode := ord('A');
  512.            while Value>0 do begin
  513.              Result := Chr((Value-1) mod CharCount+FirstCharCode)+Result;
  514.              Value := (Value-1) div CharCount;
  515.            end;
  516.         end;
  517.       rvlstUpperRoman:
  518.         Result := IntToRoman(Value);
  519.       rvlstLowerRoman:
  520.         Result := LowerCase(IntToRoman(Value));
  521.       else
  522.         Result := '';
  523.     end;
  524.   end;
  525.   {.......................................................}
  526.   function MultiLevelList : String;
  527.   var CountersVal: array [0..255] of TVarRec;
  528.       CountersStr: array [0..255] of String;
  529.       ParentIndex, CurIndex, i: Integer;
  530.       ALevelInfo: TRVListLevel;
  531.       ParentLevelNo, CurLevelNo : Integer;
  532.       ParentList, CurList: TRVMarkerList;
  533.       Marker: TRVMarkerItemInfo;
  534.       LegalStyle : Boolean;
  535.       ListType : TRVListType;
  536.   begin
  537.     LegalStyle := rvloLegalStyleNumbering in LevelInfo.Options;
  538.     CurLevelNo := Level;
  539.     Marker  := Self;
  540.     ALevelInfo := LevelInfo;
  541.     CurIndex := Index;
  542.     CurList  := List;
  543.     while True do begin
  544.       ListType := ALevelInfo.ListType;
  545.       if (CurLevelNo<Level) and (ListType in [rvlstLowerRoman, rvlstUpperRoman, rvlstLowerAlpha, rvlstUpperAlpha]) and
  546.          LegalStyle then
  547.         ListType := rvlstDecimal;
  548.       CountersStr[CurLevelNo]             := Number2Str(Marker.Counter, ListType);
  549.       if CountersStr[CurLevelNo]<>'' then
  550.         CountersVal[CurLevelNo].VAnsiString := PChar(CountersStr[CurLevelNo])
  551.       else
  552.         CountersVal[CurLevelNo].VAnsiString := nil;
  553.       CountersVal[CurLevelNo].VType       := vtAnsiString;
  554.       if CurLevelNo=0 then
  555.         break;
  556.       if CurList.FindParentMarker(CurIndex, nil, ParentList, ParentIndex) then begin
  557.         Marker     := TRVMarkerItemInfo(ParentList.Items[ParentIndex]);
  558.         ALevelInfo := Marker.GetLevelInfo(RVStyle);
  559.         ParentLevelNo := Marker.Level;
  560.         end
  561.       else begin
  562.         Marker     := nil;
  563.         ALevelInfo := nil;
  564.         ParentLevelNo := -1;
  565.       end;
  566.       for i := CurLevelNo-1 downto ParentLevelNo+1 do begin
  567.         with GetLevelInfoEx(RVStyle,i) do
  568.           CountersStr[i]  := Number2Str(StartFrom, ListType);
  569.         if CountersStr[i]<>'' then
  570.           CountersVal[i].VAnsiString := PChar(CountersStr[i])
  571.         else
  572.           CountersVal[i].VAnsiString := nil;
  573.         CountersVal[i].VType       := vtAnsiString;
  574.       end;
  575.       if ParentLevelNo<0 then
  576.         break;
  577.       CurLevelNo := ParentLevelNo;
  578.       CurIndex   := ParentIndex;
  579.       CurList    := ParentList;
  580.     end;
  581.     Result := Format(LevelInfo.FormatString, CountersVal);
  582.   end;
  583.   {.......................................................}
  584. begin
  585.   LevelInfo := GetLevelInfo(RVStyle);
  586.   case LevelInfo.ListType of
  587.     rvlstBullet:
  588.       DisplayString := LevelInfo.FormatString;
  589.     {$IFNDEF RVDONOTUSEUNICODE}
  590.     rvlstUnicodeBullet:
  591.       DisplayString := ''; // RVU_UnicodeToAnsi(RVStyle.DefCodePage, PChar(Pointer(LevelInfo.FormatStringW)))
  592.     {$ENDIF}
  593.     rvlstPicture, rvlstImageList, rvlstImageListCounter:
  594.       DisplayString := '';
  595.     else
  596.       DisplayString := MultiLevelList;
  597.   end;
  598. end;
  599. {------------------------------------------------------------------------------}
  600. procedure TRVMarkerItemInfo.Paint(x, y: Integer; Canvas: TCanvas;
  601.   State: TRVItemDrawStates; Style: TRVStyle; dli: TRVDrawLineInfo);
  602. begin
  603.   DoPaint(x, y, Canvas, State, Style, dli, rvcmColor);
  604. end;
  605. {------------------------------------------------------------------------------}
  606. procedure TRVMarkerItemInfo.DoPaint(x, y: Integer; Canvas: TCanvas;
  607.   State: TRVItemDrawStates; Style: TRVStyle; dli: TRVDrawLineInfo;
  608.   ColorMode: TRVColorMode);
  609. var LevelInfo: TRVListLevel;
  610.     Index: Integer;
  611. begin
  612.   if (ListNo<0) or (Level<0) then
  613.     exit;
  614.   Canvas.Pen.Color := clRed;
  615.   if dli<>nil then
  616.     inc(x, dli.SpaceBefore);
  617.   LevelInfo := GetLevelInfo(TRVStyle(Style));
  618.   case LevelInfo.ListType of
  619.     rvlstPicture:
  620.       begin
  621.         if LevelInfo.HasPicture then
  622.           Canvas.Draw(X,Y, LevelInfo.Picture.Graphic);
  623.       end;
  624.     rvlstImageList, rvlstImageListCounter:
  625.       begin
  626.         Index := LevelInfo.ImageIndex;
  627.         if LevelInfo.ListType = rvlstImageListCounter then
  628.           inc(Index, Counter-1);
  629.         if (LevelInfo.ImageList<>nil) and (Index>=0) and (Index<LevelInfo.ImageList.Count) then
  630.           LevelInfo.ImageList.Draw(Canvas, X,Y, Index);
  631.       end;
  632.     {$IFNDEF RVDONOTUSEUNICODE}
  633.     {$IFDEF RICHVIEWCBDEF3}
  634.     rvlstUnicodeBullet:
  635.       begin
  636.         Canvas.Font := LevelInfo.Font;
  637.         Canvas.Font.Color := RV_GetColor(Canvas.Font.Color, ColorMode);
  638.         if (Style.TextStyles.PixelsPerInch<>0) and (LevelInfo.Font.Size>0) then
  639.           Canvas.Font.Height := - MulDiv(LevelInfo.Font.Size, Style.TextStyles.PixelsPerInch, 72);
  640.         {$IFNDEF RVDONOTUSECHARSPACING}
  641.         SetTextCharacterExtra(Canvas.Handle, 0);
  642.         {$ENDIF}
  643.         SetTextAlign(Canvas.Handle, TA_LEFT);
  644.         Canvas.Brush.Style := bsClear;
  645.         TextOutW(Canvas.Handle, X,Y, Pointer(LevelInfo.FormatStringW), Length(LevelInfo.FormatStringW));
  646.       end;
  647.     {$ENDIF}
  648.     {$ENDIF}
  649.     else
  650.       begin
  651.         Canvas.Font := LevelInfo.Font;
  652.         Canvas.Font.Color := RV_GetColor(Canvas.Font.Color, ColorMode);        
  653.         if (Style.TextStyles.PixelsPerInch<>0) and (LevelInfo.Font.Size>0) then
  654.           Canvas.Font.Height := - MulDiv(LevelInfo.Font.Size, Style.TextStyles.PixelsPerInch, 72);
  655.         {$IFNDEF RVDONOTUSECHARSPACING}
  656.         SetTextCharacterExtra(Canvas.Handle, 0);
  657.         {$ENDIF}
  658.         SetTextAlign(Canvas.Handle, TA_LEFT);
  659.         Canvas.Brush.Style := bsClear;
  660.         Canvas.TextOut(X,Y, DisplayString);
  661.       end;
  662.   end;
  663. end;
  664. {------------------------------------------------------------------------------}
  665. procedure TRVMarkerItemInfo.Print(Canvas: TCanvas; x, y, x2: Integer;
  666.   Preview, Correction: Boolean; const sad: TRVScreenAndDevice;
  667.   RichView: TRVScroller; dli: TRVDrawLineInfo; Part: Integer;
  668.   ColorMode: TRVColorMode; RVData: TPersistent);
  669. begin
  670.   DoPaint(x, y, Canvas, [], TCustomRichView(RichView).Style, dli, ColorMode);
  671. end;
  672. {------------------------------------------------------------------------------}
  673. function TRVMarkerItemInfo.PrintToBitmap(Bkgnd: TBitmap; Preview: Boolean; RichView: TRVScroller;
  674.   dli: TRVDrawLineInfo; Part: Integer; ColorMode: TRVColorMode):Boolean;
  675. begin
  676.   DoPaint(0, 0, Bkgnd.Canvas, [], TCustomRichView(RichView).Style, dli, ColorMode);
  677.   Result := True;
  678. end;
  679. {------------------------------------------------------------------------------}
  680. function TRVMarkerItemInfo.GetImageHeight(RVStyle: TRVStyle): Integer;
  681. var LevelInfo: TRVListLevel;
  682. begin
  683.   Result := 0;
  684.   LevelInfo := GetLevelInfo(RVStyle);
  685.   case LevelInfo.ListType of
  686.     rvlstImageList, rvlstImageListCounter:
  687.       if LevelInfo.ImageList<>nil then
  688.         Result := TImageList(LevelInfo.ImageList).Height;
  689.     rvlstPicture:
  690.       if LevelInfo.HasPicture then
  691.         Result := LevelInfo.Picture.Graphic.Height;
  692.   end;
  693. end;
  694. {------------------------------------------------------------------------------}
  695. function TRVMarkerItemInfo.GetImageWidth(RVStyle: TRVStyle): Integer;
  696. var LevelInfo: TRVListLevel;
  697. begin
  698.   Result := 0;
  699.   LevelInfo := GetLevelInfo(RVStyle);
  700.   case LevelInfo.ListType of
  701.     rvlstImageList, rvlstImageListCounter:
  702.       if LevelInfo.ImageList<>nil then
  703.         Result := TImageList(LevelInfo.ImageList).Width;
  704.         // Result := FWidth;
  705.     rvlstPicture:
  706.       if LevelInfo.HasPicture then
  707.         Result := LevelInfo.Picture.Graphic.Width;
  708.         //Result := FWidth;
  709.   end;
  710. end;
  711. {------------------------------------------------------------------------------}
  712. {$IFNDEF RVDONOTUSERTF}
  713. procedure TRVMarkerItemInfo.FillRTFTables(ColorList: TRVColorList;
  714.   ListOverrideCountList: TRVIntegerList; RVData: TPersistent);
  715. var LevelInfo: TRVListLevel;
  716. begin
  717.   if not Reset or (ListNo<0) or (Level<0) then
  718.     exit;
  719.   LevelInfo := GetLevelInfo(TCustomRVData(RVData).GetRVStyle);
  720.   if LevelInfo=nil then
  721.     exit;
  722.   if LevelInfo.HasNumbering and (LevelInfo.ListType<>rvlstImageListCounter) then
  723.     ListOverrideCountList[ListNo] := ListOverrideCountList[ListNo]+1;
  724. end;
  725. {------------------------------------------------------------------------------}
  726. procedure TRVMarkerItemInfo.SaveRTF(Stream: TStream; const Path: String;
  727.   RVData: TPersistent; ItemNo: Integer; const Name: String; TwipsPerPixel: Double;
  728.   Level: Integer; ColorList: TRVColorList;
  729.   StyleToFont, ListOverrideOffsetsList1, ListOverrideOffsetsList2: TRVIntegerList;
  730.   FontTable: TRVList);
  731. var LevelInfo: TRVListLevel;
  732.    {$IFNDEF RVDONOTUSEUNICODE}
  733.    {$IFDEF RICHVIEWCBDEF3}
  734.     s: String;
  735.    {$ENDIF}
  736.    {$ENDIF}
  737.    ListOverrideNo: Integer;
  738. begin
  739.   LevelInfo := GetLevelInfo(TCustomRVData(RVData).GetRVStyle);
  740.   if LevelInfo=nil then
  741.     exit;
  742.   case LevelInfo.ListType of
  743.     rvlstPicture:
  744.       RVSaveImageToRTF(Stream,TwipsPerPixel, LevelInfo.Picture.Graphic,
  745.         0, 0, TCustomRVData(RVData).RTFOptions);
  746.     rvlstImageList:
  747.       RVSaveImageListImageToRTF(Stream, TwipsPerPixel, LevelInfo.ImageList,
  748.         LevelInfo.ImageIndex, TCustomRVData(RVData).RTFOptions);
  749.     rvlstImageListCounter:
  750.       RVSaveImageListImageToRTF(Stream, TwipsPerPixel, LevelInfo.ImageList,
  751.         LevelInfo.ImageIndex+Counter-1, TCustomRVData(RVData).RTFOptions);
  752.     else
  753.       begin
  754.         RVFWrite(Stream, '{listtextpardplain');
  755.         RVSaveFontToRTF(Stream, LevelInfo.Font, ColorList, TRVRTFFontTable(FontTable),
  756.           TCustomRVData(RVData).GetRVStyle);
  757.         RVFWrite(Stream, ' ');
  758.         {$IFNDEF RVDONOTUSEUNICODE}
  759.         {$IFDEF RICHVIEWCBDEF3}
  760.         if LevelInfo.ListType=rvlstUnicodeBullet then begin
  761.           SetLength(s, Length(LevelInfo.FormatStringW)*2);
  762.           Move(Pointer(LevelInfo.FormatStringW)^, Pointer(s)^, Length(s));
  763.           RVWriteUnicodeRTFStr(Stream, s, TCustomRVData(RVData).GetRVStyle.DefCodePage,
  764.           rvrtfDuplicateUnicode in TCustomRVData(RVData).RTFOptions, False);
  765.           end
  766.         else
  767.         {$ENDIF}
  768.         {$ENDIF}
  769.         begin
  770.           RVFWrite(Stream, RVMakeRTFStr(DisplayString, False, False))
  771.         end;
  772.         if Reset and LevelInfo.HasNumbering then begin
  773.           ListOverrideOffsetsList1[ListNo] := ListOverrideOffsetsList1[ListNo]+1;
  774.           ListOverrideNo := ListOverrideOffsetsList1[ListNo];
  775.           end
  776.         else
  777.           ListOverrideNo := ListOverrideOffsetsList2[ListNo];
  778.         RVFWrite(Stream, Format('tab}ls%dilvl%d ', [ListOverrideNo, Self.Level]));
  779.       end;
  780.   end;
  781. end;
  782. {$ENDIF}
  783. {------------------------------------------------------------------------------}
  784. {$IFNDEF RVDONOTUSEHTML}
  785. procedure TRVMarkerItemInfo.HTMLOpenOrCloseTags(Stream: TStream;
  786.   OldLevelNo, NewLevelNo: Integer; RVStyle: TRVStyle; UseCSS: Boolean);
  787. var i: Integer;
  788.     LevelInfo: TRVListLevel;
  789. begin
  790.   for i := OldLevelNo downto NewLevelNo+1 do begin
  791.     LevelInfo := GetLevelInfoEx(RVStyle,i);
  792.     LevelInfo.HTMLCloseTag(Stream, UseCSS);
  793.   end;
  794.   for i := OldLevelNo+1 to NewLevelNo do begin
  795.     LevelInfo := GetLevelInfoEx(RVStyle,i);
  796.     LevelInfo.HTMLOpenTag(Stream, UseCSS);
  797.   end;
  798.   if OldLevelNo<>NewLevelNo then
  799.     RVFWriteLine(Stream,'');
  800. end;
  801. {------------------------------------------------------------------------------}
  802. procedure TRVMarkerItemInfo.SaveHTMLSpecial(Stream: TStream;
  803.   Prev: TRVMarkerItemInfo; RVStyle: TRVStyle; UseCSS: Boolean);
  804. begin
  805.   if Prev<>nil then
  806.     if Prev.ListNo<>ListNo then begin
  807.       Prev.HTMLOpenOrCloseTags(Stream, Prev.Level, -1, RVStyle, UseCSS);
  808.       HTMLOpenOrCloseTags(Stream, -1, Level, RVStyle, UseCSS)
  809.       end
  810.     else
  811.       Prev.HTMLOpenOrCloseTags(Stream, Prev.Level, Level, RVStyle, UseCSS)
  812.   else
  813.     HTMLOpenOrCloseTags(Stream, -1, Level, RVStyle, UseCSS);
  814. end;
  815. {------------------------------------------------------------------------------}
  816. function GetWingdingsCode(ch: Char): Word;
  817. begin
  818.   case ord(ch) of
  819.     $28: Result := 9742;
  820.     $45: Result := 9756;
  821.     $46: Result := 9758;
  822.     $4A: Result := 9786;
  823.     $52: Result := 9788;
  824.     $5C: Result := 2384;
  825.     $6B: Result := 38;
  826.     $6C: Result := 9679;
  827.     $6D: Result := 9675;
  828.     $6E: Result := 9632;
  829.     $6F..$72,$78..$7A,$7F,$A8,$FD..$FF: Result := 9633;
  830.     $73..$74,$77: Result := 9830;
  831.     $75..$76: Result := 9670;
  832.     $80..$8A: Result := $30+ord(ch)-$80;
  833.     $8B..$95: Result := $30+ord(ch)-$8B;
  834.     $9E: Result := 183;
  835.     $9F: Result := 8226;
  836.     $A0,$A7: Result := 9642;
  837.     $A1..$A3,$A6: Result := 9675;
  838.     $A4..$A5,$B7..$C2: Result := 9678;
  839.     $A9..$B6: Result := 9733;
  840.     $F9..$FA: Result := 9643;
  841.     $D5,$D7,$DB,$DF,$E7,$EF: Result := 9668;
  842.     $D6,$D8,$DC,$E0,$E8,$F0: Result := 9658;
  843.     $D9,$DD,$E1,$E9,$F1: Result := 9650;
  844.     $DA,$DE,$E2,$EA,$F2: Result := 9660;
  845.     else
  846.       Result := 8226;
  847.   end;
  848. end;
  849. {------------------------------------------------------------------------------}
  850. procedure TRVMarkerItemInfo.SaveToHTML(Stream: TStream; RVData: TPersistent;
  851.   ItemNo: Integer; const Text, Path: String;
  852.   const imgSavePrefix: String; var imgSaveNo: Integer;
  853.   CurrentFileColor: TColor; SaveOptions: TRVSaveOptions;
  854.   UseCSS: Boolean; Bullets: TRVList);
  855. var LevelInfo: TRVListLevel;
  856.     DoDefault : Boolean;
  857.     Location, s: String;
  858.     ImageIndex, W,H, i: Integer;
  859.     EncodeText: Boolean;
  860. begin
  861.   if not (rvsoMarkersAsText in SaveOptions) then
  862.     exit;
  863.   LevelInfo := GetLevelInfo(TCustomRVData(RVData).GetRVStyle);
  864.   if LevelInfo=nil then
  865.     exit;
  866.   case LevelInfo.ListType of
  867.     rvlstBullet, rvlstDecimal, rvlstLowerAlpha, rvlstUpperAlpha, rvlstLowerRoman,
  868.     rvlstUpperRoman {$IFNDEF RVDONOTUSEUNICODE}, rvlstUnicodeBullet{$ENDIF}:
  869.       begin
  870.         EncodeText :=
  871.         {$IFNDEF RVDONOTUSEUNICODE}
  872.           (LevelInfo.ListType<>rvlstUnicodeBullet) and
  873.         {$ENDIF}
  874.           ((AnsiCompareText(LevelInfo.Font.Name,RVFONT_SYMBOL)=0) or
  875.           (AnsiCompareText(LevelInfo.Font.Name,RVFONT_WINGDINGS)=0));
  876.         if not UseCSS then begin
  877.           s := RV_HTMLOpenFontTag2(LevelInfo.Font,
  878.             TCustomRVData(RVData).GetRVStyle.TextStyles[0], True, SaveOptions);
  879.           if rvsoUTF8 in SaveOptions then
  880.             s := RVU_AnsiToUTF8(CP_ACP, s);
  881.           RVFWrite(Stream, s)
  882.           end
  883.         else begin
  884.           s := RV_GetHTMLFontCSS(LevelInfo.Font, True);
  885.           if rvsoUTF8 in SaveOptions then
  886.             s := RVU_AnsiToUTF8(CP_ACP, s);
  887.           RVFWrite(Stream, Format('<span style="%s', [s]));
  888.           if LevelInfo.MarkerIndent>=LevelInfo.LeftIndent then
  889.             RVFWrite(Stream, Format(' width: %dpx;', // workaround for IE buggy rendering: not saving width for hanging indents
  890.               [LevelInfo.LeftIndent+LevelInfo.FirstIndent-LevelInfo.MarkerIndent]));
  891.           RVFWrite(Stream, '">');
  892.         end;
  893.         {$IFNDEF RVDONOTUSEUNICODE}
  894.         if LevelInfo.ListType=rvlstUnicodeBullet then begin
  895.           {$IFDEF RICHVIEWCBDEF3}
  896.           RVFWrite(Stream, RVU_GetHTMLEncodedUnicode(RVU_GetRawUnicode(LevelInfo.FormatStringW), False))
  897.           {$ENDIF}
  898.           end
  899.         else
  900.         {$ENDIF}
  901.         begin
  902.           if EncodeText then begin
  903.             if AnsiCompareText(LevelInfo.Font.Name,RVFONT_WINGDINGS)=0 then
  904.               for i := 1 to Length(DisplayString) do
  905.                 RVFWrite(Stream, Format('&#%d;', [GetWingdingsCode(DisplayString[i])]))
  906.             else if AnsiCompareText(LevelInfo.Font.Name,RVFONT_SYMBOL)=0 then
  907.               RVFWrite(Stream, RV_MakeHTMLSymbolStr(DisplayString));
  908.             end
  909.           else
  910.             RVFWrite(Stream, DisplayString);
  911.         end;
  912.         if not UseCSS then
  913.           RVFWriteLine(Stream,RV_HTMLCloseFontTag2(LevelInfo.Font,
  914.             TCustomRVData(RVData).GetRVStyle.TextStyles[0], True))
  915.         else
  916.           RVFWriteLine(Stream,'</span>');
  917.       end;
  918.     rvlstImageList,rvlstImageListCounter:
  919.       begin
  920.         TCustomRVData(RVData).HTMLSaveImage(TCustomRVData(RVData), ItemNo, Path, CurrentFileColor, Location, DoDefault);
  921.         if DoDefault then begin
  922.           ImageIndex := LevelInfo.ImageIndex;
  923.           if LevelInfo.ListType=rvlstImageListCounter then
  924.             inc(ImageIndex, Counter-1);
  925.           if (ImageIndex>=0) and (ImageIndex<LevelInfo.ImageList.Count) and
  926.              (LevelInfo.ImageList<>nil) then begin
  927.             RVSaveImageSharedImageInHTML(LevelInfo.ImageList, ImageIndex, nil, Location, RVData, Path,
  928.               imgSavePrefix, imgSaveNo, CurrentFileColor, SaveOptions, Bullets);
  929.           end;
  930.         end;
  931.         if UseCSS and (LevelInfo.MarkerIndent>=LevelInfo.LeftIndent) then
  932.           RVFWrite(Stream, Format('<span style="width:%dpx">',
  933.             [LevelInfo.LeftIndent+LevelInfo.FirstIndent-LevelInfo.MarkerIndent]));
  934.         if Location<>'' then begin
  935.           if LevelInfo.ImageList=nil then begin
  936.             W := 0;
  937.             H := 0;
  938.             Exclude(SaveOptions, rvsoImageSizes);
  939.             end
  940.           else begin
  941.             W := TImageList(LevelInfo.ImageList).Width;
  942.             H := TImageList(LevelInfo.ImageList).Height;
  943.           end;
  944.           RVFWriteLine(Stream,
  945.             Format('<img%ssrc="%s"%s>',[RV_GetExtraIMGStr(SaveOptions, W, H, NoHTMLImageSize),
  946.               Location, RV_HTMLGetEndingSlash(SaveOptions)]));
  947.         end;
  948.         if UseCSS and (LevelInfo.MarkerIndent>=LevelInfo.LeftIndent) then
  949.           RVFWrite(Stream, Format('</span>',
  950.             [LevelInfo.LeftIndent+LevelInfo.FirstIndent-LevelInfo.MarkerIndent]));
  951.       end;
  952.     rvlstPicture:
  953.       begin
  954.         TCustomRVData(RVData).HTMLSaveImage(TCustomRVData(RVData), ItemNo, Path, CurrentFileColor, Location, DoDefault);
  955.         if DoDefault and (LevelInfo.Picture.Graphic<>nil) then
  956.           RVSaveImageSharedImageInHTML(nil, -1, LevelInfo.Picture.Graphic, Location, RVData, Path,
  957.             imgSavePrefix, imgSaveNo, CurrentFileColor, SaveOptions, Bullets);
  958.         if Location<>'' then begin
  959.           if LevelInfo.Picture.Graphic=nil then begin
  960.             W := 0;
  961.             H := 0;
  962.             Exclude(SaveOptions, rvsoImageSizes);
  963.             end
  964.           else begin
  965.             W := LevelInfo.Picture.Graphic.Width;
  966.             H := LevelInfo.Picture.Graphic.Height;
  967.           end;
  968.           RVFWriteLine(Stream,
  969.             Format('<img%ssrc="%s"%s>',
  970.               [RV_GetExtraIMGStr(SaveOptions, W, H, NoHTMLImageSize),Location,
  971.                RV_HTMLGetEndingSlash(SaveOptions)]));
  972.         end;
  973.       end;
  974.   end
  975. end;
  976. {------------------------------------------------------------------------------}
  977. function TRVMarkerItemInfo.GetLICSS(RVData: TPersistent; ItemNo: Integer; const Path,
  978.         imgSavePrefix: String; var imgSaveNo: Integer; CurrentFileColor: TColor;
  979.         SaveOptions: TRVSaveOptions; Bullets: TRVList): String;
  980. var LevelInfo: TRVListLevel;
  981.     DoDefault : Boolean;
  982.     Location: String;
  983.     ImageIndex: Integer;
  984. begin
  985.   Result := '';
  986.   LevelInfo := GetLevelInfo(TCustomRVData(RVData).GetRVStyle);
  987.   case LevelInfo.ListType of
  988.     rvlstImageList,rvlstImageListCounter:
  989.       begin
  990.         TCustomRVData(RVData).HTMLSaveImage(TCustomRVData(RVData), ItemNo, Path, CurrentFileColor, Location, DoDefault);
  991.         if DoDefault then begin
  992.           ImageIndex := LevelInfo.ImageIndex;
  993.           if LevelInfo.ListType=rvlstImageListCounter then
  994.             inc(ImageIndex, Counter-1);
  995.           if (ImageIndex>=0) and (ImageIndex<LevelInfo.ImageList.Count) and
  996.              (LevelInfo.ImageList<>nil) then begin
  997.             RVSaveImageSharedImageInHTML(LevelInfo.ImageList, ImageIndex, nil, Location, RVData, Path,
  998.               imgSavePrefix, imgSaveNo, CurrentFileColor, SaveOptions, Bullets);
  999.           end;
  1000.         end;
  1001.         if Location<>'' then
  1002.           Result := Format('list-style-image: url(''%s'')',[Location]);
  1003.       end;
  1004.     rvlstPicture:
  1005.       begin
  1006.         TCustomRVData(RVData).HTMLSaveImage(TCustomRVData(RVData), ItemNo, Path, CurrentFileColor, Location, DoDefault);
  1007.         if DoDefault and (LevelInfo.Picture.Graphic<>nil) then
  1008.             RVSaveImageSharedImageInHTML(nil, -1, LevelInfo.Picture.Graphic, Location, RVData, Path,
  1009.               imgSavePrefix, imgSaveNo, CurrentFileColor, SaveOptions, Bullets);
  1010.         if Location<>'' then
  1011.           Result := Format('list-style-image: url(''%s'')',[Location]);
  1012.       end;
  1013.   end;
  1014.   if TCustomRVData(RVData).GetRVStyle.ParaStyles[ParaNo].LeftIndent<>0 then begin
  1015.     if Result<>'' then
  1016.       Result := Result+'; ';
  1017.     Result := Result+'margin-left: 0';
  1018.   end;
  1019.   if Result<>'' then
  1020.     Result := Format(' style="{ %s }"', [Result]);
  1021. end;
  1022. {$ENDIF}
  1023. {------------------------------------------------------------------------------}
  1024. procedure TRVMarkerItemInfo.MarkStylesInUse(Data: TRVDeleteUnusedStylesData);
  1025. begin
  1026.   inherited;
  1027.   if ListNo>=0 then
  1028.     Data.UsedListStyles[ListNo] := 1;
  1029. end;
  1030. {------------------------------------------------------------------------------}
  1031. procedure TRVMarkerItemInfo.UpdateStyles(Data: TRVDeleteUnusedStylesData);
  1032. begin
  1033.   inherited;
  1034.   if ListNo>=0 then
  1035.     dec(ListNo, Data.UsedListStyles[ListNo]-1);
  1036. end;
  1037. {------------------------------------------------------------------------------}
  1038. function ProcessSymbolString(const s: String): String;
  1039. var i: Integer;
  1040. begin
  1041.   Result := s;
  1042.   for i := 1 to Length(s) do begin
  1043.     if Result[i] in [#$A7..#$AA,#$B7,#$D7,#$E0] then
  1044.       Result[i] := '*';
  1045.   end;
  1046.   RV_ReplaceStr(Result,#$DB,'<=>');
  1047.   RV_ReplaceStr(Result,#$DC,'<=');
  1048.   RV_ReplaceStr(Result,#$DE,'=>');
  1049.   RV_ReplaceStr(Result,#$AB,'<->');
  1050.   RV_ReplaceStr(Result,#$AC,'<-');
  1051.   RV_ReplaceStr(Result,#$AE,'->');
  1052. end;
  1053. {------------------------------------------------------------------------------}
  1054. function TRVMarkerItemInfo.AsText(LineWidth: Integer; RVData: TPersistent;
  1055.   const Text, Path: String; TextOnly, Unicode: Boolean): String;
  1056. var LevelInfo: TRVListLevel;
  1057.   {$IFNDEF RVDONOTUSEUNICODE}
  1058.     i: Integer;
  1059.   {$ENDIF}
  1060. begin
  1061.   Result := '';
  1062.   LevelInfo := GetLevelInfo(TCustomRVData(RVData).GetRVStyle);
  1063.   case LevelInfo.ListType of
  1064.     rvlstBullet,rvlstDecimal,rvlstLowerAlpha,rvlstUpperAlpha,
  1065.     rvlstLowerRoman,rvlstUpperRoman:
  1066.       begin
  1067.         if (AnsiCompareText(LevelInfo.Font.Name,RVFONT_SYMBOL)=0) then
  1068.           Result := ProcessSymbolString(DisplayString)
  1069.         else
  1070.           Result := DisplayString;
  1071.         Result := Result+' ';
  1072.         if Unicode then
  1073.           Result := RVU_AnsiToUnicode(CP_ACP, Result)
  1074.       end;
  1075.     rvlstPicture,rvlstImageList,rvlstImageListCounter:
  1076.       begin
  1077.         Result := '* ';
  1078.         if Unicode then
  1079.           Result := RVU_AnsiToUnicode(CP_ACP, Result)
  1080.       end;
  1081.     {$IFNDEF RVDONOTUSEUNICODE}
  1082.     {$IFDEF RICHVIEWCBDEF3}
  1083.     rvlstUnicodeBullet:
  1084.       begin
  1085.         Result := RVU_GetRawUnicode(LevelInfo.FormatStringW+' ');
  1086.         if not Unicode then begin
  1087.           Result := RVU_UnicodeToAnsi(CP_ACP, Result);
  1088.           for i := 1 to Length(Result) do begin
  1089.             if i>Length(LevelInfo.FormatStringW) then
  1090.               break;
  1091.             if (Result[i]='?') and (LevelInfo.FormatStringW[i]<>'?') then
  1092.               Result[i] := '*';
  1093.           end;
  1094.         end;
  1095.       end;
  1096.     {$ENDIF}
  1097.     {$ENDIF}
  1098.   end;
  1099. end;
  1100. {------------------------------------------------------------------------------}
  1101. function TRVMarkerItemInfo.GetIndexInList(List: TList): Integer;
  1102. begin
  1103.   if List=nil then begin
  1104.     Result := -1;
  1105.     exit;
  1106.   end;
  1107.   if (FCachedIndexInList<0) or (FCachedIndexInList>=List.Count) or
  1108.      (List.Items[FCachedIndexInList]<>Self) then
  1109.     FCachedIndexInList := List.IndexOf(Self);
  1110.   Result := FCachedIndexInList;
  1111. end;
  1112. {------------------------------------------------------------------------------}
  1113. function TRVMarkerItemInfo.GetRVFExtraPropertyCount: Integer;
  1114. begin
  1115.   Result := inherited GetRVFExtraPropertyCount;
  1116.   if NoHTMLImageSize then
  1117.     inc(Result);
  1118. end;
  1119. {------------------------------------------------------------------------------}
  1120. procedure TRVMarkerItemInfo.SaveRVFExtraProperties(Stream: TStream);
  1121. begin
  1122.   inherited SaveRVFExtraProperties(Stream);
  1123.   if NoHTMLImageSize then
  1124.     WriteRVFExtraIntPropertyStr(Stream, rvepNoHTMLImageSize, 1);
  1125. end;
  1126. {------------------------------------------------------------------------------}
  1127. function TRVMarkerItemInfo.GetExtraIntProperty(Prop: TRVExtraItemProperty;
  1128.   var Value: Integer): Boolean;
  1129. begin
  1130.   case Prop of
  1131.     rvepNoHTMLImageSize:
  1132.       begin
  1133.         Value := ord(NoHTMLImageSize);
  1134.         Result := True;
  1135.       end;
  1136.     else
  1137.       Result := inherited GetExtraIntProperty(Prop, Value);
  1138.   end;
  1139. end;
  1140. {------------------------------------------------------------------------------}
  1141. function TRVMarkerItemInfo.SetExtraIntProperty(Prop: TRVExtraItemProperty;
  1142.   Value: Integer): Boolean;
  1143. begin
  1144.   case Prop of
  1145.     rvepNoHTMLImageSize:
  1146.       begin
  1147.         NoHTMLImageSize := Value<>0;
  1148.         Result := True;
  1149.       end;
  1150.     else
  1151.       Result := inherited SetExtraIntProperty(Prop, Value);
  1152.   end;
  1153. end;
  1154. {=============================== TRVMarkerList ================================}
  1155. function TRVMarkerList.FindParentMarker(Index: Integer;
  1156.   Marker: TRVMarkerItemInfo; var ParentList: TRVMarkerList;
  1157.   var ParentIndex: Integer): Boolean;
  1158. var Marker2: TRVMarkerItemInfo;
  1159.     i: Integer;
  1160. begin
  1161.   if Marker=nil then
  1162.     Marker := TRVMarkerItemInfo(Items[Index]);
  1163.   for i := Index-1 downto 0 do begin
  1164.     Marker2 := TRVMarkerItemInfo(Items[i]);
  1165.     if (Marker2.ListNo = Marker.ListNo) and
  1166.        (Marker2.Level<Marker.Level) then begin
  1167.       ParentIndex := i;
  1168.       ParentList  := Self;
  1169.       Result := True;
  1170.       exit;
  1171.     end;
  1172.   end;
  1173.   if PrevMarkerList<>nil then
  1174.     Result := PrevMarkerList.FindParentMarker(PrevMarkerList.Count, Marker,
  1175.       ParentList, ParentIndex)
  1176.   else begin
  1177.     Result := False;
  1178.     ParentIndex := -1;
  1179.     ParentList  := nil;
  1180.   end;
  1181. end;
  1182. {------------------------------------------------------------------------------}
  1183. function TRVMarkerList.InsertAfter(InsertMe, AfterMe: TRVMarkerItemInfo): Integer;
  1184. begin
  1185.   if AfterMe = nil then
  1186.     Result := 0
  1187.   else
  1188.     Result := AfterMe.GetIndexInList(Self)+1;
  1189.   Insert(Result, InsertMe);
  1190.   InsertMe.FCachedIndexInList := Result;
  1191. end;
  1192. {------------------------------------------------------------------------------}
  1193. procedure TRVMarkerList.RecalcCounters(StartFrom: Integer; RVStyle: TRVStyle);
  1194. var i,j, ListNo: Integer;
  1195.     LevelReset: Boolean;
  1196.     Marker, Markerj: TRVMarkerItemInfo;
  1197.     LevelInfo: TRVListLevel;
  1198. begin
  1199.   if StartFrom>=Count then
  1200.     exit;
  1201.   ListNo := TRVMarkerItemInfo(Items[StartFrom]).ListNo;
  1202.   if ListNo<0 then
  1203.     exit;
  1204.   for i := StartFrom to Count-1 do begin
  1205.     Marker := TRVMarkerItemInfo(Items[i]);
  1206.     if Marker.ListNo=ListNo then begin
  1207.       if Marker.Reset then
  1208.         Marker.Counter := Marker.StartFrom
  1209.       else begin
  1210.         LevelInfo := TRVMarkerItemInfo(Items[i]).GetLevelInfo(RVStyle);
  1211.         Marker.Counter := LevelInfo.StartFrom;
  1212.         LevelReset := rvloLevelReset in LevelInfo.Options;
  1213.         for j := i-1 downto 0 do begin
  1214.           Markerj := TRVMarkerItemInfo(Items[j]);
  1215.           if Markerj.ListNo=ListNo then
  1216.             if Markerj.Level=Marker.Level then begin
  1217.               Marker.Counter := Markerj.Counter+1;
  1218.               break;
  1219.               end
  1220.             else if LevelReset and (Markerj.Level<Marker.Level) then begin
  1221.               Marker.Counter := LevelInfo.StartFrom;
  1222.               break;
  1223.               end
  1224.             else if (Markerj.Level>Marker.Level) then
  1225.               Marker.Counter := LevelInfo.StartFrom+1;
  1226.         end;
  1227.       end;
  1228.       Marker.CalcDisplayString(RVStyle, Self, i);
  1229.     end;
  1230.   end;
  1231. end;
  1232. {------------------------------------------------------------------------------}
  1233. procedure TRVMarkerList.RecalcDisplayStrings(RVStyle: TRVStyle);
  1234. var i: Integer;
  1235. begin
  1236.   for i := 0 to Count-1 do
  1237.     TRVMarkerItemInfo(Items[i]).CalcDisplayString(RVStyle, Self, i);
  1238. end;
  1239. {------------------------------------------------------------------------------}
  1240. procedure TRVMarkerList.LoadFromStream(Stream: TStream; RVData: TPersistent;
  1241.  IncludeSize: Boolean);
  1242. var i,c: Integer;
  1243.     ListNo, Level: Integer;
  1244.     Counter: Integer;
  1245.     Reset: Boolean;
  1246.     StartFrom: Integer;
  1247.     Marker: TRVMarkerItemInfo;
  1248. begin
  1249.   Clear;
  1250.   if IncludeSize then begin
  1251.     Stream.ReadBuffer(c, sizeof(c));
  1252.   end;
  1253.   Stream.ReadBuffer(c, sizeof(c));
  1254.   Stream.ReadBuffer(c, sizeof(c));
  1255.   Capacity := c;
  1256.   for i := 0 to c-1 do begin
  1257.     Stream.ReadBuffer(ListNo, sizeof(ListNo));
  1258.     Stream.ReadBuffer(Level, sizeof(Level));
  1259.     Stream.ReadBuffer(Reset, sizeof(Reset));
  1260.     Stream.ReadBuffer(StartFrom, sizeof(StartFrom));
  1261.     Stream.ReadBuffer(Counter, sizeof(Counter));
  1262.     Marker := TRVMarkerItemInfo.CreateEx(RVData, ListNo, Level, StartFrom, Reset);
  1263.     Marker.Counter := Counter;
  1264.     Add(Marker);
  1265.   end;
  1266. end;
  1267. {------------------------------------------------------------------------------}
  1268. procedure TRVMarkerList.SaveToStream(Stream: TStream; Count: Integer;
  1269.  IncludeSize: Boolean);
  1270. var i: Integer;
  1271. begin
  1272.   if IncludeSize then begin
  1273.     i := sizeof(Integer)*(1+1+Count*4)+sizeof(Boolean)*Count;
  1274.     Stream.WriteBuffer(i, sizeof(i));
  1275.   end;
  1276.   i := 0;
  1277.   Stream.WriteBuffer(i, sizeof(i));
  1278.   Stream.WriteBuffer(Count, sizeof(Count));
  1279.   for i := 0 to Count-1 do
  1280.     with TRVMarkerItemInfo(Items[i]) do begin
  1281.       Stream.WriteBuffer(ListNo, sizeof(ListNo));
  1282.       Stream.WriteBuffer(Level, sizeof(Level));
  1283.       Stream.WriteBuffer(Reset, sizeof(Reset));
  1284.       Stream.WriteBuffer(StartFrom, sizeof(StartFrom));
  1285.       Stream.WriteBuffer(Counter, sizeof(Counter));
  1286.     end;
  1287. end;
  1288. {------------------------------------------------------------------------------}
  1289. procedure TRVMarkerList.LoadBinary(const s: String; RVData: TPersistent);
  1290. var TmpStream: TMemoryStream;
  1291. begin
  1292.    TmpStream := TMemoryStream.Create;
  1293.    try
  1294.      TmpStream.WriteBuffer(PChar(s)^, Length(s));
  1295.      TmpStream.Position := 0;
  1296.      LoadFromStream(TmpStream, RVData, False);
  1297.    finally
  1298.      TmpStream.Free;
  1299.    end;
  1300. end;
  1301. {------------------------------------------------------------------------------}
  1302. procedure TRVMarkerList.LoadText(const s: String; RVData: TPersistent);
  1303. var TmpStream: TMemoryStream;
  1304. begin
  1305.    TmpStream := TMemoryStream.Create;
  1306.    try
  1307.      RVFTextString2Stream(s, TmpStream);
  1308.      TmpStream.Position := 0;
  1309.      LoadFromStream(TmpStream, RVData, False);
  1310.    finally
  1311.      TmpStream.Free;
  1312.    end;
  1313. end;
  1314. {------------------------------------------------------------------------------}
  1315. procedure TRVMarkerList.SaveTextToStream(Stream: TStream; Count: Integer);
  1316. var TmpStream: TMemoryStream;
  1317.     s: String;
  1318. begin
  1319.    TmpStream := TMemoryStream.Create;
  1320.    try
  1321.      SaveToStream(TmpStream, Count, False);
  1322.      TmpStream.Position := 0;
  1323.      s := RVFStream2TextString(TmpStream);
  1324.      RVFWriteLine(Stream, s);
  1325.    finally
  1326.      TmpStream.Free;
  1327.    end;
  1328. end;
  1329. {$ENDIF}
  1330. end.