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