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