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

RichEdit

开发平台:

Delphi

  1. {*******************************************************}
  2. {                                                       }
  3. {       RichView                                        }
  4. {       TCustomRVData is a basic class representing     }
  5. {       RichView document.                              }
  6. {                                                       }
  7. {       Copyright (c) Sergey Tkachenko                  }
  8. {       svt@trichview.com                               }
  9. {       http://www.trichview.com                        }
  10. {                                                       }
  11. {*******************************************************}
  12. unit CRVData;
  13. interface
  14. {$I RV_Defs.inc}
  15. uses
  16.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  17.   {$IFNDEF RVDONOTUSEJPEGIMAGE}
  18.   Jpeg,
  19.   {$ENDIF}
  20.   {$IFNDEF RVDONOTUSELISTS}
  21.   RVMarker,
  22.   {$ENDIF}
  23.   {$IFDEF RICHVIEWDEF4}
  24.   ImgList,
  25.   {$ENDIF}
  26.   RVStyle, RVBack, RVFuncs, RVItem, RVScroll, RVUni, RVClasses,
  27.   RVRTFErr;
  28. type
  29.   { State of RVData }
  30.   TRVState = (
  31.     rvstMakingSelection,     // Mouse selection is in process
  32.     rvstLineSelection,       // Line selection (started from the left margin)
  33.                              //   is in process
  34.     rvstDrawHover,           // There is a highlighted hyperlink
  35.     rvstSkipFormatting,      // Reformatting is not allowed
  36.     rvstIgnoreNextMouseDown, // Next mouse-down event must be ignored
  37.     rvstChangingBkPalette,   // Palette of background image is being updated
  38.                              //   (avoiding recursive call)
  39.     rvstCompletelySelected,  // RVData is completely selected (table cell)
  40.     rvstClearing,            // Document is being cleared
  41.                              //   (avoiding recursive call)
  42.     rvstDoNotMoveChildren,   // Call of AdjustChildrenCoords is not allowed
  43.     rvstForceStyleChangeEvent, // Editor must call events for changing styles
  44.                              //   even if next value assigned to current style
  45.                              //   is equal to the current value
  46.     rvstIgnoreNextChar,      // Next call of WMChar or KeyPress must be ignored
  47.                              //  (the character is already processed in WMKeyDown)
  48.     rvstDoNotTab,            // Next call of DoTabNavigation will be ignored
  49.     rvstDeselecting,         // Deselection is in process
  50.                              //   (avoiding recursive call)
  51.     rvstUnAssigningChosen,   // Unassigning chosen data is in process
  52.                              //   (avoiding recursive call)
  53.     rvstNoScroll,            // Scrolling is not allowed
  54.     rvstFinalizingUndo,      // Avoiding recursive calls of FinalizeUndoGroup
  55.     rvstRTFSkipPar,          // Saving to RTF: do not save paragraph mark
  56.     rvstLoadingAsPartOfItem, // This RVData is loaded from RVF as a part of item
  57.                              //   (cell is loaded with table)
  58.                              //   (not calling AfterLoading(rvlfRVF) for items
  59.                              //   of this RVData: will be called for the container item
  60.     rvstNoKillFocusEvents,   // Disabling processing of WMKillFocus
  61.     rvstEditorUnformatted,   // TRichViewEdit was not formatted before the call of Format
  62.     rvstNameSet,             // TRichView.Name was assigned. Used to detect placing
  63.                              // the component on the form from the Component Palette
  64.     rvstFirstParaAborted,    // This is a page saved and reloaded in ReportHelper,
  65.                              //   and the first paragraph is not completely on this page
  66.     rvstLastParaAborted,     // The same for the last paragraph
  67.     rvstInvalidSelection,    // Selection is not valid: do not create item resizer
  68.     rvstDoNotClearCurTag,    // TRVEditRVData.ChangeEx must not clear "current tag"
  69.                              //   ("current tag" is used in methods for inserting text)
  70.     rvstStartingDragDrop,    // Dragging from this RichView is about to start
  71.                              //   (WM_RVDRAGDROP was posted). Only in absolute
  72.                              //    root RVData
  73.     rvstCanDragDropDeleteSelection, // After dragging from this editor, selection
  74.                              //  must be deleted (set when moving data to
  75.                              //  another control)
  76.     rvstDragDropCursorNotMoved, // Dragging is finished, but cursor was not
  77.                              //  moved (it is not a d&d, it is a simple click on
  78.                              //  the selection)
  79.     rvstKeyPress             // do some special processing related to d&d in keypress
  80.     );
  81.   TRVStates = set of TRVState;
  82.   { Flags for RVData }
  83.   TRVFlag = (
  84.     rvflUseJumps,            // List of hyperlink coords must be maintained
  85.     rvflTrim,                // Formatting routine may not show spaces in line
  86.                              //   wrap places (always set)
  87.     rvflShareContents,       // This RVData uses smb. else's items
  88.     rvflUseExternalLeading,  // Formatting routine uses font external leading
  89.                              // (never set)
  90.     rvflMouseXYAlwaysCorrect,// Mouse processing procedures may not preprocess
  91.                              //   coordinates (used in table cells)
  92.     rvflAllowCustomDrawItems,// Formatting routine may create drawing items
  93.                              // of custom types (not only TRVDrawLineInfo) -
  94.                              // used in RVPrint and RVReportHelper
  95.     rvflPrinting,            // This is RVData with formatting for printing (or
  96.                              //   reports)
  97.     rvflRootEditor,          // This is TRVEditRVData (not RVData of inplace)
  98.     rvflRoot,                // This is TRichViewRVData or TRVEditRVData
  99.                              //  (not RVData of inplace)
  100.     rvflDBRichViewEdit,      // This is TDBRichViewEdit.RVData
  101.     rvflCanUseCustomPPI,     // Allows using RVStyle.TextStyles.PixelsPerInch
  102.     rvflCanProcessGetText);  // Allows processing WM_GETTEXT, WM_SETTEXT, WM_GETTEXTLENGTH
  103.   TRVFlags = set of TRVFlag;
  104.   { Which part to save in RVF? }
  105.   TRVFSaveScope = (
  106.     rvfss_Full,              // document
  107.      rvfss_Selection,        // selection
  108.      rvfss_Page);            // page (for TRVPrint or TRVReportHelper)
  109.   PRVIntegerList = ^TRVIntegerList;
  110.   TRVRTFFontTable = class;
  111.   TCustomRVData = class;
  112.   TRVEnumItemsProc = procedure (RVData: TCustomRVData; ItemNo: Integer;
  113.     var UserData1: Integer; const UserData2: String;
  114.     var ContinueEnum: Boolean) of object;
  115.   { ----------------------------------------------------------------------------
  116.     TRVLayoutInfo: information about document layout for saving and loading in
  117.     RVF.
  118.     Main properties:
  119.     - margins,
  120.     - min- and maxtextwidth,
  121.     - bidimode.
  122.     For saving RVReportHelper page, additional properties:
  123.     - LastParaAborted: <>0 if the last page paragraph is not completely on the page;
  124.     - FirstParaAborted: the same for the first page paragraph;
  125.     - FirstMarkerListNo, FirstMarkerLevel - information about marker of the
  126.       first page paragraph (marker is before this page)
  127.   }
  128.   TRVLayoutInfo = class
  129.     public
  130.       Loaded: Boolean;
  131.       LeftMargin, RightMargin, TopMargin, BottomMargin: Integer;
  132.       MinTextWidth, MaxTextWidth: Integer;
  133.       BiDiMode: TRVBiDiMode;
  134.       LastParaAborted, FirstParaAborted: Integer;
  135.       FirstMarkerListNo, FirstMarkerLevel: Integer;
  136.       constructor Create;
  137.       procedure SaveToStream(Stream: TStream; IncludeSize: Boolean);
  138.       procedure LoadFromStream(Stream: TStream; IncludeSize: Boolean);
  139.       procedure SaveTextToStream(Stream: TStream);
  140.       procedure LoadText(const s: String);
  141.       procedure LoadBinary(const s: String);
  142.   end;
  143.   {$IFNDEF RVDONOTUSEHTML}
  144.   { ----------------------------------------------------------------------------
  145.     TRVHTMLBulletInfo: information for saving shared images in HTML
  146.       (several items can use the same image file).
  147.     Used by: "bullets", "hotspots", list markers with pictures and image lists.
  148.   }
  149.   TRVHTMLBulletInfo = class
  150.     public
  151.       FileName: String;
  152.       ImageList: TCustomImageList;
  153.       ImageIndex: Integer;
  154.       BackColor: TColor;
  155.       Graphic: TGraphic;
  156.   end;
  157.   {$ENDIF}
  158.   { ----------------------------------------------------------------------------
  159.     TRVRTFFontTableItem: item of RTF font table (TRVRTFFontTable)
  160.   }
  161.   TRVRTFFontTableItem = class
  162.     public
  163.       FontName: String;
  164.       {$IFDEF RICHVIEWCBDEF3}
  165.       Charset: TFontCharset;
  166.       {$ENDIF}
  167.   end;
  168.   { ----------------------------------------------------------------------------
  169.     TRVRTFFontTable: RTF font table. Created for saving to RTF, contains all
  170.     fonts used in the document (both by styles and by items)
  171.   }
  172.   TRVRTFFontTable = class (TRVList)
  173.     private
  174.       function Get(Index: Integer): TRVRTFFontTableItem;
  175.       procedure Put(Index: Integer; const Value: TRVRTFFontTableItem);
  176.     public
  177.       function Find(const FontName: String
  178.         {$IFDEF RICHVIEWCBDEF3}; Charset: TFontCharset{$ENDIF}): Integer;
  179.       function AddUnique(const FontName: String
  180.         {$IFDEF RICHVIEWCBDEF3}; Charset: TFontCharset{$ENDIF}): Integer;
  181.       property Items[Index: Integer]: TRVRTFFontTableItem read Get write Put; default;
  182.   end;
  183.   { ----------------------------------------------------------------------------
  184.     TCustomRVData: RichView document. This class is not used directly.
  185.     Direct descendant: TCustomRVFormattedData.
  186.   }
  187.   TCustomRVData = class(TPersistent)
  188.   private
  189.     { Private declarations }
  190.     FFirstJumpNo: Integer;
  191.     FItems: TStringList;
  192.     { Property values }
  193.     function GetPageBreaksBeforeItems(Index: Integer): Boolean;
  194.     procedure SetPageBreaksBeforeItems(Index: Integer;  Value: Boolean);
  195.     function GetItemCount: Integer;
  196.     { HTML & RTF }
  197.     {$IFNDEF RVDONOTUSEHTML}
  198.     function ShouldSaveTextToHTML(StyleNo: Integer): Boolean;
  199.     function GetHTMLATag(ItemNo: Integer; CSS: String; UTF8: Boolean): String;
  200.     {$ENDIF}
  201.     {$IFNDEF RVDONOTUSERTF}
  202.     function ShouldSaveTextToRTF(StyleNo: Integer): Boolean;
  203.     {$ENDIF}
  204.     { Others }
  205.     procedure AddNLTag_(const s: String; StyleNo, ParaNo, Tag: Integer);
  206.     {$IFNDEF RVDONOTUSEUNICODE}
  207.     procedure AddNLATag_(const s: String; StyleNo, ParaNo, Tag: Integer);
  208.     {$ENDIF}
  209.     function AddTextUniversal(const text: String; StyleNo, FirstParaNo, OtherParaNo: Integer;
  210.       AsSingleParagraph, CheckUnicode: Boolean; Tag: Integer): Boolean;
  211.   protected
  212.     { Protected declarations }
  213.     FAllowNewPara: Boolean;
  214.     FirstCP, LastCP, NotAddedCP: TRVCPInfo;
  215.     CPCount: Integer;
  216.     function NextCharStr(const str: String; ItemNo, Index: Integer): Integer;
  217.     function PrevCharStr(const str: String; ItemNo, Index: Integer): Integer;
  218.     function NextChar(ItemNo: Integer; Index: Integer): Integer;
  219.     function PrevChar(ItemNo: Integer; Index: Integer): Integer;
  220.     procedure CheckItemClass(ItemNo: Integer;
  221.       RequiredClass: TCustomRVItemInfoClass);
  222.     function ShareItems: Boolean; dynamic;
  223.     function CanLoadLayout: Boolean; dynamic;
  224.     function GetURL(id: Integer): String; dynamic; abstract;
  225.     function GetOptions: TRVOptions; virtual;
  226.     procedure SetOptions(const Value: TRVOptions); virtual;
  227.     function GetRVFOptions: TRVFOptions; virtual;
  228.     procedure SetRVFOptions(const Value: TRVFOptions); virtual;
  229.     function GetRTFOptions: TRVRTFOptions; virtual;
  230.     procedure SetRTFOptions(const Value: TRVRTFOptions); virtual;
  231.     function GetRVFWarnings: TRVFWarnings; virtual;
  232.     procedure SetRVFWarnings(const Value: TRVFWarnings); virtual;
  233.     function GetDelimiters: String; dynamic;
  234.     function GetRVFTextStylesReadMode: TRVFReaderStyleMode; virtual;
  235.     function GetRVFParaStylesReadMode: TRVFReaderStyleMode; virtual;
  236.     procedure RVFGetLimits(SaveScope: TRVFSaveScope;
  237.       var StartItem, EndItem, StartOffs, EndOffs: Integer;
  238.       var StartPart, EndPart: TRVMultiDrawItemPart); dynamic;
  239.     function GetRTFProperties:TPersistent  {TRVRTFReaderProperties}; dynamic;
  240.     {$IFNDEF RVDONOTUSERVF}
  241.     procedure DoOnStyleReaderError(Reader: TReader; const Message: string;
  242.       var Handled: Boolean);
  243.     function InsertRVFFromStream_(Stream: TStream; var Index: Integer;
  244.       AParaNo: Integer; AllowReplaceStyles, AppendMode, EditFlag: Boolean;
  245.       var Color: TColor; Background: TRVBackground;
  246.       Layout: TRVLayoutInfo; var NonFirstItemsAdded: Integer;
  247.       var Protect, FullReformat: Boolean):Boolean;
  248.     procedure DataWriter(Stream: TStream);
  249.     procedure DataReader(Stream: TStream);
  250.     {$ENDIF}
  251.     procedure NormalizeParas(StartItemNo: Integer);
  252.     procedure InsertCheckpoint(ItemNo, Tag: Integer; const Name: String;
  253.       RaiseEvent: Boolean);
  254.     procedure UpdateCPPos(cp: TRVCPInfo; ItemNo: Integer);
  255.     procedure UnlinkCheckpoint(cp: TRVCPInfo; DecCPCount: Boolean);
  256.     function FindCPBeforeItem(ItemNo: Integer): TRVCPInfo;
  257.     procedure UpdateCPItemNo;
  258.     procedure InternalFreeItem(item: TCustomRVItemInfo; Clearing: Boolean); virtual;
  259.     function IsDelimiter(const s: String; Index: Integer;
  260.       ItemOptions: TRVItemOptions): Boolean;
  261.     function GetItemOptions(ItemNo: Integer): TRVItemOptions;
  262.     procedure Replace0(var s: String);
  263.     function RV_CanConcateItems(FirstItemNo: Integer; item1, item2: TCustomRVItemInfo;
  264.       IgnorePara: Boolean): Boolean;
  265.     procedure SimpleConcate(FirstItemNo: Integer; item1, item2: TCustomRVItemInfo);
  266.     procedure MassSimpleConcate(FirstItemNo, LastItemNo: Integer);
  267.     procedure SimpleConcateSubitems(ItemNo: Integer);
  268.     procedure InitStyleMappings(var PTextStylesMapping, PParaStylesMapping,
  269.       PListStylesMapping: PRVIntegerList); dynamic;
  270.     procedure DoneStyleMappings(PTextStylesMapping, PParaStylesMapping,
  271.       PListStylesMapping: PRVIntegerList); dynamic;
  272.     function SupportsPageBreaks: Boolean; dynamic;
  273.     {$IFNDEF RVDONOTUSEHTML}
  274.     procedure SaveHTMLCheckpoint(Stream: TStream; Checkpoint: TRVCPInfo;
  275.       var cpno: Integer; const Prefix: String; FromNewLine: Boolean;
  276.       Options: TRVSaveOptions);
  277.     function GetTextForHTML(const Path: String; ItemNo: Integer; CSSVersion: Boolean;
  278.       SaveOptions: TRVSaveOptions): String;
  279.     {$ENDIF}
  280.     function GetFirstParaItem(ItemNo: Integer): Integer;
  281.     function GetFirstParaSectionItem(ItemNo: Integer): Integer;
  282.     {$IFNDEF RVDONOTUSELISTS}
  283.     procedure DestroyMarkers; dynamic;
  284.     function FindPreviousMarker(ItemNo: Integer): TRVMarkerItemInfo;
  285.     function FindMarkerLocalLocationFrom(StartItemNo: Integer;
  286.       Marker: TRVMarkerItemInfo): Integer;
  287.     function FindLastMarkerIndex(StartAfterMeIndex: Integer; ListStyles: TRVIntegerList): Integer;
  288.     {$ENDIF}
  289.     function GetFlags: TRVFlags; virtual;                   abstract;
  290.     procedure SetFlags(const Value: TRVFlags); virtual;     abstract;
  291.     procedure AddStringFromFile(const s: String; StyleNo,ParaNo: Integer;
  292.       FromNewLine, AsSingleParagraph: Boolean; var FirstTime, PageBreak: Boolean);
  293.     procedure AfterDeleteStyles(Data: TRVDeleteUnusedStylesData); dynamic;      
  294.   public
  295.     State: TRVStates;
  296.     { Constructors - destructors }
  297.     constructor Create;
  298.     destructor Destroy; override;
  299.     { Document/control & styles properties }
  300.     function GetRVData: TCustomRVData; virtual;
  301.     function GetSourceRVData: TCustomRVData; virtual;
  302.     function GetStyleCodePage(StyleNo: Integer): TRVCodePage;
  303.     function GetStyleLocale(StyleNo: Integer): Cardinal;
  304.     function GetDefaultCodePage: TRVCodePage;
  305.     function GetRVStyle: TRVStyle; virtual;
  306.     function GetParentControl: TWinControl; dynamic;
  307.     procedure GetParentInfo(var ParentItemNo: Integer;
  308.       var Location: TRVStoreSubRVData); dynamic;
  309.     function GetChosenRVData: TCustomRVData; dynamic;
  310.     function GetChosenItem: TCustomRVItemInfo; dynamic;
  311.     function GetParentData: TCustomRVData; virtual;
  312.     function GetRootData: TCustomRVData; virtual;
  313.     function GetAbsoluteParentData: TCustomRVData; virtual;
  314.     function GetAbsoluteRootData: TCustomRVData; virtual;
  315.     { Palette }
  316.     function GetRVPalette: HPALETTE; virtual;
  317.     function GetRVLogPalette: PLogPalette; virtual;
  318.     function GetDoInPaletteMode: TRVPaletteAction; virtual;
  319.     procedure UpdateItemsPaletteInfo;
  320.     { Item properties }
  321.     function GetItemNo(Item: TCustomRVItemInfo): Integer;
  322.     function GetItem(ItemNo: Integer): TCustomRVItemInfo;
  323.     function SetItemExtraIntProperty(ItemNo: Integer;
  324.       Prop: TRVExtraItemProperty; Value: Integer): Boolean;
  325.     function GetItemExtraIntProperty(ItemNo: Integer;
  326.       Prop: TRVExtraItemProperty; var Value: Integer): Boolean;
  327.     function SetItemExtraStrProperty(ItemNo: Integer;
  328.       Prop: TRVExtraItemStrProperty; const Value: String): Boolean;
  329.     function GetItemExtraStrProperty(ItemNo: Integer;
  330.       Prop: TRVExtraItemStrProperty; var Value: String): Boolean;
  331.     function GetItemTag(ItemNo: Integer): Integer;
  332.     function IsParaStart(ItemNo: Integer): Boolean;
  333.     function GetItemPara(ItemNo: Integer): Integer;
  334.     function IsFromNewLine(ItemNo: Integer): Boolean;
  335.     function GetOffsAfterItem(ItemNo: Integer): Integer;
  336.     function GetOffsBeforeItem(ItemNo: Integer): Integer;
  337.     function ItemLength(ItemNo: Integer): Integer;
  338.     procedure SetItemTag(ItemNo: Integer; ATag: Integer);
  339.     function GetItemStyle(ItemNo: Integer): Integer;
  340.     function GetActualStyle(Item: TCustomRVItemInfo): Integer;
  341.     function GetActualStyle2(StyleNo, ParaNo: Integer): Integer;
  342.     function GetItemText(ItemNo: Integer): String;
  343.     procedure SetItemText(ItemNo: Integer; const s: String);
  344.     {$IFNDEF RVDONOTUSEUNICODE}
  345.     {$IFDEF RICHVIEWCBDEF3}
  346.     function GetTextInItemFormatW(ItemNo: Integer; const s: WideString): String;
  347.     function GetItemTextW(ItemNo: Integer): WideString;
  348.     procedure SetItemTextW(ItemNo: Integer; const s: WideString);
  349.     {$ENDIF}
  350.     function GetTextInItemFormatA(ItemNo: Integer; const s: String): String;
  351.     procedure SetItemTextA(ItemNo: Integer; const s: String);
  352.     {$ENDIF}
  353.     function GetItemTextA(ItemNo: Integer): String;    
  354.     function FindControlItemNo(actrl: TControl): Integer;
  355.     { BiDi }
  356.     function GetItemBiDiMode(ItemNo: Integer): TRVBiDiMode;
  357.     function GetParaBiDiMode(ParaNo: Integer): TRVBiDiMode;
  358.     function GetBiDiMode: TRVBiDiMode; virtual;
  359.     { Operations on items - internal }
  360.     procedure FreeItem(ItemNo: Integer; Clearing: Boolean);
  361.     { Operations on items - public }
  362.     procedure Clear; dynamic;
  363.     procedure DeleteItems(FirstItemNo, Count: Integer); dynamic;
  364.     procedure DeleteSection(const CpName: String);
  365.     { Related to events }
  366.     function IsAssignedOnProgress: Boolean; dynamic;
  367.     procedure DoProgress(Operation: TRVLongOperation; Stage: TRVProgressStage;
  368.       PercentDone: Byte); dynamic;
  369.     function GetExtraRTFCode(Area: TRVRTFSaveArea; Obj: TObject;
  370.       Index1, Index2: Integer; InStyleSheet: Boolean): String; dynamic;
  371.     function GetExtraHTMLCode(Area: TRVHTMLSaveArea;
  372.       CSSVersion: Boolean): String; dynamic;
  373.     function GetParaHTMLCode(RVData: TCustomRVData; ItemNo: Integer;
  374.       ParaStart, CSSVersion: Boolean): String; dynamic;
  375.     procedure ReadHyperlink(const Target, Extras: String; DocFormat: TRVLoadFormat;
  376.       var StyleNo, ItemTag: Integer; var ItemName: String); dynamic;
  377.     procedure WriteHyperlink(id: Integer; RVData: TCustomRVData; ItemNo: Integer;
  378.        SaveFormat: TRVSaveFormat; var Target, Extras: String); dynamic;
  379.     function SaveItemToFile(const Path: String; RVData: TCustomRVData;
  380.       ItemNo: Integer; SaveFormat: TRVSaveFormat; Unicode: Boolean;
  381.       var Text: String): Boolean; virtual;
  382.     function ImportPicture(const Location: String;
  383.       Width, Height: Integer; var Invalid: Boolean): TGraphic; dynamic;
  384.     function GetItemHint(RVData: TCustomRVData; ItemNo: Integer;
  385.       const UpperRVDataHint: String): String; dynamic;
  386.     function DoSavePicture(DocumentSaveFormat: TRVSaveFormat;
  387.       const imgSavePrefix, Path: String; var imgSaveNo: Integer;
  388.       OverrideFiles: Boolean; CurrentFileColor: TColor;
  389.       gr: TGraphic): String; virtual;
  390.     function SavePicture(DocumentSaveFormat: TRVSaveFormat;
  391.       const imgSavePrefix, Path: String; var imgSaveNo: Integer;
  392.       OverrideFiles: Boolean; CurrentFileColor: TColor;
  393.       gr: TGraphic): String;
  394.     function RVFPictureNeeded(const ItemName: String; ItemTag: Integer): TGraphic; dynamic;
  395.     procedure ControlAction(ControlAction: TRVControlAction; ItemNo: Integer;
  396.       Item: TCustomRVItemInfo);
  397.     procedure ItemAction(ItemAction: TRVItemAction; Item: TCustomRVItemInfo;
  398.       var Text: String; RVData: TCustomRVData); virtual;
  399.     procedure ControlAction2(ControlAction: TRVControlAction; ItemNo: Integer;
  400.       var Control:  TControl); dynamic; abstract;
  401.     function RVFControlNeeded(const ItemName: String; ItemTag: Integer): TControl; dynamic;
  402.     function RVFImageListNeeded(ImageListTag: Integer): TCustomImageList; dynamic;
  403.     procedure HTMLSaveImage(RVData: TCustomRVData; ItemNo: Integer;
  404.       const Path: String; BackgroundColor: TColor; var Location: String;
  405.       var DoDefault: Boolean); dynamic;
  406.     procedure SaveImage2(Graphic: TGraphic; SaveFormat: TRVSaveFormat;
  407.       const Path, ImagePrefix: String; var ImageSaveNo: Integer;
  408.       var Location: String; var DoDefault: Boolean); dynamic;
  409.     function SaveComponentToFile(const Path: String; SaveMe: TComponent;
  410.       SaveFormat: TRVSaveFormat): String; virtual;
  411.     { Text save and load }
  412.     {$IFNDEF RVDONOTUSEUNICODE}
  413.     function LoadTextFromStreamW(Stream: TStream; StyleNo, ParaNo: Integer;
  414.       DefAsSingleParagraph: Boolean):Boolean;
  415.     function LoadTextW(const FileName: String; StyleNo, ParaNo: Integer;
  416.       DefAsSingleParagraph: Boolean):Boolean;
  417.     {$ENDIF}
  418.     function SaveTextToStream(const Path: String; Stream: TStream;
  419.       LineWidth: Integer; SelectionOnly, TextOnly, Unicode,
  420.       UnicodeWriteSignature: Boolean):Boolean;
  421.     function SaveText(const FileName: String; LineWidth: Integer;
  422.       Unicode: Boolean):Boolean;
  423.     function LoadText(const FileName: String; StyleNo, ParaNo: Integer;
  424.       AsSingleParagraph: Boolean):Boolean;
  425.     function LoadTextFromStream(Stream: TStream; StyleNo, ParaNo: Integer;
  426.       AsSingleParagraph: Boolean):Boolean;
  427.     { HTML save }
  428.     {$IFNDEF RVDONOTUSEHTML}
  429.     function SaveBackgroundToHTML(bmp: TBitmap; Color: TColor;
  430.       const Path, ImagesPrefix: String; var imgSaveNo: Integer;
  431.       SaveOptions: TRVSaveOptions): String;
  432.     function SaveHTMLToStreamEx(Stream: TStream;
  433.       const Path, Title, ImagesPrefix, ExtraStyles, ExternalCSS, CPPrefix: String;
  434.       Options: TRVSaveOptions; Color: TColor; var CurrentFileColor: TColor;
  435.       var imgSaveNo: Integer; LeftMargin, TopMargin, RightMargin, BottomMargin: Integer;
  436.       Background: TRVBackground; Bullets: TRVList): Boolean; dynamic;
  437.     function SaveHTMLToStream(Stream: TStream; const Path, Title,ImagesPrefix: String;
  438.       Options: TRVSaveOptions; Color: TColor; var imgSaveNo: Integer;
  439.       LeftMargin, TopMargin, RightMargin, BottomMargin: Integer;
  440.       Background: TRVBackground; Bullets: TRVList): Boolean; dynamic;
  441.     function SaveHTMLEx(const FileName, Title, ImagesPrefix, ExtraStyles,
  442.       ExternalCSS, CPPrefix: String; Options: TRVSaveOptions;
  443.       Color: TColor; var CurrentFileColor: TColor;
  444.       var imgSaveNo: Integer; LeftMargin, TopMargin, RightMargin, BottomMargin: Integer;
  445.       Background: TRVBackground): Boolean;
  446.     function SaveHTML(const FileName,Title,ImagesPrefix: String;
  447.       Options: TRVSaveOptions; Color: TColor; var imgSaveNo: Integer;
  448.       LeftMargin, TopMargin, RightMargin, BottomMargin: Integer;
  449.       Background: TRVBackground): Boolean;
  450.     {$ENDIF}
  451.     function GetNextFileName(const ImagesPrefix, Path, Ext: String;
  452.       var imgSaveNo: Integer; OverrideFiles: Boolean): String; dynamic;
  453.     { RVF save and load }
  454.     {$IFNDEF RVDONOTUSERVF}
  455.     function LoadRVFFromStream(Stream: TStream; var Color: TColor;
  456.       Background: TRVBackground; Layout: TRVLayoutInfo):Boolean;
  457.     function InsertRVFFromStream(Stream: TStream; Index: Integer;
  458.       var Color: TColor; Background: TRVBackground; Layout: TRVLayoutInfo;
  459.       AllowReplaceStyles: Boolean):Boolean;
  460.     function AppendRVFFromStream(Stream: TStream; ParaNo: Integer;
  461.       var Color: TColor; Background: TRVBackground):Boolean;
  462.     function LoadRVF(const FileName: String;
  463.       var Color: TColor; Background: TRVBackground;
  464.       Layout: TRVLayoutInfo):Boolean;
  465.     //SelectionOnly=True - reserved here
  466.     function SaveRVFToStream(Stream: TStream; SelectionOnly: Boolean;
  467.       Color: TColor; Background: TRVBackground;
  468.       Layout: TRVLayoutInfo):Boolean;
  469.     function SaveRVFToStreamEx(Stream: TStream; SaveScope: TRVFSaveScope;
  470.       Color: TColor; Background: TRVBackground;
  471.       Layout: TRVLayoutInfo):Boolean;
  472.     //SelectionOnly=True - reserved here
  473.     function SaveRVF(const FileName: String; SelectionOnly: Boolean;
  474.       Color: TColor; Background: TRVBackground;
  475.       Layout: TRVLayoutInfo):Boolean;
  476.     {$ENDIF}
  477.     function InsertFirstRVFItem(var Index: Integer; var s: String;
  478.       var item: TCustomRVItemInfo; EditFlag: Boolean; var FullReformat: Boolean;
  479.       var NewListNo: Integer): Boolean; dynamic;
  480.     function GetRVFSaveScope(SelectionOnly: Boolean):TRVFSaveScope;
  481.     { RTF save and load }
  482.     {$IFNDEF RVDONOTUSERTF}
  483.     {$IFNDEF RVDONOTUSELISTS}
  484.     procedure SaveRTFListTable97(Stream: TStream; ColorList: TRVColorList;
  485.       ListOverrideOffsetsList: TRVIntegerList;
  486.       FontTable: TRVRTFFontTable; tpp: Double);
  487.     {$ENDIF}
  488.     function SaveRTFToStream(Stream: TStream; const Path: String; SelectionOnly: Boolean;
  489.       Level: Integer; Color: TColor; Background: TRVBackground; ColorList: TRVColorList;
  490.       StyleToFont, ListOverrideOffsetsList1, ListOverrideOffsetsList2: TRVIntegerList;
  491.       FontTable: TRVRTFFontTable; tpp: Double):Boolean; dynamic;
  492.     function SaveRTF(const FileName: String; SelectionOnly: Boolean;
  493.       Color: TColor; Background: TRVBackground):Boolean;
  494.     {$ENDIF}
  495.     {$IFNDEF RVDONOTUSERTFIMPORT}
  496.     function LoadRTFFromStream(Stream: TStream):TRVRTFErrorCode;
  497.     function LoadRTF(const FileName: String):TRVRTFErrorCode;
  498.     {$IFDEF RVUSEWORDDOC}
  499.     function LoadWordDoc(const FileName: String):TRVRTFErrorCode;
  500.     {$ENDIF}
  501.     {$ENDIF}
  502.     procedure MakeRTFTables(ColorList: TRVColorList;
  503.       ListOverrideCountList: TRVIntegerList; TopLevel: Boolean);
  504.     { Adding items - general }
  505.     procedure AddItem(const Text: String; Item: TCustomRVItemInfo);
  506.     procedure AddItemAsIs(const Text: String; Item: TCustomRVItemInfo);
  507.     { Adding items - text }
  508.     procedure AddFmt(const FormatStr: String; const Args: array of const;
  509.       StyleNo, ParaNo: Integer);
  510.     procedure AddNL(const s: String; StyleNo, ParaNo: Integer);
  511.     procedure AddNLTag(const s: String; StyleNo, ParaNo, Tag: Integer);
  512.     procedure AddTextNL(const s: String; StyleNo, FirstParaNo, OtherParaNo: Integer
  513.       {$IFDEF RICHVIEWDEF4};Tag: Integer=0{$ENDIF});
  514.     {$IFNDEF RVDONOTUSEUNICODE}
  515.     procedure AddTextNLA(const s: String; StyleNo, FirstParaNo, OtherParaNo: Integer
  516.       {$IFDEF RICHVIEWDEF4};Tag: Integer=0{$ENDIF});
  517.     {$ENDIF}
  518.     procedure AddTextBlockNL(const s: String; StyleNo, ParaNo: Integer
  519.       {$IFDEF RICHVIEWDEF4};Tag: Integer=0{$ENDIF});
  520.     {$IFNDEF RVDONOTUSEUNICODE}
  521.     {$IFDEF RICHVIEWCBDEF3}
  522.     procedure AddNLWTag(const s: WideString; StyleNo, ParaNo, Tag: Integer);
  523.     {$ENDIF}
  524.     procedure AddNLWTagRaw(const s: String; StyleNo, ParaNo, Tag: Integer);
  525.     procedure AddNLATag(const s: String; StyleNo, ParaNo, Tag: Integer);
  526.     procedure AddTextNLW(const s: String; StyleNo, FirstParaNo,
  527.       OtherParaNo: Integer; DefAsSingleParagraph: Boolean);
  528.     {$ENDIF}
  529.     { Adding items - others }
  530.     {$IFNDEF RVDONOTUSETABS}
  531.     procedure AddTab(TextStyleNo, ParaNo: Integer);
  532.     {$ENDIF}
  533.     procedure AddBreakExTag(Width: Byte; Style: TRVBreakStyle;
  534.       Color: TColor; Tag: Integer);
  535.     procedure AddBreak;
  536.     procedure AddBreakEx(Width: Byte; Style: TRVBreakStyle; Color: TColor);
  537.     procedure AddBreakTag(Tag: Integer);
  538.     procedure AddBulletEx(const Name: String; ImageIndex: Integer;
  539.       ImageList: TCustomImageList; ParaNo: Integer);
  540.     procedure AddBulletExTag(const Name: String; ImageIndex: Integer;
  541.       ImageList: TCustomImageList; ParaNo, Tag: Integer);
  542.     procedure AddHotspotEx(const Name: String; ImageIndex,
  543.       HotImageIndex: Integer; ImageList: TCustomImageList; ParaNo: Integer);
  544.     procedure AddHotspotExTag(const Name: String; ImageIndex,
  545.       HotImageIndex: Integer; ImageList: TCustomImageList; ParaNo, Tag: Integer);
  546.     procedure AddPictureExTag(const Name: String; gr: TGraphic; ParaNo: Integer;
  547.       VAlign: TRVVAlign; Tag: Integer);
  548.     procedure AddControlExTag(const Name: String; ctrl: TControl;
  549.       ParaNo: Integer; VAlign: TRVVAlign; Tag: Integer);
  550.     procedure AddPictureEx(const Name: String; gr: TGraphic; ParaNo: Integer;
  551.       VAlign: TRVVAlign);
  552.     procedure AddControlEx(const Name: String; ctrl: TControl;
  553.       ParaNo: Integer; VAlign: TRVVAlign);
  554.     procedure AddHotPicture(const Name: String; gr: TGraphic; ParaNo: Integer;
  555.       VAlign: TRVVAlign);
  556.     procedure AddHotPictureTag(const Name: String; gr: TGraphic; ParaNo: Integer;
  557.       VAlign: TRVVAlign; Tag: Integer);
  558.     { Checkpoints - internal }
  559.     procedure FreeCheckpoint(var cp: TRVCPInfo; AdjustLinks, DecCPCount: Boolean);
  560.     procedure SetCP(Item: TCustomRVItemInfo; var PrevCP, CP: TRVCPInfo);
  561.     { Checkpoints - public }
  562.     function AddNamedCheckpointExTag(const CpName: String; RaiseEvent: Boolean;
  563.       Tag: Integer): Integer;
  564.     procedure SetCheckpointInfo(ItemNo: Integer; ATag: Integer; const AName: String;
  565.       ARaiseEvent: Boolean);
  566.     function RemoveCheckpoint(ItemNo: Integer): Boolean;
  567.     function GetFirstCheckpoint: TCheckpointData;
  568.     function GetNextCheckpoint(CheckpointData: TCheckpointData): TCheckpointData;
  569.     function GetLastCheckpoint: TCheckpointData;
  570.     function GetPrevCheckpoint(CheckpointData: TCheckpointData): TCheckpointData;
  571.     function GetItemCheckpoint(ItemNo: Integer):TCheckpointData;
  572.     function FindCheckpointByName(const Name: String): TCheckpointData;
  573.     function FindCheckpointByTag(Tag: Integer): TCheckpointData;
  574.     function GetCheckpointByNo(No: Integer): TCheckpointData;
  575.     function GetCheckpointItemNo(CheckpointData: TCheckpointData): Integer;
  576.     function GetCheckpointNo(CheckpointData: TCheckpointData): Integer;
  577.     procedure GetCheckpointInfo(CheckpointData: TCheckpointData;
  578.       var Tag: Integer; var Name: String; var RaiseEvent: Boolean);
  579.     { Get info for specific item types }
  580.     procedure GetBreakInfo(ItemNo: Integer; var AWidth: Byte;
  581.       var AStyle: TRVBreakStyle; var AColor: TColor; var ATag: Integer);
  582.     procedure GetBulletInfo(ItemNo: Integer; var AName: String;
  583.       var AImageIndex: Integer; var AImageList: TCustomImageList;
  584.       var ATag: Integer);
  585.     procedure GetHotspotInfo(ItemNo: Integer; var AName: String;
  586.       var AImageIndex, AHotImageIndex: Integer; var AImageList: TCustomImageList;
  587.       var ATag: Integer);
  588.     procedure GetPictureInfo(ItemNo: Integer; var AName: String;
  589.       var Agr: TGraphic; var AVAlign: TRVVAlign; var ATag: Integer);
  590.     procedure GetControlInfo(ItemNo: Integer; var AName: String;
  591.       var Actrl: TControl; var AVAlign: TRVVAlign; var ATag: Integer);
  592.     procedure GetTextInfo(ItemNo: Integer; var AText: String;
  593.       var ATag: Integer);
  594.     { Set info for specific item types }
  595.     procedure SetGrouped(ItemNo: Integer; Grouped: Boolean);
  596.     procedure SetBreakInfo(ItemNo: Integer; AWidth: Byte; AStyle: TRVBreakStyle;
  597.       AColor: TColor; ATag: Integer);
  598.     procedure SetBulletInfo(ItemNo: Integer; const AName: String;
  599.       AImageIndex: Integer; AImageList: TCustomImageList; ATag: Integer);
  600.     procedure SetHotspotInfo(ItemNo: Integer; const AName: String;
  601.       AImageIndex, AHotImageIndex: Integer; AImageList: TCustomImageList;
  602.       ATag: Integer);
  603.     function SetPictureInfo(ItemNo: Integer; const  AName: String;
  604.       Agr: TGraphic; AVAlign: TRVVAlign; ATag: Integer): Boolean;
  605.     function SetControlInfo(ItemNo: Integer; const AName: String;
  606.       AVAlign: TRVVAlign; ATag: Integer): Boolean;
  607.     { Styles }
  608.     procedure DoMarkStylesInUse(Data: TRVDeleteUnusedStylesData);
  609.     procedure DoUpdateStyles(Data: TRVDeleteUnusedStylesData);
  610.     procedure MarkStylesInUse(Data: TRVDeleteUnusedStylesData); dynamic;
  611.     procedure DeleteMarkedStyles(Data: TRVDeleteUnusedStylesData);
  612.     procedure DeleteUnusedStyles(TextStyles, ParaStyles, ListStyles: Boolean);
  613.     { Paragraph list markers}
  614.     {$IFNDEF RVDONOTUSELISTS}
  615.     function GetMarkers(AllowCreate: Boolean): TRVMarkerList; dynamic;
  616.     function GetPrevMarkers: TRVMarkerList; dynamic;
  617.     function SetListMarkerInfo(AItemNo, AListNo, AListLevel, AStartFrom,
  618.       AParaNo: Integer; AUseStartFrom: Boolean): Integer;
  619.     procedure RecalcMarker(AItemNo: Integer; AllowCreateList: Boolean);
  620.     procedure RemoveListMarker(ItemNo: Integer);
  621.     function GetListMarkerInfo(AItemNo: Integer; var AListNo, AListLevel,
  622.       AStartFrom: Integer; var AUseStartFrom: Boolean): Integer;
  623.     procedure AddMarkerInList(ItemNo: Integer);
  624.     procedure DeleteMarkerFromList(Item: TCustomRVItemInfo; Clearing: Boolean);
  625.     {$ENDIF}
  626.     { Others }
  627.     function IsDelimiterA(ch: Char): Boolean;
  628.     function IsDelimiterW(ch: Word): Boolean;
  629.     function EnumItems(Proc: TRVEnumItemsProc; var UserData1: Integer;
  630.       const UserData2: String): Boolean;
  631.     procedure ShareItemsFrom(Source: TCustomRVData);
  632.     procedure AssignItemsFrom(Source: TCustomRVData);
  633.     procedure DrainFrom(Victim: TCustomRVData);
  634.     procedure SetParagraphStyleToAll(ParaNo: Integer);
  635.     procedure SetAddParagraphMode(AllowNewPara: Boolean);
  636.     procedure AppendFrom(Source: TCustomRVData);
  637.     procedure Inserting(RVData: TCustomRVData; Safe: Boolean);
  638.     function Edit: TCustomRVData; dynamic;
  639.     procedure Beep;
  640.     procedure ExpandToParaSection(ItemNo1,ItemNo2: Integer;
  641.       var FirstItemNo, LastItemNo: Integer);
  642.     procedure ExpandToPara(ItemNo1,ItemNo2: Integer;
  643.       var FirstItemNo, LastItemNo: Integer);
  644.     function ReplaceTabs(const s: String; StyleNo: Integer;
  645.       UnicodeDef: Boolean): String;
  646.     procedure AdjustInItemsRange(var ItemNo: Integer);      
  647.     { Properties }
  648.     function GetDocProperties: TStringList; dynamic;
  649.     property Flags: TRVFlags read GetFlags write SetFlags;
  650.     property Items: TStringList read FItems;
  651.     property ItemCount: Integer read GetItemCount;
  652.     property Options: TRVOptions read GetOptions write SetOptions;
  653.     property RVFOptions: TRVFOptions read GetRVFOptions write SetRVFOptions;
  654.     property RTFOptions: TRVRTFOptions read GetRTFOptions write SetRTFOptions;
  655.     property RVFWarnings: TRVFWarnings read GetRVFWarnings write SetRVFWarnings;
  656.     property FirstJumpNo: Integer read FFirstJumpNo write FFirstJumpNo;
  657.     property PageBreaksBeforeItems[Index: Integer]: Boolean
  658.       read GetPageBreaksBeforeItems write SetPageBreaksBeforeItems;
  659.   end;
  660.   procedure RVCheckUni(Length: Integer);
  661.   function RVCompareLocations(RVData1: TCustomRVData; ItemNo1: Integer;
  662.     RVData2: TCustomRVData; ItemNo2: Integer): Integer;
  663. {$IFNDEF RVDONOTUSERTF}
  664. procedure RVSaveFontToRTF(Stream: TStream; Font: TFont;
  665.   ColorList: TRVColorList; FontTable: TRVRTFFontTable;
  666.   RVStyle: TRVStyle);
  667. {$ENDIF}
  668. const
  669.   RichViewSavePInHTML:    Boolean = False;
  670.   RichViewSavePageBreaksInText: Boolean = False;
  671.   RichViewDoNotCheckRVFStyleRefs: Boolean = False;
  672.   cssBKAttStrFixed = 'fixed';
  673.   cssBKAttStrScroll = 'scroll';
  674.   cssBKRepStrRepeat = 'repeat';
  675.   cssBKRepStrNoRepeat = 'no-repeat';
  676.   rv_cssBkAttachment : array[TBackgroundStyle] of PChar
  677.       = ('', cssBKAttStrFixed, cssBKAttStrFixed, cssBKAttStrScroll, cssBKAttStrFixed,
  678.         cssBKAttStrFixed, cssBKAttStrFixed, cssBKAttStrFixed, cssBKAttStrFixed);
  679.   rv_cssBkRepeat     : array[TBackgroundStyle] of PChar =
  680.         ('', cssBKRepStrNoRepeat, cssBKRepStrRepeat, cssBKRepStrRepeat,
  681.         cssBKRepStrNoRepeat, cssBKRepStrNoRepeat, cssBKRepStrNoRepeat,
  682.         cssBKRepStrNoRepeat, cssBKRepStrNoRepeat);
  683. procedure RV_RegisterHTMLGraphicFormat(ClassType: TGraphicClass);
  684. procedure RV_RegisterPngGraphic(ClassType: TGraphicClass);
  685. function RV_IsHTMLGraphicFormat(gr: TGraphic): Boolean;
  686. procedure RV_ReplaceStr(var str: String; oldstr, newstr: String);
  687. var RVPngGraphiClass: TGraphicClass;
  688. implementation
  689. uses RVFMisc, RVStr, RVRTFProps;
  690. const RVF_DOCPROP_TEXTSTYLES  = 1;
  691.       RVF_DOCPROP_PARASTYLES  = 2;
  692.       RVF_DOCPROP_LISTSTYLES  = 4;
  693.       RVF_DOCPROP_LAYOUT      = 3;
  694.       RVF_DOCPROP_DOCPROPLIST = 5;
  695.       RVF_DOCPROP_PREVMARKERS = 6;
  696. const RVFVersion = 1;
  697.       RVFSubVersion = 3;
  698. const
  699.   crlf = #13#10;
  700. {==============================================================================}
  701. { Replaces in str all substrings oldstr with substring newstr.
  702.   Case insensitive. Newstr CANNOT contain oldstr as a substring.               }
  703. procedure RV_ReplaceStr(var str: String; oldstr, newstr: String);
  704. var p: Integer;
  705. begin
  706.    while true do begin
  707.      p := pos(oldstr, str);
  708.      if p=0 then break;
  709.      Delete(str,p, Length(oldstr));
  710.      Insert(newstr, str, p);
  711.    end;
  712. end;
  713. {------------------------------------------------------------------------------}
  714. { Raises an exception - error in processing Unicode text.                      }
  715. procedure RVRaiseUni;
  716. begin
  717.   raise ERichViewError.Create(errRVUnicode);
  718. end;
  719. {------------------------------------------------------------------------------}
  720. { Raises an exception is Length is odd value. It's used to check lengths of
  721.   "raw Unicode" string.                                                        }
  722. procedure RVCheckUni(Length: Integer);
  723. begin
  724.   if Length mod 2 <> 0 then
  725.     RVRaiseUni;
  726. end;
  727. {========================== HTML Graphic Classes ==============================}
  728. { List of HTML graphic classes.
  729.   Pictures of HTML graphic classes will be saved in HTML without
  730.   converting to Jpegs.
  731.   Initialization: nilled.
  732.   Finalization: freed and nilled.                                              }
  733. var HTMLGraphicFormats: TList;
  734. {------------------------------------------------------------------------------}
  735. { Registers the graphic class ClassType as an HTML graphic class.              }
  736. procedure RV_RegisterHTMLGraphicFormat(ClassType: TGraphicClass);
  737. begin
  738.   if HTMLGraphicFormats=nil then
  739.     HTMLGraphicFormats := TList.Create;
  740.   if HTMLGraphicFormats.IndexOf(ClassType)<0 then
  741.     HTMLGraphicFormats.Add(ClassType);
  742. end;
  743. {------------------------------------------------------------------------------}
  744. { Is this a picture of HTML graphic class?                                     }
  745. function RV_IsHTMLGraphicFormat(gr: TGraphic): Boolean;
  746. begin
  747.   Result := (HTMLGraphicFormats<>nil) and
  748.     (HTMLGraphicFormats.IndexOf(gr.ClassType)>=0)
  749. end;
  750. {================================ Png =========================================}
  751. procedure RV_RegisterPngGraphic(ClassType: TGraphicClass);
  752. begin
  753.   RVPngGraphiClass := ClassType;
  754. end;
  755. {================================ TRTFFontTable ===============================}
  756. { Returns an index of (FontName, Charset) item, or -1 if not found.
  757.   Charset is not supported in D2/CB1 version.
  758.   FontName is case insensitive.                                                }
  759. function TRVRTFFontTable.Find(const FontName: String
  760.   {$IFDEF RICHVIEWCBDEF3}; Charset: TFontCharset{$ENDIF}): Integer;
  761. var i: Integer;
  762. begin
  763.   for i := 0 to Count-1 do
  764.     if (AnsiCompareText(Items[i].FontName,FontName)=0)
  765.        {$IFDEF RICHVIEWCBDEF3}
  766.        and (Items[i].Charset = Charset)
  767.        {$ENDIF}
  768.        then begin
  769.       Result := i;
  770.       exit;
  771.     end;
  772.   Result := -1;
  773. end;
  774. {------------------------------------------------------------------------------}
  775. { Adds (FontName, Charset) item if it does not present.
  776.   In any case, returns an index of (FontName, Charset) item.
  777.   Charset is not supported in D2/CB1 version.
  778.   FontName is case insensitive.                                                }  
  779. function TRVRTFFontTable.AddUnique(const FontName: String
  780.  {$IFDEF RICHVIEWCBDEF3}; Charset: TFontCharset{$ENDIF}): Integer;
  781. var item: TRVRTFFontTableItem;
  782. begin
  783.   Result := Find(FontName{$IFDEF RICHVIEWCBDEF3}, Charset{$ENDIF});
  784.   if Result<0 then begin
  785.     item := TRVRTFFontTableItem.Create;
  786.     item.FontName := FontName;
  787.     {$IFDEF RICHVIEWCBDEF3}
  788.     item.Charset := Charset;
  789.     {$ENDIF}
  790.     Add(item);
  791.     Result := Count-1;
  792.   end;
  793. end;
  794. {------------------------------------------------------------------------------}
  795. { Reads Items[Index]                                                            }
  796. function TRVRTFFontTable.Get(Index: Integer): TRVRTFFontTableItem;
  797. begin
  798.   Result := TRVRTFFontTableItem(inherited Get(Index));
  799. end;
  800. {------------------------------------------------------------------------------}
  801. { Writes Items[Index]                                                          }
  802. procedure TRVRTFFontTable.Put(Index: Integer; const Value: TRVRTFFontTableItem);
  803. begin
  804.   inherited Put(Index, Value);
  805. end;
  806. {============================ TRVLayoutInfo ===================================}
  807. { Constructor.                                                                 }
  808. constructor TRVLayoutInfo.Create;
  809. begin
  810.   inherited Create;
  811.   FirstMarkerListNo := -1;
  812. end;
  813. {------------------------------------------------------------------------------}
  814. { Loads iteslf from the Stream.
  815.   If IncludeSize=True, first reads size (4 bytes) of the rest of data; reports
  816.   error is the size is too small; reads at least size bytes (for compatibility
  817.   with possible future extensions).                                            }
  818. procedure TRVLayoutInfo.LoadFromStream(Stream: TStream; IncludeSize: Boolean);
  819. var v: Integer;
  820. const defsize1 = sizeof(Integer)*(4+2)+sizeof(TRVBiDiMode);
  821. begin
  822.    if IncludeSize then
  823.      Stream.ReadBuffer(v, sizeof(Integer)); // ignoring
  824.    Stream.ReadBuffer(v,            sizeof(Integer));
  825.    Stream.ReadBuffer(v,            sizeof(Integer));
  826.    if v<defsize1 then
  827.      raise ERichViewError.Create(errRVFDocProp);
  828.    Stream.ReadBuffer(LeftMargin,   sizeof(Integer));
  829.    Stream.ReadBuffer(RightMargin,  sizeof(Integer));
  830.    Stream.ReadBuffer(TopMargin,    sizeof(Integer));
  831.    Stream.ReadBuffer(BottomMargin, sizeof(Integer));
  832.    Stream.ReadBuffer(MinTextWidth, sizeof(Integer));
  833.    Stream.ReadBuffer(MaxTextWidth, sizeof(Integer));
  834.    Stream.ReadBuffer(BiDiMode,     sizeof(TRVBiDiMode));
  835.    dec(v, defsize1);
  836.    if v>=sizeof(Integer)*4 then begin
  837.      Stream.ReadBuffer(FirstParaAborted, sizeof(Integer));
  838.      Stream.ReadBuffer(LastParaAborted, sizeof(Integer));
  839.      Stream.ReadBuffer(FirstMarkerListNo, sizeof(Integer));
  840.      Stream.ReadBuffer(FirstMarkerLevel, sizeof(Integer));
  841.      dec(v, sizeof(Integer)*4);
  842.    end;
  843.    if v>0 then
  844.      Stream.Seek(v,soFromCurrent);
  845.    Loaded := True;
  846. end;
  847. {------------------------------------------------------------------------------}
  848. { Saves itself to the stream.
  849.   If IncluseSize=True, first saves its size (4 bytes).
  850.   Size is usually processed by RVF loading procedures.                         }
  851. procedure TRVLayoutInfo.SaveToStream(Stream: TStream; IncludeSize: Boolean);
  852. var v,size: Integer;
  853. const defsize1 = sizeof(Integer)*(4+2)+sizeof(TRVBiDiMode);
  854. begin
  855.    size := defsize1;
  856.    if (FirstParaAborted<>0) or (LastParaAborted<>0) then
  857.      inc(size, sizeof(Integer)*4);
  858.    if IncludeSize then begin
  859.      v := size+sizeof(Integer)*2;
  860.      Stream.WriteBuffer(v, sizeof(Integer));
  861.    end;
  862.    v := 0;
  863.    Stream.WriteBuffer(v,            sizeof(Integer));
  864.    v := size;
  865.    Stream.WriteBuffer(v,            sizeof(Integer));
  866.    Stream.WriteBuffer(LeftMargin,   sizeof(Integer));
  867.    Stream.WriteBuffer(RightMargin,  sizeof(Integer));
  868.    Stream.WriteBuffer(TopMargin,    sizeof(Integer));
  869.    Stream.WriteBuffer(BottomMargin, sizeof(Integer));
  870.    Stream.WriteBuffer(MinTextWidth, sizeof(Integer));
  871.    Stream.WriteBuffer(MaxTextWidth, sizeof(Integer));
  872.    Stream.WriteBuffer(BiDiMode,     sizeof(TRVBiDiMode));
  873.    if (FirstParaAborted<>0) or (LastParaAborted<>0) then begin
  874.      Stream.WriteBuffer(FirstParaAborted, sizeof(Integer));
  875.      Stream.WriteBuffer(LastParaAborted, sizeof(Integer));
  876.      Stream.WriteBuffer(FirstMarkerListNo, sizeof(Integer));
  877.      Stream.WriteBuffer(FirstMarkerLevel, sizeof(Integer));
  878.    end;
  879. end;
  880. {------------------------------------------------------------------------------}
  881. { Loads itself from the hexadecimal string: extracts the string to a temporal
  882.   memory stream, and calls LoadFromStream(..., False).                         }
  883. procedure TRVLayoutInfo.LoadText(const s: String);
  884. var TmpStream: TMemoryStream;
  885. begin
  886.    TmpStream := TMemoryStream.Create;
  887.    try
  888.      RVFTextString2Stream(s, TmpStream);
  889.      TmpStream.Position := 0;
  890.      LoadFromStream(TmpStream, False);
  891.    finally
  892.      TmpStream.Free;
  893.    end;
  894. end;
  895. {------------------------------------------------------------------------------}
  896. { Loads itself from the binary string: copies the string to a temporal memory
  897.   stream, and calls LoadFromStream(..., False).                                }
  898. procedure TRVLayoutInfo.LoadBinary(const s: String);
  899. var TmpStream: TMemoryStream;
  900. begin
  901.    TmpStream := TMemoryStream.Create;
  902.    try
  903.      TmpStream.WriteBuffer(PChar(s)^, Length(s));
  904.      TmpStream.Position := 0;
  905.      LoadFromStream(TmpStream, False);
  906.    finally
  907.      TmpStream.Free;
  908.    end;
  909. end;
  910. {------------------------------------------------------------------------------}
  911. { Saves itself to stream as a hexadecimal string that can be loaded by
  912.   LoadText.                                                                    }
  913. procedure TRVLayoutInfo.SaveTextToStream(Stream: TStream);
  914. var TmpStream: TMemoryStream;
  915.     s: String;
  916. begin
  917.    TmpStream := TMemoryStream.Create;
  918.    try
  919.      SaveToStream(TmpStream, False);
  920.      TmpStream.Position := 0;
  921.      s := RVFStream2TextString(TmpStream);
  922.      RVFWriteLine(Stream, s);
  923.    finally
  924.      TmpStream.Free;
  925.    end;
  926. end;
  927. {$I+}
  928. {================================ TCustomRVData ===============================}
  929. constructor TCustomRVData.Create;
  930. begin
  931.   inherited Create;
  932.   if not ShareItems then
  933.     FItems := TStringList.Create;
  934.   FAllowNewPara  := True;
  935.   CPCount        := 0;
  936.   State          := [];
  937. end;
  938. {------------------------------------------------------------------------------}
  939. destructor TCustomRVData.Destroy;
  940. begin
  941.   Clear;
  942.   if not ShareItems then
  943.     FItems.Free;
  944.   inherited Destroy;
  945. end;
  946. {------------------------------------------------------------------------------}
  947. function TCustomRVData.SavePicture(DocumentSaveFormat: TRVSaveFormat;
  948.   const imgSavePrefix, Path: String; var imgSaveNo: Integer;
  949.   OverrideFiles: Boolean; CurrentFileColor: TColor;
  950.   gr: TGraphic): String;
  951. var fn: String;
  952.     bmp: TBitmap;
  953.     ext: String;
  954.     {$IFNDEF RVDONOTUSEJPEGIMAGE}
  955.     jpg: TJpegImage;
  956.     {$ENDIF}
  957. begin
  958.    {$IFNDEF RVDONOTUSEJPEGIMAGE}
  959.    if DocumentSaveFormat=rvsfHTML then begin
  960.      ext := '.jpg';
  961.      if RV_IsHTMLGraphicFormat(gr) then
  962.        ext := '.'+GraphicExtension(TGraphicClass(gr.ClassType));
  963.      end
  964.    else
  965.      ext := '.bmp';
  966.    {$ELSE}
  967.    ext := '.bmp';
  968.    {$ENDIF}
  969.    fn := GetNextFileName(imgSavePrefix, Path, Ext, imgSaveNo, OverrideFiles);
  970.    Result := ExtractFilePath(imgSavePrefix);
  971.    if (Length(Result)>0) and (Result[Length(Result)]<>'') then
  972.      Result := Result+'';
  973.    Result := Result+ExtractFileName(fn);
  974.    {$IFNDEF RVDONOTUSEJPEGIMAGE}
  975.    if (DocumentSaveFormat=rvsfHTML) and
  976.       ((gr is TJpegImage) or RV_IsHTMLGraphicFormat(gr)) then begin
  977.      gr.SaveToFile(fn);
  978.      exit;
  979.    end;
  980.    {$ENDIF}
  981.    bmp := TBitmap.Create;
  982.    try
  983.      if gr is TBitmap then
  984.        bmp.Assign(gr)
  985.      else begin
  986.        {$IFDEF RICHVIEWCBDEF3}
  987.        bmp.PixelFormat := pf32bit;
  988.        {$ENDIF}
  989.        bmp.Height := gr.Height;
  990.        bmp.Width := gr.Width;
  991.        if CurrentFileColor=clNone then
  992.          CurrentFileColor := clWhite;
  993.        bmp.Canvas.Brush.Color := CurrentFileColor;
  994.        bmp.Canvas.Pen.Color := CurrentFileColor;
  995.        bmp.Canvas.FillRect(Rect(0,0,gr.Width,gr.Height));
  996.        bmp.Canvas.Draw(0,0,gr);
  997.      end;
  998.      {$IFNDEF RVDONOTUSEJPEGIMAGE}
  999.      if DocumentSaveFormat=rvsfHTML then begin
  1000.        jpg := TJpegImage.Create;
  1001.        try
  1002.          jpg.Assign(bmp);
  1003.          jpg.SaveToFile(fn);
  1004.        finally
  1005.          jpg.Free;
  1006.        end;
  1007.        end
  1008.      else
  1009.        bmp.SaveToFile(fn);
  1010.      {$ELSE}
  1011.        bmp.SaveToFile(fn);
  1012.      {$ENDIF}
  1013.    finally
  1014.      bmp.Free;
  1015.    end;
  1016. end;
  1017. {------------------------------------------------------------------------------}
  1018. function TCustomRVData.DoSavePicture(DocumentSaveFormat: TRVSaveFormat;
  1019.   const imgSavePrefix, Path: String; var imgSaveNo: Integer;
  1020.   OverrideFiles: Boolean; CurrentFileColor: TColor;
  1021.   gr: TGraphic): String;
  1022. var DoDefault: Boolean;
  1023. begin
  1024.    SaveImage2(gr, DocumentSaveFormat, Path, imgSavePrefix, imgSaveNo, Result,
  1025.      DoDefault);
  1026.    if not DoDefault then
  1027.      exit;
  1028.   Result := SavePicture(DocumentSaveFormat, imgSavePrefix, Path, imgSaveNo,
  1029.     OverrideFiles, CurrentFileColor, gr);
  1030. end;
  1031. {------------------------------------------------------------------------------}
  1032. function TCustomRVData.ItemLength(ItemNo: Integer): Integer;
  1033. begin
  1034.   with GetItem(ItemNo) do
  1035.     if StyleNo<0 then
  1036.       Result := 1
  1037.     else
  1038.       Result := RVU_Length(Items[ItemNo], ItemOptions);
  1039. end;
  1040. {------------------------------------------------------------------------------}
  1041. { Returns the file name in the directory Path. File name is built as
  1042.   ImagesPrefix + <number> + Ext.
  1043.   If OverrideFiles=True, <number> is imgSaveNo+1.
  1044.   If not, <number> is increased until file name does not belong to an existing
  1045.   file.
  1046.   On exit, imgSaveNo = <number>.
  1047.   Notes:
  1048.   - ImagesPrefix can contain path. It may be the full path (contains ':')
  1049.     or relative path. In the last case the file is assumed to be in
  1050.     Path + ExtractFilePath(ImagesPrefix).
  1051.   - It's assumed that the directory exists. }
  1052. function TCustomRVData.GetNextFileName(const ImagesPrefix, Path, Ext: String;
  1053.   var imgSaveNo: Integer; OverrideFiles: Boolean): String;
  1054. var FullPath: String;
  1055. begin
  1056.   if {$IFDEF RICHVIEWCBDEF3}AnsiPos{$ELSE}Pos{$ENDIF}(':',ImagesPrefix)>0 then
  1057.     FullPath := ImagesPrefix
  1058.   else
  1059.     FullPath := Path+ImagesPrefix;
  1060.   while True do begin
  1061.     inc(imgSaveNo);
  1062.     Result := FullPath+IntToStr(imgSaveNo)+Ext;
  1063.     if not FileExists(Result) then
  1064.       exit;
  1065.     {$WARNINGS OFF}
  1066.     if OverrideFiles and ((FileGetAttr(Result) and faReadOnly)=0) then
  1067.       exit;
  1068.     {$WARNINGS ON}
  1069.   end;
  1070. end;
  1071. {------------------------------------------------------------------------------}
  1072. procedure TCustomRVData.AddItem(const Text: String; Item: TCustomRVItemInfo);
  1073. var s: String;
  1074. begin
  1075.   if (Item.ParaNo=-1) and (Items.Count<>0) and
  1076.      not GetItem(Items.Count-1).GetBoolValue(rvbpFullWidth) then begin
  1077.     Item.SameAsPrev := True;
  1078.     Item.ParaNo := TCustomRVItemInfo(Items.Objects[Items.Count-1]).ParaNo;
  1079.     end
  1080.   else begin
  1081.     {$IFNDEF RVDONOTUSELISTS}
  1082.     if (Items.Count<>0) and (GetItemStyle(Items.Count-1)=rvsListMarker) then
  1083.       AddNL('',0,-1);
  1084.     {$ENDIF}
  1085.     Item.SameAsPrev := False;
  1086.     Item.BR := (Item.BR  or not FAllowNewPara) and not Item.GetBoolValue(rvbpFullWidth);
  1087.     if Item.ParaNo=-1 then
  1088.       Item.ParaNo := 0;
  1089.   end;
  1090.   if Item.Checkpoint<>nil then
  1091.     with Item.Checkpoint do
  1092.       AddNamedCheckpointExTag(Name, RaiseEvent, Tag);
  1093.   SetCP(Item, LastCP, NotAddedCP);
  1094.   Item.UpdatePaletteInfo(GetDoInPaletteMode, False, GetRVPalette, GetRVLogPalette);
  1095.   s := Text;
  1096.   Item.Inserting(Self, s, False);
  1097.   Items.AddObject(s, Item);
  1098.   Item.Inserted(Self, Items.Count-1);
  1099. end;
  1100. {------------------------------------------------------------------------------}
  1101. procedure TCustomRVData.AddItemAsIs(const Text: String; Item: TCustomRVItemInfo);
  1102. var s: String;
  1103. begin
  1104.   if Item.Checkpoint<>nil then
  1105.     with Item.Checkpoint do
  1106.       AddNamedCheckpointExTag(Name, RaiseEvent, Tag);
  1107.   SetCP(Item, LastCP, NotAddedCP);
  1108.   Item.UpdatePaletteInfo(GetDoInPaletteMode, False, GetRVPalette, GetRVLogPalette);
  1109.   s := Text;
  1110.   Item.Inserting(Self, s, False);
  1111.   Items.AddObject(s, Item);
  1112.   Item.Inserted(Self, Items.Count-1);
  1113. end;
  1114. {------------------------------------------------------------------------------}
  1115. { Does not replace tabs }
  1116. procedure TCustomRVData.AddNLTag_(const s: String; StyleNo, ParaNo, Tag: Integer);
  1117. var Item: TCustomRVItemInfo;
  1118. begin
  1119.   Item := RichViewTextItemClass.Create(Self);
  1120.   if StyleNo<0 then
  1121.     Item.StyleNo := rvsDefStyle
  1122.   else
  1123.     Item.StyleNo := StyleNo;
  1124.   Item.ParaNo  := ParaNo;
  1125.   Item.Tag     := Tag;
  1126.   {$IFNDEF RVDONOTUSEUNICODE}
  1127.   if (GetRVStyle<>nil) and (GetRVStyle.TextStyles[GetActualStyle(Item)].Unicode) then
  1128.     Include(Item.ItemOptions, rvioUnicode);
  1129.   {$ENDIF}
  1130.   AddItem(s, Item);
  1131. end;
  1132. {------------------------------------------------------------------------------}
  1133. {$IFNDEF RVDONOTUSEUNICODE}
  1134. procedure TCustomRVData.AddNLATag_(const s: String; StyleNo, ParaNo, Tag: Integer);
  1135. var ress: String;
  1136.     LParaNo: Integer;
  1137. begin
  1138.   LParaNo := ParaNo;
  1139.   if (StyleNo<0) or (StyleNo=rvsDefStyle) then begin
  1140.     StyleNo := rvsDefStyle;
  1141.     if LParaNo=-1 then begin
  1142.      if Items.Count<>0 then
  1143.        LParaNo := GetItemPara(Items.Count-1)
  1144.      else
  1145.        LParaNo := 0;
  1146.     end;
  1147.   end;
  1148.   if (GetRVStyle<>nil) and
  1149.      (GetRVStyle.TextStyles[GetActualStyle2(StyleNo, LParaNo)].Unicode) then
  1150.     ress := RVU_AnsiToUnicode(GetStyleCodePage(GetActualStyle2(StyleNo, LParaNo)), s)
  1151.   else
  1152.     ress := s;
  1153.   AddNLTag_(ress, StyleNo, ParaNo, Tag);
  1154. end;
  1155. {$ENDIF}
  1156. {------------------------------------------------------------------------------}
  1157. procedure TCustomRVData.AddNLTag(const s: String; StyleNo, ParaNo, Tag: Integer);
  1158. var Item: TCustomRVItemInfo;
  1159. begin
  1160.   Item := RichViewTextItemClass.Create(Self);
  1161.   if StyleNo<0 then
  1162.     Item.StyleNo := rvsDefStyle
  1163.   else
  1164.     Item.StyleNo := StyleNo;
  1165.   Item.ParaNo  := ParaNo;
  1166.   Item.Tag     := Tag;
  1167.   {$IFNDEF RVDONOTUSEUNICODE}
  1168.   if (GetRVStyle<>nil) and (GetRVStyle.TextStyles[GetActualStyle(Item)].Unicode) then
  1169.     Include(Item.ItemOptions, rvioUnicode);
  1170.   {$ENDIF}
  1171.   AddItem(ReplaceTabs(s, GetActualStyle(Item), False), Item);
  1172. end;
  1173. {------------------------------------------------------------------------------}
  1174. {$IFNDEF RVDONOTUSEUNICODE}
  1175. function TCustomRVData.GetTextInItemFormatA(ItemNo: Integer; const s: String): String;
  1176. begin
  1177.   if (GetItemStyle(ItemNo)>=0) and (rvioUnicode in GetItemOptions(ItemNo)) then
  1178.     Result := RVU_AnsiToUnicode(GetStyleCodePage(GetItemStyle(ItemNo)), s)
  1179.   else
  1180.     Result := s;
  1181. end;
  1182. {------------------------------------------------------------------------------}
  1183. procedure TCustomRVData.AddNLWTagRaw(const s: String; StyleNo, ParaNo, Tag: Integer);
  1184. var ansis: String;
  1185. begin
  1186.   ansis := s;
  1187.   if StyleNo<0 then
  1188.     StyleNo := rvsDefStyle;
  1189.   if (GetRVStyle<>nil) and
  1190.      not GetRVStyle.TextStyles[GetActualStyle2(StyleNo, ParaNo)].Unicode then
  1191.     ansis := RVU_UnicodeToAnsi(GetStyleCodePage(GetActualStyle2(StyleNo, ParaNo)), ansis);
  1192.   AddNLTag(ansis, StyleNo, ParaNo, Tag);
  1193. end;
  1194. {------------------------------------------------------------------------------}
  1195. {$IFDEF RICHVIEWCBDEF3}
  1196. function TCustomRVData.GetTextInItemFormatW(ItemNo: Integer; const s: WideString): String;
  1197. begin
  1198.   Result := RVU_GetRawUnicode(s);
  1199.   if (GetItemStyle(ItemNo)<0) or not (rvioUnicode in GetItemOptions(ItemNo)) then
  1200.     Result := RVU_UnicodeToAnsi(GetStyleCodePage(GetItemStyle(ItemNo)), Result);
  1201. end;
  1202. {------------------------------------------------------------------------------}
  1203. procedure TCustomRVData.AddNLWTag(const s: WideString; StyleNo, ParaNo, Tag: Integer);
  1204. begin
  1205.   AddNLWTagRaw(RVU_GetRawUnicode(s), StyleNo, ParaNo, Tag);
  1206. end;
  1207. {------------------------------------------------------------------------------}
  1208. function TCustomRVData.GetItemTextW(ItemNo: Integer): WideString;
  1209. var s: String;
  1210. begin
  1211.   s := Items[ItemNo];
  1212.   if (GetItemStyle(ItemNo)<0) or (not (rvioUnicode in GetItemOptions(ItemNo))) then
  1213.     s := RVU_AnsiToUnicode(GetStyleCodePage(GetItemStyle(ItemNo)), s);
  1214.   Result := RVU_RawUnicodeToWideString(s);
  1215. end;
  1216. {------------------------------------------------------------------------------}
  1217. procedure TCustomRVData.SetItemTextW(ItemNo: Integer; const s: WideString);
  1218. begin
  1219.   Items[ItemNo] := GetTextInItemFormatW(ItemNo, s);
  1220. end;
  1221. {$ENDIF}
  1222. {------------------------------------------------------------------------------}
  1223. procedure TCustomRVData.AddNLATag(const s: String; StyleNo, ParaNo, Tag: Integer);
  1224. var ress: String;
  1225.     LParaNo: Integer;
  1226. begin
  1227.   LParaNo := ParaNo;
  1228.   if (StyleNo<0) or (StyleNo=rvsDefStyle) then begin
  1229.     StyleNo := rvsDefStyle;
  1230.     if LParaNo=-1 then begin
  1231.      if Items.Count<>0 then
  1232.        LParaNo := GetItemPara(Items.Count-1)
  1233.      else
  1234.        LParaNo := 0;
  1235.     end;
  1236.   end;
  1237.   if (GetRVStyle<>nil) and
  1238.      (GetRVStyle.TextStyles[GetActualStyle2(StyleNo, LParaNo)].Unicode) then
  1239.     ress := RVU_AnsiToUnicode(GetStyleCodePage(GetActualStyle2(StyleNo, LParaNo)), s)
  1240.   else
  1241.     ress := s;
  1242.   AddNLTag(ress, StyleNo, ParaNo, Tag);
  1243. end;
  1244. {------------------------------------------------------------------------------}
  1245. procedure TCustomRVData.SetItemTextA(ItemNo: Integer; const s: String);
  1246. begin
  1247.   Items[ItemNo] := GetTextInItemFormatA(ItemNo, s);
  1248. end;
  1249. {$ENDIF}
  1250. {------------------------------------------------------------------------------}
  1251. function TCustomRVData.GetItemTextA(ItemNo: Integer): String;
  1252. begin
  1253.   Result := Items[ItemNo];
  1254.   {$IFNDEF RVDONOTUSEUNICODE}
  1255.   if (GetItemStyle(ItemNo)>=0) and (rvioUnicode in GetItemOptions(ItemNo)) then
  1256.     Result := RVU_UnicodeToAnsi(GetStyleCodePage(GetItemStyle(ItemNo)), Result);
  1257.   {$ENDIF}
  1258. end;
  1259. {------------------------------------------------------------------------------}
  1260. procedure TCustomRVData.AddNL(const s: String; StyleNo, ParaNo: Integer);
  1261. begin
  1262.   AddNLTag(s, StyleNo, ParaNo, 0);
  1263. end;
  1264. {------------------------------------------------------------------------------}
  1265. procedure TCustomRVData.AddFmt(const FormatStr: String; const Args: array of const;
  1266.   StyleNo, ParaNo: Integer);
  1267. begin
  1268.   AddNL(Format(FormatStr,Args), StyleNo, ParaNo);
  1269. end;
  1270. {------------------------------------------------------------------------------}
  1271. procedure TCustomRVData.AddTextNL(const s: String; StyleNo,
  1272.   FirstParaNo, OtherParaNo : Integer
  1273.   {$IFDEF RICHVIEWDEF4};Tag: Integer=0{$ENDIF});
  1274. begin
  1275.   AddTextUniversal(s, StyleNo, FirstParaNo, OtherParaNo, False, False,
  1276.     {$IFDEF RICHVIEWDEF4}Tag{$ELSE}0{$ENDIF});
  1277. end;
  1278. {------------------------------------------------------------------------------}
  1279. {$IFNDEF RVDONOTUSEUNICODE}
  1280. procedure TCustomRVData.AddTextNLA(const s: String; StyleNo,
  1281.   FirstParaNo, OtherParaNo : Integer
  1282.   {$IFDEF RICHVIEWDEF4};Tag: Integer=0{$ENDIF});
  1283. begin
  1284.   AddTextUniversal(s, StyleNo, FirstParaNo, OtherParaNo, False, True,
  1285.     {$IFDEF RICHVIEWDEF4}Tag{$ELSE}0{$ENDIF});
  1286. end;
  1287. {$ENDIF}
  1288. {------------------------------------------------------------------------------}
  1289. procedure TCustomRVData.AddTextBlockNL(const s: String; StyleNo, ParaNo: Integer
  1290.   {$IFDEF RICHVIEWDEF4};Tag: Integer=0{$ENDIF});
  1291. begin
  1292.   AddTextUniversal(s, StyleNo, ParaNo, ParaNo, True, False,
  1293.     {$IFDEF RICHVIEWDEF4}Tag{$ELSE}0{$ENDIF});
  1294. end;
  1295. {------------------------------------------------------------------------------}
  1296. function TCustomRVData.AddNamedCheckpointExTag(const CpName: String;
  1297.                                                RaiseEvent: Boolean;
  1298.                                                Tag: Integer): Integer;
  1299. begin
  1300.   {$IFDEF RVALLOWCPBYCP}
  1301.   if NotAddedCP<>nil then begin
  1302.     Result := CPCount-1;
  1303.     exit;
  1304.   end;
  1305.   {$ELSE}
  1306.   if NotAddedCP<>nil then
  1307.     raise ERichViewError.Create(errCPByCP);
  1308.   {$ENDIF}
  1309.   NotAddedCP := TRVCPInfo.Create;
  1310.   NotAddedCP.Name := CPName;
  1311.   NotAddedCP.Tag := Tag;
  1312.   NotAddedCP.Next := nil;
  1313.   NotAddedCP.Prev := nil;
  1314.   //NotAddedCP.ItemNo := -1;
  1315.   NotAddedCP.RaiseEvent := RaiseEvent;
  1316.   Result := CPCount;
  1317.   inc(CPCount);
  1318. end;
  1319. {------------------------------------------------------------------------------}
  1320. {$IFNDEF RVDONOTUSETABS}
  1321. procedure TCustomRVData.AddTab(TextStyleNo, ParaNo: Integer);
  1322. var Item: TRVTabItemInfo;
  1323. begin
  1324.   Item := TRVTabItemInfo.Create(Self);
  1325.   Item.StyleNo := rvsTab;
  1326.   Item.TextStyleNo := TextStyleNo;
  1327.   Item.ParaNo  := ParaNo;
  1328.   Item.SameAsPrev := ParaNo=-1;
  1329.   AddItem('', Item);
  1330. end;
  1331. {$ENDIF}
  1332. {------------------------------------------------------------------------------}
  1333. procedure TCustomRVData.AddBreakExTag(Width: Byte; Style: TRVBreakStyle;
  1334.                                       Color: TColor; Tag: Integer);
  1335. var Item: TRVBreakItemInfo;
  1336. begin
  1337.   Item := TRVBreakItemInfo.CreateEx(Self, Width, Style, Color);
  1338.   Item.SameAsPrev := False;
  1339.   Item.ParaNo     := 0;
  1340.   Item.Tag        := Tag;
  1341.   AddItem('',Item);
  1342. end;
  1343. {------------------------------------------------------------------------------}
  1344. procedure TCustomRVData.AddBreakEx(Width: Byte; Style: TRVBreakStyle;
  1345.                                       Color: TColor);
  1346. begin
  1347.   AddBreakExTag(Width, Style, Color, 0);
  1348. end;
  1349. {------------------------------------------------------------------------------}
  1350. procedure TCustomRVData.AddBreakTag(Tag: Integer);
  1351. begin
  1352.   AddBreakExTag(1, rvbsLine, clNone, Tag);
  1353. end;
  1354. {------------------------------------------------------------------------------}
  1355. procedure TCustomRVData.AddBreak;
  1356. begin
  1357.   AddBreakTag(0);
  1358. end;
  1359. {------------------------------------------------------------------------------}
  1360. procedure TCustomRVData.AddHotspotExTag(const Name: String;
  1361.                                     ImageIndex, HotImageIndex: Integer;
  1362.                                     ImageList: TCustomImageList;
  1363.                                     ParaNo, Tag: Integer);
  1364. var Item: TRVHotspotItemInfo;
  1365. begin
  1366.   Item               := TRVHotspotItemInfo.CreateEx(Self, ImageIndex, HotImageIndex,
  1367.                                                     ImageList, rvvaBaseLine);
  1368.   Item.ParaNo        := ParaNo;
  1369.   Item.Tag := Tag;
  1370.   AddItem(Name, Item);
  1371. end;
  1372. {------------------------------------------------------------------------------}
  1373. procedure TCustomRVData.AddHotspotEx(const Name: String;
  1374.                                      ImageIndex, HotImageIndex: Integer;
  1375.                                      ImageList: TCustomImageList;
  1376.                                      ParaNo: Integer);
  1377. begin
  1378.   AddHotspotExTag(Name, ImageIndex, HotImageIndex, ImageList, ParaNo, 0);
  1379. end;
  1380. {------------------------------------------------------------------------------}
  1381. procedure TCustomRVData.AddBulletExTag(const Name: String; ImageIndex: Integer;
  1382.                                        ImageList: TCustomImageList;
  1383.                                        ParaNo, Tag: Integer);
  1384. var Item: TRVBulletItemInfo;
  1385. begin
  1386.   Item            := TRVBulletItemInfo.CreateEx(Self, ImageIndex, ImageList, rvvaBaseline);
  1387.   Item.ParaNo     := ParaNo;
  1388.   Item.Tag        := Tag;
  1389.   AddItem(Name, Item);
  1390. end;
  1391. {------------------------------------------------------------------------------}
  1392. procedure TCustomRVData.AddBulletEx(const Name: String; ImageIndex: Integer;
  1393.                                     ImageList: TCustomImageList;
  1394.                                     ParaNo: Integer);
  1395. begin
  1396.   AddBulletExTag(Name, ImageIndex, ImageList, ParaNo, 0)
  1397. end;
  1398. {------------------------------------------------------------------------------}
  1399. { "gr" does not copied, do not free it!                                        }
  1400. procedure TCustomRVData.AddPictureExTag(const Name: String; gr: TGraphic;
  1401.                                        ParaNo: Integer; VAlign: TRVVAlign;
  1402.                                        Tag: Integer);
  1403. var Item: TRVGraphicItemInfo;
  1404. begin
  1405.   Item := TRVGraphicItemInfo.CreateEx(Self, gr, VAlign);
  1406.   Item.ParaNo  := ParaNo;
  1407.   Item.Tag     := Tag;
  1408.   AddItem(Name, Item);
  1409. end;
  1410. {------------------------------------------------------------------------------}
  1411. { gr does not copied, do not free it!                                          }
  1412. procedure TCustomRVData.AddPictureEx(const Name: String; gr: TGraphic;
  1413.                                      ParaNo: Integer;
  1414.                                      VAlign: TRVVAlign);
  1415. begin
  1416.   AddPictureExTag(Name, gr, ParaNo, VAlign, 0);
  1417. end;
  1418. {------------------------------------------------------------------------------}
  1419. procedure TCustomRVData.AddHotPicture(const Name: String; gr: TGraphic;
  1420.   ParaNo: Integer; VAlign: TRVVAlign);
  1421. begin
  1422.   AddHotPictureTag(Name, gr, ParaNo, VAlign, 0);
  1423. end;
  1424. {------------------------------------------------------------------------------}
  1425. procedure TCustomRVData.AddHotPictureTag(const Name: String; gr: TGraphic;
  1426.   ParaNo: Integer; VAlign: TRVVAlign; Tag: Integer);
  1427. var Item: TRVHotGraphicItemInfo;
  1428. begin
  1429.   Item := TRVHotGraphicItemInfo.CreateEx(Self, gr, VAlign);
  1430.   Item.ParaNo  := ParaNo;
  1431.   Item.Tag     := Tag;
  1432.   AddItem(Name, Item);
  1433. end;
  1434. {------------------------------------------------------------------------------}
  1435. { do not free ctrl yourself!                                                   }
  1436. procedure TCustomRVData.AddControlExTag(const Name: String; ctrl: TControl;
  1437.                                        ParaNo: Integer; VAlign: TRVVAlign;
  1438.                                        Tag: Integer);
  1439. var Item: TRVControlItemInfo;
  1440. begin
  1441.   Item         := TRVControlItemInfo.CreateEx(Self, ctrl, VAlign);
  1442.   Item.StyleNo := rvsComponent;
  1443.   Item.ParaNo  := ParaNo;
  1444.   Item.Tag     := Tag;
  1445.   AddItem(Name, Item);
  1446.   ctrl.Parent := GetParentControl;
  1447. end;
  1448. {------------------------------------------------------------------------------}
  1449. { do not free ctrl yourself!                                                   }
  1450. procedure TCustomRVData.AddControlEx(const Name: String; ctrl: TControl;
  1451.                                      ParaNo: Integer;
  1452.                                      VAlign: TRVVAlign);
  1453. begin
  1454.   AddControlExTag(Name, ctrl, ParaNo, VAlign, 0);
  1455. end;
  1456. {------------------------------------------------------------------------------}
  1457. procedure TCustomRVData.SetAddParagraphMode(AllowNewPara: Boolean);
  1458. begin
  1459.  FAllowNewPara := AllowNewPara;
  1460. end;
  1461. {------------------------------------------------------------------------------}
  1462. procedure TCustomRVData.SetCP(Item: TCustomRVItemInfo; var PrevCP, CP: TRVCPInfo);
  1463. begin
  1464.   if CP=nil then
  1465.     exit;
  1466.   CP.Prev := PrevCP;
  1467.   CP.ItemInfo := Item;
  1468.   if (PrevCP=nil) then begin // inserting before first, making first
  1469.     if FirstCP<>nil then
  1470.       FirstCP.Prev := CP;
  1471.     CP.Next := FirstCP;
  1472.     FirstCP := CP;
  1473.     end
  1474.   else
  1475.     CP.Next := PrevCP.Next;
  1476.   if PrevCP<>nil then
  1477.     PrevCP.Next := CP;
  1478.   if CP.Next<>nil then
  1479.     CP.Next.Prev := CP;
  1480.   if PrevCP=LastCP then
  1481.     LastCP := CP;
  1482.   Item.Checkpoint := CP;
  1483.   CP := nil;
  1484. end;
  1485. {------------------------------------------------------------------------------}
  1486. procedure TCustomRVData.UnlinkCheckpoint(cp: TRVCPInfo; DecCPCount: Boolean);
  1487. begin
  1488.   if cp<>nil then begin
  1489.     cp.ItemInfo := nil;
  1490.     if FirstCP = cp then FirstCP := cp.Next;
  1491.     if LastCP = cp  then LastCP  := cp.Prev;
  1492.     if cp.Prev<>nil then cp.Prev.Next := cp.Next;
  1493.     if cp.Next<>nil then cp.Next.Prev := cp.Prev;
  1494.     if DecCPCount then
  1495.       dec(CPCount);
  1496.   end;
  1497. end;
  1498. {------------------------------------------------------------------------------}
  1499. procedure TCustomRVData.FreeCheckpoint(var cp: TRVCPInfo; AdjustLinks,DecCPCount: Boolean);
  1500. begin
  1501.   if cp<>nil then begin
  1502.     if AdjustLinks then
  1503.       UnlinkCheckpoint(cp,False);
  1504.     if rvoTagsArePChars in Options then
  1505.       StrDispose(PChar(cp.Tag));
  1506.     cp.Free;
  1507.     cp := nil;
  1508.     if DecCPCount then
  1509.       dec(CPCount);
  1510.   end;
  1511. end;
  1512. {------------------------------------------------------------------------------}
  1513. function TCustomRVData.ShareItems: Boolean;
  1514. begin
  1515.   Result := False;
  1516. end;
  1517. {------------------------------------------------------------------------------}
  1518. function TCustomRVData.CanLoadLayout: Boolean;
  1519. begin
  1520.   Result := False;
  1521. end;
  1522. {------------------------------------------------------------------------------}
  1523. procedure TCustomRVData.DeleteItems(FirstItemNo, Count: Integer);
  1524. var i: Integer;
  1525. begin
  1526.   if ShareItems then exit;
  1527.   if FirstItemNo>=Items.Count then exit;
  1528.   if FirstItemNo+Count>Items.Count then
  1529.     Count := Items.Count-FirstItemNo;
  1530.   Items.BeginUpdate;
  1531.   try
  1532.     for i := FirstItemNo to FirstItemNo+Count-1 do
  1533.       FreeItem(i,False);
  1534.     for i :=1 to Count do
  1535.       Items.Delete(FirstItemNo);
  1536.   finally
  1537.     Items.EndUpdate;
  1538.   end;
  1539. end;
  1540. {------------------------------------------------------------------------------}
  1541. procedure TCustomRVData.DeleteSection(const CpName: String);
  1542. var startno, endno: Integer;
  1543.     cp: TRVCPInfo;
  1544. begin
  1545.   if ShareItems then exit;
  1546.    cp := FirstCP;
  1547.    startno := -1;
  1548.    endno := -1;
  1549.    while cp<>nil do begin
  1550.      if cp.Name=CpName then begin
  1551.        startno := Items.IndexOfObject(cp.ItemInfo);
  1552.        endno := Items.Count-1;
  1553.        break;
  1554.      end;
  1555.      cp := cp.Next;
  1556.    end;
  1557.    if startno=-1 then exit;
  1558.    cp := cp.Next;
  1559.    while cp<>nil do begin
  1560.      if cp.Name<>'' then begin
  1561.        endno := Items.IndexOfObject(cp.ItemInfo)-1;
  1562.        break;
  1563.      end;
  1564.      cp := cp.Next;
  1565.    end;
  1566.    DeleteItems(startno, endno-startno+1);
  1567. end;
  1568. {------------------------------------------------------------------------------}
  1569. procedure TCustomRVData.InternalFreeItem(item: TCustomRVItemInfo; Clearing: Boolean);
  1570. begin
  1571.   if Item=nil then
  1572.     exit;
  1573.   {$IFNDEF RVDONOTUSELISTS}
  1574.   DeleteMarkerFromList(item, Clearing);
  1575.   {$ENDIF}
  1576.   FreeCheckpoint(Item.Checkpoint, True, True);
  1577.   if rvoTagsArePChars in Options then
  1578.     StrDispose(PChar(Item.Tag));
  1579.   Item.Free;
  1580. end;
  1581. {------------------------------------------------------------------------------}
  1582. procedure TCustomRVData.FreeItem(ItemNo: Integer; Clearing: Boolean);
  1583. var item: TCustomRVItemInfo;
  1584.     s: String;
  1585. begin
  1586.   item := TCustomRVItemInfo(Items.Objects[ItemNo]);
  1587.   s := Items[ItemNo];
  1588.   ItemAction(rviaDestroying, item, s, Self);
  1589.   ControlAction(rvcaDestroy, ItemNo, item);
  1590.   InternalFreeItem(item, Clearing);
  1591. end;
  1592. {------------------------------------------------------------------------------}
  1593. procedure TCustomRVData.Clear;
  1594. var i: Integer;
  1595.     Clearing: Boolean;
  1596. begin
  1597.   Clearing := rvstClearing in State;
  1598.   Include(State, rvstClearing);
  1599.   try
  1600.     Exclude(State, rvstFirstParaAborted);
  1601.     Exclude(State, rvstLastParaAborted);    
  1602.     if not ShareItems then begin
  1603.       Items.BeginUpdate;
  1604.       for i:=0 to Items.Count-1 do
  1605.         FreeItem(i,True);
  1606.       Items.Clear;
  1607.       Items.EndUpdate;
  1608.     end;
  1609.     FreeCheckpoint(NotAddedCP, False, True);
  1610.     FirstCP := nil;
  1611.     LastCP  := nil;
  1612.     if GetDocProperties<>nil then
  1613.       GetDocProperties.Clear;
  1614.   finally
  1615.     if not Clearing then
  1616.       Exclude(State, rvstClearing);  
  1617.   end;
  1618. end;
  1619. {------------------------------------------------------------------------------}
  1620. function TCustomRVData.GetOffsBeforeItem(ItemNo: Integer): Integer;
  1621. begin
  1622.   if GetItemStyle(ItemNo)<0 then
  1623.     Result := 0
  1624.   else
  1625.     Result := 1;
  1626. end;
  1627. {------------------------------------------------------------------------------}
  1628. function TCustomRVData.GetOffsAfterItem(ItemNo: Integer): Integer;
  1629. begin
  1630.   if GetItemStyle(ItemNo)<0 then
  1631.     Result := 1
  1632.   else
  1633.     Result := RVU_Length(Items[ItemNo], GetItemOptions(ItemNo))+1;
  1634. end;
  1635. {------------------------------------------------------------------------------}
  1636. function TCustomRVData.ReplaceTabs(const s: String; StyleNo: Integer;
  1637.   UnicodeDef: Boolean): String;
  1638. begin
  1639.   if GetRVStyle = nil then begin
  1640.     {$IFNDEF RVDONOTUSEUNICODE}
  1641.     if UnicodeDef then
  1642.       Result := RV_ReplaceTabsW(s,8)
  1643.     else
  1644.     {$ENDIF}
  1645.       Result := RV_ReplaceTabsA(s,8)
  1646.     end
  1647.   else
  1648.     {$IFNDEF RVDONOTUSEUNICODE}
  1649.     if GetRVStyle.TextStyles[StyleNo].Unicode then
  1650.       Result := RV_ReplaceTabsW(s, GetRVStyle.SpacesInTab)
  1651.     else
  1652.     {$ENDIF}
  1653.       Result := RV_ReplaceTabsA(s, GetRVStyle.SpacesInTab);
  1654. end;
  1655. {------------------------------------------------------------------------------}
  1656. procedure TCustomRVData.AddStringFromFile(const s: String;
  1657.   StyleNo,ParaNo: Integer; FromNewLine, AsSingleParagraph: Boolean;
  1658.   var FirstTime, PageBreak: Boolean);
  1659. begin
  1660.   if not FromNewLine then
  1661.     ParaNo := -1;
  1662.   {$IFNDEF RVDONOTUSEUNICODE}
  1663.   AddNLATag(s,StyleNo,ParaNo,0);
  1664.   {$ELSE}
  1665.   AddNLTag(s,StyleNo,ParaNo,0);
  1666.   {$ENDIF}
  1667.   if AsSingleParagraph and FirstTime then begin
  1668.     SetAddParagraphMode(False);
  1669.     FirstTime := False;
  1670.   end;
  1671.   if PageBreak then begin
  1672.     PageBreaksBeforeItems[Items.Count-1] := True;
  1673.     PageBreak := False;
  1674.   end;
  1675. end;
  1676. {------------------------------------------------------------------------------}
  1677. function TCustomRVData.LoadText(const FileName: String; StyleNo, ParaNo: Integer;
  1678.   AsSingleParagraph: Boolean): Boolean;
  1679. var Stream: TFileStream;
  1680. {
  1681.     f: TextFile;
  1682.     s: String;
  1683. }
  1684. begin
  1685. {
  1686.   AssignFile(f, FileName);
  1687.   Reset(f);
  1688.   while not eof(f) do begin
  1689.     Readln(f, s);
  1690.     AddTextNL(s, StyleNo, ParaNo, ParaNo);
  1691.   end;
  1692.   CloseFile(f);
  1693.   Result := True;
  1694.   exit;
  1695.   }
  1696.   try
  1697.     Stream := TFileStream.Create(FileName, fmOpenRead);
  1698.     try
  1699.       Result := LoadTextFromStream(Stream, StyleNo, ParaNo, AsSingleParagraph)
  1700.     finally
  1701.       Stream.Free;
  1702.     end;
  1703.   except
  1704.     Result := False;
  1705.   end;
  1706. end;
  1707. {------------------------------------------------------------------------------}
  1708. function TCustomRVData.AddTextUniversal(const text: String; StyleNo, FirstParaNo,
  1709.   OtherParaNo: Integer; AsSingleParagraph, CheckUnicode: Boolean; Tag: Integer): Boolean;
  1710. var ANP: Boolean;
  1711.     FromNewLine, FirstTime, ProcessPageBreaks, PageBreak, ProcessTabs,
  1712.     CopyTags: Boolean;
  1713.     ParaNo : Integer;
  1714.     fulltextstartptr, startptr, ptr, endptr: PChar;
  1715.     SkipIfEqual: Char;
  1716.     TabItem: TRVTabItemInfo;
  1717.     {........................................................}
  1718.     procedure AddTextItem;
  1719.     var AParaNo, ATag: Integer;
  1720.         s: String;
  1721.     begin
  1722.       s := System.Copy(text, startptr-fulltextstartptr+1, ptr-startptr);
  1723.       if (s='') and not FromNewLine then
  1724.         exit;
  1725.       if FromNewLine or PageBreak then
  1726.         AParaNo := ParaNo
  1727.       else
  1728.         AParaNo := -1;
  1729.       if CopyTags then
  1730.         ATag := RV_CopyTag(Tag, True)
  1731.       else
  1732.         ATag := Tag;
  1733.       {$IFNDEF RVDONOTUSEUNICODE}
  1734.       if not CheckUnicode then
  1735.       {$ENDIF}
  1736.         if ProcessTabs then
  1737.           AddNLTag_(s, StyleNo, AParaNo, ATag)
  1738.         else
  1739.           AddNLTag(s, StyleNo, AParaNo, ATag)
  1740.       {$IFNDEF RVDONOTUSEUNICODE}
  1741.       else
  1742.         if ProcessTabs then
  1743.           AddNLATag_(s, StyleNo, AParaNo, ATag)
  1744.         else
  1745.           AddNLATag(s, StyleNo, AParaNo, ATag)
  1746.       {$ENDIF};
  1747.       FromNewLine := False;
  1748.       if PageBreak then begin
  1749.         PageBreaksBeforeItems[Items.Count-1] := True;
  1750.         PageBreak := False;
  1751.       end;
  1752.       if AsSingleParagraph and FirstTime then begin
  1753.         SetAddParagraphMode(False);
  1754.         FirstTime := False;
  1755.       end;      
  1756.     end;
  1757.     {........................................................}
  1758. begin
  1759.   ANP := FAllowNewPara;
  1760.   FirstTime := True;
  1761.   Result := True;
  1762.   ProcessPageBreaks := SupportsPageBreaks;
  1763.   PageBreak         := False;
  1764.   ProcessTabs       := (GetRVStyle<>nil) and (GetRVStyle.SpacesInTab<=0);
  1765.   CopyTags          := (Tag<>0) and (rvoTagsArePChars in Options);
  1766.   ParaNo            := FirstParaNo;
  1767.   FromNewLine       := ParaNo>=0;
  1768.   try
  1769.     fulltextstartptr := PChar(text);
  1770.     startptr := fulltextstartptr;
  1771.     ptr      := startptr;
  1772.     endptr   := PChar(text)+Length(text);
  1773.     SkipIfEqual := #0;
  1774.     while ptr<endptr do begin
  1775.       if SkipIfEqual<>#0 then begin
  1776.         if (ptr^=SkipIfEqual) then begin
  1777.           inc(startptr);
  1778.           inc(ptr);
  1779.           SkipIfEqual := #0;
  1780.           continue;
  1781.         end;
  1782.         SkipIfEqual := #0;
  1783.       end;
  1784.       if ((ptr^) in [#10, #12, #13]) or (ProcessTabs and ((ptr^)=#9)) then begin
  1785.         AddTextItem;
  1786.         startptr := ptr+1;
  1787.       end;
  1788.       case ptr^ of
  1789.        #9: // tab
  1790.          begin
  1791.            if ProcessTabs then begin
  1792.              TabItem := TRVTabItemInfo.Create(Self);
  1793.              TabItem.StyleNo := rvsTab;
  1794.              TabItem.TextStyleNo := StyleNo;
  1795.              if FromNewLine then
  1796.                TabItem.ParaNo := ParaNo
  1797.              else
  1798.                TabItem.ParaNo := -1;
  1799.              AddItem('', TabItem);
  1800.              FromNewLine := False;
  1801.            end;
  1802.          end;
  1803.        #12: // page break
  1804.          begin
  1805.            PageBreak := ProcessPageBreaks;
  1806.            FromNewLine := True;
  1807.            ParaNo := OtherParaNo;
  1808.          end;
  1809.        #13:
  1810.          begin
  1811.            FromNewLine := True;
  1812.            SkipIfEqual := #10;
  1813.            ParaNo := OtherParaNo;
  1814.          end;
  1815.        #10:
  1816.          begin
  1817.            FromNewLine := True;
  1818.            SkipIfEqual := #13;
  1819.            ParaNo := OtherParaNo;
  1820.          end;
  1821.       end;
  1822.       inc(ptr);
  1823.     end;
  1824.     AddTextItem;
  1825.   except
  1826.     Result := False;
  1827.   end;
  1828.   SetAddParagraphMode(ANP);
  1829.   if CopyTags then
  1830.     StrDispose(PChar(Tag));
  1831. end;
  1832. {------------------------------------------------------------------------------}
  1833. function TCustomRVData.LoadTextFromStream(Stream: TStream; StyleNo,
  1834.   ParaNo: Integer; AsSingleParagraph: Boolean):Boolean;
  1835. var FullText: String;
  1836. begin
  1837.   if Stream.Size=Stream.Position then begin
  1838.     Result := True;
  1839.     exit;
  1840.   end;
  1841.   SetLength(FullText, Stream.Size-Stream.Position);
  1842.   Stream.ReadBuffer(PChar(FullText)^, Length(FullText));
  1843.   Replace0(FullText);
  1844.   Result := AddTextUniversal(FullText, StyleNo, ParaNo, ParaNo,
  1845.     AsSingleParagraph, True, 0);
  1846. end;
  1847. {------------------------------------------------------------------------------}
  1848. function TCustomRVData.SaveTextToStream(const Path: String; Stream: TStream;
  1849.   LineWidth: Integer;
  1850.   SelectionOnly, TextOnly, Unicode, UnicodeWriteSignature: Boolean):Boolean;
  1851. var i, StartItemNo,EndItemNo,StartOffs,EndOffs: Integer;
  1852.     {$IFNDEF RVDONOTUSELISTS}
  1853.     MarkerItemNo: Integer;
  1854.     {$ENDIF}
  1855.     Item: TCustomRVItemInfo;
  1856.     s: String;
  1857.     NotUsedPart: TRVMultiDrawItemPart;
  1858.     CustomSave: Boolean;
  1859.     {$IFNDEF RVDONOTUSEUNICODE}
  1860.     UniSign: Word;
  1861.     {$ENDIF}
  1862.     {..................................................}
  1863.     function GetStr(Item:TCustomRVItemInfo; const s: String;
  1864.       CustomSave: Boolean) : String;
  1865.     begin
  1866.       {$IFNDEF RVDONOTUSEUNICODE}
  1867.       if not CustomSave then begin
  1868.         if (Item=nil) or (Item.StyleNo<0) then begin
  1869.           if Unicode and ((Item=nil) or not Item.GetBoolValue(rvbpCanSaveUnicode)) then
  1870.             Result := RVU_AnsiToUnicode(GetDefaultCodePage, s)
  1871.           else
  1872.             Result := s
  1873.           end
  1874.         else if (rvioUnicode in Item.ItemOptions) and not Unicode then
  1875.           Result := RVU_UnicodeToAnsi(GetDefaultCodePage, s)
  1876.         else if not (rvioUnicode in Item.ItemOptions) and Unicode then
  1877.           Result := RVU_AnsiToUnicode(GetStyleCodePage(GetActualStyle(Item)), s)
  1878.         else
  1879.           Result := s;
  1880.         end
  1881.       else
  1882.       {$ENDIF}
  1883.         Result := s;
  1884.     end;
  1885.     {..................................................}
  1886.     function GetTextStr(ItemNo, StartOffs, EndOffs: Integer;
  1887.       var CustomSave: Boolean): String;
  1888.     begin
  1889.       if StartOffs<0 then
  1890.         Result := Items[ItemNo]
  1891.       else
  1892.         Result := RVU_Copy(Items[ItemNo], StartOffs, EndOffs-StartOffs,
  1893.           GetItem(ItemNo).ItemOptions);
  1894.       CustomSave := SaveItemToFile(Path, Self, ItemNo, rvsfText, Unicode, Result);
  1895.     end;
  1896.     {..................................................}
  1897.     function GetNonTextStr(ItemNo, StartOffs, EndOffs: Integer;
  1898.       var CustomSave: Boolean): String;
  1899.     var SaveUnicode: Boolean;
  1900.         Item: TCustomRVItemInfo;
  1901.     begin
  1902.       CustomSave := False;
  1903.       Item := GetItem(ItemNo);
  1904.       Result := '';
  1905.       if (not TextOnly or Item.GetBoolValue(rvbpAlwaysInText)) and
  1906.          (StartOffs<EndOffs) then begin
  1907.         CustomSave := SaveItemToFile(Path, Self, ItemNo, rvsfText, Unicode, Result);
  1908.         if not CustomSave then begin
  1909.           {$IFNDEF RVDONOTUSEUNICODE}
  1910.           SaveUnicode := Unicode and Item.GetBoolValue(rvbpCanSaveUnicode);
  1911.           {$ELSE}
  1912.           SaveUnicode := False;
  1913.           {$ENDIF}
  1914.           Result := GetItem(ItemNo).AsText(LineWidth, Self, Items[ItemNo], Path,
  1915.             TextOnly, SaveUnicode);
  1916.         end;
  1917.       end;
  1918.     end;
  1919.     {..................................................}
  1920. begin
  1921.   try
  1922.     Result := True;
  1923.     RVFGetLimits(GetRVFSaveScope(SelectionOnly),StartItemNo,EndItemNo,StartOffs,EndOffs,NotUsedPart,NotUsedPart);
  1924.     if (StartItemNo=-1) or (StartItemNo>EndItemNo) then
  1925.       exit;
  1926.     {$IFNDEF RVDONOTUSEUNICODE}
  1927.     if Unicode and UnicodeWriteSignature then begin
  1928.       UniSign := UNI_LSB_FIRST;
  1929.       Stream.WriteBuffer(UniSign, 2);
  1930.     end;
  1931.     {$ENDIF}
  1932.     {$IFNDEF RVDONOTUSELISTS}
  1933.     if SelectionOnly then begin
  1934.       MarkerItemNo := GetFirstParaSectionItem(StartItemNo);
  1935.       if GetItemStyle(MarkerItemNo)=rvsListMarker then begin
  1936.         s := GetNonTextStr(MarkerItemNo, 0, 1, CustomSave);
  1937.         RVFWrite(Stream, GetStr(GetItem(MarkerItemNo), s, CustomSave));
  1938.       end;
  1939.     end;
  1940.     {$ENDIF}
  1941.     Item := GetItem(StartItemNo);
  1942.     if StartItemNo = EndItemNo then begin
  1943.       if Item.StyleNo<0 then
  1944.         s := GetNonTextStr(StartItemNo, StartOffs, EndOffs, CustomSave)
  1945.       else
  1946.         s := GetTextStr(StartItemNo, StartOffs, EndOffs, CustomSave);
  1947.       RVFWrite(Stream, GetStr(Item, s, CustomSave));
  1948.       end
  1949.     else begin
  1950.       if Item.StyleNo < 0 then
  1951.         s := GetNonTextStr(StartItemNo, StartOffs, 1, CustomSave)
  1952.       else
  1953.         s := GetTextStr(StartItemNo, StartOffs, RVU_Length(Items[StartItemNo],
  1954.           Item.ItemOptions)+1, CustomSave);
  1955.       RVFWrite(Stream, GetStr(Item, s, CustomSave));
  1956.       for i := StartItemNo+1 to EndItemNo-1 do begin
  1957.         Item := GetItem(i);
  1958.         if Item.PageBreakBefore and RichViewSavePageBreaksInText then
  1959.           RVFWrite(Stream, GetStr(nil, #$0C, False))
  1960.         else if not Item.SameAsPrev then
  1961.           RVFWrite(Stream, GetStr(nil, crlf, False));
  1962.         if Item.StyleNo < 0 then
  1963.           s := GetNonTextStr(i, 0, 1, CustomSave)
  1964.         else
  1965.           s := GetTextStr(i, -1, -1, CustomSave);
  1966.         RVFWrite(Stream, GetStr(Item, s, CustomSave));
  1967.       end;
  1968.       Item := GetItem(EndItemNo);
  1969.       if Item.PageBreakBefore and RichViewSavePageBreaksInText then
  1970.         RVFWrite(Stream, GetStr(nil, #$0C, False))
  1971.       else if not Item.SameAsPrev then
  1972.         RVFWrite(Stream, GetStr(nil, crlf, False));
  1973.        if Item.StyleNo < 0 then
  1974.         s := GetNonTextStr(EndItemNo, 0, EndOffs, CustomSave)
  1975.       else
  1976.         s := GetTextStr(EndItemNo, 1, EndOffs, CustomSave);
  1977.       RVFWrite(Stream, GetStr(Item, s, CustomSave));
  1978.     end;
  1979.   except
  1980.     Result := False;
  1981.   end;
  1982. end;
  1983. {------------------------------------------------------------------------------}
  1984. function TCustomRVData.SaveText(const FileName: String; LineWidth: Integer;
  1985.   Unicode: Boolean): Boolean;
  1986. var Stream: TFileStream;
  1987. begin
  1988.   try
  1989.     Stream := TFileStream.Create(FileName, fmCreate);
  1990.     try
  1991.       Result := SaveTextToStream(ExtractFilePath(FileName), Stream, LineWidth,
  1992.         False, False, Unicode, Unicode);
  1993.     finally
  1994.       Stream.Free;
  1995.     end;
  1996.   except
  1997.     Result := False;
  1998.   end;
  1999. end;
  2000. {------------------------------------------------------------------------------}
  2001. {$IFNDEF RVDONOTUSEUNICODE}
  2002. procedure TCustomRVData.AddTextNLW(const s: String; StyleNo, FirstParaNo,
  2003.   OtherParaNo : Integer; DefAsSingleParagraph: Boolean);
  2004. var
  2005.     ParaNo: Integer;
  2006.     startptr,ptr,endptr: PWord;
  2007.     SkipIfEqual: Word;
  2008.     ANP: Boolean;
  2009.     ProcessTabs, ProcessPageBreaks, PageBreak, FromNewLine: Boolean;
  2010.     TabItem: TRVTabItemInfo;
  2011.     {.................................}
  2012.     procedure AddTextItem(AllowAddingEmpty: Boolean);
  2013.     var str: String;
  2014.         AParaNo: Integer;
  2015.     begin
  2016.       if (startptr=ptr) and (not FromNewLine or not AllowAddingEmpty) then
  2017.         exit;
  2018.       str := Copy(s, PChar(startptr)-PChar(s)+1, PChar(ptr)-PChar(startptr));
  2019.       if FromNewLine or PageBreak then
  2020.         AParaNo := ParaNo
  2021.       else
  2022.         AParaNo := -1;
  2023.       AddNLWTagRaw(str, StyleNo, AParaNo, 0);
  2024.       FromNewLine := False;
  2025.       if PageBreak then begin
  2026.         PageBreaksBeforeItems[Items.Count-1] := True;
  2027.         PageBreak := False;
  2028.       end;
  2029.     end;
  2030.     {.................................}
  2031. begin
  2032.    ANP := FAllowNewPara;
  2033.    RVCheckUni(Length(s));
  2034.    startptr := PWord(PChar(s));
  2035.    endptr   := PWord(PChar(s)+Length(s));
  2036.    RVU_ProcessByteOrderMark(startptr, Length(s) div 2);
  2037.    ptr      := startptr;
  2038.    if ptr=endptr then begin
  2039.      if FirstParaNo<>-1 then
  2040.        AddNL(s, StyleNo, FirstParaNo);
  2041.      exit;
  2042.    end;
  2043.    ParaNo := FirstParaNo;
  2044.    FromNewLine := ParaNo>=0;
  2045.    SkipIfEqual := 0;
  2046.    ProcessPageBreaks := SupportsPageBreaks;
  2047.    PageBreak         := False;
  2048.    ProcessTabs       := (GetRVStyle<>nil) and (GetRVStyle.SpacesInTab<=0);
  2049.    SetAddParagraphMode(not DefAsSingleParagraph);
  2050.    while PChar(ptr)<PChar(endptr) do begin
  2051.      if SkipIfEqual<>0 then begin
  2052.        if (ptr^=SkipIfEqual) then begin
  2053.          inc(PChar(startptr),2);
  2054.          inc(PChar(ptr), 2);
  2055.          SkipIfEqual := 0;
  2056.          continue;
  2057.        end;
  2058.        SkipIfEqual := 0;
  2059.      end;
  2060.      case ptr^ of
  2061.        UNI_LineSeparator, UNI_VerticalTab:
  2062.          begin
  2063.            AddTextItem(True);
  2064.            SetAddParagraphMode(False);
  2065.            ParaNo := OtherParaNo;
  2066.            FromNewLine := True;
  2067.            startptr := PWord(PChar(ptr)+2);
  2068.          end;
  2069.        UNI_ParagraphSeparator:
  2070.          begin
  2071.            AddTextItem(True);
  2072.            SetAddParagraphMode(True);
  2073.            ParaNo := OtherParaNo;
  2074.            FromNewLine := True;
  2075.            startptr := PWord(PChar(ptr)+2);
  2076.          end;
  2077.        UNI_FF:
  2078.          begin
  2079.            AddTextItem(True);
  2080.            PageBreak := ProcessPageBreaks;
  2081.            ParaNo := OtherParaNo;
  2082.            FromNewLine := True;
  2083.            startptr := PWord(PChar(ptr)+2);
  2084.          end;
  2085.        UNI_CR:
  2086.          begin
  2087.            AddTextItem(True);
  2088.            SetAddParagraphMode(not DefAsSingleParagraph);
  2089.            SkipIfEqual := UNI_LF;
  2090.            ParaNo := OtherParaNo;
  2091.            FromNewLine := True;
  2092.            startptr := PWord(PChar(ptr)+2);
  2093.          end;
  2094.        UNI_LF:
  2095.          begin
  2096.            AddTextItem(True);
  2097.            SetAddParagraphMode(not DefAsSingleParagraph);
  2098.            SkipIfEqual := UNI_CR;
  2099.            ParaNo := OtherParaNo;
  2100.            FromNewLine := True;
  2101.            startptr := PWord(PChar(ptr)+2);
  2102.          end;
  2103.        UNI_Tab:
  2104.          begin
  2105.            if ProcessTabs then begin
  2106.              AddTextItem(False);
  2107.              TabItem := TRVTabItemInfo.Create(Self);
  2108.              TabItem.StyleNo := rvsTab;
  2109.              TabItem.TextStyleNo := StyleNo;
  2110.              if FromNewLine then
  2111.                TabItem.ParaNo := ParaNo
  2112.              else
  2113.                TabItem.ParaNo := -1;
  2114.              AddItem('', TabItem);
  2115.              FromNewLine := False;
  2116.              SetAddParagraphMode(not DefAsSingleParagraph);
  2117.              startptr := PWord(PChar(ptr)+2);
  2118.            end;
  2119.          end;
  2120.      end;
  2121.      inc(PChar(ptr), 2);
  2122.    end;
  2123.    AddTextItem(True);
  2124.    SetAddParagraphMode(ANP);
  2125. end;
  2126. {------------------------------------------------------------------------------}
  2127. function TCustomRVData.LoadTextFromStreamW(Stream: TStream; StyleNo, ParaNo: Integer;
  2128.       DefAsSingleParagraph: Boolean):Boolean;
  2129. var s: String;
  2130. begin
  2131.   Result := True;
  2132.   try
  2133.     RVCheckUni(Stream.Size-Stream.Position);  
  2134.     SetLength(s, Stream.Size-Stream.Position);
  2135.     Stream.ReadBuffer(PChar(s)^,Stream.Size-Stream.Position);
  2136.     AddTextNLW(s, StyleNo, ParaNo, ParaNo, DefAsSingleParagraph);
  2137.   except
  2138.     Result := False;
  2139.   end;
  2140. end;
  2141. {------------------------------------------------------------------------------}
  2142. function TCustomRVData.LoadTextW(const FileName: String; StyleNo, ParaNo: Integer;
  2143.   DefAsSingleParagraph: Boolean): Boolean;
  2144. var Stream: TFileStream;
  2145. begin
  2146.   Stream := TFileStream.Create(FileName, fmOpenRead);
  2147.   try
  2148.     Result := LoadTextFromStreamW(Stream, StyleNo, ParaNo, DefAsSingleParagraph);
  2149.   finally
  2150.     Stream.Free;
  2151.   end;
  2152. end;
  2153. {$ENDIF}
  2154. {$IFNDEF RVDONOTUSEHTML}
  2155. {------------------------------------------------------------------------------}
  2156. function TCustomRVData.SaveHTML(const FileName, Title,
  2157.   ImagesPrefix: String; Options: TRVSaveOptions; Color: TColor;
  2158.   var imgSaveNo: Integer;
  2159.   LeftMargin, TopMargin, RightMargin, BottomMargin: Integer;
  2160.   Background: TRVBackground): Boolean;
  2161. var Stream: TFileStream;
  2162. begin
  2163.   try
  2164.     Stream := TFileStream.Create(FileName, fmCreate);
  2165.     try
  2166.       Result := SaveHTMLToStream(Stream, ExtractFilePath(FileName),
  2167.                                  Title, ImagesPrefix, Options,
  2168.                                  Color, imgSaveNo,
  2169.                                  LeftMargin, TopMargin,
  2170.                                  RightMargin, BottomMargin,
  2171.                                  Background, nil);
  2172.     finally
  2173.       Stream.Free;
  2174.     end;
  2175.   except
  2176.     Result := False;
  2177.   end;
  2178. end;
  2179. {------------------------------------------------------------------------------}
  2180. function TCustomRVData.SaveHTMLEx(const FileName, Title, ImagesPrefix,
  2181.   ExtraStyles, ExternalCSS, CPPrefix: String; Options: TRVSaveOptions;
  2182.   Color: TColor; var CurrentFileColor: TColor; var imgSaveNo: Integer;
  2183.   LeftMargin, TopMargin, RightMargin, BottomMargin: Integer;
  2184.   Background: TRVBackground):Boolean;
  2185. var Stream: TFileStream;
  2186. begin
  2187.   try
  2188.     Stream := TFileStream.Create(FileName, fmCreate);
  2189.     try
  2190.       Result := SaveHTMLToStreamEx(Stream, ExtractFilePath(FileName),
  2191.         Title, ImagesPrefix, ExtraStyles, ExternalCSS, CPPrefix, Options,
  2192.         Color, CurrentFileColor, imgSaveNo, LeftMargin, TopMargin,
  2193.         RightMargin, BottomMargin, Background, nil);
  2194.     finally
  2195.       Stream.Free;
  2196.     end;
  2197.   except
  2198.     Result := False;
  2199.   end;
  2200. end;
  2201. {------------------------------------------------------------------------------}
  2202. function TCustomRVData.ShouldSaveTextToHTML(StyleNo: Integer): Boolean;
  2203. begin
  2204.   with GetRVStyle.TextStyles[StyleNo] do
  2205.     Result := (rvteoHTMLCode in Options) or not (rvteoRTFCode in Options)
  2206. end;
  2207. {------------------------------------------------------------------------------}
  2208. function TCustomRVData.GetHTMLATag(ItemNo: Integer; CSS: String;
  2209.   UTF8: Boolean): String;
  2210. var Target, Extras: String;
  2211. begin
  2212.   WriteHyperlink(GetItem(ItemNo).JumpID+FirstJumpNo, Self, ItemNo, rvsfHTML,
  2213.     Target, Extras);
  2214.   if (Target<>'') or (Extras<>'') then begin
  2215.     if Extras<>'' then
  2216.       Extras := ' '+Extras;
  2217.     if CSS<>'' then
  2218.       CSS := ' '+CSS;
  2219.     Result := Format('<a%s href="%s"%s>',[CSS, Target, Extras]);
  2220.     if UTF8 then
  2221.       Result := RVU_AnsiToUTF8(GetRVStyle.DefCodePage, Result);
  2222.     end
  2223.   else
  2224.     Result := '';
  2225. end;
  2226. {------------------------------------------------------------------------------}
  2227. procedure TCustomRVData.SaveHTMLCheckpoint(Stream: TStream;
  2228.   Checkpoint: TRVCPInfo; var cpno: Integer; const Prefix: String;
  2229.   FromNewLine: Boolean; Options: TRVSaveOptions);
  2230. begin
  2231.   if Checkpoint<>nil then begin
  2232.     if FromNewLine then
  2233.       RVWriteLn(Stream,'');
  2234.     if (rvsoUseCheckpointsNames in Options) and (Checkpoint.Name<>'') then
  2235.       RVWriteLn(Stream,'<a name="'+Checkpoint.Name+'"></a>')
  2236.     else
  2237.       RVWriteLn(Stream,'<a name='+Prefix+IntToStr(cpno)+'></a>');
  2238.     inc(cpno);
  2239.   end;
  2240. end;
  2241. {------------------------------------------------------------------------------}
  2242. { Returns text string for saving to HTML. Path - path for saving HTML (pictures).
  2243.   ItemNo - index of text item to save.
  2244.   CSSVersion is True is called from SaveHTMLEx.
  2245.   Calls OnSaveItemToHTML, if assigned.
  2246.   If CSSVersion, special processing for "Symbol" font                          }
  2247. function TCustomRVData.GetTextForHTML(const Path: String; ItemNo: Integer;
  2248.   CSSVersion: Boolean; SaveOptions: TRVSaveOptions): String;
  2249. var Item: TCustomRVItemInfo;
  2250.     FontInfo: TFontInfo;
  2251.     StyleNo: Integer;
  2252. begin
  2253.   Result := Items[ItemNo];
  2254.   if not SaveItemToFile(Path, Self, ItemNo, rvsfHTML, False, Result) then begin
  2255.     if (Result='') and IsFromNewLine(ItemNo) and
  2256.       ((ItemNo+1=ItemCount) or IsFromNewLine(ItemNo+1)) then begin
  2257.       Result := Format('<br%s>', [RV_HTMLGetEndingSlash(SaveOptions)]);
  2258.       exit;
  2259.     end;
  2260.     Item := GetItem(ItemNo);
  2261.     StyleNo := GetActualStyle(Item);
  2262.     FontInfo := GetRVStyle.TextStyles[StyleNo];
  2263.     {$IFNDEF RVDONOTUSEUNICODE}
  2264.     if rvioUnicode in Item.ItemOptions then
  2265.       if CSSVersion and (AnsiCompareText(FontInfo.FontName, RVFONT_SYMBOL)=0) then
  2266.         Result := RV_MakeHTMLSymbolStrRaw(Result)
  2267.       else if rvsoUTF8 in SaveOptions then
  2268.         Result := RVU_UnicodeToUTF8(Result, rvteoHTMLCode in FontInfo.Options)
  2269.       else
  2270.         Result := RVU_GetHTMLEncodedUnicode(Result, rvteoHTMLCode in FontInfo.Options)
  2271.     else
  2272.     {$ENDIF}
  2273.       if CSSVersion and (AnsiCompareText(FontInfo.FontName, RVFONT_SYMBOL)=0) then
  2274.         Result := RV_MakeHTMLSymbolStr(Result)
  2275.       else begin
  2276.         Result := RV_MakeHTMLStr(Result, rvteoHTMLCode in FontInfo.Options);
  2277.         if rvsoUTF8 in SaveOptions then
  2278.           Result := RVU_AnsiToUTF8(GetStyleCodePage(StyleNo), Result);
  2279.       end;
  2280.   end;
  2281. end;
  2282. {------------------------------------------------------------------------------}
  2283. function TCustomRVData.SaveHTMLToStream(Stream: TStream; const Path, Title,
  2284.   ImagesPrefix: String; Options: TRVSaveOptions; Color: TColor;
  2285.   var imgSaveNo: Integer; LeftMargin, TopMargin, RightMargin, BottomMargin: Integer;
  2286.   Background: TRVBackground; Bullets: TRVList): Boolean;
  2287.     {......................................................}
  2288.     procedure WriteExtraHTMLCode(Area: TRVHTMLSaveArea; AddSpace: Boolean);
  2289.     var s: String;
  2290.     begin
  2291.       s := GetExtraHTMLCode(Area, False);
  2292.       if s<>'' then
  2293.         if AddSpace then
  2294.           RVWrite(Stream,' '+s)
  2295.         else
  2296.           RVWrite(Stream, s);
  2297.     end;
  2298.     {...........................................................}
  2299.     procedure SaveFirst(Stream: TStream; const Path, Title: String);
  2300.     var s: String;
  2301.     begin
  2302.       if rvsoXHTML in Options then begin
  2303.         RVWrite(Stream, '<?xml version="1.0"');
  2304.         {$IFDEF RICHVIEWCBDEF3}
  2305.         if rvsoUTF8 in Options then
  2306.           s := 'UTF-8'
  2307.         else
  2308.           s := RV_CharSet2HTMLLang(GetRVStyle.TextStyles[0].CharSet);
  2309.         if s<>'' then
  2310.           RVWrite(Stream,SysUtils.Format(' encoding="%s"',[s]));
  2311.         {$ENDIF}
  2312.         RVWriteLn(Stream, '?>');
  2313.       end;
  2314.       s := Title;
  2315.       if rvsoUTF8 in Options then
  2316.         s := RVU_AnsiToUTF8(GetRVStyle.DefCodePage, Title);
  2317.       RVWriteLn(Stream,'<html><head><title>'+s+'</title>');
  2318.       {$IFDEF RICHVIEWCBDEF3}
  2319.       if rvsoUTF8 in Options then
  2320.         s := 'UTF-8'
  2321.       else
  2322.         s := RV_CharSet2HTMLLang(GetRVStyle.TextStyles[0].CharSet);
  2323.       if s<>'' then
  2324.         RVWriteLn(Stream,SysUtils.Format('<meta http-equiv="Content-Type" content="text/html; charset=%s"%s>',
  2325.           [s, RV_HTMLGetEndingSlash(Options)]));
  2326.       {$ENDIF}
  2327.       WriteExtraHTMLCode(rv_thms_Head, False);
  2328.       RVWriteLn(Stream,'</head>');
  2329.       RVWrite(Stream,'<body');
  2330.       if Color<>clNone then
  2331.          RVWrite(Stream,' bgcolor='+RV_GetHTMLRGBStr(Color, True));
  2332.       if (Background.Style<>bsNoBitmap) and
  2333.          (not Background.Bitmap.Empty) then begin
  2334.          s := SaveBackgroundToHTML(Background.Bitmap, Color, Path, ImagesPrefix,
  2335.            imgSaveNo, Options);
  2336.          if s<>'' then begin
  2337.            RVWrite(Stream, Format(' background="%s"', [s]));
  2338.            if (Background.Style<>bsTiledAndScrolled) then
  2339.              RVWrite(Stream,Format(' bgproperties=%s', [RV_HTMLGetStrAttrVal('fixed', Options)]));
  2340.          end;
  2341.       end;
  2342.       WriteExtraHTMLCode(rv_thms_BodyAttribute, True);
  2343.       RVWriteLn(Stream, Format(' leftmargin=%s topmargin=%s rightmargin=%s bottommargin=%s>',
  2344.         [RV_HTMLGetIntAttrVal(LeftMargin,   Options),
  2345.          RV_HTMLGetIntAttrVal(TopMargin,    Options),
  2346.          RV_HTMLGetIntAttrVal(RightMargin,  Options),
  2347.          RV_HTMLGetIntAttrVal(BottomMargin, Options)]));
  2348.       WriteExtraHTMLCode(rv_thms_Body, False);
  2349.     end;
  2350.     {...........................................................}
  2351.     procedure SaveLast(Stream: TStream);
  2352.     begin
  2353.       WriteExtraHTMLCode(rv_thms_End, False);
  2354.       RVWriteLn(Stream,'</body></html>');
  2355.     end;
  2356.     {......................................................}
  2357.     function GetPageBreakCSS(item: TCustomRVItemInfo): String;
  2358.     begin
  2359.       if (rvsoForceNonTextCSS in Options) and item.PageBreakBefore then 
  2360.         Result := ' style="page-break-before: always;"'
  2361.       else
  2362.         Result := '';
  2363.     end;
  2364.     {...........................................................}
  2365.     function GetOpenDIVTag(Align: TRVAlignment; item: TCustomRVItemInfo): String;
  2366.     var s: String;
  2367.     begin
  2368.       s := '<%%s align=%s%%s>';
  2369.       case Align of
  2370.         rvaCenter:
  2371.           Result := Format(s, [RV_HTMLGetStrAttrVal('center',  Options)]);
  2372.         rvaRight:
  2373.           Result := Format(s, [RV_HTMLGetStrAttrVal('right',   Options)]);
  2374.         rvaJustify:
  2375.           Result := Format(s, [RV_HTMLGetStrAttrVal('justify', Options)]);
  2376.         else
  2377.           Result := '<%s%s>';
  2378.       end;
  2379.       if RichViewSavePInHTML then
  2380.         s := 'p'
  2381.       else
  2382.         s := 'div';
  2383.       Result := SysUtils.Format(Result, [s, GetPageBreakCSS(item)]);
  2384.     end;
  2385.     {...........................................................}
  2386.     function GetCloseDIVTag: String;
  2387.     begin
  2388.       if RichViewSavePInHTML then
  2389.         Result := '</p>'
  2390.       else