Introduce CPDF_Icon class to break CPWL_Icon dependence on parser/.

The cpdfdoc/ layer should shield CPWL (window layer) from
parser objects.

- Move one method into the CPDF_IconFit class to remove last
  use of CPDF_Dictionary.

Change-Id: I0fc6df01ac5e781fd4b1b29c60018e76e5ed9896
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/64091
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfdoc/BUILD.gn b/core/fpdfdoc/BUILD.gn
index 63bed74..edb2d58 100644
--- a/core/fpdfdoc/BUILD.gn
+++ b/core/fpdfdoc/BUILD.gn
@@ -41,6 +41,8 @@
     "cpdf_formcontrol.h",
     "cpdf_formfield.cpp",
     "cpdf_formfield.h",
+    "cpdf_icon.cpp",
+    "cpdf_icon.h",
     "cpdf_iconfit.cpp",
     "cpdf_iconfit.h",
     "cpdf_interactiveform.cpp",
diff --git a/core/fpdfdoc/cpdf_icon.cpp b/core/fpdfdoc/cpdf_icon.cpp
new file mode 100644
index 0000000..a450e1e
--- /dev/null
+++ b/core/fpdfdoc/cpdf_icon.cpp
@@ -0,0 +1,39 @@
+// Copyright 2019 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/fpdfdoc/cpdf_icon.h"
+
+#include "core/fpdfapi/parser/cpdf_dictionary.h"
+#include "core/fpdfapi/parser/cpdf_stream.h"
+
+CPDF_Icon::CPDF_Icon(CPDF_Stream* pStream) : m_pStream(pStream) {}
+
+CPDF_Icon::~CPDF_Icon() = default;
+
+CFX_SizeF CPDF_Icon::GetImageSize() const {
+  CPDF_Dictionary* pDict = m_pStream->GetDict();
+  if (!pDict)
+    return CFX_SizeF();
+
+  CFX_FloatRect rect = pDict->GetRectFor("BBox");
+  return {rect.right - rect.left, rect.top - rect.bottom};
+}
+
+CFX_Matrix CPDF_Icon::GetImageMatrix() const {
+  CPDF_Dictionary* pDict = m_pStream->GetDict();
+  if (!pDict)
+    return CFX_Matrix();
+
+  return pDict->GetMatrixFor("Matrix");
+}
+
+ByteString CPDF_Icon::GetImageAlias() const {
+  CPDF_Dictionary* pDict = m_pStream->GetDict();
+  if (!pDict)
+    return ByteString();
+
+  return pDict->GetStringFor("Name");
+}
diff --git a/core/fpdfdoc/cpdf_icon.h b/core/fpdfdoc/cpdf_icon.h
new file mode 100644
index 0000000..519fcda
--- /dev/null
+++ b/core/fpdfdoc/cpdf_icon.h
@@ -0,0 +1,29 @@
+// Copyright 2019 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
+
+#ifndef CORE_FPDFDOC_CPDF_ICON_H_
+#define CORE_FPDFDOC_CPDF_ICON_H_
+
+#include "core/fxcrt/fx_coordinates.h"
+#include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/retain_ptr.h"
+
+class CPDF_Stream;
+
+class CPDF_Icon final {
+ public:
+  CPDF_Icon(CPDF_Stream* pStream);
+  ~CPDF_Icon();
+
+  CFX_SizeF GetImageSize() const;
+  CFX_Matrix GetImageMatrix() const;
+  ByteString GetImageAlias() const;
+
+ private:
+  RetainPtr<CPDF_Stream> const m_pStream;
+};
+
+#endif  // CORE_FPDFDOC_CPDF_ICON_H_
diff --git a/core/fpdfdoc/cpdf_iconfit.cpp b/core/fpdfdoc/cpdf_iconfit.cpp
index 801e908..55702a3 100644
--- a/core/fpdfdoc/cpdf_iconfit.cpp
+++ b/core/fpdfdoc/cpdf_iconfit.cpp
@@ -61,3 +61,16 @@
 bool CPDF_IconFit::GetFittingBounds() const {
   return m_pDict && m_pDict->GetBooleanFor("FB", false);
 }
+
+CFX_PointF CPDF_IconFit::GetIconPosition() const {
+  if (!m_pDict)
+    return CFX_PointF();
+
+  const CPDF_Array* pA = m_pDict->GetArrayFor("A");
+  if (!pA)
+    return CFX_PointF();
+
+  size_t dwCount = pA->size();
+  return {dwCount > 0 ? pA->GetNumberAt(0) : 0.0f,
+          dwCount > 1 ? pA->GetNumberAt(1) : 0.0f};
+}
diff --git a/core/fpdfdoc/cpdf_iconfit.h b/core/fpdfdoc/cpdf_iconfit.h
index 3da3dde..86a4918 100644
--- a/core/fpdfdoc/cpdf_iconfit.h
+++ b/core/fpdfdoc/cpdf_iconfit.h
@@ -23,9 +23,9 @@
 
   ScaleMethod GetScaleMethod() const;
   bool IsProportionalScale() const;
