2128 lines · 78.3 KB · Java
RawDownload
         /* Setting default boundary values for checking first and second forward         * difference for the necessity of the restepping. See comments to the         * boundary values in ProcessQuad for more info.         */        int incStepBnd = DF_CUB_INC_BND;        int decStepBnd = DF_CUB_DEC_BND;         /* Setting default amount of steps */        int count = DF_CUB_COUNT;         /* Setting default shift for preparing to the midpoint rounding */        int shift =  DF_CUB_SHIFT;         int ax = (int)((-coords[0] + 3*coords[2] - 3*coords[4] +                 coords[6])*CUB_A_MDP_MULT);        int ay = (int)((-coords[1] + 3*coords[3] - 3*coords[5] +                 coords[7])*CUB_A_MDP_MULT);         int bx = (int)((3*coords[0] - 6*coords[2] +                 3*coords[4])*CUB_B_MDP_MULT);        int by = (int)((3*coords[1] - 6*coords[3] +                 3*coords[5])*CUB_B_MDP_MULT);         int cx = (int)((-3*coords[0] + 3*coords[2])*(CUB_C_MDP_MULT));        int cy = (int)((-3*coords[1] + 3*coords[3])*(CUB_C_MDP_MULT));         int dddpx = 6*ax;        int dddpy = 6*ay;         int ddpx = dddpx + bx;        int ddpy = dddpy + by;         int dpx = ax + (bx>>1) + cx;        int dpy = ay + (by>>1) + cy;         int x1, y1;         int x2 = x0;        int y2 = y0;         /* Calculating whole part of the first point of the curve */        int x0w = x0 & MDP_W_MASK;        int y0w = y0 & MDP_W_MASK;         int dx = xe - x0;        int dy = ye - y0;         while (count > 0) {            /* Perform decreasing step in 2 times if necessary */            while (Math.abs(ddpx) > decStepBnd ||                   Math.abs(ddpy) > decStepBnd) {                ddpx = (ddpx<<1) - dddpx;                ddpy = (ddpy<<1) - dddpy;                dpx = (dpx<<2) - (ddpx>>1);                dpy = (dpy<<2) - (ddpy>>1);                count <<=1;                decStepBnd <<=3;                incStepBnd <<=3;                px <<=3;                py <<=3;                shift += 3;            }             /* Perform increasing step in 2 times if necessary.             * Note: we could do it only in even steps             */             while ((count & 1) == 0 && shift > DF_CUB_SHIFT &&                   Math.abs(dpx) <= incStepBnd &&                   Math.abs(dpy) <= incStepBnd) {                dpx = (dpx>>2) + (ddpx>>3);                dpy = (dpy>>2) + (ddpy>>3);                ddpx = (ddpx + dddpx)>>1;                ddpy = (ddpy + dddpy)>>1;                count >>=1;                decStepBnd >>=3;                incStepBnd >>=3;                px >>=3;                py >>=3;                shift -= 3;            }             count--;             /* Performing one step less than necessary and use actual (xe,ye)             * curve's endpoint instead of calculated. This prevent us from             * running above the curve endpoint due to the accumulated errors             * during the iterations.             */            if (count > 0) {                px += dpx;                py += dpy;                 dpx += ddpx;                dpy += ddpy;                ddpx += dddpx;                ddpy += dddpy;                 x1 = x2;                y1 = y2;                 x2 = x0w + (px >> shift);                y2 = y0w + (py >> shift);                 /* Checking that we are not running out of the endpoint and                 * bounding violating coordinate.  The check is pretty simple                 * because the curve passed to the DrawCubic already splitted                 * into the monotonic in X and Y pieces                 */                 /* Bounding x2 by xe */                if (((xe-x2)^dx) < 0) {                    x2 = xe;                }                 /* Bounding y2 by ye */                if (((ye-y2)^dy) < 0) {                    y2 = ye;                }                 hnd.processFixedLine(x1, y1, x2, y2, pixelInfo, checkBounds,                                     false);            } else {                hnd.processFixedLine(x2, y2, xe, ye, pixelInfo, checkBounds,                                     false);            }        }    }     /*     * Checking size of the cubic curves and split them if necessary.     * Calling DrawMonotonicCubic for the curves of the appropriate size.     * Note: coords array could be changed     */    private static void ProcessMonotonicCubic(ProcessHandler hnd,                                              float[] coords,                                              int[] pixelInfo) {         float[] coords1 = new float[8];        float tx, ty;        float xMin, xMax;        float yMin, yMax;         xMin = xMax = coords[0];        yMin = yMax = coords[1];         for (int i = 2; i < 8; i += 2) {            xMin = (xMin > coords[i])? coords[i] : xMin;            xMax = (xMax < coords[i])? coords[i] : xMax;            yMin = (yMin > coords[i + 1])? coords[i + 1] : yMin;            yMax = (yMax < coords[i + 1])? coords[i + 1] : yMax;        }         if (hnd.clipMode == PH_MODE_DRAW_CLIP) {            /* In case of drawing we could just skip curves which are             * completely out of bounds             */            if (hnd.dhnd.xMaxf < xMin || hnd.dhnd.xMinf > xMax ||                hnd.dhnd.yMaxf < yMin || hnd.dhnd.yMinf > yMax) {                return;            }        } else {             /* In case of filling we could skip curves which are above,             * below and behind the right boundary of the visible area             */             if (hnd.dhnd.yMaxf < yMin || hnd.dhnd.yMinf > yMax ||                hnd.dhnd.xMaxf < xMin)            {                return;            }             /* We could clamp x coordinates to the corresponding boundary             * if the curve is completely behind the left one             */             if (hnd.dhnd.xMinf > xMax) {                coords[0] = coords[2] = coords[4] = coords[6] =                    hnd.dhnd.xMinf;            }        }         if (xMax - xMin > MAX_CUB_SIZE || yMax - yMin > MAX_CUB_SIZE) {            coords1[6] = coords[6];            coords1[7] = coords[7];            coords1[4] = (coords[4] + coords[6])/2.0f;            coords1[5] = (coords[5] + coords[7])/2.0f;            tx = (coords[2] + coords[4])/2.0f;            ty = (coords[3] + coords[5])/2.0f;            coords1[2] = (tx + coords1[4])/2.0f;            coords1[3] = (ty + coords1[5])/2.0f;            coords[2] =  (coords[0] + coords[2])/2.0f;            coords[3] =  (coords[1] + coords[3])/2.0f;            coords[4] = (coords[2] + tx)/2.0f;            coords[5] = (coords[3] + ty)/2.0f;            coords[6]=coords1[0]=(coords[4] + coords1[2])/2.0f;            coords[7]=coords1[1]=(coords[5] + coords1[3])/2.0f;             ProcessMonotonicCubic(hnd, coords, pixelInfo);             ProcessMonotonicCubic(hnd, coords1, pixelInfo);        } else {            DrawMonotonicCubic(hnd, coords,                               /* Set checkBounds parameter if curve intersects                                * boundary of the visible area. We know that                                * the curve is visible, so the check is pretty                                * simple                                */                                hnd.dhnd.xMinf > xMin ||                                hnd.dhnd.xMaxf < xMax ||                                hnd.dhnd.yMinf > yMin ||                                hnd.dhnd.yMaxf < yMax,                                pixelInfo);        }    }     /*     * Split cubic curve into monotonic in X and Y parts. Calling     * ProcessMonotonicCubic for each monotonic piece of the curve.     *     * Note: coords array could be changed     */    private static void ProcessCubic(ProcessHandler hnd,                                     float[] coords,                                     int[] pixelInfo) {        /* Temporary array for holding parameters corresponding to the extreme         * in X and Y points         */        double params[] = new double[4];        double eqn[] = new double[3];        double res[] = new double[2];        int cnt = 0;         /* Simple check for monotonicity in X before searching for the extreme         * points of the X(t) function. We first check if the curve is         * monotonic in X by seeing if all of the X coordinates are strongly         * ordered.         */        if ((coords[0] > coords[2] || coords[2] > coords[4] ||             coords[4] > coords[6]) &&            (coords[0] < coords[2] || coords[2] < coords[4] ||             coords[4] < coords[6]))        {            /* Searching for extreme points of the X(t) function  by solving             * dX(t)             * ----  = 0 equation             *  dt             */            eqn[2] = -coords[0] + 3*coords[2] - 3*coords[4] + coords[6];            eqn[1] = 2*(coords[0] - 2*coords[2] + coords[4]);            eqn[0] = -coords[0] + coords[2];             int nr = QuadCurve2D.solveQuadratic(eqn, res);             /* Following code also correctly works in degenerate case of             * the quadratic equation (nr = -1) because we do not need             * splitting in this case.             */            for (int i = 0; i < nr; i++) {                if (res[i] > 0 && res[i] < 1) {                    params[cnt++] = res[i];                }            }        }         /* Simple check for monotonicity in Y before searching for the extreme         * points of the Y(t) function. We first check if the curve is         * monotonic in Y by seeing if all of the Y coordinates are strongly         * ordered.         */        if ((coords[1] > coords[3] || coords[3] > coords[5] ||             coords[5] > coords[7]) &&            (coords[1] < coords[3] || coords[3] < coords[5] ||             coords[5] < coords[7]))        {            /* Searching for extreme points of the Y(t) function by solving             * dY(t)             * ----- = 0 equation             *  dt             */            eqn[2] = -coords[1] + 3*coords[3] - 3*coords[5] + coords[7];            eqn[1] = 2*(coords[1] - 2*coords[3] + coords[5]);            eqn[0] = -coords[1] + coords[3];             int nr = QuadCurve2D.solveQuadratic(eqn, res);             /* Following code also correctly works in degenerate case of             * the quadratic equation (nr = -1) because we do not need             * splitting in this case.             */            for (int i = 0; i < nr; i++) {                if (res[i] > 0 && res[i] < 1) {                    params[cnt++] = res[i];                }            }        }         if (cnt > 0) {            /* Sorting parameter values corresponding to the extreme points             * of the curve             */            Arrays.sort(params, 0, cnt);             /* Processing obtained monotonic parts */            ProcessFirstMonotonicPartOfCubic(hnd, coords, pixelInfo,                                             (float)params[0]);            for (int i = 1; i < cnt; i++) {                double param = params[i] - params[i-1];                if (param > 0) {                    ProcessFirstMonotonicPartOfCubic(hnd, coords, pixelInfo,                        /* Scale parameter to match with rest of the curve */                        (float)(param/(1.0 - params[i - 1])));                }            }        }         ProcessMonotonicCubic(hnd,coords,pixelInfo);    }     /*     * Bite the piece of the cubic curve from start point till the point     * corresponding to the specified parameter then call ProcessCubic for the     * bitten part.     * Note: coords array will be changed     */    private static void ProcessFirstMonotonicPartOfCubic(ProcessHandler hnd,                                                         float[] coords,                                                         int[] pixelInfo,                                                         float t)    {        float[] coords1 = new float[8];        float tx, ty;         coords1[0] = coords[0];        coords1[1] = coords[1];        tx = coords[2] + t*(coords[4] - coords[2]);        ty = coords[3] + t*(coords[5] - coords[3]);        coords1[2] =  coords[0] + t*(coords[2] - coords[0]);        coords1[3] =  coords[1] + t*(coords[3] - coords[1]);        coords1[4] = coords1[2] + t*(tx - coords1[2]);        coords1[5] = coords1[3] + t*(ty - coords1[3]);        coords[4] = coords[4] + t*(coords[6] - coords[4]);        coords[5] = coords[5] + t*(coords[7] - coords[5]);        coords[2] = tx + t*(coords[4] - tx);        coords[3] = ty + t*(coords[5] - ty);        coords[0]=coords1[6]=coords1[4] + t*(coords[2] - coords1[4]);        coords[1]=coords1[7]=coords1[5] + t*(coords[3] - coords1[5]);         ProcessMonotonicCubic(hnd, coords1, pixelInfo);    }     /* Note:     * For more easy reading of the code below each java version of the macros     * from the ProcessPath.c preceded by the commented origin call     * containing verbose names of the parameters     */    private static void ProcessLine(ProcessHandler hnd, float x1, float y1,                                    float x2, float y2, int[] pixelInfo) {        float xMin, yMin, xMax, yMax;        int X1, Y1, X2, Y2, X3, Y3, res;        boolean clipped = false;        float x3,y3;        float c[] = new float[]{x1, y1, x2, y2, 0, 0};         boolean lastClipped;         xMin = hnd.dhnd.xMinf;        yMin = hnd.dhnd.yMinf;        xMax = hnd.dhnd.xMaxf;        yMax = hnd.dhnd.yMaxf;         //        // TESTANDCLIP(yMin, yMax, y1, x1, y2, x2, res);        //        res = TESTANDCLIP(yMin, yMax, c, 1, 0, 3, 2);        if (res == CRES_INVISIBLE) return;        clipped = IS_CLIPPED(res);        //        // TESTANDCLIP(yMin, yMax, y2, x2, y1, x1, res);        //        res = TESTANDCLIP(yMin, yMax, c, 3, 2, 1, 0);        if (res == CRES_INVISIBLE) return;        lastClipped = IS_CLIPPED(res);        clipped = clipped || lastClipped;         if (hnd.clipMode == PH_MODE_DRAW_CLIP) {            //            // TESTANDCLIP(xMin, xMax, x1, y1, x2, y2, res);            //            res = TESTANDCLIP(xMin, xMax, c, 0, 1, 2, 3);            if (res == CRES_INVISIBLE) return;            clipped = clipped || IS_CLIPPED(res);            //            // TESTANDCLIP(xMin, xMax, x2, y2, x1, y1, res);            //            res = TESTANDCLIP(xMin, xMax, c, 2, 3, 0, 1);            if (res == CRES_INVISIBLE) return;            lastClipped = lastClipped || IS_CLIPPED(res);            clipped = clipped || lastClipped;            X1 = (int)(c[0]*MDP_MULT);            Y1 = (int)(c[1]*MDP_MULT);            X2 = (int)(c[2]*MDP_MULT);            Y2 = (int)(c[3]*MDP_MULT);             hnd.processFixedLine(X1, Y1, X2, Y2, pixelInfo,                                 clipped, /* enable boundary checking in                                             case of clipping to avoid                                             entering out of bounds which                                             could happens during rounding                                           */                                 lastClipped /* Notify pProcessFixedLine                                                that                                                this is the end of the                                                subpath (because of exiting                                                out of boundaries)                                              */                                 );        } else {            /* Clamping starting from first vertex of the the processed             * segment             *             * CLIPCLAMP(xMin, xMax, x1, y1, x2, y2, x3, y3, res);             */            res = CLIPCLAMP(xMin, xMax, c, 0, 1, 2, 3, 4, 5);            X1 = (int)(c[0]*MDP_MULT);            Y1 = (int)(c[1]*MDP_MULT);             /* Clamping only by left boundary */            if (res == CRES_MIN_CLIPPED) {                X3 = (int)(c[4]*MDP_MULT);                Y3 = (int)(c[5]*MDP_MULT);                hnd.processFixedLine(X3, Y3, X1, Y1, pixelInfo,                                     false, lastClipped);             } else if (res == CRES_INVISIBLE) {                return;            }             /* Clamping starting from last vertex of the the processed             * segment             *             * CLIPCLAMP(xMin, xMax, x2, y2, x1, y1, x3, y3, res);             */            res = CLIPCLAMP(xMin, xMax, c, 2, 3, 0, 1, 4, 5);             /* Checking if there was a clip by right boundary */            lastClipped = lastClipped || (res == CRES_MAX_CLIPPED);             X2 = (int)(c[2]*MDP_MULT);            Y2 = (int)(c[3]*MDP_MULT);            hnd.processFixedLine(X1, Y1, X2, Y2, pixelInfo,                                 false, lastClipped);             /* Clamping only by left boundary */            if (res == CRES_MIN_CLIPPED) {                X3 = (int)(c[4]*MDP_MULT);                Y3 = (int)(c[5]*MDP_MULT);                hnd.processFixedLine(X2, Y2, X3, Y3, pixelInfo,                                     false, lastClipped);            }        }    }     private static boolean doProcessPath(ProcessHandler hnd,                                         Path2D.Float p2df,                                         float transXf, float transYf) {        float coords[] = new float[8];        float tCoords[] = new float[8];        float closeCoord[] = new float[] {0.0f, 0.0f};        float firstCoord[] = new float[2];        int pixelInfo[] = new int[5];        boolean subpathStarted = false;        boolean skip = false;        float lastX, lastY;        pixelInfo[0] = 0;         /* Adjusting boundaries to the capabilities of the         * ProcessPath code         */        hnd.dhnd.adjustBounds(LOWER_OUT_BND, LOWER_OUT_BND,                              UPPER_OUT_BND, UPPER_OUT_BND);         /* Adding support of the KEY_STROKE_CONTROL rendering hint.         * Now we are supporting two modes: "pixels at centers" and         * "pixels at corners".         * First one is disabled by default but could be enabled by setting         * VALUE_STROKE_PURE to the rendering hint. It means that pixel at the         * screen (x,y) has (x + 0.5, y + 0.5) float coordinates.         *         * Second one is enabled by default and means straightforward mapping         * (x,y) --> (x,y)         */        if (hnd.dhnd.strokeControl == SunHints.INTVAL_STROKE_PURE) {            closeCoord[0] = -0.5f;            closeCoord[1] = -0.5f;            transXf -= 0.5;            transYf -= 0.5;        }

Lines 1001–1500 of 2128. Previous lines