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