001: /*
002: * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.java2d.d3d;
027:
028: import java.awt.Composite;
029: import java.awt.Polygon;
030: import java.awt.Shape;
031: import java.awt.geom.AffineTransform;
032: import java.awt.geom.Arc2D;
033: import java.awt.geom.Ellipse2D;
034: import java.awt.geom.IllegalPathStateException;
035: import java.awt.geom.PathIterator;
036: import java.awt.geom.RoundRectangle2D;
037: import sun.java2d.SunGraphics2D;
038: import sun.java2d.pipe.Region;
039: import sun.java2d.SurfaceData;
040: import sun.java2d.loops.GraphicsPrimitive;
041: import sun.java2d.pipe.LoopPipe;
042: import sun.java2d.pipe.ShapeSpanIterator;
043: import sun.java2d.pipe.SpanIterator;
044:
045: import static sun.java2d.d3d.D3DContext.*;
046: import sun.java2d.windows.DDRenderer;
047:
048: public class D3DRenderer extends DDRenderer {
049:
050: native boolean doDrawLineD3D(long pData, long pCtx, int x1, int y1,
051: int x2, int y2);
052:
053: native boolean doDrawRectD3D(long pData, long pCtx, int x, int y,
054: int w, int h);
055:
056: native boolean doFillRectD3D(long pData, long pCtx, int x, int y,
057: int width, int height);
058:
059: native void doDrawPoly(long pData, long pCtx, int transx,
060: int transy, int[] xpoints, int[] ypoints, int npoints,
061: boolean isclosed);
062:
063: native void devFillSpans(long pData, long pCtx, SpanIterator si,
064: long iterator, int transx, int transy);
065:
066: private long getContext(SunGraphics2D sg2d) {
067: AffineTransform at = sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE ? null
068: : sg2d.transform;
069: int ctxflags = (sg2d.eargb >>> 24) == 0xff ? SRC_IS_OPAQUE
070: : NO_CONTEXT_FLAGS;
071: return D3DContext.getContext(null, sg2d.surfaceData, sg2d
072: .getCompClip(), sg2d.getComposite(), at, sg2d.eargb,
073: ctxflags);
074: }
075:
076: @Override
077: public void drawLine(SunGraphics2D sg2d, int x1, int y1, int x2,
078: int y2) {
079: synchronized (D3DContext.LOCK) {
080: doDrawLineD3D(sg2d.surfaceData.getNativeOps(),
081: getContext(sg2d), x1 + sg2d.transX, y1
082: + sg2d.transY, x2 + sg2d.transX, y2
083: + sg2d.transY);
084: }
085: }
086:
087: @Override
088: public void fillRect(SunGraphics2D sg2d, int x, int y, int width,
089: int height) {
090: synchronized (D3DContext.LOCK) {
091: doFillRectD3D(sg2d.surfaceData.getNativeOps(),
092: getContext(sg2d), sg2d.transX + x, sg2d.transY + y,
093: width, height);
094: }
095: }
096:
097: @Override
098: public void drawRect(SunGraphics2D sg2d, int x, int y, int width,
099: int height) {
100: synchronized (D3DContext.LOCK) {
101: doDrawRectD3D(sg2d.surfaceData.getNativeOps(),
102: getContext(sg2d), x + sg2d.transX, sg2d.transY + y,
103: width, height);
104: }
105: }
106:
107: @Override
108: public void drawPolyline(SunGraphics2D sg2d, int xpoints[],
109: int ypoints[], int npoints) {
110: synchronized (D3DContext.LOCK) {
111: doDrawPoly(sg2d.surfaceData.getNativeOps(),
112: getContext(sg2d), sg2d.transX, sg2d.transY,
113: xpoints, ypoints, npoints, false);
114: }
115: }
116:
117: @Override
118: public void drawPolygon(SunGraphics2D sg2d, int xpoints[],
119: int ypoints[], int npoints) {
120: synchronized (D3DContext.LOCK) {
121: doDrawPoly(sg2d.surfaceData.getNativeOps(),
122: getContext(sg2d), sg2d.transX, sg2d.transY,
123: xpoints, ypoints, npoints, true);
124: }
125: }
126:
127: @Override
128: public void drawRoundRect(SunGraphics2D sg2d, int x, int y,
129: int width, int height, int arcWidth, int arcHeight) {
130: draw(sg2d, new RoundRectangle2D.Float(x, y, width, height,
131: arcWidth, arcHeight));
132: }
133:
134: @Override
135: public void drawOval(SunGraphics2D sg2d, int x, int y, int width,
136: int height) {
137: draw(sg2d, new Ellipse2D.Float(x, y, width, height));
138: }
139:
140: @Override
141: public void drawArc(SunGraphics2D sg2d, int x, int y, int width,
142: int height, int startAngle, int arcAngle) {
143: draw(sg2d, new Arc2D.Float(x, y, width, height, startAngle,
144: arcAngle, Arc2D.OPEN));
145: }
146:
147: @Override
148: public void fillRoundRect(SunGraphics2D sg2d, int x, int y,
149: int width, int height, int arcWidth, int arcHeight) {
150: fill(sg2d, new RoundRectangle2D.Float(x, y, width, height,
151: arcWidth, arcHeight));
152: }
153:
154: @Override
155: public void fillOval(SunGraphics2D sg2d, int x, int y, int width,
156: int height) {
157: fill(sg2d, new Ellipse2D.Float(x, y, width, height));
158: }
159:
160: @Override
161: public void fillArc(SunGraphics2D sg2d, int x, int y, int width,
162: int height, int startAngle, int arcAngle) {
163: fill(sg2d, new Arc2D.Float(x, y, width, height, startAngle,
164: arcAngle, Arc2D.PIE));
165: }
166:
167: @Override
168: public void fillPolygon(SunGraphics2D sg2d, int xpoints[],
169: int ypoints[], int npoints) {
170: fill(sg2d, new Polygon(xpoints, ypoints, npoints));
171: }
172:
173: @Override
174: public void draw(SunGraphics2D sg2d, Shape s) {
175: if (sg2d.strokeState == sg2d.STROKE_THIN) {
176: Polygon p;
177: if (s instanceof Polygon) {
178: p = (Polygon) s;
179: drawPolygon(sg2d, p.xpoints, p.ypoints, p.npoints);
180: return;
181: }
182: // we're letting d3d handle the transforms
183: PathIterator pi = s.getPathIterator(null, 0.5f);
184: p = new Polygon();
185: float coords[] = new float[2];
186: while (!pi.isDone()) {
187: switch (pi.currentSegment(coords)) {
188: case PathIterator.SEG_MOVETO:
189: if (p.npoints > 1) {
190: drawPolyline(sg2d, p.xpoints, p.ypoints,
191: p.npoints);
192: }
193: p.reset();
194: p.addPoint((int) Math.floor(coords[0]), (int) Math
195: .floor(coords[1]));
196: break;
197: case PathIterator.SEG_LINETO:
198: if (p.npoints == 0) {
199: throw new IllegalPathStateException(
200: "missing initial moveto in path definition");
201: }
202: p.addPoint((int) Math.floor(coords[0]), (int) Math
203: .floor(coords[1]));
204: break;
205: case PathIterator.SEG_CLOSE:
206: if (p.npoints > 0) {
207: p.addPoint(p.xpoints[0], p.ypoints[0]);
208: }
209: break;
210: default:
211: throw new IllegalPathStateException(
212: "path not flattened");
213: }
214: pi.next();
215: }
216: if (p.npoints > 1) {
217: drawPolyline(sg2d, p.xpoints, p.ypoints, p.npoints);
218: }
219: } else if (sg2d.strokeState < sg2d.STROKE_CUSTOM) {
220: ShapeSpanIterator si = LoopPipe.getStrokeSpans(sg2d, s);
221: try {
222: synchronized (D3DContext.LOCK) {
223: int ctxflags = (sg2d.eargb >>> 24) == 0xff ? SRC_IS_OPAQUE
224: : NO_CONTEXT_FLAGS;
225: // in this case the spans will be pre-transformed, so we
226: // pass null transform to getContext
227: long pCtx = D3DContext.getContext(null,
228: sg2d.surfaceData, sg2d.getCompClip(), sg2d
229: .getComposite(),
230: null /*transform*/, sg2d.eargb/*pixel*/,
231: ctxflags);
232: devFillSpans(sg2d.surfaceData.getNativeOps(), pCtx,
233: si, si.getNativeIterator(), 0, 0);
234: }
235: } finally {
236: si.dispose();
237: }
238: } else {
239: fill(sg2d, sg2d.stroke.createStrokedShape(s));
240: }
241: }
242:
243: @Override
244: public void fill(SunGraphics2D sg2d, Shape s) {
245: AffineTransform at;
246: int transx, transy;
247:
248: if (sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE) {
249: // Transform (translation) will be done by devFillSpans
250: at = null;
251: transx = sg2d.transX;
252: transy = sg2d.transY;
253: } else {
254: // Transform will be done by the PathIterator
255: at = sg2d.transform;
256: transx = transy = 0;
257: }
258:
259: ShapeSpanIterator ssi = new ShapeSpanIterator(sg2d, false);
260: try {
261: // Subtract transx/y from the SSI clip to match the
262: // (potentially untranslated) geometry fed to it
263: Region clip = sg2d.getCompClip();
264: ssi.setOutputAreaXYXY(clip.getLoX() - transx, clip.getLoY()
265: - transy, clip.getHiX() - transx, clip.getHiY()
266: - transy);
267: ssi.appendPath(s.getPathIterator(at));
268: synchronized (D3DContext.LOCK) {
269: int ctxflags = (sg2d.eargb >>> 24) == 0xff ? SRC_IS_OPAQUE
270: : NO_CONTEXT_FLAGS;
271: long pCtx = D3DContext.getContext(null,
272: sg2d.surfaceData, sg2d.getCompClip(), sg2d
273: .getComposite(), null/*transform*/,
274: sg2d.eargb/*pixel*/, ctxflags);
275: devFillSpans(sg2d.surfaceData.getNativeOps(), pCtx,
276: ssi, ssi.getNativeIterator(), transx, transy);
277: }
278: } finally {
279: ssi.dispose();
280: }
281: }
282:
283: D3DRenderer traceWrapD3D() {
284: return new Tracer();
285: }
286:
287: private class Tracer extends D3DRenderer {
288: @Override
289: public void drawLine(SunGraphics2D sg2d, int x1, int y1,
290: int x2, int y2) {
291: GraphicsPrimitive.tracePrimitive("D3DDrawLine");
292: super .drawLine(sg2d, x1, y1, x2, y2);
293: }
294:
295: @Override
296: public void drawRect(SunGraphics2D sg2d, int x, int y, int w,
297: int h) {
298: GraphicsPrimitive.tracePrimitive("D3DDrawRect");
299: super .drawRect(sg2d, x, y, w, h);
300: }
301:
302: @Override
303: public void drawPolyline(SunGraphics2D sg2d, int[] xPoints,
304: int[] yPoints, int nPoints) {
305: GraphicsPrimitive.tracePrimitive("D3DDrawPolyline");
306: super .drawPolyline(sg2d, xPoints, yPoints, nPoints);
307: }
308:
309: @Override
310: public void drawPolygon(SunGraphics2D sg2d, int[] xPoints,
311: int[] yPoints, int nPoints) {
312: GraphicsPrimitive.tracePrimitive("D3DDrawPolygon");
313: super .drawPolygon(sg2d, xPoints, yPoints, nPoints);
314: }
315:
316: @Override
317: public void fillRect(SunGraphics2D sg2d, int x, int y, int w,
318: int h) {
319: GraphicsPrimitive.tracePrimitive("D3DFillRect");
320: super .fillRect(sg2d, x, y, w, h);
321: }
322:
323: @Override
324: void devFillSpans(long pData, long pCtx, SpanIterator si,
325: long iterator, int transx, int transy) {
326: GraphicsPrimitive.tracePrimitive("D3DFillSpans");
327: super .devFillSpans(pData, pCtx, si, iterator, transx,
328: transy);
329: }
330:
331: @Override
332: public void devCopyArea(SurfaceData sData, int srcx, int srcy,
333: int dx, int dy, int w, int h) {
334: GraphicsPrimitive.tracePrimitive("DXCopyArea");
335: super.devCopyArea(sData, srcx, srcy, dx, dy, w, h);
336: }
337:
338: }
339: }
|