/* * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.javafx.sg.prism; import com.sun.javafx.geom.Rectangle; import com.sun.javafx.sg.PGImageView; import com.sun.prism.Graphics; import com.sun.prism.Image; import com.sun.prism.ResourceFactory; import com.sun.prism.Texture; import com.sun.prism.image.Coords; import com.sun.prism.image.CompoundCoords; import com.sun.prism.image.CachingCompoundImage; import com.sun.prism.image.ViewPort; /** */ public class NGImageView extends NGNode implements PGImageView { private Image image; private CachingCompoundImage compoundImage; private CompoundCoords compoundCoords; private float x, y, w, h; // Coords will be null if there was no viewport specified. // In case when we draw a huge image, coords are never null. private Coords coords; private ViewPort reqviewport; // ViewPort requested by ImageView private ViewPort imgviewport; // ViewPort scaled to the current image private boolean renderable = false; private boolean coordsOK = false; private void invalidate() { coordsOK = false; coords = null; compoundCoords = null; imgviewport = null; geometryChanged(); } public void setViewport(float vx, float vy, float vw, float vh, float cw, float ch) { if (vw > 0 && vh > 0) { reqviewport = new ViewPort(vx, vy, vw, vh); } else { reqviewport = null; } this.w = cw; this.h = ch; invalidate(); } private void calculatePositionAndClipping() { renderable = false; coordsOK = true; if (reqviewport == null) { renderable = image != null; return; } float iw = image.getWidth(); float ih = image.getHeight(); if (iw == 0 || ih == 0) return; imgviewport = reqviewport.getScaledVersion(image.getPixelScale()); coords = imgviewport.getClippedCoords(iw, ih, w, h); renderable = coords != null; } @Override protected void doRender(Graphics g) { if (!coordsOK) { calculatePositionAndClipping(); } if (renderable) { super.doRender(g); } } // method for testing reasons final static int MAX_SIZE_OVERRIDE = 0; // 64 private int maxSizeWrapper(ResourceFactory factory) { return MAX_SIZE_OVERRIDE > 0 ? MAX_SIZE_OVERRIDE : factory.getMaximumTextureSize(); } private Rectangle rect = new Rectangle(); @Override protected void renderContent(Graphics g) { int imgW = image.getWidth(); int imgH = image.getHeight(); ResourceFactory factory = g.getResourceFactory(); int maxSize = maxSizeWrapper(factory); if (imgW <= maxSize && imgH <= maxSize) { rect.width = imgW; rect.height = imgH; Texture texture = NGRegion.getImageTexture(g, image, rect); // Texture texture = factory.getCachedTexture(image, Texture.WrapMode.CLAMP_TO_EDGE); if (coords == null) { g.drawTexture(texture, x, y, x + w, y + h, rect.x, rect.y, rect.x + imgW, rect.y + imgH); } else { coords.draw(texture, g, x, y); System.err.println("Can't do this properly"); } texture.unlock(); } else { if (compoundImage == null) compoundImage = new CachingCompoundImage(image, maxSize); // coords is null iff there was no viewport specified, but // MegaCoords needs a non-null Coords so we create a dummy one if (coords == null) coords = new Coords(w, h, new ViewPort(0, 0, imgW, imgH)); if (compoundCoords == null) compoundCoords = new CompoundCoords(compoundImage, coords); compoundCoords.draw(g, compoundImage, x, y); } } @Override protected boolean hasOverlappingContents() { return false; } public void setImage(Object img) { Image newImage = (Image)img; if (image == newImage) return; boolean needsInvalidate = newImage == null || image == null || image.getPixelScale() != newImage.getPixelScale() || image.getHeight() != newImage.getHeight() || image.getWidth() != newImage.getWidth(); image = newImage; compoundImage = null; if (needsInvalidate) invalidate(); } public void setX(float x) { if (this.x != x) { this.x = x; geometryChanged(); } } public void setY(float y) { if (this.y != y) { this.y = y; geometryChanged(); } } // RT-18701: this method does nothing public void setSmooth(boolean s) {} }