ScreenViewLayer extends Layer { @Override public void paint(@NotNull Graphics2D graphics2D) { myScreenView.getSize(myScreenViewSize); myScreenViewVisibleRect.setBounds(myScreenView.getX(), myScreenView.getY(), myScreenViewSize.width, myScreenViewSize.height); Rectangle2D clipBounds = graphics2D.getClipBounds(); if (!myScreenViewVisibleRect.intersects(clipBounds)) { return; } if (myScreenViewVisibleRect.width > clipBounds.getWidth() || myScreenViewVisibleRect.height > clipBounds.getHeight()) { Rectangle2D.intersect(myScreenViewVisibleRect, clipBounds, myScreenViewVisibleRect); } BufferedImage previousVisibleImage = myCachedVisibleImage; RenderResult renderResult = myScreenView.getResult(); boolean drawNewImg = false; if (newRenderImageAvailable(renderResult)) { setLastRenderResult(renderResult); myScreenView.getScene().needsRebuildList(); drawNewImg = true; } Graphics2D g = (Graphics2D) graphics2D.create(); BufferedImage cachedVisibleImage = drawNewImg ? null : previousVisibleImage; double currentScale = myScreenView.getScale(); if (drawNewImg || currentScale != myLastScale || !myScreenViewVisibleRect.equals(myCachedScreenViewDisplayRect)) { if (myLastRenderResult != null && myLastRenderResult.hasImage()) { BufferedImage renderedImage = myLastRenderResult.getRenderedImage().getCopy(); if (renderedImage != null) { int resultImageWidth = renderedImage.getWidth(); int resultImageHeight = renderedImage.getHeight(); myCachedScreenViewDisplayRect.setBounds(myScreenViewVisibleRect); double xScaleFactor = (double)resultImageWidth / myScreenViewSize.width; double yScaleFactor = (double)resultImageHeight / myScreenViewSize.height; cancelHighQualityScaleRequests(); if (xScaleFactor > 1.2 && yScaleFactor > 1.2) { requestHighQualityScaledImage(ScaleContext.create(g)); } cachedVisibleImage = getPreviewImage(g.getDeviceConfiguration(), renderedImage, myScreenView.getX(), myScreenView.getY(), myScreenViewVisibleRect, xScaleFactor, yScaleFactor, previousVisibleImage, myScreenView.hasBorderLayer()); myCachedVisibleImage = cachedVisibleImage; myLastScale = currentScale; } } } if (cachedVisibleImage != null) { Shape screenShape = myScreenView.getScreenShape(); if (screenShape != null) { g.clip(screenShape); } UIUtil.drawImage(g, cachedVisibleImage, myScreenViewVisibleRect.x, myScreenViewVisibleRect.y, null); } g.dispose(); } ScreenViewLayer(@NotNull ScreenView screenView); @VisibleForTesting  ScreenViewLayer(@NotNull ScreenView screenView, @Nullable ScheduledExecutorService executor); @Override void paint(@NotNull Graphics2D graphics2D); @Override void dispose(); final static Map<RenderingHints.Key, Object> HQ_RENDERING_HINTS; static final int REQUEST_SCALE_DEBOUNCE_TIME_IN_MS; }
@Test public void cancelPreviewTest() { VirtualTimeScheduler timeScheduler = new VirtualTimeScheduler(); Ref<Rectangle> screenViewSize = new Ref<>(scaleRectangle(FULL_SIZE, SCALE)); ImagePool.Image imageHQ = getTestImage(IMAGE_WIDTH, IMAGE_HEIGHT); ImagePool.Image imageNoScale = getTestImage(SCREEN_VIEW_WIDTH, SCREEN_VIEW_HEIGHT); ScreenView screenView = createScreenViewMock(screenViewSize, createRenderResultMock(imageHQ), createRenderResultMock(imageNoScale)); ScreenViewLayer layer = new ScreenViewLayer(screenView, timeScheduler); BufferedImage output = new BufferedImage(SCREEN_VIEW_WIDTH, SCREEN_VIEW_HEIGHT, BufferedImage.TYPE_INT_ARGB); Graphics2D g = createGraphicsAndClean(output, screenViewSize.get()); layer.paint(g); assertEquals(1, timeScheduler.getActionsQueued()); timeScheduler.advanceBy(30, TimeUnit.MILLISECONDS); assertEquals(1, timeScheduler.getActionsQueued()); layer.paint(g); assertEquals(0, timeScheduler.getActionsQueued()); }