📄 crvfdata.pas
字号:
end;
{ First, find the length of the whole string }
GetTextExtentPoint32W(Canvas.Handle, Pointer(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;
GetTextExtentPoint32W(Canvas.handle,Pointer(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;
if RVNT then begin
Result := AdjustMaxFitR(maxlo);
if Result<>maxlo then
Result := AdjustMaxFitL(Result);
end
else
Result := maxlo;
end
end;
{$ENDIF}
{.......................................................}
procedure OnStartNewLine(li: TCustomRVItemInfo);
var LeftIndent, RightIndent: Integer;
begin
FinishScreenLine(sad, LineWidth+FirstIndent, LastDrawItem, IsParaStart, ExtraSpaceBelowLine, DontFSL);
pi := RVStyle.ParaStyles[TCustomRVItemInfo(Items.Objects[ItemNo]).ParaNo];
GetIndents(ItemNo,IsParaStart,FirstParaItemNo, LeftIndent,RightIndent);
if IsParaStart and not li.BR then begin
if ItemNo>0 then
inc(prevdesc,GetDevY(RVStyle.ParaStyles[GetItemPara(ItemNo-1)].SpaceAfter));
inc(prevdesc,GetDevY(pi.SpaceBefore));
end;
if rvpaoNoWrap in pi.Options then
LineWidth := DocumentWidth - GetDevX(LeftIndent+RightIndent)
else
LineWidth := TextWidth - GetDevX(LeftIndent+RightIndent);
FirstIndent := sad.LeftMargin+GetDevX(LeftIndent);
end;
{.......................................................}
procedure AdjustLineHeight(h: Integer);
begin
if prevabove < h then begin
j := LastDrawItem-1;
if j>=0 then
repeat
inc(DrawItems[j].Top,h-prevabove);
dec(j);
until DrawItems[j+1].FromNewLine;
inc(baseline,h-prevabove);
prevabove := h;
end;
end;
{.......................................................}
procedure OnNonText(li: TRVRectItemInfo; dli: TRVDrawLineInfo);
var above, VerticalOffs: Integer;
w,h,desc,hshift: Integer;
begin
li.OnDocWidthChange(TextWidth - GetDevX(pi.LeftIndent+pi.RightIndent+pi.FirstIndent),
dli, rvflPrinting in Flags, Canvas, Self, @sad, hshift, NoCaching);
if li.GetBoolValue(rvbpDrawingChangesFont) then
LastTextStyle := -1;
if li.GetBoolValueEx(rvbpActualPrintSize, RVStyle) then begin
w := dli.Width;
h := dli.Height;
end
else begin
w := GetDevX(li.Width);
h := GetDevY(li.Height);
end;
desc := GetDevY(li.Descent);
if li.VShiftAbs then
VerticalOffs := GetDevY(li.VShift)
else
VerticalOffs := MulDiv(h,li.VShift,100);
dli.SetSize(w, h);
if not li.SameAsPrev or
((dli is TRVMultiDrawItemInfo)
)
or
(
(x+w > LineWidth) and
not (rvpaoNoWrap in pi.Options)
{$IFNDEF RVDONOTUSELISTS}
and not ((ItemNo>0) and (GetItemStyle(ItemNo-1)=rvsListMarker))
{$ENDIF}
) then begin
if li.SameAsPrev then
IsParaStart := False;
OnStartNewLine(li);
dli.FromNewLine := True;
x :=0;
inc(baseline, ExtraSpaceBelowLine);
y := baseline + prevdesc;
case li.VAlign of
rvvaBaseline:
prevabove := h-desc;
else {rvvaMiddle:}
prevabove := h div 2;
end;
inc(prevabove, VerticalOffs);
inc (baseline,prevdesc+prevabove);
prevdesc :=h-prevabove;
end
else begin
pi := RVStyle.ParaStyles[li.ParaNo];
case li.VAlign of
rvvaBaseline:
above := h-desc;
else {rvvaMiddle:}
above := h div 2;
end;
AdjustLineHeight(above+VerticalOffs);
y := baseline - above-VerticalOffs;
if prevdesc < (h-above-VerticalOffs) then
prevdesc := (h-above-VerticalOffs);
dli.FromNewLine := False;
end;
dli.Left := x+FirstIndent+hshift;
inc(x, w+hshift);
dli.Top := y;
dli.ItemNo := ItemNo;
dli.SetSize(w, h);
dli.Offs := 0;
dli.Length := 0;
if not ShareItems then
li.DrawItemNo := LastDrawItem;
DrawItems.Insert(LastDrawItem, dli);
if rvflUseJumps in Flags then
li.BuildJumps(dli.Left, dli.Top, nJmps, jumps);
//AdjustCP(li);
inc(LastDrawItem);
end;
{.......................................................}
var HShift: Integer;
begin
RVStyle := GetRVStyle;
li := TCustomRVItemInfo(Items.Objects[ItemNo]);
pi := RVStyle.ParaStyles[li.ParaNo];
if (not li.SameAsPrev) and (StartOffs=0) then
IsParaStart := True;
{
if LineWidth<0 then
OnStartNewLine(not li.BR, li);
}
if li.StyleNo<0 then begin
if li is TRVRectItemInfo then begin
// rvsComponent, rvsHotspot, rvsBullet, rvsPicture:
if rvflAllowCustomDrawItems in Flags then
dli := li.CreatePrintingDrawItem(Self,sad)
else
dli := TRVDrawLineInfo.Create;
OnNonText(TRVRectItemInfo(li), dli);
if li.GetBoolValue(rvbpDrawingChangesFont) then
LastTextStyle := -1;
if li.GetBoolValueEx(rvbpJump, RVStyle) then begin
if rvflUseJumps in Flags then begin
jmpinfo := TRVJumpInfo.Create;
jmpinfo.w := dli.Width;
jmpinfo.h := dli.Height;
jmpinfo.id := nJmps;
jmpinfo.DrawItemNo := LastDrawItem-1;
jmpinfo.Cursor := li.GetHypertextCursor(RVStyle);
jmpinfo.RVData := Self;
jumps.Add(jmpinfo);
end;
TCustomRVItemInfo(Items.Objects[ItemNo]).JumpID := nJmps;
inc(nJmps);
end;
end
else begin
FinishScreenLine(sad, LineWidth+FirstIndent,LastDrawItem, True, ExtraSpaceBelowLine, DontFSL);
if ItemNo>0 then
inc(prevdesc,GetDevY(RVStyle.ParaStyles[TCustomRVItemInfo(Items.Objects[ItemNo-1]).ParaNo].SpaceAfter));
inc(prevdesc,GetDevY(RVStyle.ParaStyles[TCustomRVItemInfo(Items.Objects[ItemNo]).ParaNo].SpaceBefore));
if li.StyleNo=rvsBreak then begin
inc(prevdesc,GetDevY(RVStyle.ParaStyles[0].SpaceBefore));
y5 := MulDiv(5, sad.ppiyDevice, sad.ppiyScreen);
dli := TRVDrawLineInfo.CreateEx(sad.LeftMargin,baseline + prevdesc,
TextWidth,y5+y5+1,ItemNo,True);
end
else begin
LineWidth := TextWidth - GetDevX(pi.LeftIndent+pi.RightIndent);
y5 := sad.LeftMargin+GetDevX(pi.LeftIndent); // y5 <- left
if rvflAllowCustomDrawItems in Flags then
dli := li.CreatePrintingDrawItem(Self,sad)
else
dli := TRVDrawLineInfo.Create;
li.OnDocWidthChange(LineWidth, dli, rvflPrinting in Flags, Canvas, Self, @sad, HShift, NoCaching);
if li.GetBoolValue(rvbpDrawingChangesFont) then
LastTextStyle := -1;
dli.SetSize(GetDevX(TRVFullLineItemInfo(li).Width),
GetDevY(TRVFullLineItemInfo(li).Height));
case pi.Alignment of
rvaRight:
inc(y5, LineWidth-dli.Width);
rvaCenter:
begin
inc(y5, (LineWidth-dli.Width) div 2);
if y5<0 then y5 := 0;
end;
end;
dli.SetData(y5+HShift, baseline + prevdesc, ItemNo,True);
end;
if not ShareItems then
li.DrawItemNo := LastDrawItem;
DrawItems.Insert(LastDrawItem, dli);
if rvflUseJumps in Flags then
li.BuildJumps(dli.Left, dli.Top, nJmps, jumps);
//AdjustCP(li);
inc(LastDrawItem);
if li.StyleNo=rvsBreak then begin
inc (baseline,prevdesc+y5+1);
prevdesc := y5;
prevabove := y5;
end
else begin
inc (baseline,prevdesc+dli.Height);
prevabove := dli.Height;
prevdesc := 0;
end;
end
end
else begin // text
spaceEated := False;
{$IFNDEF RVDONOTUSEUNICODE}
if rvioUnicode in li.ItemOptions then
sourceStrPtr := PChar(Text)+StartOffs*2
else
{$ENDIF}
sourceStrPtr := PChar(Text)+StartOffs;
sourceStrPtrLen := Len;
if (li.StyleNo<>LastTextStyle) then begin
LastTextStyle := li.StyleNo;
RVStyle.ApplyStyle(Canvas, li.StyleNo, GetParaBiDiMode(TCustomRVItemInfo(Items.Objects[ItemNo]).ParaNo));
if (RVStyle.TextStyles[li.StyleNo].CharSpacing<>0) and (sad.ppixScreen<>sad.ppixDevice) then
SetTextCharacterExtra(Canvas.Handle, GetDevX(RVStyle.TextStyles[li.StyleNo].CharSpacing));
GetTextMetrics(Canvas.Handle, TextMetric);
VerticalOffs := MulDiv(TextMetric.tmHeight,
RVStyle.TextStyles[li.StyleNo].VShift,
100);
end;
if rvflUseExternalLeading in Flags then
ExternalLeading := TextMetric.tmExternalLeading
else
ExternalLeading := 0;
AtStart := (StartOffs=0);
if sourceStrPtrLen=0 then begin {empty string}
sz.cy := Canvas.TextHeight(' ');
sz.cx := 0;
if not li.SameAsPrev then begin
OnStartNewLine(li);
x :=0;
inc(baseline, ExtraSpaceBelowLine);
y := baseline+prevDesc;
prevabove := ExternalLeading+TextMetric.tmAscent+VerticalOffs;
inc(baseline, prevDesc+prevabove);
prevDesc := TextMetric.tmDescent-VerticalOffs;
end
else begin
AdjustLineHeight(ExternalLeading+TextMetric.tmAscent+VerticalOffs);
y := baseline - (ExternalLeading+TextMetric.tmAscent+VerticalOffs);
if prevDesc < TextMetric.tmDescent-VerticalOffs then
prevDesc := TextMetric.tmDescent-VerticalOffs;
end;
dli := TRVDrawLineInfo.CreateEx(x+FirstIndent,y, sz.cx, sz.cy, ItemNo, not li.SameAsPrev);
dli.Offs := 1+StartOffs;
inc(x, sz.cx);
if RVStyle.TextStyles[li.StyleNo].Jump then
TCustomRVItemInfo(Items.Objects[ItemNo]).JumpID := -3;
dli.Length := 0;
if AtStart and not ShareItems then
li.DrawItemNo := LastDrawItem;
DrawItems.Insert(LastDrawItem, dli);
//AdjustCP(li);
inc(LastDrawItem);
exit;
end;
newline := AtStart and not li.SameAsPrev;
while sourceStrPtrLen>0 do begin
if newline then begin
OnStartNewLine(li);
x:=0;
if (rvflTrim in Flags) and not SpaceEated and
not IsParaStart and (sourceStrPtrLen>1) then
{$IFNDEF RVDONOTUSEUNICODE}
if rvioUnicode in li.ItemOptions then begin
if PWord(sourceStrPtr)^=ord(' ') then begin
inc(sourceStrPtr,2);
dec(sourceStrPtrLen);
end;
end
else
{$ENDIF}
if sourceStrPtr^=' ' then begin
inc(sourceStrPtr);
dec(sourceStrPtrLen);
end;
SpaceEated := False;
end;
SpaceAfter := LineWidth-x;
if SpaceAfter<0 then SpaceAfter := 0;
{$IFNDEF RVDONOTUSEUNICODE}
if rvioUnicode in li.ItemOptions then
max := MaxFitW
else
{$ENDIF}
max := MaxFitA;
max2 := max;
sourceStrPtr2 := sourceStrPtr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -