/* * Copyright (c) 1999, 2018, 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: *
     *     src/share/native/sun/java2d/pipe/SpanIterator.h
     * 
*/ public long getNativeIterator() { return 0; } /* * Cleans out all internal data structures. * REMIND: Native implementation public native void dispose(); protected void finalize() { dispose(); } */ }