<commit_before>#include "GrPath.h"

GrPath::GrPath() {
    fConvexHint = kNone_ConvexHint;
}

GrPath::GrPath(const GrPath& src) : INHERITED() {
    GrPath::Iter iter(src);
    this->resetFromIter(&iter);
}

GrPath::GrPath(GrPathIter& iter) {
    this->resetFromIter(&iter);
}

GrPath::~GrPath() {
}

bool GrPath::operator ==(const GrPath& path) const {
    if (fCmds.count() != path.fCmds.count() ||
        fPts.count() != path.fPts.count()) {
        return false;
    }

    for (int v = 0; v < fCmds.count(); ++v) {
        if (fCmds[v] != path.fCmds[v]) {
            return false;
        }
    }

    for (int p = 0; p < fPts.count(); ++p) {
        if (fPts[p] != path.fPts[p]) {
            return false;
        }
    }
    return true;
}

void GrPath::ensureMoveTo() {
    if (fCmds.isEmpty() || this->wasLastVerb(kClose_PathCmd)) {
        *fCmds.append() = kMove_PathCmd;
        fPts.append()->set(0, 0);
    }
}

void GrPath::moveTo(GrScalar x, GrScalar y) {
    if (this->wasLastVerb(kMove_PathCmd)) {
        // overwrite prev kMove value
        fPts[fPts.count() - 1].set(x, y);
    } else {
        *fCmds.append() = kMove_PathCmd;
        fPts.append()->set(x, y);
    }
}

void GrPath::lineTo(GrScalar x, GrScalar y) {
    this->ensureMoveTo();
    *fCmds.append() = kLine_PathCmd;
    fPts.append()->set(x, y);
}

void GrPath::quadTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1) {
    this->ensureMoveTo();
    *fCmds.append() = kQuadratic_PathCmd;
    fPts.append()->set(x0, y0);
    fPts.append()->set(x1, y1);
}

void GrPath::cubicTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1,
                     GrScalar x2, GrScalar y2) {
    this->ensureMoveTo();
    *fCmds.append() = kCubic_PathCmd;
    fPts.append()->set(x0, y0);
    fPts.append()->set(x1, y1);
    fPts.append()->set(x2, y2);
}

void GrPath::close() {
    if (!fCmds.isEmpty() && !this->wasLastVerb(kClose_PathCmd)) {
        // should we allow kMove followed by kClose?
        *fCmds.append() = kClose_PathCmd;
    }
}

///////////////////////////////////////////////////////////////////////////////

void GrPath::offset(GrScalar tx, GrScalar ty) {
    if (!tx && !ty) {
        return; // nothing to do
    }

    GrPoint* iter = fPts.begin();
    GrPoint* stop = fPts.end();
    while (iter < stop) {
        iter->offset(tx, ty);
        ++iter;
    }
}

///////////////////////////////////////////////////////////////////////////////

static bool check_two_vecs(const GrVec& prevVec,
                           const GrVec& currVec,
                           GrScalar turnDir,
                           int* xDir,
                           int* yDir,
                           int* flipX,
                           int* flipY) {
    if (currVec.fX * *xDir < 0) {
        ++*flipX;
        if (*flipX > 2) {
            return false;
        }
        *xDir = -*xDir;
    }
    if (currVec.fY * *yDir < 0) {
        ++*flipY;
        if (*flipY > 2) {
            return false;
        }
        *yDir = -*yDir;
    }
    GrScalar d = prevVec.cross(currVec);
    return (d * turnDir) >= 0;
}

static void init_from_two_vecs(const GrVec& firstVec,
                               const GrVec& secondVec,
                               GrScalar* turnDir,
                               int* xDir, int* yDir) {
    *turnDir = firstVec.cross(secondVec);
    if (firstVec.fX > 0) {
        *xDir = 1;
    } else if (firstVec.fX < 0) {
        *xDir = -1;
    } else {
        *xDir = 0;
    }
    if (firstVec.fY > 0) {
        *yDir = 1;
    } else if (firstVec.fY < 0) {
        *yDir = -1;
    } else {
        *yDir = 0;
    }
}

