OLD | NEW |
1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include <limits.h> | 7 #include <limits.h> |
8 | 8 |
9 #include "../../include/fxcrt/fx_coordinates.h" | 9 #include "../../include/fxcrt/fx_coordinates.h" |
10 #include "../../include/fxcrt/fx_ext.h" | 10 #include "../../include/fxcrt/fx_ext.h" |
11 | 11 |
12 void FX_RECT::Normalize() | 12 void FX_RECT::Normalize() { |
13 { | 13 if (left > right) { |
14 if (left > right) { | 14 int temp = left; |
15 int temp = left; | 15 left = right; |
16 left = right; | 16 right = temp; |
17 right = temp; | 17 } |
18 } | 18 if (top > bottom) { |
19 if (top > bottom) { | 19 int temp = top; |
20 int temp = top; | 20 top = bottom; |
21 top = bottom; | 21 bottom = temp; |
22 bottom = temp; | 22 } |
23 } | 23 } |
24 } | 24 void FX_RECT::Intersect(const FX_RECT& src) { |
25 void FX_RECT::Intersect(const FX_RECT& src) | 25 FX_RECT src_n = src; |
26 { | 26 src_n.Normalize(); |
27 FX_RECT src_n = src; | 27 Normalize(); |
28 src_n.Normalize(); | 28 left = left > src_n.left ? left : src_n.left; |
29 Normalize(); | 29 top = top > src_n.top ? top : src_n.top; |
30 left = left > src_n.left ? left : src_n.left; | 30 right = right < src_n.right ? right : src_n.right; |
31 top = top > src_n.top ? top : src_n.top; | 31 bottom = bottom < src_n.bottom ? bottom : src_n.bottom; |
32 right = right < src_n.right ? right : src_n.right; | 32 if (left > right || top > bottom) { |
33 bottom = bottom < src_n.bottom ? bottom : src_n.bottom; | 33 left = top = right = bottom = 0; |
34 if (left > right || top > bottom) { | 34 } |
35 left = top = right = bottom = 0; | 35 } |
36 } | 36 void FX_RECT::Union(const FX_RECT& other_rect) { |
37 } | 37 Normalize(); |
38 void FX_RECT::Union(const FX_RECT& other_rect) | 38 FX_RECT other = other_rect; |
39 { | 39 other.Normalize(); |
40 Normalize(); | 40 left = left < other.left ? left : other.left; |
41 FX_RECT other = other_rect; | 41 right = right > other.right ? right : other.right; |
42 other.Normalize(); | 42 bottom = bottom > other.bottom ? bottom : other.bottom; |
43 left = left < other.left ? left : other.left; | 43 top = top < other.top ? top : other.top; |
44 right = right > other.right ? right : other.right; | 44 } |
45 bottom = bottom > other.bottom ? bottom : other.bottom; | 45 FX_BOOL GetIntersection(FX_FLOAT low1, |
46 top = top < other.top ? top : other.top; | 46 FX_FLOAT high1, |
47 } | 47 FX_FLOAT low2, |
48 FX_BOOL GetIntersection(FX_FLOAT low1, FX_FLOAT high1, FX_FLOAT low2, FX_FLOAT h
igh2, | 48 FX_FLOAT high2, |
49 FX_FLOAT& interlow, FX_FLOAT& interhigh) | 49 FX_FLOAT& interlow, |
50 { | 50 FX_FLOAT& interhigh) { |
51 if (low1 >= high2 || low2 >= high1) { | 51 if (low1 >= high2 || low2 >= high1) { |
52 return FALSE; | 52 return FALSE; |
53 } | 53 } |
54 interlow = low1 > low2 ? low1 : low2; | 54 interlow = low1 > low2 ? low1 : low2; |
55 interhigh = high1 > high2 ? high2 : high1; | 55 interhigh = high1 > high2 ? high2 : high1; |
| 56 return TRUE; |
| 57 } |
| 58 extern "C" int FXSYS_round(FX_FLOAT d) { |
| 59 if (d < (FX_FLOAT)INT_MIN) { |
| 60 return INT_MIN; |
| 61 } |
| 62 if (d > (FX_FLOAT)INT_MAX) { |
| 63 return INT_MAX; |
| 64 } |
| 65 |
| 66 return (int)round(d); |
| 67 } |
| 68 CFX_FloatRect::CFX_FloatRect(const FX_RECT& rect) { |
| 69 left = (FX_FLOAT)(rect.left); |
| 70 right = (FX_FLOAT)(rect.right); |
| 71 bottom = (FX_FLOAT)(rect.top); |
| 72 top = (FX_FLOAT)(rect.bottom); |
| 73 } |
| 74 void CFX_FloatRect::Normalize() { |
| 75 FX_FLOAT temp; |
| 76 if (left > right) { |
| 77 temp = left; |
| 78 left = right; |
| 79 right = temp; |
| 80 } |
| 81 if (bottom > top) { |
| 82 temp = top; |
| 83 top = bottom; |
| 84 bottom = temp; |
| 85 } |
| 86 } |
| 87 void CFX_FloatRect::Intersect(const CFX_FloatRect& other_rect) { |
| 88 Normalize(); |
| 89 CFX_FloatRect other = other_rect; |
| 90 other.Normalize(); |
| 91 left = left > other.left ? left : other.left; |
| 92 right = right < other.right ? right : other.right; |
| 93 bottom = bottom > other.bottom ? bottom : other.bottom; |
| 94 top = top < other.top ? top : other.top; |
| 95 if (left > right || bottom > top) { |
| 96 left = right = bottom = top = 0; |
| 97 } |
| 98 } |
| 99 void CFX_FloatRect::Union(const CFX_FloatRect& other_rect) { |
| 100 Normalize(); |
| 101 CFX_FloatRect other = other_rect; |
| 102 other.Normalize(); |
| 103 left = left < other.left ? left : other.left; |
| 104 right = right > other.right ? right : other.right; |
| 105 bottom = bottom < other.bottom ? bottom : other.bottom; |
| 106 top = top > other.top ? top : other.top; |
| 107 } |
| 108 void CFX_FloatRect::Transform(const CFX_Matrix* pMatrix) { |
| 109 pMatrix->TransformRect(left, right, top, bottom); |
| 110 } |
| 111 int CFX_FloatRect::Substract4(CFX_FloatRect& s, CFX_FloatRect* pRects) { |
| 112 Normalize(); |
| 113 s.Normalize(); |
| 114 int nRects = 0; |
| 115 CFX_FloatRect rects[4]; |
| 116 if (left < s.left) { |
| 117 rects[nRects].left = left; |
| 118 rects[nRects].right = s.left; |
| 119 rects[nRects].bottom = bottom; |
| 120 rects[nRects].top = top; |
| 121 nRects++; |
| 122 } |
| 123 if (s.left < right && s.top < top) { |
| 124 rects[nRects].left = s.left; |
| 125 rects[nRects].right = right; |
| 126 rects[nRects].bottom = s.top; |
| 127 rects[nRects].top = top; |
| 128 nRects++; |
| 129 } |
| 130 if (s.top > bottom && s.right < right) { |
| 131 rects[nRects].left = s.right; |
| 132 rects[nRects].right = right; |
| 133 rects[nRects].bottom = bottom; |
| 134 rects[nRects].top = s.top; |
| 135 nRects++; |
| 136 } |
| 137 if (s.bottom > bottom) { |
| 138 rects[nRects].left = s.left; |
| 139 rects[nRects].right = s.right; |
| 140 rects[nRects].bottom = bottom; |
| 141 rects[nRects].top = s.bottom; |
| 142 nRects++; |
| 143 } |
| 144 if (nRects == 0) { |
| 145 return 0; |
| 146 } |
| 147 for (int i = 0; i < nRects; i++) { |
| 148 pRects[i] = rects[i]; |
| 149 pRects[i].Intersect(*this); |
| 150 } |
| 151 return nRects; |
| 152 } |
| 153 FX_RECT CFX_FloatRect::GetOutterRect() const { |
| 154 CFX_FloatRect rect1 = *this; |
| 155 FX_RECT rect; |
| 156 rect.left = (int)FXSYS_floor(rect1.left); |
| 157 rect.right = (int)FXSYS_ceil(rect1.right); |
| 158 rect.top = (int)FXSYS_floor(rect1.bottom); |
| 159 rect.bottom = (int)FXSYS_ceil(rect1.top); |
| 160 rect.Normalize(); |
| 161 return rect; |
| 162 } |
| 163 FX_RECT CFX_FloatRect::GetInnerRect() const { |
| 164 CFX_FloatRect rect1 = *this; |
| 165 FX_RECT rect; |
| 166 rect.left = (int)FXSYS_ceil(rect1.left); |
| 167 rect.right = (int)FXSYS_floor(rect1.right); |
| 168 rect.top = (int)FXSYS_ceil(rect1.bottom); |
| 169 rect.bottom = (int)FXSYS_floor(rect1.top); |
| 170 rect.Normalize(); |
| 171 return rect; |
| 172 } |
| 173 static void _MatchFloatRange(FX_FLOAT f1, FX_FLOAT f2, int& i1, int& i2) { |
| 174 int length = (int)FXSYS_ceil(f2 - f1); |
| 175 int i1_1 = (int)FXSYS_floor(f1); |
| 176 int i1_2 = (int)FXSYS_ceil(f1); |
| 177 FX_FLOAT error1 = f1 - i1_1 + (FX_FLOAT)FXSYS_fabs(f2 - i1_1 - length); |
| 178 FX_FLOAT error2 = i1_2 - f1 + (FX_FLOAT)FXSYS_fabs(f2 - i1_2 - length); |
| 179 i1 = (error1 > error2) ? i1_2 : i1_1; |
| 180 i2 = i1 + length; |
| 181 } |
| 182 FX_RECT CFX_FloatRect::GetClosestRect() const { |
| 183 CFX_FloatRect rect1 = *this; |
| 184 FX_RECT rect; |
| 185 _MatchFloatRange(rect1.left, rect1.right, rect.left, rect.right); |
| 186 _MatchFloatRange(rect1.bottom, rect1.top, rect.top, rect.bottom); |
| 187 rect.Normalize(); |
| 188 return rect; |
| 189 } |
| 190 FX_BOOL CFX_FloatRect::Contains(const CFX_FloatRect& other_rect) const { |
| 191 CFX_FloatRect n1 = *this; |
| 192 n1.Normalize(); |
| 193 CFX_FloatRect n2 = other_rect; |
| 194 n2.Normalize(); |
| 195 if (n2.left >= n1.left && n2.right <= n1.right && n2.bottom >= n1.bottom && |
| 196 n2.top <= n1.top) { |
56 return TRUE; | 197 return TRUE; |
57 } | 198 } |
58 extern "C" int FXSYS_round(FX_FLOAT d) | 199 return FALSE; |
59 { | 200 } |
60 if (d < (FX_FLOAT)INT_MIN) { | 201 FX_BOOL CFX_FloatRect::Contains(FX_FLOAT x, FX_FLOAT y) const { |
61 return INT_MIN; | 202 CFX_FloatRect n1 = *this; |
62 } | 203 n1.Normalize(); |
63 if (d > (FX_FLOAT)INT_MAX) { | 204 return x <= n1.right && x >= n1.left && y <= n1.top && y >= n1.bottom; |
64 return INT_MAX; | 205 } |
65 } | 206 void CFX_FloatRect::UpdateRect(FX_FLOAT x, FX_FLOAT y) { |
66 | 207 if (left > x) { |
67 return (int)round(d); | 208 left = x; |
68 } | 209 } |
69 CFX_FloatRect::CFX_FloatRect(const FX_RECT& rect) | 210 if (right < x) { |
70 { | 211 right = x; |
71 left = (FX_FLOAT)(rect.left); | 212 } |
72 right = (FX_FLOAT)(rect.right); | 213 if (bottom > y) { |
73 bottom = (FX_FLOAT)(rect.top); | 214 bottom = y; |
74 top = (FX_FLOAT)(rect.bottom); | 215 } |
75 } | 216 if (top < y) { |
76 void CFX_FloatRect::Normalize() | 217 top = y; |
77 { | 218 } |
78 FX_FLOAT temp; | 219 } |
79 if (left > right) { | 220 CFX_FloatRect CFX_FloatRect::GetBBox(const CFX_FloatPoint* pPoints, |
80 temp = left; | 221 int nPoints) { |
81 left = right; | 222 if (nPoints == 0) { |
82 right = temp; | 223 return CFX_FloatRect(); |
83 } | 224 } |
84 if (bottom > top) { | 225 FX_FLOAT min_x = pPoints->x, max_x = pPoints->x, min_y = pPoints->y, |
85 temp = top; | 226 max_y = pPoints->y; |
86 top = bottom; | 227 for (int i = 1; i < nPoints; i++) { |
87 bottom = temp; | 228 if (min_x > pPoints[i].x) { |
88 } | 229 min_x = pPoints[i].x; |
89 } | 230 } |
90 void CFX_FloatRect::Intersect(const CFX_FloatRect& other_rect) | 231 if (max_x < pPoints[i].x) { |
91 { | 232 max_x = pPoints[i].x; |
92 Normalize(); | 233 } |
93 CFX_FloatRect other = other_rect; | 234 if (min_y > pPoints[i].y) { |
94 other.Normalize(); | 235 min_y = pPoints[i].y; |
95 left = left > other.left ? left : other.left; | 236 } |
96 right = right < other.right ? right : other.right; | 237 if (max_y < pPoints[i].y) { |
97 bottom = bottom > other.bottom ? bottom : other.bottom; | 238 max_y = pPoints[i].y; |
98 top = top < other.top ? top : other.top; | 239 } |
99 if (left > right || bottom > top) { | 240 } |
100 left = right = bottom = top = 0; | 241 return CFX_FloatRect(min_x, min_y, max_x, max_y); |
101 } | |
102 } | |
103 void CFX_FloatRect::Union(const CFX_FloatRect& other_rect) | |
104 { | |
105 Normalize(); | |
106 CFX_FloatRect other = other_rect; | |
107 other.Normalize(); | |
108 left = left < other.left ? left : other.left; | |
109 right = right > other.right ? right : other.right; | |
110 bottom = bottom < other.bottom ? bottom : other.bottom; | |
111 top = top > other.top ? top : other.top; | |
112 } | |
113 void CFX_FloatRect::Transform(const CFX_Matrix* pMatrix) | |
114 { | |
115 pMatrix->TransformRect(left, right, top, bottom); | |
116 } | |
117 int CFX_FloatRect::Substract4(CFX_FloatRect& s, CFX_FloatRect* pRects) | |
118 { | |
119 Normalize(); | |
120 s.Normalize(); | |
121 int nRects = 0; | |
122 CFX_FloatRect rects[4]; | |
123 if (left < s.left) { | |
124 rects[nRects].left = left; | |
125 rects[nRects].right = s.left; | |
126 rects[nRects].bottom = bottom; | |
127 rects[nRects].top = top; | |
128 nRects ++; | |
129 } | |
130 if (s.left < right && s.top < top) { | |
131 rects[nRects].left = s.left; | |
132 rects[nRects].right = right; | |
133 rects[nRects].bottom = s.top; | |
134 rects[nRects].top = top; | |
135 nRects ++; | |
136 } | |
137 if (s.top > bottom && s.right < right) { | |
138 rects[nRects].left = s.right; | |
139 rects[nRects].right = right; | |
140 rects[nRects].bottom = bottom; | |
141 rects[nRects].top = s.top; | |
142 nRects ++; | |
143 } | |
144 if (s.bottom > bottom) { | |
145 rects[nRects].left = s.left; | |
146 rects[nRects].right = s.right; | |
147 rects[nRects].bottom = bottom; | |
148 rects[nRects].top = s.bottom; | |
149 nRects ++; | |
150 } | |
151 if (nRects == 0) { | |
152 return 0; | |
153 } | |
154 for (int i = 0; i < nRects; i ++) { | |
155 pRects[i] = rects[i]; | |
156 pRects[i].Intersect(*this); | |
157 } | |
158 return nRects; | |
159 } | |
160 FX_RECT CFX_FloatRect::GetOutterRect() const | |
161 { | |
162 CFX_FloatRect rect1 = *this; | |
163 FX_RECT rect; | |
164 rect.left = (int)FXSYS_floor(rect1.left); | |
165 rect.right = (int)FXSYS_ceil(rect1.right); | |
166 rect.top = (int)FXSYS_floor(rect1.bottom); | |
167 rect.bottom = (int)FXSYS_ceil(rect1.top); | |
168 rect.Normalize(); | |
169 return rect; | |
170 } | |
171 FX_RECT CFX_FloatRect::GetInnerRect() const | |
172 { | |
173 CFX_FloatRect rect1 = *this; | |
174 FX_RECT rect; | |
175 rect.left = (int)FXSYS_ceil(rect1.left); | |
176 rect.right = (int)FXSYS_floor(rect1.right); | |
177 rect.top = (int)FXSYS_ceil(rect1.bottom); | |
178 rect.bottom = (int)FXSYS_floor(rect1.top); | |
179 rect.Normalize(); | |
180 return rect; | |
181 } | |
182 static void _MatchFloatRange(FX_FLOAT f1, FX_FLOAT f2, int& i1, int& i2) | |
183 { | |
184 int length = (int)FXSYS_ceil(f2 - f1); | |
185 int i1_1 = (int)FXSYS_floor(f1); | |
186 int i1_2 = (int)FXSYS_ceil(f1); | |
187 FX_FLOAT error1 = f1 - i1_1 + (FX_FLOAT)FXSYS_fabs(f2 - i1_1 - length); | |
188 FX_FLOAT error2 = i1_2 - f1 + (FX_FLOAT)FXSYS_fabs(f2 - i1_2 - length); | |
189 i1 = (error1 > error2) ? i1_2 : i1_1; | |
190 i2 = i1 + length; | |
191 } | |
192 FX_RECT CFX_FloatRect::GetClosestRect() const | |
193 { | |
194 CFX_FloatRect rect1 = *this; | |
195 FX_RECT rect; | |
196 _MatchFloatRange(rect1.left, rect1.right, rect.left, rect.right); | |
197 _MatchFloatRange(rect1.bottom, rect1.top, rect.top, rect.bottom); | |
198 rect.Normalize(); | |
199 return rect; | |
200 } | |
201 FX_BOOL CFX_FloatRect::Contains(const CFX_FloatRect& other_rect) const | |
202 { | |
203 CFX_FloatRect n1 = *this; | |
204 n1.Normalize(); | |
205 CFX_FloatRect n2 = other_rect; | |
206 n2.Normalize(); | |
207 if (n2.left >= n1.left && n2.right <= n1.right && n2.bottom >= n1.bottom &&
n2.top <= n1.top) { | |
208 return TRUE; | |
209 } | |
210 return FALSE; | |
211 } | |
212 FX_BOOL CFX_FloatRect::Contains(FX_FLOAT x, FX_FLOAT y) const | |
213 { | |
214 CFX_FloatRect n1 = *this; | |
215 n1.Normalize(); | |
216 return x <= n1.right && x >= n1.left && y <= n1.top && y >= n1.bottom; | |
217 } | |
218 void CFX_FloatRect::UpdateRect(FX_FLOAT x, FX_FLOAT y) | |
219 { | |
220 if (left > x) { | |
221 left = x; | |
222 } | |
223 if (right < x) { | |
224 right = x; | |
225 } | |
226 if (bottom > y) { | |
227 bottom = y; | |
228 } | |
229 if (top < y) { | |
230 top = y; | |
231 } | |
232 } | |
233 CFX_FloatRect CFX_FloatRect::GetBBox(const CFX_FloatPoint* pPoints, int nPoints) | |
234 { | |
235 if (nPoints == 0) { | |
236 return CFX_FloatRect(); | |
237 } | |
238 FX_FLOAT min_x = pPoints->x, max_x = pPoints->x, min_y = pPoints->y, max_y =
pPoints->y; | |
239 for (int i = 1; i < nPoints; i ++) { | |
240 if (min_x > pPoints[i].x) { | |
241 min_x = pPoints[i].x; | |
242 } | |
243 if (max_x < pPoints[i].x) { | |
244 max_x = pPoints[i].x; | |
245 } | |
246 if (min_y > pPoints[i].y) { | |
247 min_y = pPoints[i].y; | |
248 } | |
249 if (max_y < pPoints[i].y) { | |
250 max_y = pPoints[i].y; | |
251 } | |
252 } | |
253 return CFX_FloatRect(min_x, min_y, max_x, max_y); | |
254 } | 242 } |
255 void CFX_Matrix::Set(FX_FLOAT other_a, | 243 void CFX_Matrix::Set(FX_FLOAT other_a, |
256 FX_FLOAT other_b, | 244 FX_FLOAT other_b, |
257 FX_FLOAT other_c, | 245 FX_FLOAT other_c, |
258 FX_FLOAT other_d, | 246 FX_FLOAT other_d, |
259 FX_FLOAT other_e, | 247 FX_FLOAT other_e, |
260 FX_FLOAT other_f) | 248 FX_FLOAT other_f) { |
261 { | 249 a = other_a; |
262 a = other_a; | 250 b = other_b; |
263 b = other_b; | 251 c = other_c; |
264 c = other_c; | 252 d = other_d; |
265 d = other_d; | 253 e = other_e; |
266 e = other_e; | 254 f = other_f; |
267 f = other_f; | 255 } |
268 } | 256 void CFX_Matrix::Set(const FX_FLOAT n[6]) { |
269 void CFX_Matrix::Set(const FX_FLOAT n[6]) | 257 a = n[0]; |
270 { | 258 b = n[1]; |
271 a = n[0]; | 259 c = n[2]; |
272 b = n[1]; | 260 d = n[3]; |
273 c = n[2]; | 261 e = n[4]; |
274 d = n[3]; | 262 f = n[5]; |
275 e = n[4]; | 263 } |
276 f = n[5]; | 264 void CFX_Matrix::SetReverse(const CFX_Matrix& m) { |
277 } | 265 FX_FLOAT i = m.a * m.d - m.b * m.c; |
278 void CFX_Matrix::SetReverse(const CFX_Matrix &m) | 266 if (FXSYS_fabs(i) == 0) { |
279 { | 267 return; |
280 FX_FLOAT i = m.a * m.d - m.b * m.c; | 268 } |
281 if (FXSYS_fabs(i) == 0) { | 269 FX_FLOAT j = -i; |
282 return; | 270 a = m.d / i; |
283 } | 271 b = m.b / j; |
284 FX_FLOAT j = -i; | 272 c = m.c / j; |
285 a = m.d / i; | 273 d = m.a / i; |
286 b = m.b / j; | 274 e = (m.c * m.f - m.d * m.e) / i; |
287 c = m.c / j; | 275 f = (m.a * m.f - m.b * m.e) / j; |
288 d = m.a / i; | 276 } |
289 e = (m.c * m.f - m.d * m.e) / i; | 277 static void FXCRT_Matrix_Concat(CFX_Matrix& m, |
290 f = (m.a * m.f - m.b * m.e) / j; | 278 const CFX_Matrix& m1, |
291 } | 279 const CFX_Matrix& m2) { |
292 static void FXCRT_Matrix_Concat(CFX_Matrix &m, const CFX_Matrix &m1, const CFX_M
atrix &m2) | 280 FX_FLOAT aa = m1.a * m2.a + m1.b * m2.c; |
293 { | 281 FX_FLOAT bb = m1.a * m2.b + m1.b * m2.d; |
294 FX_FLOAT aa = m1.a * m2.a + m1.b * m2.c; | 282 FX_FLOAT cc = m1.c * m2.a + m1.d * m2.c; |
295 FX_FLOAT bb = m1.a * m2.b + m1.b * m2.d; | 283 FX_FLOAT dd = m1.c * m2.b + m1.d * m2.d; |
296 FX_FLOAT cc = m1.c * m2.a + m1.d * m2.c; | 284 FX_FLOAT ee = m1.e * m2.a + m1.f * m2.c + m2.e; |
297 FX_FLOAT dd = m1.c * m2.b + m1.d * m2.d; | 285 FX_FLOAT ff = m1.e * m2.b + m1.f * m2.d + m2.f; |
298 FX_FLOAT ee = m1.e * m2.a + m1.f * m2.c + m2.e; | 286 m.a = aa, m.b = bb, m.c = cc, m.d = dd, m.e = ee, m.f = ff; |
299 FX_FLOAT ff = m1.e * m2.b + m1.f * m2.d + m2.f; | 287 } |
300 m.a = aa, m.b = bb, m.c = cc, m.d = dd, m.e = ee, m.f = ff; | 288 void CFX_Matrix::Concat(FX_FLOAT a, |
301 } | 289 FX_FLOAT b, |
302 void CFX_Matrix::Concat(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT
e, FX_FLOAT f, FX_BOOL bPrepended) | 290 FX_FLOAT c, |
303 { | 291 FX_FLOAT d, |
304 CFX_Matrix m; | 292 FX_FLOAT e, |
305 m.Set(a, b, c, d, e, f); | 293 FX_FLOAT f, |
306 Concat(m, bPrepended); | 294 FX_BOOL bPrepended) { |
307 } | 295 CFX_Matrix m; |
308 void CFX_Matrix::Concat(const CFX_Matrix &m, FX_BOOL bPrepended) | 296 m.Set(a, b, c, d, e, f); |
309 { | 297 Concat(m, bPrepended); |
310 if (bPrepended) { | 298 } |
311 FXCRT_Matrix_Concat(*this, m, *this); | 299 void CFX_Matrix::Concat(const CFX_Matrix& m, FX_BOOL bPrepended) { |
312 } else { | 300 if (bPrepended) { |
313 FXCRT_Matrix_Concat(*this, *this, m); | 301 FXCRT_Matrix_Concat(*this, m, *this); |
314 } | 302 } else { |
315 } | 303 FXCRT_Matrix_Concat(*this, *this, m); |
316 void CFX_Matrix::ConcatInverse(const CFX_Matrix& src, FX_BOOL bPrepended) | 304 } |
317 { | 305 } |
318 CFX_Matrix m; | 306 void CFX_Matrix::ConcatInverse(const CFX_Matrix& src, FX_BOOL bPrepended) { |
319 m.SetReverse(src); | 307 CFX_Matrix m; |
320 Concat(m, bPrepended); | 308 m.SetReverse(src); |
321 } | 309 Concat(m, bPrepended); |
322 FX_BOOL CFX_Matrix::IsInvertible() const | 310 } |
323 { | 311 FX_BOOL CFX_Matrix::IsInvertible() const { |
324 return FXSYS_fabs(a * d - b * c) >= 0.0001f; | 312 return FXSYS_fabs(a * d - b * c) >= 0.0001f; |
325 } | 313 } |
326 FX_BOOL CFX_Matrix::Is90Rotated() const | 314 FX_BOOL CFX_Matrix::Is90Rotated() const { |
327 { | 315 return FXSYS_fabs(a * 1000) < FXSYS_fabs(b) && |
328 return FXSYS_fabs(a * 1000) < FXSYS_fabs(b) && FXSYS_fabs(d * 1000) < FXSYS_
fabs(c); | 316 FXSYS_fabs(d * 1000) < FXSYS_fabs(c); |
329 } | 317 } |
330 FX_BOOL CFX_Matrix::IsScaled() const | 318 FX_BOOL CFX_Matrix::IsScaled() const { |
331 { | 319 return FXSYS_fabs(b * 1000) < FXSYS_fabs(a) && |
332 return FXSYS_fabs(b * 1000) < FXSYS_fabs(a) && FXSYS_fabs(c * 1000) < FXSYS_
fabs(d); | 320 FXSYS_fabs(c * 1000) < FXSYS_fabs(d); |
333 } | 321 } |
334 void CFX_Matrix::Translate(FX_FLOAT x, FX_FLOAT y, FX_BOOL bPrepended) | 322 void CFX_Matrix::Translate(FX_FLOAT x, FX_FLOAT y, FX_BOOL bPrepended) { |
335 { | 323 if (bPrepended) { |
336 if (bPrepended) { | 324 e += x * a + y * c; |
337 e += x * a + y * c; | 325 f += y * d + x * b; |
338 f += y * d + x * b; | 326 } else { |
339 } else { | 327 e += x, f += y; |
340 e += x, f += y; | 328 } |
341 } | 329 } |
342 } | 330 void CFX_Matrix::Scale(FX_FLOAT sx, FX_FLOAT sy, FX_BOOL bPrepended) { |
343 void CFX_Matrix::Scale(FX_FLOAT sx, FX_FLOAT sy, FX_BOOL bPrepended) | 331 a *= sx, d *= sy; |
344 { | 332 if (bPrepended) { |
345 a *= sx, d *= sy; | 333 b *= sx; |
346 if (bPrepended) { | 334 c *= sy; |
347 b *= sx; | 335 } else { |
348 c *= sy; | 336 b *= sy; |
349 } else { | 337 c *= sx; |
350 b *= sy; | 338 e *= sx; |
351 c *= sx; | 339 f *= sy; |
352 e *= sx; | 340 } |
353 f *= sy; | 341 } |
354 } | 342 void CFX_Matrix::Rotate(FX_FLOAT fRadian, FX_BOOL bPrepended) { |
355 } | 343 FX_FLOAT cosValue = FXSYS_cos(fRadian); |
356 void CFX_Matrix::Rotate(FX_FLOAT fRadian, FX_BOOL bPrepended) | 344 FX_FLOAT sinValue = FXSYS_sin(fRadian); |
357 { | 345 CFX_Matrix m; |
358 FX_FLOAT cosValue = FXSYS_cos(fRadian); | 346 m.Set(cosValue, sinValue, -sinValue, cosValue, 0, 0); |
359 FX_FLOAT sinValue = FXSYS_sin(fRadian); | 347 if (bPrepended) { |
360 CFX_Matrix m; | 348 FXCRT_Matrix_Concat(*this, m, *this); |
361 m.Set(cosValue, sinValue, -sinValue, cosValue, 0, 0); | 349 } else { |
362 if (bPrepended) { | 350 FXCRT_Matrix_Concat(*this, *this, m); |
363 FXCRT_Matrix_Concat(*this, m, *this); | 351 } |
364 } else { | 352 } |
365 FXCRT_Matrix_Concat(*this, *this, m); | 353 void CFX_Matrix::RotateAt(FX_FLOAT fRadian, |
366 } | 354 FX_FLOAT dx, |
367 } | 355 FX_FLOAT dy, |
368 void CFX_Matrix::RotateAt(FX_FLOAT fRadian, FX_FLOAT dx, FX_FLOAT dy, FX_BOOL bP
repended) | 356 FX_BOOL bPrepended) { |
369 { | 357 Translate(dx, dy, bPrepended); |
370 Translate(dx, dy, bPrepended); | 358 Rotate(fRadian, bPrepended); |
371 Rotate(fRadian, bPrepended); | 359 Translate(-dx, -dy, bPrepended); |
372 Translate(-dx, -dy, bPrepended); | 360 } |
373 } | 361 void CFX_Matrix::Shear(FX_FLOAT fAlphaRadian, |
374 void CFX_Matrix::Shear(FX_FLOAT fAlphaRadian, FX_FLOAT fBetaRadian, FX_BOOL bPre
pended) | 362 FX_FLOAT fBetaRadian, |
375 { | 363 FX_BOOL bPrepended) { |
376 CFX_Matrix m; | 364 CFX_Matrix m; |
377 m.Set(1, FXSYS_tan(fAlphaRadian), FXSYS_tan(fBetaRadian), 1, 0, 0); | 365 m.Set(1, FXSYS_tan(fAlphaRadian), FXSYS_tan(fBetaRadian), 1, 0, 0); |
378 if (bPrepended) { | 366 if (bPrepended) { |
379 FXCRT_Matrix_Concat(*this, m, *this); | 367 FXCRT_Matrix_Concat(*this, m, *this); |
380 } else { | 368 } else { |
381 FXCRT_Matrix_Concat(*this, *this, m); | 369 FXCRT_Matrix_Concat(*this, *this, m); |
382 } | 370 } |
383 } | 371 } |
384 void CFX_Matrix::MatchRect(const CFX_FloatRect& dest, const CFX_FloatRect& src) | 372 void CFX_Matrix::MatchRect(const CFX_FloatRect& dest, |
385 { | 373 const CFX_FloatRect& src) { |
386 FX_FLOAT fDiff = src.left - src.right; | 374 FX_FLOAT fDiff = src.left - src.right; |
387 a = FXSYS_fabs(fDiff) < 0.001f ? 1 : (dest.left - dest.right) / fDiff; | 375 a = FXSYS_fabs(fDiff) < 0.001f ? 1 : (dest.left - dest.right) / fDiff; |
388 fDiff = src.bottom - src.top; | 376 fDiff = src.bottom - src.top; |
389 d = FXSYS_fabs(fDiff) < 0.001f ? 1 : (dest.bottom - dest.top) / fDiff; | 377 d = FXSYS_fabs(fDiff) < 0.001f ? 1 : (dest.bottom - dest.top) / fDiff; |
390 e = dest.left - src.left * a; | 378 e = dest.left - src.left * a; |
391 f = dest.bottom - src.bottom * d; | 379 f = dest.bottom - src.bottom * d; |
392 b = 0; | 380 b = 0; |
393 c = 0; | 381 c = 0; |
394 } | 382 } |
395 FX_FLOAT CFX_Matrix::GetXUnit() const | 383 FX_FLOAT CFX_Matrix::GetXUnit() const { |
396 { | 384 if (b == 0) { |
397 if (b == 0) { | 385 return (a > 0 ? a : -a); |
398 return (a > 0 ? a : -a); | 386 } |
399 } | 387 if (a == 0) { |
400 if (a == 0) { | 388 return (b > 0 ? b : -b); |
401 return (b > 0 ? b : -b); | 389 } |
402 } | 390 return FXSYS_sqrt(a * a + b * b); |
403 return FXSYS_sqrt(a * a + b * b); | 391 } |
404 } | 392 FX_FLOAT CFX_Matrix::GetYUnit() const { |
405 FX_FLOAT CFX_Matrix::GetYUnit() const | 393 if (c == 0) { |
406 { | 394 return (d > 0 ? d : -d); |
407 if (c == 0) { | 395 } |
408 return (d > 0 ? d : -d); | 396 if (d == 0) { |
409 } | 397 return (c > 0 ? c : -c); |
410 if (d == 0) { | 398 } |
411 return (c > 0 ? c : -c); | 399 return FXSYS_sqrt(c * c + d * d); |
412 } | 400 } |
413 return FXSYS_sqrt(c * c + d * d); | 401 void CFX_Matrix::GetUnitRect(CFX_RectF& rect) const { |
414 } | 402 rect.left = rect.top = 0; |
415 void CFX_Matrix::GetUnitRect(CFX_RectF &rect) const | 403 rect.width = rect.height = 1; |
416 { | 404 TransformRect(rect); |
417 rect.left = rect.top = 0; | 405 } |
418 rect.width = rect.height = 1; | 406 CFX_FloatRect CFX_Matrix::GetUnitRect() const { |
419 TransformRect(rect); | 407 CFX_FloatRect rect(0, 0, 1, 1); |
420 } | 408 rect.Transform((const CFX_Matrix*)this); |
421 CFX_FloatRect CFX_Matrix::GetUnitRect() const | 409 return rect; |
422 { | 410 } |
423 CFX_FloatRect rect(0, 0, 1, 1); | 411 FX_FLOAT CFX_Matrix::GetUnitArea() const { |
424 rect.Transform((const CFX_Matrix*)this); | 412 FX_FLOAT A = FXSYS_sqrt(a * a + b * b); |
425 return rect; | 413 FX_FLOAT B = FXSYS_sqrt(c * c + d * d); |
426 } | 414 FX_FLOAT ac = a + c, bd = b + d; |
427 FX_FLOAT CFX_Matrix::GetUnitArea() const | 415 FX_FLOAT C = FXSYS_sqrt(ac * ac + bd * bd); |
428 { | 416 FX_FLOAT P = (A + B + C) / 2; |
429 FX_FLOAT A = FXSYS_sqrt(a * a + b * b); | 417 return FXSYS_sqrt(P * (P - A) * (P - B) * (P - C)) * 2; |
430 FX_FLOAT B = FXSYS_sqrt(c * c + d * d); | 418 } |
431 FX_FLOAT ac = a + c, bd = b + d; | 419 FX_FLOAT CFX_Matrix::TransformXDistance(FX_FLOAT dx) const { |
432 FX_FLOAT C = FXSYS_sqrt(ac * ac + bd * bd); | 420 FX_FLOAT fx = a * dx, fy = b * dx; |
433 FX_FLOAT P = (A + B + C ) / 2; | 421 return FXSYS_sqrt(fx * fx + fy * fy); |
434 return FXSYS_sqrt(P * (P - A) * (P - B) * (P - C)) * 2; | 422 } |
435 } | 423 int32_t CFX_Matrix::TransformXDistance(int32_t dx) const { |
436 FX_FLOAT CFX_Matrix::TransformXDistance(FX_FLOAT dx) const | 424 FX_FLOAT fx = a * dx, fy = b * dx; |
437 { | 425 return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy)); |
438 FX_FLOAT fx = a * dx, fy = b * dx; | 426 } |
439 return FXSYS_sqrt(fx * fx + fy * fy); | 427 FX_FLOAT CFX_Matrix::TransformYDistance(FX_FLOAT dy) const { |
440 } | 428 FX_FLOAT fx = c * dy, fy = d * dy; |
441 int32_t CFX_Matrix::TransformXDistance(int32_t dx) const | 429 return FXSYS_sqrt(fx * fx + fy * fy); |
442 { | 430 } |
443 FX_FLOAT fx = a * dx, fy = b * dx; | 431 int32_t CFX_Matrix::TransformYDistance(int32_t dy) const { |
444 return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy)); | 432 FX_FLOAT fx = c * dy, fy = d * dy; |
445 } | 433 return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy)); |
446 FX_FLOAT CFX_Matrix::TransformYDistance(FX_FLOAT dy) const | 434 } |
447 { | 435 FX_FLOAT CFX_Matrix::TransformDistance(FX_FLOAT dx, FX_FLOAT dy) const { |
448 FX_FLOAT fx = c * dy, fy = d * dy; | 436 FX_FLOAT fx = a * dx + c * dy, fy = b * dx + d * dy; |
449 return FXSYS_sqrt(fx * fx + fy * fy); | 437 return FXSYS_sqrt(fx * fx + fy * fy); |
450 } | 438 } |
451 int32_t CFX_Matrix::TransformYDistance(int32_t dy) const | 439 int32_t CFX_Matrix::TransformDistance(int32_t dx, int32_t dy) const { |
452 { | 440 FX_FLOAT fx = a * dx + c * dy, fy = b * dx + d * dy; |
453 FX_FLOAT fx = c * dy, fy = d * dy; | 441 return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy)); |
454 return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy)); | 442 } |
455 } | 443 FX_FLOAT CFX_Matrix::TransformDistance(FX_FLOAT distance) const { |
456 FX_FLOAT CFX_Matrix::TransformDistance(FX_FLOAT dx, FX_FLOAT dy) const | 444 return distance * (GetXUnit() + GetYUnit()) / 2; |
457 { | 445 } |
458 FX_FLOAT fx = a * dx + c * dy, fy = b * dx + d * dy; | 446 void CFX_Matrix::TransformVector(CFX_VectorF& v) const { |
459 return FXSYS_sqrt(fx * fx + fy * fy); | 447 FX_FLOAT fx = a * v.x + c * v.y; |
460 } | 448 FX_FLOAT fy = b * v.x + d * v.y; |
461 int32_t CFX_Matrix::TransformDistance(int32_t dx, int32_t dy) const | 449 v.x = fx, v.y = fy; |
462 { | 450 } |
463 FX_FLOAT fx = a * dx + c * dy, fy = b * dx + d * dy; | 451 void CFX_Matrix::TransformVector(CFX_Vector& v) const { |
464 return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy)); | 452 FX_FLOAT fx = a * v.x + c * v.y; |
465 } | 453 FX_FLOAT fy = b * v.x + d * v.y; |
466 FX_FLOAT CFX_Matrix::TransformDistance(FX_FLOAT distance) const | 454 v.x = FXSYS_round(fx); |
467 { | 455 v.y = FXSYS_round(fy); |
468 return distance * (GetXUnit() + GetYUnit()) / 2; | 456 } |
469 } | 457 void CFX_Matrix::TransformPoints(CFX_Point* points, int32_t iCount) const { |
470 void CFX_Matrix::TransformVector(CFX_VectorF &v) const | 458 FXSYS_assert(iCount > 0); |
471 { | 459 FX_FLOAT fx, fy; |
472 FX_FLOAT fx = a * v.x + c * v.y; | 460 for (int32_t i = 0; i < iCount; i++) { |
473 FX_FLOAT fy = b * v.x + d * v.y; | 461 fx = a * points->x + c * points->y + e; |
474 v.x = fx, v.y = fy; | 462 fy = b * points->x + d * points->y + f; |
475 } | 463 points->x = FXSYS_round(fx); |
476 void CFX_Matrix::TransformVector(CFX_Vector &v) const | 464 points->y = FXSYS_round(fy); |
477 { | 465 points++; |
478 FX_FLOAT fx = a * v.x + c * v.y; | 466 } |
479 FX_FLOAT fy = b * v.x + d * v.y; | 467 } |
480 v.x = FXSYS_round(fx); | 468 void CFX_Matrix::TransformPoints(CFX_PointF* points, int32_t iCount) const { |
481 v.y = FXSYS_round(fy); | 469 FXSYS_assert(iCount > 0); |
482 } | 470 FX_FLOAT fx, fy; |
483 void CFX_Matrix::TransformPoints(CFX_Point *points, int32_t iCount) const | 471 for (int32_t i = 0; i < iCount; i++) { |
484 { | 472 fx = a * points->x + c * points->y + e; |
485 FXSYS_assert(iCount > 0); | 473 fy = b * points->x + d * points->y + f; |
486 FX_FLOAT fx, fy; | 474 points->x = fx, points->y = fy; |
487 for (int32_t i = 0; i < iCount; i ++) { | 475 points++; |
488 fx = a * points->x + c * points->y + e; | 476 } |
489 fy = b * points->x + d * points->y + f; | 477 } |
490 points->x = FXSYS_round(fx); | 478 void CFX_Matrix::TransformPoint(FX_FLOAT& x, FX_FLOAT& y) const { |
491 points->y = FXSYS_round(fy); | 479 FX_FLOAT fx = a * x + c * y + e; |
492 points ++; | 480 FX_FLOAT fy = b * x + d * y + f; |
493 } | 481 x = fx, y = fy; |
494 } | 482 } |
495 void CFX_Matrix::TransformPoints(CFX_PointF *points, int32_t iCount) const | 483 void CFX_Matrix::TransformPoint(int32_t& x, int32_t& y) const { |
496 { | 484 FX_FLOAT fx = a * x + c * y + e; |
497 FXSYS_assert(iCount > 0); | 485 FX_FLOAT fy = b * x + d * y + f; |
498 FX_FLOAT fx, fy; | 486 x = FXSYS_round(fx); |
499 for (int32_t i = 0; i < iCount; i ++) { | 487 y = FXSYS_round(fy); |
500 fx = a * points->x + c * points->y + e; | 488 } |
501 fy = b * points->x + d * points->y + f; | 489 void CFX_Matrix::TransformRect(CFX_RectF& rect) const { |
502 points->x = fx, points->y = fy; | 490 FX_FLOAT right = rect.right(), bottom = rect.bottom(); |
503 points ++; | 491 TransformRect(rect.left, right, bottom, rect.top); |
504 } | 492 rect.width = right - rect.left; |
505 } | 493 rect.height = bottom - rect.top; |
506 void CFX_Matrix::TransformPoint(FX_FLOAT &x, FX_FLOAT &y) const | 494 } |
507 { | 495 void CFX_Matrix::TransformRect(CFX_Rect& rect) const { |
508 FX_FLOAT fx = a * x + c * y + e; | 496 FX_FLOAT left = (FX_FLOAT)rect.left; |
509 FX_FLOAT fy = b * x + d * y + f; | 497 FX_FLOAT top = (FX_FLOAT)rect.bottom(); |
510 x = fx, y = fy; | 498 FX_FLOAT right = (FX_FLOAT)rect.right(); |
511 } | 499 FX_FLOAT bottom = (FX_FLOAT)rect.top; |
512 void CFX_Matrix::TransformPoint(int32_t &x, int32_t &y) const | 500 TransformRect(left, right, top, bottom); |
513 { | 501 rect.left = FXSYS_round(left); |
514 FX_FLOAT fx = a * x + c * y + e; | 502 rect.top = FXSYS_round(bottom); |
515 FX_FLOAT fy = b * x + d * y + f; | 503 rect.width = FXSYS_round(right - left); |
516 x = FXSYS_round(fx); | 504 rect.height = FXSYS_round(top - bottom); |
517 y = FXSYS_round(fy); | 505 } |
518 } | 506 void CFX_Matrix::TransformRect(FX_FLOAT& left, |
519 void CFX_Matrix::TransformRect(CFX_RectF &rect) const | 507 FX_FLOAT& right, |
520 { | 508 FX_FLOAT& top, |
521 FX_FLOAT right = rect.right(), bottom = rect.bottom(); | 509 FX_FLOAT& bottom) const { |
522 TransformRect(rect.left, right, bottom, rect.top); | 510 FX_FLOAT x[4], y[4]; |
523 rect.width = right - rect.left; | 511 x[0] = left; |
524 rect.height = bottom - rect.top; | 512 y[0] = top; |
525 } | 513 x[1] = left; |
526 void CFX_Matrix::TransformRect(CFX_Rect &rect) const | 514 y[1] = bottom; |
527 { | 515 x[2] = right; |
528 FX_FLOAT left = (FX_FLOAT)rect.left; | 516 y[2] = top; |
529 FX_FLOAT top = (FX_FLOAT)rect.bottom(); | 517 x[3] = right; |
530 FX_FLOAT right = (FX_FLOAT)rect.right(); | 518 y[3] = bottom; |
531 FX_FLOAT bottom = (FX_FLOAT)rect.top; | 519 int i; |
532 TransformRect(left, right, top, bottom); | 520 for (i = 0; i < 4; i++) { |
533 rect.left = FXSYS_round(left); | 521 Transform(x[i], y[i], x[i], y[i]); |
534 rect.top = FXSYS_round(bottom); | 522 } |
535 rect.width = FXSYS_round(right - left); | 523 right = left = x[0]; |
536 rect.height = FXSYS_round(top - bottom); | 524 top = bottom = y[0]; |
537 } | 525 for (i = 1; i < 4; i++) { |
538 void CFX_Matrix::TransformRect(FX_FLOAT& left, FX_FLOAT& right, FX_FLOAT& top, F
X_FLOAT& bottom) const | 526 if (right < x[i]) { |
539 { | 527 right = x[i]; |
540 FX_FLOAT x[4], y[4]; | 528 } |
541 x[0] = left; | 529 if (left > x[i]) { |
542 y[0] = top; | 530 left = x[i]; |
543 x[1] = left; | 531 } |
544 y[1] = bottom; | 532 if (top < y[i]) { |
545 x[2] = right; | 533 top = y[i]; |
546 y[2] = top; | 534 } |
547 x[3] = right; | 535 if (bottom > y[i]) { |
548 y[3] = bottom; | 536 bottom = y[i]; |
549 int i; | 537 } |
550 for (i = 0; i < 4; i ++) { | 538 } |
551 Transform(x[i], y[i], x[i], y[i]); | 539 } |
552 } | |
553 right = left = x[0]; | |
554 top = bottom = y[0]; | |
555 for (i = 1; i < 4; i ++) { | |
556 if (right < x[i]) { | |
557 right = x[i]; | |
558 } | |
559 if (left > x[i]) { | |
560 left = x[i]; | |
561 } | |
562 if (top < y[i]) { | |
563 top = y[i]; | |
564 } | |
565 if (bottom > y[i]) { | |
566 bottom = y[i]; | |
567 } | |
568 } | |
569 } | |
OLD | NEW |