blob: c56cd7b0802615db59ae3cfdb2fb04bd8ab52e82 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.java2d.d3d;
27
28import java.awt.Composite;
29import java.awt.Polygon;
30import java.awt.Shape;
31import java.awt.geom.AffineTransform;
32import java.awt.geom.Arc2D;
33import java.awt.geom.Ellipse2D;
34import java.awt.geom.IllegalPathStateException;
35import java.awt.geom.PathIterator;
36import java.awt.geom.RoundRectangle2D;
37import sun.java2d.SunGraphics2D;
38import sun.java2d.pipe.Region;
39import sun.java2d.SurfaceData;
40import sun.java2d.loops.GraphicsPrimitive;
41import sun.java2d.pipe.LoopPipe;
42import sun.java2d.pipe.ShapeSpanIterator;
43import sun.java2d.pipe.SpanIterator;
44
45import static sun.java2d.d3d.D3DContext.*;
46import sun.java2d.windows.DDRenderer;
47
48public class D3DRenderer extends DDRenderer {
49
50 native boolean doDrawLineD3D(long pData, long pCtx,
51 int x1, int y1, int x2, int y2);
52 native boolean doDrawRectD3D(long pData, long pCtx,
53 int x, int y, int w, int h);
54 native boolean doFillRectD3D(long pData, long pCtx, int x, int y,
55 int width, int height);
56 native void doDrawPoly(long pData, long pCtx, int transx, int transy,
57 int[] xpoints, int[] ypoints,
58 int npoints, boolean isclosed);
59 native void devFillSpans(long pData, long pCtx, SpanIterator si,
60 long iterator, int transx, int transy);
61
62
63 private long getContext(SunGraphics2D sg2d) {
64 AffineTransform at =
65 sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE ?
66 null : sg2d.transform;
67 int ctxflags = (sg2d.eargb >>> 24) == 0xff ?
68 SRC_IS_OPAQUE : NO_CONTEXT_FLAGS;
69 return D3DContext.getContext(null, sg2d.surfaceData,
70 sg2d.getCompClip(),
71 sg2d.getComposite(),
72 at,
73 sg2d.eargb,
74 ctxflags);
75 }
76
77 @Override
78 public void drawLine(SunGraphics2D sg2d,
79 int x1, int y1, int x2, int y2)
80 {
81 synchronized (D3DContext.LOCK) {
82 doDrawLineD3D(sg2d.surfaceData.getNativeOps(),
83 getContext(sg2d),
84 x1 + sg2d.transX, y1 + sg2d.transY,
85 x2 + sg2d.transX, y2 + sg2d.transY);
86 }
87 }
88
89 @Override
90 public void fillRect(SunGraphics2D sg2d,
91 int x, int y, int width, int height)
92 {
93 synchronized (D3DContext.LOCK) {
94 doFillRectD3D(sg2d.surfaceData.getNativeOps(),
95 getContext(sg2d),
96 sg2d.transX + x, sg2d.transY + y, width, height);
97 }
98 }
99
100 @Override
101 public void drawRect(SunGraphics2D sg2d,
102 int x, int y, int width, int height)
103 {
104 synchronized (D3DContext.LOCK) {
105 doDrawRectD3D(sg2d.surfaceData.getNativeOps(),
106 getContext(sg2d),
107 x + sg2d.transX, sg2d.transY + y, width, height);
108 }
109 }
110
111 @Override
112 public void drawPolyline(SunGraphics2D sg2d,
113 int xpoints[], int ypoints[], int npoints)
114 {
115 synchronized (D3DContext.LOCK) {
116 doDrawPoly(sg2d.surfaceData.getNativeOps(),
117 getContext(sg2d),
118 sg2d.transX, sg2d.transY,
119 xpoints, ypoints, npoints, false);
120 }
121 }
122
123 @Override
124 public void drawPolygon(SunGraphics2D sg2d,
125 int xpoints[], int ypoints[], int npoints)
126 {
127 synchronized (D3DContext.LOCK) {
128 doDrawPoly(sg2d.surfaceData.getNativeOps(),
129 getContext(sg2d),
130 sg2d.transX, sg2d.transY,
131 xpoints, ypoints, npoints, true);
132 }
133 }
134
135 @Override
136 public void drawRoundRect(SunGraphics2D sg2d,
137 int x, int y, int width, int height,
138 int arcWidth, int arcHeight)
139 {
140 draw(sg2d, new RoundRectangle2D.Float(x, y, width, height,
141 arcWidth, arcHeight));
142 }
143
144 @Override
145 public void drawOval(SunGraphics2D sg2d,
146 int x, int y, int width, int height)
147 {
148 draw(sg2d, new Ellipse2D.Float(x, y, width, height));
149 }
150
151 @Override
152 public void drawArc(SunGraphics2D sg2d,
153 int x, int y, int width, int height,
154 int startAngle, int arcAngle)
155 {
156 draw(sg2d, new Arc2D.Float(x, y, width, height,
157 startAngle, arcAngle,
158 Arc2D.OPEN));
159 }
160
161 @Override
162 public void fillRoundRect(SunGraphics2D sg2d,
163 int x, int y, int width, int height,
164 int arcWidth, int arcHeight)
165 {
166 fill(sg2d, new RoundRectangle2D.Float(x, y, width, height,
167 arcWidth, arcHeight));
168 }
169
170 @Override
171 public void fillOval(SunGraphics2D sg2d,
172 int x, int y, int width, int height)
173 {
174 fill(sg2d, new Ellipse2D.Float(x, y, width, height));
175 }
176
177 @Override
178 public void fillArc(SunGraphics2D sg2d,
179 int x, int y, int width, int height,
180 int startAngle, int arcAngle)
181 {
182 fill(sg2d, new Arc2D.Float(x, y, width, height,
183 startAngle, arcAngle, Arc2D.PIE));
184 }
185
186 @Override
187 public void fillPolygon(SunGraphics2D sg2d,
188 int xpoints[], int ypoints[],
189 int npoints)
190 {
191 fill(sg2d, new Polygon(xpoints, ypoints, npoints));
192 }
193
194 @Override
195 public void draw(SunGraphics2D sg2d, Shape s)
196 {
197 if (sg2d.strokeState == sg2d.STROKE_THIN) {
198 Polygon p;
199 if (s instanceof Polygon) {
200 p = (Polygon) s;
201 drawPolygon(sg2d, p.xpoints, p.ypoints, p.npoints);
202 return;
203 }
204 // we're letting d3d handle the transforms
205 PathIterator pi = s.getPathIterator(null, 0.5f);
206 p = new Polygon();
207 float coords[] = new float[2];
208 while (!pi.isDone()) {
209 switch (pi.currentSegment(coords)) {
210 case PathIterator.SEG_MOVETO:
211 if (p.npoints > 1) {
212 drawPolyline(sg2d, p.xpoints, p.ypoints, p.npoints);
213 }
214 p.reset();
215 p.addPoint((int) Math.floor(coords[0]),
216 (int) Math.floor(coords[1]));
217 break;
218 case PathIterator.SEG_LINETO:
219 if (p.npoints == 0) {
220 throw new IllegalPathStateException
221 ("missing initial moveto in path definition");
222 }
223 p.addPoint((int) Math.floor(coords[0]),
224 (int) Math.floor(coords[1]));
225 break;
226 case PathIterator.SEG_CLOSE:
227 if (p.npoints > 0) {
228 p.addPoint(p.xpoints[0], p.ypoints[0]);
229 }
230 break;
231 default:
232 throw new
233 IllegalPathStateException("path not flattened");
234 }
235 pi.next();
236 }
237 if (p.npoints > 1) {
238 drawPolyline(sg2d, p.xpoints, p.ypoints, p.npoints);
239 }
240 } else if (sg2d.strokeState < sg2d.STROKE_CUSTOM) {
241 ShapeSpanIterator si = LoopPipe.getStrokeSpans(sg2d, s);
242 try {
243 synchronized (D3DContext.LOCK) {
244 int ctxflags = (sg2d.eargb >>> 24) == 0xff ?
245 SRC_IS_OPAQUE : NO_CONTEXT_FLAGS;
246 // in this case the spans will be pre-transformed, so we
247 // pass null transform to getContext
248 long pCtx = D3DContext.getContext(null, sg2d.surfaceData,
249 sg2d.getCompClip(),
250 sg2d.getComposite(),
251 null /*transform*/,
252 sg2d.eargb/*pixel*/,
253 ctxflags);
254 devFillSpans(sg2d.surfaceData.getNativeOps(), pCtx, si,
255 si.getNativeIterator(), 0, 0);
256 }
257 } finally {
258 si.dispose();
259 }
260 } else {
261 fill(sg2d, sg2d.stroke.createStrokedShape(s));
262 }
263 }
264
265 @Override
266 public void fill(SunGraphics2D sg2d, Shape s) {
267 AffineTransform at;
268 int transx, transy;
269
270 if ( sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE) {
271 // Transform (translation) will be done by devFillSpans
272 at = null;
273 transx = sg2d.transX;
274 transy = sg2d.transY;
275 } else {
276 // Transform will be done by the PathIterator
277 at = sg2d.transform;
278 transx = transy = 0;
279 }
280
281 ShapeSpanIterator ssi = LoopPipe.getFillSSI(sg2d);
282 try {
283 // Subtract transx/y from the SSI clip to match the
284 // (potentially untranslated) geometry fed to it
285 Region clip = sg2d.getCompClip();
286 ssi.setOutputAreaXYXY(clip.getLoX() - transx,
287 clip.getLoY() - transy,
288 clip.getHiX() - transx,
289 clip.getHiY() - transy);
290 ssi.appendPath(s.getPathIterator(at));
291 synchronized (D3DContext.LOCK) {
292 int ctxflags = (sg2d.eargb >>> 24) == 0xff ?
293 SRC_IS_OPAQUE : NO_CONTEXT_FLAGS;
294 long pCtx = D3DContext.getContext(null, sg2d.surfaceData,
295 sg2d.getCompClip(),
296 sg2d.getComposite(),
297 null/*transform*/,
298 sg2d.eargb/*pixel*/,
299 ctxflags);
300 devFillSpans(sg2d.surfaceData.getNativeOps(), pCtx, ssi,
301 ssi.getNativeIterator(),
302 transx, transy);
303 }
304 } finally {
305 ssi.dispose();
306 }
307 }
308
309 D3DRenderer traceWrapD3D() {
310 return new Tracer();
311 }
312
313 private class Tracer extends D3DRenderer {
314 @Override
315 public void drawLine(SunGraphics2D sg2d,
316 int x1, int y1, int x2, int y2)
317 {
318 GraphicsPrimitive.tracePrimitive("D3DDrawLine");
319 super.drawLine(sg2d, x1, y1, x2, y2);
320 }
321 @Override
322 public void drawRect(SunGraphics2D sg2d, int x, int y, int w, int h) {
323 GraphicsPrimitive.tracePrimitive("D3DDrawRect");
324 super.drawRect(sg2d, x, y, w, h);
325 }
326 @Override
327 public void drawPolyline(SunGraphics2D sg2d,
328 int[] xPoints, int[] yPoints,
329 int nPoints)
330 {
331 GraphicsPrimitive.tracePrimitive("D3DDrawPolyline");
332 super.drawPolyline(sg2d, xPoints, yPoints, nPoints);
333 }
334 @Override
335 public void drawPolygon(SunGraphics2D sg2d,
336 int[] xPoints, int[] yPoints,
337 int nPoints)
338 {
339 GraphicsPrimitive.tracePrimitive("D3DDrawPolygon");
340 super.drawPolygon(sg2d, xPoints, yPoints, nPoints);
341 }
342 @Override
343 public void fillRect(SunGraphics2D sg2d, int x, int y, int w, int h) {
344 GraphicsPrimitive.tracePrimitive("D3DFillRect");
345 super.fillRect(sg2d, x, y, w, h);
346 }
347 @Override
348 void devFillSpans(long pData, long pCtx, SpanIterator si, long iterator,
349 int transx, int transy)
350 {
351 GraphicsPrimitive.tracePrimitive("D3DFillSpans");
352 super.devFillSpans(pData, pCtx, si, iterator, transx, transy);
353 }
354 @Override
355 public void devCopyArea(SurfaceData sData,
356 int srcx, int srcy,
357 int dx, int dy,
358 int w, int h)
359 {
360 GraphicsPrimitive.tracePrimitive("DXCopyArea");
361 super.devCopyArea(sData, srcx, srcy, dx, dy, w, h);
362 }
363
364 }
365}