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;
|
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;
|