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