3909N/A * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 0N/A * Class: sun_java2d_loops_MaskFill 3265N/A/* Fills an aligned rectangle with potentially translucent edges. */ 3265N/A /* Convert xy12 into the edge coverage fractions for those edges. */ 3265N/A /* Accumulate bottom coverage into top coverage. */ 3265N/A /* prevent processing of "bottom fractional row" */ 3265N/A /* Accumulate right coverage into left coverage. */ 3265N/A /* prevent processing of "right fractional column" */ 3265N/A /* Check for a visible "top fractional row" and process it */ 3265N/A /* Check for a visible "left fract, solid middle, right fract" section. */ 3265N/A /* First process the left "fractional column" if it is visible. */ 3265N/A /* Note: maskscan == 0 means we reuse this value for every row. */ 3265N/A /* Process the central solid section if it is visible. */ 3265N/A /* A NULL mask buffer means "all coverages are 0xff" */ 3265N/A /* Finally process the right "fractional column" if it is visible. */ 3265N/A /* Note: maskscan == 0 means we reuse this value for every row. */ 3265N/A /* Check for a visible "bottom fractional row" and process it */ 3265N/A * Support code for arbitrary tracing and MaskFill filling of 3265N/A * non-rectilinear (diagonal) parallelograms. 3265N/A * This code is based upon the following model of AA coverage. 3265N/A * Each edge of a parallelogram (for fillPgram) or a double 3265N/A * parallelogram (inner and outer parallelograms for drawPgram) 3265N/A * can be rasterized independently because the geometry is well 3265N/A * defined in such a way that none of the sides will ever cross 3265N/A * each other and they have a fixed ordering that is fairly 3265N/A * So, for each edge we will look at the diagonal line that 3265N/A * the edge makes as it passes through a row of pixels. Some 3265N/A * such diagonal lines may pass entirely through the row of 3265N/A * pixels in a single pixel column. Some may cut across the 3265N/A * row and pass through several pixel columns before they pass 3265N/A * As the edge passes through the row of pixels it will affect 3265N/A * the coverage of the pixels it passes through as well as all 3265N/A * of the pixels to the right of the edge. The coverage will 3265N/A * either be increased (by a left edge of a parallelogram) or 3265N/A * decreased (by a right edge) for all pixels to the right, until 3265N/A * another edge passing the opposite direction is encountered. 3265N/A * The coverage added or subtracted by an edge as it crosses a 3265N/A * given pixel is calculated using a trapezoid formula in the 3265N/A * The area to the right of that edge for the pixel where it 3265N/A * trapheight * (topedge + bottomedge)/2 3265N/A * Another thing to note is that the above formula gives the 3265N/A * contribution of that edge to the given pixel where it crossed, 3265N/A * but in so crossing the pixel row, it also created 100% coverage 3265N/A * for all of the pixels to the right. 3265N/A * This example was simplified in that the edge depicted crossed 3265N/A * the complete pixel row and it did so entirely within the bounds 3265N/A * of a single pixel column. In practice, many edges may start or 3265N/A * end in a given row and thus provide only partial row coverage 3265N/A * (i.e. the total "trapheight" in the formula never reaches 1.0). 3265N/A * And in other cases, edges may travel sideways through several 3265N/A * pixel columns on a given pixel row from where they enter it to 3265N/A * where the leave it (which also mans that the trapheight for a 3265N/A * given pixel will be less than 1.0, but by the time the edge 3265N/A * completes its journey through the pixel row the "coverage shadow" 3265N/A * that it casts on all pixels to the right eventually reaches 100%). 3265N/A * In order to simplify the calculations so that we don't have to 3265N/A * keep propagating coverages we calculate for one edge "until we 3265N/A * reach another edge" we will process one edge at a time and 3265N/A * simply record in a buffer the amount that an edge added to 3265N/A * or subtracted from the coverage for a given pixel and its 3265N/A * following right-side neighbors. Thus, the true total coverage 3265N/A * of a given pixel is only determined by summing the deltas for 3265N/A * that pixel and all of the pixels to its left. Since we already 3265N/A * have to scan the buffer to change floating point coverages into 3265N/A * mask values for a MaskFill loop, it is simple enough to sum the 3265N/A * values as we perform that scan from left to right. 3265N/A * In the above example, note that 2 deltas need to be recorded even 3265N/A * though the edge only intersected a single pixel. The delta recorded 3265N/A * for the pixel where the edge crossed will be approximately 55% 3265N/A * (guesstimating by examining the poor ascii art) which is fine for 3265N/A * determining how to render that pixel, but the rest of the pixels 3265N/A * to its right should have their coverage modified by a full 100% 3265N/A * and the 55% delta value we recorded for the pixel that the edge 3265N/A * crossed will not get them there. We adjust for this by adding 3265N/A * the "remainder" of the coverage implied by the shadow to the 3265N/A * pixel immediately to the right of where we record a trapezoidal 3265N/A * contribution. In this case a delta of 45% will be recorded in 3265N/A * the pixel immediately to the right to raise the total to 100%. 3265N/A * As we sum these delta values as we process the line from left 3265N/A * to right, these delta values will typically drive the sum from 3265N/A * 0% up to 100% and back down to 0% over the course of a single 3265N/A * pixel row. In the case of a drawn (double) parallelogram the 3265N/A * sum will go to 100% and back to 0% twice on most scanlines. 3265N/A * The fillAAPgram and drawAAPgram functions drive the main flow 3265N/A * of the algorithm with help from the following structures, 3265N/A * macros, and functions. It is probably best to start with 3265N/A * those 2 functions to gain an understanding of the algorithm. 3265N/A * Calculates slopes and deltas for an edge and stores results in an EdgeInfo. 3265N/A * Returns true if the edge was valid (i.e. not ignored for some reason). 3265N/A /* Note that parallelograms are sorted so dy is always non-negative */ 3265N/A y <
cy2 &&
/* NaN and "OUT_BELOW" protection */ 3265N/A /* Note: "OUT_LEFT" segments may still contribute coverage... */ 3265N/A /* no NaNs, dy is not horizontal, and segment contributes to clip */ 3265N/A /* dx is essentially vertical */ 3265N/A /* There is some reason to ignore this segment, "celldy=0" omits it */ 3265N/A * Calculates and stores slopes and deltas for all edges of a parallelogram. 3265N/A * Returns true if at least 1 edge was valid (i.e. not ignored for some reason). 3265N/A * The inverted flag is true for an outer parallelogram (left and right 3265N/A * edges are leading and trailing) and false for an inner parallelogram 3265N/A * (where the left edge is trailing and the right edge is leading). 3265N/A * The X0,Y0,X1,Y1 values represent a trapezoidal fragment whose 3265N/A * coverage must be accounted for in the accum buffer. 3265N/A * All four values are assumed to fall within (or on the edge of) 3265N/A * The trapezoid area is accumulated into the proper element of 3265N/A * the accum buffer and the remainder of the "slice height" is 3265N/A * accumulated into the element to its right. 3265N/A /* Accumulate the entire slice height into accum[0]. */ \
3265N/A * Accumulate the contributions for a given edge crossing a given 3265N/A * scan line into the corresponding entries of the accum buffer. 3265N/A * CY1 is the Y coordinate of the top edge of the scanline and CY2 3265N/A * is equal to (CY1 + 1) and is the Y coordinate of the bottom edge 3265N/A * of the scanline. CX1 and CX2 are the left and right edges of the 3265N/A * clip (or area of interest) being rendered. 3265N/A * The edge is processed from the top edge to the bottom edge and 3265N/A * a single pixel column at a time. 3265N/A/* Main function to fill a single Parallelogram */ 3265N/A /* If ranges overlap, handle both in the first pass. */ 3265N/A /* Check for a solid center section. */ 3265N/A /* First process the existing partial coverage data. */ 3265N/A /* Where does the center section end? */ 3265N/A /* If there is no right AA edge in the accum buffer, then */ 3265N/A /* the right edge was beyond the clip, so fill out to width */ 3265N/A /* We are not at 0 coverage, but there is no right edge, */ 3265N/A /* force a right edge so we process pixels out to width. */ 3265N/A /* The following loop will process the right AA edge and/or any */ 3265N/A /* partial coverage center section not processed above. */ 3265N/A * Class: sun_java2d_loops_MaskFill 3265N/A * Sort parallelogram by y values, ensure that each delta vector 3265N/A * has a non-negative y delta. 3265N/A // We sorted by Y above, but not by X 3265N/A // We sorted by Y above, but not by X 3265N/A/* Main function to fill a double pair of (inner and outer) parallelograms */ 3265N/A /* If outer pgram does not contribute, then inner cannot either. */ 3265N/A /* If ranges overlap, handle both in the first pass. */ 3265N/A /* Check for an empty or solidcenter section. */ 3265N/A /* First process the existing partial coverage data. */ 3265N/A /* Where does the center section end? */ 3265N/A /* If there is no right AA edge in the accum buffer, then */ 3265N/A /* the right edge was beyond the clip, so fill out to width */ 3265N/A /* We are not at 0 coverage, but there is no right edge, */ 3265N/A /* force a right edge so we process pixels out to width. */ 3265N/A /* The following loop will process the right AA edge and/or any */ 3265N/A /* partial coverage center section not processed above. */ 3265N/A * Class: sun_java2d_loops_MaskFill 3265N/A * Sort parallelogram by y values, ensure that each delta vector 3265N/A * has a non-negative y delta. 3265N/A // dx,dy for line width in the "1" and "2" directions. 3265N/A // calculate origin of the outer parallelogram 3265N/A /* Only need to fill an outer pgram if the interior no longer 3265N/A * has a hole in it (i.e. if either of the line width ratios 3265N/A * were greater than or equal to 1.0). 3265N/A * NOTE: aligned rects could probably be drawn 3265N/A * even faster with a little work here. 3265N/A * if (dy1 == 0 && dx2 == 0) { 3265N/A * drawAARect(pPrim, &rasInfo, &compInfo, 3265N/A * ox0, oy0, ox0+dx1+ldx1, oy0+dy2+ldy2, ldx1, ldy2); 3265N/A * } else if (dx1 == 0 && dy2 == 0) { 3265N/A * drawAARect(pPrim, &rasInfo, &compInfo, 3265N/A * ox0, oy0, ox0+dx2+ldx2, oy0+dy1+ldy1, ldx2, ldy1);