Fix scroll rendering artifacts by removing ScrollDC

ScrollDC shifted buffer pixels during parsing before dirty rows were
rendered, causing unrendered garbage to propagate into non-dirty rows
on successive scrolls. Replace with FAllDirty to repaint all rows from
cell data after any scroll. With batched TextOut this costs ~250 GDI
calls per scroll instead of the old 12,000, so the overhead is minimal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Duensing 2026-02-26 21:18:15 -06:00
parent ca99d1d21b
commit a96dbb3faa

View file

@ -101,7 +101,6 @@ type
procedure RecalcCellSize; procedure RecalcCellSize;
procedure RedrawBuffers; procedure RedrawBuffers;
procedure ResizeScreen; procedure ResizeScreen;
procedure ScrollBufs(N: Integer);
procedure SetCols(Value: Integer); procedure SetCols(Value: Integer);
procedure SetCursorVisible(Value: Boolean); procedure SetCursorVisible(Value: Boolean);
procedure SetRows(Value: Integer); procedure SetRows(Value: Integer);
@ -761,24 +760,6 @@ begin
end; end;
procedure TKPAnsi.ScrollBufs(N: Integer);
var
R: TRect;
I: Integer;
ScrollY: Integer;
begin
if FBufDC[0] = 0 then
Exit;
ScrollY := N * FCellHeight;
R.Left := 0;
R.Top := 0;
R.Right := FBufW;
R.Bottom := FBufH;
for I := 0 to 1 do
ScrollDC(FBufDC[I], 0, -ScrollY, R, R, 0, nil);
end;
procedure TKPAnsi.DeleteChars(N: Integer); procedure TKPAnsi.DeleteChars(N: Integer);
var var
Line: PTermLine; Line: PTermLine;
@ -864,8 +845,7 @@ begin
GetMem(Line, SizeOf(TTermLineRec)); GetMem(Line, SizeOf(TTermLineRec));
AllocLine(Line); AllocLine(Line);
FScreen.Insert(0, Line); FScreen.Insert(0, Line);
ScrollBufs(-1); FAllDirty := True;
FDirtyRow[0] := True;
end; end;
@ -885,8 +865,7 @@ begin
AllocLine(Line); AllocLine(Line);
FScreen.Add(Line); FScreen.Add(Line);
UpdateScrollbar; UpdateScrollbar;
ScrollBufs(1); FAllDirty := True;
FDirtyRow[FRows - 1] := True;
end; end;