eee0dfb2601eb8d45e50010f187781f2e599994a
[pdfium.git] / core / include / fxcrt / fx_coordinates.h
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4  \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #ifndef _FXCRT_COORDINATES_\r
8 #define _FXCRT_COORDINATES_\r
9 template<class baseType> class CFX_PSVTemplate;\r
10 template<class baseType> class CFX_VTemplate;\r
11 template<class baseType> class CFX_PRLTemplate;\r
12 template<class baseType> class CFX_RTemplate;\r
13 template<class baseType> class CFX_ETemplate;\r
14 template<class baseType> class CFX_ATemplate;\r
15 template<class baseType> class CFX_RRTemplate;\r
16 class CFX_Matrix;\r
17 template<class baseType>\r
18 class CFX_PSVTemplate : public CFX_Object\r
19 {\r
20 public:\r
21     typedef CFX_PSVTemplate<baseType>   FXT_PSV;\r
22     typedef CFX_PSVTemplate<baseType>   FXT_POINT;\r
23     typedef CFX_PSVTemplate<baseType>   FXT_SIZE;\r
24     void                Set(baseType x, baseType y)\r
25     {\r
26         FXT_PSV::x = x, FXT_PSV::y = y;\r
27     }\r
28     void                Set(const FXT_PSV &psv)\r
29     {\r
30         FXT_PSV::x = psv.x, FXT_PSV::y = psv.y;\r
31     }\r
32     void                Add(baseType x, baseType y)\r
33     {\r
34         FXT_PSV::x += x, FXT_PSV::y += y;\r
35     }\r
36     void                Subtract(baseType x, baseType y)\r
37     {\r
38         FXT_PSV::x -= x, FXT_PSV::y -= y;\r
39     }\r
40     void                Reset()\r
41     {\r
42         FXT_PSV::x = FXT_PSV::y = 0;\r
43     }\r
44     FXT_PSV&    operator += (const FXT_PSV &obj)\r
45     {\r
46         x += obj.x;\r
47         y += obj.y;\r
48         return *this;\r
49     }\r
50     FXT_PSV&    operator -= (const FXT_PSV &obj)\r
51     {\r
52         x -= obj.x;\r
53         y -= obj.y;\r
54         return *this;\r
55     }\r
56     FXT_PSV&    operator *= (baseType lamda)\r
57     {\r
58         x *= lamda;\r
59         y *= lamda;\r
60         return *this;\r
61     }\r
62     FXT_PSV&    operator /= (baseType lamda)\r
63     {\r
64         x /= lamda;\r
65         y /= lamda;\r
66         return *this;\r
67     }\r
68     friend      FX_BOOL         operator == (const FXT_PSV &obj1, const FXT_PSV &obj2)\r
69     {\r
70         return obj1.x == obj2.x && obj1.y == obj2.y;\r
71     }\r
72     friend      FX_BOOL         operator != (const FXT_PSV &obj1, const FXT_PSV &obj2)\r
73     {\r
74         return obj1.x != obj2.x || obj1.y != obj2.y;\r
75     }\r
76     friend      FXT_PSV         operator + (const FXT_PSV &obj1, const FXT_PSV &obj2)\r
77     {\r
78         CFX_PSVTemplate obj;\r
79         obj.x = obj1.x + obj2.x;\r
80         obj.y = obj1.y + obj2.y;\r
81         return obj;\r
82     }\r
83     friend      FXT_PSV         operator - (const FXT_PSV &obj1, const FXT_PSV &obj2)\r
84     {\r
85         CFX_PSVTemplate obj;\r
86         obj.x = obj1.x - obj2.x;\r
87         obj.y = obj1.y - obj2.y;\r
88         return obj;\r
89     }\r
90     friend      FXT_PSV         operator * (const FXT_PSV &obj, baseType lamda)\r
91     {\r
92         CFX_PSVTemplate t;\r
93         t.x = obj.x * lamda;\r
94         t.y = obj.y * lamda;\r
95         return t;\r
96     }\r
97     friend      FXT_PSV         operator * (baseType lamda, const FXT_PSV &obj)\r
98     {\r
99         CFX_PSVTemplate t;\r
100         t.x = lamda * obj.x;\r
101         t.y = lamda * obj.y;\r
102         return t;\r
103     }\r
104     friend      FXT_PSV         operator / (const FXT_PSV &obj, baseType lamda)\r
105     {\r
106         CFX_PSVTemplate t;\r
107         t.x = obj.x / lamda;\r
108         t.y = obj.y / lamda;\r
109         return t;\r
110     }\r
111     baseType x, y;\r
112 };\r
113 typedef CFX_PSVTemplate<FX_INT32>                       CFX_Point;\r
114 typedef CFX_PSVTemplate<FX_FLOAT>                       CFX_PointF;\r
115 typedef CFX_PSVTemplate<FX_INT32>                       CFX_Size;\r
116 typedef CFX_PSVTemplate<FX_FLOAT>                       CFX_SizeF;\r
117 typedef CFX_ArrayTemplate<CFX_Point>            CFX_Points;\r
118 typedef CFX_ArrayTemplate<CFX_PointF>           CFX_PointsF;\r
119 typedef CFX_PSVTemplate<FX_INT32> *                     FX_LPPOINT;\r
120 typedef CFX_PSVTemplate<FX_FLOAT> *                     FX_LPPOINTF;\r
121 typedef CFX_PSVTemplate<FX_INT32> const *       FX_LPCPOINT;\r
122 typedef CFX_PSVTemplate<FX_FLOAT> const *       FX_LPCPOINTF;\r
123 #define CFX_FloatPoint  CFX_PointF\r
124 template<class baseType>\r
125 class CFX_VTemplate: public CFX_PSVTemplate<baseType>\r
126 {\r
127 public:\r
128     typedef CFX_PSVTemplate<baseType>   FXT_PSV;\r
129     typedef CFX_PSVTemplate<baseType>   FXT_POINT;\r
130     typedef CFX_PSVTemplate<baseType>   FXT_SIZE;\r
131     typedef CFX_VTemplate<baseType>             FXT_VECTOR;\r
132     void                Set(baseType x, baseType y)\r
133     {\r
134         FXT_PSV::x = x, FXT_PSV::y = y;\r
135     }\r
136     void                Set(const FXT_PSV &psv)\r
137     {\r
138         FXT_PSV::x = psv.x, FXT_PSV::y = psv.y;\r
139     }\r
140     void                Set(const FXT_POINT &p1, const FXT_POINT &p2)\r
141     {\r
142         FXT_PSV::x = p2.x - p1.x, FXT_PSV::y = p2.y - p1.y;\r
143     }\r
144     void                Reset()\r
145     {\r
146         FXT_PSV::x = FXT_PSV::y = 0;\r
147     }\r
148     baseType    SquareLength() const\r
149     {\r
150         return FXT_PSV::x * FXT_PSV::x + FXT_PSV::y * FXT_PSV::y;\r
151     }\r
152     baseType    Length() const\r
153     {\r
154         return FXSYS_sqrt(FXT_PSV::x * FXT_PSV::x + FXT_PSV::y * FXT_PSV::y);\r
155     }\r
156     void                Normalize()\r
157     {\r
158         FX_FLOAT fLen = FXSYS_sqrt(FXT_PSV::x * FXT_PSV::x + FXT_PSV::y * FXT_PSV::y);\r
159         FXSYS_assert(fLen >= 0.0001f);\r
160         FXT_PSV::x = ((baseType)FXT_PSV::x) / fLen;\r
161         FXT_PSV::y = ((baseType)FXT_PSV::y) / fLen;\r
162     }\r
163     baseType    DotProduct(baseType x, baseType y) const\r
164     {\r
165         return FXT_PSV::x * x + FXT_PSV::y * y;\r
166     }\r
167     baseType    DotProduct(const FXT_VECTOR &v) const\r
168     {\r
169         return FXT_PSV::x * v.x + FXT_PSV::y * v.y;\r
170     }\r
171     FX_BOOL             IsParallel(baseType x, baseType y) const\r
172     {\r
173         baseType t = FXT_PSV::x * y - FXT_PSV::y * x;\r
174         return FXSYS_fabs(t) < 0x0001f;\r
175     }\r
176     FX_BOOL             IsParallel(const FXT_VECTOR &v) const\r
177     {\r
178         return IsParallel(v.x, v.y);\r
179     }\r
180     FX_BOOL             IsPerpendicular(baseType x, baseType y) const\r
181     {\r
182         baseType t = DotProduct(x, y);\r
183         return FXSYS_fabs(t) < 0x0001f;\r
184     }\r
185     FX_BOOL             IsPerpendicular(const FXT_VECTOR &v) const\r
186     {\r
187         return IsPerpendicular(v.x, v.y);\r
188     }\r
189     void                Translate(baseType dx, baseType dy)\r
190     {\r
191         FXT_PSV::x += dx, FXT_PSV::y += dy;\r
192     }\r
193     void                Scale(baseType sx, baseType sy)\r
194     {\r
195         FXT_PSV::x *= sx, FXT_PSV::y *= sy;\r
196     }\r
197     void                Rotate(FX_FLOAT fRadian)\r
198     {\r
199         FX_FLOAT xx = (FX_FLOAT)FXT_PSV::x;\r
200         FX_FLOAT yy = (FX_FLOAT)FXT_PSV::y;\r
201         FX_FLOAT cosValue = FXSYS_cos(fRadian);\r
202         FX_FLOAT sinValue = FXSYS_sin(fRadian);\r
203         FXT_PSV::x = xx * cosValue - yy * sinValue;\r
204         FXT_PSV::y = xx * sinValue + yy * cosValue;\r
205     }\r
206     friend      FX_FLOAT        Cosine(const FXT_VECTOR &v1, const FXT_VECTOR &v2)\r
207     {\r
208         FXSYS_assert(v1.SquareLength() != 0 && v2.SquareLength() != 0);\r
209         FX_FLOAT dotProduct = v1.DotProduct(v2);\r
210         return dotProduct / (FX_FLOAT)FXSYS_sqrt(v1.SquareLength() * v2.SquareLength());\r
211     }\r
212     friend      FX_FLOAT        ArcCosine(const FXT_VECTOR &v1, const FXT_VECTOR &v2)\r
213     {\r
214         return (FX_FLOAT)FXSYS_acos(Cosine(v1, v2));\r
215     }\r
216     friend      FX_FLOAT        SlopeAngle(const FXT_VECTOR &v)\r
217     {\r
218         CFX_VTemplate vx;\r
219         vx.Set(1, 0);\r
220         FX_FLOAT fSlope = ArcCosine(v, vx);\r
221         return v.y < 0 ? -fSlope : fSlope;\r
222     }\r
223 };\r
224 typedef CFX_VTemplate<FX_INT32> CFX_Vector;\r
225 typedef CFX_VTemplate<FX_FLOAT> CFX_VectorF;\r
226 template<class baseType>\r
227 class CFX_RTemplate: public CFX_Object\r
228 {\r
229 public:\r
230     typedef CFX_PSVTemplate<baseType>   FXT_POINT;\r
231     typedef CFX_PSVTemplate<baseType>   FXT_SIZE;\r
232     typedef CFX_VTemplate<baseType>             FXT_VECTOR;\r
233     typedef CFX_PRLTemplate<baseType>   FXT_PARAL;\r
234     typedef CFX_RTemplate<baseType>             FXT_RECT;\r
235     void                Set(baseType left, baseType top, baseType width, baseType height)\r
236     {\r
237         FXT_RECT::left = left, FXT_RECT::top = top, FXT_RECT::width = width, FXT_RECT::height = height;\r
238     }\r
239     void                Set(baseType left, baseType top, const FXT_SIZE &size)\r
240     {\r
241         FXT_RECT::left = left, FXT_RECT::top = top, FXT_RECT::Size(size);\r
242     }\r
243     void                Set(const FXT_POINT &p, baseType width, baseType height)\r
244     {\r
245         TopLeft(p), FXT_RECT::width = width, FXT_RECT::height = height;\r
246     }\r
247     void                Set(const FXT_POINT &p1, const FXT_POINT &p2)\r
248     {\r
249         TopLeft(p1), FXT_RECT::width = p2.x - p1.x, FXT_RECT::height = p2.y - p1.y, FXT_RECT::Normalize();\r
250     }\r
251     void                Set(const FXT_POINT &p, const FXT_VECTOR &v)\r
252     {\r
253         TopLeft(p), FXT_RECT::width = v.x, FXT_RECT::height = v.y, FXT_RECT::Normalize();\r
254     }\r
255     void                Reset()\r
256     {\r
257         FXT_RECT::left = FXT_RECT::top = FXT_RECT::width = FXT_RECT::height = 0;\r
258     }\r
259     FXT_RECT&   operator += (const FXT_POINT &p)\r
260     {\r
261         left += p.x, top += p.y;\r
262         return *this;\r
263     }\r
264     FXT_RECT&   operator -= (const FXT_POINT &p)\r
265     {\r
266         left -= p.x, top -= p.y;\r
267         return *this;\r
268     }\r
269     baseType    right() const\r
270     {\r
271         return left + width;\r
272     }\r
273     baseType    bottom() const\r
274     {\r
275         return top + height;\r
276     }\r
277     void                Normalize()\r
278     {\r
279         if (width < 0) {\r
280             left += width;\r
281             width = -width;\r
282         }\r
283         if (height < 0) {\r
284             top += height;\r
285             height = -height;\r
286         }\r
287     }\r
288     void                Offset(baseType dx, baseType dy)\r
289     {\r
290         left += dx;\r
291         top += dy;\r
292     }\r
293     void                Inflate(baseType x, baseType y)\r
294     {\r
295         left -= x;\r
296         width += x * 2;\r
297         top -= y;\r
298         height += y * 2;\r
299     }\r
300     void                Inflate(const FXT_POINT &p)\r
301     {\r
302         Inflate(p.x, p.y);\r
303     }\r
304     void                Inflate(baseType left, baseType top, baseType right, baseType bottom)\r
305     {\r
306         FXT_RECT::left -= left;\r
307         FXT_RECT::top -= top;\r
308         FXT_RECT::width += left + right;\r
309         FXT_RECT::height += top + bottom;\r
310     }\r
311     void                Inflate(const FXT_RECT &rt)\r
312     {\r
313         Inflate(rt.left, rt.top, rt.left + rt.width, rt.top + rt.height);\r
314     }\r
315     void                Deflate(baseType x, baseType y)\r
316     {\r
317         left += x;\r
318         width -= x * 2;\r
319         top += y;\r
320         height -= y * 2;\r
321     }\r
322     void                Deflate(const FXT_POINT &p)\r
323     {\r
324         Deflate(p.x, p.y);\r
325     }\r
326     void                Deflate(baseType left, baseType top, baseType right, baseType bottom)\r
327     {\r
328         FXT_RECT::left += left;\r
329         FXT_RECT::top += top;\r
330         FXT_RECT::width -= left + right;\r
331         FXT_RECT::height -= top + bottom;\r
332     }\r
333     void                Deflate(const FXT_RECT &rt)\r
334     {\r
335         Deflate(rt.left, rt.top, rt.top + rt.width, rt.top + rt.height);\r
336     }\r
337     FX_BOOL             IsEmpty() const\r
338     {\r
339         return width <= 0 || height <= 0;\r
340     }\r
341     FX_BOOL             IsEmpty(FX_FLOAT fEpsilon) const\r
342     {\r
343         return width <= fEpsilon || height <= fEpsilon;\r
344     }\r
345     void                Empty()\r
346     {\r
347         width = height = 0;\r
348     }\r
349     FX_BOOL             Contains(baseType x, baseType y) const\r
350     {\r
351         return x >= left && x < left + width && y >= top && y < top + height;\r
352     }\r
353     FX_BOOL             Contains(const FXT_POINT &p) const\r
354     {\r
355         return Contains(p.x, p.y);\r
356     }\r
357     FX_BOOL             Contains(const FXT_RECT &rt) const\r
358     {\r
359         return rt.left >= left && rt.right() <= right() && rt.top >= top && rt.bottom() <= bottom();\r
360     }\r
361     baseType    Width() const\r
362     {\r
363         return width;\r
364     }\r
365     baseType    Height() const\r
366     {\r
367         return height;\r
368     }\r
369     FXT_SIZE    Size() const\r
370     {\r
371         FXT_SIZE size;\r
372         size.Set(width, height);\r
373         return size;\r
374     }\r
375     void                Size(FXT_SIZE s)\r
376     {\r
377         width = s.x, height = s.y;\r
378     }\r
379     FXT_POINT   TopLeft() const\r
380     {\r
381         FXT_POINT p;\r
382         p.x = left;\r
383         p.y = top;\r
384         return p;\r
385     }\r
386     FXT_POINT   TopRight() const\r
387     {\r
388         FXT_POINT p;\r
389         p.x = left + width;\r
390         p.y = top;\r
391         return p;\r
392     }\r
393     FXT_POINT   BottomLeft() const\r
394     {\r
395         FXT_POINT p;\r
396         p.x = left;\r
397         p.y = top + height;\r
398         return p;\r
399     }\r
400     FXT_POINT   BottomRight() const\r
401     {\r
402         FXT_POINT p;\r
403         p.x = left + width;\r
404         p.y = top + height;\r
405         return p;\r
406     }\r
407     void                TopLeft(FXT_POINT tl)\r
408     {\r
409         left = tl.x;\r
410         top = tl.y;\r
411     }\r
412     void                TopRight(FXT_POINT tr)\r
413     {\r
414         width = tr.x - left;\r
415         top = tr.y;\r
416     }\r
417     void                BottomLeft(FXT_POINT bl)\r
418     {\r
419         left = bl.x;\r
420         height = bl.y - top;\r
421     }\r
422     void                BottomRight(FXT_POINT br)\r
423     {\r
424         width = br.x - left;\r
425         height = br.y - top;\r
426     }\r
427     FXT_POINT   Center() const\r
428     {\r
429         FXT_POINT p;\r
430         p.x = left + width / 2;\r
431         p.y = top + height / 2;\r
432         return p;\r
433     }\r
434     void                GetParallelogram(FXT_PARAL &pg) const\r
435     {\r
436         pg.x = left, pg.y = top;\r
437         pg.x1 = width, pg.y1 = 0;\r
438         pg.x2 = 0, pg.y2 = height;\r
439     }\r
440     void                Union(baseType x, baseType y)\r
441     {\r
442         baseType r = right(), b = bottom();\r
443         if (left > x) {\r
444             left = x;\r
445         }\r
446         if (r < x) {\r
447             r = x;\r
448         }\r
449         if (top > y) {\r
450             top = y;\r
451         }\r
452         if (b < y) {\r
453             b = y;\r
454         }\r
455         width = r - left;\r
456         height = b - top;\r
457     }\r
458     void                Union(const FXT_POINT &p)\r
459     {\r
460         Union(p.x, p.y);\r
461     }\r
462     void                Union(const FXT_RECT &rt)\r
463     {\r
464         baseType r = right(), b = bottom();\r
465         if (left > rt.left) {\r
466             left = rt.left;\r
467         }\r
468         if (r < rt.right()) {\r
469             r = rt.right();\r
470         }\r
471         if (top > rt.top) {\r
472             top = rt.top;\r
473         }\r
474         if (b < rt.bottom()) {\r
475             b = rt.bottom();\r
476         }\r
477         width = r - left;\r
478         height = b - top;\r
479     }\r
480     void                Intersect(const FXT_RECT &rt)\r
481     {\r
482         baseType r = right(), b = bottom();\r
483         if (left < rt.left) {\r
484             left = rt.left;\r
485         }\r
486         if (r > rt.right()) {\r
487             r = rt.right();\r
488         }\r
489         if (top < rt.top) {\r
490             top = rt.top;\r
491         }\r
492         if (b > rt.bottom()) {\r
493             b = rt.bottom();\r
494         }\r
495         width = r - left;\r
496         height = b - top;\r
497     }\r
498     FX_BOOL             IntersectWith(const FXT_RECT &rt) const\r
499     {\r
500         FXT_RECT rect = rt;\r
501         rect.Intersect(*this);\r
502         return !rect.IsEmpty();\r
503     }\r
504     FX_BOOL             IntersectWith(const FXT_RECT &rt, FX_FLOAT fEpsilon) const\r
505     {\r
506         FXT_RECT rect = rt;\r
507         rect.Intersect(*this);\r
508         return !rect.IsEmpty(fEpsilon);\r
509     }\r
510     friend      FX_BOOL operator == (const FXT_RECT &rc1, const FXT_RECT &rc2)\r
511     {\r
512         return rc1.left == rc2.left && rc1.top == rc2.top && rc1.width == rc2.width && rc1.height == rc2.height;\r
513     }\r
514     friend      FX_BOOL operator != (const FXT_RECT &rc1, const FXT_RECT &rc2)\r
515     {\r
516         return rc1.left != rc2.left || rc1.top != rc2.top || rc1.width != rc2.width || rc1.height != rc2.height;\r
517     }\r
518     baseType left, top;\r
519     baseType width, height;\r
520 };\r
521 typedef CFX_RTemplate<FX_INT32>                 CFX_Rect;\r
522 typedef CFX_RTemplate<FX_FLOAT>                 CFX_RectF;\r
523 typedef CFX_RTemplate<FX_INT32> *               FX_LPRECT;\r
524 typedef CFX_RTemplate<FX_FLOAT> *               FX_LPRECTF;\r
525 typedef CFX_RTemplate<FX_INT32> const * FX_LPCRECT;\r
526 typedef CFX_RTemplate<FX_FLOAT> const * FX_LPCRECTF;\r
527 typedef CFX_ArrayTemplate<CFX_RectF>    CFX_RectFArray;\r
528 struct FX_RECT {\r
529 \r
530     int                 left;\r
531 \r
532     int                 top;\r
533 \r
534     int                 right;\r
535 \r
536     int                 bottom;\r
537 \r
538     FX_RECT() {}\r
539 \r
540     FX_RECT(int left1, int top1, int right1, int bottom1)\r
541     {\r
542         left = left1;\r
543         top = top1;\r
544         right = right1;\r
545         bottom = bottom1;\r
546     }\r
547 \r
548     int                 Width() const\r
549     {\r
550         return right - left;\r
551     }\r
552 \r
553     int                 Height() const\r
554     {\r
555         return bottom - top;\r
556     }\r
557 \r
558     FX_BOOL             IsEmpty() const\r
559     {\r
560         return right <= left || bottom <= top;\r
561     }\r
562 \r
563     void                Normalize();\r
564 \r
565     void                Intersect(const FX_RECT& src);\r
566 \r
567     void                Intersect(int left1, int top1, int right1, int bottom1)\r
568     {\r
569         Intersect(FX_RECT(left1, top1, right1, bottom1));\r
570     }\r
571 \r
572     void                Union(const FX_RECT& other_rect);\r
573 \r
574     FX_BOOL             operator == (const FX_RECT& src) const\r
575     {\r
576         return left == src.left && right == src.right && top == src.top && bottom == src.bottom;\r
577     }\r
578 \r
579     void                Offset(int dx, int dy)\r
580     {\r
581         left += dx;\r
582         right += dx;\r
583         top += dy;\r
584         bottom += dy;\r
585     }\r
586 \r
587     FX_BOOL             Contains(const FX_RECT& other_rect) const\r
588     {\r
589         return other_rect.left >= left && other_rect.right <= right && other_rect.top >= top && other_rect.bottom <= bottom;\r
590     }\r
591 \r
592     FX_BOOL             Contains(int x, int y) const\r
593     {\r
594         return x >= left && x < right && y >= top && y < bottom;\r
595     }\r
596 };\r
597 struct FX_SMALL_RECT {\r
598 \r
599     FX_SHORT    Left;\r
600 \r
601     FX_SHORT    Top;\r
602 \r
603     FX_SHORT    Right;\r
604 \r
605     FX_SHORT    Bottom;\r
606 };\r
607 class CFX_FloatRect : public CFX_Object\r
608 {\r
609 public:\r
610 \r
611     CFX_FloatRect()\r
612     {\r
613         left = right = bottom = top = 0;\r
614     }\r
615 \r
616     CFX_FloatRect(FX_FLOAT left1, FX_FLOAT bottom1, FX_FLOAT right1, FX_FLOAT top1)\r
617     {\r
618         left = left1;\r
619         bottom = bottom1;\r
620         right = right1;\r
621         top = top1;\r
622     }\r
623 \r
624     CFX_FloatRect(const FX_FLOAT* pArray)\r
625     {\r
626         left = pArray[0];\r
627         bottom = pArray[1];\r
628         right = pArray[2];\r
629         top = pArray[3];\r
630     }\r
631 \r
632     CFX_FloatRect(const FX_RECT& rect);\r
633 \r
634     FX_BOOL                             IsEmpty() const\r
635     {\r
636         return left >= right || bottom >= top;\r
637     }\r
638 \r
639     void                                Normalize();\r
640 \r
641     void                                Reset()\r
642     {\r
643         left = right = bottom = top = 0;\r
644     }\r
645 \r
646     FX_BOOL                             Contains(const CFX_FloatRect& other_rect) const;\r
647 \r
648     FX_BOOL                             Contains(FX_FLOAT x, FX_FLOAT y) const;\r
649 \r
650     void                                Transform(const CFX_Matrix* pMatrix);\r
651 \r
652     void                                Intersect(const CFX_FloatRect& other_rect);\r
653 \r
654     void                                Union(const CFX_FloatRect& other_rect);\r
655 \r
656     FX_RECT                             GetInnerRect() const;\r
657 \r
658     FX_RECT                             GetOutterRect() const;\r
659 \r
660     FX_RECT                             GetClosestRect() const;\r
661 \r
662     int                                 Substract4(CFX_FloatRect& substract_rect, CFX_FloatRect* pRects);\r
663 \r
664     void                                InitRect(FX_FLOAT x, FX_FLOAT y)\r
665     {\r
666         left = right = x;\r
667         bottom = top = y;\r
668     }\r
669 \r
670     void                                UpdateRect(FX_FLOAT x, FX_FLOAT y);\r
671 \r
672     FX_FLOAT                    Width() const\r
673     {\r
674         return right - left;\r
675     }\r
676 \r
677     FX_FLOAT                    Height() const\r
678     {\r
679         return top - bottom;\r
680     }\r
681 \r
682     void                                Inflate(FX_FLOAT x, FX_FLOAT y)\r
683     {\r
684         Normalize();\r
685         left -= x;\r
686         right += x;\r
687         bottom -= y;\r
688         top += y;\r
689     }\r
690 \r
691     void                                Inflate(FX_FLOAT left, FX_FLOAT bottom, FX_FLOAT right, FX_FLOAT top)\r
692     {\r
693         Normalize();\r
694         this->left -= left;\r
695         this->bottom -= bottom;\r
696         this->right += right;\r
697         this->top += top;\r
698     }\r
699 \r
700     void                                Inflate(const CFX_FloatRect &rt)\r
701     {\r
702         Inflate(rt.left, rt.bottom, rt.right, rt.top);\r
703     }\r
704 \r
705     void                                Deflate(FX_FLOAT x, FX_FLOAT y)\r
706     {\r
707         Normalize();\r
708         left += x;\r
709         right -= x;\r
710         bottom += y;\r
711         top -= y;\r
712     }\r
713 \r
714     void                                Deflate(FX_FLOAT left, FX_FLOAT bottom, FX_FLOAT right, FX_FLOAT top)\r
715     {\r
716         Normalize();\r
717         this->left += left;\r
718         this->bottom += bottom;\r
719         this->right -= right;\r
720         this->top -= top;\r
721     }\r
722 \r
723     void                                Deflate(const CFX_FloatRect &rt)\r
724     {\r
725         Deflate(rt.left, rt.bottom, rt.right, rt.top);\r
726     }\r
727 \r
728     void                                Translate(FX_FLOAT e, FX_FLOAT f)\r
729     {\r
730         left += e;\r
731         right += e;\r
732         top += f;\r
733         bottom += f;\r
734     }\r
735 \r
736     static CFX_FloatRect        GetBBox(const CFX_FloatPoint* pPoints, int nPoints);\r
737 \r
738     FX_FLOAT                    left;\r
739 \r
740     FX_FLOAT                    right;\r
741 \r
742     FX_FLOAT                    bottom;\r
743 \r
744     FX_FLOAT                    top;\r
745 };\r
746 class CFX_Matrix : public CFX_Object\r
747 {\r
748 public:\r
749 \r
750     CFX_Matrix()\r
751     {\r
752         a = d = 1;\r
753         b = c = e = f = 0;\r
754     }\r
755 \r
756     CFX_Matrix(FX_FLOAT a1, FX_FLOAT b1, FX_FLOAT c1, FX_FLOAT d1, FX_FLOAT e1, FX_FLOAT f1)\r
757     {\r
758         a = a1;\r
759         b = b1;\r
760         c = c1;\r
761         d = d1;\r
762         e = e1;\r
763         f = f1;\r
764     }\r
765 \r
766     void                        Set(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f);\r
767     void                        Set(const FX_FLOAT n[6]);\r
768 \r
769     void                        SetIdentity()\r
770     {\r
771         a = d = 1;\r
772         b = c = e = f = 0;\r
773     }\r
774 \r
775     void                        SetReverse(const CFX_Matrix &m);\r
776 \r
777     void                        Concat(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f, FX_BOOL bPrepended = FALSE);\r
778 \r
779     void                        Concat(const CFX_Matrix &m, FX_BOOL bPrepended = FALSE);\r
780 \r
781     void                        ConcatInverse(const CFX_Matrix& m, FX_BOOL bPrepended = FALSE);\r
782     void                        Reset()\r
783     {\r
784         SetIdentity();\r
785     }\r
786 \r
787     void                        Copy(const CFX_Matrix& m)\r
788     {\r
789         *this = m;\r
790     }\r
791 \r
792     FX_BOOL                     IsIdentity() const\r
793     {\r
794         return a == 1 && b == 0 && c == 0 && d == 1 && e == 0 && f == 0;\r
795     }\r
796     FX_BOOL                     IsInvertible() const;\r
797 \r
798     FX_BOOL                     Is90Rotated() const;\r
799 \r
800     FX_BOOL                     IsScaled() const;\r
801 \r
802     void                        Translate(FX_FLOAT x, FX_FLOAT y, FX_BOOL bPrepended = FALSE);\r
803 \r
804     void                        TranslateI(FX_INT32 x, FX_INT32 y, FX_BOOL bPrepended = FALSE)\r
805     {\r
806         Translate((FX_FLOAT)x, (FX_FLOAT)y, bPrepended);\r
807     }\r
808 \r
809     void                        Scale(FX_FLOAT sx, FX_FLOAT sy, FX_BOOL bPrepended = FALSE);\r
810 \r
811     void                        Rotate(FX_FLOAT fRadian, FX_BOOL bPrepended = FALSE);\r
812 \r
813     void                        RotateAt(FX_FLOAT fRadian, FX_FLOAT x, FX_FLOAT y, FX_BOOL bPrepended = FALSE);\r
814 \r
815     void                        Shear(FX_FLOAT fAlphaRadian, FX_FLOAT fBetaRadian, FX_BOOL bPrepended = FALSE);\r
816 \r
817     void                        MatchRect(const CFX_FloatRect &dest, const CFX_FloatRect &src);\r
818 \r
819     FX_FLOAT            GetXUnit() const;\r
820 \r
821     FX_FLOAT            GetYUnit() const;\r
822     void                        GetUnitRect(CFX_RectF &rect) const;\r
823 \r
824     CFX_FloatRect       GetUnitRect() const;\r
825 \r
826     FX_FLOAT            GetUnitArea() const;\r
827     FX_FLOAT            TransformXDistance(FX_FLOAT dx) const;\r
828     FX_INT32            TransformXDistance(FX_INT32 dx) const;\r
829     FX_FLOAT            TransformYDistance(FX_FLOAT dy) const;\r
830     FX_INT32            TransformYDistance(FX_INT32 dy) const;\r
831     FX_FLOAT            TransformDistance(FX_FLOAT dx, FX_FLOAT dy) const;\r
832     FX_INT32            TransformDistance(FX_INT32 dx, FX_INT32 dy) const;\r
833 \r
834     FX_FLOAT            TransformDistance(FX_FLOAT distance) const;\r
835     void                        TransformPoint(FX_FLOAT &x, FX_FLOAT &y) const;\r
836     void                        TransformPoint(FX_INT32 &x, FX_INT32 &y) const;\r
837     void                        TransformPoints(CFX_PointF *points, FX_INT32 iCount) const;\r
838     void                        TransformPoints(CFX_Point *points, FX_INT32 iCount) const;\r
839 \r
840     void                        Transform(FX_FLOAT& x, FX_FLOAT& y) const\r
841     {\r
842         TransformPoint(x, y);\r
843     }\r
844 \r
845     void                        Transform(FX_FLOAT x, FX_FLOAT y, FX_FLOAT& x1, FX_FLOAT& y1) const\r
846     {\r
847         x1 = x, y1 = y;\r
848         TransformPoint(x1, y1);\r
849     }\r
850     void                        TransformVector(CFX_VectorF &v) const;\r
851     void                        TransformVector(CFX_Vector &v) const;\r
852     void                        TransformRect(CFX_RectF &rect) const;\r
853     void                        TransformRect(CFX_Rect &rect) const;\r
854 \r
855     void                        TransformRect(FX_FLOAT& left, FX_FLOAT& right, FX_FLOAT& top, FX_FLOAT& bottom) const;\r
856 \r
857     void                        TransformRect(CFX_FloatRect& rect) const\r
858     {\r
859         TransformRect(rect.left, rect.right, rect.top, rect.bottom);\r
860     }\r
861 \r
862     FX_FLOAT            GetA() const\r
863     {\r
864         return a;\r
865     }\r
866 \r
867     FX_FLOAT            GetB() const\r
868     {\r
869         return b;\r
870     }\r
871 \r
872     FX_FLOAT            GetC() const\r
873     {\r
874         return c;\r
875     }\r
876 \r
877     FX_FLOAT            GetD() const\r
878     {\r
879         return d;\r
880     }\r
881 \r
882     FX_FLOAT            GetE() const\r
883     {\r
884         return e;\r
885     }\r
886 \r
887     FX_FLOAT            GetF() const\r
888     {\r
889         return f;\r
890     }\r
891 public:\r
892     FX_FLOAT a;\r
893     FX_FLOAT b;\r
894     FX_FLOAT c;\r
895     FX_FLOAT d;\r
896     FX_FLOAT e;\r
897     FX_FLOAT f;\r
898 };\r
899 #define CFX_AffineMatrix        CFX_Matrix\r
900 #endif\r