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