Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/sun/java2d/pipe/LoopPipe.java
41159 views
1
/*
2
* Copyright (c) 1999, 2021, 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.pipe;
27
28
import java.awt.Shape;
29
import java.awt.BasicStroke;
30
import java.awt.geom.AffineTransform;
31
import java.awt.geom.PathIterator;
32
import java.awt.geom.RoundRectangle2D;
33
import java.awt.geom.Ellipse2D;
34
import java.awt.geom.Arc2D;
35
import java.awt.geom.Path2D;
36
import sun.java2d.SunGraphics2D;
37
import sun.java2d.SurfaceData;
38
import sun.java2d.loops.FillParallelogram;
39
import sun.java2d.loops.DrawParallelogram;
40
import sun.awt.SunHints;
41
42
public class LoopPipe
43
implements PixelDrawPipe,
44
PixelFillPipe,
45
ParallelogramPipe,
46
ShapeDrawPipe,
47
LoopBasedPipe
48
{
49
static final RenderingEngine RenderEngine = RenderingEngine.getInstance();
50
51
public void drawLine(SunGraphics2D sg2d,
52
int x1, int y1, int x2, int y2)
53
{
54
int tX = sg2d.transX;
55
int tY = sg2d.transY;
56
sg2d.loops.drawLineLoop.DrawLine(sg2d, sg2d.getSurfaceData(),
57
x1 + tX, y1 + tY,
58
x2 + tX, y2 + tY);
59
}
60
61
public void drawRect(SunGraphics2D sg2d,
62
int x, int y, int width, int height)
63
{
64
sg2d.loops.drawRectLoop.DrawRect(sg2d, sg2d.getSurfaceData(),
65
x + sg2d.transX,
66
y + sg2d.transY,
67
width, height);
68
}
69
70
public void drawRoundRect(SunGraphics2D sg2d,
71
int x, int y, int width, int height,
72
int arcWidth, int arcHeight)
73
{
74
sg2d.shapepipe.draw(sg2d,
75
new RoundRectangle2D.Float(x, y, width, height,
76
arcWidth, arcHeight));
77
}
78
79
public void drawOval(SunGraphics2D sg2d,
80
int x, int y, int width, int height)
81
{
82
sg2d.shapepipe.draw(sg2d, new Ellipse2D.Float(x, y, width, height));
83
}
84
85
public void drawArc(SunGraphics2D sg2d,
86
int x, int y, int width, int height,
87
int startAngle, int arcAngle)
88
{
89
sg2d.shapepipe.draw(sg2d, new Arc2D.Float(x, y, width, height,
90
startAngle, arcAngle,
91
Arc2D.OPEN));
92
}
93
94
public void drawPolyline(SunGraphics2D sg2d,
95
int[] xPoints, int[] yPoints,
96
int nPoints)
97
{
98
int[] nPointsArray = { nPoints };
99
sg2d.loops.drawPolygonsLoop.DrawPolygons(sg2d, sg2d.getSurfaceData(),
100
xPoints, yPoints,
101
nPointsArray, 1,
102
sg2d.transX, sg2d.transY,
103
false);
104
}
105
106
public void drawPolygon(SunGraphics2D sg2d,
107
int[] xPoints, int[] yPoints,
108
int nPoints)
109
{
110
int[] nPointsArray = { nPoints };
111
sg2d.loops.drawPolygonsLoop.DrawPolygons(sg2d, sg2d.getSurfaceData(),
112
xPoints, yPoints,
113
nPointsArray, 1,
114
sg2d.transX, sg2d.transY,
115
true);
116
}
117
118
public void fillRect(SunGraphics2D sg2d,
119
int x, int y, int width, int height)
120
{
121
sg2d.loops.fillRectLoop.FillRect(sg2d, sg2d.getSurfaceData(),
122
x + sg2d.transX,
123
y + sg2d.transY,
124
width, height);
125
}
126
127
public void fillRoundRect(SunGraphics2D sg2d,
128
int x, int y, int width, int height,
129
int arcWidth, int arcHeight)
130
{
131
sg2d.shapepipe.fill(sg2d,
132
new RoundRectangle2D.Float(x, y, width, height,
133
arcWidth, arcHeight));
134
}
135
136
public void fillOval(SunGraphics2D sg2d,
137
int x, int y, int width, int height)
138
{
139
sg2d.shapepipe.fill(sg2d, new Ellipse2D.Float(x, y, width, height));
140
}
141
142
public void fillArc(SunGraphics2D sg2d,
143
int x, int y, int width, int height,
144
int startAngle, int arcAngle)
145
{
146
sg2d.shapepipe.fill(sg2d, new Arc2D.Float(x, y, width, height,
147
startAngle, arcAngle,
148
Arc2D.PIE));
149
}
150
151
public void fillPolygon(SunGraphics2D sg2d,
152
int[] xPoints, int[] yPoints,
153
int nPoints)
154
{
155
ShapeSpanIterator sr = getFillSSI(sg2d);
156
157
try {
158
sr.setOutputArea(sg2d.getCompClip());
159
sr.appendPoly(xPoints, yPoints, nPoints, sg2d.transX, sg2d.transY);
160
fillSpans(sg2d, sr);
161
} finally {
162
sr.dispose();
163
}
164
}
165
166
167
public void draw(SunGraphics2D sg2d, Shape s) {
168
if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) {
169
Path2D.Float p2df;
170
int transX;
171
int transY;
172
if (sg2d.transformState <= SunGraphics2D.TRANSFORM_INT_TRANSLATE) {
173
if (s instanceof Path2D.Float) {
174
p2df = (Path2D.Float)s;
175
} else {
176
p2df = new Path2D.Float(s);
177
}
178
transX = sg2d.transX;
179
transY = sg2d.transY;
180
} else {
181
p2df = new Path2D.Float(s, sg2d.transform);
182
transX = 0;
183
transY = 0;
184
}
185
sg2d.loops.drawPathLoop.DrawPath(sg2d, sg2d.getSurfaceData(),
186
transX, transY, p2df);
187
return;
188
}
189
190
if (sg2d.strokeState == SunGraphics2D.STROKE_CUSTOM) {
191
fill(sg2d, sg2d.stroke.createStrokedShape(s));
192
return;
193
}
194
195
ShapeSpanIterator sr = getStrokeSpans(sg2d, s);
196
197
try {
198
fillSpans(sg2d, sr);
199
} finally {
200
sr.dispose();
201
}
202
}
203
204
/**
205
* Return a ShapeSpanIterator instance that normalizes as
206
* appropriate for a fill operation as per the settings in
207
* the specified SunGraphics2D object.
208
*
209
* The ShapeSpanIterator will be newly constructed and ready
210
* to start taking in geometry.
211
*
212
* Note that the caller is responsible for calling dispose()
213
* on the returned ShapeSpanIterator inside a try/finally block:
214
* <pre>
215
* ShapeSpanIterator ssi = LoopPipe.getFillSSI(sg2d);
216
* try {
217
* ssi.setOutputArea(clip);
218
* ssi.appendPath(...); // or appendPoly
219
* // iterate the spans from ssi and operate on them
220
* } finally {
221
* ssi.dispose();
222
* }
223
* </pre>
224
*/
225
public static ShapeSpanIterator getFillSSI(SunGraphics2D sg2d) {
226
boolean adjust = ((sg2d.stroke instanceof BasicStroke) &&
227
sg2d.strokeHint != SunHints.INTVAL_STROKE_PURE);
228
return new ShapeSpanIterator(adjust);
229
}
230
231
/*
232
* Return a ShapeSpanIterator ready to iterate the spans of the wide
233
* outline of Shape s using the attributes of the SunGraphics2D
234
* object.
235
*
236
* The ShapeSpanIterator returned will be fully constructed
237
* and filled with the geometry from the Shape widened by the
238
* appropriate BasicStroke and normalization parameters taken
239
* from the SunGraphics2D object and be ready to start returning
240
* spans.
241
*
242
* Note that the caller is responsible for calling dispose()
243
* on the returned ShapeSpanIterator inside a try/finally block.
244
* <pre>
245
* ShapeSpanIterator ssi = LoopPipe.getStrokeSpans(sg2d, s);
246
* try {
247
* // iterate the spans from ssi and operate on them
248
* } finally {
249
* ssi.dispose();
250
* }
251
* </pre>
252
*
253
* REMIND: This should return a SpanIterator interface object
254
* but the caller needs to dispose() the object and that method
255
* is only on ShapeSpanIterator.
256
* TODO: Add a dispose() method to the SpanIterator interface.
257
*/
258
public static ShapeSpanIterator getStrokeSpans(SunGraphics2D sg2d,
259
Shape s)
260
{
261
ShapeSpanIterator sr = new ShapeSpanIterator(false);
262
263
try {
264
final Region clip = sg2d.getCompClip();
265
sr.setOutputArea(clip);
266
sr.setRule(PathIterator.WIND_NON_ZERO);
267
268
BasicStroke bs = (BasicStroke) sg2d.stroke;
269
boolean thin = (sg2d.strokeState <= SunGraphics2D.STROKE_THINDASHED);
270
boolean normalize =
271
(sg2d.strokeHint != SunHints.INTVAL_STROKE_PURE);
272
273
RenderEngine.strokeTo(s,
274
sg2d.transform, clip, bs,
275
thin, normalize, false, sr);
276
} catch (Throwable t) {
277
sr.dispose();
278
sr = null;
279
throw new InternalError("Unable to Stroke shape ("+
280
t.getMessage()+")", t);
281
}
282
return sr;
283
}
284
285
public void fill(SunGraphics2D sg2d, Shape s) {
286
if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) {
287
Path2D.Float p2df;
288
int transX;
289
int transY;
290
if (sg2d.transformState <= SunGraphics2D.TRANSFORM_INT_TRANSLATE) {
291
if (s instanceof Path2D.Float) {
292
p2df = (Path2D.Float)s;
293
} else {
294
p2df = new Path2D.Float(s);
295
}
296
transX = sg2d.transX;
297
transY = sg2d.transY;
298
} else {
299
p2df = new Path2D.Float(s, sg2d.transform);
300
transX = 0;
301
transY = 0;
302
}
303
sg2d.loops.fillPathLoop.FillPath(sg2d, sg2d.getSurfaceData(),
304
transX, transY, p2df);
305
return;
306
}
307
308
ShapeSpanIterator sr = getFillSSI(sg2d);
309
try {
310
sr.setOutputArea(sg2d.getCompClip());
311
AffineTransform at =
312
((sg2d.transformState == SunGraphics2D.TRANSFORM_ISIDENT)
313
? null
314
: sg2d.transform);
315
sr.appendPath(s.getPathIterator(at));
316
fillSpans(sg2d, sr);
317
} finally {
318
sr.dispose();
319
}
320
}
321
322
private static void fillSpans(SunGraphics2D sg2d, SpanIterator si) {
323
// REMIND: Eventually, the plan is that it will not be possible for
324
// fs to be null since the FillSpans loop will be the fundamental
325
// loop implemented for any destination type...
326
if (sg2d.clipState == SunGraphics2D.CLIP_SHAPE) {
327
si = sg2d.clipRegion.filter(si);
328
// REMIND: Region.filter produces a Java-only iterator
329
// with no native counterpart...
330
} else {
331
sun.java2d.loops.FillSpans fs = sg2d.loops.fillSpansLoop;
332
if (fs != null) {
333
fs.FillSpans(sg2d, sg2d.getSurfaceData(), si);
334
return;
335
}
336
}
337
int[] spanbox = new int[4];
338
SurfaceData sd = sg2d.getSurfaceData();
339
while (si.nextSpan(spanbox)) {
340
int x = spanbox[0];
341
int y = spanbox[1];
342
int w = spanbox[2] - x;
343
int h = spanbox[3] - y;
344
sg2d.loops.fillRectLoop.FillRect(sg2d, sd, x, y, w, h);
345
}
346
}
347
348
public void fillParallelogram(SunGraphics2D sg2d,
349
double ux1, double uy1,
350
double ux2, double uy2,
351
double x, double y,
352
double dx1, double dy1,
353
double dx2, double dy2)
354
{
355
FillParallelogram fp = sg2d.loops.fillParallelogramLoop;
356
fp.FillParallelogram(sg2d, sg2d.getSurfaceData(),
357
x, y, dx1, dy1, dx2, dy2);
358
}
359
360
public void drawParallelogram(SunGraphics2D sg2d,
361
double ux1, double uy1,
362
double ux2, double uy2,
363
double x, double y,
364
double dx1, double dy1,
365
double dx2, double dy2,
366
double lw1, double lw2)
367
{
368
DrawParallelogram dp = sg2d.loops.drawParallelogramLoop;
369
dp.DrawParallelogram(sg2d, sg2d.getSurfaceData(),
370
x, y, dx1, dy1, dx2, dy2, lw1, lw2);
371
}
372
}
373
374