-  CFX_PointF GetIconBottomLeftPosition() const;
   bool GetFittingBounds() const;
-  const CPDF_Dictionary* GetDict() const { return m_pDict.Get(); }
+  CFX_PointF GetIconBottomLeftPosition() const;
+  CFX_PointF GetIconPosition() const;
 
  private:
   RetainPtr<const CPDF_Dictionary> const m_pDict;
diff --git a/fpdfsdk/cpdfsdk_appstream.cpp b/fpdfsdk/cpdfsdk_appstream.cpp
index 50cd8c1..b6600d2 100644
--- a/fpdfsdk/cpdfsdk_appstream.cpp
+++ b/fpdfsdk/cpdfsdk_appstream.cpp
@@ -20,6 +20,7 @@
 #include "core/fpdfapi/parser/fpdf_parser_decode.h"
 #include "core/fpdfdoc/cba_fontmap.h"
 #include "core/fpdfdoc/cpdf_formcontrol.h"
+#include "core/fpdfdoc/cpdf_icon.h"
 #include "core/fpdfdoc/cpvt_word.h"
 #include "fpdfsdk/cpdfsdk_formfillenvironment.h"
 #include "fpdfsdk/cpdfsdk_interactiveform.h"
@@ -689,7 +690,7 @@
   CPWL_Wnd::CreateParams cp;
   cp.dwFlags = PWS_VISIBLE;
 
-  CPWL_Icon icon(cp, pIconStream, &fit);
+  CPWL_Icon icon(cp, pdfium::MakeUnique<CPDF_Icon>(pIconStream), &fit);
   icon.Realize();
   if (!icon.Move(rcIcon, false, false))
     return ByteString();
diff --git a/fpdfsdk/pwl/BUILD.gn b/fpdfsdk/pwl/BUILD.gn
index 71bbf09..ea26c13 100644
--- a/fpdfsdk/pwl/BUILD.gn
+++ b/fpdfsdk/pwl/BUILD.gn
@@ -38,7 +38,6 @@
     "../../:pdfium_public_headers",
     "../../constants",
     "../../core/fpdfapi/font",
-    "../../core/fpdfapi/parser",
     "../../core/fpdfapi/render",
     "../../core/fpdfdoc",
     "../../core/fxcrt",
diff --git a/fpdfsdk/pwl/cpwl_icon.cpp b/fpdfsdk/pwl/cpwl_icon.cpp
index a720af4..67df09e 100644
--- a/fpdfsdk/pwl/cpwl_icon.cpp
+++ b/fpdfsdk/pwl/cpwl_icon.cpp
@@ -10,76 +10,49 @@
 #include <sstream>
 #include <utility>
 
-#include "core/fpdfapi/parser/cpdf_array.h"
-#include "core/fpdfapi/parser/cpdf_dictionary.h"
-#include "core/fpdfapi/parser/cpdf_stream.h"
+#include "core/fpdfdoc/cpdf_icon.h"
 #include "core/fpdfdoc/cpdf_iconfit.h"
 #include "fpdfsdk/pwl/cpwl_wnd.h"
 
 CPWL_Icon::CPWL_Icon(const CreateParams& cp,
-                     CPDF_Stream* pStream,
+                     std::unique_ptr<CPDF_Icon> pIcon,
                      CPDF_IconFit* pFit)
-    : CPWL_Wnd(cp, nullptr), m_pPDFStream(pStream), m_pIconFit(pFit) {}
+    : CPWL_Wnd(cp, nullptr), m_pIcon(std::move(pIcon)), m_pIconFit(pFit) {
+  ASSERT(m_pIcon);
+}
 
 CPWL_Icon::~CPWL_Icon() = default;
 
