-
Notifications
You must be signed in to change notification settings - Fork 190
Fix GC#drawImage + 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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1183,15 +1183,6 @@ void apply() { | |
| drawImage(getImage(), source.x, source.y, source.width, source.height, destination.x, destination.y, destination.width, destination.height, gcZoom, srcImageZoom); | ||
| } | ||
|
|
||
| private Collection<Integer> getAllCurrentMonitorZooms() { | ||
| if (device instanceof Display display) { | ||
| return Arrays.stream(display.getMonitors()) | ||
| .map(Monitor::getZoom) | ||
| .collect(Collectors.toSet()); | ||
| } | ||
| return Collections.emptySet(); | ||
| } | ||
|
|
||
| private int calculateZoomForImage(int gcZoom, int srcWidth, int srcHeight, int destWidth, int destHeight) { | ||
| if (srcWidth == 1 && srcHeight == 1) { | ||
| // One pixel images can use the GC zoom | ||
|
|
@@ -1207,13 +1198,7 @@ private int calculateZoomForImage(int gcZoom, int srcWidth, int srcHeight, int d | |
|
|
||
| float imageScaleFactor = 1f * destWidth / srcWidth; | ||
| int imageZoom = Math.round(gcZoom * imageScaleFactor); | ||
| if (getAllCurrentMonitorZooms().contains(imageZoom)) { | ||
| return imageZoom; | ||
| } | ||
| if (imageZoom > 150) { | ||
| return 200; | ||
| } | ||
| return 100; | ||
| return imageZoom; | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -1243,6 +1228,7 @@ private void drawImage(Image image, int destX, int destY, int destWidth, int des | |
|
|
||
| private void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHeight, int destX, int destY, | ||
| int destWidth, int destHeight, int imageZoom, int scaledImageZoom) { | ||
|
|
||
| Rectangle src = Win32DPIUtils.pointToPixel(drawable, new Rectangle(srcX, srcY, srcWidth, srcHeight), scaledImageZoom); | ||
| Rectangle dest = Win32DPIUtils.pointToPixel(drawable, new Rectangle(destX, destY, destWidth, destHeight), imageZoom); | ||
| if (scaledImageZoom != 100) { | ||
|
|
@@ -1262,7 +1248,31 @@ private void drawImage(Image image, int srcX, int srcY, int srcWidth, int srcHei | |
| } | ||
| } | ||
| } | ||
| drawImage(image, src.x, src.y, src.width, src.height, dest.x, dest.y, dest.width, dest.height, false, image.getHandle(scaledImageZoom, data.nativeZoom)); | ||
| Rectangle fullImageBounds = image.getBounds(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can see |
||
| Rectangle targetSrc = Win32DPIUtils.pointToPixel(drawable, fullImageBounds, scaledImageZoom); | ||
| Rectangle startSrc = new Rectangle(srcX, srcY, srcWidth, srcHeight); | ||
| image.executeOnImageHandleAtBestFittingSizeAtZoom((tempHandle) -> { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO it is better to have an additional override for |
||
| Rectangle src1 = computeSourceRectangle(tempHandle, fullImageBounds, targetSrc, startSrc, src); | ||
| drawImage(image, src1.x, src1.y, src1.width, src1.height, dest.x, dest.y, dest.width, | ||
| dest.height, false, tempHandle); | ||
| }, scaledImageZoom); | ||
|
|
||
| } | ||
|
|
||
| private Rectangle computeSourceRectangle(ImageHandle imageHandle, Rectangle fullImageBounds, Rectangle targetSrc, Rectangle startSrc, Rectangle srcPart) { | ||
| if (new Rectangle(0, 0, imageHandle.getWidth(), imageHandle.getHeight()).equals(targetSrc)) { | ||
| return srcPart; | ||
| } else { | ||
| /* | ||
| * the achieved handle with its drawings has not the required size, thus we calculate the zoom of the handle | ||
| * | ||
| * with respect to the full 100% image. The point values (x,y,width,height) of the source "part" of the full image will | ||
| * be computed to pixels by this zoom. | ||
| */ | ||
| float scaleFactor = 1f * imageHandle.getWidth() / fullImageBounds.width; | ||
| int closestZoomOfHandle = Math.round(scaleFactor * 100); | ||
| return Win32DPIUtils.pointToPixel(drawable, startSrc, closestZoomOfHandle); | ||
| } | ||
| } | ||
|
|
||
| private class DrawImageToImageOperation extends ImageOperation { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -179,6 +179,17 @@ private Optional<ImageHandle> createHandleAtExactSize(int width, int height) { | |
| return Optional.empty(); | ||
| } | ||
|
|
||
| public ImageHandle getOrCreateImageHandleAtClosestSizeAtZoom(int scaledZoom) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shouldnt this be private |
||
| scaledZoom = DPIUtil.getZoomForAutoscaleProperty(scaledZoom); | ||
| ImageHandle bestFittingHandle = zoomLevelToImageHandle.get(scaledZoom); | ||
| if (bestFittingHandle == null) { | ||
| ImageData bestFittingImageData = imageProvider.loadImageData(scaledZoom).element(); | ||
| ImageData adaptedData = adaptImageDataIfDisabledOrGray(bestFittingImageData); | ||
| bestFittingHandle = init(adaptedData, -1); | ||
| } | ||
| return bestFittingHandle; | ||
| } | ||
|
|
||
| private ImageHandle getOrCreateImageHandleAtClosestSize(int widthHint, int heightHint) { | ||
| Rectangle bounds = getBounds(100); | ||
| int imageZoomForWidth = 100 * widthHint / bounds.width; | ||
|
|
@@ -880,6 +891,15 @@ void executeOnImageHandleAtBestFittingSize(Consumer<ImageHandle> handleAtSizeCon | |
| handleAtSizeConsumer.accept(imageHandle); | ||
| } | ||
|
|
||
| void executeOnImageHandleAtBestFittingSizeAtZoom(Consumer<ImageHandle> handleAtSizeConsumer, int scaledZoom) { | ||
| ImageHandle imageHandle = lastRequestedHandle.getOrCreateImageHandleAtClosestSizeAtZoom(scaledZoom); | ||
| handleAtSizeConsumer.accept(imageHandle); | ||
| } | ||
| void executeOnImageHandleAtSizeOrZoom(BiConsumer<ImageHandle, Point> handleAtSizeConsumer, int targetWidth, int targetHeight, int zoom) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this used anywhere? |
||
| ImageHandle imageHandle = lastRequestedHandle.getOrCreateImageHandleAtClosestSizeAtZoom(zoom); | ||
| handleAtSizeConsumer.accept(imageHandle, new Point(imageHandle.getWidth(), imageHandle.getHeight())); | ||
| } | ||
|
|
||
| /** | ||
| * <b>IMPORTANT:</b> This method is not part of the public | ||
| * API for Image. It is marked public only so that 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.