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