-std::pair<float, float> CPWL_Icon::GetImageSize() {
-  if (!m_pPDFStream)
-    return {0.0f, 0.0f};
-
-  CPDF_Dictionary* pDict = m_pPDFStream->GetDict();
-  if (!pDict)
-    return {0.0f, 0.0f};
-
-  CFX_FloatRect rect = pDict->GetRectFor("BBox");
-  return {rect.right - rect.left, rect.top - rect.bottom};
+CFX_SizeF CPWL_Icon::GetImageSize() {
+  return m_pIcon->GetImageSize();
 }
 
 CFX_Matrix CPWL_Icon::GetImageMatrix() {
-  if (!m_pPDFStream)
-    return CFX_Matrix();
-  if (CPDF_Dictionary* pDict = m_pPDFStream->GetDict())
-    return pDict->GetMatrixFor("Matrix");
-  return CFX_Matrix();
+  return m_pIcon->GetImageMatrix();
 }
 
 ByteString CPWL_Icon::GetImageAlias() {
-  if (!m_pPDFStream)
-    return ByteString();
-  if (CPDF_Dictionary* pDict = m_pPDFStream->GetDict())
-    return pDict->GetStringFor("Name");
-  return ByteString();
+  return m_pIcon->GetImageAlias();
 }
 
-std::pair<float, float> CPWL_Icon::GetIconPosition() {
+CFX_PointF CPWL_Icon::GetIconPosition() {
   if (!m_pIconFit)
-    return {0.0f, 0.0f};
+    return CFX_PointF();
 
-  const CPDF_Array* pA =
-      m_pIconFit->GetDict() ? m_pIconFit->GetDict()->GetArrayFor("A") : nullptr;
-  if (!pA)
-    return {0.0f, 0.0f};
-
-  size_t dwCount = pA->size();
-  return {dwCount > 0 ? pA->GetNumberAt(0) : 0.0f,
-          dwCount > 1 ? pA->GetNumberAt(1) : 0.0f};
+  return m_pIconFit->GetIconPosition();
 }
 
 std::pair<float, float> CPWL_Icon::GetScale() {
   float fHScale = 1.0f;
   float fVScale = 1.0f;
 
-  if (!m_pPDFStream)
-    return {fHScale, fVScale};
-
   CFX_FloatRect rcPlate = GetClientRect();
   float fPlateWidth = rcPlate.Width();
   float fPlateHeight = rcPlate.Height();
 
-  float fImageWidth;
-  float fImageHeight;
-  std::tie(fImageWidth, fImageHeight) = GetImageSize();
-
+  CFX_SizeF image_size = GetImageSize();
+  float fImageWidth = image_size.width;
+  float fImageHeight = image_size.height;
   int32_t nScaleMethod = m_pIconFit ? m_pIconFit->GetScaleMethod() : 0;
 
   switch (nScaleMethod) {
@@ -114,13 +87,13 @@
 }
 
 std::pair<float, float> CPWL_Icon::GetImageOffset() {
-  float fLeft;
-  float fBottom;
-  std::tie(fLeft, fBottom) = GetIconPosition();
+  CFX_PointF icon_position = GetIconPosition();
+  float fLeft = icon_position.x;
+  float fBottom = icon_position.y;
 
-  float fImageWidth;
-  float fImageHeight;
-  std::tie(fImageWidth, fImageHeight) = GetImageSize();
+  CFX_SizeF image_size = GetImageSize();
+  float fImageWidth = image_size.width;
+  float fImageHeight = image_size.height;
 
   float fHScale, fVScale;
   std::tie(fHScale, fVScale) = GetScale();
diff --git a/fpdfsdk/pwl/cpwl_icon.h b/fpdfsdk/pwl/cpwl_icon.h
index 3e19f84..aa9b3d7 100644
--- a/fpdfsdk/pwl/cpwl_icon.h
+++ b/fpdfsdk/pwl/cpwl_icon.h
@@ -14,12 +14,14 @@
 #include "core/fxcrt/unowned_ptr.h"
 #include "fpdfsdk/pwl/cpwl_wnd.h"
 
+class CPDF_Icon;
 class CPDF_IconFit;
-class CPDF_Stream;
 
 class CPWL_Icon final : public CPWL_Wnd {
  public:
-  CPWL_Icon(const CreateParams& cp, CPDF_Stream* pStream, CPDF_IconFit* pFit);
+  CPWL_Icon(const CreateParams& cp,
+            std::unique_ptr<CPDF_Icon> pIcon,
+            CPDF_IconFit* pFit);
   ~CPWL_Icon() override;
 
   // horizontal scale, vertical scale
@@ -32,13 +34,10 @@
   ByteString GetImageAlias();
 
  private:
-  // left, bottom
-  std::pair<float, float> GetIconPosition();
+  CFX_PointF GetIconPosition();  // left, bottom coordinates.
+  CFX_SizeF GetImageSize();
 
-  // width, height
-  std::pair<float, float> GetImageSize();
-
-  RetainPtr<CPDF_Stream> const m_pPDFStream;
+  std::unique_ptr<CPDF_Icon> const m_pIcon;
   UnownedPtr<CPDF_IconFit> const m_pIconFit;
 };