2128 lines · 78.3 KB · Java
RawDownload
            if ((pixelInfo[1] == X1 && pixelInfo[2] == Y1) ||                (pixelInfo[3] == X1 && pixelInfo[4] == Y1))            {                if (checkBounds &&                    (dhnd.yMin > Y1  ||                     dhnd.yMax <= Y1 ||                     dhnd.xMin > X1  ||                     dhnd.xMax <= X1)) {                    return;                }                 dhnd.drawPixel(X1, Y1);            }            pixelInfo[3] = X1;            pixelInfo[4] = Y1;        }         void PROCESS_POINT(int fX, int fY, boolean checkBounds,                           int[] pixelInfo) {            int _X = fX>> MDP_PREC;            int _Y = fY>> MDP_PREC;            if (checkBounds &&                (dhnd.yMin > _Y  ||                 dhnd.yMax <= _Y ||                 dhnd.xMin > _X  ||                 dhnd.xMax <= _X)) return;            /*             *  (_X,_Y) should be inside boundaries             *             *  assert(dhnd.yMin <= _Y &&             *         dhnd.yMax >  _Y &&             *         dhnd.xMin <= _X &&             *         dhnd.xMax >  _X);             *             */            if (pixelInfo[0] == 0) {                pixelInfo[0] = 1;                pixelInfo[1] = _X;                pixelInfo[2] = _Y;                pixelInfo[3] = _X;                pixelInfo[4] = _Y;                dhnd.drawPixel(_X, _Y);            } else if ((_X != pixelInfo[3] || _Y != pixelInfo[4]) &&                       (_X != pixelInfo[1] || _Y != pixelInfo[2])) {                dhnd.drawPixel(_X, _Y);                pixelInfo[3] = _X;                pixelInfo[4] = _Y;            }        }         /*                  Drawing line with subpixel endpoints         *         * (x1, y1), (x2, y2) -  fixed point coordinates of the endpoints         *                       with MDP_PREC bits for the fractional part         *         * pixelInfo          -  structure which keeps drawing info for avoiding         *                       multiple drawing at the same position on the         *                       screen (required for the XOR mode of drawing)         *         *                          pixelInfo[0]   - state of the drawing         *                                           0 - no pixel drawn between         *                                           moveTo/close of the path         *                                           1 - there are drawn pixels         *         *                          pixelInfo[1,2] - first pixel of the path         *                                           between moveTo/close of the         *                                           path         *         *                          pixelInfo[3,4] - last drawn pixel between         *                                           moveTo/close of the path         *         * checkBounds        - flag showing necessity of checking the clip         *         */        public void  processFixedLine(int x1, int y1, int x2, int y2,                                      int[] pixelInfo, boolean checkBounds,                                      boolean endSubPath)  {             /* Checking if line is inside a (X,Y),(X+MDP_MULT,Y+MDP_MULT) box */            int c = ((x1 ^ x2) | (y1 ^ y2));            int rx1, ry1, rx2, ry2;            if ((c & MDP_W_MASK) == 0) {                /* Checking for the segments with integer coordinates having                 * the same start and end points                 */                if (c == 0) {                    PROCESS_POINT(x1 + MDP_HALF_MULT, y1 + MDP_HALF_MULT,                                  checkBounds, pixelInfo);                }                return;            }             if (x1 == x2 || y1 == y2) {                rx1 = x1 + MDP_HALF_MULT;                rx2 = x2 + MDP_HALF_MULT;                ry1 = y1 + MDP_HALF_MULT;                ry2 = y2 + MDP_HALF_MULT;            } else {                /* Neither dx nor dy can be zero because of the check above */                int dx = x2 - x1;                int dy = y2 - y1;                 /* Floor of x1, y1, x2, y2 */                int fx1 = x1 & MDP_W_MASK;                int fy1 = y1 & MDP_W_MASK;                int fx2 = x2 & MDP_W_MASK;                int fy2 = y2 & MDP_W_MASK;                 /* Processing first endpoint */                if (fx1 == x1 || fy1 == y1) {                    /* Adding MDP_HALF_MULT to the [xy]1 if f[xy]1 == [xy]1                     * will not affect the result                     */                    rx1 = x1 + MDP_HALF_MULT;                    ry1 = y1 + MDP_HALF_MULT;                } else {                    /* Boundary at the direction from (x1,y1) to (x2,y2) */                    int bx1 = (x1 < x2) ? fx1 + MDP_MULT : fx1;                    int by1 = (y1 < y2) ? fy1 + MDP_MULT : fy1;                     /* intersection with column bx1 */                    int cross = y1 + ((bx1 - x1)*dy)/dx;                    if (cross >= fy1 && cross <= fy1 + MDP_MULT) {                        rx1 = bx1;                        ry1 = cross + MDP_HALF_MULT;                    } else {                        /* intersection with row by1 */                        cross = x1 + ((by1 - y1)*dx)/dy;                        rx1 = cross + MDP_HALF_MULT;                        ry1 = by1;                    }                }                 /* Processing second endpoint */                if (fx2 == x2 || fy2 == y2) {                    /* Adding MDP_HALF_MULT to the [xy]2 if f[xy]2 == [xy]2                     * will not affect the result                     */                    rx2 = x2 + MDP_HALF_MULT;                    ry2 = y2 + MDP_HALF_MULT;                } else {                    /* Boundary at the direction from (x2,y2) to (x1,y1) */                    int bx2 = (x1 > x2) ? fx2 + MDP_MULT : fx2;                    int by2 = (y1 > y2) ? fy2 + MDP_MULT : fy2;                     /* intersection with column bx2 */                    int cross = y2 + ((bx2 - x2)*dy)/dx;                    if (cross >= fy2 && cross <= fy2 + MDP_MULT) {                        rx2 = bx2;                        ry2 = cross + MDP_HALF_MULT;                    } else {                        /* intersection with row by2 */                        cross = x2 + ((by2 - y2)*dx)/dy;                        rx2 = cross + MDP_HALF_MULT;                        ry2 = by2;                    }                }            }            PROCESS_LINE(rx1, ry1, rx2, ry2, checkBounds, pixelInfo);        }    }     /* Performing drawing of the monotonic in X and Y quadratic curves with     * sizes less than MAX_QUAD_SIZE by using forward differencing method of     * calculation. See comments to the DrawMonotonicQuad in the     * ProcessGeneralPath.c     */    private static void DrawMonotonicQuad(ProcessHandler hnd,                                          float[] coords,                                          boolean checkBounds,                                          int[] pixelInfo) {         int x0 = (int)(coords[0]*MDP_MULT);        int y0 = (int)(coords[1]*MDP_MULT);         int xe = (int)(coords[4]*MDP_MULT);        int ye = (int)(coords[5]*MDP_MULT);         /* Extracting fractional part of coordinates of first control point */        int px = (x0 & (~MDP_W_MASK)) << DF_QUAD_SHIFT;        int py = (y0 & (~MDP_W_MASK)) << DF_QUAD_SHIFT;         /* Setting default amount of steps */        int count = DF_QUAD_COUNT;         /* Setting default shift for preparing to the midpoint rounding */        int shift =  DF_QUAD_SHIFT;         int ax = (int)((coords[0] - 2*coords[2] +                         coords[4])*QUAD_A_MDP_MULT);        int ay = (int)((coords[1] - 2*coords[3] +                         coords[5])*QUAD_A_MDP_MULT);         int bx = (int)((-2*coords[0] + 2*coords[2])*QUAD_B_MDP_MULT);        int by = (int)((-2*coords[1] + 2*coords[3])*QUAD_B_MDP_MULT);         int ddpx = 2*ax;        int ddpy = 2*ay;         int dpx = ax + bx;        int dpy = ay + by;         int x1, y1;         int x2 = x0;        int y2 = y0;         int maxDD = Math.max(Math.abs(ddpx),Math.abs(ddpy));         int dx = xe - x0;        int dy = ye - y0;         int x0w = x0 & MDP_W_MASK;        int y0w = y0 & MDP_W_MASK;         /* Perform decreasing step in 2 times if slope of the first forward         * difference changes too quickly (more than a pixel per step in X or Y         * direction).  We can perform adjusting of the step size before the         * rendering loop because the curvature of the quad curve remains the         * same along all the curve         */        while (maxDD > DF_QUAD_DEC_BND) {            dpx = (dpx<<1) - ax;            dpy = (dpy<<1) - ay;            count <<= 1;            maxDD >>= 2;            px <<=2;            py <<=2;            shift += 2;        }         while(count-- > 1) {            px += dpx;            py += dpy;             dpx += ddpx;            dpy += ddpy;             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);        }         /* We are performing one step less than necessary and use actual         * (xe,ye) endpoint of the curve instead of calculated. This prevent us         * from running above the curve endpoint due to the accumulated errors         * during the iterations.         */         hnd.processFixedLine(x2, y2, xe, ye, pixelInfo, checkBounds, false);    }     /*     * Checking size of the quad curves and split them if necessary.     * Calling DrawMonotonicQuad for the curves of the appropriate size.     * Note: coords array could be changed     */    private static void ProcessMonotonicQuad(ProcessHandler hnd,                                             float[] coords,                                             int[] pixelInfo) {         float[] coords1 = new float[6];        float tx, ty;        float xMin, yMin, xMax, yMax;         xMin = xMax = coords[0];        yMin = yMax = coords[1];        for (int i = 2; i < 6; 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] = hnd.dhnd.xMinf;            }        }         if (xMax - xMin > MAX_QUAD_SIZE || yMax - yMin > MAX_QUAD_SIZE) {            coords1[4] = coords[4];            coords1[5] = coords[5];            coords1[2] = (coords[2] + coords[4])/2.0f;            coords1[3] = (coords[3] + coords[5])/2.0f;            coords[2] = (coords[0] + coords[2])/2.0f;            coords[3] = (coords[1] + coords[3])/2.0f;            coords[4] = coords1[0] = (coords[2] + coords1[2])/2.0f;            coords[5] = coords1[1] = (coords[3] + coords1[3])/2.0f;             ProcessMonotonicQuad(hnd, coords, pixelInfo);             ProcessMonotonicQuad(hnd, coords1, pixelInfo);        } else {            DrawMonotonicQuad(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 quadratic curve into monotonic in X and Y parts. Calling     * ProcessMonotonicQuad for each monotonic piece of the curve.     * Note: coords array could be changed     */    private static void ProcessQuad(ProcessHandler hnd, float[] coords,                                    int[] pixelInfo) {        /* Temporary array for holding parameters corresponding to the extreme         * in X and Y points         */        double params[] = new double[2];        int cnt = 0;        double param;         /* 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[0] < coords[2] || coords[2] < coords[4]))        {            /* Searching for extreme points of the X(t) function  by solving             * dX(t)             * ----  = 0 equation             *  dt             */            double ax = coords[0] - 2*coords[2] + coords[4];            if (ax != 0) {                /* Calculating root of the following equation                 * ax*t + bx = 0                 */                double bx = coords[0] - coords[2];                 param = bx/ax;                if (param < 1.0 && param > 0.0) {                    params[cnt++] = param;                }            }        }         /* 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[1] < coords[3] || coords[3] < coords[5]))        {            /* Searching for extreme points of the Y(t) function by solving             * dY(t)             * ----- = 0 equation             *  dt             */            double ay = coords[1] - 2*coords[3] + coords[5];             if (ay != 0) {                /* Calculating root of the following equation                 * ay*t + by = 0                 */                double by = coords[1] - coords[3];                 param = by/ay;                if (param < 1.0 && param > 0.0) {                    if (cnt > 0) {                        /* Inserting parameter only if it differs from                         * already stored                         */                        if (params[0] >  param) {                            params[cnt++] = params[0];                            params[0] = param;                        } else if (params[0] <  param) {                            params[cnt++] = param;                        }                    } else {                        params[cnt++] = param;                    }                }            }        }         /* Processing obtained monotonic parts */        switch(cnt) {            case 0:                break;            case 1:                ProcessFirstMonotonicPartOfQuad(hnd, coords, pixelInfo,                                                (float)params[0]);                break;            case 2:                ProcessFirstMonotonicPartOfQuad(hnd, coords, pixelInfo,                                                (float)params[0]);                param = params[1] - params[0];                if (param > 0) {                    ProcessFirstMonotonicPartOfQuad(hnd, coords, pixelInfo,                                           /* Scale parameter to match with                                            * rest of the curve                                            */                                           (float)(param/(1.0 - params[0])));                }                break;        }         ProcessMonotonicQuad(hnd,coords,pixelInfo);    }     /*     * Bite the piece of the quadratic curve from start point till the point     * corresponding to the specified parameter then call ProcessQuad for the     * bitten part.     * Note: coords array will be changed     */    private static void ProcessFirstMonotonicPartOfQuad(ProcessHandler hnd,                                                        float[] coords,                                                        int[] pixelInfo,                                                        float t) {        float[] coords1 = new float[6];         coords1[0] = coords[0];        coords1[1] = coords[1];        coords1[2] = coords[0] + t*(coords[2] - coords[0]);        coords1[3] = coords[1] + t*(coords[3] - coords[1]);        coords[2] = coords[2] + t*(coords[4] - coords[2]);        coords[3] = coords[3] + t*(coords[5] - coords[3]);        coords[0] = coords1[4] = coords1[2] + t*(coords[2] - coords1[2]);        coords[1] = coords1[5] = coords1[3] + t*(coords[3] - coords1[3]);         ProcessMonotonicQuad(hnd, coords1, pixelInfo);    }     /* Performing drawing of the monotonic in X and Y cubic curves with sizes     * less than MAX_CUB_SIZE by using forward differencing method of     * calculation.  See comments to the DrawMonotonicCubic in the     * ProcessGeneralPath.c     */    private static void DrawMonotonicCubic(ProcessHandler hnd,                                           float[] coords,                                           boolean checkBounds,                                           int[] pixelInfo) {        int x0 = (int)(coords[0]*MDP_MULT);        int y0 = (int)(coords[1]*MDP_MULT);         int xe = (int)(coords[6]*MDP_MULT);        int ye = (int)(coords[7]*MDP_MULT);         /* Extracting fractional part of coordinates of first control point */        int px = (x0 & (~MDP_W_MASK)) << DF_CUB_SHIFT;        int py = (y0 & (~MDP_W_MASK)) << DF_CUB_SHIFT;

Lines 501–1000 of 2128. Previous lines