Home | History | Annotate | Download | only in fxcrt
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #ifndef CORE_INCLUDE_FXCRT_FX_COORDINATES_H_
      8 #define CORE_INCLUDE_FXCRT_FX_COORDINATES_H_
      9 
     10 #include "fx_basic.h"
     11 
     12 template <class baseType>
     13 class CFX_PSVTemplate;
     14 template <class baseType>
     15 class CFX_VTemplate;
     16 template <class baseType>
     17 class CFX_PRLTemplate;
     18 template <class baseType>
     19 class CFX_RTemplate;
     20 template <class baseType>
     21 class CFX_ETemplate;
     22 template <class baseType>
     23 class CFX_ATemplate;
     24 template <class baseType>
     25 class CFX_RRTemplate;
     26 class CFX_Matrix;
     27 template <class baseType>
     28 class CFX_PSVTemplate {
     29  public:
     30   typedef CFX_PSVTemplate<baseType> FXT_PSV;
     31   typedef CFX_PSVTemplate<baseType> FXT_POINT;
     32   typedef CFX_PSVTemplate<baseType> FXT_SIZE;
     33   void Set(baseType x, baseType y) { FXT_PSV::x = x, FXT_PSV::y = y; }
     34   void Set(const FXT_PSV& psv) { FXT_PSV::x = psv.x, FXT_PSV::y = psv.y; }
     35   void Add(baseType x, baseType y) { FXT_PSV::x += x, FXT_PSV::y += y; }
     36   void Subtract(baseType x, baseType y) { FXT_PSV::x -= x, FXT_PSV::y -= y; }
     37   void Reset() { FXT_PSV::x = FXT_PSV::y = 0; }
     38   FXT_PSV& operator+=(const FXT_PSV& obj) {
     39     x += obj.x;
     40     y += obj.y;
     41     return *this;
     42   }
     43   FXT_PSV& operator-=(const FXT_PSV& obj) {
     44     x -= obj.x;
     45     y -= obj.y;
     46     return *this;
     47   }
     48   FXT_PSV& operator*=(baseType lamda) {
     49     x *= lamda;
     50     y *= lamda;
     51     return *this;
     52   }
     53   FXT_PSV& operator/=(baseType lamda) {
     54     x /= lamda;
     55     y /= lamda;
     56     return *this;
     57   }
     58   friend FX_BOOL operator==(const FXT_PSV& obj1, const FXT_PSV& obj2) {
     59     return obj1.x == obj2.x && obj1.y == obj2.y;
     60   }
     61   friend FX_BOOL operator!=(const FXT_PSV& obj1, const FXT_PSV& obj2) {
     62     return obj1.x != obj2.x || obj1.y != obj2.y;
     63   }
     64   friend FXT_PSV operator+(const FXT_PSV& obj1, const FXT_PSV& obj2) {
     65     CFX_PSVTemplate obj;
     66     obj.x = obj1.x + obj2.x;
     67     obj.y = obj1.y + obj2.y;
     68     return obj;
     69   }
     70   friend FXT_PSV operator-(const FXT_PSV& obj1, const FXT_PSV& obj2) {
     71     CFX_PSVTemplate obj;
     72     obj.x = obj1.x - obj2.x;
     73     obj.y = obj1.y - obj2.y;
     74     return obj;
     75   }
     76   friend FXT_PSV operator*(const FXT_PSV& obj, baseType lamda) {
     77     CFX_PSVTemplate t;
     78     t.x = obj.x * lamda;
     79     t.y = obj.y * lamda;
     80     return t;
     81   }
     82   friend FXT_PSV operator*(baseType lamda, const FXT_PSV& obj) {
     83     CFX_PSVTemplate t;
     84     t.x = lamda * obj.x;
     85     t.y = lamda * obj.y;
     86     return t;
     87   }
     88   friend FXT_PSV operator/(const FXT_PSV& obj, baseType lamda) {
     89     CFX_PSVTemplate t;
     90     t.x = obj.x / lamda;
     91     t.y = obj.y / lamda;
     92     return t;
     93   }
     94   baseType x, y;
     95 };
     96 typedef CFX_PSVTemplate<int32_t> CFX_Point;
     97 typedef CFX_PSVTemplate<FX_FLOAT> CFX_PointF;
     98 typedef CFX_PSVTemplate<int32_t> CFX_Size;
     99 typedef CFX_PSVTemplate<FX_FLOAT> CFX_SizeF;
    100 typedef CFX_ArrayTemplate<CFX_Point> CFX_Points;
    101 typedef CFX_ArrayTemplate<CFX_PointF> CFX_PointsF;
    102 typedef CFX_PSVTemplate<int32_t>* FX_LPPOINT;
    103 typedef CFX_PSVTemplate<FX_FLOAT>* FX_LPPOINTF;
    104 typedef CFX_PSVTemplate<int32_t> const* FX_LPCPOINT;
    105 typedef CFX_PSVTemplate<FX_FLOAT> const* FX_LPCPOINTF;
    106 #define CFX_FloatPoint CFX_PointF
    107 template <class baseType>
    108 class CFX_VTemplate : public CFX_PSVTemplate<baseType> {
    109  public:
    110   typedef CFX_PSVTemplate<baseType> FXT_PSV;
    111   typedef CFX_PSVTemplate<baseType> FXT_POINT;
    112   typedef CFX_PSVTemplate<baseType> FXT_SIZE;
    113   typedef CFX_VTemplate<baseType> FXT_VECTOR;
    114   void Set(baseType newx, baseType newy) {
    115     FXT_PSV::x = newx;
    116     FXT_PSV::y = newy;
    117   }
    118   void Set(const FXT_PSV& psv) { FXT_PSV::x = psv.x, FXT_PSV::y = psv.y; }
    119   void Set(const FXT_POINT& p1, const FXT_POINT& p2) {
    120     FXT_PSV::x = p2.x - p1.x, FXT_PSV::y = p2.y - p1.y;
    121   }
    122   void Reset() { FXT_PSV::x = FXT_PSV::y = 0; }
    123   baseType SquareLength() const {
    124     return FXT_PSV::x * FXT_PSV::x + FXT_PSV::y * FXT_PSV::y;
    125   }
    126   baseType Length() const {
    127     return FXSYS_sqrt(FXT_PSV::x * FXT_PSV::x + FXT_PSV::y * FXT_PSV::y);
    128   }
    129   void Normalize() {
    130     FX_FLOAT fLen =
    131         FXSYS_sqrt(FXT_PSV::x * FXT_PSV::x + FXT_PSV::y * FXT_PSV::y);
    132     if (fLen < 0.0001f) {
    133       return;
    134     }
    135     FXT_PSV::x = ((baseType)FXT_PSV::x) / fLen;
    136     FXT_PSV::y = ((baseType)FXT_PSV::y) / fLen;
    137   }
    138   baseType DotProduct(baseType otherx, baseType othery) const {
    139     return FXT_PSV::x * otherx + FXT_PSV::y * othery;
    140   }
    141   baseType DotProduct(const FXT_VECTOR& v) const {
    142     return FXT_PSV::x * v.x + FXT_PSV::y * v.y;
    143   }
    144   FX_BOOL IsParallel(baseType otherx, baseType othery) const {
    145     baseType t = FXT_PSV::x * othery - FXT_PSV::y * otherx;
    146     return FXSYS_fabs(t) < 0x0001f;
    147   }
    148   FX_BOOL IsParallel(const FXT_VECTOR& v) const { return IsParallel(v.x, v.y); }
    149   FX_BOOL IsPerpendicular(baseType otherx, baseType othery) const {
    150     baseType t = DotProduct(otherx, othery);
    151     return FXSYS_fabs(t) < 0x0001f;
    152   }
    153   FX_BOOL IsPerpendicular(const FXT_VECTOR& v) const {
    154     return IsPerpendicular(v.x, v.y);
    155   }
    156   void Translate(baseType dx, baseType dy) {
    157     FXT_PSV::x += dx, FXT_PSV::y += dy;
    158   }
    159   void Scale(baseType sx, baseType sy) { FXT_PSV::x *= sx, FXT_PSV::y *= sy; }
    160   void Rotate(FX_FLOAT fRadian) {
    161     FX_FLOAT xx = (FX_FLOAT)FXT_PSV::x;
    162     FX_FLOAT yy = (FX_FLOAT)FXT_PSV::y;
    163     FX_FLOAT cosValue = FXSYS_cos(fRadian);
    164     FX_FLOAT sinValue = FXSYS_sin(fRadian);
    165     FXT_PSV::x = xx * cosValue - yy * sinValue;
    166     FXT_PSV::y = xx * sinValue + yy * cosValue;
    167   }
    168   friend FX_FLOAT Cosine(const FXT_VECTOR& v1, const FXT_VECTOR& v2) {
    169     FXSYS_assert(v1.SquareLength() != 0 && v2.SquareLength() != 0);
    170     FX_FLOAT dotProduct = v1.DotProduct(v2);
    171     return dotProduct /
    172            (FX_FLOAT)FXSYS_sqrt(v1.SquareLength() * v2.SquareLength());
    173   }
    174   friend FX_FLOAT ArcCosine(const FXT_VECTOR& v1, const FXT_VECTOR& v2) {
    175     return (FX_FLOAT)FXSYS_acos(Cosine(v1, v2));
    176   }
    177   friend FX_FLOAT SlopeAngle(const FXT_VECTOR& v) {
    178     CFX_VTemplate vx;
    179     vx.Set(1, 0);
    180     FX_FLOAT fSlope = ArcCosine(v, vx);
    181     return v.y < 0 ? -fSlope : fSlope;
    182   }
    183 };
    184 typedef CFX_VTemplate<int32_t> CFX_Vector;
    185 typedef CFX_VTemplate<FX_FLOAT> CFX_VectorF;
    186 template <class baseType>
    187 class CFX_RTemplate {
    188  public:
    189   typedef CFX_PSVTemplate<baseType> FXT_POINT;
    190   typedef CFX_PSVTemplate<baseType> FXT_SIZE;
    191   typedef CFX_VTemplate<baseType> FXT_VECTOR;
    192   typedef CFX_PRLTemplate<baseType> FXT_PARAL;
    193   typedef CFX_RTemplate<baseType> FXT_RECT;
    194   void Set(baseType left, baseType top, baseType width, baseType height) {
    195     FXT_RECT::left = left, FXT_RECT::top = top, FXT_RECT::width = width,
    196     FXT_RECT::height = height;
    197   }
    198   void Set(baseType left, baseType top, const FXT_SIZE& size) {
    199     FXT_RECT::left = left, FXT_RECT::top = top, FXT_RECT::Size(size);
    200   }
    201   void Set(const FXT_POINT& p, baseType width, baseType height) {
    202     TopLeft(p), FXT_RECT::width = width, FXT_RECT::height = height;
    203   }
    204   void Set(const FXT_POINT& p1, const FXT_POINT& p2) {
    205     TopLeft(p1), FXT_RECT::width = p2.x - p1.x, FXT_RECT::height = p2.y - p1.y,
    206                  FXT_RECT::Normalize();
    207   }
    208   void Set(const FXT_POINT& p, const FXT_VECTOR& v) {
    209     TopLeft(p), FXT_RECT::width = v.x, FXT_RECT::height = v.y,
    210                 FXT_RECT::Normalize();
    211   }
    212   void Reset() {
    213     FXT_RECT::left = FXT_RECT::top = FXT_RECT::width = FXT_RECT::height = 0;
    214   }
    215   FXT_RECT& operator+=(const FXT_POINT& p) {
    216     left += p.x, top += p.y;
    217     return *this;
    218   }
    219   FXT_RECT& operator-=(const FXT_POINT& p) {
    220     left -= p.x, top -= p.y;
    221     return *this;
    222   }
    223   baseType right() const { return left + width; }
    224   baseType bottom() const { return top + height; }
    225   void Normalize() {
    226     if (width < 0) {
    227       left += width;
    228       width = -width;
    229     }
    230     if (height < 0) {
    231       top += height;
    232       height = -height;
    233     }
    234   }
    235   void Offset(baseType dx, baseType dy) {
    236     left += dx;
    237     top += dy;
    238   }
    239   void Inflate(baseType x, baseType y) {
    240     left -= x;
    241     width += x * 2;
    242     top -= y;
    243     height += y * 2;
    244   }
    245   void Inflate(const FXT_POINT& p) { Inflate(p.x, p.y); }
    246   void Inflate(baseType left, baseType top, baseType right, baseType bottom) {
    247     FXT_RECT::left -= left;
    248     FXT_RECT::top -= top;
    249     FXT_RECT::width += left + right;
    250     FXT_RECT::height += top + bottom;
    251   }
    252   void Inflate(const FXT_RECT& rt) {
    253     Inflate(rt.left, rt.top, rt.left + rt.width, rt.top + rt.height);
    254   }
    255   void Deflate(baseType x, baseType y) {
    256     left += x;
    257     width -= x * 2;
    258     top += y;
    259     height -= y * 2;
    260   }
    261   void Deflate(const FXT_POINT& p) { Deflate(p.x, p.y); }
    262   void Deflate(baseType left, baseType top, baseType right, baseType bottom) {
    263     FXT_RECT::left += left;
    264     FXT_RECT::top += top;
    265     FXT_RECT::width -= left + right;
    266     FXT_RECT::height -= top + bottom;
    267   }
    268   void Deflate(const FXT_RECT& rt) {
    269     Deflate(rt.left, rt.top, rt.top + rt.width, rt.top + rt.height);
    270   }
    271   FX_BOOL IsEmpty() const { return width <= 0 || height <= 0; }
    272   FX_BOOL IsEmpty(FX_FLOAT fEpsilon) const {
    273     return width <= fEpsilon || height <= fEpsilon;
    274   }
    275   void Empty() { width = height = 0; }
    276   FX_BOOL Contains(baseType x, baseType y) const {
    277     return x >= left && x < left + width && y >= top && y < top + height;
    278   }
    279   FX_BOOL Contains(const FXT_POINT& p) const { return Contains(p.x, p.y); }
    280   FX_BOOL Contains(const FXT_RECT& rt) const {
    281     return rt.left >= left && rt.right() <= right() && rt.top >= top &&
    282            rt.bottom() <= bottom();
    283   }
    284   baseType Width() const { return width; }
    285   baseType Height() const { return height; }
    286   FXT_SIZE Size() const {
    287     FXT_SIZE size;
    288     size.Set(width, height);
    289     return size;
    290   }
    291   void Size(FXT_SIZE s) { width = s.x, height = s.y; }
    292   FXT_POINT TopLeft() const {
    293     FXT_POINT p;
    294     p.x = left;
    295     p.y = top;
    296     return p;
    297   }
    298   FXT_POINT TopRight() const {
    299     FXT_POINT p;
    300     p.x = left + width;
    301     p.y = top;
    302     return p;
    303   }
    304   FXT_POINT BottomLeft() const {
    305     FXT_POINT p;
    306     p.x = left;
    307     p.y = top + height;
    308     return p;
    309   }
    310   FXT_POINT BottomRight() const {
    311     FXT_POINT p;
    312     p.x = left + width;
    313     p.y = top + height;
    314     return p;
    315   }
    316   void TopLeft(FXT_POINT tl) {
    317     left = tl.x;
    318     top = tl.y;
    319   }
    320   void TopRight(FXT_POINT tr) {
    321     width = tr.x - left;
    322     top = tr.y;
    323   }
    324   void BottomLeft(FXT_POINT bl) {
    325     left = bl.x;
    326     height = bl.y - top;
    327   }
    328   void BottomRight(FXT_POINT br) {
    329     width = br.x - left;
    330     height = br.y - top;
    331   }
    332   FXT_POINT Center() const {
    333     FXT_POINT p;
    334     p.x = left + width / 2;
    335     p.y = top + height / 2;
    336     return p;
    337   }
    338   void GetParallelogram(FXT_PARAL& pg) const {
    339     pg.x = left, pg.y = top;
    340     pg.x1 = width, pg.y1 = 0;
    341     pg.x2 = 0, pg.y2 = height;
    342   }
    343   void Union(baseType x, baseType y) {
    344     baseType r = right(), b = bottom();
    345     if (left > x) {
    346       left = x;
    347     }
    348     if (r < x) {
    349       r = x;
    350     }
    351     if (top > y) {
    352       top = y;
    353     }
    354     if (b < y) {
    355       b = y;
    356     }
    357     width = r - left;
    358     height = b - top;
    359   }
    360   void Union(const FXT_POINT& p) { Union(p.x, p.y); }
    361   void Union(const FXT_RECT& rt) {
    362     baseType r = right(), b = bottom();
    363     if (left > rt.left) {
    364       left = rt.left;
    365     }
    366     if (r < rt.right()) {
    367       r = rt.right();
    368     }
    369     if (top > rt.top) {
    370       top = rt.top;
    371     }
    372     if (b < rt.bottom()) {
    373       b = rt.bottom();
    374     }
    375     width = r - left;
    376     height = b - top;
    377   }
    378   void Intersect(const FXT_RECT& rt) {
    379     baseType r = right(), b = bottom();
    380     if (left < rt.left) {
    381       left = rt.left;
    382     }
    383     if (r > rt.right()) {
    384       r = rt.right();
    385     }
    386     if (top < rt.top) {
    387       top = rt.top;
    388     }
    389     if (b > rt.bottom()) {
    390       b = rt.bottom();
    391     }
    392     width = r - left;
    393     height = b - top;
    394   }
    395   FX_BOOL IntersectWith(const FXT_RECT& rt) const {
    396     FXT_RECT rect = rt;
    397     rect.Intersect(*this);
    398     return !rect.IsEmpty();
    399   }
    400   FX_BOOL IntersectWith(const FXT_RECT& rt, FX_FLOAT fEpsilon) const {
    401     FXT_RECT rect = rt;
    402     rect.Intersect(*this);
    403     return !rect.IsEmpty(fEpsilon);
    404   }
    405   friend FX_BOOL operator==(const FXT_RECT& rc1, const FXT_RECT& rc2) {
    406     return rc1.left == rc2.left && rc1.top == rc2.top &&
    407            rc1.width == rc2.width && rc1.height == rc2.height;
    408   }
    409   friend FX_BOOL operator!=(const FXT_RECT& rc1, const FXT_RECT& rc2) {
    410     return rc1.left != rc2.left || rc1.top != rc2.top ||
    411            rc1.width != rc2.width || rc1.height != rc2.height;
    412   }
    413   baseType left, top;
    414   baseType width, height;
    415 };
    416 typedef CFX_RTemplate<int32_t> CFX_Rect;
    417 typedef CFX_RTemplate<FX_FLOAT> CFX_RectF;
    418 typedef CFX_RTemplate<int32_t>* FX_LPRECT;
    419 typedef CFX_RTemplate<FX_FLOAT>* FX_LPRECTF;
    420 typedef CFX_RTemplate<int32_t> const* FX_LPCRECT;
    421 typedef CFX_RTemplate<FX_FLOAT> const* FX_LPCRECTF;
    422 typedef CFX_ArrayTemplate<CFX_RectF> CFX_RectFArray;
    423 struct FX_RECT {
    424   int left;
    425 
    426   int top;
    427 
    428   int right;
    429 
    430   int bottom;
    431 
    432   FX_RECT() : left(0), top(0), right(0), bottom(0) {}
    433 
    434   FX_RECT(int left1, int top1, int right1, int bottom1) {
    435     left = left1;
    436     top = top1;
    437     right = right1;
    438     bottom = bottom1;
    439   }
    440 
    441   int Width() const { return right - left; }
    442 
    443   int Height() const { return bottom - top; }
    444 
    445   FX_BOOL IsEmpty() const { return right <= left || bottom <= top; }
    446 
    447   void Normalize();
    448 
    449   void Intersect(const FX_RECT& src);
    450 
    451   void Intersect(int left1, int top1, int right1, int bottom1) {
    452     Intersect(FX_RECT(left1, top1, right1, bottom1));
    453   }
    454 
    455   void Union(const FX_RECT& other_rect);
    456 
    457   FX_BOOL operator==(const FX_RECT& src) const {
    458     return left == src.left && right == src.right && top == src.top &&
    459            bottom == src.bottom;
    460   }
    461 
    462   void Offset(int dx, int dy) {
    463     left += dx;
    464     right += dx;
    465     top += dy;
    466     bottom += dy;
    467   }
    468 
    469   FX_BOOL Contains(const FX_RECT& other_rect) const {
    470     return other_rect.left >= left && other_rect.right <= right &&
    471            other_rect.top >= top && other_rect.bottom <= bottom;
    472   }
    473 
    474   FX_BOOL Contains(int x, int y) const {
    475     return x >= left && x < right && y >= top && y < bottom;
    476   }
    477 };
    478 struct FX_SMALL_RECT {
    479   int16_t Left;
    480 
    481   int16_t Top;
    482 
    483   int16_t Right;
    484 
    485   int16_t Bottom;
    486 };
    487 class CFX_FloatRect {
    488  public:
    489   CFX_FloatRect() { left = right = bottom = top = 0; }
    490 
    491   CFX_FloatRect(FX_FLOAT left1,
    492                 FX_FLOAT bottom1,
    493                 FX_FLOAT right1,
    494                 FX_FLOAT top1) {
    495     left = left1;
    496     bottom = bottom1;
    497     right = right1;
    498     top = top1;
    499   }
    500 
    501   CFX_FloatRect(const FX_FLOAT* pArray) {
    502     left = pArray[0];
    503     bottom = pArray[1];
    504     right = pArray[2];
    505     top = pArray[3];
    506   }
    507 
    508   CFX_FloatRect(const FX_RECT& rect);
    509 
    510   FX_BOOL IsEmpty() const { return left >= right || bottom >= top; }
    511 
    512   void Normalize();
    513 
    514   void Reset() { left = right = bottom = top = 0; }
    515 
    516   FX_BOOL Contains(const CFX_FloatRect& other_rect) const;
    517 
    518   FX_BOOL Contains(FX_FLOAT x, FX_FLOAT y) const;
    519 
    520   void Transform(const CFX_Matrix* pMatrix);
    521 
    522   void Intersect(const CFX_FloatRect& other_rect);
    523 
    524   void Union(const CFX_FloatRect& other_rect);
    525 
    526   FX_RECT GetInnerRect() const;
    527 
    528   FX_RECT GetOutterRect() const;
    529 
    530   FX_RECT GetClosestRect() const;
    531 
    532   int Substract4(CFX_FloatRect& substract_rect, CFX_FloatRect* pRects);
    533 
    534   void InitRect(FX_FLOAT x, FX_FLOAT y) {
    535     left = right = x;
    536     bottom = top = y;
    537   }
    538 
    539   void UpdateRect(FX_FLOAT x, FX_FLOAT y);
    540 
    541   FX_FLOAT Width() const { return right - left; }
    542 
    543   FX_FLOAT Height() const { return top - bottom; }
    544 
    545   void Inflate(FX_FLOAT x, FX_FLOAT y) {
    546     Normalize();
    547     left -= x;
    548     right += x;
    549     bottom -= y;
    550     top += y;
    551   }
    552 
    553   void Inflate(FX_FLOAT other_left,
    554                FX_FLOAT other_bottom,
    555                FX_FLOAT other_right,
    556                FX_FLOAT other_top) {
    557     Normalize();
    558     left -= other_left;
    559     bottom -= other_bottom;
    560     right += other_right;
    561     top += other_top;
    562   }
    563 
    564   void Inflate(const CFX_FloatRect& rt) {
    565     Inflate(rt.left, rt.bottom, rt.right, rt.top);
    566   }
    567 
    568   void Deflate(FX_FLOAT x, FX_FLOAT y) {
    569     Normalize();
    570     left += x;
    571     right -= x;
    572     bottom += y;
    573     top -= y;
    574   }
    575 
    576   void Deflate(FX_FLOAT other_left,
    577                FX_FLOAT other_bottom,
    578                FX_FLOAT other_right,
    579                FX_FLOAT other_top) {
    580     Normalize();
    581     left += other_left;
    582     bottom += other_bottom;
    583     right -= other_right;
    584     top -= other_top;
    585   }
    586 
    587   void Deflate(const CFX_FloatRect& rt) {
    588     Deflate(rt.left, rt.bottom, rt.right, rt.top);
    589   }
    590 
    591   void Translate(FX_FLOAT e, FX_FLOAT f) {
    592     left += e;
    593     right += e;
    594     top += f;
    595     bottom += f;
    596   }
    597 
    598   static CFX_FloatRect GetBBox(const CFX_FloatPoint* pPoints, int nPoints);
    599 
    600   FX_FLOAT left;
    601 
    602   FX_FLOAT right;
    603 
    604   FX_FLOAT bottom;
    605 
    606   FX_FLOAT top;
    607 };
    608 class CFX_Matrix {
    609  public:
    610   CFX_Matrix() { SetIdentity(); }
    611 
    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 
    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 
    651   void Copy(const CFX_Matrix& m) { *this = m; }
    652 
    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 
    704   void Transform(FX_FLOAT& x, FX_FLOAT& y) const { TransformPoint(x, y); }
    705 
    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 
    720   void TransformRect(CFX_FloatRect& rect) const {
    721     TransformRect(rect.left, rect.right, rect.top, rect.bottom);
    722   }
    723 
    724   FX_FLOAT GetA() const { return a; }
    725 
    726   FX_FLOAT GetB() const { return b; }
    727 
    728   FX_FLOAT GetC() const { return c; }
    729 
    730   FX_FLOAT GetD() const { return d; }
    731 
    732   FX_FLOAT GetE() const { return e; }
    733 
    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