/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* This class clips a SpanIterator to a Region and outputs the
* resulting spans as another SpanIterator.
*
* Spans are output in the usual y/x order, unless the input span
* iterator doesn't conform to this order, or the iterator's span
* straddle more than one band of the Region used for clipping.
*
* Principle of operation:
*
* The iterator maintains a several cursors onto the RegionIterator
* in order to avoid having to buffer spans from the SpanIterator.
* They are:
* resetState The initial state of the RegionIterator
* lwm Low Water Mark, a running start point for
* processing each band. Usually goes down, but
* can be reset to resetState if a span has a lower
* start coordinate than the previous one.
* row The start of the current band of the RegionIterator
* box The current span of the current row
*
* The main nextSpan() loop implements a coroutine like structure, with
* three producers to get the next span, row and box calling each other
* to iterate through the span iterator and region.
*
* REMIND: Needs a native implementation!
*/
// The inputs to the filter
// The cursors that track the progress through the region
// The bounds of the current span iterator span
// The extent of the region band marking the low water mark
// The bounds of the current region box
// The bounding box of the input Region. Used for click
// rejection of iterator spans
// The array used to hold coordinates from the region iterator
// The array used to hold coordinates from the span iterator
// True if the next iterator span should be read on the next
// iteration of the main nextSpan() loop
boolean doNextSpan;
// True if the next region box should be read on the next
// iteration of the main nextSpan() loop
boolean doNextBox;
// True if there are no more spans or the Region is empty
boolean done = false;
/*
* Creates an instance that filters the spans generated by
* spanIter through the region described by rgn.
*/
done = true;
return;
}
if (rgnbndslox >= rgnbndshix ||
rgnbndsloy >= rgnbndshiy) {
done = true;
return;
}
doNextSpan = true;
doNextBox = false;
}
/*
* Gets the bbox of the available path segments, clipped to the
* Region.
*/
int[] rgnbox = new int[4];
}
}
}
}
}
/*
* Intersects the path box with the given bbox.
* Returned spans are clipped to this region, or discarded
* altogether if they lie outside it.
*/
}
/*
* Fetches the next span that needs to be operated on.
* If the return value is false then there are no more spans.
*/
if (done) {
return false;
}
boolean doNextRow = false;
// REMIND: Cache the coordinate inst vars used in this loop
// in locals vars.
while (true) {
// We've exhausted the current span so get the next one
if (doNextSpan) {
done = true;
return false;
} else {
// Clip out spans that lie outside of the rgn's bounds
if (spanlox >= rgnbndshix) {
continue;
}
if (spanloy >= rgnbndshiy) {
continue;
}
if (spanhix <= rgnbndslox) {
continue;
}
if (spanhiy <= rgnbndsloy) {
continue;
}
}
// If the span starts higher up than the low-water mark,
// reset the lwm. This can only happen if spans aren't
// returned in strict y/x order, or the first time through.
}
// Skip to the first rgn row whose bottom edge is
// below the top of the current span. This will only
// execute >0 times when the current span starts in a
// lower region row than the previous one, or possibly the
// first time through.
break;
}
// If the row overlaps the span, process it, otherwise
// fetch another span
// Update the current row if it's different from the
// new lwm
}
doNextBox = true;
doNextSpan = false;
}
continue;
}
// The current row's spans are exhausted, do the next one
if (doNextRow) {
// Next time we either do the next span or the next box
doNextRow = false;
// Get the next row
// If there was one, update the bounds
if (ok) {
}
// If we've exhausted the rows or this one is below the span,
// go onto the next span
doNextSpan = true;
}
else {
// Otherwise get the first box on this row
doNextBox = true;
}
continue;
}
// Process the next box in the current row
if (doNextBox) {
if (ok) {
}
// If there was no next rgn span or it's beyond the
// source span, go onto the next row or span
doNextBox = false;
// If the current row totally overlaps the span,
// go onto the next span
doNextSpan = true;
} else {
// otherwise go onto the next rgn row
doNextRow = true;
}
} else {
// Otherwise, if the new rgn span overlaps the
// spanbox, no need to get another box
}
continue;
}
// Prepare to do the next box either on this call or
// or the subsequent one
doNextBox = true;
// Clip the current span against the current box
}
else {
}
}
else {
}
}
else {
}
}
else {
}
// If the result is empty, try then next box
// otherwise return the box.
// REMIND: I think by definition it's non-empty
// if we're here. Need to think about this some more.
continue;
}
else {
break;
}
}
return true;
}
/**
* This method tells the iterator that it may skip all spans
* whose Y range is completely above the indicated Y coordinate.
*/
public void skipDownTo(int y) {
spanIter.skipDownTo(y);
}
/**
* This method returns a native pointer to a function block that
* can be used by a native method to perform the same iteration
* cycle that the above methods provide while avoiding upcalls to
* the Java object.
* The definition of the structure whose pointer is returned by
* this method is defined in:
* <pre>
* </pre>
*/
public long getNativeIterator() {
return 0;
}
/*
* Cleans out all internal data structures.
*/
//public native void dispose();
protected void finalize() {
//dispose();
}
}