SynEdit: refactor detection of combining chars

git-svn-id: trunk@39120 -
This commit is contained in:
martin 2012-10-18 00:04:13 +00:00
parent 9270a6f705
commit 0b12629f67

View File

@ -193,7 +193,7 @@ type
procedure UndoEditLinesDelete(LogY, ACount: Integer); procedure UndoEditLinesDelete(LogY, ACount: Integer);
procedure IncreaseTextChangeStamp; procedure IncreaseTextChangeStamp;
procedure DoGetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer; PWidths: PPhysicalCharWidth); override; procedure DoGetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer; PWidths: PPhysicalCharWidth); override;
function LogicPosIsCombining(const ALine: String; ALogicalPos: integer): Boolean; inline; function LogicPosIsCombining(const AChar: PChar): Boolean; inline;
function GetDisplayView: TLazSynDisplayView; override; function GetDisplayView: TLazSynDisplayView; override;
public public
@ -828,30 +828,37 @@ begin
for i := 0 to LineLen-1 do begin for i := 0 to LineLen-1 do begin
case Line^ of case Line^ of
#$00..#$7F:
PWidths^ := 1;
#$80..#$BF: #$80..#$BF:
PWidths^ := 0; PWidths^ := 0;
#$CC: else
if ((Line+1)^ in [#$80..#$FF]) and (i>0) if LogicPosIsCombining(Line) then
then PWidths^ := 0 // Combining Diacritical Marks (belongs to previos char) 0300-036F PWidths^ := 0
else PWidths^ := 1;
#$CD:
if ((Line+1)^ in [#$00..#$AF]) and (i>0)
then PWidths^ := 0 // Combining Diacritical Marks
else PWidths^ := 1;
#$E1:
if (((Line+1)^ = #$B7) and ((Line+2)^ in [#$80..#$BF])) and (i>0)
then PWidths^ := 0 // Combining Diacritical Marks Supplement 1DC0-1DFF
else PWidths^ := 1;
#$E2:
if (((Line+1)^ = #$83) and ((Line+2)^ in [#$90..#$FF])) and (i>0)
then PWidths^ := 0 // Combining Diacritical Marks for Symbols 20D0-20FF
else PWidths^ := 1;
#$EF:
if (((Line+1)^ = #$B8) and ((Line+2)^ in [#$A0..#$AF])) and (i>0)
then PWidths^ := 0 // Combining half Marks FE20-FE2F
else PWidths^ := 1;
else else
PWidths^ := 1; PWidths^ := 1;
//#$CC:
// if ((Line+1)^ in [#$80..#$FF]) and (i>0)
// then PWidths^ := 0 // Combining Diacritical Marks (belongs to previos char) 0300-036F
// else PWidths^ := 1;
//#$CD:
// if ((Line+1)^ in [#$00..#$AF]) and (i>0)
// then PWidths^ := 0 // Combining Diacritical Marks
// else PWidths^ := 1;
//#$E1:
// if (((Line+1)^ = #$B7) and ((Line+2)^ in [#$80..#$BF])) and (i>0)
// then PWidths^ := 0 // Combining Diacritical Marks Supplement 1DC0-1DFF
// else PWidths^ := 1;
//#$E2:
// if (((Line+1)^ = #$83) and ((Line+2)^ in [#$90..#$FF])) and (i>0)
// then PWidths^ := 0 // Combining Diacritical Marks for Symbols 20D0-20FF
// else PWidths^ := 1;
//#$EF:
// if (((Line+1)^ = #$B8) and ((Line+2)^ in [#$A0..#$AF])) and (i>0)
// then PWidths^ := 0 // Combining half Marks FE20-FE2F
// else PWidths^ := 1;
//else
// PWidths^ := 1;
end; end;
inc(PWidths); inc(PWidths);
inc(Line); inc(Line);
@ -859,18 +866,17 @@ begin
end; end;
function TSynEditStringList.LogicPosIsCombining(const ALine: String; function TSynEditStringList.LogicPosIsCombining(const AChar: PChar): Boolean;
ALogicalPos: integer): Boolean;
begin begin
Result := (ALogicalPos > 1) and ( Result := (
( (ALine[ALogicalPos] = #$CC) {and (ALine[ALogicalPos+1] in [#$80..#$FF])} ) or // Combining Diacritical Marks (belongs to previos char) 0300-036F ( (AChar[0] = #$CC) {and (AChar[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 ( (AChar[0] = #$CD) and (AChar[1] in [#$80..#$AF]) ) or // Combining Diacritical Marks
( (ALine[ALogicalPos] = #$E1) and (ALine[ALogicalPos+1] = #$B7) ) or // Combining Diacritical Marks Supplement 1DC0-1DFF ( (AChar[0] = #$E1) and (AChar[1] = #$B7) ) or // Combining Diacritical Marks Supplement 1DC0-1DFF
// (ALine[ALogicalPos+2] in [#$80..#$BF]) // (AChar[0+2] in [#$80..#$BF])
( (ALine[ALogicalPos] = #$E2) and (ALine[ALogicalPos+1] = #$83) and ( (AChar[0] = #$E2) and (AChar[1] = #$83) and
(ALine[ALogicalPos+2] in [#$90..#$FF]) ) or // Combining Diacritical Marks for Symbols 20D0-20FF (AChar[2] in [#$90..#$FF]) ) or // Combining Diacritical Marks for Symbols 20D0-20FF
( (ALine[ALogicalPos] = #$EF) and (ALine[ALogicalPos+1] = #$B8) and ( (AChar[0] = #$EF) and (AChar[1] = #$B8) and
(ALine[ALogicalPos+2] in [#$A0..#$AF]) ) // Combining half Marks FE20-FE2F (AChar[2] in [#$A0..#$AF]) ) // Combining half Marks FE20-FE2F
); );
end; end;
@ -1066,7 +1072,7 @@ begin
if ACount > 0 then begin; if ACount > 0 then begin;
while (Result < l) and (ACount > 0) do begin while (Result < l) and (ACount > 0) do begin
inc(Result); inc(Result);
if (ALine[Result] in [#0..#127, #192..#255]) and (not LogicPosIsCombining(ALine, Result)) then if (ALine[Result] in [#0..#127, #192..#255]) and (not LogicPosIsCombining(@ALine[Result])) then
dec(ACount); dec(ACount);
end; end;
if AllowPastEOL then if AllowPastEOL then
@ -1074,14 +1080,14 @@ begin
if (Result <= l) then if (Result <= l) then
while (Result > 1) and while (Result > 1) and
( (not(ALine[Result] in [#0..#127, #192..#255])) or LogicPosIsCombining(ALine, Result) ) ( (not(ALine[Result] in [#0..#127, #192..#255])) or LogicPosIsCombining(@ALine[Result]) )
do do
dec(Result); dec(Result);
end else begin end else begin
while (Result > 1) and (ACount < 0) do begin while (Result > 1) and (ACount < 0) do begin
dec(Result); dec(Result);
if (Result > l) or if (Result > l) or (Result = 1) or
( (ALine[Result] in [#0..#127, #192..#255]) and (not LogicPosIsCombining(ALine, Result)) ) ( (ALine[Result] in [#0..#127, #192..#255]) and (not LogicPosIsCombining(@ALine[Result])) )
then then
inc(ACount); inc(ACount);
end; end;
@ -1097,7 +1103,7 @@ begin
Result := ALine[ALogicalPos] in [#0..#127, #192..#255]; Result := ALine[ALogicalPos] in [#0..#127, #192..#255];
if Result then if Result then
Result := not LogicPosIsCombining(ALine, ALogicalPos); Result := (ALogicalPos = 1) or (not LogicPosIsCombining(@ALine[ALogicalPos]));
end; end;
function TSynEditStringList.LogicPosAdjustToChar(const ALine: String; ALogicalPos: integer; function TSynEditStringList.LogicPosAdjustToChar(const ALine: String; ALogicalPos: integer;
@ -1109,7 +1115,8 @@ begin
if ANext then begin if ANext then begin
while (Result <= length(ALine)) and while (Result <= length(ALine)) and
( (not(ALine[Result] in [#0..#127, #192..#255])) or LogicPosIsCombining(ALine, Result) ) ( (not(ALine[Result] in [#0..#127, #192..#255])) or
((Result <> 1) and LogicPosIsCombining(@ALine[Result])) )
do do
inc(Result); inc(Result);
end; end;
@ -1118,7 +1125,7 @@ begin
Result := length(ALine); Result := length(ALine);
while (Result > 1) and while (Result > 1) and
( (not(ALine[Result] in [#0..#127, #192..#255])) or LogicPosIsCombining(ALine, Result) ) ( (not(ALine[Result] in [#0..#127, #192..#255])) or LogicPosIsCombining(@ALine[Result]) )
do do
dec(Result); dec(Result);
end; end;