Zooms out by making the source rectangle (srcRect) larger and centering it on (x,y). If we can't make it larger, then make the window smaller. Note that sx and sy are screen coordinates.
(int sx, int sy)
| 970 | then make the window smaller. Note that |
| 971 | sx and sy are screen coordinates. */ |
| 972 | public void zoomOut(int sx, int sy) { |
| 973 | if (magnification<=zoomLevels[0]) |
| 974 | return; |
| 975 | boolean mouseMoved = sqr(sx-lastZoomSX) + sqr(sy-lastZoomSY) > MAX_MOUSEMOVE_ZOOM*MAX_MOUSEMOVE_ZOOM; |
| 976 | lastZoomSX = sx; |
| 977 | lastZoomSY = sy; |
| 978 | if (mouseMoved || zoomTargetOX<0) { |
| 979 | boolean cursorInside = sx >= 0 && sy >= 0 && sx < dstWidth && sy < dstHeight; |
| 980 | zoomTargetOX = offScreenX(cursorInside ? sx : dstWidth/2); //where to zoom, offscreen (image) coordinates |
| 981 | zoomTargetOY = offScreenY(cursorInside ? sy : dstHeight/2); |
| 982 | } |
| 983 | double oldMag = magnification; |
| 984 | double newMag = getLowerZoomLevel(magnification); |
| 985 | double srcRatio = (double)srcRect.width/srcRect.height; |
| 986 | double imageRatio = (double)imageWidth/imageHeight; |
| 987 | double initialMag = imp.getWindow().getInitialMagnification(); |
| 988 | if (Math.abs(srcRatio-imageRatio)>0.05) { |
| 989 | double scale = oldMag/newMag; |
| 990 | int newSrcWidth = (int)Math.round(srcRect.width*scale); |
| 991 | int newSrcHeight = (int)Math.round(srcRect.height*scale); |
| 992 | if (newSrcWidth>imageWidth) newSrcWidth=imageWidth; |
| 993 | if (newSrcHeight>imageHeight) newSrcHeight=imageHeight; |
| 994 | int newSrcX = srcRect.x - (newSrcWidth - srcRect.width)/2; |
| 995 | int newSrcY = srcRect.y - (newSrcHeight - srcRect.height)/2; |
| 996 | if (newSrcX + newSrcWidth > imageWidth) newSrcX = imageWidth - newSrcWidth; |
| 997 | if (newSrcY + newSrcHeight > imageHeight) newSrcY = imageHeight - newSrcHeight; |
| 998 | if (newSrcX<0) newSrcX = 0; |
| 999 | if (newSrcY<0) newSrcY = 0; |
| 1000 | srcRect = new Rectangle(newSrcX, newSrcY, newSrcWidth, newSrcHeight); |
| 1001 | int newDstWidth = (int)(srcRect.width*newMag); |
| 1002 | int newDstHeight = (int)(srcRect.height*newMag); |
| 1003 | setMagnification(newMag); |
| 1004 | setMaxBounds(); |
| 1005 | if (newDstWidth<dstWidth || newDstHeight<dstHeight) { |
| 1006 | setSize(newDstWidth, newDstHeight); |
| 1007 | imp.getWindow().pack(); |
| 1008 | } else |
| 1009 | repaint(); |
| 1010 | return; |
| 1011 | } |
| 1012 | if (imageWidth*newMag>dstWidth) { |
| 1013 | int w = (int)Math.round(dstWidth/newMag); |
| 1014 | if (w*newMag<dstWidth) w++; |
| 1015 | int h = (int)Math.round(dstHeight/newMag); |
| 1016 | if (h*newMag<dstHeight) h++; |
| 1017 | Rectangle r = new Rectangle(zoomTargetOX-w/2, zoomTargetOY-h/2, w, h); |
| 1018 | if (r.x<0) r.x = 0; |
| 1019 | if (r.y<0) r.y = 0; |
| 1020 | if (r.x+w>imageWidth) r.x = imageWidth-w; |
| 1021 | if (r.y+h>imageHeight) r.y = imageHeight-h; |
| 1022 | srcRect = r; |
| 1023 | setMagnification(newMag); |
| 1024 | } else { |
| 1025 | srcRect = new Rectangle(0, 0, imageWidth, imageHeight); |
| 1026 | setSize((int)(imageWidth*newMag), (int)(imageHeight*newMag)); |
| 1027 | setMagnification(newMag); |
| 1028 | imp.getWindow().pack(); |
| 1029 | } |
no test coverage detected