SynEdit: Fixes for displaying ligatures (experimental, window only)

git-svn-id: trunk@39534 -
This commit is contained in:
martin 2012-12-14 05:46:43 +00:00
parent 0034704084
commit c073cb340f
2 changed files with 45 additions and 11 deletions

View File

@ -81,6 +81,8 @@ type
TSynLogCharSide = (cslBefore, cslAfter, cslFollowLtr, cslFollowRtl);
TSynPhysCharSide = (cspLeft, cspRight, cspFollowLtr, cspFollowRtl);
TSynLogPhysFlag = (lpfAdjustToCharBegin, lpfAdjustToNextChar);
TSynLogPhysFlags = set of TSynLogPhysFlag;
(** LRL // L=Ltr-Char / R=RTl-Char
@ -124,6 +126,8 @@ type
TSynLogicalPhysicalConvertor = class
private
FLastLogicalResultPos: Integer;
FLastPhysicalResultPos: Integer;
FLines: TSynEditStrings;
FCurrentWidths: TPhysicalCharWidths;
FCurrentWidthsLen, FCurrentWidthsAlloc: Integer;
@ -139,11 +143,17 @@ type
// Line is 0-based // Column is 1-based
function PhysicalToLogical(AIndex, AColumn: Integer): Integer;
function PhysicalToLogical(AIndex, AColumn: Integer; out AColOffset: Integer;
ACharSide: TSynPhysCharSide= cspFollowLtr): Integer;
ACharSide: TSynPhysCharSide= cspFollowLtr//;
{AFlags: TSynLogPhysFlags = []}): Integer;
// ACharPos 1=before 1st char
function LogicalToPhysical(AIndex, ABytePos: Integer): Integer;
function LogicalToPhysical(AIndex, ABytePos: Integer; var AColOffset: Integer;
ACharSide: TSynLogCharSide = cslFollowLtr): Integer;
ACharSide: TSynLogCharSide = cslFollowLtr;
AFlags: TSynLogPhysFlags = []): Integer;
// properties set, if lpfAdjustTo... is used
property LastLogicalResultPos: Integer read FLastLogicalResultPos;
//property LastLogicalResultColOffs: Integer read FLastLogicalResultColOffs;
property LastPhysicalResultPos: Integer read FLastPhysicalResultPos;
end;
(*
@ -615,7 +625,7 @@ begin
end;
function TSynLogicalPhysicalConvertor.PhysicalToLogical(AIndex, AColumn: Integer; out
AColOffset: Integer; ACharSide: TSynPhysCharSide): Integer;
AColOffset: Integer; ACharSide: TSynPhysCharSide{; AFlags: TSynLogPhysFlags}): Integer;
var
BytePos, ScreenPos, ScreenPosOld: integer;
RtlPos, RtlScreen: Integer;
@ -732,11 +742,13 @@ begin
end;
function TSynLogicalPhysicalConvertor.LogicalToPhysical(AIndex, ABytePos: Integer;
var AColOffset: Integer; ACharSide: TSynLogCharSide): Integer;
var AColOffset: Integer; ACharSide: TSynLogCharSide; AFlags: TSynLogPhysFlags): Integer;
var
i: integer;
RtlLen: Integer;
begin
FLastLogicalResultPos := ABytePos;
FLastPhysicalResultPos := ABytePos;
{$IFDEF AssertSynMemIndex}
if (ABytePos <= 0) then
raise Exception.Create(Format('Bad Bytpos for PhystoLogical BytePos=%d ColOffs= %d idx= %d',[ABytePos, AColOffset, AIndex]));
@ -753,6 +765,25 @@ begin
PrepareWidthsForLine(AIndex);
dec(ABytePos);
if ABytePos < FCurrentWidthsLen then begin
if (FCurrentWidths[ABytePos] and PCWMask) = 0 then begin
if lpfAdjustToCharBegin in AFlags then begin
while (ABytePos > 0) and ((FCurrentWidths[ABytePos] and PCWMask) = 0) do
dec(ABytePos);
end
else
if lpfAdjustToNextChar in AFlags then begin
while (ABytePos < FCurrentWidthsLen) and ((FCurrentWidths[ABytePos] and PCWMask) = 0) do
inc(ABytePos);
end;
FLastLogicalResultPos := ABytePos+1;
assert((FCurrentWidths[ABytePos] and PCWMask) <> 0, 'LogicalToPhysical at char');
end;
if ABytePos < FCurrentWidthsLen then
AColOffset := Min(AColOffset, (FCurrentWidths[ABytePos] and PCWMask)-1);
Result := 1 + AColOffset;
end;
if ABytePos >= FCurrentWidthsLen then
begin
Result := 1 + ABytePos - FCurrentWidthsLen;
@ -760,14 +791,8 @@ begin
ACharSide := cslAfter;
ABytePos := FCurrentWidthsLen;
AColOffset := 0;
end
else begin
AColOffset := Min(AColOffset, (FCurrentWidths[ABytePos] and PCWMask)-1);
assert((FCurrentWidths[ABytePos] and PCWMask) <> 0, 'LogicalToPhysical at char');
Result := 1 + AColOffset;
end;
RtlLen := 0;
for i := 0 to ABytePos - 1 do begin
if ((FCurrentWidths[i] and PCWMask) = 0) then
@ -809,6 +834,7 @@ begin
then
Result := Result + RtlLen;
{$ENDIF}
FLastPhysicalResultPos := Result;
end;
{ TSynEditStrings }

View File

@ -501,6 +501,7 @@ var
CharWidths: TPhysicalCharWidths;
GotCharWidths: Boolean;
MaxOffs: Integer;
Flag: TSynLogPhysFlags;
function GetMaxOffs(AlogPos: Integer): Integer;
begin
@ -516,6 +517,7 @@ begin
UpdateBytePos;
If ACount > 0 then begin
Flag := [lpfAdjustToNextChar];
if (FBytePos <= length(L)) and (L[FBytePos] = #9) and (not FSkipTabs) then
MaxOffs := GetMaxOffs(FBytePos) - 1
else
@ -537,6 +539,7 @@ begin
Result := FBytePos <= length(L) + 1;
end
else begin
Flag := [lpfAdjustToCharBegin];
while ACount < 0 do begin
if FBytePosOffset > 0 then
dec(FBytePosOffset)
@ -553,7 +556,12 @@ begin
end;
Result := ACount = 0;
end;
CharPos := FLines.LogPhysConvertor.LogicalToPhysical(FLinePos - 1, FBytePos, FBytePosOffset);
CharPos := FLines.LogPhysConvertor.LogicalToPhysical(FLinePos - 1, FBytePos,
FBytePosOffset, cslFollowLtr, Flag);
if FBytePos <> FLines.LogPhysConvertor.LastLogicalResultPos then begin
FBytePos := FLines.LogPhysConvertor.LastLogicalResultPos;
FBytePosOffset := 0;
end;
end;
procedure TSynEditCaret.setLinePos(const AValue : Integer);