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;
Set(baseType x,baseType y)33   void Set(baseType x, baseType y) { FXT_PSV::x = x, FXT_PSV::y = y; }
Set(const FXT_PSV & psv)34   void Set(const FXT_PSV& psv) { FXT_PSV::x = psv.x, FXT_PSV::y = psv.y; }
Add(baseType x,baseType y)35   void Add(baseType x, baseType y) { FXT_PSV::x += x, FXT_PSV::y += y; }
Subtract(baseType x,baseType y)36   void Subtract(baseType x, baseType y) { FXT_PSV::x -= x, FXT_PSV::y -= y; }
Reset()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;
Set(baseType newx,baseType newy)114   void Set(baseType newx, baseType newy) {
115     FXT_PSV::x = newx;
116     FXT_PSV::y = newy;
117   }
Set(const FXT_PSV & psv)118   void Set(const FXT_PSV& psv) { FXT_PSV::x = psv.x, FXT_PSV::y = psv.y; }
Set(const FXT_POINT & p1,const FXT_POINT & p2)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   }
Reset()122   void Reset() { FXT_PSV::x = FXT_PSV::y = 0; }
SquareLength()123   baseType SquareLength() const {
124     return FXT_PSV::x * FXT_PSV::x + FXT_PSV::y * FXT_PSV::y;
125   }
Length()126   baseType Length() const {
127     return FXSYS_sqrt(FXT_PSV::x * FXT_PSV::x + FXT_PSV::y * FXT_PSV::y);
128   }
Normalize()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   }
DotProduct(baseType otherx,baseType othery)138   baseType DotProduct(baseType otherx, baseType othery) const {
139     return FXT_PSV::x * otherx + FXT_PSV::y * othery;
140   }
DotProduct(const FXT_VECTOR & v)141   baseType DotProduct(const FXT_VECTOR& v) const {
142     return FXT_PSV::x * v.x + FXT_PSV::y * v.y;
143   }
IsParallel(baseType otherx,baseType othery)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   }
IsParallel(const FXT_VECTOR & v)148   FX_BOOL IsParallel(const FXT_VECTOR& v) const { return IsParallel(v.x, v.y); }
IsPerpendicular(baseType otherx,baseType othery)149   FX_BOOL IsPerpendicular(baseType otherx, baseType othery) const {
150     baseType t = DotProduct(otherx, othery);
151     return FXSYS_fabs(t) < 0x0001f;
152   }
IsPerpendicular(const FXT_VECTOR & v)153   FX_BOOL IsPerpendicular(const FXT_VECTOR& v) const {
154     return IsPerpendicular(v.x, v.y);
155   }
Translate(baseType dx,baseType dy)156   void Translate(baseType dx, baseType dy) {
157     FXT_PSV::x += dx, FXT_PSV::y += dy;
158   }
Scale(baseType sx,baseType sy)159   void Scale(baseType sx, baseType sy) { FXT_PSV::x *= sx, FXT_PSV::y *= sy; }
Rotate(FX_FLOAT fRadian)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   }
Cosine(const FXT_VECTOR & v1,const FXT_VECTOR & v2)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   }
ArcCosine(const FXT_VECTOR & v1,const FXT_VECTOR & v2)174   friend FX_FLOAT ArcCosine(const FXT_VECTOR& v1, const FXT_VECTOR& v2) {
175     return (FX_FLOAT)FXSYS_acos(Cosine(v1, v2));
176   }
SlopeAngle(const FXT_VECTOR & v)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;
Set(baseType left,baseType top,baseType width,baseType height)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   }
Set(baseType left,baseType top,const FXT_SIZE & size)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   }
Set(const FXT_POINT & p,baseType width,baseType height)201   void Set(const FXT_POINT& p, baseType width, baseType height) {
202     TopLeft(p), FXT_RECT::width = width, FXT_RECT::height = height;
203   }
Set(const FXT_POINT & p1,const FXT_POINT & p2)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   }
Set(const FXT_POINT & p,const FXT_VECTOR & v)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   }
Reset()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   }
right()223   baseType right() const { return left + width; }
bottom()224   baseType bottom() const { return top + height; }
Normalize()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   }
Offset(baseType dx,baseType dy)235   void Offset(baseType dx, baseType dy) {
236     left += dx;
237     top += dy;
238   }
Inflate(baseType x,baseType y)239   void Inflate(baseType x, baseType y) {
240     left -= x;
241     width += x * 2;
242     top -= y;
243     height += y * 2;
244   }
Inflate(const FXT_POINT & p)245   void Inflate(const FXT_POINT& p) { Inflate(p.x, p.y); }
Inflate(baseType left,baseType top,baseType right,baseType bottom)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   }
Inflate(const FXT_RECT & rt)252   void Inflate(const FXT_RECT& rt) {
253     Inflate(rt.left, rt.top, rt.left + rt.width, rt.top + rt.height);
254   }
Deflate(baseType x,baseType y)255   void Deflate(baseType x, baseType y) {
256     left += x;
257     width -= x * 2;
258     top += y;
259     height -= y * 2;
260   }
Deflate(const FXT_POINT & p)261   void Deflate(const FXT_POINT& p) { Deflate(p.x, p.y); }
Deflate(baseType left,baseType top,baseType right,baseType bottom)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   }
Deflate(const FXT_RECT & rt)268   void Deflate(const FXT_RECT& rt) {
269     Deflate(rt.left, rt.top, rt.top + rt.width, rt.top + rt.height);
270   }
IsEmpty()271   FX_BOOL IsEmpty() const { return width <= 0 || height <= 0; }
IsEmpty(FX_FLOAT fEpsilon)272   FX_BOOL IsEmpty(FX_FLOAT fEpsilon) const {
273     return width <= fEpsilon || height <= fEpsilon;
274   }
Empty()275   void Empty() { width = height = 0; }
Contains(baseType x,baseType y)276   FX_BOOL Contains(baseType x, baseType y) const {
277     return x >= left && x < left + width && y >= top && y < top + height;
278   }
Contains(const FXT_POINT & p)279   FX_BOOL Contains(const FXT_POINT& p) const { return Contains(p.x, p.y); }
Contains(const FXT_RECT & rt)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   }
Width()284   baseType Width() const { return width; }
Height()285   baseType Height() const { return height; }
Size()286   FXT_SIZE Size() const {
287     FXT_SIZE size;
288     size.Set(width, height);
289     return size;
290   }
Size(FXT_SIZE s)291   void Size(FXT_SIZE s) { width = s.x, height = s.y; }
TopLeft()292   FXT_POINT TopLeft() const {
293     FXT_POINT p;
294     p.x = left;
295     p.y = top;
296     return p;
297   }
TopRight()298   FXT_POINT TopRight() const {
299     FXT_POINT p;
300     p.x = left + width;
301     p.y = top;
302     return p;
303   }
BottomLeft()304   FXT_POINT BottomLeft() const {
305     FXT_POINT p;
306     p.x = left;
307     p.y = top + height;
308     return p;
309   }
BottomRight()310   FXT_POINT BottomRight() const {
311     FXT_POINT p;
312     p.x = left + width;
313     p.y = top + height;
314     return p;
315   }
TopLeft(FXT_POINT tl)316   void TopLeft(FXT_POINT tl) {
317     left = tl.x;
318     top = tl.y;
319   }
TopRight(FXT_POINT tr)320   void TopRight(FXT_POINT tr) {
321     width = tr.x - left;
322     top = tr.y;
323   }
BottomLeft(FXT_POINT bl)324   void BottomLeft(FXT_POINT bl) {
325     left = bl.x;
326     height = bl.y - top;
327   }
BottomRight(FXT_POINT br)328   void BottomRight(FXT_POINT br) {
329     width = br.x - left;
330     height = br.y - top;
331   }
Center()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   }
GetParallelogram(FXT_PARAL & pg)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   }
Union(baseType x,baseType y)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   }
Union(const FXT_POINT & p)360   void Union(const FXT_POINT& p) { Union(p.x, p.y); }
Union(const FXT_RECT & rt)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   }
Intersect(const FXT_RECT & rt)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   }
IntersectWith(const FXT_RECT & rt)395   FX_BOOL IntersectWith(const FXT_RECT& rt) const {
396     FXT_RECT rect = rt;
397     rect.Intersect(*this);
398     return !rect.IsEmpty();
399   }
IntersectWith(const FXT_RECT & rt,FX_FLOAT fEpsilon)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 
FX_RECTFX_RECT432   FX_RECT() : left(0), top(0), right(0), bottom(0) {}
433 
FX_RECTFX_RECT434   FX_RECT(int left1, int top1, int right1, int bottom1) {
435     left = left1;
436     top = top1;
437     right = right1;
438     bottom = bottom1;
439   }
440 
WidthFX_RECT441   int Width() const { return right - left; }
442 
HeightFX_RECT443   int Height() const { return bottom - top; }
444 
IsEmptyFX_RECT445   FX_BOOL IsEmpty() const { return right <= left || bottom <= top; }
446 
447   void Normalize();
448 
449   void Intersect(const FX_RECT& src);
450 
IntersectFX_RECT451   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 
OffsetFX_RECT462   void Offset(int dx, int dy) {
463     left += dx;
464     right += dx;
465     top += dy;
466     bottom += dy;
467   }
468 
ContainsFX_RECT469   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 
ContainsFX_RECT474   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:
CFX_FloatRect()489   CFX_FloatRect() { left = right = bottom = top = 0; }
490 
CFX_FloatRect(FX_FLOAT left1,FX_FLOAT bottom1,FX_FLOAT right1,FX_FLOAT top1)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 
CFX_FloatRect(const FX_FLOAT * pArray)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 
IsEmpty()510   FX_BOOL IsEmpty() const { return left >= right || bottom >= top; }
511 
512   void Normalize();
513 
Reset()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 
InitRect(FX_FLOAT x,FX_FLOAT y)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 
Width()541   FX_FLOAT Width() const { return right - left; }
542 
Height()543   FX_FLOAT Height() const { return top - bottom; }
544 
Inflate(FX_FLOAT x,FX_FLOAT y)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 
Inflate(FX_FLOAT other_left,FX_FLOAT other_bottom,FX_FLOAT other_right,FX_FLOAT other_top)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 
Inflate(const CFX_FloatRect & rt)564   void Inflate(const CFX_FloatRect& rt) {
565     Inflate(rt.left, rt.bottom, rt.right, rt.top);
566   }
567 
Deflate(FX_FLOAT x,FX_FLOAT y)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 
Deflate(FX_FLOAT other_left,FX_FLOAT other_bottom,FX_FLOAT other_right,FX_FLOAT other_top)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 
Deflate(const CFX_FloatRect & rt)587   void Deflate(const CFX_FloatRect& rt) {
588     Deflate(rt.left, rt.bottom, rt.right, rt.top);
589   }
590 
Translate(FX_FLOAT e,FX_FLOAT f)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:
CFX_Matrix()610   CFX_Matrix() { SetIdentity(); }
611 
CFX_Matrix(FX_FLOAT a1,FX_FLOAT b1,FX_FLOAT c1,FX_FLOAT d1,FX_FLOAT e1,FX_FLOAT f1)612   CFX_Matrix(FX_FLOAT a1,
613              FX_FLOAT b1,
614              FX_FLOAT c1,
615              FX_FLOAT d1,
616              FX_FLOAT e1,
617              FX_FLOAT f1) {
618     a = a1;
619     b = b1;
620     c = c1;
621     d = d1;
622     e = e1;
623     f = f1;
624   }
625 
626   void Set(FX_FLOAT a,
627            FX_FLOAT b,
628            FX_FLOAT c,
629            FX_FLOAT d,
630            FX_FLOAT e,
631            FX_FLOAT f);
632   void Set(const FX_FLOAT n[6]);
633 
SetIdentity()634   void SetIdentity() {
635     a = d = 1;
636     b = c = e = f = 0;
637   }
638 
639   void SetReverse(const CFX_Matrix& m);
640 
641   void Concat(FX_FLOAT a,
642               FX_FLOAT b,
643               FX_FLOAT c,
644               FX_FLOAT d,
645               FX_FLOAT e,
646               FX_FLOAT f,
647               FX_BOOL bPrepended = FALSE);
648   void Concat(const CFX_Matrix& m, FX_BOOL bPrepended = FALSE);
649   void ConcatInverse(const CFX_Matrix& m, FX_BOOL bPrepended = FALSE);
650 
Copy(const CFX_Matrix & m)651   void Copy(const CFX_Matrix& m) { *this = m; }
652 
IsIdentity()653   FX_BOOL IsIdentity() const {
654     return a == 1 && b == 0 && c == 0 && d == 1 && e == 0 && f == 0;
655   }
656   FX_BOOL IsInvertible() const;
657 
658   FX_BOOL Is90Rotated() const;
659 
660   FX_BOOL IsScaled() const;
661 
662   void Translate(FX_FLOAT x, FX_FLOAT y, FX_BOOL bPrepended = FALSE);
663 
664   void TranslateI(int32_t x, int32_t y, FX_BOOL bPrepended = FALSE) {
665     Translate((FX_FLOAT)x, (FX_FLOAT)y, bPrepended);
666   }
667 
668   void Scale(FX_FLOAT sx, FX_FLOAT sy, FX_BOOL bPrepended = FALSE);
669 
670   void Rotate(FX_FLOAT fRadian, FX_BOOL bPrepended = FALSE);
671 
672   void RotateAt(FX_FLOAT fRadian,
673                 FX_FLOAT x,
674                 FX_FLOAT y,
675                 FX_BOOL bPrepended = FALSE);
676 
677   void Shear(FX_FLOAT fAlphaRadian,
678              FX_FLOAT fBetaRadian,
679              FX_BOOL bPrepended = FALSE);
680 
681   void MatchRect(const CFX_FloatRect& dest, const CFX_FloatRect& src);
682 
683   FX_FLOAT GetXUnit() const;
684 
685   FX_FLOAT GetYUnit() const;
686   void GetUnitRect(CFX_RectF& rect) const;
687 
688   CFX_FloatRect GetUnitRect() const;
689 
690   FX_FLOAT GetUnitArea() const;
691   FX_FLOAT TransformXDistance(FX_FLOAT dx) const;
692   int32_t TransformXDistance(int32_t dx) const;
693   FX_FLOAT TransformYDistance(FX_FLOAT dy) const;
694   int32_t TransformYDistance(int32_t dy) const;
695   FX_FLOAT TransformDistance(FX_FLOAT dx, FX_FLOAT dy) const;
696   int32_t TransformDistance(int32_t dx, int32_t dy) const;
697 
698   FX_FLOAT TransformDistance(FX_FLOAT distance) const;
699   void TransformPoint(FX_FLOAT& x, FX_FLOAT& y) const;
700   void TransformPoint(int32_t& x, int32_t& y) const;
701   void TransformPoints(CFX_PointF* points, int32_t iCount) const;
702   void TransformPoints(CFX_Point* points, int32_t iCount) const;
703 
Transform(FX_FLOAT & x,FX_FLOAT & y)704   void Transform(FX_FLOAT& x, FX_FLOAT& y) const { TransformPoint(x, y); }
705 
Transform(FX_FLOAT x,FX_FLOAT y,FX_FLOAT & x1,FX_FLOAT & y1)706   void Transform(FX_FLOAT x, FX_FLOAT y, FX_FLOAT& x1, FX_FLOAT& y1) const {
707     x1 = x, y1 = y;
708     TransformPoint(x1, y1);
709   }
710   void TransformVector(CFX_VectorF& v) const;
711   void TransformVector(CFX_Vector& v) const;
712   void TransformRect(CFX_RectF& rect) const;
713   void TransformRect(CFX_Rect& rect) const;
714 
715   void TransformRect(FX_FLOAT& left,
716                      FX_FLOAT& right,
717                      FX_FLOAT& top,
718                      FX_FLOAT& bottom) const;
719 
TransformRect(CFX_FloatRect & rect)720   void TransformRect(CFX_FloatRect& rect) const {
721     TransformRect(rect.left, rect.right, rect.top, rect.bottom);
722   }
723 
GetA()724   FX_FLOAT GetA() const { return a; }
725 
GetB()726   FX_FLOAT GetB() const { return b; }
727 
GetC()728   FX_FLOAT GetC() const { return c; }
729 
GetD()730   FX_FLOAT GetD() const { return d; }
731 
GetE()732   FX_FLOAT GetE() const { return e; }
733 
GetF()734   FX_FLOAT GetF() const { return f; }
735 
736  public:
737   FX_FLOAT a;
738   FX_FLOAT b;
739   FX_FLOAT c;
740   FX_FLOAT d;
741   FX_FLOAT e;
742   FX_FLOAT f;
743 };
744 
745 #endif  // CORE_INCLUDE_FXCRT_FX_COORDINATES_H_
746