SynEdit: Markup and more paint-token-breaker for future bidi support

git-svn-id: trunk@38996 -
This commit is contained in:
martin 2012-10-08 11:16:06 +00:00
parent b8dc7e13eb
commit 3bb19f7f9a
13 changed files with 147 additions and 84 deletions

View File

@ -50,7 +50,7 @@ type
FCurTxtLineIdx : Integer; FCurTxtLineIdx : Integer;
FCurViewToken: TLazSynDisplayTokenInfoEx; FCurViewToken: TLazSynDisplayTokenInfoEx;
FCurViewTokenViewPhysStart: Integer; FCurViewTokenViewPhysStart: TLazSynDisplayTokenBound;
FCurViewinRTL: Boolean; FCurViewinRTL: Boolean;
FCurViewRtlPhysStart: integer; FCurViewRtlPhysStart: integer;
FCurViewRtlPhysEnd: integer; FCurViewRtlPhysEnd: integer;
@ -377,8 +377,8 @@ begin
FCurMarkupNextRtlInfo := ATokenInfo.NextRtlInfo; FCurMarkupNextRtlInfo := ATokenInfo.NextRtlInfo;
FMarkupTokenAttr.Assign(ATokenInfo.Attr); FMarkupTokenAttr.Assign(ATokenInfo.Attr);
FMarkupTokenAttr.CurrentStartX := ATokenInfo.StartPos.Physical; // current sub-token FMarkupTokenAttr.CurrentStartX := ATokenInfo.StartPos; // current sub-token
FMarkupTokenAttr.CurrentEndX := ATokenInfo.EndPos.Physical-1; FMarkupTokenAttr.CurrentEndX := ATokenInfo.EndPos;
end; end;
fMarkupManager.MergeMarkupAttributeAtRowCol(FCurTxtLineIdx + 1, fMarkupManager.MergeMarkupAttributeAtRowCol(FCurTxtLineIdx + 1,
@ -402,8 +402,10 @@ end;
function TLazSynPaintTokenBreaker.GetNextHighlighterTokenFromView(out function TLazSynPaintTokenBreaker.GetNextHighlighterTokenFromView(out
ATokenInfo: TLazSynDisplayTokenInfoEx; APhysEnd: Integer; ALogEnd: Integer): Boolean; ATokenInfo: TLazSynDisplayTokenInfoEx; APhysEnd: Integer; ALogEnd: Integer): Boolean;
procedure InitSynAttr(var ATarget: TSynSelectedColor; ASource: TSynHighlighterAttributes; procedure InitSynAttr(var ATarget: TSynSelectedColor; const ASource: TSynHighlighterAttributes;
AnAttrStartX: Integer); const AnAttrStartX: TLazSynDisplayTokenBound);
const
NoEnd: TLazSynDisplayTokenBound = (Physical: -1; Logical: -1; Offset: 0);
begin begin
ATarget.Clear; ATarget.Clear;
if Assigned(ASource) then begin if Assigned(ASource) then begin
@ -420,15 +422,15 @@ function TLazSynPaintTokenBreaker.GetNextHighlighterTokenFromView(out
end; end;
ATarget.MergeFinalStyle := True; ATarget.MergeFinalStyle := True;
ATarget.StyleMask := []; ATarget.StyleMask := [];
FCurViewToken.Attr.StartX := AnAttrStartX; ATarget.StartX := AnAttrStartX;
ATarget.EndX := -1; //PhysicalStartPos + TokenCharLen - 1; ATarget.EndX := NoEnd;
end; end;
function MaybeFetchToken: Boolean; inline; function MaybeFetchToken: Boolean; inline;
begin begin
Result := FCurViewToken.Tk.TokenLength > 0; Result := FCurViewToken.Tk.TokenLength > 0;
if Result or (FCurViewToken.Tk.TokenLength < 0) then exit; if Result or (FCurViewToken.Tk.TokenLength < 0) then exit;
FCurViewTokenViewPhysStart := FCurViewToken.PhysicalCharStart; FCurViewTokenViewPhysStart := FCurViewToken.StartPos;
while FCurViewToken.Tk.TokenLength = 0 do begin // Todo: is SyncroEd-test a zero size token is returned while FCurViewToken.Tk.TokenLength = 0 do begin // Todo: is SyncroEd-test a zero size token is returned
Result := FDisplayView.GetNextHighlighterToken(FCurViewToken.Tk); Result := FDisplayView.GetNextHighlighterToken(FCurViewToken.Tk);
if not Result then begin if not Result then begin
@ -723,7 +725,7 @@ begin
InitSynAttr(FCurViewToken.Attr, FCurViewToken.Tk.TokenAttr, FCurViewTokenViewPhysStart); InitSynAttr(FCurViewToken.Attr, FCurViewToken.Tk.TokenAttr, FCurViewTokenViewPhysStart);
if FCurViewToken.Tk.TokenLength = 0 then if FCurViewToken.Tk.TokenLength = 0 then
ATokenInfo.Attr.EndX := PhysPos-1; ATokenInfo.Attr.EndX := ATokenInfo.EndPos; // PhysPos-1;
MaybeFetchToken; MaybeFetchToken;
if MaybeChangeToRtl(LogicIdx, LogicEnd) then begin // get NextTokenPhysStart if MaybeChangeToRtl(LogicIdx, LogicEnd) then begin // get NextTokenPhysStart
@ -841,7 +843,7 @@ begin
InitSynAttr(FCurViewToken.Attr, FCurViewToken.Tk.TokenAttr, FCurViewTokenViewPhysStart); InitSynAttr(FCurViewToken.Attr, FCurViewToken.Tk.TokenAttr, FCurViewTokenViewPhysStart);
if FCurViewToken.Tk.TokenLength = 0 then if FCurViewToken.Tk.TokenLength = 0 then
ATokenInfo.Attr.EndX := PhysPos-1; ATokenInfo.Attr.EndX := ATokenInfo.EndPos; // PhysPos-1;
MaybeFetchToken; MaybeFetchToken;
SkipRtlOffScreen(LogicIdx, LogicEnd); SkipRtlOffScreen(LogicIdx, LogicEnd);

View File

@ -30,12 +30,6 @@ uses
SynEditMiscClasses, Controls, SynEditHighlighter, LCLProc; SynEditMiscClasses, Controls, SynEditHighlighter, LCLProc;
type type
TLazSynDisplayTokenBound = record
Physical: Integer; // 1 based - May be in middle of char
Logical: Integer; // 1 based
Offset: Integer; // default 0. MultiWidth (e.g. Tab), if token starts in the middle of char
end;
TLazSynDisplayRtlInfo = record TLazSynDisplayRtlInfo = record
IsRtl: Boolean; IsRtl: Boolean;
PhysLeft: integer; // 1-based PhysLeft: integer; // 1-based
@ -392,7 +386,7 @@ var
begin begin
c := GetMarkupAttributeAtRowCol(aRow, aStartCol, AnRtlInfo); c := GetMarkupAttributeAtRowCol(aRow, aStartCol, AnRtlInfo);
if assigned(c) then if assigned(c) then
AMarkup.Merge(c, aStartCol.Physical, AEndCol.Physical - 1); AMarkup.Merge(c, aStartCol, AEndCol);
end; end;
procedure TSynEditMarkup.TextChanged(aFirstCodeLine, aLastCodeLine: Integer); procedure TSynEditMarkup.TextChanged(aFirstCodeLine, aLastCodeLine: Integer);

View File

@ -234,8 +234,7 @@ begin
or ((FBracketHighlightAntiPos.y = aRow) and (FBracketHighlightAntiPos.x = aStartCol.Logical)) or ((FBracketHighlightAntiPos.y = aRow) and (FBracketHighlightAntiPos.x = aStartCol.Logical))
then begin then begin
Result := MarkupInfo; Result := MarkupInfo;
MarkupInfo.StartX := aStartCol.Logical; MarkupInfo.SetFrameBoundsLog(aStartCol.Logical, aStartCol.Logical + 1); // bracket is alvays 1 byte
MarkupInfo.EndX := aStartCol.Logical;
end; end;
end; end;

View File

@ -237,8 +237,7 @@ begin
if (aRow = FCtrlMouseLine) and FCtrlLinkable then begin if (aRow = FCtrlMouseLine) and FCtrlLinkable then begin
FCurX1 := LogicalToPhysicalPos(Point(FCtrlMouseX1, FCtrlMouseLine)).x; FCurX1 := LogicalToPhysicalPos(Point(FCtrlMouseX1, FCtrlMouseLine)).x;
FCurX2 := LogicalToPhysicalPos(Point(FCtrlMouseX2, FCtrlMouseLine)).x; FCurX2 := LogicalToPhysicalPos(Point(FCtrlMouseX2, FCtrlMouseLine)).x;
MarkupInfo.StartX := FCurX1; MarkupInfo.SetFrameBoundsPhys(FCurX1, FCurX2);
MarkupInfo.EndX := FCurX2;
end; end;
end; end;
@ -250,8 +249,7 @@ begin
((aStartCol.Physical < FCurX1) or (aStartCol.Physical >= FCurX2)) ((aStartCol.Physical < FCurX1) or (aStartCol.Physical >= FCurX2))
then exit; then exit;
Result := MarkupInfo; Result := MarkupInfo;
MarkupInfo.StartX := FCurX1; MarkupInfo.SetFrameBoundsPhys(FCurX1, FCurX2);
MarkupInfo.EndX := FCurX2;
end; end;
procedure TSynEditMarkupCtrlMouseLink.GetNextMarkupColAfterRowCol(const aRow: Integer; procedure TSynEditMarkupCtrlMouseLink.GetNextMarkupColAfterRowCol(const aRow: Integer;

View File

@ -138,8 +138,7 @@ begin
( (FRowData[i].Priority < FoundPri) or (i = 0) ) ( (FRowData[i].Priority < FoundPri) or (i = 0) )
then begin then begin
Result := FRowData[i].Markup; Result := FRowData[i].Markup;
Result.StartX := FRowData[i].StartX; MarkupInfo.SetFrameBoundsPhys(FRowData[i].StartX, FRowData[i].EndX);
Result.EndX := FRowData[i].EndX-1;
FoundPri := FRowData[i].Priority; FoundPri := FRowData[i].Priority;
end; end;
end; end;

View File

@ -480,7 +480,7 @@ end;
function TSynEditMarkupHighlightAll.GetMarkupAttributeAtRowCol(const aRow: Integer; function TSynEditMarkupHighlightAll.GetMarkupAttributeAtRowCol(const aRow: Integer;
const aStartCol: TLazSynDisplayTokenBound; const AnRtlInfo: TLazSynDisplayRtlInfo): TSynSelectedColor; const aStartCol: TLazSynDisplayTokenBound; const AnRtlInfo: TLazSynDisplayRtlInfo): TSynSelectedColor;
var var
Pos: Integer; Pos, s, e: Integer;
begin begin
result := nil; result := nil;
if (fSearchString = '') then if (fSearchString = '') then
@ -502,13 +502,14 @@ begin
//debugLN('+++>MARUP *ON* ',dbgs(@result),' / ',dbgs(ARow), ' at index ', dbgs(Pos)); //debugLN('+++>MARUP *ON* ',dbgs(@result),' / ',dbgs(ARow), ' at index ', dbgs(Pos));
if fMatches.Point[Pos-1].y < aRow then if fMatches.Point[Pos-1].y < aRow then
MarkupInfo.StartX := -1 s := -1
else else
MarkupInfo.StartX := fMatches.Point[Pos-1].x; s := fMatches.Point[Pos-1].x;
if fMatches.Point[Pos].y > aRow then if fMatches.Point[Pos].y > aRow then
MarkupInfo.EndX := -1 e := -1
else else
MarkupInfo.EndX := fMatches.Point[Pos].x-1; e := fMatches.Point[Pos].x;
MarkupInfo.SetFrameBoundsPhys(s, e);
result := MarkupInfo; result := MarkupInfo;
end; end;

View File

@ -138,8 +138,7 @@ begin
end; end;
end; end;
end; end;
MarkupInfo.StartX := nSelStart; MarkupInfo.SetFrameBoundsPhys(nSelStart, nSelEnd);
MarkupInfo.EndX := nSelEnd-1;
end; end;
function TSynEditMarkupSelection.GetMarkupAttributeAtRowCol(const aRow: Integer; function TSynEditMarkupSelection.GetMarkupAttributeAtRowCol(const aRow: Integer;

View File

@ -114,8 +114,7 @@ begin
if (aStartCol.Physical >= FCurStart) and (aStartCol.Physical < FCurEnd) then begin if (aStartCol.Physical >= FCurStart) and (aStartCol.Physical < FCurEnd) then begin
Result := MarkupInfo; Result := MarkupInfo;
Result.StartX := FCurStart; MarkupInfo.SetFrameBoundsPhys(FCurStart, FCurEnd);
Result.EndX := FCurEnd - 1;
end; end;
end; end;

View File

@ -180,8 +180,7 @@ function TSynEditMarkupSpecialLine.GetMarkupAttributeAtRowCol(const aRow: Intege
const aStartCol: TLazSynDisplayTokenBound; const AnRtlInfo: TLazSynDisplayRtlInfo): TSynSelectedColor; const aStartCol: TLazSynDisplayTokenBound; const AnRtlInfo: TLazSynDisplayRtlInfo): TSynSelectedColor;
begin begin
Result := nil; Result := nil;
MarkupInfo.StartX := 1; MarkupInfo.SetFrameBoundsPhys(1, MaxInt);
MarkupInfo.EndX := MaxInt;
if FSpecialLine then if FSpecialLine then
Result := MarkupInfo; Result := MarkupInfo;
end; end;

View File

@ -400,24 +400,21 @@ begin
(aStartCol.Physical >= FHighlightPos1.x) and (aStartCol.Physical < FHighlightPos1.X2) then (aStartCol.Physical >= FHighlightPos1.x) and (aStartCol.Physical < FHighlightPos1.X2) then
begin begin
Result := MarkupInfo; Result := MarkupInfo;
MarkupInfo.StartX := FHighlightPos1.x; MarkupInfo.SetFrameBoundsPhys(FHighlightPos1.x, FHighlightPos1.x2);
MarkupInfo.EndX := FHighlightPos1.X2 - 1;
end end
else else
if (FHighlightPos3.y = aRow) and if (FHighlightPos3.y = aRow) and
(aStartCol.Physical >= FHighlightPos3.x) and (aStartCol.Physical < FHighlightPos3.X2) then (aStartCol.Physical >= FHighlightPos3.x) and (aStartCol.Physical < FHighlightPos3.X2) then
begin begin
Result := MarkupInfo; Result := MarkupInfo;
MarkupInfo.StartX := FHighlightPos3.x; MarkupInfo.SetFrameBoundsPhys(FHighlightPos3.x, FHighlightPos3.x2);
MarkupInfo.EndX := FHighlightPos3.X2 - 1;
end end
else else
if (FHighlightPos2.y = aRow) and if (FHighlightPos2.y = aRow) and
(aStartCol.Physical >= FHighlightPos2.x) and (aStartCol.Physical < FHighlightPos2.X2) then (aStartCol.Physical >= FHighlightPos2.x) and (aStartCol.Physical < FHighlightPos2.X2) then
begin begin
Result := MarkupInfo; Result := MarkupInfo;
MarkupInfo.StartX := FHighlightPos2.x; MarkupInfo.SetFrameBoundsPhys(FHighlightPos2.x, FHighlightPos2.x2);
MarkupInfo.EndX := FHighlightPos2.X2 - 1;
end; end;
end; end;

View File

@ -201,15 +201,21 @@ type
TSynObjectListItemClass = class of TSynObjectListItem; TSynObjectListItemClass = class of TSynObjectListItem;
TLazSynDisplayTokenBound = record
Physical: Integer; // 1 based - May be in middle of char
Logical: Integer; // 1 based
Offset: Integer; // default 0. MultiWidth (e.g. Tab), if token starts in the middle of char
end;
{ TSynSelectedColor } { TSynSelectedColor }
TSynSelectedColor = class(TLazSynCustomTextAttributes) TSynSelectedColor = class(TLazSynCustomTextAttributes)
private private
FCurrentEndX: Integer; FCurrentStartX: TLazSynDisplayTokenBound;
FCurrentStartX: Integer; FCurrentEndX: TLazSynDisplayTokenBound;
FOnChange: TNotifyEvent; FOnChange: TNotifyEvent;
// 0 or -1 start/end before/after line // 1 first char // 0 or -1 start/end before/after line // 1 first char
FStartX, FEndX: Integer; FStartX, FEndX: TLazSynDisplayTokenBound;
FFrameSidesInitialized: Boolean; FFrameSidesInitialized: Boolean;
FFrameSideColors: array[TLazSynBorderSide] of TColor; FFrameSideColors: array[TLazSynBorderSide] of TColor;
FFrameSideStyles: array[TLazSynBorderSide] of TSynLineStyle; FFrameSideStyles: array[TLazSynBorderSide] of TSynLineStyle;
@ -219,6 +225,7 @@ type
function GetFrameSideOrigin(Side: TLazSynBorderSide): TSynFrameEdges; function GetFrameSideOrigin(Side: TLazSynBorderSide): TSynFrameEdges;
function GetFrameSidePriority(Side: TLazSynBorderSide): integer; function GetFrameSidePriority(Side: TLazSynBorderSide): integer;
function GetFrameSideStyles(Side: TLazSynBorderSide): TSynLineStyle; function GetFrameSideStyles(Side: TLazSynBorderSide): TSynLineStyle;
function IsMatching(ABound1, ABound2: TLazSynDisplayTokenBound): Boolean;
protected protected
procedure DoChange; override; procedure DoChange; override;
procedure AssignFrom(Src: TLazSynCustomTextAttributes); override; procedure AssignFrom(Src: TLazSynCustomTextAttributes); override;
@ -229,14 +236,18 @@ type
// but PaintLines creates an instance that contains an actual style (without mask) // but PaintLines creates an instance that contains an actual style (without mask)
// Todo: always start with actual style // Todo: always start with actual style
MergeFinalStyle: Boolean; MergeFinalStyle: Boolean;
procedure Merge(Other: TSynSelectedColor; LeftCol, RightCol: Integer); deprecated; procedure Merge(Other: TSynSelectedColor; LeftCol, RightCol: TLazSynDisplayTokenBound); deprecated;
procedure MergeFrames(Other: TSynSelectedColor; LeftCol, RightCol: Integer); deprecated; procedure MergeFrames(Other: TSynSelectedColor; LeftCol, RightCol: TLazSynDisplayTokenBound); deprecated;
property FrameSideColors[Side: TLazSynBorderSide]: TColor read GetFrameSideColors; property FrameSideColors[Side: TLazSynBorderSide]: TColor read GetFrameSideColors;
property FrameSideStyles[Side: TLazSynBorderSide]: TSynLineStyle read GetFrameSideStyles; property FrameSideStyles[Side: TLazSynBorderSide]: TSynLineStyle read GetFrameSideStyles;
property StartX: Integer read FStartX write FStartX; // boundaries of the frame
property EndX: Integer read FEndX write FEndX; procedure SetFrameBoundsPhys(AStart, AEnd: Integer);
property CurrentStartX: Integer read FCurrentStartX write FCurrentStartX; procedure SetFrameBoundsLog(AStart, AEnd: Integer; AStartOffs: Integer = 0; AEndOffs: Integer = 0);
property CurrentEndX: Integer read FCurrentEndX write FCurrentEndX; property StartX: TLazSynDisplayTokenBound read FStartX write FStartX;
property EndX: TLazSynDisplayTokenBound read FEndX write FEndX;
// boundaries for current paint
property CurrentStartX: TLazSynDisplayTokenBound read FCurrentStartX write FCurrentStartX;
property CurrentEndX: TLazSynDisplayTokenBound read FCurrentEndX write FCurrentEndX;
public public
constructor Create; constructor Create;
procedure Clear; override; procedure Clear; override;
@ -599,6 +610,7 @@ end;
constructor TSynSelectedColor.Create; constructor TSynSelectedColor.Create;
begin begin
inherited Create; inherited Create;
Clear;
MergeFinalStyle := False; MergeFinalStyle := False;
Background := clHighLight; Background := clHighLight;
Foreground := clHighLightText; Foreground := clHighLightText;
@ -632,8 +644,8 @@ begin
else else
if (Side in SynFrameEdgeToSides[FrameEdges]) and ( if (Side in SynFrameEdgeToSides[FrameEdges]) and (
(Side in [bsTop, bsBottom]) or (Side in [bsTop, bsBottom]) or
( (Side = bsLeft) and (FCurrentStartX = FStartX) ) or ( (Side = bsLeft) and IsMatching(FCurrentStartX, FStartX) ) or
( (Side = bsRight) and (FCurrentEndX = FEndX) ) ( (Side = bsRight) and IsMatching(FCurrentEndX, FEndX) )
) )
then Result := FrameColor then Result := FrameColor
else Result := clNone; else Result := clNone;
@ -655,8 +667,8 @@ begin
else else
if (Side in SynFrameEdgeToSides[FrameEdges]) and ( if (Side in SynFrameEdgeToSides[FrameEdges]) and (
(Side in [bsTop, bsBottom]) or (Side in [bsTop, bsBottom]) or
( (Side = bsLeft) and (FCurrentStartX = FStartX) ) or ( (Side = bsLeft) and IsMatching(FCurrentStartX, FStartX) ) or
( (Side = bsRight) and (FCurrentEndX = FEndX) ) ( (Side = bsRight) and IsMatching(FCurrentEndX, FEndX) )
) )
then Result := FramePriority then Result := FramePriority
else Result := 0; else Result := 0;
@ -672,6 +684,16 @@ begin
else Result := slsSolid; else Result := slsSolid;
end; end;
function TSynSelectedColor.IsMatching(ABound1, ABound2: TLazSynDisplayTokenBound): Boolean;
begin
Result := ( (ABound1.Physical > 0) and
(ABound1.Physical = ABound2.Physical)
) or
( (ABound1.Logical > 0) and
(ABound1.Logical = ABound2.Logical) and (ABound1.Offset = ABound2.Offset)
);
end;
procedure TSynSelectedColor.DoChange; procedure TSynSelectedColor.DoChange;
begin begin
if Assigned(FOnChange) then if Assigned(FOnChange) then
@ -700,7 +722,8 @@ begin
Changed; {TODO: only if really changed} Changed; {TODO: only if really changed}
end; end;
procedure TSynSelectedColor.Merge(Other: TSynSelectedColor; LeftCol, RightCol: Integer); procedure TSynSelectedColor.Merge(Other: TSynSelectedColor; LeftCol,
RightCol: TLazSynDisplayTokenBound);
var var
sKeep, sSet, sClr, sInv, sInvInv: TFontStyles; sKeep, sSet, sClr, sInv, sInvInv: TFontStyles;
j: TFontStyle; j: TFontStyle;
@ -751,7 +774,8 @@ begin
EndUpdate; EndUpdate;
end; end;
procedure TSynSelectedColor.MergeFrames(Other: TSynSelectedColor; LeftCol, RightCol: Integer); procedure TSynSelectedColor.MergeFrames(Other: TSynSelectedColor; LeftCol,
RightCol: TLazSynDisplayTokenBound);
procedure SetSide(ASide: TLazSynBorderSide; ASrc: TSynSelectedColor); procedure SetSide(ASide: TLazSynBorderSide; ASrc: TSynSelectedColor);
begin begin
@ -767,9 +791,9 @@ procedure TSynSelectedColor.MergeFrames(Other: TSynSelectedColor; LeftCol, Right
FFrameSidePriority[ASide] := ASrc.FramePriority; FFrameSidePriority[ASide] := ASrc.FramePriority;
FFrameSideOrigin[ASide] := ASrc.FrameEdges; FFrameSideOrigin[ASide] := ASrc.FrameEdges;
if ASide = bsLeft then if ASide = bsLeft then
FStartX := ASrc.FStartX; FStartX := LeftCol; // LeftCol has Phys and log ; // ASrc.FStartX;
if ASide = bsRight then if ASide = bsRight then
FEndX := ASrc.FEndX; FEndX := RightCol; // ASrc.FEndX;
end; end;
var var
@ -792,8 +816,8 @@ begin
case Other.FrameEdges of case Other.FrameEdges of
sfeAround: begin sfeAround: begin
// UpdateOnly, frame keeps behind individual sites // UpdateOnly, frame keeps behind individual sites
if (Other.StartX = LeftCol) then SetSide(bsLeft, Other); if IsMatching(Other.StartX, LeftCol) then SetSide(bsLeft, Other);
if (Other.EndX = RightCol) then SetSide(bsRight, Other); if IsMatching(Other.EndX, RightCol) then SetSide(bsRight, Other);
SetSide(bsBottom, Other); SetSide(bsBottom, Other);
SetSide(bsTop, Other); SetSide(bsTop, Other);
//FrameColor := Other.FrameColor; //FrameColor := Other.FrameColor;
@ -810,6 +834,27 @@ begin
end; end;
end; end;
procedure TSynSelectedColor.SetFrameBoundsPhys(AStart, AEnd: Integer);
begin
FStartX.Physical := AStart;
FEndX.Physical := AEnd;
FStartX.Logical := -1;
FEndX.Logical := -1;
FStartX.Offset := 0;
FEndX.Offset := 0;
end;
procedure TSynSelectedColor.SetFrameBoundsLog(AStart, AEnd: Integer; AStartOffs: Integer;
AEndOffs: Integer);
begin
FStartX.Physical := -1;
FEndX.Physical := -1;
FStartX.Logical := AStart;
FEndX.Logical := AEnd;
FStartX.Offset := AStartOffs;
FEndX.Offset := AEndOffs;
end;
procedure TSynSelectedColor.Clear; procedure TSynSelectedColor.Clear;
var var
i: TLazSynBorderSide; i: TLazSynBorderSide;
@ -822,10 +867,18 @@ begin
FFrameSideStyles[i] := slsSolid; FFrameSideStyles[i] := slsSolid;
FFrameSideOrigin[i] := sfeNone; FFrameSideOrigin[i] := sfeNone;
end; end;
FStartX := -1; FStartX.Physical := -1;
FEndX := -1; FEndX.Physical := -1;
FCurrentStartX := -1; FStartX.Logical := -1;
FCurrentEndX := -1; FEndX.Logical := -1;
FStartX.Offset := 0;
FEndX.Offset := 0;
FCurrentStartX.Physical := -1;
FCurrentEndX.Physical := -1;
FCurrentStartX.Logical := -1;
FCurrentEndX.Logical := -1;
FCurrentStartX.Offset := 0;
FCurrentEndX.Offset := 0;
EndUpdate; EndUpdate;
end; end;

View File

@ -530,14 +530,14 @@ end;
function TSynPluginSyncronizedEditMarkup.GetMarkupAttributeAtRowCol(const aRow: Integer; function TSynPluginSyncronizedEditMarkup.GetMarkupAttributeAtRowCol(const aRow: Integer;
const aStartCol: TLazSynDisplayTokenBound; const AnRtlInfo: TLazSynDisplayRtlInfo): TSynSelectedColor; const aStartCol: TLazSynDisplayTokenBound; const AnRtlInfo: TLazSynDisplayRtlInfo): TSynSelectedColor;
var var
i, col: Integer; i: Integer;
s, e: Integer;
begin begin
col := PhysicalToLogicalPos(Point(aStartCol.Physical, aRow)).x;
Result := nil; Result := nil;
for i := FPreparedCellFrom to FPreparedCellTo do begin for i := FPreparedCellFrom to FPreparedCellTo do begin
if ( ((Cells[i].LogStart.y = aRow) and (Cells[i].LogStart.x <= Col)) or if ( ((Cells[i].LogStart.y = aRow) and (Cells[i].LogStart.x <= aStartCol.Logical)) or
(Cells[i].LogStart.y < aRow) ) and (Cells[i].LogStart.y < aRow) ) and
( ((Cells[i].LogEnd.y = aRow) and (Cells[i].LogEnd.x > Col)) or ( ((Cells[i].LogEnd.y = aRow) and (Cells[i].LogEnd.x > aStartCol.Logical)) or
(Cells[i].LogEnd.y > aRow) ) and (Cells[i].LogEnd.y > aRow) ) and
(Cells[i].Group >= 0) // do not't display negative groups (Cells[i].Group >= 0) // do not't display negative groups
then begin then begin
@ -549,12 +549,13 @@ begin
else else
Result := MarkupInfo; Result := MarkupInfo;
Result.StartX := LogicalToPhysicalPos(Cells[i].LogStart).x; s := Cells[i].LogStart.x;
if Cells[i].LogStart.y < aRow then if Cells[i].LogStart.y < aRow then
Result.StartX := -1; s := -1;
Result.EndX := LogicalToPhysicalPos(Cells[i].LogEnd).x - 1; e := Cells[i].LogEnd.x;
if Cells[i].LogEnd.y > aRow then if Cells[i].LogEnd.y > aRow then
Result.EndX := -1; e := -1;
Result.SetFrameBoundsLog(s, e);
break; break;
end; end;
end; end;
@ -564,24 +565,21 @@ procedure TSynPluginSyncronizedEditMarkup.GetNextMarkupColAfterRowCol(const aRow
const aStartCol: TLazSynDisplayTokenBound; const AnRtlInfo: TLazSynDisplayRtlInfo; out ANextPhys, const aStartCol: TLazSynDisplayTokenBound; const AnRtlInfo: TLazSynDisplayRtlInfo; out ANextPhys,
ANextLog: Integer); ANextLog: Integer);
var var
i, col: Integer; i: Integer;
begin begin
col := PhysicalToLogicalPos(Point(aStartCol.Physical, aRow)).x;
ANextLog := -1; ANextLog := -1;
ANextPhys := -1; ANextPhys := -1;
for i := FPreparedCellFrom to FPreparedCellTo do begin for i := FPreparedCellFrom to FPreparedCellTo do begin
if Cells[i].Group < 0 then continue; if Cells[i].Group < 0 then continue;
if (Cells[i].LogStart.y = aRow) and (Cells[i].LogStart.x > Col) and if (Cells[i].LogStart.y = aRow) and (Cells[i].LogStart.x > aStartCol.Logical) and
( (Cells[i].LogStart.x < ANextPhys) or (ANextPhys < 0) ) ( (Cells[i].LogStart.x < ANextLog) or (ANextLog < 0) )
then then
ANextPhys := Cells[i].LogStart.x; ANextLog := Cells[i].LogStart.x;
if (Cells[i].LogEnd.y = aRow) and (Cells[i].LogEnd.x > Col) and if (Cells[i].LogEnd.y = aRow) and (Cells[i].LogEnd.x > aStartCol.Logical) and
( (Cells[i].LogEnd.x < ANextPhys) or (ANextPhys < 0) ) ( (Cells[i].LogEnd.x < ANextLog) or (ANextLog < 0) )
then then
ANextPhys := Cells[i].LogEnd.x; ANextLog := Cells[i].LogEnd.x;
end; end;
if ANextPhys >= 0 then
ANextPhys := LogicalToPhysicalPos(Point(ANextPhys, aRow)).x;
end; end;
procedure TSynPluginSyncronizedEditMarkup.PrepareMarkupForRow(aRow: Integer); procedure TSynPluginSyncronizedEditMarkup.PrepareMarkupForRow(aRow: Integer);

View File

@ -7,7 +7,8 @@ interface
uses uses
Classes, SysUtils, fpcunit, testregistry, TestBase, LazSynTextArea, SynEditTypes, Classes, SysUtils, fpcunit, testregistry, TestBase, LazSynTextArea, SynEditTypes,
SynEditMarkupBracket, SynEdit, SynHighlighterPosition, SynEditMarkup, Graphics, Forms; SynEditMarkupBracket, SynEdit, SynHighlighterPosition, SynEditMarkup, SynEditMiscClasses,
Graphics, Forms;
type type
@ -89,6 +90,7 @@ begin
'ABشس يCD', 'ABشس يCD',
#9'i'#9'12'#9, #9'i'#9'12'#9,
'ي'#9'شس', // 15 'ي'#9'شس', // 15
#9'('#9')',
'' ''
]); ]);
end; end;
@ -727,6 +729,29 @@ type
TestEnd; TestEnd;
{%endregion} {%endregion}
{%region}
SynEdit.Options :=SynEdit.Options + [eoBracketHighlight];
SynEdit.BracketHighlightStyle := sbhsBoth;
SynEdit.BracketMatchColor.Foreground := clMaroon;
SynEdit.BracketMatchColor.FrameColor := clBlack;
SynEdit.BracketMatchColor.FrameEdges := sfeAround;
SynEdit.BracketMatchColor.FrameStyle := slsSolid;
SynEdit.LogicalCaretXY := point(2, 16);
TestStart('Scan full line / hl-token', 16, 1, 10, 16);
TestNext([], b( 1, 1, 0), b( 5, 2, 0), 1, 5, 1, 5, False, #9, clBlack);
AssertEquals(Name + ' #9 No-Frame l', clNone, Token.Attr.FrameSideColors[bsLeft]);
AssertEquals(Name + ' #9 No-Frame r', clNone, Token.Attr.FrameSideColors[bsRight]);
TestNext([], b( 5, 2, 0), b( 6, 3, 0), 5, 6, 5, 6, False, '(', clMaroon);
AssertEquals(Name + ' "(" Frame t', clBlack, Token.Attr.FrameSideColors[bsTop]);
AssertEquals(Name + ' "(" Frame l', clBlack, Token.Attr.FrameSideColors[bsLeft]);
AssertEquals(Name + ' "(" Frame r', clBlack, Token.Attr.FrameSideColors[bsRight]);
TestNext([], b( 6, 3, 0), b( 9, 4, 0), 6, 9, 6, 9, False, #9, clBlack);
{%endregion}
{%endregion} {%endregion}
{%region RTL only } {%region RTL only }