1 /* 2 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.java2d.xr; 27 28 import java.awt.*; 29 import java.awt.geom.*; 30 31 /** 32 * Management of mask used for some blit-types. 33 * 34 * @author Clemens Eisserer 35 */ 36 37 public class XRMaskImage { 38 39 private static final int MASK_SCALE_FACTOR = 8; 40 41 private static final int BLIT_MASK_SIZE = 8; 42 43 Dimension blitMaskDimensions = new Dimension(BLIT_MASK_SIZE, BLIT_MASK_SIZE); 44 int blitMaskPixmap; 45 int blitMaskPicture; 46 int lastMaskWidth = 0; 47 int lastMaskHeight = 0; 48 int lastEA = -1; 49 AffineTransform lastMaskTransform; 50 51 XRCompositeManager xrMgr; 52 XRBackend con; 53 54 public XRMaskImage(XRCompositeManager xrMgr, int parentDrawable) { 55 this.xrMgr = xrMgr; 56 this.con = xrMgr.getBackend(); 57 58 initBlitMask(parentDrawable, BLIT_MASK_SIZE, BLIT_MASK_SIZE); 59 } 60 61 62 /** 63 * Prepares a mask used by a TransformedBlit, fills mask-contents and applies 64 * transformation. 65 */ 66 public int prepareBlitMask(XRSurfaceData dst, AffineTransform maskTX, int width, 67 int height) { 68 69 int maskWidth = Math.max(width / MASK_SCALE_FACTOR, 1); 70 int maskHeight = Math.max(height / MASK_SCALE_FACTOR, 1); 71 maskTX.scale(((double) width) / maskWidth, ((double) height) / maskHeight); 72 73 try { 74 maskTX.invert(); 75 } catch (NoninvertibleTransformException ex) { 76 maskTX.setToIdentity(); 77 } 78 79 ensureBlitMaskSize(maskWidth, maskHeight); 80 81 if (lastMaskTransform == null || !lastMaskTransform.equals(maskTX)) { 82 con.setPictureTransform(blitMaskPicture, maskTX); 83 lastMaskTransform = maskTX; 84 } 85 86 int currentEA = xrMgr.getAlphaColor().getAlpha(); 87 if (lastMaskWidth != maskWidth || lastMaskHeight != maskHeight || lastEA != currentEA) { 88 //Only clear mask, if previous mask area is larger than new one, otherwise simple overpaint it 89 if (lastMaskWidth > maskWidth || lastMaskHeight > maskHeight) { 90 con.renderRectangle(blitMaskPicture, XRUtils.PictOpClear, XRColor.NO_ALPHA, 0, 0, lastMaskWidth, lastMaskHeight); 91 } 92 93 con.renderRectangle(blitMaskPicture, XRUtils.PictOpSrc, xrMgr.getAlphaColor(), 0, 0, maskWidth, maskHeight); 94 lastEA = currentEA; 95 } 96 97 lastMaskWidth = maskWidth; 98 lastMaskHeight = maskHeight; 99 100 return blitMaskPicture; 101 } 102 103 private void initBlitMask(int parentDrawable, int width, int height) { 104 int newPM = con.createPixmap(parentDrawable, 8, width, height); 105 int newPict = con.createPicture(newPM, XRUtils.PictStandardA8); 106 107 /*Free old mask*/ 108 if (blitMaskPixmap != 0) { 109 con.freePixmap(blitMaskPixmap); 110 con.freePicture(blitMaskPicture); 111 } 112 113 blitMaskPixmap = newPM; 114 blitMaskPicture = newPict; 115 116 con.renderRectangle(blitMaskPicture, XRUtils.PictOpClear, XRColor.NO_ALPHA, 0, 0, width, height); 117 118 blitMaskDimensions.width = width; 119 blitMaskDimensions.height = height; 120 lastMaskWidth = 0; 121 lastMaskHeight = 0; 122 lastMaskTransform = null; 123 } 124 125 private void ensureBlitMaskSize(int minSizeX, int minSizeY) { 126 if (minSizeX > blitMaskDimensions.width || minSizeY > blitMaskDimensions.height) { 127 int newWidth = Math.max(minSizeX, blitMaskDimensions.width); 128 int newHeight = Math.max(minSizeY, blitMaskDimensions.height); 129 initBlitMask(blitMaskPixmap, newWidth, newHeight); 130 } 131 } 132 }