Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java
32288 views
1
/*
2
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. 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. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.java2d.xr;
27
28
import java.awt.*;
29
import java.awt.geom.*;
30
import sun.awt.SunToolkit;
31
import sun.java2d.InvalidPipeException;
32
import sun.java2d.SunGraphics2D;
33
import sun.java2d.loops.*;
34
import sun.java2d.pipe.Region;
35
import sun.java2d.pipe.PixelDrawPipe;
36
import sun.java2d.pipe.PixelFillPipe;
37
import sun.java2d.pipe.ShapeDrawPipe;
38
import sun.java2d.pipe.SpanIterator;
39
import sun.java2d.pipe.ShapeSpanIterator;
40
import sun.java2d.pipe.LoopPipe;
41
42
import static sun.java2d.xr.XRUtils.clampToShort;
43
import static sun.java2d.xr.XRUtils.clampToUShort;
44
45
/**
46
* XRender provides only accalerated rectangles. To emulate higher "order"
47
* geometry we have to pass everything else to DoPath/FillSpans.
48
*
49
* TODO: DrawRect could be instrified
50
*
51
* @author Clemens Eisserer
52
*/
53
54
public class XRRenderer implements PixelDrawPipe, PixelFillPipe, ShapeDrawPipe {
55
XRDrawHandler drawHandler;
56
MaskTileManager tileManager;
57
XRDrawLine lineGen;
58
GrowableRectArray rectBuffer;
59
60
public XRRenderer(MaskTileManager tileManager) {
61
this.tileManager = tileManager;
62
this.rectBuffer = tileManager.getMainTile().getRects();
63
64
this.drawHandler = new XRDrawHandler();
65
this.lineGen = new XRDrawLine();
66
}
67
68
/**
69
* Common validate method, used by all XRRender functions to validate the
70
* destination context.
71
*/
72
private final void validateSurface(SunGraphics2D sg2d) {
73
XRSurfaceData xrsd;
74
try {
75
xrsd = (XRSurfaceData) sg2d.surfaceData;
76
} catch (ClassCastException e) {
77
throw new InvalidPipeException("wrong surface data type: " + sg2d.surfaceData);
78
}
79
xrsd.validateAsDestination(sg2d, sg2d.getCompClip());
80
xrsd.maskBuffer.validateCompositeState(sg2d.composite, sg2d.transform,
81
sg2d.paint, sg2d);
82
}
83
84
public void drawLine(SunGraphics2D sg2d, int x1, int y1, int x2, int y2) {
85
Region compClip = sg2d.getCompClip();
86
int transX1 = Region.clipAdd(x1, sg2d.transX);
87
int transY1 = Region.clipAdd(y1, sg2d.transY);
88
int transX2 = Region.clipAdd(x2, sg2d.transX);
89
int transY2 = Region.clipAdd(y2, sg2d.transY);
90
91
SunToolkit.awtLock();
92
try {
93
validateSurface(sg2d);
94
lineGen.rasterizeLine(rectBuffer, transX1, transY1,
95
transX2, transY2, compClip.getLoX(), compClip.getLoY(),
96
compClip.getHiX(), compClip.getHiY(), true, true);
97
tileManager.fillMask((XRSurfaceData) sg2d.surfaceData);
98
} finally {
99
SunToolkit.awtUnlock();
100
}
101
}
102
103
public void drawRect(SunGraphics2D sg2d,
104
int x, int y, int width, int height) {
105
draw(sg2d, new Rectangle2D.Float(x, y, width, height));
106
}
107
108
public void drawPolyline(SunGraphics2D sg2d,
109
int xpoints[], int ypoints[], int npoints) {
110
Path2D.Float p2d = new Path2D.Float();
111
if (npoints > 1) {
112
p2d.moveTo(xpoints[0], ypoints[0]);
113
for (int i = 1; i < npoints; i++) {
114
p2d.lineTo(xpoints[i], ypoints[i]);
115
}
116
}
117
118
draw(sg2d, p2d);
119
}
120
121
public void drawPolygon(SunGraphics2D sg2d,
122
int xpoints[], int ypoints[], int npoints) {
123
draw(sg2d, new Polygon(xpoints, ypoints, npoints));
124
}
125
126
public void fillRect(SunGraphics2D sg2d, int x, int y, int width, int height) {
127
x = Region.clipAdd(x, sg2d.transX);
128
y = Region.clipAdd(y, sg2d.transY);
129
130
/*
131
* Limit x/y to signed short, width/height to unsigned short,
132
* to match the X11 coordinate limits for rectangles.
133
* Correct width/height in case x/y have been modified by clipping.
134
*/
135
if (x > Short.MAX_VALUE || y > Short.MAX_VALUE) {
136
return;
137
}
138
139
int x2 = Region.dimAdd(x, width);
140
int y2 = Region.dimAdd(y, height);
141
142
if (x2 < Short.MIN_VALUE || y2 < Short.MIN_VALUE) {
143
return;
144
}
145
146
x = clampToShort(x);
147
y = clampToShort(y);
148
width = clampToUShort(x2 - x);
149
height = clampToUShort(y2 - y);
150
151
if (width == 0 || height == 0) {
152
return;
153
}
154
155
SunToolkit.awtLock();
156
try {
157
validateSurface(sg2d);
158
rectBuffer.pushRectValues(x, y, width, height);
159
tileManager.fillMask((XRSurfaceData) sg2d.surfaceData);
160
} finally {
161
SunToolkit.awtUnlock();
162
}
163
}
164
165
public void fillPolygon(SunGraphics2D sg2d,
166
int xpoints[], int ypoints[], int npoints) {
167
fill(sg2d, new Polygon(xpoints, ypoints, npoints));
168
}
169
170
public void drawRoundRect(SunGraphics2D sg2d,
171
int x, int y, int width, int height,
172
int arcWidth, int arcHeight) {
173
draw(sg2d, new RoundRectangle2D.Float(x, y, width, height,
174
arcWidth, arcHeight));
175
}
176
177
public void fillRoundRect(SunGraphics2D sg2d, int x, int y,
178
int width, int height,
179
int arcWidth, int arcHeight) {
180
fill(sg2d, new RoundRectangle2D.Float(x, y, width, height,
181
arcWidth, arcHeight));
182
}
183
184
public void drawOval(SunGraphics2D sg2d,
185
int x, int y, int width, int height) {
186
draw(sg2d, new Ellipse2D.Float(x, y, width, height));
187
}
188
189
public void fillOval(SunGraphics2D sg2d,
190
int x, int y, int width, int height) {
191
fill(sg2d, new Ellipse2D.Float(x, y, width, height));
192
}
193
194
public void drawArc(SunGraphics2D sg2d,
195
int x, int y, int width, int height,
196
int startAngle, int arcAngle) {
197
draw(sg2d, new Arc2D.Float(x, y, width, height,
198
startAngle, arcAngle, Arc2D.OPEN));
199
}
200
201
public void fillArc(SunGraphics2D sg2d,
202
int x, int y, int width, int height,
203
int startAngle, int arcAngle) {
204
fill(sg2d, new Arc2D.Float(x, y, width, height,
205
startAngle, arcAngle, Arc2D.PIE));
206
}
207
208
private class XRDrawHandler extends ProcessPath.DrawHandler {
209
DirtyRegion region;
210
211
XRDrawHandler() {
212
// these are bogus values; the caller will use validate()
213
// to ensure that they are set properly prior to each usage
214
super(0, 0, 0, 0);
215
this.region = new DirtyRegion();
216
}
217
218
/**
219
* This method needs to be called prior to each draw/fillPath()
220
* operation to ensure the clip bounds are up to date.
221
*/
222
void validate(SunGraphics2D sg2d) {
223
Region clip = sg2d.getCompClip();
224
setBounds(clip.getLoX(), clip.getLoY(),
225
clip.getHiX(), clip.getHiY(), sg2d.strokeHint);
226
validateSurface(sg2d);
227
}
228
229
public void drawLine(int x1, int y1, int x2, int y2) {
230
region.setDirtyLineRegion(x1, y1, x2, y2);
231
int xDiff = region.x2 - region.x;
232
int yDiff = region.y2 - region.y;
233
234
if (xDiff == 0 || yDiff == 0) {
235
// horizontal / diagonal lines can be represented by a single
236
// rectangle
237
rectBuffer.pushRectValues(region.x, region.y, region.x2 - region.x
238
+ 1, region.y2 - region.y + 1);
239
} else if (xDiff == 1 && yDiff == 1) {
240
// fast path for pattern commonly generated by
241
// ProcessPath.DrawHandler
242
rectBuffer.pushRectValues(x1, y1, 1, 1);
243
rectBuffer.pushRectValues(x2, y2, 1, 1);
244
} else {
245
lineGen.rasterizeLine(rectBuffer, x1, y1, x2, y2, 0, 0,
246
0, 0, false, false);
247
}
248
}
249
250
public void drawPixel(int x, int y) {
251
rectBuffer.pushRectValues(x, y, 1, 1);
252
}
253
254
public void drawScanline(int x1, int x2, int y) {
255
rectBuffer.pushRectValues(x1, y, x2 - x1 + 1, 1);
256
}
257
}
258
259
protected void drawPath(SunGraphics2D sg2d, Path2D.Float p2df,
260
int transx, int transy) {
261
SunToolkit.awtLock();
262
try {
263
validateSurface(sg2d);
264
drawHandler.validate(sg2d);
265
ProcessPath.drawPath(drawHandler, p2df, transx, transy);
266
tileManager.fillMask(((XRSurfaceData) sg2d.surfaceData));
267
} finally {
268
SunToolkit.awtUnlock();
269
}
270
}
271
272
protected void fillPath(SunGraphics2D sg2d, Path2D.Float p2df,
273
int transx, int transy) {
274
SunToolkit.awtLock();
275
try {
276
validateSurface(sg2d);
277
drawHandler.validate(sg2d);
278
ProcessPath.fillPath(drawHandler, p2df, transx, transy);
279
tileManager.fillMask(((XRSurfaceData) sg2d.surfaceData));
280
} finally {
281
SunToolkit.awtUnlock();
282
}
283
}
284
285
protected void fillSpans(SunGraphics2D sg2d, SpanIterator si,
286
int transx, int transy) {
287
SunToolkit.awtLock();
288
try {
289
validateSurface(sg2d);
290
int[] spanBox = new int[4];
291
while (si.nextSpan(spanBox)) {
292
rectBuffer.pushRectValues(spanBox[0] + transx,
293
spanBox[1] + transy,
294
spanBox[2] - spanBox[0],
295
spanBox[3] - spanBox[1]);
296
}
297
tileManager.fillMask(((XRSurfaceData) sg2d.surfaceData));
298
} finally {
299
SunToolkit.awtUnlock();
300
}
301
}
302
303
public void draw(SunGraphics2D sg2d, Shape s) {
304
if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) {
305
Path2D.Float p2df;
306
int transx, transy;
307
if (sg2d.transformState <= SunGraphics2D.TRANSFORM_INT_TRANSLATE) {
308
if (s instanceof Path2D.Float) {
309
p2df = (Path2D.Float) s;
310
} else {
311
p2df = new Path2D.Float(s);
312
}
313
transx = sg2d.transX;
314
transy = sg2d.transY;
315
} else {
316
p2df = new Path2D.Float(s, sg2d.transform);
317
transx = 0;
318
transy = 0;
319
}
320
drawPath(sg2d, p2df, transx, transy);
321
} else if (sg2d.strokeState < SunGraphics2D.STROKE_CUSTOM) {
322
ShapeSpanIterator si = LoopPipe.getStrokeSpans(sg2d, s);
323
try {
324
fillSpans(sg2d, si, 0, 0);
325
} finally {
326
si.dispose();
327
}
328
} else {
329
fill(sg2d, sg2d.stroke.createStrokedShape(s));
330
}
331
}
332
333
public void fill(SunGraphics2D sg2d, Shape s) {
334
int transx, transy;
335
336
if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) {
337
// Here we are able to use fillPath() for
338
// high-quality fills.
339
Path2D.Float p2df;
340
if (sg2d.transformState <= SunGraphics2D.TRANSFORM_INT_TRANSLATE) {
341
if (s instanceof Path2D.Float) {
342
p2df = (Path2D.Float) s;
343
} else {
344
p2df = new Path2D.Float(s);
345
}
346
transx = sg2d.transX;
347
transy = sg2d.transY;
348
} else {
349
p2df = new Path2D.Float(s, sg2d.transform);
350
transx = 0;
351
transy = 0;
352
}
353
fillPath(sg2d, p2df, transx, transy);
354
return;
355
}
356
357
AffineTransform at;
358
if (sg2d.transformState <= SunGraphics2D.TRANSFORM_INT_TRANSLATE) {
359
// Transform (translation) will be done by FillSpans
360
at = null;
361
transx = sg2d.transX;
362
transy = sg2d.transY;
363
} else {
364
// Transform will be done by the PathIterator
365
at = sg2d.transform;
366
transx = transy = 0;
367
}
368
369
ShapeSpanIterator ssi = LoopPipe.getFillSSI(sg2d);
370
try {
371
// Subtract transx/y from the SSI clip to match the
372
// (potentially untranslated) geometry fed to it
373
Region clip = sg2d.getCompClip();
374
ssi.setOutputAreaXYXY(clip.getLoX() - transx,
375
clip.getLoY() - transy,
376
clip.getHiX() - transx,
377
clip.getHiY() - transy);
378
ssi.appendPath(s.getPathIterator(at));
379
fillSpans(sg2d, ssi, transx, transy);
380
} finally {
381
ssi.dispose();
382
}
383
}
384
}
385
386