📄 crvfdata.pas
字号:
min := 0;
max := 0;
fl := True;
repeat
if (TCustomRVItemInfo(Items.Objects[DrawItems[j].ItemNo]).StyleNo>=0) then begin
if fl or (DrawItems[j].Top<min) then
min := DrawItems[j].Top;
if fl or (DrawItems[j].Top+DrawItems[j].Height>max) then
max := DrawItems[j].Top+DrawItems[j].Height;
fl := False;
end;
dec(j);
until (j<0) or DrawItems[j+1].FromNewLine;
if not fl then
ExtraSpace := (max-min)*(pi.LineSpacing-100) div 100;
end;
end;
end;
if ExtraSpace<>0 then begin
j := i;
repeat
DrawItems[j].ExtraSpaceBelow := ExtraSpace;
dec(j);
until (j<0) or DrawItems[j+1].FromNewLine;
end;
{$IFNDEF DONOTUSEJUSTIFY}
if (pi.Alignment = rvaJustify) and not ParaFinished then begin
with DrawItems[i] do begin
{
if not (rvflShareContents in Flags) and
(TCustomRVItemInfo(Items.Objects[ItemNo]).StyleNo<0) then
TRVNonTextItemInfo(Items.Objects[ItemNo]).AdjustInserted
(Left-GetHOffs, Top-GetVOffs, False);
}
if FromNewLine then exit;
end;
SpaceCount := 0;
while (i>=0) and not DrawItems[i].FromNewLine do
with DrawItems[i] do begin
if (TCustomRVItemInfo(Items.Objects[ItemNo]).StyleNo>=0) then begin
s := DrawItems.GetString(i,Items);
if (System.Length(s)>0) and RVU_IsSpace(s, 1, GetItemOptions(ItemNo)) then
inc(SpaceCount)
end;
dec(i);
end;
strt := i+1;
for i := strt to LastDrawItem-1 do
with DrawItems[i] do begin
if (TCustomRVItemInfo(Items.Objects[ItemNo]).StyleNo>=0) then begin
s := DrawItems.GetString(i,Items);
if (System.Length(s)>0) and RVU_IsSpace(s, 1, GetItemOptions(ItemNo)) then begin
SpaceBefore := dx div SpaceCount;
inc(Width,SpaceBefore);
dec(dx,SpaceBefore);
dec(SpaceCount);
end;
end;
if not FromNewLine then
Left := DrawItems[i-1].Left+DrawItems[i-1].Width;
{
if not (rvflShareContents in Flags) and
(TCustomRVItemInfo(Items.Objects[ItemNo]).StyleNo<0) then
TRVNonTextItemInfo(Items.Objects[ItemNo]).AdjustInserted
(Left-GetHOffs, Top-GetVOffs, False);
}
end;
RearrangeLine(LastDrawItem-1);
exit;
end;
{$ENDIF}
while (i>=0) do begin
with DrawItems[i] do begin
inc(Left,dx);
{
if not (rvflShareContents in Flags) and
(TCustomRVItemInfo(Items.Objects[ItemNo]).StyleNo<0) then
TRVNonTextItemInfo(Items.Objects[ItemNo]).AdjustInserted
(Left-GetHOffs, Top-GetVOffs, False);
}
if FromNewLine then begin
RearrangeLine(LastDrawItem-1);
exit;
end;
end;
dec(i);
end;
end;
{------------------------------------------------------------------------------}
procedure TCustomRVFormattedData.GetIndents(ItemNo: Integer; IsParaStart: Boolean;
var FirstParaItemNo: Integer; var LeftIndent, RightIndent: Integer);
var RVStyle: TRVStyle;
item : TCustomRVItemInfo;
{$IFNDEF RVDONOTUSELISTS}
item2 : TCustomRVItemInfo;
bidimode: TRVBiDiMode;
{$ENDIF}
pi : TParaInfo;
begin
RVStyle := GetRVStyle;
item := GetItem(ItemNo);
{$IFNDEF RVDONOTUSELISTS}
bidimode := GetParaBiDiMode(item.ParaNo);
{$ENDIF}
pi := RVStyle.ParaStyles[item.ParaNo];
if IsParaStart then begin
{$IFNDEF RVDONOTUSELISTS}
if (item.StyleNo=rvsListMarker) and (TRVMarkerItemInfo(item).GetLevelInfo(RVStyle)<>nil) then
if bidimode=rvbdRightToLeft then begin
RightIndent := TRVMarkerItemInfo(item).GetLevelInfo(RVStyle).MarkerIndent;
LeftIndent := pi.LeftIndent;
end
else begin
LeftIndent := TRVMarkerItemInfo(item).GetLevelInfo(RVStyle).MarkerIndent;
RightIndent := pi.RightIndent;
end
else begin
if FirstParaItemNo<0 then
FirstParaItemNo := GetFirstParaItem(ItemNo);
item2 := GetItem(FirstParaItemNo);
if (item2.StyleNo=rvsListMarker) and (TRVMarkerItemInfo(item2).GetLevelInfo(RVStyle)<>nil) then
if bidimode=rvbdRightToLeft then begin
RightIndent := TRVMarkerItemInfo(item2).GetLevelInfo(RVStyle).LeftIndent;
LeftIndent := pi.LeftIndent;
end
else begin
LeftIndent := TRVMarkerItemInfo(item2).GetLevelInfo(RVStyle).LeftIndent;
RightIndent := pi.RightIndent;
end
else
{$ENDIF}
begin
LeftIndent := pi.LeftIndent;
if not item.BR and not item.GetBoolValue(rvbpFullWidth) then
inc(LeftIndent, pi.FirstIndent);
RightIndent := pi.RightIndent;
end;
{$IFNDEF RVDONOTUSELISTS}
end;
{$ENDIF}
end
else begin
{$IFNDEF RVDONOTUSELISTS}
if FirstParaItemNo<0 then
FirstParaItemNo := GetFirstParaItem(ItemNo);
item2 := GetItem(FirstParaItemNo);
if (item2.StyleNo=rvsListMarker) and (TRVMarkerItemInfo(item2).GetLevelInfo(RVStyle)<>nil) then begin
if bidimode=rvbdRightToLeft then begin
RightIndent := TRVMarkerItemInfo(item2).GetLevelInfo(RVStyle).LeftIndent;
LeftIndent := pi.LeftIndent;
end
else begin
LeftIndent := TRVMarkerItemInfo(item2).GetLevelInfo(RVStyle).LeftIndent;
RightIndent := pi.RightIndent;
end
end
else
{$ENDIF}
begin
LeftIndent := pi.LeftIndent;
RightIndent := pi.RightIndent;
end;
end;
end;
{------------------------------------------------------------------------------}
function TCustomRVFormattedData.GetMaxIndent(ItemNo: Integer; var FirstParaItemNo: Integer): Integer;
var RVStyle: TRVStyle;
item: TCustomRVItemInfo;
pi : TParaInfo;
{$IFNDEF RVDONOTUSELISTS}
levelinfo: TRVListLevel;
item2 : TCustomRVItemInfo;
bidimode: TRVBiDiMode;
{$ENDIF}
begin
RVStyle := GetRVStyle;
item := GetItem(ItemNo);
{$IFNDEF RVDONOTUSELISTS}
bidimode := GetParaBiDiMode(item.ParaNo);
{$ENDIF}
pi := RVStyle.ParaStyles[item.ParaNo];
{$IFNDEF RVDONOTUSELISTS}
if FirstParaItemNo<0 then
FirstParaItemNo := GetFirstParaItem(ItemNo);
item2 := GetItem(FirstParaItemNo);
if (item2.StyleNo=rvsListMarker) and (TRVMarkerItemInfo(item2).GetLevelInfo(RVStyle)<>nil) then begin
levelinfo := TRVMarkerItemInfo(item2).GetLevelInfo(RVStyle);
Result := levelinfo.LeftIndent;
if levelinfo.FirstIndent>0 then
inc(Result,levelinfo.FirstIndent);
if bidimode=rvbdRightToLeft then
inc(Result, pi.LeftIndent)
else
inc(Result, pi.RightIndent);
end
else
{$ENDIF}
begin
Result := pi.LeftIndent+pi.RightIndent;
if (pi.FirstIndent>0) and not item.GetBoolValue(rvbpFullWidth) then
inc(Result,pi.FirstIndent);
end;
end;
{------------------------------------------------------------------------------}
procedure TCustomRVFormattedData.FormatLine(
const Text: String;
StartOffs, Len, ItemNo: Integer;
var x, baseline, prevdesc, prevabove: Integer;
Canvas: TCanvas;
var sad: TRVScreenAndDevice;
var IsParaStart: Boolean;
var LineWidth, FirstIndent, LastDrawItem, VerticalOffs: Integer;
var DontFSL: Boolean; var LastTextStyle: Integer;
var TextMetric: TTextMetric;
var FirstParaItemNo: Integer;
NoCaching: Boolean);
var sourceStrPtr,sourceStrPtr2, strForAdd, strSpacePos: PChar;
sourceStrPtrLen: Integer;
sz: TSIZE;
max,max2,j, y: Integer;
dli: TRVDrawLineInfo;
newline, spaceEated, AtStart:Boolean;
jmpinfo: TRVJumpInfo;
y5, Offs : Integer;
pi: TParaInfo;
SpaceAfter, ExternalLeading, ExtraSpaceBelowLine: Integer;
li: TCustomRVItemInfo;
RVStyle: TRVStyle;
{.......................................................}
function GetDevX(ScreenX: Integer): Integer;
begin
Result := MulDiv(ScreenX, sad.ppixDevice, sad.ppixScreen);
end;
{.......................................................}
function GetDevY(ScreenY: Integer): Integer;
begin
Result := MulDiv(ScreenY, sad.ppiyDevice, sad.ppiyScreen);
end;
{.......................................................}
{$IFNDEF RVDONOTUSEUNICODE}
function AdjustMaxFitR(value: Integer): Integer;
var PStart, PCur, PCur2: PChar;
begin
Result := value;
PStart := sourceStrPtr;
// we cannot use CharNextW() because string does not have WideChar(0) at the end
while True do begin
if (Result=0) or (Result=sourceStrPtrLen) then
exit;
PCur := PStart + (Result+1)*2;
PCur2 := PChar(CharPrevW(Pointer(PStart), Pointer(PCur)));
if PCur2=PStart+(Result)*2 then
exit;
inc(Result);
end;
end;
{.......................................................}
function AdjustMaxFitL(value: Integer): Integer;
var PStart, PCur, PCur2: PChar;
begin
Result := value;
GetTextExtentPoint32W(Canvas.handle,Pointer(sourceStrPtr),Result,sz);
if sz.cx<=SpaceAfter then
exit;
PStart := sourceStrPtr;
PCur := PStart + (Result-1)*2;
PCur2 := PChar(CharPrevW(Pointer(PStart), Pointer(PCur)));
Result := (PCur2-PStart) div 2;
end;
{$ENDIF}
function MaxFitSafe: Integer; // out: sz
{$IFNDEF RVDONOTUSEUNICODE}
var r: Integer;
{$ENDIF}
begin
if (rvpaoNoWrap in pi.Options) then
Result := sourceStrPtrLen
else begin
RVU_GetTextExtentExPointPC(Canvas, sourceStrPtr, sourceStrPtrLen, SpaceAfter, Result, nil, li.ItemOptions, sz);
{$IFNDEF RVDONOTUSEUNICODE}
if (rvioUnicode in li.ItemOptions) and RVNT then begin
r := Result;
Result := AdjustMaxFitR(r);
end;
{$ENDIF}
end;
end;
{.......................................................}
function MaxFitA: Integer; // out: sz
var maxlo, maxhi, cxlo, cxhi : Integer;
begin
if RichViewSafeFormatting or (not RVNT and (rvflPrinting in Flags)) then begin
Result := MaxFitSafe;
exit;
end;
{ First, find the length of the whole string }
GetTextExtentPoint32(Canvas.Handle, sourceStrPtr, sourceStrPtrLen, sz);
if (rvpaoNoWrap in pi.Options) or ((sz.cx <= SpaceAfter) and (sz.cx>0)) then
{ it will fit on the line }
Result := sourceStrPtrLen
else begin
maxlo := 0;
maxhi := sourceStrPtrLen;
cxlo := 0;
cxhi := sz.cx;
while maxhi > (maxlo + 1) do begin
{ make the best estimate of where max should be }
if cxhi=cxlo then
inc(cxhi);
Result := maxlo + (maxhi - maxlo) * (SpaceAfter - cxlo) div (cxhi - cxlo);
if Result <= maxlo then
Result := maxlo + 1;
if Result >= maxhi then
Result := maxhi - 1;
GetTextExtentPoint32(Canvas.handle,sourceStrPtr,Result,sz);
{ if sz.cx = SpaceAfter then max is correct }
if sz.cx = SpaceAfter then begin
maxlo := Result;
maxhi := Result;
end
else if (sz.cx < SpaceAfter) and (sz.cx>0) then begin
maxlo := Result;
cxlo := sz.cx;
end
else { sz.cx > SpaceAfter } begin
maxhi := Result;
cxhi := sz.cx;
end;
end;
Result := maxlo;
end
end;
{.......................................................}
{$IFNDEF RVDONOTUSEUNICODE}
function MaxFitW: Integer; // out: sz
var maxlo, maxhi, cxlo, cxhi : Integer;
begin
if RichViewSafeFormatting or (not RVNT and (rvflPrinting in Flags)) then begin
Result := MaxFitSafe;
exit;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -