Home | History | Annotate | Download | only in fxcrt
      1 // Copyright 2017 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 #include "core/fxcrt/fx_coordinates.h"
      6 
      7 #include <vector>
      8 
      9 #include "testing/gtest/include/gtest/gtest.h"
     10 
     11 TEST(CFX_FloatRect, GetBBox) {
     12   CFX_FloatRect rect = CFX_FloatRect::GetBBox(nullptr, 0);
     13   EXPECT_FLOAT_EQ(0.0f, rect.left);
     14   EXPECT_FLOAT_EQ(0.0f, rect.bottom);
     15   EXPECT_FLOAT_EQ(0.0f, rect.right);
     16   EXPECT_FLOAT_EQ(0.0f, rect.top);
     17 
     18   std::vector<CFX_PointF> data;
     19   data.emplace_back(0.0f, 0.0f);
     20   rect = CFX_FloatRect::GetBBox(data.data(), 0);
     21   EXPECT_FLOAT_EQ(0.0f, rect.left);
     22   EXPECT_FLOAT_EQ(0.0f, rect.bottom);
     23   EXPECT_FLOAT_EQ(0.0f, rect.right);
     24   EXPECT_FLOAT_EQ(0.0f, rect.top);
     25   rect = CFX_FloatRect::GetBBox(data.data(), data.size());
     26   EXPECT_FLOAT_EQ(0.0f, rect.left);
     27   EXPECT_FLOAT_EQ(0.0f, rect.bottom);
     28   EXPECT_FLOAT_EQ(0.0f, rect.right);
     29   EXPECT_FLOAT_EQ(0.0f, rect.top);
     30 
     31   data.emplace_back(2.5f, 6.2f);
     32   data.emplace_back(1.5f, 6.2f);
     33   rect = CFX_FloatRect::GetBBox(data.data(), 2);
     34   EXPECT_FLOAT_EQ(0.0f, rect.left);
     35   EXPECT_FLOAT_EQ(0.0f, rect.bottom);
     36   EXPECT_FLOAT_EQ(2.5f, rect.right);
     37   EXPECT_FLOAT_EQ(6.2f, rect.top);
     38 
     39   rect = CFX_FloatRect::GetBBox(data.data(), data.size());
     40   EXPECT_FLOAT_EQ(0.0f, rect.left);
     41   EXPECT_FLOAT_EQ(0.0f, rect.bottom);
     42   EXPECT_FLOAT_EQ(2.5f, rect.right);
     43   EXPECT_FLOAT_EQ(6.2f, rect.top);
     44 
     45   data.emplace_back(2.5f, 6.3f);
     46   rect = CFX_FloatRect::GetBBox(data.data(), data.size());
     47   EXPECT_FLOAT_EQ(0.0f, rect.left);
     48   EXPECT_FLOAT_EQ(0.0f, rect.bottom);
     49   EXPECT_FLOAT_EQ(2.5f, rect.right);
     50   EXPECT_FLOAT_EQ(6.3f, rect.top);
     51 
     52   data.emplace_back(-3.0f, 6.3f);
     53   rect = CFX_FloatRect::GetBBox(data.data(), data.size());
     54   EXPECT_FLOAT_EQ(-3.0f, rect.left);
     55   EXPECT_FLOAT_EQ(0.0f, rect.bottom);
     56   EXPECT_FLOAT_EQ(2.5f, rect.right);
     57   EXPECT_FLOAT_EQ(6.3f, rect.top);
     58 
     59   data.emplace_back(4.0f, -8.0f);
     60   rect = CFX_FloatRect::GetBBox(data.data(), data.size());
     61   EXPECT_FLOAT_EQ(-3.0f, rect.left);
     62   EXPECT_FLOAT_EQ(-8.0f, rect.bottom);
     63   EXPECT_FLOAT_EQ(4.0f, rect.right);
     64   EXPECT_FLOAT_EQ(6.3f, rect.top);
     65 }
     66 
     67 TEST(CFX_FloatRect, Normalize) {
     68   CFX_FloatRect rect;
     69   rect.Normalize();
     70   EXPECT_FLOAT_EQ(0.0f, rect.left);
     71   EXPECT_FLOAT_EQ(0.0f, rect.bottom);
     72   EXPECT_FLOAT_EQ(0.0f, rect.right);
     73   EXPECT_FLOAT_EQ(0.0f, rect.top);
     74 
     75   rect = CFX_FloatRect(-1.0f, -3.0f, 4.5f, 3.2f);
     76   rect.Normalize();
     77   EXPECT_FLOAT_EQ(-1.0f, rect.left);
     78   EXPECT_FLOAT_EQ(-3.0f, rect.bottom);
     79   EXPECT_FLOAT_EQ(4.5f, rect.right);
     80   EXPECT_FLOAT_EQ(3.2f, rect.top);
     81   rect.Scale(-1.0f);
     82   rect.Normalize();
     83   EXPECT_FLOAT_EQ(-4.5f, rect.left);
     84   EXPECT_FLOAT_EQ(-3.2f, rect.bottom);
     85   EXPECT_FLOAT_EQ(1.0f, rect.right);
     86   EXPECT_FLOAT_EQ(3.0f, rect.top);
     87 }
     88 
     89 TEST(CFX_FloatRect, Scale) {
     90   CFX_FloatRect rect(-1.0f, -3.0f, 4.5f, 3.2f);
     91   rect.Scale(1.0f);
     92   EXPECT_FLOAT_EQ(-1.0f, rect.left);
     93   EXPECT_FLOAT_EQ(-3.0f, rect.bottom);
     94   EXPECT_FLOAT_EQ(4.5f, rect.right);
     95   EXPECT_FLOAT_EQ(3.2f, rect.top);
     96   rect.Scale(0.5f);
     97   EXPECT_FLOAT_EQ(-0.5, rect.left);
     98   EXPECT_FLOAT_EQ(-1.5, rect.bottom);
     99   EXPECT_FLOAT_EQ(2.25f, rect.right);
    100   EXPECT_FLOAT_EQ(1.6f, rect.top);
    101   rect.Scale(2.0f);
    102   EXPECT_FLOAT_EQ(-1.0f, rect.left);
    103   EXPECT_FLOAT_EQ(-3.0f, rect.bottom);
    104   EXPECT_FLOAT_EQ(4.5f, rect.right);
    105   EXPECT_FLOAT_EQ(3.2f, rect.top);
    106   rect.Scale(-1.0f);
    107   EXPECT_FLOAT_EQ(1.0f, rect.left);
    108   EXPECT_FLOAT_EQ(3.0f, rect.bottom);
    109   EXPECT_FLOAT_EQ(-4.5f, rect.right);
    110   EXPECT_FLOAT_EQ(-3.2f, rect.top);
    111   rect.Scale(0.0f);
    112   EXPECT_FLOAT_EQ(0.0f, rect.left);
    113   EXPECT_FLOAT_EQ(0.0f, rect.bottom);
    114   EXPECT_FLOAT_EQ(0.0f, rect.right);
    115   EXPECT_FLOAT_EQ(0.0f, rect.top);
    116 }
    117 
    118 TEST(CFX_FloatRect, ScaleEmpty) {
    119   CFX_FloatRect rect;
    120   rect.Scale(1.0f);
    121   EXPECT_FLOAT_EQ(0.0f, rect.left);
    122   EXPECT_FLOAT_EQ(0.0f, rect.bottom);
    123   EXPECT_FLOAT_EQ(0.0f, rect.right);
    124   EXPECT_FLOAT_EQ(0.0f, rect.top);
    125   rect.Scale(0.5f);
    126   EXPECT_FLOAT_EQ(0.0f, rect.left);
    127   EXPECT_FLOAT_EQ(0.0f, rect.bottom);
    128   EXPECT_FLOAT_EQ(0.0f, rect.right);
    129   EXPECT_FLOAT_EQ(0.0f, rect.top);
    130   rect.Scale(2.0f);
    131   EXPECT_FLOAT_EQ(0.0f, rect.left);
    132   EXPECT_FLOAT_EQ(0.0f, rect.bottom);
    133   EXPECT_FLOAT_EQ(0.0f, rect.right);
    134   EXPECT_FLOAT_EQ(0.0f, rect.top);
    135   rect.Scale(0.0f);
    136   EXPECT_FLOAT_EQ(0.0f, rect.left);
    137   EXPECT_FLOAT_EQ(0.0f, rect.bottom);
    138   EXPECT_FLOAT_EQ(0.0f, rect.right);
    139   EXPECT_FLOAT_EQ(0.0f, rect.top);
    140 }
    141 
    142 TEST(CFX_FloatRect, ScaleFromCenterPoint) {
    143   CFX_FloatRect rect(-1.0f, -3.0f, 4.5f, 3.2f);
    144   rect.ScaleFromCenterPoint(1.0f);
    145   EXPECT_FLOAT_EQ(-1.0f, rect.left);
    146   EXPECT_FLOAT_EQ(-3.0f, rect.bottom);
    147   EXPECT_FLOAT_EQ(4.5f, rect.right);
    148   EXPECT_FLOAT_EQ(3.2f, rect.top);
    149   rect.ScaleFromCenterPoint(0.5f);
    150   EXPECT_FLOAT_EQ(0.375f, rect.left);
    151   EXPECT_FLOAT_EQ(-1.45f, rect.bottom);
    152   EXPECT_FLOAT_EQ(3.125f, rect.right);
    153   EXPECT_FLOAT_EQ(1.65f, rect.top);
    154   rect.ScaleFromCenterPoint(2.0f);
    155   EXPECT_FLOAT_EQ(-1.0f, rect.left);
    156   EXPECT_FLOAT_EQ(-3.0f, rect.bottom);
    157   EXPECT_FLOAT_EQ(4.5f, rect.right);
    158   EXPECT_FLOAT_EQ(3.2f, rect.top);
    159   rect.ScaleFromCenterPoint(-1.0f);
    160   EXPECT_FLOAT_EQ(4.5f, rect.left);
    161   EXPECT_FLOAT_EQ(3.2f, rect.bottom);
    162   EXPECT_FLOAT_EQ(-1.0f, rect.right);
    163   EXPECT_FLOAT_EQ(-3.0f, rect.top);
    164   rect.ScaleFromCenterPoint(0.0f);
    165   EXPECT_FLOAT_EQ(1.75f, rect.left);
    166   EXPECT_NEAR(0.1f, rect.bottom, 0.001f);
    167   EXPECT_FLOAT_EQ(1.75f, rect.right);
    168   EXPECT_NEAR(0.1f, rect.top, 0.001f);
    169 }
    170 
    171 TEST(CFX_FloatRect, ScaleFromCenterPointEmpty) {
    172   CFX_FloatRect rect;
    173   rect.ScaleFromCenterPoint(1.0f);
    174   EXPECT_FLOAT_EQ(0.0f, rect.left);
    175   EXPECT_FLOAT_EQ(0.0f, rect.bottom);
    176   EXPECT_FLOAT_EQ(0.0f, rect.right);
    177   EXPECT_FLOAT_EQ(0.0f, rect.top);
    178   rect.ScaleFromCenterPoint(0.5f);
    179   EXPECT_FLOAT_EQ(0.0f, rect.left);
    180   EXPECT_FLOAT_EQ(0.0f, rect.bottom);
    181   EXPECT_FLOAT_EQ(0.0f, rect.right);
    182   EXPECT_FLOAT_EQ(0.0f, rect.top);
    183   rect.ScaleFromCenterPoint(2.0f);
    184   EXPECT_FLOAT_EQ(0.0f, rect.left);
    185   EXPECT_FLOAT_EQ(0.0f, rect.bottom);
    186   EXPECT_FLOAT_EQ(0.0f, rect.right);
    187   EXPECT_FLOAT_EQ(0.0f, rect.top);
    188   rect.ScaleFromCenterPoint(0.0f);
    189   EXPECT_FLOAT_EQ(0.0f, rect.left);
    190   EXPECT_FLOAT_EQ(0.0f, rect.bottom);
    191   EXPECT_FLOAT_EQ(0.0f, rect.right);
    192   EXPECT_FLOAT_EQ(0.0f, rect.top);
    193 }
    194 
    195 #ifndef NDEBUG
    196 TEST(CFX_FloatRect, Print) {
    197   std::ostringstream os;
    198   CFX_FloatRect rect;
    199   os << rect;
    200   EXPECT_STREQ("rect[0x0 (0, 0)]", os.str().c_str());
    201 
    202   os.str("");
    203   rect = CFX_FloatRect(10, 20, 14, 23);
    204   os << rect;
    205   EXPECT_STREQ("rect[4x3 (10, 20)]", os.str().c_str());
    206 
    207   os.str("");
    208   rect = CFX_FloatRect(10.5, 20.5, 14.75, 23.75);
    209   os << rect;
    210   EXPECT_STREQ("rect[4.25x3.25 (10.5, 20.5)]", os.str().c_str());
    211 }
    212 #endif
    213 
    214 TEST(CFX_Matrix, ReverseIdentity) {
    215   CFX_Matrix m;
    216   m.SetIdentity();
    217   CFX_Matrix rev = m.GetInverse();
    218 
    219   EXPECT_FLOAT_EQ(1.0, rev.a);
    220   EXPECT_FLOAT_EQ(0.0, rev.b);
    221   EXPECT_FLOAT_EQ(0.0, rev.c);
    222   EXPECT_FLOAT_EQ(1.0, rev.d);
    223   EXPECT_FLOAT_EQ(0.0, rev.e);
    224   EXPECT_FLOAT_EQ(0.0, rev.f);
    225 
    226   CFX_PointF expected(2, 3);
    227   CFX_PointF result = rev.Transform(m.Transform(CFX_PointF(2, 3)));
    228   EXPECT_FLOAT_EQ(expected.x, result.x);
    229   EXPECT_FLOAT_EQ(expected.y, result.y);
    230 }
    231 
    232 TEST(CFX_Matrix, Reverse) {
    233   static constexpr float data[6] = {3, 0, 2, 3, 1, 4};
    234   CFX_Matrix m(data);
    235   CFX_Matrix rev = m.GetInverse();
    236 
    237   EXPECT_FLOAT_EQ(0.33333334f, rev.a);
    238   EXPECT_FLOAT_EQ(0.0f, rev.b);
    239   EXPECT_FLOAT_EQ(-0.22222222f, rev.c);
    240   EXPECT_FLOAT_EQ(0.33333334f, rev.d);
    241   EXPECT_FLOAT_EQ(0.55555556f, rev.e);
    242   EXPECT_FLOAT_EQ(-1.3333334f, rev.f);
    243 
    244   CFX_PointF expected(2, 3);
    245   CFX_PointF result = rev.Transform(m.Transform(CFX_PointF(2, 3)));
    246   EXPECT_FLOAT_EQ(expected.x, result.x);
    247   EXPECT_FLOAT_EQ(expected.y, result.y);
    248 }
    249 
    250 // Note, I think these are a bug and the matrix should be the identity.
    251 TEST(CFX_Matrix, ReverseCR702041) {
    252   // The determinate is < std::numeric_limits<float>::epsilon()
    253   static constexpr float data[6] = {0.947368443f, -0.108947366f, -0.923076928f,
    254                                     0.106153846f, 18.0f,         787.929993f};
    255   CFX_Matrix m(data);
    256   CFX_Matrix rev = m.GetInverse();
    257 
    258   EXPECT_FLOAT_EQ(14247728.0f, rev.a);
    259   EXPECT_FLOAT_EQ(14622668.0f, rev.b);
    260   EXPECT_FLOAT_EQ(1.2389329e+08f, rev.c);
    261   EXPECT_FLOAT_EQ(1.2715364e+08f, rev.d);
    262   EXPECT_FLOAT_EQ(-9.7875698e+10f, rev.e);
    263   EXPECT_FLOAT_EQ(-1.0045138e+11f, rev.f);
    264 
    265   // Should be 2, 3
    266   CFX_PointF expected(0, 0);
    267   CFX_PointF result = rev.Transform(m.Transform(CFX_PointF(2, 3)));
    268   EXPECT_FLOAT_EQ(expected.x, result.x);
    269   EXPECT_FLOAT_EQ(expected.y, result.y);
    270 }
    271 
    272 TEST(CFX_Matrix, ReverseCR714187) {
    273   // The determinate is < std::numeric_limits<float>::epsilon()
    274   static constexpr float data[6] = {0.000037f,  0.0f,        0.0f,
    275                                     -0.000037f, 182.413101f, 136.977646f};
    276   CFX_Matrix m(data);
    277   CFX_Matrix rev = m.GetInverse();
    278 
    279   EXPECT_FLOAT_EQ(27027.025f, rev.a);
    280   EXPECT_FLOAT_EQ(0.0f, rev.b);
    281   EXPECT_FLOAT_EQ(0.0f, rev.c);
    282   EXPECT_FLOAT_EQ(-27027.025f, rev.d);
    283   EXPECT_FLOAT_EQ(-4930083.5f, rev.e);
    284   EXPECT_FLOAT_EQ(3702098.2f, rev.f);
    285 
    286   // Should be 3 ....
    287   CFX_PointF expected(2, 2.75);
    288   CFX_PointF result = rev.Transform(m.Transform(CFX_PointF(2, 3)));
    289   EXPECT_FLOAT_EQ(expected.x, result.x);
    290   EXPECT_FLOAT_EQ(expected.y, result.y);
    291 }
    292