36 import sun.java2d.pipe.ShapeDrawPipe;
37 import sun.java2d.pipe.SpanIterator;
38 import sun.java2d.pipe.ShapeSpanIterator;
39 import sun.java2d.pipe.LoopPipe;
40
41 import static sun.java2d.xr.XRUtils.clampToShort;
42 import static sun.java2d.xr.XRUtils.clampToUShort;
43
44 /**
45 * XRender provides only accalerated rectangles. To emulate higher "order"
46 * geometry we have to pass everything else to DoPath/FillSpans.
47 *
48 * TODO: DrawRect could be instrified
49 *
50 * @author Clemens Eisserer
51 */
52
53 public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
54 XRDrawHandler drawHandler;
55 MaskTileManager tileManager;
56
57 public XRRenderer(MaskTileManager tileManager) {
58 this.tileManager = tileManager;
59 this.drawHandler = new XRDrawHandler();
60 }
61
62 /**
63 * Common validate method, used by all XRRender functions to validate the
64 * destination context.
65 */
66 private final void validateSurface(SunGraphics2D sg2d) {
67 XRSurfaceData xrsd = (XRSurfaceData) sg2d.surfaceData;
68 xrsd.validateAsDestination(sg2d, sg2d.getCompClip());
69 xrsd.maskBuffer.validateCompositeState(sg2d.composite, sg2d.transform,
70 sg2d.paint, sg2d);
71 }
72
73 public void drawLine(SunGraphics2D sg2d, int x1, int y1, int x2, int y2) {
74 Region compClip = sg2d.getCompClip();
75 int transX1 = Region.clipAdd(x1, sg2d.transX);
76 int transY1 = Region.clipAdd(y1, sg2d.transY);
77 int transX2 = Region.clipAdd(x2, sg2d.transX);
78 int transY2 = Region.clipAdd(y2, sg2d.transY);
79
80 // Non clipped fast path
81 if (compClip.contains(transX1, transY1)
82 && compClip.contains(transX2, transY2)) {
83 SunToolkit.awtLock();
84 try {
85 validateSurface(sg2d);
86 tileManager.addLine(transX1, transY1, transX2, transY2);
87 tileManager.fillMask((XRSurfaceData) sg2d.surfaceData);
88 } finally {
89 SunToolkit.awtUnlock();
90 }
91 } else {
92 draw(sg2d, new Line2D.Float(x1, y1, x2, y2));
93 }
94 }
95
96 public void drawRect(SunGraphics2D sg2d,
97 int x, int y, int width, int height) {
98 draw(sg2d, new Rectangle2D.Float(x, y, width, height));
99 }
100
101 public void drawPolyline(SunGraphics2D sg2d,
102 int xpoints[], int ypoints[], int npoints) {
103 Path2D.Float p2d = new Path2D.Float();
104 if (npoints > 1) {
105 p2d.moveTo(xpoints[0], ypoints[0]);
106 for (int i = 1; i < npoints; i++) {
107 p2d.lineTo(xpoints[i], ypoints[i]);
108 }
109 }
110
111 draw(sg2d, p2d);
112 }
113
131
132 int x2 = Region.dimAdd(x, width);
133 int y2 = Region.dimAdd(y, height);
134
135 if (x2 < Short.MIN_VALUE || y2 < Short.MIN_VALUE) {
136 return;
137 }
138
139 x = clampToShort(x);
140 y = clampToShort(y);
141 width = clampToUShort(x2 - x);
142 height = clampToUShort(y2 - y);
143
144 if (width == 0 || height == 0) {
145 return;
146 }
147
148 SunToolkit.awtLock();
149 try {
150 validateSurface(sg2d);
151 tileManager.addRect(x, y, width, height);
152 tileManager.fillMask((XRSurfaceData) sg2d.surfaceData);
153 } finally {
154 SunToolkit.awtUnlock();
155 }
156 }
157
158 public void fillPolygon(SunGraphics2D sg2d,
159 int xpoints[], int ypoints[], int npoints) {
160 fill(sg2d, new Polygon(xpoints, ypoints, npoints));
161 }
162
163 public void drawRoundRect(SunGraphics2D sg2d,
164 int x, int y, int width, int height,
165 int arcWidth, int arcHeight) {
166 draw(sg2d, new RoundRectangle2D.Float(x, y, width, height,
167 arcWidth, arcHeight));
168 }
169
170 public void fillRoundRect(SunGraphics2D sg2d, int x, int y,
171 int width, int height,
182 public void fillOval(SunGraphics2D sg2d,
183 int x, int y, int width, int height) {
184 fill(sg2d, new Ellipse2D.Float(x, y, width, height));
185 }
186
187 public void drawArc(SunGraphics2D sg2d,
188 int x, int y, int width, int height,
189 int startAngle, int arcAngle) {
190 draw(sg2d, new Arc2D.Float(x, y, width, height,
191 startAngle, arcAngle, Arc2D.OPEN));
192 }
193
194 public void fillArc(SunGraphics2D sg2d,
195 int x, int y, int width, int height,
196 int startAngle, int arcAngle) {
197 fill(sg2d, new Arc2D.Float(x, y, width, height,
198 startAngle, arcAngle, Arc2D.PIE));
199 }
200
201 private class XRDrawHandler extends ProcessPath.DrawHandler {
202
203 XRDrawHandler() {
204 // these are bogus values; the caller will use validate()
205 // to ensure that they are set properly prior to each usage
206 super(0, 0, 0, 0);
207 }
208
209 /**
210 * This method needs to be called prior to each draw/fillPath()
211 * operation to ensure the clip bounds are up to date.
212 */
213 void validate(SunGraphics2D sg2d) {
214 Region clip = sg2d.getCompClip();
215 setBounds(clip.getLoX(), clip.getLoY(),
216 clip.getHiX(), clip.getHiY(), sg2d.strokeHint);
217 validateSurface(sg2d);
218 }
219
220 public void drawLine(int x1, int y1, int x2, int y2) {
221 tileManager.addLine(x1, y1, x2, y2);
222 }
223
224 public void drawPixel(int x, int y) {
225 tileManager.addRect(x, y, 1, 1);
226 }
227
228 public void drawScanline(int x1, int x2, int y) {
229 tileManager.addRect(x1, y, x2 - x1 + 1, 1);
230 }
231 }
232
233 protected void drawPath(SunGraphics2D sg2d, Path2D.Float p2df,
234 int transx, int transy) {
235 SunToolkit.awtLock();
236 try {
237 validateSurface(sg2d);
238 drawHandler.validate(sg2d);
239 ProcessPath.drawPath(drawHandler, p2df, transx, transy);
240 tileManager.fillMask(((XRSurfaceData) sg2d.surfaceData));
241 } finally {
242 SunToolkit.awtUnlock();
243 }
244 }
245
246 protected void fillPath(SunGraphics2D sg2d, Path2D.Float p2df,
247 int transx, int transy) {
248 SunToolkit.awtLock();
249 try {
250 validateSurface(sg2d);
251 drawHandler.validate(sg2d);
252 ProcessPath.fillPath(drawHandler, p2df, transx, transy);
253 tileManager.fillMask(((XRSurfaceData) sg2d.surfaceData));
254 } finally {
255 SunToolkit.awtUnlock();
256 }
257 }
258
259 protected void fillSpans(SunGraphics2D sg2d, SpanIterator si,
260 int transx, int transy) {
261 SunToolkit.awtLock();
262 try {
263 validateSurface(sg2d);
264 int[] spanBox = new int[4];
265 while (si.nextSpan(spanBox)) {
266 tileManager.addRect(spanBox[0] + transx,
267 spanBox[1] + transy,
268 spanBox[2] - spanBox[0],
269 spanBox[3] - spanBox[1]);
270 }
271 tileManager.fillMask(((XRSurfaceData) sg2d.surfaceData));
272 } finally {
273 SunToolkit.awtUnlock();
274 }
275 }
276
277 public void draw(SunGraphics2D sg2d, Shape s) {
278 if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) {
279 Path2D.Float p2df;
280 int transx, transy;
281 if (sg2d.transformState <= SunGraphics2D.TRANSFORM_INT_TRANSLATE) {
282 if (s instanceof Path2D.Float) {
283 p2df = (Path2D.Float) s;
284 } else {
285 p2df = new Path2D.Float(s);
286 }
|
36 import sun.java2d.pipe.ShapeDrawPipe;
37 import sun.java2d.pipe.SpanIterator;
38 import sun.java2d.pipe.ShapeSpanIterator;
39 import sun.java2d.pipe.LoopPipe;
40
41 import static sun.java2d.xr.XRUtils.clampToShort;
42 import static sun.java2d.xr.XRUtils.clampToUShort;
43
44 /**
45 * XRender provides only accalerated rectangles. To emulate higher "order"
46 * geometry we have to pass everything else to DoPath/FillSpans.
47 *
48 * TODO: DrawRect could be instrified
49 *
50 * @author Clemens Eisserer
51 */
52
53 public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
54 XRDrawHandler drawHandler;
55 MaskTileManager tileManager;
56 XRDrawLine lineGen;
57 GrowableRectArray rectBuffer;
58
59 public XRRenderer(MaskTileManager tileManager) {
60 this.tileManager = tileManager;
61 this.rectBuffer = tileManager.getMainTile().getRects();
62
63 this.drawHandler = new XRDrawHandler();
64 this.lineGen = new XRDrawLine();
65 }
66
67 /**
68 * Common validate method, used by all XRRender functions to validate the
69 * destination context.
70 */
71 private final void validateSurface(SunGraphics2D sg2d) {
72 XRSurfaceData xrsd = (XRSurfaceData) sg2d.surfaceData;
73 xrsd.validateAsDestination(sg2d, sg2d.getCompClip());
74 xrsd.maskBuffer.validateCompositeState(sg2d.composite, sg2d.transform,
75 sg2d.paint, sg2d);
76 }
77
78 public void drawLine(SunGraphics2D sg2d, int x1, int y1, int x2, int y2) {
79 Region compClip = sg2d.getCompClip();
80 int transX1 = Region.clipAdd(x1, sg2d.transX);
81 int transY1 = Region.clipAdd(y1, sg2d.transY);
82 int transX2 = Region.clipAdd(x2, sg2d.transX);
83 int transY2 = Region.clipAdd(y2, sg2d.transY);
84
85 SunToolkit.awtLock();
86 try {
87 validateSurface(sg2d);
88 lineGen.rasterizeLine(rectBuffer, transX1, transY1,
89 transX2, transY2, compClip.getLoX(), compClip.getLoY(),
90 compClip.getHiX(), compClip.getHiY(), true, true);
91 tileManager.fillMask((XRSurfaceData) sg2d.surfaceData);
92 } finally {
93 SunToolkit.awtUnlock();
94 }
95 }
96
97 public void drawRect(SunGraphics2D sg2d,
98 int x, int y, int width, int height) {
99 draw(sg2d, new Rectangle2D.Float(x, y, width, height));
100 }
101
102 public void drawPolyline(SunGraphics2D sg2d,
103 int xpoints[], int ypoints[], int npoints) {
104 Path2D.Float p2d = new Path2D.Float();
105 if (npoints > 1) {
106 p2d.moveTo(xpoints[0], ypoints[0]);
107 for (int i = 1; i < npoints; i++) {
108 p2d.lineTo(xpoints[i], ypoints[i]);
109 }
110 }
111
112 draw(sg2d, p2d);
113 }
114
132
133 int x2 = Region.dimAdd(x, width);
134 int y2 = Region.dimAdd(y, height);
135
136 if (x2 < Short.MIN_VALUE || y2 < Short.MIN_VALUE) {
137 return;
138 }
139
140 x = clampToShort(x);
141 y = clampToShort(y);
142 width = clampToUShort(x2 - x);
143 height = clampToUShort(y2 - y);
144
145 if (width == 0 || height == 0) {
146 return;
147 }
148
149 SunToolkit.awtLock();
150 try {
151 validateSurface(sg2d);
152 rectBuffer.pushRectValues(x, y, width, height);
153 tileManager.fillMask((XRSurfaceData) sg2d.surfaceData);
154 } finally {
155 SunToolkit.awtUnlock();
156 }
157 }
158
159 public void fillPolygon(SunGraphics2D sg2d,
160 int xpoints[], int ypoints[], int npoints) {
161 fill(sg2d, new Polygon(xpoints, ypoints, npoints));
162 }
163
164 public void drawRoundRect(SunGraphics2D sg2d,
165 int x, int y, int width, int height,
166 int arcWidth, int arcHeight) {
167 draw(sg2d, new RoundRectangle2D.Float(x, y, width, height,
168 arcWidth, arcHeight));
169 }
170
171 public void fillRoundRect(SunGraphics2D sg2d, int x, int y,
172 int width, int height,
183 public void fillOval(SunGraphics2D sg2d,
184 int x, int y, int width, int height) {
185 fill(sg2d, new Ellipse2D.Float(x, y, width, height));
186 }
187
188 public void drawArc(SunGraphics2D sg2d,
189 int x, int y, int width, int height,
190 int startAngle, int arcAngle) {
191 draw(sg2d, new Arc2D.Float(x, y, width, height,
192 startAngle, arcAngle, Arc2D.OPEN));
193 }
194
195 public void fillArc(SunGraphics2D sg2d,
196 int x, int y, int width, int height,
197 int startAngle, int arcAngle) {
198 fill(sg2d, new Arc2D.Float(x, y, width, height,
199 startAngle, arcAngle, Arc2D.PIE));
200 }
201
202 private class XRDrawHandler extends ProcessPath.DrawHandler {
203 DirtyRegion region;
204
205 XRDrawHandler() {
206 // these are bogus values; the caller will use validate()
207 // to ensure that they are set properly prior to each usage
208 super(0, 0, 0, 0);
209 this.region = new DirtyRegion();
210 }
211
212 /**
213 * This method needs to be called prior to each draw/fillPath()
214 * operation to ensure the clip bounds are up to date.
215 */
216 void validate(SunGraphics2D sg2d) {
217 Region clip = sg2d.getCompClip();
218 setBounds(clip.getLoX(), clip.getLoY(),
219 clip.getHiX(), clip.getHiY(), sg2d.strokeHint);
220 validateSurface(sg2d);
221 }
222
223 public void drawLine(int x1, int y1, int x2, int y2) {
224 region.setDirtyLineRegion(x1, y1, x2, y2);
225 int xDiff = region.x2 - region.x;
226 int yDiff = region.y2 - region.y;
227
228 if (xDiff == 0 || yDiff == 0) {
229 // horizontal / diagonal lines can be represented by a single
230 // rectangle
231 rectBuffer.pushRectValues(region.x, region.y, region.x2 - region.x
232 + 1, region.y2 - region.y + 1);
233 } else if (xDiff == 1 && yDiff == 1) {
234 // fast path for pattern commonly generated by
235 // ProcessPath.DrawHandler
236 rectBuffer.pushRectValues(x1, y1, 1, 1);
237 rectBuffer.pushRectValues(x2, y2, 1, 1);
238 } else {
239 lineGen.rasterizeLine(rectBuffer, x1, y1, x2, y2, 0, 0,
240 0, 0, false, false);
241 }
242 }
243
244 public void drawPixel(int x, int y) {
245 rectBuffer.pushRectValues(x, y, 1, 1);
246 }
247
248 public void drawScanline(int x1, int x2, int y) {
249 rectBuffer.pushRectValues(x1, y, x2 - x1 + 1, 1);
250 }
251 }
252
253 protected void drawPath(SunGraphics2D sg2d, Path2D.Float p2df,
254 int transx, int transy) {
255 SunToolkit.awtLock();
256 try {
257 validateSurface(sg2d);
258 drawHandler.validate(sg2d);
259 ProcessPath.drawPath(drawHandler, p2df, transx, transy);
260 tileManager.fillMask(((XRSurfaceData) sg2d.surfaceData));
261 } finally {
262 SunToolkit.awtUnlock();
263 }
264 }
265
266 protected void fillPath(SunGraphics2D sg2d, Path2D.Float p2df,
267 int transx, int transy) {
268 SunToolkit.awtLock();
269 try {
270 validateSurface(sg2d);
271 drawHandler.validate(sg2d);
272 ProcessPath.fillPath(drawHandler, p2df, transx, transy);
273 tileManager.fillMask(((XRSurfaceData) sg2d.surfaceData));
274 } finally {
275 SunToolkit.awtUnlock();
276 }
277 }
278
279 protected void fillSpans(SunGraphics2D sg2d, SpanIterator si,
280 int transx, int transy) {
281 SunToolkit.awtLock();
282 try {
283 validateSurface(sg2d);
284 int[] spanBox = new int[4];
285 while (si.nextSpan(spanBox)) {
286 rectBuffer.pushRectValues(spanBox[0] + transx,
287 spanBox[1] + transy,
288 spanBox[2] - spanBox[0],
289 spanBox[3] - spanBox[1]);
290 }
291 tileManager.fillMask(((XRSurfaceData) sg2d.surfaceData));
292 } finally {
293 SunToolkit.awtUnlock();
294 }
295 }
296
297 public void draw(SunGraphics2D sg2d, Shape s) {
298 if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) {
299 Path2D.Float p2df;
300 int transx, transy;
301 if (sg2d.transformState <= SunGraphics2D.TRANSFORM_INT_TRANSLATE) {
302 if (s instanceof Path2D.Float) {
303 p2df = (Path2D.Float) s;
304 } else {
305 p2df = new Path2D.Float(s);
306 }
|