Make CPDF_GeneralStateData private.

All interaction goes through the CPDF_GeneralState, which
manages the underlying storage transparently to the callers.

Make StateData use a real string and a real matrix rather
than C-style arrays.

Review-Url: https://codereview.chromium.org/2302683002
diff --git a/BUILD.gn b/BUILD.gn
index 2f4ea34..ae50f1f 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -426,7 +426,6 @@
     "core/fpdfapi/fpdf_page/cpdf_form.cpp",
     "core/fpdfapi/fpdf_page/cpdf_formobject.cpp",
     "core/fpdfapi/fpdf_page/cpdf_generalstate.cpp",
-    "core/fpdfapi/fpdf_page/cpdf_generalstatedata.cpp",
     "core/fpdfapi/fpdf_page/cpdf_graphicstates.cpp",
     "core/fpdfapi/fpdf_page/cpdf_graphicstates.h",
     "core/fpdfapi/fpdf_page/cpdf_graphstate.cpp",
@@ -466,7 +465,6 @@
     "core/fpdfapi/fpdf_page/include/cpdf_form.h",
     "core/fpdfapi/fpdf_page/include/cpdf_formobject.h",
     "core/fpdfapi/fpdf_page/include/cpdf_generalstate.h",
-    "core/fpdfapi/fpdf_page/include/cpdf_generalstatedata.h",
     "core/fpdfapi/fpdf_page/include/cpdf_image.h",
     "core/fpdfapi/fpdf_page/include/cpdf_imageobject.h",
     "core/fpdfapi/fpdf_page/include/cpdf_page.h",
