Example #1
0
static int vertical_coincident(const SkDLine& line, double x) {
    double min = line[0].fX;
    double max = line[1].fX;
    if (min > max) {
        SkTSwap(min, max);
    }
    if (!precisely_between(min, x, max)) {
        return 0;
    }
    if (AlmostEqualUlps(min, max)) {
        return 2;
    }
    return 1;
}
Example #2
0
int SkIntersections::vertical(const SkDLine& line, double x) {
    double min = line[0].fX;
    double max = line[1].fX;
    if (min > max) {
        SkTSwap(min, max);
    }
    if (!precisely_between(min, x, max)) {
        return fUsed = 0;
    }
    if (AlmostEqualUlps(min, max)) {
        fT[0][0] = 0;
        fT[0][1] = 1;
        return fUsed = 2;
    }
    fT[0][0] = (x - line[0].fX) / (line[1].fX - line[0].fX);
    return fUsed = 1;
}
Example #3
0
int SkIntersections::vertical(const SkDLine& line, double top, double bottom,
                              double x, bool flipped) {
    int result = vertical(line, x);
    switch (result) {
        case 0:
            break;
        case 1: {
            double yIntercept = line[0].fY + fT[0][0] * (line[1].fY - line[0].fY);
            if (!precisely_between(top, yIntercept, bottom)) {
                return fUsed = 0;
            }
            fT[1][0] = (yIntercept - top) / (bottom - top);
            break;
        }
        case 2:
            double a0 = line[0].fY;
            double a1 = line[1].fY;
            double b0 = flipped ? bottom : top;
            double b1 = flipped ? top : bottom;
            // FIXME: share common code above
            double at0 = (a0 - b0) / (a0 - a1);
            double at1 = (a0 - b1) / (a0 - a1);
            if ((at0 < 0 && at1 < 0) || (at0 > 1 && at1 > 1)) {
                return fUsed = 0;
            }
            fT[0][0] = SkTMax(SkTMin(at0, 1.0), 0.0);
            fT[0][1] = SkTMax(SkTMin(at1, 1.0), 0.0);
            int bIn = (a0 - a1) * (b0 - b1) < 0;
            fT[1][bIn] = SkTMax(SkTMin((b0 - a0) / (b0 - b1), 1.0), 0.0);
            fT[1][!bIn] = SkTMax(SkTMin((b0 - a1) / (b0 - b1), 1.0), 0.0);
            bool second = fabs(fT[0][0] - fT[0][1]) > FLT_EPSILON;
            SkASSERT((fabs(fT[1][0] - fT[1][1]) <= FLT_EPSILON) ^ second);
            return computePoints(line, 1 + second);
    }
    if (flipped) {
        // OPTIMIZATION: instead of swapping, pass original line, use [1].fY - [0].fY
        for (int index = 0; index < result; ++index) {
            fT[1][index] = 1 - fT[1][index];
        }
    }
    return computePoints(line, result);
}
Example #4
0
int SkIntersections::horizontal(const SkDLine& line, double left, double right,
                                double y, bool flipped) {
    int result = horizontal(line, y);
    switch (result) {
        case 0:
            break;
        case 1: {
            double xIntercept = line[0].fX + fT[0][0] * (line[1].fX - line[0].fX);
            if (!precisely_between(left, xIntercept, right)) {
                return fUsed = 0;
            }
            fT[1][0] = (xIntercept - left) / (right - left);
            break;
        }
        case 2:
            double a0 = line[0].fX;
            double a1 = line[1].fX;
            double b0 = flipped ? right : left;
            double b1 = flipped ? left : right;
            // FIXME: share common code below
            double at0 = (a0 - b0) / (a0 - a1);
            double at1 = (a0 - b1) / (a0 - a1);
            if ((at0 < 0 && at1 < 0) || (at0 > 1 && at1 > 1)) {
                return fUsed = 0;
            }
            fT[0][0] = SkTMax(SkTMin(at0, 1.0), 0.0);
            fT[0][1] = SkTMax(SkTMin(at1, 1.0), 0.0);
            int bIn = (a0 - a1) * (b0 - b1) < 0;
            fT[1][bIn] = SkTMax(SkTMin((b0 - a0) / (b0 - b1), 1.0), 0.0);
            fT[1][!bIn] = SkTMax(SkTMin((b0 - a1) / (b0 - b1), 1.0), 0.0);
            bool second = fabs(fT[0][0] - fT[0][1]) > FLT_EPSILON;
            SkASSERT((fabs(fT[1][0] - fT[1][1]) <= FLT_EPSILON) ^ second);
            return computePoints(line, 1 + second);
    }
    if (flipped) {
        // OPTIMIZATION: instead of swapping, pass original line, use [1].fX - [0].fX
        for (int index = 0; index < result; ++index) {
            fT[1][index] = 1 - fT[1][index];
        }
    }
    return computePoints(line, result);
}
int SkIntersections::vertical(const SkDLine& line, double top, double bottom,
                                double x, bool flipped) {
    // see if end points intersect the opposite line
    double t;
    if (checkEndPoint(x, top, line, &t, false)) {
        insert(t, flipped, x, top);
    }
    if (top != bottom) {
        if (checkEndPoint(x, bottom,line, &t, false)) {
            insert(t, !flipped, x, bottom);
        }
        for (int index = 0; index < 2; ++index) {
            if (!checkEndPointV(line[index], top, bottom, x, flipped, &t)) {
                continue;
            }
            insert( index, t, line[index]);
        }
    }
    if (used() > 0) {
        SkASSERT(fUsed <= 2);
        return used(); // coincident lines are returned here
    }
    int result = vertical(line, x);
    if (!result) {
        return 0;
    }
    SkASSERT(result == 1);
    double yIntercept = line[0].fY + fT[0][0] * (line[1].fY - line[0].fY);
    if (!precisely_between(top, yIntercept, bottom)) {
        return fUsed = 0;
    }
    fT[1][0] = (yIntercept - top) / (bottom - top);
    if (flipped) {
        // OPTIMIZATION: instead of swapping, pass original line, use [1].fY - [0].fY
        for (int index = 0; index < result; ++index) {
            fT[1][index] = 1 - fT[1][index];
        }
    }
    return computePoints(line, result);
}
int SkIntersections::horizontal(const SkDLine& line, double left, double right,
                                double y, bool flipped) {
    // see if end points intersect the opposite line
    double t;
    if (checkEndPoint(left, y, line, &t, true)) {
        insert(t, flipped, left, y);
    }
    if (left != right) {
        if (checkEndPoint(right, y, line, &t, true)) {
            insert(t, !flipped, right, y);
        }
        for (int index = 0; index < 2; ++index) {
            if (!checkEndPointH(line[index], left, right, y, flipped, &t)) {
                continue;
            }
            insert(index, t, line[index]);
        }
    }
    if (used() > 0) {
        SkASSERT(fUsed <= 2);
        return used(); // coincident lines are returned here
    }
    int result = horizontal(line, y);
    if (!result) {
        return 0;
    }
    SkASSERT(result == 1);
    double xIntercept = line[0].fX + fT[0][0] * (line[1].fX - line[0].fX);
    if (!precisely_between(left, xIntercept, right)) {
        return fUsed = 0;
    }
    fT[1][0] = (xIntercept - left) / (right - left);
    if (flipped) {
        // OPTIMIZATION: ? instead of swapping, pass original line, use [1].fX - [0].fX
        for (int index = 0; index < result; ++index) {
            fT[1][index] = 1 - fT[1][index];
        }
    }
    return computePoints(line, result);
}
Example #7
0
bool SkDCubic::monotonicInY() const {
    return precisely_between(fPts[0].fY, fPts[1].fY, fPts[3].fY)
            && precisely_between(fPts[0].fY, fPts[2].fY, fPts[3].fY);
}