mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-10-24 09:11:44 +02:00
SynEdit: Refactor, LengthOfLongestLine
git-svn-id: trunk@25787 -
This commit is contained in:
parent
569641d81d
commit
a305372d19
@ -419,7 +419,7 @@ var
|
||||
L: String;
|
||||
begin
|
||||
L := LineText;
|
||||
CharWidths := FLines.GetPhysicalCharWidths(L, FLinePos-1);
|
||||
CharWidths := FLines.GetPhysicalCharWidths(Pchar(L), length(L), FLinePos-1);
|
||||
LogLen := Length(CharWidths);
|
||||
ScreenPos := 1;
|
||||
LogPos := 0;
|
||||
|
||||
@ -58,6 +58,8 @@ type
|
||||
);
|
||||
|
||||
TPhysicalCharWidths = Array of Shortint;
|
||||
TPhysicalCharWidth = ShortInt;
|
||||
PPhysicalCharWidth = ^TPhysicalCharWidth;
|
||||
|
||||
TSynEditUndoList = class;
|
||||
TSynEditUndoItem = class;
|
||||
@ -163,6 +165,8 @@ type
|
||||
|
||||
procedure SetUpdateState(Updating: Boolean); override;
|
||||
procedure SetUpdateState(Updating: Boolean; Sender: TObject); virtual; abstract;
|
||||
|
||||
procedure DoGetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer; PWidths: PPhysicalCharWidth); virtual; abstract;
|
||||
public
|
||||
constructor Create;
|
||||
procedure BeginUpdate(Sender: TObject); overload;
|
||||
@ -198,7 +202,7 @@ type
|
||||
procedure FlushNotificationCache; virtual; abstract;
|
||||
public
|
||||
function GetPhysicalCharWidths(Index: Integer): TPhysicalCharWidths;
|
||||
function GetPhysicalCharWidths(const Line: String; Index: Integer): TPhysicalCharWidths; virtual; abstract;
|
||||
function GetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer): TPhysicalCharWidths;
|
||||
// Byte to Char
|
||||
function LogicalToPhysicalPos(const p: TPoint): TPoint;
|
||||
function LogicalToPhysicalCol(const Line: String;
|
||||
@ -263,6 +267,7 @@ type
|
||||
procedure PutObject(Index: integer; AObject: TObject); override;
|
||||
|
||||
procedure SetUpdateState(Updating: Boolean; Sender: TObject); override;
|
||||
procedure DoGetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer; PWidths: PPhysicalCharWidth); override;
|
||||
public
|
||||
constructor Create(ASynStringSource: TSynEditStrings);
|
||||
|
||||
@ -287,7 +292,7 @@ type
|
||||
ASender: TObject); override;
|
||||
procedure FlushNotificationCache; override;
|
||||
|
||||
function GetPhysicalCharWidths(const Line: String; Index: Integer): TPhysicalCharWidths; override;
|
||||
//function GetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer): TPhysicalCharWidths; override;
|
||||
property NextLines: TSynEditStrings read fSynStrings write fSynStrings;
|
||||
public
|
||||
// LogX, LogY are 1-based
|
||||
@ -489,8 +494,20 @@ begin
|
||||
end;
|
||||
|
||||
function TSynEditStrings.GetPhysicalCharWidths(Index: Integer): TPhysicalCharWidths;
|
||||
var
|
||||
s: string;
|
||||
begin
|
||||
Result := GetPhysicalCharWidths(Strings[Index], Index);
|
||||
s := Strings[Index];
|
||||
Result := GetPhysicalCharWidths(PChar(s), length(s), Index);
|
||||
end;
|
||||
|
||||
function TSynEditStrings.GetPhysicalCharWidths(Line: PChar; LineLen,
|
||||
Index: Integer): TPhysicalCharWidths;
|
||||
begin
|
||||
SetLength(Result, LineLen);
|
||||
if LineLen = 0 then
|
||||
exit;
|
||||
DoGetPhysicalCharWidths(Line, LineLen, Index, @Result[0]);
|
||||
end;
|
||||
|
||||
function TSynEditStrings.GetIsUtf8 : Boolean;
|
||||
@ -571,7 +588,7 @@ var
|
||||
i, ByteLen: integer;
|
||||
CharWidths: TPhysicalCharWidths;
|
||||
begin
|
||||
CharWidths := GetPhysicalCharWidths(Line, Index);
|
||||
CharWidths := GetPhysicalCharWidths(Pchar(Line), length(Line), Index);
|
||||
ByteLen := length(Line);
|
||||
dec(LogicalPos);
|
||||
|
||||
@ -600,7 +617,7 @@ var
|
||||
ScreenPos: integer;
|
||||
CharWidths: TPhysicalCharWidths;
|
||||
begin
|
||||
CharWidths := GetPhysicalCharWidths(Line, Index);
|
||||
CharWidths := GetPhysicalCharWidths(PChar(Line), length(Line), Index);
|
||||
ByteLen := Length(Line);
|
||||
ScreenPos := 1;
|
||||
BytePos := 0;
|
||||
@ -775,10 +792,10 @@ begin
|
||||
fSynStrings.PutObject(Index, AObject);
|
||||
end;
|
||||
|
||||
function TSynEditStringsLinked.GetPhysicalCharWidths(const Line: String; Index: Integer): TPhysicalCharWidths;
|
||||
begin
|
||||
Result := fSynStrings.GetPhysicalCharWidths(Line, Index);
|
||||
end;
|
||||
//function TSynEditStringsLinked.GetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer): TPhysicalCharWidths;
|
||||
//begin
|
||||
// Result := fSynStrings.GetPhysicalCharWidths(Line, LineLen, Index);
|
||||
//end;
|
||||
|
||||
procedure TSynEditStringsLinked.SetUpdateState(Updating: Boolean; Sender: TObject);
|
||||
begin
|
||||
@ -789,6 +806,12 @@ begin
|
||||
fSynStrings.EndUpdate(Sender);
|
||||
end;
|
||||
|
||||
procedure TSynEditStringsLinked.DoGetPhysicalCharWidths(Line: PChar;
|
||||
LineLen, Index: Integer; PWidths: PPhysicalCharWidth);
|
||||
begin
|
||||
fSynStrings.DoGetPhysicalCharWidths(Line, LineLen, Index, PWidths);
|
||||
end;
|
||||
|
||||
procedure TSynEditStringsLinked.EditInsert(LogX, LogY: Integer; AText: String);
|
||||
begin
|
||||
fSynStrings.EditInsert(LogX, LogY, AText);
|
||||
|
||||
@ -166,6 +166,7 @@ type
|
||||
|
||||
procedure UndoEditLinesDelete(LogY, ACount: Integer);
|
||||
procedure IncreaseTextChangeStamp;
|
||||
procedure DoGetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer; PWidths: PPhysicalCharWidth); override;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
@ -188,9 +189,7 @@ type
|
||||
aBytePos: Integer = -1; aLen: Integer = 0; aTxt: String = ''); override;
|
||||
procedure SendNotification(AReason: TSynEditNotifyReason;
|
||||
ASender: TObject); override;
|
||||
procedure FlushNotificationCache; override;
|
||||
function GetPhysicalCharWidths(const Line: String; Index: Integer): TPhysicalCharWidths; override;
|
||||
// For Textbuffersharing
|
||||
procedure FlushNotificationCache; override;
|
||||
procedure AttachSynEdit(AEdit: TSynEditBase);
|
||||
procedure DetachSynEdit(AEdit: TSynEditBase);
|
||||
function AttachedSynEditCount: Integer;
|
||||
@ -700,24 +699,27 @@ end;
|
||||
|
||||
// Maps the Physical Width (ScreenCells) to each character
|
||||
// Multibyte Chars have thw width on the first byte, and a 0 Width for all other bytes
|
||||
function TSynEditStringList.GetPhysicalCharWidths(const Line: String; Index: Integer): TPhysicalCharWidths;
|
||||
procedure TSynEditStringList.DoGetPhysicalCharWidths(Line: PChar;
|
||||
LineLen, Index: Integer; PWidths: PPhysicalCharWidth);
|
||||
var
|
||||
i, j: Integer;
|
||||
p: PChar;
|
||||
begin
|
||||
SetLength(Result, Length(Line));
|
||||
if not IsUtf8 then begin
|
||||
for i := 0 to LineLen-1 do
|
||||
PWidths[i] := 1;
|
||||
exit;
|
||||
end;
|
||||
j := 0;
|
||||
p := PChar(line);
|
||||
for i := 0 to length(Line)-1 do begin
|
||||
for i := 0 to LineLen-1 do begin
|
||||
if j > 0 then begin
|
||||
Result[i] := 0;
|
||||
PWidths^ := 0;
|
||||
dec(j);
|
||||
end else begin
|
||||
Result[i] := 1;
|
||||
if IsUtf8 then
|
||||
j := UTF8CharacterLength(p) - 1;
|
||||
PWidths^ := 1;
|
||||
j := UTF8CharacterLength(Line) - 1;
|
||||
end;
|
||||
inc(p);
|
||||
inc(Line);
|
||||
inc(PWidths);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
@ -40,8 +40,8 @@ type
|
||||
{ SynEditTextDoubleWidthChars }
|
||||
|
||||
SynEditStringDoubleWidthChars = class(TSynEditStringsLinked)
|
||||
public
|
||||
function GetPhysicalCharWidths(const Line: String; Index: Integer): TPhysicalCharWidths; override;
|
||||
protected
|
||||
procedure DoGetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer; PWidths: PPhysicalCharWidth); override;
|
||||
end;
|
||||
|
||||
|
||||
@ -49,114 +49,116 @@ implementation
|
||||
|
||||
{ SynEditTextDoubleWidthChars }
|
||||
|
||||
function SynEditStringDoubleWidthChars.GetPhysicalCharWidths(const Line: String; Index: Integer): TPhysicalCharWidths;
|
||||
procedure SynEditStringDoubleWidthChars.DoGetPhysicalCharWidths(Line: PChar;
|
||||
LineLen, Index: Integer; PWidths: PPhysicalCharWidth);
|
||||
var
|
||||
i: Integer;
|
||||
p: PChar;
|
||||
begin
|
||||
Result := inherited GetPhysicalCharWidths(Line, Index);
|
||||
inherited DoGetPhysicalCharWidths(Line, LineLen, Index, PWidths);
|
||||
if not IsUtf8 then
|
||||
exit;
|
||||
|
||||
p := Pchar(Line)-1;
|
||||
for i := 0 to length(Line) -1 do begin
|
||||
inc(p);
|
||||
if Result[i] = 0 then continue;
|
||||
case p[0] of
|
||||
dec(Line);
|
||||
dec(PWidths);
|
||||
for i := 0 to LineLen - 1 do begin
|
||||
inc(Line);
|
||||
inc(PWidths);
|
||||
if PWidths^ = 0 then continue;
|
||||
case Line[0] of
|
||||
#$e1:
|
||||
case p[1] of
|
||||
case Line[1] of
|
||||
#$84:
|
||||
if (p[2] >= #$80) then Result[i] := 2;
|
||||
if (Line[2] >= #$80) then PWidths^ := 2;
|
||||
#$85:
|
||||
if (p[2] <= #$9f) then Result[i] := 2;
|
||||
if (Line[2] <= #$9f) then PWidths^ := 2;
|
||||
end;
|
||||
#$e2:
|
||||
case p[1] of
|
||||
case Line[1] of
|
||||
#$8c:
|
||||
if (p[2] = #$a9) or (p[2] = #$aa) then Result[i] := 2;
|
||||
if (Line[2] = #$a9) or (Line[2] = #$aa) then PWidths^ := 2;
|
||||
#$ba:
|
||||
if (p[2] >= #$80) then Result[i] := 2;
|
||||
if (Line[2] >= #$80) then PWidths^ := 2;
|
||||
#$bb..#$ff:
|
||||
Result[i] := 2;
|
||||
PWidths^ := 2;
|
||||
end;
|
||||
#$e3:
|
||||
case p[1] of
|
||||
case Line[1] of
|
||||
#$81:
|
||||
if (p[2] >= #$81) then Result[i] := 2;
|
||||
if (Line[2] >= #$81) then PWidths^ := 2;
|
||||
#$82..#$8e:
|
||||
Result[i] := 2;
|
||||
PWidths^ := 2;
|
||||
#$8f:
|
||||
if (p[2] <= #$bf) then Result[i] := 2;
|
||||
if (Line[2] <= #$bf) then PWidths^ := 2;
|
||||
#$90:
|
||||
if (p[2] >= #$80) then Result[i] := 2;
|
||||
if (Line[2] >= #$80) then PWidths^ := 2;
|
||||
#$91..#$FF:
|
||||
Result[i] := 2;
|
||||
PWidths^ := 2;
|
||||
end;
|
||||
#$e4:
|
||||
case p[1] of
|
||||
case Line[1] of
|
||||
#$00..#$b5:
|
||||
Result[i] := 2;
|
||||
PWidths^ := 2;
|
||||
#$b6:
|
||||
if (p[2] <= #$b5) then Result[i] := 2;
|
||||
if (Line[2] <= #$b5) then PWidths^ := 2;
|
||||
#$b8:
|
||||
if (p[2] >= #$80) then Result[i] := 2;
|
||||
if (Line[2] >= #$80) then PWidths^ := 2;
|
||||
#$b9..#$ff:
|
||||
Result[i] := 2;
|
||||
PWidths^ := 2;
|
||||
end;
|
||||
#$e5..#$e8:
|
||||
Result[i] := 2;
|
||||
PWidths^ := 2;
|
||||
#$e9:
|
||||
if (p[1] <= #$bf) or (p[2] <= #$83) then Result[i] := 2;
|
||||
if (Line[1] <= #$bf) or (Line[2] <= #$83) then PWidths^ := 2;
|
||||
#$ea:
|
||||
case p[1] of
|
||||
case Line[1] of
|
||||
#$80, #$b0:
|
||||
if (p[2] >= #$80) then Result[i] := 2;
|
||||
if (Line[2] >= #$80) then PWidths^ := 2;
|
||||
#$81..#$92, #$b1..#$ff:
|
||||
Result[i] := 2;
|
||||
PWidths^ := 2;
|
||||
#$93:
|
||||
if (p[2] <= #$86) then Result[i] := 2;
|
||||
if (Line[2] <= #$86) then PWidths^ := 2;
|
||||
end;
|
||||
#$eb..#$ec:
|
||||
Result[i] := 2;
|
||||
PWidths^ := 2;
|
||||
#$ed:
|
||||
if (p[1] <= #$9e) or (p[2] <= #$a3) then Result[i] := 2;
|
||||
if (Line[1] <= #$9e) or (Line[2] <= #$a3) then PWidths^ := 2;
|
||||
|
||||
#$ef:
|
||||
case p[1] of
|
||||
case Line[1] of
|
||||
#$a4:
|
||||
if (p[2] >= #$80) then Result[i] := 2;
|
||||
if (Line[2] >= #$80) then PWidths^ := 2;
|
||||
#$a5..#$aa:
|
||||
Result[i] := 2;
|
||||
PWidths^ := 2;
|
||||
#$ab:
|
||||
if (p[2] <= #$99) then Result[i] := 2;
|
||||
if (Line[2] <= #$99) then PWidths^ := 2;
|
||||
#$b8:
|
||||
if (p[2] in [#$90..#$99,#$b0..#$ff]) then Result[i] := 2;
|
||||
if (Line[2] in [#$90..#$99,#$b0..#$ff]) then PWidths^ := 2;
|
||||
#$b9:
|
||||
if (p[2] <= #$ab) then Result[i] := 2;
|
||||
if (Line[2] <= #$ab) then PWidths^ := 2;
|
||||
#$bc:
|
||||
if (p[2] >= #$81) then Result[i] := 2;
|
||||
if (Line[2] >= #$81) then PWidths^ := 2;
|
||||
#$bd:
|
||||
if (p[2] <= #$a0) then Result[i] := 2;
|
||||
if (Line[2] <= #$a0) then PWidths^ := 2;
|
||||
#$bf:
|
||||
if (p[2] >= #$a0) and (p[2] <= #$a6) then Result[i] := 2;
|
||||
if (Line[2] >= #$a0) and (Line[2] <= #$a6) then PWidths^ := 2;
|
||||
end;
|
||||
#$f0:
|
||||
case p[1] of
|
||||
case Line[1] of
|
||||
#$a0, #$b0:
|
||||
case p[2] of
|
||||
case Line[2] of
|
||||
#$80:
|
||||
if (p[3] >= #$80) then Result[i] := 2;
|
||||
if (Line[3] >= #$80) then PWidths^ := 2;
|
||||
#$81..#$ff:
|
||||
Result[i] := 2;
|
||||
PWidths^ := 2;
|
||||
end;
|
||||
#$a1..#$ae, #$b1..#$be:
|
||||
Result[i] := 2;
|
||||
PWidths^ := 2;
|
||||
#$af, #$bf:
|
||||
case p[2] of
|
||||
case Line[2] of
|
||||
#$00..#$be:
|
||||
Result[i] := 2;
|
||||
PWidths^ := 2;
|
||||
#$bf:
|
||||
if (p[3] <= #$bd) then Result[i] := 2;
|
||||
if (Line[3] <= #$bd) then PWidths^ := 2;
|
||||
end;
|
||||
end
|
||||
end;
|
||||
|
||||
@ -26,8 +26,7 @@ unit SynEditTextTabExpander;
|
||||
interface
|
||||
|
||||
uses
|
||||
LCLProc,
|
||||
Classes, SysUtils, SynEditTextBase;
|
||||
LCLProc, Classes, SysUtils, SynEditTextBase;
|
||||
|
||||
type
|
||||
|
||||
@ -67,10 +66,10 @@ type
|
||||
procedure SetTabWidth(const AValue : integer);
|
||||
function GetExpandedString(Index: integer): string; override;
|
||||
function GetLengthOfLongestLine: integer; override;
|
||||
procedure DoGetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer; PWidths: PPhysicalCharWidth); override;
|
||||
public
|
||||
constructor Create(ASynStringSource: TSynEditStrings);
|
||||
destructor Destroy; override;
|
||||
function GetPhysicalCharWidths(const Line: String; Index: Integer): TPhysicalCharWidths; override;
|
||||
|
||||
property LengthOfLongestLine: integer read GetLengthOfLongestLine;
|
||||
public
|
||||
@ -228,7 +227,7 @@ begin
|
||||
// xxx wrong double width // none latin ...
|
||||
//FTabData[Index] := length(Result) + NO_TAB_IN_LINE_OFFSET;
|
||||
end else begin
|
||||
CharWidths := GetPhysicalCharWidths(Line, Index);
|
||||
CharWidths := GetPhysicalCharWidths(Pchar(Line), length(Line), Index);
|
||||
l := 0;
|
||||
for i := 0 to length(CharWidths)-1 do
|
||||
l := l + CharWidths[i];
|
||||
@ -261,7 +260,9 @@ begin
|
||||
Result := 0;
|
||||
FTabData[Index] := Result + NO_TAB_IN_LINE_OFFSET;
|
||||
end else begin
|
||||
CharWidths := GetPhysicalCharWidths(Line, Index);
|
||||
i := length(Line);
|
||||
SetLength(CharWidths, i);
|
||||
DoGetPhysicalCharWidths(Pchar(Line), i, Index, @CharWidths[0]);
|
||||
Result := 0;
|
||||
for i := 0 to length(CharWidths)-1 do
|
||||
Result := Result + CharWidths[i];
|
||||
@ -284,32 +285,35 @@ begin
|
||||
Result := '';
|
||||
end;
|
||||
|
||||
function TSynEditStringTabExpander.GetPhysicalCharWidths(const Line: String;
|
||||
Index: Integer): TPhysicalCharWidths;
|
||||
procedure TSynEditStringTabExpander.DoGetPhysicalCharWidths(Line: PChar;
|
||||
LineLen, Index: Integer; PWidths: PPhysicalCharWidth);
|
||||
var
|
||||
p: PChar;
|
||||
HasTab: Boolean;
|
||||
i, j: Integer;
|
||||
begin
|
||||
Result := inherited GetPhysicalCharWidths(Line, Index);
|
||||
inherited DoGetPhysicalCharWidths(Line, LineLen, Index, PWidths);
|
||||
HasTab := False;
|
||||
p := PChar(Line);
|
||||
j := 0;
|
||||
for i := 0 to length(Line) -1 do begin
|
||||
if Result[i] <> 0 then begin
|
||||
if p^ = #9 then begin
|
||||
Result[i] := FTabWidth - (j mod FTabWidth);
|
||||
for i := 0 to LineLen - 1 do begin
|
||||
if PWidths^ <> 0 then begin
|
||||
if Line^ = #9 then begin
|
||||
PWidths^ := FTabWidth - (j mod FTabWidth);
|
||||
HasTab := True;
|
||||
end;
|
||||
j := j + Result[i];
|
||||
j := j + PWidths^;
|
||||
end;
|
||||
inc(p);
|
||||
inc(Line);
|
||||
inc(PWidths);
|
||||
end;
|
||||
FLastLineHasTab := HasTab;
|
||||
end;
|
||||
|
||||
function TSynEditStringTabExpander.GetLengthOfLongestLine: integer;
|
||||
var
|
||||
Line: String;
|
||||
CharWidths: TPhysicalCharWidths;
|
||||
n, m: Integer;
|
||||
//var
|
||||
i, j: integer;
|
||||
begin
|
||||
if (fIndexOfLongestLine >= 0) and (fIndexOfLongestLine < Count) then begin
|
||||
@ -319,10 +323,32 @@ begin
|
||||
end;
|
||||
|
||||
Result := 0;
|
||||
m := 0;
|
||||
for i := 0 to Count - 1 do begin
|
||||
j := FTabData[i];
|
||||
if j = LINE_LEN_UNKNOWN then
|
||||
j := ExpandedStringLength(i)
|
||||
if j = LINE_LEN_UNKNOWN then begin
|
||||
// embedd a copy of ExpandedStringLength
|
||||
// allows to re-use CharWidths
|
||||
Line := fSynStrings[i];
|
||||
j := 0;
|
||||
if (Line = '') then begin
|
||||
FTabData[i] := j + NO_TAB_IN_LINE_OFFSET;
|
||||
end else begin
|
||||
n := length(Line);
|
||||
if n > m then begin
|
||||
SetLength(CharWidths, n);
|
||||
m := n;
|
||||
end;
|
||||
DoGetPhysicalCharWidths(Pchar(Line), n, i, @CharWidths[0]);
|
||||
for m := 0 to n-1 do
|
||||
j := j + CharWidths[m];
|
||||
|
||||
if FLastLineHasTab then // FLastLineHasTab is set by GetPhysicalCharWidths
|
||||
FTabData[i] := j
|
||||
else
|
||||
FTabData[i] := j + NO_TAB_IN_LINE_OFFSET;
|
||||
end;
|
||||
end
|
||||
else
|
||||
if j >= NO_TAB_IN_LINE_OFFSET then
|
||||
j := j - NO_TAB_IN_LINE_OFFSET;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user