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/RegionClipSpanIterator.java
38918 views
1
/*
2
* Copyright (c) 1999, 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.geom.PathIterator;
29
import java.awt.Rectangle;
30
31
/**
32
* This class clips a SpanIterator to a Region and outputs the
33
* resulting spans as another SpanIterator.
34
*
35
* Spans are output in the usual y/x order, unless the input span
36
* iterator doesn't conform to this order, or the iterator's span
37
* straddle more than one band of the Region used for clipping.
38
*
39
* Principle of operation:
40
*
41
* The iterator maintains a several cursors onto the RegionIterator
42
* in order to avoid having to buffer spans from the SpanIterator.
43
* They are:
44
* resetState The initial state of the RegionIterator
45
* lwm Low Water Mark, a running start point for
46
* processing each band. Usually goes down, but
47
* can be reset to resetState if a span has a lower
48
* start coordinate than the previous one.
49
* row The start of the current band of the RegionIterator
50
* box The current span of the current row
51
*
52
* The main nextSpan() loop implements a coroutine like structure, with
53
* three producers to get the next span, row and box calling each other
54
* to iterate through the span iterator and region.
55
*
56
* REMIND: Needs a native implementation!
57
*/
58
public class RegionClipSpanIterator implements SpanIterator {
59
60
// The inputs to the filter
61
Region rgn;
62
SpanIterator spanIter;
63
64
// The cursors that track the progress through the region
65
RegionIterator resetState;
66
RegionIterator lwm;
67
RegionIterator row;
68
RegionIterator box;
69
70
// The bounds of the current span iterator span
71
int spanlox, spanhix, spanloy, spanhiy;
72
73
// The extent of the region band marking the low water mark
74
int lwmloy, lwmhiy;
75
76
// The bounds of the current region box
77
int rgnlox, rgnloy, rgnhix, rgnhiy;
78
79
// The bounding box of the input Region. Used for click
80
// rejection of iterator spans
81
int rgnbndslox, rgnbndsloy, rgnbndshix, rgnbndshiy;
82
83
// The array used to hold coordinates from the region iterator
84
int rgnbox[] = new int[4];
85
86
// The array used to hold coordinates from the span iterator
87
int spanbox[] = new int[4];
88
89
// True if the next iterator span should be read on the next
90
// iteration of the main nextSpan() loop
91
boolean doNextSpan;
92
93
// True if the next region box should be read on the next
94
// iteration of the main nextSpan() loop
95
boolean doNextBox;
96
97
// True if there are no more spans or the Region is empty
98
boolean done = false;
99
100
/*
101
* Creates an instance that filters the spans generated by
102
* spanIter through the region described by rgn.
103
*/
104
public RegionClipSpanIterator(Region rgn, SpanIterator spanIter) {
105
106
this.spanIter = spanIter;
107
108
resetState = rgn.getIterator();
109
lwm = resetState.createCopy();
110
111
if (!lwm.nextYRange(rgnbox)) {
112
done = true;
113
return;
114
}
115
116
rgnloy = lwmloy = rgnbox[1];
117
rgnhiy = lwmhiy = rgnbox[3];
118
119
rgn.getBounds(rgnbox);
120
rgnbndslox = rgnbox[0];
121
rgnbndsloy = rgnbox[1];
122
rgnbndshix = rgnbox[2];
123
rgnbndshiy = rgnbox[3];
124
if (rgnbndslox >= rgnbndshix ||
125
rgnbndsloy >= rgnbndshiy) {
126
done = true;
127
return;
128
}
129
130
this.rgn = rgn;
131
132
133
row = lwm.createCopy();
134
box = row.createCopy();
135
doNextSpan = true;
136
doNextBox = false;
137
}
138
139
/*
140
* Gets the bbox of the available path segments, clipped to the
141
* Region.
142
*/
143
public void getPathBox(int pathbox[]) {
144
int[] rgnbox = new int[4];
145
rgn.getBounds(rgnbox);
146
spanIter.getPathBox(pathbox);
147
148
if (pathbox[0] < rgnbox[0]) {
149
pathbox[0] = rgnbox[0];
150
}
151
152
if (pathbox[1] < rgnbox[1]) {
153
pathbox[1] = rgnbox[1];
154
}
155
156
if (pathbox[2] > rgnbox[2]) {
157
pathbox[2] = rgnbox[2];
158
}
159
160
if (pathbox[3] > rgnbox[3]) {
161
pathbox[3] = rgnbox[3];
162
}
163
}
164
165
/*
166
* Intersects the path box with the given bbox.
167
* Returned spans are clipped to this region, or discarded
168
* altogether if they lie outside it.
169
*/
170
public void intersectClipBox(int lox, int loy, int hix, int hiy) {
171
spanIter.intersectClipBox(lox, loy, hix, hiy);
172
}
173
174
175
/*
176
* Fetches the next span that needs to be operated on.
177
* If the return value is false then there are no more spans.
178
*/
179
public boolean nextSpan(int resultbox[]) {
180
if (done) {
181
return false;
182
}
183
184
int resultlox, resultloy, resulthix, resulthiy;
185
boolean doNextRow = false;
186
187
// REMIND: Cache the coordinate inst vars used in this loop
188
// in locals vars.
189
while (true) {
190
// We've exhausted the current span so get the next one
191
if (doNextSpan) {
192
if (!spanIter.nextSpan(spanbox)) {
193
done = true;
194
return false;
195
} else {
196
spanlox = spanbox[0];
197
// Clip out spans that lie outside of the rgn's bounds
198
if (spanlox >= rgnbndshix) {
199
continue;
200
}
201
202
spanloy = spanbox[1];
203
if (spanloy >= rgnbndshiy) {
204
continue;
205
}
206
207
spanhix = spanbox[2];
208
if (spanhix <= rgnbndslox) {
209
continue;
210
}
211
212
spanhiy = spanbox[3];
213
if (spanhiy <= rgnbndsloy) {
214
continue;
215
}
216
}
217
// If the span starts higher up than the low-water mark,
218
// reset the lwm. This can only happen if spans aren't
219
// returned in strict y/x order, or the first time through.
220
if (lwmloy > spanloy) {
221
lwm.copyStateFrom(resetState);
222
lwm.nextYRange(rgnbox);
223
lwmloy = rgnbox[1];
224
lwmhiy = rgnbox[3];
225
}
226
// Skip to the first rgn row whose bottom edge is
227
// below the top of the current span. This will only
228
// execute >0 times when the current span starts in a
229
// lower region row than the previous one, or possibly the
230
// first time through.
231
while (lwmhiy <= spanloy) {
232
if (!lwm.nextYRange(rgnbox))
233
break;
234
lwmloy = rgnbox[1];
235
lwmhiy = rgnbox[3];
236
}
237
// If the row overlaps the span, process it, otherwise
238
// fetch another span
239
if (lwmhiy > spanloy && lwmloy < spanhiy) {
240
// Update the current row if it's different from the
241
// new lwm
242
if (rgnloy != lwmloy) {
243
row.copyStateFrom(lwm);
244
rgnloy = lwmloy;
245
rgnhiy = lwmhiy;
246
}
247
box.copyStateFrom(row);
248
doNextBox = true;
249
doNextSpan = false;
250
}
251
continue;
252
}
253
254
// The current row's spans are exhausted, do the next one
255
if (doNextRow) {
256
// Next time we either do the next span or the next box
257
doNextRow = false;
258
// Get the next row
259
boolean ok = row.nextYRange(rgnbox);
260
// If there was one, update the bounds
261
if (ok) {
262
rgnloy = rgnbox[1];
263
rgnhiy = rgnbox[3];
264
}
265
if (!ok || rgnloy >= spanhiy) {
266
// If we've exhausted the rows or this one is below the span,
267
// go onto the next span
268
doNextSpan = true;
269
}
270
else {
271
// Otherwise get the first box on this row
272
box.copyStateFrom(row);
273
doNextBox = true;
274
}
275
continue;
276
}
277
278
// Process the next box in the current row
279
if (doNextBox) {
280
boolean ok = box.nextXBand(rgnbox);
281
if (ok) {
282
rgnlox = rgnbox[0];
283
rgnhix = rgnbox[2];
284
}
285
if (!ok || rgnlox >= spanhix) {
286
// If there was no next rgn span or it's beyond the
287
// source span, go onto the next row or span
288
doNextBox = false;
289
if (rgnhiy >= spanhiy) {
290
// If the current row totally overlaps the span,
291
// go onto the next span
292
doNextSpan = true;
293
} else {
294
// otherwise go onto the next rgn row
295
doNextRow = true;
296
}
297
} else {
298
// Otherwise, if the new rgn span overlaps the
299
// spanbox, no need to get another box
300
doNextBox = rgnhix <= spanlox;
301
}
302
continue;
303
}
304
305
// Prepare to do the next box either on this call or
306
// or the subsequent one
307
doNextBox = true;
308
309
// Clip the current span against the current box
310
if (spanlox > rgnlox) {
311
resultlox = spanlox;
312
}
313
else {
314
resultlox = rgnlox;
315
}
316
317
if (spanloy > rgnloy) {
318
resultloy = spanloy;
319
}
320
else {
321
resultloy = rgnloy;
322
}
323
324
if (spanhix < rgnhix) {
325
resulthix = spanhix;
326
}
327
else {
328
resulthix = rgnhix;
329
}
330
331
if (spanhiy < rgnhiy) {
332
resulthiy = spanhiy;
333
}
334
else {
335
resulthiy = rgnhiy;
336
}
337
338
// If the result is empty, try then next box
339
// otherwise return the box.
340
// REMIND: I think by definition it's non-empty
341
// if we're here. Need to think about this some more.
342
if (resultlox >= resulthix ||
343
resultloy >= resulthiy) {
344
continue;
345
}
346
else {
347
break;
348
}
349
}
350
351
resultbox[0] = resultlox;
352
resultbox[1] = resultloy;
353
resultbox[2] = resulthix;
354
resultbox[3] = resulthiy;
355
return true;
356
357
}
358
359
360
/**
361
* This method tells the iterator that it may skip all spans
362
* whose Y range is completely above the indicated Y coordinate.
363
*/
364
public void skipDownTo(int y) {
365
spanIter.skipDownTo(y);
366
}
367
368
/**
369
* This method returns a native pointer to a function block that
370
* can be used by a native method to perform the same iteration
371
* cycle that the above methods provide while avoiding upcalls to
372
* the Java object.
373
* The definition of the structure whose pointer is returned by
374
* this method is defined in:
375
* <pre>
376
* src/share/native/sun/java2d/pipe/SpanIterator.h
377
* </pre>
378
*/
379
public long getNativeIterator() {
380
return 0;
381
}
382
383
/*
384
* Cleans out all internal data structures.
385
*/
386
//public native void dispose();
387
388
protected void finalize() {
389
//dispose();
390
}
391
392
}
393
394