From 6c2cd439b755e54201b455dbeb39f18a5f02412b Mon Sep 17 00:00:00 2001 From: Martin Date: Mon, 3 Feb 2025 12:01:31 +0100 Subject: [PATCH] SynEdit: DisplayView, return PhysXPos of first token, paint wrapped sub-lines with correct Phys-X (not Viewed-X) for Markup --- components/synedit/lazsynedittext.pas | 6 +- components/synedit/lazsyntextarea.pp | 92 ++++++++++++---------- components/synedit/syneditfoldedview.pp | 6 +- components/synedit/synedittextbuffer.pp | 5 +- components/synedit/synedittexttrimmer.pas | 6 +- components/synedit/syneditviewedlinemap.pp | 6 +- components/synedit/syneditwrappedview.pp | 15 ++-- components/synedit/test/testwordwrap.pas | 8 +- ide/sourcesyneditor.pas | 6 +- 9 files changed, 81 insertions(+), 69 deletions(-) diff --git a/components/synedit/lazsynedittext.pas b/components/synedit/lazsynedittext.pas index cb17bd67e6..b496433b1a 100644 --- a/components/synedit/lazsynedittext.pas +++ b/components/synedit/lazsynedittext.pas @@ -216,7 +216,7 @@ type property NextView: TLazSynDisplayView read FNextView write FNextView; public procedure InitHighlighterTokens(AHighlighter: TSynCustomHighlighter); virtual; - procedure SetHighlighterTokensLine(ALine: TLineIdx; out ARealLine: TLineIdx; out AStartBytePos, ALineByteLen: Integer); virtual; + procedure SetHighlighterTokensLine(ALine: TLineIdx; out ARealLine: TLineIdx; out AStartBytePos, AStartPhysPos, ALineByteLen: Integer); virtual; procedure FinishHighlighterTokens; virtual; function GetNextHighlighterToken(out ATokenInfo: TLazSynDisplayTokenInfo): Boolean; virtual; function GetLinesCount: Integer; virtual; @@ -637,11 +637,11 @@ begin end; procedure TLazSynDisplayView.SetHighlighterTokensLine(ALine: TLineIdx; out - ARealLine: TLineIdx; out AStartBytePos, ALineByteLen: Integer); + ARealLine: TLineIdx; out AStartBytePos, AStartPhysPos, ALineByteLen: Integer); begin //AStartBytePos := 1; if assigned(FNextView) then - FNextView.SetHighlighterTokensLine(ALine, ARealLine, AStartBytePos, ALineByteLen); + FNextView.SetHighlighterTokensLine(ALine, ARealLine, AStartBytePos, AStartPhysPos, ALineByteLen); end; procedure TLazSynDisplayView.FinishHighlighterTokens; diff --git a/components/synedit/lazsyntextarea.pp b/components/synedit/lazsyntextarea.pp index 078714c64a..abe5dc91bd 100644 --- a/components/synedit/lazsyntextarea.pp +++ b/components/synedit/lazsyntextarea.pp @@ -49,7 +49,8 @@ type FForegroundColor: TColor; FSpaceExtraByteCount: Integer; FTabExtraByteCount: Integer; - FFirstCol, FLastCol: integer; // Physical + FFirstCol, FLastCol: integer; // Physical, Column-range after scroll and/or clip + FVirtualFirstCol, FVirtualLastCol: integer; // Adjusted to simulate range for wrapped sub-line FDisplayView: TLazSynDisplayView; FLinesView: TSynEditStrings; @@ -61,6 +62,7 @@ type FCurTxtLineIdx : Integer; FCurLineByteLen: Integer; FIsLastViewedSubLine: Boolean; + FCurLinePhysStart: integer; // Fields for GetNextHighlighterTokenFromView // Info about the token (from highlighter) @@ -283,8 +285,8 @@ begin end else begin // past eol FCurMarkupNextStart := TmpTokenInfo.StartPos; - FCurMarkupNextStart.Logical := FCurMarkupNextStart.Logical + (FFirstCol - FCurMarkupNextStart.Physical); - FCurMarkupNextStart.Physical := FFirstCol; + FCurMarkupNextStart.Logical := FCurMarkupNextStart.Logical + (FVirtualFirstCol - FCurMarkupNextStart.Physical); + FCurMarkupNextStart.Physical := FVirtualFirstCol; FCurMarkupNextRtlInfo.IsRtl := False; end; end; @@ -313,6 +315,8 @@ begin FMarkupManager := AMarkupManager; FFirstCol := AFirstCol; FLastCol := ALastCol; + FVirtualFirstCol := FFirstCol; + FVirtualLastCol := FLastCol; end; procedure TLazSynPaintTokenBreaker.Finish; @@ -327,7 +331,7 @@ procedure TLazSynPaintTokenBreaker.SetHighlighterTokensLine(ALine: TLineIdx; out var LogLeftPos: Integer; begin - FDisplayView.SetHighlighterTokensLine(ALine, ARealLine, LogLeftPos, FCurLineByteLen); + FDisplayView.SetHighlighterTokensLine(ALine, ARealLine, LogLeftPos, FCurLinePhysStart, FCurLineByteLen); if FLinesView.LogPhysConvertor.CurrentLine = ARealLine then begin if not FCharWidthsFromConverter then begin FCharWidthsFromConverter := True; @@ -348,11 +352,15 @@ begin FCurViewToken.TokenLength := 0; FCurViewScannerPos.Logical := LogLeftPos; - FCurViewScannerPos.Physical := 1; + FCurViewScannerPos.Physical := FCurLinePhysStart; FCurViewScannerPos.Offset := 0; - FCurViewScannerPhysCharPos := 1; + FCurViewScannerPhysCharPos := FCurLinePhysStart; FCurViewinRTL := False; + dec(FCurLinePhysStart); + FVirtualFirstCol := FCurLinePhysStart + FFirstCol; + FVirtualLastCol := FCurLinePhysStart + FLastCol; + FNextMarkupPhysPos := -1; FNextMarkupLogPos := -1; FCurMarkupState := cmPreInit; @@ -414,15 +422,15 @@ begin ATokenInfo.StartPos := FCurMarkupNextStart end else - if FFirstCol > ATokenInfo.StartPos.Physical then begin - ATokenInfo.StartPos.Logical := ATokenInfo.StartPos.Logical + (FFirstCol - ATokenInfo.StartPos.Physical); - ATokenInfo.StartPos.Physical := FFirstCol; + if FVirtualFirstCol > ATokenInfo.StartPos.Physical then begin + ATokenInfo.StartPos.Logical := ATokenInfo.StartPos.Logical + (FVirtualFirstCol - ATokenInfo.StartPos.Physical); + ATokenInfo.StartPos.Physical := FVirtualFirstCol; end; if (FCurMarkupState <> cmPastWrapEnd) then FCurMarkupState := cmPastEOL; - Result := (ATokenInfo.StartPos.Physical < FLastCol); + Result := (ATokenInfo.StartPos.Physical < FVirtualLastCol); if not Result then exit; assert((FNextMarkupPhysPos <= 0) or (FNextMarkupPhysPos > ATokenInfo.StartPos.Physical), 'FNextMarkupPhysPos > ATokenInfo.StartPos.Physical'); @@ -431,8 +439,8 @@ begin ATokenInfo.Tk.TokenLength := 1; if FNextMarkupPhysPos > 0 - then ATokenInfo.EndPos.Physical := Min(FNextMarkupPhysPos, FLastCol) - else ATokenInfo.EndPos.Physical := FLastCol; + then ATokenInfo.EndPos.Physical := Min(FNextMarkupPhysPos, FVirtualLastCol) + else ATokenInfo.EndPos.Physical := FVirtualLastCol; ATokenInfo.EndPos.Offset := 0; ATokenInfo.EndPos.Logical := ATokenInfo.StartPos.Logical + (ATokenInfo.EndPos.Physical - ATokenInfo.StartPos.Physical); @@ -450,10 +458,10 @@ begin end; FCurMarkupNextRtlInfo.IsRtl := False; - ATokenInfo.PhysicalCharStart := ATokenInfo.StartPos.Physical; - ATokenInfo.PhysicalClipStart := ATokenInfo.StartPos.Physical; - ATokenInfo.PhysicalCharEnd := ATokenInfo.EndPos.Physical; - ATokenInfo.PhysicalClipEnd := ATokenInfo.EndPos.Physical; + ATokenInfo.PhysicalCharStart := ATokenInfo.StartPos.Physical - FCurLinePhysStart; + ATokenInfo.PhysicalClipStart := ATokenInfo.StartPos.Physical - FCurLinePhysStart; + ATokenInfo.PhysicalCharEnd := ATokenInfo.EndPos.Physical - FCurLinePhysStart; + ATokenInfo.PhysicalClipEnd := ATokenInfo.EndPos.Physical - FCurLinePhysStart; ATokenInfo.RtlInfo.IsRtl := False; FMarkupTokenAttr.Clear; if ATokenInfo.Attr <> nil then begin @@ -573,14 +581,14 @@ function TLazSynPaintTokenBreaker.GetNextHighlighterTokenFromView(out j: Integer; pcw: TPhysicalCharWidth; begin - if (FCurViewScannerPhysCharPos >= FFirstCol) then + if (FCurViewScannerPhysCharPos >= FVirtualFirstCol) then exit; pcw := GetCharWidthData(ALogicIdx); if (pcw and PCWFlagRTL <> 0) then exit; j := (pcw and PCWMask); - while (ALogicIdx < ALogicEnd) and (FCurViewScannerPhysCharPos + j <= FFirstCol) and + while (ALogicIdx < ALogicEnd) and (FCurViewScannerPhysCharPos + j <= FVirtualFirstCol) and (pcw and PCWFlagRTL = 0) do begin inc(FCurViewScannerPhysCharPos, j); @@ -600,10 +608,10 @@ function TLazSynPaintTokenBreaker.GetNextHighlighterTokenFromView(out if FCurViewScannerPhysCharPos > FCurViewScannerPos.Physical then FCurViewScannerPos.Physical := FCurViewScannerPhysCharPos; - if (FCurViewScannerPos.Physical < FFirstCol) and - (FCurViewScannerPos.Physical + j > FFirstCol) + if (FCurViewScannerPos.Physical < FVirtualFirstCol) and + (FCurViewScannerPos.Physical + j > FVirtualFirstCol) then - FCurViewScannerPos.Physical := FFirstCol; + FCurViewScannerPos.Physical := FVirtualFirstCol; end; procedure SkipRtlOffScreen(var ALogicIdx: integer; ALogicEnd: Integer); inline; @@ -611,8 +619,8 @@ function TLazSynPaintTokenBreaker.GetNextHighlighterTokenFromView(out j: Integer; pcw: TPhysicalCharWidth; begin - if (FCurViewScannerPhysCharPos <= FFirstCol) then begin -// TODO: end, if FCurViewRtlPhysEnd >= FLastCol; + if (FCurViewScannerPhysCharPos <= FVirtualFirstCol) then begin +// TODO: end, if FCurViewRtlPhysEnd >= FVirtualLastCol; if ALogicIdx + FCurViewToken.TokenLength < FCurViewRtlLogEnd then begin if FCurViewToken.TokenLength > 0 then begin ALogicIdx := ALogicIdx + FCurViewToken.TokenLength; @@ -633,14 +641,14 @@ function TLazSynPaintTokenBreaker.GetNextHighlighterTokenFromView(out exit; end; - if (FCurViewScannerPhysCharPos <= FLastCol) then + if (FCurViewScannerPhysCharPos <= FVirtualLastCol) then exit; pcw := GetCharWidthData(ALogicIdx); if (pcw and PCWFlagRTL = 0) then exit; j := (pcw and PCWMask); - while (ALogicIdx < ALogicEnd) and (FCurViewScannerPhysCharPos - j >= FLastCol) and + while (ALogicIdx < ALogicEnd) and (FCurViewScannerPhysCharPos - j >= FVirtualLastCol) and (pcw and PCWFlagRTL <> 0) do begin dec(FCurViewScannerPhysCharPos, j); @@ -657,8 +665,8 @@ function TLazSynPaintTokenBreaker.GetNextHighlighterTokenFromView(out AdjustCurTokenLogStart(ALogicIdx + 1); assert(FCurViewToken.TokenLength >= 0, 'FCurViewToken.TokenLength > 0'); end; - if FCurViewScannerPos.Physical > FLastCol then - FCurViewScannerPos.Physical := FLastCol; + if FCurViewScannerPos.Physical > FVirtualLastCol then + FCurViewScannerPos.Physical := FVirtualLastCol; end; procedure ChangeToRtl(ALogicIdx, ALogicEnd: Integer); @@ -779,9 +787,9 @@ begin continue; if APhysEnd > 0 - then PhysTokenStop := Min(FLastCol, APhysEnd) - else PhysTokenStop := FLastCol; - // TODO: APhysEnd should always allow some data. Compare with FLastCol? Assert for APhysEnd + then PhysTokenStop := Min(FVirtualLastCol, APhysEnd) + else PhysTokenStop := FVirtualLastCol; + // TODO: APhysEnd should always allow some data. Compare with FVirtualLastCol? Assert for APhysEnd Result := PhysTokenStop > FCurViewScannerPos.Physical; if not Result then begin ATokenInfo.StartPos := FCurViewScannerPos; @@ -846,10 +854,10 @@ begin ATokenInfo.EndPos.Physical := Min(PhysPos, PhysTokenStop); ATokenInfo.EndPos.Offset := ATokenInfo.EndPos.Physical - PhysPos; // Zero or Negative. Paint ends before Logical - ATokenInfo.PhysicalCharStart := FCurViewScannerPhysCharPos; - ATokenInfo.PhysicalClipStart := ATokenInfo.StartPos.Physical; - ATokenInfo.PhysicalCharEnd := PhysPos; - ATokenInfo.PhysicalClipEnd := ATokenInfo.EndPos.Physical; + ATokenInfo.PhysicalCharStart := FCurViewScannerPhysCharPos - FCurLinePhysStart; + ATokenInfo.PhysicalClipStart := ATokenInfo.StartPos.Physical - FCurLinePhysStart; + ATokenInfo.PhysicalCharEnd := PhysPos - FCurLinePhysStart; + ATokenInfo.PhysicalClipEnd := ATokenInfo.EndPos.Physical - FCurLinePhysStart; ATokenInfo.RtlInfo.IsRtl := False; //ATokenInfo.RtlInfo.PhysLeft := FCurViewRtlPhysStart; //ATokenInfo.RtlInfo.PhysRight := FCurViewRtlPhysEnd; @@ -912,10 +920,10 @@ begin continue; if APhysEnd >= FCurViewRtlPhysEnd - then PhysTokenStop := FFirstCol - else PhysTokenStop := Max(FFirstCol, APhysEnd); + then PhysTokenStop := FVirtualFirstCol + else PhysTokenStop := Max(FVirtualFirstCol, APhysEnd); // TODO: APhysEnd should always allow some data. Assert for APhysEnd - // FFirstCol must be less PPS. Otherwise it would have gone LTR + // FVirtualFirstCol must be less PPS. Otherwise it would have gone LTR // Result := PhysTokenStop < FCurViewScannerPos.Physical; // if not Result then exit; @@ -979,10 +987,10 @@ begin ATokenInfo.EndPos.Physical := Max(PhysPos, PhysTokenStop); ATokenInfo.EndPos.Offset := PhysPos - ATokenInfo.EndPos.Physical; // <= 0 - ATokenInfo.PhysicalCharStart := PhysPos; - ATokenInfo.PhysicalClipStart := ATokenInfo.EndPos.Physical; - ATokenInfo.PhysicalCharEnd := FCurViewScannerPhysCharPos; - ATokenInfo.PhysicalClipEnd := ATokenInfo.StartPos.Physical; + ATokenInfo.PhysicalCharStart := PhysPos - FCurLinePhysStart; + ATokenInfo.PhysicalClipStart := ATokenInfo.EndPos.Physical - FCurLinePhysStart; + ATokenInfo.PhysicalCharEnd := FCurViewScannerPhysCharPos - FCurLinePhysStart; + ATokenInfo.PhysicalClipEnd := ATokenInfo.StartPos.Physical - FCurLinePhysStart; ATokenInfo.RtlInfo.IsRtl := True; ATokenInfo.RtlInfo.PhysLeft := FCurViewRtlPhysStart; ATokenInfo.RtlInfo.PhysRight := FCurViewRtlPhysEnd; @@ -1000,7 +1008,7 @@ begin assert(ATokenInfo.StartPos.Offset >= 0, 'FCurViewScannerPos.Offset >= 0'); assert(ATokenInfo.EndPos.Offset <= 0, 'FCurViewToken.EndPos.Offset <= 0'); - if (PhysPos < PhysTokenStop) and (PhysTokenStop > FFirstCol) then begin // Last char goes over paint boundary + if (PhysPos < PhysTokenStop) and (PhysTokenStop > FVirtualFirstCol) then begin // Last char goes over paint boundary LogicIdx := PrevLogicIdx; PhysPos := PrevPhysPos; end diff --git a/components/synedit/syneditfoldedview.pp b/components/synedit/syneditfoldedview.pp index e509a6a05f..4940a8bfd6 100644 --- a/components/synedit/syneditfoldedview.pp +++ b/components/synedit/syneditfoldedview.pp @@ -373,7 +373,7 @@ type public constructor Create(AFoldView: TSynEditFoldedView); destructor Destroy; override; - procedure SetHighlighterTokensLine(ALine: TLineIdx; out ARealLine: TLineIdx; out AStartBytePos, ALineByteLen: Integer); override; + procedure SetHighlighterTokensLine(ALine: TLineIdx; out ARealLine: TLineIdx; out AStartBytePos, AStartPhysPos, ALineByteLen: Integer); override; function GetNextHighlighterToken(out ATokenInfo: TLazSynDisplayTokenInfo): Boolean; override; function GetLinesCount: Integer; override; @@ -736,7 +736,7 @@ begin end; procedure TLazSynDisplayFold.SetHighlighterTokensLine(ALine: TLineIdx; out - ARealLine: TLineIdx; out AStartBytePos, ALineByteLen: Integer); + ARealLine: TLineIdx; out AStartBytePos, AStartPhysPos, ALineByteLen: Integer); begin FLineState := 0; CurrentTokenLine := ALine; @@ -753,7 +753,7 @@ begin FFoldView.MarkupInfoHiddenCodeLine.SetFrameBoundsLog(1, MaxInt, 0); end; - inherited SetHighlighterTokensLine(FFoldView.InternViewToTextIndex(ALine), ARealLine, AStartBytePos, ALineByteLen); + inherited SetHighlighterTokensLine(FFoldView.InternViewToTextIndex(ALine), ARealLine, AStartBytePos, AStartPhysPos, ALineByteLen); end; function TLazSynDisplayFold.GetNextHighlighterToken(out ATokenInfo: TLazSynDisplayTokenInfo): Boolean; diff --git a/components/synedit/synedittextbuffer.pp b/components/synedit/synedittextbuffer.pp index 80c7e7f639..28dff81f51 100644 --- a/components/synedit/synedittextbuffer.pp +++ b/components/synedit/synedittextbuffer.pp @@ -126,7 +126,7 @@ type FAtLineStart: Boolean; public constructor Create(ABuffer: TSynEditStringList); - procedure SetHighlighterTokensLine(ALine: TLineIdx; out ARealLine: TLineIdx; out AStartBytePos, ALineByteLen: Integer); override; + procedure SetHighlighterTokensLine(ALine: TLineIdx; out ARealLine: TLineIdx; out AStartBytePos, AStartPhysPos, ALineByteLen: Integer); override; function GetNextHighlighterToken(out ATokenInfo: TLazSynDisplayTokenInfo): Boolean; override; function GetDrawDividerInfo: TSynDividerDrawConfigSetting; override; function GetLinesCount: Integer; override; @@ -386,11 +386,12 @@ begin end; procedure TLazSynDisplayBuffer.SetHighlighterTokensLine(ALine: TLineIdx; out - ARealLine: TLineIdx; out AStartBytePos, ALineByteLen: Integer); + ARealLine: TLineIdx; out AStartBytePos, AStartPhysPos, ALineByteLen: Integer); begin CurrentTokenLine := ALine; ARealLine := ALine; AStartBytePos := 1; + AStartPhysPos := 1; ALineByteLen := Length(FBuffer[ARealLine]); FAtLineStart := True; end; diff --git a/components/synedit/synedittexttrimmer.pas b/components/synedit/synedittexttrimmer.pas index c39cac391e..e9d39477bc 100644 --- a/components/synedit/synedittexttrimmer.pas +++ b/components/synedit/synedittexttrimmer.pas @@ -47,7 +47,7 @@ type public constructor Create(ATrimer: TSynEditStringTrimmingList); procedure FinishHighlighterTokens; override; - procedure SetHighlighterTokensLine(ALine: TLineIdx; out ARealLine: TLineIdx; out AStartBytePos, ALineByteLen: Integer); override; + procedure SetHighlighterTokensLine(ALine: TLineIdx; out ARealLine: TLineIdx; out AStartBytePos, AStartPhysPos, ALineByteLen: Integer); override; function GetNextHighlighterToken(out ATokenInfo: TLazSynDisplayTokenInfo): Boolean; override; end; @@ -321,14 +321,14 @@ begin end; procedure TLazSynDisplayTrim.SetHighlighterTokensLine(ALine: TLineIdx; out - ARealLine: TLineIdx; out AStartBytePos, ALineByteLen: Integer); + ARealLine: TLineIdx; out AStartBytePos, AStartPhysPos, ALineByteLen: Integer); begin CurrentTokenLine := ALine; FAtLineStart := True; if (CurrentTokenHighlighter = nil) and (FTrimer.Spaces(CurrentTokenLine) <> '') then begin ALineByteLen := Length(FTrimer[CurrentTokenLine]); end; - inherited SetHighlighterTokensLine(ALine, ARealLine, AStartBytePos, ALineByteLen); + inherited SetHighlighterTokensLine(ALine, ARealLine, AStartBytePos, AStartPhysPos, ALineByteLen); ALineByteLen := ALineByteLen + length(FTrimer.Spaces(ALine)); end; diff --git a/components/synedit/syneditviewedlinemap.pp b/components/synedit/syneditviewedlinemap.pp index 71206f55a7..64a142aa77 100644 --- a/components/synedit/syneditviewedlinemap.pp +++ b/components/synedit/syneditviewedlinemap.pp @@ -239,7 +239,7 @@ type public constructor Create(AWrappedView: TSynEditLineMappingView); procedure SetHighlighterTokensLine(AWrappedLine: TLineIdx; out - ARealLine: TLineIdx; out AStartBytePos, ALineByteLen: Integer); override; + ARealLine: TLineIdx; out AStartBytePos, AStartPhysPos, ALineByteLen: Integer); override; // function GetNextHighlighterToken(out ATokenInfo: TLazSynDisplayTokenInfo): Boolean; override; procedure FinishHighlighterTokens; override; function TextToViewIndex(ATextIndex: TLineIdx): TLineRange; override; @@ -1289,7 +1289,7 @@ end; procedure TLazSynDisplayLineMapping.SetHighlighterTokensLine( AWrappedLine: TLineIdx; out ARealLine: TLineIdx; out AStartBytePos, - ALineByteLen: Integer); + AStartPhysPos, ALineByteLen: Integer); var RealIdx: IntIdx; begin @@ -1307,7 +1307,7 @@ begin FCurrentWrapSubline := 0; end; - inherited SetHighlighterTokensLine(RealIdx, ARealLine, AStartBytePos, ALineByteLen); + inherited SetHighlighterTokensLine(RealIdx, ARealLine, AStartBytePos, AStartPhysPos, ALineByteLen); end; procedure TLazSynDisplayLineMapping.FinishHighlighterTokens; diff --git a/components/synedit/syneditwrappedview.pp b/components/synedit/syneditwrappedview.pp index 7fdf0b0404..8947603ebe 100644 --- a/components/synedit/syneditwrappedview.pp +++ b/components/synedit/syneditwrappedview.pp @@ -180,14 +180,15 @@ type private FWrapPlugin: TLazSynEditLineWrapPlugin; - FCurSubLineLogStartIdx, FCurSubLineNextLogStartIdx, FCurSubLinePhysStartIdx: Integer; + FCurSubLineLogStartIdx, FCurSubLineNextLogStartIdx: Integer; + FCurSubLinePhysStartIdx, FPrevSubLinePhysWidth: Integer; FCurToken: TLazSynDisplayTokenInfo; FCurLineLogIdx: Integer; public constructor Create(AWrappedView: TSynEditLineMappingView; AWrapPlugin: TLazSynEditLineWrapPlugin); //destructor Destroy; override; procedure SetHighlighterTokensLine(AWrappedLine: TLineIdx; out - ARealLine: TLineIdx; out AStartBytePos, ALineByteLen: Integer); override; + ARealLine: TLineIdx; out AStartBytePos, AStartPhysPos, ALineByteLen: Integer); override; function GetNextHighlighterToken(out ATokenInfo: TLazSynDisplayTokenInfo): Boolean; override; end; @@ -1484,7 +1485,7 @@ end; procedure TLazSynDisplayWordWrap.SetHighlighterTokensLine( AWrappedLine: TLineIdx; out ARealLine: TLineIdx; out AStartBytePos, - ALineByteLen: Integer); + AStartPhysPos, ALineByteLen: Integer); var IsNext: Boolean; PrevSub: IntIdx; @@ -1495,7 +1496,7 @@ begin IsNext := (AWrappedLine = FCurWrappedLine + 1) and (FCurWrappedLine >= 0); PrevSub := FCurrentWrapSubline; - inherited SetHighlighterTokensLine(AWrappedLine, ARealLine, AStartBytePos, ALineByteLen); + inherited SetHighlighterTokensLine(AWrappedLine, ARealLine, AStartBytePos, AStartPhysPos, ALineByteLen); LineTxt := FLineMappingView.NextLines.Strings[ARealLine]; FLineMappingView.LogPhysConvertor.CurrentLine := ARealLine; @@ -1506,13 +1507,15 @@ begin FCurSubLineLogStartIdx := FCurSubLineNextLogStartIdx; FCurSubLineNextLogStartIdx := FWrapPlugin.CalculateNextBreak(PChar(LineTxt), FCurSubLineNextLogStartIdx, MaxW, PWidth, PhysWidth); - FCurSubLinePhysStartIdx := FCurSubLinePhysStartIdx + PhysWidth; + FCurSubLinePhysStartIdx := FCurSubLinePhysStartIdx + FPrevSubLinePhysWidth; + FPrevSubLinePhysWidth := PhysWidth; end else begin FWrapPlugin.GetSublineBounds(LineTxt, MaxW, PWidth, FCurrentWrapSubline, - FCurSubLineLogStartIdx, FCurSubLineNextLogStartIdx, FCurSubLinePhysStartIdx, PhysWidth); + FCurSubLineLogStartIdx, FCurSubLineNextLogStartIdx, FCurSubLinePhysStartIdx, FPrevSubLinePhysWidth); end; AStartBytePos := AStartBytePos + FCurSubLineLogStartIdx; + AStartPhysPos := ToPos(FCurSubLinePhysStartIdx); ALineByteLen := FCurSubLineNextLogStartIdx - FCurSubLineLogStartIdx; FCurLineLogIdx := 0; diff --git a/components/synedit/test/testwordwrap.pas b/components/synedit/test/testwordwrap.pas index 2db8f42f36..42659edf9b 100644 --- a/components/synedit/test/testwordwrap.pas +++ b/components/synedit/test/testwordwrap.pas @@ -1748,13 +1748,13 @@ procedure TTestWordWrapPluginBase.InternalCheckLine(AName: String; NoTrim: Boolean); var gotRealLine: TLineIdx; - gotStartPos, GotLineLen: Integer; + gotStartPos, GotLineLen, gotStartPhys: Integer; gotTokenOk: Boolean; gotToken: TLazSynDisplayTokenInfo; gotText: PChar; s: String; begin - dsp.SetHighlighterTokensLine(ALine, gotRealLine, gotStartPos, GotLineLen); + dsp.SetHighlighterTokensLine(ALine, gotRealLine, gotStartPos, gotStartPhys, GotLineLen); gotTokenOk := dsp.GetNextHighlighterToken(gotToken); if gotTokenOk then gotText := gotToken.TokenStart @@ -1805,7 +1805,7 @@ procedure TTestWordWrapPluginBase.CheckLines(AName: String; var v: TSynEditStringsLinked; dsp: TLazSynDisplayView; - i, gotStartPos, GotLineLen: Integer; + i, gotStartPos, GotLineLen, gotStartPhys: Integer; gotTokenOk: Boolean; gotToken: TLazSynDisplayTokenInfo; s: String; @@ -1822,7 +1822,7 @@ begin dsp.FinishHighlighterTokens; dsp.InitHighlighterTokens(nil); for i := 0 to Length(AExpTextStart)-1 do begin - dsp.SetHighlighterTokensLine(AStartLine+i, gotRealLine, gotStartPos, GotLineLen); + dsp.SetHighlighterTokensLine(AStartLine+i, gotRealLine, gotStartPos, gotStartPhys, GotLineLen); s := ''; while dsp.GetNextHighlighterToken(gotToken) and (gotToken.TokenLength > 0) do s := s + copy(gotToken.TokenStart, 1, gotToken.TokenLength); diff --git a/ide/sourcesyneditor.pas b/ide/sourcesyneditor.pas index 28275527e4..4805dbff2c 100644 --- a/ide/sourcesyneditor.pas +++ b/ide/sourcesyneditor.pas @@ -82,7 +82,7 @@ type procedure SetLineMap(Index: Integer; AValue: Integer); procedure SetLineMapCount(AValue: integer); public - procedure SetHighlighterTokensLine(ALine: TLineIdx; out ARealLine: TLineIdx; out AStartBytePos, ALineByteLen: Integer); override; + procedure SetHighlighterTokensLine(ALine: TLineIdx; out ARealLine: TLineIdx; out AStartBytePos, AStartPhysPos, ALineByteLen: Integer); override; function GetLinesCount: Integer; override; function TextToViewIndex(AIndex: TLineIdx): TLineRange; override; function ViewToTextIndex(AIndex: TLineIdx): TLineIdx; override; @@ -1319,10 +1319,10 @@ begin end; procedure TSourceLazSynTopInfoView.SetHighlighterTokensLine(ALine: TLineIdx; - out ARealLine: TLineIdx; out AStartBytePos, ALineByteLen: Integer); + out ARealLine: TLineIdx; out AStartBytePos, AStartPhysPos, ALineByteLen: Integer); begin CurrentTokenLine := ALine; - inherited SetHighlighterTokensLine(FLineMap[ALine], ARealLine, AStartBytePos, ALineByteLen); + inherited SetHighlighterTokensLine(FLineMap[ALine], ARealLine, AStartBytePos, AStartPhysPos, ALineByteLen); end; function TSourceLazSynTopInfoView.GetLinesCount: Integer;