mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-25 14:39:11 +02:00
SynEdit: WrappedView, caret calculations for RTL/LTR text
This commit is contained in:
parent
6f2525c144
commit
5b080436ce
components/synedit
@ -234,13 +234,18 @@ public
|
||||
function GetSublineCount (ALine: String; AMaxWidth: Integer; const APhysCharWidths: TPhysicalCharWidths): Integer; inline;
|
||||
procedure GetSublineBounds(ALine: String; AMaxWidth, AWrapIndent: Integer;
|
||||
const APhysCharWidths: TPhysicalCharWidths; ASubLine: Integer; out ALogStartX,
|
||||
ANextLogStartX, APhysStart: IntIdx; out APhysWidth: integer);
|
||||
ANextLogStartX, APhysStart: IntIdx; out APhysWidth: integer); // APhysStart is based on LTR only
|
||||
procedure GetSublineBounds(ALine: String; AMaxWidth, AWrapIndent: Integer; const APhysCharWidths: TPhysicalCharWidths;
|
||||
ASubLine: Integer;
|
||||
out ALogStartX, ANextLogStartX, APhysStart: IntIdx; out APhysWidth: integer;
|
||||
var AViewedX: integer;
|
||||
out APhysX: integer);
|
||||
function GetSubLineFromX (ALine: String; AMaxWidth, AWrapIndent: Integer; const APhysCharWidths: TPhysicalCharWidths; var APhysToViewedXPos: Integer): integer;
|
||||
|
||||
procedure GetWrapInfoForViewedXY(var AViewedXY: TViewedPoint; AFlags: TViewedXYInfoFlags; out AFirstViewedX: IntPos; ALogPhysConvertor: TSynLogicalPhysicalConvertor);
|
||||
|
||||
function TextXYToLineXY(ATextXY: TPhysPoint): TViewedSubPoint_0;
|
||||
function LineXYToTextX(ARealLine: IntPos; ALineXY: TViewedSubPoint_0): Integer;
|
||||
function ViewedSubLineXYToTextX(ARealLine: IntPos; ALineXY: TViewedSubPoint_0): Integer;
|
||||
function CalculateWrapForLine(ALineIdx: IntIdx; AMaxWidth: integer): Integer; inline;
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
@ -1296,7 +1301,7 @@ begin
|
||||
Result := inherited ViewXYIdxToTextXYIdx(AViewXYIdx, ANodeStartLine);
|
||||
Result.y := ANodeStartLine + GetOffsetForWrap(Result.y - ANodeStartLine, SubOffset);
|
||||
|
||||
Result.x := FSynEditWrappedPlugin.LineXYToTextX(Result.y, Point(Result.x, SubOffset) );
|
||||
Result.x := FSynEditWrappedPlugin.ViewedSubLineXYToTextX(Result.y, Point(Result.x, SubOffset) );
|
||||
end;
|
||||
|
||||
procedure TSynWordWrapIndexPage.InvalidateLines(AFromOffset, AToOffset: Integer);
|
||||
@ -1866,6 +1871,35 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function FindPreviousCharStart(const APhysCharWidths: TPhysicalCharWidths; AnX: integer): Integer; inline;
|
||||
begin
|
||||
assert(AnX > 0, 'FindPreviousCharStart: AnX > 0');
|
||||
Result := AnX - 1;
|
||||
while (Result >= 0) and (APhysCharWidths[Result] = 0) do
|
||||
dec(Result);
|
||||
end;
|
||||
function CalculateRtlLead(const APhysCharWidths: TPhysicalCharWidths; AnX: integer): Integer; //inline;
|
||||
begin
|
||||
Result := 0;
|
||||
while (AnX >= 0) and
|
||||
( (APhysCharWidths[AnX] = 0) or ((APhysCharWidths[AnX] and PCWFlagRTL) <> 0) )
|
||||
do begin
|
||||
Result := Result + (APhysCharWidths[AnX] and PCWMask);
|
||||
dec(AnX);
|
||||
end;
|
||||
end;
|
||||
function CalculateRtlRemainder(const APhysCharWidths: TPhysicalCharWidths; ALineLen, AnX: integer): Integer; //inline;
|
||||
begin
|
||||
Result := 0;
|
||||
while (AnX < ALineLen) and
|
||||
( (APhysCharWidths[AnX] = 0) or ((APhysCharWidths[AnX] and PCWFlagRTL) <> 0) )
|
||||
do begin
|
||||
Result := Result + (APhysCharWidths[AnX] and PCWMask);
|
||||
inc(AnX);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure TLazSynEditLineWrapPlugin.GetSublineBounds(ALine: String; AMaxWidth,
|
||||
AWrapIndent: Integer; const APhysCharWidths: TPhysicalCharWidths; ASubLine: Integer; out
|
||||
ALogStartX, ANextLogStartX, APhysStart: IntIdx; out APhysWidth: integer);
|
||||
@ -1887,16 +1921,71 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TLazSynEditLineWrapPlugin.GetSublineBounds(ALine: String; AMaxWidth,
|
||||
AWrapIndent: Integer; const APhysCharWidths: TPhysicalCharWidths; ASubLine: Integer; out
|
||||
ALogStartX, ANextLogStartX, APhysStart: IntIdx; out APhysWidth: integer; var AViewedX: integer;
|
||||
out APhysX: integer);
|
||||
var
|
||||
x, RtlRemainderWidth, RtlLeadWitdh: Integer;
|
||||
begin
|
||||
GetSublineBounds(ALine, AMaxWidth, AWrapIndent, APhysCharWidths, ASubLine, ALogStartX, ANextLogStartX, APhysStart, APhysWidth);
|
||||
|
||||
if (ASubLine > 0) then begin
|
||||
AViewedX := max(1, AViewedX - AWrapIndent);
|
||||
if (AViewedX = 1) and (FCaretWrapPos = wcpEOL) then
|
||||
AViewedX := 2;
|
||||
end;
|
||||
if (ANextLogStartX > 0) and (ANextLogStartX < Length(ALine)) then begin
|
||||
x := APhysWidth;
|
||||
if FCaretWrapPos = wcpEOL then
|
||||
inc(x);
|
||||
if AViewedX > x then
|
||||
AViewedX := x;
|
||||
end;
|
||||
|
||||
APhysX := AViewedX;
|
||||
|
||||
if (ALogStartX > 0) and ((APhysCharWidths[ALogStartX] and PCWFlagRTL) <> 0) then begin
|
||||
x := FindPreviousCharStart(APhysCharWidths, ALogStartX);
|
||||
if (APhysCharWidths[x] and PCWFlagRTL) <> 0 then begin
|
||||
RtlRemainderWidth := CalculateRtlRemainder(APhysCharWidths, Length(ALine), ALogStartX);
|
||||
if APhysX < RtlRemainderWidth then begin
|
||||
RtlLeadWitdh := CalculateRtlLead(APhysCharWidths, x);
|
||||
APhysX := APhysX
|
||||
+ (APhysStart - RtlLeadWitdh)
|
||||
+ Max(0,RtlRemainderWidth - APhysWidth);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
if (ANextLogStartX > 0) and (ANextLogStartX < Length(ALine)) and ((APhysCharWidths[ANextLogStartX] and PCWFlagRTL) <> 0) then begin
|
||||
x := FindPreviousCharStart(APhysCharWidths, ANextLogStartX);
|
||||
RtlLeadWitdh := CalculateRtlLead(APhysCharWidths, x);
|
||||
assert(APhysWidth >= RtlLeadWitdh, 'TLazSynEditLineWrapPlugin.GetSublineBounds: APhysWidth > RtlLeadWitdh');
|
||||
if APhysX - 1 > APhysWidth - RtlLeadWitdh then begin
|
||||
RtlRemainderWidth := CalculateRtlRemainder(APhysCharWidths, Length(ALine), ANextLogStartX);
|
||||
APhysX := APhysX + APhysStart + RtlRemainderWidth;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
APhysX := APhysX + APhysStart;
|
||||
end;
|
||||
|
||||
function TLazSynEditLineWrapPlugin.GetSubLineFromX(ALine: String; AMaxWidth, AWrapIndent: Integer;
|
||||
const APhysCharWidths: TPhysicalCharWidths; var APhysToViewedXPos: Integer): integer;
|
||||
var
|
||||
x, PhysWidth, AMaxWidth2: Integer;
|
||||
x, PhysWidth, AMaxWidth2, x2: Integer;
|
||||
RtlLeadWitdh, RtlRemainderWidth, PhysToViewedInRTLOffs, LtrLead: integer;
|
||||
begin
|
||||
Result := 0;
|
||||
if Length(ALine) = 0 then
|
||||
exit;
|
||||
Result := -1;
|
||||
x := 0;
|
||||
RtlRemainderWidth := 0;
|
||||
PhysToViewedInRTLOffs := 0;
|
||||
|
||||
AMaxWidth2 := AMaxWidth - AWrapIndent;
|
||||
assert(AMaxWidth2>0, 'TLazSynEditLineWrapPlugin.GetSublineCount: AMaxWidth>0');
|
||||
@ -1906,17 +1995,56 @@ begin
|
||||
inc(Result);
|
||||
x := CalculateNextBreak(PChar(ALine), x, AMaxWidth, APhysCharWidths, PhysWidth);
|
||||
AMaxWidth := AMaxWidth2;
|
||||
if x >= Length(ALine) then
|
||||
break;
|
||||
if (FCaretWrapPos = wcpBOL) and (PhysWidth = APhysToViewedXPos) and (x < Length(ALine))
|
||||
then begin
|
||||
inc(Result);
|
||||
APhysToViewedXPos := APhysToViewedXPos - PhysWidth;
|
||||
if (x >= Length(ALine)) and (PhysToViewedInRTLOffs = 0) then
|
||||
break;
|
||||
|
||||
if RtlRemainderWidth > 0 then begin
|
||||
LtrLead := 0;
|
||||
RtlRemainderWidth := Max(0, RtlRemainderWidth - PhysWidth);
|
||||
end;
|
||||
|
||||
if (RtlRemainderWidth = 0) and
|
||||
(PhysToViewedInRTLOffs = 0) and
|
||||
(x > 0) and ((APhysCharWidths[x] and PCWFlagRTL) <> 0) then begin
|
||||
x2 := FindPreviousCharStart(APhysCharWidths, x);
|
||||
if ((APhysCharWidths[x2] and PCWFlagRTL) <> 0) then begin
|
||||
// IN RTL run
|
||||
RtlLeadWitdh := CalculateRtlLead(APhysCharWidths, x2);
|
||||
assert(RtlLeadWitdh <= PhysWidth, 'TLazSynEditLineWrapPlugin.GetSubLineFromX: RtlLeadWitdh <= PhysWidth');
|
||||
|
||||
if (APhysToViewedXPos <= PhysWidth - RtlLeadWitdh) then
|
||||
break;
|
||||
|
||||
RtlRemainderWidth := CalculateRtlRemainder(APhysCharWidths, Length(ALine), x);
|
||||
|
||||
LtrLead := PhysWidth - RtlLeadWitdh;
|
||||
PhysToViewedInRTLOffs := APhysToViewedXPos - LtrLead;
|
||||
|
||||
if PhysToViewedInRTLOffs >= RtlLeadWitdh + RtlRemainderWidth then //NOT_IN_THIS_RUN;
|
||||
PhysToViewedInRTLOffs := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
if (PhysToViewedInRTLOffs > 0) then begin
|
||||
if (PhysToViewedInRTLOffs > RtlRemainderWidth) or
|
||||
( (FCaretWrapPos = wcpBOL) and (PhysToViewedInRTLOffs = RtlRemainderWidth) )
|
||||
then begin // within RtlLeadWitdh on the right side
|
||||
//APhysToViewedXPos := APhysToViewedXPos - RtlRemainderWidth;
|
||||
APhysToViewedXPos := LtrLead + PhysToViewedInRTLOffs - RtlRemainderWidth;
|
||||
break;
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
if (FCaretWrapPos = wcpBOL) and (PhysWidth = APhysToViewedXPos) and (x < Length(ALine))
|
||||
then begin
|
||||
inc(Result);
|
||||
APhysToViewedXPos := APhysToViewedXPos - PhysWidth;
|
||||
break;
|
||||
end;
|
||||
if PhysWidth >= APhysToViewedXPos then
|
||||
break;
|
||||
APhysToViewedXPos := APhysToViewedXPos - PhysWidth;
|
||||
end;
|
||||
if PhysWidth >= APhysToViewedXPos then
|
||||
break;
|
||||
APhysToViewedXPos := APhysToViewedXPos - PhysWidth;
|
||||
end;
|
||||
APhysToViewedXPos := ToPos(APhysToViewedXPos);
|
||||
end;
|
||||
@ -1928,8 +2056,8 @@ var
|
||||
SubLineOffset, YIdx: TLineIdx;
|
||||
LineTxt: String;
|
||||
PWidth: TPhysicalCharWidths;
|
||||
LogX, NextLogX, PhysX: IntIdx;
|
||||
PhysWidth, WrapInd, AMaxWidth: Integer;
|
||||
BoundLogX, NextBoundLogX, BoundPhysX: IntIdx;
|
||||
PhysWidth, WrapInd, AMaxWidth, PhysXPos: Integer;
|
||||
begin
|
||||
|
||||
YIdx := FLineMapView.Tree.GetLineForForWrap(ToIdx(AViewedXY.y), SubLineOffset);
|
||||
@ -1941,26 +2069,19 @@ begin
|
||||
AMaxWidth := WrapColumn;
|
||||
WrapInd := CalculateIndentFor(PChar(LineTxt), AMaxWidth, PWidth);
|
||||
|
||||
GetSublineBounds(LineTxt, AMaxWidth, WrapInd, PWidth, SubLineOffset, LogX, NextLogX, PhysX, PhysWidth);
|
||||
GetSublineBounds(LineTxt, AMaxWidth, WrapInd, PWidth, SubLineOffset, BoundLogX, NextBoundLogX, BoundPhysX, PhysWidth, AViewedXY.x, PhysXPos);
|
||||
|
||||
case CaretWrapPos of
|
||||
wcpEOL: begin
|
||||
if (SubLineOffset > 0) and (AViewedXY.x <= 1) then
|
||||
AViewedXY.x := 2
|
||||
else
|
||||
if (NextLogX < length(LineTxt)) and (AViewedXY.x > ToPos(PhysWidth)) then
|
||||
AViewedXY.x := ToPos(PhysWidth);
|
||||
AFirstViewedX := 2;
|
||||
end;
|
||||
wcpBOL: begin
|
||||
if (NextLogX < length(LineTxt)) and (AViewedXY.x >= ToPos(PhysWidth)) then
|
||||
AViewedXY.x := ToPos(PhysWidth) - 1;
|
||||
AFirstViewedX := 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
AViewedXY.x := PhysXPos;
|
||||
AViewedXY.y := ToPos(YIdx);
|
||||
AViewedXY.x := AViewedXY.x + PhysX;
|
||||
end;
|
||||
|
||||
function TLazSynEditLineWrapPlugin.TextXYToLineXY(ATextXY: TPhysPoint
|
||||
@ -1978,17 +2099,18 @@ begin
|
||||
Result.x := ATextXY.x;
|
||||
Result.y :=
|
||||
GetSubLineFromX(ALine, AMaxWidth, WrapInd, APhysCharWidths, Result.x);
|
||||
if Result.x <> ATextXY.x then
|
||||
//if Result.x <> ATextXY.x then
|
||||
if Result.y > 0 then
|
||||
Result.x := Result.x + WrapInd; // Result is on sub-line
|
||||
end;
|
||||
|
||||
function TLazSynEditLineWrapPlugin.LineXYToTextX(ARealLine: IntPos;
|
||||
function TLazSynEditLineWrapPlugin.ViewedSubLineXYToTextX(ARealLine: IntPos;
|
||||
ALineXY: TViewedSubPoint_0): Integer;
|
||||
var
|
||||
AMaxWidth, WrapInd, ANextLogX, APhysWidth: Integer;
|
||||
ALine: String;
|
||||
APhysCharWidths: TPhysicalCharWidths;
|
||||
dummy: integer;
|
||||
dummy, PhysXPos: integer;
|
||||
begin
|
||||
FLineMapView.LogPhysConvertor.CurrentLine := ARealLine;
|
||||
ALine := FLineMapView.NextLines.Strings[ARealLine];
|
||||
@ -1996,22 +2118,8 @@ begin
|
||||
AMaxWidth := WrapColumn;
|
||||
WrapInd := CalculateIndentFor(PChar(ALine), AMaxWidth, APhysCharWidths);
|
||||
|
||||
GetSublineBounds(ALine, AMaxWidth, WrapInd, APhysCharWidths, ALineXY.y, dummy, ANextLogX, Result, APhysWidth);
|
||||
|
||||
if (ALineXY.y > 0) then
|
||||
ALineXY.x := max(1, ALineXY.x -WrapInd);
|
||||
if (ALineXY.y > 0) and (ALineXY.X <= 1) and (FCaretWrapPos = wcpEOL) then begin
|
||||
ALineXY.x := 2;
|
||||
end
|
||||
else
|
||||
if (ANextLogX > 0) and (ANextLogX < Length(ALine)) then begin
|
||||
if FCaretWrapPos = wcpEOL then
|
||||
inc(APhysWidth);
|
||||
if ALineXY.X > APhysWidth then
|
||||
ALineXY.x := APhysWidth;
|
||||
end;
|
||||
|
||||
Result := Result + ALineXY.x;
|
||||
GetSublineBounds(ALine, AMaxWidth, WrapInd, APhysCharWidths, ALineXY.y, dummy, ANextLogX, Result, APhysWidth, ALineXY.x, PhysXPos);
|
||||
Result := PhysXPos;
|
||||
end;
|
||||
|
||||
function TLazSynEditLineWrapPlugin.CalculateWrapForLine(ALineIdx: IntIdx;
|
||||
|
@ -2014,15 +2014,36 @@ begin
|
||||
SynEdit.TabWidth := 4;
|
||||
|
||||
SetLines([
|
||||
// 0
|
||||
'abc def ' + 'ABC DEFG ' + 'XYZ',
|
||||
//'A' #9'B' #9'C ' + 'DEF G'#9'H' #9 + '' #9 #9'xy',
|
||||
'A'#9'B'#9'C ' + 'DEF G'#9'H'#9 + #9#9'xy',
|
||||
'äää ööö ' + 'ÄÄÄ ÖÖÖ ' + 'ÜÜÜ',
|
||||
'999'
|
||||
'999',
|
||||
|
||||
// 4
|
||||
'A نمت X',
|
||||
'A نمت X Foo',
|
||||
// 6
|
||||
'Abc d نمت Foo',
|
||||
'Abc de نمت Foo',
|
||||
'Abcde def نمت Foo',
|
||||
'Abcde def نمت Foo',
|
||||
|
||||
// 10
|
||||
'Abcde نمت نمت Foo',
|
||||
'Abc de نمت نمت Foo',
|
||||
'Abc de نمت نمت F نمت نمت Foo',
|
||||
'Abc de نمت نمت نمت نمت Foo',
|
||||
|
||||
// 13
|
||||
'نمت) نمت نمت 789 123 نمت', // digits are weak LTR/RTL
|
||||
''
|
||||
]);
|
||||
|
||||
SetSynEditWidth(10);
|
||||
CheckLines('', 0, [
|
||||
// 0 // Virt = 0
|
||||
'abc def ',
|
||||
'ABC DEFG ',
|
||||
'XYZ',
|
||||
@ -2032,7 +2053,41 @@ begin
|
||||
'äää ööö ',
|
||||
'ÄÄÄ ÖÖÖ ',
|
||||
'ÜÜÜ',
|
||||
'999'
|
||||
'999',
|
||||
|
||||
// 4 // Virt= 10
|
||||
'A نمت X',
|
||||
'A نمت X ',
|
||||
'Foo',
|
||||
// 6 // Virt=13
|
||||
'Abc d نمت ',
|
||||
'Foo',
|
||||
'Abc de نمت',
|
||||
' Foo',
|
||||
'Abcde def ',
|
||||
'نمت Foo',
|
||||
'Abcde def',
|
||||
' نمت Foo',
|
||||
|
||||
// 10 // Virt = 21
|
||||
'Abcde نمت ',
|
||||
'نمت Foo',
|
||||
'Abc de نمت',
|
||||
' نمت Foo',
|
||||
'Abc de نمت',
|
||||
' نمت F نمت'
|
||||
,' نمت Foo',
|
||||
'Abc de نمت',
|
||||
' نمت نمت '
|
||||
,'نمت Foo',
|
||||
|
||||
// 14 // Virt = 31
|
||||
'نمت) نمت ',
|
||||
'نمت 789 ',
|
||||
'123 نمت',
|
||||
|
||||
''
|
||||
|
||||
], True);
|
||||
|
||||
CheckLines('', ViewedExp(0, [
|
||||
@ -2045,7 +2100,41 @@ begin
|
||||
l(2, 0, 'äää ööö '),
|
||||
l(2, 1, 'ÄÄÄ ÖÖÖ '),
|
||||
l(2, 2, 'ÜÜÜ'),
|
||||
l(3, 0, '999')
|
||||
l(3, 0, '999'),
|
||||
|
||||
// 4 // Virt= 10
|
||||
l(4, 0, 'A نمت X'),
|
||||
l(5, 0, 'A نمت X '),
|
||||
l(5, 1, 'Foo'),
|
||||
// 6 // Virt=13
|
||||
l(6, 0, 'Abc d نمت '),
|
||||
l(6, 1, 'Foo'),
|
||||
l(7, 0, 'Abc de نمت'),
|
||||
l(7, 1, ' Foo'),
|
||||
l(8, 0, 'Abcde def '),
|
||||
l(8, 1, 'نمت Foo'),
|
||||
l(9, 0, 'Abcde def'),
|
||||
l(9, 1, ' نمت Foo'),
|
||||
|
||||
// 10 // Virt = 21
|
||||
l(10, 0, 'Abcde نمت '),
|
||||
l(10, 1, 'نمت Foo'),
|
||||
l(11, 0, 'Abc de نمت'),
|
||||
l(11, 1, ' نمت Foo'),
|
||||
l(12, 0, 'Abc de نمت'),
|
||||
l(12, 1, ' نمت F نمت'),
|
||||
l(12, 2, ' نمت Foo'),
|
||||
l(13, 0, 'Abc de نمت'),
|
||||
l(13, 1, ' نمت نمت '),
|
||||
l(13, 2, 'نمت Foo'),
|
||||
|
||||
// 14 // Virt = 31
|
||||
l(14, 0, 'نمت) نمت '),
|
||||
l(14, 1, 'نمت 789 '),
|
||||
l(14, 2, '123 نمت'),
|
||||
|
||||
l(15, 0, '')
|
||||
|
||||
], tTrue));
|
||||
|
||||
|
||||
@ -2224,6 +2313,64 @@ begin
|
||||
CheckXyMap('wcpBOL', p( 2,8, 10,3, 17,3)); // after "Ä"
|
||||
CheckXyMap('wcpBOL', p( 1,9, 17,3, 29,3)); // after " "
|
||||
|
||||
//FWordWrap.CaretWrapPos := wcpBOL;
|
||||
|
||||
FWordWrap.CaretWrapPos := wcpEOL;
|
||||
// viewed phys log x,y
|
||||
// line 5 (idx=4)
|
||||
CheckXyMap('RTL', p( 2,11, 2,5, 2,5)); // after A
|
||||
CheckXyMap('RTL', p( 3,11, 3,5, 3,5)); // after A space // befare first RTL / could be PX = 6
|
||||
CheckXyMap('RTL', p( 5,11, 5,5, 5,5)); // after first RTL
|
||||
CheckXyMap('RTL', p( 4,11, 4,5, 7,5)); // after 2nd RTL
|
||||
CheckXyMap('RTL', p( 6,11, 6,5, 9,5)); // after 3rd RTL // before space / could be PX=3
|
||||
CheckXyMap('RTL', p( 7,11, 7,5, 10,5)); // after 2nd space
|
||||
CheckXyMap('RTL', p( 8,11, 8,5, 11,5)); // after X
|
||||
|
||||
// line 6 (idx=5)
|
||||
CheckXyMap('RTL', p( 8,12, 8,6, 11,6)); // after X
|
||||
CheckXyMap('RTL', p( 9,12, 9,6, 12,6)); // after X space
|
||||
CheckXyMap('RTL', p( 2,13, 10,6, 13,6)); // after F of Foo
|
||||
|
||||
// line 7 (idx=6)
|
||||
CheckXyMap('RTL', p(11,14, 11,7, 14,7)); // after last space in first line
|
||||
CheckXyMap('RTL', p( 2,15, 12,7, 15,7)); // after F of Foo (subline)
|
||||
|
||||
// line 8 (idx=7)
|
||||
CheckXyMap('RTL', p(11,16, 11,8, 14,8)); // after last RTL
|
||||
CheckXyMap('RTL', p( 2,17, 12,8, 15,8)); // after space, before Foo (subline)
|
||||
|
||||
// line 9 (idx=8)
|
||||
FWordWrap.CaretWrapPos := wcpBOL;
|
||||
CheckXyMap('RTL BOL', p( 1,19, 11,9, 11,9)); // subline at start (before first RTL)
|
||||
CheckXyMap('RTL BOL', p( 3,19, 13,9, 13,9)); // subline (after first RTL)
|
||||
CheckXyMap('RTL BOL', p( 2,19, 12,9, 15,9)); // subline (after 2nd RTL)
|
||||
FWordWrap.CaretWrapPos := wcpEOL;
|
||||
CheckXyMap('RTL', p(11,18, 11,9, 11,9)); // at end of first line
|
||||
CheckXyMap('RTL', p( 3,19, 13,9, 13,9)); // subline (after first RTL)
|
||||
CheckXyMap('RTL', p( 2,19, 12,9, 15,9)); // subline (after 2nd RTL)
|
||||
|
||||
// line 10 (idx=9) / Virt 20
|
||||
|
||||
// line 11 (idx=10) / Virt 22
|
||||
(* The space at the end of the first line is the space between the 2 RTL sequences.
|
||||
(the space is part of the overall RTL sequence)
|
||||
That space is therefore displayed at the left end of the RTL run.
|
||||
I.e. On the screen it is right after the normal space from "ABCDE "
|
||||
The RTL sequence in the first line is the sequence from the right of the RTL run
|
||||
*)
|
||||
FWordWrap.CaretWrapPos := wcpEOL;
|
||||
CheckXyMap('RTL', p(10,22, 13,11, 9,11)); // after first RTL (first line)
|
||||
CheckXyMap('RTL', p( 9,22, 12,11, 11,11)); // after 2nd RTL (first line)
|
||||
CheckXyMap('RTL', p( 8,22, 11,11, 13,11)); // after 3rd / before space
|
||||
// The viewed-x is between the leading LTR and the RTL text. So it can not be distinguished
|
||||
// CheckXyMap('RTL', p( 7,22, 10,11, 14,11)); // after space //???????????? TEST BOL <> EOL
|
||||
|
||||
// same at the end
|
||||
// CheckXyMap('RTL', p( 3,23, 9,11, 16,11)); // 1st subline: after 1st RTL (2nd sequence)
|
||||
CheckXyMap('RTL', p( 2,23, 8,11, 18,11)); // 1st subline: after 2nd RTL (2nd sequence)
|
||||
CheckXyMap('RTL', p( 4,23, 14,11, 20,11)); // 1st subline: after 3rd RTL (2nd sequence) => go to LTR sequence
|
||||
|
||||
|
||||
end;
|
||||
|
||||
|
||||
@ -2234,8 +2381,8 @@ begin
|
||||
|
||||
|
||||
SynEdit.ExecuteCommand(ecEditorBottom, '', nil);
|
||||
AssertEquals('ecEditorBottom', 4 ,SynEdit.CaretY);
|
||||
AssertEquals('ecEditorBottom', 10 ,SynEdit.CaretObj.ViewedLineCharPos.y);
|
||||
AssertEquals('ecEditorBottom', 15 ,SynEdit.CaretY);
|
||||
AssertEquals('ecEditorBottom', 34 ,SynEdit.CaretObj.ViewedLineCharPos.y);
|
||||
|
||||
SetSynEditWidth(65);
|
||||
AddLines(0, 6000, 60, 'A');
|
||||
|
Loading…
Reference in New Issue
Block a user