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;
Set(baseType x,baseType y)27     void		Set(baseType x, baseType y)
28     {
29         FXT_PSV::x = x, FXT_PSV::y = y;
30     }
Set(const FXT_PSV & psv)31     void		Set(const FXT_PSV &psv)
32     {
33         FXT_PSV::x = psv.x, FXT_PSV::y = psv.y;
34     }
Add(baseType x,baseType y)35     void		Add(baseType x, baseType y)
36     {
37         FXT_PSV::x += x, FXT_PSV::y += y;
38     }
Subtract(baseType x,baseType y)39     void		Subtract(baseType x, baseType y)
40     {
41         FXT_PSV::x -= x, FXT_PSV::y -= y;
42     }
Reset()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;
Set(baseType newx,baseType newy)135     void		Set(baseType newx, baseType newy)
136     {
137         FXT_PSV::x = newx;
138         FXT_PSV::y = newy;
139     }
Set(const FXT_PSV & psv)140     void		Set(const FXT_PSV &psv)
141     {
142         FXT_PSV::x = psv.x, FXT_PSV::y = psv.y;
143     }
Set(const FXT_POINT & p1,const FXT_POINT & p2)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     }
Reset()148     void		Reset()
149     {
150         FXT_PSV::x = FXT_PSV::y = 0;
151     }
SquareLength()152     baseType	SquareLength() const
153     {
154         return FXT_PSV::x * FXT_PSV::x + FXT_PSV::y * FXT_PSV::y;
155     }
Length()156     baseType	Length() const
157     {
158         return FXSYS_sqrt(FXT_PSV::x * FXT_PSV::x + FXT_PSV::y * FXT_PSV::y);
159     }
Normalize()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     }
DotProduct(baseType otherx,baseType othery)169     baseType	DotProduct(baseType otherx, baseType othery) const
170     {
171         return FXT_PSV::x * otherx + FXT_PSV::y * othery;
172     }
DotProduct(const FXT_VECTOR & v)173     baseType	DotProduct(const FXT_VECTOR &v) const
174     {
175         return FXT_PSV::x * v.x + FXT_PSV::y * v.y;
176     }
IsParallel(baseType otherx,baseType othery)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     }
IsParallel(const FXT_VECTOR & v)182     FX_BOOL		IsParallel(const FXT_VECTOR &v) const
183     {
184         return IsParallel(v.x, v.y);
185     }
IsPerpendicular(baseType otherx,baseType othery)186     FX_BOOL		IsPerpendicular(baseType otherx, baseType othery) const
187     {
188         baseType t = DotProduct(otherx, othery);
189         return FXSYS_fabs(t) < 0x0001f;
190     }
IsPerpendicular(const FXT_VECTOR & v)191     FX_BOOL		IsPerpendicular(const FXT_VECTOR &v) const
192     {
193         return IsPerpendicular(v.x, v.y);
194     }
Translate(baseType dx,baseType dy)195     void		Translate(baseType dx, baseType dy)
196     {
197         FXT_PSV::x += dx, FXT_PSV::y += dy;
198     }
Scale(baseType sx,baseType sy)199     void		Scale(baseType sx, baseType sy)
200     {
201         FXT_PSV::x *= sx, FXT_PSV::y *= sy;
202     }
Rotate(FX_FLOAT fRadian)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     }
Cosine(const FXT_VECTOR & v1,const FXT_VECTOR & v2)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     }
ArcCosine(const FXT_VECTOR & v1,const FXT_VECTOR & v2)218     friend	FX_FLOAT	ArcCosine(const FXT_VECTOR &v1, const FXT_VECTOR &v2)
219     {
220         return (FX_FLOAT)FXSYS_acos(Cosine(v1, v2));
221     }
SlopeAngle(const FXT_VECTOR & v)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;
Set(baseType left,baseType top,baseType width,baseType height)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     }
Set(baseType left,baseType top,const FXT_SIZE & size)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     }
Set(const FXT_POINT & p,baseType width,baseType height)249     void		Set(const FXT_POINT &p, baseType width, baseType height)
250     {
251         TopLeft(p), FXT_RECT::width = width, FXT_RECT::height = height;
252     }
Set(const FXT_POINT & p1,const FXT_POINT & p2)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     }
Set(const FXT_POINT & p,const FXT_VECTOR & v)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     }
Reset()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     }
right()275     baseType	right() const
276     {
277         return left + width;
278     }
bottom()279     baseType	bottom() const
280     {
281         return top + height;
282     }
Normalize()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     }
Offset(baseType dx,baseType dy)294     void		Offset(baseType dx, baseType dy)
295     {
296         left += dx;
297         top += dy;
298     }
Inflate(baseType x,baseType y)299     void		Inflate(baseType x, baseType y)
300     {
301         left -= x;
302         width += x * 2;
303         top -= y;
304         height += y * 2;
305     }
Inflate(const FXT_POINT & p)306     void		Inflate(const FXT_POINT &p)
307     {
308         Inflate(p.x, p.y);
309     }
Inflate(baseType left,baseType top,baseType right,baseType bottom)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     }
Inflate(const FXT_RECT & rt)317     void		Inflate(const FXT_RECT &rt)
318     {
319         Inflate(rt.left, rt.top, rt.left + rt.width, rt.top + rt.height);
320     }
Deflate(baseType x,baseType y)321     void		Deflate(baseType x, baseType y)
322     {
323         left += x;
324         width -= x * 2;
325         top += y;
326         height -= y * 2;
327     }
Deflate(const FXT_POINT & p)328     void		Deflate(const FXT_POINT &p)
329     {
330         Deflate(p.x, p.y);
331     }
Deflate(baseType left,baseType top,baseType right,baseType bottom)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     }
Deflate(const FXT_RECT & rt)339     void		Deflate(const FXT_RECT &rt)
340     {
341         Deflate(rt.left, rt.top, rt.top + rt.width, rt.top + rt.height);
342     }
IsEmpty()343     FX_BOOL		IsEmpty() const
344     {
345         return width <= 0 || height <= 0;
346     }
IsEmpty(FX_FLOAT fEpsilon)347     FX_BOOL		IsEmpty(FX_FLOAT fEpsilon) const
348     {
349         return width <= fEpsilon || height <= fEpsilon;
350     }
Empty()351     void		Empty()
352     {
353         width = height = 0;
354     }
Contains(baseType x,baseType y)355     FX_BOOL		Contains(baseType x, baseType y) const
356     {
357         return x >= left && x < left + width && y >= top && y < top + height;
358     }
Contains(const FXT_POINT & p)359     FX_BOOL		Contains(const FXT_POINT &p) const
360     {
361         return Contains(p.x, p.y);
362     }
Contains(const FXT_RECT & rt)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     }
Width()367     baseType	Width() const
368     {
369         return width;
370     }
Height()371     baseType	Height() const
372     {
373         return height;
374     }
Size()375     FXT_SIZE	Size() const
376     {
377         FXT_SIZE size;
378         size.Set(width, height);
379         return size;
380     }
Size(FXT_SIZE s)381     void		Size(FXT_SIZE s)
382     {
383         width = s.x, height = s.y;
384     }
TopLeft()385     FXT_POINT	TopLeft() const
386     {
387         FXT_POINT p;
388         p.x = left;
389         p.y = top;
390         return p;
391     }
TopRight()392     FXT_POINT	TopRight() const
393     {
394         FXT_POINT p;
395         p.x = left + width;
396         p.y = top;
397         return p;
398     }
BottomLeft()399     FXT_POINT	BottomLeft() const
400     {
401         FXT_POINT p;
402         p.x = left;
403         p.y = top + height;
404         return p;
405     }
BottomRight()406     FXT_POINT	BottomRight() const
407     {
408         FXT_POINT p;
409         p.x = left + width;
410         p.y = top + height;
411         return p;
412     }
TopLeft(FXT_POINT tl)413     void		TopLeft(FXT_POINT tl)
414     {
415         left = tl.x;
416         top = tl.y;
417     }
TopRight(FXT_POINT tr)418     void		TopRight(FXT_POINT tr)
419     {
420         width = tr.x - left;
421         top = tr.y;
422     }
BottomLeft(FXT_POINT bl)423     void		BottomLeft(FXT_POINT bl)
424     {
425         left = bl.x;
426         height = bl.y - top;
427     }
BottomRight(FXT_POINT br)428     void		BottomRight(FXT_POINT br)
429     {
430         width = br.x - left;
431         height = br.y - top;
432     }
Center()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     }
GetParallelogram(FXT_PARAL & pg)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     }
Union(baseType x,baseType y)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     }
Union(const FXT_POINT & p)464     void		Union(const FXT_POINT &p)
465     {
466         Union(p.x, p.y);
467     }
Union(const FXT_RECT & rt)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     }
Intersect(const FXT_RECT & rt)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     }
IntersectWith(const FXT_RECT & rt)504     FX_BOOL		IntersectWith(const FXT_RECT &rt) const
505     {
506         FXT_RECT rect = rt;
507         rect.Intersect(*this);
508         return !rect.IsEmpty();
509     }
IntersectWith(const FXT_RECT & rt,FX_FLOAT fEpsilon)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 
FX_RECTFX_RECT544     FX_RECT(): left(0), top(0), right(0), bottom(0) { }
545 
FX_RECTFX_RECT546     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 
WidthFX_RECT554     int			Width() const
555     {
556         return right - left;
557     }
558 
HeightFX_RECT559     int			Height() const
560     {
561         return bottom - top;
562     }
563 
IsEmptyFX_RECT564     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 
IntersectFX_RECT573     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 
OffsetFX_RECT585     void		Offset(int dx, int dy)
586     {
587         left += dx;
588         right += dx;
589         top += dy;
590         bottom += dy;
591     }
592 
ContainsFX_RECT593     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 
ContainsFX_RECT598     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 
CFX_FloatRect()617     CFX_FloatRect()
618     {
619         left = right = bottom = top = 0;
620     }
621 
CFX_FloatRect(FX_FLOAT left1,FX_FLOAT bottom1,FX_FLOAT right1,FX_FLOAT top1)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 
CFX_FloatRect(const FX_FLOAT * pArray)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 
IsEmpty()640     FX_BOOL				IsEmpty() const
641     {
642         return left >= right || bottom >= top;
643     }
644 
645     void				Normalize();
646 
Reset()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 
InitRect(FX_FLOAT x,FX_FLOAT y)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 
Width()678     FX_FLOAT			Width() const
679     {
680         return right - left;
681     }
682 
Height()683     FX_FLOAT			Height() const
684     {
685         return top - bottom;
686     }
687 
Inflate(FX_FLOAT x,FX_FLOAT y)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 
Inflate(FX_FLOAT left,FX_FLOAT bottom,FX_FLOAT right,FX_FLOAT top)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 
Inflate(const CFX_FloatRect & rt)706     void				Inflate(const CFX_FloatRect &rt)
707     {
708         Inflate(rt.left, rt.bottom, rt.right, rt.top);
709     }
710 
Deflate(FX_FLOAT x,FX_FLOAT y)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 
Deflate(FX_FLOAT left,FX_FLOAT bottom,FX_FLOAT right,FX_FLOAT top)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 
Deflate(const CFX_FloatRect & rt)729     void				Deflate(const CFX_FloatRect &rt)
730     {
731         Deflate(rt.left, rt.bottom, rt.right, rt.top);
732     }
733 
Translate(FX_FLOAT e,FX_FLOAT f)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 
CFX_Matrix()756     CFX_Matrix()
757     {
758         a = d = 1;
759         b = c = e = f = 0;
760     }
761 
CFX_Matrix(FX_FLOAT a1,FX_FLOAT b1,FX_FLOAT c1,FX_FLOAT d1,FX_FLOAT e1,FX_FLOAT f1)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 
SetIdentity()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);
Reset()788     void			Reset()
789     {
790         SetIdentity();
791     }
792 
Copy(const CFX_Matrix & m)793     void			Copy(const CFX_Matrix& m)
794     {
795         *this = m;
796     }
797 
IsIdentity()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 
Transform(FX_FLOAT & x,FX_FLOAT & y)846     void			Transform(FX_FLOAT& x, FX_FLOAT& y) const
847     {
848         TransformPoint(x, y);
849     }
850 
Transform(FX_FLOAT x,FX_FLOAT y,FX_FLOAT & x1,FX_FLOAT & y1)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 
TransformRect(CFX_FloatRect & rect)863     void			TransformRect(CFX_FloatRect& rect) const
864     {
865         TransformRect(rect.left, rect.right, rect.top, rect.bottom);
866     }
867 
GetA()868     FX_FLOAT		GetA() const
869     {
870         return a;
871     }
872 
GetB()873     FX_FLOAT		GetB() const
874     {
875         return b;
876     }
877 
GetC()878     FX_FLOAT		GetC() const
879     {
880         return c;
881     }
882 
GetD()883     FX_FLOAT		GetD() const
884     {
885         return d;
886     }
887 
GetE()888     FX_FLOAT		GetE() const
889     {
890         return e;
891     }
892 
GetF()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_
908