History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/java2d/pipe/RegionClipSpanIterator.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/java2d/pipe/RegionClipSpanIterator.java+392−0
@@ -0,0 +1,392 @@
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+}