1/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7#ifndef SkPathOpBounds_DEFINED
8#define SkPathOpBounds_DEFINED
9
10#include "SkPathOpsRect.h"
11#include "SkRect.h"
12
13// SkPathOpsBounds, unlike SkRect, does not consider a line to be empty.
14struct SkPathOpsBounds : public SkRect {
15    static bool Intersects(const SkPathOpsBounds& a, const SkPathOpsBounds& b) {
16        return AlmostLessOrEqualUlps(a.fLeft, b.fRight)
17                && AlmostLessOrEqualUlps(b.fLeft, a.fRight)
18                && AlmostLessOrEqualUlps(a.fTop, b.fBottom)
19                && AlmostLessOrEqualUlps(b.fTop, a.fBottom);
20    }
21
22   // Note that add(), unlike SkRect::join() or SkRect::growToInclude()
23   // does not treat the bounds of horizontal and vertical lines as
24   // empty rectangles.
25    void add(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom) {
26        if (left < fLeft) fLeft = left;
27        if (top < fTop) fTop = top;
28        if (right > fRight) fRight = right;
29        if (bottom > fBottom) fBottom = bottom;
30    }
31
32    void add(const SkPathOpsBounds& toAdd) {
33        add(toAdd.fLeft, toAdd.fTop, toAdd.fRight, toAdd.fBottom);
34    }
35
36    void add(const SkPoint& pt) {
37        if (pt.fX < fLeft) fLeft = pt.fX;
38        if (pt.fY < fTop) fTop = pt.fY;
39        if (pt.fX > fRight) fRight = pt.fX;
40        if (pt.fY > fBottom) fBottom = pt.fY;
41    }
42
43    bool almostContains(const SkPoint& pt) {
44        return AlmostLessOrEqualUlps(fLeft, pt.fX)
45                && AlmostLessOrEqualUlps(pt.fX, fRight)
46                && AlmostLessOrEqualUlps(fTop, pt.fY)
47                && AlmostLessOrEqualUlps(pt.fY, fBottom);
48    }
49
50    // unlike isEmpty(), this permits lines, but not points
51    // FIXME: unused for now
52    bool isReallyEmpty() const {
53        // use !<= instead of > to detect NaN values
54        return !(fLeft <= fRight) || !(fTop <= fBottom)
55                || (fLeft == fRight && fTop == fBottom);
56    }
57
58    void setCubicBounds(const SkPoint a[4]);
59    void setLineBounds(const SkPoint a[2]);
60    void setQuadBounds(const SkPoint a[3]);
61
62    void setPointBounds(const SkPoint& pt) {
63        fLeft = fRight = pt.fX;
64        fTop = fBottom = pt.fY;
65    }
66
67    typedef SkRect INHERITED;
68};
69
70extern void (SkPathOpsBounds::*SetCurveBounds[])(const SkPoint[]);
71
72#endif
73