mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-30 21:18:25 +00:00
190 lines
5.6 KiB
Java
190 lines
5.6 KiB
Java
/*
|
|
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* 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.
|
|
*/
|
|
|
|
package sun.java2d.pipe;
|
|
|
|
/**
|
|
* This class implements the ShapeIterator interface for a Region.
|
|
* This is useful as the source iterator of a device clip region
|
|
* (in its native guise), and also as the result of clipping a
|
|
* Region to a rectangle.
|
|
*/
|
|
public class RegionSpanIterator implements SpanIterator {
|
|
// The RegionIterator that we use to do the work
|
|
RegionIterator ri;
|
|
|
|
// Clipping bounds
|
|
int lox, loy, hix, hiy;
|
|
|
|
// Current Y band limits
|
|
int curloy, curhiy;
|
|
|
|
// Are we done?
|
|
boolean done = false;
|
|
|
|
// Is the associated Region rectangular?
|
|
boolean isrect;
|
|
|
|
/**
|
|
* Constructs an instance based on the given Region
|
|
*/
|
|
public RegionSpanIterator(Region r) {
|
|
int[] bounds = new int[4];
|
|
|
|
r.getBounds(bounds);
|
|
lox = bounds[0];
|
|
loy = bounds[1];
|
|
hix = bounds[2];
|
|
hiy = bounds[3];
|
|
isrect = r.isRectangular();
|
|
|
|
ri = r.getIterator();
|
|
}
|
|
|
|
/**
|
|
* Gets the bbox of the available region spans.
|
|
*/
|
|
public void getPathBox(int[] pathbox) {
|
|
pathbox[0] = lox;
|
|
pathbox[1] = loy;
|
|
pathbox[2] = hix;
|
|
pathbox[3] = hiy;
|
|
}
|
|
|
|
/**
|
|
* Intersect the box used for clipping the output spans with the
|
|
* given box.
|
|
*/
|
|
public void intersectClipBox(int clox, int cloy, int chix, int chiy) {
|
|
if (clox > lox) {
|
|
lox = clox;
|
|
}
|
|
if (cloy > loy) {
|
|
loy = cloy;
|
|
}
|
|
if (chix < hix) {
|
|
hix = chix;
|
|
}
|
|
if (chiy < hiy) {
|
|
hiy = chiy;
|
|
}
|
|
done = lox >= hix || loy >= hiy;
|
|
}
|
|
|
|
/**
|
|
* Fetches the next span that needs to be operated on.
|
|
* If the return value is false then there are no more spans.
|
|
*/
|
|
public boolean nextSpan(int[] spanbox) {
|
|
|
|
// Quick test for end conditions
|
|
if (done) {
|
|
return false;
|
|
}
|
|
|
|
// If the Region is rectangular, we store our bounds (possibly
|
|
// clipped via intersectClipBox()) in spanbox and return true
|
|
// so that the caller will process the single span. We set done
|
|
// to true to ensure that this will be the last span processed.
|
|
if (isrect) {
|
|
getPathBox(spanbox);
|
|
done = true;
|
|
return true;
|
|
}
|
|
|
|
// Local cache of current span's bounds
|
|
int curlox, curhix;
|
|
int curloy = this.curloy;
|
|
int curhiy = this.curhiy;
|
|
|
|
while (true) {
|
|
if (!ri.nextXBand(spanbox)) {
|
|
if (!ri.nextYRange(spanbox)) {
|
|
done = true;
|
|
return false;
|
|
}
|
|
// Update the current y band and clip it
|
|
curloy = spanbox[1];
|
|
curhiy = spanbox[3];
|
|
if (curloy < loy) {
|
|
curloy = loy;
|
|
}
|
|
if (curhiy > hiy) {
|
|
curhiy = hiy;
|
|
}
|
|
// Check for moving below the clip rect
|
|
if (curloy >= hiy) {
|
|
done = true;
|
|
return false;
|
|
}
|
|
continue;
|
|
}
|
|
// Clip the x box
|
|
curlox = spanbox[0];
|
|
curhix = spanbox[2];
|
|
if (curlox < lox) {
|
|
curlox = lox;
|
|
}
|
|
if (curhix > hix) {
|
|
curhix = hix;
|
|
}
|
|
// If it's non- box, we're done
|
|
if (curlox < curhix && curloy < curhiy) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Update the result and the store y range
|
|
spanbox[0] = curlox;
|
|
spanbox[1] = this.curloy = curloy;
|
|
spanbox[2] = curhix;
|
|
spanbox[3] = this.curhiy = curhiy;
|
|
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) {
|
|
loy = 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>
|
|
* src/share/native/sun/java2d/pipe/SpanIterator.h
|
|
* </pre>
|
|
*/
|
|
public long getNativeIterator() {
|
|
return 0;
|
|
}
|
|
}
|