KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > java > swing > plaf > nimbus > ImageScalingHelper


1 /*
2  * @(#)ImageScalingHelper.java 1.2 07/12/12
3  *
4  * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package com.sun.java.swing.plaf.nimbus;
8
9 import java.awt.Graphics JavaDoc;
10 import java.awt.Image JavaDoc;
11 import java.awt.Insets JavaDoc;
12
13 /**
14  * ImageScalingHelper
15  *
16  * @author Created by Jasper Potts (Aug 8, 2007)
17  * @version 1.0
18  */

19 class ImageScalingHelper {
20
21     /** Enumeration for the types of painting this class can handle. */
22     enum PaintType {
23         /**
24          * Painting type indicating the image should be centered in the space provided. When used the <code>mask</code>
25          * is ignored.
26          */

27         CENTER,
28
29         /**
30          * Painting type indicating the image should be tiled across the specified width and height. When used the
31          * <code>mask</code> is ignored.
32          */

33         TILE,
34
35         /**
36          * Painting type indicating the image should be split into nine regions with the top, left, bottom and right
37          * areas stretched.
38          */

39         PAINT9_STRETCH,
40
41         /**
42          * Painting type indicating the image should be split into nine regions with the top, left, bottom and right
43          * areas tiled.
44          */

45         PAINT9_TILE
46     }
47
48     ;
49
50     private static final Insets JavaDoc EMPTY_INSETS = new Insets JavaDoc(0, 0, 0, 0);
51
52     static final int PAINT_TOP_LEFT = 1;
53     static final int PAINT_TOP = 2;
54     static final int PAINT_TOP_RIGHT = 4;
55     static final int PAINT_LEFT = 8;
56     static final int PAINT_CENTER = 16;
57     static final int PAINT_RIGHT = 32;
58     static final int PAINT_BOTTOM_RIGHT = 64;
59     static final int PAINT_BOTTOM = 128;
60     static final int PAINT_BOTTOM_LEFT = 256;
61     /**
62      * Specifies that all regions should be painted. If this is set any other regions specified will not be painted.
63      * For example PAINT_ALL | PAINT_CENTER will paint all but the center.
64      */

65     static final int PAINT_ALL = 512;
66
67     /**
68      * Paints using the algorightm specified by <code>paintType</code>.
69      *
70      * @param g Graphics to render to
71      * @param x X-coordinate
72      * @param y Y-coordinate
73      * @param w Width to render to
74      * @param h Height to render to
75      * @param image Image to render from, if <code>null</code> this method will do nothing
76      * @param sInsets Insets specifying the portion of the image that will be stretched or tiled, if <code>null</code>
77      * empty <code>Insets</code> will be used.
78      * @param dInsets Destination insets specifying the portion of the image will be stretched or tiled, if
79      * <code>null</code> empty <code>Insets</code> will be used.
80      * @param paintType Specifies what type of algorithm to use in painting
81      * @param mask Specifies portion of image to render, if <code>PAINT_ALL</code> is specified, any other regions
82      * specified will not be painted, for example PAINT_ALL | PAINT_CENTER paints everything but the
83      * center.
84      */

85     public static void paint(Graphics JavaDoc g, int x, int y, int w, int h,
86                       Image JavaDoc image, Insets JavaDoc sInsets,
87                       Insets JavaDoc dInsets, PaintType paintType, int mask) {
88         if (image == null || image.getWidth(null) <= 0 || image.getHeight(null) <= 0) {
89             return;
90         }
91         if (sInsets == null) {
92             sInsets = EMPTY_INSETS;
93         }
94         if (dInsets == null) {
95             dInsets = EMPTY_INSETS;
96         }
97         int iw = image.getWidth(null);
98         int ih = image.getHeight(null);
99
100         if (paintType == PaintType.CENTER) {
101             // Center the image
102
g.drawImage(image, x + (w - iw) / 2,
103                     y + (h - ih) / 2, null);
104         } else if (paintType == PaintType.TILE) {
105             // Tile the image
106
int lastIY = 0;
107             for (int yCounter = y, maxY = y + h; yCounter < maxY;
108                  yCounter += (ih - lastIY), lastIY = 0) {
109                 int lastIX = 0;
110                 for (int xCounter = x, maxX = x + w; xCounter < maxX;
111                      xCounter += (iw - lastIX), lastIX = 0) {
112                     int dx2 = Math.min(maxX, xCounter + iw - lastIX);
113                     int dy2 = Math.min(maxY, yCounter + ih - lastIY);
114                     g.drawImage(image, xCounter, yCounter, dx2, dy2,
115                             lastIX, lastIY, lastIX + dx2 - xCounter,
116                             lastIY + dy2 - yCounter, null);
117                 }
118             }
119         } else {
120             int st = sInsets.top;
121             int sl = sInsets.left;
122             int sb = sInsets.bottom;
123             int sr = sInsets.right;
124
125             int dt = dInsets.top;
126             int dl = dInsets.left;
127             int db = dInsets.bottom;
128             int dr = dInsets.right;
129
130             // Constrain the insets to the size of the image
131
if (st + sb > ih) {
132                 db = dt = sb = st = Math.max(0, ih / 2);
133             }
134             if (sl + sr > iw) {
135                 dl = dr = sl = sr = Math.max(0, iw / 2);
136             }
137
138             // Constrain the insets to the size of the region we're painting
139
// in.
140
if (dt + db > h) {
141                 dt = db = Math.max(0, h / 2 - 1);
142             }
143             if (dl + dr > w) {
144                 dl = dr = Math.max(0, w / 2 - 1);
145             }
146
147             boolean stretch = (paintType == PaintType.PAINT9_STRETCH);
148             if ((mask & PAINT_ALL) != 0) {
149                 mask = (PAINT_ALL - 1) & ~mask;
150             }
151
152             if ((mask & PAINT_LEFT) != 0) {
153                 drawChunk(image, g, stretch, x, y + dt, x + dl, y + h - db,
154                         0, st, sl, ih - sb, false);
155             }
156             if ((mask & PAINT_TOP_LEFT) != 0) {
157                 drawImage(image, g, x, y, x + dl, y + dt,
158                         0, 0, sl, st);
159             }
160             if ((mask & PAINT_TOP) != 0) {
161                 drawChunk(image, g, stretch, x + dl, y, x + w - dr, y + dt,
162                         sl, 0, iw - sr, st, true);
163             }
164             if ((mask & PAINT_TOP_RIGHT) != 0) {
165                 drawImage(image, g, x + w - dr, y, x + w, y + dt,
166                         iw - sr, 0, iw, st);
167             }
168             if ((mask & PAINT_RIGHT) != 0) {
169                 drawChunk(image, g, stretch,
170                         x + w - dr, y + dt, x + w, y + h - db,
171                         iw - sr, st, iw, ih - sb, false);
172             }
173             if ((mask & PAINT_BOTTOM_RIGHT) != 0) {
174                 drawImage(image, g, x + w - dr, y + h - db, x + w, y + h,
175                         iw - sr, ih - sb, iw, ih);
176             }
177             if ((mask & PAINT_BOTTOM) != 0) {
178                 drawChunk(image, g, stretch,
179                         x + dl, y + h - db, x + w - dr, y + h,
180                         sl, ih - sb, iw - sr, ih, true);
181             }
182             if ((mask & PAINT_BOTTOM_LEFT) != 0) {
183                 drawImage(image, g, x, y + h - db, x + dl, y + h,
184                         0, ih - sb, sl, ih);
185             }
186             if ((mask & PAINT_CENTER) != 0) {
187                 drawImage(image, g, x + dl, y + dt, x + w - dr, y + h - db,
188                         sl, st, iw - sr, ih - sb);
189             }
190         }
191     }
192
193     /**
194      * Draws a portion of an image, stretched or tiled.
195      *
196      * @param image Image to render.
197      * @param g Graphics to render to
198      * @param stretch Whether the image should be stretched or timed in the
199      * provided space.
200      * @param dx1 X origin to draw to
201      * @param dy1 Y origin to draw to
202      * @param dx2 End x location to draw to
203      * @param dy2 End y location to draw to
204      * @param sx1 X origin to draw from
205      * @param sy1 Y origin to draw from
206      * @param sx2 Max x location to draw from
207      * @param sy2 Max y location to draw from
208      * @param xDirection Used if the image is not stretched. If true it
209      * indicates the image should be tiled along the x axis.
210      */

211     private static void drawChunk(Image JavaDoc image, Graphics JavaDoc g, boolean stretch,
212                            int dx1, int dy1, int dx2, int dy2, int sx1,
213                            int sy1, int sx2, int sy2,
214                            boolean xDirection) {
215         if (dx2 - dx1 <= 0 || dy2 - dy1 <= 0 || sx2 - sx1 <= 0 ||
216                               sy2 - sy1 <= 0) {
217             // Bogus location, nothing to paint
218
return;
219         }
220         if (stretch) {
221             g.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null);
222         }
223         else {
224             int xSize = sx2 - sx1;
225             int ySize = sy2 - sy1;
226             int deltaX;
227             int deltaY;
228
229             if (xDirection) {
230                 deltaX = xSize;
231                 deltaY = 0;
232             }
233             else {
234                 deltaX = 0;
235                 deltaY = ySize;
236             }
237             while (dx1 < dx2 && dy1 < dy2) {
238                 int newDX2 = Math.min(dx2, dx1 + xSize);
239                 int newDY2 = Math.min(dy2, dy1 + ySize);
240
241                 g.drawImage(image, dx1, dy1, newDX2, newDY2,
242                             sx1, sy1, sx1 + newDX2 - dx1,
243                             sy1 + newDY2 - dy1, null);
244                 dx1 += deltaX;
245                 dy1 += deltaY;
246             }
247         }
248     }
249
250     private static void drawImage(Image JavaDoc image, Graphics JavaDoc g,
251                            int dx1, int dy1, int dx2, int dy2, int sx1,
252                            int sy1, int sx2, int sy2) {
253         // PENDING: is this necessary, will G2D do it for me?
254
if (dx2 - dx1 <= 0 || dy2 - dy1 <= 0 || sx2 - sx1 <= 0 ||
255                 sy2 - sy1 <= 0) {
256             // Bogus location, nothing to paint
257
return;
258         }
259         g.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, null);
260     }
261
262
263 }
264
Popular Tags