106 } |
105 } |
107 |
106 |
108 void setXRPaint(SunGraphics2D sg2d, Paint pt) { |
107 void setXRPaint(SunGraphics2D sg2d, Paint pt) { |
109 GradientPaint paint = (GradientPaint) pt; |
108 GradientPaint paint = (GradientPaint) pt; |
110 |
109 |
111 int[] pixels = convertToIntArgbPixels(new Color[] { paint.getColor1(), paint.getColor2() }, false); |
110 int repeat = paint.isCyclic() ? XRUtils.RepeatReflect : XRUtils.RepeatPad; |
112 |
111 float fractions[] = {0, 1}; |
113 float fractions[] = new float[2]; |
112 int[] pixels = convertToIntArgbPixels(new Color[] { paint.getColor1(), paint.getColor2() }); |
114 fractions[0] = 0; |
|
115 fractions[1] = 1; |
|
116 |
113 |
117 Point2D pt1 = paint.getPoint1(); |
114 Point2D pt1 = paint.getPoint1(); |
118 Point2D pt2 = paint.getPoint2(); |
115 Point2D pt2 = paint.getPoint2(); |
119 |
116 |
120 AffineTransform at = (AffineTransform) sg2d.transform.clone(); |
117 XRBackend con = xrCompMan.getBackend(); |
|
118 int gradient = con.createLinearGradient(pt1, pt2, fractions, pixels, repeat); |
|
119 xrCompMan.setGradientPaint(new XRSurfaceData.XRInternalSurfaceData(con, gradient)); |
|
120 } |
|
121 } |
|
122 |
|
123 public int getGradientLength(Point2D pt1, Point2D pt2) { |
|
124 double xDiff = Math.max(pt1.getX(), pt2.getX()) - Math.min(pt1.getX(), pt2.getX()); |
|
125 double yDiff = Math.max(pt1.getY(), pt2.getY()) - Math.min(pt1.getY(), pt2.getY()); |
|
126 return (int) Math.ceil(Math.sqrt(xDiff*xDiff + yDiff*yDiff)); |
|
127 } |
|
128 |
|
129 private static class XRLinearGradient extends XRPaints { |
|
130 |
|
131 @Override |
|
132 boolean isPaintValid(SunGraphics2D sg2d) { |
|
133 return ((LinearGradientPaint) sg2d.getPaint()).getColorSpace() == ColorSpaceType.SRGB; |
|
134 } |
|
135 |
|
136 @Override |
|
137 void setXRPaint(SunGraphics2D sg2d, Paint pt) { |
|
138 LinearGradientPaint paint = (LinearGradientPaint) pt; |
|
139 |
|
140 Color[] colors = paint.getColors(); |
|
141 Point2D pt1 = paint.getStartPoint(); |
|
142 Point2D pt2 = paint.getEndPoint(); |
|
143 |
|
144 int repeat = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod()); |
|
145 float[] fractions = paint.getFractions(); |
|
146 int[] pixels = convertToIntArgbPixels(colors); |
|
147 |
|
148 AffineTransform at = paint.getTransform(); |
|
149 try { |
|
150 at.invert(); |
|
151 } catch (NoninvertibleTransformException ex) { |
|
152 ex.printStackTrace(); |
|
153 } |
|
154 |
|
155 XRBackend con = xrCompMan.getBackend(); |
|
156 int gradient = con.createLinearGradient(pt1, pt2, fractions, pixels, repeat); |
|
157 XRInternalSurfaceData x11sd = new XRSurfaceData.XRInternalSurfaceData(con, gradient); |
|
158 x11sd.setStaticSrcTx(at); |
|
159 xrCompMan.setGradientPaint(x11sd); |
|
160 } |
|
161 } |
|
162 |
|
163 private static class XRRadialGradient extends XRPaints { |
|
164 |
|
165 @Override |
|
166 boolean isPaintValid(SunGraphics2D sg2d) { |
|
167 RadialGradientPaint grad = (RadialGradientPaint) sg2d.paint; |
|
168 return grad.getFocusPoint().equals(grad.getCenterPoint()) |
|
169 && grad.getColorSpace() == ColorSpaceType.SRGB; |
|
170 } |
|
171 |
|
172 @Override |
|
173 void setXRPaint(SunGraphics2D sg2d, Paint pt) { |
|
174 RadialGradientPaint paint = (RadialGradientPaint) pt; |
|
175 Color[] colors = paint.getColors(); |
|
176 Point2D center = paint.getCenterPoint(); |
|
177 |
|
178 int repeat = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod()); |
|
179 float[] fractions = paint.getFractions(); |
|
180 int[] pixels = convertToIntArgbPixels(colors); |
|
181 float radius = paint.getRadius(); |
|
182 |
|
183 float cx = (float) center.getX(); |
|
184 float cy = (float) center.getY(); |
|
185 |
|
186 AffineTransform at = paint.getTransform(); |
|
187 try { |
|
188 at.invert(); |
|
189 } catch (NoninvertibleTransformException ex) { |
|
190 ex.printStackTrace(); |
|
191 } |
|
192 |
|
193 XRBackend con = xrCompMan.getBackend(); |
|
194 int gradient = con.createRadialGradient(cx, cy, 0, radius, fractions, pixels, repeat); |
|
195 XRInternalSurfaceData x11sd = new XRSurfaceData.XRInternalSurfaceData(con, gradient); |
|
196 x11sd.setStaticSrcTx(at); |
|
197 xrCompMan.setGradientPaint(x11sd); |
|
198 } |
|
199 } |
|
200 |
|
201 private static class XRTexture extends XRPaints { |
|
202 |
|
203 private XRSurfaceData getAccSrcSurface(XRSurfaceData dstData, BufferedImage bi) { |
|
204 // REMIND: this is a hack that attempts to cache the system |
|
205 // memory image from the TexturePaint instance into an |
|
206 // XRender pixmap... |
|
207 SurfaceData srcData = dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null); |
|
208 if (!(srcData instanceof XRSurfaceData)) { |
|
209 srcData = dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null); |
|
210 if (!(srcData instanceof XRSurfaceData)) { |
|
211 throw new InternalError("Surface not cachable"); |
|
212 } |
|
213 } |
|
214 |
|
215 return (XRSurfaceData) srcData; |
|
216 } |
|
217 |
|
218 @Override |
|
219 boolean isPaintValid(SunGraphics2D sg2d) { |
|
220 TexturePaint paint = (TexturePaint) sg2d.paint; |
|
221 BufferedImage bi = paint.getImage(); |
|
222 XRSurfaceData dstData = (XRSurfaceData) sg2d.getDestSurface(); |
|
223 |
|
224 return getAccSrcSurface(dstData, bi) != null; |
|
225 } |
|
226 |
|
227 @Override |
|
228 void setXRPaint(SunGraphics2D sg2d, Paint pt) { |
|
229 TexturePaint paint = (TexturePaint) pt; |
|
230 BufferedImage bi = paint.getImage(); |
|
231 Rectangle2D anchor = paint.getAnchorRect(); |
|
232 |
|
233 XRSurfaceData dstData = (XRSurfaceData) sg2d.surfaceData; |
|
234 XRSurfaceData srcData = (XRSurfaceData) getAccSrcSurface(dstData, bi); |
|
235 |
|
236 AffineTransform at = new AffineTransform(); |
|
237 at.translate(anchor.getX(), anchor.getY()); |
|
238 at.scale(anchor.getWidth() / ((double) bi.getWidth()), anchor.getHeight() / ((double) bi.getHeight())); |
|
239 |
121 try { |
240 try { |
122 at.invert(); |
241 at.invert(); |
123 } catch (NoninvertibleTransformException ex) { |
242 } catch (NoninvertibleTransformException ex) { |
124 at.setToIdentity(); |
243 at.setToIdentity(); |
125 } |
244 } |
126 |
245 srcData.setStaticSrcTx(at); |
127 int repeat = paint.isCyclic() ? XRUtils.RepeatReflect : XRUtils.RepeatPad; |
246 |
128 |
247 srcData.validateAsSource(at, XRUtils.RepeatNormal, XRUtils.ATransOpToXRQuality(sg2d.interpolationType)); |
129 XRBackend con = xrCompMan.getBackend(); |
248 xrCompMan.setTexturePaint(srcData); |
130 int gradient = con.createLinearGradient(pt1, pt2, fractions, pixels, repeat, at); |
249 } |
131 xrCompMan.setGradientPaint(new XRSurfaceData.XRInternalSurfaceData(con, gradient, at)); |
250 } |
132 } |
251 |
133 } |
252 public int[] convertToIntArgbPixels(Color[] colors) { |
134 |
|
135 public int getGradientLength(Point2D pt1, Point2D pt2) { |
|
136 double xDiff = Math.max(pt1.getX(), pt2.getX()) - Math.min(pt1.getX(), pt2.getX()); |
|
137 double yDiff = Math.max(pt1.getY(), pt2.getY()) - Math.min(pt1.getY(), pt2.getY()); |
|
138 return (int) Math.ceil(Math.sqrt(xDiff*xDiff + yDiff*yDiff)); |
|
139 } |
|
140 |
|
141 private static class XRLinearGradient extends XRPaints { |
|
142 |
|
143 @Override |
|
144 boolean isPaintValid(SunGraphics2D sg2d) { |
|
145 return true; |
|
146 } |
|
147 |
|
148 @Override |
|
149 void setXRPaint(SunGraphics2D sg2d, Paint pt) { |
|
150 LinearGradientPaint paint = (LinearGradientPaint) pt; |
|
151 boolean linear = (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB); |
|
152 |
|
153 Color[] colors = paint.getColors(); |
|
154 Point2D pt1 = paint.getStartPoint(); |
|
155 Point2D pt2 = paint.getEndPoint(); |
|
156 |
|
157 |
|
158 AffineTransform at = paint.getTransform(); |
|
159 at.preConcatenate(sg2d.transform); |
|
160 |
|
161 int repeat = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod()); |
|
162 float[] fractions = paint.getFractions(); |
|
163 int[] pixels = convertToIntArgbPixels(colors, linear); |
|
164 |
|
165 try { |
|
166 at.invert(); |
|
167 } catch (NoninvertibleTransformException ex) { |
|
168 ex.printStackTrace(); |
|
169 } |
|
170 |
|
171 XRBackend con = xrCompMan.getBackend(); |
|
172 int gradient = con.createLinearGradient(pt1, pt2, fractions, pixels, repeat, at); |
|
173 xrCompMan.setGradientPaint(new XRSurfaceData.XRInternalSurfaceData(con, gradient, at)); |
|
174 } |
|
175 } |
|
176 |
|
177 private static class XRRadialGradient extends XRPaints { |
|
178 |
|
179 @Override |
|
180 boolean isPaintValid(SunGraphics2D sg2d) { |
|
181 RadialGradientPaint grad = (RadialGradientPaint) sg2d.paint; |
|
182 return grad.getFocusPoint().equals(grad.getCenterPoint()); |
|
183 } |
|
184 |
|
185 @Override |
|
186 void setXRPaint(SunGraphics2D sg2d, Paint pt) { |
|
187 RadialGradientPaint paint = (RadialGradientPaint) pt; |
|
188 boolean linear = (paint.getColorSpace() == ColorSpaceType.LINEAR_RGB); |
|
189 Color[] colors = paint.getColors(); |
|
190 Point2D center = paint.getCenterPoint(); |
|
191 Point2D focus = paint.getFocusPoint(); |
|
192 |
|
193 int repeat = XRUtils.getRepeatForCycleMethod(paint.getCycleMethod()); |
|
194 float[] fractions = paint.getFractions(); |
|
195 int[] pixels = convertToIntArgbPixels(colors, linear); |
|
196 float radius = paint.getRadius(); |
|
197 |
|
198 // save original (untransformed) center and focus points |
|
199 double cx = center.getX(); |
|
200 double cy = center.getY(); |
|
201 double fx = focus.getX(); |
|
202 double fy = focus.getY(); |
|
203 |
|
204 AffineTransform at = paint.getTransform(); |
|
205 at.preConcatenate(sg2d.transform); |
|
206 focus = at.transform(focus, focus); |
|
207 |
|
208 // transform unit circle to gradient coords; we start with the |
|
209 // unit circle (center=(0,0), focus on positive x-axis, radius=1) |
|
210 // and then transform into gradient space |
|
211 at.translate(cx, cy); |
|
212 at.rotate(fx - cx, fy - cy); |
|
213 // at.scale(radius, radius); |
|
214 |
|
215 // invert to get mapping from device coords to unit circle |
|
216 try { |
|
217 at.invert(); |
|
218 } catch (Exception e) { |
|
219 at.setToScale(0.0, 0.0); |
|
220 } |
|
221 focus = at.transform(focus, focus); |
|
222 |
|
223 // clamp the focus point so that it does not rest on, or outside |
|
224 // of, the circumference of the gradient circle |
|
225 fx = Math.min(focus.getX(), 0.99); |
|
226 |
|
227 XRBackend con = xrCompMan.getBackend(); |
|
228 int gradient = con.createRadialGradient(new Point2D.Float(0, 0), new Point2D.Float(0, 0), 0, radius, fractions, pixels, repeat, at); |
|
229 xrCompMan.setGradientPaint(new XRSurfaceData.XRInternalSurfaceData(con, gradient, at)); |
|
230 } |
|
231 } |
|
232 |
|
233 private static class XRTexture extends XRPaints { |
|
234 |
|
235 @Override |
|
236 boolean isPaintValid(SunGraphics2D sg2d) { |
|
237 TexturePaint paint = (TexturePaint) sg2d.paint; |
|
238 BufferedImage bi = paint.getImage(); |
|
239 XRSurfaceData dstData = (XRSurfaceData) sg2d.getDestSurface(); |
|
240 |
|
241 SurfaceData srcData = dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null); |
|
242 if (!(srcData instanceof XRSurfaceData)) { |
|
243 // REMIND: this is a hack that attempts to cache the system |
|
244 // memory image from the TexturePaint instance into an |
|
245 // OpenGL texture... |
|
246 srcData = dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null); |
|
247 if (!(srcData instanceof XRSurfaceData)) { |
|
248 return false; |
|
249 } |
|
250 } |
|
251 |
|
252 return true; |
|
253 } |
|
254 |
|
255 @Override |
|
256 void setXRPaint(SunGraphics2D sg2d, Paint pt) { |
|
257 TexturePaint paint = (TexturePaint) pt; |
|
258 |
|
259 BufferedImage bi = paint.getImage(); |
|
260 SurfaceData dstData = sg2d.surfaceData; |
|
261 SurfaceData srcData = dstData.getSourceSurfaceData(bi, SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null); |
|
262 |
|
263 // REMIND: this hack tries to ensure that we have a cached texture |
|
264 if (!(srcData instanceof XRSurfaceData)) { |
|
265 srcData = dstData.getSourceSurfaceData(paint.getImage(), SunGraphics2D.TRANSFORM_ISIDENT, CompositeType.SrcOver, null); |
|
266 if (!(srcData instanceof XRSurfaceData)) { |
|
267 throw new InternalError("Surface not cachable"); |
|
268 } |
|
269 } |
|
270 |
|
271 XRSurfaceData x11SrcData = (XRSurfaceData) srcData; |
|
272 |
|
273 AffineTransform at = (AffineTransform) sg2d.transform.clone(); |
|
274 Rectangle2D anchor = paint.getAnchorRect(); |
|
275 at.translate(anchor.getX(), anchor.getY()); |
|
276 at.scale(anchor.getWidth() / ((double) bi.getWidth()), anchor.getHeight() / ((double) bi.getHeight())); |
|
277 |
|
278 try { |
|
279 at.invert(); |
|
280 } catch (NoninvertibleTransformException ex) { |
|
281 at.setToIdentity(); /* TODO: Right thing to do in this case? */ |
|
282 } |
|
283 |
|
284 x11SrcData.validateAsSource(at, XRUtils.RepeatNormal, XRUtils.ATransOpToXRQuality(sg2d.interpolationType)); |
|
285 xrCompMan.setTexturePaint(((XRSurfaceData) srcData)); |
|
286 } |
|
287 } |
|
288 |
|
289 public int[] convertToIntArgbPixels(Color[] colors, boolean linear) { |
|
290 int[] pixels = new int[colors.length]; |
253 int[] pixels = new int[colors.length]; |
291 for (int i = 0; i < colors.length; i++) { |
254 for (int i = 0; i < colors.length; i++) { |
292 pixels[i] = colorToIntArgbPixel(colors[i], linear); |
255 pixels[i] = colorToIntArgbPixel(colors[i]); |
293 } |
256 } |
294 return pixels; |
257 return pixels; |
295 } |
258 } |
296 |
259 |
297 public int colorToIntArgbPixel(Color c, boolean linear) { |
260 public int colorToIntArgbPixel(Color c) { |
298 int rgb = c.getRGB(); |
261 int rgb = c.getRGB(); |
299 |
262 int a = (int) Math.round(xrCompMan.getExtraAlpha() * (rgb >>> 24)); |
300 int a = rgb >>> 24; |
263 return ((a << 24) | (rgb & 0x00FFFFFF)); |
301 int r = (rgb >> 16) & 0xff; |
|
302 int g = (rgb >> 8) & 0xff; |
|
303 int b = (rgb) & 0xff; |
|
304 if (linear) { |
|
305 r = BufferedPaints.convertSRGBtoLinearRGB(r); |
|
306 g = BufferedPaints.convertSRGBtoLinearRGB(g); |
|
307 b = BufferedPaints.convertSRGBtoLinearRGB(b); |
|
308 } |
|
309 |
|
310 a *= xrCompMan.getExtraAlpha(); |
|
311 |
|
312 return ((a << 24) | (r << 16) | (g << 8) | (b)); |
|
313 } |
264 } |
314 } |
265 } |