001: /*
002: * Copyright (c) 2005-2008 Substance Kirill Grouchnikov. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of Substance Kirill Grouchnikov nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030: package org.jvnet.substance.watermark;
031:
032: import java.awt.*;
033: import java.awt.image.BufferedImage;
034:
035: import org.jvnet.substance.SubstanceLookAndFeel;
036: import org.jvnet.substance.utils.SubstanceColorUtilities;
037: import org.jvnet.substance.utils.SubstanceCoreUtilities;
038:
039: /**
040: * Simple implementation of {@link SubstanceWatermark}, drawing cross hatches
041: * as watermark. This class is part of officially supported API.
042: *
043: * @author Kirill Grouchnikov
044: * @author Chris Hall
045: */
046: public class SubstanceMetalWallWatermark implements SubstanceWatermark {
047: /**
048: * Watermark image (screen-sized).
049: */
050: private static Image watermarkImage = null;
051:
052: /*
053: * (non-Javadoc)
054: *
055: * @see org.jvnet.substance.watermark.SubstanceWatermark#drawWatermarkImage(java.awt.Graphics,
056: * int, int, int, int)
057: */
058: public void drawWatermarkImage(Graphics graphics, Component c,
059: int x, int y, int width, int height) {
060: if (!c.isShowing())
061: return;
062: int dx = c.getLocationOnScreen().x;
063: int dy = c.getLocationOnScreen().y;
064: graphics.drawImage(SubstanceMetalWallWatermark.watermarkImage,
065: x, y, x + width, y + height, x + dx, y + dy, x + dx
066: + width, y + dy + height, null);
067: }
068:
069: /*
070: * (non-Javadoc)
071: *
072: * @see org.jvnet.substance.watermark.SubstanceWatermark#updateWatermarkImage()
073: */
074: public boolean updateWatermarkImage() {
075: // fix by Chris for bug 67 - support for multiple screens
076: Rectangle virtualBounds = new Rectangle();
077: GraphicsEnvironment ge = GraphicsEnvironment
078: .getLocalGraphicsEnvironment();
079: GraphicsDevice[] gds = ge.getScreenDevices();
080: for (GraphicsDevice gd : gds) {
081: GraphicsConfiguration gc = gd.getDefaultConfiguration();
082: virtualBounds = virtualBounds.union(gc.getBounds());
083: }
084:
085: int screenWidth = virtualBounds.width;
086: int screenHeight = virtualBounds.height;
087: SubstanceMetalWallWatermark.watermarkImage = SubstanceCoreUtilities
088: .getBlankImage(screenWidth, screenHeight);
089:
090: Graphics2D graphics = (Graphics2D) SubstanceMetalWallWatermark.watermarkImage
091: .getGraphics().create();
092:
093: boolean status = this .drawWatermarkImage(graphics, 0, 0,
094: screenWidth, screenHeight, false);
095: graphics.dispose();
096: return status;
097: }
098:
099: /*
100: * (non-Javadoc)
101: *
102: * @see org.jvnet.substance.watermark.SubstanceWatermark#previewWatermark(java.awt.Graphics,
103: * int, int, int, int)
104: */
105: public void previewWatermark(Graphics g, int x, int y, int width,
106: int height) {
107: this .drawWatermarkImage((Graphics2D) g, x - 60, y - 120,
108: 60 + width, 120 + height, true);
109: }
110:
111: /**
112: * Draws the specified portion of the watermark image.
113: *
114: * @param graphics
115: * Graphic context.
116: * @param x
117: * the <i>x</i> coordinate of the watermark to be drawn.
118: * @param y
119: * The <i>y</i> coordinate of the watermark to be drawn.
120: * @param width
121: * The width of the watermark to be drawn.
122: * @param height
123: * The height of the watermark to be drawn.
124: * @param isPreview
125: * Indication whether the result is a preview image.
126: * @return Indication whether the draw succeeded.
127: */
128: private boolean drawWatermarkImage(Graphics2D graphics, int x,
129: int y, int width, int height, boolean isPreview) {
130: Color stampColorDark = null;
131: Color stampColorAll = null;
132: // Color stampColorLight = null;
133: if (isPreview) {
134: stampColorDark = SubstanceCoreUtilities
135: .isThemeDark(SubstanceLookAndFeel.getTheme()) ? Color.white
136: : Color.black;
137: stampColorAll = Color.lightGray;
138: // stampColorLight = SubstanceCoreUtilities
139: // .isThemeDark(SubstanceLookAndFeel.getTheme()) ? Color.black
140: // : Color.white;
141: } else {
142: stampColorDark = SubstanceColorUtilities
143: .getWatermarkDarkColor();
144: stampColorAll = SubstanceColorUtilities
145: .getWatermarkStampColor();
146: // stampColorLight = SubstanceColorUtilities.getWatermarkLightColor();
147: }
148:
149: graphics.setColor(stampColorAll);
150: graphics.fillRect(0, 0, width, height);
151:
152: Color c1 = stampColorDark;
153: Color c2 = SubstanceColorUtilities.getInterpolatedColor(
154: stampColorDark, stampColorAll, 0.5);
155:
156: BufferedImage tile = SubstanceCoreUtilities.getBlankImage(128,
157: 128);
158: this .drawTilePolygon(tile, new Polygon(
159: new int[] { 0, 49, 49, 0 }, new int[] { 0, 0, 17, 17 },
160: 4), c1, c2);
161: this .drawBolt(tile, 3, 3, c1, c2);
162: this .drawBolt(tile, 44, 3, c1, c2);
163: this .drawBolt(tile, 44, 12, c1, c2);
164: this .drawBolt(tile, 3, 12, c1, c2);
165:
166: this .drawTilePolygon(tile, new Polygon(new int[] { 66, 85, 85,
167: 49, 49 }, new int[] { 0, 0, 30, 30, 17 }, 5), c1, c1);
168: this .drawBolt(tile, 67, 3, c1, c2);
169: this .drawBolt(tile, 80, 3, c1, c2);
170: this .drawBolt(tile, 80, 25, c1, c2);
171: this .drawBolt(tile, 51, 25, c1, c2);
172:
173: this .drawTilePolygon(tile, new Polygon(new int[] { 86, 102,
174: 102, 86 }, new int[] { 0, 0, 17, 17 }, 4), c1, c2);
175: this .drawBolt(tile, 88, 3, c1, c2);
176: this .drawBolt(tile, 97, 3, c1, c2);
177: this .drawBolt(tile, 97, 11, c1, c2);
178: this .drawBolt(tile, 88, 11, c1, c2);
179:
180: this .drawTilePolygon(tile, new Polygon(
181: new int[] { -1, 9, 9, -1 },
182: new int[] { 22, 22, 36, 36 }, 4), c1, c2);
183: this .drawBolt(tile, 5, 24, c1, c2);
184: this .drawBolt(tile, 5, 31, c1, c2);
185:
186: this .drawTilePolygon(tile, new Polygon(new int[] { 118, 128,
187: 128, 118 }, new int[] { 22, 22, 36, 36 }, 4), c1, c2);
188: this .drawBolt(tile, 120, 24, c1, c2);
189: this .drawBolt(tile, 120, 31, c1, c2);
190:
191: this .drawTilePolygon(tile, new Polygon(new int[] { 49, 85, 85,
192: 45, 45, 22, 0, 29 }, new int[] { 31, 31, 57, 57, 75,
193: 75, 50, 50 }, 8), c1, c2);
194: this .drawBolt(tile, 51, 33, c1, c2);
195: this .drawBolt(tile, 80, 33, c1, c2);
196: this .drawBolt(tile, 80, 52, c1, c2);
197: this .drawBolt(tile, 51, 52, c1, c2);
198: this .drawBolt(tile, 40, 70, c1, c2);
199: this .drawBolt(tile, 24, 70, c1, c2);
200: this .drawBolt(tile, 8, 52, c1, c2);
201: this .drawBolt(tile, 30, 52, c1, c2);
202:
203: this .drawTilePolygon(tile, new Polygon(new int[] { 86, 96, 96,
204: 86 }, new int[] { 45, 45, 57, 57 }, 4), c1, c2);
205: this .drawBolt(tile, 88, 47, c1, c2);
206: this .drawBolt(tile, 88, 52, c1, c2);
207:
208: this .drawTilePolygon(tile, new Polygon(new int[] { 97, 118,
209: 118, 127, 127, 102, 102, 97 }, new int[] { 45, 45, 60,
210: 60, 100, 69, 57, 57 }, 8), c1, c2);
211: this .drawBolt(tile, 99, 47, c1, c2);
212: this .drawBolt(tile, 113, 47, c1, c2);
213: this .drawBolt(tile, 119, 62, c1, c2);
214: this .drawBolt(tile, 104, 67, c1, c2);
215: this .drawBolt(tile, 115, 80, c1, c2);
216: this .drawBolt(tile, 123, 91, c1, c2);
217:
218: this .drawTilePolygon(tile, new Polygon(new int[] { 46, 66, 66,
219: 40, 40, 32, 32, 0, 0, 22, 22, 46 }, new int[] { 58, 58,
220: 85, 109, 127, 127, 109, 109, 100, 100, 76, 76 }, 12),
221: c1, c2);
222: this .drawBolt(tile, 48, 58, c1, c2);
223: this .drawBolt(tile, 61, 58, c1, c2);
224: this .drawBolt(tile, 61, 82, c1, c2);
225: this .drawBolt(tile, 34, 122, c1, c2);
226: this .drawBolt(tile, 16, 102, c1, c2);
227: this .drawBolt(tile, 3, 102, c1, c2);
228: this .drawBolt(tile, 24, 77, c1, c2);
229: this .drawBolt(tile, 43, 77, c1, c2);
230:
231: this .drawTilePolygon(tile, new Polygon(new int[] { 67, 102,
232: 102, 85, 85, 66, 66, 45 }, new int[] { 85, 85, 104,
233: 104, 127, 127, 112, 106 }, 8), c1, c2);
234: this .drawBolt(tile, 68, 87, c1, c2);
235: this .drawBolt(tile, 97, 87, c1, c2);
236: this .drawBolt(tile, 97, 99, c1, c2);
237: this .drawBolt(tile, 80, 104, c1, c2);
238: this .drawBolt(tile, 80, 122, c1, c2);
239: this .drawBolt(tile, 68, 122, c1, c2);
240: this .drawBolt(tile, 52, 102, c1, c2);
241:
242: this .drawTilePolygon(tile, new Polygon(new int[] { 86, 127,
243: 127, 102, 93, 127, 127, 86 }, new int[] { 105, 105,
244: 109, 109, 118, 117, 127, 127 }, 8), c1, c2);
245: this .drawBolt(tile, 88, 106, c1, c2);
246: this .drawBolt(tile, 122, 122, c1, c2);
247: this .drawBolt(tile, 88, 122, c1, c2);
248:
249: for (int row = 0; row < height; row += 127) {
250: for (int col = 0; col < width; col += 127) {
251: graphics.drawImage(tile, x + col, y + row, null);
252: }
253: }
254: return true;
255: }
256:
257: /**
258: * Draws a single tile polygon.
259: *
260: * @param tile
261: * Tile to draw on.
262: * @param polygon
263: * Polygon path.
264: * @param colorLight
265: * Light color.
266: * @param colorDark
267: * Dark color.
268: */
269: private void drawTilePolygon(BufferedImage tile, Polygon polygon,
270: Color colorLight, Color colorDark) {
271: int minX = tile.getWidth();
272: int maxX = 0;
273: for (int x : polygon.xpoints) {
274: minX = Math.min(x, minX);
275: maxX = Math.max(x, maxX);
276: }
277: int minY = tile.getHeight();
278: int maxY = 0;
279: for (int y : polygon.ypoints) {
280: minY = Math.min(y, minY);
281: maxY = Math.max(y, maxY);
282: }
283:
284: Graphics2D graphics = (Graphics2D) tile.getGraphics().create();
285: graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
286: RenderingHints.VALUE_ANTIALIAS_ON);
287:
288: graphics.setStroke(new BasicStroke(0.7f));
289: graphics.setPaint(new GradientPaint(minX, minY, colorLight,
290: maxX, maxY, colorDark));
291: graphics.drawPolygon(polygon);
292: graphics.setComposite(AlphaComposite.getInstance(
293: AlphaComposite.SRC_OVER, 0.1f));
294: graphics.fillPolygon(polygon);
295:
296: graphics.dispose();
297: }
298:
299: /**
300: * Draws a single bolt.
301: *
302: * @param tile
303: * Tile to draw on.
304: * @param x
305: * Bolt X.
306: * @param y
307: * Bolt Y.
308: * @param colorLight
309: * Light color.
310: * @param colorDark
311: * Dark color.
312: */
313: private void drawBolt(BufferedImage tile, int x, int y,
314: Color colorLight, Color colorDark) {
315: Graphics2D graphics = (Graphics2D) tile.getGraphics().create();
316: graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
317: RenderingHints.VALUE_ANTIALIAS_OFF);
318: graphics.setColor(colorDark);
319: graphics.fillOval(x, y, 4, 4);
320: graphics.setColor(colorLight);
321: graphics.fillOval(x, y, 3, 3);
322: }
323:
324: /*
325: * (non-Javadoc)
326: *
327: * @see org.jvnet.substance.watermark.SubstanceWatermark#getDisplayName()
328: */
329: public String getDisplayName() {
330: return SubstanceMetalWallWatermark.getName();
331: }
332:
333: /**
334: * Returns the name of all watermarks of <code>this</code> class.
335: *
336: * @return The name of all watermarks of <code>this</code> class.
337: */
338: public static String getName() {
339: return "Metal Wall";
340: }
341:
342: /*
343: * (non-Javadoc)
344: *
345: * @see org.jvnet.substance.watermark.SubstanceWatermark#isDependingOnTheme()
346: */
347: public boolean isDependingOnTheme() {
348: return true;
349: }
350:
351: /*
352: * (non-Javadoc)
353: *
354: * @see org.jvnet.substance.watermark.SubstanceWatermark#dispose()
355: */
356: public void dispose() {
357: watermarkImage = null;
358: }
359: }
|