1 /**
2   This module contains some type definitions.  
3  */
4 module types;
5 
6 /**  2D point */
7 struct Point {
8     /// x coordinate
9     int x;
10     /// y coordinate
11     int y;
12     this(int x0, int y0) {
13         x = x0;
14         y = y0;
15     }
16 }
17 
18 /**  2D rectangle */
19 struct Rect {
20     /// x coordinate of top left corner
21     int left;
22     /// y coordinate of top left corner
23     int top;
24     /// x coordinate of bottom right corner
25     int right;
26     /// y coordinate of bottom right corner
27     int bottom;
28     /// returns average of left, right
29     @property int middlex() { return (left + right) / 2; }
30     /// returns average of top, bottom
31     @property int middley() { return (top + bottom) / 2; }
32     /// returns middle point
33     @property Point middle() { return Point(middlex, middley); }
34     /// add offset to horizontal and vertical coordinates
35     void offset(int dx, int dy) {
36         left += dx;
37         right += dx;
38         top += dy;
39         bottom += dy;
40     }
41     /// expand rectangle dimensions
42     void expand(int dx, int dy) {
43         left -= dx;
44         right += dx;
45         top -= dy;
46         bottom += dy;
47     }
48     /// shrink rectangle dimensions
49     void shrink(int dx, int dy) {
50         left += dx;
51         right -= dx;
52         top += dy;
53         bottom -= dy;
54     }
55     /// for all fields, sets this.field to rc.field if rc.field > this.field
56     void setMax(Rect rc) {
57         if (left < rc.left)
58             left = rc.left;
59         if (right < rc.right)
60             right = rc.right;
61         if (top < rc.top)
62             top = rc.top;
63         if (bottom < rc.bottom)
64             bottom = rc.bottom;
65     }
66     /// returns width of rectangle (right - left)
67     @property int width() { return right - left; }
68     /// returns height of rectangle (bottom - top)
69     @property int height() { return bottom - top; }
70     /// constructs rectangle using left, top, right, bottom coordinates
71     this(int x0, int y0, int x1, int y1) {
72         left = x0;
73         top = y0;
74         right = x1;
75         bottom = y1;
76     }
77     /// returns true if rectangle is empty (right <= left || bottom <= top)
78     @property bool empty() {
79         return right <= left || bottom <= top;
80     }
81     /// translate rectangle coordinates by (x,y) - add deltax to x coordinates, and deltay to y coordinates
82     void moveBy(int deltax, int deltay) {
83         left += deltax;
84         right += deltax;
85         top += deltay;
86         bottom += deltay;
87     }
88     /// moves this rect to fit rc bounds, retaining the same size
89     void moveToFit(ref Rect rc) {
90         if (right > rc.right)
91             moveBy(rc.right - right, 0);
92         if (bottom > rc.bottom)
93             moveBy(0, rc.bottom - bottom);
94         if (left < rc.left)
95             moveBy(rc.left - left, 0);
96         if (top < rc.top)
97             moveBy(0, rc.top - top);
98 
99     }
100     /// updates this rect to intersection with rc, returns true if result is non empty
101     bool intersect(Rect rc) {
102         if (left < rc.left)
103             left = rc.left;
104         if (top < rc.top)
105             top = rc.top;
106         if (right > rc.right)
107             right = rc.right;
108         if (bottom > rc.bottom)
109             bottom = rc.bottom;
110         return right > left && bottom > top;
111     }
112     /// returns true if this rect has nonempty intersection with rc
113     bool intersects(Rect rc) {
114         if (rc.left >= right || rc.top >= bottom || rc.right <= left || rc.bottom <= top)
115             return false;
116         return true;
117     }
118     /// returns true if point is inside of this rectangle
119     bool isPointInside(Point pt) {
120         return pt.x >= left && pt.x < right && pt.y >= top && pt.y < bottom;
121     }
122     /// returns true if point is inside of this rectangle
123     bool isPointInside(int x, int y) {
124         return x >= left && x < right && y >= top && y < bottom;
125     }
126     /// this rectangle is completely inside rc
127     bool isInsideOf(Rect rc) {
128         return left >= rc.left && right <= rc.right && top >= rc.top && bottom <= rc.bottom;
129     }
130 
131     bool opEquals(Rect rc) {
132         return left == rc.left && right == rc.right && top == rc.top && bottom == rc.bottom;
133     }
134 }
135