1223 lines · 44.9 KB · Java
RawDownload
         int kind = 0;        Iterator<Integer> it = Curve.breakPtsAtTs(middle, 8, subdivTs, nSplits);        while(it.hasNext()) {            int curCurveOff = it.next();             kind = computeOffsetCubic(middle, curCurveOff, lp, rp);            emitLineTo(lp[0], lp[1]);            switch(kind) {            case 8:                emitCurveTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], lp[6], lp[7], false);                emitCurveTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7], true);                break;            case 4:                emitLineTo(lp[2], lp[3]);                emitLineTo(rp[0], rp[1], true);                break;            }            emitLineTo(rp[kind - 2], rp[kind - 1], true);        }         this.cmx = (lp[kind - 2] - rp[kind - 2]) / 2;        this.cmy = (lp[kind - 1] - rp[kind - 1]) / 2;        this.cdx = dxf;        this.cdy = dyf;        this.cx0 = xf;        this.cy0 = yf;        this.prev = DRAWING_OP_TO;    }     @Override public void quadTo(float x1, float y1, float x2, float y2) {        middle[0] = cx0; middle[1] = cy0;        middle[2] = x1;  middle[3] = y1;        middle[4] = x2;  middle[5] = y2;         // inlined version of somethingTo(8);        // See the TODO on somethingTo         // need these so we can update the state at the end of this method        final float xf = middle[4], yf = middle[5];        float dxs = middle[2] - middle[0];        float dys = middle[3] - middle[1];        float dxf = middle[4] - middle[2];        float dyf = middle[5] - middle[3];        if ((dxs == 0f && dys == 0f) || (dxf == 0f && dyf == 0f)) {            dxs = dxf = middle[4] - middle[0];            dys = dyf = middle[5] - middle[1];        }        if (dxs == 0f && dys == 0f) {            // this happens iff the "curve" is just a point            lineTo(middle[0], middle[1]);            return;        }        // if these vectors are too small, normalize them, to avoid future        // precision problems.        if (Math.abs(dxs) < 0.1f && Math.abs(dys) < 0.1f) {            float len = (float) sqrt(dxs*dxs + dys*dys);            dxs /= len;            dys /= len;        }        if (Math.abs(dxf) < 0.1f && Math.abs(dyf) < 0.1f) {            float len = (float) sqrt(dxf*dxf + dyf*dyf);            dxf /= len;            dyf /= len;        }         computeOffset(dxs, dys, lineWidth2, offset[0]);        final float mx = offset[0][0];        final float my = offset[0][1];        drawJoin(cdx, cdy, cx0, cy0, dxs, dys, cmx, cmy, mx, my);         int nSplits = findSubdivPoints(middle, subdivTs, 6, lineWidth2);         int kind = 0;        Iterator<Integer> it = Curve.breakPtsAtTs(middle, 6, subdivTs, nSplits);        while(it.hasNext()) {            int curCurveOff = it.next();             kind = computeOffsetQuad(middle, curCurveOff, lp, rp);            emitLineTo(lp[0], lp[1]);            switch(kind) {            case 6:                emitQuadTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], false);                emitQuadTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], true);                break;            case 4:                emitLineTo(lp[2], lp[3]);                emitLineTo(rp[0], rp[1], true);                break;            }            emitLineTo(rp[kind - 2], rp[kind - 1], true);        }         this.cmx = (lp[kind - 2] - rp[kind - 2]) / 2;        this.cmy = (lp[kind - 1] - rp[kind - 1]) / 2;        this.cdx = dxf;        this.cdy = dyf;        this.cx0 = xf;        this.cy0 = yf;        this.prev = DRAWING_OP_TO;    }     @Override public long getNativeConsumer() {        throw new InternalError("Stroker doesn't use a native consumer");    }     // a stack of polynomial curves where each curve shares endpoints with    // adjacent ones.    private static final class PolyStack {        float[] curves;        int end;        int[] curveTypes;        int numCurves;         private static final int INIT_SIZE = 50;         PolyStack() {            curves = new float[8 * INIT_SIZE];            curveTypes = new int[INIT_SIZE];            end = 0;            numCurves = 0;        }         public boolean isEmpty() {            return numCurves == 0;        }         private void ensureSpace(int n) {            if (end + n >= curves.length) {                int newSize = (end + n) * 2;                curves = Arrays.copyOf(curves, newSize);            }            if (numCurves >= curveTypes.length) {                int newSize = numCurves * 2;                curveTypes = Arrays.copyOf(curveTypes, newSize);            }        }         public void pushCubic(float x0, float y0,                              float x1, float y1,                              float x2, float y2)        {            ensureSpace(6);            curveTypes[numCurves++] = 8;            // assert(x0 == lastX && y0 == lastY)             // we reverse the coordinate order to make popping easier            curves[end++] = x2;    curves[end++] = y2;            curves[end++] = x1;    curves[end++] = y1;            curves[end++] = x0;    curves[end++] = y0;        }         public void pushQuad(float x0, float y0,                             float x1, float y1)        {            ensureSpace(4);            curveTypes[numCurves++] = 6;            // assert(x0 == lastX && y0 == lastY)            curves[end++] = x1;    curves[end++] = y1;            curves[end++] = x0;    curves[end++] = y0;        }         public void pushLine(float x, float y) {            ensureSpace(2);            curveTypes[numCurves++] = 4;            // assert(x0 == lastX && y0 == lastY)            curves[end++] = x;    curves[end++] = y;        }         @SuppressWarnings("unused")        public int pop(float[] pts) {            int ret = curveTypes[numCurves - 1];            numCurves--;            end -= (ret - 2);            System.arraycopy(curves, end, pts, 0, ret - 2);            return ret;        }         public void pop(PathConsumer2D io) {            numCurves--;            int type = curveTypes[numCurves];            end -= (type - 2);            switch(type) {            case 8:                io.curveTo(curves[end+0], curves[end+1],                           curves[end+2], curves[end+3],                           curves[end+4], curves[end+5]);                break;            case 6:                io.quadTo(curves[end+0], curves[end+1],                           curves[end+2], curves[end+3]);                 break;            case 4:                io.lineTo(curves[end], curves[end+1]);            }        }         @Override        public String toString() {            String ret = "";            int nc = numCurves;            int end = this.end;            while (nc > 0) {                nc--;                int type = curveTypes[numCurves];                end -= (type - 2);                switch(type) {                case 8:                    ret += "cubic: ";                    break;                case 6:                    ret += "quad: ";                    break;                case 4:                    ret += "line: ";                    break;                }                ret += Arrays.toString(Arrays.copyOfRange(curves, end, end+type-2)) + "\n";            }            return ret;        }    }}

Lines 1001–1223 of 1223. Previous lines