View Javadoc

1   /*
2    * Copyright (c) 2003-2008 by Cosylab d. d.
3    *
4    * This file is part of CosyBeans-Common.
5    *
6    * CosyBeans-Common 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 3 of the License, or
9    * (at your option) any later version.
10   *
11   * CosyBeans-Common is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with CosyBeans-Common.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  package com.cosylab.gui.components.ledder;
21  
22  import java.awt.PaintContext;
23  import java.awt.image.ColorModel;
24  import java.awt.image.Raster;
25  import java.awt.image.WritableRaster;
26  
27  
28  /**
29   * Renderer for Leds. Implements ray tracing with specular highlighting and
30   * antialiasing.
31   *
32   * @author <a href="mailto:ales.pucelj@cosylab.com">Ales Pucelj</a>
33   * @version $id$
34   */
35  public class LedPaintContext implements PaintContext
36  {
37  	private LedRenderer lr;
38  	private int aliasFactor = 1;
39  	private int[] offset;
40  	private int lastOffsetW = 0;
41  	private int lastOffsetF = 0;
42  
43  	/**
44  	 * Creates a new LedPaintContext object.
45  	 *
46  	 * @param x horizontal size.
47  	 * @param y vertical size.
48  	 * @param parameters defining the context.
49  	 */
50  	public LedPaintContext(int x, int y, LedPaintParameters parameters)
51  	{
52  		aliasFactor = parameters.antialiasing;
53  		lr = new LedRenderer(aliasFactor * x, aliasFactor * y,
54  			    aliasFactor * parameters.radius, parameters);
55  	}
56  
57  	/**
58  	 * Destroys this context.
59  	 */
60  	public void dispose()
61  	{
62  		offset = null;
63  		lr = null;
64  	}
65  
66  	/**
67  	 * Returns color model used by this context:
68  	 * <code>ColorModel.getRGBdefault()</code>.
69  	 *
70  	 * @return RGB Color model.
71  	 */
72  	public ColorModel getColorModel()
73  	{
74  		return ColorModel.getRGBdefault();
75  	}
76  
77  	private int[] subsample(final int[] pixels, final int w, final int h,
78  	    final int f)
79  	{
80  		int[] result = new int[4 * w * h];
81  		int oR = 0;
82  		int c = f * f;
83  		int acc;
84  		int base = 0;
85  		int baseInc = 4 * (f - 1);
86  
87  		for (int y = 0; y < h; y++) {
88  			base = c * y * w << 2;
89  
90  			for (int x = 0; x < w; x++) {
91  				for (int i = 0; i < 4; i++) {
92  					acc = 0;
93  
94  					for (int n = 0; n < c; n++) {
95  						acc += pixels[base + offset[n]];
96  					}
97  
98  					result[oR++] = acc / c;
99  					base++;
100 				}
101 
102 				base += baseInc;
103 			}
104 		}
105 
106 		return result;
107 	}
108 
109 	/**
110 	 * Creates array for antialiasing.
111 	 *
112 	 * @param factor by which to scale the array.
113 	 * @param width original width of the array.
114 	 */
115 	public void createOffsetArray(final int factor, final int width)
116 	{
117 		if ((lastOffsetW == width) && (lastOffsetF == factor)) {
118 			return;
119 		}
120 
121 		lastOffsetW = width;
122 		lastOffsetF = factor;
123 
124 		offset = new int[factor * factor];
125 
126 		int c = 0;
127 
128 		for (int m = 0; m < factor; m++) {
129 			for (int n = 0; n < factor; n++) {
130 				offset[c++] = 4 * (m * factor * width + n);
131 			}
132 		}
133 	}
134 
135 	/**
136 	 * Creates buffer, renders the led and antialiases the result.
137 	 *
138 	 * @param x offset.
139 	 * @param y offset.
140 	 * @param w width of area to render.
141 	 * @param h height of area to render.
142 	 *
143 	 * @return Raster of rendered pixels.
144 	 */
145 	public Raster getRaster(int x, int y, int w, int h)
146 	{
147 		WritableRaster raster = getColorModel().createCompatibleWritableRaster(w,
148 			    h);
149 
150 		int[] data = lr.renderSection(aliasFactor * x, aliasFactor * y,
151 			    aliasFactor * w, aliasFactor * h);
152 
153 		createOffsetArray(aliasFactor, w);
154 
155 		int[] result = (aliasFactor == 1) ? data
156 			: subsample(data, w, h, aliasFactor);
157 
158 		raster.setPixels(0, 0, w, h, result);
159 
160 		return raster;
161 	}
162 }
163 
164 /* __oOo__ */