diff --git a/core/fpdfapi/fpdf_page/cpdf_allstates.cpp b/core/fpdfapi/fpdf_page/cpdf_allstates.cpp
index 89c1321..b92f10b 100644
--- a/core/fpdfapi/fpdf_page/cpdf_allstates.cpp
+++ b/core/fpdfapi/fpdf_page/cpdf_allstates.cpp
@@ -106,10 +106,8 @@
         break;
       case FXBSTR_ID('B', 'M', 0, 0): {
         CPDF_Array* pArray = pObject->AsArray();
-        CFX_ByteString mode =
-            pArray ? pArray->GetStringAt(0) : pObject->GetString();
-
-        m_GeneralState.SetBlendMode(mode.AsStringC());
+        m_GeneralState.SetBlendMode(pArray ? pArray->GetStringAt(0)
+                                           : pObject->GetString());
         if (m_GeneralState.GetBlendType() > FXDIB_BLEND_MULTIPLY)
           pParser->GetPageObjectHolder()->SetBackgroundAlphaNeeded(TRUE);
         break;
@@ -117,8 +115,7 @@
       case FXBSTR_ID('S', 'M', 'a', 's'):
         if (ToDictionary(pObject)) {
           m_GeneralState.SetSoftMask(pObject);
-          FXSYS_memcpy(m_GeneralState.GetMutableSMaskMatrix(),
-                       &pParser->GetCurStates()->m_CTM, sizeof(CFX_Matrix));
+          m_GeneralState.SetSMaskMatrix(pParser->GetCurStates()->m_CTM);
         } else {
           m_GeneralState.SetSoftMask(nullptr);
         }
diff --git a/core/fpdfapi/fpdf_page/cpdf_generalstate.cpp b/core/fpdfapi/fpdf_page/cpdf_generalstate.cpp
index e34801f..601cf0c 100644
--- a/core/fpdfapi/fpdf_page/cpdf_generalstate.cpp
+++ b/core/fpdfapi/fpdf_page/cpdf_generalstate.cpp
@@ -6,6 +6,9 @@
 
 #include "core/fpdfapi/fpdf_page/include/cpdf_generalstate.h"
 
+#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
+#include "core/fpdfapi/fpdf_render/render_int.h"
+
 namespace {
 
 int RI_StringToId(const CFX_ByteString& ri) {
@@ -22,6 +25,45 @@
   return 0;
 }
 
+int GetBlendTypeInternal(const CFX_ByteString& mode) {
+  switch (mode.GetID()) {
+    case FXBSTR_ID('N', 'o', 'r', 'm'):
+    case FXBSTR_ID('C', 'o', 'm', 'p'):
+      return FXDIB_BLEND_NORMAL;
+    case FXBSTR_ID('M', 'u', 'l', 't'):
+      return FXDIB_BLEND_MULTIPLY;
+    case FXBSTR_ID('S', 'c', 'r', 'e'):
+      return FXDIB_BLEND_SCREEN;
+    case FXBSTR_ID('O', 'v', 'e', 'r'):
+      return FXDIB_BLEND_OVERLAY;
+    case FXBSTR_ID('D', 'a', 'r', 'k'):
+      return FXDIB_BLEND_DARKEN;
+    case FXBSTR_ID('L', 'i', 'g', 'h'):
+      return FXDIB_BLEND_LIGHTEN;
+    case FXBSTR_ID('C', 'o', 'l', 'o'):
+      if (mode.GetLength() == 10)
+        return FXDIB_BLEND_COLORDODGE;
+      if (mode.GetLength() == 9)
+        return FXDIB_BLEND_COLORBURN;
+      return FXDIB_BLEND_COLOR;
+    case FXBSTR_ID('H', 'a', 'r', 'd'):
+      return FXDIB_BLEND_HARDLIGHT;
+    case FXBSTR_ID('S', 'o', 'f', 't'):
+      return FXDIB_BLEND_SOFTLIGHT;
+    case FXBSTR_ID('D', 'i', 'f', 'f'):
+      return FXDIB_BLEND_DIFFERENCE;
+    case FXBSTR_ID('E', 'x', 'c', 'l'):
+      return FXDIB_BLEND_EXCLUSION;
+    case FXBSTR_ID('H', 'u', 'e', 0):
+      return FXDIB_BLEND_HUE;
+    case FXBSTR_ID('S', 'a', 't', 'u'):
+      return FXDIB_BLEND_SATURATION;
+    case FXBSTR_ID('L', 'u', 'm', 'i'):
+      return FXDIB_BLEND_LUMINOSITY;
+  }
+  return FXDIB_BLEND_NORMAL;
+}
+
 }  // namespace
 
 CPDF_GeneralState::CPDF_GeneralState() {}
@@ -36,7 +78,7 @@
 }
 
 int CPDF_GeneralState::GetBlendType() const {
-  const CPDF_GeneralStateData* pData = m_Ref.GetObject();
+  const StateData* pData = m_Ref.GetObject();
   return pData ? pData->m_BlendType : FXDIB_BLEND_NORMAL;
 }
 
@@ -45,7 +87,7 @@
 }
 
 FX_FLOAT CPDF_GeneralState::GetFillAlpha() const {
-  const CPDF_GeneralStateData* pData = m_Ref.GetObject();
+  const StateData* pData = m_Ref.GetObject();
   return pData ? pData->m_FillAlpha : 1.0f;
 }
 
@@ -54,7 +96,7 @@
 }
 
 FX_FLOAT CPDF_GeneralState::GetStrokeAlpha() const {
-  const CPDF_GeneralStateData* pData = m_Ref.GetObject();
+  const StateData* pData = m_Ref.GetObject();
   return pData ? pData->m_StrokeAlpha : 1.0f;
 }
 
@@ -63,7 +105,7 @@
 }
 
 CPDF_Object* CPDF_GeneralState::GetSoftMask() const {
-  const CPDF_GeneralStateData* pData = m_Ref.GetObject();
+  const StateData* pData = m_Ref.GetObject();
   return pData ? pData->m_pSoftMask : nullptr;
 }
 
@@ -72,7 +114,7 @@
 }
 
 CPDF_Object* CPDF_GeneralState::GetTR() const {
-  const CPDF_GeneralStateData* pData = m_Ref.GetObject();
+  const StateData* pData = m_Ref.GetObject();
   return pData ? pData->m_pTR : nullptr;
 }
 
