Skip to content

Fixed issue #1074: PaintTree with poUnbuffered misplaces nodes under a mapping mode - #1384

Open
TetzkatLipHoka wants to merge 1 commit into
JAM-Software:masterfrom
TetzkatLipHoka:fix/issue-1074-mapmode
Open

Fixed issue #1074: PaintTree with poUnbuffered misplaces nodes under a mapping mode#1384
TetzkatLipHoka wants to merge 1 commit into
JAM-Software:masterfrom
TetzkatLipHoka:fix/issue-1074-mapmode

Conversation

@TetzkatLipHoka

Copy link
Copy Markdown
Contributor

Fixes #1074.

Cause

SetCanvasOrigin() in VirtualTrees.Utils.pas transformed its shift through LPtoDP before passing it to SetWindowOrgEx:

// The shifting is expected in physical points, so we have to transform them accordingly.
P := Point(X, Y);
LPtoDP(Canvas.Handle, P, 1);
SetWindowOrgEx(Canvas.Handle, P.X, P.Y, nil);

SetWindowOrgEx however expects logical units — the same units the tree calculates with. On a canvas with a mapping mode (the issue uses MM_ANISOTROPIC with a 2x viewport) the shift therefore got scaled twice, so the unbuffered paint path drew every node at twice its offset: node contents, tree lines, buttons and grid lines all drift apart, exactly as shown in the issue's screenshot. With the default MM_TEXT mapping LPtoDP is the identity, which is why the ordinary paint paths never showed the problem.

Fix

Pass the shift to SetWindowOrgEx untransformed.

Verification (all measured offscreen via pixel analysis)

  • With a 2x MM_ANISOTROPIC mapping, the unbuffered rendering now places all grid lines and tree lines pixel-identical to the buffered rendering, and exactly at twice the unmapped positions.
  • The MM_TEXT rendering is byte-identical to the one before the fix — no change for normal painting.
  • TBaseVirtualTree.Print is unaffected: it renders into an unmapped bitmap and scales via StretchBlt.
  • New regression test Tests/VTPaintTreeIssue1074Tests.pas asserts both properties (unbuffered = buffered under mapping, mapped = 2x unmapped); without the fix both assertions fail. Full suite: no new failures (the two TestCopyHTML failures also occur on unmodified master).

🤖 Generated with Claude Code

…nodes under a mapping mode

SetCanvasOrigin() transformed its shift through LPtoDP before passing
it to SetWindowOrgEx. SetWindowOrgEx however expects logical units -
the same units the tree calculates with - so on a canvas with a
mapping mode (the issue uses MM_ANISOTROPIC with a 2x viewport) the
shift was scaled twice and every node was drawn at twice its offset:
node contents, tree lines, buttons and grid lines all drifted apart,
exactly as shown in the issue. With the default MM_TEXT mapping the
transformation was a no-op, which is why the ordinary paint paths
never showed the problem.

Pass the shift to SetWindowOrgEx untransformed.

Measured offscreen (2x MM_ANISOTROPIC): after the fix the unbuffered
rendering places all grid lines and tree lines pixel-identical to the
buffered rendering, and exactly at twice the unmapped positions; the
MM_TEXT rendering is byte-identical to the one before the fix. New
regression test Tests/VTPaintTreeIssue1074Tests.pas asserts both
properties; without the fix both assertions fail. Test suite: 2
pre-existing failures (TestCopyHTML1/2, also failing on unmodified
master), no new failures.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

problem with painting nodes PaintTree with poUnbuffered in options and setMapMode...

1 participant