-
Notifications
You must be signed in to change notification settings - Fork 189
Use OS#Polygon in GC#drawRectangleInPixels #2874
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Use OS#Polygon in GC#drawRectangleInPixels #2874
Conversation
This commit replaces OS#Rectangle with OS#Polygon in drawRectangleInPixels since, the behaviour of Rectangle doesn't comply with the documentation in https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-rectangle for win32
|
I think there's a fundamental misunderstanding here. The consumers are not doing anything wrong - they're correctly using the API as designed. The issue isn't about subtracting "one pixel" but rather about properly accounting for the stroke/border width, which could be any value (1pt, 5pt, etc.). The Correct ModelWhen drawing a rectangle with a border/stroke, the standard graphics model works as follows: For a drawing area of 100x100 points with a stroke width of 1pt:
Scaling ConsiderationsWith a 175% scaling factor, the transformation should be:
The rounding here is where complexity arises:
The Real IssueThe problem isn't that consumers are using the API incorrectly. The issue is that SWT needs to handle the fractional coordinate transformations and stroke width scaling consistently across different DPI settings. This includes:
Rather than changing how consumers use the API, SWT should internally handle these transformations to maintain consistent behavior across all DPI settings. |
Also, In this snippet's case, the lineWidth is set to 0.0. When I set it to 1, half the pixel grows outwards each side and when I set it to 2, then 1 pixel grows outwards and 1 inwards. In any case, any idea why there is a +1 in this call? |

This PR addresses the following issue: vi-eclipse/Eclipse-Platform#555
To analyse the problem, consider a zoom factor of 175%.
Context
Before the introduction of
ImageGcDrawer, SWT created all images at 100% zoom and scaled them afterwards. Since scaling happened post-drawing, the image data preserved the expected geometry and visual alignment, even when consumers used two slightly different conventions (widthvswidth - 1).After
ImageGcDrawerwas added, SWT now creates the image at the target zoom directly, rather than scaling from 100%. This produces sharper results but exposes a long-standing behavioural mismatch in how rectangles are drawn.Root Cause
GC.drawRectangledelegates to OS.Rectangle, whose Win32 documentation states:The supplied right/bottom coordinates represent the limits of the interior; the bottom/right border pixels are excluded.Example: drawing (0, 0, 210, 210) produces:
However, the actual behaviour differs.
Passing
(0,0,210,210)results in:The total painted width becomes 210 px, contrary to the documentation.
This discrepancy was masked before because the rectangle was drawn at 100% and later scaled. But now that we draw directly at scaled resolutions:
gc.drawRectangle(x, y, width - 1, height - 1);intending to compensate for border thickness.
(-1)becomes incorrect, because it represents points, not pixels. For example:(120 - 1) * 1.75 = 208.25, truncated to 208, causing visible shifts.Observation Snippet
With this snippet, if you run it on master, you'll see the outline is inside the filled red rectangle. This happens because when we do
(120 - 1) * 1.75, we get approximately 208 and thenGC#drawRectangleappliesx + width + 1leading to 209. According to theOS.Rectangledocumentation it should add a right border after 209 making it overall 210 px wide — but it does not. HenceOS.Rectangleis not behaving as documented in this context and we have the right and the bottom border a pixel extra inside.Proposed Fix
Since a rectangle is also a polygon, use OS.Polygon by calling
GCdrawPolygoninstead ofOS.Rectangle. The polygon approach aligns with the intended semantics and produces the correct visual result under zoom.Notes and Limitations
This is a workaround rather than a perfect solution: consumers are still commonly calling the API with
width - 1(which is incorrect for logical/point coordinates) instead of width.The polygon workaround improves behaviour for the observed cases (e.g., 175% zoom) but may not be perfect at very high zoom levels (e.g., 350%).
A full, robust fix would require adjusting consumers to pass the correct values (i.e., use width/height as logical sizes) or otherwise revisiting the API semantics.