@@ -81,7 +123,7 @@
 }
 
 CPDF_TransferFunc* CPDF_GeneralState::GetTransferFunc() const {
-  const CPDF_GeneralStateData* pData = m_Ref.GetObject();
+  const StateData* pData = m_Ref.GetObject();
   return pData ? pData->m_pTransferFunc : nullptr;
 }
 
@@ -89,21 +131,23 @@
   m_Ref.GetPrivateCopy()->m_pTransferFunc = pFunc;
 }
 
-void CPDF_GeneralState::SetBlendMode(const CFX_ByteStringC& mode) {
-  m_Ref.GetPrivateCopy()->SetBlendMode(mode);
+void CPDF_GeneralState::SetBlendMode(const CFX_ByteString& mode) {
+  StateData* pData = m_Ref.GetPrivateCopy();
+  pData->m_BlendMode = mode;
+  pData->m_BlendType = GetBlendTypeInternal(mode);
 }
 
-const FX_FLOAT* CPDF_GeneralState::GetSMaskMatrix() const {
-  const CPDF_GeneralStateData* pData = m_Ref.GetObject();
-  return pData ? pData->m_SMaskMatrix : nullptr;
+const CFX_Matrix* CPDF_GeneralState::GetSMaskMatrix() const {
+  const StateData* pData = m_Ref.GetObject();
+  return pData ? &pData->m_SMaskMatrix : nullptr;
 }
 
-FX_FLOAT* CPDF_GeneralState::GetMutableSMaskMatrix() {
-  return m_Ref.GetPrivateCopy()->m_SMaskMatrix;
+void CPDF_GeneralState::SetSMaskMatrix(const CFX_Matrix& matrix) {
+  m_Ref.GetPrivateCopy()->m_SMaskMatrix = matrix;
 }
 
 bool CPDF_GeneralState::GetFillOP() const {
-  const CPDF_GeneralStateData* pData = m_Ref.GetObject();
+  const StateData* pData = m_Ref.GetObject();
   return pData && pData->m_FillOP;
 }
 
@@ -116,7 +160,7 @@
 }
 
 bool CPDF_GeneralState::GetStrokeOP() const {
-  const CPDF_GeneralStateData* pData = m_Ref.GetObject();
+  const StateData* pData = m_Ref.GetObject();
   return pData && pData->m_StrokeOP;
 }
 
@@ -149,7 +193,7 @@
 }
 
 bool CPDF_GeneralState::GetStrokeAdjust() const {
-  const CPDF_GeneralStateData* pData = m_Ref.GetObject();
+  const StateData* pData = m_Ref.GetObject();
   return pData && pData->m_StrokeAdjust;
 }
 
@@ -172,3 +216,66 @@
 CFX_Matrix* CPDF_GeneralState::GetMutableMatrix() {
   return &m_Ref.GetPrivateCopy()->m_Matrix;
 }
+
+CPDF_GeneralState::StateData::StateData()
+    : m_BlendMode("Normal"),
+      m_BlendType(0),
+      m_pSoftMask(nullptr),
+      m_StrokeAlpha(1.0),
+      m_FillAlpha(1.0f),
+      m_pTR(nullptr),
+      m_pTransferFunc(nullptr),
+      m_RenderIntent(0),
+      m_StrokeAdjust(false),
+      m_AlphaSource(false),
+      m_TextKnockout(false),
+      m_StrokeOP(false),
+      m_FillOP(false),
+      m_OPMode(0),
+      m_pBG(nullptr),
+      m_pUCR(nullptr),
+      m_pHT(nullptr),
+      m_Flatness(1.0f),
+      m_Smoothness(0.0f) {
+  m_SMaskMatrix.SetIdentity();
+  m_Matrix.SetIdentity();
+}
+
+CPDF_GeneralState::StateData::StateData(const StateData& that)
+    : m_BlendMode(that.m_BlendMode),
+      m_BlendType(that.m_BlendType),
+      m_pSoftMask(that.m_pSoftMask),
+      m_StrokeAlpha(that.m_StrokeAlpha),
+      m_FillAlpha(that.m_FillAlpha),
+      m_pTR(that.m_pTR),
+      m_pTransferFunc(that.m_pTransferFunc),
+      m_RenderIntent(that.m_RenderIntent),
+      m_StrokeAdjust(that.m_StrokeAdjust),
+      m_AlphaSource(that.m_AlphaSource),
+      m_TextKnockout(that.m_TextKnockout),
+      m_StrokeOP(that.m_StrokeOP),
+      m_FillOP(that.m_FillOP),
+      m_OPMode(that.m_OPMode),
+      m_pBG(that.m_pBG),
+      m_pUCR(that.m_pUCR),
+      m_pHT(that.m_pHT),
+      m_Flatness(that.m_Flatness),
+      m_Smoothness(that.m_Smoothness) {
+  m_Matrix = that.m_Matrix;
+  m_SMaskMatrix = that.m_SMaskMatrix;
+
+  if (that.m_pTransferFunc && that.m_pTransferFunc->m_pPDFDoc) {
+    CPDF_DocRenderData* pDocCache =
+        that.m_pTransferFunc->m_pPDFDoc->GetRenderData();
+    if (pDocCache)
+      m_pTransferFunc = pDocCache->GetTransferFunc(m_pTR);
+  }
+}
+
+CPDF_GeneralState::StateData::~StateData() {
+  if (m_pTransferFunc && m_pTransferFunc->m_pPDFDoc) {
+    CPDF_DocRenderData* pDocCache = m_pTransferFunc->m_pPDFDoc->GetRenderData();
+    if (pDocCache)
+      pDocCache->ReleaseTransferFunc(m_pTR);
+  }
+}
diff --git a/core/fpdfapi/fpdf_page/cpdf_generalstatedata.cpp b/core/fpdfapi/fpdf_page/cpdf_generalstatedata.cpp
deleted file mode 100644
index 37ec63f..0000000
--- a/core/fpdfapi/fpdf_page/cpdf_generalstatedata.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2016 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "core/fpdfapi/fpdf_page/include/cpdf_generalstatedata.h"
-
-#include "core/fpdfapi/fpdf_parser/include/cpdf_document.h"
-#include "core/fpdfapi/fpdf_render/render_int.h"
-
-namespace {
-
-static int GetBlendTypeInternal(const CFX_ByteStringC& mode) {
-  switch (mode.GetID()) {
-    case FXBSTR_ID('N', 'o', 'r', 'm'):
-    case FXBSTR_ID('C', 'o', 'm', 'p'):
-      return FXDIB_BLEND_NORMAL;
-    case FXBSTR_ID('M', 'u', 'l', 't'):
-      return FXDIB_BLEND_MULTIPLY;
-    case FXBSTR_ID('S', 'c', 'r', 'e'):
-      return FXDIB_BLEND_SCREEN;
-    case FXBSTR_ID('O', 'v', 'e', 'r'):
-      return FXDIB_BLEND_OVERLAY;
-    case FXBSTR_ID('D', 'a', 'r', 'k'):
-      return FXDIB_BLEND_DARKEN;
-    case FXBSTR_ID('L', 'i', 'g', 'h'):
-      return FXDIB_BLEND_LIGHTEN;
-    case FXBSTR_ID('C', 'o', 'l', 'o'):
-      if (mode.GetLength() == 10)
-        return FXDIB_BLEND_COLORDODGE;
-
-      if (mode.GetLength() == 9)
-        return FXDIB_BLEND_COLORBURN;
-
-      return FXDIB_BLEND_COLOR;
-    case FXBSTR_ID('H', 'a', 'r', 'd'):
-      return FXDIB_BLEND_HARDLIGHT;
-    case FXBSTR_ID('S', 'o', 'f', 't'):
-      return FXDIB_BLEND_SOFTLIGHT;
-    case FXBSTR_ID('D', 'i', 'f', 'f'):
-      return FXDIB_BLEND_DIFFERENCE;
-    case FXBSTR_ID('E', 'x', 'c', 'l'):
-      return FXDIB_BLEND_EXCLUSION;
-    case FXBSTR_ID('H', 'u', 'e', 0):
-      return FXDIB_BLEND_HUE;
-    case FXBSTR_ID('S', 'a', 't', 'u'):
-      return FXDIB_BLEND_SATURATION;
-    case FXBSTR_ID('L', 'u', 'm', 'i'):
-      return FXDIB_BLEND_LUMINOSITY;
-  }
-  return FXDIB_BLEND_NORMAL;
-}
-
-}  // namespace
-
-CPDF_GeneralStateData::CPDF_GeneralStateData() {
-  FXSYS_memset(this, 0, sizeof(CPDF_GeneralStateData));
-  FXSYS_strcpy((FX_CHAR*)m_BlendMode, "Normal");
-  m_StrokeAlpha = 1.0f;
-  m_FillAlpha = 1.0f;
-  m_Flatness = 1.0f;
-  m_Matrix.SetIdentity();
-}
-
-CPDF_GeneralStateData::CPDF_GeneralStateData(const CPDF_GeneralStateData& src) {
-  FXSYS_memcpy(this, &src, sizeof(CPDF_GeneralStateData));
-  if (src.m_pTransferFunc && src.m_pTransferFunc->m_pPDFDoc) {
-    CPDF_DocRenderData* pDocCache =
-        src.m_pTransferFunc->m_pPDFDoc->GetRenderData();
-    if (!pDocCache)
-      return;
-
-    m_pTransferFunc = pDocCache->GetTransferFunc(m_pTR);
-  }
-}
-
-CPDF_GeneralStateData::~CPDF_GeneralStateData() {
-  if (m_pTransferFunc && m_pTransferFunc->m_pPDFDoc) {
-    CPDF_DocRenderData* pDocCache = m_pTransferFunc->m_pPDFDoc->GetRenderData();
-    if (!pDocCache)
-      return;
-
-    pDocCache->ReleaseTransferFunc(m_pTR);
-  }
-}
-
-void CPDF_GeneralStateData::SetBlendMode(const CFX_ByteStringC& blend_mode) {
-  if (blend_mode.GetLength() > 15) {
-    return;
-  }
-  FXSYS_memcpy(m_BlendMode, blend_mode.raw_str(), blend_mode.GetLength());
-  m_BlendMode[blend_mode.GetLength()] = 0;
-  m_BlendType = GetBlendTypeInternal(blend_mode);
-}
diff --git a/core/fpdfapi/fpdf_page/include/cpdf_generalstate.h b/core/fpdfapi/fpdf_page/include/cpdf_generalstate.h
index b653d64..f07e411 100644
--- a/core/fpdfapi/fpdf_page/include/cpdf_generalstate.h
+++ b/core/fpdfapi/fpdf_page/include/cpdf_generalstate.h
@@ -7,8 +7,12 @@
 #ifndef CORE_FPDFAPI_FPDF_PAGE_INCLUDE_CPDF_GENERALSTATE_H_
 #define CORE_FPDFAPI_FPDF_PAGE_INCLUDE_CPDF_GENERALSTATE_H_
 
-#include "core/fpdfapi/fpdf_page/include/cpdf_generalstatedata.h"
 #include "core/fxcrt/include/fx_basic.h"
+#include "core/fxcrt/include/fx_coordinates.h"
+#include "core/fxge/include/fx_dib.h"
+
+class CPDF_Object;
+class CPDF_TransferFunc;
 
 class CPDF_GeneralState {
  public:
@@ -39,10 +43,10 @@
   CPDF_TransferFunc* GetTransferFunc() const;
   void SetTransferFunc(CPDF_TransferFunc* pFunc);
 
-  void SetBlendMode(const CFX_ByteStringC& mode);
+  void SetBlendMode(const CFX_ByteString& mode);
 
-  const FX_FLOAT* GetSMaskMatrix() const;
-  FX_FLOAT* GetMutableSMaskMatrix();
+  const CFX_Matrix* GetSMaskMatrix() const;
+  void SetSMaskMatrix(const CFX_Matrix& matrix);
 
   bool GetFillOP() const;
   void SetFillOP(bool op);
@@ -70,7 +74,36 @@
   CFX_Matrix* GetMutableMatrix();
 
  private:
-  CFX_CountRef<CPDF_GeneralStateData> m_Ref;
+  class StateData {
+   public:
+    StateData();
+    StateData(const StateData& that);
+    ~StateData();
+
+    CFX_ByteString m_BlendMode;
+    int m_BlendType;
+    CPDF_Object* m_pSoftMask;
+    CFX_Matrix m_SMaskMatrix;
+    FX_FLOAT m_StrokeAlpha;
+    FX_FLOAT m_FillAlpha;
+    CPDF_Object* m_pTR;
+    CPDF_TransferFunc* m_pTransferFunc;
+    CFX_Matrix m_Matrix;
+    int m_RenderIntent;
+    bool m_StrokeAdjust;
+    bool m_AlphaSource;
+    bool m_TextKnockout;
+    bool m_StrokeOP;
+    bool m_FillOP;
+    int m_OPMode;
+    CPDF_Object* m_pBG;
+    CPDF_Object* m_pUCR;
+    CPDF_Object* m_pHT;
+    FX_FLOAT m_Flatness;
+    FX_FLOAT m_Smoothness;
+  };
+
+  CFX_CountRef<StateData> m_Ref;
 };
 
 #endif  // CORE_FPDFAPI_FPDF_PAGE_INCLUDE_CPDF_GENERALSTATE_H_
diff --git a/core/fpdfapi/fpdf_render/fpdf_render.cpp b/core/fpdfapi/fpdf_render/fpdf_render.cpp
index 1ac5bfa..27c9fa9 100644
--- a/core/fpdfapi/fpdf_render/fpdf_render.cpp
+++ b/core/fpdfapi/fpdf_render/fpdf_render.cpp
@@ -804,9 +804,7 @@
   bitmap_render.ProcessObjectNoClip(pPageObj, &new_matrix);
   m_bStopped = bitmap_render.m_bStopped;
   if (pSMaskDict) {
-    CFX_Matrix smask_matrix;
-    FXSYS_memcpy(&smask_matrix, pPageObj->m_GeneralState.GetSMaskMatrix(),
-                 sizeof smask_matrix);
+    CFX_Matrix smask_matrix = *pPageObj->m_GeneralState.GetSMaskMatrix();
     smask_matrix.Concat(*pObj2Device);
     std::unique_ptr<CFX_DIBSource> pSMaskSource(
         LoadSMask(pSMaskDict, &rect, &smask_matrix));
diff --git a/fpdfsdk/fpdfeditpage.cpp b/fpdfsdk/fpdfeditpage.cpp
index d11bfa9..0b677be 100644
--- a/fpdfsdk/fpdfeditpage.cpp
+++ b/fpdfsdk/fpdfeditpage.cpp
@@ -13,7 +13,6 @@
 #include "core/fpdfapi/fpdf_edit/include/cpdf_pagecontentgenerator.h"
 #include "core/fpdfapi/fpdf_page/include/cpdf_form.h"
 #include "core/fpdfapi/fpdf_page/include/cpdf_formobject.h"
-#include "core/fpdfapi/fpdf_page/include/cpdf_generalstatedata.h"
 #include "core/fpdfapi/fpdf_page/include/cpdf_imageobject.h"
 #include "core/fpdfapi/fpdf_page/include/cpdf_page.h"
 #include "core/fpdfapi/fpdf_page/include/cpdf_pageobject.h"