| /* |
| * Copyright (c) 1999, 2002, 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; |
| |
| /* |
| REMIND: For native implementation |
| long pData; // Private storage of rect info |
| |
| static { |
| initIDs(); |
| } |
| |
| public static native void initIDs(); |
| */ |
| |
| /** |
| * 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; |
| } |
| |
| /* |
| * Cleans out all internal data structures. |
| * REMIND: Native implementation |
| public native void dispose(); |
| |
| protected void finalize() { |
| dispose(); |
| } |
| */ |
| } |