Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / javax / swing / plaf / metal / MetalUtils.java
blobb9d5ea76434c5334e42df18ceda15cecf520d792
1 /* MetalUtils.java
2 Copyright (C) 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package javax.swing.plaf.metal;
40 import gnu.classpath.SystemProperties;
42 import java.awt.Color;
43 import java.awt.Component;
44 import java.awt.Graphics;
45 import java.awt.Graphics2D;
46 import java.awt.TexturePaint;
47 import java.awt.geom.Rectangle2D;
48 import java.awt.image.BufferedImage;
49 import java.util.List;
51 import javax.swing.SwingConstants;
52 import javax.swing.UIManager;
54 /**
55 * Some utility and helper methods for the Metal Look & Feel.
57 * @author Roman Kennke (roman@kennke.org)
59 class MetalUtils
62 /**
63 * The typical metal pattern for use with Graphics2D.
65 static BufferedImage pattern2D;
67 /**
68 * The light color to draw the pattern.
70 static Color lightColor;
72 /**
73 * The dark color to draw to draw the pattern.
75 static Color darkColor;
77 /**
78 * Fills a rectangle with the typical Metal pattern.
80 * @param g the <code>Graphics</code> context to use
81 * @param x the X coordinate of the upper left corner of the rectangle to
82 * fill
83 * @param y the Y coordinate of the upper left corner of the rectangle to
84 * fill
85 * @param w the width of the rectangle to fill
86 * @param h the height of the rectangle to fill
87 * @param light the light color to use
88 * @param dark the dark color to use
90 static void fillMetalPattern(Component c, Graphics g, int x, int y, int w, int h,
91 Color light, Color dark)
93 if (g instanceof Graphics2D
94 && SystemProperties.getProperty("gnu.javax.swing.noGraphics2D") != null)
95 fillMetalPattern2D((Graphics2D) g, x, y, w, h, light, dark);
96 else
98 int xOff = 0;
99 for (int mY = y; mY < (y + h); mY++)
101 // set color alternating with every line
102 if (((mY - y) % 2) == 0)
103 g.setColor(light);
104 else
105 g.setColor(dark);
107 for (int mX = x + (xOff); mX < (x + w); mX += 4)
109 g.drawLine(mX, mY, mX, mY);
112 // increase x offset
113 xOff++;
114 if (xOff > 3)
115 xOff = 0;
121 * Fills a rectangle with the typical Metal pattern using Java2D.
123 * @param g2d the <code>Graphics2D</code> context to use
124 * @param x the X coordinate of the upper left corner of the rectangle to
125 * fill
126 * @param y the Y coordinate of the upper left corner of the rectangle to
127 * fill
128 * @param w the width of the rectangle to fill
129 * @param h the height of the rectangle to fill
131 static void fillMetalPattern2D(Graphics2D g2d, int x, int y, int w, int h,
132 Color light, Color dark)
134 if (pattern2D == null || !darkColor.equals(dark) || !lightColor.equals(light))
135 initializePattern(light, dark);
137 // Prepare the texture.
138 TexturePaint texture =
139 new TexturePaint(pattern2D, new Rectangle2D.Double(0., 0., 4., 4.));
140 g2d.setPaint(texture);
141 g2d.fillRect(x, y, w, h);
145 * Initializes the pattern image.
147 static void initializePattern(Color light, Color dark)
149 pattern2D = new BufferedImage(4, 4, BufferedImage.TYPE_INT_ARGB);
150 lightColor = light;
151 darkColor = dark;
152 Graphics g = pattern2D.getGraphics();
153 g.setColor(light);
154 g.fillRect(0, 0, 1, 1);
155 g.fillRect(2, 2, 1, 1);
156 g.setColor(dark);
157 g.fillRect(1, 1, 1, 1);
158 g.fillRect(3, 3, 1, 1);
159 g.dispose();
163 * Paints the typical Metal gradient. See {@link #paintGradient(Graphics,
164 * int, int, int, int, double, double, Color, Color, Color, int)}
165 * for more details.
167 * The parameters are fetched from the UIManager using the key
168 * <code>uiProp</code>. The value is expected to be a {@link List} that
169 * contains 4 values: two {@link Double}s and 3 {@link Color} object that
170 * together make up the parameters passed to the painting method.
172 * @param g the graphics context to use
173 * @param x the X coordinate of the upper left corner of the rectangle
174 * @param y the Y coordinate of the upper left corner of the rectangle
175 * @param w the width of the rectangle
176 * @param h the height of the rectangle
177 * @param dir the direction of the gradient, either
178 * @param uiProp the key of the UIManager property that has the parameters
180 static void paintGradient(Graphics g, int x, int y, int w, int h,
181 int dir, String uiProp)
183 List params = (List) UIManager.get(uiProp);
184 double g1 = ((Double) params.get(0)).doubleValue();
185 double g2 = ((Double) params.get(1)).doubleValue();
186 Color c1 = (Color) params.get(2);
187 Color c2 = (Color) params.get(3);
188 Color c3 = (Color) params.get(4);
189 paintGradient(g, x, y, w, h, g1, g2, c1, c2, c3, dir);
193 * Paints the typical Metal gradient. The gradient is painted as follows:
194 * <pre>
196 * +-------+--------+--------+-----------------------------+
197 * | | | | |
198 * +-------+--------+--------+-----------------------------+
199 * c1 -> c2 -- c2 -> c1 --------> c3
200 * < -g1- > < -g2- > < -g1- >
201 * </pre>
203 * There are 4 distinct areas in this gradient:
204 * <ol>
205 * <li>A gradient from color 1 to color 2 with the relative width specified
206 * by <code>g1</code></li>
207 * <li>A solid area with the color 2 and the relative width specified by
208 * <code>g2</code></li>
209 * <li>A gradient from color 2 to color 1 with the relative width specified
210 * by <code>g1</code></li>
212 * @param g the graphics context to use
213 * @param x the X coordinate of the upper left corner of the rectangle
214 * @param y the Y coordinate of the upper left corner of the rectangle
215 * @param w the width of the rectangle
216 * @param h the height of the rectangle
217 * @param g1 the relative width of the c1->c2 gradients
218 * @param g2 the relative width of the c2 solid area
219 * @param c1 the color 1
220 * @param c2 the color 2
221 * @param c3 the color 3
222 * @param dir the direction of the gradient, either
223 * {@link SwingConstants#HORIZONTAL} or {@link SwingConstants#VERTICAL}
225 static void paintGradient(Graphics g, int x, int y, int w, int h, double g1,
226 double g2, Color c1, Color c2, Color c3, int dir)
228 if (dir == SwingConstants.HORIZONTAL)
229 paintHorizontalGradient(g, x, y, w, h, g1, g2, c1, c2, c3);
230 else
231 paintVerticalGradient(g, x, y, w, h, g1, g2, c1, c2, c3);
235 * Paints a horizontal gradient. See {@link #paintGradient(Graphics, int,
236 * int, int, int, double, double, Color, Color, Color, int)} for details.
238 * @param x the X coordinate of the upper left corner of the rectangle
239 * @param y the Y coordinate of the upper left corner of the rectangle
240 * @param w the width of the rectangle
241 * @param h the height of the rectangle
242 * @param g1 the relative width of the c1->c2 gradients
243 * @param g2 the relative width of the c2 solid area
244 * @param c1 the color 1
245 * @param c2 the color 2
246 * @param c3 the color 3
248 static void paintHorizontalGradient(Graphics g, int x, int y, int w, int h,
249 double g1, double g2, Color c1, Color c2,
250 Color c3)
252 // Calculate the coordinates.
253 // The size of the first gradient area (c1->2).
254 int w1 = (int) (w * g1);
255 // The size of the solid c2 area.
256 int w2 = (int) (w * g2);
257 int x0 = x;
258 int x1 = x0 + w1;
259 int x2 = x1 + w2;
260 int x3 = x2 + w1;
261 int x4 = x + w;
263 // Paint first gradient area (c1->c2).
264 int xc; // The current y coordinate.
265 for (xc = x0; xc < x1; xc++)
267 if (xc > x + w)
268 break;
270 // Perform color interpolation;
271 double factor = (xc - x0) / (double) w1;
272 int rInt = (int) ((c2.getRed() - c1.getRed()) * factor + c1.getRed());
273 int gInt = (int) ((c2.getGreen() - c1.getGreen()) * factor
274 + c1.getGreen());
275 int bInt = (int) ((c2.getBlue() - c1.getBlue()) * factor
276 + c1.getBlue());
277 Color interpolated = new Color(rInt, gInt, bInt);
278 g.setColor(interpolated);
279 g.drawLine(xc, y, xc, y + h);
281 // Paint solid c2 area.
282 g.setColor(c2);
283 g.fillRect(x1, y, x2 - x1, h);
285 // Paint second gradient area (c2->c1).
286 for (xc = x2; xc < x3; xc++)
288 if (xc > x + w)
289 break;
291 // Perform color interpolation;
292 double factor = (xc - x2) / (double) w1;
293 int rInt = (int) ((c1.getRed() - c2.getRed()) * factor + c2.getRed());
294 int gInt = (int) ((c1.getGreen() - c2.getGreen()) * factor
295 + c2.getGreen());
296 int bInt = (int) ((c1.getBlue() - c2.getBlue()) * factor
297 + c2.getBlue());
298 Color interpolated = new Color(rInt, gInt, bInt);
299 g.setColor(interpolated);
300 g.drawLine(xc, y, xc, y + h);
303 // Paint third gradient area (c1->c3).
304 for (xc = x3; xc < x4; xc++)
306 if (xc > x + w)
307 break;
309 // Perform color interpolation;
310 double factor = (xc - x3) / (double) (x4 - x3);
311 int rInt = (int) ((c3.getRed() - c1.getRed()) * factor + c1.getRed());
312 int gInt = (int) ((c3.getGreen() - c1.getGreen()) * factor
313 + c1.getGreen());
314 int bInt = (int) ((c3.getBlue() - c1.getBlue()) * factor
315 + c1.getBlue());
316 Color interpolated = new Color(rInt, gInt, bInt);
317 g.setColor(interpolated);
318 g.drawLine(xc, y, xc, y + h);
323 * Paints a vertical gradient. See {@link #paintGradient(Graphics, int, int,
324 * int, int, double, double, Color, Color, Color, int)} for details.
326 * @param x the X coordinate of the upper left corner of the rectangle
327 * @param y the Y coordinate of the upper left corner of the rectangle
328 * @param w the width of the rectangle
329 * @param h the height of the rectangle
330 * @param g1 the relative width of the c1->c2 gradients
331 * @param g2 the relative width of the c2 solid area
332 * @param c1 the color 1
333 * @param c2 the color 2
334 * @param c3 the color 3
336 static void paintVerticalGradient(Graphics g, int x, int y, int w, int h,
337 double g1, double g2, Color c1, Color c2,
338 Color c3)
340 // Calculate the coordinates.
341 // The size of the first gradient area (c1->2).
342 int w1 = (int) (h * g1);
343 // The size of the solid c2 area.
344 int w2 = (int) (h * g2);
345 int y0 = y;
346 int y1 = y0 + w1;
347 int y2 = y1 + w2;
348 int y3 = y2 + w1;
349 int y4 = y + h;
351 // Paint first gradient area (c1->c2).
352 int yc; // The current y coordinate.
353 for (yc = y0; yc < y1; yc++)
355 if (yc > y + h)
356 break;
358 // Perform color interpolation;
359 double factor = (yc - y0) / (double) w1;
360 int rInt = (int) ((c2.getRed() - c1.getRed()) * factor + c1.getRed());
361 int gInt = (int) ((c2.getGreen() - c1.getGreen()) * factor
362 + c1.getGreen());
363 int bInt = (int) ((c2.getBlue() - c1.getBlue()) * factor
364 + c1.getBlue());
365 Color interpolated = new Color(rInt, gInt, bInt);
366 g.setColor(interpolated);
367 g.drawLine(x, yc, x + w, yc);
369 // Paint solid c2 area.
370 g.setColor(c2);
371 g.fillRect(x, y1, w, y2 - y1);
373 // Paint second gradient area (c2->c1).
374 for (yc = y2; yc < y3; yc++)
376 if (yc > y + h)
377 break;
379 // Perform color interpolation;
380 double factor = (yc - y2) / (double) w1;
381 int rInt = (int) ((c1.getRed() - c2.getRed()) * factor + c2.getRed());
382 int gInt = (int) ((c1.getGreen() - c2.getGreen()) * factor
383 + c2.getGreen());
384 int bInt = (int) ((c1.getBlue() - c2.getBlue()) * factor
385 + c2.getBlue());
386 Color interpolated = new Color(rInt, gInt, bInt);
387 g.setColor(interpolated);
388 g.drawLine(x, yc, x + w, yc);
391 // Paint third gradient area (c1->c3).
392 for (yc = y3; yc < y4; yc++)
394 if (yc > y + h)
395 break;
397 // Perform color interpolation;
398 double factor = (yc - y3) / (double) (y4 - y3);
399 int rInt = (int) ((c3.getRed() - c1.getRed()) * factor + c1.getRed());
400 int gInt = (int) ((c3.getGreen() - c1.getGreen()) * factor
401 + c1.getGreen());
402 int bInt = (int) ((c3.getBlue() - c1.getBlue()) * factor
403 + c1.getBlue());
404 Color interpolated = new Color(rInt, gInt, bInt);
405 g.setColor(interpolated);
406 g.drawLine(x, yc, x + w, yc);