1 // Copyright 2018 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/fpdfapi/page/cpdf_pageobjectholder.h"
6 
7 #include <limits>
8 
9 #include "testing/gtest/include/gtest/gtest.h"
10 
11 // See https://crbug.com/852273
TEST(CPDFPageObjectHolder,GraphicsDataAsKey)12 TEST(CPDFPageObjectHolder, GraphicsDataAsKey) {
13   const float fMin = std::numeric_limits<float>::min();
14   const float fMax = std::numeric_limits<float>::max();
15   const float fInf = std::numeric_limits<float>::infinity();
16   const float fNan = std::numeric_limits<float>::quiet_NaN();
17 
18   // Verify self-comparisions.
19   for (float c1 : {fMin, 1.0f, 2.0f, fMax, fInf, fNan}) {
20     for (float c2 : {fMin, 1.0f, 2.0f, fMax, fInf, fNan}) {
21       for (BlendMode c3 : {BlendMode::kMultiply, BlendMode::kScreen})
22         EXPECT_FALSE(GraphicsData({c1, c2, c3}) < GraphicsData({c1, c2, c3}));
23     }
24   }
25 
26   std::map<GraphicsData, int> graphics_map;
27 
28   // Insert in reverse index permuted order.
29   size_t x = 0;
30   for (BlendMode c3 : {BlendMode::kScreen, BlendMode::kMultiply}) {
31     for (float c2 : {fNan, fInf, fMax, 2.0f, 1.0f, fMin}) {
32       for (float c1 : {fNan, fInf, fMax, 2.0f, 1.0f, fMin}) {
33         graphics_map[{c1, c2, c3}] = x++;
34       }
35     }
36   }
37   EXPECT_EQ(72u, x);
38   EXPECT_EQ(72u, graphics_map.size());
39 
40   // clang-format off
41   const int expected[72] = {
42       71, 35, 65, 29, 59, 23, 53, 17, 47, 11, 41, 5,
43       70, 34, 64, 28, 58, 22, 52, 16, 46, 10, 40, 4,
44       69, 33, 63, 27, 57, 21, 51, 15, 45, 9,  39, 3,
45       68, 32, 62, 26, 56, 20, 50, 14, 44, 8,  38, 2,
46       67, 31, 61, 25, 55, 19, 49, 13, 43, 7,  37, 1,
47       66, 30, 60, 24, 54, 18, 48, 12, 42, 6,  36, 0
48   };
49   // clang-format on
50 
51   x = 0;
52   for (const auto& item : graphics_map) {
53     EXPECT_EQ(expected[x], item.second) << " for position " << x;
54     ++x;
55   }
56   EXPECT_EQ(72u, x);
57 
58   // Erase in forward index permuted order.
59   for (BlendMode c3 : {BlendMode::kMultiply, BlendMode::kScreen}) {
60     for (float c2 : {fMin, 1.0f, 2.0f, fMax, fInf, fNan}) {
61       for (float c1 : {fMin, 1.0f, 2.0f, fMax, fInf, fNan})
62         graphics_map.erase({c1, c2, c3});
63     }
64   }
65   EXPECT_EQ(0u, graphics_map.size());
66 }
67