-
Notifications
You must be signed in to change notification settings - Fork 191
Fix GC#drawImage with ImageGcDrawer for Cropping and Scaling #2913
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
Fix GC#drawImage with ImageGcDrawer for Cropping and Scaling #2913
Conversation
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java
Outdated
Show resolved
Hide resolved
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Image.java
Outdated
Show resolved
Hide resolved
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
Outdated
Show resolved
Hide resolved
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
Outdated
Show resolved
Hide resolved
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
Outdated
Show resolved
Hide resolved
53c83c8 to
804f78d
Compare
804f78d to
6ae439d
Compare
|
@arunjose696 i edited the PR such that the Regarding that hack: it seems to me that i does not make sense. The hack is motivated by potential rounding errors, but without further investigation, i assume that passing correct source coordinates/width/height which lie in the space of the full image, the statement |
6ae439d to
35a7cb5
Compare
35a7cb5 to
feed58c
Compare
3aae4a5 to
d70266a
Compare
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
Outdated
Show resolved
Hide resolved
Using the same overload makes sense and has simplified the changes IMO.
Thanks for streamlining it , i have a some concerns in the changes though, and few more comments |
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
Outdated
Show resolved
Hide resolved
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
Outdated
Show resolved
Hide resolved
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
Outdated
Show resolved
Hide resolved
9753a8a to
6399bff
Compare
|
@arunjose696 have you reviewed this already? |
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
Outdated
Show resolved
Hide resolved
6399bff to
411b534
Compare
411b534 to
65fc8f3
Compare
65fc8f3 to
eeadb8c
Compare
arunjose696
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Testing the changes everything looks good to me I tested with cropping pngs and svgs with snippet, this also resolves the issue mentioned.
eeadb8c to
a925bac
Compare
akoch-yatta
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, I did a small adaption by moving up and re-using the src Rectangle to create one less Rectangle. I tested mostly with Snippet389 and the IDE and everything worked as expected.
Although there are now more calculations involved, I did not see an easier way to achieve the same result to use the best quality image handle available in a cropping+scaling scenario
HeikoKlare
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have also tested with Snippet389 (with both raster images at 100% and 200% as well as with SVGs) and found everything to work fine. Still I think the current error calculation is not correct and with that the overall calculation of the srcPixels.
Apart from that, I only have comments regarding code style.
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
Show resolved
Hide resolved
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
Outdated
Show resolved
Hide resolved
| int errX = srcPixels.x + srcPixels.width - fullImageBoundsPixels.width; | ||
| int errY = srcPixels.y + srcPixels.height - fullImageBoundsPixels.height; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we change this calculation? Previously, src was used instead of srcPixels and compared against b, which seems to have been the bounds in pixels. That does not sound correct. Is that the reason for changing it? But since the srcPixels might be different later (depending on what handle we get), this new calculation is not correct either, is it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src was in pixels before, the naming has changed here to differ between both of them.
But this correction should be placed somewhere later, when the actual image handle size is known.
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
Outdated
Show resolved
Hide resolved
a925bac to
b86bf2d
Compare
|
@HeikoKlare I updated the PR and addressed your comments as discussed. I tested it again mostly with the Snippet on different zooms and it still works as expected. As I originally approved this PR, I would ask you to approve it as well, if the changes are fine for you. |
HeikoKlare
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation works perfectly fine and I also think the code is in good shape with coherent responsibilities. I only have two very nitpicky comments left.
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
Outdated
Show resolved
Hide resolved
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/GC.java
Outdated
Show resolved
Hide resolved
b86bf2d to
46fdef3
Compare
4679718 to
e955986
Compare
46fdef3 to
5b098a6
Compare
The GC#drawImage method takes (image, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight) as arguments and crops and scales from the source region to the destination region. Passing an image drawn via ImageGCDrawer led to the following issue: The image handle from the subcall is resolved using the monitor zoom (data.nativeZoom) and the calculated scaledImageZoom (gcZoom * scaleFactor). This handle corresponds to an ImageData initialized at scaledImageZoom, whereas the drawings of the second GC are performed using the monitor zoom, subject to the auto-scale property. This mismatch results in unaligned sizing of drawings. For example, a 200% monitor zoom combined with a scale factor of 0.5 produces a scaledImageZoom of 100%. As a result, the ImageData is initialized at 100%, while drawing occurs at 200%. Furthermore, the calculation of scaledImageZoom uses fallback logic that only allows 100% and 200% as possible outcomes, which is clearly unintended in this context. The fix delegates resolving the correct handle to the Image class by passing the width/height of the full image scaled by the scaledImageZoom. This is a space on where scaled src coordinates/width/height lie. A callback then creates a new handle for the height/width and respects the auto-scale property. If the returned handle matches the full image scaled to the requested scaledImageZoom in width and height, the source region coordinates/width/height are passed directly in pixels at that zoom. Otherwise, the internal zoom factor is derived from the returned handle’s width relative to the full image, and the source region coordinates are converted to pixel values using this internal zoom.
5b098a6 to
7c7f6a2
Compare
The GC#drawImage method takes
(image, srcX, srcY, srcWidth, srcHeight, destX, destY, destWidth, destHeight)
as arguments and crops and scales from the source region to the destination
region.
Passing an image drawn via ImageGCDrawer led to the following issue:
The image handle from the subcall is resolved using the monitor zoom
(data.nativeZoom) and the calculated scaledImageZoom (gcZoom * scaleFactor).
This handle corresponds to an ImageData initialized at scaledImageZoom,
whereas the drawings of the second GC are performed using the monitor zoom,
subject to the auto-scale property.
This mismatch results in unaligned sizing of drawings. For example, a 200%
monitor zoom combined with a scale factor of 0.5 produces a scaledImageZoom of
100%. As a result, the ImageData is initialized at 100%, while drawing occurs
at 200%.
Furthermore, the calculation of scaledImageZoom uses fallback logic that only
allows 100% and 200% as possible outcomes, which is clearly unintended in this
context.
The fix delegates resolving the correct handle to the Image class by passing
the width/height of the full image scaled by the scaledImageZoom. This
is a space on where scaled
srccoordinates/width/height lie. A callbackthen creates a new handle for the height/width and respects the auto-scale property.
If the returned handle matches the full image scaled to the requested
scaledImageZoom in width and height, the source region
coordinates/width/height are passed directly in pixels at that zoom. Otherwise,
the internal zoom factor is derived from the returned handle’s width relative to
the full image, and the source region coordinates are converted to pixel values
using this internal zoom.
Note: Snippet 10 used to demonstrate that method. Although the sizing issue is fixed, the method is replaced by GC#drawImage(destX, destY, destWidth, destHeight) as the use case here is only scaling and not cropping. Currently, a new snippet is in progress which will be developed to address the cropping + scaling scenario (see #2912 as a first version without drawings via the ImageGcDrawer).