Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/java2d/pipe/RegionClipSpanIterator.java
38918 views
/*1* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.java2d.pipe;2627import java.awt.geom.PathIterator;28import java.awt.Rectangle;2930/**31* This class clips a SpanIterator to a Region and outputs the32* resulting spans as another SpanIterator.33*34* Spans are output in the usual y/x order, unless the input span35* iterator doesn't conform to this order, or the iterator's span36* straddle more than one band of the Region used for clipping.37*38* Principle of operation:39*40* The iterator maintains a several cursors onto the RegionIterator41* in order to avoid having to buffer spans from the SpanIterator.42* They are:43* resetState The initial state of the RegionIterator44* lwm Low Water Mark, a running start point for45* processing each band. Usually goes down, but46* can be reset to resetState if a span has a lower47* start coordinate than the previous one.48* row The start of the current band of the RegionIterator49* box The current span of the current row50*51* The main nextSpan() loop implements a coroutine like structure, with52* three producers to get the next span, row and box calling each other53* to iterate through the span iterator and region.54*55* REMIND: Needs a native implementation!56*/57public class RegionClipSpanIterator implements SpanIterator {5859// The inputs to the filter60Region rgn;61SpanIterator spanIter;6263// The cursors that track the progress through the region64RegionIterator resetState;65RegionIterator lwm;66RegionIterator row;67RegionIterator box;6869// The bounds of the current span iterator span70int spanlox, spanhix, spanloy, spanhiy;7172// The extent of the region band marking the low water mark73int lwmloy, lwmhiy;7475// The bounds of the current region box76int rgnlox, rgnloy, rgnhix, rgnhiy;7778// The bounding box of the input Region. Used for click79// rejection of iterator spans80int rgnbndslox, rgnbndsloy, rgnbndshix, rgnbndshiy;8182// The array used to hold coordinates from the region iterator83int rgnbox[] = new int[4];8485// The array used to hold coordinates from the span iterator86int spanbox[] = new int[4];8788// True if the next iterator span should be read on the next89// iteration of the main nextSpan() loop90boolean doNextSpan;9192// True if the next region box should be read on the next93// iteration of the main nextSpan() loop94boolean doNextBox;9596// True if there are no more spans or the Region is empty97boolean done = false;9899/*100* Creates an instance that filters the spans generated by101* spanIter through the region described by rgn.102*/103public RegionClipSpanIterator(Region rgn, SpanIterator spanIter) {104105this.spanIter = spanIter;106107resetState = rgn.getIterator();108lwm = resetState.createCopy();109110if (!lwm.nextYRange(rgnbox)) {111done = true;112return;113}114115rgnloy = lwmloy = rgnbox[1];116rgnhiy = lwmhiy = rgnbox[3];117118rgn.getBounds(rgnbox);119rgnbndslox = rgnbox[0];120rgnbndsloy = rgnbox[1];121rgnbndshix = rgnbox[2];122rgnbndshiy = rgnbox[3];123if (rgnbndslox >= rgnbndshix ||124rgnbndsloy >= rgnbndshiy) {125done = true;126return;127}128129this.rgn = rgn;130131132row = lwm.createCopy();133box = row.createCopy();134doNextSpan = true;135doNextBox = false;136}137138/*139* Gets the bbox of the available path segments, clipped to the140* Region.141*/142public void getPathBox(int pathbox[]) {143int[] rgnbox = new int[4];144rgn.getBounds(rgnbox);145spanIter.getPathBox(pathbox);146147if (pathbox[0] < rgnbox[0]) {148pathbox[0] = rgnbox[0];149}150151if (pathbox[1] < rgnbox[1]) {152pathbox[1] = rgnbox[1];153}154155if (pathbox[2] > rgnbox[2]) {156pathbox[2] = rgnbox[2];157}158159if (pathbox[3] > rgnbox[3]) {160pathbox[3] = rgnbox[3];161}162}163164/*165* Intersects the path box with the given bbox.166* Returned spans are clipped to this region, or discarded167* altogether if they lie outside it.168*/169public void intersectClipBox(int lox, int loy, int hix, int hiy) {170spanIter.intersectClipBox(lox, loy, hix, hiy);171}172173174/*175* Fetches the next span that needs to be operated on.176* If the return value is false then there are no more spans.177*/178public boolean nextSpan(int resultbox[]) {179if (done) {180return false;181}182183int resultlox, resultloy, resulthix, resulthiy;184boolean doNextRow = false;185186// REMIND: Cache the coordinate inst vars used in this loop187// in locals vars.188while (true) {189// We've exhausted the current span so get the next one190if (doNextSpan) {191if (!spanIter.nextSpan(spanbox)) {192done = true;193return false;194} else {195spanlox = spanbox[0];196// Clip out spans that lie outside of the rgn's bounds197if (spanlox >= rgnbndshix) {198continue;199}200201spanloy = spanbox[1];202if (spanloy >= rgnbndshiy) {203continue;204}205206spanhix = spanbox[2];207if (spanhix <= rgnbndslox) {208continue;209}210211spanhiy = spanbox[3];212if (spanhiy <= rgnbndsloy) {213continue;214}215}216// If the span starts higher up than the low-water mark,217// reset the lwm. This can only happen if spans aren't218// returned in strict y/x order, or the first time through.219if (lwmloy > spanloy) {220lwm.copyStateFrom(resetState);221lwm.nextYRange(rgnbox);222lwmloy = rgnbox[1];223lwmhiy = rgnbox[3];224}225// Skip to the first rgn row whose bottom edge is226// below the top of the current span. This will only227// execute >0 times when the current span starts in a228// lower region row than the previous one, or possibly the229// first time through.230while (lwmhiy <= spanloy) {231if (!lwm.nextYRange(rgnbox))232break;233lwmloy = rgnbox[1];234lwmhiy = rgnbox[3];235}236// If the row overlaps the span, process it, otherwise237// fetch another span238if (lwmhiy > spanloy && lwmloy < spanhiy) {239// Update the current row if it's different from the240// new lwm241if (rgnloy != lwmloy) {242row.copyStateFrom(lwm);243rgnloy = lwmloy;244rgnhiy = lwmhiy;245}246box.copyStateFrom(row);247doNextBox = true;248doNextSpan = false;249}250continue;251}252253// The current row's spans are exhausted, do the next one254if (doNextRow) {255// Next time we either do the next span or the next box256doNextRow = false;257// Get the next row258boolean ok = row.nextYRange(rgnbox);259// If there was one, update the bounds260if (ok) {261rgnloy = rgnbox[1];262rgnhiy = rgnbox[3];263}264if (!ok || rgnloy >= spanhiy) {265// If we've exhausted the rows or this one is below the span,266// go onto the next span267doNextSpan = true;268}269else {270// Otherwise get the first box on this row271box.copyStateFrom(row);272doNextBox = true;273}274continue;275}276277// Process the next box in the current row278if (doNextBox) {279boolean ok = box.nextXBand(rgnbox);280if (ok) {281rgnlox = rgnbox[0];282rgnhix = rgnbox[2];283}284if (!ok || rgnlox >= spanhix) {285// If there was no next rgn span or it's beyond the286// source span, go onto the next row or span287doNextBox = false;288if (rgnhiy >= spanhiy) {289// If the current row totally overlaps the span,290// go onto the next span291doNextSpan = true;292} else {293// otherwise go onto the next rgn row294doNextRow = true;295}296} else {297// Otherwise, if the new rgn span overlaps the298// spanbox, no need to get another box299doNextBox = rgnhix <= spanlox;300}301continue;302}303304// Prepare to do the next box either on this call or305// or the subsequent one306doNextBox = true;307308// Clip the current span against the current box309if (spanlox > rgnlox) {310resultlox = spanlox;311}312else {313resultlox = rgnlox;314}315316if (spanloy > rgnloy) {317resultloy = spanloy;318}319else {320resultloy = rgnloy;321}322323if (spanhix < rgnhix) {324resulthix = spanhix;325}326else {327resulthix = rgnhix;328}329330if (spanhiy < rgnhiy) {331resulthiy = spanhiy;332}333else {334resulthiy = rgnhiy;335}336337// If the result is empty, try then next box338// otherwise return the box.339// REMIND: I think by definition it's non-empty340// if we're here. Need to think about this some more.341if (resultlox >= resulthix ||342resultloy >= resulthiy) {343continue;344}345else {346break;347}348}349350resultbox[0] = resultlox;351resultbox[1] = resultloy;352resultbox[2] = resulthix;353resultbox[3] = resulthiy;354return true;355356}357358359/**360* This method tells the iterator that it may skip all spans361* whose Y range is completely above the indicated Y coordinate.362*/363public void skipDownTo(int y) {364spanIter.skipDownTo(y);365}366367/**368* This method returns a native pointer to a function block that369* can be used by a native method to perform the same iteration370* cycle that the above methods provide while avoiding upcalls to371* the Java object.372* The definition of the structure whose pointer is returned by373* this method is defined in:374* <pre>375* src/share/native/sun/java2d/pipe/SpanIterator.h376* </pre>377*/378public long getNativeIterator() {379return 0;380}381382/*383* Cleans out all internal data structures.384*/385//public native void dispose();386387protected void finalize() {388//dispose();389}390391}392393394