-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy patharea.go
More file actions
85 lines (74 loc) · 1.81 KB
/
Copy patharea.go
File metadata and controls
85 lines (74 loc) · 1.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Copyright 2025 Jacek Olszak
// This code is licensed under MIT license (see LICENSE for details)
package pi
// Area specifies rectangular boundaries on a [Surface].
//
// It is used by [Sprite], [SetClip], [Surface.CloneArea], [Surface.LinesIterator], and others.
type Area[T Number] struct {
X, Y, W, H T
}
// IntArea is an Area with integer coordinates.
type IntArea = Area[int]
// Size returns the number of values in the area.
func (a Area[T]) Size() T {
return a.W * a.H
}
// WithX returns a new Area with the X value updated.
func (a Area[T]) WithX(x T) Area[T] {
a.X = x
return a
}
// WithY returns a new Area with the Y value updated.
func (a Area[T]) WithY(y T) Area[T] {
a.Y = y
return a
}
// WithW returns a new Area with the W value updated.
func (a Area[T]) WithW(w T) Area[T] {
a.W = w
return a
}
// WithH returns a new Area with the H value updated.
func (a Area[T]) WithH(h T) Area[T] {
a.H = h
return a
}
// MovedBy returns a new Area moved by dx and dy.
func (a Area[T]) MovedBy(dx, dy T) Area[T] {
a.X += dx
a.Y += dy
return a
}
// ClippedBy clips the area so it does not extend beyond the given clip region.
//
// In addition to the new area, it also returns how much it was shifted.
// The output parameters dx and dy are always positive.
func (a Area[T]) ClippedBy(clip Area[T]) (_ Area[T], dx, dy T) {
if a.X < clip.X {
dx = clip.X - a.X
a.W -= dx
a.X = clip.X
}
if a.Y < clip.Y {
dy = clip.Y - a.Y
a.H -= dy
a.Y = clip.Y
}
if a.X+a.W > clip.X+clip.W {
a.W = clip.X + clip.W - a.X
}
if a.W < 0 {
a.W = 0
}
if a.Y+a.H > clip.Y+clip.H {
a.H = clip.Y + clip.H - a.Y
}
if a.H < 0 {
a.H = 0
}
return a, dx, dy
}
// Contains reports whether the point (x, y) is inside the Area.
func (a Area[T]) Contains(x, y T) bool {
return x >= a.X && x < a.X+a.W && y >= a.Y && y < a.Y+a.H
}