180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkCullPoints.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "Sk64.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic bool cross_product_is_neg(const SkIPoint& v, int dx, int dy) {
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if 0
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return v.fX * dy - v.fY * dx < 0;
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#else
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Sk64   tmp0, tmp1;
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    tmp0.setMul(v.fX, dy);
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    tmp1.setMul(dx, v.fY);
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    tmp0.sub(tmp1);
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return tmp0.isNeg() != 0;
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkCullPoints::sect_test(int x0, int y0, int x1, int y1) const {
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkIRect& r = fR;
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if ((x0 < r.fLeft    && x1 < r.fLeft) ||
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        (x0 > r.fRight   && x1 > r.fRight) ||
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        (y0 < r.fTop     && y1 < r.fTop) ||
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        (y0 > r.fBottom  && y1 > r.fBottom)) {
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // since the crossprod test is a little expensive, check for easy-in cases first
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (r.contains(x0, y0) || r.contains(x1, y1)) {
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return true;
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // At this point we're not sure, so we do a crossprod test
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkIPoint           vec;
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkIPoint*    rAsQuad = fAsQuad;
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    vec.set(x1 - x0, y1 - y0);
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool isNeg = cross_product_is_neg(vec, x0 - rAsQuad[0].fX, y0 - rAsQuad[0].fY);
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 1; i < 4; i++) {
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (cross_product_is_neg(vec, x0 - rAsQuad[i].fX, y0 - rAsQuad[i].fY) != isNeg) {
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return true;
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return false;   // we didn't intersect
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic void toQuad(const SkIRect& r, SkIPoint quad[4]) {
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(quad);
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    quad[0].set(r.fLeft, r.fTop);
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    quad[1].set(r.fRight, r.fTop);
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    quad[2].set(r.fRight, r.fBottom);
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    quad[3].set(r.fLeft, r.fBottom);
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkCullPoints::SkCullPoints() {
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkIRect    r;
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    r.setEmpty();
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->reset(r);
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkCullPoints::SkCullPoints(const SkIRect& r) {
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->reset(r);
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkCullPoints::reset(const SkIRect& r) {
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fR = r;
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    toQuad(fR, fAsQuad);
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPrevPt.set(0, 0);
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPrevResult = kNo_Result;
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkCullPoints::moveTo(int x, int y) {
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPrevPt.set(x, y);
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPrevResult = kNo_Result;   // so we trigger a movetolineto later
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkCullPoints::LineToResult SkCullPoints::lineTo(int x, int y, SkIPoint line[]) {
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(line != NULL);
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    LineToResult result = kNo_Result;
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int x0 = fPrevPt.fX;
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int y0 = fPrevPt.fY;
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // need to upgrade sect_test to chop the result
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // and to correctly return kLineTo_Result when the result is connected
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // to the previous call-out
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (this->sect_test(x0, y0, x, y)) {
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        line[0].set(x0, y0);
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        line[1].set(x, y);
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (fPrevResult != kNo_Result && fPrevPt.equals(x0, y0)) {
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            result = kLineTo_Result;
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            result = kMoveToLineTo_Result;
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPrevPt.set(x, y);
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPrevResult = result;
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return result;
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/////////////////////////////////////////////////////////////////////////////////////////////////
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPath.h"
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkCullPointsPath::SkCullPointsPath()
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    : fCP(), fPath(NULL) {
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkCullPointsPath::SkCullPointsPath(const SkIRect& r, SkPath* dst)
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    : fCP(r), fPath(dst) {
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkCullPointsPath::reset(const SkIRect& r, SkPath* dst) {
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fCP.reset(r);
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fPath = dst;
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkCullPointsPath::moveTo(int x, int y) {
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fCP.moveTo(x, y);
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkCullPointsPath::lineTo(int x, int y) {
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkIPoint   pts[2];
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    switch (fCP.lineTo(x, y, pts)) {
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    case SkCullPoints::kMoveToLineTo_Result:
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPath->moveTo(SkIntToScalar(pts[0].fX), SkIntToScalar(pts[0].fY));
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // fall through to the lineto case
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    case SkCullPoints::kLineTo_Result:
14280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fPath->lineTo(SkIntToScalar(pts[1].fX), SkIntToScalar(pts[1].fY));
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        break;
14480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    default:
14580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        break;
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkMatrix.h"
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkRegion.h"
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkHitTestPath(const SkPath& path, SkRect& target, bool hires) {
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (target.isEmpty()) {
15680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
15780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool isInverse = path.isInverseFillType();
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (path.isEmpty()) {
16180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return isInverse;
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRect bounds = path.getBounds();
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool sects = SkRect::Intersects(target, bounds);
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (isInverse) {
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (!sects) {
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return true;
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (!sects) {
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return false;
17480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
17580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (target.contains(bounds)) {
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return true;
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
17980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPath devPath;
18180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkPath* pathPtr;
18280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRect        devTarget;
18380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (hires) {
18580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const SkScalar coordLimit = SkIntToScalar(16384);
18680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        const SkRect limit = { 0, 0, coordLimit, coordLimit };
18780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
18880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkMatrix matrix;
18980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        matrix.setRectToRect(bounds, limit, SkMatrix::kFill_ScaleToFit);
19080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        path.transform(matrix, &devPath);
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        matrix.mapRect(&devTarget, target);
19380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        pathPtr = &devPath;
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } else {
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        devTarget = target;
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        pathPtr = &path;
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkIRect iTarget;
20180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    devTarget.round(&iTarget);
20280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (iTarget.isEmpty()) {
20380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        iTarget.fLeft = SkScalarFloorToInt(devTarget.fLeft);
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        iTarget.fTop = SkScalarFloorToInt(devTarget.fTop);
20580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        iTarget.fRight = iTarget.fLeft + 1;
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        iTarget.fBottom = iTarget.fTop + 1;
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRegion clip(iTarget);
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRegion rgn;
21180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return rgn.setPath(*pathPtr, clip) ^ isInverse;
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
21480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querubool SkHitTestPath(const SkPath& path, SkScalar x, SkScalar y, bool hires) {
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkScalar half = SK_ScalarHalf;
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkScalar one = SK_Scalar1;
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRect r = SkRect::MakeXYWH(x - half, y - half, one, one);
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return SkHitTestPath(path, r, hires);
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
220