void GrPath::resetFromIter(GrPathIter* iter) {
    fPts.reset();
    fCmds.reset();

    fConvexHint = iter->convexHint();

    // first point of the subpath
    GrPoint firstPt(0,0);
    // first edge of the subpath
    GrVec firstVec(0,0);
    // vec of most recently processed edge, that wasn't degenerate
    GrVec previousVec(0,0);
    // most recently processed point
    GrPoint previousPt(0,0);

    // sign indicates whether we're bending left or right
    GrScalar turnDir = 0;
    // number of times the direction has flipped in x or y

    // we track which direction we are moving in x/y and the
    // number of times it changes.
    int xDir = 0;
    int yDir = 0;
    int flipX = 0;
    int flipY = 0;

    // counts number of sub path pts that didn't add a degenerate edge.
    int subPathPts = 0;

    int numSubPaths = 0;
    iter->rewind();
    GrPathCmd cmd;
    GrPoint pts[4];
    bool subPathClosed;
    do {
        cmd = iter->next(pts);
        // If the convexity test is ever updated to handle multiple subpaths
        // the loop has to be adjusted to handle moving to a new subpath without
        // closing the previous one. Currently the implicit closing vectors for a
        // filled path would never be examined.<commit_msg>Fix warning about uninit var subpathClosed<commit_after>#include "GrPath.h"

GrPath::GrPath() {
    fConvexHint = kNone_ConvexHint;
}

GrPath::GrPath(const GrPath& src) : INHERITED() {
    GrPath::Iter iter(src);
    this->resetFromIter(&iter);
}

GrPath::GrPath(GrPathIter& iter) {
    this->resetFromIter(&iter);
}

GrPath::~GrPath() {
}

bool GrPath::operator ==(const GrPath& path) const {
    if (fCmds.count() != path.fCmds.count() ||
        fPts.count() != path.fPts.count()) {
        return false;
    }

    for (int v = 0; v < fCmds.count(); ++v) {
        if (fCmds[v] != path.fCmds[v]) {
            return false;
        }
    }

    for (int p = 0; p < fPts.count(); ++p) {
        if (fPts[p] != path.fPts[p]) {
            return false;
        }
    }
    return true;
}

void GrPath::ensureMoveTo() {
    if (fCmds.isEmpty() || this->wasLastVerb(kClose_PathCmd)) {
        *fCmds.append() = kMove_PathCmd;
        fPts.append()->set(0, 0);
    }
}

void GrPath::moveTo(GrScalar x, GrScalar y) {
    if (this->wasLastVerb(kMove_PathCmd)) {
        // overwrite prev kMove value
        fPts[fPts.count() - 1].set(x, y);
    } else {
        *fCmds.append() = kMove_PathCmd;
        fPts.append()->set(x, y);
    }
}

void GrPath::lineTo(GrScalar x, GrScalar y) {
    this->ensureMoveTo();
    *fCmds.append() = kLine_PathCmd;
    fPts.append()->set(x, y);
}

void GrPath::quadTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1) {
    this->ensureMoveTo();
    *fCmds.append() = kQuadratic_PathCmd;
    fPts.append()->set(x0, y0);
    fPts.append()->set(x1, y1);
}

void GrPath::cubicTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1,
                     GrScalar x2, GrScalar y2) {
    this->ensureMoveTo();
    *fCmds.append() = kCubic_PathCmd;
    fPts.append()->set(x0, y0);
    fPts.append()->set(x1, y1);
    fPts.append()->set(x2, y2);
}

void GrPath::close() {
    if (!fCmds.isEmpty() && !this->wasLastVerb(kClose_PathCmd)) {
        // should we allow kMove followed by kClose?
        *fCmds.append() = kClose_PathCmd;
    }
}

///////////////////////////////////////////////////////////////////////////////

void GrPath::offset(GrScalar tx, GrScalar ty) {
    if (!tx && !ty) {
        return; // nothing to do
    }

    GrPoint* iter = fPts.begin();
    GrPoint* stop = fPts.end();
    while (iter < stop) {
        iter->offset(tx, ty);
        ++iter;
    }
}

///////////////////////////////////////////////////////////////////////////////

static bool check_two_vecs(const GrVec& prevVec,
                           const GrVec& currVec,
                           GrScalar turnDir,
                           int* xDir,
                           int* yDir,
                           int* flipX,
                           int* flipY) {
    if (currVec.fX * *xDir < 0) {
        ++*flipX;
        if (*flipX > 2) {
            return false;
        }
        *xDir = -*xDir;
    }
    if (currVec.fY * *yDir < 0) {
        ++*flipY;
        if (*flipY > 2) {
            return false;
        }
        *yDir = -*yDir;
    }
    GrScalar d = prevVec.cross(currVec);
    return (d * turnDir) >= 0;
}

static void init_from_two_vecs(const GrVec& firstVec,
                               const GrVec& secondVec,
                               GrScalar* turnDir,
                               int* xDir, int* yDir) {
    *turnDir = firstVec.cross(secondVec);
    if (firstVec.fX > 0) {
        *xDir = 1;
    } else if (firstVec.fX < 0) {
        *xDir = -1;
    } else {
        *xDir = 0;
    }
    if (firstVec.fY > 0) {
        *yDir = 1;
    } else if (firstVec.fY < 0) {
        *yDir = -1;
    } else {
        *yDir = 0;
    }
}

void GrPath::resetFromIter(GrPathIter* iter) {
    fPts.reset();
    fCmds.reset();

    fConvexHint = iter->convexHint();

    // first point of the subpath
    GrPoint firstPt(0,0);
    // first edge of the subpath
    GrVec firstVec(0,0);
    // vec of most recently processed edge, that wasn't degenerate
    GrVec previousVec(0,0);
    // most recently processed point
    GrPoint previousPt(0,0);

    // sign indicates whether we're bending left or right
    GrScalar turnDir = 0;
    // number of times the direction has flipped in x or y

    // we track which direction we are moving in x/y and the
    // number of times it changes.
    int xDir = 0;
    int yDir = 0;
    int flipX = 0;
    int flipY = 0;

    // counts number of sub path pts that didn't add a degenerate edge.
    int subPathPts = 0;
    bool subPathClosed = false;

    int numSubPaths = 0;
    iter->rewind();
    GrPathCmd cmd;
    GrPoint pts[4];
    do {
        cmd = iter->next(pts);
        // If the convexity test is ever updated to handle multiple subpaths
        // the loop has to be adjusted to handle moving to a new subpath without
        // closing the previous one. Currently the implicit closing vectors for a
        // filled path would never be examined.
{'fraction_non_alphanumeric': 0.1646855633445088, 'fraction_numerical': 0.01137864472213756, 'mean_word_length': 1.7605159842961302, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2179335', 'n_tokens_mistral': 3451, 'n_tokens_neox': 3375, 'n_words': 845}