mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-31 11:40:33 +02:00
SynEdit: more support for combining codepoints
git-svn-id: trunk@39094 -
This commit is contained in:
parent
946e1acb17
commit
caf2837329
@ -193,6 +193,7 @@ type
|
||||
procedure UndoEditLinesDelete(LogY, ACount: Integer);
|
||||
procedure IncreaseTextChangeStamp;
|
||||
procedure DoGetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer; PWidths: PPhysicalCharWidth); override;
|
||||
function LogicPosIsCombining(const ALine: String; ALogicalPos: integer): Boolean; inline;
|
||||
|
||||
function GetDisplayView: TLazSynDisplayView; override;
|
||||
public
|
||||
@ -858,6 +859,21 @@ begin
|
||||
|
||||
end;
|
||||
|
||||
function TSynEditStringList.LogicPosIsCombining(const ALine: String;
|
||||
ALogicalPos: integer): Boolean;
|
||||
begin
|
||||
Result := (ALogicalPos > 1) and (
|
||||
( (ALine[ALogicalPos] = #$CC) {and (ALine[ALogicalPos+1] in [#$80..#$FF])} ) or // Combining Diacritical Marks (belongs to previos char) 0300-036F
|
||||
( (ALine[ALogicalPos] = #$CD) and (ALine[ALogicalPos+1] in [#$80..#$AF]) ) or // Combining Diacritical Marks
|
||||
( (ALine[ALogicalPos] = #$E1) and (ALine[ALogicalPos+1] = #$B7) ) or // Combining Diacritical Marks Supplement 1DC0-1DFF
|
||||
// (ALine[ALogicalPos+2] in [#$80..#$BF])
|
||||
( (ALine[ALogicalPos] = #$E2) and (ALine[ALogicalPos+1] = #$83) and
|
||||
(ALine[ALogicalPos+2] in [#$90..#$FF]) ) or // Combining Diacritical Marks for Symbols 20D0-20FF
|
||||
( (ALine[ALogicalPos] = #$EF) and (ALine[ALogicalPos+1] = #$B8) and
|
||||
(ALine[ALogicalPos+2] in [#$A0..#$AF]) ) // Combining half Marks FE20-FE2F
|
||||
);
|
||||
end;
|
||||
|
||||
function TSynEditStringList.GetDisplayView: TLazSynDisplayView;
|
||||
begin
|
||||
Result := FDisplayView;
|
||||
@ -1051,15 +1067,17 @@ begin
|
||||
if ACount > 0 then begin;
|
||||
while (Result < length(ALine)) and (ACount > 0) do begin
|
||||
inc(Result);
|
||||
if ALine[Result] in [#0..#127, #192..#255] then
|
||||
if (ALine[Result] in [#0..#127, #192..#255]) and (not LogicPosIsCombining(ALine, Result)) then
|
||||
dec(ACount);
|
||||
end;
|
||||
while (Result > 1) and not(ALine[Result] in [#0..#127, #192..#255]) do
|
||||
while (Result > 1) and
|
||||
( (not(ALine[Result] in [#0..#127, #192..#255])) or LogicPosIsCombining(ALine, Result) )
|
||||
do
|
||||
dec(Result);
|
||||
end else begin
|
||||
while (Result > 1) and (ACount < 0) do begin
|
||||
dec(Result);
|
||||
if ALine[Result] in [#0..#127, #192..#255] then
|
||||
if (ALine[Result] in [#0..#127, #192..#255]) and (not LogicPosIsCombining(ALine, Result)) then
|
||||
inc(ACount);
|
||||
end;
|
||||
end;
|
||||
@ -1072,6 +1090,9 @@ begin
|
||||
Result := False;
|
||||
if (ALogicalPos < 1) or (ALogicalPos > length(ALine)) then exit;
|
||||
Result := ALine[ALogicalPos] in [#0..#127, #192..#255];
|
||||
|
||||
if Result then
|
||||
Result := not LogicPosIsCombining(ALine, ALogicalPos);
|
||||
end;
|
||||
|
||||
function TSynEditStringList.LogicPosAdjustToChar(const ALine: String; ALogicalPos: integer;
|
||||
@ -1082,11 +1103,15 @@ begin
|
||||
if (ALogicalPos < 1) or (ALogicalPos > length(ALine)) then exit;
|
||||
|
||||
if ANext then begin
|
||||
while (Result < length(ALine)) and not(ALine[Result] in [#0..#127, #192..#255]) do
|
||||
while (Result < length(ALine)) and
|
||||
( (not(ALine[Result] in [#0..#127, #192..#255])) or LogicPosIsCombining(ALine, Result) )
|
||||
do
|
||||
inc(Result);
|
||||
end;
|
||||
|
||||
while (Result > 1) and not(ALine[Result] in [#0..#127, #192..#255]) do
|
||||
while (Result > 1) and
|
||||
( (not(ALine[Result] in [#0..#127, #192..#255])) or LogicPosIsCombining(ALine, Result) )
|
||||
do
|
||||
dec(Result);
|
||||
end;
|
||||
|
||||
|
@ -326,6 +326,7 @@ procedure TTestSynNavigation.TestCaretLeftRight;
|
||||
'abc def ü'#9'üü xyz', // 7: utf8 multibyte + tabs
|
||||
'abc あdefあ123', // 8: Double withs
|
||||
'abc あdef'#9'あ'#9'123', // 9: Double withs + tabs
|
||||
'Aa'#$CC#$81'B', // 10: a-accent, in 2 (combining) codepoints)
|
||||
''
|
||||
]);
|
||||
end;
|
||||
@ -577,6 +578,7 @@ begin
|
||||
|
||||
TestLeftRight('Umlaut right', 6, 9, ecRight, 10,11, 11,13);
|
||||
TestLeftRight('Double W right', 8, 5, ecRight, 7, 8, 8, 9);
|
||||
TestLeftRight('combining right', 10, 2, ecRight, 3, 5, 4, 6);
|
||||
|
||||
TestLeftRight('at EOL right', 5, 10, ecRight, 1, 1, 2, 2, True, True, -1 , 6);
|
||||
|
||||
@ -618,6 +620,7 @@ begin
|
||||
|
||||
TestLeftRight('Umlaut left', 6, 10, ecLeft, 9, 9, 8, 8);
|
||||
TestLeftRight('Double W left', 8, 7, ecLeft, 5, 5, 4, 4);
|
||||
TestLeftRight('combining left', 10, 3, ecLeft, 2, 2, 1, 1);
|
||||
|
||||
TestLeftRight('at BOL left', 6, 1, ecLeft, 10, 8, 9, 7, True, True, -1 , 5);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user