1 | // LAF Gfx Library |
2 | // Copyright (C) 2020 Igara Studio S.A. |
3 | // Copyright (C) 2001-2016 David Capello |
4 | // |
5 | // This file is released under the terms of the MIT license. |
6 | // Read LICENSE.txt for more information. |
7 | |
8 | #ifndef GFX_CLIP_H_INCLUDED |
9 | #define GFX_CLIP_H_INCLUDED |
10 | #pragma once |
11 | |
12 | #include "gfx/point.h" |
13 | #include "gfx/rect.h" |
14 | #include "gfx/size.h" |
15 | |
16 | namespace gfx { |
17 | |
18 | template<typename T> |
19 | class ClipT { |
20 | public: |
21 | PointT<T> dst; |
22 | PointT<T> src; |
23 | SizeT<T> size; |
24 | |
25 | ClipT() |
26 | : dst(0, 0) |
27 | , src(0, 0) |
28 | , size(0, 0) { |
29 | } |
30 | |
31 | ClipT(T w, T h) |
32 | : dst(0, 0) |
33 | , src(0, 0) |
34 | , size(w, h) { |
35 | } |
36 | |
37 | ClipT(T dst_x, T dst_y, T src_x, T src_y, T w, T h) |
38 | : dst(dst_x, dst_y) |
39 | , src(src_x, src_y) |
40 | , size(w, h) { |
41 | } |
42 | |
43 | ClipT(T dst_x, T dst_y, const RectT<T>& srcBounds) |
44 | : dst(dst_x, dst_y) |
45 | , src(srcBounds.x, srcBounds.y) |
46 | , size(srcBounds.w, srcBounds.h) { |
47 | } |
48 | |
49 | ClipT(const PointT<T>& dst, const PointT<T>& src, const SizeT<T>& size) |
50 | : dst(dst) |
51 | , src(src) |
52 | , size(size) { |
53 | } |
54 | |
55 | ClipT(const PointT<T>& dst, const RectT<T>& srcBounds) |
56 | : dst(dst) |
57 | , src(srcBounds.x, srcBounds.y) |
58 | , size(srcBounds.w, srcBounds.h) { |
59 | } |
60 | |
61 | ClipT(const RectT<T>& bounds) |
62 | : dst(bounds.x, bounds.y) |
63 | , src(bounds.x, bounds.y) |
64 | , size(bounds.w, bounds.h) { |
65 | } |
66 | |
67 | template<typename U> |
68 | ClipT(const ClipT<U>& other) |
69 | : dst(other.dst) |
70 | , src(other.src) |
71 | , size(other.size) { |
72 | } |
73 | |
74 | RectT<T> dstBounds() const { return RectT<T>(dst, size); } |
75 | RectT<T> srcBounds() const { return RectT<T>(src, size); } |
76 | |
77 | bool operator==(const ClipT<T>& other) const { |
78 | return (dst == other.dst && |
79 | src == other.src && |
80 | size == other.size); |
81 | } |
82 | |
83 | bool clip( |
84 | // Available area |
85 | T avail_dst_w, |
86 | T avail_dst_h, |
87 | T avail_src_w, |
88 | T avail_src_h) { |
89 | // Clip srcBounds |
90 | |
91 | if (src.x < T(0)) { |
92 | size.w += src.x; |
93 | dst.x -= src.x; |
94 | src.x = T(0); |
95 | } |
96 | |
97 | if (src.y < T(0)) { |
98 | size.h += src.y; |
99 | dst.y -= src.y; |
100 | src.y = T(0); |
101 | } |
102 | |
103 | if (src.x + size.w > avail_src_w) |
104 | size.w -= src.x + size.w - avail_src_w; |
105 | |
106 | if (src.y + size.h > avail_src_h) |
107 | size.h -= src.y + size.h - avail_src_h; |
108 | |
109 | // Clip dstBounds |
110 | |
111 | if (dst.x < T(0)) { |
112 | size.w += dst.x; |
113 | src.x -= dst.x; |
114 | dst.x = T(0); |
115 | } |
116 | |
117 | if (dst.y < T(0)) { |
118 | size.h += dst.y; |
119 | src.y -= dst.y; |
120 | dst.y = T(0); |
121 | } |
122 | |
123 | if (dst.x + size.w > avail_dst_w) |
124 | size.w -= dst.x + size.w - avail_dst_w; |
125 | |
126 | if (dst.y + size.h > avail_dst_h) |
127 | size.h -= dst.y + size.h - avail_dst_h; |
128 | |
129 | return (size.w > T(0) && size.h > T(0)); |
130 | } |
131 | |
132 | }; |
133 | |
134 | typedef ClipT<int> Clip; |
135 | typedef ClipT<double> ClipF; |
136 | |
137 | } // namespace gfx |
138 | |
139 | #endif |
140 | |