Exemple #1
0
// Modify pts[] in place so that it is clipped in Y to the clip rect
static void chop_cubic_in_Y(SkPoint pts[4], const SkRect& clip) {

    // are we partially above
    if (pts[0].fY < clip.fTop) {
        SkScalar t;
        if (chopMonoCubicAtY(pts, clip.fTop, &t)) {
            SkPoint tmp[7];
            SkChopCubicAt(pts, tmp, t);

            // tmp[3, 4, 5].fY should all be to the below clip.fTop.
            // Since we can't trust the numerics of
            // the chopper, we force those conditions now
            tmp[3].fY = clip.fTop;
            clamp_ge(tmp[4].fY, clip.fTop);
            clamp_ge(tmp[5].fY, clip.fTop);

            pts[0] = tmp[3];
            pts[1] = tmp[4];
            pts[2] = tmp[5];
        } else {
            // if chopMonoCubicAtY failed, then we may have hit inexact numerics
            // so we just clamp against the top
            for (int i = 0; i < 4; i++) {
                clamp_ge(pts[i].fY, clip.fTop);
            }
        }
    }

    // are we partially below
    if (pts[3].fY > clip.fBottom) {
        SkScalar t;
        if (chopMonoCubicAtY(pts, clip.fBottom, &t)) {
            SkPoint tmp[7];
            SkChopCubicAt(pts, tmp, t);
            tmp[3].fY = clip.fBottom;
            clamp_le(tmp[2].fY, clip.fBottom);

            pts[1] = tmp[1];
            pts[2] = tmp[2];
            pts[3] = tmp[3];
        } else {
            // if chopMonoCubicAtY failed, then we may have hit inexact numerics
            // so we just clamp against the bottom
            for (int i = 0; i < 4; i++) {
                clamp_le(pts[i].fY, clip.fBottom);
            }
        }
    }
}
Exemple #2
0
bool SkCubicClipper::clipCubic(const SkPoint srcPts[4], SkPoint dst[4]) {
    bool reverse;

    // we need the data to be monotonically descending in Y
    if (srcPts[0].fY > srcPts[3].fY) {
        dst[0] = srcPts[3];
        dst[1] = srcPts[2];
        dst[2] = srcPts[1];
        dst[3] = srcPts[0];
        reverse = true;
    } else {
        memcpy(dst, srcPts, 4 * sizeof(SkPoint));
        reverse = false;
    }

    // are we completely above or below
    const SkScalar ctop = fClip.fTop;
    const SkScalar cbot = fClip.fBottom;
    if (dst[3].fY <= ctop || dst[0].fY >= cbot) {
        return false;
    }

    SkScalar t;
    SkPoint tmp[7]; // for SkChopCubicAt

    // are we partially above
    if (dst[0].fY < ctop && chopMonoCubicAtY(dst, ctop, &t)) {
        SkChopCubicAt(dst, tmp, t);
        dst[0] = tmp[3];
        dst[1] = tmp[4];
        dst[2] = tmp[5];
    }

    // are we partially below
    if (dst[3].fY > cbot && chopMonoCubicAtY(dst, cbot, &t)) {
        SkChopCubicAt(dst, tmp, t);
        dst[1] = tmp[1];
        dst[2] = tmp[2];
        dst[3] = tmp[3];
    }

    if (reverse) {
        SkTSwap<SkPoint>(dst[0], dst[3]);
        SkTSwap<SkPoint>(dst[1], dst[2]);
    }
    return true;
}
Exemple #3
0
// Modify pts[] in place so that it is clipped in Y to the clip rect
static void chop_cubic_in_Y(SkPoint pts[4], const SkRect& clip) {
    SkScalar t;
    SkPoint tmp[7]; // for SkChopCubicAt
    
    // are we partially above
    if (pts[0].fY < clip.fTop) {
        if (chopMonoCubicAtY(pts, clip.fTop, &t)) {
            SkChopCubicAt(pts, tmp, t);
            // given the imprecision of computing t, we just slam our Y coord
            // to the top of the clip. This also saves us in the bad case where
            // the t was soooo bad that the entire segment could have been
            // below fBottom
            tmp[3].fY = clip.fTop;
            clamp_ge(tmp[4].fY, clip.fTop);
            clamp_ge(tmp[5].fY, clip.fTop);
            pts[0] = tmp[3];
            pts[1] = tmp[4];
            pts[2] = tmp[5];
        } else {
            // if chopMonoCubicAtY failed, then we may have hit inexact numerics
            // so we just clamp against the top
            for (int i = 0; i < 4; i++) {
                clamp_ge(pts[i].fY, clip.fTop);
            }
        }
    }
    
    // are we partially below
    if (pts[3].fY > clip.fBottom) {
        if (chopMonoCubicAtY(pts, clip.fBottom, &t)) {
            SkChopCubicAt(pts, tmp, t);
            clamp_le(tmp[1].fY, clip.fBottom);
            clamp_le(tmp[2].fY, clip.fBottom);
            clamp_le(tmp[3].fY, clip.fBottom);
            pts[1] = tmp[1];
            pts[2] = tmp[2];
            pts[3] = tmp[3];
        } else {
            // if chopMonoCubicAtY failed, then we may have hit inexact numerics
            // so we just clamp against the bottom
            for (int i = 0; i < 4; i++) {
                clamp_le(pts[i].fY, clip.fBottom);
            }
        }
    }
}