Ensure CPDF_ColorSpace classes are only created via MakeRetain<>.

These are retainable, and it would be bad if somehow someone made
a retain pointer to a non heap-based object.

- Remove stale comment from cpdf_colorspace.h
- Re-organize a few methods in cpdf_colorspace.h, so that simple
  accessors come before pure virtuals come before virtuals etc.

Change-Id: I2afc644c7a7e8e407ec3df28d87d5b1a933dae9a
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/56731
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fpdfapi/page/cpdf_colorspace.cpp b/core/fpdfapi/page/cpdf_colorspace.cpp
index 20adc6a..338025f 100644
--- a/core/fpdfapi/page/cpdf_colorspace.cpp
+++ b/core/fpdfapi/page/cpdf_colorspace.cpp
@@ -107,14 +107,16 @@
 
 class CPDF_CalGray final : public CPDF_ColorSpace {
  public:
-  explicit CPDF_CalGray(CPDF_Document* pDoc);
-  ~CPDF_CalGray() override {}
+  template <typename T, typename... Args>
+  friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
+  ~CPDF_CalGray() override;
 
   // CPDF_ColorSpace:
+  bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
   uint32_t v_Load(CPDF_Document* pDoc,
                   const CPDF_Array* pArray,
                   std::set<const CPDF_Object*>* pVisited) override;
-  bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
   void TranslateImageLine(uint8_t* pDestBuf,
                           const uint8_t* pSrcBuf,
                           int pixels,
@@ -125,6 +127,8 @@
  private:
   static constexpr float kDefaultGamma = 1.0f;
 
+  explicit CPDF_CalGray(CPDF_Document* pDoc);
+
   float m_Gamma = kDefaultGamma;
   float m_WhitePoint[kBlackWhitePointCount];
   float m_BlackPoint[kBlackWhitePointCount];
@@ -132,26 +136,29 @@
 
 class CPDF_CalRGB final : public CPDF_ColorSpace {
  public:
-  explicit CPDF_CalRGB(CPDF_Document* pDoc);
-  ~CPDF_CalRGB() override {}
+  template <typename T, typename... Args>
+  friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
 
-  uint32_t v_Load(CPDF_Document* pDoc,
-                  const CPDF_Array* pArray,
-                  std::set<const CPDF_Object*>* pVisited) override;
+  ~CPDF_CalRGB() override;
 
+  // CPDF_ColorSpace:
   bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
-
   void TranslateImageLine(uint8_t* pDestBuf,
                           const uint8_t* pSrcBuf,
                           int pixels,
                           int image_width,
                           int image_height,
                           bool bTransMask) const override;
+  uint32_t v_Load(CPDF_Document* pDoc,
+                  const CPDF_Array* pArray,
+                  std::set<const CPDF_Object*>* pVisited) override;
 
  private:
   static constexpr size_t kGammaCount = 3;
   static constexpr size_t kMatrixCount = 9;
 
+  explicit CPDF_CalRGB(CPDF_Document* pDoc);
+
   float m_WhitePoint[kBlackWhitePointCount];
   float m_BlackPoint[kBlackWhitePointCount];
   float m_Gamma[kGammaCount];
@@ -162,29 +169,32 @@
 
 class CPDF_LabCS final : public CPDF_ColorSpace {
  public:
-  explicit CPDF_LabCS(CPDF_Document* pDoc);
-  ~CPDF_LabCS() override {}
+  template <typename T, typename... Args>
+  friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
 
-  uint32_t v_Load(CPDF_Document* pDoc,
-                  const CPDF_Array* pArray,
-                  std::set<const CPDF_Object*>* pVisited) override;
+  ~CPDF_LabCS() override;
 
+  // CPDF_ColorSpace:
+  bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
   void GetDefaultValue(int iComponent,
                        float* value,
                        float* min,
                        float* max) const override;
-  bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
-
   void TranslateImageLine(uint8_t* pDestBuf,
                           const uint8_t* pSrcBuf,
                           int pixels,
                           int image_width,
                           int image_height,
                           bool bTransMask) const override;
+  uint32_t v_Load(CPDF_Document* pDoc,
+                  const CPDF_Array* pArray,
+                  std::set<const CPDF_Object*>* pVisited) override;
 
  private:
   static constexpr size_t kRangesCount = 4;
 
+  explicit CPDF_LabCS(CPDF_Document* pDoc);
+
   float m_WhitePoint[kBlackWhitePointCount];
   float m_BlackPoint[kBlackWhitePointCount];
   float m_Ranges[kRangesCount];
@@ -192,13 +202,12 @@
 
 class CPDF_ICCBasedCS final : public CPDF_ColorSpace {
  public:
-  explicit CPDF_ICCBasedCS(CPDF_Document* pDoc);
+  template <typename T, typename... Args>
+  friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
   ~CPDF_ICCBasedCS() override;
 
   // CPDF_ColorSpace:
-  uint32_t v_Load(CPDF_Document* pDoc,
-                  const CPDF_Array* pArray,
-                  std::set<const CPDF_Object*>* pVisited) override;
   bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
   void EnableStdConversion(bool bEnabled) override;
   void TranslateImageLine(uint8_t* pDestBuf,
@@ -208,8 +217,13 @@
                           int image_height,
                           bool bTransMask) const override;
   bool IsNormal() const override;
+  uint32_t v_Load(CPDF_Document* pDoc,
+                  const CPDF_Array* pArray,
+                  std::set<const CPDF_Object*>* pVisited) override;
 
  private:
+  explicit CPDF_ICCBasedCS(CPDF_Document* pDoc);
+
   // If no valid ICC profile or using sRGB, try looking for an alternate.
   bool FindAlternateProfile(CPDF_Document* pDoc,
                             const CPDF_Dictionary* pDict,
@@ -229,18 +243,22 @@
 
 class CPDF_IndexedCS final : public CPDF_ColorSpace {
  public:
-  explicit CPDF_IndexedCS(CPDF_Document* pDoc);
+  template <typename T, typename... Args>
+  friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
   ~CPDF_IndexedCS() override;
 
+  // CPDF_ColorSpace:
+  bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
+  void EnableStdConversion(bool bEnabled) override;
   uint32_t v_Load(CPDF_Document* pDoc,
                   const CPDF_Array* pArray,
                   std::set<const CPDF_Object*>* pVisited) override;
 
-  bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
-
-  void EnableStdConversion(bool bEnabled) override;
 
  private:
+  explicit CPDF_IndexedCS(CPDF_Document* pDoc);
+
   RetainPtr<CPDF_ColorSpace> m_pBaseCS;
   uint32_t m_nBaseComponents = 0;
   int m_MaxIndex = 0;
@@ -250,43 +268,52 @@
 
 class CPDF_SeparationCS final : public CPDF_ColorSpace {
  public:
-  explicit CPDF_SeparationCS(CPDF_Document* pDoc);
+  template <typename T, typename... Args>
+  friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
   ~CPDF_SeparationCS() override;
 
   // CPDF_ColorSpace:
+  bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
   void GetDefaultValue(int iComponent,
                        float* value,
                        float* min,
                        float* max) const override;
+  void EnableStdConversion(bool bEnabled) override;
   uint32_t v_Load(CPDF_Document* pDoc,
                   const CPDF_Array* pArray,
                   std::set<const CPDF_Object*>* pVisited) override;
-  bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
-  void EnableStdConversion(bool bEnabled) override;
 
  private:
   enum { None, All, Colorant } m_Type;
+
+  explicit CPDF_SeparationCS(CPDF_Document* pDoc);
+
   RetainPtr<CPDF_ColorSpace> m_pAltCS;
   std::unique_ptr<const CPDF_Function> m_pFunc;
 };
 
 class CPDF_DeviceNCS final : public CPDF_ColorSpace {
  public:
-  explicit CPDF_DeviceNCS(CPDF_Document* pDoc);
+  template <typename T, typename... Args>
+  friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
   ~CPDF_DeviceNCS() override;
 
   // CPDF_ColorSpace:
+  bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
   void GetDefaultValue(int iComponent,
                        float* value,
                        float* min,
                        float* max) const override;
+  void EnableStdConversion(bool bEnabled) override;
   uint32_t v_Load(CPDF_Document* pDoc,
                   const CPDF_Array* pArray,
                   std::set<const CPDF_Object*>* pVisited) override;
-  bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
-  void EnableStdConversion(bool bEnabled) override;
 
  private:
+  explicit CPDF_DeviceNCS(CPDF_Document* pDoc);
+
   RetainPtr<CPDF_ColorSpace> m_pAltCS;
   std::unique_ptr<const CPDF_Function> m_pFunc;
 };
@@ -629,7 +656,7 @@
 CPDF_ColorSpace::CPDF_ColorSpace(CPDF_Document* pDoc, int family)
     : m_pDocument(pDoc), m_Family(family) {}
 
-CPDF_ColorSpace::~CPDF_ColorSpace() {}
+CPDF_ColorSpace::~CPDF_ColorSpace() = default;
 
 void CPDF_ColorSpace::SetComponentsForStockCS(uint32_t nComponents) {
   ASSERT(!m_pDocument);  // Stock colorspace is not associated with a document.
@@ -639,6 +666,8 @@
 CPDF_CalGray::CPDF_CalGray(CPDF_Document* pDoc)
     : CPDF_ColorSpace(pDoc, PDFCS_CALGRAY) {}
 
+CPDF_CalGray::~CPDF_CalGray() = default;
+
 uint32_t CPDF_CalGray::v_Load(CPDF_Document* pDoc,
                               const CPDF_Array* pArray,
                               std::set<const CPDF_Object*>* pVisited) {
@@ -683,6 +712,8 @@
 CPDF_CalRGB::CPDF_CalRGB(CPDF_Document* pDoc)
     : CPDF_ColorSpace(pDoc, PDFCS_CALRGB) {}
 
+CPDF_CalRGB::~CPDF_CalRGB() = default;
+
 uint32_t CPDF_CalRGB::v_Load(CPDF_Document* pDoc,
                              const CPDF_Array* pArray,
                              std::set<const CPDF_Object*>* pVisited) {
@@ -770,6 +801,8 @@
 CPDF_LabCS::CPDF_LabCS(CPDF_Document* pDoc)
     : CPDF_ColorSpace(pDoc, PDFCS_LAB) {}
 
+CPDF_LabCS::~CPDF_LabCS() = default;
+
 void CPDF_LabCS::GetDefaultValue(int iComponent,
                                  float* value,
                                  float* min,
@@ -1178,7 +1211,7 @@
 CPDF_SeparationCS::CPDF_SeparationCS(CPDF_Document* pDoc)
     : CPDF_ColorSpace(pDoc, PDFCS_SEPARATION) {}
 
-CPDF_SeparationCS::~CPDF_SeparationCS() {}
+CPDF_SeparationCS::~CPDF_SeparationCS() = default;
 
 void CPDF_SeparationCS::GetDefaultValue(int iComponent,
                                         float* value,
@@ -1261,7 +1294,7 @@
 CPDF_DeviceNCS::CPDF_DeviceNCS(CPDF_Document* pDoc)
     : CPDF_ColorSpace(pDoc, PDFCS_DEVICEN) {}
 
-CPDF_DeviceNCS::~CPDF_DeviceNCS() {}
+CPDF_DeviceNCS::~CPDF_DeviceNCS() = default;
 
 void CPDF_DeviceNCS::GetDefaultValue(int iComponent,
                                      float* value,
diff --git a/core/fpdfapi/page/cpdf_colorspace.h b/core/fpdfapi/page/cpdf_colorspace.h
index 333d9b9..193268b 100644
--- a/core/fpdfapi/page/cpdf_colorspace.h
+++ b/core/fpdfapi/page/cpdf_colorspace.h
@@ -55,6 +55,8 @@
       std::set<const CPDF_Object*>* pVisited);
   static uint32_t ComponentsForFamily(int family);
 
+  const CPDF_Array* GetArray() const { return m_pArray.Get(); }
+  CPDF_Document* GetDocument() const { return m_pDocument.Get(); }
   size_t GetBufSize() const;
   float* CreateBuf() const;
 
@@ -68,16 +70,15 @@
            GetFamily() == PDFCS_INDEXED || GetFamily() == PDFCS_PATTERN;
   }
 
-  virtual void GetDefaultValue(int iComponent,
-                               float* value,
-                               float* min,
-                               float* max) const;
-
   virtual bool GetRGB(const float* pBuf,
                       float* R,
                       float* G,
                       float* B) const = 0;
 
+  virtual void GetDefaultValue(int iComponent,
+                               float* value,
+                               float* min,
+                               float* max) const;
   virtual void TranslateImageLine(uint8_t* dest_buf,
                                   const uint8_t* src_buf,
                                   int pixels,
@@ -85,11 +86,8 @@
                                   int image_height,
                                   bool bTransMask) const;
   virtual void EnableStdConversion(bool bEnabled);
-
   virtual bool IsNormal() const;
 
-  // Only call these 3 methods below if GetFamily() returns |PDFCS_PATTERN|.
-
   // Returns |this| as a CPDF_PatternCS* if |this| is a pattern.
   virtual CPDF_PatternCS* AsPatternCS();
   virtual const CPDF_PatternCS* AsPatternCS() const;
@@ -100,9 +98,6 @@
                              float* G,
                              float* B) const;
 
-  const CPDF_Array* GetArray() const { return m_pArray.Get(); }
-  CPDF_Document* GetDocument() const { return m_pDocument.Get(); }
-
  protected:
   CPDF_ColorSpace(CPDF_Document* pDoc, int family);
   ~CPDF_ColorSpace() override;
diff --git a/core/fpdfapi/page/cpdf_devicecs.h b/core/fpdfapi/page/cpdf_devicecs.h
index ab88d74..c8e256c 100644
--- a/core/fpdfapi/page/cpdf_devicecs.h
+++ b/core/fpdfapi/page/cpdf_devicecs.h
@@ -10,16 +10,16 @@
 #include <set>
 
 #include "core/fpdfapi/page/cpdf_colorspace.h"
+#include "core/fxcrt/retain_ptr.h"
 
 class CPDF_DeviceCS final : public CPDF_ColorSpace {
  public:
-  explicit CPDF_DeviceCS(int family);
+  template <typename T, typename... Args>
+  friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
   ~CPDF_DeviceCS() override;
 
   // CPDF_ColorSpace:
-  uint32_t v_Load(CPDF_Document* pDoc,
-                  const CPDF_Array* pArray,
-                  std::set<const CPDF_Object*>* pVisited) override;
   bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
   void TranslateImageLine(uint8_t* pDestBuf,
                           const uint8_t* pSrcBuf,
@@ -27,6 +27,12 @@
                           int image_width,
                           int image_height,
                           bool bTransMask) const override;
+  uint32_t v_Load(CPDF_Document* pDoc,
+                  const CPDF_Array* pArray,
+                  std::set<const CPDF_Object*>* pVisited) override;
+
+ private:
+  explicit CPDF_DeviceCS(int family);
 };
 
 #endif  // CORE_FPDFAPI_PAGE_CPDF_DEVICECS_H_
diff --git a/core/fpdfapi/page/cpdf_devicecs_unittest.cpp b/core/fpdfapi/page/cpdf_devicecs_unittest.cpp
index a171d01..fbf2558 100644
--- a/core/fpdfapi/page/cpdf_devicecs_unittest.cpp
+++ b/core/fpdfapi/page/cpdf_devicecs_unittest.cpp
@@ -5,46 +5,48 @@
 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
 
 #include "core/fpdfapi/page/cpdf_devicecs.h"
+
+#include "core/fxcrt/retain_ptr.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 TEST(CPDF_DeviceCSTest, GetRGBFromGray) {
   float R;
   float G;
   float B;
-  CPDF_DeviceCS device_gray(PDFCS_DEVICEGRAY);
+  auto device_gray = pdfium::MakeRetain<CPDF_DeviceCS>(PDFCS_DEVICEGRAY);
 
   // Test normal values. For gray, only first value from buf should be used.
   float buf[3] = {0.43f, 0.11f, 0.34f};
-  ASSERT_TRUE(device_gray.GetRGB(buf, &R, &G, &B));
+  ASSERT_TRUE(device_gray->GetRGB(buf, &R, &G, &B));
   EXPECT_FLOAT_EQ(0.43f, R);
   EXPECT_FLOAT_EQ(0.43f, G);
   EXPECT_FLOAT_EQ(0.43f, B);
   buf[0] = 0.872f;
-  ASSERT_TRUE(device_gray.GetRGB(buf, &R, &G, &B));
+  ASSERT_TRUE(device_gray->GetRGB(buf, &R, &G, &B));
   EXPECT_FLOAT_EQ(0.872f, R);
   EXPECT_FLOAT_EQ(0.872f, G);
   EXPECT_FLOAT_EQ(0.872f, B);
 
   // Test boundary values
   buf[0] = {0.0f};
-  ASSERT_TRUE(device_gray.GetRGB(buf, &R, &G, &B));
+  ASSERT_TRUE(device_gray->GetRGB(buf, &R, &G, &B));
   EXPECT_FLOAT_EQ(0.0f, R);
   EXPECT_FLOAT_EQ(0.0f, G);
   EXPECT_FLOAT_EQ(0.0f, B);
   buf[0] = 1.0f;
-  ASSERT_TRUE(device_gray.GetRGB(buf, &R, &G, &B));
+  ASSERT_TRUE(device_gray->GetRGB(buf, &R, &G, &B));
   EXPECT_FLOAT_EQ(1.0f, R);
   EXPECT_FLOAT_EQ(1.0f, G);
   EXPECT_FLOAT_EQ(1.0f, B);
 
   // Test out of range values
   buf[0] = -0.01f;
-  ASSERT_TRUE(device_gray.GetRGB(buf, &R, &G, &B));
+  ASSERT_TRUE(device_gray->GetRGB(buf, &R, &G, &B));
   EXPECT_FLOAT_EQ(0.0f, R);
   EXPECT_FLOAT_EQ(0.0f, G);
   EXPECT_FLOAT_EQ(0.0f, B);
   buf[0] = 12.5f;
-  ASSERT_TRUE(device_gray.GetRGB(buf, &R, &G, &B));
+  ASSERT_TRUE(device_gray->GetRGB(buf, &R, &G, &B));
   EXPECT_FLOAT_EQ(1.0f, R);
   EXPECT_FLOAT_EQ(1.0f, G);
   EXPECT_FLOAT_EQ(1.0f, B);
@@ -54,18 +56,18 @@
   float R;
   float G;
   float B;
-  CPDF_DeviceCS device_rgb(PDFCS_DEVICERGB);
+  auto device_rgb = pdfium::MakeRetain<CPDF_DeviceCS>(PDFCS_DEVICERGB);
 
   // Test normal values
   float buf[3] = {0.13f, 1.0f, 0.652f};
-  ASSERT_TRUE(device_rgb.GetRGB(buf, &R, &G, &B));
+  ASSERT_TRUE(device_rgb->GetRGB(buf, &R, &G, &B));
   EXPECT_FLOAT_EQ(0.13f, R);
   EXPECT_FLOAT_EQ(1.0f, G);
   EXPECT_FLOAT_EQ(0.652f, B);
   buf[0] = 0.0f;
   buf[1] = 0.52f;
   buf[2] = 0.78f;
-  ASSERT_TRUE(device_rgb.GetRGB(buf, &R, &G, &B));
+  ASSERT_TRUE(device_rgb->GetRGB(buf, &R, &G, &B));
   EXPECT_FLOAT_EQ(0.0f, R);
   EXPECT_FLOAT_EQ(0.52f, G);
   EXPECT_FLOAT_EQ(0.78f, B);
@@ -73,7 +75,7 @@
   // Test out of range values
   buf[0] = -10.5f;
   buf[1] = 100.0f;
-  ASSERT_TRUE(device_rgb.GetRGB(buf, &R, &G, &B));
+  ASSERT_TRUE(device_rgb->GetRGB(buf, &R, &G, &B));
   EXPECT_FLOAT_EQ(0.0f, R);
   EXPECT_FLOAT_EQ(1.0f, G);
   EXPECT_FLOAT_EQ(0.78f, B);
@@ -83,23 +85,23 @@
   float R;
   float G;
   float B;
-  CPDF_DeviceCS device_cmyk(PDFCS_DEVICECMYK);
+  auto device_cmyk = pdfium::MakeRetain<CPDF_DeviceCS>(PDFCS_DEVICECMYK);
 
   // Test normal values
   float buf[4] = {0.6f, 0.5f, 0.3f, 0.9f};
-  ASSERT_TRUE(device_cmyk.GetRGB(buf, &R, &G, &B));
+  ASSERT_TRUE(device_cmyk->GetRGB(buf, &R, &G, &B));
   EXPECT_FLOAT_EQ(0.0627451f, R);
   EXPECT_FLOAT_EQ(0.0627451f, G);
   EXPECT_FLOAT_EQ(0.10588236f, B);
   buf[0] = 0.15f;
   buf[2] = 0.0f;
-  ASSERT_TRUE(device_cmyk.GetRGB(buf, &R, &G, &B));
+  ASSERT_TRUE(device_cmyk->GetRGB(buf, &R, &G, &B));
   EXPECT_FLOAT_EQ(0.2f, R);
   EXPECT_FLOAT_EQ(0.0862745f, G);
   EXPECT_FLOAT_EQ(0.16470589f, B);
   buf[2] = 1.0f;
   buf[3] = 0.0f;
-  ASSERT_TRUE(device_cmyk.GetRGB(buf, &R, &G, &B));
+  ASSERT_TRUE(device_cmyk->GetRGB(buf, &R, &G, &B));
   EXPECT_FLOAT_EQ(0.85098046f, R);
   EXPECT_FLOAT_EQ(0.552941f, G);
   EXPECT_FLOAT_EQ(0.15686275f, B);
@@ -107,7 +109,7 @@
   // Test out of range values
   buf[2] = 1.5f;
   buf[3] = -0.6f;
-  ASSERT_TRUE(device_cmyk.GetRGB(buf, &R, &G, &B));
+  ASSERT_TRUE(device_cmyk->GetRGB(buf, &R, &G, &B));
   EXPECT_FLOAT_EQ(0.85098046f, R);
   EXPECT_FLOAT_EQ(0.552941f, G);
   EXPECT_FLOAT_EQ(0.15686275f, B);
diff --git a/core/fpdfapi/page/cpdf_patterncs.h b/core/fpdfapi/page/cpdf_patterncs.h
index e0e2a8a..b6b46f6 100644
--- a/core/fpdfapi/page/cpdf_patterncs.h
+++ b/core/fpdfapi/page/cpdf_patterncs.h
@@ -16,7 +16,9 @@
 
 class CPDF_PatternCS final : public CPDF_ColorSpace {
  public:
-  explicit CPDF_PatternCS(CPDF_Document* pDoc);
+  template <typename T, typename... Args>
+  friend RetainPtr<T> pdfium::MakeRetain(Args&&... args);
+
   ~CPDF_PatternCS() override;
 
   // Called for the stock pattern, since it is not initialized via
@@ -24,18 +26,20 @@
   void InitializeStockPattern();
 
   // CPDF_ColorSpace:
-  uint32_t v_Load(CPDF_Document* pDoc,
-                  const CPDF_Array* pArray,
-                  std::set<const CPDF_Object*>* pVisited) override;
   bool GetRGB(const float* pBuf, float* R, float* G, float* B) const override;
-  CPDF_PatternCS* AsPatternCS() override;
-  const CPDF_PatternCS* AsPatternCS() const override;
   bool GetPatternRGB(const PatternValue& value,
                      float* R,
                      float* G,
                      float* B) const override;
+  CPDF_PatternCS* AsPatternCS() override;
+  const CPDF_PatternCS* AsPatternCS() const override;
+  uint32_t v_Load(CPDF_Document* pDoc,
+                  const CPDF_Array* pArray,
+                  std::set<const CPDF_Object*>* pVisited) override;
 
  private:
+  explicit CPDF_PatternCS(CPDF_Document* pDoc);
+
   RetainPtr<CPDF_ColorSpace> m_pBaseCS;
 };