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 AffineTransform lastMaskTransform; 49 50 XRCompositeManager xrMgr; 51 XRBackend con; 52 53 public XRMaskImage(XRCompositeManager xrMgr, int parentDrawable) { 54 this.xrMgr = xrMgr; 55 this.con = xrMgr.getBackend(); 56 57 initBlitMask(parentDrawable, BLIT_MASK_SIZE, BLIT_MASK_SIZE); 58 } 59 60 61 /** 62 * Prepares a mask used by a TransformedBlit, fills mask-contents and applies 63 * transformation. 64 */ 65 public int prepareBlitMask(XRSurfaceData dst, AffineTransform maskTX, int width, 66 int height) { 67 68 int maskWidth = Math.max(width / MASK_SCALE_FACTOR, 1); 69 int maskHeight = Math.max(height / MASK_SCALE_FACTOR, 1); 70 maskTX.scale(((double) width) / maskWidth, ((double) height) / maskHeight); 71 72 try { 73 maskTX.invert(); 74 } catch (NoninvertibleTransformException ex) { 75 maskTX.setToIdentity(); 76 } 77 78 ensureBlitMaskSize(maskWidth, maskHeight); 79 80 if (lastMaskTransform == null || !lastMaskTransform.equals(maskTX)) { 81 con.setPictureTransform(blitMaskPicture, maskTX); 82 lastMaskTransform = maskTX; 83 } 84 85 if (lastMaskWidth != maskWidth || lastMaskHeight != maskHeight) { 86 //Only clear mask, if previous mask area is larger than new one, otherwise simple overpaint it 87 if (lastMaskWidth > maskWidth || lastMaskHeight > maskHeight) { 88 con.renderRectangle(blitMaskPicture, XRUtils.PictOpClear, XRColor.NO_ALPHA, 0, 0, lastMaskWidth, lastMaskHeight); 89 } 90 91 con.renderRectangle(blitMaskPicture, XRUtils.PictOpSrc, xrMgr.getAlphaColor(), 0, 0, maskWidth, maskHeight); 92 } 93 94 lastMaskWidth = maskWidth; 95 lastMaskHeight = maskHeight; 96 97 return blitMaskPicture; 98 } 99 100 private void initBlitMask(int parentDrawable, int width, int height) { 101 int newPM = con.createPixmap(parentDrawable, 8, width, height); 102 int newPict = con.createPicture(newPM, XRUtils.PictStandardA8); 103 104 /*Free old mask*/ 105 if (blitMaskPixmap != 0) { 106 con.freePixmap(blitMaskPixmap); 107 con.freePicture(blitMaskPicture); 108 } 109 110 blitMaskPixmap = newPM; 111 blitMaskPicture = newPict; 112 113 con.renderRectangle(blitMaskPicture, XRUtils.PictOpClear, XRColor.NO_ALPHA, 0, 0, width, height); 114 115 blitMaskDimensions.width = width; 116 blitMaskDimensions.height = height; 117 lastMaskWidth = 0; 118 lastMaskHeight = 0; 119 lastMaskTransform = null; 120 } 121 122 private void ensureBlitMaskSize(int minSizeX, int minSizeY) { 123 if (minSizeX > blitMaskDimensions.width || minSizeY > blitMaskDimensions.height) { 124 int newWidth = Math.max(minSizeX, blitMaskDimensions.width); 125 int newHeight = Math.max(minSizeY, blitMaskDimensions.height); 126 initBlitMask(blitMaskPixmap, newWidth, newHeight); 127 } 128 } 129 }