📄 crvfdata.pas
字号:
const gdinLastCompleteVisible = 2;
const gdinLastVisible = 3;
const MAXLINELENGTH = 1000;
{------------------------------------------------------------------------------}
function MyStrRScanA(Str: PChar; Chr: Char; Length: Integer): PChar;
begin
Result := Str+Length-1;
while Result>=Str do begin
if Result^=Chr then
exit;
dec(Result);
end;
Result := nil;
end;
{------------------------------------------------------------------------------}
{$IFNDEF RVDONOTUSEUNICODE}
{
function MyStrRScanW(Str: PChar; Chr: Char; Length: Integer): PChar;
begin
Result := Str+(Length-1)*2;
while Result>=Str do begin
if (Result^=Chr) and ((Result+1)^=#0) then
exit;
dec(Result, 2);
end;
Result := nil;
end;
}
{$ENDIF}
{------------------------------------------------------------------------------}
function max(a,b: Integer): Integer;
begin
if a>b then
max := a
else
max := b;
end;
{=========================== TRVSoftPageBreakList =============================}
function TRVSoftPageBreakList.FindItem(ItemNo: Integer): Integer;
var a,b,no: Integer;
{....................................}
procedure AdjustResult(var R: Integer);
begin
while (R>0) and (TRVSoftPageBreakInfo(Items[R-1]).ItemNo=ItemNo) do
dec(R);
end;
{....................................}
begin
a := 0;
b := Count-1;
while b-a>1 do begin
Result := (a+b) div 2;
no := TRVSoftPageBreakInfo(Items[Result]).ItemNo;
if no=ItemNo then begin
AdjustResult(Result);
exit;
end;
if no<ItemNo then
a := Result
else
b := Result;
end;
if TRVSoftPageBreakInfo(Items[a]).ItemNo=ItemNo then
Result := a
else if TRVSoftPageBreakInfo(Items[b]).ItemNo=ItemNo then
Result := b
else
Result := -1;
AdjustResult(Result);
end;
{============================ TCustomRVFormattedData ==========================}
constructor TCustomRVFormattedData.Create;
begin
inherited Create;
DrawItems := TRVDrawLines.Create;
Jumps := TList.Create;
FSelStartNo := -1;
FSelEndNo := -1;
FSelStartOffs := 0;
FSelEndOffs := 0;
TextWidth := -1;
DocumentWidth := -1;
DocumentHeight := 0;//GetTopMargin;
LastItemFormatted := -1;
LastJumpMovedAbove := -1;
LastDIMovedAbove := -1;
LastJumpDowned := -1;
FocusedItemNo := -1;
FActiveItem := nil;
FPartialSelectedItem := nil;
FZoomPercent := 100;
end;
{------------------------------------------------------------------------------}
destructor TCustomRVFormattedData.Destroy;
begin
ClearTemporal;
DrawItems.Free;
DrawItems := nil;
Jumps.Free;
Jumps := nil;
inherited Destroy;
end;
{------------------------------------------------------------------------------}
procedure TCustomRVFormattedData.ClearLastJump;
begin
if LastRVDataMovedAbove<>nil then begin
LastRVDataMovedAbove.State := LastRVDataMovedAbove.State - [rvstDrawHover];
LastRVDataMovedAbove.LastJumpMovedAbove := -1;
LastRVDataMovedAbove.LastJumpDowned := -1;
DoRVMouseMove(-1);
end;
State := State - [rvstDrawHover];
LastJumpMovedAbove := -1;
LastJumpDowned := -1;
LastRVDataMovedAbove := nil;
end;
{------------------------------------------------------------------------------}
procedure TCustomRVFormattedData.ClearJumps;
var i: Integer;
begin
if Jumps<>nil then begin
for i:=0 to Jumps.Count-1 do
TObject(Jumps[i]).Free;
Jumps.Clear;
ClearLastJump;
end;
end;
{------------------------------------------------------------------------------}
procedure TCustomRVFormattedData.ClearTemporal;
var i: Integer;
begin
if DrawItems<>nil then begin
for i:=0 to DrawItems.Count-1 do
DrawItems[i].Free;
DrawItems.Clear;
ClearJumps;
nJmps := 0;
FActiveItem := nil;
//FPartialSelectedItem := nil;
FCaptureMouseItem := nil;
LastDIMovedAbove := -1;
LastRVDataMovedAbove := nil;
State := State - [ rvstMakingSelection, rvstDrawHover];
LastRaisedCP := nil;
end;
end;
{------------------------------------------------------------------------------}
procedure TCustomRVFormattedData.Clear;
var Clearing: Boolean;
begin
Clearing := rvstClearing in State;
Include(State, rvstClearing);
try
ClearSoftPageBreaks;
Deselect(nil, True);
ClearTemporal;
inherited Clear;
finally
if not Clearing then
Exclude(State, rvstClearing);
end;
end;
{------------------------------------------------------------------------------}
procedure TCustomRVFormattedData.Deselect(NewPartiallySelected: TCustomRVItemInfo;
MakeEvent: Boolean);
begin
if rvstDeselecting in State then
exit;
State := State + [rvstDeselecting];
try
State := State - [rvstMakingSelection];
FSelStartNo := -1;
FSelEndNo := -1;
FSelStartOffs := 0;
FSelEndOffs := 0;
FocusedItemNo := -1;
DeselectPartiallySelectedItem(NewPartiallySelected);
if MakeEvent then
DoSelect;
finally
State := State - [rvstDeselecting];
end;
end;
{------------------------------------------------------------------------------}
procedure TCustomRVFormattedData.SelectAll;
begin
if Items.Count=0 then
exit;
DestroyInplaceEditor;
DeselectPartiallySelectedItem(nil);
FSelStartNo := 0;
FSelEndNo := DrawItems.Count-1;
FSelStartOffs := GetOffsBeforeDrawItem(0);
FSelEndOffs := GetOffsAfterDrawItem(FSelEndNo);
DoOnSelection;
DoSelect;
end;
procedure TCustomRVFormattedData.ConcateItems(FirstItemNo: Integer);
var item1,item2: TCustomRVItemInfo;
begin
item1 := TCustomRVItemInfo(Items.Objects[FirstItemNo]);
item2 := TCustomRVItemInfo(Items.Objects[FirstItemNo+1]);
if ((rvioUnicode in item1.ItemOptions)<>
(rvioUnicode in item2.ItemOptions)) and
(Items[FirstItemNo+1]<>'') then begin
item2.SameAsPrev := item1.SameAsPrev;
item2.BR := item1.BR;
FreeItem(FirstItemNo, False);
Items.Delete(FirstItemNo);
end
else begin
Items[FirstItemNo] := Items[FirstItemNo]+Items[FirstItemNo+1];
FreeItem(FirstItemNo+1, False);
Items.Delete(FirstItemNo+1);
end;
end;
{------------------------------------------------------------------------------}
procedure TCustomRVFormattedData.Normalize;
var li, li2: TCustomRVItemInfo;
i: Integer;
begin
for i := Items.Count-1 downto 1 do begin
li := TCustomRVItemInfo(Items.Objects[i-1]);
li2 := TCustomRVItemInfo(Items.Objects[i]);
if RV_CanConcateItems(i-1, li,li2,False) then
ConcateItems(i-1);
end;
end;
{------------------------------------------------------------------------------}
function TCustomRVFormattedData.GetOffsBeforeDrawItem(DrawItemNo: Integer): Integer;
begin
if TCustomRVItemInfo(Items.Objects[DrawItems[DrawItemNo].ItemNo]).StyleNo<0 then
Result := 0
else
Result := 1;
end;
{------------------------------------------------------------------------------}
function TCustomRVFormattedData.GetOffsAfterDrawItem(DrawItemNo: Integer): Integer;
begin
if TCustomRVItemInfo(Items.Objects[DrawItems[DrawItemNo].ItemNo]).StyleNo<0 then
Result := 1
else
Result := DrawItems[DrawItemNo].Length+1;
end;
{------------------------------------------------------------------------------}
procedure TCustomRVFormattedData.FinishScreenLine(const sad: TRVScreenAndDevice;
LineWidth, LastDrawItem: Integer;
parafinished: Boolean;
var ExtraSpace: Integer;
var dontdoit: Boolean);
var pi: TParaInfo;
{.......................................................}
function GetDevY(ScreenY: Integer): Integer;
begin
Result := MulDiv(ScreenY, sad.ppiyDevice, sad.ppiyScreen);
end;
{.......................................................}
function GetDevX(ScreenX: Integer): Integer;
begin
Result := MulDiv(ScreenX, sad.ppixDevice, sad.ppixScreen);
end;
{.......................................................}
procedure RearrangeLine(LastDrawItem: Integer);
var FirstDrawItem, i: Integer;
extrax, curx: Integer;
begin
if GetParaBiDiMode(TCustomRVItemInfo(Items.Objects[DrawItems[LastDrawItem].ItemNo]).ParaNo)<>rvbdRightToLeft then
exit;
FirstDrawItem := LastDrawItem;
while (FirstDrawItem>0) and
not DrawItems[FirstDrawItem].FromNewLine do
dec(FirstDrawItem);
if not GetItem(DrawItems[FirstDrawItem].ItemNo).SameAsPrev and
(DrawItems[FirstDrawItem].Offs<=GetOffsBeforeItem(DrawItems[FirstDrawItem].ItemNo)) then begin
{$IFNDEF RVDONOTUSELISTS}
if (GetItemStyle(DrawItems[FirstDrawItem].ItemNo)=rvsListMarker) then begin
extrax := GetDevX(-TRVMarkerItemInfo(GetItem(DrawItems[FirstDrawItem].ItemNo)).GetLeftOverhang);
end
else
{$ENDIF}
begin
extrax := GetDevX(pi.FirstIndent);
end;
if extrax<>0 then
for i := FirstDrawItem to LastDrawItem do
dec(DrawItems[i].Left, extrax);
end;
if FirstDrawItem=LastDrawItem then
exit;
curx := DrawItems[FirstDrawItem].Left;
for i := LastDrawItem downto FirstDrawItem do begin
if i>FirstDrawItem then
extrax := DrawItems[i].Left-(DrawItems[i-1].Left+DrawItems[i-1].Width)
else
extrax := 0;
DrawItems[i].Left := curx;
inc(curx, DrawItems[i].Width+extrax);
end;
end;
{.......................................................}
var i, j, dx, min,max: Integer;
fl: Boolean;
{$IFNDEF DONOTUSEJUSTIFY}
SpaceCount, strt: Integer;
s: String;
{$ENDIF}
begin
ExtraSpace := 0;
if dontdoit then begin
dontdoit := False;
exit;
end;
i := LastDrawItem-1;
if i=-1 then exit;
with DrawItems[i] do begin
if GetItem(ItemNo).GetBoolValue(rvbpFullWidth) then exit;
pi := GetRVStyle.ParaStyles[TCustomRVItemInfo(Items.Objects[ItemNo]).ParaNo];
if (pi.Alignment = rvaLeft) or
((pi.Alignment = rvaJustify) and ParaFinished) then
dx := 0
else begin
dx := LineWidth - (Left+Width);
if pi.Alignment = rvaCenter then begin
dx := dx div 2;
if dx<0 then
dx := 0;
end;
end;
end;
case pi.LineSpacingType of
rvlsSpaceBetween:
if pi.LineSpacing>=0 then
ExtraSpace := GetDevY(pi.LineSpacing);
rvlsPercent:
begin
if pi.LineSpacing>100 then begin
j := i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -