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