jdk/src/share/native/sun/java2d/loops/FillParallelogram.c
changeset 7487 9b031d062ede
child 7668 d4a77089c587
child 7745 ebd6382e93fd
equal deleted inserted replaced
7486:6a36b1ebc620 7487:9b031d062ede
       
     1 /*
       
     2  * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 #include "math.h"
       
    27 #include "GraphicsPrimitiveMgr.h"
       
    28 
       
    29 #include "sun_java2d_loops_FillParallelogram.h"
       
    30 
       
    31 #define PGRAM_MIN_MAX(bmin, bmax, v0, dv1, dv2) \
       
    32     do { \
       
    33         double vmin, vmax; \
       
    34         if (dv1 < 0) { \
       
    35             vmin = v0+dv1; \
       
    36             vmax = v0; \
       
    37         } else { \
       
    38             vmin = v0; \
       
    39             vmax = v0+dv1; \
       
    40         } \
       
    41         if (dv2 < 0) { \
       
    42             vmin -= dv2; \
       
    43         } else { \
       
    44             vmax += dv2; \
       
    45         } \
       
    46         bmin = (jint) floor(vmin + 0.5); \
       
    47         bmax = (jint) floor(vmax + 0.5); \
       
    48     } while(0)
       
    49 
       
    50 #define PGRAM_INIT_X(starty, x, y, slope) \
       
    51     (DblToLong((x) + (slope) * ((starty)+0.5 - (y))) + LongOneHalf - 1)
       
    52 
       
    53 /*
       
    54  * Class:     sun_java2d_loops_FillParallelogram
       
    55  * Method:    FillParallelogram
       
    56  * Signature: (Lsun/java2d/SunGraphics2D;Lsun/java2d/SurfaceData;DDDDDD)V
       
    57  */
       
    58 JNIEXPORT void JNICALL
       
    59 Java_sun_java2d_loops_FillParallelogram_FillParallelogram
       
    60     (JNIEnv *env, jobject self,
       
    61      jobject sg2d, jobject sData,
       
    62      jdouble x0, jdouble y0,
       
    63      jdouble dx1, jdouble dy1,
       
    64      jdouble dx2, jdouble dy2)
       
    65 {
       
    66     SurfaceDataOps *sdOps;
       
    67     SurfaceDataRasInfo rasInfo;
       
    68     NativePrimitive *pPrim;
       
    69     CompositeInfo compInfo;
       
    70     jint pixel;
       
    71     jint ix1, iy1, ix2, iy2;
       
    72 
       
    73     if ((dy1 == 0 && dx1 == 0) || (dy2 == 0 && dx2 == 0)) {
       
    74         return;
       
    75     }
       
    76 
       
    77     /*
       
    78      * Sort parallelogram by y values, ensure that each delta vector
       
    79      * has a non-negative y delta, and eliminate degenerate parallelograms.
       
    80      */
       
    81     if (dy1 < 0) {
       
    82         x0 += dx1;  y0 += dy1;
       
    83         dx1 = -dx1; dy1 = -dy1;
       
    84     }
       
    85     if (dy2 < 0) {
       
    86         x0 += dx2;  y0 += dy2;
       
    87         dx2 = -dx2; dy2 = -dy2;
       
    88     }
       
    89     /* Sort delta vectors so dxy1 is left of dxy2. */
       
    90     if (dx1 * dy2 > dx2 * dy1) {
       
    91         double v = dx1; dx1 = dx2; dx2 = v;
       
    92                v = dy1; dy1 = dy2; dy2 = v;
       
    93     }
       
    94     PGRAM_MIN_MAX(ix1, ix2, x0, dx1, dx2);
       
    95     iy1 = (jint) floor(y0 + 0.5);
       
    96     iy2 = (jint) floor(y0 + dy1 + dy2 + 0.5);
       
    97 
       
    98     pPrim = GetNativePrim(env, self);
       
    99     if (pPrim == NULL) {
       
   100         return;
       
   101     }
       
   102     pixel = GrPrim_Sg2dGetPixel(env, sg2d);
       
   103     if (pPrim->pCompType->getCompInfo != NULL) {
       
   104         GrPrim_Sg2dGetCompInfo(env, sg2d, pPrim, &compInfo);
       
   105     }
       
   106 
       
   107     sdOps = SurfaceData_GetOps(env, sData);
       
   108     if (sdOps == NULL) {
       
   109         return;
       
   110     }
       
   111 
       
   112     GrPrim_Sg2dGetClip(env, sg2d, &rasInfo.bounds);
       
   113     SurfaceData_IntersectBoundsXYXY(&rasInfo.bounds, ix1, iy1, ix2, iy2);
       
   114     if (rasInfo.bounds.y2 <= rasInfo.bounds.y1 ||
       
   115         rasInfo.bounds.x2 <= rasInfo.bounds.x1)
       
   116     {
       
   117         return;
       
   118     }
       
   119 
       
   120     if (sdOps->Lock(env, sdOps, &rasInfo, pPrim->dstflags) != SD_SUCCESS) {
       
   121         return;
       
   122     }
       
   123 
       
   124     ix1 = rasInfo.bounds.x1;
       
   125     iy1 = rasInfo.bounds.y1;
       
   126     ix2 = rasInfo.bounds.x2;
       
   127     iy2 = rasInfo.bounds.y2;
       
   128     if (ix2 > ix1 && iy2 > iy1) {
       
   129         sdOps->GetRasInfo(env, sdOps, &rasInfo);
       
   130         if (rasInfo.rasBase) {
       
   131             jdouble lslope = (dy1 == 0) ? 0 : dx1 / dy1;
       
   132             jdouble rslope = (dy2 == 0) ? 0 : dx2 / dy2;
       
   133             jlong ldx = DblToLong(lslope);
       
   134             jlong rdx = DblToLong(rslope);
       
   135             jint cy1, cy2, loy, hiy;
       
   136             dx1 += x0;
       
   137             dy1 += y0;
       
   138             dx2 += x0;
       
   139             dy2 += y0;
       
   140             cy1 = (jint) floor(dy1 + 0.5);
       
   141             cy2 = (jint) floor(dy2 + 0.5);
       
   142 
       
   143             /* Top triangular portion. */
       
   144             loy = iy1;
       
   145             hiy = (cy1 < cy2) ? cy1 : cy2;
       
   146             if (hiy > iy2) hiy = iy2;
       
   147             if (loy < hiy) {
       
   148                 jlong lx = PGRAM_INIT_X(loy, x0, y0, lslope);
       
   149                 jlong rx = PGRAM_INIT_X(loy, x0, y0, rslope);
       
   150                 (*pPrim->funcs.fillparallelogram)(&rasInfo,
       
   151                                                   ix1, loy, ix2, hiy,
       
   152                                                   lx, ldx, rx, rdx,
       
   153                                                   pixel, pPrim, &compInfo);
       
   154             }
       
   155 
       
   156             /* Middle parallelogram portion, which way does it slant? */
       
   157             if (cy1 < cy2) {
       
   158                 /* Middle parallelogram portion, slanted to right. */
       
   159                 /* left leg turned a corner at y0+dy1 */
       
   160                 /* right leg continuing on its initial trajectory from y0 */
       
   161                 loy = cy1;
       
   162                 hiy = cy2;
       
   163                 if (loy < iy1) loy = iy1;
       
   164                 if (hiy > iy2) hiy = iy2;
       
   165                 if (loy < hiy) {
       
   166                     jlong lx = PGRAM_INIT_X(loy, dx1, dy1, rslope);
       
   167                     jlong rx = PGRAM_INIT_X(loy,  x0,  y0, rslope);
       
   168                     (*pPrim->funcs.fillparallelogram)(&rasInfo,
       
   169                                                       ix1, loy, ix2, hiy,
       
   170                                                       lx, rdx, rx, rdx,
       
   171                                                       pixel, pPrim, &compInfo);
       
   172                 }
       
   173             } else if (cy2 < cy1) {
       
   174                 /* Middle parallelogram portion, slanted to left. */
       
   175                 /* left leg continuing on its initial trajectory from y0 */
       
   176                 /* right leg turned a corner at y0+dy2 */
       
   177                 loy = cy2;
       
   178                 hiy = cy1;
       
   179                 if (loy < iy1) loy = iy1;
       
   180                 if (hiy > iy2) hiy = iy2;
       
   181                 if (loy < hiy) {
       
   182                     jlong lx = PGRAM_INIT_X(loy,  x0,  y0, lslope);
       
   183                     jlong rx = PGRAM_INIT_X(loy, dx2, dy2, lslope);
       
   184                     (*pPrim->funcs.fillparallelogram)(&rasInfo,
       
   185                                                       ix1, loy, ix2, hiy,
       
   186                                                       lx, ldx, rx, ldx,
       
   187                                                       pixel, pPrim, &compInfo);
       
   188                 }
       
   189             }
       
   190 
       
   191             /* Bottom triangular portion. */
       
   192             loy = (cy1 > cy2) ? cy1 : cy2;
       
   193             if (loy < iy1) loy = iy1;
       
   194             hiy = iy2;
       
   195             if (loy < hiy) {
       
   196                 /* left leg turned its corner at y0+dy1, now moving right */
       
   197                 /* right leg turned its corner at y0+dy2, now moving left */
       
   198                 jlong lx = PGRAM_INIT_X(loy, dx1, dy1, rslope);
       
   199                 jlong rx = PGRAM_INIT_X(loy, dx2, dy2, lslope);
       
   200                 (*pPrim->funcs.fillparallelogram)(&rasInfo,
       
   201                                                   ix1, loy, ix2, hiy,
       
   202                                                   lx, rdx, rx, ldx,
       
   203                                                   pixel, pPrim, &compInfo);
       
   204             }
       
   205         }
       
   206         SurfaceData_InvokeRelease(env, sdOps, &rasInfo);
       
   207     }
       
   208     SurfaceData_InvokeUnlock(env, sdOps, &rasInfo);
       
   209 }