210 lines · 6.0 KB · Java
RawDownload
/* * 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();    }     */}