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

RichEdit

开发平台:

Delphi

  1. {*******************************************************}
  2. {                                                       }
  3. {       RichView                                        }
  4. {       TRVDrawLineInfo: stores formatting for          }
  5. {       one item in RichView document.                  }
  6. {       TRVDrawLines: a list of TRVDrawLineInfo.        }
  7. {                                                       }
  8. {       Copyright (c) Sergey Tkachenko                  }
  9. {       svt@trichview.com                               }
  10. {       http://www.trichview.com                        }
  11. {                                                       }
  12. {*******************************************************}
  13. unit DLines;
  14. interface
  15. {$I RV_Defs.inc}
  16. uses Classes;
  17. type
  18. {-----------------------------------------------------------------------}
  19. {
  20.   TRVDrawLineInfo stores formatting for one item in RichView document.
  21.   These classes are often referred in other places as "draw items".
  22.   One item can corresponds to several draw items:
  23.   - each line of wrapped text item corresponds to one draw item.
  24.   This class is actually used for the most of items. But in some cases
  25.   (printing item on several pages) inherited classes are used instead.
  26. }
  27.   TRVDrawLineInfo = class
  28.     public
  29.      // space before the item, pixels (used for justified text and paragraph lists)
  30.      {$IFNDEF RVDONOTUSEJUSTIFY}
  31.      SpaceBefore: Integer;
  32.      {$ELSE}
  33.      {$IFNDEF RVDONOTUSELISTS}
  34.      SpaceBefore: Integer;
  35.      {$ENDIF}
  36.      {$ENDIF}
  37.      Left, Top, Width, Height: Integer; // coordinates, relative to the top left of document
  38.      ItemNo, Offs, Length: Integer; // links to items; length is used for text drawitems
  39.      ExtraSpaceBelow: Integer;      // used for line spacing
  40.      FromNewLine: ByteBool;         // true, if draw item starts a screen line
  41.      constructor CreateEx(ALeft, ATop, AWidth, AHeight, AItemNo: Integer;
  42.        AFromNewLine: ByteBool);
  43.      procedure SetData(ALeft, ATop, AItemNo: Integer;
  44.                        AFromNewLine: ByteBool); virtual;
  45.      procedure SetSize(AWidth, AHeight: Integer);virtual;
  46.      function InitSplit: Boolean; dynamic;
  47.      function CanSplitFirst(Y: Integer): Boolean; dynamic;
  48.      function SplitAt(Y: Integer): Boolean; dynamic;
  49.   end;
  50.   TRVDrawLineInfoClass = class of TRVDrawLineInfo;
  51. {-----------------------------------------------------------------------}
  52. {
  53.   TRVDrawLines - a list of TRVDrawLineInfo
  54. }
  55.   TRVDrawLines = class (TList)
  56.     private
  57.       FStartDeletedIndex, FDeletedCount: Integer;
  58.       function Get(Index: Integer): TRVDrawLineInfo;
  59.       procedure Put(Index: Integer; const Value: TRVDrawLineInfo);
  60.       procedure DeleteRange(Index1, Index2: Integer);      
  61.     public
  62.       constructor Create;
  63.       procedure MarkForDelete(Index1, Index2: Integer);
  64.       procedure DeleteMarked;
  65.       procedure Insert(Index: Integer; Item: Pointer);
  66.       procedure Delete(Index: Integer);
  67.       function GetString(Index: Integer; AItems: TStringList): String;
  68.       function GetSubString(Index: Integer; AItems: TStringList;
  69.         AStartIndex, ALength: Integer): String;
  70.       function GetRightString(Index: Integer; AItems: TStringList;
  71.         AStartIndex: Integer): String;
  72.       property Items[Index: Integer]: TRVDrawLineInfo read Get write Put; default;
  73.   end;
  74. implementation
  75. uses RVUni, RVItem;
  76. {=============================== TRVDrawLineInfo ==============================}
  77. { Constructor. Assigns the main properties                                     }
  78. constructor TRVDrawLineInfo.CreateEx(ALeft, ATop, AWidth, AHeight,
  79.   AItemNo: Integer; AFromNewLine: ByteBool);
  80. begin
  81.   inherited Create;
  82.   SetData(ALeft, ATop, AItemNo, AFromNewLine);
  83.   SetSize(AWidth, AHeight);
  84. end;
  85. {------------------------------------------------------------------------------}
  86. { Assigning the main properties                                                }
  87. procedure TRVDrawLineInfo.SetData(ALeft, ATop, AItemNo: Integer; AFromNewLine: ByteBool);
  88. begin
  89.   Left   := ALeft;
  90.   Top    := ATop;
  91.   ItemNo := AItemNo;
  92.   FromNewLine := AFromNewLine;
  93. end;
  94. {------------------------------------------------------------------------------}
  95. { Assigning width and height                                                   }
  96. procedure TRVDrawLineInfo.SetSize(AWidth, AHeight: Integer);
  97. begin
  98.   Width  := AWidth;
  99.   Height := AHeight;
  100. end;
  101. {------------------------------------------------------------------------------}
  102. { CanSplitFirst, InitSplit, SplitAt are used for printing items across pages.
  103.   Actual implementations are in inherited classes.
  104.   CanSplitFirst: can item be split at position Y (relative to the top of item) }
  105. function TRVDrawLineInfo.CanSplitFirst(Y: Integer): Boolean;
  106. begin
  107.   Result := False;
  108. end;
  109. {------------------------------------------------------------------------------}
  110. { Initialize splitting. Return true if successful                              }
  111. function TRVDrawLineInfo.InitSplit: Boolean;
  112. begin
  113.   Result := False;
  114. end;
  115. {------------------------------------------------------------------------------}
  116. { Split at the specified position (Y is relative to the top of item)           }
  117. function TRVDrawLineInfo.SplitAt(Y: Integer): Boolean;
  118. begin
  119.   Result := False;
  120. end;
  121. {================================ TRVDrawLines ================================}
  122. { Constructor                                                                  }
  123. constructor TRVDrawLines.Create;
  124. begin
  125.   inherited Create;
  126.   FStartDeletedIndex := -1;
  127.   FDeletedCount      := 0;
  128. end;
  129. {------------------------------------------------------------------------------}
  130. { This method is used in editor for reformatting a part of document.
  131.   It's more efficient to mark a range of items for deletion (freeing the
  132.   corresponding objects) and reuse list items, than to perform actual deletion
  133.   with subsequent insertion }
  134. procedure TRVDrawLines.MarkForDelete(Index1, Index2: Integer);
  135. var i: Integer;
  136. begin
  137.   FStartDeletedIndex := Index1;
  138.   FDeletedCount      := Index2-Index1+1;
  139.   for i := Index1 to Index2 do
  140.     TObject(Items[i]).Free;
  141. end;
  142. {------------------------------------------------------------------------------}
  143. { Deletes items marked by MarkForDelete                                        }
  144. procedure TRVDrawLines.DeleteMarked;
  145. begin
  146.   if FDeletedCount<>0 then begin
  147.     DeleteRange(FStartDeletedIndex, FStartDeletedIndex+FDeletedCount-1);
  148.     FDeletedCount := 0;
  149.   end;
  150. end;
  151. {------------------------------------------------------------------------------}
  152. { Inserts a new item at the position Index. Tries to reuse items marked by
  153.   MarkForDelete                                                                }
  154. procedure TRVDrawLines.Insert(Index: Integer; Item: Pointer);
  155. begin
  156.   if FDeletedCount=0 then
  157.     inherited Insert(Index, Item)
  158.   else begin
  159.     //Assert(Index=FStartDeletedIndex);
  160.     inc(FStartDeletedIndex);
  161.     dec(FDeletedCount);
  162.     Items[Index] := Item;
  163.   end;
  164. end;
  165. {------------------------------------------------------------------------------}
  166. { Deletes the item at the position Index. Takes marking for deletion into
  167.   account                                                                      }
  168. procedure TRVDrawLines.Delete(Index: Integer);
  169. begin
  170.   Items[Index].Free;
  171.   if FDeletedCount=0 then
  172.     inherited Delete(Index)
  173.   else begin
  174.     //Assert(Index=FStartDeletedIndex);
  175.     dec(FStartDeletedIndex);
  176.     inc(FDeletedCount);
  177.   end;
  178. end;
  179. {------------------------------------------------------------------------------}
  180. { Internal method. Deletes a range of items from Index1 to Index2.
  181.   Assumes that corresponding objects are alredy freed                          }
  182. procedure TRVDrawLines.DeleteRange(Index1, Index2: Integer);
  183. begin
  184.   if Index2 < Count-1 then
  185.     System.Move(List^[Index2 + 1], List^[Index1],
  186.       (Count - Index2 -1) * SizeOf(Pointer));
  187.   Count := Count - (Index2-Index1+1);
  188. end;
  189. {------------------------------------------------------------------------------}
  190. { Method for accessing property Items[Index]                                   }
  191. function TRVDrawLines.Get(Index: Integer): TRVDrawLineInfo;
  192. begin
  193.   Result := TRVDrawLineInfo(inherited Get(Index));
  194. end;
  195. {------------------------------------------------------------------------------}
  196. { Method for assigning property Items[Index]                                   }
  197. procedure TRVDrawLines.Put(Index: Integer; const Value: TRVDrawLineInfo);
  198. begin
  199.   inherited Put(Index, Value);
  200. end;
  201. {------------------------------------------------------------------------------}
  202. { Returns a string corresponding to the Index-th draw item.
  203.   String is taken from the list of items (AItems).
  204.   If one item corresponds to one draw item, this is a AItems[drawitem.ItemNo].
  205.   If not (because of text wrapping), this is a substring of it (starting from
  206.   the drawitem.Offs, having length drawitem.Length
  207.   In case of Unicode, returns "raw unicode" string                             }
  208. function TRVDrawLines.GetString(Index: Integer; AItems: TStringList): String;
  209. begin
  210.  {$IFDEF RVDONOTUSEUNICODE}
  211.   with Items[Index] do
  212.     Result := Copy(AItems[ItemNo], Offs, Length);
  213.   {$ELSE}
  214.   with Items[Index] do
  215.     Result := RVU_Copy(AItems[ItemNo], Offs, Length,
  216.       TCustomRVItemInfo(AItems.Objects[ItemNo]).ItemOptions);
  217.   {$ENDIF}
  218. end;
  219. {------------------------------------------------------------------------------}
  220. { The same, but returns substring of drawitem's text, starting at AStartIndex
  221.   position (1-based).                                                          }
  222. function TRVDrawLines.GetRightString(Index: Integer; AItems: TStringList;
  223.   AStartIndex: Integer): String;
  224. begin
  225.   {$IFDEF RVDONOTUSEUNICODE}
  226.   with Items[Index] do
  227.     Result := Copy(AItems[ItemNo], Offs+AStartIndex-1, Length-AStartIndex+1);
  228.   {$ELSE}
  229.   with Items[Index] do
  230.     Result := RVU_Copy(AItems[ItemNo], Offs+AStartIndex-1, Length-AStartIndex+1,
  231.       TCustomRVItemInfo(AItems.Objects[ItemNo]).ItemOptions);
  232.   {$ENDIF}
  233. end;
  234. {------------------------------------------------------------------------------}
  235. { The same, but returns substring of drawitem's text, starting at AStartIndex
  236.   position (1-based) and having length ALength                                 }
  237. function TRVDrawLines.GetSubString(Index: Integer; AItems: TStringList;
  238.   AStartIndex, ALength: Integer): String;
  239. begin
  240.   with Items[Index] do begin
  241.     if AStartIndex+ALength>Length+1 then
  242.       ALength := Length-AStartIndex+1;
  243.     {$IFDEF RVDONOTUSEUNICODE}
  244.     Result := Copy(AItems[ItemNo], Offs+AStartIndex-1, ALength);
  245.     {$ELSE}
  246.     Result := RVU_Copy(AItems[ItemNo], Offs+AStartIndex-1, ALength,
  247.       TCustomRVItemInfo(AItems.Objects[ItemNo]).ItemOptions);
  248.     {$ENDIF}
  249.   end;
  250. end;
  251. end.